def update_coords(coords, relation): """ Returns the added coords and relation as a list where each element is the sum of the two corresponding numbers. If relation is None, returns None. """ if not relation: return coords return helper.tuple_add(coords, relation)
def add_item(coordinates, relation, item, model): """ New version of add_item + add_it Function adds the given item to the model by using the coordinates and the relation (relation and coordinates need to be tuples). Adds the relation to the coordinates in order to get the real coordinates that the item should have in the model by calling tuple_add. If the relation is (0, 0, 0), gets the item at the target coordinates, if there is an element, and concatenates item and this element. If the slot is still empty, the item is simply inserted at this slot and afterwards the model is returned. If the relation wasn´t (0, 0, 0), search for the first empty slot (by adding the relation to the target coordinates until a free slot is reached), and insert the item. (Note: Only the Temporal Model needs to work on the copy in order to construct all possible models, but it works that way as well for the Spatial Model.) """ target_coords = helper.tuple_add(coordinates, relation) if PRINT_MODEL: print("add_item: coords:", coordinates, "rel", relation, "--> target", target_coords, "item", item, "mod", model) if relation == (0, 0, 0): # check if there is already an object at the given coords. if model.get(target_coords) is not None: item = [item, model.get(target_coords) ] # add the item to the already existing one model[target_coords] = item # add the item to the model at the coords return model # check if there is another object at the current coords. while model.get(target_coords) is not None: # search the first free spot in the correlating axis in the model. # add the relation to coords until a free spot is found. target_coords = helper.tuple_add(target_coords, relation) if PRINT_MODEL: print("add the item at coords:, ", item, target_coords) model2 = copy.deepcopy(model) # FOR TEMPORAL model2[target_coords] = item # add the item to the model return model2
def insert_it(rel, item, coords, mod): """ Function inserts an item according to the relation. If the target coordinates are not contained in the dictionary, function simply inserts the target coordinates as a key with the new value (item) in the dictionary. If the target spot is already occupied and if the relation contains a positive number, the function adds the item at the according target spot (or with a negative number, at the coords spot) and shifts all other items, that are affected by the new insertion, one spot to the right/top (+1). (Note: The function works on copies of the model since in case a problem can lead to many models, all of these models should be created and thus the insertion process should be continued on a copied version of the original model). """ target = helper.tuple_add(rel, coords) if mod.get(target) is None: # add item to empty target cell mod2 = copy.deepcopy(mod) mod2[target] = item return mod2 else: # target cell already occupied if mod.get(coords) is not None: mod3 = copy.deepcopy(mod) if rel[0] == 1: # after relation --> shift elements mod3 = shift_coordinates(mod3, target, 0) mod3[target] = item elif rel[0] == -1: # before relation --> shift elements mod3 = shift_coordinates(mod3, coords, 0) mod3[coords] = item elif rel[1] == 1: mod3 = shift_coordinates(mod3, target, 1) mod3[target] = item elif rel[1] == -1: mod3 = shift_coordinates(mod3, coords, 1) mod3[coords] = item elif rel[2] == 1: mod3 = shift_coordinates(mod3, target, 2) mod3[target] = item elif rel[2] == -1: mod3 = shift_coordinates(mod3, coords, 2) mod3[coords] = item return mod3 return mod
def shift_coordinates(mod, coords, index): """ Function to shift all items with their coordinates in a model that are affected by the insertion of a new item. "coords" are the coordinates, where the new item is going to be inserted, so all items that have coordinates that equal to "coords" or are bigger than "coords" need to be shifted to the right. Function first determines on which axis the affected items need to be shifted to, then saves all of the affected keys with the new key-coordinates in the list "keys_to_delete", and after finishing the for-loop, deletes this keys and inserts the new key-values for the shifted items. """ if PRINT_MODEL: print("shift_coordinates: mod", mod, "coords", coords, "index", index) # Determine axis to shift the key-coordinates. tuple_to_add = () if index == 0: tuple_to_add = (1, 0, 0) elif index == 1: tuple_to_add = (0, 1, 0) elif index == 2: tuple_to_add = (0, 0, 1) # Determine all keys that need to be replaced by another key. keys_to_delete = [] # First is the key to delete, second the new key for key in mod.keys(): if key[index] >= coords[index]: new_coords = helper.tuple_add(key, tuple_to_add) keys_to_delete.append([key, new_coords]) keys_to_delete = sorted(keys_to_delete, key=lambda x: x[0]) if PRINT_MODEL: print("keys to update/delete are", reversed(keys_to_delete)) # Replace the old key-coordinates by the new ones. for key in reversed(keys_to_delete): new_val = mod[key[0]] mod[key[1]] = new_val del mod[key[0]] if PRINT_MODEL: print("model after shifting is", mod) return mod
def add_item_mod(coords, rel, item, mod, spatial_parser): """ Function adds the specified item to the model. In case there is an indeterminacy, the function returns a list of models corresponding to each possible interpretation, otherwise a list of one model. (Note: Indeterminacies do not occur in case of "while" so far) (Note2: The Temporal model shall construct all possible models for a given Spatial or Temporal problem. However, in case of a temporal problem with the relation "while", the order between the items which are in a while-relation to each other, does not matter. In that case (and no other case), the function "add_item", which is mainly used by the Spatial Model and implements a first-fit-strategy, can be used to insert the item). """ if PRINT_MODEL: print("add_item_mod; rel", rel, "co", coords, "item", item, "mod", mod) # order is only irrelevant in temporal models for a "while" relation. if not spatial_parser and (rel == (0, 1, 0)): if PRINT_MODEL: print("add_item_mod: relation is while, call add-it!") return [add_item(coords, rel, item, mod)] else: tmp = insert_it(rel, item, coords, mod) tmp2 = make_indets(rel, item, helper.tuple_add(coords, rel), mod, spatial_parser) if PRINT_MODEL: print("Add_item_mod: Insert leaded to:", tmp, "make_indets leaded to:", tmp2) if tmp2 != None: print("add_item_mod: Inserting item", item, "leaded to different models!") return_list = [] return_list.append(tmp) for model in tmp2: return_list.append(model) if PRINT_MODEL: print("add_item_mod: Return the following list:", return_list) return return_list else: return [tmp]
def make_indets(rel, item, co_, mod, spatial_parser): """ Function creates set of different potential models when a temporal relation is indeterminate, allowing each indeterminacy between two items x and y to yield a model in which x is before y, a model in which x is after y and a model where x is while y. Example: rel = (-1,0,0), item a is before d. mod = b c d. Leads to five different models (in this case, the direction left-right is before/after, and elements beneath other elements illustrate "while"): a b c d, b c d, b a c d, b c d, b c a d a a (b and c in this example are called the "interveners".) (Note: Function was adapted to also work for Spatial relations, except the case of the relation (0,-1,0) which would interfere with the while-relation in case the problem is a temporal problem. (this is due to the fact that for temporal relations, the order of items in a while-relation doesn´t matter, so (0, 1, 0) can be added without problems to the coordinates of a temporal problem to get the while-intervener. Since spatial problems work differently and the order always matters, this approach does not work for spatial problems, so an exception is need to be made)). """ if PRINT_MODEL: print("Function call - make_indets; rel", rel, "item", item, "co", co_, "mod", mod) # Check if coordinates are already outside current dimensions. dims = helper.dict_dimensions(mod) if rel == (0, 1, 0) or rel == (0, -1, 0): # while relation --> y-coord relevant! if (co_[1] > dims[1]) or (co_[1] < -dims[1]): return None elif rel == (0, 0, 1) or rel == (0, 0, -1): # Third dimension, only for spatial if (co_[2] > dims[2]) or (co_[2] < -dims[2]): return None else: # before or after relation --> x-coord relevant! if (co_[0] > dims[0]) or (co_[0] < -dims[0]): return None if mod.get(co_) != None: ins = insert_it(rel, item, co_, mod) # item relation intervener add = None if rel != (0, -1, 0): # EXCEPTION FOR SPATIAL PROBLEMS (see docstring above) add = add_item(co_, (0, 1, 0), item, mod) # item while intervener ind = make_indets(rel, item, helper.tuple_add(co_, rel), mod, spatial_parser) if PRINT_MODEL: print("---Make indets: Insert it is: ", ins, " add is: ", add, " indets is: ", ind) if add != None: if ind != None: return_list = [ins, add] for model in ind: return_list.append(model) return return_list return [ins, add] elif ind != None: return_list = [ins] for model in ind: return_list.append(model) return return_list return [ins] ind2 = make_indets(rel, item, helper.tuple_add(co_, rel), mod, spatial_parser) if PRINT_MODEL: print("Make indets (außerhalb if):", ind2) return ind2