@@ -468,7 +468,7 @@ def enumerate(self) -> Iterator[Tuple[Predicate, float]]:
468468 "((0:robot).fingers<=[idx 0]0.5)"
469469 ],
470470 "burger_no_move" : [
471- "((0:robot).fingers<=[idx 0]0.5)"
471+ "((0:robot).fingers<=[idx 0]0.5)" ,
472472 ],
473473 "unittest" : [
474474 "((0:robot).hand<=[idx 0]0.65)" , "((0:block).grasp<=[idx 0]0.0)" ,
@@ -885,6 +885,7 @@ class _ForallPredicateGrammarWrapper(_PredicateGrammar):
885885 base_grammar : _PredicateGrammar
886886
887887 def enumerate (self ) -> Iterator [Tuple [Predicate , float ]]:
888+ forall_penalty = CFG .grammar_search_forall_penalty
888889 for (predicate , cost ) in self .base_grammar .enumerate ():
889890 yield (predicate , cost )
890891 if predicate .arity == 0 :
@@ -894,14 +895,15 @@ def enumerate(self) -> Iterator[Tuple[Predicate, float]]:
894895 forall_predicate = Predicate (str (forall_classifier ), [],
895896 forall_classifier )
896897 assert forall_predicate .arity == 0
897- yield (forall_predicate , cost + 1 ) # add arity + 1 to cost
898+ yield (forall_predicate , cost + forall_penalty )
898899 # Generate NOT-Forall(x)
899900 notforall_classifier = _NegationClassifier (forall_predicate )
900901 notforall_predicate = Predicate (str (notforall_classifier ),
901902 forall_predicate .types ,
902903 notforall_classifier )
903904 assert notforall_predicate .arity == 0
904- yield (notforall_predicate , cost + 1 ) # add arity + 1 to cost
905+ yield (notforall_predicate , cost + forall_penalty )
906+
905907 # Generate UFFs
906908 if predicate .arity >= 2 :
907909 for idx in range (predicate .arity ):
@@ -911,14 +913,14 @@ def enumerate(self) -> Iterator[Tuple[Predicate, float]]:
911913 [predicate .types [idx ]],
912914 uff_classifier )
913915 assert uff_predicate .arity == 1
914- yield (uff_predicate , cost + 2 ) # add arity + 1 to cost
916+ yield (uff_predicate , cost + forall_penalty + 1 )
915917 # Negated UFF
916918 notuff_classifier = _NegationClassifier (uff_predicate )
917919 notuff_predicate = Predicate (str (notuff_classifier ),
918920 uff_predicate .types ,
919921 notuff_classifier )
920922 assert notuff_predicate .arity == 1
921- yield (notuff_predicate , cost + 2 ) # add arity + 1 to cost
923+ yield (notuff_predicate , cost + forall_penalty + 1 )
922924
923925
924926################################################################################
@@ -942,6 +944,12 @@ def __init__(self, initial_predicates: Set[Predicate],
942944 def get_name (cls ) -> str :
943945 return "grammar_search_invention"
944946
947+ def load (self , online_learning_cycle : Optional [int ]) -> None :
948+ super ().load (online_learning_cycle )
949+ preds , _ = utils .extract_preds_and_types (self ._nsrts )
950+ self ._learned_predicates = set (
951+ preds .values ()) - self ._initial_predicates
952+
945953 def _get_current_predicates (self ) -> Set [Predicate ]:
946954 return self ._initial_predicates | self ._learned_predicates
947955
@@ -959,6 +967,9 @@ def _generate_atom_dataset_via_grammar(
959967 self ._metrics ["grammar_size" ] = len (candidates )
960968 for predicate , cost in candidates .items ():
961969 logging .info (f"{ predicate } { cost } " )
970+ # Now, rename these predicates to be compatible with PDDL planners!
971+ renamed_candidates = self .\
972+ _rename_predicates_to_remove_incompatible_chars (candidates )
962973 # Apply the candidate predicates to the data.
963974 logging .info ("Applying predicates to data..." )
964975
@@ -983,13 +994,13 @@ def _generate_atom_dataset_via_grammar(
983994 else :
984995 atom_dataset = utils .create_ground_atom_dataset (
985996 dataset .trajectories ,
986- set (candidates ) | self ._initial_predicates )
997+ set (renamed_candidates ) | self ._initial_predicates )
987998 # Save this atoms dataset if the save_atoms flag is set.
988999 if CFG .save_atoms :
9891000 utils .save_ground_atom_dataset (atom_dataset , dataset_fname )
9901001 logging .info ("Done." )
9911002 assert atom_dataset is not None
992- return (atom_dataset , candidates )
1003+ return (atom_dataset , renamed_candidates )
9931004
9941005 def _parse_atom_dataset_from_annotated_dataset (
9951006 self , dataset : Dataset
@@ -1016,6 +1027,22 @@ def _parse_atom_dataset_from_annotated_dataset(
10161027 logging .debug (f"All candidate predicates: { candidates .keys ()} " )
10171028 return (atom_dataset , candidates )
10181029
1030+ def _rename_predicates_to_remove_incompatible_chars (
1031+ self , predicates_and_costs : Dict [Predicate ,
1032+ float ]) -> Dict [Predicate , float ]:
1033+ """Renames predicates to get rid of characters in the name that are
1034+ incompatible with PDDL planners like FD."""
1035+ renamed_predicates : Dict [Predicate , float ] = {}
1036+ for p in predicates_and_costs :
1037+ if isinstance (p , VLMPredicate ): # pragma: no cover.
1038+ renamed_predicates [p ] = predicates_and_costs [p ]
1039+ continue
1040+ new_name = p .name .replace ("(" , "[" ).replace (")" ,
1041+ "]" ).replace (" " , "_" )
1042+ renamed_pred = Predicate (new_name , p .types , p ._classifier ) # pylint:disable=protected-access
1043+ renamed_predicates [renamed_pred ] = predicates_and_costs [p ]
1044+ return renamed_predicates
1045+
10191046 def learn_from_offline_dataset (self , dataset : Dataset ) -> None :
10201047 if CFG .offline_data_method in [
10211048 "geo_and_demo_with_vlm_imgs" , "geo_and_demo+labelled_atoms" ,
@@ -1027,7 +1054,15 @@ def learn_from_offline_dataset(self, dataset: Dataset) -> None:
10271054 self ._parse_atom_dataset_from_annotated_dataset (dataset )
10281055 atom_dataset = utils .merge_ground_atom_datasets (
10291056 atom_dataset_from_grammar , atom_dataset_from_vlm )
1030- candidates = candidates_from_grammar | candidates_from_vlm
1057+ # If grammar_search_invent_geo_predicates_only is False, then we
1058+ # want to invent both VLM and geo predicates
1059+ if not CFG .grammar_search_invent_geo_predicates_only :
1060+ candidates = candidates_from_grammar | candidates_from_vlm
1061+ # Otherwise, we only want to invent geo predicates, and directly
1062+ # select all the VLM predicates.
1063+ else :
1064+ candidates = candidates_from_grammar
1065+ self ._initial_predicates |= set (candidates_from_vlm .keys ())
10311066 elif not CFG .offline_data_method in [
10321067 "demo+labelled_atoms" , "saved_vlm_img_demos_folder" ,
10331068 "demo_with_vlm_imgs"
@@ -1045,8 +1080,22 @@ def learn_from_offline_dataset(self, dataset: Dataset) -> None:
10451080 CFG .grammar_search_use_handcoded_debug_grammar :
10461081 # Skip hill-climbing and select all the predicates from the
10471082 # debug grammar.
1083+ # Same functionality as
1084+ # _rename_predicates_to_remove_incompatible_chars.
1085+ # We have to do it again here because the predicates in
1086+ # _DEBUG_GEOMETRIC_PREDICATES haven't been renamed to make them
1087+ # compatible with fast-downward. If we do rename them, grammar
1088+ # generation gets messed up (for a
1089+ # not-yet-investigated reason).
1090+ def rename (p : str ) -> str : # pragma: no cover
1091+ return p .replace ("(" , "[" ).replace (")" ,
1092+ "]" ).replace (" " , "_" )
1093+
1094+ renamed_debug_geometric_predicates = [
1095+ rename (p ) for p in _DEBUG_GEOMETRIC_PREDICATES [CFG .env ]
1096+ ]
10481097 debug_predicate_names = _DEBUG_VLM_PREDICATES [
1049- CFG .env ] + _DEBUG_GEOMETRIC_PREDICATES [ CFG . env ]
1098+ CFG .env ] + renamed_debug_geometric_predicates
10501099 self ._learned_predicates = set (
10511100 p for p in candidates .keys ()
10521101 if p .name in debug_predicate_names )
@@ -1066,21 +1115,21 @@ def learn_from_offline_dataset(self, dataset: Dataset) -> None:
10661115 elif CFG .grammar_search_pred_selection_approach == "no_select" :
10671116 self ._learned_predicates = set (candidates .keys ())
10681117 logging .info ("Done." )
1069- # Now, rename these predicates to be compatible with PDDL planners!
1070- renamed_predicates : Set [Predicate ] = set ()
1071- for p in self ._learned_predicates :
1072- if isinstance (p , VLMPredicate ): # pragma: no cover.
1073- renamed_predicates .add (p )
1074- continue
1075- new_name = p .name .replace ("(" , "[" ).replace (")" ,
1076- "]" ).replace (" " , "_" )
1077- renamed_pred = Predicate (new_name , p .types , p ._classifier ) # pylint:disable=protected-access
1078- renamed_predicates .add (renamed_pred )
1079- self ._learned_predicates = renamed_predicates
10801118 # Finally, learn NSRTs via superclass, using all the kept predicates.
10811119 annotations = None
10821120 if dataset .has_annotations :
1083- annotations = dataset .annotations
1121+ if CFG .offline_data_method in [
1122+ "geo_and_demo_with_vlm_imgs" ,
1123+ "geo_and_demo+labelled_atoms" ,
1124+ "geo_and_saved_vlm_img_demos_folder"
1125+ ]:
1126+ # IMPORTANT: in this case, we need to make sure the dataset
1127+ # annotations include the geo predicates as well as the VLM
1128+ # predicates, so we need to set the annotations to the generated
1129+ # atom_dataset and not just the dataset.annotations.
1130+ annotations = [atoms_data [1 ] for atoms_data in atom_dataset ]
1131+ else :
1132+ annotations = dataset .annotations
10841133 self ._learn_nsrts (dataset .trajectories ,
10851134 online_learning_cycle = None ,
10861135 annotations = annotations )
@@ -1119,10 +1168,12 @@ def _get_successors(
11191168 _check_goal ,
11201169 _get_successors ,
11211170 score_function .evaluate ,
1171+ early_termination_heuristic_thresh = CFG .
1172+ grammar_search_early_termination_heuristic_thresh ,
11221173 enforced_depth = CFG .grammar_search_hill_climbing_depth ,
11231174 parallelize = CFG .grammar_search_parallelize_hill_climbing )
11241175 logging .info ("\n Hill climbing summary:" )
1125- for i in range (1 , len (path )):
1176+ for i in range (1 , len (path )): # pragma: no cover
11261177 new_additions = path [i ] - path [i - 1 ]
11271178 assert len (new_additions ) == 1
11281179 new_addition = next (iter (new_additions ))
@@ -1178,7 +1229,7 @@ def _get_successors(
11781229
11791230 logging .info (f"\n Selected { len (kept_predicates )} predicates out of "
11801231 f"{ len (candidates )} candidates:" )
1181- for pred in kept_predicates :
1232+ for pred in kept_predicates : # pragma: no cover
11821233 logging .info (f"\t { pred } " )
11831234 score_function .evaluate (kept_predicates ) # log useful numbers
11841235
0 commit comments