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 _beside_template( figure: TemplateObjectVariable, ground: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], *, is_right: bool, is_training: bool, ) -> Phase1SituationTemplate: direction_str = "right" if is_right else "left" handle = "training" if is_training else "testing" return Phase1SituationTemplate( f"preposition-{handle}-{figure.handle}-beside-{ground.handle}-{direction_str}", salient_object_variables=[figure, ground], background_object_variables=background, asserted_always_relations=[ near( figure, ground, direction=Direction( positive=is_right, relative_to_axis=HorizontalAxisOfObject(ground, index=0), ), ) ], gazed_objects=[figure], )
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 _go_under_template( agent: TemplateObjectVariable, goal_object: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], *, is_distal: bool, # pylint:disable=unused-argument ) -> Phase1SituationTemplate: return Phase1SituationTemplate( f"go_under-{agent.handle}-under-{goal_object.handle}", salient_object_variables=[agent, goal_object], background_object_variables=background, actions=[ Action( GO, argument_roles_to_fillers=[ (AGENT, agent), ( GOAL, Region( goal_object, distance=PROXIMAL, direction=GRAVITATIONAL_DOWN ), ), ], ) ], before_action_relations=[negate(on(goal_object, GROUND_OBJECT_TEMPLATE))], asserted_always_relations=[negate(on(goal_object, GROUND_OBJECT_TEMPLATE))], after_action_relations=[ negate(on(goal_object, GROUND_OBJECT_TEMPLATE)), near(agent, goal_object), ], constraining_relations=flatten_relations(bigger_than(goal_object, agent)), )
def _near_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}-near-{ground.handle}", salient_object_variables=[figure, ground], background_object_variables=background, asserted_always_relations=[near(figure, ground)], gazed_objects=[figure], syntax_hints=[USE_NEAR], )
def _go_to_template( agent: TemplateObjectVariable, goal_object: TemplateObjectVariable, background: Iterable[TemplateObjectVariable], ) -> Phase1SituationTemplate: return Phase1SituationTemplate( f"go_to-{agent.handle}-to-{goal_object.handle}", salient_object_variables=[agent, goal_object], background_object_variables=background, actions=[ Action( GO, argument_roles_to_fillers=[ (AGENT, agent), (GOAL, Region(goal_object, distance=PROXIMAL)), ], ) ], after_action_relations=[near(agent, goal_object)], gazed_objects=[agent], )
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 test_learner_as_default_addressee(): learner = object_variable("learner", root_node=LEARNER) ball = object_variable("ball", root_node=BALL) template_with_learner = Phase1SituationTemplate( "template with learner", salient_object_variables=[learner, ball], asserted_always_relations=[near(learner, ball)], ) template_with_out_learner = Phase1SituationTemplate( "template with out learner", salient_object_variables=[object_variable("ball", root_node=BALL)], ) template_with_addressee = Phase1SituationTemplate( "template with addressee", salient_object_variables=[ object_variable("mom", root_node=MOM, added_properties=[IS_ADDRESSEE]) ], ) situation_with_learner = tuple( sampled( template_with_learner, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, )) situation_with_out_learner = tuple( sampled( template_with_out_learner, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, )) situation_with_addressee = tuple( sampled( template_with_addressee, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, )) for object_ in situation_with_learner[0].all_objects: if object_.ontology_node == LEARNER: assert IS_ADDRESSEE in object_.properties break assert situation_with_learner[0].axis_info assert situation_with_learner[0].axis_info.addressee assert len(situation_with_out_learner[0].all_objects) == 2 for object_ in situation_with_out_learner[0].all_objects: if object_.ontology_node == LEARNER: assert IS_ADDRESSEE in object_.properties break assert situation_with_out_learner[0].axis_info assert situation_with_out_learner[0].axis_info.addressee for object_ in situation_with_addressee[0].all_objects: if object_.ontology_node == LEARNER: assert False assert situation_with_addressee[0].axis_info assert situation_with_addressee[0].axis_info.addressee
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()