diff --git a/adam/curriculum/attribute_constraining_action_curriculum.py b/adam/curriculum/attribute_constraining_action_curriculum.py index 5999cabf4..6ce0dcc1d 100644 --- a/adam/curriculum/attribute_constraining_action_curriculum.py +++ b/adam/curriculum/attribute_constraining_action_curriculum.py @@ -45,6 +45,7 @@ def make_human_eat_curriculum( max_to_sample=num_samples if num_samples else 5, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -69,6 +70,7 @@ def make_animal_eat_curriculum( max_to_sample=num_samples if num_samples else 5, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -100,6 +102,7 @@ def make_german_eat_test_curriculum( max_to_sample=num_samples if num_samples else 5, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) ] ), diff --git a/adam/curriculum/imprecise_descriptions_curriculum.py b/adam/curriculum/imprecise_descriptions_curriculum.py index 8224f1a8a..9e9959f99 100644 --- a/adam/curriculum/imprecise_descriptions_curriculum.py +++ b/adam/curriculum/imprecise_descriptions_curriculum.py @@ -1,9 +1,10 @@ from itertools import chain -from typing import Sequence, Optional +from typing import Sequence, Optional, Iterable from immutablecollections import immutableset from more_itertools import flatten from adam.language.language_generator import LanguageGenerator from adam.language.dependency import LinearizedDependencyTree +from adam.ontology import OntologyNode from adam.curriculum.curriculum_utils import ( Phase1InstanceGroup, PHASE1_CHOOSER_FACTORY, @@ -12,6 +13,9 @@ learner_template_factory, make_noise_objects, ) +from adam.language_specific import MASS_NOUN +from adam.language.dependency.universal_dependencies import NOUN +from adam.ontology.phase2_ontology import gravitationally_aligned_axis_is_largest from adam.ontology import IS_SPEAKER, IS_ADDRESSEE from adam.curriculum.phase1_curriculum import ( make_pass_template, @@ -34,7 +38,6 @@ ) from adam.language_specific.english.english_language_generator import ( USE_ADVERBIAL_PATH_MODIFIER, - USE_VERTICAL_MODIFIERS, ) from adam.ontology import THING from adam.ontology.phase1_ontology import ( @@ -68,6 +71,8 @@ TABLE, THEME, SPIN, + HEAD, + HAND, ) from adam.situation import Action, SituationObject from adam.situation.high_level_semantics_situation import HighLevelSemanticsSituation @@ -76,72 +81,30 @@ TemplateObjectVariable, Phase1SituationTemplate, ) +from adam.language_specific.english.english_phase_1_lexicon import ( + GAILA_PHASE_1_ENGLISH_LEXICON, +) BOOL_SET = immutableset([True, False]) - -def _big_x_template( - theme: TemplateObjectVariable, noise_objects: Optional[int] -) -> Phase1SituationTemplate: - learner = learner_template_factory() - computed_background = [learner] - computed_background.extend(make_noise_objects(noise_objects)) - return Phase1SituationTemplate( - f"big-{theme.handle}", - salient_object_variables=[theme], - background_object_variables=computed_background, - asserted_always_relations=[bigger_than(theme, learner)], - ) - - -def _little_x_template( - theme: TemplateObjectVariable, noise_objects: Optional[int] -) -> Phase1SituationTemplate: - learner = learner_template_factory() - computed_background = [learner] - computed_background.extend(make_noise_objects(noise_objects)) - return Phase1SituationTemplate( - f"small-{theme.handle}", - salient_object_variables=[theme], - background_object_variables=computed_background, - asserted_always_relations=[bigger_than(learner, theme)], - ) - - -def _tall_x_template( - theme: TemplateObjectVariable, noise_objects: Optional[int] -) -> Phase1SituationTemplate: - learner = learner_template_factory() - computed_background = [learner] - computed_background.extend(make_noise_objects(noise_objects)) - - # TODO: This difference should be an axis size but we can't yet - # implement that. See: https://github.com/isi-vista/adam/issues/832 - return Phase1SituationTemplate( - f"tall-{theme.handle}", - salient_object_variables=[theme], - background_object_variables=computed_background, - asserted_always_relations=[bigger_than(theme, learner)], - syntax_hints=[USE_VERTICAL_MODIFIERS], - ) - - -def _short_x_template( - theme: TemplateObjectVariable, noise_objects: Optional[int] -) -> Phase1SituationTemplate: - learner = learner_template_factory() - computed_background = [learner] - computed_background.extend(make_noise_objects(noise_objects)) - - # TODO: This difference should be an axis size but we can't yet - # implement that. See: https://github.com/isi-vista/adam/issues/832 - return Phase1SituationTemplate( - f"tall-{theme.handle}", - salient_object_variables=[theme], - background_object_variables=computed_background, - asserted_always_relations=[bigger_than(learner, theme)], - syntax_hints=[USE_VERTICAL_MODIFIERS], - ) +# easy hack to get all nouns that aren't recognized particulars, body parts, or mass nouns -- i.e. the ones that can be big or small +NODES_TO_CHOOSE_FROM = [ + x[0] + for x in GAILA_PHASE_1_ENGLISH_LEXICON._ontology_node_to_word.items() # pylint:disable=protected-access + if x[1].part_of_speech in [NOUN] + and MASS_NOUN not in x[1].properties + and x[0] not in [BABY, HEAD, HAND] +] +# differentiate between the nodes that can be modified with tall and those that can't +TALL_ELIGIBLE_NODES = [ + node + for node in NODES_TO_CHOOSE_FROM + if gravitationally_aligned_axis_is_largest(node, GAILA_PHASE_1_ONTOLOGY) +] +BIG_ELIGIBLE_NODES = [ + node for node in NODES_TO_CHOOSE_FROM if node not in TALL_ELIGIBLE_NODES +] +CHOOSER = PHASE1_CHOOSER_FACTORY() def make_eat_big_small_curriculum( # pylint: disable=unused-argument @@ -170,7 +133,12 @@ def make_eat_big_small_curriculum( # pylint: disable=unused-argument for _object in [COOKIE, WATERMELON]: object_to_eat = SituationObject.instantiate_ontology_node( ontology_node=_object, - debug_handle=_object.handle, + debug_handle=_object.handle + "_salient", + ontology=GAILA_PHASE_1_ONTOLOGY, + ) + object_to_eat2 = SituationObject.instantiate_ontology_node( + ontology_node=_object, + debug_handle=_object.handle + "_non_salient", ontology=GAILA_PHASE_1_ONTOLOGY, ) other_edibles = [ @@ -183,15 +151,16 @@ def make_eat_big_small_curriculum( # pylint: disable=unused-argument ] computed_background = [learner] computed_background.extend(other_edibles) + computed_background.extend([object_to_eat2]) # Big for relation_list in [ [ - bigger_than(object_to_eat, learner), + bigger_than(object_to_eat, object_to_eat2), bigger_than(object_to_eat, other_edibles), ], [ - bigger_than(learner, object_to_eat), + bigger_than(object_to_eat2, object_to_eat), bigger_than(other_edibles, object_to_eat), ], ]: @@ -218,9 +187,82 @@ def make_eat_big_small_curriculum( # pylint: disable=unused-argument ) -# TODO: Refactor this curriculum -# See: https://github.com/isi-vista/adam/issues/898 -def make_spin_tall_short_curriculum( # pylint: disable=unused-argument +def _tall_x_template( + background: Iterable[TemplateObjectVariable], + random_node: OntologyNode = CHOOSER.choice(TALL_ELIGIBLE_NODES), +) -> Phase1SituationTemplate: + # hack to pick a random node that will yield "tall" + theme1 = standard_object("theme1", random_node) + theme2 = standard_object("theme2", random_node) + computed_background = [theme2] + computed_background.extend(background) + return Phase1SituationTemplate( + f"tall-{theme1.handle}", + salient_object_variables=[theme1], + background_object_variables=computed_background, + asserted_always_relations=[bigger_than(theme1, theme2)], + gazed_objects=[theme1], + ) + + +def _big_x_template( + background: Iterable[TemplateObjectVariable], + random_node: OntologyNode = CHOOSER.choice(BIG_ELIGIBLE_NODES), +) -> Phase1SituationTemplate: + # hack to pick a random node that will yield "big" + theme1 = standard_object("theme1", random_node) + theme2 = standard_object("theme2", random_node) + computed_background = [theme2, learner_template_factory()] + computed_background.extend(background) + return Phase1SituationTemplate( + f"big-{theme1.handle}", + salient_object_variables=[theme1], + background_object_variables=computed_background, + asserted_always_relations=[bigger_than(theme1, theme2)], + gazed_objects=[theme1], + ) + + +def _little_x_template( + background: Iterable[TemplateObjectVariable], + random_node: OntologyNode = CHOOSER.choice(BIG_ELIGIBLE_NODES), +) -> Phase1SituationTemplate: + # hack to pick a random node that will yield "little" + theme1 = standard_object("theme1", random_node) + theme2 = standard_object("theme2", random_node) + computed_background = [theme2] + computed_background.extend(background) + return Phase1SituationTemplate( + f"little-{theme1.handle}", + salient_object_variables=[theme1], + background_object_variables=computed_background, + asserted_always_relations=[bigger_than(theme2, theme1)], + gazed_objects=[theme1], + ) + + +def _short_x_template( + background: Iterable[TemplateObjectVariable], + random_node: OntologyNode = CHOOSER.choice(TALL_ELIGIBLE_NODES), +) -> Phase1SituationTemplate: + # hack to pick a random node that will yield "short" + theme1 = standard_object("theme1", random_node) + theme2 = standard_object("theme2", random_node) + computed_background = [theme2] + computed_background.extend(background) + return Phase1SituationTemplate( + f"short-{theme1.handle}", + salient_object_variables=[theme1], + background_object_variables=computed_background, + asserted_always_relations=[bigger_than(theme2, theme1)], + gazed_objects=[theme1], + ) + + +def make_spin_tall_short_curriculum( + # TODO: Refactor this curriculum + # See: https://github.com/isi-vista/adam/issues/898 + # pylint: disable=unused-argument num_samples: Optional[int], noise_objects: Optional[int], language_generator: LanguageGenerator[ @@ -245,7 +287,12 @@ def make_spin_tall_short_curriculum( # pylint: disable=unused-argument for _object in [CHAIR, TABLE]: theme = SituationObject.instantiate_ontology_node( ontology_node=_object, - debug_handle=_object.handle, + debug_handle=_object.handle + "_salient", + ontology=GAILA_PHASE_1_ONTOLOGY, + ) + theme2 = SituationObject.instantiate_ontology_node( + ontology_node=_object, + debug_handle=_object.handle + "_non_salient", ontology=GAILA_PHASE_1_ONTOLOGY, ) other_objs = [ @@ -258,11 +305,12 @@ def make_spin_tall_short_curriculum( # pylint: disable=unused-argument ] computed_background = [learner] computed_background.extend(other_objs) + computed_background.extend([theme2]) # Tall and short for relation_list in [ - [bigger_than(learner, theme), bigger_than(other_objs, theme)], - [bigger_than(theme, learner), bigger_than(theme, other_objs)], + [bigger_than(theme2, theme), bigger_than(other_objs, theme)], + [bigger_than(theme, theme2), bigger_than(theme, other_objs)], ]: situations.append( HighLevelSemanticsSituation( @@ -279,7 +327,6 @@ def make_spin_tall_short_curriculum( # pylint: disable=unused-argument ) ], always_relations=relation_list, - syntax_hints=[USE_VERTICAL_MODIFIERS], ) ) @@ -295,31 +342,51 @@ def make_imprecise_size_descriptions( HighLevelSemanticsSituation, LinearizedDependencyTree ], ) -> Phase1InstanceGroup: - theme_0 = standard_object("theme", banned_properties=[IS_SPEAKER, IS_ADDRESSEE]) - theme_1 = standard_object( - "theme-thing", THING, banned_properties=[IS_SPEAKER, IS_ADDRESSEE] + # we choose random tall and short nodes here + random_tall_nodes = ( + [CHOOSER.choice(TALL_ELIGIBLE_NODES) for i in range(num_samples)] + if num_samples + else [CHOOSER.choice(TALL_ELIGIBLE_NODES) for i in range(5)] + ) + random_big_nodes = ( + [CHOOSER.choice(BIG_ELIGIBLE_NODES) for i in range(num_samples)] + if num_samples + else [CHOOSER.choice(BIG_ELIGIBLE_NODES) for i in range(5)] ) + background = make_noise_objects(noise_objects) + return phase1_instances( "Imprecise Size", chain( flatten( + # generate big and small for all eligible nodes [ sampled( - template(theme, noise_objects), + template(random_node=node, background=background), ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=False, max_to_sample=num_samples if num_samples else 5, ) - for template in [ - _big_x_template, - _little_x_template, - _tall_x_template, - _short_x_template, - ] - for theme in [theme_0, theme_1] + for node in random_big_nodes + for template in [_big_x_template, _little_x_template] ] - ) + ), + flatten( + # generate tall and short for all eligible nodes + [ + sampled( + template(random_node=node, background=background), + ontology=GAILA_PHASE_1_ONTOLOGY, + chooser=PHASE1_CHOOSER_FACTORY(), + max_to_sample=1, + block_multiple_of_the_same_type=False, + ) + for node in random_tall_nodes + for template in [_tall_x_template, _short_x_template] + ] + ), ), language_generator=language_generator, ) @@ -363,6 +430,7 @@ def make_throw_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -379,6 +447,7 @@ def make_throw_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -396,6 +465,7 @@ def make_throw_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET for is_up in BOOL_SET @@ -413,6 +483,7 @@ def make_throw_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -457,6 +528,7 @@ def make_move_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -473,6 +545,7 @@ def make_move_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -514,6 +587,7 @@ def make_jump_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for use_adverbial_path_modifier in (True, False) for is_fast in BOOL_SET @@ -553,6 +627,7 @@ def make_take_grab_subtle_verb_distinction( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for use_adverbial_path_modifier in BOOL_SET for hard_force in BOOL_SET @@ -611,6 +686,7 @@ def make_push_shove_subtle_verb_distinctions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in templates ] @@ -654,6 +730,7 @@ def make_walk_run_subtle_verb_distinction( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for use_adverbial_path_modifier in BOOL_SET for hard_force in BOOL_SET @@ -694,6 +771,7 @@ def make_pass_toss_subtle_verb_distinction( else [SOFT_FORCE], background=background, ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, @@ -737,6 +815,7 @@ def make_roll_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -753,6 +832,7 @@ def make_roll_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -769,6 +849,7 @@ def make_roll_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), @@ -804,6 +885,7 @@ def make_fly_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_up in BOOL_SET for syntax_hints in syntax_hints_options @@ -841,6 +923,7 @@ def make_fall_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for object_ends_up_on_ground in BOOL_SET for syntax_hints in syntax_hints_options @@ -857,6 +940,7 @@ def make_fall_imprecise_temporal_descriptions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_fast in BOOL_SET ), diff --git a/adam/curriculum/m6_curriculum.py b/adam/curriculum/m6_curriculum.py index 8724f5a52..061128212 100644 --- a/adam/curriculum/m6_curriculum.py +++ b/adam/curriculum/m6_curriculum.py @@ -135,6 +135,7 @@ def _make_m6_on_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) @@ -167,6 +168,7 @@ def _make_m6_beside_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) @@ -199,6 +201,7 @@ def _make_m6_under_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) @@ -231,6 +234,7 @@ def _make_m6_over_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) @@ -264,6 +268,7 @@ def _make_m6_behind_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) @@ -297,6 +302,7 @@ def _make_m6_in_front_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 1, + block_multiple_of_the_same_type=True, ) for object_1 in r.sample(SMALL_OBJECT_VARS, 3) for object_2 in r.sample(LARGE_OBJECT_VARS, 3) diff --git a/adam/curriculum/phase1_curriculum.py b/adam/curriculum/phase1_curriculum.py index 5f2204682..78424cfa6 100644 --- a/adam/curriculum/phase1_curriculum.py +++ b/adam/curriculum/phase1_curriculum.py @@ -211,6 +211,7 @@ def _make_each_object_by_itself_curriculum( # pylint: disable=unused-argument max_to_sample=num_samples, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -223,6 +224,7 @@ def _make_each_object_by_itself_curriculum( # pylint: disable=unused-argument max_to_sample=num_samples, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -236,6 +238,7 @@ def _make_each_object_by_itself_curriculum( # pylint: disable=unused-argument ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=5, + block_multiple_of_the_same_type=True, ) for object in [MOM, DAD, BABY] ), @@ -245,6 +248,7 @@ def _make_each_object_by_itself_curriculum( # pylint: disable=unused-argument ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=5, + block_multiple_of_the_same_type=True, ) for object in [MOM, DAD, BABY] ), @@ -283,6 +287,7 @@ def _make_objects_with_colors_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 80, + block_multiple_of_the_same_type=True, ) ] ), @@ -320,6 +325,7 @@ def _make_objects_with_colors_is_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 80, + block_multiple_of_the_same_type=True, ) ] ), @@ -467,6 +473,7 @@ def _make_object_on_ground_curriculum( # pylint: disable=unused-argument ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -479,6 +486,7 @@ def _make_object_on_ground_curriculum( # pylint: disable=unused-argument ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -531,6 +539,7 @@ def _make_person_has_object_curriculum( inanimate_object_0, background=background, ), + block_multiple_of_the_same_type=True, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 35, @@ -599,6 +608,7 @@ def _make_part_whole_curriculum( # pylint: disable=unused-argument chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ).instances() @@ -620,6 +630,7 @@ def _make_part_whole_curriculum( # pylint: disable=unused-argument chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=3, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ).instances() @@ -672,6 +683,7 @@ def _make_my_your_object_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 20, + block_multiple_of_the_same_type=True, ) for person in owners ] @@ -797,6 +809,7 @@ def _make_fall_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -860,6 +873,7 @@ def _make_transfer_of_possession_curriculum( max_to_sample=num_samples if num_samples else 100, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for template in make_give_templates(background) ] @@ -896,6 +910,7 @@ def _make_object_on_object_curriculum( max_to_sample=num_samples if num_samples else 100, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -937,6 +952,7 @@ def _make_object_beside_object_curriculum( max_to_sample=num_samples if num_samples else 50, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -977,6 +993,7 @@ def _make_object_under_or_over_object_curriculum( max_to_sample=num_samples if num_samples else 100, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for template in templates ] @@ -1023,12 +1040,14 @@ def _make_object_in_other_object_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ), sampled( solid_template, max_to_sample=num_samples * 3 if num_samples else 75, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ), ] ), @@ -1115,6 +1134,7 @@ def _make_fly_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -1277,6 +1297,7 @@ def _make_roll_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for situation in make_roll_templates(noise_objects) ] @@ -1323,6 +1344,7 @@ def _make_transitive_roll_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for situation in make_transitive_roll_templates(noise_objects) ] @@ -1400,6 +1422,7 @@ def _make_templates() -> Iterable[Phase1SituationTemplate]: max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for template in _make_templates() ) @@ -1546,6 +1569,7 @@ def _make_jump_curriculum( use_adverbial_path_modifier=use_adverbial_path_modifier, background=background, ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 25, @@ -1561,6 +1585,7 @@ def _make_jump_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) ] ), @@ -1611,6 +1636,7 @@ def _make_put_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 25, + block_multiple_of_the_same_type=True, ) for template in make_put_templates(noise_objects) ] @@ -1658,6 +1684,7 @@ def _make_put_on_speaker_addressee_body_part_curriculum( body_part_of_putter, background=make_noise_objects(noise_objects), ), + block_multiple_of_the_same_type=True, max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, @@ -1740,6 +1767,7 @@ def _make_drink_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -1754,6 +1782,7 @@ def _make_drink_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ), ] ), @@ -1806,6 +1835,7 @@ def _make_eat_curriculum( max_to_sample=num_samples if num_samples else 25, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) ] ), @@ -1938,6 +1968,7 @@ def _make_sit_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -2082,6 +2113,7 @@ def _make_take_curriculum( operator=operator, background=make_noise_objects(noise_objects), ), + block_multiple_of_the_same_type=True, max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, @@ -2216,6 +2248,7 @@ def _make_move_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for situation in make_move_templates(noise_objects) ] @@ -2280,6 +2313,7 @@ def _make_spin_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for situation in make_spin_templates(noise_objects) ] @@ -2338,6 +2372,7 @@ def _make_go_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for situation in make_go_templates(noise_objects) ] @@ -2354,6 +2389,7 @@ def _make_go_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for is_distal in (True, False) ] @@ -2478,6 +2514,7 @@ def _make_push_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for adverbial_path_modifier in [True, False] for operator in [TOWARD, AWAY_FROM] @@ -2800,6 +2837,7 @@ def _make_throw_curriculum( max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for template in make_throw_templates(noise_objects) ] @@ -2842,6 +2880,7 @@ def _make_pass_curriculum( operator=operator, background=make_noise_objects(noise_objects), ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 25, @@ -2948,6 +2987,7 @@ def _make_come_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -2960,6 +3000,7 @@ def _make_come_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -2972,12 +3013,14 @@ def _make_come_curriculum( max_to_sample=num_samples if num_samples else 25, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ), sampled( _make_come_down_template(movee, object_, speaker, ground, background), max_to_sample=num_samples if num_samples else 25, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ), ] ), @@ -3049,6 +3092,7 @@ def make_behind_in_front_templates() -> Iterable[Phase1SituationTemplate]: max_to_sample=num_samples if num_samples else 25, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ) for template in make_behind_in_front_templates() ) diff --git a/adam/curriculum/phase2_curriculum.py b/adam/curriculum/phase2_curriculum.py index 3cdd0f372..b23ca13b0 100644 --- a/adam/curriculum/phase2_curriculum.py +++ b/adam/curriculum/phase2_curriculum.py @@ -124,6 +124,7 @@ def _make_sit_on_chair_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_2_ONTOLOGY, max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -180,6 +181,7 @@ def _make_drink_cups_curriculum( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_2_ONTOLOGY, max_to_sample=num_samples, + block_multiple_of_the_same_type=True, ) if num_samples else all_possible( @@ -218,6 +220,7 @@ def _make_put_in_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 20, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) diff --git a/adam/curriculum/preposition_curriculum.py b/adam/curriculum/preposition_curriculum.py index d62857a84..9087f19e5 100644 --- a/adam/curriculum/preposition_curriculum.py +++ b/adam/curriculum/preposition_curriculum.py @@ -293,6 +293,7 @@ def _make_on_training( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -338,6 +339,7 @@ def _make_beside_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -378,6 +380,7 @@ def _make_under_training( is_distal=use_above_below, syntax_hints=[USE_ABOVE_BELOW] if use_above_below else [], ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, @@ -424,6 +427,7 @@ def _make_over_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -464,6 +468,7 @@ def _make_in_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -509,6 +514,7 @@ def _make_behind_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -556,6 +562,7 @@ def _make_in_front_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -603,6 +610,7 @@ def _make_near_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -649,6 +657,7 @@ def _make_far_training( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -705,6 +714,7 @@ def _make_on_tests( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -756,6 +766,7 @@ def _make_beside_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -803,6 +814,7 @@ def _make_under_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -853,6 +865,7 @@ def _make_over_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -907,6 +920,7 @@ def _make_in_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -956,6 +970,7 @@ def _make_behind_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -1008,6 +1023,7 @@ def _make_in_front_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -1059,6 +1075,7 @@ def _make_near_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds @@ -1109,6 +1126,7 @@ def _make_far_tests( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for figure in figures for ground in grounds diff --git a/adam/curriculum/pursuit_curriculum.py b/adam/curriculum/pursuit_curriculum.py index 48ad81462..57d7fa72d 100644 --- a/adam/curriculum/pursuit_curriculum.py +++ b/adam/curriculum/pursuit_curriculum.py @@ -105,6 +105,7 @@ def make_simple_pursuit_curriculum( max_to_sample=num_instances - num_noise_instances, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_2_ONTOLOGY, + block_multiple_of_the_same_type=True, ), perception_generator=perception_generator, language_generator=language_generator, @@ -128,6 +129,7 @@ def make_simple_pursuit_curriculum( max_to_sample=num_noise_instances, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_2_ONTOLOGY, + block_multiple_of_the_same_type=True, ), perception_generator=perception_generator, language_generator=language_generator, diff --git a/adam/curriculum/verbs_with_dynamic_prepositions_curriculum.py b/adam/curriculum/verbs_with_dynamic_prepositions_curriculum.py index 4e8649fcc..68dc41548 100644 --- a/adam/curriculum/verbs_with_dynamic_prepositions_curriculum.py +++ b/adam/curriculum/verbs_with_dynamic_prepositions_curriculum.py @@ -2561,6 +2561,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in to_in_templates ] @@ -2580,6 +2581,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -2599,6 +2601,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -2619,6 +2622,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -2640,6 +2644,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_ending_proximal in BOOL_SET for is_towards in BOOL_SET @@ -2661,6 +2666,7 @@ def _make_push_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -2712,6 +2718,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -2723,6 +2730,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -2736,6 +2744,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -2754,6 +2763,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_behind in BOOL_SET @@ -2769,6 +2779,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -2786,6 +2797,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -2806,6 +2818,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_behind in BOOL_SET for is_near_path in BOOL_SET @@ -2827,6 +2840,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_over in BOOL_SET for is_near_goal in BOOL_SET @@ -2846,6 +2860,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET for is_near_goal in BOOL_SET @@ -2865,6 +2880,7 @@ def _make_go_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -2908,6 +2924,7 @@ def _make_sit_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options ] @@ -2922,6 +2939,7 @@ def _make_sit_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options ] @@ -2982,6 +3000,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3001,6 +3020,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_behind in BOOL_SET @@ -3019,6 +3039,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -3036,6 +3057,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -3054,6 +3076,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3074,6 +3097,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_behind in BOOL_SET @@ -3094,6 +3118,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_over in BOOL_SET ] @@ -3113,6 +3138,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_over in BOOL_SET for surface in surfaces @@ -3132,6 +3158,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET for surface in surfaces @@ -3152,6 +3179,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET for surface in surfaces @@ -3167,6 +3195,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for surface in surfaces ] @@ -3185,6 +3214,7 @@ def _make_roll_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for surface in surfaces ] @@ -3216,6 +3246,7 @@ def _make_take_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -3262,6 +3293,7 @@ def _make_fall_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options ] @@ -3276,6 +3308,7 @@ def _make_fall_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options ] @@ -3294,6 +3327,7 @@ def _make_fall_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options for is_right in BOOL_SET @@ -3314,6 +3348,7 @@ def _make_fall_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options for is_distal in BOOL_SET @@ -3334,6 +3369,7 @@ def _make_fall_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for syntax_hints in syntax_hints_options for is_toward in BOOL_SET @@ -3391,6 +3427,7 @@ def _make_put_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in on_in_templates ] @@ -3405,6 +3442,7 @@ def _make_put_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for speaker_addressee in special_agents ] @@ -3419,6 +3457,7 @@ def _make_put_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3433,6 +3472,7 @@ def _make_put_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3452,6 +3492,7 @@ def _make_put_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -3514,6 +3555,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3532,6 +3574,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -3547,6 +3590,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3561,6 +3605,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET ] @@ -3573,6 +3618,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in situation_templates ] @@ -3591,6 +3637,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3609,6 +3656,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3628,6 +3676,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -3647,6 +3696,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET ] @@ -3665,6 +3715,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3684,6 +3735,7 @@ def _make_move_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3732,6 +3784,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in situation_templates ] @@ -3746,6 +3799,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3765,6 +3819,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -3780,6 +3835,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3798,6 +3854,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -3816,6 +3873,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET ] @@ -3834,6 +3892,7 @@ def _make_throw_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_towards in BOOL_SET ] @@ -3885,6 +3944,7 @@ def _make_jump_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for template in templates ] @@ -3899,6 +3959,7 @@ def _make_jump_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3917,6 +3978,7 @@ def _make_jump_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -3961,6 +4023,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -3974,6 +4037,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_right in BOOL_SET ] @@ -3992,6 +4056,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_distal in BOOL_SET for is_in_front in BOOL_SET @@ -4005,6 +4070,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -4016,6 +4082,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -4029,6 +4096,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) for is_toward in BOOL_SET ] @@ -4041,6 +4109,7 @@ def _make_fly_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ), @@ -4079,6 +4148,7 @@ def _make_come_with_prepositions( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 5, + block_multiple_of_the_same_type=True, ) ] ) diff --git a/adam/experiment/experiment_utils.py b/adam/experiment/experiment_utils.py index c18a231a9..019c8a6ac 100644 --- a/adam/experiment/experiment_utils.py +++ b/adam/experiment/experiment_utils.py @@ -178,6 +178,7 @@ def _make_sit_on_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 25, + block_multiple_of_the_same_type=True, ), sampled( make_sit_transitive( @@ -186,6 +187,7 @@ def _make_sit_on_curriculum( ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=num_samples if num_samples else 25, + block_multiple_of_the_same_type=True, ), ] ), diff --git a/adam/language_specific/chinese/chinese_language_generator.py b/adam/language_specific/chinese/chinese_language_generator.py index 1c5003aea..68af8b67a 100644 --- a/adam/language_specific/chinese/chinese_language_generator.py +++ b/adam/language_specific/chinese/chinese_language_generator.py @@ -9,6 +9,7 @@ from adam.language_specific.chinese.chinese_phase_2_lexicon import ( GAILA_PHASE_2_CHINESE_LEXICON, ) +from adam.ontology.phase2_ontology import gravitationally_aligned_axis_is_largest from adam.axes import FacingAddresseeAxis, GRAVITATIONAL_DOWN_TO_UP_AXIS from adam.language.dependency import ( DependencyRole, @@ -512,10 +513,15 @@ def _translate_relation_to_action_modifier( if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): # tall - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("gau1 da4", ADJECTIVE) # big else: @@ -530,10 +536,15 @@ def _translate_relation_to_action_modifier( if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): # short - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("dwan3", ADJECTIVE) # small else: @@ -1012,15 +1023,20 @@ def _translate_relation( relation: Relation[SituationObject], ): """Translate relations that the user explicitly calls out, including possession and region""" - if relation.relation_type == BIGGER_THAN: + # big is specified when there's two objects of the same type, and the second isn't salient if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): # tall - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("gau1 da4", ADJECTIVE) # big else: @@ -1035,10 +1051,15 @@ def _translate_relation( if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): # short - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("dwan3", ADJECTIVE) # small else: @@ -1323,5 +1344,4 @@ def _init_object_counts(self) -> Mapping[OntologyNode, int]: ATTRIBUTES_AS_X_IS_Y = "ATTRIBUTES_AS_X_IS_Y" USE_NEAR = "USE_NEAR" IGNORE_GOAL = "IGNORE_GOAL" -USE_VERTICAL_MODIFIERS = "USE_VERTICAL_MODIFIERS" USE_ABOVE_BELOW = "USE_ABOVE_BELOW" diff --git a/adam/language_specific/english/english_language_generator.py b/adam/language_specific/english/english_language_generator.py index 256140668..34cdb2e38 100644 --- a/adam/language_specific/english/english_language_generator.py +++ b/adam/language_specific/english/english_language_generator.py @@ -1,7 +1,7 @@ import collections from itertools import chain from typing import Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union, cast - +from adam.ontology.phase2_ontology import gravitationally_aligned_axis_is_largest from attr import Factory, attrib, attrs from attr.validators import instance_of from immutablecollections import ImmutableSet, immutableset, immutablesetmultidict @@ -433,9 +433,14 @@ def _add_attributes( if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("tall", ADJECTIVE) else: token = DependencyTreeToken("big", ADJECTIVE) @@ -447,9 +452,14 @@ def _add_attributes( if ( relation.first_slot in self.situation.salient_objects and isinstance(relation.second_slot, SituationObject) - and relation.second_slot.ontology_node == LEARNER + and relation.second_slot.ontology_node + not in self.situation.salient_objects + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node ): - if USE_VERTICAL_MODIFIERS in self.situation.syntax_hints: + if gravitationally_aligned_axis_is_largest( + relation.first_slot.ontology_node, self.situation.ontology + ): token = DependencyTreeToken("short", ADJECTIVE) else: token = DependencyTreeToken("small", ADJECTIVE) @@ -1202,6 +1212,5 @@ def _init_object_counts(self) -> Mapping[OntologyNode, int]: ATTRIBUTES_AS_X_IS_Y = "ATTRIBUTES_AS_X_IS_Y" IGNORE_SIZE_ATTRIBUTE = "IGNORE_SIZE_ATTRIBUTE" IGNORE_GOAL = "IGNORE_GOAL" -USE_VERTICAL_MODIFIERS = "USE_VERTICAL_MODIFIERS" USE_ABOVE_BELOW = "USE_ABOVE_BELOW" USE_NEAR = "USE_NEAR" diff --git a/adam/learner/learner_utils.py b/adam/learner/learner_utils.py index 3641e9610..8c79248ff 100644 --- a/adam/learner/learner_utils.py +++ b/adam/learner/learner_utils.py @@ -71,19 +71,6 @@ def pattern_match_to_description( This requires a mapping from matched object nodes in the perception to the strings which should be used to name them. """ - matched_object_nodes = immutableset( - perception_node - for perception_node in match.pattern_node_to_matched_graph_node.values() - if isinstance(perception_node, ObjectSemanticNode) - ) - matched_object_nodes_without_names = matched_object_nodes - immutableset( - matched_objects_to_names.keys() - ) - if matched_object_nodes_without_names: - raise RuntimeError( - f"The following matched object nodes lack descriptions: " - f"{matched_object_nodes_without_names}" - ) try: return surface_template.instantiate( @@ -107,8 +94,8 @@ def pattern_match_to_description( and pattern_node in pattern.pattern_node_to_template_variable ) ) - except KeyError: - print("foo") + except KeyError as e: + logging.warning(str(e)) raise diff --git a/adam/learner/object_recognizer.py b/adam/learner/object_recognizer.py index 7affd39ff..ad6e855b1 100644 --- a/adam/learner/object_recognizer.py +++ b/adam/learner/object_recognizer.py @@ -111,7 +111,7 @@ def __attrs_post_init__(self) -> None: self.description_to_matched_object_node.values() ) if matched_object_nodes != described_matched_object_nodes: - raise RuntimeError( + logging.warning( f"A matched object node should be present in the graph" f"if and only if it is described. Got matches objects " f"{matched_object_nodes} but those described were {described_matched_object_nodes}" @@ -319,7 +319,9 @@ def match_objects( matched_object_node, graph_to_return, pattern_match ) - candidate_object_subgraphs = extract_candidate_objects(perception_graph) + candidate_object_subgraphs = extract_candidate_objects( + perception_graph, sort_by_increasing_size=True + ) for candidate_object_graph in candidate_object_subgraphs: num_object_nodes = candidate_object_graph.count_nodes_matching( @@ -333,7 +335,6 @@ def match_objects( # and we can bail out early. if num_object_nodes != self._concept_to_num_subobjects[concept]: continue - with Timer(factor=1000) as t: matcher = pattern.matcher( candidate_object_graph, match_mode=MatchMode.OBJECT @@ -374,6 +375,7 @@ def match_objects( break else: cumulative_millis_in_failed_matches_ms += t.elapsed + if object_nodes: logging.info( "Object recognizer recognized: %s", @@ -539,7 +541,7 @@ def _init_patterns_to_num_subobjects(self) -> ImmutableDict[ObjectConcept, int]: def extract_candidate_objects( - whole_scene_perception_graph: PerceptionGraph + whole_scene_perception_graph: PerceptionGraph, sort_by_increasing_size: bool ) -> Sequence[PerceptionGraph]: """ @@ -639,6 +641,13 @@ def is_root_object_node(node) -> bool: immutableset(candidate_subgraph_nodes) ) ) + # we sort the candidate objects' graphs from least to greatest number of nodes in the graph. This allows us to match objects + # with less cost before objects with greater cost, and also causes us to match gazed objects after non-gazed objects, which is the + # order needed to ensure that gaze is assigned to the correct object if there are multiple in the scene + if sort_by_increasing_size: + candidate_objects.sort( + key=lambda x: len(x._graph.node) # pylint:disable=protected-access + ) return candidate_objects diff --git a/adam/learner/objects.py b/adam/learner/objects.py index 5a8d90b56..bbb0d47d8 100644 --- a/adam/learner/objects.py +++ b/adam/learner/objects.py @@ -490,7 +490,8 @@ def _hypotheses_from_perception( template_variable_to_pattern_node=immutabledict(), ) for candidate_object in extract_candidate_objects( - learning_state.perception_semantic_alignment.perception_graph + learning_state.perception_semantic_alignment.perception_graph, + sort_by_increasing_size=False, ) ) @@ -556,7 +557,7 @@ def _enrich_post_process( new_nodes = [] perception_graph_after_processing = perception_graph_after_matching for candiate_object_graph in extract_candidate_objects( - perception_graph_after_matching + perception_graph_after_matching, sort_by_increasing_size=False ): fake_pattern_graph = PerceptionGraphPattern.from_graph(candiate_object_graph) fake_object_semantic_node = ObjectSemanticNode( @@ -685,7 +686,8 @@ def _hypotheses_from_perception( template_variable_to_pattern_node=immutabledict(), ) for candidate_object in extract_candidate_objects( - learning_state.perception_semantic_alignment.perception_graph + learning_state.perception_semantic_alignment.perception_graph, + sort_by_increasing_size=False, ) ) diff --git a/adam/ontology/phase1_ontology.py b/adam/ontology/phase1_ontology.py index 3d896c9d7..16591df64 100644 --- a/adam/ontology/phase1_ontology.py +++ b/adam/ontology/phase1_ontology.py @@ -654,6 +654,11 @@ def _far_region_factory( subtype(SIZE_RELATION, RELATION) BIGGER_THAN = OntologyNode("biggerThan") +BIGGER_THAN_SAME_TYPE = OntologyNode( + "biggerThanSameType" +) # For relative size between objects of same type + +SAME_TYPE = OntologyNode("same-type") """ A relation indicating that one object is bigger than another object. @@ -661,19 +666,27 @@ def _far_region_factory( https://github.com/isi-vista/adam/issues/70 """ subtype(BIGGER_THAN, SIZE_RELATION) +subtype(BIGGER_THAN_SAME_TYPE, SIZE_RELATION) SMALLER_THAN = OntologyNode("smallerThan") +SMALLER_THAN_SAME_TYPE = OntologyNode( + "smallerThanSameType" +) # For relative size between objects of same type """ A relation indicating that one object is smaller than another object. This is a placeholder for a more sophisticated representation of size: https://github.com/isi-vista/adam/issues/70 """ +subtype(SMALLER_THAN_SAME_TYPE, SIZE_RELATION) subtype(SMALLER_THAN, SIZE_RELATION) bigger_than = make_opposite_dsl_relation( # pylint:disable=invalid-name BIGGER_THAN, opposite_type=SMALLER_THAN ) +bigger_than_same = make_opposite_dsl_relation( # pylint:disable=invalid-name + BIGGER_THAN_SAME_TYPE, opposite_type=SMALLER_THAN_SAME_TYPE +) AXIS_RELATION = OntologyNode("axis-relation") subtype(AXIS_RELATION, RELATION) diff --git a/adam/ontology/phase2_ontology.py b/adam/ontology/phase2_ontology.py index ea4842169..1572c9b4b 100644 --- a/adam/ontology/phase2_ontology.py +++ b/adam/ontology/phase2_ontology.py @@ -4,6 +4,8 @@ from adam.ontology import OntologyNode, CAN_FILL_TEMPLATE_SLOT from adam.ontology.ontology import Ontology from adam.ontology.phase1_ontology import ( + MUCH_BIGGER_THAN, + MUCH_SMALLER_THAN, _make_cup_schema, _CHAIR_SCHEMA_BACK, _CHAIR_SCHEMA_SQUARE_SEAT, @@ -273,3 +275,32 @@ GAILA_PHASE_2_SIZE_GRADES, relation_type=BIGGER_THAN, opposite_type=SMALLER_THAN ), ) + + +def gravitationally_aligned_axis_is_largest( + ontology_node: OntologyNode, ontology: Ontology +) -> bool: + schemata = list(ontology.structural_schemata(ontology_node)) + if not schemata or len(schemata) != 1: + return False + gravitational = schemata[0].axes.gravitationally_aligned_axis + relations = schemata[0].axes.axis_relations + if not gravitational or not relations: + return False + return ( + any( + r.first_slot == gravitational + and r.relation_type in [BIGGER_THAN, MUCH_BIGGER_THAN] + for r in relations + ) + and not any( + r.first_slot == gravitational + and r.relation_type in [SMALLER_THAN, MUCH_SMALLER_THAN] + for r in relations + ) + and not any( + r.second_slot == gravitational + and r.relation_type in [BIGGER_THAN, MUCH_BIGGER_THAN] + for r in relations + ) + ) diff --git a/adam/perception/high_level_semantics_situation_to_developmental_primitive_perception.py b/adam/perception/high_level_semantics_situation_to_developmental_primitive_perception.py index f5b3de6c9..3141133e6 100644 --- a/adam/perception/high_level_semantics_situation_to_developmental_primitive_perception.py +++ b/adam/perception/high_level_semantics_situation_to_developmental_primitive_perception.py @@ -3,10 +3,8 @@ from random import Random from typing import Dict, Iterable, List, Mapping, MutableMapping, Optional, Union, cast from typing_extensions import Protocol, runtime - from more_itertools import only, quantify from networkx import DiGraph - from adam.axes import AxesInfo, WORLD_AXES from adam.axis import GeonAxis from adam.geon import Geon @@ -36,6 +34,9 @@ SIZE_RELATIONS, TWO_DIMENSIONAL, on, + BIGGER_THAN_SAME_TYPE, + BIGGER_THAN, + SMALLER_THAN_SAME_TYPE, ) from adam.ontology.phase1_spatial_relations import ( EXTERIOR_BUT_IN_CONTACT, @@ -303,10 +304,9 @@ def _real_do(self) -> PerceptualRepresentation[DevelopmentalPrimitivePerceptionF ) # Once all the objects and relations are perceived, determine their colors. self._perceive_colors() - # Handle implicit size relations self._perceive_size_relative_to_learner() - # self._perceive_implicit_size() + self._perceive_all_relative_size() # for now, we assume that actions do not alter the relationship of objects axes # to the speaker, learner, and addressee @@ -804,6 +804,37 @@ def dfs_walk(node: ObjectPerception, inherited_color=None): dfs_walk(root) + def _perceive_all_relative_size(self) -> None: + """This method handles perception of relative size of two objects of the same type""" + size_relations = [ + relation + for relation in self._situation.always_relations + if relation.relation_type in SIZE_RELATIONS + and ( + isinstance(relation.first_slot, SituationObject) + and isinstance(relation.second_slot, SituationObject) + and relation.first_slot.ontology_node + == relation.second_slot.ontology_node + ) + ] + for relation in size_relations: + # We convert biggerThan to biggerThanSameType to denote it's a special type of relative size between + # objects of same type. + new_relation_type = ( + BIGGER_THAN_SAME_TYPE + if relation.relation_type == BIGGER_THAN + else SMALLER_THAN_SAME_TYPE + ) + size_relation_same_type = Relation( + relation_type=new_relation_type, + first_slot=self._objects_to_perceptions[relation.first_slot], + second_slot=self._objects_to_perceptions[ # type:ignore + relation.second_slot + ], + negated=relation.negated, + ) + self._relation_perceptions.extend([size_relation_same_type]) + def _perceive_size_relative_to_learner(self) -> None: """ When doing object recognition, diff --git a/adam/perception/perception_graph.py b/adam/perception/perception_graph.py index 2949a4a2d..065efbf55 100644 --- a/adam/perception/perception_graph.py +++ b/adam/perception/perception_graph.py @@ -3046,7 +3046,6 @@ def _map_relation( ) else: label = relation.relation_type - graph.add_edge( self._map_node(relation.first_slot), self._map_node(relation.second_slot), diff --git a/adam/situation/templates/phase1_templates.py b/adam/situation/templates/phase1_templates.py index e47fc718d..65e7d3c2e 100644 --- a/adam/situation/templates/phase1_templates.py +++ b/adam/situation/templates/phase1_templates.py @@ -321,6 +321,7 @@ def sampled( chooser: SequenceChooser, max_to_sample: int, default_addressee_node: OntologyNode = LEARNER, + block_multiple_of_the_same_type: bool, ) -> Iterable[HighLevelSemanticsSituation]: """ Gets *max_to_sample* instantiations of *situation_template* with *ontology* @@ -330,7 +331,9 @@ def sampled( take( max_to_sample, _Phase1SituationTemplateGenerator( - ontology=ontology, variable_assigner=_SamplingVariableAssigner() + ontology=ontology, + variable_assigner=_SamplingVariableAssigner(), + block_multiple_objects_of_the_same_type=block_multiple_of_the_same_type, ).generate_situations( situation_template, chooser=chooser, @@ -424,7 +427,6 @@ def generate_situations( object_var_to_instantiations ): continue - if self.block_multiple_objects_of_the_same_type: object_instantiations_ontology_nodes = [ object_instantiation.ontology_node diff --git a/tests/language_specific/chinese/test_chinese_language_generator.py b/tests/language_specific/chinese/test_chinese_language_generator.py index 6fd2d362a..d9d4dc4f1 100644 --- a/tests/language_specific/chinese/test_chinese_language_generator.py +++ b/tests/language_specific/chinese/test_chinese_language_generator.py @@ -10,6 +10,7 @@ AxesInfo, GRAVITATIONAL_AXIS_FUNCTION, ) +from adam.ontology.phase2_ontology import gravitationally_aligned_axis_is_largest from adam.language_specific.chinese.chinese_language_generator import ( PREFER_DITRANSITIVE, SimpleRuleBasedChineseLanguageGenerator, @@ -17,7 +18,6 @@ IGNORE_HAS_AS_VERB, ATTRIBUTES_AS_X_IS_Y, IGNORE_GOAL, - USE_VERTICAL_MODIFIERS, USE_ABOVE_BELOW, USE_NEAR, ) @@ -2507,50 +2507,56 @@ def test_I_walk_out_of_house(): assert generated_tokens(situation) == ("wo3", "bu4 sying2", "chu1", "wu1") -def test_big_truck(): - learner = situation_object(LEARNER) - truck = situation_object(TRUCK) +def test_big_truck_updated(): + truck1 = situation_object(TRUCK, debug_handle="truck1") + truck2 = situation_object(TRUCK, debug_handle="truck2") situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[truck], - always_relations=[(bigger_than(truck, learner))], + salient_objects=[truck1], + other_objects=[truck2], + always_relations=[(bigger_than(truck1, truck2))], ) + assert not gravitationally_aligned_axis_is_largest(TRUCK, GAILA_PHASE_1_ONTOLOGY) assert generated_tokens(situation) == ("da4", "ka3 che1") -def test_tall_truck(): - learner = situation_object(LEARNER) - truck = situation_object(TRUCK) +def test_tall_book_updated(): + book1 = situation_object(BOOK, debug_handle="book1") + book2 = situation_object(BOOK, debug_handle="book2") situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[truck], - always_relations=[(bigger_than(truck, learner))], - syntax_hints=[USE_VERTICAL_MODIFIERS], + salient_objects=[book1], + other_objects=[book2], + always_relations=[(bigger_than(book1, book2))], ) - assert generated_tokens(situation) == ("gau1 da4", "ka3 che1") + assert gravitationally_aligned_axis_is_largest(BOOK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("gau1 da4", "shu1") -def test_small_truck(): - learner = situation_object(LEARNER) - truck = situation_object(TRUCK) +def test_small_truck_updated(): + truck1 = situation_object(TRUCK, debug_handle="truck1") + truck2 = situation_object(TRUCK, debug_handle="truck2") situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[truck], - always_relations=[(bigger_than(learner, truck))], + salient_objects=[truck1], + other_objects=[truck2], + always_relations=[(bigger_than(truck2, truck1))], ) + assert not gravitationally_aligned_axis_is_largest(TRUCK, GAILA_PHASE_1_ONTOLOGY) assert generated_tokens(situation) == ("syau3", "ka3 che1") -def test_short_truck(): - learner = situation_object(LEARNER) - truck = situation_object(TRUCK) +def test_short_book_updated(): + book1 = situation_object(BOOK, debug_handle="book1") + book2 = situation_object(BOOK, debug_handle="book2") situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[truck], - always_relations=[(bigger_than(learner, truck))], - syntax_hints=[USE_VERTICAL_MODIFIERS], + salient_objects=[book1], + other_objects=[book2], + always_relations=[(bigger_than(book2, book1))], ) - assert generated_tokens(situation) == ("dwan3", "ka3 che1") + assert gravitationally_aligned_axis_is_largest(BOOK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("dwan3", "shu1") # there is no under/below distinction in Chinese diff --git a/tests/language_specific/english/test_english_language_generator.py b/tests/language_specific/english/test_english_language_generator.py index 08af2cd01..07fe11169 100644 --- a/tests/language_specific/english/test_english_language_generator.py +++ b/tests/language_specific/english/test_english_language_generator.py @@ -2,7 +2,7 @@ import pytest from more_itertools import only - +from adam.ontology.phase2_ontology import gravitationally_aligned_axis_is_largest from adam.axes import HorizontalAxisOfObject, FacingAddresseeAxis, AxesInfo from adam.language_specific.english.english_language_generator import ( PREFER_DITRANSITIVE, @@ -12,7 +12,6 @@ IGNORE_COLORS, USE_ABOVE_BELOW, USE_NEAR, - USE_VERTICAL_MODIFIERS, ) from adam.language_specific.english.english_phase_1_lexicon import ( GAILA_PHASE_1_ENGLISH_LEXICON, @@ -21,7 +20,9 @@ from adam.ontology.during import DuringAction from adam.ontology.phase1_ontology import ( AGENT, + BOOK, BABY, + TRUCK, BALL, BIRD, BOX, @@ -1639,50 +1640,56 @@ def test_box_without_attribute(): generated_tokens(box_without_attribute) -def test_bigger_than(): - box = situation_object(BOX) - learner = situation_object(LEARNER) - big_box = HighLevelSemanticsSituation( +def test_big_truck_updated(): + truck1 = situation_object(TRUCK, debug_handle="truck1") + truck2 = situation_object(TRUCK, debug_handle="truck2") + situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[box, learner], - always_relations=[bigger_than(box, learner)], + salient_objects=[truck1], + other_objects=[truck2], + always_relations=[(bigger_than(truck1, truck2))], ) - assert generated_tokens(situation=big_box) == ("a", "big", "box") + assert not gravitationally_aligned_axis_is_largest(TRUCK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("a", "big", "truck") -def test_taller_than(): - box = situation_object(BOX) - learner = situation_object(LEARNER) - big_box = HighLevelSemanticsSituation( +def test_tall_book_updated(): + book1 = situation_object(BOOK, debug_handle="book1") + book2 = situation_object(BOOK, debug_handle="book2") + situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[box, learner], - always_relations=[bigger_than(box, learner)], - syntax_hints=[USE_VERTICAL_MODIFIERS], + salient_objects=[book1], + other_objects=[book2], + always_relations=[(bigger_than(book1, book2))], ) - assert generated_tokens(situation=big_box) == ("a", "tall", "box") + assert gravitationally_aligned_axis_is_largest(BOOK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("a", "tall", "book") -def test_shorter_than(): - box = situation_object(BOX) - learner = situation_object(LEARNER) - big_box = HighLevelSemanticsSituation( +def test_short_book_updated(): + book1 = situation_object(BOOK, debug_handle="book1") + book2 = situation_object(BOOK, debug_handle="book2") + situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[box, learner], - always_relations=[bigger_than(learner, box)], - syntax_hints=[USE_VERTICAL_MODIFIERS], + salient_objects=[book1], + other_objects=[book2], + always_relations=[(bigger_than(book2, book1))], ) - assert generated_tokens(situation=big_box) == ("a", "short", "box") + assert gravitationally_aligned_axis_is_largest(BOOK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("a", "short", "book") -def test_smaller_than(): - box = situation_object(BOX) - learner = situation_object(LEARNER) - big_box = HighLevelSemanticsSituation( +def test_small_truck_updated(): + truck1 = situation_object(TRUCK, debug_handle="truck1") + truck2 = situation_object(TRUCK, debug_handle="truck2") + situation = HighLevelSemanticsSituation( ontology=GAILA_PHASE_1_ONTOLOGY, - salient_objects=[box, learner], - always_relations=[bigger_than(learner, box)], + salient_objects=[truck1], + other_objects=[truck2], + always_relations=[(bigger_than(truck2, truck1))], ) - assert generated_tokens(situation=big_box) == ("a", "small", "box") + assert not gravitationally_aligned_axis_is_largest(TRUCK, GAILA_PHASE_1_ONTOLOGY) + assert generated_tokens(situation) == ("a", "small", "truck") def test_run(): diff --git a/tests/learner/learn_imprecise_descriptions_test.py b/tests/learner/learn_imprecise_descriptions_test.py new file mode 100644 index 000000000..0237a50f3 --- /dev/null +++ b/tests/learner/learn_imprecise_descriptions_test.py @@ -0,0 +1,150 @@ +from itertools import chain + +import pytest + +from adam.curriculum.curriculum_utils import ( + phase1_instances, + PHASE1_CHOOSER_FACTORY, + PHASE1_TEST_CHOOSER_FACTORY, +) +from adam.language.language_utils import phase1_language_generator +from adam.curriculum.imprecise_descriptions_curriculum import ( + _big_x_template, + _little_x_template, + _short_x_template, + _tall_x_template, +) +from adam.learner import LearningExample + +from adam.learner.verbs import SubsetVerbLearnerNew +from adam.learner.attributes import SubsetAttributeLearner, SubsetAttributeLearnerNew +from adam.learner.integrated_learner import IntegratedTemplateLearner +from adam.learner.language_mode import LanguageMode +from adam.learner.objects import ObjectRecognizerAsTemplateLearner +from adam.ontology.phase1_ontology import GAILA_PHASE_1_ONTOLOGY +from adam.situation.templates.phase1_templates import sampled +from tests.learner import object_recognizer_factory + + +def subset_attribute_leaner_factory(language_mode: LanguageMode): + return SubsetAttributeLearner( + object_recognizer=object_recognizer_factory(language_mode), + ontology=GAILA_PHASE_1_ONTOLOGY, + language_mode=language_mode, + ) + + +def integrated_learner_factory(language_mode: LanguageMode): + return IntegratedTemplateLearner( + object_learner=ObjectRecognizerAsTemplateLearner( + object_recognizer=object_recognizer_factory(language_mode), + language_mode=language_mode, + ), + attribute_learner=SubsetAttributeLearnerNew( + ontology=GAILA_PHASE_1_ONTOLOGY, beam_size=5, language_mode=language_mode + ), + action_learner=SubsetVerbLearnerNew( + ontology=GAILA_PHASE_1_ONTOLOGY, beam_size=5, language_mode=language_mode + ), + ) + + +def run_imprecise_test(learner, situation_template, language_generator): + train_curriculum = phase1_instances( + "train", + chain( + *[ + sampled( + situation_template, + max_to_sample=10, + ontology=GAILA_PHASE_1_ONTOLOGY, + chooser=PHASE1_CHOOSER_FACTORY(), + # this is a hack since our current object recognizer will throw a runtime error if there are percieved objects not in the description + block_multiple_of_the_same_type=False, + ) + ] + ), + language_generator=language_generator, + ) + test_curriculum = phase1_instances( + "test", + chain( + *[ + sampled( + situation_template, + max_to_sample=1, + ontology=GAILA_PHASE_1_ONTOLOGY, + chooser=PHASE1_TEST_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=False, + ) + ] + ), + language_generator=language_generator, + ) + + for ( + _, + linguistic_description, + perceptual_representation, + ) in train_curriculum.instances(): + # Get the object matches first - preposition learner can't learn without already recognized objects + learner.observe( + LearningExample(perceptual_representation, linguistic_description) + ) + for ( + _, + test_lingustics_description, + test_perceptual_representation, + ) in test_curriculum.instances(): + descriptions_from_learner = learner.describe(test_perceptual_representation) + gold = test_lingustics_description.as_token_sequence() + assert descriptions_from_learner + assert gold in [desc.as_token_sequence() for desc in descriptions_from_learner] + + +@pytest.mark.parametrize( + "learner", [subset_attribute_leaner_factory, integrated_learner_factory] +) +@pytest.mark.parametrize("language", [LanguageMode.ENGLISH, LanguageMode.CHINESE]) +def test_tall(learner, language): + run_imprecise_test( + learner(language), + _tall_x_template(background=[]), + language_generator=phase1_language_generator(language), + ) + + +@pytest.mark.parametrize( + "learner", [subset_attribute_leaner_factory, integrated_learner_factory] +) +@pytest.mark.parametrize("language", [LanguageMode.ENGLISH, LanguageMode.CHINESE]) +def test_short(learner, language): + run_imprecise_test( + learner(language), + _short_x_template(background=[]), + language_generator=phase1_language_generator(language), + ) + + +@pytest.mark.parametrize( + "learner", [subset_attribute_leaner_factory, integrated_learner_factory] +) +@pytest.mark.parametrize("language", [LanguageMode.ENGLISH, LanguageMode.CHINESE]) +def test_big(learner, language): + run_imprecise_test( + learner(language), + _big_x_template(background=[]), + language_generator=phase1_language_generator(language), + ) + + +@pytest.mark.parametrize( + "learner", [subset_attribute_leaner_factory, integrated_learner_factory] +) +@pytest.mark.parametrize("language", [LanguageMode.ENGLISH, LanguageMode.CHINESE]) +def test_small(learner, language): + run_imprecise_test( + learner(language), + _little_x_template(background=[]), + language_generator=phase1_language_generator(language), + ) diff --git a/tests/learner/object_learner_test.py b/tests/learner/object_learner_test.py index 01faf1776..3b745dbf0 100644 --- a/tests/learner/object_learner_test.py +++ b/tests/learner/object_learner_test.py @@ -118,6 +118,7 @@ def run_subset_learner_for_object( chooser=PHASE1_TEST_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) diff --git a/tests/learner/pursuit_preposition_learner_test.py b/tests/learner/pursuit_preposition_learner_test.py index fd0edf516..bfefac7f5 100644 --- a/tests/learner/pursuit_preposition_learner_test.py +++ b/tests/learner/pursuit_preposition_learner_test.py @@ -60,6 +60,7 @@ def test_pursuit_preposition_on_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -70,6 +71,7 @@ def test_pursuit_preposition_on_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -120,6 +122,7 @@ def test_pursuit_preposition_beside_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -132,6 +135,7 @@ def test_pursuit_preposition_beside_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -182,6 +186,7 @@ def test_pursuit_preposition_under_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -194,6 +199,7 @@ def test_pursuit_preposition_under_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -242,6 +248,7 @@ def test_pursuit_preposition_over_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -254,6 +261,7 @@ def test_pursuit_preposition_over_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -302,6 +310,7 @@ def test_pursuit_preposition_in_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -312,6 +321,7 @@ def test_pursuit_preposition_in_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -366,6 +376,7 @@ def test_pursuit_preposition_behind_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -383,6 +394,7 @@ def test_pursuit_preposition_behind_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -437,6 +449,7 @@ def test_pursuit_preposition_in_front_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=10, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -454,6 +467,7 @@ def test_pursuit_preposition_in_front_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -495,6 +509,7 @@ def test_pursuit_preposition_has_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=2, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -506,6 +521,7 @@ def test_pursuit_preposition_has_learner(language_mode): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) diff --git a/tests/learner/subset_attribute_learner_test.py b/tests/learner/subset_attribute_learner_test.py index 7c413363f..a41402bb7 100644 --- a/tests/learner/subset_attribute_learner_test.py +++ b/tests/learner/subset_attribute_learner_test.py @@ -114,6 +114,7 @@ def test_subset_color_attribute( chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=2, + block_multiple_of_the_same_type=True, ) for template in templates ] @@ -129,6 +130,7 @@ def test_subset_color_attribute( chooser=PHASE1_TEST_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -189,6 +191,7 @@ def test_subset_my_attribute_learner_integrated(language_mode, learner): ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=5, + block_multiple_of_the_same_type=True, ) for person in [MOM, DAD, BABY] ), @@ -208,6 +211,7 @@ def test_subset_my_attribute_learner_integrated(language_mode, learner): inanimate_object, syntax_hints=[IGNORE_HAS_AS_VERB], ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_TEST_CHOOSER_FACTORY(), max_to_sample=1, @@ -278,6 +282,7 @@ def test_your_attribute_learner(language_mode, learner): background=[person_0], syntax_hints=[IGNORE_HAS_AS_VERB], ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), max_to_sample=5, @@ -294,6 +299,7 @@ def test_your_attribute_learner(language_mode, learner): background=[person_0], syntax_hints=[IGNORE_HAS_AS_VERB], ), + block_multiple_of_the_same_type=True, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_TEST_CHOOSER_FACTORY(), max_to_sample=1, diff --git a/tests/learner/subset_preposition_learner_test.py b/tests/learner/subset_preposition_learner_test.py index 4db6949f9..ed030d23f 100644 --- a/tests/learner/subset_preposition_learner_test.py +++ b/tests/learner/subset_preposition_learner_test.py @@ -66,6 +66,7 @@ def run_preposition_test(learner, situation_template, language_generator): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=2, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -76,6 +77,7 @@ def run_preposition_test(learner, situation_template, language_generator): chooser=PHASE1_TEST_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) @@ -297,6 +299,7 @@ def test_subset_preposition_has(language_mode, learner): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), ).instances() ) @@ -309,6 +312,7 @@ def test_subset_preposition_has(language_mode, learner): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), ).instances() ) @@ -320,6 +324,7 @@ def test_subset_preposition_has(language_mode, learner): chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, max_to_sample=1, + block_multiple_of_the_same_type=True, ), language_generator=language_generator, ) diff --git a/tests/learner/subset_verb_learner_test.py b/tests/learner/subset_verb_learner_test.py index 5ced34650..25db45034 100644 --- a/tests/learner/subset_verb_learner_test.py +++ b/tests/learner/subset_verb_learner_test.py @@ -106,6 +106,7 @@ def run_verb_test(learner, situation_template, language_generator): max_to_sample=10, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) ] ), @@ -120,6 +121,7 @@ def run_verb_test(learner, situation_template, language_generator): max_to_sample=1, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_TEST_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) ] ), @@ -503,6 +505,7 @@ def test_throw_animacy(language_mode, learner): max_to_sample=10, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) for situation_template in make_throw_animacy_templates(None) ] @@ -519,6 +522,7 @@ def test_throw_animacy(language_mode, learner): max_to_sample=1, ontology=GAILA_PHASE_1_ONTOLOGY, chooser=PHASE1_CHOOSER_FACTORY(), + block_multiple_of_the_same_type=True, ) for situation_template in make_throw_animacy_templates(None) ] diff --git a/tests/learner/test_object_recognizer.py b/tests/learner/test_object_recognizer.py index f24942318..1e27a3277 100644 --- a/tests/learner/test_object_recognizer.py +++ b/tests/learner/test_object_recognizer.py @@ -139,6 +139,7 @@ def test_recognize_in_transfer_of_possession(language_mode): max_to_sample=1, chooser=PHASE1_CHOOSER_FACTORY(), ontology=GAILA_PHASE_1_ONTOLOGY, + block_multiple_of_the_same_type=True, ), ).instances() ) diff --git a/tests/perception/high_level_semantics_situation_to_developmental_primitive_perception_test.py b/tests/perception/high_level_semantics_situation_to_developmental_primitive_perception_test.py index 6c47aac10..dfae211da 100644 --- a/tests/perception/high_level_semantics_situation_to_developmental_primitive_perception_test.py +++ b/tests/perception/high_level_semantics_situation_to_developmental_primitive_perception_test.py @@ -5,6 +5,8 @@ from adam.axes import HorizontalAxisOfObject from adam.ontology import IN_REGION, OntologyNode, IS_SPEAKER from adam.ontology.phase1_ontology import ( + BIGGER_THAN_SAME_TYPE, + SMALLER_THAN_SAME_TYPE, AGENT, ANIMATE, BALL, @@ -44,6 +46,7 @@ far, near, on, + bigger_than, ) from adam.ontology.phase1_spatial_relations import ( DISTAL, @@ -78,6 +81,38 @@ ) +def test_big_ball(): + ball1 = situation_object(BALL, debug_handle="ball_0") + ball2 = situation_object(BALL, debug_handle="ball_1") + + ball_situation = HighLevelSemanticsSituation( + ontology=GAILA_PHASE_1_ONTOLOGY, + salient_objects=[ball2, ball1], + always_relations=[bigger_than(ball1, ball2)], + ) + + assert ( + ball_situation.always_relations[0].first_slot.ontology_node + == ball_situation.always_relations[0].second_slot.ontology_node + ) + + ball_perception = _PERCEPTION_GENERATOR.generate_perception( + ball_situation, chooser=RandomChooser.for_seed(0) + ) + + perceived_objects = ball_perception.frames[0].perceived_objects + object_handles = set(obj.debug_handle for obj in perceived_objects) + assert object_handles == {"**ball_0", "**ball_1", "the ground"} + assert any( + relation.relation_type == BIGGER_THAN_SAME_TYPE + for relation in ball_perception.frames[0].relations + ) + assert any( + relation.relation_type == SMALLER_THAN_SAME_TYPE + for relation in ball_perception.frames[0].relations + ) + + def test_person_and_ball(): person = situation_object(PERSON) ball = situation_object(BALL) diff --git a/tests/situation/templates/phase1_template_test.py b/tests/situation/templates/phase1_template_test.py index 8a715b7a9..47149da85 100644 --- a/tests/situation/templates/phase1_template_test.py +++ b/tests/situation/templates/phase1_template_test.py @@ -160,6 +160,7 @@ def test_learner_as_default_addressee(): ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, + block_multiple_of_the_same_type=True, ) ) @@ -169,6 +170,7 @@ def test_learner_as_default_addressee(): ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, + block_multiple_of_the_same_type=True, ) ) @@ -178,6 +180,7 @@ def test_learner_as_default_addressee(): ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, + block_multiple_of_the_same_type=True, ) ) @@ -233,6 +236,7 @@ def test_before_after_relations_asserted(): ontology=GAILA_PHASE_1_ONTOLOGY, chooser=RandomChooser.for_seed(0), max_to_sample=1, + block_multiple_of_the_same_type=True, ) )