From 7b36c169a44b70cdb841c3f33654f357248e70f7 Mon Sep 17 00:00:00 2001 From: Gerard Canal Date: Wed, 21 Jun 2023 18:07:20 +0100 Subject: [PATCH 1/3] Groundnig fixes --- pddl/grounding.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pddl/grounding.py b/pddl/grounding.py index 8b35ed6..59d5b57 100644 --- a/pddl/grounding.py +++ b/pddl/grounding.py @@ -109,6 +109,8 @@ def prepare_symbol_tables(self, domain : Domain, problem): self.type_symbol_tables["object"] = SymbolTable() for type in domain.type_tree.keys(): self.type_symbol_tables[type] = SymbolTable() + if domain.type_tree[type].parent not in domain.type_tree: + self.type_symbol_tables[domain.type_tree[type].parent] = SymbolTable() for type in domain.type_tree.keys(): if type in problem.type_objects_map: for obj in problem.type_objects_map[type]: @@ -119,13 +121,19 @@ def prepare_symbol_tables(self, domain : Domain, problem): def update_type_symbol_table(self, obj_name : str, obj_type : str): self.type_symbol_tables[obj_type].add_symbol(obj_name) - if obj_type in self.domain.type_tree: + if obj_type in self.domain.type_tree and self.domain.type_tree[obj_type].parent != obj_type: + # The second part of the if prevents an infinite recursion, for instance when there's a type "object" in the PDDL self.update_type_symbol_table(obj_name, self.domain.type_tree[obj_type].parent) def ground_object_list(self, problem): self.type_counts["object"] = len(problem.objects_type_map) + len(self.domain.constants_type_map) for type in self.domain.type_tree.keys(): self.type_counts[type] = len(self.type_symbol_tables[type].symbol_list) + if self.domain.type_tree[type].parent not in self.domain.type_tree: + if self.domain.type_tree[type].parent not in self.type_counts: + self.type_counts[self.domain.type_tree[type].parent] = len(self.type_symbol_tables[type].symbol_list) # Initialise + else: + self.type_counts[self.domain.type_tree[type].parent] += len(self.type_symbol_tables[type].symbol_list) def ground_symbol_list(self, symbol_table : SymbolTable, formulae : dict[str, AtomicFormula], heads : dict[str, int]): head = 0 From 3de4fb358144fa44d3fd03cde3e6433a66891dc2 Mon Sep 17 00:00:00 2001 From: Gerard Canal Date: Thu, 22 Jun 2023 20:23:40 +0100 Subject: [PATCH 2/3] Fixes in RPG generation --- plan_graphs/relaxed_plan_graph.py | 39 +++++++++++++++++-------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/plan_graphs/relaxed_plan_graph.py b/plan_graphs/relaxed_plan_graph.py index 6b74f64..5c3398d 100644 --- a/plan_graphs/relaxed_plan_graph.py +++ b/plan_graphs/relaxed_plan_graph.py @@ -3,6 +3,7 @@ from pddl.grounding import Grounding from pddl.problem import Problem from pddl.state import State +from pddl.time_spec import TimeSpec class RelaxedPlanGraph: @@ -46,17 +47,18 @@ def _cache_actions(self) -> None: """ self.actions_cached = True for action_id in range(self.grounding.action_count): - pos, _ = self.grounding.get_simple_action_condition_from_id(action_id) - adds, _ = self.grounding.get_simple_action_effect_from_id(action_id) - self.action_add_effect_spikes[action_id] = adds - self.action_positive_condition_spikes[action_id] = pos - self.action_precondition_counts[action_id] = np.count_nonzero(pos) - - # cache precondition mapping - for prop in np.nonzero(pos)[0]: - if prop not in self.proposition_condition_map: - self.proposition_condition_map[prop] = [] - self.proposition_condition_map[prop].append(action_id) + for time_spec in [TimeSpec.AT_START, TimeSpec.OVER_ALL, TimeSpec.AT_END]: + pos, _ = self.grounding.get_simple_action_condition_from_id(action_id, time_spec) + adds, _ = self.grounding.get_simple_action_effect_from_id(action_id, time_spec) + self.action_add_effect_spikes[action_id] = adds + self.action_positive_condition_spikes[action_id] = pos + self.action_precondition_counts[action_id] = np.count_nonzero(pos) + + # cache precondition mapping + for prop in np.nonzero(pos)[0]: + if prop not in self.proposition_condition_map: + self.proposition_condition_map[prop] = [] + self.proposition_condition_map[prop].append(action_id) def build_graph(self, state : State = None, stop_at_goal = True) -> int: """ @@ -120,13 +122,14 @@ def build_graph(self, state : State = None, stop_at_goal = True) -> int: self.fix_point_reached = False # increment counters on action conditions - for a in self.proposition_condition_map[prop_id]: - self.action_counters[a] += 1 - if self.action_counters[a] == self.action_precondition_counts[a] and self.action_membership[a] == 0: - # new action achievable - self.action_membership[a] = self.last_layer + 1 - self.action_layers[self.last_layer+1].add(a) - next_actions.append(a) + if prop_id in self.proposition_condition_map: + for a in self.proposition_condition_map[prop_id]: + self.action_counters[a] += 1 + if self.action_counters[a] == self.action_precondition_counts[a] and self.action_membership[a] == 0: + # new action achievable + self.action_membership[a] = self.last_layer + 1 + self.action_layers[self.last_layer+1].add(a) + next_actions.append(a) current_actions = next_actions From 5d3bedf3a9a1a672c4b3a0957a3720119c7be57c Mon Sep 17 00:00:00 2001 From: Gerard Canal Date: Thu, 22 Jun 2023 21:40:43 +0100 Subject: [PATCH 3/3] Fix precondition counts in rpg --- plan_graphs/relaxed_plan_graph.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plan_graphs/relaxed_plan_graph.py b/plan_graphs/relaxed_plan_graph.py index 5c3398d..886f98e 100644 --- a/plan_graphs/relaxed_plan_graph.py +++ b/plan_graphs/relaxed_plan_graph.py @@ -52,7 +52,10 @@ def _cache_actions(self) -> None: adds, _ = self.grounding.get_simple_action_effect_from_id(action_id, time_spec) self.action_add_effect_spikes[action_id] = adds self.action_positive_condition_spikes[action_id] = pos - self.action_precondition_counts[action_id] = np.count_nonzero(pos) + if action_id in self.action_precondition_counts: + self.action_precondition_counts[action_id] += np.count_nonzero(pos) + else: + self.action_precondition_counts[action_id] = np.count_nonzero(pos) # cache precondition mapping for prop in np.nonzero(pos)[0]: