예제 #1
0
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)
예제 #2
0
def combine(rel, subj_coords, obj_coords, subj_mod, obj_mod):
    """ This func. combines subj_mod and obj_mod in a way that
    satisfies rel."""
    # Get the dimensions of subj_mod and obj_mod, we need to add
    # (1, 1, 1) as the dimensions function returns 0-indexed dims.
    subj_dims = utilities.list_add(spatial_array.dimensions(subj_mod),
                                   (1, 1, 1))
    obj_dims = utilities.list_add(spatial_array.dimensions(obj_mod), (1, 1, 1))
    # dims origins will return a 3-tuple: new dims, new origin for
    # subj_mod and new origin for obj_mod
    tmp = spatial_array.dims_origins(rel, subj_dims, obj_dims, subj_coords,
                                     obj_coords)
    new_dims, new_subj_orig, new_obj_orig = tmp
    # The call to copy_array with subj_mod as inarr creates an outarr
    # of desired dimensions, and then inserts the values in inarr at the
    # correct positions in the new outarr through the copy_arr function.
    outarr = spatial_array.copy_array(subj_mod, {}, new_dims, new_subj_orig)
    # The call to copy_array with obj_mod doesn't need to create a new
    # array, it uses the array produced by the previous call with subj_mod
    # (which already has the correct dims). So this only inserts values
    # in outarr from inarr through the copy_arr function.
    outarr = spatial_array.copy_array(obj_mod, outarr, new_dims, new_obj_orig)
    return outarr
def verify(rel, subj_coords, obj_coords, mod):
    """ It returns mod if rel holds between subj_coords and obj_coords
    in mod (i.e. subj_coord can be reached by adding rel to obj_coord
    a certain number of times). Otherwise, it returns None. """
    obj_coords = utilities.list_add(rel, obj_coords)
    dims_mod = spatial_array.dimensions(mod)
    if utilities.outside(obj_coords, dims_mod) is not None:
        # obj_coords is outside dims_mod, this might occur, for e.g.,
        # when addition of rel to obj_mod has caused it to become
        # more extreme than subj_mod (and dims).
        return None
    if subj_coords == obj_coords:
        # If obj reaches subj after a certain no. of steps
        return mod
    # Recursive call with new obj_coords
    return verify(rel, subj_coords, obj_coords, mod)
예제 #4
0
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)
예제 #5
0
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)