def add_it_prism(coords, rel, items, mod, annotations):
    """ This func. adds item and returns the new model (mod). The first
    test detects 'in same place' and item is added to whatever is at
    coords.  Second test detects when coords are outside, then list of
    new_dims + new_orig is used to copy mod to new mod. item is added to
    this, having changed coords by adding new_orig to them. Third test:
    used to check if mod[coords], i.e. cell at current coords, is empty.
    In this case, item is added.  Finally, where cells already has item,
    update coords according to rel and try again. As it is recursive and
    may increase co-ords, it needs to expand array sometimes. """
    item, item_in_mod = items
    if rel == (0, 0, 0):
        # Get what is currently present in mod at coordinates coords.
        current = mod.get(coords)
        # Concatenate item to what is already present at the given
        # coordinates in mod (item and current are strings).
        item = item + current if current is not None else item
        mod[coords] = item
        return mod, annotations
    dims_mod = spatial_array.dimensions(mod)
    # If coords is not within dims_mod, adjust origin and coords suitably.
    # outside returns ((new_coords),(new_origin)) = newlis
    newlis = utilities.outside(coords, dims_mod)
    if newlis is not None:
        # Expand mod by making space for an extra item
        mod = spatial_array.copy_array(mod, {}, newlis[0], newlis[1])
        # New origin, so old coords have to be updated
        new_coords = utilities.list_add(coords, newlis[1])
        items = (item, item_in_mod)
        return add_it_prism(new_coords, rel, items, mod, annotations)
    # Reaches here when coords is within dims, rel != 0,0,0 and
    # mod[coords] has space (is None) for a new item, which can be inserted.
    if mod.get(coords) is None:
        # An annotation is necessary only in the special case where the already
        # -present item is the 2nd element (LO) of some annotation AND we
        # are moving in the same direction as rel. In this case, we add
        # the annotation: [rel, item, item_in_mod]
        new_annotation = subj_or_obj_in_annotations(annotations, item, rel,
                                                    item_in_mod)
        if new_annotation is not None:
            annotations.append(new_annotation)
        mod[coords] = item
        return mod, annotations
    # If there is another item at mod[coords], move further along the
    # direction specified by rel, and try to add item there.

    # Find the coords of the token already present in the model (this might be
    # the subject or the object. Remember, coords has already been updated in
    # add_item. We don't need to reverse this update.

    # Whether it's add subj or add obj, rel will be the same (as add_obj gets
    # the negation of rel. The new item is somewhere to the rel of item_in_mod
    # The ref obj always goes at the end of the annotation
    new_annotation = [rel, item, item_in_mod]
    if new_annotation not in annotations:
        annotations.append(new_annotation)
    # Continue as per fff strategy and add the token.
    updated_coords = utilities.update_coords(coords, rel)
    items = (item, item_in_mod)
    return add_it_prism(updated_coords, rel, items, mod, annotations)
def move(item, item_coords, rel, other_coords, mod):
    """ Moves the item at item_coords into rel with other_coords in model.
    Uses update_coords and rel of (0,0,0) so as to put item into cell
    even if cell is already occupied. Note: this is called on subject/obj
    of each of the conflicting props (premises) AFTER swapping the subject and
    object of the conclusion premise. Finally, it returns the updated model.
    """
    # Deep copy needed as mod is mutable.
    new_mod = copy.deepcopy(mod)
    # remove the item at item coord
    new_mod = remove_item(item, item_coords, new_mod)
    updated_coords = utilities.update_coords(other_coords, rel)
    new_pos = new_position(item_coords, rel, other_coords, updated_coords)
    new_mod = model_builder.add_item(new_pos, (0, 0, 0), item, new_mod)
    return new_mod
def add_item(coords, rel, item, mod):
    """ This function updates coordinates (coords) according to rel
    and then calls add_it. It checks if coordinates are outside the
    model, and if so, expands mod. This is necessary in case rel is
    (0, 0, 0), but assigned coords are outside. """

    coords = utilities.update_coords(coords, rel)
    # Dimensions: 0-based.
    dims_mod = spatial_array.dimensions(mod)
    # Check if new token will fit into the existing array, or if it needs
    # expansion. If it needs expansion, get the new dimensions & new origin.
    # newlis = (newdims, neworigin)
    newlis = utilities.outside(coords, dims_mod)
    if rel == (0, 0, 0) and newlis is not None:
        mod = spatial_array.copy_array(mod, {}, newlis[0], newlis[1])
        coords = utilities.list_add(coords, newlis[1])
    return add_it(coords, rel, item, mod)
