def test_perceive_explicit_relations(): # we want to test that relations explicitly called out in the situation are perceived. # Such relations fall into three buckets: # those which hold before an action, # those which hold after an action, # and those which hold both before and after an action. # To test all three of these at once, we use a situation where # (a) Mom is putting a ball on a table # (b) before the action the ball is far from a box, # (c) but after the action the ball is near the box, # (d) throughout the action the box is on the table. mom = situation_object(MOM) ball = situation_object(BALL) box = situation_object(BOX) table = situation_object(TABLE) situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, salient_objects=[mom, box, ball, table], always_relations=[on(ball, table)], before_action_relations=[far(ball, box)], after_action_relations=[near(ball, box)], actions=[ Action( PUT, argument_roles_to_fillers=[ (AGENT, mom), (THEME, ball), ( GOAL, Region( reference_object=table, distance=EXTERIOR_BUT_IN_CONTACT, direction=GRAVITATIONAL_UP, ), ), ], ) ], ) perception = _PERCEPTION_GENERATOR.generate_perception( situation, chooser=RandomChooser.for_seed(0) ) ball_perception = perception_with_handle(perception.frames[0], "**ball_0") box_perception = perception_with_handle(perception.frames[0], "**box_0") table_perception = perception_with_handle(perception.frames[0], "**table_0") assert only(on(ball_perception, table_perception)) in perception.frames[0].relations assert only(on(ball_perception, table_perception)) in perception.frames[0].relations assert only(far(ball_perception, box_perception)) in perception.frames[0].relations assert ( only(far(ball_perception, box_perception)) not in perception.frames[1].relations ) assert ( only(near(ball_perception, box_perception)) not in perception.frames[0].relations ) assert only(near(ball_perception, box_perception)) in perception.frames[1].relations
def test_before_after_relations_asserted(): ball = object_variable("ball", root_node=BALL) box = object_variable("box", root_node=BOX) ground = object_variable("ground", root_node=GROUND) template_action = Phase1SituationTemplate( "Before/After Relation", salient_object_variables=[ball, box], background_object_variables=[ground], actions=[ Action( ROLL, argument_roles_to_fillers=[(AGENT, ball)], auxiliary_variable_bindings=[(ROLL_SURFACE_AUXILIARY, ground)], ) ], before_action_relations=flatten_relations([on(ball, box)]), after_action_relations=flatten_relations([far(ball, box)]), ) situation_with_relations = tuple( sampled( template_action, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, )) assert situation_with_relations[0].before_action_relations assert situation_with_relations[0].after_action_relations
def _in_front_template( figure: TemplateObjectVariable, ground: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], *, is_training: bool, is_near: bool, speaker_root_node: OntologyNode = PERSON, ) -> Phase1SituationTemplate: handle = "training" if is_training else "testing" direction = Direction(positive=True, relative_to_axis=FacingAddresseeAxis(ground)) speaker = standard_object("speaker", speaker_root_node, added_properties=[IS_SPEAKER]) addressee = standard_object("addressee", LEARNER, added_properties=[IS_ADDRESSEE]) computed_background = [speaker, addressee] computed_background.extend(background) return Phase1SituationTemplate( f"preposition-{handle}-{figure.handle}-behind-{ground.handle}", salient_object_variables=[figure, ground], background_object_variables=computed_background, asserted_always_relations=[ near(figure, ground, direction=direction) if is_near else far(figure, ground, direction=direction) ], gazed_objects=[figure], )
def _far_template( figure: TemplateObjectVariable, ground: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], *, is_training: bool, ) -> Phase1SituationTemplate: handle = "training" if is_training else "testing" return Phase1SituationTemplate( f"preposition-{handle}-{figure.handle}-far-{ground.handle}", salient_object_variables=[figure, ground], background_object_variables=background, asserted_always_relations=[far(figure, ground)], gazed_objects=[figure], )
def _in_front_template( figure: TemplateObjectVariable, ground: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], *, is_training: bool, is_near: bool, background_relations: Iterable[Relation[Any]] = immutableset(), ) -> Phase1SituationTemplate: handle = "training" if is_training else "testing" direction = Direction(positive=True, relative_to_axis=FacingAddresseeAxis(ground)) relations = [ near(figure, ground, direction=direction) if is_near else far(figure, ground, direction=direction) ] relations.extend(background_relations) # type: ignore return Phase1SituationTemplate( f"preposition-{handle}-{figure.handle}-behind-{ground.handle}", salient_object_variables=[figure, ground], background_object_variables=background, asserted_always_relations=flatten_relations(relations), gazed_objects=[figure], )
def background_relations_builder( background_objects: Iterable[TemplateObjectVariable], num_relations: int, *, target: Optional[TemplateObjectVariable] = None, target_2: Optional[TemplateObjectVariable] = None, add_noise: bool = True, include_targets_in_noise: bool = False, chooser: RandomChooser = RandomChooser.for_seed(0), ) -> Iterable[Relation[Any]]: if add_noise: potential_objects = list(background_objects) if target and include_targets_in_noise: potential_objects.append(target) if target_2 and include_targets_in_noise: potential_objects.append(target_2) if len(potential_objects) < 2: return immutableset() relations = [] for _ in range(num_relations): choice = chooser.choice(NOISE_RELATION_DSL_OPTIONS) if choice == "on": relations.append( on( chooser.choice(potential_objects), chooser.choice(potential_objects), )) elif choice == "beside": obj_choice_2 = chooser.choice(potential_objects) relations.append( near( chooser.choice(potential_objects), obj_choice_2, direction=Direction( positive=chooser.choice(BOOL_SET), relative_to_axis=HorizontalAxisOfObject( obj_choice_2, index=0), ), )) elif choice == "under": relations.append( strictly_under( chooser.choice(potential_objects), chooser.choice(potential_objects), dist=DISTAL if chooser.choice(BOOL_SET) else PROXIMAL, )) elif choice == "in_front": obj_choice_2 = chooser.choice(potential_objects) direction = Direction( positive=chooser.choice(BOOL_SET), relative_to_axis=FacingAddresseeAxis(obj_choice_2), ) relations.append( near( chooser.choice(potential_objects), obj_choice_2, direction=direction, ) if chooser.choice(BOOL_SET) else far( chooser.choice(potential_objects), obj_choice_2, direction=direction, )) else: raise RuntimeError( "Invalid relation type in background relations") return flatten_relations(relations) else: return immutableset()