def add_it(coords, rel, item, mod):
    """ This func. adds item and returns the new model (mod). The first
    test detects 'in same place' and item is added to whatever is at
    coords.  Second test detects when coords are outside, then list of
    new_dims + new_orig is used to copy mod to new mod. item is added to
    this, having changed coords by adding new_orig to them. Third test:
    used to check if mod[coords], i.e. cell at current coords, is empty.
    In this case, item is added.  Finally, where cells already has item,
    update coords according to rel and try again. As it is recursive and
    may increase co-ords, it needs to expand array sometimes. """
    if rel == (0, 0, 0):
        # Get what is currently present in mod at coordinates coords.
        current = mod.get(coords)
        # Concatenate item to what is already present at the given
        # coordinates in mod (item and current are strings).
        item = item + current if current is not None else item
        mod[coords] = item
        return mod
    dims_mod = spatial_array.dimensions(mod)
    # If coords is not within dims_mod, adjust origin and coords suitably.
    # outside returns ((new_coords),(new_origin)) = newlis
    newlis = utilities.outside(coords, dims_mod)
    if newlis is not None:
        # Expand mod by making space for an extra item
        mod = spatial_array.copy_array(mod, {}, newlis[0], newlis[1])
        # New origin, so old coords have to be updated
        new_coords = utilities.list_add(coords, newlis[1])
        return add_it(new_coords, rel, item, mod)
    # Reaches here when coords is within dims, rel != 0,0,0 and
    # mod[coords]has space (is None) for a new item, which can be inserted.
    if mod.get(coords) is None:
        mod[coords] = item
        return mod
    # If there is another item at mod[coords], move further along the
    # direction specified by rel, and try to add item there.
    updated_coords = utilities.update_coords(coords, rel)
    return add_it(updated_coords, rel, item, mod)
Exemple #5
0
    def get_alternate_models(self, mod, i=0, neighbourhood=0):
        """ Recursive: goes through annotations, find the reference object (3rd
        term in annotation) and located object (2nd term) in the model. Find
        intermed object by moving from loc to ref object in the correct dir.
        The intermediate and located objects are effectively exchanged, along
        with objects which are grouped with them.
        KWARGS: i: iteration number (used to get alternate models from each
                   of the models in the changing list self.modelslist).
                neighbourhood: current neigbhourhood
        The recursive call at the end gets alternative models for every member
        in self.modelslist: i.e. this includes models created inside the for
        loop in the previous iteration. The stopping condition is when the
        iteration variable becomes len(self.modelslist) - 1.
        """
        orig_mod = copy.deepcopy(mod)
        new_neighbourhood = neighbourhood + 1
        for annotation in self.annotations:
            # annotation: [[rel], l.o., r.o]
            # coords_to_swap is of the form [[coords_loc1, coords_int1],
            # [coords_loc2, coords_int2],...]. mod[coords_int_m] and
            # mod[coords_loc_n] need to be swapped.
            located_object = annotation[1]
            # Get the coords of reference_object and located_object in mod.
            # reference_object = annotation[2]
            ref_coords = utilities.get_coordinates_from_token(
                annotation[2], orig_mod)
            loc_coords = utilities.get_coordinates_from_token(
                located_object, orig_mod)
            # Move in direction negate(rel) from the located object - i.e. find
            # tokens in between ref object and loc object.
            rel_to_move = utilities.convert(annotation[0])
            # Find instances in which the reference object is found in the
            # subject of the premise (intensionalrepr), and instances in which
            # it is found in the object of the premise.
            intermediate_coords = utilities.update_coords(
                loc_coords, rel_to_move)
            # If intermeidate_coords = ref_coords (and therefore, ref_obj
            # = intermediate_object, this annotation should NOT be processed.
            # The ref and loc object SHOULD NOT be swapped in any case)
            if intermediate_coords == ref_coords:
                continue
            intermediate_object = orig_mod.get(intermediate_coords)
            tokens_coordinates = self.create_groups(
                rel_to_move, (intermediate_object, intermediate_coords),
                (located_object, loc_coords), orig_mod)

            mod = spatial_array.insert_moved_objects(tokens_coordinates,
                                                     orig_mod)
            if mod not in self.modelslist:
                self.modelslist.append(mod)
                self.neighbourhoodmodels[new_neighbourhood].append(mod)

        if i < len(self.modelslist) - 1:
            # Set the value of new_neighbourhood to send in the recursive call
            # based on if a model has already been inserted in the current
            # neighbourhood or not. If not, the recursive call will have the
            # old value of neighbourhood again.
            new_neighbourhood = new_neighbourhood \
                if self.neighbourhoodmodels[new_neighbourhood] != [] \
                else neighbourhood
            # The above check produces an empty list because it's a defaultdict
            # Remove this new empty list element at a new key
            self.delete_empty_keys()
            # Recursive call with next model in modelslist
            #  newmod = copy.deepcopy(self.modelslist[i+1])
            self.get_alternate_models(copy.deepcopy(self.modelslist[i + 1]),
                                      i + 1, new_neighbourhood)