From a1090c0981cd05451f83b9a9e62a790f346c7ec4 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Thu, 25 Sep 2025 13:49:02 -0400 Subject: [PATCH 01/19] Update to include test code, realize issues, and clean up unnecessary files --- linearize.py | 108 + logistics-test-probs.py | 46 + .../.coveragerc | 0 .flake8 => other_shit_idgafabout/.flake8 | 0 .../CONTRIBUTING.md | 0 LICENSE => other_shit_idgafabout/LICENSE | 0 .../SUBMODULE.md | 0 .../agents.ipynb | 0 .../agents4e.py | 0 other_shit_idgafabout/aima_8puzzle.py | 21 + other_shit_idgafabout/aima_my_tsp.py | 93 + .../arc_consistency_heuristics.ipynb | 0 csp.ipynb => other_shit_idgafabout/csp.ipynb | 0 .../deep_learning4e.py | 0 .../games.ipynb | 0 games.py => other_shit_idgafabout/games.py | 0 .../games4e.ipynb | 0 .../games4e.py | 0 .../improving_sat_algorithms.ipynb | 0 .../index.ipynb | 0 .../intro.ipynb | 0 .../ipyviews.py | 0 {js => other_shit_idgafabout/js}/canvas.js | 0 .../js}/continuousworld.js | 0 {js => other_shit_idgafabout/js}/gridworld.js | 0 .../knowledge.py | 0 .../knowledge_FOIL.ipynb | 0 .../knowledge_current_best.ipynb | 0 .../knowledge_version_space.ipynb | 0 .../learning.ipynb | 0 .../learning.py | 0 .../learning4e.py | 0 .../learning_apps.ipynb | 0 .../making_simple_decision4e.py | 0 mdp.ipynb => other_shit_idgafabout/mdp.ipynb | 0 mdp.py => other_shit_idgafabout/mdp.py | 0 mdp4e.py => other_shit_idgafabout/mdp4e.py | 0 .../mdp_apps.ipynb | 0 .../neural_nets.ipynb | 0 nlp.ipynb => other_shit_idgafabout/nlp.ipynb | 0 nlp.py => other_shit_idgafabout/nlp.py | 0 nlp4e.py => other_shit_idgafabout/nlp4e.py | 0 .../nlp_apps.ipynb | 0 .../notebook.py | 0 .../notebook4e.py | 0 .../notebooks}/chapter19/Learners.ipynb | 0 .../chapter19/Loss Functions and Layers.ipynb | 0 .../Optimizer and Backpropagation.ipynb | 0 .../notebooks}/chapter19/RNN.ipynb | 0 .../chapter19/images/autoencoder.png | Bin .../notebooks}/chapter19/images/backprop.png | Bin .../chapter19/images/corss_entropy_plot.png | Bin .../notebooks}/chapter19/images/mse_plot.png | Bin .../notebooks}/chapter19/images/nn.png | Bin .../notebooks}/chapter19/images/nn_steps.png | Bin .../chapter19/images/perceptron.png | Bin .../chapter19/images/rnn_connections.png | Bin .../notebooks}/chapter19/images/rnn_unit.png | Bin .../notebooks}/chapter19/images/rnn_units.png | Bin .../notebooks}/chapter19/images/vanilla.png | Bin .../Active Reinforcement Learning.ipynb | 0 .../Passive Reinforcement Learning.ipynb | 0 .../notebooks}/chapter21/images/mdp.png | Bin .../notebooks}/chapter22/Grammar.ipynb | 0 .../notebooks}/chapter22/Introduction.ipynb | 0 .../notebooks}/chapter22/Parsing.ipynb | 0 .../chapter22/images/parse_tree.png | Bin .../notebooks}/chapter22/nlp_apps.ipynb | 0 .../chapter24/Image Edge Detection.ipynb | 0 .../chapter24/Image Segmentation.ipynb | 0 .../chapter24/Objects in Images.ipynb | 0 .../notebooks}/chapter24/images/RCNN.png | Bin .../images/derivative_of_gaussian.png | Bin .../notebooks}/chapter24/images/gradients.png | Bin .../notebooks}/chapter24/images/laplacian.png | Bin .../chapter24/images/laplacian_kernels.png | Bin .../notebooks}/chapter24/images/stapler.png | Bin .../chapter24/images/stapler_bbox.png | Bin .../obsolete_search4e.ipynb | 0 .../perception4e.py | 0 .../probabilistic_learning.py | 0 .../probability.ipynb | 0 .../probability.py | 0 .../probability4e.ipynb | 0 .../probability4e.py | 0 .../pytest.ini | 0 .../reinforcement_learning.ipynb | 0 .../reinforcement_learning.py | 0 .../reinforcement_learning4e.py | 0 .../search4e.ipynb | 0 .../tests}/__init__.py | 0 .../tests}/pytest.ini | 0 .../tests}/test_agents.py | 0 .../tests}/test_agents4e.py | 0 .../tests}/test_csp.py | 0 .../tests}/test_deep_learning4e.py | 0 .../tests}/test_games.py | 0 .../tests}/test_games4e.py | 0 .../tests}/test_knowledge.py | 0 .../tests}/test_learning.py | 0 .../tests}/test_learning4e.py | 0 .../tests}/test_logic.py | 0 .../tests}/test_logic4e.py | 0 .../tests}/test_mdp.py | 0 .../tests}/test_mdp4e.py | 0 .../tests}/test_nlp.py | 0 .../tests}/test_nlp4e.py | 0 .../tests}/test_perception4e.py | 0 .../tests}/test_planning.py | 0 .../tests}/test_probabilistic_learning.py | 0 .../tests}/test_probability.py | 0 .../tests}/test_probability4e.py | 0 .../tests}/test_reinforcement_learning.py | 0 .../tests}/test_reinforcement_learning4e.py | 0 .../tests}/test_search.py | 0 .../tests}/test_text.py | 0 .../tests}/test_utils.py | 0 .../text.ipynb | 0 text.py => other_shit_idgafabout/text.py | 0 .../utils4e.py | 0 .../vacuum_world.ipynb | 0 .../viterbi_algorithm.ipynb | 0 planning.py | 135 +- planning1.py | 2077 +++++++++++++++++ submission-2a.py | 332 +++ submission_1.py | 128 + submission_1_test.py | 98 + 127 files changed, 3030 insertions(+), 8 deletions(-) create mode 100644 linearize.py create mode 100644 logistics-test-probs.py rename .coveragerc => other_shit_idgafabout/.coveragerc (100%) rename .flake8 => other_shit_idgafabout/.flake8 (100%) rename CONTRIBUTING.md => other_shit_idgafabout/CONTRIBUTING.md (100%) rename LICENSE => other_shit_idgafabout/LICENSE (100%) rename SUBMODULE.md => other_shit_idgafabout/SUBMODULE.md (100%) rename agents.ipynb => other_shit_idgafabout/agents.ipynb (100%) rename agents4e.py => other_shit_idgafabout/agents4e.py (100%) create mode 100644 other_shit_idgafabout/aima_8puzzle.py create mode 100644 other_shit_idgafabout/aima_my_tsp.py rename arc_consistency_heuristics.ipynb => other_shit_idgafabout/arc_consistency_heuristics.ipynb (100%) rename csp.ipynb => other_shit_idgafabout/csp.ipynb (100%) rename deep_learning4e.py => other_shit_idgafabout/deep_learning4e.py (100%) rename games.ipynb => other_shit_idgafabout/games.ipynb (100%) rename games.py => other_shit_idgafabout/games.py (100%) rename games4e.ipynb => other_shit_idgafabout/games4e.ipynb (100%) rename games4e.py => other_shit_idgafabout/games4e.py (100%) rename improving_sat_algorithms.ipynb => other_shit_idgafabout/improving_sat_algorithms.ipynb (100%) rename index.ipynb => other_shit_idgafabout/index.ipynb (100%) rename intro.ipynb => other_shit_idgafabout/intro.ipynb (100%) rename ipyviews.py => other_shit_idgafabout/ipyviews.py (100%) rename {js => other_shit_idgafabout/js}/canvas.js (100%) rename {js => other_shit_idgafabout/js}/continuousworld.js (100%) rename {js => other_shit_idgafabout/js}/gridworld.js (100%) rename knowledge.py => other_shit_idgafabout/knowledge.py (100%) rename knowledge_FOIL.ipynb => other_shit_idgafabout/knowledge_FOIL.ipynb (100%) rename knowledge_current_best.ipynb => other_shit_idgafabout/knowledge_current_best.ipynb (100%) rename knowledge_version_space.ipynb => other_shit_idgafabout/knowledge_version_space.ipynb (100%) rename learning.ipynb => other_shit_idgafabout/learning.ipynb (100%) rename learning.py => other_shit_idgafabout/learning.py (100%) rename learning4e.py => other_shit_idgafabout/learning4e.py (100%) rename learning_apps.ipynb => other_shit_idgafabout/learning_apps.ipynb (100%) rename making_simple_decision4e.py => other_shit_idgafabout/making_simple_decision4e.py (100%) rename mdp.ipynb => other_shit_idgafabout/mdp.ipynb (100%) rename mdp.py => other_shit_idgafabout/mdp.py (100%) rename mdp4e.py => other_shit_idgafabout/mdp4e.py (100%) rename mdp_apps.ipynb => other_shit_idgafabout/mdp_apps.ipynb (100%) rename neural_nets.ipynb => other_shit_idgafabout/neural_nets.ipynb (100%) rename nlp.ipynb => other_shit_idgafabout/nlp.ipynb (100%) rename nlp.py => other_shit_idgafabout/nlp.py (100%) rename nlp4e.py => other_shit_idgafabout/nlp4e.py (100%) rename nlp_apps.ipynb => other_shit_idgafabout/nlp_apps.ipynb (100%) rename notebook.py => other_shit_idgafabout/notebook.py (100%) rename notebook4e.py => other_shit_idgafabout/notebook4e.py (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/Learners.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/Loss Functions and Layers.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/Optimizer and Backpropagation.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/RNN.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/autoencoder.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/backprop.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/corss_entropy_plot.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/mse_plot.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/nn.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/nn_steps.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/perceptron.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/rnn_connections.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/rnn_unit.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/rnn_units.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter19/images/vanilla.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter21/Active Reinforcement Learning.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter21/Passive Reinforcement Learning.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter21/images/mdp.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter22/Grammar.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter22/Introduction.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter22/Parsing.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter22/images/parse_tree.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter22/nlp_apps.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/Image Edge Detection.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/Image Segmentation.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/Objects in Images.ipynb (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/RCNN.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/derivative_of_gaussian.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/gradients.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/laplacian.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/laplacian_kernels.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/stapler.png (100%) rename {notebooks => other_shit_idgafabout/notebooks}/chapter24/images/stapler_bbox.png (100%) rename obsolete_search4e.ipynb => other_shit_idgafabout/obsolete_search4e.ipynb (100%) rename perception4e.py => other_shit_idgafabout/perception4e.py (100%) rename probabilistic_learning.py => other_shit_idgafabout/probabilistic_learning.py (100%) rename probability.ipynb => other_shit_idgafabout/probability.ipynb (100%) rename probability.py => other_shit_idgafabout/probability.py (100%) rename probability4e.ipynb => other_shit_idgafabout/probability4e.ipynb (100%) rename probability4e.py => other_shit_idgafabout/probability4e.py (100%) rename pytest.ini => other_shit_idgafabout/pytest.ini (100%) rename reinforcement_learning.ipynb => other_shit_idgafabout/reinforcement_learning.ipynb (100%) rename reinforcement_learning.py => other_shit_idgafabout/reinforcement_learning.py (100%) rename reinforcement_learning4e.py => other_shit_idgafabout/reinforcement_learning4e.py (100%) rename search4e.ipynb => other_shit_idgafabout/search4e.ipynb (100%) rename {tests => other_shit_idgafabout/tests}/__init__.py (100%) rename {tests => other_shit_idgafabout/tests}/pytest.ini (100%) rename {tests => other_shit_idgafabout/tests}/test_agents.py (100%) rename {tests => other_shit_idgafabout/tests}/test_agents4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_csp.py (100%) rename {tests => other_shit_idgafabout/tests}/test_deep_learning4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_games.py (100%) rename {tests => other_shit_idgafabout/tests}/test_games4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_knowledge.py (100%) rename {tests => other_shit_idgafabout/tests}/test_learning.py (100%) rename {tests => other_shit_idgafabout/tests}/test_learning4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_logic.py (100%) rename {tests => other_shit_idgafabout/tests}/test_logic4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_mdp.py (100%) rename {tests => other_shit_idgafabout/tests}/test_mdp4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_nlp.py (100%) rename {tests => other_shit_idgafabout/tests}/test_nlp4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_perception4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_planning.py (100%) rename {tests => other_shit_idgafabout/tests}/test_probabilistic_learning.py (100%) rename {tests => other_shit_idgafabout/tests}/test_probability.py (100%) rename {tests => other_shit_idgafabout/tests}/test_probability4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_reinforcement_learning.py (100%) rename {tests => other_shit_idgafabout/tests}/test_reinforcement_learning4e.py (100%) rename {tests => other_shit_idgafabout/tests}/test_search.py (100%) rename {tests => other_shit_idgafabout/tests}/test_text.py (100%) rename {tests => other_shit_idgafabout/tests}/test_utils.py (100%) rename text.ipynb => other_shit_idgafabout/text.ipynb (100%) rename text.py => other_shit_idgafabout/text.py (100%) rename utils4e.py => other_shit_idgafabout/utils4e.py (100%) rename vacuum_world.ipynb => other_shit_idgafabout/vacuum_world.ipynb (100%) rename viterbi_algorithm.ipynb => other_shit_idgafabout/viterbi_algorithm.ipynb (100%) create mode 100644 planning1.py create mode 100644 submission-2a.py create mode 100644 submission_1.py create mode 100644 submission_1_test.py diff --git a/linearize.py b/linearize.py new file mode 100644 index 000000000..6fc6065c8 --- /dev/null +++ b/linearize.py @@ -0,0 +1,108 @@ + +class Linearize: + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + + def filter(self, solution): + """Filter out persistence actions from a solution""" + + new_solution = [] + for section in solution[0]: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + new_solution.append(new_section) + return new_solution + + def orderlevel(self, level, planning_problem): + """Return valid linear order of actions for a given level""" + + for permutation in itertools.permutations(level): + print(f"TRYING PARTIAL PLAN: {permutation}") ## Bill's hack + temp = copy.deepcopy(planning_problem) + count = 0 + ## print(f"PERMUTATION: {permutation}") ## Bill's hack + for action in permutation: + try: + # print(f"TRY ACTION: {action}") ## Bill's hack + temp.act(action) + count += 1 + # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack + except: + # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack + count = 0 + temp = copy.deepcopy(planning_problem) + continue ##break + if count == len(permutation): + print(f"\nSUCCESSFUL PARTIAL PLAN ORDERING: {permutation}") ## Bill's hack + return list(permutation), temp + print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack + return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem + + def execute(self): + """Finds total-order solution for a planning graph""" + + graphPlan_solution = GraphPlan(self.planning_problem).execute() + + ## Bill's stuff from playing around + ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack + ## pnl(graphPlan_solution) + ## for possible_plan in graphPlan_solution: + ## possible_plan = [possible_plan] + ## filtered_possible_plan = self.filter(possible_plan) + ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack + ## flattened_graphplan = self.filter(graphPlan_solution) + ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack + ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack + ## flattened_graphplan = [flattened_graphplan] + ## graphPlan_solution = [flattened_graphplan] ## Bill's hack + ## pnl(flattened_graphplan) + + ## I think I have to go over all permutations of possbile partial graphplans + + for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack + + ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list + ## filtered_solution = self.filter(graphPlan_solution) # original + + filtered_solution = self.filter(possible_plan) # my mod + + print(f"TRYING FILTERED PLAN: {filtered_solution}") ## Bill's hack + + ## filtered_solution = self.filter(possible_plan) # mod + ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack + ## pnl(filtered_solution) + ## filtered_solution = possible_plan + + ordered_solution = [] + planning_problem = self.planning_problem + for level in filtered_solution: + + ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack + + ## the below is a key line, the key line + level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied + if not level_solution: # This checks if level_solution is None or an empty list + print(f"PLAN FAIL: {filtered_solution}") ## Bill's hack + continue ## Bill's hack!! if empty, continue looking. + + print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack + ##print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack + ## for action in level_solution: + ## print(f"APPLY ACTION: {action}") ## Bill's hack + ## planning_problem.act(action) # complete guess, apply action to the problem and keep going + + ## I think we need to apply the plan to the planning problem and modify it + for element in level_solution: + ordered_solution.append(element) + + if not ordered_solution: + continue ## no plan possible from the partial plan at the level + else: + print(f"WORKING SOL'N: {ordered_solution}") ## Bill's hack + break + + return ordered_solution + diff --git a/logistics-test-probs.py b/logistics-test-probs.py new file mode 100644 index 000000000..c70933c3b --- /dev/null +++ b/logistics-test-probs.py @@ -0,0 +1,46 @@ + + +## initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + +logisticsPlan('In(C1, D1)') + +logisticsPlan('In(C1,D2)') + +logisticsPlan('In(C1, D1) & In(R1, D2)') +logisticsPlan('In(R1, D2) & In(C1, D1)') + +logisticsPlan('In(C1, D1) & In(C3, R1)') +logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') + +logisticsPlan('In(C1, D1) & In(R1, D3) & In(C3, R1)') +logisticsPlan('In(C1, D1) & In(C3, D3)') + +logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') + +logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') + +logisticsPlan('In(C1, D1) & In(C2, D3)') + + +logisticsPlan('In(C3, D1)') + +logisticsPlan('In(C2, D3)') + +logisticsPlan('In(C3, D3)') + + +#no plans for these below +logisticsPlan('In(C2, D3) & In(C3, D3)') + +logisticsPlan('In(C3, D3) & In(C2, D3)') + +logisticsPlan('In(C1, D2) & In(C3, D3)') + +logisticsPlan('In(C1, D3) & In(C2, D3) & In(C3, D3)') ## homework?? + +logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D1)') + + +#kaboom... didn't stop? +logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)') + diff --git a/.coveragerc b/other_shit_idgafabout/.coveragerc similarity index 100% rename from .coveragerc rename to other_shit_idgafabout/.coveragerc diff --git a/.flake8 b/other_shit_idgafabout/.flake8 similarity index 100% rename from .flake8 rename to other_shit_idgafabout/.flake8 diff --git a/CONTRIBUTING.md b/other_shit_idgafabout/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to other_shit_idgafabout/CONTRIBUTING.md diff --git a/LICENSE b/other_shit_idgafabout/LICENSE similarity index 100% rename from LICENSE rename to other_shit_idgafabout/LICENSE diff --git a/SUBMODULE.md b/other_shit_idgafabout/SUBMODULE.md similarity index 100% rename from SUBMODULE.md rename to other_shit_idgafabout/SUBMODULE.md diff --git a/agents.ipynb b/other_shit_idgafabout/agents.ipynb similarity index 100% rename from agents.ipynb rename to other_shit_idgafabout/agents.ipynb diff --git a/agents4e.py b/other_shit_idgafabout/agents4e.py similarity index 100% rename from agents4e.py rename to other_shit_idgafabout/agents4e.py diff --git a/other_shit_idgafabout/aima_8puzzle.py b/other_shit_idgafabout/aima_8puzzle.py new file mode 100644 index 000000000..2d7229983 --- /dev/null +++ b/other_shit_idgafabout/aima_8puzzle.py @@ -0,0 +1,21 @@ +""" +Demo for A* with EightPuzzle +For use with the AIMA codebase: https://github.com/aimacode/aima-python +CMSC 421 - Fall 2025 +""" +from time import time +from search import EightPuzzle, astar_search + +# INITIAL_STATE = (1, 2, 3, 4, 5, 6, 7, 8, 0) # already solved +INITIAL_STATE = (1, 2, 3, 4, 5, 6, 7, 0, 8) # just one swap to solve +# INITIAL_STATE = (1, 2, 3, 4, 0, 6, 7, 5, 8) # just two swaps to solve +# INITIAL_STATE = (1, 2, 3, 0, 4, 6, 7, 5, 8) # just three swaps to solve +# INITIAL_STATE = (8, 3, 2, 4, 5, 7, 1, 6, 0) # more complex initial state + +EP = EightPuzzle(INITIAL_STATE) +print('Initial State: ' + str(INITIAL_STATE)) +print('Initial State solvable: ' + str(EP.check_solvability(INITIAL_STATE))) +print('Running A*...') +t0 = time() +astar_search(EP, display=True) +print('Solved in %f seconds'%(time()-t0)) \ No newline at end of file diff --git a/other_shit_idgafabout/aima_my_tsp.py b/other_shit_idgafabout/aima_my_tsp.py new file mode 100644 index 000000000..737bbf7fa --- /dev/null +++ b/other_shit_idgafabout/aima_my_tsp.py @@ -0,0 +1,93 @@ +""" +Code skeleton for A* with TSP +For use with the AIMA codebase: https://github.com/aimacode/aima-python +CMSC 421 - Fall 2025 +""" +from time import time +import numpy as np +from search import Problem, astar_search +from scipy.sparse import csgraph + +### Define TSP ### + +class MyTSP(Problem): + + # NOTE: This is just a suggestion for setting up your __init__, + # you can use any design you want + def __init__(self, weights, initial=(0,), goal=None): + super().__init__(initial, goal) + self.weights = weights + self.num_cities = weights.shape[0] + self.cities = list(range(0, self.num_cities)) + + def actions(self, state): + """Return the actions that can be executed in the given + state. The result would typically be a list, but if there are + many actions, consider yielding them one at a time in an + iterator, rather than building them all at once.""" + raise NotImplementedError + # TODO: your code here + + # NOTE: If you make your state a list object, you'll wind + # up with an error like this: TypeError: unhashable type: 'list' + # One work-around is the make your states tuples instead. + def result(self, state, action): + """Return the state that results from executing the given + action in the given state. The action must be one of + self.actions(state).""" + raise NotImplementedError + # TODO: your code here + + def goal_test(self, state): + """Return True if the state is a goal. The default method compares the + state to self.goal or checks for state in self.goal if it is a + list, as specified in the constructor. Override this method if + checking against a single self.goal is not enough.""" + raise NotImplementedError + # TODO: your code here + + # NOTE: Remember the full cost includes the round trip back to the starting city! + # So if you are adding the final city to the path, you should also add the cost + # for the final edge too. + def path_cost(self, c, state1, action, state2): + """Return the cost of a solution path that arrives at state2 from + state1 via action, assuming cost c to get up to state1. If the problem + is such that the path doesn't matter, this function will only look at + state2. If the path does matter, it will consider c and maybe state1 + and action. The default method costs 1 for every step in the path.""" + raise NotImplementedError + # TODO: your code here + + def value(self, state): + """For optimization problems, each state has a value. Hill Climbing + and related algorithms try to maximize this value.""" + raise NotImplementedError + # TODO: your code here + + # NOTE: For debugging purposes, you can use h(n)=0 while writing and testing + # the rest of your code + def h(self, node): + """Return the heuristic value for a given state. astar_search will + look for this heuristic function when run.""" + raise NotImplementedError + # TODO: your code here + +### Run A* ### + +# NOTE: select a weight matrix to load, depending on where you unzipped them +MATRIX_FILE = '/home/carwyn/dev/phd/ta/aima/aima-python/aima-data/mats_911/5_random_adj_mat_0.txt' + +MAT = np.loadtxt(MATRIX_FILE) +print('Loaded road cost matrix:') +print(MAT) +MTSP = MyTSP(MAT) + +print('Running A*...') +t0 = time() +tsp_sol = astar_search(MTSP, display=True) +print('Solved in %f seconds'%(time()-t0)) + +tsp_sol = tsp_sol.state +print('Solution Path: ' + str(tsp_sol)) +sol_cost = MTSP.value(tsp_sol) +print('Solution Cost: ' + str(sol_cost)) diff --git a/arc_consistency_heuristics.ipynb b/other_shit_idgafabout/arc_consistency_heuristics.ipynb similarity index 100% rename from arc_consistency_heuristics.ipynb rename to other_shit_idgafabout/arc_consistency_heuristics.ipynb diff --git a/csp.ipynb b/other_shit_idgafabout/csp.ipynb similarity index 100% rename from csp.ipynb rename to other_shit_idgafabout/csp.ipynb diff --git a/deep_learning4e.py b/other_shit_idgafabout/deep_learning4e.py similarity index 100% rename from deep_learning4e.py rename to other_shit_idgafabout/deep_learning4e.py diff --git a/games.ipynb b/other_shit_idgafabout/games.ipynb similarity index 100% rename from games.ipynb rename to other_shit_idgafabout/games.ipynb diff --git a/games.py b/other_shit_idgafabout/games.py similarity index 100% rename from games.py rename to other_shit_idgafabout/games.py diff --git a/games4e.ipynb b/other_shit_idgafabout/games4e.ipynb similarity index 100% rename from games4e.ipynb rename to other_shit_idgafabout/games4e.ipynb diff --git a/games4e.py b/other_shit_idgafabout/games4e.py similarity index 100% rename from games4e.py rename to other_shit_idgafabout/games4e.py diff --git a/improving_sat_algorithms.ipynb b/other_shit_idgafabout/improving_sat_algorithms.ipynb similarity index 100% rename from improving_sat_algorithms.ipynb rename to other_shit_idgafabout/improving_sat_algorithms.ipynb diff --git a/index.ipynb b/other_shit_idgafabout/index.ipynb similarity index 100% rename from index.ipynb rename to other_shit_idgafabout/index.ipynb diff --git a/intro.ipynb b/other_shit_idgafabout/intro.ipynb similarity index 100% rename from intro.ipynb rename to other_shit_idgafabout/intro.ipynb diff --git a/ipyviews.py b/other_shit_idgafabout/ipyviews.py similarity index 100% rename from ipyviews.py rename to other_shit_idgafabout/ipyviews.py diff --git a/js/canvas.js b/other_shit_idgafabout/js/canvas.js similarity index 100% rename from js/canvas.js rename to other_shit_idgafabout/js/canvas.js diff --git a/js/continuousworld.js b/other_shit_idgafabout/js/continuousworld.js similarity index 100% rename from js/continuousworld.js rename to other_shit_idgafabout/js/continuousworld.js diff --git a/js/gridworld.js b/other_shit_idgafabout/js/gridworld.js similarity index 100% rename from js/gridworld.js rename to other_shit_idgafabout/js/gridworld.js diff --git a/knowledge.py b/other_shit_idgafabout/knowledge.py similarity index 100% rename from knowledge.py rename to other_shit_idgafabout/knowledge.py diff --git a/knowledge_FOIL.ipynb b/other_shit_idgafabout/knowledge_FOIL.ipynb similarity index 100% rename from knowledge_FOIL.ipynb rename to other_shit_idgafabout/knowledge_FOIL.ipynb diff --git a/knowledge_current_best.ipynb b/other_shit_idgafabout/knowledge_current_best.ipynb similarity index 100% rename from knowledge_current_best.ipynb rename to other_shit_idgafabout/knowledge_current_best.ipynb diff --git a/knowledge_version_space.ipynb b/other_shit_idgafabout/knowledge_version_space.ipynb similarity index 100% rename from knowledge_version_space.ipynb rename to other_shit_idgafabout/knowledge_version_space.ipynb diff --git a/learning.ipynb b/other_shit_idgafabout/learning.ipynb similarity index 100% rename from learning.ipynb rename to other_shit_idgafabout/learning.ipynb diff --git a/learning.py b/other_shit_idgafabout/learning.py similarity index 100% rename from learning.py rename to other_shit_idgafabout/learning.py diff --git a/learning4e.py b/other_shit_idgafabout/learning4e.py similarity index 100% rename from learning4e.py rename to other_shit_idgafabout/learning4e.py diff --git a/learning_apps.ipynb b/other_shit_idgafabout/learning_apps.ipynb similarity index 100% rename from learning_apps.ipynb rename to other_shit_idgafabout/learning_apps.ipynb diff --git a/making_simple_decision4e.py b/other_shit_idgafabout/making_simple_decision4e.py similarity index 100% rename from making_simple_decision4e.py rename to other_shit_idgafabout/making_simple_decision4e.py diff --git a/mdp.ipynb b/other_shit_idgafabout/mdp.ipynb similarity index 100% rename from mdp.ipynb rename to other_shit_idgafabout/mdp.ipynb diff --git a/mdp.py b/other_shit_idgafabout/mdp.py similarity index 100% rename from mdp.py rename to other_shit_idgafabout/mdp.py diff --git a/mdp4e.py b/other_shit_idgafabout/mdp4e.py similarity index 100% rename from mdp4e.py rename to other_shit_idgafabout/mdp4e.py diff --git a/mdp_apps.ipynb b/other_shit_idgafabout/mdp_apps.ipynb similarity index 100% rename from mdp_apps.ipynb rename to other_shit_idgafabout/mdp_apps.ipynb diff --git a/neural_nets.ipynb b/other_shit_idgafabout/neural_nets.ipynb similarity index 100% rename from neural_nets.ipynb rename to other_shit_idgafabout/neural_nets.ipynb diff --git a/nlp.ipynb b/other_shit_idgafabout/nlp.ipynb similarity index 100% rename from nlp.ipynb rename to other_shit_idgafabout/nlp.ipynb diff --git a/nlp.py b/other_shit_idgafabout/nlp.py similarity index 100% rename from nlp.py rename to other_shit_idgafabout/nlp.py diff --git a/nlp4e.py b/other_shit_idgafabout/nlp4e.py similarity index 100% rename from nlp4e.py rename to other_shit_idgafabout/nlp4e.py diff --git a/nlp_apps.ipynb b/other_shit_idgafabout/nlp_apps.ipynb similarity index 100% rename from nlp_apps.ipynb rename to other_shit_idgafabout/nlp_apps.ipynb diff --git a/notebook.py b/other_shit_idgafabout/notebook.py similarity index 100% rename from notebook.py rename to other_shit_idgafabout/notebook.py diff --git a/notebook4e.py b/other_shit_idgafabout/notebook4e.py similarity index 100% rename from notebook4e.py rename to other_shit_idgafabout/notebook4e.py diff --git a/notebooks/chapter19/Learners.ipynb b/other_shit_idgafabout/notebooks/chapter19/Learners.ipynb similarity index 100% rename from notebooks/chapter19/Learners.ipynb rename to other_shit_idgafabout/notebooks/chapter19/Learners.ipynb diff --git a/notebooks/chapter19/Loss Functions and Layers.ipynb b/other_shit_idgafabout/notebooks/chapter19/Loss Functions and Layers.ipynb similarity index 100% rename from notebooks/chapter19/Loss Functions and Layers.ipynb rename to other_shit_idgafabout/notebooks/chapter19/Loss Functions and Layers.ipynb diff --git a/notebooks/chapter19/Optimizer and Backpropagation.ipynb b/other_shit_idgafabout/notebooks/chapter19/Optimizer and Backpropagation.ipynb similarity index 100% rename from notebooks/chapter19/Optimizer and Backpropagation.ipynb rename to other_shit_idgafabout/notebooks/chapter19/Optimizer and Backpropagation.ipynb diff --git a/notebooks/chapter19/RNN.ipynb b/other_shit_idgafabout/notebooks/chapter19/RNN.ipynb similarity index 100% rename from notebooks/chapter19/RNN.ipynb rename to other_shit_idgafabout/notebooks/chapter19/RNN.ipynb diff --git a/notebooks/chapter19/images/autoencoder.png b/other_shit_idgafabout/notebooks/chapter19/images/autoencoder.png similarity index 100% rename from notebooks/chapter19/images/autoencoder.png rename to other_shit_idgafabout/notebooks/chapter19/images/autoencoder.png diff --git a/notebooks/chapter19/images/backprop.png b/other_shit_idgafabout/notebooks/chapter19/images/backprop.png similarity index 100% rename from notebooks/chapter19/images/backprop.png rename to other_shit_idgafabout/notebooks/chapter19/images/backprop.png diff --git a/notebooks/chapter19/images/corss_entropy_plot.png b/other_shit_idgafabout/notebooks/chapter19/images/corss_entropy_plot.png similarity index 100% rename from notebooks/chapter19/images/corss_entropy_plot.png rename to other_shit_idgafabout/notebooks/chapter19/images/corss_entropy_plot.png diff --git a/notebooks/chapter19/images/mse_plot.png b/other_shit_idgafabout/notebooks/chapter19/images/mse_plot.png similarity index 100% rename from notebooks/chapter19/images/mse_plot.png rename to other_shit_idgafabout/notebooks/chapter19/images/mse_plot.png diff --git a/notebooks/chapter19/images/nn.png b/other_shit_idgafabout/notebooks/chapter19/images/nn.png similarity index 100% rename from notebooks/chapter19/images/nn.png rename to other_shit_idgafabout/notebooks/chapter19/images/nn.png diff --git a/notebooks/chapter19/images/nn_steps.png b/other_shit_idgafabout/notebooks/chapter19/images/nn_steps.png similarity index 100% rename from notebooks/chapter19/images/nn_steps.png rename to other_shit_idgafabout/notebooks/chapter19/images/nn_steps.png diff --git a/notebooks/chapter19/images/perceptron.png b/other_shit_idgafabout/notebooks/chapter19/images/perceptron.png similarity index 100% rename from notebooks/chapter19/images/perceptron.png rename to other_shit_idgafabout/notebooks/chapter19/images/perceptron.png diff --git a/notebooks/chapter19/images/rnn_connections.png b/other_shit_idgafabout/notebooks/chapter19/images/rnn_connections.png similarity index 100% rename from notebooks/chapter19/images/rnn_connections.png rename to other_shit_idgafabout/notebooks/chapter19/images/rnn_connections.png diff --git a/notebooks/chapter19/images/rnn_unit.png b/other_shit_idgafabout/notebooks/chapter19/images/rnn_unit.png similarity index 100% rename from notebooks/chapter19/images/rnn_unit.png rename to other_shit_idgafabout/notebooks/chapter19/images/rnn_unit.png diff --git a/notebooks/chapter19/images/rnn_units.png b/other_shit_idgafabout/notebooks/chapter19/images/rnn_units.png similarity index 100% rename from notebooks/chapter19/images/rnn_units.png rename to other_shit_idgafabout/notebooks/chapter19/images/rnn_units.png diff --git a/notebooks/chapter19/images/vanilla.png b/other_shit_idgafabout/notebooks/chapter19/images/vanilla.png similarity index 100% rename from notebooks/chapter19/images/vanilla.png rename to other_shit_idgafabout/notebooks/chapter19/images/vanilla.png diff --git a/notebooks/chapter21/Active Reinforcement Learning.ipynb b/other_shit_idgafabout/notebooks/chapter21/Active Reinforcement Learning.ipynb similarity index 100% rename from notebooks/chapter21/Active Reinforcement Learning.ipynb rename to other_shit_idgafabout/notebooks/chapter21/Active Reinforcement Learning.ipynb diff --git a/notebooks/chapter21/Passive Reinforcement Learning.ipynb b/other_shit_idgafabout/notebooks/chapter21/Passive Reinforcement Learning.ipynb similarity index 100% rename from notebooks/chapter21/Passive Reinforcement Learning.ipynb rename to other_shit_idgafabout/notebooks/chapter21/Passive Reinforcement Learning.ipynb diff --git a/notebooks/chapter21/images/mdp.png b/other_shit_idgafabout/notebooks/chapter21/images/mdp.png similarity index 100% rename from notebooks/chapter21/images/mdp.png rename to other_shit_idgafabout/notebooks/chapter21/images/mdp.png diff --git a/notebooks/chapter22/Grammar.ipynb b/other_shit_idgafabout/notebooks/chapter22/Grammar.ipynb similarity index 100% rename from notebooks/chapter22/Grammar.ipynb rename to other_shit_idgafabout/notebooks/chapter22/Grammar.ipynb diff --git a/notebooks/chapter22/Introduction.ipynb b/other_shit_idgafabout/notebooks/chapter22/Introduction.ipynb similarity index 100% rename from notebooks/chapter22/Introduction.ipynb rename to other_shit_idgafabout/notebooks/chapter22/Introduction.ipynb diff --git a/notebooks/chapter22/Parsing.ipynb b/other_shit_idgafabout/notebooks/chapter22/Parsing.ipynb similarity index 100% rename from notebooks/chapter22/Parsing.ipynb rename to other_shit_idgafabout/notebooks/chapter22/Parsing.ipynb diff --git a/notebooks/chapter22/images/parse_tree.png b/other_shit_idgafabout/notebooks/chapter22/images/parse_tree.png similarity index 100% rename from notebooks/chapter22/images/parse_tree.png rename to other_shit_idgafabout/notebooks/chapter22/images/parse_tree.png diff --git a/notebooks/chapter22/nlp_apps.ipynb b/other_shit_idgafabout/notebooks/chapter22/nlp_apps.ipynb similarity index 100% rename from notebooks/chapter22/nlp_apps.ipynb rename to other_shit_idgafabout/notebooks/chapter22/nlp_apps.ipynb diff --git a/notebooks/chapter24/Image Edge Detection.ipynb b/other_shit_idgafabout/notebooks/chapter24/Image Edge Detection.ipynb similarity index 100% rename from notebooks/chapter24/Image Edge Detection.ipynb rename to other_shit_idgafabout/notebooks/chapter24/Image Edge Detection.ipynb diff --git a/notebooks/chapter24/Image Segmentation.ipynb b/other_shit_idgafabout/notebooks/chapter24/Image Segmentation.ipynb similarity index 100% rename from notebooks/chapter24/Image Segmentation.ipynb rename to other_shit_idgafabout/notebooks/chapter24/Image Segmentation.ipynb diff --git a/notebooks/chapter24/Objects in Images.ipynb b/other_shit_idgafabout/notebooks/chapter24/Objects in Images.ipynb similarity index 100% rename from notebooks/chapter24/Objects in Images.ipynb rename to other_shit_idgafabout/notebooks/chapter24/Objects in Images.ipynb diff --git a/notebooks/chapter24/images/RCNN.png b/other_shit_idgafabout/notebooks/chapter24/images/RCNN.png similarity index 100% rename from notebooks/chapter24/images/RCNN.png rename to other_shit_idgafabout/notebooks/chapter24/images/RCNN.png diff --git a/notebooks/chapter24/images/derivative_of_gaussian.png b/other_shit_idgafabout/notebooks/chapter24/images/derivative_of_gaussian.png similarity index 100% rename from notebooks/chapter24/images/derivative_of_gaussian.png rename to other_shit_idgafabout/notebooks/chapter24/images/derivative_of_gaussian.png diff --git a/notebooks/chapter24/images/gradients.png b/other_shit_idgafabout/notebooks/chapter24/images/gradients.png similarity index 100% rename from notebooks/chapter24/images/gradients.png rename to other_shit_idgafabout/notebooks/chapter24/images/gradients.png diff --git a/notebooks/chapter24/images/laplacian.png b/other_shit_idgafabout/notebooks/chapter24/images/laplacian.png similarity index 100% rename from notebooks/chapter24/images/laplacian.png rename to other_shit_idgafabout/notebooks/chapter24/images/laplacian.png diff --git a/notebooks/chapter24/images/laplacian_kernels.png b/other_shit_idgafabout/notebooks/chapter24/images/laplacian_kernels.png similarity index 100% rename from notebooks/chapter24/images/laplacian_kernels.png rename to other_shit_idgafabout/notebooks/chapter24/images/laplacian_kernels.png diff --git a/notebooks/chapter24/images/stapler.png b/other_shit_idgafabout/notebooks/chapter24/images/stapler.png similarity index 100% rename from notebooks/chapter24/images/stapler.png rename to other_shit_idgafabout/notebooks/chapter24/images/stapler.png diff --git a/notebooks/chapter24/images/stapler_bbox.png b/other_shit_idgafabout/notebooks/chapter24/images/stapler_bbox.png similarity index 100% rename from notebooks/chapter24/images/stapler_bbox.png rename to other_shit_idgafabout/notebooks/chapter24/images/stapler_bbox.png diff --git a/obsolete_search4e.ipynb b/other_shit_idgafabout/obsolete_search4e.ipynb similarity index 100% rename from obsolete_search4e.ipynb rename to other_shit_idgafabout/obsolete_search4e.ipynb diff --git a/perception4e.py b/other_shit_idgafabout/perception4e.py similarity index 100% rename from perception4e.py rename to other_shit_idgafabout/perception4e.py diff --git a/probabilistic_learning.py b/other_shit_idgafabout/probabilistic_learning.py similarity index 100% rename from probabilistic_learning.py rename to other_shit_idgafabout/probabilistic_learning.py diff --git a/probability.ipynb b/other_shit_idgafabout/probability.ipynb similarity index 100% rename from probability.ipynb rename to other_shit_idgafabout/probability.ipynb diff --git a/probability.py b/other_shit_idgafabout/probability.py similarity index 100% rename from probability.py rename to other_shit_idgafabout/probability.py diff --git a/probability4e.ipynb b/other_shit_idgafabout/probability4e.ipynb similarity index 100% rename from probability4e.ipynb rename to other_shit_idgafabout/probability4e.ipynb diff --git a/probability4e.py b/other_shit_idgafabout/probability4e.py similarity index 100% rename from probability4e.py rename to other_shit_idgafabout/probability4e.py diff --git a/pytest.ini b/other_shit_idgafabout/pytest.ini similarity index 100% rename from pytest.ini rename to other_shit_idgafabout/pytest.ini diff --git a/reinforcement_learning.ipynb b/other_shit_idgafabout/reinforcement_learning.ipynb similarity index 100% rename from reinforcement_learning.ipynb rename to other_shit_idgafabout/reinforcement_learning.ipynb diff --git a/reinforcement_learning.py b/other_shit_idgafabout/reinforcement_learning.py similarity index 100% rename from reinforcement_learning.py rename to other_shit_idgafabout/reinforcement_learning.py diff --git a/reinforcement_learning4e.py b/other_shit_idgafabout/reinforcement_learning4e.py similarity index 100% rename from reinforcement_learning4e.py rename to other_shit_idgafabout/reinforcement_learning4e.py diff --git a/search4e.ipynb b/other_shit_idgafabout/search4e.ipynb similarity index 100% rename from search4e.ipynb rename to other_shit_idgafabout/search4e.ipynb diff --git a/tests/__init__.py b/other_shit_idgafabout/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to other_shit_idgafabout/tests/__init__.py diff --git a/tests/pytest.ini b/other_shit_idgafabout/tests/pytest.ini similarity index 100% rename from tests/pytest.ini rename to other_shit_idgafabout/tests/pytest.ini diff --git a/tests/test_agents.py b/other_shit_idgafabout/tests/test_agents.py similarity index 100% rename from tests/test_agents.py rename to other_shit_idgafabout/tests/test_agents.py diff --git a/tests/test_agents4e.py b/other_shit_idgafabout/tests/test_agents4e.py similarity index 100% rename from tests/test_agents4e.py rename to other_shit_idgafabout/tests/test_agents4e.py diff --git a/tests/test_csp.py b/other_shit_idgafabout/tests/test_csp.py similarity index 100% rename from tests/test_csp.py rename to other_shit_idgafabout/tests/test_csp.py diff --git a/tests/test_deep_learning4e.py b/other_shit_idgafabout/tests/test_deep_learning4e.py similarity index 100% rename from tests/test_deep_learning4e.py rename to other_shit_idgafabout/tests/test_deep_learning4e.py diff --git a/tests/test_games.py b/other_shit_idgafabout/tests/test_games.py similarity index 100% rename from tests/test_games.py rename to other_shit_idgafabout/tests/test_games.py diff --git a/tests/test_games4e.py b/other_shit_idgafabout/tests/test_games4e.py similarity index 100% rename from tests/test_games4e.py rename to other_shit_idgafabout/tests/test_games4e.py diff --git a/tests/test_knowledge.py b/other_shit_idgafabout/tests/test_knowledge.py similarity index 100% rename from tests/test_knowledge.py rename to other_shit_idgafabout/tests/test_knowledge.py diff --git a/tests/test_learning.py b/other_shit_idgafabout/tests/test_learning.py similarity index 100% rename from tests/test_learning.py rename to other_shit_idgafabout/tests/test_learning.py diff --git a/tests/test_learning4e.py b/other_shit_idgafabout/tests/test_learning4e.py similarity index 100% rename from tests/test_learning4e.py rename to other_shit_idgafabout/tests/test_learning4e.py diff --git a/tests/test_logic.py b/other_shit_idgafabout/tests/test_logic.py similarity index 100% rename from tests/test_logic.py rename to other_shit_idgafabout/tests/test_logic.py diff --git a/tests/test_logic4e.py b/other_shit_idgafabout/tests/test_logic4e.py similarity index 100% rename from tests/test_logic4e.py rename to other_shit_idgafabout/tests/test_logic4e.py diff --git a/tests/test_mdp.py b/other_shit_idgafabout/tests/test_mdp.py similarity index 100% rename from tests/test_mdp.py rename to other_shit_idgafabout/tests/test_mdp.py diff --git a/tests/test_mdp4e.py b/other_shit_idgafabout/tests/test_mdp4e.py similarity index 100% rename from tests/test_mdp4e.py rename to other_shit_idgafabout/tests/test_mdp4e.py diff --git a/tests/test_nlp.py b/other_shit_idgafabout/tests/test_nlp.py similarity index 100% rename from tests/test_nlp.py rename to other_shit_idgafabout/tests/test_nlp.py diff --git a/tests/test_nlp4e.py b/other_shit_idgafabout/tests/test_nlp4e.py similarity index 100% rename from tests/test_nlp4e.py rename to other_shit_idgafabout/tests/test_nlp4e.py diff --git a/tests/test_perception4e.py b/other_shit_idgafabout/tests/test_perception4e.py similarity index 100% rename from tests/test_perception4e.py rename to other_shit_idgafabout/tests/test_perception4e.py diff --git a/tests/test_planning.py b/other_shit_idgafabout/tests/test_planning.py similarity index 100% rename from tests/test_planning.py rename to other_shit_idgafabout/tests/test_planning.py diff --git a/tests/test_probabilistic_learning.py b/other_shit_idgafabout/tests/test_probabilistic_learning.py similarity index 100% rename from tests/test_probabilistic_learning.py rename to other_shit_idgafabout/tests/test_probabilistic_learning.py diff --git a/tests/test_probability.py b/other_shit_idgafabout/tests/test_probability.py similarity index 100% rename from tests/test_probability.py rename to other_shit_idgafabout/tests/test_probability.py diff --git a/tests/test_probability4e.py b/other_shit_idgafabout/tests/test_probability4e.py similarity index 100% rename from tests/test_probability4e.py rename to other_shit_idgafabout/tests/test_probability4e.py diff --git a/tests/test_reinforcement_learning.py b/other_shit_idgafabout/tests/test_reinforcement_learning.py similarity index 100% rename from tests/test_reinforcement_learning.py rename to other_shit_idgafabout/tests/test_reinforcement_learning.py diff --git a/tests/test_reinforcement_learning4e.py b/other_shit_idgafabout/tests/test_reinforcement_learning4e.py similarity index 100% rename from tests/test_reinforcement_learning4e.py rename to other_shit_idgafabout/tests/test_reinforcement_learning4e.py diff --git a/tests/test_search.py b/other_shit_idgafabout/tests/test_search.py similarity index 100% rename from tests/test_search.py rename to other_shit_idgafabout/tests/test_search.py diff --git a/tests/test_text.py b/other_shit_idgafabout/tests/test_text.py similarity index 100% rename from tests/test_text.py rename to other_shit_idgafabout/tests/test_text.py diff --git a/tests/test_utils.py b/other_shit_idgafabout/tests/test_utils.py similarity index 100% rename from tests/test_utils.py rename to other_shit_idgafabout/tests/test_utils.py diff --git a/text.ipynb b/other_shit_idgafabout/text.ipynb similarity index 100% rename from text.ipynb rename to other_shit_idgafabout/text.ipynb diff --git a/text.py b/other_shit_idgafabout/text.py similarity index 100% rename from text.py rename to other_shit_idgafabout/text.py diff --git a/utils4e.py b/other_shit_idgafabout/utils4e.py similarity index 100% rename from utils4e.py rename to other_shit_idgafabout/utils4e.py diff --git a/vacuum_world.ipynb b/other_shit_idgafabout/vacuum_world.ipynb similarity index 100% rename from vacuum_world.ipynb rename to other_shit_idgafabout/vacuum_world.ipynb diff --git a/viterbi_algorithm.ipynb b/other_shit_idgafabout/viterbi_algorithm.ipynb similarity index 100% rename from viterbi_algorithm.ipynb rename to other_shit_idgafabout/viterbi_algorithm.ipynb diff --git a/planning.py b/planning.py index 1e4a19209..661cdb4ec 100644 --- a/planning.py +++ b/planning.py @@ -80,8 +80,9 @@ def expand_fluents(self, name=None): return expansions + def expand_actions(self, name=None): - """Generate all possible actions with variable bindings for precondition selection heuristic""" + "Generate all possible actions with variable bindings for precondition selection heuristic" has_domains = all(action.domain for action in self.actions if action.precond) kb = None @@ -221,7 +222,7 @@ def relaxed(self): list(filter(lambda effect: effect.op[:3] != 'Not', self.effect))) def substitute(self, e, args): - """Replaces variables in expression with their respective Propositional symbol""" + "Replaces variables in expression with their respective Propositional symbol" new_args = list(e.args) for num, x in enumerate(e.args): @@ -231,7 +232,7 @@ def substitute(self, e, args): return Expr(e.op, *new_args) def check_precond(self, kb, args): - """Checks if the precondition is satisfied in the current state""" + "Checks if the precondition is satisfied in the current state" if isinstance(kb, list): kb = FolKB(kb) @@ -776,6 +777,19 @@ def __init__(self, kb): def __call__(self, actions, objects): self.build(actions, objects) self.find_mutex() + + def __str__(self): + state_str = ", ".join(str(s) for s in self.current_state) + action_str = ", ".join(str(a) for a in self.current_action_links.keys()) + mutex_str = ", ".join([str(m) for m in self.mutex]) + return ( + f"\n" + f" Current State: {{{state_str}}}\n" + f" Actions: {{{action_str}}}\n" + f" Mutex: {{{mutex_str}}}\n" + ) + + __repr__ = __str__ def separate(self, e): """Separates an iterable of elements into positive and negative parts""" @@ -789,8 +803,9 @@ def separate(self, e): positive.append(clause) return positive, negative + def find_mutex(self): - """Finds mutually exclusive actions""" + "Finds mutually exclusive actions" # Inconsistent effects pos_nsl, neg_nsl = self.separate(self.next_state_links) @@ -894,6 +909,18 @@ def __init__(self, planning_problem): def __call__(self): self.expand_graph() + + def __str__(self): + levels_str = "\n".join( + f"Level {i}:\n{str(level)}" for i, level in enumerate(self.levels) + ) + return ( + f"\n" + f" Objects: {self.objects}\n" + f"{levels_str}\n" + ) + + __repr__ = __str__ def expand_graph(self): """Expands the graph by a level""" @@ -911,7 +938,7 @@ def non_mutex_goals(self, goals, index): return False return True - + class GraphPlan: """ Class for formulation GraphPlan algorithm @@ -923,6 +950,20 @@ def __init__(self, planning_problem): self.graph = Graph(planning_problem) self.no_goods = [] self.solution = [] + + def __str__(self): + sol_str = ( + "No solution found" + if not self.solution + else f"Solution with {len(self.solution)} steps" + ) + return ( + f"\n" + f" Nogoods: {len(self.no_goods)}\n" + f" {sol_str}\n" + ) + + __repr__ = __str__ def check_leveloff(self): """Checks if the graph has levelled off""" @@ -999,6 +1040,7 @@ def execute(self): while True: self.graph.expand_graph() + print(self.graph) if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): solution = self.extract_solution(self.graph.planning_problem.goals, -1) @@ -1013,6 +1055,9 @@ class Linearize: def __init__(self, planning_problem): self.planning_problem = planning_problem + + def __str__(self): + return f"" def filter(self, solution): """Filter out persistence actions from a solution""" @@ -1026,8 +1071,9 @@ def filter(self, solution): new_solution.append(new_section) return new_solution + """ def orderlevel(self, level, planning_problem): - """Return valid linear order of actions for a given level""" + "Return valid linear order of actions for a given level" for permutation in itertools.permutations(level): temp = copy.deepcopy(planning_problem) @@ -1043,9 +1089,37 @@ def orderlevel(self, level, planning_problem): if count == len(permutation): return list(permutation), temp return None + """ + + def orderlevel(self, level, planning_problem): + "Return valid linear order of actions for a given level" + + # Iterate through all permutations of actions in the level + for permutation in itertools.permutations(level): + # Create a deep copy of the planning problem for this permutation + temp = copy.deepcopy(planning_problem) + is_valid_permutation = True + # Attempt to apply each action in the current permutation + for action in permutation: + try: + temp.act(action) + except Exception: + # If an action fails, this entire permutation is invalid. + is_valid_permutation = False + break # Exit the inner loop immediately and try the next permutation. + + # If the inner loop completed without any failures + if is_valid_permutation: + # This is a valid linear ordering for the current level + return list(permutation), temp + + # If no valid permutation was found after checking all possibilities + return None, None + + """ def execute(self): - """Finds total-order solution for a planning graph""" + "Finds total-order solution for a planning graph" graphPlan_solution = GraphPlan(self.planning_problem).execute() filtered_solution = self.filter(graphPlan_solution) @@ -1057,11 +1131,56 @@ def execute(self): ordered_solution.append(element) return ordered_solution + """ + + def execute(self): + """Finds a total-order solution for a planning graph.""" + # This might return multiple solutions, let's call it a list of "raw plans" + raw_plans = GraphPlan(self.planning_problem).execute() + + if not raw_plans: + return None # No plans were found by GraphPlan + + # Iterate through each raw plan returned by GraphPlan + for raw_plan in raw_plans: + # The filter and ordering logic should be applied to each plan one by one. + # This is a good place for a helper function. + ordered_plan = self._attempt_linearization(raw_plan) + if ordered_plan: + return ordered_plan # Return the first successful plan + + return None # No valid linearization was found for any of the plans + + def _attempt_linearization(self, raw_plan): + """Helper function to linearize a single raw plan.""" + # Filter out persistence actions + filtered_plan = self._filter(raw_plan) + ordered_solution = [] + planning_problem = copy.deepcopy(self.planning_problem) + + # Order actions level by level + for level in filtered_plan: + level_solution, planning_problem = self.orderlevel(level, planning_problem) + if level_solution is None: + return None # Failed to order this plan, try the next one + ordered_solution.extend(level_solution) + return ordered_solution + + def _filter(self, raw_plan): + """Filter out persistence actions from a single raw plan.""" + new_solution = [] + for section in raw_plan: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + new_solution.append(new_section) + return new_solution def linearize(solution): """Converts a level-ordered solution into a linear solution""" - + linear_solution = [] for section in solution[0]: for operation in section: diff --git a/planning1.py b/planning1.py new file mode 100644 index 000000000..840fd6abb --- /dev/null +++ b/planning1.py @@ -0,0 +1,2077 @@ +"""Planning (Chapters 10-11)""" + +import copy +import itertools +from collections import deque, defaultdict +from functools import reduce as _reduce + +import numpy as np + +import search +from csp import sat_up, NaryCSP, Constraint, ac_search_solver, is_constraint +from logic import FolKB, conjuncts, unify_mm, associate, SAT_plan, cdcl_satisfiable +from search import Node +from utils import Expr, expr, first + + +class PlanningProblem: + """ + Planning Domain Definition Language (PlanningProblem) used to define a search problem. + It stores states in a knowledge base consisting of first order logic statements. + The conjunction of these logical statements completely defines a state. + """ + + def __init__(self, initial, goals, actions, domain=None): + self.initial = self.convert(initial) if domain is None else self.convert(initial) + self.convert(domain) + self.goals = self.convert(goals) + self.actions = actions + self.domain = domain + + def convert(self, clauses): + """Converts strings into exprs""" + if not isinstance(clauses, Expr): + if len(clauses) > 0: + clauses = expr(clauses) + else: + clauses = [] + try: + clauses = conjuncts(clauses) + except AttributeError: + pass + + new_clauses = [] + for clause in clauses: + if clause.op == '~': + new_clauses.append(expr('Not' + str(clause.args[0]))) + else: + new_clauses.append(clause) + return new_clauses + + def expand_fluents(self, name=None): + + kb = None + if self.domain: + kb = FolKB(self.convert(self.domain)) + for action in self.actions: + if action.precond: + for fests in set(action.precond).union(action.effect).difference(self.convert(action.domain)): + if fests.op[:3] != 'Not': + kb.tell(expr(str(action.domain) + ' ==> ' + str(fests))) + + objects = set(arg for clause in set(self.initial + self.goals) for arg in clause.args) + fluent_list = [] + if name is not None: + for fluent in self.initial + self.goals: + if str(fluent) == name: + fluent_list.append(fluent) + break + else: + fluent_list = list(map(lambda fluent: Expr(fluent[0], *fluent[1]), + {fluent.op: fluent.args for fluent in self.initial + self.goals + + [clause for action in self.actions for clause in action.effect if + clause.op[:3] != 'Not']}.items())) + + expansions = [] + for fluent in fluent_list: + for permutation in itertools.permutations(objects, len(fluent.args)): + new_fluent = Expr(fluent.op, *permutation) + if (self.domain and kb.ask(new_fluent) is not False) or not self.domain: + expansions.append(new_fluent) + + return expansions + + def expand_actions(self, name=None): + """Generate all possible actions with variable bindings for precondition selection heuristic""" + + has_domains = all(action.domain for action in self.actions if action.precond) + kb = None + if has_domains: + kb = FolKB(self.initial) + for action in self.actions: + if action.precond: + kb.tell(expr(str(action.domain) + ' ==> ' + str(action))) + + objects = set(arg for clause in self.initial for arg in clause.args) + expansions = [] + action_list = [] + if name is not None: + for action in self.actions: + if str(action.name) == name: + action_list.append(action) + break + else: + action_list = self.actions + + for action in action_list: + for permutation in itertools.permutations(objects, len(action.args)): + bindings = unify_mm(Expr(action.name, *action.args), Expr(action.name, *permutation)) + if bindings is not None: + new_args = [] + for arg in action.args: + if arg in bindings: + new_args.append(bindings[arg]) + else: + new_args.append(arg) + new_expr = Expr(str(action.name), *new_args) + if (has_domains and kb.ask(new_expr) is not False) or ( + has_domains and not action.precond) or not has_domains: + new_preconds = [] + for precond in action.precond: + new_precond_args = [] + for arg in precond.args: + if arg in bindings: + new_precond_args.append(bindings[arg]) + else: + new_precond_args.append(arg) + new_precond = Expr(str(precond.op), *new_precond_args) + new_preconds.append(new_precond) + new_effects = [] + for effect in action.effect: + new_effect_args = [] + for arg in effect.args: + if arg in bindings: + new_effect_args.append(bindings[arg]) + else: + new_effect_args.append(arg) + new_effect = Expr(str(effect.op), *new_effect_args) + new_effects.append(new_effect) + expansions.append(Action(new_expr, new_preconds, new_effects)) + + return expansions + + def is_strips(self): + """ + Returns True if the problem does not contain negative literals in preconditions and goals + """ + return (all(clause.op[:3] != 'Not' for clause in self.goals) and + all(clause.op[:3] != 'Not' for action in self.actions for clause in action.precond)) + + def goal_test(self): + """Checks if the goals have been reached""" + return all(goal in self.initial for goal in self.goals) + + def act(self, action): + """ + Performs the action given as argument. + Note that action is an Expr like expr('Remove(Glass, Table)') or expr('Eat(Sandwich)') + """ + action_name = action.op + args = action.args + list_action = first(a for a in self.actions if a.name == action_name) + if list_action is None: + raise Exception("Action '{}' not found".format(action_name)) + if not list_action.check_precond(self.initial, args): + raise Exception("Action '{}' pre-conditions not satisfied".format(action)) + self.initial = list_action(self.initial, args).clauses + + +class Action: + """ + Defines an action schema using preconditions and effects. + Use this to describe actions in PlanningProblem. + action is an Expr where variables are given as arguments(args). + Precondition and effect are both lists with positive and negative literals. + Negative preconditions and effects are defined by adding a 'Not' before the name of the clause + Example: + precond = [expr("Human(person)"), expr("Hungry(Person)"), expr("NotEaten(food)")] + effect = [expr("Eaten(food)"), expr("Hungry(person)")] + eat = Action(expr("Eat(person, food)"), precond, effect) + """ + + def __init__(self, action, precond, effect, domain=None): + if isinstance(action, str): + action = expr(action) + self.name = action.op + self.args = action.args + self.precond = self.convert(precond) if domain is None else self.convert(precond) + self.convert(domain) + self.effect = self.convert(effect) + self.domain = domain + + def __call__(self, kb, args): + return self.act(kb, args) + + def __repr__(self): + return '{}'.format(Expr(self.name, *self.args)) + + def convert(self, clauses): + """Converts strings into Exprs""" + if isinstance(clauses, Expr): + clauses = conjuncts(clauses) + for i in range(len(clauses)): + if clauses[i].op == '~': + clauses[i] = expr('Not' + str(clauses[i].args[0])) + + elif isinstance(clauses, str): + clauses = clauses.replace('~', 'Not') + if len(clauses) > 0: + clauses = expr(clauses) + + try: + clauses = conjuncts(clauses) + except AttributeError: + pass + + return clauses + + def relaxed(self): + """ + Removes delete list from the action by removing all negative literals from action's effect + """ + return Action(Expr(self.name, *self.args), self.precond, + list(filter(lambda effect: effect.op[:3] != 'Not', self.effect))) + + def substitute(self, e, args): + """Replaces variables in expression with their respective Propositional symbol""" + + new_args = list(e.args) + for num, x in enumerate(e.args): + for i, _ in enumerate(self.args): + if self.args[i] == x: + new_args[num] = args[i] + return Expr(e.op, *new_args) + + def check_precond(self, kb, args): + """Checks if the precondition is satisfied in the current state""" + + if isinstance(kb, list): + kb = FolKB(kb) + for clause in self.precond: + if self.substitute(clause, args) not in kb.clauses: + return False + return True + + def act(self, kb, args): + """Executes the action on the state's knowledge base""" + + if isinstance(kb, list): + kb = FolKB(kb) + + if not self.check_precond(kb, args): + raise Exception('Action pre-conditions not satisfied') + for clause in self.effect: + kb.tell(self.substitute(clause, args)) + if clause.op[:3] == 'Not': + new_clause = Expr(clause.op[3:], *clause.args) + + if kb.ask(self.substitute(new_clause, args)) is not False: + kb.retract(self.substitute(new_clause, args)) + else: + new_clause = Expr('Not' + clause.op, *clause.args) + + if kb.ask(self.substitute(new_clause, args)) is not False: + kb.retract(self.substitute(new_clause, args)) + + return kb + + +def goal_test(goals, state): + """Generic goal testing helper function""" + + if isinstance(state, list): + kb = FolKB(state) + else: + kb = state + return all(kb.ask(q) is not False for q in goals) + + +def air_cargo(): + """ + [Figure 10.1] AIR-CARGO-PROBLEM + + An air-cargo shipment problem for delivering cargo to different locations, + given the starting location and airplanes. + + Example: + >>> from planning import * + >>> ac = air_cargo() + >>> ac.goal_test() + False + >>> ac.act(expr('Load(C2, P2, JFK)')) + >>> ac.act(expr('Load(C1, P1, SFO)')) + >>> ac.act(expr('Fly(P1, SFO, JFK)')) + >>> ac.act(expr('Fly(P2, JFK, SFO)')) + >>> ac.act(expr('Unload(C2, P2, SFO)')) + >>> ac.goal_test() + False + >>> ac.act(expr('Unload(C1, P1, JFK)')) + >>> ac.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK)', + goals='At(C1, JFK) & At(C2, SFO)', + actions=[Action('Load(c, p, a)', + precond='At(c, a) & At(p, a)', + effect='In(c, p) & ~At(c, a)', + domain='Cargo(c) & Plane(p) & Airport(a)'), + Action('Unload(c, p, a)', + precond='In(c, p) & At(p, a)', + effect='At(c, a) & ~In(c, p)', + domain='Cargo(c) & Plane(p) & Airport(a)'), + Action('Fly(p, f, to)', + precond='At(p, f)', + effect='At(p, to) & ~At(p, f)', + domain='Plane(p) & Airport(f) & Airport(to)')], + domain='Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)') + + +def spare_tire(): + """ + [Figure 10.2] SPARE-TIRE-PROBLEM + + A problem involving changing the flat tire of a car + with a spare tire from the trunk. + + Example: + >>> from planning import * + >>> st = spare_tire() + >>> st.goal_test() + False + >>> st.act(expr('Remove(Spare, Trunk)')) + >>> st.act(expr('Remove(Flat, Axle)')) + >>> st.goal_test() + False + >>> st.act(expr('PutOn(Spare, Axle)')) + >>> st.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(Flat, Axle) & At(Spare, Trunk)', + goals='At(Spare, Axle) & At(Flat, Ground)', + actions=[Action('Remove(obj, loc)', + precond='At(obj, loc)', + effect='At(obj, Ground) & ~At(obj, loc)', + domain='Tire(obj)'), + Action('PutOn(t, Axle)', + precond='At(t, Ground) & ~At(Flat, Axle)', + effect='At(t, Axle) & ~At(t, Ground)', + domain='Tire(t)'), + Action('LeaveOvernight', + precond='', + effect='~At(Spare, Ground) & ~At(Spare, Axle) & ~At(Spare, Trunk) & \ + ~At(Flat, Ground) & ~At(Flat, Axle) & ~At(Flat, Trunk)')], + domain='Tire(Flat) & Tire(Spare)') + + +def three_block_tower(): + """ + [Figure 10.3] THREE-BLOCK-TOWER + + A blocks-world problem of stacking three blocks in a certain configuration, + also known as the Sussman Anomaly. + + Example: + >>> from planning import * + >>> tbt = three_block_tower() + >>> tbt.goal_test() + False + >>> tbt.act(expr('MoveToTable(C, A)')) + >>> tbt.act(expr('Move(B, Table, C)')) + >>> tbt.goal_test() + False + >>> tbt.act(expr('Move(A, Table, B)')) + >>> tbt.goal_test() + True + >>> + """ + return PlanningProblem(initial='On(A, Table) & On(B, Table) & On(C, A) & Clear(B) & Clear(C)', + goals='On(A, B) & On(B, C)', + actions=[Action('Move(b, x, y)', + precond='On(b, x) & Clear(b) & Clear(y)', + effect='On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)', + domain='Block(b) & Block(y)'), + Action('MoveToTable(b, x)', + precond='On(b, x) & Clear(b)', + effect='On(b, Table) & Clear(x) & ~On(b, x)', + domain='Block(b) & Block(x)')], + domain='Block(A) & Block(B) & Block(C)') + + +def simple_blocks_world(): + """ + SIMPLE-BLOCKS-WORLD + + A simplified definition of the Sussman Anomaly problem. + + Example: + >>> from planning import * + >>> sbw = simple_blocks_world() + >>> sbw.goal_test() + False + >>> sbw.act(expr('ToTable(A, B)')) + >>> sbw.act(expr('FromTable(B, A)')) + >>> sbw.goal_test() + False + >>> sbw.act(expr('FromTable(C, B)')) + >>> sbw.goal_test() + True + >>> + """ + + return PlanningProblem(initial='On(A, B) & Clear(A) & OnTable(B) & OnTable(C) & Clear(C)', + goals='On(B, A) & On(C, B)', + actions=[Action('ToTable(x, y)', + precond='On(x, y) & Clear(x)', + effect='~On(x, y) & Clear(y) & OnTable(x)'), + Action('FromTable(y, x)', + precond='OnTable(y) & Clear(y) & Clear(x)', + effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) + + +def have_cake_and_eat_cake_too(): + """ + [Figure 10.7] CAKE-PROBLEM + + A problem where we begin with a cake and want to + reach the state of having a cake and having eaten a cake. + The possible actions include baking a cake and eating a cake. + + Example: + >>> from planning import * + >>> cp = have_cake_and_eat_cake_too() + >>> cp.goal_test() + False + >>> cp.act(expr('Eat(Cake)')) + >>> cp.goal_test() + False + >>> cp.act(expr('Bake(Cake)')) + >>> cp.goal_test() + True + >>> + """ + + return PlanningProblem(initial='Have(Cake)', + goals='Have(Cake) & Eaten(Cake)', + actions=[Action('Eat(Cake)', + precond='Have(Cake)', + effect='Eaten(Cake) & ~Have(Cake)'), + Action('Bake(Cake)', + precond='~Have(Cake)', + effect='Have(Cake)')]) + + +def shopping_problem(): + """ + SHOPPING-PROBLEM + + A problem of acquiring some items given their availability at certain stores. + + Example: + >>> from planning import * + >>> sp = shopping_problem() + >>> sp.goal_test() + False + >>> sp.act(expr('Go(Home, HW)')) + >>> sp.act(expr('Buy(Drill, HW)')) + >>> sp.act(expr('Go(HW, SM)')) + >>> sp.act(expr('Buy(Banana, SM)')) + >>> sp.goal_test() + False + >>> sp.act(expr('Buy(Milk, SM)')) + >>> sp.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)', + goals='Have(Milk) & Have(Banana) & Have(Drill)', + actions=[Action('Buy(x, store)', + precond='At(store) & Sells(store, x)', + effect='Have(x)', + domain='Store(store) & Item(x)'), + Action('Go(x, y)', + precond='At(x)', + effect='At(y) & ~At(x)', + domain='Place(x) & Place(y)')], + domain='Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & ' + 'Item(Milk) & Item(Banana) & Item(Drill)') + + +def socks_and_shoes(): + """ + SOCKS-AND-SHOES-PROBLEM + + A task of wearing socks and shoes on both feet + + Example: + >>> from planning import * + >>> ss = socks_and_shoes() + >>> ss.goal_test() + False + >>> ss.act(expr('RightSock')) + >>> ss.act(expr('RightShoe')) + >>> ss.act(expr('LeftSock')) + >>> ss.goal_test() + False + >>> ss.act(expr('LeftShoe')) + >>> ss.goal_test() + True + >>> + """ + + return PlanningProblem(initial='', + goals='RightShoeOn & LeftShoeOn', + actions=[Action('RightShoe', + precond='RightSockOn', + effect='RightShoeOn'), + Action('RightSock', + precond='', + effect='RightSockOn'), + Action('LeftShoe', + precond='LeftSockOn', + effect='LeftShoeOn'), + Action('LeftSock', + precond='', + effect='LeftSockOn')]) + + +def double_tennis_problem(): + """ + [Figure 11.10] DOUBLE-TENNIS-PROBLEM + + A multiagent planning problem involving two partner tennis players + trying to return an approaching ball and repositioning around in the court. + + Example: + >>> from planning import * + >>> dtp = double_tennis_problem() + >>> goal_test(dtp.goals, dtp.initial) + False + >>> dtp.act(expr('Go(A, RightBaseLine, LeftBaseLine)')) + >>> dtp.act(expr('Hit(A, Ball, RightBaseLine)')) + >>> goal_test(dtp.goals, dtp.initial) + False + >>> dtp.act(expr('Go(A, LeftNet, RightBaseLine)')) + >>> goal_test(dtp.goals, dtp.initial) + True + >>> + """ + + return PlanningProblem( + initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', + goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', + actions=[Action('Hit(actor, Ball, loc)', + precond='Approaching(Ball, loc) & At(actor, loc)', + effect='Returned(Ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + + +class ForwardPlan(search.Problem): + """ + [Section 10.2.1] + Forward state-space search + """ + + def __init__(self, planning_problem): + super().__init__(associate('&', planning_problem.initial), associate('&', planning_problem.goals)) + self.planning_problem = planning_problem + self.expanded_actions = self.planning_problem.expand_actions() + + def actions(self, state): + return [action for action in self.expanded_actions if all(pre in conjuncts(state) for pre in action.precond)] + + def result(self, state, action): + return associate('&', action(conjuncts(state), action.args).clauses) + + def goal_test(self, state): + return all(goal in conjuncts(state) for goal in self.planning_problem.goals) + + def h(self, state): + """ + Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that + by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be + easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic. + """ + relaxed_planning_problem = PlanningProblem(initial=state.state, + goals=self.goal, + actions=[action.relaxed() for action in + self.planning_problem.actions]) + try: + return len(linearize(GraphPlan(relaxed_planning_problem).execute())) + except: + return np.inf + + +class BackwardPlan(search.Problem): + """ + [Section 10.2.2] + Backward relevant-states search + """ + + def __init__(self, planning_problem): + super().__init__(associate('&', planning_problem.goals), associate('&', planning_problem.initial)) + self.planning_problem = planning_problem + self.expanded_actions = self.planning_problem.expand_actions() + + def actions(self, subgoal): + """ + Returns True if the action is relevant to the subgoal, i.e.: + - the action achieves an element of the effects + - the action doesn't delete something that needs to be achieved + - the preconditions are consistent with other subgoals that need to be achieved + """ + + def negate_clause(clause): + return Expr(clause.op.replace('Not', ''), *clause.args) if clause.op[:3] == 'Not' else Expr( + 'Not' + clause.op, *clause.args) + + subgoal = conjuncts(subgoal) + return [action for action in self.expanded_actions if + (any(prop in action.effect for prop in subgoal) and + not any(negate_clause(prop) in subgoal for prop in action.effect) and + not any(negate_clause(prop) in subgoal and negate_clause(prop) not in action.effect + for prop in action.precond))] + + def result(self, subgoal, action): + # g' = (g - effects(a)) + preconds(a) + return associate('&', set(set(conjuncts(subgoal)).difference(action.effect)).union(action.precond)) + + def goal_test(self, subgoal): + return all(goal in conjuncts(self.goal) for goal in conjuncts(subgoal)) + + def h(self, subgoal): + """ + Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that + by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be + easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic. + """ + relaxed_planning_problem = PlanningProblem(initial=self.goal, + goals=subgoal.state, + actions=[action.relaxed() for action in + self.planning_problem.actions]) + try: + return len(linearize(GraphPlan(relaxed_planning_problem).execute())) + except: + return np.inf + + +def CSPlan(planning_problem, solution_length, CSP_solver=ac_search_solver, arc_heuristic=sat_up): + """ + [Section 10.4.3] + Planning as Constraint Satisfaction Problem + """ + + def st(var, stage): + """Returns a string for the var-stage pair that can be used as a variable""" + return str(var) + "_" + str(stage) + + def if_(v1, v2): + """If the second argument is v2, the first argument must be v1""" + + def if_fun(x1, x2): + return x1 == v1 if x2 == v2 else True + + if_fun.__name__ = "if the second argument is " + str(v2) + " then the first argument is " + str(v1) + " " + return if_fun + + def eq_if_not_in_(actset): + """First and third arguments are equal if action is not in actset""" + + def eq_if_not_in(x1, a, x2): + return x1 == x2 if a not in actset else True + + eq_if_not_in.__name__ = "first and third arguments are equal if action is not in " + str(actset) + " " + return eq_if_not_in + + expanded_actions = planning_problem.expand_actions() + fluent_values = planning_problem.expand_fluents() + for horizon in range(solution_length): + act_vars = [st('action', stage) for stage in range(horizon + 1)] + domains = {av: list(map(lambda action: expr(str(action)), expanded_actions)) for av in act_vars} + domains.update({st(var, stage): {True, False} for var in fluent_values for stage in range(horizon + 2)}) + # initial state constraints + constraints = [Constraint((st(var, 0),), is_constraint(val)) + for (var, val) in {expr(str(fluent).replace('Not', '')): + True if fluent.op[:3] != 'Not' else False + for fluent in planning_problem.initial}.items()] + constraints += [Constraint((st(var, 0),), is_constraint(False)) + for var in {expr(str(fluent).replace('Not', '')) + for fluent in fluent_values if fluent not in planning_problem.initial}] + # goal state constraints + constraints += [Constraint((st(var, horizon + 1),), is_constraint(val)) + for (var, val) in {expr(str(fluent).replace('Not', '')): + True if fluent.op[:3] != 'Not' else False + for fluent in planning_problem.goals}.items()] + # precondition constraints + constraints += [Constraint((st(var, stage), st('action', stage)), if_(val, act)) + # st(var, stage) == val if st('action', stage) == act + for act, strps in {expr(str(action)): action for action in expanded_actions}.items() + for var, val in {expr(str(fluent).replace('Not', '')): + True if fluent.op[:3] != 'Not' else False + for fluent in strps.precond}.items() + for stage in range(horizon + 1)] + # effect constraints + constraints += [Constraint((st(var, stage + 1), st('action', stage)), if_(val, act)) + # st(var, stage + 1) == val if st('action', stage) == act + for act, strps in {expr(str(action)): action for action in expanded_actions}.items() + for var, val in {expr(str(fluent).replace('Not', '')): True if fluent.op[:3] != 'Not' else False + for fluent in strps.effect}.items() + for stage in range(horizon + 1)] + # frame constraints + constraints += [Constraint((st(var, stage), st('action', stage), st(var, stage + 1)), + eq_if_not_in_(set(map(lambda action: expr(str(action)), + {act for act in expanded_actions if var in act.effect + or Expr('Not' + var.op, *var.args) in act.effect})))) + for var in fluent_values for stage in range(horizon + 1)] + csp = NaryCSP(domains, constraints) + sol = CSP_solver(csp, arc_heuristic=arc_heuristic) + if sol: + return [sol[a] for a in act_vars] + + +def SATPlan(planning_problem, solution_length, SAT_solver=cdcl_satisfiable): + """ + [Section 10.4.1] + Planning as Boolean satisfiability + """ + + def expand_transitions(state, actions): + state = sorted(conjuncts(state)) + for action in filter(lambda act: act.check_precond(state, act.args), actions): + transition[associate('&', state)].update( + {Expr(action.name, *action.args): + associate('&', sorted(set(filter(lambda clause: clause.op[:3] != 'Not', + action(state, action.args).clauses)))) + if planning_problem.is_strips() + else associate('&', sorted(set(action(state, action.args).clauses)))}) + for state in transition[associate('&', state)].values(): + if state not in transition: + expand_transitions(expr(state), actions) + + transition = defaultdict(dict) + expand_transitions(associate('&', planning_problem.initial), planning_problem.expand_actions()) + + return SAT_plan(associate('&', sorted(planning_problem.initial)), transition, + associate('&', sorted(planning_problem.goals)), solution_length, SAT_solver=SAT_solver) + + +class Level: + """ + Contains the state of the planning problem + and exhaustive list of actions which use the + states as pre-condition. + """ + + def __init__(self, kb): + """Initializes variables to hold state and action details of a level""" + + self.kb = kb + # current state + self.current_state = kb.clauses + # current action to state link + self.current_action_links = {} + # current state to action link + self.current_state_links = {} + # current action to next state link + self.next_action_links = {} + # next state to current action link + self.next_state_links = {} + # mutually exclusive actions + self.mutex = [] + + def __call__(self, actions, objects): + self.build(actions, objects) + self.find_mutex() + + def separate(self, e): + """Separates an iterable of elements into positive and negative parts""" + + positive = [] + negative = [] + for clause in e: + if clause.op[:3] == 'Not': + negative.append(clause) + else: + positive.append(clause) + return positive, negative + + def find_mutex(self): + """Finds mutually exclusive actions""" + + # Inconsistent effects + pos_nsl, neg_nsl = self.separate(self.next_state_links) + + for negeff in neg_nsl: + new_negeff = Expr(negeff.op[3:], *negeff.args) + for poseff in pos_nsl: + if new_negeff == poseff: + for a in self.next_state_links[poseff]: + for b in self.next_state_links[negeff]: + if {a, b} not in self.mutex: + self.mutex.append({a, b}) + + # Interference will be calculated with the last step + pos_csl, neg_csl = self.separate(self.current_state_links) + + # Competing needs + for pos_precond in pos_csl: + for neg_precond in neg_csl: + new_neg_precond = Expr(neg_precond.op[3:], *neg_precond.args) + if new_neg_precond == pos_precond: + for a in self.current_state_links[pos_precond]: + for b in self.current_state_links[neg_precond]: + if {a, b} not in self.mutex: + self.mutex.append({a, b}) + + # Inconsistent support + state_mutex = [] + for pair in self.mutex: + next_state_0 = self.next_action_links[list(pair)[0]] + if len(pair) == 2: + next_state_1 = self.next_action_links[list(pair)[1]] + else: + next_state_1 = self.next_action_links[list(pair)[0]] + if (len(next_state_0) == 1) and (len(next_state_1) == 1): + state_mutex.append({next_state_0[0], next_state_1[0]}) + + self.mutex = self.mutex + state_mutex + + def build(self, actions, objects): + """Populates the lists and dictionaries containing the state action dependencies""" + + for clause in self.current_state: + p_expr = Expr('P' + clause.op, *clause.args) + self.current_action_links[p_expr] = [clause] + self.next_action_links[p_expr] = [clause] + self.current_state_links[clause] = [p_expr] + self.next_state_links[clause] = [p_expr] + + for a in actions: + num_args = len(a.args) + possible_args = tuple(itertools.permutations(objects, num_args)) + + for arg in possible_args: + if a.check_precond(self.kb, arg): + for num, symbol in enumerate(a.args): + if not symbol.op.islower(): + arg = list(arg) + arg[num] = symbol + arg = tuple(arg) + + new_action = a.substitute(Expr(a.name, *a.args), arg) + self.current_action_links[new_action] = [] + + for clause in a.precond: + new_clause = a.substitute(clause, arg) + self.current_action_links[new_action].append(new_clause) + if new_clause in self.current_state_links: + self.current_state_links[new_clause].append(new_action) + else: + self.current_state_links[new_clause] = [new_action] + + self.next_action_links[new_action] = [] + for clause in a.effect: + new_clause = a.substitute(clause, arg) + + self.next_action_links[new_action].append(new_clause) + if new_clause in self.next_state_links: + self.next_state_links[new_clause].append(new_action) + else: + self.next_state_links[new_clause] = [new_action] + + def perform_actions(self): + """Performs the necessary actions and returns a new Level""" + + new_kb = FolKB(list(set(self.next_state_links.keys()))) + return Level(new_kb) + + +class Graph: + """ + Contains levels of state and actions + Used in graph planning algorithm to extract a solution + """ + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + self.kb = FolKB(planning_problem.initial) + self.levels = [Level(self.kb)] + self.objects = set(arg for clause in self.kb.clauses for arg in clause.args) + + def __call__(self): + self.expand_graph() + + def expand_graph(self): + """Expands the graph by a level""" + + last_level = self.levels[-1] + last_level(self.planning_problem.actions, self.objects) + self.levels.append(last_level.perform_actions()) + + def non_mutex_goals(self, goals, index): + """Checks whether the goals are mutually exclusive""" + + goal_perm = itertools.combinations(goals, 2) + for g in goal_perm: + if set(g) in self.levels[index].mutex: + return False + return True + + +class GraphPlan: + """ + Class for formulation GraphPlan algorithm + Constructs a graph of state and action space + Returns solution for the planning problem + """ + + def __init__(self, planning_problem): + self.graph = Graph(planning_problem) + self.no_goods = [] + self.solution = [] + + def check_leveloff(self): + """Checks if the graph has levelled off""" + + check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) + + if check: + return True + + def extract_solution(self, goals, index): + """Extracts the solution""" + + level = self.graph.levels[index] + if not self.graph.non_mutex_goals(goals, index): + self.no_goods.append((level, goals)) + return + + level = self.graph.levels[index - 1] + + # Create all combinations of actions that satisfy the goal + actions = [] + for goal in goals: + actions.append(level.next_state_links[goal]) + + all_actions = list(itertools.product(*actions)) + + # Filter out non-mutex actions + non_mutex_actions = [] + for action_tuple in all_actions: + action_pairs = itertools.combinations(list(set(action_tuple)), 2) + non_mutex_actions.append(list(set(action_tuple))) + for pair in action_pairs: + if set(pair) in level.mutex: + non_mutex_actions.pop(-1) + break + + # Recursion + for action_list in non_mutex_actions: + if [action_list, index] not in self.solution: + self.solution.append([action_list, index]) + + new_goals = [] + for act in set(action_list): + if act in level.current_action_links: + new_goals = new_goals + level.current_action_links[act] + + if abs(index) + 1 == len(self.graph.levels): + return + elif (level, new_goals) in self.no_goods: + return + else: + self.extract_solution(new_goals, index - 1) + + # Level-Order multiple solutions + solution = [] + for item in self.solution: + if item[1] == -1: + solution.append([]) + solution[-1].append(item[0]) + else: + solution[-1].append(item[0]) + + for num, item in enumerate(solution): + item.reverse() + solution[num] = item + + return solution + + def goal_test(self, kb): + return all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) + + def execute(self): + """Executes the GraphPlan algorithm for the given problem""" + + while True: + self.graph.expand_graph() + if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( + self.graph.planning_problem.goals, -1)): + solution = self.extract_solution(self.graph.planning_problem.goals, -1) + if solution: + return solution + + if len(self.graph.levels) >= 2 and self.check_leveloff(): + return None + + +def print_nested_list(nested_list, indent=0): + """Recursively prints a nested list with indentation to show structure.""" + for item in nested_list: + if isinstance(item, list): # If item is a list, recurse deeper + print(" " * indent + "- List:") + print_nested_list(item, indent + 4) + else: + print(" " * indent + f"- {item}") + +pnl = print_nested_list + + +class Linearize: + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + + def filter(self, solution): + """Filter out persistence actions from a solution""" + + new_solution = [] + for section in solution[0]: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + new_solution.append(new_section) + return new_solution + + def orderlevel(self, level, planning_problem): + """Return valid linear order of actions for a given level""" + + for permutation in itertools.permutations(level): + temp = copy.deepcopy(planning_problem) + count = 0 + ## print(f"PERMUTATION: {permutation}") ## Bill's hack + for action in permutation: + try: + # print(f"TRY ACTION: {action}") ## Bill's hack + temp.act(action) + count += 1 + # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack + except: + # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack + count = 0 + temp = copy.deepcopy(planning_problem) + continue ##break + if count == len(permutation): + print(f"SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack + return list(permutation), temp + print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack + return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem + + def execute(self): + """Finds total-order solution for a planning graph""" + + graphPlan_solution = GraphPlan(self.planning_problem).execute() + + ## Bill's stuff from playing around + ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack + ## pnl(graphPlan_solution) + ## for possible_plan in graphPlan_solution: + ## possible_plan = [possible_plan] + ## filtered_possible_plan = self.filter(possible_plan) + ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack + ## flattened_graphplan = self.filter(graphPlan_solution) + ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack + ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack + ## flattened_graphplan = [flattened_graphplan] + ## graphPlan_solution = [flattened_graphplan] ## Bill's hack + ## pnl(flattened_graphplan) + + ## I think I have to go over all permutations of possbile partial graphplans + + for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack + + ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list + ## filtered_solution = self.filter(graphPlan_solution) # original + + filtered_solution = self.filter(possible_plan) # my mod + + ## filtered_solution = self.filter(possible_plan) # mod + ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack + ## pnl(filtered_solution) + ## filtered_solution = possible_plan + + ordered_solution = [] + planning_problem = self.planning_problem + for level in filtered_solution: + + ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack + + ## the below is a key line, the key line + level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied + if not level_solution: # This checks if level_solution is None or an empty list + continue ## Bill's hack!! if empty, continue looking. + + print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack + print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack + ## for action in level_solution: + ## print(f"APPLY ACTION: {action}") ## Bill's hack + ## planning_problem.act(action) # complete guess, apply action to the problem and keep going + + ## I think we need to apply the plan to the planning problem and modify it + for element in level_solution: + ordered_solution.append(element) + + if not ordered_solution: + continue + else: + break + + return ordered_solution + + + + +def linearize(solution): + """Converts a level-ordered solution into a linear solution""" + + linear_solution = [] + for section in solution[0]: + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + linear_solution.append(operation) + + return linear_solution + + +class PartialOrderPlanner: + """ + [Section 10.13] PARTIAL-ORDER-PLANNER + + Partially ordered plans are created by a search through the space of plans + rather than a search through the state space. It views planning as a refinement of partially ordered plans. + A partially ordered plan is defined by a set of actions and a set of constraints of the form A < B, + which denotes that action A has to be performed before action B. + To summarize the working of a partial order planner, + 1. An open precondition is selected (a sub-goal that we want to achieve). + 2. An action that fulfils the open precondition is chosen. + 3. Temporal constraints are updated. + 4. Existing causal links are protected. Protection is a method that checks if the causal links conflict + and if they do, temporal constraints are added to fix the threats. + 5. The set of open preconditions is updated. + 6. Temporal constraints of the selected action and the next action are established. + 7. A new causal link is added between the selected action and the owner of the open precondition. + 8. The set of new causal links is checked for threats and if found, the threat is removed by either promotion or + demotion. If promotion or demotion is unable to solve the problem, the planning problem cannot be solved with + the current sequence of actions or it may not be solvable at all. + 9. These steps are repeated until the set of open preconditions is empty. + """ + + def __init__(self, planning_problem): + self.tries = 1 + self.planning_problem = planning_problem + self.causal_links = [] + self.start = Action('Start', [], self.planning_problem.initial) + self.finish = Action('Finish', self.planning_problem.goals, []) + self.actions = set() + self.actions.add(self.start) + self.actions.add(self.finish) + self.constraints = set() + self.constraints.add((self.start, self.finish)) + self.agenda = set() + for precond in self.finish.precond: + self.agenda.add((precond, self.finish)) + self.expanded_actions = planning_problem.expand_actions() + + def find_open_precondition(self): + """Find open precondition with the least number of possible actions""" + + number_of_ways = dict() + actions_for_precondition = dict() + for element in self.agenda: + open_precondition = element[0] + possible_actions = list(self.actions) + self.expanded_actions + for action in possible_actions: + for effect in action.effect: + if effect == open_precondition: + if open_precondition in number_of_ways: + number_of_ways[open_precondition] += 1 + actions_for_precondition[open_precondition].append(action) + else: + number_of_ways[open_precondition] = 1 + actions_for_precondition[open_precondition] = [action] + + number = sorted(number_of_ways, key=number_of_ways.__getitem__) + + for k, v in number_of_ways.items(): + if v == 0: + return None, None, None + + act1 = None + for element in self.agenda: + if element[0] == number[0]: + act1 = element[1] + break + + if number[0] in self.expanded_actions: + self.expanded_actions.remove(number[0]) + + return number[0], act1, actions_for_precondition[number[0]] + + def find_action_for_precondition(self, oprec): + """Find action for a given precondition""" + + # either + # choose act0 E Actions such that act0 achieves G + for action in self.actions: + for effect in action.effect: + if effect == oprec: + return action, 0 + + # or + # choose act0 E Actions such that act0 achieves G + for action in self.planning_problem.actions: + for effect in action.effect: + if effect.op == oprec.op: + bindings = unify_mm(effect, oprec) + if bindings is None: + break + return action, bindings + + def generate_expr(self, clause, bindings): + """Generate atomic expression from generic expression given variable bindings""" + + new_args = [] + for arg in clause.args: + if arg in bindings: + new_args.append(bindings[arg]) + else: + new_args.append(arg) + + try: + return Expr(str(clause.name), *new_args) + except: + return Expr(str(clause.op), *new_args) + + def generate_action_object(self, action, bindings): + """Generate action object given a generic action and variable bindings""" + + # if bindings is 0, it means the action already exists in self.actions + if bindings == 0: + return action + + # bindings cannot be None + else: + new_expr = self.generate_expr(action, bindings) + new_preconds = [] + for precond in action.precond: + new_precond = self.generate_expr(precond, bindings) + new_preconds.append(new_precond) + new_effects = [] + for effect in action.effect: + new_effect = self.generate_expr(effect, bindings) + new_effects.append(new_effect) + return Action(new_expr, new_preconds, new_effects) + + def cyclic(self, graph): + """Check cyclicity of a directed graph""" + + new_graph = dict() + for element in graph: + if element[0] in new_graph: + new_graph[element[0]].append(element[1]) + else: + new_graph[element[0]] = [element[1]] + + path = set() + + def visit(vertex): + path.add(vertex) + for neighbor in new_graph.get(vertex, ()): + if neighbor in path or visit(neighbor): + return True + path.remove(vertex) + return False + + value = any(visit(v) for v in new_graph) + return value + + def add_const(self, constraint, constraints): + """Add the constraint to constraints if the resulting graph is acyclic""" + + if constraint[0] == self.finish or constraint[1] == self.start: + return constraints + + new_constraints = set(constraints) + new_constraints.add(constraint) + + if self.cyclic(new_constraints): + return constraints + return new_constraints + + def is_a_threat(self, precondition, effect): + """Check if effect is a threat to precondition""" + + if (str(effect.op) == 'Not' + str(precondition.op)) or ('Not' + str(effect.op) == str(precondition.op)): + if effect.args == precondition.args: + return True + return False + + def protect(self, causal_link, action, constraints): + """Check and resolve threats by promotion or demotion""" + + threat = False + for effect in action.effect: + if self.is_a_threat(causal_link[1], effect): + threat = True + break + + if action != causal_link[0] and action != causal_link[2] and threat: + # try promotion + new_constraints = set(constraints) + new_constraints.add((action, causal_link[0])) + if not self.cyclic(new_constraints): + constraints = self.add_const((action, causal_link[0]), constraints) + else: + # try demotion + new_constraints = set(constraints) + new_constraints.add((causal_link[2], action)) + if not self.cyclic(new_constraints): + constraints = self.add_const((causal_link[2], action), constraints) + else: + # both promotion and demotion fail + print('Unable to resolve a threat caused by', action, 'onto', causal_link) + return + return constraints + + def convert(self, constraints): + """Convert constraints into a dict of Action to set orderings""" + + graph = dict() + for constraint in constraints: + if constraint[0] in graph: + graph[constraint[0]].add(constraint[1]) + else: + graph[constraint[0]] = set() + graph[constraint[0]].add(constraint[1]) + return graph + + def toposort(self, graph): + """Generate topological ordering of constraints""" + + if len(graph) == 0: + return + + graph = graph.copy() + + for k, v in graph.items(): + v.discard(k) + + extra_elements_in_dependencies = _reduce(set.union, graph.values()) - set(graph.keys()) + + graph.update({element: set() for element in extra_elements_in_dependencies}) + while True: + ordered = set(element for element, dependency in graph.items() if len(dependency) == 0) + if not ordered: + break + yield ordered + graph = {element: (dependency - ordered) + for element, dependency in graph.items() + if element not in ordered} + if len(graph) != 0: + raise ValueError('The graph is not acyclic and cannot be linearly ordered') + + def display_plan(self): + """Display causal links, constraints and the plan""" + + print('Causal Links') + for causal_link in self.causal_links: + print(causal_link) + + print('\nConstraints') + for constraint in self.constraints: + print(constraint[0], '<', constraint[1]) + + print('\nPartial Order Plan') + print(list(reversed(list(self.toposort(self.convert(self.constraints)))))) + + def execute(self, display=True): + """Execute the algorithm""" + + step = 1 + while len(self.agenda) > 0: + step += 1 + # select from Agenda + try: + G, act1, possible_actions = self.find_open_precondition() + except IndexError: + print('Probably Wrong') + break + + act0 = possible_actions[0] + # remove from Agenda + self.agenda.remove((G, act1)) + + # For actions with variable number of arguments, use least commitment principle + # act0_temp, bindings = self.find_action_for_precondition(G) + # act0 = self.generate_action_object(act0_temp, bindings) + + # Actions = Actions U {act0} + self.actions.add(act0) + + # Constraints = add_const(start < act0, Constraints) + self.constraints = self.add_const((self.start, act0), self.constraints) + + # for each CL E CausalLinks do + # Constraints = protect(CL, act0, Constraints) + for causal_link in self.causal_links: + self.constraints = self.protect(causal_link, act0, self.constraints) + + # Agenda = Agenda U {: P is a precondition of act0} + for precondition in act0.precond: + self.agenda.add((precondition, act0)) + + # Constraints = add_const(act0 < act1, Constraints) + self.constraints = self.add_const((act0, act1), self.constraints) + + # CausalLinks U {} + if (act0, G, act1) not in self.causal_links: + self.causal_links.append((act0, G, act1)) + + # for each A E Actions do + # Constraints = protect(, A, Constraints) + for action in self.actions: + self.constraints = self.protect((act0, G, act1), action, self.constraints) + + if step > 200: + print("Couldn't find a solution") + return None, None + + if display: + self.display_plan() + else: + return self.constraints, self.causal_links + + +def spare_tire_graphPlan(): + """Solves the spare tire problem using GraphPlan""" + return GraphPlan(spare_tire()).execute() + + +def three_block_tower_graphPlan(): + """Solves the Sussman Anomaly problem using GraphPlan""" + return GraphPlan(three_block_tower()).execute() + + +def air_cargo_graphPlan(): + """Solves the air cargo problem using GraphPlan""" + return GraphPlan(air_cargo()).execute() + + +def have_cake_and_eat_cake_too_graphPlan(): + """Solves the cake problem using GraphPlan""" + return [GraphPlan(have_cake_and_eat_cake_too()).execute()[1]] + + +def shopping_graphPlan(): + """Solves the shopping problem using GraphPlan""" + return GraphPlan(shopping_problem()).execute() + + +def socks_and_shoes_graphPlan(): + """Solves the socks and shoes problem using GraphPlan""" + return GraphPlan(socks_and_shoes()).execute() + + +def simple_blocks_world_graphPlan(): + """Solves the simple blocks world problem""" + return GraphPlan(simple_blocks_world()).execute() + + +class HLA(Action): + """ + Define Actions for the real-world (that may be refined further), and satisfy resource + constraints. + """ + unique_group = 1 + + def __init__(self, action, precond=None, effect=None, duration=0, consume=None, use=None): + """ + As opposed to actions, to define HLA, we have added constraints. + duration holds the amount of time required to execute the task + consumes holds a dictionary representing the resources the task consumes + uses holds a dictionary representing the resources the task uses + """ + precond = precond or [None] + effect = effect or [None] + super().__init__(action, precond, effect) + self.duration = duration + self.consumes = consume or {} + self.uses = use or {} + self.completed = False + # self.priority = -1 # must be assigned in relation to other HLAs + # self.job_group = -1 # must be assigned in relation to other HLAs + + def do_action(self, job_order, available_resources, kb, args): + """ + An HLA based version of act - along with knowledge base updation, it handles + resource checks, and ensures the actions are executed in the correct order. + """ + if not self.has_usable_resource(available_resources): + raise Exception('Not enough usable resources to execute {}'.format(self.name)) + if not self.has_consumable_resource(available_resources): + raise Exception('Not enough consumable resources to execute {}'.format(self.name)) + if not self.inorder(job_order): + raise Exception("Can't execute {} - execute prerequisite actions first". + format(self.name)) + kb = super().act(kb, args) # update knowledge base + for resource in self.consumes: # remove consumed resources + available_resources[resource] -= self.consumes[resource] + self.completed = True # set the task status to complete + return kb + + def has_consumable_resource(self, available_resources): + """ + Ensure there are enough consumable resources for this action to execute. + """ + for resource in self.consumes: + if available_resources.get(resource) is None: + return False + if available_resources[resource] < self.consumes[resource]: + return False + return True + + def has_usable_resource(self, available_resources): + """ + Ensure there are enough usable resources for this action to execute. + """ + for resource in self.uses: + if available_resources.get(resource) is None: + return False + if available_resources[resource] < self.uses[resource]: + return False + return True + + def inorder(self, job_order): + """ + Ensure that all the jobs that had to be executed before the current one have been + successfully executed. + """ + for jobs in job_order: + if self in jobs: + for job in jobs: + if job is self: + return True + if not job.completed: + return False + return True + + +class RealWorldPlanningProblem(PlanningProblem): + """ + Define real-world problems by aggregating resources as numerical quantities instead of + named entities. + + This class is identical to PDDL, except that it overloads the act function to handle + resource and ordering conditions imposed by HLA as opposed to Action. + """ + + def __init__(self, initial, goals, actions, jobs=None, resources=None): + super().__init__(initial, goals, actions) + self.jobs = jobs + self.resources = resources or {} + + def act(self, action): + """ + Performs the HLA given as argument. + + Note that this is different from the superclass action - where the parameter was an + Expression. For real world problems, an Expr object isn't enough to capture all the + detail required for executing the action - resources, preconditions, etc need to be + checked for too. + """ + args = action.args + list_action = first(a for a in self.actions if a.name == action.name) + if list_action is None: + raise Exception("Action '{}' not found".format(action.name)) + self.initial = list_action.do_action(self.jobs, self.resources, self.initial, args).clauses + + def refinements(self, library): # refinements may be (multiple) HLA themselves ... + """ + State is a Problem, containing the current state kb library is a + dictionary containing details for every possible refinement. e.g.: + { + 'HLA': [ + 'Go(Home, SFO)', + 'Go(Home, SFO)', + 'Drive(Home, SFOLongTermParking)', + 'Shuttle(SFOLongTermParking, SFO)', + 'Taxi(Home, SFO)' + ], + 'steps': [ + ['Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)'], + ['Taxi(Home, SFO)'], + [], + [], + [] + ], + # empty refinements indicate a primitive action + 'precond': [ + ['At(Home) & Have(Car)'], + ['At(Home)'], + ['At(Home) & Have(Car)'], + ['At(SFOLongTermParking)'], + ['At(Home)'] + ], + 'effect': [ + ['At(SFO) & ~At(Home)'], + ['At(SFO) & ~At(Home)'], + ['At(SFOLongTermParking) & ~At(Home)'], + ['At(SFO) & ~At(SFOLongTermParking)'], + ['At(SFO) & ~At(Home)'] + ]} + """ + indices = [i for i, x in enumerate(library['HLA']) if expr(x).op == self.name] + for i in indices: + actions = [] + for j in range(len(library['steps'][i])): + # find the index of the step [j] of the HLA + index_step = [k for k, x in enumerate(library['HLA']) if x == library['steps'][i][j]][0] + precond = library['precond'][index_step][0] # preconditions of step [j] + effect = library['effect'][index_step][0] # effect of step [j] + actions.append(HLA(library['steps'][i][j], precond, effect)) + yield actions + + def hierarchical_search(self, hierarchy): + """ + [Figure 11.5] + 'Hierarchical Search, a Breadth First Search implementation of Hierarchical + Forward Planning Search' + The problem is a real-world problem defined by the problem class, and the hierarchy is + a dictionary of HLA - refinements (see refinements generator for details) + """ + act = Node(self.initial, None, [self.actions[0]]) + frontier = deque() + frontier.append(act) + while True: + if not frontier: + return None + plan = frontier.popleft() + # finds the first non primitive hla in plan actions + (hla, index) = RealWorldPlanningProblem.find_hla(plan, hierarchy) + prefix = plan.action[:index] + outcome = RealWorldPlanningProblem( + RealWorldPlanningProblem.result(self.initial, prefix), self.goals, self.actions) + suffix = plan.action[index + 1:] + if not hla: # hla is None and plan is primitive + if outcome.goal_test(): + return plan.action + else: + for sequence in RealWorldPlanningProblem.refinements(hla, hierarchy): # find refinements + frontier.append(Node(outcome.initial, plan, prefix + sequence + suffix)) + + def result(state, actions): + """The outcome of applying an action to the current problem""" + for a in actions: + if a.check_precond(state, a.args): + state = a(state, a.args).clauses + return state + + def angelic_search(self, hierarchy, initial_plan): + """ + [Figure 11.8] + A hierarchical planning algorithm that uses angelic semantics to identify and + commit to high-level plans that work while avoiding high-level plans that don’t. + The predicate MAKING-PROGRESS checks to make sure that we aren’t stuck in an infinite regression + of refinements. + At top level, call ANGELIC-SEARCH with [Act] as the initialPlan. + + InitialPlan contains a sequence of HLA's with angelic semantics + + The possible effects of an angelic HLA in initialPlan are: + ~ : effect remove + $+: effect possibly add + $-: effect possibly remove + $$: possibly add or remove + """ + frontier = deque(initial_plan) + while True: + if not frontier: + return None + plan = frontier.popleft() # sequence of HLA/Angelic HLA's + opt_reachable_set = RealWorldPlanningProblem.reach_opt(self.initial, plan) + pes_reachable_set = RealWorldPlanningProblem.reach_pes(self.initial, plan) + if self.intersects_goal(opt_reachable_set): + if RealWorldPlanningProblem.is_primitive(plan, hierarchy): + return [x for x in plan.action] + guaranteed = self.intersects_goal(pes_reachable_set) + if guaranteed and RealWorldPlanningProblem.making_progress(plan, initial_plan): + final_state = guaranteed[0] # any element of guaranteed + return RealWorldPlanningProblem.decompose(hierarchy, final_state, pes_reachable_set) + # there should be at least one HLA/AngelicHLA, otherwise plan would be primitive + hla, index = RealWorldPlanningProblem.find_hla(plan, hierarchy) + prefix = plan.action[:index] + suffix = plan.action[index + 1:] + outcome = RealWorldPlanningProblem( + RealWorldPlanningProblem.result(self.initial, prefix), self.goals, self.actions) + for sequence in RealWorldPlanningProblem.refinements(hla, hierarchy): # find refinements + frontier.append( + AngelicNode(outcome.initial, plan, prefix + sequence + suffix, prefix + sequence + suffix)) + + def intersects_goal(self, reachable_set): + """ + Find the intersection of the reachable states and the goal + """ + return [y for x in list(reachable_set.keys()) + for y in reachable_set[x] + if all(goal in y for goal in self.goals)] + + def is_primitive(plan, library): + """ + checks if the hla is primitive action + """ + for hla in plan.action: + indices = [i for i, x in enumerate(library['HLA']) if expr(x).op == hla.name] + for i in indices: + if library["steps"][i]: + return False + return True + + def reach_opt(init, plan): + """ + Finds the optimistic reachable set of the sequence of actions in plan + """ + reachable_set = {0: [init]} + optimistic_description = plan.action # list of angelic actions with optimistic description + return RealWorldPlanningProblem.find_reachable_set(reachable_set, optimistic_description) + + def reach_pes(init, plan): + """ + Finds the pessimistic reachable set of the sequence of actions in plan + """ + reachable_set = {0: [init]} + pessimistic_description = plan.action_pes # list of angelic actions with pessimistic description + return RealWorldPlanningProblem.find_reachable_set(reachable_set, pessimistic_description) + + def find_reachable_set(reachable_set, action_description): + """ + Finds the reachable states of the action_description when applied in each state of reachable set. + """ + for i in range(len(action_description)): + reachable_set[i + 1] = [] + if type(action_description[i]) is AngelicHLA: + possible_actions = action_description[i].angelic_action() + else: + possible_actions = action_description + for action in possible_actions: + for state in reachable_set[i]: + if action.check_precond(state, action.args): + if action.effect[0]: + new_state = action(state, action.args).clauses + reachable_set[i + 1].append(new_state) + else: + reachable_set[i + 1].append(state) + return reachable_set + + def find_hla(plan, hierarchy): + """ + Finds the the first HLA action in plan.action, which is not primitive + and its corresponding index in plan.action + """ + hla = None + index = len(plan.action) + for i in range(len(plan.action)): # find the first HLA in plan, that is not primitive + if not RealWorldPlanningProblem.is_primitive(Node(plan.state, plan.parent, [plan.action[i]]), hierarchy): + hla = plan.action[i] + index = i + break + return hla, index + + def making_progress(plan, initial_plan): + """ + Prevents from infinite regression of refinements + + (infinite regression of refinements happens when the algorithm finds a plan that + its pessimistic reachable set intersects the goal inside a call to decompose on + the same plan, in the same circumstances) + """ + for i in range(len(initial_plan)): + if plan == initial_plan[i]: + return False + return True + + def decompose(hierarchy, plan, s_f, reachable_set): + solution = [] + i = max(reachable_set.keys()) + while plan.action_pes: + action = plan.action_pes.pop() + if i == 0: + return solution + s_i = RealWorldPlanningProblem.find_previous_state(s_f, reachable_set, i, action) + problem = RealWorldPlanningProblem(s_i, s_f, plan.action) + angelic_call = RealWorldPlanningProblem.angelic_search(problem, hierarchy, + [AngelicNode(s_i, Node(None), [action], [action])]) + if angelic_call: + for x in angelic_call: + solution.insert(0, x) + else: + return None + s_f = s_i + i -= 1 + return solution + + def find_previous_state(s_f, reachable_set, i, action): + """ + Given a final state s_f and an action finds a state s_i in reachable_set + such that when action is applied to state s_i returns s_f. + """ + s_i = reachable_set[i - 1][0] + for state in reachable_set[i - 1]: + if s_f in [x for x in RealWorldPlanningProblem.reach_pes( + state, AngelicNode(state, None, [action], [action]))[1]]: + s_i = state + break + return s_i + + +def job_shop_problem(): + """ + [Figure 11.1] JOB-SHOP-PROBLEM + + A job-shop scheduling problem for assembling two cars, + with resource and ordering constraints. + + Example: + >>> from planning import * + >>> p = job_shop_problem() + >>> p.goal_test() + False + >>> p.act(p.jobs[1][0]) + >>> p.act(p.jobs[1][1]) + >>> p.act(p.jobs[1][2]) + >>> p.act(p.jobs[0][0]) + >>> p.act(p.jobs[0][1]) + >>> p.goal_test() + False + >>> p.act(p.jobs[0][2]) + >>> p.goal_test() + True + >>> + """ + resources = {'EngineHoists': 1, 'WheelStations': 2, 'Inspectors': 2, 'LugNuts': 500} + + add_engine1 = HLA('AddEngine1', precond='~Has(C1, E1)', effect='Has(C1, E1)', duration=30, use={'EngineHoists': 1}) + add_engine2 = HLA('AddEngine2', precond='~Has(C2, E2)', effect='Has(C2, E2)', duration=60, use={'EngineHoists': 1}) + add_wheels1 = HLA('AddWheels1', precond='~Has(C1, W1)', effect='Has(C1, W1)', duration=30, use={'WheelStations': 1}, + consume={'LugNuts': 20}) + add_wheels2 = HLA('AddWheels2', precond='~Has(C2, W2)', effect='Has(C2, W2)', duration=15, use={'WheelStations': 1}, + consume={'LugNuts': 20}) + inspect1 = HLA('Inspect1', precond='~Inspected(C1)', effect='Inspected(C1)', duration=10, use={'Inspectors': 1}) + inspect2 = HLA('Inspect2', precond='~Inspected(C2)', effect='Inspected(C2)', duration=10, use={'Inspectors': 1}) + + actions = [add_engine1, add_engine2, add_wheels1, add_wheels2, inspect1, inspect2] + + job_group1 = [add_engine1, add_wheels1, inspect1] + job_group2 = [add_engine2, add_wheels2, inspect2] + + return RealWorldPlanningProblem( + initial='Car(C1) & Car(C2) & Wheels(W1) & Wheels(W2) & Engine(E2) & Engine(E2) & ~Has(C1, E1) & ~Has(C2, ' + 'E2) & ~Has(C1, W1) & ~Has(C2, W2) & ~Inspected(C1) & ~Inspected(C2)', + goals='Has(C1, W1) & Has(C1, E1) & Inspected(C1) & Has(C2, W2) & Has(C2, E2) & Inspected(C2)', + actions=actions, + jobs=[job_group1, job_group2], + resources=resources) + + +def go_to_sfo(): + """Go to SFO Problem""" + + go_home_sfo1 = HLA('Go(Home, SFO)', precond='At(Home) & Have(Car)', effect='At(SFO) & ~At(Home)') + go_home_sfo2 = HLA('Go(Home, SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') + drive_home_sfoltp = HLA('Drive(Home, SFOLongTermParking)', precond='At(Home) & Have(Car)', + effect='At(SFOLongTermParking) & ~At(Home)') + shuttle_sfoltp_sfo = HLA('Shuttle(SFOLongTermParking, SFO)', precond='At(SFOLongTermParking)', + effect='At(SFO) & ~At(SFOLongTermParking)') + taxi_home_sfo = HLA('Taxi(Home, SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') + + actions = [go_home_sfo1, go_home_sfo2, drive_home_sfoltp, shuttle_sfoltp_sfo, taxi_home_sfo] + + library = { + 'HLA': [ + 'Go(Home, SFO)', + 'Go(Home, SFO)', + 'Drive(Home, SFOLongTermParking)', + 'Shuttle(SFOLongTermParking, SFO)', + 'Taxi(Home, SFO)' + ], + 'steps': [ + ['Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)'], + ['Taxi(Home, SFO)'], + [], + [], + [] + ], + 'precond': [ + ['At(Home) & Have(Car)'], + ['At(Home)'], + ['At(Home) & Have(Car)'], + ['At(SFOLongTermParking)'], + ['At(Home)'] + ], + 'effect': [ + ['At(SFO) & ~At(Home)'], + ['At(SFO) & ~At(Home)'], + ['At(SFOLongTermParking) & ~At(Home)'], + ['At(SFO) & ~At(SFOLongTermParking)'], + ['At(SFO) & ~At(Home)']]} + + return RealWorldPlanningProblem(initial='At(Home)', goals='At(SFO)', actions=actions), library + + +class AngelicHLA(HLA): + """ + Define Actions for the real-world (that may be refined further), under angelic semantics + """ + + def __init__(self, action, precond, effect, duration=0, consume=None, use=None): + super().__init__(action, precond, effect, duration, consume, use) + + def convert(self, clauses): + """ + Converts strings into Exprs + An HLA with angelic semantics can achieve the effects of simple HLA's (add / remove a variable) + and furthermore can have following effects on the variables: + Possibly add variable ( $+ ) + Possibly remove variable ( $- ) + Possibly add or remove a variable ( $$ ) + + Overrides HLA.convert function + """ + lib = {'~': 'Not', + '$+': 'PosYes', + '$-': 'PosNot', + '$$': 'PosYesNot'} + + if isinstance(clauses, Expr): + clauses = conjuncts(clauses) + for i in range(len(clauses)): + for ch in lib.keys(): + if clauses[i].op == ch: + clauses[i] = expr(lib[ch] + str(clauses[i].args[0])) + + elif isinstance(clauses, str): + for ch in lib.keys(): + clauses = clauses.replace(ch, lib[ch]) + if len(clauses) > 0: + clauses = expr(clauses) + + try: + clauses = conjuncts(clauses) + except AttributeError: + pass + + return clauses + + def angelic_action(self): + """ + Converts a high level action (HLA) with angelic semantics into all of its corresponding high level actions (HLA). + An HLA with angelic semantics can achieve the effects of simple HLA's (add / remove a variable) + and furthermore can have following effects for each variable: + + Possibly add variable ( $+: 'PosYes' ) --> corresponds to two HLAs: + HLA_1: add variable + HLA_2: leave variable unchanged + + Possibly remove variable ( $-: 'PosNot' ) --> corresponds to two HLAs: + HLA_1: remove variable + HLA_2: leave variable unchanged + + Possibly add / remove a variable ( $$: 'PosYesNot' ) --> corresponds to three HLAs: + HLA_1: add variable + HLA_2: remove variable + HLA_3: leave variable unchanged + + + example: the angelic action with effects possibly add A and possibly add or remove B corresponds to the + following 6 effects of HLAs: + + + '$+A & $$B': HLA_1: 'A & B' (add A and add B) + HLA_2: 'A & ~B' (add A and remove B) + HLA_3: 'A' (add A) + HLA_4: 'B' (add B) + HLA_5: '~B' (remove B) + HLA_6: ' ' (no effect) + + """ + + effects = [[]] + for clause in self.effect: + (n, w) = AngelicHLA.compute_parameters(clause) + effects = effects * n # create n copies of effects + it = range(1) + if len(effects) != 0: + # split effects into n sublists (separate n copies created in compute_parameters) + it = range(len(effects) // n) + for i in it: + if effects[i]: + if clause.args: + effects[i] = expr(str(effects[i]) + '&' + str( + Expr(clause.op[w:], clause.args[0]))) # make changes in the ith part of effects + if n == 3: + effects[i + len(effects) // 3] = expr( + str(effects[i + len(effects) // 3]) + '&' + str(Expr(clause.op[6:], clause.args[0]))) + else: + effects[i] = expr( + str(effects[i]) + '&' + str(expr(clause.op[w:]))) # make changes in the ith part of effects + if n == 3: + effects[i + len(effects) // 3] = expr( + str(effects[i + len(effects) // 3]) + '&' + str(expr(clause.op[6:]))) + + else: + if clause.args: + effects[i] = Expr(clause.op[w:], clause.args[0]) # make changes in the ith part of effects + if n == 3: + effects[i + len(effects) // 3] = Expr(clause.op[6:], clause.args[0]) + + else: + effects[i] = expr(clause.op[w:]) # make changes in the ith part of effects + if n == 3: + effects[i + len(effects) // 3] = expr(clause.op[6:]) + + return [HLA(Expr(self.name, self.args), self.precond, effects[i]) for i in range(len(effects))] + + def compute_parameters(clause): + """ + computes n,w + + n = number of HLA effects that the angelic HLA corresponds to + w = length of representation of angelic HLA effect + + n = 1, if effect is add + n = 1, if effect is remove + n = 2, if effect is possibly add + n = 2, if effect is possibly remove + n = 3, if effect is possibly add or remove + + """ + if clause.op[:9] == 'PosYesNot': + # possibly add/remove variable: three possible effects for the variable + n = 3 + w = 9 + elif clause.op[:6] == 'PosYes': # possibly add variable: two possible effects for the variable + n = 2 + w = 6 + elif clause.op[:6] == 'PosNot': # possibly remove variable: two possible effects for the variable + n = 2 + w = 3 # We want to keep 'Not' from 'PosNot' when adding action + else: # variable or ~variable + n = 1 + w = 0 + return n, w + + +class AngelicNode(Node): + """ + Extends the class Node. + self.action: contains the optimistic description of an angelic HLA + self.action_pes: contains the pessimistic description of an angelic HLA + """ + + def __init__(self, state, parent=None, action_opt=None, action_pes=None, path_cost=0): + super().__init__(state, parent, action_opt, path_cost) + self.action_pes = action_pes diff --git a/submission-2a.py b/submission-2a.py new file mode 100644 index 000000000..322b8cdd0 --- /dev/null +++ b/submission-2a.py @@ -0,0 +1,332 @@ +import collections, sys, os +from logic import * +from planning import * + +############################################################ +# Problem 1: propositional logic +# Convert each of the following natural language sentences into a propositional +# logic formula. See rainWet() in examples.py for a relevant example. + +# Sentence: "If it's summer and we're in California, then it doesn't rain." +def formula1a(): + # Predicates to use: + Summer = Atom('Summer') # whether it's summer + California = Atom('California') # whether we're in California + Rain = Atom('Rain') # whether it's raining + # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) + return Implies(And(Summer, California),Not(Rain)) + # END_YOUR_CODE + +# Sentence: "It's wet if and only if it is raining or the sprinklers are on." +def formula1b(): + # Predicates to use: + Rain = Atom('Rain') # whether it is raining + Wet = Atom('Wet') # whether it it wet + Sprinklers = Atom('Sprinklers') # whether the sprinklers are on + # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) + return And(Implies(Wet,Or(Rain, Sprinklers)), Implies(Or(Rain, Sprinklers),Wet)) + # END_YOUR_CODE + +# Sentence: "Either it's day or night (but not both)." +def formula1c(): + # Predicates to use: + Day = Atom('Day') # whether it's day + Night = Atom('Night') # whether it's night + # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) + return Or(And(Day, Not(Night)), And(Not(Day),Night)) + # END_YOUR_CODE + +############################################################ +# Problem 2: first-order logic + +# Sentence: "Every person has a mother." +def formula2a(): + # Predicates to use: + def Person(x): return Atom('Person', x) # whether x is a person + def Mother(x, y): return Atom('Mother', x, y) # whether x's mother is y + + # Note: You do NOT have to enforce that the mother is a "person" + # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) + return Forall('$x', Implies(Person('$x'), Exists('$y', Mother('$x', '$y')))) + # END_YOUR_CODE + +# Sentence: "At least one person has no children." +def formula2b(): + # Predicates to use: + def Person(x): return Atom('Person', x) # whether x is a person + def Child(x, y): return Atom('Child', x, y) # whether x has a child y + + # Note: You do NOT have to enforce that the child is a "person" + # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) + return Not(Forall('$x', Implies(Person('$x'), Exists('$y', Child('$x', '$y'))))) + # END_YOUR_CODE + +# Return a formula which defines Daughter in terms of Female and Child. +# See parentChild() in examples.py for a relevant example. +def formula2c(): + # Predicates to use: + def Female(x): return Atom('Female', x) # whether x is female + def Child(x, y): return Atom('Child', x, y) # whether x has a child y + def Daughter(x, y): return Atom('Daughter', x, y) # whether x has a daughter y + # BEGIN_YOUR_CODE (our solution is 4 lines of code, but don't worry if you deviate from this) + return Forall('$x', Forall('$y', Equiv(And(Female('$x'), Child('$y', '$x')), Daughter('$y', '$x')))) + # END_YOUR_CODE + +# Return a formula which defines Grandmother in terms of Female and Parent. +# Note: It is ok for a person to be her own parent +def formula2d(): + # Predicates to use: + def Female(x): return Atom('Female', x) # whether x is female + def Parent(x, y): return Atom('Parent', x, y) # whether x has a parent y + def Grandmother(x, y): return Atom('Grandmother', x, y) # whether x has a grandmother y + # BEGIN_YOUR_CODE (our solution is 5 lines of code, but don't worry if you deviate from this) + + return Forall('$gen1', Forall('$gen3', Equiv(Exists( '$gen2',And(And(Female('$gen1'), Parent('$gen2', '$gen1')), Parent('$gen3', '$gen2'))), Grandmother('$gen3', '$gen1')))) + # END_YOUR_CODE + +############################################################ +# Problem 3: Liar puzzle + +# Facts: +# 0. John: "It wasn't me!" +# 1. Susan: "It was Nicole!" +# 2. Mark: "No, it was Susan!" +# 3. Nicole: "Susan's a liar." +# 4. Exactly one person is telling the truth. +# 5. Exactly one person crashed the server. +# Query: Who did it? +# This function returns a list of 6 formulas corresponding to each of the +# above facts. +# Hint: You might want to use the Equals predicate, defined in logic.py. This +# predicate is used to assert that two objects are the same. +# In particular, Equals(x,x) = True and Equals(x,y) = False iff x is not equal to y. +def liar(): + def TellTruth(x): return Atom('TellTruth', x) + def CrashedServer(x): return Atom('CrashedServer', x) + john = Constant('john') + susan = Constant('susan') + nicole = Constant('nicole') + mark = Constant('mark') + formulas = [] + # We provide the formula for fact 0 here. + formulas.append(Equiv(TellTruth(john), Not(CrashedServer(john)))) + + # You should add 5 formulas, one for each of facts 1-5. + # BEGIN_YOUR_CODE (our solution is 11 lines of code, but don't worry if you deviate from this) + formulas.append(Equiv(TellTruth(susan), CrashedServer(nicole))) + formulas.append(Equiv(TellTruth(mark), CrashedServer(susan))) + formulas.append(Equiv(TellTruth(nicole), Not(TellTruth(susan)))) + formulas.append(Or(And(TellTruth(john), And(Not(TellTruth(susan)), And(Not(TellTruth(nicole)), Not(TellTruth(mark))))), + Or(And(Not(TellTruth(john)), And(TellTruth(susan), And(Not(TellTruth(nicole)), Not(TellTruth(mark))))), + Or(And(Not(TellTruth(john)), And(Not(TellTruth(susan)), And(TellTruth(nicole), Not(TellTruth(mark))))), + And(Not(TellTruth(john)), And(Not(TellTruth(susan)), And(Not(TellTruth(nicole)), TellTruth(mark)))))))) + formulas.append( + Or(And(CrashedServer(john), And(Not(CrashedServer(susan)), And(Not(CrashedServer(nicole)), Not(CrashedServer(mark))))), + Or(And(Not(CrashedServer(john)), And(CrashedServer(susan), And(Not(CrashedServer(nicole)), Not(CrashedServer(mark))))), + Or(And(Not(CrashedServer(john)), And(Not(CrashedServer(susan)), And(CrashedServer(nicole), Not(CrashedServer(mark))))), + And(Not(CrashedServer(john)), And(Not(CrashedServer(susan)), And(Not(CrashedServer(nicole)), CrashedServer(mark)))))))) + # END_YOUR_CODE + query = CrashedServer('$x') + return (formulas, query) + + +############################################################ +# Problem 4: Planning + +# Blocks world modification +def blocksWorldModPlan(): + # BEGIN_YOUR_CODE (make modifications to the initial and goal states) + initial_state = 'On(A, B) & Clear(A) & OnTable(B) & OnTable(D) & On(C,D) & Clear(C)' + goal_state = 'On(B, A) & On(C, B) & On(D,C)' + # END_YOUR_CODE + + planning_problem = \ + PlanningProblem(initial=initial_state, + goals=goal_state, + actions=[Action('ToTable(x, y)', + precond='On(x, y) & Clear(x)', + effect='~On(x, y) & Clear(y) & OnTable(x)'), + Action('FromTable(y, x)', + precond='OnTable(y) & Clear(y) & Clear(x)', + effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) + print(linearize(GraphPlan(planning_problem).execute())) + return linearize(GraphPlan(planning_problem).execute()) + + # BEGIN_YOUR_CODE (use the previous problem as a guide and uncomment the starter code below if you want!) + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = 'In(C1, D3) & In(C2, D3) & In(C3, D3)' + # doesn't work: [PutDown(R1, C2, D3), PutDown(R1, C3, D3)] + + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = logisticsPlan('In(C1,D2)') + # works: [Move(R1, D1, D2), PutDown(R1, C1, D2)] + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = logisticsPlan('In(C1, D1) & In(R1, D2)') + # works: [Move(R1, D1, D2), PutDown(R1, C1, D1)] but backwards + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') + # works: [Move(R1, D1, D2), PutDown(R1, C1, D1), PickUp(R1, C3, D2)] but wrong order + + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = 'In(C1, D2) & In(C3, D3)' + # doesn't work: [Move(R1, D1, D2), Move(R1, D1, D3), PutDown(R1, C1, D2)] + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = 'In(C1, D1) & In(C3, R1)' + # works, subset of above, but wrong order: [Move(R1, D1, D2), PutDown(R1, C1, D1), PickUp(R1, C3, D2)] + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = 'In(C1, D1) & In(C3, R1) & In(R1, D3)' + # seems to work, wrong order: [Move(R1, D1, D2), PutDown(R1, C1, D1), Move(R1, D1, D3), PickUp(R1, C3, D2)] + + + # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + # goal_state = 'In(C1, D1) & In(C2, D3)' + # kaboom + + # goal_state = 'In(C1, D3) & In(C2, D3) & In(C3, D3)' + +def logisticsPlan(the_goal_state): # + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + goal_state = the_goal_state ## 'In(C1, D1) & In(C2, D3)' + + planning_problem = \ + PlanningProblem(initial = initial_state, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r,d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') + # END_YOUR_CODE + + return Linearize(planning_problem).execute() + +return GraphPlan(planning_problem).execute() + + + +## initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + +logisticsPlan('In(C1, D1)') + +logisticsPlan('In(C1,D2)') + +logisticsPlan('In(C1, D1) & In(R1, D2)') +logisticsPlan('In(R1, D2) & In(C1, D1)') + +logisticsPlan('In(C1, D1) & In(C3, R1)') +logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') + +logisticsPlan('In(C1, D1) & In(R1, D3) & In(C3, R1)') +logisticsPlan('In(C1, D1) & In(C3, D3)') + +logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') + +logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') + +logisticsPlan('In(C1, D1) & In(C2, D3)') + + +logisticsPlan('In(C3, D1)') + +logisticsPlan('In(C2, D3)') + +logisticsPlan('In(C3, D3)') + + +#no plans for these below +logisticsPlan('In(C2, D3) & In(C3, D3)') + +logisticsPlan('In(C3, D3) & In(C2, D3)') + +logisticsPlan('In(C1, D2) & In(C3, D3)') + +logisticsPlan('In(C1, D3) & In(C2, D3) & In(C3, D3)') ## homework?? + +logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D1)') + + +#kaboom... didn't stop? +logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)') + + + + + +def logisticsPlan(the_goal_state): + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + goal_state = the_goal_state ## 'In(C1, D1) & In(C2, D3)' + planning_problem = \ + PlanningProblem(initial = initial_state, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r, d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Connected(d_start, d_end) & Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1) & Connected(D1,D2) & Connected(D2,D3)') + # END_YOUR_CODE + + return linearize(GraphPlan(planning_problem).execute()) + +logisticsPlan('In(C1, D1) & In(C2, D3)') + + + #return GraphPlan(planning_problem).execute() + +# the_plan = " " + # new_line_symbol = " " + # linear_plan = " " + # the_pop_plan = " " + # the_plan = GraphPlan(planning_problem).execute() + # new_line_symbol = "| |" + # linear_plan = linearize(the_plan) + # the_pop_plan = PartialOrderPlanner(planning_problem).execute() + # plan_output = f"{the_plan}{new_line_symbol}{linear_plan}{new_line_symbol}{the_pop_plan}" + # return plan_output + +## |[PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), Move(R1, D1, D3), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D3), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PutDown(R1, C2, D3)]' + +""" **IMPORTANT** Reflection (4 pts) + For this problem I have three different defined actions- pick up, put down, and move. Pick up changes the location of a container + from in a room to inside a robot, making sure to update the appropriate states so it is no longer inside the room and is inside the + robot. I also use a variable that states whether or not the robot is already holding something as the robot can only carry one thing + at a time. This variable is also used in the action PutDown since it must check what the robot is holding and changes the location of + the container from inside the robot to inside the room. Finally in moving the robot, it changes the location of the robot from it's + starting position to the ending position. Any time a location changes, the previous location predicate is negated to ensure that + an object is only in one area at a time. I also included domains specifying whether the variables are containers, places, or a robot + so that the algorithm doesn't try something like put a container in a container and move that instead of a robot. + The output for this algorithm is incorrect however, I believe this is because there appears to be an issue in updating the states as + it doesn't always seem to correctly check the preconditions for each action. It also may be due to issues in removing mutually exclusive + actions, or in removing repeated actions when the environment is in different states, in the planning algorithm due to the need to + repeatedly enter the same room. The true action that should be recorded are + + Move[R1, D1, D3], PutDown[R1, C1, D3], Move[R1, D3, D1], PickUp[R1, C2, D1], Move[R1, D1, D3], PutDown[R1, C2, D3], Move[R1, D3, D2], + PickUp[R1, C3, D2], Move[R1, D2, D3], PutDown[R1, C3, D3] + + or + + Move[R1, D1, D3], PutDown[R1, C1, D3], Move[R1, D3, D2], PickUp[R1, C3, D2], Move[R1, D2, D3], PutDown[R1, C3, D3], Move[R1, D3, D1], + PickUp[R1, C2, D1], Move[R1, D1, D3], PutDown[R1, C2, D3] +""" diff --git a/submission_1.py b/submission_1.py new file mode 100644 index 000000000..b2e2b54fb --- /dev/null +++ b/submission_1.py @@ -0,0 +1,128 @@ +import sys +#sys.path.append('/opt/homebrew/lib/python3.9/site-packages') + +import collections, os +from planning import * +from logic import * + +# Problem 4: Planning + +""" **IMPORTANT** Reflection (4 pts) +Please *breifly* report your findings and reflect on what they mean: +As I worked on 4b, I found that it was interesting that I needed to specify that certain tiles were adjacent when I constructed my response. +Then, I realized that when the planning problem is generalizing, it needs to be able to handle all different types of locations and plans. +Therefore, telling the algorithm whether two spaces are adjacent or not becomes relevant. +I think my output is incorrect because when I printed the output, it was a list of two actions: +[PutDown(R1, C3, D3), PutDown(R1, C2, D3)]. I believe this output is incorrect because these two actions can't both +be performed back to back when the robot isn't holding a package. +Planning algorithms are very useful for generalizing these issues and having the machine solve logic problems like these ones using planning. +I liked how easy it was to write and run this planning algorithm, especially compared to the searching in the last project. +Abstracting this algorithm, machines can solve lots of these type of problems very easily. +""" + +# Blocks world modification +def blocksWorldModPlan(): + # BEGIN_YOUR_CODE (make modifications to the initial and goal states) + initial_state = 'On(A, B) & Clear(A) & OnTable(B) & On(C,D) & Clear(C) & OnTable(D)' + goal_state = 'On(B, A) & On(C, B) & On(D, C)' + # END_YOUR_CODE + + planning_problem = \ + PlanningProblem(initial=initial_state, + goals=goal_state, + actions=[Action('ToTable(x, y)', + precond='On(x, y) & Clear(x)', + effect='~On(x, y) & Clear(y) & OnTable(x)'), + Action('FromTable(y, x)', + precond='OnTable(y) & Clear(y) & Clear(x)', + effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) + + return linearize(GraphPlan(planning_problem).execute()) + +""" +def logisticsPlan(): + # BEGIN_YOUR_CODE (use the previous problem as a guide and uncomment the starter code below if you want!) + initial_state = 'RobotIn(R1,D1) & RobotCarrying(R1,C1) & ContainerAt(C2,D1) & ContainerAt(C3,D1) & Adjacent(D1,D2) & Adjacent(D1,D3) & Adjacent(D2,D3) & Adjacent(D2,D1) & Adjacent(D3,D1) & Adjacent(D3,D2)' + goal_state = 'ContainerAt(C1,D3) & ContainerAt(C2,D3) & ContainerAt(C3,D3)' + planning_problem = \ + PlanningProblem(initial=initial_state, + goals=goal_state, + actions=[Action('PickUp(robot,container,location)', + precond='RobotNotCarrying(robot) & RobotIn(robot,location) & ContainerAt(container,location)', + effect='~ContainerAt(container,location) & ~RobotNotCarrying(robot) & RobotCarrying(robot,container)'), + Action('PutDown(robot,container,location)', + precond='RobotIn(robot,location) & RobotCarrying(robot,container)', + effect='~RobotCarrying(robot,container) & RobotNotCarrying(robot) & ContainerAt(container,location)'), + Action('RobotMove(robot,location1,location2)', + precond='RobotIn(robot,location1) & Adjacent(location1,location2)', + effect='~RobotIn(robot,location1) & RobotIn(robot,location2)')]) + # END_YOUR_CODE + + return linearize(GraphPlan(planning_problem).execute()) +""" + +def logisticsPlanCustom(initial_state=None, goal_state=None): + if initial_state == None: + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + if goal_state == None: + raise ValueError("Goal must be defined") + + planning_problem = \ + PlanningProblem(initial = initial_state, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r,d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') + # END_YOUR_CODE + + return Linearize(planning_problem).execute() + +if __name__ == "__main__": + + """ + Call the above functions here with initial/goal states for testing your code. + """ + + #initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + #goal_state = 'In(C1, D2)' + #print(logisticsPlanCustom(initial_state, goal_state)) + + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + goal_state = "In(C1, D1) & In(C3, R1) & In(R1, D3)" + print(logisticsPlanCustom(initial_state, goal_state)) + +""" +Standard logistics environment +Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1) + +Start: +In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) + +Goal: +In(C1, D1) & In(C3, R1) & In(R1, D3) + +Start: + - C1 is in R1 + - C2 is in D1 + - C3 is in D2 + - R1 is in D1 + - R1 is currnetly holding + +How to get to: + - C1 in D1 (just put it down) + - C3 in R1 (robot must move to D2, Pick up C3) + - R1 in D3 (robot must move to D3) + +So a valid solution is: +["PutDown(R1, C1, D1)", "Move(R1, D1, D2)", "PickUp(R1, C3, D2)", "Move(R1, D2, D3)"] +""" \ No newline at end of file diff --git a/submission_1_test.py b/submission_1_test.py new file mode 100644 index 000000000..a56622cd6 --- /dev/null +++ b/submission_1_test.py @@ -0,0 +1,98 @@ +import sys, os +import collections +from planning import * +from logic import * + +import pytest +import submission_1 as sub + + +def test_blocksworld_manual(): + sbw = simple_blocks_world() + assert sbw.goal_test() == False + sbw.act(expr('ToTable(A, B)')) + sbw.act(expr('FromTable(B, A)')) + assert sbw.goal_test() == False + sbw.act(expr('FromTable(C, B)')) + assert sbw.goal_test() == True + + +def test_air_cargo(): + P = air_cargo() + assert isinstance(Linearize(P).execute(), list) + +def test_spare_tire(): + P = spare_tire() + assert isinstance(Linearize(P).execute(), list) + +def test_three_block_tower(): + P = three_block_tower() + assert isinstance(Linearize(P).execute(), list) + +def test_simple_blocks_world(): + P = simple_blocks_world() + assert isinstance(Linearize(P).execute(), list) + +def test_shopping_problem(): + P = shopping_problem() + assert isinstance(Linearize(P).execute(), list) + +def test_socks_and_shoes(): + P = socks_and_shoes() + assert isinstance(Linearize(P).execute(), list) + +def test_double_tennis_problem(): + P = double_tennis_problem() + assert isinstance(Linearize(P).execute(), list) + + +@pytest.mark.parametrize("goal_state", [ + "In(C1, D1)", + "In(C1, D2)", + "In(C1, D1) & In(R1, D2)", + "In(R1, D2) & In(C1, D1)", + "In(C1, D1) & In(C3, R1)", + "In(C1, D1) & In(C3, R1) & In(R1, D3)", + "In(C1, D1) & In(R1, D3) & In(C3, R1)", + "In(C1, D1) & In(C3, D3)", + "In(C1, D1) & In(R1, D2) & In(C3, R1)", + "In(C1, D1) & In(C3, R1) & In(R1, D3)", + "In(C1, D1) & In(C2, D3)", + "In(C3, D1)", + "In(C2, D3)", + "In(C3, D3)", +]) +def test_logistics_plan_valid(goal_state): + """These should yield a valid (non-crashing) plan, even if empty.""" + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + result = sub.logisticsPlanCustom(init, goal_state) + assert result is None or isinstance(result, list) + + +@pytest.mark.parametrize("goal_state", [ + "In(C2, D3) & In(C3, D3)", + "In(C3, D3) & In(C2, D3)", + "In(C1, D2) & In(C3, D3)", + "In(C1, D3) & In(C2, D3) & In(C3, D3)", + "In(C1, D2) & In(C3, D3) & In(C2, D1)", +]) +def test_logistics_plan_no_plan(goal_state): + """These are known to have no valid plan.""" + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + result = sub.logisticsPlanCustom(init, goal_state) + # Depending on your GraphPlan, no-plan might return [] or None + assert result in ([], None) + + +@pytest.mark.parametrize("goal_state", [ + "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)", +]) +def test_logistics_plan_kaboom(goal_state): + """This case is known to cause planner explosion. Catch and mark as expected failure.""" + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + try: + result = sub.logisticsPlanCustom(init, goal_state) + # If it actually returns, that's fine too + assert result is None or isinstance(result, list) + except Exception: + pytest.xfail("Known kaboom case – planner explosion or unsolvable problem") \ No newline at end of file From f023860ef2f49302fd9370545648351d8175e199 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 27 Sep 2025 12:09:58 -0400 Subject: [PATCH 02/19] Update, identified location of bug that exists within linearize, but yet to pinpoint it. --- .../.coveragerc => .coveragerc | 0 other_shit_idgafabout/.flake8 => .flake8 | 0 .../CONTRIBUTING.md => CONTRIBUTING.md | 0 other_shit_idgafabout/LICENSE => LICENSE | 0 .../SUBMODULE.md => SUBMODULE.md | 0 .../agents.ipynb => agents.ipynb | 0 .../agents4e.py => agents4e.py | 0 .../aima_8puzzle.py => aima_8puzzle.py | 0 .../aima_my_tsp.py => aima_my_tsp.py | 0 ....ipynb => arc_consistency_heuristics.ipynb | 0 other_shit_idgafabout/csp.ipynb => csp.ipynb | 0 .../deep_learning4e.py => deep_learning4e.py | 0 .../games.ipynb => games.ipynb | 0 other_shit_idgafabout/games.py => games.py | 0 .../games4e.ipynb => games4e.ipynb | 0 .../games4e.py => games4e.py | 0 ...ms.ipynb => improving_sat_algorithms.ipynb | 0 .../index.ipynb => index.ipynb | 0 .../intro.ipynb => intro.ipynb | 0 .../ipyviews.py => ipyviews.py | 0 {other_shit_idgafabout/js => js}/canvas.js | 0 .../js => js}/continuousworld.js | 0 {other_shit_idgafabout/js => js}/gridworld.js | 0 .../knowledge.py => knowledge.py | 0 ...owledge_FOIL.ipynb => knowledge_FOIL.ipynb | 0 ...best.ipynb => knowledge_current_best.ipynb | 0 ...ace.ipynb => knowledge_version_space.ipynb | 0 .../learning.ipynb => learning.ipynb | 0 .../learning.py => learning.py | 0 .../learning4e.py => learning4e.py | 0 ...learning_apps.ipynb => learning_apps.ipynb | 0 ...cision4e.py => making_simple_decision4e.py | 0 other_shit_idgafabout/mdp.ipynb => mdp.ipynb | 0 other_shit_idgafabout/mdp.py => mdp.py | 0 other_shit_idgafabout/mdp4e.py => mdp4e.py | 0 .../mdp_apps.ipynb => mdp_apps.ipynb | 0 .../neural_nets.ipynb => neural_nets.ipynb | 0 other_shit_idgafabout/nlp.ipynb => nlp.ipynb | 0 other_shit_idgafabout/nlp.py => nlp.py | 0 other_shit_idgafabout/nlp4e.py => nlp4e.py | 0 .../nlp_apps.ipynb => nlp_apps.ipynb | 0 .../notebook.py => notebook.py | 0 .../notebook4e.py => notebook4e.py | 0 .../chapter19/Learners.ipynb | 0 .../chapter19/Loss Functions and Layers.ipynb | 0 .../Optimizer and Backpropagation.ipynb | 0 .../chapter19/RNN.ipynb | 0 .../chapter19/images/autoencoder.png | Bin .../chapter19/images/backprop.png | Bin .../chapter19/images/corss_entropy_plot.png | Bin .../chapter19/images/mse_plot.png | Bin .../chapter19/images/nn.png | Bin .../chapter19/images/nn_steps.png | Bin .../chapter19/images/perceptron.png | Bin .../chapter19/images/rnn_connections.png | Bin .../chapter19/images/rnn_unit.png | Bin .../chapter19/images/rnn_units.png | Bin .../chapter19/images/vanilla.png | Bin .../Active Reinforcement Learning.ipynb | 0 .../Passive Reinforcement Learning.ipynb | 0 .../chapter21/images/mdp.png | Bin .../chapter22/Grammar.ipynb | 0 .../chapter22/Introduction.ipynb | 0 .../chapter22/Parsing.ipynb | 0 .../chapter22/images/parse_tree.png | Bin .../chapter22/nlp_apps.ipynb | 0 .../chapter24/Image Edge Detection.ipynb | 0 .../chapter24/Image Segmentation.ipynb | 0 .../chapter24/Objects in Images.ipynb | 0 .../chapter24/images/RCNN.png | Bin .../images/derivative_of_gaussian.png | Bin .../chapter24/images/gradients.png | Bin .../chapter24/images/laplacian.png | Bin .../chapter24/images/laplacian_kernels.png | Bin .../chapter24/images/stapler.png | Bin .../chapter24/images/stapler_bbox.png | Bin ..._search4e.ipynb => obsolete_search4e.ipynb | 0 .../perception4e.py => perception4e.py | 0 planning.py | 75 ++++++++++++++++-- ...c_learning.py => probabilistic_learning.py | 0 .../probability.ipynb => probability.ipynb | 0 .../probability.py => probability.py | 0 ...probability4e.ipynb => probability4e.ipynb | 0 .../probability4e.py => probability4e.py | 0 .../pytest.ini => pytest.ini | 0 ...ning.ipynb => reinforcement_learning.ipynb | 0 ...t_learning.py => reinforcement_learning.py | 0 ...arning4e.py => reinforcement_learning4e.py | 0 .../search4e.ipynb => search4e.ipynb | 0 submission_1.py => submission1.py | 21 ++++- submission_1_test.py => submission1_test.py | 10 ++- .../tests => tests}/__init__.py | 0 .../tests => tests}/pytest.ini | 0 .../tests => tests}/test_agents.py | 0 .../tests => tests}/test_agents4e.py | 0 .../tests => tests}/test_csp.py | 0 .../tests => tests}/test_deep_learning4e.py | 0 .../tests => tests}/test_games.py | 0 .../tests => tests}/test_games4e.py | 0 .../tests => tests}/test_knowledge.py | 0 .../tests => tests}/test_learning.py | 0 .../tests => tests}/test_learning4e.py | 0 .../tests => tests}/test_logic.py | 0 .../tests => tests}/test_logic4e.py | 0 .../tests => tests}/test_mdp.py | 0 .../tests => tests}/test_mdp4e.py | 0 .../tests => tests}/test_nlp.py | 0 .../tests => tests}/test_nlp4e.py | 0 .../tests => tests}/test_perception4e.py | 0 .../tests => tests}/test_planning.py | 0 .../test_probabilistic_learning.py | 0 .../tests => tests}/test_probability.py | 0 .../tests => tests}/test_probability4e.py | 0 .../test_reinforcement_learning.py | 0 .../test_reinforcement_learning4e.py | 0 .../tests => tests}/test_search.py | 0 .../tests => tests}/test_text.py | 0 .../tests => tests}/test_utils.py | 0 .../text.ipynb => text.ipynb | 0 other_shit_idgafabout/text.py => text.py | 0 understanding_mutexes.md | 50 ++++++++++++ .../utils4e.py => utils4e.py | 0 .../vacuum_world.ipynb => vacuum_world.ipynb | 0 ...algorithm.ipynb => viterbi_algorithm.ipynb | 0 124 files changed, 145 insertions(+), 11 deletions(-) rename other_shit_idgafabout/.coveragerc => .coveragerc (100%) rename other_shit_idgafabout/.flake8 => .flake8 (100%) rename other_shit_idgafabout/CONTRIBUTING.md => CONTRIBUTING.md (100%) rename other_shit_idgafabout/LICENSE => LICENSE (100%) rename other_shit_idgafabout/SUBMODULE.md => SUBMODULE.md (100%) rename other_shit_idgafabout/agents.ipynb => agents.ipynb (100%) rename other_shit_idgafabout/agents4e.py => agents4e.py (100%) rename other_shit_idgafabout/aima_8puzzle.py => aima_8puzzle.py (100%) rename other_shit_idgafabout/aima_my_tsp.py => aima_my_tsp.py (100%) rename other_shit_idgafabout/arc_consistency_heuristics.ipynb => arc_consistency_heuristics.ipynb (100%) rename other_shit_idgafabout/csp.ipynb => csp.ipynb (100%) rename other_shit_idgafabout/deep_learning4e.py => deep_learning4e.py (100%) rename other_shit_idgafabout/games.ipynb => games.ipynb (100%) rename other_shit_idgafabout/games.py => games.py (100%) rename other_shit_idgafabout/games4e.ipynb => games4e.ipynb (100%) rename other_shit_idgafabout/games4e.py => games4e.py (100%) rename other_shit_idgafabout/improving_sat_algorithms.ipynb => improving_sat_algorithms.ipynb (100%) rename other_shit_idgafabout/index.ipynb => index.ipynb (100%) rename other_shit_idgafabout/intro.ipynb => intro.ipynb (100%) rename other_shit_idgafabout/ipyviews.py => ipyviews.py (100%) rename {other_shit_idgafabout/js => js}/canvas.js (100%) rename {other_shit_idgafabout/js => js}/continuousworld.js (100%) rename {other_shit_idgafabout/js => js}/gridworld.js (100%) rename other_shit_idgafabout/knowledge.py => knowledge.py (100%) rename other_shit_idgafabout/knowledge_FOIL.ipynb => knowledge_FOIL.ipynb (100%) rename other_shit_idgafabout/knowledge_current_best.ipynb => knowledge_current_best.ipynb (100%) rename other_shit_idgafabout/knowledge_version_space.ipynb => knowledge_version_space.ipynb (100%) rename other_shit_idgafabout/learning.ipynb => learning.ipynb (100%) rename other_shit_idgafabout/learning.py => learning.py (100%) rename other_shit_idgafabout/learning4e.py => learning4e.py (100%) rename other_shit_idgafabout/learning_apps.ipynb => learning_apps.ipynb (100%) rename other_shit_idgafabout/making_simple_decision4e.py => making_simple_decision4e.py (100%) rename other_shit_idgafabout/mdp.ipynb => mdp.ipynb (100%) rename other_shit_idgafabout/mdp.py => mdp.py (100%) rename other_shit_idgafabout/mdp4e.py => mdp4e.py (100%) rename other_shit_idgafabout/mdp_apps.ipynb => mdp_apps.ipynb (100%) rename other_shit_idgafabout/neural_nets.ipynb => neural_nets.ipynb (100%) rename other_shit_idgafabout/nlp.ipynb => nlp.ipynb (100%) rename other_shit_idgafabout/nlp.py => nlp.py (100%) rename other_shit_idgafabout/nlp4e.py => nlp4e.py (100%) rename other_shit_idgafabout/nlp_apps.ipynb => nlp_apps.ipynb (100%) rename other_shit_idgafabout/notebook.py => notebook.py (100%) rename other_shit_idgafabout/notebook4e.py => notebook4e.py (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/Learners.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/Loss Functions and Layers.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/Optimizer and Backpropagation.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/RNN.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/autoencoder.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/backprop.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/corss_entropy_plot.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/mse_plot.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/nn.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/nn_steps.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/perceptron.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/rnn_connections.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/rnn_unit.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/rnn_units.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter19/images/vanilla.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter21/Active Reinforcement Learning.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter21/Passive Reinforcement Learning.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter21/images/mdp.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter22/Grammar.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter22/Introduction.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter22/Parsing.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter22/images/parse_tree.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter22/nlp_apps.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/Image Edge Detection.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/Image Segmentation.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/Objects in Images.ipynb (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/RCNN.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/derivative_of_gaussian.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/gradients.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/laplacian.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/laplacian_kernels.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/stapler.png (100%) rename {other_shit_idgafabout/notebooks => notebooks}/chapter24/images/stapler_bbox.png (100%) rename other_shit_idgafabout/obsolete_search4e.ipynb => obsolete_search4e.ipynb (100%) rename other_shit_idgafabout/perception4e.py => perception4e.py (100%) rename other_shit_idgafabout/probabilistic_learning.py => probabilistic_learning.py (100%) rename other_shit_idgafabout/probability.ipynb => probability.ipynb (100%) rename other_shit_idgafabout/probability.py => probability.py (100%) rename other_shit_idgafabout/probability4e.ipynb => probability4e.ipynb (100%) rename other_shit_idgafabout/probability4e.py => probability4e.py (100%) rename other_shit_idgafabout/pytest.ini => pytest.ini (100%) rename other_shit_idgafabout/reinforcement_learning.ipynb => reinforcement_learning.ipynb (100%) rename other_shit_idgafabout/reinforcement_learning.py => reinforcement_learning.py (100%) rename other_shit_idgafabout/reinforcement_learning4e.py => reinforcement_learning4e.py (100%) rename other_shit_idgafabout/search4e.ipynb => search4e.ipynb (100%) rename submission_1.py => submission1.py (90%) rename submission_1_test.py => submission1_test.py (90%) rename {other_shit_idgafabout/tests => tests}/__init__.py (100%) rename {other_shit_idgafabout/tests => tests}/pytest.ini (100%) rename {other_shit_idgafabout/tests => tests}/test_agents.py (100%) rename {other_shit_idgafabout/tests => tests}/test_agents4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_csp.py (100%) rename {other_shit_idgafabout/tests => tests}/test_deep_learning4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_games.py (100%) rename {other_shit_idgafabout/tests => tests}/test_games4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_knowledge.py (100%) rename {other_shit_idgafabout/tests => tests}/test_learning.py (100%) rename {other_shit_idgafabout/tests => tests}/test_learning4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_logic.py (100%) rename {other_shit_idgafabout/tests => tests}/test_logic4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_mdp.py (100%) rename {other_shit_idgafabout/tests => tests}/test_mdp4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_nlp.py (100%) rename {other_shit_idgafabout/tests => tests}/test_nlp4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_perception4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_planning.py (100%) rename {other_shit_idgafabout/tests => tests}/test_probabilistic_learning.py (100%) rename {other_shit_idgafabout/tests => tests}/test_probability.py (100%) rename {other_shit_idgafabout/tests => tests}/test_probability4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_reinforcement_learning.py (100%) rename {other_shit_idgafabout/tests => tests}/test_reinforcement_learning4e.py (100%) rename {other_shit_idgafabout/tests => tests}/test_search.py (100%) rename {other_shit_idgafabout/tests => tests}/test_text.py (100%) rename {other_shit_idgafabout/tests => tests}/test_utils.py (100%) rename other_shit_idgafabout/text.ipynb => text.ipynb (100%) rename other_shit_idgafabout/text.py => text.py (100%) create mode 100644 understanding_mutexes.md rename other_shit_idgafabout/utils4e.py => utils4e.py (100%) rename other_shit_idgafabout/vacuum_world.ipynb => vacuum_world.ipynb (100%) rename other_shit_idgafabout/viterbi_algorithm.ipynb => viterbi_algorithm.ipynb (100%) diff --git a/other_shit_idgafabout/.coveragerc b/.coveragerc similarity index 100% rename from other_shit_idgafabout/.coveragerc rename to .coveragerc diff --git a/other_shit_idgafabout/.flake8 b/.flake8 similarity index 100% rename from other_shit_idgafabout/.flake8 rename to .flake8 diff --git a/other_shit_idgafabout/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from other_shit_idgafabout/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/other_shit_idgafabout/LICENSE b/LICENSE similarity index 100% rename from other_shit_idgafabout/LICENSE rename to LICENSE diff --git a/other_shit_idgafabout/SUBMODULE.md b/SUBMODULE.md similarity index 100% rename from other_shit_idgafabout/SUBMODULE.md rename to SUBMODULE.md diff --git a/other_shit_idgafabout/agents.ipynb b/agents.ipynb similarity index 100% rename from other_shit_idgafabout/agents.ipynb rename to agents.ipynb diff --git a/other_shit_idgafabout/agents4e.py b/agents4e.py similarity index 100% rename from other_shit_idgafabout/agents4e.py rename to agents4e.py diff --git a/other_shit_idgafabout/aima_8puzzle.py b/aima_8puzzle.py similarity index 100% rename from other_shit_idgafabout/aima_8puzzle.py rename to aima_8puzzle.py diff --git a/other_shit_idgafabout/aima_my_tsp.py b/aima_my_tsp.py similarity index 100% rename from other_shit_idgafabout/aima_my_tsp.py rename to aima_my_tsp.py diff --git a/other_shit_idgafabout/arc_consistency_heuristics.ipynb b/arc_consistency_heuristics.ipynb similarity index 100% rename from other_shit_idgafabout/arc_consistency_heuristics.ipynb rename to arc_consistency_heuristics.ipynb diff --git a/other_shit_idgafabout/csp.ipynb b/csp.ipynb similarity index 100% rename from other_shit_idgafabout/csp.ipynb rename to csp.ipynb diff --git a/other_shit_idgafabout/deep_learning4e.py b/deep_learning4e.py similarity index 100% rename from other_shit_idgafabout/deep_learning4e.py rename to deep_learning4e.py diff --git a/other_shit_idgafabout/games.ipynb b/games.ipynb similarity index 100% rename from other_shit_idgafabout/games.ipynb rename to games.ipynb diff --git a/other_shit_idgafabout/games.py b/games.py similarity index 100% rename from other_shit_idgafabout/games.py rename to games.py diff --git a/other_shit_idgafabout/games4e.ipynb b/games4e.ipynb similarity index 100% rename from other_shit_idgafabout/games4e.ipynb rename to games4e.ipynb diff --git a/other_shit_idgafabout/games4e.py b/games4e.py similarity index 100% rename from other_shit_idgafabout/games4e.py rename to games4e.py diff --git a/other_shit_idgafabout/improving_sat_algorithms.ipynb b/improving_sat_algorithms.ipynb similarity index 100% rename from other_shit_idgafabout/improving_sat_algorithms.ipynb rename to improving_sat_algorithms.ipynb diff --git a/other_shit_idgafabout/index.ipynb b/index.ipynb similarity index 100% rename from other_shit_idgafabout/index.ipynb rename to index.ipynb diff --git a/other_shit_idgafabout/intro.ipynb b/intro.ipynb similarity index 100% rename from other_shit_idgafabout/intro.ipynb rename to intro.ipynb diff --git a/other_shit_idgafabout/ipyviews.py b/ipyviews.py similarity index 100% rename from other_shit_idgafabout/ipyviews.py rename to ipyviews.py diff --git a/other_shit_idgafabout/js/canvas.js b/js/canvas.js similarity index 100% rename from other_shit_idgafabout/js/canvas.js rename to js/canvas.js diff --git a/other_shit_idgafabout/js/continuousworld.js b/js/continuousworld.js similarity index 100% rename from other_shit_idgafabout/js/continuousworld.js rename to js/continuousworld.js diff --git a/other_shit_idgafabout/js/gridworld.js b/js/gridworld.js similarity index 100% rename from other_shit_idgafabout/js/gridworld.js rename to js/gridworld.js diff --git a/other_shit_idgafabout/knowledge.py b/knowledge.py similarity index 100% rename from other_shit_idgafabout/knowledge.py rename to knowledge.py diff --git a/other_shit_idgafabout/knowledge_FOIL.ipynb b/knowledge_FOIL.ipynb similarity index 100% rename from other_shit_idgafabout/knowledge_FOIL.ipynb rename to knowledge_FOIL.ipynb diff --git a/other_shit_idgafabout/knowledge_current_best.ipynb b/knowledge_current_best.ipynb similarity index 100% rename from other_shit_idgafabout/knowledge_current_best.ipynb rename to knowledge_current_best.ipynb diff --git a/other_shit_idgafabout/knowledge_version_space.ipynb b/knowledge_version_space.ipynb similarity index 100% rename from other_shit_idgafabout/knowledge_version_space.ipynb rename to knowledge_version_space.ipynb diff --git a/other_shit_idgafabout/learning.ipynb b/learning.ipynb similarity index 100% rename from other_shit_idgafabout/learning.ipynb rename to learning.ipynb diff --git a/other_shit_idgafabout/learning.py b/learning.py similarity index 100% rename from other_shit_idgafabout/learning.py rename to learning.py diff --git a/other_shit_idgafabout/learning4e.py b/learning4e.py similarity index 100% rename from other_shit_idgafabout/learning4e.py rename to learning4e.py diff --git a/other_shit_idgafabout/learning_apps.ipynb b/learning_apps.ipynb similarity index 100% rename from other_shit_idgafabout/learning_apps.ipynb rename to learning_apps.ipynb diff --git a/other_shit_idgafabout/making_simple_decision4e.py b/making_simple_decision4e.py similarity index 100% rename from other_shit_idgafabout/making_simple_decision4e.py rename to making_simple_decision4e.py diff --git a/other_shit_idgafabout/mdp.ipynb b/mdp.ipynb similarity index 100% rename from other_shit_idgafabout/mdp.ipynb rename to mdp.ipynb diff --git a/other_shit_idgafabout/mdp.py b/mdp.py similarity index 100% rename from other_shit_idgafabout/mdp.py rename to mdp.py diff --git a/other_shit_idgafabout/mdp4e.py b/mdp4e.py similarity index 100% rename from other_shit_idgafabout/mdp4e.py rename to mdp4e.py diff --git a/other_shit_idgafabout/mdp_apps.ipynb b/mdp_apps.ipynb similarity index 100% rename from other_shit_idgafabout/mdp_apps.ipynb rename to mdp_apps.ipynb diff --git a/other_shit_idgafabout/neural_nets.ipynb b/neural_nets.ipynb similarity index 100% rename from other_shit_idgafabout/neural_nets.ipynb rename to neural_nets.ipynb diff --git a/other_shit_idgafabout/nlp.ipynb b/nlp.ipynb similarity index 100% rename from other_shit_idgafabout/nlp.ipynb rename to nlp.ipynb diff --git a/other_shit_idgafabout/nlp.py b/nlp.py similarity index 100% rename from other_shit_idgafabout/nlp.py rename to nlp.py diff --git a/other_shit_idgafabout/nlp4e.py b/nlp4e.py similarity index 100% rename from other_shit_idgafabout/nlp4e.py rename to nlp4e.py diff --git a/other_shit_idgafabout/nlp_apps.ipynb b/nlp_apps.ipynb similarity index 100% rename from other_shit_idgafabout/nlp_apps.ipynb rename to nlp_apps.ipynb diff --git a/other_shit_idgafabout/notebook.py b/notebook.py similarity index 100% rename from other_shit_idgafabout/notebook.py rename to notebook.py diff --git a/other_shit_idgafabout/notebook4e.py b/notebook4e.py similarity index 100% rename from other_shit_idgafabout/notebook4e.py rename to notebook4e.py diff --git a/other_shit_idgafabout/notebooks/chapter19/Learners.ipynb b/notebooks/chapter19/Learners.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/Learners.ipynb rename to notebooks/chapter19/Learners.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter19/Loss Functions and Layers.ipynb b/notebooks/chapter19/Loss Functions and Layers.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/Loss Functions and Layers.ipynb rename to notebooks/chapter19/Loss Functions and Layers.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter19/Optimizer and Backpropagation.ipynb b/notebooks/chapter19/Optimizer and Backpropagation.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/Optimizer and Backpropagation.ipynb rename to notebooks/chapter19/Optimizer and Backpropagation.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter19/RNN.ipynb b/notebooks/chapter19/RNN.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/RNN.ipynb rename to notebooks/chapter19/RNN.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter19/images/autoencoder.png b/notebooks/chapter19/images/autoencoder.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/autoencoder.png rename to notebooks/chapter19/images/autoencoder.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/backprop.png b/notebooks/chapter19/images/backprop.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/backprop.png rename to notebooks/chapter19/images/backprop.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/corss_entropy_plot.png b/notebooks/chapter19/images/corss_entropy_plot.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/corss_entropy_plot.png rename to notebooks/chapter19/images/corss_entropy_plot.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/mse_plot.png b/notebooks/chapter19/images/mse_plot.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/mse_plot.png rename to notebooks/chapter19/images/mse_plot.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/nn.png b/notebooks/chapter19/images/nn.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/nn.png rename to notebooks/chapter19/images/nn.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/nn_steps.png b/notebooks/chapter19/images/nn_steps.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/nn_steps.png rename to notebooks/chapter19/images/nn_steps.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/perceptron.png b/notebooks/chapter19/images/perceptron.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/perceptron.png rename to notebooks/chapter19/images/perceptron.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/rnn_connections.png b/notebooks/chapter19/images/rnn_connections.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/rnn_connections.png rename to notebooks/chapter19/images/rnn_connections.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/rnn_unit.png b/notebooks/chapter19/images/rnn_unit.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/rnn_unit.png rename to notebooks/chapter19/images/rnn_unit.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/rnn_units.png b/notebooks/chapter19/images/rnn_units.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/rnn_units.png rename to notebooks/chapter19/images/rnn_units.png diff --git a/other_shit_idgafabout/notebooks/chapter19/images/vanilla.png b/notebooks/chapter19/images/vanilla.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter19/images/vanilla.png rename to notebooks/chapter19/images/vanilla.png diff --git a/other_shit_idgafabout/notebooks/chapter21/Active Reinforcement Learning.ipynb b/notebooks/chapter21/Active Reinforcement Learning.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter21/Active Reinforcement Learning.ipynb rename to notebooks/chapter21/Active Reinforcement Learning.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter21/Passive Reinforcement Learning.ipynb b/notebooks/chapter21/Passive Reinforcement Learning.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter21/Passive Reinforcement Learning.ipynb rename to notebooks/chapter21/Passive Reinforcement Learning.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter21/images/mdp.png b/notebooks/chapter21/images/mdp.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter21/images/mdp.png rename to notebooks/chapter21/images/mdp.png diff --git a/other_shit_idgafabout/notebooks/chapter22/Grammar.ipynb b/notebooks/chapter22/Grammar.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter22/Grammar.ipynb rename to notebooks/chapter22/Grammar.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter22/Introduction.ipynb b/notebooks/chapter22/Introduction.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter22/Introduction.ipynb rename to notebooks/chapter22/Introduction.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter22/Parsing.ipynb b/notebooks/chapter22/Parsing.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter22/Parsing.ipynb rename to notebooks/chapter22/Parsing.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter22/images/parse_tree.png b/notebooks/chapter22/images/parse_tree.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter22/images/parse_tree.png rename to notebooks/chapter22/images/parse_tree.png diff --git a/other_shit_idgafabout/notebooks/chapter22/nlp_apps.ipynb b/notebooks/chapter22/nlp_apps.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter22/nlp_apps.ipynb rename to notebooks/chapter22/nlp_apps.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter24/Image Edge Detection.ipynb b/notebooks/chapter24/Image Edge Detection.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/Image Edge Detection.ipynb rename to notebooks/chapter24/Image Edge Detection.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter24/Image Segmentation.ipynb b/notebooks/chapter24/Image Segmentation.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/Image Segmentation.ipynb rename to notebooks/chapter24/Image Segmentation.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter24/Objects in Images.ipynb b/notebooks/chapter24/Objects in Images.ipynb similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/Objects in Images.ipynb rename to notebooks/chapter24/Objects in Images.ipynb diff --git a/other_shit_idgafabout/notebooks/chapter24/images/RCNN.png b/notebooks/chapter24/images/RCNN.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/RCNN.png rename to notebooks/chapter24/images/RCNN.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/derivative_of_gaussian.png b/notebooks/chapter24/images/derivative_of_gaussian.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/derivative_of_gaussian.png rename to notebooks/chapter24/images/derivative_of_gaussian.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/gradients.png b/notebooks/chapter24/images/gradients.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/gradients.png rename to notebooks/chapter24/images/gradients.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/laplacian.png b/notebooks/chapter24/images/laplacian.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/laplacian.png rename to notebooks/chapter24/images/laplacian.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/laplacian_kernels.png b/notebooks/chapter24/images/laplacian_kernels.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/laplacian_kernels.png rename to notebooks/chapter24/images/laplacian_kernels.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/stapler.png b/notebooks/chapter24/images/stapler.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/stapler.png rename to notebooks/chapter24/images/stapler.png diff --git a/other_shit_idgafabout/notebooks/chapter24/images/stapler_bbox.png b/notebooks/chapter24/images/stapler_bbox.png similarity index 100% rename from other_shit_idgafabout/notebooks/chapter24/images/stapler_bbox.png rename to notebooks/chapter24/images/stapler_bbox.png diff --git a/other_shit_idgafabout/obsolete_search4e.ipynb b/obsolete_search4e.ipynb similarity index 100% rename from other_shit_idgafabout/obsolete_search4e.ipynb rename to obsolete_search4e.ipynb diff --git a/other_shit_idgafabout/perception4e.py b/perception4e.py similarity index 100% rename from other_shit_idgafabout/perception4e.py rename to perception4e.py diff --git a/planning.py b/planning.py index 661cdb4ec..38befa19d 100644 --- a/planning.py +++ b/planning.py @@ -476,7 +476,7 @@ def shopping_problem(): >>> """ - return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)', + return PlanningProblem(initial='At(Home)', goals='Have(Milk) & Have(Banana) & Have(Drill)', actions=[Action('Buy(x, store)', precond='At(store) & Sells(store, x)', @@ -487,7 +487,8 @@ def shopping_problem(): effect='At(y) & ~At(x)', domain='Place(x) & Place(y)')], domain='Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & ' - 'Item(Milk) & Item(Banana) & Item(Drill)') + 'Item(Milk) & Item(Banana) & Item(Drill) & ' + 'Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)') def socks_and_shoes(): @@ -550,6 +551,12 @@ def double_tennis_problem(): >>> """ + # The authors mistakenly used `a` rather than `A`, and also set it to two locations? + # This is the original function, but it's faulty. Although, it does technically pass pytests? Just for some reason, not graphPlan... + # I believe this fails GraphPlan because of the way it extracts objects, which does not include objects that only exist in goal states? + # - Therefore the GraphPlan fails, but the pytests that manuallys solve pass? + # - To explain why At(a, LeftNet), At(a,RightNet) passes, perhaps since it doesn't see `a` in objects, it takes it as a variable? Where any object can make it true? Which A and B do? + """ return PlanningProblem( initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', @@ -559,8 +566,57 @@ def double_tennis_problem(): Action('Go(actor, to, loc)', precond='At(actor, loc)', effect='At(actor, to) & ~At(actor, loc)')]) + """ + + """ + [Figure 11.10] DOUBLE-TENNIS-PROBLEM + A multiagent planning problem involving two partner tennis players + trying to return an approaching ball and repositioning around in the court. + """ + # This works, but adds extra unnecessary detail to the problem + """ + return PlanningProblem( + initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', + goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', + actions=[Action('Hit(actor, Ball, loc)', + precond='Approaching(Ball, loc) & At(actor, loc)', + effect='Returned(Ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)', + domain='Player(actor) & CourtLoc(to) & CourtLoc(loc)')], + domain='Player(A) & Player(B) & Ball(Ball) & CourtLoc(LeftBaseLine) & CourtLoc(RightBaseLine) & CourtLoc(LeftNet) & CourtLoc(RightNet)' + ) + """ + + # THIS DOESNT WORK BECAUSE LeftNet isn't recognized as an object + """ + return PlanningProblem( + initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', + goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', + actions=[Action('Hit(actor, Ball, loc)', + precond='Approaching(Ball, loc) & At(actor, loc)', + effect='Returned(Ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + """ + + return PlanningProblem( + initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', + goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', + actions=[Action('Hit(actor, Ball, loc)', + precond='Approaching(Ball, loc) & At(actor, loc)', + effect='Returned(Ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')], + domain='CourtLoc(LeftNet) & CourtLoc(RightNet) & CourtLoc(LeftBaseline) & CourtLoc(RightBaseline)' + ) + + class ForwardPlan(search.Problem): """ [Section 10.2.1] @@ -1091,6 +1147,7 @@ def orderlevel(self, level, planning_problem): return None """ + """ def orderlevel(self, level, planning_problem): "Return valid linear order of actions for a given level" @@ -1116,8 +1173,8 @@ def orderlevel(self, level, planning_problem): # If no valid permutation was found after checking all possibilities return None, None - """ + def execute(self): "Finds total-order solution for a planning graph" @@ -1127,14 +1184,17 @@ def execute(self): planning_problem = self.planning_problem for level in filtered_solution: level_solution, planning_problem = self.orderlevel(level, planning_problem) + # Handle empty level_solutions + if level_solution is None: + continue for element in level_solution: ordered_solution.append(element) return ordered_solution - """ + """ def execute(self): - """Finds a total-order solution for a planning graph.""" + "Finds a total-order solution for a planning graph." # This might return multiple solutions, let's call it a list of "raw plans" raw_plans = GraphPlan(self.planning_problem).execute() @@ -1152,7 +1212,7 @@ def execute(self): return None # No valid linearization was found for any of the plans def _attempt_linearization(self, raw_plan): - """Helper function to linearize a single raw plan.""" + "Helper function to linearize a single raw plan." # Filter out persistence actions filtered_plan = self._filter(raw_plan) ordered_solution = [] @@ -1167,7 +1227,7 @@ def _attempt_linearization(self, raw_plan): return ordered_solution def _filter(self, raw_plan): - """Filter out persistence actions from a single raw plan.""" + "Filter out persistence actions from a single raw plan." new_solution = [] for section in raw_plan: new_section = [] @@ -1176,6 +1236,7 @@ def _filter(self, raw_plan): new_section.append(operation) new_solution.append(new_section) return new_solution + """ def linearize(solution): diff --git a/other_shit_idgafabout/probabilistic_learning.py b/probabilistic_learning.py similarity index 100% rename from other_shit_idgafabout/probabilistic_learning.py rename to probabilistic_learning.py diff --git a/other_shit_idgafabout/probability.ipynb b/probability.ipynb similarity index 100% rename from other_shit_idgafabout/probability.ipynb rename to probability.ipynb diff --git a/other_shit_idgafabout/probability.py b/probability.py similarity index 100% rename from other_shit_idgafabout/probability.py rename to probability.py diff --git a/other_shit_idgafabout/probability4e.ipynb b/probability4e.ipynb similarity index 100% rename from other_shit_idgafabout/probability4e.ipynb rename to probability4e.ipynb diff --git a/other_shit_idgafabout/probability4e.py b/probability4e.py similarity index 100% rename from other_shit_idgafabout/probability4e.py rename to probability4e.py diff --git a/other_shit_idgafabout/pytest.ini b/pytest.ini similarity index 100% rename from other_shit_idgafabout/pytest.ini rename to pytest.ini diff --git a/other_shit_idgafabout/reinforcement_learning.ipynb b/reinforcement_learning.ipynb similarity index 100% rename from other_shit_idgafabout/reinforcement_learning.ipynb rename to reinforcement_learning.ipynb diff --git a/other_shit_idgafabout/reinforcement_learning.py b/reinforcement_learning.py similarity index 100% rename from other_shit_idgafabout/reinforcement_learning.py rename to reinforcement_learning.py diff --git a/other_shit_idgafabout/reinforcement_learning4e.py b/reinforcement_learning4e.py similarity index 100% rename from other_shit_idgafabout/reinforcement_learning4e.py rename to reinforcement_learning4e.py diff --git a/other_shit_idgafabout/search4e.ipynb b/search4e.ipynb similarity index 100% rename from other_shit_idgafabout/search4e.ipynb rename to search4e.ipynb diff --git a/submission_1.py b/submission1.py similarity index 90% rename from submission_1.py rename to submission1.py index b2e2b54fb..c150f4f90 100644 --- a/submission_1.py +++ b/submission1.py @@ -97,9 +97,24 @@ def logisticsPlanCustom(initial_state=None, goal_state=None): #goal_state = 'In(C1, D2)' #print(logisticsPlanCustom(initial_state, goal_state)) - initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - goal_state = "In(C1, D1) & In(C3, R1) & In(R1, D3)" - print(logisticsPlanCustom(initial_state, goal_state)) + #initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + #goal_state = "In(C1, D1) & In(C3, R1) & In(R1, D3)" + #print(logisticsPlanCustom(initial_state, goal_state)) + + # NOW WORKS: issue was in problem domain definition + #P = double_tennis_problem() + #print(GraphPlan(P).execute()) + + P = shopping_problem() + #print(GraphPlan(P).execute()) + """ + [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), + PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), + PItem(Drill), Go(Home, SM)], + [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] + """ + + print(Linearize(P).execute()) """ Standard logistics environment diff --git a/submission_1_test.py b/submission1_test.py similarity index 90% rename from submission_1_test.py rename to submission1_test.py index a56622cd6..00447dfaa 100644 --- a/submission_1_test.py +++ b/submission1_test.py @@ -4,7 +4,7 @@ from logic import * import pytest -import submission_1 as sub +import submission1 as sub def test_blocksworld_manual(): @@ -35,6 +35,13 @@ def test_simple_blocks_world(): def test_shopping_problem(): P = shopping_problem() + #print(GraphPlan(P).execute()) + """ + [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), + PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), + PItem(Drill), Go(Home, SM)], + [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] + """ assert isinstance(Linearize(P).execute(), list) def test_socks_and_shoes(): @@ -43,6 +50,7 @@ def test_socks_and_shoes(): def test_double_tennis_problem(): P = double_tennis_problem() + #print(GraphPlan(P).execute()) assert isinstance(Linearize(P).execute(), list) diff --git a/other_shit_idgafabout/tests/__init__.py b/tests/__init__.py similarity index 100% rename from other_shit_idgafabout/tests/__init__.py rename to tests/__init__.py diff --git a/other_shit_idgafabout/tests/pytest.ini b/tests/pytest.ini similarity index 100% rename from other_shit_idgafabout/tests/pytest.ini rename to tests/pytest.ini diff --git a/other_shit_idgafabout/tests/test_agents.py b/tests/test_agents.py similarity index 100% rename from other_shit_idgafabout/tests/test_agents.py rename to tests/test_agents.py diff --git a/other_shit_idgafabout/tests/test_agents4e.py b/tests/test_agents4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_agents4e.py rename to tests/test_agents4e.py diff --git a/other_shit_idgafabout/tests/test_csp.py b/tests/test_csp.py similarity index 100% rename from other_shit_idgafabout/tests/test_csp.py rename to tests/test_csp.py diff --git a/other_shit_idgafabout/tests/test_deep_learning4e.py b/tests/test_deep_learning4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_deep_learning4e.py rename to tests/test_deep_learning4e.py diff --git a/other_shit_idgafabout/tests/test_games.py b/tests/test_games.py similarity index 100% rename from other_shit_idgafabout/tests/test_games.py rename to tests/test_games.py diff --git a/other_shit_idgafabout/tests/test_games4e.py b/tests/test_games4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_games4e.py rename to tests/test_games4e.py diff --git a/other_shit_idgafabout/tests/test_knowledge.py b/tests/test_knowledge.py similarity index 100% rename from other_shit_idgafabout/tests/test_knowledge.py rename to tests/test_knowledge.py diff --git a/other_shit_idgafabout/tests/test_learning.py b/tests/test_learning.py similarity index 100% rename from other_shit_idgafabout/tests/test_learning.py rename to tests/test_learning.py diff --git a/other_shit_idgafabout/tests/test_learning4e.py b/tests/test_learning4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_learning4e.py rename to tests/test_learning4e.py diff --git a/other_shit_idgafabout/tests/test_logic.py b/tests/test_logic.py similarity index 100% rename from other_shit_idgafabout/tests/test_logic.py rename to tests/test_logic.py diff --git a/other_shit_idgafabout/tests/test_logic4e.py b/tests/test_logic4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_logic4e.py rename to tests/test_logic4e.py diff --git a/other_shit_idgafabout/tests/test_mdp.py b/tests/test_mdp.py similarity index 100% rename from other_shit_idgafabout/tests/test_mdp.py rename to tests/test_mdp.py diff --git a/other_shit_idgafabout/tests/test_mdp4e.py b/tests/test_mdp4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_mdp4e.py rename to tests/test_mdp4e.py diff --git a/other_shit_idgafabout/tests/test_nlp.py b/tests/test_nlp.py similarity index 100% rename from other_shit_idgafabout/tests/test_nlp.py rename to tests/test_nlp.py diff --git a/other_shit_idgafabout/tests/test_nlp4e.py b/tests/test_nlp4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_nlp4e.py rename to tests/test_nlp4e.py diff --git a/other_shit_idgafabout/tests/test_perception4e.py b/tests/test_perception4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_perception4e.py rename to tests/test_perception4e.py diff --git a/other_shit_idgafabout/tests/test_planning.py b/tests/test_planning.py similarity index 100% rename from other_shit_idgafabout/tests/test_planning.py rename to tests/test_planning.py diff --git a/other_shit_idgafabout/tests/test_probabilistic_learning.py b/tests/test_probabilistic_learning.py similarity index 100% rename from other_shit_idgafabout/tests/test_probabilistic_learning.py rename to tests/test_probabilistic_learning.py diff --git a/other_shit_idgafabout/tests/test_probability.py b/tests/test_probability.py similarity index 100% rename from other_shit_idgafabout/tests/test_probability.py rename to tests/test_probability.py diff --git a/other_shit_idgafabout/tests/test_probability4e.py b/tests/test_probability4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_probability4e.py rename to tests/test_probability4e.py diff --git a/other_shit_idgafabout/tests/test_reinforcement_learning.py b/tests/test_reinforcement_learning.py similarity index 100% rename from other_shit_idgafabout/tests/test_reinforcement_learning.py rename to tests/test_reinforcement_learning.py diff --git a/other_shit_idgafabout/tests/test_reinforcement_learning4e.py b/tests/test_reinforcement_learning4e.py similarity index 100% rename from other_shit_idgafabout/tests/test_reinforcement_learning4e.py rename to tests/test_reinforcement_learning4e.py diff --git a/other_shit_idgafabout/tests/test_search.py b/tests/test_search.py similarity index 100% rename from other_shit_idgafabout/tests/test_search.py rename to tests/test_search.py diff --git a/other_shit_idgafabout/tests/test_text.py b/tests/test_text.py similarity index 100% rename from other_shit_idgafabout/tests/test_text.py rename to tests/test_text.py diff --git a/other_shit_idgafabout/tests/test_utils.py b/tests/test_utils.py similarity index 100% rename from other_shit_idgafabout/tests/test_utils.py rename to tests/test_utils.py diff --git a/other_shit_idgafabout/text.ipynb b/text.ipynb similarity index 100% rename from other_shit_idgafabout/text.ipynb rename to text.ipynb diff --git a/other_shit_idgafabout/text.py b/text.py similarity index 100% rename from other_shit_idgafabout/text.py rename to text.py diff --git a/understanding_mutexes.md b/understanding_mutexes.md new file mode 100644 index 000000000..e74610bd9 --- /dev/null +++ b/understanding_mutexes.md @@ -0,0 +1,50 @@ +Actions: Buy, Go + +Go(Home, SM) +Go(Home, HW) + +It includes Place, Store, Item, Sells in state (?) + +Level 0: + +Correctly identifies it can go to HW, SM, adds as mutexes + - Relies on At(Home) precondition, notes this + +Level 1: + +Adds Place(SM), Place(HW) into state, adds NotAt(Home) to state (we still have At(Home) + - Says no mutexes or actions - hasn't been generated yet. + +Graph: + +Level 1 is updated to have all applicable actions? Large mutex state: + +Has prior current state + + - Adds Buy(all, hw/sm appropriate) + - Mutex: + - not at home and at home + - Go(Home, HW), At(Home) ? GPT tells me this means that Go deletes the At(Home), so in the next state, these are disjoint. (makes sense) + - A mutex, therefore, means that two states or results of actions or intertwined, cannot have effects or states in the next state concurrently. + + + Mutex: + {{PNotAt(Home), PAt(Home)}, + {Go(Home, HW), PAt(Home)}, + {Go(Home, SM), PAt(Home)}, + {Go(HW, Home), PNotAt(Home)}, + {Go(HW, Home), Go(Home, HW)}, + {Go(HW, Home), Go(Home, SM)}, + {Go(SM, Home), PNotAt(Home)}, + {Go(SM, Home), Go(Home, HW)}, #duplicate? + {Go(SM, Home), Go(Home, SM)}, + {PAt(HW), Go(HW, Home)}, + {PAt(HW), Go(HW, SM)}, + {Go(HW, SM), Go(Home, HW)}, + {Go(HW, Home), Go(SM, HW)}, + {Go(HW, SM), Go(SM, HW)}, + {Go(SM, Home), PAt(SM)}, + {Go(SM, HW), PAt(SM)}, + {Go(Home, SM), Go(SM, HW)}, {Go(HW, SM), Go(SM, Home)}, {PNotAt(Home), Go(Home, HW)}, {PNotAt(Home), Go(Home, SM)}, {NotAt(Home), At(Home)}} # duplicate + + All seem well, and sufficient diff --git a/other_shit_idgafabout/utils4e.py b/utils4e.py similarity index 100% rename from other_shit_idgafabout/utils4e.py rename to utils4e.py diff --git a/other_shit_idgafabout/vacuum_world.ipynb b/vacuum_world.ipynb similarity index 100% rename from other_shit_idgafabout/vacuum_world.ipynb rename to vacuum_world.ipynb diff --git a/other_shit_idgafabout/viterbi_algorithm.ipynb b/viterbi_algorithm.ipynb similarity index 100% rename from other_shit_idgafabout/viterbi_algorithm.ipynb rename to viterbi_algorithm.ipynb From 31349ba6a445e7c3105409e00c366432ed1d0e57 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 27 Sep 2025 17:01:57 -0400 Subject: [PATCH 03/19] Add initial layer interference test, recursive goal testing, and appropriate level off condition that accounts for mutex changes. This version of graph plan works alright ... no plans tested fail, but the planner explosion, no_plan, double_tennis, air_cargo tests take too long for me to wait (i.e. they may fail). --- planning.py | 404 ++++++++++++++++++++++++++++++++++----- submission1.py | 6 +- submission1_test.py | 8 +- understanding_mutexes.md | 49 ++++- 4 files changed, 414 insertions(+), 53 deletions(-) diff --git a/planning.py b/planning.py index 38befa19d..a1bc18ff0 100644 --- a/planning.py +++ b/planning.py @@ -476,8 +476,8 @@ def shopping_problem(): >>> """ - return PlanningProblem(initial='At(Home)', - goals='Have(Milk) & Have(Banana) & Have(Drill)', + return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(HW, Drill)', + goals='Have(Milk) & Have(Drill)', actions=[Action('Buy(x, store)', precond='At(store) & Sells(store, x)', effect='Have(x)', @@ -485,10 +485,9 @@ def shopping_problem(): Action('Go(x, y)', precond='At(x)', effect='At(y) & ~At(x)', - domain='Place(x) & Place(y)')], - domain='Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & ' - 'Item(Milk) & Item(Banana) & Item(Drill) & ' - 'Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)') + domain='Rplace(x) & Rplace(y)')], + domain='Rplace(Home) & Rplace(SM) & Rplace(HW) & Store(SM) & Store(HW) & ' + 'Item(Milk) & Item(Drill)') def socks_and_shoes(): @@ -819,16 +818,27 @@ def __init__(self, kb): self.kb = kb # current state self.current_state = kb.clauses + # current action to state link + # Action -> preconditions for that action self.current_action_links = {} + # current state to action link + # Precondition -> what is applicable (actions) self.current_state_links = {} - # current action to next state link + + # current action to next state link (E.g. Go(Home, HW) --> At(HW) and NotAt(Home)) + # aka forward link in time (dependency) self.next_action_links = {} - # next state to current action link + + # next state to current action link (E.g. NotAt(Home): [Go(Home, HW), Go(Home, SM)]) + # aka backwards link in time (dependency) self.next_state_links = {} + # mutually exclusive actions self.mutex = [] + + self.isfirstlayer = True def __call__(self, actions, objects): self.build(actions, objects) @@ -863,7 +873,7 @@ def separate(self, e): def find_mutex(self): "Finds mutually exclusive actions" - # Inconsistent effects + # Inconsistent effects - one action adds a literal that another deletes pos_nsl, neg_nsl = self.separate(self.next_state_links) for negeff in neg_nsl: @@ -876,9 +886,10 @@ def find_mutex(self): self.mutex.append({a, b}) # Interference will be calculated with the last step + # Interference - One action deletes a precondition or effect of another pos_csl, neg_csl = self.separate(self.current_state_links) - # Competing needs + # Competing needs - preconditions of two actions are mutex at previous proposition layer for pos_precond in pos_csl: for neg_precond in neg_csl: new_neg_precond = Expr(neg_precond.op[3:], *neg_precond.args) @@ -888,7 +899,39 @@ def find_mutex(self): if {a, b} not in self.mutex: self.mutex.append({a, b}) - # Inconsistent support + # Only consider actual actions (not propositions) + action_keys = [a for a in self.next_action_links.keys() if not a.op.startswith("P")] + + if self.isfirstlayer: + for a1, a2 in itertools.combinations(action_keys, 2): + preconds_a1 = self.current_action_links.get(a1, []) + preconds_a2 = self.current_action_links.get(a2, []) + effects_a1 = self.next_action_links.get(a1, []) + effects_a2 = self.next_action_links.get(a2, []) + + # Check for interference + interference = False + for p1 in preconds_a1: + if Expr("Not" + p1.op, *p1.args) in effects_a2: + interference = True + for p2 in preconds_a2: + if Expr("Not" + p2.op, *p2.args) in effects_a1: + interference = True + for e1 in effects_a1: + if Expr("Not" + e1.op, *e1.args) in effects_a2: + interference = True + for e2 in effects_a2: + if Expr("Not" + e2.op, *e2.args) in effects_a1: + interference = True + + if interference: + mutex_pair = {a1, a2} + if mutex_pair not in self.mutex: # <-- avoid duplicates + self.mutex.append(mutex_pair) + + self.isfirstlayer = False + + # Inconsistent support - two props cannot be true given competing supporting actions state_mutex = [] for pair in self.mutex: next_state_0 = self.next_action_links[list(pair)[0]] @@ -900,6 +943,8 @@ def find_mutex(self): state_mutex.append({next_state_0[0], next_state_1[0]}) self.mutex = self.mutex + state_mutex + + #print(self.current_state_links, self.current_action_links) def build(self, actions, objects): """Populates the lists and dictionaries containing the state action dependencies""" @@ -918,7 +963,7 @@ def build(self, actions, objects): for arg in possible_args: if a.check_precond(self.kb, arg): for num, symbol in enumerate(a.args): - if not symbol.op.islower(): + if not symbol.op.islower(): # If not lowercase, we care about exact match to object? arg = list(arg) arg[num] = symbol arg = tuple(arg) @@ -947,6 +992,7 @@ def build(self, actions, objects): def perform_actions(self): """Performs the necessary actions and returns a new Level""" + # next_state_links.keys() will give the valid next states (the values would be all the actions that could cause it) new_kb = FolKB(list(set(self.next_state_links.keys()))) return Level(new_kb) @@ -985,14 +1031,69 @@ def expand_graph(self): last_level(self.planning_problem.actions, self.objects) self.levels.append(last_level.perform_actions()) + """ def non_mutex_goals(self, goals, index): - """Checks whether the goals are mutually exclusive""" + "Checks whether the goals are mutually exclusive" goal_perm = itertools.combinations(goals, 2) for g in goal_perm: if set(g) in self.levels[index].mutex: return False return True + """ + + def non_mutex_goals(self, goals, index): + "Checks whether the goals are mutually exclusive recursively" + + #print(f"mutexcheck: {index} == layer {len(self.levels) + index}") + num_layers = len(self.levels) + + # Base case: no goals left or first level reached + if num_layers + index == 0 or not goals: + return True + + # Base case: level 0, assume persistence actions handle mutexes there + if num_layers + index == 0: + goal_perm = itertools.combinations(goals, 2) + for g in goal_perm: + if frozenset(g) in self.levels[0].mutex: + return False + return True + + # Check current level mutexes first + goal_perm = itertools.combinations(goals, 2) + for g in goal_perm: + if frozenset(g) in self.levels[index].mutex: + return False + + # Recursive check: ensure for each pair of goals there exist non-mutex actions in previous level + level = self.levels[index - 1] + + for goal in goals: + # if the goal has no supporting actions in previous level, can't satisfy + if goal not in level.next_state_links: + return False + + # Generate all combinations of supporting actions + supporting_actions_lists = [level.next_state_links[goal] for goal in goals] + for action_tuple in itertools.product(*supporting_actions_lists): + # Check if any pair of actions is mutex + mutex_found = False + for a1, a2 in itertools.combinations(action_tuple, 2): + if frozenset((a1, a2)) in level.mutex: + mutex_found = True + break + if not mutex_found: + # At least one combination works, recurse to previous level + prev_goals = [] + for act in action_tuple: + if act in level.current_action_links: + prev_goals += level.current_action_links[act] + if self.non_mutex_goals(prev_goals, index - 1): + return True + + # If no combination works, goals are mutex + return False class GraphPlan: @@ -1024,11 +1125,84 @@ def __str__(self): def check_leveloff(self): """Checks if the graph has levelled off""" - check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) + check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) and \ + self.graph.levels[-1].mutex == self.graph.levels[-2].mutex if check: return True + """ + def extract_solution(self, goals, index): + "Extracts the solution" + + level = self.graph.levels[index] + if not self.graph.non_mutex_goals(goals, index): + self.no_goods.append((level, goals)) + return + + level = self.graph.levels[index - 1] + #print(f" On level {index-1}") + #print(f" Mutexes: \n {level.mutex}") + + # Create all combinations of actions that satisfy the goal + actions = [] + for goal in goals: + actions.append(level.next_state_links[goal]) + + all_actions = list(itertools.product(*actions)) + #print(f" ALL ACTION COMBINATIONS at level {index-1}:") + #for a in all_actions: + #print(" ", a) + + # Filter out non-mutex actions + non_mutex_actions = [] + for action_tuple in all_actions: + action_pairs = itertools.combinations(list(set(action_tuple)), 2) + non_mutex_actions.append(list(set(action_tuple))) + acts = list(set(action_tuple)) + #print(f"CHECKING tuple {acts} at level {index-1}") + for pair in action_pairs: + #print(" testing pair", pair, "mutex?", frozenset(pair) in level.mutex) + if set(pair) in level.mutex: + non_mutex_actions.pop(-1) + break + + #print(f"NON-MUTEX ACTION SETS at level {index}: {non_mutex_actions}") + + # Recursion + for action_list in non_mutex_actions: + if [action_list, index] not in self.solution: + self.solution.append([action_list, index]) + + new_goals = [] + for act in set(action_list): + if act in level.current_action_links: + new_goals = new_goals + level.current_action_links[act] + + if abs(index) + 1 == len(self.graph.levels): + return + elif (level, new_goals) in self.no_goods: + return + else: + #print(f" Recursing with new goal: {new_goals}") + self.extract_solution(new_goals, index - 1) + + # Level-Order multiple solutions + solution = [] + for item in self.solution: + if item[1] == -1: + solution.append([]) + solution[-1].append(item[0]) + else: + solution[-1].append(item[0]) + + for num, item in enumerate(solution): + item.reverse() + solution[num] = item + + return solution + """ + def extract_solution(self, goals, index): """Extracts the solution""" @@ -1087,36 +1261,49 @@ def extract_solution(self, goals, index): solution[num] = item return solution - + def goal_test(self, kb): return all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) def execute(self): """Executes the GraphPlan algorithm for the given problem""" + print("Forward Search") while True: self.graph.expand_graph() - print(self.graph) + #print(self.graph) if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): + #breakpoint() + print("SOLVED, EXTRACTING SOLUTION") + print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) + #self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) + print(self.graph) + print("Last level state:", self.graph.levels[-1].current_state) + print("Last level mutexes:", self.graph.levels[-1].mutex) + print("Next state links:", self.graph.levels[-1].next_state_links) + print("Current action links:", self.graph.levels[-1].current_action_links) + print("Extract Solution") solution = self.extract_solution(self.graph.planning_problem.goals, -1) if solution: + print(f"SOLUTION::::!!!!!!!!!!!!!!!!\n{solution}") return solution + #print(len(self.graph.levels)) if len(self.graph.levels) >= 2 and self.check_leveloff(): + breakpoint() return None +# BILLS CLASS + class Linearize: def __init__(self, planning_problem): self.planning_problem = planning_problem - - def __str__(self): - return f"" def filter(self, solution): - """Filter out persistence actions from a solution""" + "Filter out persistence actions from a solution" new_solution = [] for section in solution[0]: @@ -1127,27 +1314,119 @@ def filter(self, solution): new_solution.append(new_section) return new_solution - """ def orderlevel(self, level, planning_problem): "Return valid linear order of actions for a given level" for permutation in itertools.permutations(level): + print(f"TRYING PARTIAL PLAN: {permutation}") ## Bill's hack temp = copy.deepcopy(planning_problem) count = 0 + ## print(f"PERMUTATION: {permutation}") ## Bill's hack for action in permutation: try: + # print(f"TRY ACTION: {action}") ## Bill's hack temp.act(action) count += 1 + # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack except: + # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack count = 0 temp = copy.deepcopy(planning_problem) - break + continue ##break if count == len(permutation): + print(f"\nSUCCESSFUL PARTIAL PLAN ORDERING: {permutation}") ## Bill's hack return list(permutation), temp - return None - """ - - """ + print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack + return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem + + def execute(self): + "Finds total-order solution for a planning graph" + + graphPlan_solution = GraphPlan(self.planning_problem).execute() + + ## Bill's stuff from playing around + ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack + ## pnl(graphPlan_solution) + ## for possible_plan in graphPlan_solution: + ## possible_plan = [possible_plan] + ## filtered_possible_plan = self.filter(possible_plan) + ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack + ## flattened_graphplan = self.filter(graphPlan_solution) + ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack + ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack + ## flattened_graphplan = [flattened_graphplan] + ## graphPlan_solution = [flattened_graphplan] ## Bill's hack + ## pnl(flattened_graphplan) + + ## I think I have to go over all permutations of possbile partial graphplans + + for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack + + ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list + ## filtered_solution = self.filter(graphPlan_solution) # original + + filtered_solution = self.filter(possible_plan) # my mod + + print(f"TRYING FILTERED PLAN: {filtered_solution}") ## Bill's hack + + ## filtered_solution = self.filter(possible_plan) # mod + ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack + ## pnl(filtered_solution) + ## filtered_solution = possible_plan + + ordered_solution = [] + planning_problem = self.planning_problem + for level in filtered_solution: + + ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack + + ## the below is a key line, the key line + level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied + if not level_solution: # This checks if level_solution is None or an empty list + print(f"PLAN FAIL: {filtered_solution}") ## Bill's hack + continue ## Bill's hack!! if empty, continue looking. + + print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack + ##print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack + ## for action in level_solution: + ## print(f"APPLY ACTION: {action}") ## Bill's hack + ## planning_problem.act(action) # complete guess, apply action to the problem and keep going + + ## I think we need to apply the plan to the planning problem and modify it + for element in level_solution: + ordered_solution.append(element) + + if not ordered_solution: + continue ## no plan possible from the partial plan at the level + else: + print(f"WORKING SOL'N: {ordered_solution}") ## Bill's hack + break + + return ordered_solution + +""" +# GPT Modified + +class Linearize: + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + + def __str__(self): + return f"" + + def filter(self, solution): + "Filter out persistence actions from a solution" + + new_solution = [] + for section in solution[0]: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + new_solution.append(new_section) + return new_solution + def orderlevel(self, level, planning_problem): "Return valid linear order of actions for a given level" @@ -1173,26 +1452,7 @@ def orderlevel(self, level, planning_problem): # If no valid permutation was found after checking all possibilities return None, None - """ - - def execute(self): - "Finds total-order solution for a planning graph" - graphPlan_solution = GraphPlan(self.planning_problem).execute() - filtered_solution = self.filter(graphPlan_solution) - ordered_solution = [] - planning_problem = self.planning_problem - for level in filtered_solution: - level_solution, planning_problem = self.orderlevel(level, planning_problem) - # Handle empty level_solutions - if level_solution is None: - continue - for element in level_solution: - ordered_solution.append(element) - - return ordered_solution - - """ def execute(self): "Finds a total-order solution for a planning graph." # This might return multiple solutions, let's call it a list of "raw plans" @@ -1236,9 +1496,61 @@ def _filter(self, raw_plan): new_section.append(operation) new_solution.append(new_section) return new_solution - """ +""" + +""" +# ORIGINAL + +class Linearize: + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + + def filter(self, solution): + "Filter out persistence actions from a solution" + + new_solution = [] + for section in solution[0]: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + new_solution.append(new_section) + return new_solution + + def orderlevel(self, level, planning_problem): + "Return valid linear order of actions for a given level" + + for permutation in itertools.permutations(level): + temp = copy.deepcopy(planning_problem) + count = 0 + for action in permutation: + try: + temp.act(action) + count += 1 + except: + count = 0 + temp = copy.deepcopy(planning_problem) + break + if count == len(permutation): + return list(permutation), temp + return None + def execute(self): + "Finds total-order solution for a planning graph" + + graphPlan_solution = GraphPlan(self.planning_problem).execute() + filtered_solution = self.filter(graphPlan_solution) + ordered_solution = [] + planning_problem = self.planning_problem + for level in filtered_solution: + level_solution, planning_problem = self.orderlevel(level, planning_problem) + for element in level_solution: + ordered_solution.append(element) + return ordered_solution +""" + def linearize(solution): """Converts a level-ordered solution into a linear solution""" diff --git a/submission1.py b/submission1.py index c150f4f90..ca93fdcae 100644 --- a/submission1.py +++ b/submission1.py @@ -106,7 +106,9 @@ def logisticsPlanCustom(initial_state=None, goal_state=None): #print(GraphPlan(P).execute()) P = shopping_problem() - #print(GraphPlan(P).execute()) + #gplan = GraphPlan(P).execute() + #print(gplan) + print(Linearize(P).execute()) """ [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), @@ -114,7 +116,7 @@ def logisticsPlanCustom(initial_state=None, goal_state=None): [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] """ - print(Linearize(P).execute()) + #print(Linearize(P).execute()) """ Standard logistics environment diff --git a/submission1_test.py b/submission1_test.py index 00447dfaa..b120987c3 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -17,7 +17,7 @@ def test_blocksworld_manual(): assert sbw.goal_test() == True -def test_air_cargo(): +def ptest_air_cargo(): P = air_cargo() assert isinstance(Linearize(P).execute(), list) @@ -48,7 +48,7 @@ def test_socks_and_shoes(): P = socks_and_shoes() assert isinstance(Linearize(P).execute(), list) -def test_double_tennis_problem(): +def ptest_double_tennis_problem(): P = double_tennis_problem() #print(GraphPlan(P).execute()) assert isinstance(Linearize(P).execute(), list) @@ -84,7 +84,7 @@ def test_logistics_plan_valid(goal_state): "In(C1, D3) & In(C2, D3) & In(C3, D3)", "In(C1, D2) & In(C3, D3) & In(C2, D1)", ]) -def test_logistics_plan_no_plan(goal_state): +def ptest_logistics_plan_no_plan(goal_state): """These are known to have no valid plan.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" result = sub.logisticsPlanCustom(init, goal_state) @@ -95,7 +95,7 @@ def test_logistics_plan_no_plan(goal_state): @pytest.mark.parametrize("goal_state", [ "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)", ]) -def test_logistics_plan_kaboom(goal_state): +def ptest_logistics_plan_kaboom(goal_state): """This case is known to cause planner explosion. Catch and mark as expected failure.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" try: diff --git a/understanding_mutexes.md b/understanding_mutexes.md index e74610bd9..1fb5d231b 100644 --- a/understanding_mutexes.md +++ b/understanding_mutexes.md @@ -47,4 +47,51 @@ Has prior current state {Go(SM, HW), PAt(SM)}, {Go(Home, SM), Go(SM, HW)}, {Go(HW, SM), Go(SM, Home)}, {PNotAt(Home), Go(Home, HW)}, {PNotAt(Home), Go(Home, SM)}, {NotAt(Home), At(Home)}} # duplicate - All seem well, and sufficient + All seem well, and NOT sufficient + + + + + + +The issue is that: + + +At layer 1 (index -2), we have: + +print(self.levels[index].mutex) +[{PAt(Home), PNotAt(Home)}, {Go(Home, HW), PAt(Home)}, {Go(Home, SM), PAt(Home)}, {Go(HW, Home), PNotAt(Home)}, {Go(Home, HW), Go(HW, Home)}, {Go(Home, SM), Go(HW, Home)}, {PNotAt(Home), Go(SM, Home)}, {Go(Home, HW), Go(SM, Home)}, {Go(Home, SM), Go(SM, Home)}, {Go(HW, Home), PAt(HW)}, {PAt(HW), Go(HW, SM)}, {Go(Home, HW), Go(HW, SM)}, {Go(HW, Home), Go(SM, HW)}, {Go(SM, HW), Go(HW, SM)}, {Go(SM, HW), PAt(SM)}, {Go(SM, Home), PAt(SM)}, {Go(SM, Home), Go(HW, SM)}, {Go(Home, SM), Go(SM, HW)}, {Go(Home, HW), PNotAt(Home)}, {Go(Home, SM), PNotAt(Home)}, {At(Home), NotAt(Home)}] + +And our goal permutations is: + +print(list(goal_perm)) +[(At(SM), Sells(SM, Milk)), (At(SM), Store(SM)), (At(SM), Item(Milk)), (At(SM), At(SM)), (At(SM), Sells(SM, Banana)), (At(SM), Store(SM)), (At(SM), Item(Banana)), (At(SM), At(HW)), (At(SM), Sells(HW, Drill)), (At(SM), Store(HW)), (At(SM), Item(Drill)), (Sells(SM, Milk), Store(SM)), (Sells(SM, Milk), Item(Milk)), (Sells(SM, Milk), At(SM)), (Sells(SM, Milk), Sells(SM, Banana)), (Sells(SM, Milk), Store(SM)), (Sells(SM, Milk), Item(Banana)), (Sells(SM, Milk), At(HW)), (Sells(SM, Milk), Sells(HW, Drill)), (Sells(SM, Milk), Store(HW)), (Sells(SM, Milk), Item(Drill)), (Store(SM), Item(Milk)), (Store(SM), At(SM)), (Store(SM), Sells(SM, Banana)), (Store(SM), Store(SM)), (Store(SM), Item(Banana)), (Store(SM), At(HW)), (Store(SM), Sells(HW, Drill)), (Store(SM), Store(HW)), (Store(SM), Item(Drill)), (Item(Milk), At(SM)), (Item(Milk), Sells(SM, Banana)), (Item(Milk), Store(SM)), (Item(Milk), Item(Banana)), (Item(Milk), At(HW)), (Item(Milk), Sells(HW, Drill)), (Item(Milk), Store(HW)), (Item(Milk), Item(Drill)), (At(SM), Sells(SM, Banana)), (At(SM), Store(SM)), (At(SM), Item(Banana)), (At(SM), At(HW)), (At(SM), Sells(HW, Drill)), (At(SM), Store(HW)), (At(SM), Item(Drill)), (Sells(SM, Banana), Store(SM)), (Sells(SM, Banana), Item(Banana)), (Sells(SM, Banana), At(HW)), (Sells(SM, Banana), Sells(HW, Drill)), (Sells(SM, Banana), Store(HW)), (Sells(SM, Banana), Item(Drill)), (Store(SM), Item(Banana)), (Store(SM), At(HW)), (Store(SM), Sells(HW, Drill)), (Store(SM), Store(HW)), (Store(SM), Item(Drill)), (Item(Banana), At(HW)), (Item(Banana), Sells(HW, Drill)), (Item(Banana), Store(HW)), (Item(Banana), Item(Drill)), (At(HW), Sells(HW, Drill)), (At(HW), Store(HW)), (At(HW), Item(Drill)), (Sells(HW, Drill), Store(HW)), (Sells(HW, Drill), Item(Drill)), (Store(HW), Item(Drill))] + +Notably, including + +(At(SM), At(HW)) + +But, since we don't include our persistance state, it doesn't recognize the issue with this. + + + +Then + +we go to index -3, layer 0 + +print(supporting_actions_lists) +[[Go(Home, SM)], [PSells(SM, Milk)], [PStore(SM)], [PItem(Milk)], [Go(Home, SM)], [PSells(SM, Banana)], [PStore(SM)], [PItem(Banana)], [Go(Home, HW)], [PSells(HW, Drill)], [PStore(HW)], [PItem(Drill)]] + +our supporting actions includes + +[Go(Home, SM)], [Go(Home, HW)] + +But our mutexes only include: +[{Go(Home, HW), PAt(Home)}, {Go(Home, SM), PAt(Home)}] + +Shouldn't we have {Go(Home, HW), Go(Home, SM)} ? This would solve the issue... + + + + +WHY do we not have a {Go(Home, HW), Go(Home, SM)} mutex? \ No newline at end of file From e2f48d3230eb28104089133a1087b6feb6755c11 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 27 Sep 2025 17:33:35 -0400 Subject: [PATCH 04/19] Add action application to verify results --- planning.py | 25 ++++++++++++++++++++++ submission1.py | 34 ++++++----------------------- submission1_test.py | 52 ++++++++++++++++++++++----------------------- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/planning.py b/planning.py index a1bc18ff0..faa210fce 100644 --- a/planning.py +++ b/planning.py @@ -389,6 +389,31 @@ def three_block_tower(): domain='Block(b) & Block(x)')], domain='Block(A) & Block(B) & Block(C)') +def logisticsPlanCustom(initial_state=None, goal_state=None): + if initial_state == None: + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + if goal_state == None: + raise ValueError("Goal must be defined") + + planning_problem = \ + PlanningProblem(initial = initial_state, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r,d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') + + return planning_problem + def simple_blocks_world(): """ diff --git a/submission1.py b/submission1.py index ca93fdcae..db9d5c736 100644 --- a/submission1.py +++ b/submission1.py @@ -61,31 +61,6 @@ def logisticsPlan(): return linearize(GraphPlan(planning_problem).execute()) """ -def logisticsPlanCustom(initial_state=None, goal_state=None): - if initial_state == None: - initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - if goal_state == None: - raise ValueError("Goal must be defined") - - planning_problem = \ - PlanningProblem(initial = initial_state, - goals = goal_state, - actions=[Action('PickUp(r, c, d)', - precond='In(r, d) & In (c, d) & ~Holding(r)', - effect='Holding(r) & ~In(c, d) & In(c, r)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('PutDown(r, c, d)', - precond='In(r, d) & In(c, r) & Holding(r)', - effect='~Holding(r) & ~In(c, r) & In(c, d)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('Move(r, d_start, d_end)', - precond='In(r,d_start)', - effect='~In(r, d_start) & In(r, d_end)', - domain='Robot(r) & Place(d_start) & Place(d_end)')], - domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') - # END_YOUR_CODE - - return Linearize(planning_problem).execute() if __name__ == "__main__": @@ -105,10 +80,10 @@ def logisticsPlanCustom(initial_state=None, goal_state=None): #P = double_tennis_problem() #print(GraphPlan(P).execute()) - P = shopping_problem() + #P = shopping_problem() #gplan = GraphPlan(P).execute() #print(gplan) - print(Linearize(P).execute()) + #print(Linearize(P).execute()) """ [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), @@ -118,6 +93,11 @@ def logisticsPlanCustom(initial_state=None, goal_state=None): #print(Linearize(P).execute()) + #P = air_cargo() + P = double_tennis_problem() + print(GraphPlan(P).execute()) + #Linearize(P).execute() + """ Standard logistics environment Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1) diff --git a/submission1_test.py b/submission1_test.py index b120987c3..b847114b9 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -4,8 +4,6 @@ from logic import * import pytest -import submission1 as sub - def test_blocksworld_manual(): sbw = simple_blocks_world() @@ -17,42 +15,41 @@ def test_blocksworld_manual(): assert sbw.goal_test() == True +def verify_solution(P): + sol = Linearize(P).execute() + print(sol) + assert P.goal_test() == False + for act in sol: + P.act(expr(act)) + assert P.goal_test() == True + def ptest_air_cargo(): P = air_cargo() - assert isinstance(Linearize(P).execute(), list) + verify_solution(P) def test_spare_tire(): P = spare_tire() - assert isinstance(Linearize(P).execute(), list) - -def test_three_block_tower(): + verify_solution(P) + +def ptest_three_block_tower(): P = three_block_tower() - assert isinstance(Linearize(P).execute(), list) + verify_solution(P) def test_simple_blocks_world(): P = simple_blocks_world() - assert isinstance(Linearize(P).execute(), list) + verify_solution(P) def test_shopping_problem(): P = shopping_problem() - #print(GraphPlan(P).execute()) - """ - [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), - PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), - PItem(Drill), Go(Home, SM)], - [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] - """ - assert isinstance(Linearize(P).execute(), list) + verify_solution(P) def test_socks_and_shoes(): P = socks_and_shoes() - assert isinstance(Linearize(P).execute(), list) + verify_solution(P) def ptest_double_tennis_problem(): P = double_tennis_problem() - #print(GraphPlan(P).execute()) - assert isinstance(Linearize(P).execute(), list) - + verify_solution(P) @pytest.mark.parametrize("goal_state", [ "In(C1, D1)", @@ -73,9 +70,8 @@ def ptest_double_tennis_problem(): def test_logistics_plan_valid(goal_state): """These should yield a valid (non-crashing) plan, even if empty.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - result = sub.logisticsPlanCustom(init, goal_state) - assert result is None or isinstance(result, list) - + P = logisticsPlanCustom(init, goal_state) + verify_solution(P) @pytest.mark.parametrize("goal_state", [ "In(C2, D3) & In(C3, D3)", @@ -87,9 +83,10 @@ def test_logistics_plan_valid(goal_state): def ptest_logistics_plan_no_plan(goal_state): """These are known to have no valid plan.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - result = sub.logisticsPlanCustom(init, goal_state) + P = logisticsPlanCustom(init, goal_state) + sol = Linearize(P).execute() # Depending on your GraphPlan, no-plan might return [] or None - assert result in ([], None) + assert sol in ([], None) @pytest.mark.parametrize("goal_state", [ @@ -99,8 +96,9 @@ def ptest_logistics_plan_kaboom(goal_state): """This case is known to cause planner explosion. Catch and mark as expected failure.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" try: - result = sub.logisticsPlanCustom(init, goal_state) + P = logisticsPlanCustom(init, goal_state) + sol = Linearize(P).execute() # If it actually returns, that's fine too - assert result is None or isinstance(result, list) + assert sol is None or isinstance(sol, list) except Exception: pytest.xfail("Known kaboom case – planner explosion or unsolvable problem") \ No newline at end of file From 0fb3902befef650735760781a83908816f879c80 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 29 Sep 2025 11:03:50 -0400 Subject: [PATCH 05/19] Add changes, stuff doesn't work --- Screenshot from 2025-09-28 11-02-00.png | Bin 0 -> 80215 bytes planning.py | 159 +++++++++++++++++++----- submission1.py | 8 +- understanding_mutexes.md | 96 +++++++++++++- 4 files changed, 229 insertions(+), 34 deletions(-) create mode 100644 Screenshot from 2025-09-28 11-02-00.png diff --git a/Screenshot from 2025-09-28 11-02-00.png b/Screenshot from 2025-09-28 11-02-00.png new file mode 100644 index 0000000000000000000000000000000000000000..5821b6553976283840b9e885c6776af0129df643 GIT binary patch literal 80215 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 literal 0 HcmV?d00001 diff --git a/planning.py b/planning.py index faa210fce..14e864c5e 100644 --- a/planning.py +++ b/planning.py @@ -13,7 +13,6 @@ from search import Node from utils import Expr, expr, first - class PlanningProblem: """ Planning Domain Definition Language (PlanningProblem) used to define a search problem. @@ -468,7 +467,7 @@ def have_cake_and_eat_cake_too(): >>> """ - return PlanningProblem(initial='Have(Cake)', + return PlanningProblem(initial='Have(Cake) & ~Eaten(Cake)', goals='Have(Cake) & Eaten(Cake)', actions=[Action('Eat(Cake)', precond='Have(Cake)', @@ -627,18 +626,31 @@ def double_tennis_problem(): precond='At(actor, loc)', effect='At(actor, to) & ~At(actor, loc)')]) """ - + + """ return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), + initial='At(A, LeftBaseline) & At(B, RightNet) & Approaching(ball, RightBaseline)', + goals='At(A, LeftNet) & At(B, RightBaseline) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc) & CourtLoc(loc) & IsBall(ball) & isActor(actor)', + effect='Returned(ball)'), Action('Go(actor, to, loc)', - precond='At(actor, loc)', + precond='At(actor, loc) & CourtLoc(loc) & CourtLoc(to) & IsActor(actor)', effect='At(actor, to) & ~At(actor, loc)')], - domain='CourtLoc(LeftNet) & CourtLoc(RightNet) & CourtLoc(LeftBaseline) & CourtLoc(RightBaseline)' + domain='CourtLoc(LeftNet) & CourtLoc(RightNet) & CourtLoc(LeftBaseline) & CourtLoc(RightBaseline) & IsBall(ball) & IsActor(A) & IsActor(B)' ) + """ + + return PlanningProblem( + initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', + goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')], + domain="Loc(LeftBaseline)") class ForwardPlan(search.Problem): @@ -837,7 +849,7 @@ class Level: states as pre-condition. """ - def __init__(self, kb): + def __init__(self, kb, is_first_layer=False): """Initializes variables to hold state and action details of a level""" self.kb = kb @@ -863,11 +875,13 @@ def __init__(self, kb): # mutually exclusive actions self.mutex = [] - self.isfirstlayer = True - + self.is_first_layer = is_first_layer + self.prior_level = None + def __call__(self, actions, objects): self.build(actions, objects) self.find_mutex() + #self.deduplify() def __str__(self): state_str = ", ".join(str(s) for s in self.current_state) @@ -897,6 +911,10 @@ def separate(self, e): def find_mutex(self): "Finds mutually exclusive actions" + "This function is only entered after state, actions at this level are computed." + "Therefore, we're computing it for the current state and current (state+1) action layer" + + breakpoint() # Inconsistent effects - one action adds a literal that another deletes pos_nsl, neg_nsl = self.separate(self.next_state_links) @@ -909,6 +927,9 @@ def find_mutex(self): for b in self.next_state_links[negeff]: if {a, b} not in self.mutex: self.mutex.append({a, b}) + + breakpoint() + # Interference will be calculated with the last step # Interference - One action deletes a precondition or effect of another @@ -923,11 +944,16 @@ def find_mutex(self): for b in self.current_state_links[neg_precond]: if {a, b} not in self.mutex: self.mutex.append({a, b}) + + + breakpoint() # Only consider actual actions (not propositions) + """ action_keys = [a for a in self.next_action_links.keys() if not a.op.startswith("P")] - if self.isfirstlayer: + if self.is_first_layer: + #breakpoint() for a1, a2 in itertools.combinations(action_keys, 2): preconds_a1 = self.current_action_links.get(a1, []) preconds_a2 = self.current_action_links.get(a2, []) @@ -953,10 +979,12 @@ def find_mutex(self): mutex_pair = {a1, a2} if mutex_pair not in self.mutex: # <-- avoid duplicates self.mutex.append(mutex_pair) - - self.isfirstlayer = False - + + self.is_first_layer = False + """ + # Inconsistent support - two props cannot be true given competing supporting actions + """ state_mutex = [] for pair in self.mutex: next_state_0 = self.next_action_links[list(pair)[0]] @@ -966,8 +994,33 @@ def find_mutex(self): next_state_1 = self.next_action_links[list(pair)[0]] if (len(next_state_0) == 1) and (len(next_state_1) == 1): state_mutex.append({next_state_0[0], next_state_1[0]}) + """ + + # Inconsistent support - two props cannot be true given competing supporting actions + state_mutex = [] + for pair in self.mutex: # mutex is currently action-action mutexes + a1, a2 = list(pair) + #print("mutex pair: ", a1,a2) - self.mutex = self.mutex + state_mutex + # Get all effects of each action + effects_a1 = self.next_action_links.get(a1, []) + effects_a2 = self.next_action_links.get(a2, []) + + #print("ef1: ", effects_a1) + #print("ef2: ", effects_a2) + + # For every effect pair, mark propositions as mutex + for p1 in effects_a1: + for p2 in effects_a2: + mutex_pair = {p1, p2} + if mutex_pair not in state_mutex: + state_mutex.append(mutex_pair) + + #breakpoint() + self.state_mutex = state_mutex + + if self.prior_level and self.prior_level.state_mutex: + self.mutex = self.mutex + self.prior_level.state_mutex #print(self.current_state_links, self.current_action_links) @@ -1015,12 +1068,36 @@ def build(self, actions, objects): self.next_state_links[new_clause] = [new_action] def perform_actions(self): - """Performs the necessary actions and returns a new Level""" + "Performs the necessary actions and returns a new Level" # next_state_links.keys() will give the valid next states (the values would be all the actions that could cause it) new_kb = FolKB(list(set(self.next_state_links.keys()))) return Level(new_kb) + """ + def deduplify(self): + "Remove duplicate entries from state, actions, links, and mutex lists." + + # --- Deduplicate state --- + self.current_state = list(dict.fromkeys(self.current_state)) # order-preserving unique + + # --- Deduplicate links (values are lists of actions/states) --- + for mapping in [self.current_action_links, self.current_state_links, + self.next_action_links, self.next_state_links]: + for k, v in mapping.items(): + mapping[k] = list(dict.fromkeys(v)) # unique but keep order + + # --- Deduplicate mutex pairs --- + seen = set() + unique_mutex = [] + for pair in self.mutex: + # turn {a,b} into a frozenset so it’s hashable + frozen = frozenset(pair) + if frozen not in seen: + seen.add(frozen) + unique_mutex.append(pair) + self.mutex = unique_mutex + """ class Graph: """ @@ -1031,7 +1108,7 @@ class Graph: def __init__(self, planning_problem): self.planning_problem = planning_problem self.kb = FolKB(planning_problem.initial) - self.levels = [Level(self.kb)] + self.levels = [Level(self.kb, True)] self.objects = set(arg for clause in self.kb.clauses for arg in clause.args) def __call__(self): @@ -1052,11 +1129,27 @@ def __str__(self): def expand_graph(self): """Expands the graph by a level""" + #last_level = self.levels[-1] + #last_level(self.planning_problem.actions, self.objects) + #self.levels.append(last_level.perform_actions()) + + #breakpoint() + + """ + if hasattr(self, "notFirstRun"): # not the very first iteration + new_level = self.levels[-1].perform_actions() + if len(self.levels) > 0: + new_level.prior_level = self.levels[-1] + self.levels.append(new_level) + else: + self.notFirstRun = True + + # then continue as usual last_level = self.levels[-1] last_level(self.planning_problem.actions, self.objects) - self.levels.append(last_level.perform_actions()) + """ + - """ def non_mutex_goals(self, goals, index): "Checks whether the goals are mutually exclusive" @@ -1065,8 +1158,8 @@ def non_mutex_goals(self, goals, index): if set(g) in self.levels[index].mutex: return False return True - """ + """ def non_mutex_goals(self, goals, index): "Checks whether the goals are mutually exclusive recursively" @@ -1096,7 +1189,8 @@ def non_mutex_goals(self, goals, index): for goal in goals: # if the goal has no supporting actions in previous level, can't satisfy - if goal not in level.next_state_links: + #breakpoint() + if goal not in level.next_state_links.keys(): return False # Generate all combinations of supporting actions @@ -1119,7 +1213,7 @@ def non_mutex_goals(self, goals, index): # If no combination works, goals are mutex return False - + """ class GraphPlan: """ @@ -1133,6 +1227,9 @@ def __init__(self, planning_problem): self.no_goods = [] self.solution = [] + global isFirstLayer + isFirstLayer = True + def __str__(self): sol_str = ( "No solution found" @@ -1288,7 +1385,9 @@ def extract_solution(self, goals, index): return solution def goal_test(self, kb): - return all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) + goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) + #print(goal_achieved) + return goal_achieved def execute(self): """Executes the GraphPlan algorithm for the given problem""" @@ -1296,10 +1395,12 @@ def execute(self): print("Forward Search") while True: self.graph.expand_graph() - #print(self.graph) + print(self.graph) + print("Number of levels: ", len(self.graph.levels)) + #breakpoint() if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): - #breakpoint() + print("SOLVED, EXTRACTING SOLUTION") print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) #self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) @@ -1316,7 +1417,7 @@ def execute(self): #print(len(self.graph.levels)) if len(self.graph.levels) >= 2 and self.check_leveloff(): - breakpoint() + #breakpoint() return None diff --git a/submission1.py b/submission1.py index db9d5c736..94a482684 100644 --- a/submission1.py +++ b/submission1.py @@ -90,13 +90,13 @@ def logisticsPlan(): PItem(Drill), Go(Home, SM)], [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] """ - - #print(Linearize(P).execute()) + #P = shopping_problem() #P = air_cargo() - P = double_tennis_problem() + #P = double_tennis_problem() + P = have_cake_and_eat_cake_too() print(GraphPlan(P).execute()) - #Linearize(P).execute() + #print(Linearize(P).execute()) """ Standard logistics environment diff --git a/understanding_mutexes.md b/understanding_mutexes.md index 1fb5d231b..60b1256c0 100644 --- a/understanding_mutexes.md +++ b/understanding_mutexes.md @@ -94,4 +94,98 @@ Shouldn't we have {Go(Home, HW), Go(Home, SM)} ? This would solve the issue... -WHY do we not have a {Go(Home, HW), Go(Home, SM)} mutex? \ No newline at end of file +WHY do we not have a {Go(Home, HW), Go(Home, SM)} mutex? + + + +Forward Search + + Objects: {RightBaseline, LeftNet, LeftBaseline, RightBaseLine, B, LeftBaseLine, RightNet, Ball, A} +Level 0: + + Current State: + + {At(A, LeftBaseLine), At(B, RightNet), Approaching(Ball, RightBaseLine), Partner(A, B), Partner(B, A), CourtLoc(LeftNet), CourtLoc(RightNet), CourtLoc(LeftBaseline), CourtLoc(RightBaseline)} + + Actions: + + { + PAt(A, LeftBaseLine), + PAt(B, RightNet), + PApproaching(Ball, RightBaseLine), + PPartner(A, B), PPartner(B, A), + PCourtLoc(LeftNet), PCourtLoc(RightNet), PCourtLoc(LeftBaseline), PCourtLoc(RightBaseline), + + Go(B, RightBaseline, RightNet), Go(B, LeftNet, RightNet), Go(B, LeftBaseline, RightNet), Go(B, RightBaseLine, RightNet), Go(B, LeftBaseLine, RightNet), Go(B, Ball, RightNet), Go(B, A, RightNet), Go(A, RightBaseline, LeftBaseLine), Go(A, LeftNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine), Go(A, B, LeftBaseLine), Go(A, RightNet, LeftBaseLine), Go(A, Ball, LeftBaseLine)} + +# Too unconstrained + - Can go to ball? + - Duplicate actions + + Mutex: + + {{Go(B, RightBaseline, RightNet), PAt(B, RightNet)}, {Go(B, LeftNet, RightNet), PAt(B, RightNet)}, {Go(B, LeftBaseline, RightNet), PAt(B, RightNet)}, {Go(B, RightBaseLine, RightNet), PAt(B, RightNet)}, {Go(B, LeftBaseLine, RightNet), PAt(B, RightNet)}, {Go(B, Ball, RightNet), PAt(B, RightNet)}, {Go(B, A, RightNet), PAt(B, RightNet)}, {PAt(A, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, B, LeftBaseLine), PAt(A, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, RightNet, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, Ball, LeftBaseLine)}, {Go(B, LeftNet, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftBaseline, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, Ball, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, A, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, RightBaseLine, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, LeftNet, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, Ball, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, A, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, Ball, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftBaseline, RightNet), Go(B, A, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, RightBaseLine, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, Ball, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, A, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, Ball, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, A, RightNet)}, {Go(B, Ball, RightNet), Go(B, A, RightNet)}, {Go(A, LeftNet, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, LeftBaseline, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, LeftNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightNet, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, Ball, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, Ball, LeftBaseLine)}} + +![alt text]() + +1. We don't have !Eaten as a starting propostion, or ever .. should we? Do we need this? Note - we miss a mutex here b/c of it. +2. We have (Bake, Have) in our mutexes, they do not. Is this valid? +3. We have an invalid mutex {have} .... ? +4. We are missing (have, eaten) +5. Can we differentiate between different types of mutexes? I.e. state-state vs action-state, etc.? +6. We have duplicate (have, notHave) + + + +When I add in !Eaten in our start state + + +file:///home/carwyn/Pictures/Screenshots/Screenshot%20from%202025-09-28%2011-14-54.png + +1. We dont' have mutexes between (have, eaten), (!have, !eaten) in S1. + - Something is going wrong (lacking) in our inconsistent support checking + - Two propositions a,b should be mutex if every actions that produce a is mutex with every action that can produce b. +2. (bake, have) in a2 shouldn't exist + - This is correct - overriding SBU slides +3. (eat, !have) in a2 shouldn't exist + - This is correct - overriding SBU slides + + +https://www3.cs.stonybrook.edu/~sael/teaching/cse537/Slides/chapter10b.pdf +TODO: + - DONE: Remove my recursive backwards checker - it should be enough to just check final state mutexes + - Fix inconsistent support check + - Validate improvement on cake problem, where I expect to see mutexes between (have, eaten), (!have, !eaten) in S1 + - Debug shopping problem + + + + +ISSUE IDENTIFIED IN INCONSISTENT SUPPORT CHECK: +file:///home/carwyn/Pictures/Screenshots/Screenshot%20from%202025-09-28%2021-02-27.png + +Now I'm getting these concerning (incorrect) mutexes on level 2: + +{Eaten(Cake), Have(Cake)} +{Have(Cake)}, +{Eaten(Cake), NotHave(Cake)}, +{NotHave(Cake)} + +1. Enforce no single atom mutexes +2. Identify where these incorrect mutexes are coming in (note - they are valid on layer 1 ...) + +Level 1: + + Current State: {NotEaten(Cake), Eaten(Cake), Have(Cake), NotHave(Cake)} + Actions: {PNotEaten(Cake), PEaten(Cake), PHave(Cake), PNotHave(Cake), Eat(Cake), Bake(Cake)} + Mutex: {{PEaten(Cake), PNotEaten(Cake)}, {Eat(Cake), PNotEaten(Cake)}, {PNotHave(Cake), PHave(Cake)}, {Eat(Cake), PHave(Cake)}, {PNotHave(Cake), Bake(Cake)}, {Bake(Cake), Eat(Cake)}, {Bake(Cake), PHave(Cake)}, {PNotHave(Cake), Eat(Cake)}, {NotEaten(Cake), Eaten(Cake)}, {NotEaten(Cake), NotHave(Cake)}, {Have(Cake), NotHave(Cake)}, {Eaten(Cake), Have(Cake)}, {Have(Cake)}, {Eaten(Cake), NotHave(Cake)}, {NotHave(Cake)}} + + + Mutex: {{PEaten(Cake), PNotEaten(Cake)}, {Eat(Cake), PNotEaten(Cake)}, {PNotHave(Cake), PHave(Cake)}, {Eat(Cake), PHave(Cake)}, {PNotHave(Cake), Bake(Cake)}, {Eat(Cake), Bake(Cake)}, {Bake(Cake), PHave(Cake)}, {PNotHave(Cake), Eat(Cake)}, {Eaten(Cake), NotEaten(Cake)}, {NotEaten(Cake), NotHave(Cake)}, {Eaten(Cake), Have(Cake)}, {Have(Cake), NotHave(Cake)}} + + Probably issue: + - propositions are maintained in mutexes similarly to actions. I dont' think I'm accounting for this difference when I move to the next state level + - do we even have the correct logic for moving from action levels to state levels? + + + I think we conclude at s2 because we can satisfy with eat -> bake \ No newline at end of file From 7a3ad7ccead9046409662e65a92586eadcf584f6 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 29 Sep 2025 12:25:47 -0400 Subject: [PATCH 06/19] I have made the formulation understandable now. Each level is grouped by a state and consecutive next action level. Our is our action mutexes, and our state mutex is computed by our previous state. So, when we first enter a level, we have our state mutexes (so we can check for goal state), then we nullify them and compute our action mutexes, and then we compute the next levels state mutexes based on our current action mutexes and next state. There is still at least one issue. --- Screenshot from 2025-09-29 11-24-54.png | Bin 0 -> 99722 bytes planning.py | 94 ++++++++++++------------ understanding_mutexes.md | 6 +- 3 files changed, 51 insertions(+), 49 deletions(-) create mode 100644 Screenshot from 2025-09-29 11-24-54.png diff --git a/Screenshot from 2025-09-29 11-24-54.png b/Screenshot from 2025-09-29 11-24-54.png new file mode 100644 index 0000000000000000000000000000000000000000..dfddfc7187473c5d62ddde882a987c4fbf8e91f4 GIT binary patch literal 99722 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 literal 0 HcmV?d00001 diff --git a/planning.py b/planning.py index 14e864c5e..1e5b7e95d 100644 --- a/planning.py +++ b/planning.py @@ -876,7 +876,7 @@ def __init__(self, kb, is_first_layer=False): self.mutex = [] self.is_first_layer = is_first_layer - self.prior_level = None + self.next_state_mutexes = [] def __call__(self, actions, objects): self.build(actions, objects) @@ -892,6 +892,7 @@ def __str__(self): f" Current State: {{{state_str}}}\n" f" Actions: {{{action_str}}}\n" f" Mutex: {{{mutex_str}}}\n" + f" Next state mutexes: {{{self.next_state_mutexes}}}\n" ) __repr__ = __str__ @@ -914,7 +915,8 @@ def find_mutex(self): "This function is only entered after state, actions at this level are computed." "Therefore, we're computing it for the current state and current (state+1) action layer" - breakpoint() + #breakpoint() + self.mutex = [] # clear out effects from state mutex prior computation # Inconsistent effects - one action adds a literal that another deletes pos_nsl, neg_nsl = self.separate(self.next_state_links) @@ -928,9 +930,6 @@ def find_mutex(self): if {a, b} not in self.mutex: self.mutex.append({a, b}) - breakpoint() - - # Interference will be calculated with the last step # Interference - One action deletes a precondition or effect of another pos_csl, neg_csl = self.separate(self.current_state_links) @@ -945,9 +944,6 @@ def find_mutex(self): if {a, b} not in self.mutex: self.mutex.append({a, b}) - - breakpoint() - # Only consider actual actions (not propositions) """ action_keys = [a for a in self.next_action_links.keys() if not a.op.startswith("P")] @@ -996,33 +992,46 @@ def find_mutex(self): state_mutex.append({next_state_0[0], next_state_1[0]}) """ + #breakpoint() + + + def populate_prop_mutexes(self): + "Compute the next level's proposition mutexes based on our current action mutexes" # Inconsistent support - two props cannot be true given competing supporting actions + + # self.next_action_links is a map from {next_state: [actions_leading_there]} + # We want to choose two next states, and add a mutex if all actions leading there are mutex state_mutex = [] - for pair in self.mutex: # mutex is currently action-action mutexes - a1, a2 = list(pair) - #print("mutex pair: ", a1,a2) - - # Get all effects of each action - effects_a1 = self.next_action_links.get(a1, []) - effects_a2 = self.next_action_links.get(a2, []) + next_state_pairs = itertools.combinations(self.next_state_links.keys(), 2) + for next_state_pair in list(next_state_pairs): + s1, s2 = list(next_state_pair) + acts_to_s1 = self.next_state_links.get(s1, []) + acts_to_s2 = self.next_state_links.get(s2, []) - #print("ef1: ", effects_a1) - #print("ef2: ", effects_a2) - - # For every effect pair, mark propositions as mutex - for p1 in effects_a1: - for p2 in effects_a2: - mutex_pair = {p1, p2} + # ensure our mutexes only apply to pairs, not single states. + if acts_to_s1 == [] or acts_to_s2 == []: + continue + + # if any two actions that lead to these states is not mutex, do not add a mutex to these states. + if not any([{a1,a2} not in self.mutex and {a2,a1} not in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): + mutex_pair = {s1, s2} + if mutex_pair not in state_mutex: + state_mutex.append(mutex_pair) + + # If there are pairs of propositions that are negations of each other, they need to be mutex + for s1i in range(len(self.current_state)): + for s2i in range(1,len(self.current_state)): + s1, s2 = self.current_state[s1i], self.current_state[s2i] + if repr(s2)[0:3] == "Not" and repr(s1) == repr(s2)[3:] or repr(s1)[0:3] == "Not" and repr(s1)[3:] == repr(s2): + mutex_pair = {s1, s2} if mutex_pair not in state_mutex: state_mutex.append(mutex_pair) - - #breakpoint() - self.state_mutex = state_mutex - - if self.prior_level and self.prior_level.state_mutex: - self.mutex = self.mutex + self.prior_level.state_mutex - #print(self.current_state_links, self.current_action_links) + + #breakpoint() + self.next_state_mutexes = state_mutex + return state_mutex + def build(self, actions, objects): """Populates the lists and dictionaries containing the state action dependencies""" @@ -1072,7 +1081,9 @@ def perform_actions(self): # next_state_links.keys() will give the valid next states (the values would be all the actions that could cause it) new_kb = FolKB(list(set(self.next_state_links.keys()))) - return Level(new_kb) + new_level = Level(new_kb) + + return new_level """ def deduplify(self): @@ -1129,27 +1140,14 @@ def __str__(self): def expand_graph(self): """Expands the graph by a level""" - #last_level = self.levels[-1] - #last_level(self.planning_problem.actions, self.objects) - #self.levels.append(last_level.perform_actions()) - - #breakpoint() - - """ - if hasattr(self, "notFirstRun"): # not the very first iteration - new_level = self.levels[-1].perform_actions() - if len(self.levels) > 0: - new_level.prior_level = self.levels[-1] - self.levels.append(new_level) - else: - self.notFirstRun = True - - # then continue as usual last_level = self.levels[-1] last_level(self.planning_problem.actions, self.objects) - """ - + new_level = last_level.perform_actions() + new_level.mutex = last_level.populate_prop_mutexes() + self.levels.append(new_level) + #breakpoint() + def non_mutex_goals(self, goals, index): "Checks whether the goals are mutually exclusive" diff --git a/understanding_mutexes.md b/understanding_mutexes.md index 60b1256c0..b1b0499e2 100644 --- a/understanding_mutexes.md +++ b/understanding_mutexes.md @@ -188,4 +188,8 @@ Level 1: - do we even have the correct logic for moving from action levels to state levels? - I think we conclude at s2 because we can satisfy with eat -> bake \ No newline at end of file + I think we conclude at s2 because we can satisfy with eat -> bake + + + + It's frustrating that they don't differentiate between state and action levels \ No newline at end of file From 5234d7b90e4aff8c690aecc7a55b2db17f233069 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 29 Sep 2025 13:10:20 -0400 Subject: [PATCH 07/19] Cake problem works now. On to debugging shopping problem ); --- Screenshot from 2025-09-28 11-02-00.png | Bin 80215 -> 0 bytes Screenshot from 2025-09-29 11-24-54.png | Bin 99722 -> 0 bytes cake_example_graph.png | Bin 0 -> 100204 bytes cake_problem_graph2.png | Bin 0 -> 100010 bytes cake_problem_graph3.png | Bin 0 -> 104394 bytes planning.py | 41 +++++++++++++++++++++--- submission1_test.py | 6 ++-- 7 files changed, 40 insertions(+), 7 deletions(-) delete mode 100644 Screenshot from 2025-09-28 11-02-00.png delete mode 100644 Screenshot from 2025-09-29 11-24-54.png create mode 100644 cake_example_graph.png create mode 100644 cake_problem_graph2.png create mode 100644 cake_problem_graph3.png diff --git a/Screenshot from 2025-09-28 11-02-00.png b/Screenshot from 2025-09-28 11-02-00.png deleted file mode 100644 index 5821b6553976283840b9e885c6776af0129df643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80215 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 diff --git a/Screenshot from 2025-09-29 11-24-54.png b/Screenshot from 2025-09-29 11-24-54.png deleted file mode 100644 index dfddfc7187473c5d62ddde882a987c4fbf8e91f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99722 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 diff --git a/cake_example_graph.png b/cake_example_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..8f95169a6929120819816b42143cd46360d25035 GIT binary patch literal 100204 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𝔴LcA%K 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 literal 0 HcmV?d00001 diff --git a/cake_problem_graph2.png b/cake_problem_graph2.png new file mode 100644 index 0000000000000000000000000000000000000000..28d2420e1aaa2de92fc4d71167ef5b8123ce5c36 GIT binary patch literal 100010 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%0D^( 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 literal 0 HcmV?d00001 diff --git a/cake_problem_graph3.png b/cake_problem_graph3.png new file mode 100644 index 0000000000000000000000000000000000000000..ba0ca7be935963902525f99d7b14a5db5a0d3129 GIT binary patch literal 104394 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¥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


gJ0{y2|0-0{RqJKnw`t`lgb&TTR@}toAt076j`P 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 literal 0 HcmV?d00001 diff --git a/planning.py b/planning.py index 1e5b7e95d..38a018f54 100644 --- a/planning.py +++ b/planning.py @@ -877,6 +877,7 @@ def __init__(self, kb, is_first_layer=False): self.is_first_layer = is_first_layer self.next_state_mutexes = [] + self.state_mutexes = [] def __call__(self, actions, objects): self.build(actions, objects) @@ -916,6 +917,7 @@ def find_mutex(self): "Therefore, we're computing it for the current state and current (state+1) action layer" #breakpoint() + self.state_mutexes = self.mutex # save state mutexes self.mutex = [] # clear out effects from state mutex prior computation # Inconsistent effects - one action adds a literal that another deletes @@ -930,11 +932,15 @@ def find_mutex(self): if {a, b} not in self.mutex: self.mutex.append({a, b}) - # Interference will be calculated with the last step + # Interference will be calculated with the last step ??? # Interference - One action deletes a precondition or effect of another - pos_csl, neg_csl = self.separate(self.current_state_links) + # Competing needs - preconditions of two actions are mutex at previous proposition layer + """ + pos_csl, neg_csl = self.separate(self.current_state_links) + # Why are we looking at syntactic components (negation)??? + breakpoint() for pos_precond in pos_csl: for neg_precond in neg_csl: new_neg_precond = Expr(neg_precond.op[3:], *neg_precond.args) @@ -943,9 +949,36 @@ def find_mutex(self): for b in self.current_state_links[neg_precond]: if {a, b} not in self.mutex: self.mutex.append({a, b}) - - # Only consider actual actions (not propositions) """ + + # Competing Needs + # self.current_state_links = map from current state vars -> actions applicable + # self.current_action_links = map from current actions -> starting states + + # Implement here: Iterate over all valid pairs of actions, and if the states they come from are mutex (use self.state_mutexes), add a mutex pair to self.mutex + # Competing Needs - two actions are mutex if any of their preconditions are mutex at the previous state level + for a1, a2 in itertools.combinations(self.current_action_links.keys(), 2): + preconds_a1 = self.current_action_links[a1] # states + preconds_a2 = self.current_action_links[a2] + + #if len(preconds_a1) > 1 or len(preconds_a2) > 1: + # print("An action has multiple preconditions (state)? Is the following logic implemented correctly? I think so") + + # check all pairs of preconditions + for p in preconds_a1: + for q in preconds_a2: + if {p, q} in self.state_mutexes: + mutex_pair = {a1, a2} + if mutex_pair not in self.mutex: + self.mutex.append(mutex_pair) + # no need to keep checking once we've marked them + break + else: + continue + break + + """ + # Only consider actual actions (not propositions) action_keys = [a for a in self.next_action_links.keys() if not a.op.startswith("P")] if self.is_first_layer: diff --git a/submission1_test.py b/submission1_test.py index b847114b9..f6d104632 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -23,7 +23,7 @@ def verify_solution(P): P.act(expr(act)) assert P.goal_test() == True -def ptest_air_cargo(): +def test_air_cargo(): P = air_cargo() verify_solution(P) @@ -31,7 +31,7 @@ def test_spare_tire(): P = spare_tire() verify_solution(P) -def ptest_three_block_tower(): +def test_three_block_tower(): P = three_block_tower() verify_solution(P) @@ -80,7 +80,7 @@ def test_logistics_plan_valid(goal_state): "In(C1, D3) & In(C2, D3) & In(C3, D3)", "In(C1, D2) & In(C3, D3) & In(C2, D1)", ]) -def ptest_logistics_plan_no_plan(goal_state): +def test_logistics_plan_no_plan(goal_state): """These are known to have no valid plan.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" P = logisticsPlanCustom(init, goal_state) From 5fbbc85bf941e12426ab5c103ed5438358004377 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 29 Sep 2025 23:24:29 -0400 Subject: [PATCH 08/19] If I ever see GraphPlan in a dark alley it's not leaving alive. ... but tests seem to pass??? Not sure if actually correct or my drowsiness is making it look like greeon on my screen --- planning.py | 180 ++++++++++++++++++++++++++++++++++--------------- submission1.py | 28 +++++++- 2 files changed, 151 insertions(+), 57 deletions(-) diff --git a/planning.py b/planning.py index 38a018f54..f2184846c 100644 --- a/planning.py +++ b/planning.py @@ -877,6 +877,8 @@ def __init__(self, kb, is_first_layer=False): self.is_first_layer = is_first_layer self.next_state_mutexes = [] + + # mutually exclusive states self.state_mutexes = [] def __call__(self, actions, objects): @@ -975,43 +977,48 @@ def find_mutex(self): break else: continue - break + break + + # Interference + # Example - in shopping, ensure Move(Home,HW) and Move(Home,SM) are both mutex in L0 - """ - # Only consider actual actions (not propositions) - action_keys = [a for a in self.next_action_links.keys() if not a.op.startswith("P")] + # current_action_links = current action -> current state map - if self.is_first_layer: - #breakpoint() - for a1, a2 in itertools.combinations(action_keys, 2): - preconds_a1 = self.current_action_links.get(a1, []) - preconds_a2 = self.current_action_links.get(a2, []) - effects_a1 = self.next_action_links.get(a1, []) - effects_a2 = self.next_action_links.get(a2, []) - - # Check for interference - interference = False - for p1 in preconds_a1: - if Expr("Not" + p1.op, *p1.args) in effects_a2: - interference = True - for p2 in preconds_a2: - if Expr("Not" + p2.op, *p2.args) in effects_a1: - interference = True - for e1 in effects_a1: - if Expr("Not" + e1.op, *e1.args) in effects_a2: - interference = True - for e2 in effects_a2: - if Expr("Not" + e2.op, *e2.args) in effects_a1: - interference = True - - if interference: - mutex_pair = {a1, a2} - if mutex_pair not in self.mutex: # <-- avoid duplicates - self.mutex.append(mutex_pair) - - self.is_first_layer = False - """ + savemutextemp = copy.copy(self.mutex) + + for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): + preconds_a1 = self.current_action_links.get(a1, []) + preconds_a2 = self.current_action_links.get(a2, []) + effects_a1 = self.next_action_links.get(a1, []) + effects_a2 = self.next_action_links.get(a2, []) + # Check for interference + interference = False + # Check if a precondition of one action is negated by effect of another + for p1 in preconds_a1: + if Expr("Not" + p1.op, *p1.args) in effects_a2: + interference = True + for p2 in preconds_a2: + if Expr("Not" + p2.op, *p2.args) in effects_a1: + interference = True + # Check if effect of one action is negated by effect of other action (inconsistent effects?) + """ + for e1 in effects_a1: + if Expr("Not" + e1.op, *e1.args) in effects_a2: + interference = True + for e2 in effects_a2: + if Expr("Not" + e2.op, *e2.args) in effects_a1: + interference = True + """ + + if interference: + mutex_pair = {a1, a2} + if mutex_pair not in self.mutex: # <-- avoid duplicates + self.mutex.append(mutex_pair) + + print([x for x in self.mutex if x not in savemutextemp]) + #breakpoint() + # Inconsistent support - two props cannot be true given competing supporting actions """ state_mutex = [] @@ -1065,6 +1072,64 @@ def populate_prop_mutexes(self): self.next_state_mutexes = state_mutex return state_mutex + def prune_invalid_actions(self): + """Remove actions whose own preconditions are mutex (unsupportable).""" + to_remove = [] + + # Debug + # breakpoint() + # print("STATE_MUTEXES:", self.state_mutexes) + + # Normalize state mutex set for fast membership checks: + # state_mutex_lookup contains frozenset pairs like frozenset({p,q}) + state_mutex_lookup = set() + for m in self.state_mutexes: + # m might already be a set/frozenset or possibly a tuple depending on other code + state_mutex_lookup.add(frozenset(m)) + + for action, preconds in list(self.current_action_links.items()): + invalid = False + # show debug info if you want: + # print(action, preconds, list(itertools.combinations(preconds, 2))) + + for p1, p2 in itertools.combinations(preconds, 2): + if frozenset({p1, p2}) in state_mutex_lookup: + invalid = True + break + + if invalid: + to_remove.append(action) + + # Debug + #print("REMOVING: ", to_remove) + #breakpoint() + + # Remove invalid actions from all mappings + for action in to_remove: + # forward mappings + self.current_action_links.pop(action, None) + self.next_action_links.pop(action, None) + + # reverse mapping: state -> actions (current_state_links) + for precond in list(self.current_state_links.keys()): + actions_for_pre = self.current_state_links.get(precond, []) + if action in actions_for_pre: + actions_for_pre.remove(action) + # if no more actions support this precond, drop the key + if not actions_for_pre: + self.current_state_links.pop(precond, None) + else: + self.current_state_links[precond] = actions_for_pre + + # reverse mapping: next_state -> actions (next_state_links) + for effect in list(self.next_state_links.keys()): + actions_for_eff = self.next_state_links.get(effect, []) + if action in actions_for_eff: + actions_for_eff.remove(action) + if not actions_for_eff: + self.next_state_links.pop(effect, None) + else: + self.next_state_links[effect] = actions_for_eff def build(self, actions, objects): """Populates the lists and dictionaries containing the state action dependencies""" @@ -1075,7 +1140,7 @@ def build(self, actions, objects): self.next_action_links[p_expr] = [clause] self.current_state_links[clause] = [p_expr] self.next_state_links[clause] = [p_expr] - + for a in actions: num_args = len(a.args) possible_args = tuple(itertools.permutations(objects, num_args)) @@ -1174,9 +1239,10 @@ def expand_graph(self): """Expands the graph by a level""" last_level = self.levels[-1] - last_level(self.planning_problem.actions, self.objects) - new_level = last_level.perform_actions() - new_level.mutex = last_level.populate_prop_mutexes() + last_level(self.planning_problem.actions, self.objects) # populate state/actions/mutexes + last_level.prune_invalid_actions() + new_level = last_level.perform_actions() # Create new level + new_level.mutex = last_level.populate_prop_mutexes() # Populate the mutexes for the next state level to come self.levels.append(new_level) #breakpoint() @@ -1284,7 +1350,6 @@ def check_leveloff(self): if check: return True - """ def extract_solution(self, goals, index): "Extracts the solution" @@ -1298,13 +1363,14 @@ def extract_solution(self, goals, index): #print(f" Mutexes: \n {level.mutex}") # Create all combinations of actions that satisfy the goal + #breakpoint() actions = [] for goal in goals: actions.append(level.next_state_links[goal]) all_actions = list(itertools.product(*actions)) #print(f" ALL ACTION COMBINATIONS at level {index-1}:") - #for a in all_actions: + ##for a in all_actions: #print(" ", a) # Filter out non-mutex actions @@ -1312,15 +1378,17 @@ def extract_solution(self, goals, index): for action_tuple in all_actions: action_pairs = itertools.combinations(list(set(action_tuple)), 2) non_mutex_actions.append(list(set(action_tuple))) - acts = list(set(action_tuple)) + #acts = list(set(action_tuple)) #print(f"CHECKING tuple {acts} at level {index-1}") - for pair in action_pairs: + for pair in list(action_pairs): #print(" testing pair", pair, "mutex?", frozenset(pair) in level.mutex) if set(pair) in level.mutex: non_mutex_actions.pop(-1) - break - + break #? + #print(f"NON-MUTEX ACTION SETS at level {index}: {non_mutex_actions}") + #print(len(non_mutex_actions), non_mutex_actions) + #breakpoint() # Recursion for action_list in non_mutex_actions: @@ -1352,12 +1420,12 @@ def extract_solution(self, goals, index): for num, item in enumerate(solution): item.reverse() solution[num] = item - + return solution - """ + """ def extract_solution(self, goals, index): - """Extracts the solution""" + "Extracts the solution" level = self.graph.levels[index] if not self.graph.non_mutex_goals(goals, index): @@ -1414,11 +1482,13 @@ def extract_solution(self, goals, index): solution[num] = item return solution + """ def goal_test(self, kb): goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) #print(goal_achieved) return goal_achieved + def execute(self): """Executes the GraphPlan algorithm for the given problem""" @@ -1427,20 +1497,20 @@ def execute(self): while True: self.graph.expand_graph() print(self.graph) - print("Number of levels: ", len(self.graph.levels)) + #print("Number of levels: ", len(self.graph.levels)) #breakpoint() if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): print("SOLVED, EXTRACTING SOLUTION") - print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) + #print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) #self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) - print(self.graph) - print("Last level state:", self.graph.levels[-1].current_state) - print("Last level mutexes:", self.graph.levels[-1].mutex) - print("Next state links:", self.graph.levels[-1].next_state_links) - print("Current action links:", self.graph.levels[-1].current_action_links) - print("Extract Solution") + #print(self.graph) + #print("Last level state:", self.graph.levels[-1].current_state) + #print("Last level mutexes:", self.graph.levels[-1].mutex) + #print("Next state links:", self.graph.levels[-1].next_state_links) + #print("Current action links:", self.graph.levels[-1].current_action_links) + #print(f"Extract Solution from {len(self.graph.levels)} levels, {len(self.graph.levels) - 1} actions") solution = self.extract_solution(self.graph.planning_problem.goals, -1) if solution: print(f"SOLUTION::::!!!!!!!!!!!!!!!!\n{solution}") diff --git a/submission1.py b/submission1.py index 94a482684..43d543a62 100644 --- a/submission1.py +++ b/submission1.py @@ -92,11 +92,35 @@ def logisticsPlan(): """ #P = shopping_problem() - #P = air_cargo() + P = air_cargo() #P = double_tennis_problem() - P = have_cake_and_eat_cake_too() + #P = have_cake_and_eat_cake_too() + #init = "In(C1, R1) & In(C2, D2) & In(R1, D1) & Holding(R1)" + #goal_state = "In(C2, D1)" + #P = logisticsPlanCustom(init, goal_state) + + # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. + """ + P = PlanningProblem(initial = init, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r,d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Place(D1) & Place(D2) & Robot(R1)') + """ + print(GraphPlan(P).execute()) #print(Linearize(P).execute()) + """ Standard logistics environment From 60d33ea6aab5a9006ee8d31b7f4a7df07016f062 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 29 Sep 2025 23:34:55 -0400 Subject: [PATCH 09/19] Now I'm confused about some of the tests. ... tennis problem also fails btw --- submission1.py | 8 ++++---- submission1_test.py | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/submission1.py b/submission1.py index 43d543a62..cc8f19c0e 100644 --- a/submission1.py +++ b/submission1.py @@ -92,12 +92,12 @@ def logisticsPlan(): """ #P = shopping_problem() - P = air_cargo() + #P = air_cargo() #P = double_tennis_problem() #P = have_cake_and_eat_cake_too() - #init = "In(C1, R1) & In(C2, D2) & In(R1, D1) & Holding(R1)" - #goal_state = "In(C2, D1)" - #P = logisticsPlanCustom(init, goal_state) + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + goal_state = "In(C1, D2) & In(C3, D3)" + P = logisticsPlanCustom(init, goal_state) # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. """ diff --git a/submission1_test.py b/submission1_test.py index f6d104632..4bd02020a 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -73,12 +73,12 @@ def test_logistics_plan_valid(goal_state): P = logisticsPlanCustom(init, goal_state) verify_solution(P) -@pytest.mark.parametrize("goal_state", [ +@pytest.mark.parametrize("goal_state", [ # Why don't any of these have a solution? "In(C2, D3) & In(C3, D3)", "In(C3, D3) & In(C2, D3)", - "In(C1, D2) & In(C3, D3)", + "In(C1, D2) & In(C3, D3)", # Why doesn't this have a solution? It finds one ... "In(C1, D3) & In(C2, D3) & In(C3, D3)", - "In(C1, D2) & In(C3, D3) & In(C2, D1)", + "In(C1, D2) & In(C3, D3) & In(C2, D1)", # Why doesn't this also have a solutioN? it finds one ]) def test_logistics_plan_no_plan(goal_state): """These are known to have no valid plan.""" @@ -86,13 +86,14 @@ def test_logistics_plan_no_plan(goal_state): P = logisticsPlanCustom(init, goal_state) sol = Linearize(P).execute() # Depending on your GraphPlan, no-plan might return [] or None - assert sol in ([], None) + #assert sol in ([], None) + verify_solution(P) @pytest.mark.parametrize("goal_state", [ "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)", ]) -def ptest_logistics_plan_kaboom(goal_state): +def test_logistics_plan_kaboom(goal_state): """This case is known to cause planner explosion. Catch and mark as expected failure.""" init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" try: From cb71b641c2e9004f47c47ca1e5fe96243ab4ae9a Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Tue, 30 Sep 2025 15:14:51 -0400 Subject: [PATCH 10/19] Improved extract_solution --- debugging_air_cargo | 60 +++++ ...l_failure_causes_tennis_simple2_to_fail.md | 22 ++ planning.py | 235 ++++++++++++++---- submission1.py | 10 +- submission1_test.py | 52 ++-- 5 files changed, 294 insertions(+), 85 deletions(-) create mode 100644 debugging_air_cargo create mode 100644 pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md diff --git a/debugging_air_cargo b/debugging_air_cargo new file mode 100644 index 000000000..669ee2cd7 --- /dev/null +++ b/debugging_air_cargo @@ -0,0 +1,60 @@ +Look at current goals + - Index = -1, len(self.graph.levels) = 3 + +Add action sets that lead to each goal in goal state into actions list (one of each of these actions must be true) + - (Pdb) print(action_list) + - [Unload(C2, P2, SFO), Unload(C1, P1, JFK)] +Get sets of actions such that each set has one action from each of these lists (i.e. the cartesian product, done with itertools.product) +Filter out mutex action pairs + - At this point, we NEED at least one set of actions to be non-mutex in order to find a valid way to get to that next state. + +Update self.solution with these new goal actions +Identify states that have these actions applicable. Add these states to "new_goals" + - Unload(C2, P2, SFO): [In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO)] + - Unload(C1, P1, JFK): [In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] + +(Pdb) print(new_goals) +[In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO), In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] + +self.extract_solution(new_goals, index - 1) + - [In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO), In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] -2 + + (Pdb) print(actions) +[[Load(C2, P2, JFK)], [Fly(P2, JFK, SFO)], [PCargo(C2)], [PPlane(P2)], [PAirport(SFO)], [Load(C1, P1, SFO)], [Fly(P1, SFO, JFK)], [PCargo(C1)], [PPlane(P1)], [PAirport(JFK)]] + +None are non-mutex !!!!!!!!!!!!!!!!!!!!!!!!!! DEBUG + +(Pdb) print(all_actions) +[(Load(C2, P2, JFK), Fly(P2, JFK, SFO), PCargo(C2), PPlane(P2), PAirport(SFO), Load(C1, P1, SFO), Fly(P1, SFO, JFK), PCargo(C1), PPlane(P1), PAirport(JFK))] + +(Pdb) print(list(action_pairs)) +[(Load(C1, P1, SFO), Load(C2, P2, JFK)), (Load(C1, P1, SFO), PAirport(JFK)), (PAirport(SFO), Fly(P2, JFK, SFO)), (PAirport(SFO), PCargo(C1)), (PAirport(SFO), PPlane(P2)), (PAirport(SFO), Fly(P1, SFO, JFK)), (PAirport(SFO), Load(C2, P2, JFK)), (PAirport(SFO), PAirport(JFK)), (Fly(P2, JFK, SFO), PCargo(C1)), (Fly(P2, JFK, SFO), PPlane(P2)), (Fly(P2, JFK, SFO), Fly(P1, SFO, JFK)), (Fly(P2, JFK, SFO), Load(C2, P2, JFK)), (Fly(P2, JFK, SFO), PAirport(JFK)), (PCargo(C1), PPlane(P2)), (PCargo(C1), Fly(P1, SFO, JFK)), (PCargo(C1), Load(C2, P2, JFK)), (PCargo(C1), PAirport(JFK)), (PPlane(P2), Fly(P1, SFO, JFK)), (PPlane(P2), Load(C2, P2, JFK)), (PPlane(P2), PAirport(JFK)), (Fly(P1, SFO, JFK), Load(C2, P2, JFK)), (Fly(P1, SFO, JFK), PAirport(JFK)), (Load(C2, P2, JFK), PAirport(JFK))] + - (Fly(P2, JFK, SFO), Fly(P1, SFO, JFK)) + +(Pdb) print(level.mutex) +[{Load(C2, P2, JFK), PAt(C2, JFK)}, {PAt(C1, SFO), Load(C1, P1, SFO)}, {Fly(P1, SFO, JFK), PAt(P1, SFO)}, {PAt(P2, JFK), Fly(P2, JFK, SFO)}, {Load(C2, P2, JFK), Fly(P2, JFK, SFO)}, {Fly(P1, SFO, JFK), Load(C1, P1, SFO)}] + - + + + + Observable issue: + +Final layer has state `At(C1, JFK) & At(C2, SFO)` non-mutex + +At(C1, JFK) requires Unload(C1, P1, JFK) +At(C2, SFO) requires Unload(C2, P2, SFO) + +These actions Unload(C1, P1, JFK) and Unload(C2, P2, SFO) are NOT mutex in action layer + +They rely on the following state at s_1 + - Unload(C2, P2, SFO): [In(C2, P2), At(P2, SFO),...] + - Unload(C1, P1, JFK): [In(C1, P1), At(P1, JFK),...] + +Preconditions, e.g. for Unload(C2, P2, SFO): + - In(C2, P2), At(P2, SFO) + - are mutex, but since they both exist in the state, we still apply the action anyway? When is this supposed to be caught? + + + +[{At(C1, SFO), In(C1, P1)}, {At(C1, SFO), NotAt(C1, SFO)}, {At(C2, JFK), In(C2, P2)}, {At(C2, JFK), NotAt(C2, JFK)}, {At(P1, SFO), At(P1, JFK)}, {At(P1, SFO), NotAt(P1, SFO)}, {At(P2, JFK), At(P2, SFO)}, {NotAt(P2, JFK), At(P2, JFK)}, {At(P1, JFK), In(C1, P1)}, {NotAt(P1, SFO), In(C1, P1)}, {At(P1, JFK), NotAt(C1, SFO)}, {NotAt(P1, SFO), NotAt(C1, SFO)}, {At(P2, SFO), In(C2, P2)}, {NotAt(P2, JFK), In(C2, P2)}, {NotAt(C2, JFK), At(P2, SFO)}, {NotAt(P2, JFK), NotAt(C2, JFK)}] + diff --git a/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md b/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md new file mode 100644 index 000000000..63e9a795c --- /dev/null +++ b/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md @@ -0,0 +1,22 @@ +# Goal States: +[ + At(A, LeftNet), + Returned(ball), + At(B, LeftNet) +] + +#Action sets that lead to goal states +[ + [PAt(A, LeftNet), Go(A, LeftNet, ball), Go(A, LeftNet, B), Go(A, LeftNet, RightNet)], + [Hit(A, ball, RightNet), Hit(B, ball, RightNet)], + [PAt(B, LeftNet), Go(B, LeftNet, ball), Go(B, LeftNet, A), Go(B, LeftNet, RightNet)] +] + +# Allegedly, all combinations are disjoint + +Hit(A, ball, RightNet), Hit(B, ball, RightNet) + - Requires either A or B to be in RightNet + - First list requires A to move to LeftNet + - Last list requires B to move to LeftNet + +These are disjoint in total, but none of the two are disjoint \ No newline at end of file diff --git a/planning.py b/planning.py index f2184846c..c2c1b02ca 100644 --- a/planning.py +++ b/planning.py @@ -552,6 +552,41 @@ def socks_and_shoes(): effect='LeftSockOn')]) +def double_tennis_problem_simple(): + return PlanningProblem( + initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', + goals='At(A, LeftBaseline) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')], + domain="Loc(LeftBaseline)") + +def double_tennis_problem_simple2(): + return PlanningProblem( + initial='At(A, LeftNet) & At(B, LeftNet) & Approaching(ball, RightNet)', + goals='At(A, LeftNet) & Returned(ball) & At(B, LeftNet)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + +def double_tennis_problem_simple3(): + return PlanningProblem( + initial='At(A, LeftNet) & Approaching(ball, RightNet)', + goals='At(A, LeftNet) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + + def double_tennis_problem(): """ [Figure 11.10] DOUBLE-TENNIS-PROBLEM @@ -643,7 +678,7 @@ def double_tennis_problem(): return PlanningProblem( initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', - goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', + goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', actions=[Action('Hit(actor, ball, loc)', precond='Approaching(ball, loc) & At(actor, loc)', effect='Returned(ball)'), @@ -652,7 +687,7 @@ def double_tennis_problem(): effect='At(actor, to) & ~At(actor, loc)')], domain="Loc(LeftBaseline)") - + class ForwardPlan(search.Problem): """ [Section 10.2.1] @@ -1016,7 +1051,7 @@ def find_mutex(self): if mutex_pair not in self.mutex: # <-- avoid duplicates self.mutex.append(mutex_pair) - print([x for x in self.mutex if x not in savemutextemp]) + #print([x for x in self.mutex if x not in savemutextemp]) #breakpoint() # Inconsistent support - two props cannot be true given competing supporting actions @@ -1311,7 +1346,7 @@ def non_mutex_goals(self, goals, index): # If no combination works, goals are mutex return False """ - + class GraphPlan: """ Class for formulation GraphPlan algorithm @@ -1323,10 +1358,12 @@ def __init__(self, planning_problem): self.graph = Graph(planning_problem) self.no_goods = [] self.solution = [] - + global isFirstLayer isFirstLayer = True - + + self.calledextr = False + def __str__(self): sol_str = ( "No solution found" @@ -1353,41 +1390,53 @@ def check_leveloff(self): def extract_solution(self, goals, index): "Extracts the solution" + #breakpoint() + isfirst = False + if self.calledextr != True: + self.calledextr = True + isfirst = True + level = self.graph.levels[index] if not self.graph.non_mutex_goals(goals, index): self.no_goods.append((level, goals)) return level = self.graph.levels[index - 1] - #print(f" On level {index-1}") - #print(f" Mutexes: \n {level.mutex}") - - # Create all combinations of actions that satisfy the goal + # print(f" On level {index-1}") + # print(f" Mutexes: \n {level.mutex}") + #breakpoint() + + # Create all combinations of actions that satisfy each goal + # `actions` will be a list of tuples, where each tuple is every action that satisfies one goal literal actions = [] for goal in goals: actions.append(level.next_state_links[goal]) - all_actions = list(itertools.product(*actions)) - #print(f" ALL ACTION COMBINATIONS at level {index-1}:") - ##for a in all_actions: - #print(" ", a) + # `all_actions` selects elements from each list and creates a new list of actions that satisfies all goals at next level + all_actions = list(itertools.product(*actions)) # Why only product? Why not all subsets of non-mutex preconditions? + + #breakpoint() # Filter out non-mutex actions non_mutex_actions = [] for action_tuple in all_actions: + # Get all pairs of actions in our satisfactory action_tuple action_pairs = itertools.combinations(list(set(action_tuple)), 2) non_mutex_actions.append(list(set(action_tuple))) - #acts = list(set(action_tuple)) - #print(f"CHECKING tuple {acts} at level {index-1}") + # acts = list(set(action_tuple)) + # print(f"CHECKING tuple {acts} at level {index-1}") for pair in list(action_pairs): - #print(" testing pair", pair, "mutex?", frozenset(pair) in level.mutex) if set(pair) in level.mutex: non_mutex_actions.pop(-1) - break #? - - #print(f"NON-MUTEX ACTION SETS at level {index}: {non_mutex_actions}") - #print(len(non_mutex_actions), non_mutex_actions) + break # If any actions are mutex, remove the entire tuple from our list + + # print(f"NON-MUTEX ACTION SETS at level {index}: {non_mutex_actions}") + # print(len(non_mutex_actions), non_mutex_actions) + # breakpoint() + + # At this point, the non_mutex_actions contains a list of lists of valid actions that are all non-mutex and satisfy our goal state + #breakpoint() # Recursion @@ -1405,24 +1454,112 @@ def extract_solution(self, goals, index): elif (level, new_goals) in self.no_goods: return else: - #print(f" Recursing with new goal: {new_goals}") - self.extract_solution(new_goals, index - 1) + # print(f" Recursing with new goal: {new_goals}") + self.extract_solution(new_goals, index - 1) # DFS search + + + print("self.solution = ", self.solution) + print("self.nogoods = ", self.no_goods) + #if isfirst: + # breakpoint() + """ # Level-Order multiple solutions solution = [] - for item in self.solution: - if item[1] == -1: + for item in self.solution: # self.solution will contain sets of actions at a level. + if item[1] == -1: # We are at the bottom of the tree in recursion, and we create a new unique solution for this leaf node solution.append([]) + solution[-1].append(item[0]) + else: # We are at an intermediate node, we add it to our last solution (but not other possible nodes?) solution[-1].append(item[0]) - else: - solution[-1].append(item[0]) + + #breakpoint() for num, item in enumerate(solution): item.reverse() solution[num] = item - + return solution + """ + + if not self.solution: + return [] + + # 1. Determine the leaf level and the expected length of a valid plan. + leaf_level = min(item[1] for item in self.solution) + expected_plan_length = abs(leaf_level) + print(f"DEBUG: Target leaf level: {leaf_level}, Expected plan length: {expected_plan_length}\n") + + + completed_plans = [] + current_path = [] + initial_state = set(self.graph.levels[0].current_state) + level_zero = self.graph.levels[0] + + # 2. Iterate through the ordered search log. + for i, item in enumerate(self.solution): + actions, level = item + print(f"--- Iteration {i+1} ---") + print(f"Processing Item: {item}") + print(f"Path BEFORE changes: {current_path}") + + # 3. Rewind the current path to handle backtracks. + rewound = False + while current_path and level != current_path[-1][1] - 1: + if not rewound: + print(f"-> Backtrack detected (Lvl {level} doesn't follow Lvl {current_path[-1][1]}). Rewinding path...") + rewound = True + popped_item = current_path.pop() + print(f" ...Popped: {popped_item}") + + if rewound: + print(f"Path AFTER rewind: {current_path}") + + # 4. Append the current item to form the new active path. + current_path.append(item) + print(f"Appending item. New Path is now: {current_path}\n") + + # 5. Check if the active path has a valid structure. + is_rooted = current_path[0][1] == -1 + is_grounded = current_path[-1][1] == leaf_level + is_contiguous = len(current_path) == expected_plan_length + + # Only proceed if the path is structurally sound. + if is_rooted and is_grounded and is_contiguous: + print(f"-> Path is structurally valid. Performing final initial state check...") + + # 6. Final Check: Verify first actions' preconditions against the initial state. + initial_state_satisfied = True + first_actions_in_plan = set(current_path[-1][0]) + + for action in first_actions_in_plan: + preconditions = level_zero.current_action_links.get(action,None) + if preconditions is None: + initial_state_satisfied = False + preconditions = [] + preconditions = set(preconditions) + print("Testing preconditions: ", preconditions, ", and initial_state: ", initial_state) + if not preconditions.issubset(initial_state): + initial_state_satisfied = False + print(f" ❗️ Path failed validation. Action '{action}' preconditions {preconditions} are not met by initial state.") + break + + if initial_state_satisfied: + print(f" ✅ Success! Plan fully verified and found: {current_path}\n") + completed_plans.append(list(current_path)) + print(f"--- Loop Finished ---") + print(f"Found {len(completed_plans)} complete plan(s) before final formatting.") + + # Format the final solutions + solution = [] + for plan in completed_plans: + action_plan = [item[0] for item in plan] + action_plan.reverse() + solution.append(action_plan) + + return solution + """ def extract_solution(self, goals, index): "Extracts the solution" @@ -1483,47 +1620,48 @@ def extract_solution(self, goals, index): return solution """ - + def goal_test(self, kb): goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) - #print(goal_achieved) + # print(goal_achieved) return goal_achieved - def execute(self): - """Executes the GraphPlan algorithm for the given problem""" + "Executes the GraphPlan algorithm for the given problem" print("Forward Search") while True: self.graph.expand_graph() - print(self.graph) - #print("Number of levels: ", len(self.graph.levels)) + #print(self.graph) + # print("Number of levels: ", len(self.graph.levels)) #breakpoint() if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): - + print("SOLVED, EXTRACTING SOLUTION") - #print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) - #self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) - #print(self.graph) - #print("Last level state:", self.graph.levels[-1].current_state) - #print("Last level mutexes:", self.graph.levels[-1].mutex) - #print("Next state links:", self.graph.levels[-1].next_state_links) - #print("Current action links:", self.graph.levels[-1].current_action_links) - #print(f"Extract Solution from {len(self.graph.levels)} levels, {len(self.graph.levels) - 1} actions") + # print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) + # self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) + # print(self.graph) + # print("Last level state:", self.graph.levels[-1].current_state) + # print("Last level mutexes:", self.graph.levels[-1].mutex) + # print("Next state links:", self.graph.levels[-1].next_state_links) + # print("Current action links:", self.graph.levels[-1].current_action_links) + # print(f"Extract Solution from {len(self.graph.levels)} levels, {len(self.graph.levels) - 1} actions") solution = self.extract_solution(self.graph.planning_problem.goals, -1) + self.calledextr = False if solution: print(f"SOLUTION::::!!!!!!!!!!!!!!!!\n{solution}") return solution - #print(len(self.graph.levels)) + # print(len(self.graph.levels)) if len(self.graph.levels) >= 2 and self.check_leveloff(): - #breakpoint() + # breakpoint() return None # BILLS CLASS +""" class Linearize: def __init__(self, planning_problem): @@ -1570,6 +1708,7 @@ def execute(self): "Finds total-order solution for a planning graph" graphPlan_solution = GraphPlan(self.planning_problem).execute() + breakpoint() ## Bill's stuff from playing around ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack @@ -1630,6 +1769,7 @@ def execute(self): break return ordered_solution +""" """ # GPT Modified @@ -1725,7 +1865,7 @@ def _filter(self, raw_plan): return new_solution """ -""" + # ORIGINAL class Linearize: @@ -1776,8 +1916,7 @@ def execute(self): ordered_solution.append(element) return ordered_solution -""" - + def linearize(solution): """Converts a level-ordered solution into a linear solution""" diff --git a/submission1.py b/submission1.py index cc8f19c0e..6fdff37e6 100644 --- a/submission1.py +++ b/submission1.py @@ -95,9 +95,9 @@ def logisticsPlan(): #P = air_cargo() #P = double_tennis_problem() #P = have_cake_and_eat_cake_too() - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - goal_state = "In(C1, D2) & In(C3, D3)" - P = logisticsPlanCustom(init, goal_state) + #init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + #goal_state = "In(C1, D2) & In(C3, D3)" + #P = logisticsPlanCustom(init, goal_state) # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. """ @@ -117,8 +117,8 @@ def logisticsPlan(): domain='Robot(r) & Place(d_start) & Place(d_end)')], domain='Container(C1) & Container(C2) & Place(D1) & Place(D2) & Robot(R1)') """ - - print(GraphPlan(P).execute()) + P = double_tennis_problem_simple2() + #GraphPlan(P).execute() #print(Linearize(P).execute()) diff --git a/submission1_test.py b/submission1_test.py index 4bd02020a..2e359d71a 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -47,10 +47,6 @@ def test_socks_and_shoes(): P = socks_and_shoes() verify_solution(P) -def ptest_double_tennis_problem(): - P = double_tennis_problem() - verify_solution(P) - @pytest.mark.parametrize("goal_state", [ "In(C1, D1)", "In(C1, D2)", @@ -65,7 +61,13 @@ def ptest_double_tennis_problem(): "In(C1, D1) & In(C2, D3)", "In(C3, D1)", "In(C2, D3)", + #"In(C2, D3) & In(C3, D3)", \ + #"In(C3, D3) & In(C2, D3)", \ + "In(C1, D2) & In(C3, D3)", + #"In(C1, D3) & In(C2, D3) & In(C3, D3)", \ + "In(C1, D2) & In(C3, D3) & In(C2, D1)", "In(C3, D3)", + #"In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)" \ ]) def test_logistics_plan_valid(goal_state): """These should yield a valid (non-crashing) plan, even if empty.""" @@ -73,33 +75,19 @@ def test_logistics_plan_valid(goal_state): P = logisticsPlanCustom(init, goal_state) verify_solution(P) -@pytest.mark.parametrize("goal_state", [ # Why don't any of these have a solution? - "In(C2, D3) & In(C3, D3)", - "In(C3, D3) & In(C2, D3)", - "In(C1, D2) & In(C3, D3)", # Why doesn't this have a solution? It finds one ... - "In(C1, D3) & In(C2, D3) & In(C3, D3)", - "In(C1, D2) & In(C3, D3) & In(C2, D1)", # Why doesn't this also have a solutioN? it finds one -]) -def test_logistics_plan_no_plan(goal_state): - """These are known to have no valid plan.""" - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - P = logisticsPlanCustom(init, goal_state) - sol = Linearize(P).execute() - # Depending on your GraphPlan, no-plan might return [] or None - #assert sol in ([], None) +def test_double_tennis_problem_simple(): + P = double_tennis_problem_simple() + verify_solution(P) + + +def test_double_tennis_problem_simple2(): + P = double_tennis_problem_simple2() + verify_solution(P) + +def test_double_tennis_problem_simple3(): + P = double_tennis_problem_simple3() verify_solution(P) - -@pytest.mark.parametrize("goal_state", [ - "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)", -]) -def test_logistics_plan_kaboom(goal_state): - """This case is known to cause planner explosion. Catch and mark as expected failure.""" - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - try: - P = logisticsPlanCustom(init, goal_state) - sol = Linearize(P).execute() - # If it actually returns, that's fine too - assert sol is None or isinstance(sol, list) - except Exception: - pytest.xfail("Known kaboom case – planner explosion or unsolvable problem") \ No newline at end of file +def test_double_tennis_problem(): + P = double_tennis_problem() + verify_solution(P) From 256863c3433eddf3a9c148c598842240b383fe83 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Wed, 1 Oct 2025 10:18:15 -0400 Subject: [PATCH 11/19] Most tests consistently passing --- debug_logistics_err.py | 94 ++++++++++++++++++++++++++++++++++++++++++ planning.py | 71 ++++++++++++++++++++++++++++++- submission1.py | 14 +++++-- 3 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 debug_logistics_err.py diff --git a/debug_logistics_err.py b/debug_logistics_err.py new file mode 100644 index 000000000..e0b23b78d --- /dev/null +++ b/debug_logistics_err.py @@ -0,0 +1,94 @@ + +# In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) +# In(C3, D3) + +# Sol should be: +# putdown(c1), move(r1, d2), pickup c3, move d3, putdown d3a + + +ISSUE: + PickUp(R1, C1, D2), + PickUp(R1, C3, D2), +in same layer. + +[ + [ + [ + PHolding(R1), + PContainer(C3), + PIn(C1, R1), + PPlace(D2), + PPlace(D3), + PContainer(C1), + PRobot(R1), + Move(R1, D1, D2), + PIn(C3, D2), + ], + [ + PutDown(R1, C1, D2), + PContainer(C3), + PPlace(D2), + PPlace(D3), + PIn(R1, D2), + PContainer(C1), + PRobot(R1), + PIn(C3, D2), + ], + [ + PContainer(C3), + PPlace(D2), + PPlace(D3), + PickUp(R1, C1, D2), + PIn(R1, D2), + PRobot(R1), + PickUp(R1, C3, D2), + ], + [ + PHolding(R1), + PContainer(C3), + Move(R1, D2, D3), + PPlace(D3), + PIn(C3, R1), + PRobot(R1), + ], + [PutDown(R1, C3, D3)], + ], + [ + [ + PutDown(R1, C1, D1), + PContainer(C3), + PPlace(D2), + PPlace(D3), + PIn(R1, D1), + PPlace(D1), + PRobot(R1), + PIn(C3, D2), + ], + [ + PContainer(C3), + PPlace(D2), + PPlace(D3), + PRobot(R1), + PNotHolding(R1), + Move(R1, D1, D2), + PIn(C3, D2), + ], + [ + PContainer(C3), + PPlace(D2), + PPlace(D3), + PIn(R1, D2), + PRobot(R1), + PickUp(R1, C3, D2), + ], + [ + PHolding(R1), + PContainer(C3), + Move(R1, D2, D3), + PPlace(D3), + PIn(C3, R1), + PRobot(R1), + ], + [PutDown(R1, C3, D3)], + ], +] diff --git a/planning.py b/planning.py index c2c1b02ca..a168420b9 100644 --- a/planning.py +++ b/planning.py @@ -1658,6 +1658,74 @@ def execute(self): # breakpoint() return None +# Carwyns mods +class Linearize: + + def __init__(self, planning_problem): + self.planning_problem = planning_problem + + def filter(self, solution): + "Filter out persistence actions from a solution" + + new_solution = [] + for section in solution: + new_section = [] + for operation in section: + if not (operation.op[0] == 'P' and operation.op[1].isupper()): + new_section.append(operation) + # filter may remove all actions if all actions are persistent + if new_section != []: + new_solution.append(new_section) + return new_solution + + def orderlevel(self, level, planning_problem): + "Return valid linear order of actions for a given level" + + for permutation in itertools.permutations(level): + temp = copy.deepcopy(planning_problem) + count = 0 + for action in permutation: + try: + temp.act(action) + count += 1 + except: + count = 0 + temp = copy.deepcopy(planning_problem) + continue + if count == len(permutation): + return list(permutation), temp + # identifying a linear ordering for level failed ... return no solution and same planning problem state + return None, planning_problem + + def execute(self): + "Finds a total-order solution for a planning graph. Possibly not the only linearization possible." + + graphPlan_solution = GraphPlan(self.planning_problem).execute() + + for itr, possible_plan in enumerate(graphPlan_solution): + filtered_solution = self.filter(possible_plan) + #print(f"Trying filtered plan #{itr}: {filtered_solution}") + + ordered_solution = [] + # planning_problem will maintain the current state as we iterate over levels, allowing test application of actions + planning_problem = self.planning_problem + for level in filtered_solution: + level_solution, planning_problem = self.orderlevel(level, planning_problem) + if not level_solution: + # level failed to apply, this plan shouldn't work + ordered_solution = None + break # technically could try `continue` anyway, but we shouldn't need to + + for element in level_solution: + ordered_solution.append(element) + + if not ordered_solution: + continue ## no plan possible from the partial plan at the level + else: + break + + return ordered_solution + # BILLS CLASS @@ -1865,7 +1933,7 @@ def _filter(self, raw_plan): return new_solution """ - +""" # ORIGINAL class Linearize: @@ -1916,6 +1984,7 @@ def execute(self): ordered_solution.append(element) return ordered_solution +""" def linearize(solution): """Converts a level-ordered solution into a linear solution""" diff --git a/submission1.py b/submission1.py index 6fdff37e6..4906499b9 100644 --- a/submission1.py +++ b/submission1.py @@ -5,6 +5,8 @@ from planning import * from logic import * +from submission1_test import verify_solution + # Problem 4: Planning """ **IMPORTANT** Reflection (4 pts) @@ -95,9 +97,14 @@ def logisticsPlan(): #P = air_cargo() #P = double_tennis_problem() #P = have_cake_and_eat_cake_too() - #init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + goal_state = "In(C1,D1)" + #goal_state = "In(C3, D1)" + #goal_state = "In(C2, D3)" + #goal_state = "In(C3, D3)" + # putdown c1, move r1 to d2, pickup c3 in d2, move robot to d1, putdown c3 #goal_state = "In(C1, D2) & In(C3, D3)" - #P = logisticsPlanCustom(init, goal_state) + P = logisticsPlanCustom(init, goal_state) # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. """ @@ -117,9 +124,10 @@ def logisticsPlan(): domain='Robot(r) & Place(d_start) & Place(d_end)')], domain='Container(C1) & Container(C2) & Place(D1) & Place(D2) & Robot(R1)') """ - P = double_tennis_problem_simple2() + #P = double_tennis_problem_simple2() #GraphPlan(P).execute() #print(Linearize(P).execute()) + verify_solution(P) """ From 204b19b79416627e66abce7ca7c470af3c7fa986 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 4 Oct 2025 15:35:22 -0400 Subject: [PATCH 12/19] Working! Needed to update the extract_solution to attempt every powerset of possible action tuples for each goal (but implemented efficiently with DFS recursive early-exit search --- GRAPH-LOGISTICS.py | 57 ++++ debug_logistics_err.py | 63 ++++ graphplan_debugger.py | 133 +++++++++ logistics_trace1.txt | 17 ++ planning.py | 641 ++++++++++++++--------------------------- plotter.py | 60 ++++ submission1.py | 10 +- submission1_test.py | 25 +- utils.py | 44 +++ 9 files changed, 617 insertions(+), 433 deletions(-) create mode 100644 GRAPH-LOGISTICS.py create mode 100644 graphplan_debugger.py create mode 100644 logistics_trace1.txt create mode 100644 plotter.py diff --git a/GRAPH-LOGISTICS.py b/GRAPH-LOGISTICS.py new file mode 100644 index 000000000..e2c9c533a --- /dev/null +++ b/GRAPH-LOGISTICS.py @@ -0,0 +1,57 @@ + + Objects: {D1, R1, D3, C2, C3, C1, D2} +Level 0: + + Current State: {In(C1, R1), In(C2, D1), In(C3, D2), In(R1, D1), Holding(R1), Container(C1), Container(C2), Container(C3), Place(D1), Place(D2), Place(D3), Robot(R1)} + Actions: {PIn(C1, R1), PIn(C2, D1), PIn(C3, D2), PIn(R1, D1), PHolding(R1), PContainer(C1), PContainer(C2), PContainer(C3), PPlace(D1), PPlace(D2), PPlace(D3), PRobot(R1), PutDown(R1, C1, D1), Move(R1, D1, D3), Move(R1, D1, D2)} + Mutex: {{PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {Move(R1, D1, D2), Move(R1, D1, D3)}} + Next state mutexes: {[{NotHolding(R1), In(C1, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(C1, D1), In(C1, R1)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), In(R1, D3)}, {In(R1, D1), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {NotIn(C1, R1), Holding(R1)}, {In(C1, D1), Holding(R1)}, {NotIn(R1, D1), NotHolding(R1)}, {NotHolding(R1), In(R1, D3)}, {NotHolding(R1), In(R1, D2)}, {NotIn(C1, R1), NotIn(R1, D1)}, {NotIn(C1, R1), In(R1, D3)}, {NotIn(C1, R1), In(R1, D2)}, {NotIn(R1, D1), In(C1, D1)}, {In(C1, D1), In(R1, D3)}, {In(C1, D1), In(R1, D2)}, {In(R1, D3), In(R1, D2)}]} + +Level 1: + + Current State: {Container(C3), Place(D1), Place(D3), In(C1, D1), In(R1, D2), NotIn(R1, D1), Holding(R1), In(C3, D2), In(C1, R1), Robot(R1), NotIn(C1, R1), NotHolding(R1), In(R1, D1), In(R1, D3), Place(D2), In(C2, D1), Container(C1), Container(C2)} + Actions: {PContainer(C3), PPlace(D1), PPlace(D3), PIn(C1, D1), PIn(R1, D2), PNotIn(R1, D1), PHolding(R1), PIn(C3, D2), PIn(C1, R1), PRobot(R1), PNotIn(C1, R1), PNotHolding(R1), PIn(R1, D1), PIn(R1, D3), PPlace(D2), PIn(C2, D1), PContainer(C1), PContainer(C2), PickUp(R1, C2, D1), PickUp(R1, C1, D1), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PIn(C1, D1), PIn(R1, D2)}, {PIn(C1, D1), PNotIn(R1, D1)}, {PIn(C1, D1), PHolding(R1)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PIn(R1, D3)}, {PIn(C1, D1), PickUp(R1, C3, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PIn(C1, D1), Move(R1, D3, D1)}, {PIn(C1, D1), Move(R1, D3, D2)}, {PIn(C1, D1), Move(R1, D2, D1)}, {PIn(C1, D1), Move(R1, D2, D3)}, {PNotIn(C1, R1), PIn(R1, D2)}, {PIn(R1, D2), PNotHolding(R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C3, D2), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PNotIn(R1, D1), PNotIn(C1, R1)}, {PNotIn(R1, D1), PNotHolding(R1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D2)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PHolding(R1), PNotIn(C1, R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PIn(C1, R1), PNotHolding(R1)}, {PickUp(R1, C2, D1), PIn(C1, R1)}, {PickUp(R1, C3, D2), PIn(C1, R1)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PNotIn(C1, R1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PNotIn(C1, R1), Move(R1, D3, D1)}, {PNotIn(C1, R1), Move(R1, D3, D2)}, {PNotIn(C1, R1), Move(R1, D2, D1)}, {PNotIn(C1, R1), Move(R1, D2, D3)}, {PNotHolding(R1), PIn(R1, D3)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {Move(R1, D3, D1), PNotHolding(R1)}, {PNotHolding(R1), Move(R1, D3, D2)}, {Move(R1, D2, D1), PNotHolding(R1)}, {PNotHolding(R1), Move(R1, D2, D3)}, {PIn(R1, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{In(C1, D1), In(C1, R1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, D2)}, {In(C1, D1), NotIn(R1, D3)}, {NotIn(R1, D2), In(C1, D1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D3), In(R1, D2)}, {NotIn(C2, D1), In(R1, D2)}, {In(C2, R1), In(R1, D2)}, {NotIn(C1, D1), In(R1, D2)}, {In(C1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(R1, D1), NotIn(C2, D1)}, {NotIn(R1, D1), In(C2, R1)}, {NotIn(R1, D1), NotIn(C1, D1)}, {NotHolding(R1), Holding(R1)}, {In(C1, D3), Holding(R1)}, {Holding(R1), In(C1, D2)}, {NotIn(C1, R1), In(C1, R1)}, {NotHolding(R1), In(C1, R1)}, {In(C1, D3), In(C1, R1)}, {In(C1, D2), In(C1, R1)}, {NotIn(C1, R1), NotIn(C1, D1)}, {NotIn(C1, R1), NotIn(R1, D3)}, {NotIn(C1, R1), NotIn(R1, D2)}, {NotHolding(R1), NotIn(C2, D1)}, {NotHolding(R1), In(C2, R1)}, {NotHolding(R1), NotIn(C1, D1)}, {NotHolding(R1), NotIn(R1, D3)}, {NotIn(R1, D2), NotHolding(R1)}, {In(R1, D1), In(R1, D3)}, {In(C1, D3), In(R1, D1)}, {In(R1, D1), In(C1, D2)}, {NotIn(C2, D1), In(R1, D3)}, {In(R1, D3), In(C2, R1)}, {NotIn(C1, D1), In(R1, D3)}, {In(C1, D2), In(R1, D3)}, {NotIn(R1, D3), In(R1, D3)}, {In(C2, D1), NotIn(C2, D1)}, {In(C2, D1), In(C2, R1)}, {In(C1, D3), NotIn(C2, D1)}, {In(C1, D2), NotIn(C2, D1)}, {NotIn(R1, D3), NotIn(C2, D1)}, {NotIn(R1, D2), NotIn(C2, D1)}, {In(C1, D3), In(C2, R1)}, {In(C1, D2), In(C2, R1)}, {NotIn(R1, D3), In(C2, R1)}, {NotIn(R1, D2), In(C2, R1)}, {In(C1, D3), NotIn(C1, D1)}, {In(C1, D2), NotIn(C1, D1)}, {NotIn(R1, D3), NotIn(C1, D1)}, {NotIn(R1, D2), NotIn(C1, D1)}, {In(C1, D3), In(C1, D2)}, {NotIn(R1, D3), In(C1, D3)}, {NotIn(R1, D2), In(C1, D3)}, {NotIn(R1, D3), In(C1, D2)}, {NotIn(R1, D2), In(C1, D2)}, {NotIn(R1, D2), NotIn(R1, D3)}]} + +Level 2: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), Container(C3), Container(C1), In(C1, D2), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(R1, D2), Place(D1), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), In(C2, D1)} + Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(R1, D2), PPlace(D1), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PNotIn(C2, D1), PIn(C1, D2)}, {PIn(R1, D2), PNotIn(C2, D1)}, {PNotHolding(R1), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C2, D1)}, {PNotIn(R1, D2), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PickUp(R1, C3, D2), PNotIn(C2, D1)}, {PickUp(R1, C1, D1), PNotIn(C2, D1)}, {PickUp(R1, C1, D3), PNotIn(C2, D1)}, {PickUp(R1, C1, D2), PNotIn(C2, D1)}, {PutDown(R1, C2, D3), PNotIn(C2, D1)}, {PutDown(R1, C2, D2), PNotIn(C2, D1)}, {PutDown(R1, C1, D3), PNotIn(C2, D1)}, {PutDown(R1, C1, D2), PNotIn(C2, D1)}, {Move(R1, D3, D1), PNotIn(C2, D1)}, {Move(R1, D3, D2), PNotIn(C2, D1)}, {Move(R1, D2, D1), PNotIn(C2, D1)}, {Move(R1, D2, D3), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C1, D2)}, {PIn(C2, R1), PIn(R1, D2)}, {PIn(C2, R1), PNotHolding(R1)}, {PIn(C2, R1), PIn(R1, D3)}, {PNotIn(R1, D3), PIn(C2, R1)}, {PNotIn(R1, D2), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D3)}, {PNotIn(R1, D1), PIn(C2, R1)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C3, D2), PIn(C2, R1)}, {PickUp(R1, C1, D1), PIn(C2, R1)}, {PickUp(R1, C1, D3), PIn(C2, R1)}, {PickUp(R1, C1, D2), PIn(C2, R1)}, {PutDown(R1, C1, D3), PIn(C2, R1)}, {PutDown(R1, C1, D2), PIn(C2, R1)}, {Move(R1, D3, D1), PIn(C2, R1)}, {PIn(C2, R1), Move(R1, D3, D2)}, {Move(R1, D2, D1), PIn(C2, R1)}, {PIn(C2, R1), Move(R1, D2, D3)}, {PNotIn(C1, R1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PNotIn(C1, R1)}, {PNotIn(C1, R1), PNotIn(R1, D2)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(C1, D2), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PIn(C1, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PHolding(R1), PIn(C1, D2)}, {PIn(R1, D3), PIn(C1, D2)}, {PNotIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PNotIn(R1, D3), PIn(C1, D2)}, {PNotIn(R1, D2), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C2, D1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C1, D2)}, {PutDown(R1, C2, D3), PIn(C1, D2)}, {PutDown(R1, C2, D2), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {Move(R1, D1, D3), PIn(C1, D2)}, {Move(R1, D1, D2), PIn(C1, D2)}, {Move(R1, D3, D1), PIn(C1, D2)}, {Move(R1, D3, D2), PIn(C1, D2)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(R1, D2), PNotIn(C1, D1)}, {PIn(R1, D2), PIn(C1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C2, D2), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C1, D3)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PNotHolding(R1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PNotHolding(R1)}, {PNotIn(R1, D2), PNotHolding(R1)}, {PIn(C1, R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C1, D1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D3), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D1)}, {PNotIn(R1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D1), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C1, D1)}, {PickUp(R1, C2, D1), PNotIn(C1, D1)}, {PickUp(R1, C3, D2), PNotIn(C1, D1)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, D1)}, {PickUp(R1, C1, D2), PNotIn(C1, D1)}, {PutDown(R1, C2, D3), PNotIn(C1, D1)}, {PutDown(R1, C2, D2), PNotIn(C1, D1)}, {PutDown(R1, C1, D3), PNotIn(C1, D1)}, {PutDown(R1, C1, D2), PNotIn(C1, D1)}, {Move(R1, D3, D1), PNotIn(C1, D1)}, {Move(R1, D3, D2), PNotIn(C1, D1)}, {Move(R1, D2, D1), PNotIn(C1, D1)}, {Move(R1, D2, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(R1, D3)}, {PIn(C1, D1), PNotIn(R1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(R1, D2)}, {PNotIn(R1, D3), PIn(C1, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D1)}, {PNotIn(R1, D3), PickUp(R1, C3, D2)}, {PNotIn(R1, D3), PickUp(R1, C1, D1)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D2)}, {PNotIn(R1, D3), PutDown(R1, C2, D1)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D2), PIn(C1, D3)}, {PNotIn(R1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D1), PNotIn(R1, D2)}, {PickUp(R1, C1, D3), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D1), PNotIn(R1, D2)}, {PutDown(R1, C2, D3), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C2, D1), PIn(C1, D3)}, {PickUp(R1, C3, D2), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C2, D1), PIn(C1, D3)}, {PutDown(R1, C2, D3), PIn(C1, D3)}, {PutDown(R1, C2, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {Move(R1, D1, D3), PIn(C1, D3)}, {Move(R1, D1, D2), PIn(C1, D3)}, {Move(R1, D2, D1), PIn(C1, D3)}, {Move(R1, D2, D3), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C2, D3), PNotIn(R1, D1)}, {PNotIn(R1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C2, D1), PIn(C1, R1)}, {PickUp(R1, C3, D2), PIn(C1, R1)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{In(C1, D2), NotIn(C2, D1)}, {NotIn(R1, D3), NotIn(C2, D1)}, {NotIn(R1, D2), NotIn(C2, D1)}, {In(C1, D3), NotIn(C2, D1)}, {In(C2, D1), NotIn(C2, D1)}, {NotIn(C3, D2), NotIn(C2, D1)}, {In(C3, R1), NotIn(C2, D1)}, {NotIn(C1, D3), NotIn(C2, D1)}, {NotIn(C1, D2), NotIn(C2, D1)}, {NotIn(C2, R1), NotIn(C2, D1)}, {In(C1, D2), In(C2, R1)}, {NotIn(R1, D3), In(C2, R1)}, {NotIn(R1, D2), In(C2, R1)}, {In(C1, D3), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C3, D2), In(C2, R1)}, {In(C3, R1), In(C2, R1)}, {NotIn(C1, D3), In(C2, R1)}, {NotIn(C1, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {NotIn(C1, R1), NotIn(C1, D1)}, {NotIn(C1, R1), In(C1, R1)}, {NotIn(C1, R1), NotIn(C1, D3)}, {NotIn(C1, R1), NotIn(C1, D2)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(C3, D2), In(R1, D1)}, {In(R1, D1), In(C3, R1)}, {NotIn(C1, D3), In(R1, D1)}, {NotIn(C1, D2), In(R1, D1)}, {In(C1, D2), NotIn(C1, D1)}, {In(C1, D1), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C1, D3), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {NotIn(C2, R1), In(C1, D2)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C1, D3), In(R1, D2)}, {NotIn(C2, R1), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C1, D3), Holding(R1)}, {NotIn(C2, R1), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {In(C3, D2), In(C3, R1)}, {NotIn(C3, D2), NotHolding(R1)}, {NotHolding(R1), In(C3, R1)}, {NotIn(C1, D3), NotHolding(R1)}, {NotIn(C1, D2), NotHolding(R1)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C3, D2), In(R1, D3)}, {In(C3, R1), In(R1, D3)}, {NotIn(C1, D2), In(R1, D3)}, {NotIn(C2, R1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {NotIn(R1, D3), NotIn(C1, D1)}, {NotIn(R1, D2), NotIn(C1, D1)}, {In(C1, D3), NotIn(C1, D1)}, {NotIn(C3, D2), NotIn(C1, D1)}, {In(C3, R1), NotIn(C1, D1)}, {NotIn(C1, D3), NotIn(C1, D1)}, {NotIn(C1, D2), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C1, D3), In(C1, D1)}, {NotIn(C1, D2), In(C1, D1)}, {NotIn(C3, D2), NotIn(R1, D3)}, {NotIn(R1, D3), In(C3, R1)}, {NotIn(C1, D3), NotIn(R1, D3)}, {NotIn(C1, D2), NotIn(R1, D3)}, {NotIn(C2, R1), NotIn(R1, D3)}, {NotIn(R1, D2), NotIn(C3, D2)}, {NotIn(R1, D2), In(C3, R1)}, {NotIn(R1, D2), NotIn(C1, D3)}, {NotIn(R1, D2), NotIn(C1, D2)}, {NotIn(R1, D2), NotIn(C2, R1)}, {In(C1, D3), In(C1, R1)}, {NotIn(C3, D2), In(C1, D3)}, {In(C1, D3), In(C3, R1)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C1, D2), In(C1, D3)}, {NotIn(C2, R1), In(C1, D3)}, {NotIn(C2, R1), NotIn(R1, D1)}, {NotIn(C3, D2), NotIn(C1, D3)}, {NotIn(C2, R1), NotIn(C3, D2)}, {NotIn(C1, D3), In(C3, R1)}, {NotIn(C2, R1), In(C3, R1)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D2)}]} + +Level 3: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), Place(D1), NotIn(C1, D2), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} + Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PPlace(D1), PNotIn(C1, D2), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C1, D3), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D2)}, {PNotIn(C2, D1), PIn(C3, R1)}, {PNotIn(R1, D3), PNotIn(C2, D1)}, {PNotIn(C3, D2), PNotIn(C2, D1)}, {PNotIn(R1, D2), PNotIn(C2, D1)}, {PNotIn(C1, D2), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D3)}, {PNotIn(C2, R1), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PickUp(R1, C1, D3), PNotIn(C2, D1)}, {PickUp(R1, C1, D2), PNotIn(C2, D1)}, {PutDown(R1, C3, D1), PNotIn(C2, D1)}, {PutDown(R1, C3, D3), PNotIn(C2, D1)}, {PutDown(R1, C3, D2), PNotIn(C2, D1)}, {PNotIn(C1, D3), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D2)}, {PIn(C2, R1), PIn(C3, R1)}, {PNotIn(R1, D3), PIn(C2, R1)}, {PNotIn(C3, D2), PIn(C2, R1)}, {PNotIn(R1, D2), PIn(C2, R1)}, {PNotIn(C1, D2), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D3)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C1, D3), PIn(C2, R1)}, {PickUp(R1, C1, D2), PIn(C2, R1)}, {PutDown(R1, C3, D1), PIn(C2, R1)}, {PutDown(R1, C3, D3), PIn(C2, R1)}, {PutDown(R1, C3, D2), PIn(C2, R1)}, {PNotIn(C1, D3), PNotIn(C1, R1)}, {PNotIn(C1, R1), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PNotIn(C1, D3), PIn(R1, D1)}, {PIn(C3, R1), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, D2), PIn(R1, D1)}, {PNotIn(C1, D2), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D1), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C1, D2)}, {PNotIn(C1, D3), PIn(C3, R1)}, {PNotIn(C1, D3), PIn(R1, D2)}, {PNotIn(C1, D3), PNotHolding(R1)}, {PNotIn(C1, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D2)}, {PNotIn(C1, D3), PNotIn(R1, D2)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D1)}, {PNotIn(C1, D3), PickUp(R1, C3, D2)}, {PNotIn(C1, D3), PickUp(R1, C1, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D3)}, {PutDown(R1, C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PNotIn(C1, D3)}, {PutDown(R1, C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), Move(R1, D1, D3)}, {PNotIn(C1, D3), Move(R1, D1, D2)}, {PNotIn(C1, D3), Move(R1, D2, D1)}, {PNotIn(C1, D3), Move(R1, D2, D3)}, {PNotIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PNotIn(C2, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C1, D2)}, {PutDown(R1, C2, D3), PIn(C1, D2)}, {PutDown(R1, C2, D2), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C3, D2)}, {PNotHolding(R1), PIn(C3, R1)}, {PIn(C3, R1), PIn(R1, D3)}, {PNotIn(C1, D1), PIn(C3, R1)}, {PNotIn(R1, D3), PIn(C3, R1)}, {PNotIn(R1, D2), PIn(C3, R1)}, {PIn(C3, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C3, R1)}, {PickUp(R1, C2, D1), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PickUp(R1, C1, D1), PIn(C3, R1)}, {PickUp(R1, C1, D3), PIn(C3, R1)}, {PickUp(R1, C1, D2), PIn(C3, R1)}, {PutDown(R1, C2, D1), PIn(C3, R1)}, {PutDown(R1, C2, D3), PIn(C3, R1)}, {PutDown(R1, C2, D2), PIn(C3, R1)}, {PutDown(R1, C1, D1), PIn(C3, R1)}, {PutDown(R1, C1, D3), PIn(C3, R1)}, {Move(R1, D1, D3), PIn(C3, R1)}, {Move(R1, D1, D2), PIn(C3, R1)}, {Move(R1, D3, D1), PIn(C3, R1)}, {Move(R1, D3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PNotIn(C2, R1), PIn(R1, D2)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C1, D3)}, {PHolding(R1), PNotIn(C2, R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotIn(C3, D2), PNotHolding(R1)}, {PNotIn(C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C3, D2), PIn(R1, D3)}, {PNotIn(C1, D2), PIn(R1, D3)}, {PNotIn(C2, R1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D3), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D1)}, {PNotIn(C3, D2), PNotIn(C1, D1)}, {PNotIn(R1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, D1)}, {PickUp(R1, C1, D2), PNotIn(C1, D1)}, {PutDown(R1, C3, D1), PNotIn(C1, D1)}, {PutDown(R1, C3, D3), PNotIn(C1, D1)}, {PutDown(R1, C3, D2), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C3, D2)}, {PNotIn(R1, D3), PNotIn(C1, D2)}, {PNotIn(R1, D3), PNotIn(C2, R1)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D1)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PutDown(R1, C3, D1)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D2)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, D2), PNotIn(R1, D2)}, {PNotIn(C3, D2), PIn(C1, D3)}, {PNotIn(C3, D2), PNotIn(C2, R1)}, {PNotIn(C3, D2), PickUp(R1, C2, D1)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C3, D2), PickUp(R1, C1, D1)}, {PNotIn(C3, D2), PickUp(R1, C1, D3)}, {PNotIn(C3, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C3, D2)}, {PutDown(R1, C2, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C3, D2)}, {PNotIn(C3, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C3, D2)}, {PutDown(R1, C1, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), Move(R1, D1, D3)}, {PNotIn(C3, D2), Move(R1, D1, D2)}, {PNotIn(C3, D2), Move(R1, D3, D1)}, {PNotIn(C3, D2), Move(R1, D3, D2)}, {PNotIn(C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), PNotIn(C2, R1)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D1), PNotIn(R1, D2)}, {PutDown(R1, C2, D3), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D1), PNotIn(R1, D2)}, {PutDown(R1, C3, D3), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C1, D2), PIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D1)}, {PNotIn(C1, D2), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D1)}, {PNotIn(C1, D2), PickUp(R1, C1, D3)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D2)}, {PutDown(R1, C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C1, D2)}, {PutDown(R1, C1, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), Move(R1, D1, D3)}, {PNotIn(C1, D2), Move(R1, D1, D2)}, {PNotIn(C1, D2), Move(R1, D3, D1)}, {PNotIn(C1, D2), Move(R1, D3, D2)}, {PIn(C1, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C2, D1), PIn(C1, D3)}, {PutDown(R1, C2, D3), PIn(C1, D3)}, {PutDown(R1, C2, D2), PIn(C1, D3)}, {PutDown(R1, C3, D1), PIn(C1, D3)}, {PutDown(R1, C3, D3), PIn(C1, D3)}, {PutDown(R1, C3, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C2, R1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C3, D2), PNotIn(C2, R1)}, {PickUp(R1, C1, D3), PNotIn(C2, R1)}, {PickUp(R1, C1, D2), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C3, D2), PNotIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C2, R1)}, {PutDown(R1, C1, D3), PNotIn(C2, R1)}, {PutDown(R1, C1, D2), PNotIn(C2, R1)}, {PNotIn(C2, R1), Move(R1, D3, D1)}, {PNotIn(C2, R1), Move(R1, D3, D2)}, {PNotIn(C2, R1), Move(R1, D2, D1)}, {PNotIn(C2, R1), Move(R1, D2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{NotIn(C1, D3), NotIn(C2, D1)}, {NotIn(C1, D2), NotIn(C2, D1)}, {In(C2, D1), NotIn(C2, D1)}, {NotIn(C3, R1), NotIn(C2, D1)}, {NotIn(C1, D3), In(C2, R1)}, {NotIn(C1, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C3, R1), In(C2, R1)}, {NotIn(C1, R1), NotIn(C1, D3)}, {NotIn(C1, R1), NotIn(C1, D2)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), In(C2, D3)}, {In(R1, D1), In(C2, D2)}, {NotIn(C3, R1), In(R1, D1)}, {NotIn(C1, D3), In(C1, D2)}, {NotIn(C1, D3), In(C3, R1)}, {NotIn(C1, D3), NotHolding(R1)}, {NotIn(C1, D3), NotIn(C1, D1)}, {NotIn(C1, D3), In(C1, D1)}, {NotIn(C3, D2), NotIn(C1, D3)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C1, D3), In(C2, D3)}, {NotIn(C1, D3), In(C2, D2)}, {NotIn(C1, D3), NotIn(C3, R1)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C2, R1), In(C1, D2)}, {In(C1, D2), In(C2, D3)}, {In(C1, D2), In(C2, D2)}, {In(C3, D2), In(C3, R1)}, {NotIn(C2, R1), In(C3, R1)}, {In(C2, D3), In(C3, R1)}, {In(C2, D2), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {In(C2, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {Holding(R1), In(C2, D3)}, {Holding(R1), In(C2, D2)}, {NotIn(C3, R1), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C2, D2), In(R1, D3)}, {NotIn(C3, R1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {NotIn(C1, D2), NotIn(C1, D1)}, {NotIn(C3, R1), NotIn(C1, D1)}, {NotIn(C1, D2), In(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, R1), NotIn(R1, D3)}, {NotIn(R1, D3), In(C2, D3)}, {NotIn(R1, D3), In(C2, D2)}, {NotIn(R1, D3), NotIn(C3, R1)}, {NotIn(C2, R1), NotIn(C3, D2)}, {NotIn(C3, D2), In(C2, D3)}, {NotIn(C3, D2), In(C2, D2)}, {NotIn(C3, D2), NotIn(C3, R1)}, {NotIn(R1, D2), NotIn(C2, R1)}, {NotIn(R1, D2), In(C2, D3)}, {NotIn(R1, D2), In(C2, D2)}, {NotIn(R1, D2), NotIn(C3, R1)}, {NotIn(C1, D2), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D2)}, {NotIn(C1, D2), In(C2, D3)}, {NotIn(C1, D2), In(C2, D2)}, {In(C1, D3), In(C1, R1)}, {NotIn(C2, R1), In(C1, D3)}, {In(C1, D3), In(C2, D3)}, {In(C1, D3), In(C2, D2)}, {NotIn(C3, R1), In(C1, D3)}, {NotIn(C2, R1), NotIn(C3, R1)}, {In(C2, D1), In(C2, D3)}, {In(C2, D1), In(C2, D2)}, {In(C2, D3), In(C2, D2)}, {NotIn(C3, R1), In(C2, D3)}, {NotIn(C3, R1), In(C2, D2)}]} + +Level 4: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), Container(C1), In(C1, D2), In(C2, D3), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} + Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(C2, D3), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C1, D3), PNotIn(C2, D1)}, {PNotIn(C3, R1), PNotIn(C2, D1)}, {PNotIn(C1, D2), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PNotIn(C1, D3), PIn(C2, R1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, R1)}, {PNotIn(C1, D2), PIn(C2, R1)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PNotIn(C1, D3), PNotIn(C1, R1)}, {PNotIn(C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(C2, D3), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(C2, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, R1), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C1, D2)}, {PNotIn(C1, D3), PIn(C2, D3)}, {PNotIn(C1, D3), PIn(C3, R1)}, {PNotIn(C1, D3), PNotHolding(R1)}, {PNotIn(C1, D3), PIn(C2, D2)}, {PNotIn(C1, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D2)}, {PNotIn(C3, R1), PNotIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D1)}, {PNotIn(C1, D3), PickUp(R1, C2, D3)}, {PNotIn(C1, D3), PickUp(R1, C2, D2)}, {PNotIn(C1, D3), PickUp(R1, C3, D2)}, {PNotIn(C1, D3), PickUp(R1, C1, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D3)}, {PutDown(R1, C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D2)}, {PIn(C2, D3), PIn(C1, D2)}, {PIn(C2, D2), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PNotIn(C2, R1), PIn(C1, D2)}, {PickUp(R1, C2, D3), PIn(C1, D2)}, {PickUp(R1, C2, D2), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C2, D3)}, {PIn(R1, D2), PIn(C2, D3)}, {PHolding(R1), PIn(C2, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PNotIn(R1, D3), PIn(C2, D3)}, {PNotIn(C3, D2), PIn(C2, D3)}, {PNotIn(R1, D2), PIn(C2, D3)}, {PNotIn(C3, R1), PIn(C2, D3)}, {PNotIn(C1, D2), PIn(C2, D3)}, {PIn(C1, D3), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D2), PIn(C2, D3)}, {PickUp(R1, C1, D1), PIn(C2, D3)}, {PickUp(R1, C1, D3), PIn(C2, D3)}, {PickUp(R1, C1, D2), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PutDown(R1, C3, D1), PIn(C2, D3)}, {PutDown(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C3, D2), PIn(C2, D3)}, {PutDown(R1, C1, D1), PIn(C2, D3)}, {PutDown(R1, C1, D3), PIn(C2, D3)}, {PutDown(R1, C1, D2), PIn(C2, D3)}, {Move(R1, D1, D3), PIn(C2, D3)}, {Move(R1, D1, D2), PIn(C2, D3)}, {Move(R1, D2, D1), PIn(C2, D3)}, {Move(R1, D2, D3), PIn(C2, D3)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, R1), PIn(C2, D2)}, {PNotIn(C2, R1), PIn(C3, R1)}, {PickUp(R1, C2, D3), PIn(C3, R1)}, {PickUp(R1, C2, D2), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C2, D2)}, {PNotIn(C3, R1), PHolding(R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PIn(R1, D3), PIn(C2, D2)}, {PNotIn(R1, D3), PIn(C2, D2)}, {PNotIn(C3, D2), PIn(C2, D2)}, {PNotIn(R1, D2), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, D2)}, {PNotIn(C1, D2), PIn(C2, D2)}, {PIn(C1, D3), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PickUp(R1, C1, D1), PIn(C2, D2)}, {PickUp(R1, C1, D3), PIn(C2, D2)}, {PickUp(R1, C1, D2), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PutDown(R1, C3, D1), PIn(C2, D2)}, {PutDown(R1, C3, D3), PIn(C2, D2)}, {PutDown(R1, C3, D2), PIn(C2, D2)}, {PutDown(R1, C1, D1), PIn(C2, D2)}, {PutDown(R1, C1, D3), PIn(C2, D2)}, {PutDown(R1, C1, D2), PIn(C2, D2)}, {Move(R1, D1, D3), PIn(C2, D2)}, {Move(R1, D1, D2), PIn(C2, D2)}, {Move(R1, D3, D1), PIn(C2, D2)}, {Move(R1, D3, D2), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(C3, R1), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, D1)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C3, R1)}, {PNotIn(R1, D3), PNotIn(C2, R1)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D2)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, R1), PNotIn(C3, D2)}, {PNotIn(C3, D2), PNotIn(C2, R1)}, {PNotIn(C3, D2), PickUp(R1, C2, D3)}, {PNotIn(C3, D2), PickUp(R1, C2, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C3, R1), PNotIn(R1, D2)}, {PNotIn(R1, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(R1, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PIn(C1, D3)}, {PNotIn(C3, R1), PNotIn(C2, R1)}, {PNotIn(C3, R1), PickUp(R1, C2, D1)}, {PNotIn(C3, R1), PickUp(R1, C2, D3)}, {PNotIn(C3, R1), PickUp(R1, C2, D2)}, {PNotIn(C3, R1), PickUp(R1, C1, D1)}, {PNotIn(C3, R1), PickUp(R1, C1, D3)}, {PNotIn(C3, R1), PutDown(R1, C2, D1)}, {PNotIn(C3, R1), PutDown(R1, C2, D3)}, {PNotIn(C3, R1), PutDown(R1, C2, D2)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C3, R1), PutDown(R1, C1, D1)}, {PNotIn(C3, R1), PutDown(R1, C1, D3)}, {PNotIn(C3, R1), PutDown(R1, C1, D2)}, {PNotIn(C3, R1), Move(R1, D1, D3)}, {PNotIn(C3, R1), Move(R1, D1, D2)}, {PNotIn(C3, R1), Move(R1, D3, D1)}, {PNotIn(C3, R1), Move(R1, D3, D2)}, {PNotIn(C1, D2), PIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D3)}, {PNotIn(C1, D2), PickUp(R1, C2, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D1)}, {PNotIn(C1, D2), PickUp(R1, C1, D3)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D2)}, {PutDown(R1, C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C2, D2)}, {PIn(C1, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C1, D3)}, {PickUp(R1, C2, D3), PIn(C1, D3)}, {PickUp(R1, C2, D2), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C1, D3), PNotIn(C2, R1)}, {PickUp(R1, C1, D2), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C3, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(C2, D3), In(R1, D1)}, {NotIn(C2, D2), In(R1, D1)}, {In(C3, D3), In(R1, D1)}, {NotIn(C1, D3), In(C2, D3)}, {NotIn(C1, D3), In(C2, D2)}, {NotIn(C1, D3), NotIn(C3, R1)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C1, D3), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C1, D3)}, {NotIn(C1, D3), In(C3, D1)}, {NotIn(C1, D3), In(C3, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C2, D3), In(C1, D2)}, {NotIn(C2, D2), In(C1, D2)}, {Holding(R1), In(C2, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C3, R1), In(C2, D3)}, {NotIn(C1, D2), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C2, D2), In(C2, D3)}, {In(C3, D1), In(C2, D3)}, {In(C3, D3), In(C2, D3)}, {In(C3, D2), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {NotIn(C2, D3), In(C3, R1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C2, D3), In(R1, D2)}, {In(C3, D1), In(R1, D2)}, {In(C3, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D1), Holding(R1)}, {In(C3, D3), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {In(C3, D1), In(C3, D2)}, {In(C3, D3), In(C3, D2)}, {NotIn(C2, D3), NotHolding(R1)}, {NotIn(C2, D2), NotHolding(R1)}, {NotIn(C3, R1), In(C2, D2)}, {NotIn(C1, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(C2, D3), In(C2, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C3, D1), In(C2, D2)}, {In(C3, D3), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C2, D2), In(R1, D3)}, {In(C3, D1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D3), NotIn(R1, D3)}, {NotIn(C2, D2), NotIn(R1, D3)}, {NotIn(R1, D3), In(C3, D3)}, {NotIn(C3, D2), NotIn(C2, D3)}, {NotIn(R1, D2), NotIn(C2, D3)}, {NotIn(R1, D2), NotIn(C2, D2)}, {NotIn(C2, R1), NotIn(C3, R1)}, {NotIn(C2, D3), NotIn(C3, R1)}, {NotIn(C2, D2), NotIn(C3, R1)}, {NotIn(C2, R1), NotIn(C1, D2)}, {NotIn(C1, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C1, D2)}, {In(C1, D3), In(C1, R1)}, {NotIn(C2, D3), In(C1, D3)}, {NotIn(C2, D2), In(C1, D3)}, {NotIn(R1, D1), In(C3, D1)}, {NotIn(C2, R1), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D2)}, {NotIn(C2, R1), In(C3, D1)}, {NotIn(C2, R1), In(C3, D3)}, {NotIn(C2, D3), In(C2, D1)}, {NotIn(C2, D2), In(C2, D1)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D3), In(C3, D1)}, {NotIn(C2, D3), In(C3, D3)}, {NotIn(C2, D2), In(C3, D1)}, {NotIn(C2, D2), In(C3, D3)}, {In(C3, D1), In(C3, D3)}]} + +Level 5: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, D1), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} + Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PIn(C2, D3), PContainer(C1), PIn(C1, D2), PIn(C3, D1), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PIn(C3, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(C2, D2), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PNotIn(C2, D3), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D1), PickUp(R1, C3, D3), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(C2, D2), PIn(C2, D2)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D1)}, {PNotIn(C3, R1), PickUp(R1, C3, D3)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C3, D1), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PIn(C3, D3), PIn(R1, D1)}, {PNotIn(C2, D2), PIn(R1, D1)}, {PNotIn(C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C2, D3)}, {PNotIn(C1, D3), PIn(C3, D1)}, {PNotIn(C1, D3), PIn(C2, D2)}, {PIn(C3, D3), PNotIn(C1, D3)}, {PNotIn(C2, D2), PNotIn(C1, D3)}, {PNotIn(C3, R1), PNotIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D3)}, {PNotIn(C1, D3), PickUp(R1, C2, D2)}, {PNotIn(C1, D3), PickUp(R1, C3, D1)}, {PNotIn(C1, D3), PickUp(R1, C3, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PIn(C3, D1), PIn(C2, D3)}, {PHolding(R1), PIn(C2, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PIn(C3, D3), PIn(C2, D3)}, {PNotIn(C2, D2), PIn(C2, D3)}, {PNotIn(C3, R1), PIn(C2, D3)}, {PNotIn(C1, D2), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D1), PIn(C2, D3)}, {PickUp(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PutDown(R1, C3, D1), PIn(C2, D3)}, {PutDown(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C3, D2), PIn(C2, D3)}, {PutDown(R1, C1, D1), PIn(C2, D3)}, {PutDown(R1, C1, D3), PIn(C2, D3)}, {PutDown(R1, C1, D2), PIn(C2, D3)}, {PIn(C1, D1), PIn(C1, D2)}, {PNotIn(C2, D2), PIn(C1, D2)}, {PNotIn(C2, D3), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, D1), PIn(C3, R1)}, {PIn(C3, D1), PIn(R1, D2)}, {PIn(C3, D1), PHolding(R1)}, {PIn(C3, D1), PIn(C3, D2)}, {PIn(C3, D1), PIn(C2, D2)}, {PIn(C3, D1), PIn(R1, D3)}, {PIn(C3, D3), PIn(C3, D1)}, {PNotIn(C2, D2), PIn(C3, D1)}, {PNotIn(C2, D3), PIn(C3, D1)}, {PNotIn(R1, D1), PIn(C3, D1)}, {PIn(C3, D1), PNotIn(C2, R1)}, {PIn(C3, D1), PickUp(R1, C2, D3)}, {PIn(C3, D1), PickUp(R1, C2, D2)}, {PIn(C3, D1), PickUp(R1, C3, D3)}, {PIn(C3, D1), PickUp(R1, C3, D2)}, {PIn(C3, D1), PickUp(R1, C1, D3)}, {PIn(C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PIn(C3, D1)}, {PutDown(R1, C2, D3), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C3, D3)}, {PIn(C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PIn(C3, D1)}, {PutDown(R1, C1, D3), PIn(C3, D1)}, {PutDown(R1, C1, D2), PIn(C3, D1)}, {PIn(C3, D1), Move(R1, D3, D1)}, {PIn(C3, D1), Move(R1, D3, D2)}, {PIn(C3, D1), Move(R1, D2, D1)}, {PIn(C3, D1), Move(R1, D2, D3)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, R1)}, {PNotIn(C2, D3), PIn(C3, R1)}, {PickUp(R1, C3, D1), PIn(C3, R1)}, {PickUp(R1, C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(C3, D3), PIn(R1, D2)}, {PNotIn(C2, D3), PIn(R1, D2)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C3, D1), PIn(R1, D2)}, {PickUp(R1, C3, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PIn(C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PIn(C3, D3), PIn(C3, D2)}, {PickUp(R1, C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotIn(C2, D2), PNotHolding(R1)}, {PNotIn(C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PIn(C3, D3), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, D2)}, {PNotIn(C1, D2), PIn(C2, D2)}, {PNotIn(C2, D3), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PickUp(R1, C3, D1), PIn(C2, D2)}, {PickUp(R1, C3, D3), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D2)}, {PIn(C3, D3), PNotIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D3)}, {PIn(C3, D3), PNotIn(C2, R1)}, {PIn(C3, D3), PickUp(R1, C2, D1)}, {PIn(C3, D3), PickUp(R1, C2, D3)}, {PIn(C3, D3), PickUp(R1, C2, D2)}, {PIn(C3, D3), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D2)}, {PIn(C3, D3), PickUp(R1, C1, D1)}, {PIn(C3, D3), PickUp(R1, C1, D2)}, {PIn(C3, D3), PutDown(R1, C2, D1)}, {PIn(C3, D3), PutDown(R1, C2, D3)}, {PIn(C3, D3), PutDown(R1, C2, D2)}, {PIn(C3, D3), PutDown(R1, C3, D1)}, {PIn(C3, D3), PutDown(R1, C3, D3)}, {PIn(C3, D3), PutDown(R1, C3, D2)}, {PIn(C3, D3), PutDown(R1, C1, D1)}, {PIn(C3, D3), PutDown(R1, C1, D3)}, {PIn(C3, D3), PutDown(R1, C1, D2)}, {PIn(C3, D3), Move(R1, D1, D3)}, {PIn(C3, D3), Move(R1, D1, D2)}, {PIn(C3, D3), Move(R1, D2, D1)}, {PIn(C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PNotIn(R1, D2)}, {PNotIn(C3, R1), PNotIn(C2, D2)}, {PNotIn(C1, D2), PNotIn(C2, D2)}, {PNotIn(C2, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PIn(C1, D3)}, {PNotIn(C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C2, D1)}, {PNotIn(C2, D2), PickUp(R1, C2, D3)}, {PNotIn(C2, D2), PickUp(R1, C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C3, D1)}, {PNotIn(C2, D2), PickUp(R1, C3, D3)}, {PNotIn(C2, D2), PickUp(R1, C3, D2)}, {PNotIn(C2, D2), PickUp(R1, C1, D1)}, {PNotIn(C2, D2), PickUp(R1, C1, D3)}, {PNotIn(C2, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C2, D2)}, {PutDown(R1, C2, D3), PNotIn(C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C2, D2)}, {PutDown(R1, C1, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), Move(R1, D1, D3)}, {PNotIn(C2, D2), Move(R1, D1, D2)}, {PNotIn(C2, D2), Move(R1, D3, D1)}, {PNotIn(C2, D2), Move(R1, D3, D2)}, {PNotIn(R1, D3), PNotIn(C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C2, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(R1, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PNotIn(C2, D3)}, {PNotIn(C3, R1), PNotIn(C2, R1)}, {PNotIn(C3, R1), PickUp(R1, C2, D3)}, {PNotIn(C3, R1), PickUp(R1, C2, D2)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D3)}, {PNotIn(C1, D2), PickUp(R1, C2, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C1, D3)}, {PNotIn(C2, D3), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D1)}, {PNotIn(C2, D3), PickUp(R1, C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D2)}, {PNotIn(C2, D3), PickUp(R1, C3, D1)}, {PNotIn(C2, D3), PickUp(R1, C3, D3)}, {PNotIn(C2, D3), PickUp(R1, C3, D2)}, {PNotIn(C2, D3), PickUp(R1, C1, D1)}, {PNotIn(C2, D3), PickUp(R1, C1, D3)}, {PNotIn(C2, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C3, D3)}, {PNotIn(C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PNotIn(C2, D3)}, {PutDown(R1, C1, D2), PNotIn(C2, D3)}, {PNotIn(C2, D3), Move(R1, D1, D3)}, {PNotIn(C2, D3), Move(R1, D1, D2)}, {PNotIn(C2, D3), Move(R1, D2, D1)}, {PNotIn(C2, D3), Move(R1, D2, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C3, D1), PNotIn(C2, R1)}, {PickUp(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D2)}, {PickUp(R1, C3, D1), Move(R1, D2, D1)}, {PickUp(R1, C3, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C3, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C3, D1)}, {Move(R1, D1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C1, D3)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C1, D3), NotIn(C3, D1)}, {In(C3, D1), In(C2, D3)}, {In(C2, D3), In(C2, D2)}, {In(C3, D3), In(C2, D3)}, {NotIn(C2, D2), In(C2, D3)}, {NotIn(C2, D3), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D3), NotIn(C3, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {NotIn(C2, D2), In(C3, D1)}, {In(C3, D1), NotIn(C2, D3)}, {In(C3, D1), NotIn(C3, D1)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C3, D1), In(R1, D2)}, {NotIn(C3, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotHolding(R1), NotIn(C3, D1)}, {NotHolding(R1), NotIn(C3, D3)}, {NotIn(C2, D2), In(C2, D2)}, {NotIn(C2, D3), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(C3, D1), In(C2, D2)}, {In(C2, D2), NotIn(C3, D3)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C3, D1), In(R1, D3)}, {NotIn(C2, D2), In(C3, D3)}, {NotIn(C2, D3), In(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C3, D3), NotIn(C3, D3)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D2)}, {NotIn(C2, D2), In(C2, D1)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(R1, D3), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, R1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C1, D2), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D3)}, {NotIn(C2, D3), In(C2, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D3)}, {In(C1, D3), In(C1, R1)}, {NotIn(R1, D1), NotIn(C3, D1)}, {NotIn(C2, R1), NotIn(C3, D1)}, {NotIn(C2, R1), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}]} + +Level 6: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), In(C3, D1), NotIn(C1, D3), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C3, D3), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(C3, D1), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} + Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PIn(C3, D1), PNotIn(C1, D3), PContainer(C3), PIn(C2, D3), PContainer(C1), PIn(C1, D2), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PIn(C3, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(C3, D3), PNotIn(C2, D2), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PNotIn(C2, D3), PIn(C1, D3), PNotIn(C3, D1), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D1), PickUp(R1, C3, D3), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} + Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C3, D3), PNotIn(C3, D3)}, {PIn(C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PNotIn(C3, D3)}, {PNotIn(C2, D2), PIn(C2, D2)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D1)}, {PNotIn(C3, R1), PickUp(R1, C3, D3)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D3)}, {PIn(C3, D1), PNotIn(C3, D1)}, {PIn(C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PNotIn(C3, D1)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, D3), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PIn(C3, D1), PIn(C2, D3)}, {PIn(C3, D1), PIn(C3, R1)}, {PIn(C3, D1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, D1)}, {PIn(C3, D1), PNotIn(C3, D3)}, {PNotIn(C2, D2), PIn(C3, D1)}, {PNotIn(C2, D3), PIn(C3, D1)}, {PIn(C3, D1), PickUp(R1, C2, D3)}, {PIn(C3, D1), PickUp(R1, C3, D3)}, {PIn(C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C3, D3)}, {PIn(C3, D1), PutDown(R1, C3, D2)}, {PNotIn(C2, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PIn(C3, D3), PIn(C2, D3)}, {PNotIn(C3, D3), PIn(C2, D3)}, {PNotIn(C2, D2), PIn(C2, D3)}, {PNotIn(C3, D1), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D1), PIn(C2, D3)}, {PickUp(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D1), PIn(C3, R1)}, {PickUp(R1, C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(R1, D2), PNotIn(C3, D3)}, {PIn(R1, D2), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C3, D1), PIn(R1, D2)}, {PickUp(R1, C3, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PIn(C3, D3), PIn(C3, D2)}, {PNotIn(C3, D3), PIn(C3, D2)}, {PNotIn(C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotHolding(R1), PNotIn(C3, D3)}, {PNotHolding(R1), PNotIn(C3, D1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C3, D3), PIn(C2, D2)}, {PNotIn(C2, D3), PIn(C2, D2)}, {PNotIn(C3, D1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PIn(R1, D3), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D2)}, {PIn(C3, D3), PNotIn(C2, D3)}, {PIn(C3, D3), PNotIn(C3, D1)}, {PIn(C3, D3), PickUp(R1, C2, D3)}, {PIn(C3, D3), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D2)}, {PIn(C3, D3), PutDown(R1, C3, D1)}, {PIn(C3, D3), PutDown(R1, C3, D3)}, {PIn(C3, D3), PutDown(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(C2, D2), PNotIn(C3, D3)}, {PNotIn(R1, D3), PNotIn(C3, D3)}, {PNotIn(C3, R1), PNotIn(C3, D3)}, {PNotIn(C2, D3), PNotIn(C3, D3)}, {PNotIn(C3, D3), PNotIn(C3, D1)}, {PNotIn(C2, R1), PNotIn(C3, D3)}, {PickUp(R1, C2, D1), PNotIn(C3, D3)}, {PickUp(R1, C2, D3), PNotIn(C3, D3)}, {PickUp(R1, C2, D2), PNotIn(C3, D3)}, {PickUp(R1, C3, D1), PNotIn(C3, D3)}, {PickUp(R1, C3, D3), PNotIn(C3, D3)}, {PickUp(R1, C3, D2), PNotIn(C3, D3)}, {PickUp(R1, C1, D1), PNotIn(C3, D3)}, {PickUp(R1, C1, D3), PNotIn(C3, D3)}, {PickUp(R1, C1, D2), PNotIn(C3, D3)}, {PutDown(R1, C2, D1), PNotIn(C3, D3)}, {PutDown(R1, C2, D2), PNotIn(C3, D3)}, {PutDown(R1, C3, D1), PNotIn(C3, D3)}, {PutDown(R1, C3, D2), PNotIn(C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C3, D3)}, {PutDown(R1, C1, D2), PNotIn(C3, D3)}, {Move(R1, D1, D3), PNotIn(C3, D3)}, {Move(R1, D1, D2), PNotIn(C3, D3)}, {Move(R1, D2, D1), PNotIn(C3, D3)}, {Move(R1, D2, D3), PNotIn(C3, D3)}, {PNotIn(C2, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PNotIn(C3, D1)}, {PNotIn(C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C2, D1)}, {PNotIn(C2, D2), PickUp(R1, C2, D3)}, {PNotIn(C2, D2), PickUp(R1, C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C3, D1)}, {PNotIn(C2, D2), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PNotIn(C2, D3)}, {PNotIn(C3, R1), PNotIn(C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C2, D3), PNotIn(C3, D1)}, {PNotIn(C2, D3), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D1)}, {PNotIn(C2, D3), PickUp(R1, C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D2)}, {PNotIn(C2, D3), PickUp(R1, C3, D1)}, {PNotIn(C2, D3), PickUp(R1, C3, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C3, D1)}, {PNotIn(C2, R1), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PNotIn(C3, D1)}, {PickUp(R1, C2, D3), PNotIn(C3, D1)}, {PickUp(R1, C2, D2), PNotIn(C3, D1)}, {PickUp(R1, C3, D1), PNotIn(C3, D1)}, {PickUp(R1, C3, D3), PNotIn(C3, D1)}, {PickUp(R1, C3, D2), PNotIn(C3, D1)}, {PickUp(R1, C1, D1), PNotIn(C3, D1)}, {PickUp(R1, C1, D3), PNotIn(C3, D1)}, {PickUp(R1, C1, D2), PNotIn(C3, D1)}, {PutDown(R1, C2, D3), PNotIn(C3, D1)}, {PutDown(R1, C2, D2), PNotIn(C3, D1)}, {PutDown(R1, C3, D3), PNotIn(C3, D1)}, {PutDown(R1, C3, D2), PNotIn(C3, D1)}, {PutDown(R1, C1, D3), PNotIn(C3, D1)}, {PutDown(R1, C1, D2), PNotIn(C3, D1)}, {Move(R1, D3, D1), PNotIn(C3, D1)}, {Move(R1, D3, D2), PNotIn(C3, D1)}, {Move(R1, D2, D1), PNotIn(C3, D1)}, {Move(R1, D2, D3), PNotIn(C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D2)}, {PickUp(R1, C3, D1), Move(R1, D2, D1)}, {PickUp(R1, C3, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C3, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C3, D1)}, {Move(R1, D1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} + Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D1), NotIn(C3, D1)}, {NotIn(C1, D3), In(C1, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C3, D3), NotIn(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {In(C1, D3), In(C1, R1)}]} + +Level 7: + + Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), In(C3, D1), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C3, D3), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(C3, D1), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} + Actions: {} + Mutex: {{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D1), NotIn(C3, D1)}, {NotIn(C1, D3), In(C1, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C3, D3), NotIn(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {In(C1, D3), In(C1, R1)}} + Next state mutexes: {[]} \ No newline at end of file diff --git a/debug_logistics_err.py b/debug_logistics_err.py index e0b23b78d..5c55f3f88 100644 --- a/debug_logistics_err.py +++ b/debug_logistics_err.py @@ -92,3 +92,66 @@ [PutDown(R1, C3, D3)], ], ] + + + + + + +goal: +[Robot(R1), In(C3, R1), Place(D3), In(R1, D3), Container(C3), In(R1, D3), In(C1, D3), NotHolding(R1), Robot(R1), Place(D3), Container(C1), In(C2, D3)] + +These non mutex actions that lead to above + +[[PRobot(R1), PIn(C3, R1), PPlace(D3), PIn(R1, D3), PContainer(C3), PickUp(R1, C1, D3), PIn(C2, D3)]] + + + + + +# Why is `PIn(C3, R1)` not mutex with `PickUp(R1, C1, D3)`? + + +Technically, no direct precondition error +PIn(C3,R1) required a PickUp(R1, C3, ?) at some point, + + +[PRobot(R1)], [PPlace(D3)], [PContainer(C3)], PHolding(R1), [PIn(C2, D3)] [ Move(R1, D2, D3), Move(R1, D1, D3)]], PIn(C3, R1) + +# (PHolding(R1), PIn(C2, D3)) is mutex @ -3 level + +""" +goal state -1 +putdown layer +previous_layer -2 +wacky_actions - (PHolding(R1), PIn(C2, D3)) is mutex - shoudl be move to d3 +previous_layer -3 - (Holding(R1), In(C2, D3)) is mutex +should be pickup(c3) - + + +Not inconsistent effects +Not interference +Has to be competing needs - preconditions are mutex + - Therefore, (Holding(R1), In(C2, D3)) is likely mutex - it is + +Why are these mutex? Props are only mutex if actions that cause it in prior layer are ... + - (pickup anything, holding(r1)), (In(C2, D3), putdown(d2,d3)) + - Pickup(R1, C3, D2), PIn(C2, D3) shouldn't be mutex, but it is + - + +""" + +PickUp(R1, C1, D2), PickUp(R1, C3, D2) are not mutex +Why? +Preconds: + In(r, d) & In (c, d) & ~Holding(r) +Effects: + Holding(r) & ~In(c, d) & In(c, r) + + +They negate the same precondition? One makes the others precondition false + + +(PIn(C2, D3), Move(R1, D2, D3), PIn(C3, R1), PHolding(R1), PRobot(R1), PPlace(D3), PContainer(C3)) failed due to (PIn(C2, D3), PHolding(R1)) in mutex + +mutex (PHolding(R1), PIn(C2, D3)) excludes our action set from being applicable. diff --git a/graphplan_debugger.py b/graphplan_debugger.py new file mode 100644 index 000000000..6691a06df --- /dev/null +++ b/graphplan_debugger.py @@ -0,0 +1,133 @@ +import re +from typing import List, Set, Any +from logic import expr, Expr + + +""" +PlanDebugger.run("logistics_trace1.txt", self.graph) +""" + +def rund(graph): + return PlanDebugger.run("logistics_trace1.txt", graph) + + +class PlanLevel: + def __init__(self, current_state: Set[Any], actions: Set[Any], next_state: Set[Any]): + self.current_state = current_state + self.actions = actions + self.next_state = next_state + + def __repr__(self): + return (f"\n" + f" Current State: {self.current_state}\n" + f" Actions: {self.actions}\n" + f" Next State: {self.next_state}\n") + +class PlanDebugger: + """ + Utility to parse a plan trace from file and check it against a GraphPlan graph. + """ + + + @staticmethod + def parse_plan_file(filename: str) -> List[PlanLevel]: + plan_levels = [] + current_level = None + + state_prefixes = ('In(', 'Holding(', 'NotHolding(') # , 'PIn(', 'PHolding(' + + with open(filename, 'r') as f: + for line in f: + line = line.strip() + if not line: + continue + + tokens = [expr(tok.strip()) for tok in line.split("&") if tok.strip()] + + # Heuristic: starts with state prefixes → state line + if all(str(t).startswith(state_prefixes) for t in tokens): + # Start a new level + if current_level is not None: + # Assign previous level's next_state + current_level.next_state = set(tokens) + plan_levels.append(current_level) + + current_level = PlanLevel(current_state=set(tokens), actions=set(), next_state=set()) + + else: + # Action line → assign to current level + if current_level is None: + raise ValueError("File starts with actions before any state.") + current_level.actions = set(tokens) + + # Append the last level + if current_level is not None: + plan_levels.append(current_level) + + return plan_levels + + + @staticmethod + def check_plan_against_graph(plan_levels: List[PlanLevel], graph) -> str: + + for i, plan_level in enumerate(plan_levels): + plan_states = plan_level.current_state + plan_actions = plan_level.actions + next_plan_states = plan_level.next_state + + level = graph.levels[i] + print("# Levels: ", len(plan_levels)) + + # --- State check --- + graph_states = set(level.current_state) + missing_states = plan_states - graph_states + #print("PLAN_STATES: ", plan_states, "\nGRAPH_STATES: ", graph_states) + if missing_states: + return (f"❌ Divergence at LEVEL {i}: plan states not in graph level. " + f"Missing states: {missing_states}") + + # --- Action check --- + if plan_actions: + # Check applicability + for act in plan_actions: + if act not in level.next_action_links: + print(f"At level {i}, {level}") + return f"❌ Divergence at LEVEL {i}: action {act} not applicable" + + # Check mutex + if i == 7: + print(level.mutex) + for a1 in plan_actions: + for a2 in plan_actions: + if a1 != a2 and {a1, a2} in level.mutex: + return f"❌ Divergence at LEVEL {i}: actions {a1} and {a2} are mutex" + + # Verify successor states + successor_states = set() + for act in plan_actions: + if act in level.next_action_links: + successor_states.update(level.next_action_links[act]) + missing_next_states = next_plan_states - successor_states + if missing_next_states: + return (f"❌ Divergence at LEVEL {i}: next states don’t match action effects. " + f"Missing next states: {missing_next_states}") + + # --- State mutex check --- + for s1 in plan_states: + for s2 in plan_states: + if s1 != s2 and {s1, s2} in level.state_mutexes: + return f"❌ Divergence at LEVEL {i}: states {s1} and {s2} are mutex" + + return "✅ Plan is valid against the graph!" + + + @staticmethod + def run(filename: str, graph) -> str: + """ + Convenience wrapper to parse a plan file and check it against a graph. + """ + plan_levels = PlanDebugger.parse_plan_file(filename) + print("Plan: ", plan_levels) + result = PlanDebugger.check_plan_against_graph(plan_levels, graph) + return result + \ No newline at end of file diff --git a/logistics_trace1.txt b/logistics_trace1.txt new file mode 100644 index 000000000..7666425db --- /dev/null +++ b/logistics_trace1.txt @@ -0,0 +1,17 @@ +In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) +PutDown(R1, C1, D1) & PIn(C2, D1) & PIn(C3, D2) & PIn(R1, D1) +In(C1, D1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & NotHolding(R1) +PickUp(R1, C2, D1) & PIn(C1, D1) & PIn(C3, D2) & PIn(R1, D1) +In(C1, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) & In(C2, R1) +Move(R1, D1, D3) & PIn(C1, D1) & PIn(C3, D2) & PHolding(R1) & PIn(C2, R1) +In(C1, D1) & In(C3, D2) & In(C2, R1) & In(R1, D3) & Holding(R1) +PutDown(R1, C2, D3) & PIn(C1, D1) & PIn(C3, D2) & PIn(R1, D3) +In(C1, D1) & In(C3, D2) & In(R1, D3) & NotHolding(R1) & In(C2, D3) +Move(R1, D3, D2) & PIn(C1, D1) & PIn(C3, D2) & PIn(C2, D3) & PNotHolding(R1) +In(C1, D1) & In(C3, D2) & In(R1, D2) & NotHolding(R1) & In(C2, D3) +PickUp(R1, C3, D2) & PIn(C1, D1) & PIn(C2, D3) & PIn(R1, D2) +In(C1, D1) & In(C2, D3) & In(R1, D2) & Holding(R1) & In(C3, R1) +Move(R1, D2, D3) & PIn(C1, D1) & PIn(C2, D3) & PHolding(R1) & PIn(C3, R1) +In(C1, D1) & In(C2, D3) & In(C3, R1) & In(R1, D3) & Holding(R1) +PutDown(R1, C3, D3) & PIn(C1, D1) & PIn(C2, D3) & PIn(R1, D3) +In(C1, D1) & In(C2, D3) & In(C3, D3) & In(R1, D3) & NotHolding(R1) \ No newline at end of file diff --git a/planning.py b/planning.py index a168420b9..b46c840f0 100644 --- a/planning.py +++ b/planning.py @@ -11,7 +11,10 @@ from csp import sat_up, NaryCSP, Constraint, ac_search_solver, is_constraint from logic import FolKB, conjuncts, unify_mm, associate, SAT_plan, cdcl_satisfiable from search import Node -from utils import Expr, expr, first +from utils import Expr, expr, first, powerset_product + +from plotter import * +from graphplan_debugger import * class PlanningProblem: """ @@ -136,7 +139,6 @@ def expand_actions(self, name=None): new_effect = Expr(str(effect.op), *new_effect_args) new_effects.append(new_effect) expansions.append(Action(new_expr, new_preconds, new_effects)) - return expansions def is_strips(self): @@ -957,6 +959,9 @@ def find_mutex(self): self.state_mutexes = self.mutex # save state mutexes self.mutex = [] # clear out effects from state mutex prior computation + """ + # Technically correct version of Inconsistent effects, but introduces duplicates + ic1 = [] # Inconsistent effects - one action adds a literal that another deletes pos_nsl, neg_nsl = self.separate(self.next_state_links) @@ -966,13 +971,37 @@ def find_mutex(self): if new_negeff == poseff: for a in self.next_state_links[poseff]: for b in self.next_state_links[negeff]: - if {a, b} not in self.mutex: - self.mutex.append({a, b}) - - # Interference will be calculated with the last step ??? - # Interference - One action deletes a precondition or effect of another + #if {a, b} not in self.mutex: + self.mutex.append({a, b}) + ic1.append({a,b}) + """ + """ + # Version that we have implemented efficiently below + ic2 = [] + for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): + preconds_a1 = self.current_action_links.get(a1, []) + preconds_a2 = self.current_action_links.get(a2, []) + effects_a1 = self.next_action_links.get(a1, []) + effects_a2 = self.next_action_links.get(a2, []) + + # Check for interference + interference = False + # Check if effect of one action is negated by effect of other action (inconsistent effects?) + for e1 in effects_a1: + if e1.predicate_negate() in effects_a2: + interference = True + for e2 in effects_a2: + if e2.predicate_negate() in effects_a1: + interference = True + if interference: + mutex_pair = {a1, a2} + #if mutex_pair not in self.mutex: # <-- avoid duplicates + ic2.append(mutex_pair) + """ + + # Competing needs - preconditions of two actions are mutex at previous proposition layer """ pos_csl, neg_csl = self.separate(self.current_state_links) @@ -991,66 +1020,53 @@ def find_mutex(self): # Competing Needs # self.current_state_links = map from current state vars -> actions applicable # self.current_action_links = map from current actions -> starting states - # Implement here: Iterate over all valid pairs of actions, and if the states they come from are mutex (use self.state_mutexes), add a mutex pair to self.mutex # Competing Needs - two actions are mutex if any of their preconditions are mutex at the previous state level for a1, a2 in itertools.combinations(self.current_action_links.keys(), 2): preconds_a1 = self.current_action_links[a1] # states preconds_a2 = self.current_action_links[a2] - #if len(preconds_a1) > 1 or len(preconds_a2) > 1: - # print("An action has multiple preconditions (state)? Is the following logic implemented correctly? I think so") - - # check all pairs of preconditions - for p in preconds_a1: - for q in preconds_a2: - if {p, q} in self.state_mutexes: - mutex_pair = {a1, a2} - if mutex_pair not in self.mutex: - self.mutex.append(mutex_pair) - # no need to keep checking once we've marked them - break - else: - continue - break + if any({p, q} in self.state_mutexes for p in preconds_a1 for q in preconds_a2): + mutex_pair = {a1, a2} + if mutex_pair not in self.mutex: + self.mutex.append(mutex_pair) - # Interference + # Interference AND Inconsistent Effects # Example - in shopping, ensure Move(Home,HW) and Move(Home,SM) are both mutex in L0 - # current_action_links = current action -> current state map - - savemutextemp = copy.copy(self.mutex) - for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): preconds_a1 = self.current_action_links.get(a1, []) preconds_a2 = self.current_action_links.get(a2, []) effects_a1 = self.next_action_links.get(a1, []) effects_a2 = self.next_action_links.get(a2, []) + #print(a1,a2) + #if "PickUp" in a1.op and "PickUp" in a2.op: + # breakpoint() + # Check for interference interference = False # Check if a precondition of one action is negated by effect of another for p1 in preconds_a1: - if Expr("Not" + p1.op, *p1.args) in effects_a2: + if p1.predicate_negate() in effects_a2: interference = True for p2 in preconds_a2: - if Expr("Not" + p2.op, *p2.args) in effects_a1: + if p2.predicate_negate() in effects_a1: interference = True - # Check if effect of one action is negated by effect of other action (inconsistent effects?) - """ + # Check if effect of one action is negated by effect of other action (inconsistent effects) for e1 in effects_a1: - if Expr("Not" + e1.op, *e1.args) in effects_a2: - interference = True + if e1.predicate_negate() in effects_a2: + interference = True # Technically inconsistent effects for e2 in effects_a2: - if Expr("Not" + e2.op, *e2.args) in effects_a1: - interference = True - """ + if e2.predicate_negate() in effects_a1: + interference = True # Technically inconsistent effects if interference: mutex_pair = {a1, a2} if mutex_pair not in self.mutex: # <-- avoid duplicates self.mutex.append(mutex_pair) + #print([x for x in self.mutex if x not in savemutextemp]) #breakpoint() @@ -1088,14 +1104,15 @@ def populate_prop_mutexes(self): continue # if any two actions that lead to these states is not mutex, do not add a mutex to these states. - if not any([{a1,a2} not in self.mutex and {a2,a1} not in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): + #if not any([{a1,a2} not in self.mutex and {a2,a1} not in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): + if all([{a1,a2} in self.mutex or {a2,a1} in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): mutex_pair = {s1, s2} if mutex_pair not in state_mutex: state_mutex.append(mutex_pair) # If there are pairs of propositions that are negations of each other, they need to be mutex for s1i in range(len(self.current_state)): - for s2i in range(1,len(self.current_state)): + for s2i in range(s1i,len(self.current_state)): s1, s2 = self.current_state[s1i], self.current_state[s2i] if repr(s2)[0:3] == "Not" and repr(s1) == repr(s2)[3:] or repr(s1)[0:3] == "Not" and repr(s1)[3:] == repr(s2): mutex_pair = {s1, s2} @@ -1111,10 +1128,6 @@ def prune_invalid_actions(self): """Remove actions whose own preconditions are mutex (unsupportable).""" to_remove = [] - # Debug - # breakpoint() - # print("STATE_MUTEXES:", self.state_mutexes) - # Normalize state mutex set for fast membership checks: # state_mutex_lookup contains frozenset pairs like frozenset({p,q}) state_mutex_lookup = set() @@ -1124,7 +1137,6 @@ def prune_invalid_actions(self): for action, preconds in list(self.current_action_links.items()): invalid = False - # show debug info if you want: # print(action, preconds, list(itertools.combinations(preconds, 2))) for p1, p2 in itertools.combinations(preconds, 2): @@ -1135,10 +1147,6 @@ def prune_invalid_actions(self): if invalid: to_remove.append(action) - # Debug - #print("REMOVING: ", to_remove) - #breakpoint() - # Remove invalid actions from all mappings for action in to_remove: # forward mappings @@ -1280,7 +1288,6 @@ def expand_graph(self): new_level.mutex = last_level.populate_prop_mutexes() # Populate the mutexes for the next state level to come self.levels.append(new_level) - #breakpoint() def non_mutex_goals(self, goals, index): "Checks whether the goals are mutually exclusive" @@ -1362,8 +1369,6 @@ def __init__(self, planning_problem): global isFirstLayer isFirstLayer = True - self.calledextr = False - def __str__(self): sol_str = ( "No solution found" @@ -1387,18 +1392,122 @@ def check_leveloff(self): if check: return True - def extract_solution(self, goals, index): - "Extracts the solution" + + + + + def _get_preconditions_for(self, action_set, level): + #Collects all unique preconditions for a given set of actions in a level. + all_preconditions = set() + for action in action_set: + # Assumes level.current_action_links maps an action to its preconditions + preconditions = level.current_action_links.get(action, []) + all_preconditions.update(preconditions) + return all_preconditions + + + def _find_valid_action_sets(self, goals, level): + #Finds sets of actions in the given level that are not mutually exclusive + #and that collectively satisfy all the goals. + #This correctly replaces the flawed `itertools.product` logic. + valid_sets = [] + + # 1. Map each goal to the list of actions that can achieve it. + actions_for_goal = {g: level.next_state_links.get(g, []) for g in goals} + + # 2. Generate combinations of actions that could potentially satisfy the goals. + # This creates a list of lists, where each inner list contains potential achievers for one goal. + potential_action_groups = [actions_for_goal[g] for g in goals] + # The cartesian product gives us tuples, where each tuple contains one action + # choice for each goal. + for action_combination in itertools.product(*potential_action_groups): + # We only need the unique actions in the combination. + action_set = set(action_combination) + + # 3. Check for mutexes within this set of actions. + is_mutex = False + for a1, a2 in itertools.combinations(action_set, 2): + if {a1, a2} in level.mutex: + is_mutex = True + break + + # 4. If the set is non-mutex and we haven't already added it, it's a valid option. + if not is_mutex and action_set not in valid_sets: + valid_sets.append(action_set) + + return valid_sets + + # Place this within your GraphPlan class + def extract_solution(self, goals, level_index, root=False): + #Primary method to start the solution extraction process. + #It calls the recursive helper and returns the final plan. + # Start the recursive search from the level where goals must be true + final_plan = self._extract_solution_recursive(set(goals), len(self.graph.levels)-1) + return final_plan + + # Place this within your GraphPlan class, replacing the previous version + def _extract_solution_recursive(self, goals, level_index): + #Recursively searches for a plan backwards from a given level using negative indexing. + + #Args: + # goals (set): The set of goal propositions to satisfy. + # level_index (int): level index + #print(level_index) #breakpoint() - isfirst = False - if self.calledextr != True: - self.calledextr = True - isfirst = True + # BASE CASE: We've recursed back to the initial proposition layer (Level 0). + # The 'goals' at this point are the preconditions for the very first set of actions. + # We must check if they exist in the initial state. No further recursion is needed. + if level_index == 0: + #breakpoint() + initial_state = set(self.graph.levels[0].current_state) + if goals.issubset(initial_state): + return [] # Success! Return the empty plan to be built upon. + else: + return None # Failure. This path is invalid as preconditions are not met. + + # MEMOIZATION: Check if we've already proven this subproblem is unsolvable. + # TODO: ADD SUPERSET CHECK + if (level_index, frozenset(goals)) in self.no_goods: + return None + + # RECURSIVE STEP: + # To satisfy goals at `level_index`, we need to find a suitable set of non-mutex actions + # from the *previous* level's action layer. + action_level = self.graph.levels[level_index - 1] + valid_action_sets = self._find_valid_action_sets(goals, action_level) + + # Iterate through each valid action set and try to find a path. + for action_set in valid_action_sets: + # The new sub-goals are the combined preconditions for this action set. + new_goals = self._get_preconditions_for(action_set, action_level) + + # Recurse to solve for the new goals at the previous proposition layer. + sub_plan = self._extract_solution_recursive(new_goals, level_index - 1) + + # If the recursive call succeeded, we have a solution! + if sub_plan is not None: + # Append the current level's actions and return the full plan. + return sub_plan + [list(action_set)] + + # If the loop finishes without a solution, this subproblem is a "no-good". + nogood_item = (level_index, frozenset(goals)) + if nogood_item not in self.no_goods: + self.no_goods.append(nogood_item) + return None + + + """ + def extract_solution(self, goals, index, root=False): + "Extracts the solution" + + #print(f"ENTER extract_solution with goals: {goals}") + level = self.graph.levels[index] if not self.graph.non_mutex_goals(goals, index): self.no_goods.append((level, goals)) + #print(" Level failed, goals are all mutex") return level = self.graph.levels[index - 1] @@ -1414,32 +1523,46 @@ def extract_solution(self, goals, index): actions.append(level.next_state_links[goal]) # `all_actions` selects elements from each list and creates a new list of actions that satisfies all goals at next level - all_actions = list(itertools.product(*actions)) # Why only product? Why not all subsets of non-mutex preconditions? - - #breakpoint() + #all_actions = list(itertools.product(*actions)) # Why only product? Why not all subsets of non-mutex preconditions? + #all_actions = powerset_product(actions) + print(len(list(itertools.product(*actions)))) + all_actions = [*list(itertools.product(*actions)), *(powerset_product(actions)[0:5])] + print(len(all_actions)) # Filter out non-mutex actions non_mutex_actions = [] for action_tuple in all_actions: + + #actlst = ["Move(R1, D2, D3)", "PIn(C2, D3)", "PHolding(R1)", "PIn(C3, R1)"] + #actlevellst = [str(repr(x)) for x in action_tuple] + #print(action_tuple) + #if all([x in actlevellst for x in actlst]): + #print("hi") + #breakpoint() + #print("hi") + # Get all pairs of actions in our satisfactory action_tuple action_pairs = itertools.combinations(list(set(action_tuple)), 2) non_mutex_actions.append(list(set(action_tuple))) + #if not any(["PickUp" in str(x.op) for x in action_tuple]): + #breakpoint() # acts = list(set(action_tuple)) # print(f"CHECKING tuple {acts} at level {index-1}") for pair in list(action_pairs): if set(pair) in level.mutex: + #print(action_tuple, " failed due to ", pair, " in mutex") non_mutex_actions.pop(-1) break # If any actions are mutex, remove the entire tuple from our list - - # print(f"NON-MUTEX ACTION SETS at level {index}: {non_mutex_actions}") - # print(len(non_mutex_actions), non_mutex_actions) - # breakpoint() + + if len(non_mutex_actions) == 0: + #print(" Level failed: No actions create state and are non-mutex") + return # At this point, the non_mutex_actions contains a list of lists of valid actions that are all non-mutex and satisfy our goal state - #breakpoint() - # Recursion + + #print(f"Depth of solutions: {len(self.graph.levels)}, current level = {index-1}") for action_list in non_mutex_actions: if [action_list, index] not in self.solution: self.solution.append([action_list, index]) @@ -1454,41 +1577,25 @@ def extract_solution(self, goals, index): elif (level, new_goals) in self.no_goods: return else: - # print(f" Recursing with new goal: {new_goals}") - self.extract_solution(new_goals, index - 1) # DFS search + #print(f" Goals achieved: {goals}, actions used: {action_list}") + #breakpoint() + self.extract_solution(new_goals, index - 1) # DFS search; goals at this layer, index of this layer - print("self.solution = ", self.solution) - print("self.nogoods = ", self.no_goods) - #if isfirst: - # breakpoint() - - """ - # Level-Order multiple solutions - solution = [] - for item in self.solution: # self.solution will contain sets of actions at a level. - if item[1] == -1: # We are at the bottom of the tree in recursion, and we create a new unique solution for this leaf node - solution.append([]) - solution[-1].append(item[0]) - else: # We are at an intermediate node, we add it to our last solution (but not other possible nodes?) - solution[-1].append(item[0]) - + # Exit prior to computing solutions if we are not at the root. + if not root: + return + + #print(self.solution) #breakpoint() - for num, item in enumerate(solution): - item.reverse() - solution[num] = item - - return solution - """ - if not self.solution: return [] # 1. Determine the leaf level and the expected length of a valid plan. leaf_level = min(item[1] for item in self.solution) expected_plan_length = abs(leaf_level) - print(f"DEBUG: Target leaf level: {leaf_level}, Expected plan length: {expected_plan_length}\n") + #print(f"DEBUG: Target leaf level: {leaf_level}, Expected plan length: {expected_plan_length}\n") completed_plans = [] @@ -1499,25 +1606,25 @@ def extract_solution(self, goals, index): # 2. Iterate through the ordered search log. for i, item in enumerate(self.solution): actions, level = item - print(f"--- Iteration {i+1} ---") - print(f"Processing Item: {item}") - print(f"Path BEFORE changes: {current_path}") + #print(f"--- Iteration {i+1} ---") + #print(f"Processing Item: {item}") + #print(f"Path BEFORE changes: {current_path}") # 3. Rewind the current path to handle backtracks. rewound = False while current_path and level != current_path[-1][1] - 1: if not rewound: - print(f"-> Backtrack detected (Lvl {level} doesn't follow Lvl {current_path[-1][1]}). Rewinding path...") + #print(f"-> Backtrack detected (Lvl {level} doesn't follow Lvl {current_path[-1][1]}). Rewinding path...") rewound = True popped_item = current_path.pop() - print(f" ...Popped: {popped_item}") + #print(f" ...Popped: {popped_item}") - if rewound: - print(f"Path AFTER rewind: {current_path}") + #if rewound: + # print(f"Path AFTER rewind: {current_path}") # 4. Append the current item to form the new active path. current_path.append(item) - print(f"Appending item. New Path is now: {current_path}\n") + #print(f"Appending item. New Path is now: {current_path}\n") # 5. Check if the active path has a valid structure. is_rooted = current_path[0][1] == -1 @@ -1526,7 +1633,7 @@ def extract_solution(self, goals, index): # Only proceed if the path is structurally sound. if is_rooted and is_grounded and is_contiguous: - print(f"-> Path is structurally valid. Performing final initial state check...") + #print(f"-> Path is structurally valid. Performing final initial state check...") # 6. Final Check: Verify first actions' preconditions against the initial state. initial_state_satisfied = True @@ -1538,14 +1645,14 @@ def extract_solution(self, goals, index): initial_state_satisfied = False preconditions = [] preconditions = set(preconditions) - print("Testing preconditions: ", preconditions, ", and initial_state: ", initial_state) + #print("Testing preconditions: ", preconditions, ", and initial_state: ", initial_state) if not preconditions.issubset(initial_state): initial_state_satisfied = False - print(f" ❗️ Path failed validation. Action '{action}' preconditions {preconditions} are not met by initial state.") + #print(f" ❗️ Path failed validation. Action '{action}' preconditions {preconditions} are not met by initial state.") break if initial_state_satisfied: - print(f" ✅ Success! Plan fully verified and found: {current_path}\n") + #print(f" ✅ Success! Plan fully verified and found: {current_path}\n") completed_plans.append(list(current_path)) print(f"--- Loop Finished ---") @@ -1559,67 +1666,8 @@ def extract_solution(self, goals, index): solution.append(action_plan) return solution - """ - def extract_solution(self, goals, index): - "Extracts the solution" - level = self.graph.levels[index] - if not self.graph.non_mutex_goals(goals, index): - self.no_goods.append((level, goals)) - return - - level = self.graph.levels[index - 1] - - # Create all combinations of actions that satisfy the goal - actions = [] - for goal in goals: - actions.append(level.next_state_links[goal]) - - all_actions = list(itertools.product(*actions)) - - # Filter out non-mutex actions - non_mutex_actions = [] - for action_tuple in all_actions: - action_pairs = itertools.combinations(list(set(action_tuple)), 2) - non_mutex_actions.append(list(set(action_tuple))) - for pair in action_pairs: - if set(pair) in level.mutex: - non_mutex_actions.pop(-1) - break - - # Recursion - for action_list in non_mutex_actions: - if [action_list, index] not in self.solution: - self.solution.append([action_list, index]) - - new_goals = [] - for act in set(action_list): - if act in level.current_action_links: - new_goals = new_goals + level.current_action_links[act] - - if abs(index) + 1 == len(self.graph.levels): - return - elif (level, new_goals) in self.no_goods: - return - else: - self.extract_solution(new_goals, index - 1) - - # Level-Order multiple solutions - solution = [] - for item in self.solution: - if item[1] == -1: - solution.append([]) - solution[-1].append(item[0]) - else: - solution[-1].append(item[0]) - - for num, item in enumerate(solution): - item.reverse() - solution[num] = item - - return solution - """ def goal_test(self, kb): goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) @@ -1639,6 +1687,8 @@ def execute(self): self.graph.planning_problem.goals, -1)): print("SOLVED, EXTRACTING SOLUTION") + #print(self.graph) + #breakpoint() # print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) # self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) # print(self.graph) @@ -1647,18 +1697,17 @@ def execute(self): # print("Next state links:", self.graph.levels[-1].next_state_links) # print("Current action links:", self.graph.levels[-1].current_action_links) # print(f"Extract Solution from {len(self.graph.levels)} levels, {len(self.graph.levels) - 1} actions") - solution = self.extract_solution(self.graph.planning_problem.goals, -1) - self.calledextr = False + #breakpoint() + solution = self.extract_solution(self.graph.planning_problem.goals, -1, True) if solution: print(f"SOLUTION::::!!!!!!!!!!!!!!!!\n{solution}") - return solution + return [solution] # print(len(self.graph.levels)) if len(self.graph.levels) >= 2 and self.check_leveloff(): # breakpoint() return None -# Carwyns mods class Linearize: def __init__(self, planning_problem): @@ -1726,266 +1775,6 @@ def execute(self): return ordered_solution - -# BILLS CLASS - -""" -class Linearize: - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - - def filter(self, solution): - "Filter out persistence actions from a solution" - - new_solution = [] - for section in solution[0]: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution - - def orderlevel(self, level, planning_problem): - "Return valid linear order of actions for a given level" - - for permutation in itertools.permutations(level): - print(f"TRYING PARTIAL PLAN: {permutation}") ## Bill's hack - temp = copy.deepcopy(planning_problem) - count = 0 - ## print(f"PERMUTATION: {permutation}") ## Bill's hack - for action in permutation: - try: - # print(f"TRY ACTION: {action}") ## Bill's hack - temp.act(action) - count += 1 - # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack - except: - # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack - count = 0 - temp = copy.deepcopy(planning_problem) - continue ##break - if count == len(permutation): - print(f"\nSUCCESSFUL PARTIAL PLAN ORDERING: {permutation}") ## Bill's hack - return list(permutation), temp - print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack - return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem - - def execute(self): - "Finds total-order solution for a planning graph" - - graphPlan_solution = GraphPlan(self.planning_problem).execute() - breakpoint() - - ## Bill's stuff from playing around - ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack - ## pnl(graphPlan_solution) - ## for possible_plan in graphPlan_solution: - ## possible_plan = [possible_plan] - ## filtered_possible_plan = self.filter(possible_plan) - ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack - ## flattened_graphplan = self.filter(graphPlan_solution) - ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack - ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack - ## flattened_graphplan = [flattened_graphplan] - ## graphPlan_solution = [flattened_graphplan] ## Bill's hack - ## pnl(flattened_graphplan) - - ## I think I have to go over all permutations of possbile partial graphplans - - for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack - - ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list - ## filtered_solution = self.filter(graphPlan_solution) # original - - filtered_solution = self.filter(possible_plan) # my mod - - print(f"TRYING FILTERED PLAN: {filtered_solution}") ## Bill's hack - - ## filtered_solution = self.filter(possible_plan) # mod - ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack - ## pnl(filtered_solution) - ## filtered_solution = possible_plan - - ordered_solution = [] - planning_problem = self.planning_problem - for level in filtered_solution: - - ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack - - ## the below is a key line, the key line - level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied - if not level_solution: # This checks if level_solution is None or an empty list - print(f"PLAN FAIL: {filtered_solution}") ## Bill's hack - continue ## Bill's hack!! if empty, continue looking. - - print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack - ##print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack - ## for action in level_solution: - ## print(f"APPLY ACTION: {action}") ## Bill's hack - ## planning_problem.act(action) # complete guess, apply action to the problem and keep going - - ## I think we need to apply the plan to the planning problem and modify it - for element in level_solution: - ordered_solution.append(element) - - if not ordered_solution: - continue ## no plan possible from the partial plan at the level - else: - print(f"WORKING SOL'N: {ordered_solution}") ## Bill's hack - break - - return ordered_solution -""" - -""" -# GPT Modified - -class Linearize: - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - - def __str__(self): - return f"" - - def filter(self, solution): - "Filter out persistence actions from a solution" - - new_solution = [] - for section in solution[0]: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution - - def orderlevel(self, level, planning_problem): - "Return valid linear order of actions for a given level" - - # Iterate through all permutations of actions in the level - for permutation in itertools.permutations(level): - # Create a deep copy of the planning problem for this permutation - temp = copy.deepcopy(planning_problem) - is_valid_permutation = True - - # Attempt to apply each action in the current permutation - for action in permutation: - try: - temp.act(action) - except Exception: - # If an action fails, this entire permutation is invalid. - is_valid_permutation = False - break # Exit the inner loop immediately and try the next permutation. - - # If the inner loop completed without any failures - if is_valid_permutation: - # This is a valid linear ordering for the current level - return list(permutation), temp - - # If no valid permutation was found after checking all possibilities - return None, None - - def execute(self): - "Finds a total-order solution for a planning graph." - # This might return multiple solutions, let's call it a list of "raw plans" - raw_plans = GraphPlan(self.planning_problem).execute() - - if not raw_plans: - return None # No plans were found by GraphPlan - - # Iterate through each raw plan returned by GraphPlan - for raw_plan in raw_plans: - # The filter and ordering logic should be applied to each plan one by one. - # This is a good place for a helper function. - ordered_plan = self._attempt_linearization(raw_plan) - if ordered_plan: - return ordered_plan # Return the first successful plan - - return None # No valid linearization was found for any of the plans - - def _attempt_linearization(self, raw_plan): - "Helper function to linearize a single raw plan." - # Filter out persistence actions - filtered_plan = self._filter(raw_plan) - ordered_solution = [] - planning_problem = copy.deepcopy(self.planning_problem) - - # Order actions level by level - for level in filtered_plan: - level_solution, planning_problem = self.orderlevel(level, planning_problem) - if level_solution is None: - return None # Failed to order this plan, try the next one - ordered_solution.extend(level_solution) - return ordered_solution - - def _filter(self, raw_plan): - "Filter out persistence actions from a single raw plan." - new_solution = [] - for section in raw_plan: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution -""" - -""" -# ORIGINAL - -class Linearize: - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - - def filter(self, solution): - "Filter out persistence actions from a solution" - - new_solution = [] - for section in solution[0]: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution - - def orderlevel(self, level, planning_problem): - "Return valid linear order of actions for a given level" - - for permutation in itertools.permutations(level): - temp = copy.deepcopy(planning_problem) - count = 0 - for action in permutation: - try: - temp.act(action) - count += 1 - except: - count = 0 - temp = copy.deepcopy(planning_problem) - break - if count == len(permutation): - return list(permutation), temp - return None - - def execute(self): - "Finds total-order solution for a planning graph" - - graphPlan_solution = GraphPlan(self.planning_problem).execute() - filtered_solution = self.filter(graphPlan_solution) - ordered_solution = [] - planning_problem = self.planning_problem - for level in filtered_solution: - level_solution, planning_problem = self.orderlevel(level, planning_problem) - for element in level_solution: - ordered_solution.append(element) - - return ordered_solution -""" - def linearize(solution): """Converts a level-ordered solution into a linear solution""" diff --git a/plotter.py b/plotter.py new file mode 100644 index 000000000..e058d58ff --- /dev/null +++ b/plotter.py @@ -0,0 +1,60 @@ +import matplotlib.pyplot as plt +import networkx as nx + +class GraphVisualizer: + @staticmethod + def plot_graph(graph_obj): + """ + Plot a GraphPlan graph with levels alternating between state and action nodes. + Left-to-right layout, edges show applicability (state → action). + """ + G = nx.DiGraph() + + # Assign positions explicitly for left-to-right layout + pos = {} + x_offset = 0 + y_spacing = 1.5 # vertical spacing + + for i, level in enumerate(graph_obj.levels): + # Place states at even i, actions at odd i + y_offset = 0 + if i % 2 == 0: # state layer + for j, state in enumerate(level.current_state): + node_id = f"S{i}_{j}" + G.add_node(node_id, label=str(state), type="state") + pos[node_id] = (x_offset, -j * y_spacing) + + # connect to actions in this level + for action, preconds in level.current_action_links.items(): + act_id = f"A{i}_{str(action)}" + if act_id not in G: + G.add_node(act_id, label=str(action), type="action") + pos[act_id] = (x_offset + 1.5, -len(G.nodes) * 0.1) + + # draw edges from preconditions to this action + for pre in preconds: + for sid, attrs in G.nodes(data=True): + if attrs.get("label") == str(pre): + G.add_edge(sid, act_id) + + x_offset += 3 # shift to the right for next level + + # Draw + node_colors = [ + "skyblue" if data["type"] == "state" else "lightgreen" + for _, data in G.nodes(data=True) + ] + nx.draw( + G, + pos, + with_labels=True, + labels=nx.get_node_attributes(G, "label"), + node_size=2000, + node_color=node_colors, + font_size=8, + arrows=True, + arrowsize=10, + ) + + plt.title("GraphPlan Levels") + plt.show() \ No newline at end of file diff --git a/submission1.py b/submission1.py index 4906499b9..35d95410a 100644 --- a/submission1.py +++ b/submission1.py @@ -98,7 +98,11 @@ def logisticsPlan(): #P = double_tennis_problem() #P = have_cake_and_eat_cake_too() init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - goal_state = "In(C1,D1)" + #goal_state = "In(C1,D1)" + goal_state = "In(C2, D3) & In(C3, D3)" + #goal_state = "In(C1, D3) & In(C2, D3) & In(C3, D3)" + # putdown(c1), pickup(c2), move(d3), putdown(c2), move(d2), pickup(c3), move(d3), putdown(c3) + #goal_state = "In(C3, D1)" #goal_state = "In(C2, D3)" #goal_state = "In(C3, D3)" @@ -126,8 +130,8 @@ def logisticsPlan(): """ #P = double_tennis_problem_simple2() #GraphPlan(P).execute() - #print(Linearize(P).execute()) - verify_solution(P) + print(Linearize(P).execute()) + #verify_solution(P) """ diff --git a/submission1_test.py b/submission1_test.py index 2e359d71a..e30255474 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -15,6 +15,23 @@ def test_blocksworld_manual(): assert sbw.goal_test() == True +def test_logistics_manual(): + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + goal_state = "In(C2, D3) & In(C3, D3)" + P = logisticsPlanCustom(init, goal_state) + assert P.goal_test() == False + P.act(expr('PutDown(R1, C1, D1)')) + P.act(expr('PickUp(R1, C2, D1)')) + P.act(expr('Move(R1, D1, D3)')) + P.act(expr('PutDown(R1, C2, D3)')) + P.act(expr('Move(R1, D3, D2)')) + P.act(expr('PickUp(R1, C3, D2)')) + P.act(expr('Move(R1, D2, D3)')) + assert P.goal_test() == False + P.act(expr('PutDown(R1, C3, D3)')) + assert P.goal_test() == True + + def verify_solution(P): sol = Linearize(P).execute() print(sol) @@ -61,13 +78,13 @@ def test_socks_and_shoes(): "In(C1, D1) & In(C2, D3)", "In(C3, D1)", "In(C2, D3)", - #"In(C2, D3) & In(C3, D3)", \ - #"In(C3, D3) & In(C2, D3)", \ + "In(C2, D3) & In(C3, D3)", \ + "In(C3, D3) & In(C2, D3)", \ "In(C1, D2) & In(C3, D3)", - #"In(C1, D3) & In(C2, D3) & In(C3, D3)", \ + "In(C1, D3) & In(C2, D3) & In(C3, D3)", \ "In(C1, D2) & In(C3, D3) & In(C2, D1)", "In(C3, D3)", - #"In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)" \ + "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)" \ ]) def test_logistics_plan_valid(goal_state): """These should yield a valid (non-crashing) plan, even if empty.""" diff --git a/utils.py b/utils.py index 3158e3793..4a891ecac 100644 --- a/utils.py +++ b/utils.py @@ -9,6 +9,7 @@ import os.path import random from itertools import chain, combinations +import itertools from statistics import mean import numpy as np @@ -618,6 +619,17 @@ def __repr__(self): else: # (x - y) opp = (' ' + op + ' ') return '(' + opp.join(args) + ')' + + def predicate_negate(self): + """ + Return the logical negation of an Expr. + Assumes we are using "Not" as our negation operator. Avoids double "Not" as prefix + """ + if self.op.startswith("Not"): + # strip the Not prefix + return Expr(self.op[3:], *self.args) + else: + return Expr("Not" + self.op, *self.args) # An 'Expression' is either an Expr or a Number. @@ -788,3 +800,35 @@ class Bool(int): T = Bool(True) F = Bool(False) + + + + +def powerset_product(list_of_lists): + """ + Computes the Cartesian product of the power sets of the inner lists. + + Args: + list_of_lists: A list of lists, e.g., [[1, 2], ['a', 'b']]. + + Returns: + A list of lists, where each inner list is a combination of subsets. + """ + + # Helper function to generate the power set for a single iterable + def powerset(iterable): + s = list(iterable) + # chain.from_iterable() flattens the list of tuples from combinations + # combinations(s, r) gives all subsets of length r + return list(chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))) + + # 1. Generate the power set for each inner list + all_power_sets = [powerset(sublist) for sublist in list_of_lists] + + # 2. Compute the Cartesian product of the power sets + cartesian_prod = itertools.product(*all_power_sets) + + # 3. Combine the tuples of tuples into a single list for each result + result = [list(chain.from_iterable(item)) for item in cartesian_prod] + + return result From ea6ca75e7bece6b6d2c2b9e45f2bc1defb941601 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 4 Oct 2025 16:15:34 -0400 Subject: [PATCH 13/19] Cleanup --- GRAPH-LOGISTICS.py | 57 - PR_UPDATES_GRAPHPLAN.MD | 57 + cake_example_graph.png | Bin 100204 -> 0 bytes cake_problem_graph2.png | Bin 100010 -> 0 bytes cake_problem_graph3.png | Bin 104394 -> 0 bytes debugging_air_cargo | 60 - ...l_failure_causes_tennis_simple2_to_fail.md | 22 - planning.py | 832 +------ planning1.py | 2077 ----------------- planning_envs.py | 348 +++ submission1.py | 1 + submission1_test.py | 4 + understanding_mutexes.md | 195 -- 13 files changed, 435 insertions(+), 3218 deletions(-) delete mode 100644 GRAPH-LOGISTICS.py create mode 100644 PR_UPDATES_GRAPHPLAN.MD delete mode 100644 cake_example_graph.png delete mode 100644 cake_problem_graph2.png delete mode 100644 cake_problem_graph3.png delete mode 100644 debugging_air_cargo delete mode 100644 pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md delete mode 100644 planning1.py create mode 100644 planning_envs.py delete mode 100644 understanding_mutexes.md diff --git a/GRAPH-LOGISTICS.py b/GRAPH-LOGISTICS.py deleted file mode 100644 index e2c9c533a..000000000 --- a/GRAPH-LOGISTICS.py +++ /dev/null @@ -1,57 +0,0 @@ - - Objects: {D1, R1, D3, C2, C3, C1, D2} -Level 0: - - Current State: {In(C1, R1), In(C2, D1), In(C3, D2), In(R1, D1), Holding(R1), Container(C1), Container(C2), Container(C3), Place(D1), Place(D2), Place(D3), Robot(R1)} - Actions: {PIn(C1, R1), PIn(C2, D1), PIn(C3, D2), PIn(R1, D1), PHolding(R1), PContainer(C1), PContainer(C2), PContainer(C3), PPlace(D1), PPlace(D2), PPlace(D3), PRobot(R1), PutDown(R1, C1, D1), Move(R1, D1, D3), Move(R1, D1, D2)} - Mutex: {{PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {Move(R1, D1, D2), Move(R1, D1, D3)}} - Next state mutexes: {[{NotHolding(R1), In(C1, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(C1, D1), In(C1, R1)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), In(R1, D3)}, {In(R1, D1), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {NotIn(C1, R1), Holding(R1)}, {In(C1, D1), Holding(R1)}, {NotIn(R1, D1), NotHolding(R1)}, {NotHolding(R1), In(R1, D3)}, {NotHolding(R1), In(R1, D2)}, {NotIn(C1, R1), NotIn(R1, D1)}, {NotIn(C1, R1), In(R1, D3)}, {NotIn(C1, R1), In(R1, D2)}, {NotIn(R1, D1), In(C1, D1)}, {In(C1, D1), In(R1, D3)}, {In(C1, D1), In(R1, D2)}, {In(R1, D3), In(R1, D2)}]} - -Level 1: - - Current State: {Container(C3), Place(D1), Place(D3), In(C1, D1), In(R1, D2), NotIn(R1, D1), Holding(R1), In(C3, D2), In(C1, R1), Robot(R1), NotIn(C1, R1), NotHolding(R1), In(R1, D1), In(R1, D3), Place(D2), In(C2, D1), Container(C1), Container(C2)} - Actions: {PContainer(C3), PPlace(D1), PPlace(D3), PIn(C1, D1), PIn(R1, D2), PNotIn(R1, D1), PHolding(R1), PIn(C3, D2), PIn(C1, R1), PRobot(R1), PNotIn(C1, R1), PNotHolding(R1), PIn(R1, D1), PIn(R1, D3), PPlace(D2), PIn(C2, D1), PContainer(C1), PContainer(C2), PickUp(R1, C2, D1), PickUp(R1, C1, D1), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PIn(C1, D1), PIn(R1, D2)}, {PIn(C1, D1), PNotIn(R1, D1)}, {PIn(C1, D1), PHolding(R1)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PIn(R1, D3)}, {PIn(C1, D1), PickUp(R1, C3, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PIn(C1, D1), Move(R1, D3, D1)}, {PIn(C1, D1), Move(R1, D3, D2)}, {PIn(C1, D1), Move(R1, D2, D1)}, {PIn(C1, D1), Move(R1, D2, D3)}, {PNotIn(C1, R1), PIn(R1, D2)}, {PIn(R1, D2), PNotHolding(R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C3, D2), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PNotIn(R1, D1), PNotIn(C1, R1)}, {PNotIn(R1, D1), PNotHolding(R1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D2)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PHolding(R1), PNotIn(C1, R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PIn(C1, R1), PNotHolding(R1)}, {PickUp(R1, C2, D1), PIn(C1, R1)}, {PickUp(R1, C3, D2), PIn(C1, R1)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PNotIn(C1, R1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PNotIn(C1, R1), Move(R1, D3, D1)}, {PNotIn(C1, R1), Move(R1, D3, D2)}, {PNotIn(C1, R1), Move(R1, D2, D1)}, {PNotIn(C1, R1), Move(R1, D2, D3)}, {PNotHolding(R1), PIn(R1, D3)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {Move(R1, D3, D1), PNotHolding(R1)}, {PNotHolding(R1), Move(R1, D3, D2)}, {Move(R1, D2, D1), PNotHolding(R1)}, {PNotHolding(R1), Move(R1, D2, D3)}, {PIn(R1, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{In(C1, D1), In(C1, R1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, D2)}, {In(C1, D1), NotIn(R1, D3)}, {NotIn(R1, D2), In(C1, D1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D3), In(R1, D2)}, {NotIn(C2, D1), In(R1, D2)}, {In(C2, R1), In(R1, D2)}, {NotIn(C1, D1), In(R1, D2)}, {In(C1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(R1, D1), NotIn(C2, D1)}, {NotIn(R1, D1), In(C2, R1)}, {NotIn(R1, D1), NotIn(C1, D1)}, {NotHolding(R1), Holding(R1)}, {In(C1, D3), Holding(R1)}, {Holding(R1), In(C1, D2)}, {NotIn(C1, R1), In(C1, R1)}, {NotHolding(R1), In(C1, R1)}, {In(C1, D3), In(C1, R1)}, {In(C1, D2), In(C1, R1)}, {NotIn(C1, R1), NotIn(C1, D1)}, {NotIn(C1, R1), NotIn(R1, D3)}, {NotIn(C1, R1), NotIn(R1, D2)}, {NotHolding(R1), NotIn(C2, D1)}, {NotHolding(R1), In(C2, R1)}, {NotHolding(R1), NotIn(C1, D1)}, {NotHolding(R1), NotIn(R1, D3)}, {NotIn(R1, D2), NotHolding(R1)}, {In(R1, D1), In(R1, D3)}, {In(C1, D3), In(R1, D1)}, {In(R1, D1), In(C1, D2)}, {NotIn(C2, D1), In(R1, D3)}, {In(R1, D3), In(C2, R1)}, {NotIn(C1, D1), In(R1, D3)}, {In(C1, D2), In(R1, D3)}, {NotIn(R1, D3), In(R1, D3)}, {In(C2, D1), NotIn(C2, D1)}, {In(C2, D1), In(C2, R1)}, {In(C1, D3), NotIn(C2, D1)}, {In(C1, D2), NotIn(C2, D1)}, {NotIn(R1, D3), NotIn(C2, D1)}, {NotIn(R1, D2), NotIn(C2, D1)}, {In(C1, D3), In(C2, R1)}, {In(C1, D2), In(C2, R1)}, {NotIn(R1, D3), In(C2, R1)}, {NotIn(R1, D2), In(C2, R1)}, {In(C1, D3), NotIn(C1, D1)}, {In(C1, D2), NotIn(C1, D1)}, {NotIn(R1, D3), NotIn(C1, D1)}, {NotIn(R1, D2), NotIn(C1, D1)}, {In(C1, D3), In(C1, D2)}, {NotIn(R1, D3), In(C1, D3)}, {NotIn(R1, D2), In(C1, D3)}, {NotIn(R1, D3), In(C1, D2)}, {NotIn(R1, D2), In(C1, D2)}, {NotIn(R1, D2), NotIn(R1, D3)}]} - -Level 2: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), Container(C3), Container(C1), In(C1, D2), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(R1, D2), Place(D1), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), In(C2, D1)} - Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(R1, D2), PPlace(D1), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PNotIn(C2, D1), PIn(C1, D2)}, {PIn(R1, D2), PNotIn(C2, D1)}, {PNotHolding(R1), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C2, D1)}, {PNotIn(R1, D2), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PickUp(R1, C3, D2), PNotIn(C2, D1)}, {PickUp(R1, C1, D1), PNotIn(C2, D1)}, {PickUp(R1, C1, D3), PNotIn(C2, D1)}, {PickUp(R1, C1, D2), PNotIn(C2, D1)}, {PutDown(R1, C2, D3), PNotIn(C2, D1)}, {PutDown(R1, C2, D2), PNotIn(C2, D1)}, {PutDown(R1, C1, D3), PNotIn(C2, D1)}, {PutDown(R1, C1, D2), PNotIn(C2, D1)}, {Move(R1, D3, D1), PNotIn(C2, D1)}, {Move(R1, D3, D2), PNotIn(C2, D1)}, {Move(R1, D2, D1), PNotIn(C2, D1)}, {Move(R1, D2, D3), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C1, D2)}, {PIn(C2, R1), PIn(R1, D2)}, {PIn(C2, R1), PNotHolding(R1)}, {PIn(C2, R1), PIn(R1, D3)}, {PNotIn(R1, D3), PIn(C2, R1)}, {PNotIn(R1, D2), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D3)}, {PNotIn(R1, D1), PIn(C2, R1)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C3, D2), PIn(C2, R1)}, {PickUp(R1, C1, D1), PIn(C2, R1)}, {PickUp(R1, C1, D3), PIn(C2, R1)}, {PickUp(R1, C1, D2), PIn(C2, R1)}, {PutDown(R1, C1, D3), PIn(C2, R1)}, {PutDown(R1, C1, D2), PIn(C2, R1)}, {Move(R1, D3, D1), PIn(C2, R1)}, {PIn(C2, R1), Move(R1, D3, D2)}, {Move(R1, D2, D1), PIn(C2, R1)}, {PIn(C2, R1), Move(R1, D2, D3)}, {PNotIn(C1, R1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PNotIn(C1, R1)}, {PNotIn(C1, R1), PNotIn(R1, D2)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(C1, D2), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PIn(C1, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PHolding(R1), PIn(C1, D2)}, {PIn(R1, D3), PIn(C1, D2)}, {PNotIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PNotIn(R1, D3), PIn(C1, D2)}, {PNotIn(R1, D2), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C2, D1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C1, D2)}, {PutDown(R1, C2, D3), PIn(C1, D2)}, {PutDown(R1, C2, D2), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {Move(R1, D1, D3), PIn(C1, D2)}, {Move(R1, D1, D2), PIn(C1, D2)}, {Move(R1, D3, D1), PIn(C1, D2)}, {Move(R1, D3, D2), PIn(C1, D2)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(R1, D2), PNotIn(C1, D1)}, {PIn(R1, D2), PIn(C1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C2, D2), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C1, D3)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PNotHolding(R1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PNotHolding(R1)}, {PNotIn(R1, D2), PNotHolding(R1)}, {PIn(C1, R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C1, D1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D3), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D1)}, {PNotIn(R1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D1), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C1, D1)}, {PickUp(R1, C2, D1), PNotIn(C1, D1)}, {PickUp(R1, C3, D2), PNotIn(C1, D1)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, D1)}, {PickUp(R1, C1, D2), PNotIn(C1, D1)}, {PutDown(R1, C2, D3), PNotIn(C1, D1)}, {PutDown(R1, C2, D2), PNotIn(C1, D1)}, {PutDown(R1, C1, D3), PNotIn(C1, D1)}, {PutDown(R1, C1, D2), PNotIn(C1, D1)}, {Move(R1, D3, D1), PNotIn(C1, D1)}, {Move(R1, D3, D2), PNotIn(C1, D1)}, {Move(R1, D2, D1), PNotIn(C1, D1)}, {Move(R1, D2, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(R1, D3)}, {PIn(C1, D1), PNotIn(R1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(R1, D2)}, {PNotIn(R1, D3), PIn(C1, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D1)}, {PNotIn(R1, D3), PickUp(R1, C3, D2)}, {PNotIn(R1, D3), PickUp(R1, C1, D1)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D2)}, {PNotIn(R1, D3), PutDown(R1, C2, D1)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D2), PIn(C1, D3)}, {PNotIn(R1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D1), PNotIn(R1, D2)}, {PickUp(R1, C1, D3), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D1), PNotIn(R1, D2)}, {PutDown(R1, C2, D3), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C2, D1), PIn(C1, D3)}, {PickUp(R1, C3, D2), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C2, D1), PIn(C1, D3)}, {PutDown(R1, C2, D3), PIn(C1, D3)}, {PutDown(R1, C2, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {Move(R1, D1, D3), PIn(C1, D3)}, {Move(R1, D1, D2), PIn(C1, D3)}, {Move(R1, D2, D1), PIn(C1, D3)}, {Move(R1, D2, D3), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C2, D3), PNotIn(R1, D1)}, {PNotIn(R1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C2, D1), PIn(C1, R1)}, {PickUp(R1, C3, D2), PIn(C1, R1)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{In(C1, D2), NotIn(C2, D1)}, {NotIn(R1, D3), NotIn(C2, D1)}, {NotIn(R1, D2), NotIn(C2, D1)}, {In(C1, D3), NotIn(C2, D1)}, {In(C2, D1), NotIn(C2, D1)}, {NotIn(C3, D2), NotIn(C2, D1)}, {In(C3, R1), NotIn(C2, D1)}, {NotIn(C1, D3), NotIn(C2, D1)}, {NotIn(C1, D2), NotIn(C2, D1)}, {NotIn(C2, R1), NotIn(C2, D1)}, {In(C1, D2), In(C2, R1)}, {NotIn(R1, D3), In(C2, R1)}, {NotIn(R1, D2), In(C2, R1)}, {In(C1, D3), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C3, D2), In(C2, R1)}, {In(C3, R1), In(C2, R1)}, {NotIn(C1, D3), In(C2, R1)}, {NotIn(C1, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {NotIn(C1, R1), NotIn(C1, D1)}, {NotIn(C1, R1), In(C1, R1)}, {NotIn(C1, R1), NotIn(C1, D3)}, {NotIn(C1, R1), NotIn(C1, D2)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(C3, D2), In(R1, D1)}, {In(R1, D1), In(C3, R1)}, {NotIn(C1, D3), In(R1, D1)}, {NotIn(C1, D2), In(R1, D1)}, {In(C1, D2), NotIn(C1, D1)}, {In(C1, D1), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C1, D3), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {NotIn(C2, R1), In(C1, D2)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C1, D3), In(R1, D2)}, {NotIn(C2, R1), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C1, D3), Holding(R1)}, {NotIn(C2, R1), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {In(C3, D2), In(C3, R1)}, {NotIn(C3, D2), NotHolding(R1)}, {NotHolding(R1), In(C3, R1)}, {NotIn(C1, D3), NotHolding(R1)}, {NotIn(C1, D2), NotHolding(R1)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C3, D2), In(R1, D3)}, {In(C3, R1), In(R1, D3)}, {NotIn(C1, D2), In(R1, D3)}, {NotIn(C2, R1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {NotIn(R1, D3), NotIn(C1, D1)}, {NotIn(R1, D2), NotIn(C1, D1)}, {In(C1, D3), NotIn(C1, D1)}, {NotIn(C3, D2), NotIn(C1, D1)}, {In(C3, R1), NotIn(C1, D1)}, {NotIn(C1, D3), NotIn(C1, D1)}, {NotIn(C1, D2), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C1, D3), In(C1, D1)}, {NotIn(C1, D2), In(C1, D1)}, {NotIn(C3, D2), NotIn(R1, D3)}, {NotIn(R1, D3), In(C3, R1)}, {NotIn(C1, D3), NotIn(R1, D3)}, {NotIn(C1, D2), NotIn(R1, D3)}, {NotIn(C2, R1), NotIn(R1, D3)}, {NotIn(R1, D2), NotIn(C3, D2)}, {NotIn(R1, D2), In(C3, R1)}, {NotIn(R1, D2), NotIn(C1, D3)}, {NotIn(R1, D2), NotIn(C1, D2)}, {NotIn(R1, D2), NotIn(C2, R1)}, {In(C1, D3), In(C1, R1)}, {NotIn(C3, D2), In(C1, D3)}, {In(C1, D3), In(C3, R1)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C1, D2), In(C1, D3)}, {NotIn(C2, R1), In(C1, D3)}, {NotIn(C2, R1), NotIn(R1, D1)}, {NotIn(C3, D2), NotIn(C1, D3)}, {NotIn(C2, R1), NotIn(C3, D2)}, {NotIn(C1, D3), In(C3, R1)}, {NotIn(C2, R1), In(C3, R1)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D2)}]} - -Level 3: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), Place(D1), NotIn(C1, D2), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} - Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PPlace(D1), PNotIn(C1, D2), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C1, D3), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D2)}, {PNotIn(C2, D1), PIn(C3, R1)}, {PNotIn(R1, D3), PNotIn(C2, D1)}, {PNotIn(C3, D2), PNotIn(C2, D1)}, {PNotIn(R1, D2), PNotIn(C2, D1)}, {PNotIn(C1, D2), PNotIn(C2, D1)}, {PNotIn(C2, D1), PIn(C1, D3)}, {PNotIn(C2, R1), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PickUp(R1, C1, D3), PNotIn(C2, D1)}, {PickUp(R1, C1, D2), PNotIn(C2, D1)}, {PutDown(R1, C3, D1), PNotIn(C2, D1)}, {PutDown(R1, C3, D3), PNotIn(C2, D1)}, {PutDown(R1, C3, D2), PNotIn(C2, D1)}, {PNotIn(C1, D3), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D2)}, {PIn(C2, R1), PIn(C3, R1)}, {PNotIn(R1, D3), PIn(C2, R1)}, {PNotIn(C3, D2), PIn(C2, R1)}, {PNotIn(R1, D2), PIn(C2, R1)}, {PNotIn(C1, D2), PIn(C2, R1)}, {PIn(C2, R1), PIn(C1, D3)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C1, D3), PIn(C2, R1)}, {PickUp(R1, C1, D2), PIn(C2, R1)}, {PutDown(R1, C3, D1), PIn(C2, R1)}, {PutDown(R1, C3, D3), PIn(C2, R1)}, {PutDown(R1, C3, D2), PIn(C2, R1)}, {PNotIn(C1, D3), PNotIn(C1, R1)}, {PNotIn(C1, R1), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PNotIn(C1, D3), PIn(R1, D1)}, {PIn(C3, R1), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, D2), PIn(R1, D1)}, {PNotIn(C1, D2), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D1), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C1, D2)}, {PNotIn(C1, D3), PIn(C3, R1)}, {PNotIn(C1, D3), PIn(R1, D2)}, {PNotIn(C1, D3), PNotHolding(R1)}, {PNotIn(C1, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D2)}, {PNotIn(C1, D3), PNotIn(R1, D2)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D1)}, {PNotIn(C1, D3), PickUp(R1, C3, D2)}, {PNotIn(C1, D3), PickUp(R1, C1, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D3)}, {PutDown(R1, C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PNotIn(C1, D3)}, {PutDown(R1, C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), Move(R1, D1, D3)}, {PNotIn(C1, D3), Move(R1, D1, D2)}, {PNotIn(C1, D3), Move(R1, D2, D1)}, {PNotIn(C1, D3), Move(R1, D2, D3)}, {PNotIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PNotIn(C2, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C2, D1), PIn(C1, D2)}, {PutDown(R1, C2, D3), PIn(C1, D2)}, {PutDown(R1, C2, D2), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C3, D2)}, {PNotHolding(R1), PIn(C3, R1)}, {PIn(C3, R1), PIn(R1, D3)}, {PNotIn(C1, D1), PIn(C3, R1)}, {PNotIn(R1, D3), PIn(C3, R1)}, {PNotIn(R1, D2), PIn(C3, R1)}, {PIn(C3, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C3, R1)}, {PickUp(R1, C2, D1), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PickUp(R1, C1, D1), PIn(C3, R1)}, {PickUp(R1, C1, D3), PIn(C3, R1)}, {PickUp(R1, C1, D2), PIn(C3, R1)}, {PutDown(R1, C2, D1), PIn(C3, R1)}, {PutDown(R1, C2, D3), PIn(C3, R1)}, {PutDown(R1, C2, D2), PIn(C3, R1)}, {PutDown(R1, C1, D1), PIn(C3, R1)}, {PutDown(R1, C1, D3), PIn(C3, R1)}, {Move(R1, D1, D3), PIn(C3, R1)}, {Move(R1, D1, D2), PIn(C3, R1)}, {Move(R1, D3, D1), PIn(C3, R1)}, {Move(R1, D3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PNotIn(C2, R1), PIn(R1, D2)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C1, D3)}, {PHolding(R1), PNotIn(C2, R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotIn(C3, D2), PNotHolding(R1)}, {PNotIn(C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C3, D2), PIn(R1, D3)}, {PNotIn(C1, D2), PIn(R1, D3)}, {PNotIn(C2, R1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D3), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(R1, D3), PNotIn(C1, D1)}, {PNotIn(C3, D2), PNotIn(C1, D1)}, {PNotIn(R1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, D1)}, {PNotIn(C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, D1)}, {PickUp(R1, C1, D2), PNotIn(C1, D1)}, {PutDown(R1, C3, D1), PNotIn(C1, D1)}, {PutDown(R1, C3, D3), PNotIn(C1, D1)}, {PutDown(R1, C3, D2), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C3, D2)}, {PNotIn(R1, D3), PNotIn(C1, D2)}, {PNotIn(R1, D3), PNotIn(C2, R1)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D1)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PutDown(R1, C3, D1)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D2)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, D2), PNotIn(R1, D2)}, {PNotIn(C3, D2), PIn(C1, D3)}, {PNotIn(C3, D2), PNotIn(C2, R1)}, {PNotIn(C3, D2), PickUp(R1, C2, D1)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C3, D2), PickUp(R1, C1, D1)}, {PNotIn(C3, D2), PickUp(R1, C1, D3)}, {PNotIn(C3, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C3, D2)}, {PutDown(R1, C2, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C3, D2)}, {PNotIn(C3, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C3, D2)}, {PutDown(R1, C1, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), Move(R1, D1, D3)}, {PNotIn(C3, D2), Move(R1, D1, D2)}, {PNotIn(C3, D2), Move(R1, D3, D1)}, {PNotIn(C3, D2), Move(R1, D3, D2)}, {PNotIn(C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), PNotIn(C2, R1)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D1), PNotIn(R1, D2)}, {PutDown(R1, C2, D3), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D1), PNotIn(R1, D2)}, {PutDown(R1, C3, D3), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C1, D2), PIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D1)}, {PNotIn(C1, D2), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D1)}, {PNotIn(C1, D2), PickUp(R1, C1, D3)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D2)}, {PutDown(R1, C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C1, D2)}, {PutDown(R1, C1, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), Move(R1, D1, D3)}, {PNotIn(C1, D2), Move(R1, D1, D2)}, {PNotIn(C1, D2), Move(R1, D3, D1)}, {PNotIn(C1, D2), Move(R1, D3, D2)}, {PIn(C1, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C2, D1), PIn(C1, D3)}, {PutDown(R1, C2, D3), PIn(C1, D3)}, {PutDown(R1, C2, D2), PIn(C1, D3)}, {PutDown(R1, C3, D1), PIn(C1, D3)}, {PutDown(R1, C3, D3), PIn(C1, D3)}, {PutDown(R1, C3, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C2, R1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C3, D2), PNotIn(C2, R1)}, {PickUp(R1, C1, D3), PNotIn(C2, R1)}, {PickUp(R1, C1, D2), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C3, D2), PNotIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C2, R1)}, {PutDown(R1, C1, D3), PNotIn(C2, R1)}, {PutDown(R1, C1, D2), PNotIn(C2, R1)}, {PNotIn(C2, R1), Move(R1, D3, D1)}, {PNotIn(C2, R1), Move(R1, D3, D2)}, {PNotIn(C2, R1), Move(R1, D2, D1)}, {PNotIn(C2, R1), Move(R1, D2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{NotIn(C1, D3), NotIn(C2, D1)}, {NotIn(C1, D2), NotIn(C2, D1)}, {In(C2, D1), NotIn(C2, D1)}, {NotIn(C3, R1), NotIn(C2, D1)}, {NotIn(C1, D3), In(C2, R1)}, {NotIn(C1, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C3, R1), In(C2, R1)}, {NotIn(C1, R1), NotIn(C1, D3)}, {NotIn(C1, R1), NotIn(C1, D2)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), In(C2, D3)}, {In(R1, D1), In(C2, D2)}, {NotIn(C3, R1), In(R1, D1)}, {NotIn(C1, D3), In(C1, D2)}, {NotIn(C1, D3), In(C3, R1)}, {NotIn(C1, D3), NotHolding(R1)}, {NotIn(C1, D3), NotIn(C1, D1)}, {NotIn(C1, D3), In(C1, D1)}, {NotIn(C3, D2), NotIn(C1, D3)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C1, D3), In(C2, D3)}, {NotIn(C1, D3), In(C2, D2)}, {NotIn(C1, D3), NotIn(C3, R1)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C2, R1), In(C1, D2)}, {In(C1, D2), In(C2, D3)}, {In(C1, D2), In(C2, D2)}, {In(C3, D2), In(C3, R1)}, {NotIn(C2, R1), In(C3, R1)}, {In(C2, D3), In(C3, R1)}, {In(C2, D2), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {In(C2, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {Holding(R1), In(C2, D3)}, {Holding(R1), In(C2, D2)}, {NotIn(C3, R1), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C2, D2), In(R1, D3)}, {NotIn(C3, R1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {NotIn(C1, D2), NotIn(C1, D1)}, {NotIn(C3, R1), NotIn(C1, D1)}, {NotIn(C1, D2), In(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, R1), NotIn(R1, D3)}, {NotIn(R1, D3), In(C2, D3)}, {NotIn(R1, D3), In(C2, D2)}, {NotIn(R1, D3), NotIn(C3, R1)}, {NotIn(C2, R1), NotIn(C3, D2)}, {NotIn(C3, D2), In(C2, D3)}, {NotIn(C3, D2), In(C2, D2)}, {NotIn(C3, D2), NotIn(C3, R1)}, {NotIn(R1, D2), NotIn(C2, R1)}, {NotIn(R1, D2), In(C2, D3)}, {NotIn(R1, D2), In(C2, D2)}, {NotIn(R1, D2), NotIn(C3, R1)}, {NotIn(C1, D2), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D2)}, {NotIn(C1, D2), In(C2, D3)}, {NotIn(C1, D2), In(C2, D2)}, {In(C1, D3), In(C1, R1)}, {NotIn(C2, R1), In(C1, D3)}, {In(C1, D3), In(C2, D3)}, {In(C1, D3), In(C2, D2)}, {NotIn(C3, R1), In(C1, D3)}, {NotIn(C2, R1), NotIn(C3, R1)}, {In(C2, D1), In(C2, D3)}, {In(C2, D1), In(C2, D2)}, {In(C2, D3), In(C2, D2)}, {NotIn(C3, R1), In(C2, D3)}, {NotIn(C3, R1), In(C2, D2)}]} - -Level 4: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), Container(C1), In(C1, D2), In(C2, D3), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} - Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PContainer(C1), PIn(C1, D2), PIn(C2, D3), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C1, D3), PNotIn(C2, D1)}, {PNotIn(C3, R1), PNotIn(C2, D1)}, {PNotIn(C1, D2), PNotIn(C2, D1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PNotIn(C1, D3), PIn(C2, R1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, R1)}, {PNotIn(C1, D2), PIn(C2, R1)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PNotIn(C1, D3), PNotIn(C1, R1)}, {PNotIn(C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(C2, D3), PIn(R1, D1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(C2, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, R1), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C1, D2)}, {PNotIn(C1, D3), PIn(C2, D3)}, {PNotIn(C1, D3), PIn(C3, R1)}, {PNotIn(C1, D3), PNotHolding(R1)}, {PNotIn(C1, D3), PIn(C2, D2)}, {PNotIn(C1, D3), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D2)}, {PNotIn(C3, R1), PNotIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D1)}, {PNotIn(C1, D3), PickUp(R1, C2, D3)}, {PNotIn(C1, D3), PickUp(R1, C2, D2)}, {PNotIn(C1, D3), PickUp(R1, C3, D2)}, {PNotIn(C1, D3), PickUp(R1, C1, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D3)}, {PutDown(R1, C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C1, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D3)}, {PNotIn(C1, D3), PutDown(R1, C3, D2)}, {PIn(C2, D3), PIn(C1, D2)}, {PIn(C2, D2), PIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PNotIn(C2, R1), PIn(C1, D2)}, {PickUp(R1, C2, D3), PIn(C1, D2)}, {PickUp(R1, C2, D2), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C2, D3)}, {PIn(R1, D2), PIn(C2, D3)}, {PHolding(R1), PIn(C2, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PNotIn(R1, D3), PIn(C2, D3)}, {PNotIn(C3, D2), PIn(C2, D3)}, {PNotIn(R1, D2), PIn(C2, D3)}, {PNotIn(C3, R1), PIn(C2, D3)}, {PNotIn(C1, D2), PIn(C2, D3)}, {PIn(C1, D3), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D2), PIn(C2, D3)}, {PickUp(R1, C1, D1), PIn(C2, D3)}, {PickUp(R1, C1, D3), PIn(C2, D3)}, {PickUp(R1, C1, D2), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PutDown(R1, C3, D1), PIn(C2, D3)}, {PutDown(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C3, D2), PIn(C2, D3)}, {PutDown(R1, C1, D1), PIn(C2, D3)}, {PutDown(R1, C1, D3), PIn(C2, D3)}, {PutDown(R1, C1, D2), PIn(C2, D3)}, {Move(R1, D1, D3), PIn(C2, D3)}, {Move(R1, D1, D2), PIn(C2, D3)}, {Move(R1, D2, D1), PIn(C2, D3)}, {Move(R1, D2, D3), PIn(C2, D3)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, R1), PIn(C2, D2)}, {PNotIn(C2, R1), PIn(C3, R1)}, {PickUp(R1, C2, D3), PIn(C3, R1)}, {PickUp(R1, C2, D2), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PIn(C2, D2)}, {PNotIn(C3, R1), PHolding(R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PIn(R1, D3), PIn(C2, D2)}, {PNotIn(R1, D3), PIn(C2, D2)}, {PNotIn(C3, D2), PIn(C2, D2)}, {PNotIn(R1, D2), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, D2)}, {PNotIn(C1, D2), PIn(C2, D2)}, {PIn(C1, D3), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PickUp(R1, C1, D1), PIn(C2, D2)}, {PickUp(R1, C1, D3), PIn(C2, D2)}, {PickUp(R1, C1, D2), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PutDown(R1, C3, D1), PIn(C2, D2)}, {PutDown(R1, C3, D3), PIn(C2, D2)}, {PutDown(R1, C3, D2), PIn(C2, D2)}, {PutDown(R1, C1, D1), PIn(C2, D2)}, {PutDown(R1, C1, D3), PIn(C2, D2)}, {PutDown(R1, C1, D2), PIn(C2, D2)}, {Move(R1, D1, D3), PIn(C2, D2)}, {Move(R1, D1, D2), PIn(C2, D2)}, {Move(R1, D3, D1), PIn(C2, D2)}, {Move(R1, D3, D2), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PNotIn(C3, R1), PNotIn(C1, D1)}, {PNotIn(C1, D2), PNotIn(C1, D1)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PNotIn(C1, D2)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C3, R1)}, {PNotIn(R1, D3), PNotIn(C2, R1)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D2)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, R1), PNotIn(C3, D2)}, {PNotIn(C3, D2), PNotIn(C2, R1)}, {PNotIn(C3, D2), PickUp(R1, C2, D3)}, {PNotIn(C3, D2), PickUp(R1, C2, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C3, R1), PNotIn(R1, D2)}, {PNotIn(R1, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(R1, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PIn(C1, D3)}, {PNotIn(C3, R1), PNotIn(C2, R1)}, {PNotIn(C3, R1), PickUp(R1, C2, D1)}, {PNotIn(C3, R1), PickUp(R1, C2, D3)}, {PNotIn(C3, R1), PickUp(R1, C2, D2)}, {PNotIn(C3, R1), PickUp(R1, C1, D1)}, {PNotIn(C3, R1), PickUp(R1, C1, D3)}, {PNotIn(C3, R1), PutDown(R1, C2, D1)}, {PNotIn(C3, R1), PutDown(R1, C2, D3)}, {PNotIn(C3, R1), PutDown(R1, C2, D2)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C3, R1), PutDown(R1, C1, D1)}, {PNotIn(C3, R1), PutDown(R1, C1, D3)}, {PNotIn(C3, R1), PutDown(R1, C1, D2)}, {PNotIn(C3, R1), Move(R1, D1, D3)}, {PNotIn(C3, R1), Move(R1, D1, D2)}, {PNotIn(C3, R1), Move(R1, D3, D1)}, {PNotIn(C3, R1), Move(R1, D3, D2)}, {PNotIn(C1, D2), PIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D3)}, {PNotIn(C1, D2), PickUp(R1, C2, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D1)}, {PNotIn(C1, D2), PickUp(R1, C1, D3)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C1, D2)}, {PutDown(R1, C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C2, D2)}, {PIn(C1, R1), PIn(C1, D3)}, {PNotIn(C2, R1), PIn(C1, D3)}, {PickUp(R1, C2, D3), PIn(C1, D3)}, {PickUp(R1, C2, D2), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C1, D3), PNotIn(C2, R1)}, {PickUp(R1, C1, D2), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PutDown(R1, C3, D1), PNotIn(C2, R1)}, {PutDown(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C3, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {NotIn(C2, D3), In(R1, D1)}, {NotIn(C2, D2), In(R1, D1)}, {In(C3, D3), In(R1, D1)}, {NotIn(C1, D3), In(C2, D3)}, {NotIn(C1, D3), In(C2, D2)}, {NotIn(C1, D3), NotIn(C3, R1)}, {NotIn(C1, D3), NotIn(C1, D2)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C2, R1), NotIn(C1, D3)}, {NotIn(C1, D3), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C1, D3)}, {NotIn(C1, D3), In(C3, D1)}, {NotIn(C1, D3), In(C3, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {NotIn(C2, D3), In(C1, D2)}, {NotIn(C2, D2), In(C1, D2)}, {Holding(R1), In(C2, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C3, R1), In(C2, D3)}, {NotIn(C1, D2), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C2, D2), In(C2, D3)}, {In(C3, D1), In(C2, D3)}, {In(C3, D3), In(C2, D3)}, {In(C3, D2), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {NotIn(C2, D3), In(C3, R1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C2, D3), In(R1, D2)}, {In(C3, D1), In(R1, D2)}, {In(C3, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D1), Holding(R1)}, {In(C3, D3), Holding(R1)}, {NotIn(C3, D2), In(C3, D2)}, {In(C3, D1), In(C3, D2)}, {In(C3, D3), In(C3, D2)}, {NotIn(C2, D3), NotHolding(R1)}, {NotIn(C2, D2), NotHolding(R1)}, {NotIn(C3, R1), In(C2, D2)}, {NotIn(C1, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(C2, D3), In(C2, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C3, D1), In(C2, D2)}, {In(C3, D3), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C2, D2), In(R1, D3)}, {In(C3, D1), In(R1, D3)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D3), NotIn(R1, D3)}, {NotIn(C2, D2), NotIn(R1, D3)}, {NotIn(R1, D3), In(C3, D3)}, {NotIn(C3, D2), NotIn(C2, D3)}, {NotIn(R1, D2), NotIn(C2, D3)}, {NotIn(R1, D2), NotIn(C2, D2)}, {NotIn(C2, R1), NotIn(C3, R1)}, {NotIn(C2, D3), NotIn(C3, R1)}, {NotIn(C2, D2), NotIn(C3, R1)}, {NotIn(C2, R1), NotIn(C1, D2)}, {NotIn(C1, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C1, D2)}, {In(C1, D3), In(C1, R1)}, {NotIn(C2, D3), In(C1, D3)}, {NotIn(C2, D2), In(C1, D3)}, {NotIn(R1, D1), In(C3, D1)}, {NotIn(C2, R1), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D2)}, {NotIn(C2, R1), In(C3, D1)}, {NotIn(C2, R1), In(C3, D3)}, {NotIn(C2, D3), In(C2, D1)}, {NotIn(C2, D2), In(C2, D1)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D3), In(C3, D1)}, {NotIn(C2, D3), In(C3, D3)}, {NotIn(C2, D2), In(C3, D1)}, {NotIn(C2, D2), In(C3, D3)}, {In(C3, D1), In(C3, D3)}]} - -Level 5: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, D1), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} - Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PNotIn(C1, D3), PContainer(C3), PIn(C2, D3), PContainer(C1), PIn(C1, D2), PIn(C3, D1), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PIn(C3, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(C2, D2), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PNotIn(C2, D3), PIn(C1, D3), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D1), PickUp(R1, C3, D3), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PNotIn(C2, D2), PIn(C2, D2)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D1)}, {PNotIn(C3, R1), PickUp(R1, C3, D3)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C3, D1), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PIn(C3, D3), PIn(R1, D1)}, {PNotIn(C2, D2), PIn(R1, D1)}, {PNotIn(C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PNotIn(C1, D3), PIn(C2, D3)}, {PNotIn(C1, D3), PIn(C3, D1)}, {PNotIn(C1, D3), PIn(C2, D2)}, {PIn(C3, D3), PNotIn(C1, D3)}, {PNotIn(C2, D2), PNotIn(C1, D3)}, {PNotIn(C3, R1), PNotIn(C1, D3)}, {PNotIn(C1, D2), PNotIn(C1, D3)}, {PNotIn(C2, D3), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C2, R1)}, {PNotIn(C1, D3), PickUp(R1, C2, D3)}, {PNotIn(C1, D3), PickUp(R1, C2, D2)}, {PNotIn(C1, D3), PickUp(R1, C3, D1)}, {PNotIn(C1, D3), PickUp(R1, C3, D3)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PIn(C3, D1), PIn(C2, D3)}, {PHolding(R1), PIn(C2, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PIn(C3, D3), PIn(C2, D3)}, {PNotIn(C2, D2), PIn(C2, D3)}, {PNotIn(C3, R1), PIn(C2, D3)}, {PNotIn(C1, D2), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D1), PIn(C2, D3)}, {PickUp(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PutDown(R1, C3, D1), PIn(C2, D3)}, {PutDown(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C3, D2), PIn(C2, D3)}, {PutDown(R1, C1, D1), PIn(C2, D3)}, {PutDown(R1, C1, D3), PIn(C2, D3)}, {PutDown(R1, C1, D2), PIn(C2, D3)}, {PIn(C1, D1), PIn(C1, D2)}, {PNotIn(C2, D2), PIn(C1, D2)}, {PNotIn(C2, D3), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, D1), PIn(C3, R1)}, {PIn(C3, D1), PIn(R1, D2)}, {PIn(C3, D1), PHolding(R1)}, {PIn(C3, D1), PIn(C3, D2)}, {PIn(C3, D1), PIn(C2, D2)}, {PIn(C3, D1), PIn(R1, D3)}, {PIn(C3, D3), PIn(C3, D1)}, {PNotIn(C2, D2), PIn(C3, D1)}, {PNotIn(C2, D3), PIn(C3, D1)}, {PNotIn(R1, D1), PIn(C3, D1)}, {PIn(C3, D1), PNotIn(C2, R1)}, {PIn(C3, D1), PickUp(R1, C2, D3)}, {PIn(C3, D1), PickUp(R1, C2, D2)}, {PIn(C3, D1), PickUp(R1, C3, D3)}, {PIn(C3, D1), PickUp(R1, C3, D2)}, {PIn(C3, D1), PickUp(R1, C1, D3)}, {PIn(C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PIn(C3, D1)}, {PutDown(R1, C2, D3), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C3, D3)}, {PIn(C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PIn(C3, D1)}, {PutDown(R1, C1, D3), PIn(C3, D1)}, {PutDown(R1, C1, D2), PIn(C3, D1)}, {PIn(C3, D1), Move(R1, D3, D1)}, {PIn(C3, D1), Move(R1, D3, D2)}, {PIn(C3, D1), Move(R1, D2, D1)}, {PIn(C3, D1), Move(R1, D2, D3)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, R1)}, {PNotIn(C2, D3), PIn(C3, R1)}, {PickUp(R1, C3, D1), PIn(C3, R1)}, {PickUp(R1, C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(C3, D3), PIn(R1, D2)}, {PNotIn(C2, D3), PIn(R1, D2)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C3, D1), PIn(R1, D2)}, {PickUp(R1, C3, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PIn(C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PIn(C3, D3), PIn(C3, D2)}, {PickUp(R1, C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotIn(C2, D2), PNotHolding(R1)}, {PNotIn(C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PIn(C3, D3), PIn(C2, D2)}, {PNotIn(C3, R1), PIn(C2, D2)}, {PNotIn(C1, D2), PIn(C2, D2)}, {PNotIn(C2, D3), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PickUp(R1, C3, D1), PIn(C2, D2)}, {PickUp(R1, C3, D3), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PIn(R1, D3)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D2)}, {PIn(C3, D3), PNotIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D3)}, {PIn(C3, D3), PNotIn(C2, R1)}, {PIn(C3, D3), PickUp(R1, C2, D1)}, {PIn(C3, D3), PickUp(R1, C2, D3)}, {PIn(C3, D3), PickUp(R1, C2, D2)}, {PIn(C3, D3), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D2)}, {PIn(C3, D3), PickUp(R1, C1, D1)}, {PIn(C3, D3), PickUp(R1, C1, D2)}, {PIn(C3, D3), PutDown(R1, C2, D1)}, {PIn(C3, D3), PutDown(R1, C2, D3)}, {PIn(C3, D3), PutDown(R1, C2, D2)}, {PIn(C3, D3), PutDown(R1, C3, D1)}, {PIn(C3, D3), PutDown(R1, C3, D3)}, {PIn(C3, D3), PutDown(R1, C3, D2)}, {PIn(C3, D3), PutDown(R1, C1, D1)}, {PIn(C3, D3), PutDown(R1, C1, D3)}, {PIn(C3, D3), PutDown(R1, C1, D2)}, {PIn(C3, D3), Move(R1, D1, D3)}, {PIn(C3, D3), Move(R1, D1, D2)}, {PIn(C3, D3), Move(R1, D2, D1)}, {PIn(C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(R1, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PNotIn(R1, D2)}, {PNotIn(C3, R1), PNotIn(C2, D2)}, {PNotIn(C1, D2), PNotIn(C2, D2)}, {PNotIn(C2, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PIn(C1, D3)}, {PNotIn(C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C2, D1)}, {PNotIn(C2, D2), PickUp(R1, C2, D3)}, {PNotIn(C2, D2), PickUp(R1, C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C3, D1)}, {PNotIn(C2, D2), PickUp(R1, C3, D3)}, {PNotIn(C2, D2), PickUp(R1, C3, D2)}, {PNotIn(C2, D2), PickUp(R1, C1, D1)}, {PNotIn(C2, D2), PickUp(R1, C1, D3)}, {PNotIn(C2, D2), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C2, D2)}, {PutDown(R1, C2, D3), PNotIn(C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C2, D2)}, {PutDown(R1, C1, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), Move(R1, D1, D3)}, {PNotIn(C2, D2), Move(R1, D1, D2)}, {PNotIn(C2, D2), Move(R1, D3, D1)}, {PNotIn(C2, D2), Move(R1, D3, D2)}, {PNotIn(R1, D3), PNotIn(C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C2, D3), PNotIn(C3, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(R1, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PNotIn(C2, D3)}, {PNotIn(C3, R1), PNotIn(C2, R1)}, {PNotIn(C3, R1), PickUp(R1, C2, D3)}, {PNotIn(C3, R1), PickUp(R1, C2, D2)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PNotIn(C2, R1)}, {PNotIn(C1, D2), PickUp(R1, C2, D3)}, {PNotIn(C1, D2), PickUp(R1, C2, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C1, D3)}, {PNotIn(C2, D3), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D1)}, {PNotIn(C2, D3), PickUp(R1, C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D2)}, {PNotIn(C2, D3), PickUp(R1, C3, D1)}, {PNotIn(C2, D3), PickUp(R1, C3, D3)}, {PNotIn(C2, D3), PickUp(R1, C3, D2)}, {PNotIn(C2, D3), PickUp(R1, C1, D1)}, {PNotIn(C2, D3), PickUp(R1, C1, D3)}, {PNotIn(C2, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C3, D3)}, {PNotIn(C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PNotIn(C2, D3)}, {PutDown(R1, C1, D2), PNotIn(C2, D3)}, {PNotIn(C2, D3), Move(R1, D1, D3)}, {PNotIn(C2, D3), Move(R1, D1, D2)}, {PNotIn(C2, D3), Move(R1, D2, D1)}, {PNotIn(C2, D3), Move(R1, D2, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PickUp(R1, C3, D1), PNotIn(C2, R1)}, {PickUp(R1, C3, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D2)}, {PickUp(R1, C3, D1), Move(R1, D2, D1)}, {PickUp(R1, C3, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C3, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C3, D1)}, {Move(R1, D1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(R1, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C1, D3)}, {NotIn(C1, D3), In(C1, D3)}, {NotIn(C1, D3), NotIn(C3, D1)}, {In(C3, D1), In(C2, D3)}, {In(C2, D3), In(C2, D2)}, {In(C3, D3), In(C2, D3)}, {NotIn(C2, D2), In(C2, D3)}, {NotIn(C2, D3), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D3), NotIn(C3, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {NotIn(C2, D2), In(C3, D1)}, {In(C3, D1), NotIn(C2, D3)}, {In(C3, D1), NotIn(C3, D1)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotIn(C3, D1), In(R1, D2)}, {NotIn(C3, D3), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotHolding(R1), NotIn(C3, D1)}, {NotHolding(R1), NotIn(C3, D3)}, {NotIn(C2, D2), In(C2, D2)}, {NotIn(C2, D3), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(C3, D1), In(C2, D2)}, {In(C2, D2), NotIn(C3, D3)}, {NotIn(R1, D3), In(R1, D3)}, {NotIn(C3, D1), In(R1, D3)}, {NotIn(C2, D2), In(C3, D3)}, {NotIn(C2, D3), In(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C3, D3), NotIn(C3, D3)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D2)}, {NotIn(C2, D2), In(C2, D1)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(R1, D3), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, R1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C1, D2), NotIn(C2, D3)}, {NotIn(C2, R1), NotIn(C2, D3)}, {NotIn(C2, D3), In(C2, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D3)}, {In(C1, D3), In(C1, R1)}, {NotIn(R1, D1), NotIn(C3, D1)}, {NotIn(C2, R1), NotIn(C3, D1)}, {NotIn(C2, R1), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}]} - -Level 6: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), In(C3, D1), NotIn(C1, D3), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C3, D3), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(C3, D1), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} - Actions: {PPlace(D3), PNotIn(C2, D1), PIn(C2, R1), PNotIn(C1, R1), PIn(R1, D1), PPlace(D2), PIn(C3, D1), PNotIn(C1, D3), PContainer(C3), PIn(C2, D3), PContainer(C1), PIn(C1, D2), PIn(C3, R1), PIn(R1, D2), PHolding(R1), PIn(C3, D2), PNotHolding(R1), PIn(C2, D2), PIn(R1, D3), PIn(C3, D3), PNotIn(C1, D1), PContainer(C2), PIn(C1, D1), PNotIn(C3, D3), PNotIn(C2, D2), PNotIn(R1, D3), PNotIn(C3, D2), PNotIn(R1, D2), PNotIn(C3, R1), PPlace(D1), PNotIn(C1, D2), PNotIn(C2, D3), PIn(C1, D3), PNotIn(C3, D1), PNotIn(R1, D1), PIn(C1, R1), PRobot(R1), PNotIn(C2, R1), PIn(C2, D1), PickUp(R1, C2, D1), PickUp(R1, C2, D3), PickUp(R1, C2, D2), PickUp(R1, C3, D1), PickUp(R1, C3, D3), PickUp(R1, C3, D2), PickUp(R1, C1, D1), PickUp(R1, C1, D3), PickUp(R1, C1, D2), PutDown(R1, C2, D1), PutDown(R1, C2, D3), PutDown(R1, C2, D2), PutDown(R1, C3, D1), PutDown(R1, C3, D3), PutDown(R1, C3, D2), PutDown(R1, C1, D1), PutDown(R1, C1, D3), PutDown(R1, C1, D2), Move(R1, D1, D3), Move(R1, D1, D2), Move(R1, D3, D1), Move(R1, D3, D2), Move(R1, D2, D1), Move(R1, D2, D3)} - Mutex: {{PIn(C2, D1), PNotIn(C2, D1)}, {PIn(C2, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D1), PNotIn(C2, D1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D1)}, {PNotIn(C1, R1), PIn(C1, R1)}, {PutDown(R1, C1, D1), PIn(C1, R1)}, {PutDown(R1, C1, D3), PIn(C1, R1)}, {PutDown(R1, C1, D2), PIn(C1, R1)}, {PNotIn(C1, R1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotIn(C1, R1)}, {PutDown(R1, C1, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C1, D3), PIn(C1, D3)}, {PickUp(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D3), PNotIn(C1, D3)}, {PHolding(R1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PHolding(R1)}, {PutDown(R1, C2, D3), PHolding(R1)}, {PHolding(R1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PHolding(R1)}, {PutDown(R1, C3, D3), PHolding(R1)}, {PutDown(R1, C3, D2), PHolding(R1)}, {PutDown(R1, C1, D1), PHolding(R1)}, {PutDown(R1, C1, D3), PHolding(R1)}, {PutDown(R1, C1, D2), PHolding(R1)}, {PickUp(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C2, D2)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D3)}, {PickUp(R1, C2, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C2, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C2, D2)}, {PickUp(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D1)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D3), PickUp(R1, C3, D2)}, {PutDown(R1, C1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D2), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D1)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D3)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D2), PNotHolding(R1)}, {PutDown(R1, C2, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D3), PickUp(R1, C1, D2)}, {PutDown(R1, C3, D2), PickUp(R1, C1, D2)}, {PIn(C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C3, D3), PNotIn(C3, D3)}, {PIn(C3, D3), PickUp(R1, C3, D3)}, {PutDown(R1, C3, D3), PNotIn(C3, D3)}, {PNotIn(C2, D2), PIn(C2, D2)}, {PickUp(R1, C2, D2), PIn(C2, D2)}, {PNotIn(C2, D2), PutDown(R1, C2, D2)}, {PNotIn(R1, D3), PIn(R1, D3)}, {Move(R1, D3, D1), PIn(R1, D3)}, {Move(R1, D3, D2), PIn(R1, D3)}, {PNotIn(R1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D3), Move(R1, D3, D1)}, {Move(R1, D1, D3), Move(R1, D3, D2)}, {PNotIn(R1, D3), Move(R1, D2, D3)}, {Move(R1, D3, D1), Move(R1, D2, D3)}, {Move(R1, D3, D2), Move(R1, D2, D3)}, {PNotIn(C3, D2), PIn(C3, D2)}, {PickUp(R1, C3, D2), PIn(C3, D2)}, {PutDown(R1, C3, D2), PNotIn(C3, D2)}, {PNotIn(R1, D2), PIn(R1, D2)}, {Move(R1, D2, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), PNotIn(R1, D2)}, {Move(R1, D1, D2), Move(R1, D2, D1)}, {Move(R1, D1, D2), Move(R1, D2, D3)}, {PNotIn(R1, D2), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D3, D2)}, {PNotIn(C3, R1), PIn(C3, R1)}, {PutDown(R1, C3, D1), PIn(C3, R1)}, {PutDown(R1, C3, D3), PIn(C3, R1)}, {PutDown(R1, C3, D2), PIn(C3, R1)}, {PNotIn(C3, R1), PickUp(R1, C3, D1)}, {PNotIn(C3, R1), PickUp(R1, C3, D3)}, {PNotIn(C3, R1), PickUp(R1, C3, D2)}, {PNotIn(C1, D2), PIn(C1, D2)}, {PickUp(R1, C1, D2), PIn(C1, D2)}, {PNotIn(C1, D2), PutDown(R1, C1, D2)}, {PNotIn(C2, D3), PIn(C2, D3)}, {PickUp(R1, C2, D3), PIn(C2, D3)}, {PNotIn(C2, D3), PutDown(R1, C2, D3)}, {PIn(C3, D1), PNotIn(C3, D1)}, {PIn(C3, D1), PickUp(R1, C3, D1)}, {PutDown(R1, C3, D1), PNotIn(C3, D1)}, {PNotIn(R1, D1), PIn(R1, D1)}, {Move(R1, D1, D3), PIn(R1, D1)}, {Move(R1, D1, D2), PIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D3, D1)}, {Move(R1, D1, D2), Move(R1, D3, D1)}, {PNotIn(R1, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), Move(R1, D2, D1)}, {PNotIn(C2, R1), PIn(C2, R1)}, {PutDown(R1, C2, D1), PIn(C2, R1)}, {PutDown(R1, C2, D3), PIn(C2, R1)}, {PutDown(R1, C2, D2), PIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, R1)}, {PickUp(R1, C2, D3), PNotIn(C2, R1)}, {PickUp(R1, C2, D2), PNotIn(C2, R1)}, {PickUp(R1, C2, D1), PNotIn(C2, D1)}, {PIn(C2, R1), PIn(C2, D3)}, {PIn(C2, R1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D1), PIn(C2, R1)}, {PickUp(R1, C2, D3), PIn(C2, R1)}, {PickUp(R1, C2, D2), PIn(C2, R1)}, {PutDown(R1, C1, D1), PNotIn(C1, R1)}, {PutDown(R1, C1, D3), PNotIn(C1, R1)}, {PutDown(R1, C1, D2), PNotIn(C1, R1)}, {PIn(R1, D2), PIn(R1, D1)}, {PIn(R1, D3), PIn(R1, D1)}, {PNotIn(C3, D3), PIn(R1, D1)}, {PickUp(R1, C2, D3), PIn(R1, D1)}, {PickUp(R1, C2, D2), PIn(R1, D1)}, {PickUp(R1, C3, D3), PIn(R1, D1)}, {PickUp(R1, C3, D2), PIn(R1, D1)}, {PickUp(R1, C1, D3), PIn(R1, D1)}, {PickUp(R1, C1, D2), PIn(R1, D1)}, {PutDown(R1, C2, D3), PIn(R1, D1)}, {PutDown(R1, C2, D2), PIn(R1, D1)}, {PutDown(R1, C3, D3), PIn(R1, D1)}, {PutDown(R1, C3, D2), PIn(R1, D1)}, {PutDown(R1, C1, D3), PIn(R1, D1)}, {PutDown(R1, C1, D2), PIn(R1, D1)}, {Move(R1, D3, D1), PIn(R1, D1)}, {Move(R1, D3, D2), PIn(R1, D1)}, {Move(R1, D2, D1), PIn(R1, D1)}, {Move(R1, D2, D3), PIn(R1, D1)}, {PIn(C3, D1), PIn(C2, D3)}, {PIn(C3, D1), PIn(C3, R1)}, {PIn(C3, D1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, D1)}, {PIn(C3, D1), PNotIn(C3, D3)}, {PNotIn(C2, D2), PIn(C3, D1)}, {PNotIn(C2, D3), PIn(C3, D1)}, {PIn(C3, D1), PickUp(R1, C2, D3)}, {PIn(C3, D1), PickUp(R1, C3, D3)}, {PIn(C3, D1), PickUp(R1, C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D1)}, {PIn(C3, D1), PutDown(R1, C3, D3)}, {PIn(C3, D1), PutDown(R1, C3, D2)}, {PNotIn(C2, D2), PNotIn(C1, D3)}, {PNotIn(C1, D3), PNotIn(C3, D1)}, {PNotIn(C1, D3), PickUp(R1, C1, D3)}, {PIn(C2, D2), PIn(C2, D3)}, {PIn(C3, D3), PIn(C2, D3)}, {PNotIn(C3, D3), PIn(C2, D3)}, {PNotIn(C2, D2), PIn(C2, D3)}, {PNotIn(C3, D1), PIn(C2, D3)}, {PIn(C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D1), PIn(C2, D3)}, {PickUp(R1, C2, D2), PIn(C2, D3)}, {PickUp(R1, C3, D1), PIn(C2, D3)}, {PickUp(R1, C3, D3), PIn(C2, D3)}, {PutDown(R1, C2, D1), PIn(C2, D3)}, {PutDown(R1, C2, D3), PIn(C2, D3)}, {PutDown(R1, C2, D2), PIn(C2, D3)}, {PIn(C1, D1), PIn(C1, D2)}, {PIn(C1, D3), PIn(C1, D2)}, {PIn(C1, R1), PIn(C1, D2)}, {PickUp(R1, C1, D1), PIn(C1, D2)}, {PickUp(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D1), PIn(C1, D2)}, {PutDown(R1, C1, D3), PIn(C1, D2)}, {PutDown(R1, C1, D2), PIn(C1, D2)}, {PIn(C3, R1), PIn(C3, D2)}, {PIn(C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D1), PIn(C3, R1)}, {PickUp(R1, C3, D3), PIn(C3, R1)}, {PickUp(R1, C3, D2), PIn(C3, R1)}, {PIn(R1, D2), PIn(R1, D3)}, {PIn(R1, D2), PNotIn(C3, D3)}, {PIn(R1, D2), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PIn(R1, D2)}, {PickUp(R1, C2, D3), PIn(R1, D2)}, {PickUp(R1, C3, D1), PIn(R1, D2)}, {PickUp(R1, C3, D3), PIn(R1, D2)}, {PickUp(R1, C1, D1), PIn(R1, D2)}, {PickUp(R1, C1, D3), PIn(R1, D2)}, {PutDown(R1, C2, D1), PIn(R1, D2)}, {PutDown(R1, C2, D3), PIn(R1, D2)}, {PutDown(R1, C3, D1), PIn(R1, D2)}, {PutDown(R1, C3, D3), PIn(R1, D2)}, {PutDown(R1, C1, D1), PIn(R1, D2)}, {PutDown(R1, C1, D3), PIn(R1, D2)}, {Move(R1, D1, D3), PIn(R1, D2)}, {Move(R1, D1, D2), PIn(R1, D2)}, {Move(R1, D3, D1), PIn(R1, D2)}, {PIn(R1, D2), Move(R1, D3, D2)}, {PHolding(R1), PickUp(R1, C2, D1)}, {PHolding(R1), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D2), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PHolding(R1)}, {PHolding(R1), PickUp(R1, C3, D2)}, {PHolding(R1), PickUp(R1, C1, D1)}, {PHolding(R1), PickUp(R1, C1, D3)}, {PHolding(R1), PickUp(R1, C1, D2)}, {PIn(C3, D3), PIn(C3, D2)}, {PNotIn(C3, D3), PIn(C3, D2)}, {PNotIn(C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D1), PIn(C3, D2)}, {PickUp(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D1), PIn(C3, D2)}, {PutDown(R1, C3, D3), PIn(C3, D2)}, {PutDown(R1, C3, D2), PIn(C3, D2)}, {PNotHolding(R1), PNotIn(C3, D3)}, {PNotHolding(R1), PNotIn(C3, D1)}, {PutDown(R1, C2, D1), PNotHolding(R1)}, {PutDown(R1, C2, D3), PNotHolding(R1)}, {PutDown(R1, C2, D2), PNotHolding(R1)}, {PutDown(R1, C3, D1), PNotHolding(R1)}, {PutDown(R1, C3, D3), PNotHolding(R1)}, {PutDown(R1, C3, D2), PNotHolding(R1)}, {PutDown(R1, C1, D1), PNotHolding(R1)}, {PutDown(R1, C1, D3), PNotHolding(R1)}, {PutDown(R1, C1, D2), PNotHolding(R1)}, {PNotIn(C3, D3), PIn(C2, D2)}, {PNotIn(C2, D3), PIn(C2, D2)}, {PNotIn(C3, D1), PIn(C2, D2)}, {PIn(C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D1), PIn(C2, D2)}, {PickUp(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D1), PIn(C2, D2)}, {PutDown(R1, C2, D3), PIn(C2, D2)}, {PutDown(R1, C2, D2), PIn(C2, D2)}, {PIn(R1, D3), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PIn(R1, D3)}, {PickUp(R1, C2, D2), PIn(R1, D3)}, {PickUp(R1, C3, D1), PIn(R1, D3)}, {PickUp(R1, C3, D2), PIn(R1, D3)}, {PickUp(R1, C1, D1), PIn(R1, D3)}, {PickUp(R1, C1, D2), PIn(R1, D3)}, {PutDown(R1, C2, D1), PIn(R1, D3)}, {PutDown(R1, C2, D2), PIn(R1, D3)}, {PutDown(R1, C3, D1), PIn(R1, D3)}, {PutDown(R1, C3, D2), PIn(R1, D3)}, {PutDown(R1, C1, D1), PIn(R1, D3)}, {PutDown(R1, C1, D2), PIn(R1, D3)}, {Move(R1, D1, D3), PIn(R1, D3)}, {Move(R1, D1, D2), PIn(R1, D3)}, {Move(R1, D2, D1), PIn(R1, D3)}, {Move(R1, D2, D3), PIn(R1, D3)}, {PIn(C3, D3), PNotIn(C2, D2)}, {PIn(C3, D3), PNotIn(C2, D3)}, {PIn(C3, D3), PNotIn(C3, D1)}, {PIn(C3, D3), PickUp(R1, C2, D3)}, {PIn(C3, D3), PickUp(R1, C3, D1)}, {PIn(C3, D3), PickUp(R1, C3, D2)}, {PIn(C3, D3), PutDown(R1, C3, D1)}, {PIn(C3, D3), PutDown(R1, C3, D3)}, {PIn(C3, D3), PutDown(R1, C3, D2)}, {PickUp(R1, C1, D1), PNotIn(C1, D1)}, {PIn(C1, D1), PIn(C1, D3)}, {PIn(C1, D1), PIn(C1, R1)}, {PIn(C1, D1), PickUp(R1, C1, D3)}, {PIn(C1, D1), PickUp(R1, C1, D2)}, {PIn(C1, D1), PutDown(R1, C1, D1)}, {PIn(C1, D1), PutDown(R1, C1, D3)}, {PIn(C1, D1), PutDown(R1, C1, D2)}, {PNotIn(C2, D2), PNotIn(C3, D3)}, {PNotIn(R1, D3), PNotIn(C3, D3)}, {PNotIn(C3, R1), PNotIn(C3, D3)}, {PNotIn(C2, D3), PNotIn(C3, D3)}, {PNotIn(C3, D3), PNotIn(C3, D1)}, {PNotIn(C2, R1), PNotIn(C3, D3)}, {PickUp(R1, C2, D1), PNotIn(C3, D3)}, {PickUp(R1, C2, D3), PNotIn(C3, D3)}, {PickUp(R1, C2, D2), PNotIn(C3, D3)}, {PickUp(R1, C3, D1), PNotIn(C3, D3)}, {PickUp(R1, C3, D3), PNotIn(C3, D3)}, {PickUp(R1, C3, D2), PNotIn(C3, D3)}, {PickUp(R1, C1, D1), PNotIn(C3, D3)}, {PickUp(R1, C1, D3), PNotIn(C3, D3)}, {PickUp(R1, C1, D2), PNotIn(C3, D3)}, {PutDown(R1, C2, D1), PNotIn(C3, D3)}, {PutDown(R1, C2, D2), PNotIn(C3, D3)}, {PutDown(R1, C3, D1), PNotIn(C3, D3)}, {PutDown(R1, C3, D2), PNotIn(C3, D3)}, {PutDown(R1, C1, D1), PNotIn(C3, D3)}, {PutDown(R1, C1, D2), PNotIn(C3, D3)}, {Move(R1, D1, D3), PNotIn(C3, D3)}, {Move(R1, D1, D2), PNotIn(C3, D3)}, {Move(R1, D2, D1), PNotIn(C3, D3)}, {Move(R1, D2, D3), PNotIn(C3, D3)}, {PNotIn(C2, D3), PNotIn(C2, D2)}, {PNotIn(C2, D2), PNotIn(C3, D1)}, {PNotIn(C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C2, D1)}, {PNotIn(C2, D2), PickUp(R1, C2, D3)}, {PNotIn(C2, D2), PickUp(R1, C2, D2)}, {PNotIn(C2, D2), PickUp(R1, C3, D1)}, {PNotIn(C2, D2), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C2, D3)}, {PNotIn(R1, D3), PickUp(R1, C3, D3)}, {PNotIn(R1, D3), PickUp(R1, C1, D3)}, {PNotIn(R1, D3), PutDown(R1, C2, D3)}, {PNotIn(R1, D3), PutDown(R1, C3, D3)}, {PNotIn(R1, D3), PutDown(R1, C1, D3)}, {PNotIn(R1, D3), Move(R1, D3, D1)}, {PNotIn(R1, D3), Move(R1, D3, D2)}, {PNotIn(C3, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D2), PNotIn(R1, D2)}, {PickUp(R1, C3, D2), PNotIn(R1, D2)}, {PickUp(R1, C1, D2), PNotIn(R1, D2)}, {PutDown(R1, C2, D2), PNotIn(R1, D2)}, {PutDown(R1, C3, D2), PNotIn(R1, D2)}, {PutDown(R1, C1, D2), PNotIn(R1, D2)}, {PNotIn(R1, D2), Move(R1, D2, D1)}, {PNotIn(R1, D2), Move(R1, D2, D3)}, {PNotIn(C3, R1), PNotIn(C2, D3)}, {PNotIn(C3, R1), PNotIn(C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D1)}, {PNotIn(C3, R1), PutDown(R1, C3, D3)}, {PNotIn(C3, R1), PutDown(R1, C3, D2)}, {PNotIn(C2, D3), PNotIn(C1, D2)}, {PNotIn(C1, D2), PickUp(R1, C1, D2)}, {PNotIn(C2, D3), PNotIn(C3, D1)}, {PNotIn(C2, D3), PNotIn(C2, R1)}, {PIn(C2, D1), PNotIn(C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D1)}, {PNotIn(C2, D3), PickUp(R1, C2, D3)}, {PNotIn(C2, D3), PickUp(R1, C2, D2)}, {PNotIn(C2, D3), PickUp(R1, C3, D1)}, {PNotIn(C2, D3), PickUp(R1, C3, D3)}, {PIn(C1, R1), PIn(C1, D3)}, {PickUp(R1, C1, D1), PIn(C1, D3)}, {PickUp(R1, C1, D2), PIn(C1, D3)}, {PutDown(R1, C1, D1), PIn(C1, D3)}, {PutDown(R1, C1, D3), PIn(C1, D3)}, {PutDown(R1, C1, D2), PIn(C1, D3)}, {PNotIn(R1, D1), PNotIn(C3, D1)}, {PNotIn(C2, R1), PNotIn(C3, D1)}, {PickUp(R1, C2, D1), PNotIn(C3, D1)}, {PickUp(R1, C2, D3), PNotIn(C3, D1)}, {PickUp(R1, C2, D2), PNotIn(C3, D1)}, {PickUp(R1, C3, D1), PNotIn(C3, D1)}, {PickUp(R1, C3, D3), PNotIn(C3, D1)}, {PickUp(R1, C3, D2), PNotIn(C3, D1)}, {PickUp(R1, C1, D1), PNotIn(C3, D1)}, {PickUp(R1, C1, D3), PNotIn(C3, D1)}, {PickUp(R1, C1, D2), PNotIn(C3, D1)}, {PutDown(R1, C2, D3), PNotIn(C3, D1)}, {PutDown(R1, C2, D2), PNotIn(C3, D1)}, {PutDown(R1, C3, D3), PNotIn(C3, D1)}, {PutDown(R1, C3, D2), PNotIn(C3, D1)}, {PutDown(R1, C1, D3), PNotIn(C3, D1)}, {PutDown(R1, C1, D2), PNotIn(C3, D1)}, {Move(R1, D3, D1), PNotIn(C3, D1)}, {Move(R1, D3, D2), PNotIn(C3, D1)}, {Move(R1, D2, D1), PNotIn(C3, D1)}, {Move(R1, D2, D3), PNotIn(C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C2, D1)}, {PNotIn(R1, D1), PickUp(R1, C3, D1)}, {PNotIn(R1, D1), PickUp(R1, C1, D1)}, {PutDown(R1, C2, D1), PNotIn(R1, D1)}, {PutDown(R1, C3, D1), PNotIn(R1, D1)}, {PutDown(R1, C1, D1), PNotIn(R1, D1)}, {PNotIn(R1, D1), Move(R1, D1, D3)}, {PNotIn(R1, D1), Move(R1, D1, D2)}, {PickUp(R1, C1, D1), PIn(C1, R1)}, {PickUp(R1, C1, D3), PIn(C1, R1)}, {PickUp(R1, C1, D2), PIn(C1, R1)}, {PutDown(R1, C2, D1), PNotIn(C2, R1)}, {PutDown(R1, C2, D3), PNotIn(C2, R1)}, {PutDown(R1, C2, D2), PNotIn(C2, R1)}, {PIn(C2, D1), PickUp(R1, C2, D3)}, {PIn(C2, D1), PickUp(R1, C2, D2)}, {PIn(C2, D1), PutDown(R1, C2, D1)}, {PIn(C2, D1), PutDown(R1, C2, D3)}, {PIn(C2, D1), PutDown(R1, C2, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C2, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D1)}, {PickUp(R1, C2, D1), Move(R1, D3, D2)}, {PickUp(R1, C2, D1), Move(R1, D2, D1)}, {PickUp(R1, C2, D1), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C2, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C2, D3)}, {PickUp(R1, C2, D3), Move(R1, D2, D1)}, {PickUp(R1, C2, D3), Move(R1, D2, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C2, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D3)}, {PickUp(R1, C2, D2), Move(R1, D1, D2)}, {PickUp(R1, C2, D2), Move(R1, D3, D1)}, {PickUp(R1, C2, D2), Move(R1, D3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D3), PickUp(R1, C3, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D1)}, {PickUp(R1, C3, D1), Move(R1, D3, D2)}, {PickUp(R1, C3, D1), Move(R1, D2, D1)}, {PickUp(R1, C3, D1), Move(R1, D2, D3)}, {PickUp(R1, C3, D3), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C3, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D3)}, {PickUp(R1, C3, D3), Move(R1, D2, D1)}, {PickUp(R1, C3, D3), Move(R1, D2, D3)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C3, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C3, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C3, D2)}, {PickUp(R1, C3, D2), Move(R1, D3, D1)}, {PickUp(R1, C3, D2), Move(R1, D3, D2)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D1)}, {PickUp(R1, C1, D1), Move(R1, D3, D2)}, {PickUp(R1, C1, D1), Move(R1, D2, D1)}, {PickUp(R1, C1, D1), Move(R1, D2, D3)}, {PickUp(R1, C1, D3), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D3), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D3)}, {PickUp(R1, C1, D3), Move(R1, D2, D1)}, {PickUp(R1, C1, D3), Move(R1, D2, D3)}, {PickUp(R1, C1, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PickUp(R1, C1, D2)}, {PickUp(R1, C1, D2), Move(R1, D3, D1)}, {PickUp(R1, C1, D2), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C2, D1), Move(R1, D3, D1)}, {PutDown(R1, C2, D1), Move(R1, D3, D2)}, {PutDown(R1, C2, D1), Move(R1, D2, D1)}, {PutDown(R1, C2, D1), Move(R1, D2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D3)}, {PutDown(R1, C2, D3), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), Move(R1, D2, D1)}, {PutDown(R1, C2, D3), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C3, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D1, D3)}, {Move(R1, D1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D3, D1)}, {PutDown(R1, C2, D2), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C3, D1), Move(R1, D3, D1)}, {PutDown(R1, C3, D1), Move(R1, D3, D2)}, {PutDown(R1, C3, D1), Move(R1, D2, D1)}, {PutDown(R1, C3, D1), Move(R1, D2, D3)}, {PutDown(R1, C3, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D3)}, {PutDown(R1, C3, D3), Move(R1, D1, D2)}, {PutDown(R1, C3, D3), Move(R1, D2, D1)}, {PutDown(R1, C3, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C3, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D1, D3)}, {PutDown(R1, C3, D2), Move(R1, D1, D2)}, {PutDown(R1, C3, D2), Move(R1, D3, D1)}, {PutDown(R1, C3, D2), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D1), PutDown(R1, C1, D2)}, {PutDown(R1, C1, D1), Move(R1, D3, D1)}, {PutDown(R1, C1, D1), Move(R1, D3, D2)}, {PutDown(R1, C1, D1), Move(R1, D2, D1)}, {PutDown(R1, C1, D1), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), PutDown(R1, C1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D3)}, {PutDown(R1, C1, D3), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D2, D1)}, {PutDown(R1, C1, D3), Move(R1, D2, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D3)}, {PutDown(R1, C1, D2), Move(R1, D1, D2)}, {PutDown(R1, C1, D2), Move(R1, D3, D1)}, {PutDown(R1, C1, D2), Move(R1, D3, D2)}, {Move(R1, D1, D3), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D3, D2)}, {Move(R1, D3, D1), Move(R1, D2, D1)}, {Move(R1, D1, D3), PickUp(R1, C2, D1)}, {Move(R1, D1, D2), PickUp(R1, C2, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D1)}, {PickUp(R1, C2, D3), Move(R1, D3, D2)}, {PickUp(R1, C2, D2), Move(R1, D2, D1)}, {PickUp(R1, C2, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C3, D1)}, {Move(R1, D1, D2), PickUp(R1, C3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D1)}, {PickUp(R1, C3, D3), Move(R1, D3, D2)}, {PickUp(R1, C3, D2), Move(R1, D2, D1)}, {PickUp(R1, C3, D2), Move(R1, D2, D3)}, {Move(R1, D1, D3), PickUp(R1, C1, D1)}, {Move(R1, D1, D2), PickUp(R1, C1, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D1)}, {PickUp(R1, C1, D3), Move(R1, D3, D2)}, {PickUp(R1, C1, D2), Move(R1, D2, D1)}, {PickUp(R1, C1, D2), Move(R1, D2, D3)}, {PutDown(R1, C2, D1), PutDown(R1, C3, D1)}, {PutDown(R1, C2, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C2, D1), Move(R1, D1, D3)}, {PutDown(R1, C2, D1), Move(R1, D1, D2)}, {PutDown(R1, C2, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C1, D3), PutDown(R1, C2, D3)}, {PutDown(R1, C2, D3), Move(R1, D3, D1)}, {PutDown(R1, C2, D3), Move(R1, D3, D2)}, {PutDown(R1, C3, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C2, D2)}, {PutDown(R1, C2, D2), Move(R1, D2, D1)}, {PutDown(R1, C2, D2), Move(R1, D2, D3)}, {PutDown(R1, C3, D1), PutDown(R1, C1, D1)}, {PutDown(R1, C3, D1), Move(R1, D1, D3)}, {PutDown(R1, C3, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), PutDown(R1, C3, D3)}, {PutDown(R1, C3, D3), Move(R1, D3, D1)}, {PutDown(R1, C3, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), PutDown(R1, C3, D2)}, {PutDown(R1, C3, D2), Move(R1, D2, D1)}, {PutDown(R1, C3, D2), Move(R1, D2, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D3)}, {PutDown(R1, C1, D1), Move(R1, D1, D2)}, {PutDown(R1, C1, D3), Move(R1, D3, D1)}, {PutDown(R1, C1, D3), Move(R1, D3, D2)}, {PutDown(R1, C1, D2), Move(R1, D2, D1)}, {PutDown(R1, C1, D2), Move(R1, D2, D3)}, {Move(R1, D1, D2), Move(R1, D1, D3)}, {Move(R1, D3, D1), Move(R1, D3, D2)}, {Move(R1, D2, D1), Move(R1, D2, D3)}} - Next state mutexes: {[{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D1), NotIn(C3, D1)}, {NotIn(C1, D3), In(C1, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C3, D3), NotIn(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {In(C1, D3), In(C1, R1)}]} - -Level 7: - - Current State: {Place(D3), NotIn(C2, D1), In(C2, R1), NotIn(C1, R1), In(R1, D1), Place(D2), NotIn(C1, D3), In(C3, D1), Container(C3), In(C2, D3), Container(C1), In(C1, D2), In(C3, R1), In(R1, D2), Holding(R1), In(C3, D2), NotHolding(R1), In(C2, D2), In(R1, D3), In(C3, D3), NotIn(C1, D1), Container(C2), In(C1, D1), NotIn(C3, D3), NotIn(C2, D2), NotIn(R1, D3), NotIn(C3, D2), NotIn(R1, D2), NotIn(C3, R1), Place(D1), NotIn(C1, D2), NotIn(C2, D3), In(C1, D3), NotIn(C3, D1), NotIn(R1, D1), In(C1, R1), Robot(R1), NotIn(C2, R1), In(C2, D1)} - Actions: {} - Mutex: {{In(C2, D1), NotIn(C2, D1)}, {In(C2, D3), In(C2, R1)}, {In(C2, D2), In(C2, R1)}, {NotIn(C2, R1), In(C2, R1)}, {In(C2, D1), In(C2, R1)}, {NotIn(C1, R1), In(C1, R1)}, {In(R1, D1), In(R1, D2)}, {In(R1, D1), In(R1, D3)}, {NotIn(R1, D1), In(R1, D1)}, {In(C3, D1), In(C3, R1)}, {In(C3, D1), In(C3, D2)}, {In(C3, D1), In(C3, D3)}, {In(C3, D1), NotIn(C3, D3)}, {In(C3, D1), NotIn(C3, D1)}, {NotIn(C1, D3), In(C1, D3)}, {In(C2, D3), In(C2, D2)}, {NotIn(C2, D3), In(C2, D3)}, {NotIn(C3, D1), In(C2, D3)}, {In(C2, D1), In(C2, D3)}, {In(C1, D1), In(C1, D2)}, {NotIn(C1, D2), In(C1, D2)}, {In(C1, D3), In(C1, D2)}, {In(C1, D2), In(C1, R1)}, {In(C3, D2), In(C3, R1)}, {In(C3, D3), In(C3, R1)}, {NotIn(C3, R1), In(C3, R1)}, {In(R1, D3), In(R1, D2)}, {NotIn(R1, D2), In(R1, D2)}, {NotHolding(R1), Holding(R1)}, {In(C3, D3), In(C3, D2)}, {In(C3, D2), NotIn(C3, D3)}, {NotIn(C3, D2), In(C3, D2)}, {NotIn(C3, D1), In(C3, D2)}, {NotIn(C2, D2), In(C2, D2)}, {In(C2, D1), In(C2, D2)}, {NotIn(R1, D3), In(R1, D3)}, {In(C3, D3), NotIn(C3, D3)}, {In(C3, D3), NotIn(C3, D1)}, {In(C1, D1), NotIn(C1, D1)}, {In(C1, D1), In(C1, D3)}, {In(C1, D1), In(C1, R1)}, {NotIn(C2, D2), NotIn(C3, D3)}, {NotIn(C3, R1), NotIn(C3, D3)}, {NotIn(C2, D3), NotIn(C3, D3)}, {NotIn(C3, D1), NotIn(C3, D3)}, {NotIn(C2, D2), NotIn(C2, D3)}, {NotIn(C2, D2), NotIn(C3, D1)}, {NotIn(C3, R1), NotIn(C3, D1)}, {NotIn(C2, D3), NotIn(C3, D1)}, {In(C1, D3), In(C1, R1)}} - Next state mutexes: {[]} \ No newline at end of file diff --git a/PR_UPDATES_GRAPHPLAN.MD b/PR_UPDATES_GRAPHPLAN.MD new file mode 100644 index 000000000..840568fc3 --- /dev/null +++ b/PR_UPDATES_GRAPHPLAN.MD @@ -0,0 +1,57 @@ +# Improvements / Necessary Fixes to GraphPlan in AIMA + +## Fixes to the double tennis environment + + - Original env used `a`, `b` in goals rather than `A`, `B` as defined in initial. + - IIRC, `a` and `b`, that is, lowercase variables, can be satisfied by any other variable? Hence, the test still passed, but it was probably not the intention + - Environment failed to search `LeftNet` because it doesn't show up in initial or domain, only goal. + - Original env: + """ + return PlanningProblem( + initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', + goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', + actions=[Action('Hit(actor, Ball, loc)', + precond='Approaching(Ball, loc) & At(actor, loc)', + effect='Returned(Ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + """ + - Note - this passed the pytest manual tests, but not GraphPlan algorithm natively (although that was broken in general ...) + + +## Explicit state and action mutexes + + - In the original implementation, state and action layers, as well as state (proposition) and action mutexes were jumbled together, with no differentiation. + - Technically, I'm not certain that an issue existed with this presentation, but it doesn't follow any of the learner-friendly material on GraphPlan that exists. + - I repurposed the `GraphPlan.graph.levels[i].mutex` to refer to action mutexes, and added a `state_mutexes` attribute to refer to state mutexes. + +## No Interference Computation + + - In the original implementation, I don't see interference (one action deletes the precondition of another) being computed anywhere. + - I have added interference explicitly. + +## Linearization Error? + + - TODO + +## Level compute/expand issue + + - In the original implementation, mutexes were computed after expanding a level and performing goal tests. Therefore, the goal test would not be able to test the goals until one extra layer had been expanded. I reordered the `expand_graph` method to expand a layer, and populate `state_mutexes` before the goal test. + +## Extract_Solution Issue + + - `extract_solution` is a method with the purpose of expanding the graph backwards to the start, identifying subgoals for each next layer, and selecting a set of actions that fulfill this layers subgoals, proceeding to the next layer with the preconditions of those actions as new subgoals. However, the authors wrote this implementation with `itertools.product(*actions)`, which chooses combinations of specifically one action that satisfies each goal. Unfortunately, this is not satisfactory, and certain combinations may not provide necessary support for later layers, despite not having explicit mutexes for these dependencies. + - I have replaced this with a full recursive DFS backwards search, with early exiting. This is required to make it efficient, as technically now this backwards search is a Cartesian product of the powerset of actions, which is 2^(2n) different action sets to test (infeasible) + +## Added debugging tools + +## Added actual GraphPlan tests + + - Currently tests exist for environments, with hardcoded solutions encoded to verify that the goal state actually is achievable. + - However, there are no GraphPlan algorithm tests (?) + - I've created a pytest file and added it to the test dir to improve reliability (and for my own debugging) + + +## Separated Environments from Algorithms + diff --git a/cake_example_graph.png b/cake_example_graph.png deleted file mode 100644 index 8f95169a6929120819816b42143cd46360d25035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100204 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𝔴LcA%K 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 diff --git a/cake_problem_graph2.png b/cake_problem_graph2.png deleted file mode 100644 index 28d2420e1aaa2de92fc4d71167ef5b8123ce5c36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100010 zcmZU*bzD>X{|63EmgcC|rJjA*!zCxXNS8tPd{j_;$HF zUIh3l-v^H zt^VKN{?8>eVIb2*{?`$C0oa#J|G$p|m!cS!6zHogOO3N%hoJqko&R(5e{NK0E%`)w zt9;2PRv$X5FYyG!`~Q6st6PwmsG1j}x&ePbqUO9pEA9V%*j#pSXNO)}k34=&0~6tc zGX@i)y3fxEGv}5*C(SGj=jW&L=UMm_AA;E#e%q(v0}pek%n}V4c>Z(z%=whBJJOVJ zdw>2)Fi0mB#G^|WpAw{~4^4)*hb$z3Py7U-g!l8Pqi)iLH=(f%)DtD_xdr7&Q}+}r zr2Sk^*|qR{*Jo4PsXrqePw(1H*rkO|_Uw2CF}aw-s)f#c&bQC4eRnu52F5qHeQ*)y z{k;yKOG?l24d=(tpmTu~Cp!3BV49C0lh3-K;A!&Sb6o0q$z|1y-?Tp@UkuHoIH6w* zLan0h9DH-RBqd9KvK2^@SS1u=?!R!bH`K91F?47@EiVhNYQnMVK7ndKfJ7P;=WY#4 zn?oRZ^~{n)+KFBbF=azhqlQ%umz=7$xW5{1nPKUx`nUL+-_5!N00Ym+rTRNvyF zdnN_7jZHK^4ptpC2`r341?Z!JrMOzqV;S@SCcuONlt%~#QM8a&Gw>ETM1T9i?qwgH z*}t^UY8#zDh%CkG>_dNC$-e<^d)ycJ_CW8e1` zqnYI!Xx{ve-e&iL`%;Z>YSbRYR}k{91C#A>mnq7GnpB>Tlyj9F^k{(iAdjGh3Pm5E zuCQZ#@CE0s69o&JlWch^!#=HkWOKf)oxV?(O!l#E%mVRt%Ft7=zj9TpU+V%YzF=1y z953*sWO|N)(YGOucq2N?W0QeXlO*0j`~Zr(OoidmfUQr;4gFSIM&Qe(+YuM|9$8So z_HL4!4`_T8v@jlS7i~jHM`sspQMf~U6HMa=qTySNs}*_Ynv#8_R_5-sVShrrPn{ zjL0sY-~)H?Po`tKcHQ&~cC(9%4&_2%m(jMRf}iu3CFx@4 z5r=`&7e~b_V`?gIkAh~zLz&m3#O6EsAiP(=ggt?C2MfRZQGZ7WNOlZh;W>VmFs z@-8ZC6XpaE6OO<}sFGv-Wyqf`@a|HDL=&Fne3wO*A9nuIo~{hWz~(nEt}sg+(NCb8 zm0=7HgoznKIg?|z5T49_7pKDF<>aI888!agnGcdg174=(5EJ6FiME*QmEUUyvFX~_ z8+t7G9){n$rZvI0)kE7B;2cqQ!(Z{WqP^i$3BxH{e15%2g3LY@>mUkeSc1$=O&S(= zU*tO5Yh<)ovhg6!_6Ya`W9S`k>C;IQta8+K)yT`GWY^NUcF?7F9uE}ob&0RW=s>kE zLZ19yhfQlptz~*USSmXDQRt?n?xff?UB*byoI+xN>d<7zI`$(`T+0HR)U8_LTG4N8 ztb()q)<}vYYxToKfrh0GOQ)nR(a|b+^6lBD8}>^mcqcC>fKG;Hpn|wXUFa$K@X0_c z#~@S$H~GG-(NEYxe2~h8)90upwM@f%4~aSL^YQjrWMdg)K1c(XsmRP<$I$n=DtoL* z&x{e)QVBnWNG{bY8ro@J+vQ>;^A=g;$(AVOlvFShaYC1F+eS#te>@WR*%!BN4!nv1 zO26S*e}wn%q~&~cr`ES%P!`J1WS|`;*2ubja4&6N{-lwroVMYl6;l-9W#zHs&oar3 z{S{QsC4Y*>Fm1c4oE=p(Os%>a8&m&v3s@{F&=V9`?$^eSD7}P3n8#Hw+p?S!8znsH`H~x{b%X3!ABjebkJl6rocI&nJ)Ixu})e_Uqky`P8?Z#Y%gT68&yklw01 z0{&c)8t`jdPi^mSIUzoD{n;5Ed~Ov#%zo={ImB6dY}X+soJaH~G<>jw z%F8PVL5%r@Jt{iN$$ovpsgn^2)ehC9LkK9Rk<@{F*+M5WQZ=9PN`V)~^6YDJeTAC^ z^wIfHf%gzy1C2DZ5i*b_!?hz{Pm`NgdPU>pb6~J@>(vx@LQ0XbHeeNrKOo<*DEXu{e2k~7mm7zITD5M zppU-i9C0Pt-S<%+tKb@`9xfYa_SozX(+!Tlz7t}A`)a%S z%9B=L1HVLq7DGK9z>%i*G~6_z8m>*$Sn`!H8>bBK$A@2O>wd_tNcOF9RjfphjCG^+#n#{w%n(0z?aw+hP=+1f~7x z!Z)964wh?FRH1@et_pq6&u@W&q8JVHMz2)VALbpcYc*7R0h`5|2yo8$;QM|$$u@%8 z)J#6OUCg}#H}wV#dWWNL?}B#^y|lgv0*wX-%293V-SpknZU^7VYV=Ms z3!%`U50}$`&2jn0qxTaJOuci>Xe<9Pzf(HJy^)g!+>*et%19_Jmwp>rgV39dJFtdv z3l-7$dQ&ZNi%vo1S&9&WJCIyXaL1ijY#uZWCVk}L;fHqocr?lOFhA}h6+O~W7{kl)-jnNAFd=1FpKpaYX% z@C#H*@6vh#9bJZwHeGpAyGUr4C)l4K4Zm3ic8^0tI_j6~NLB9;0YGhaUI4V)dOXvj zFpQRKn4rwKBXEmBq-j5d{(zo#l7X#Kv+$mTLWRGH@PpG>OTRbi@Rw+DJm0i7YZi`J znkKAlgsrSes=jhFM`9FJU8e>9Mo;W(iN_gR#K}rTP8ytJN4%O>w$BOMXFu~0s*{_3 zX5FDGKP%Cq!@TQA(FHI>_lYqX?UmsR;9Qm5m7ygzmeWV))5D&#>NhqRizzya@AVPK zQ4W%{nm|P|Rt~>!TxFFZpqHQlt=l&2Vb?9JhTdUAgg4OezK3D&L8;VEE0cB~7hb-* z)Z-j52-{Ba*cywibDd4(6FsQ{ddb5%64NcIV!dw1qy=b?a`;2}C0i}W<0*tKjdcF* ziCkBuAkD0~u`u7eJ9gx`LP}9wnzfhTgbKM0H_<)aevb(Pq1i)dZkr%OAv>3YuQJ!{ zF2?1)j%2qmnSpIv+c+kAhbZcc^6EzOwnlAWf)a-Y4qNPPlf-bl@yaZnv-X^c-5pQX78F6RJ8A52^s=3iF~ zwD!hwYJKUB*2AV0ZM>Y2JKG$TH+A|JZ_lGHxADUyf%-$9N9b)|8eP#gS8A<7_dnxO zakHScF3#lg_x4-0-#u5;gN{aidqy;UEF-D@{f&Rf#&dzOf=7Qh7{Bsjk)sq|aOU=xtIIuQ9x*P--B_3`~sC>)&pXl#iT zH~;St7XCWlLNrX!0&R8AQIQ5`l2Ux$L|gxhmX`*vPv_KWDx~pB=a+e=(8W6*kCSin z%Er@(?;v4o&BQV$2JV2Kvd4AKbFLM8ep1!_I)z&nx23@_LnSv0o3UM|1@1#R(Vz^vg*X&O4WKFm& z-u9}~P9yj@t~KvdZTo`Pjs3P-8LqYcEAI3C3!H;=Pm~k!_H*5}hqkdqRw_&`;;`)y zS5sPdG@he}d8cIwFVr>KXPQ^l--{;fEo-Li#eADe-u7IP#z!%APIJ>VGTpBWbs`G^ zStfw$1?;bmDTmoUrK?IoSL`61Q%S94A{{9h1qP!%gi|wl5EMzNxJ52ZjsgCi{8eMR z8q)r^KKXy;L}dS~1?&pCdTqE4m!y;#?8YEIKR*u!<+PDfT#3w#Q`)Vss`0euCsn&ewJK=L+V>9^4R`mY(39uJJeCF z_RxLT{GmCvT%(|^nUy89IO5Roe#9c0PZ$?nJZZAKKQiaEfKSauEk&IZ1MzS45W`(;<97Bd4Q|$x};Q9w>N+EBo}hO_Z-j#y7R6PkRwIEC3g%cAz~juc*uO zsff*tV04qw{lnBdp=lv#VYZmbSFSwITzQo{%5-Fo0o++Fv~i}}kb1VrC0~Vamd7bg zSY#z9Q0q!##XLIB(i+RsioU35xWV{lcfT3hOBnVTGbw$}Gx|N5M;@^qiHIn0GvR`z zQgoc!)L@1iU?!_l>3^MDADJc58;FTD@@CIWy0uGB_t!q@eR2&U9HR*x{SIZ_HyIxH zsSJI+!OEB>;I*cj=p1_N)_vXk_0xbJ4gt?OiZcyJys3W{6mt~3f{R~6rKgEDhoxc{-`9AqC&V&4w%IpPyCxL8PY=4B!#Z;l$ci(fQZn{O+ zC&D_A2SKnqUY*Q*`SX-NuKxiQ>X7cPiAcqQOBa?NANzIyKzzi9VkBJFG+B+p*)1Bq zZ5ChyAa*edXw9)cONGSO-*cy7l2k~E%QZUz0+V!*9eOYv6bh35w%Qe^<}{Q6Ocw+6 zkyt0)nCf@C=;dWnygC7SkoqZOzt8)q6~V#=!}GIzQ~m zLX)d7O$(87`+;CsM2V8XM4`R##_;%46{aB{;aMXSa!Xctjgla$ z2a~Z`!EIm5UV?!uEzv_qDgw7aDA@0Xo8YkwCDnwIkS|x^{ru zi^5AZ$bd-v%OoPzDCqXCcCb{Di|NRuDQtNeTZ*((bkaz#gJ>bI)CcZ(N@MdK#;Xvf zucThvOh>h|Jzrja~zVdwiGfcU#?Y=;ML5)IomtY4uCO{BmPo_=#}xB1C(Ij&?EC zZ^N35QBk~h?rP%T9px>c<92y}JBJ`DmG-^9YE;pYw?#WgO0vNWHYady&5YB(CIk0> zh7{Vr1=Kn%sDubqyRmk$A46tI7ojFuba?tQn!g?GWZpVjCg<>C#*EJ-xp(EOP+AWG z8cr{;Lswy}D|t;byhuzb$0w&7kP_mAM(?M-Io6vaDpUod*Wl(b>|dW)MJ`mkt-$QIm#|26r~fa$sm!MAvAm9!PMkzR_*<5VR3K0 zknrmfr6$oYiW4)>Lx0I`*+x_vg!ZIv&y(0>={S7^(??JCY5dfoY&ym_1sbd&+g zicom9C>enqrtO1zn!V{D=EE_7gfL|VUe+V~@M0o@1Vq|J zFMWZDS^JvC!^g$jo%PhbTK5`(%eGx+&ZaA-05)r@)qov3lR~3!%0>*6XyL+m$V(*O z!!>5xQj%_FHS-KSUTQ?A9;|2R(i|rKwh+wNCb=%hxv%Ql zJBb?!i=*PNnOP6Q@@YlURZ||PF^z!G2dEXf_N!*@(-j|v727&q0Km*UgbO{OEKjd7 zkU4g;`{O1~>HaAi)pWhf*8~n~%C}t-2MyQA za=QFXmABSu%7=eaJ5hL!P;BZmJ9OOcfy*i$YrkiL)f`?NI_ADOqq*>5GW;74yN)h z!FZG56T7{2PKGHA=6c&t$@h>ERtaOu)8${Wri@rh|02Z}!}1eAXA_u~$Go9bMULni zC#AgrIPfqqrg;_}OI}-!scjHD(0-4tx8vFPNd5504x}vi99_wCVzYB1+NG2Pe>Bl%^a2#bqJ1ImFy9z=a}+x1FKzCxpi>F|4tS(wNx!4Fr-=YV&5XU__o z@v<#xFp7C?NJ4RofWiC{HhEPnhOPH9TZ&=QCegHWQODeF4Sgn~=PcmM~fBCx9<548fRdWhGTgp@N zk(E2shLL^Tw~|hU3~SK>sk?6{cY#_Ckf@H5!%tZ4inBG=#5ix^-x?(S`^)}yZ(UHN zVCXLcxEPC|ODodSxWmD1 zP0fD39afgN$$iu)=$?iTH5M$lRQ9Y;9A|Q9>(uC8QDxyiSA3Bnj`XO=qo2Yz>wS^k*^$mg9k7)hZ=63n%F=B zkw?~lzCE!x%@D}Ub+!z#q)UA}M!C28Hd=0Ye6x={+wI~O@2JnaC?T0)HKJuUkpOa% zs(MK!yoCv{G&mc_CprpaddT-1b*A?|FTdhym&l(A(=!ZQ8Ri2It2IZ%n9(dxirA9~BvhxjG?ck5 zgTExINeqyVmD$0*7riO^3z9zt8#(6orbxjb&oopG_X!#*(X#`SWv;NoXVT zttY*$^%0joG*T`k8<5DYdx5WwK*Ea0-ul?Q9yk+I$UE;LTPClNn9_C(kcTy#a?bFo zrW#i^QRgw>}5b@?Xf#LXb?JFbl zEID6KBZ9Z~;G2MTzB{&js)BEwmBrH(EuhgT40&$%P*TtY*-a`eF(0U!kN);h+LtRS zvmXP)hRfF8t^nS#B-)B=Z7+gTyI=Wc(LCy|11l_*v7=(Qk>k9rG17Do(hWMOk~Hq{ zl0Ky(pl6L0p#N$C(_1LP3Bb<14gfNRHlzh!zRmwG11+1nj9XBjJW2S8 z&J1?=Z_fr0!>2swS4ZyTeo`J~yk<_5%THVz3j&SoX}#$Y*ELvW;8K0saW`32eD zUR-%DL%p?2CP2;Xb!+=xF^~5wvbLBTK=j4fhpzhk|f&QI-Bfk(r14pFTfIneO}b7Lu0?NMT>6SGK4g(^X8|^3N{%6IC!ww(}*F`;H_P+09j$7e%3e#rCe=YPgjid>4{S4{>dI zH@*5oNZc19kK0+crZzGT(D^%7@iGJ?ol7%!2p{>Y4N{-XV13B9CFoSwyLPXfh*~j3 z;X$4$68>{yHzvZM{{24@3~frtuNlhM+x)JMe#{yJKF2$0{*d*sLPz=K0OqIX*2a+M zyE=&=F@Il&F#0TQ-2OH)RALtpN`TKB-je|2EBeK3y~k~LXA#b%+yYMFBcm=eUdPL( z_bF~uu(|F8aC_$$dj5SqFoNZhhDLCN$eUAZ7YF=e5?DF59 z)JmQs+R1;XH_CcQDVz)kZ*-4*wqbeV?v*04G?M~QwhczhOp^s;t6^z>Dp(+*r}{+^ z@kMrt)O&4HDI_jEmp%`j*%DQRx^9-m@?>w))>S7^!<>PD?=TL01YWnqWB0Oi*}0O7FF?_KNb1ps?xm8jf#TVVEVpuUKVMr@wfCbEPC z3q(<7S}3?In7OY5o9_jDcmCHLP$K^xsMc8$S)2U<&&bUFW3FVUXZt6t$^70zub-9i zLULumRr;*`jZxkg*6INW&`Xc^rW`R!Lg zRZ}qCT+zu~!lghX%B=qlnHYH0h62HlS8pFYq}io8#KDpm^D+9l<9VFm(94Ok5K^m4 z^gP3leP`%Mb6y2~)%z0`qG{~V)2xfheA-JRzHf*ShWWhG#F9t=ovb@Gv*B)s06&_y z43KXBq=HbdR}`Z28-ljr-&I_A7aKisuWeO_Y?mYrk;Zfm{!$se$3MhcPe-K9D-PA8 z>zU_mOXQ9H`+1Vo7R)X8-_Ko*=_11^oRfG9<~RVT1>l59fR32b2+1s5F^V+Wd^X>t zJIDUs%RVNvW+3|DM1)|l^ly$R4^3K~sF z{Gyzf>33a!JHPB{u|1T1EeO;WW&G9+6>P<9yXPE15R;sUHv*$rF;P3vslIM?&%F-n4 zfH+mhzxk(PAYqfVNTq~^Z3(8u#Hf+e_%xQ!`4WB!u)?IfUiA*x4huQ>In7MiCXT=O z3499m*wHX3mQ(xS@1cF~ke2=Tl=NN$)4}S|hpRV~M%JvK1!CymEZ;R95P&7rGdz@N zTrxX(EI%>U%c)JQOSvE-t%XPxCHzyR;y@4UfY*|^2Vu9M)XA!hPC&rf@AC+tJSe2;w0pP(C0B$GhKLED=PYTSC(LODBYD*IJ z$hd{m0)DaX`{ww@N7VrqeTQdXG8yY(Rp{X*#YFrXi1C_;ZOIzyR-BsGvBCMFLD()& zJ#lSnTM-{{6t7h#@NXgvm9U69(&ug)@FA@D91T7Wyk-2(V+CDq)o}HaSF~E&z4ISb z=YsAky1>?(N4+7&Pg=Jcvc3M3I-7_Dg=$662}K7Qj2>61FuR#ZV^=ezq0YabPRRnl zb;-s9JW;0^4>&#jD4}-fV0gk|E74yjZ}B1q3joF8IAQSE`p)AQPQZN&-xIYfviMh- z|B1hi%1Q2Q7@Su#!r)}|sz6>sV;oS%4~_u$xJ-8Lvc{_2tRJ}CA0qXGNy4#lM}7^a zv2Nd_!0_cbV&@~{*51kWWq$Bd2UvN0hYHb>noyI}`*Vq@GBHDZ@9HrMM5R05?B^(x zprN8M?wKU0&CDgUbJ$GOcYDv<0Tl*=*6?=NW+b%B9Tj0r1w39!AB`Hvx;mT}zil)UZt%r`K=bM|T)S#&ZU zKAl!#-ivg>SQ^yeH_hZXW}e%!?Mhx6qt&8sP*&13=d0kG zT(b|3fz*QegxB%Z1P~qQu~E}oU>GrH6tgndsu>>|f06GH>yl@wmxBQ~v@9O*h;$=@ zO4^w{N^|rNvtmn$8 z@#fLyg*>+o0VNV!QsTnn)_>~r-@R@0K7<|Vm#Egz+_}p1ie6&{c#H8F{M1ZYNh*F5 zUwUkNeq=jA^g_!Q!llcJ_Vd&sV;Nc|(O%Hkx zt0$oZ9sr`EpriRY`pR1_Q~05ifBH7DtG)~d!3d$xqnD2zIb4(8(LF_f=wc-h4Nky= z)GF1gTYrIB67X^JSmH4lgUFrCx&Ur-d7tO9NZ2liPc(sAe9yIrUN&DeGV}aFl<@Sy zckwb7!cI^kjy%_M0EIG}Jhe8+>NWiE?F?gZ5WBB&exQL*=UmHw6B1OgMZ9u?ae60^ zptnI}$w$C0Ehfr{JqtSH{8a9`rd{Bcs|r+ki2D8Hx~om=WGo#y%s6yQ(Dl!sGhzE8 z3d~X1y|{+SiST+S6cu>ITg25jHuyQ?lvbSG^m~Wwc zA29L-3N}zbH#(?&%?qdBT5RkUpRz_ZhOh zEdS3G2ZJO~+VjF+qS0wL$SLpeH%DEMRpSbupH&6dQ^?MLWE;OOa$zZ)B;u5OU)5~29#E+_vZ~By zuUC(EUIRC+e$uqyKf&1gOlah;4F1;fm`m>)y#+5m_^Y^f+zzd(U#z$I7p(bU}+nCuH`pro6vPgC%j6n%m z#6>x450(IgPc0kLW<;vjkp*0BE@Q6cb0ZfM;ZF1M&w7Dd;NJmVUoKLrXr&V4b2cYJ z*NW|W;-o-;MV4s#-v$zmdv#AiARDrxB=F3^H=nLbl~$9V4xc!Bdh z0lf5^gG^AR;f}iGI2T;6stI-LZG%||A_EVr?&pJSkto-Q-I*|c0gs>i2wEjQfl1(h z)5+6Mru_-<0^vzwuMXI5dWV{~OMCbFpT4va26$ALEu+7E7y5BAP?2Nvchu86De2;& zF!Ik%M#@Pt@SBYh-Uk^+ja1%+XdV`*JsgIY38()3$GqYS!u9ePM;2|y(5RRCZqyKS zeu+7KaIx5kX=1H)0cN$KLBX>maVl395csyZIznYl(;ZtjO~#beLq`-frF9MDh>J5R zLHP4GG-ww4Gj(G6sJ!Q%sfEF5r&hvDhUra@+pp^In-P{hKy5r9cKeYZI%oe3gFOlX zDCN;upLe;zejAdQBEp}U%7dJ8bf&V?kCRqpvhcuO-V`mpnxc|Rw-mZdOaiEKHLrgK z!~)AsN-NYXIgx#}`Z*Jmpd$~(6UM4+|J4FsvH>CNUcYSbKgdS=2}Ce~?(-xNvSbT< znRuo;aJA5+`T{R^JPvm8>^O(YYgK6iuzOKQA5~<&%HrmzY=MmY!dbIss74@X3(*$s zIW!7{vTYOH<{BXQG!rg+Ga*aW?FY`p*eGsA-lrfVr!~}6`Dg~n z&R5hOPuHyYpMBEs{5nD_)W(}}NKBSSs1EE)PciL=wy?`4r+?%GX}akPxg>O=j;?)n z%^K{iY2o1S*WXVVIZ(-tF5PXfbQu~ev&I}b!UpJO@|Dh%UrE!QYE?Gf8mIE!@h7Yf z5hqU{+*XVV5D;(c-1T=>o;-e?3qynk)*U>hfyAib|ncpOK(H}BuP4=ij5keil zXMor~=tHwYRQ}I`d`^OZv6;$~>^IqzB*ia_H;h>bi}oXmH$;DP-(486$V=tN0%_=x zBVvA&F%Eto*!Lb4KuAbm9ZU3Y+A4pOTbp)wmJGtB56gvUhMwvr%~tE@s?WztqBKrV zPFY93mh}x;9t@q4GaSD%8FylDR^`LQ}MQ4;(lFbD8X`28w{x=m-(~Q z7kirJ;$6AbWkzo8`n8h{kk3-rDk52Wef`9nnwfTilM%rn9%6mfO38Xy^iM~5nF@Mw z-`;RY5@k+L-Yuv`CpaIVLKgUxyLU)u#IjD5*K2m4$~VqRwDJSdSg)Y1-wD993V7S^ z&;H&|J;yC)=MPR%YseHely8pzaUHe*)Q2!05iciZ=c|j>CtjIyE8(LLQumCyg|++5 zP8yAH)km8QrJAF}F$}xSE8yRo)6)57a=*r5)8x67LhA07IK>}?`6?1QW2Dj6ncheu z3o#sRsk^{{e_dob5Zbp5RByb|U762RSKVrVZC*@>>O;AZy_Ou$;e!YLVF2>20qu4w z+nGrCdZ64wqETLQsID`-*yKmWSgM3C*GU!}-h9ZikkZ(7(h8PXzia^1HyoS#7nbf0 z0s1Xmmts9>*Wg`UplBtz0nplG*-iWA|67^^C7!%^#SIYzjDXZFdQtj7w9}9)9k;G> zgk=$2k=S{TsXN*6I!`Rjg+9}@z@#Kk>Eh?2{A(f#DTZph03(CgF;9@ayIu|=Jk)+{qBw8<~1adzC4AP@tOd7dpj|z>AZHP z6?ofyJ>YG@&ZfL`n?Dm`vPkHI%BzepShfAi@1f(CP_wKb-rlRfl&GwU^}?f$3IIUf zZ*t{AwLPDN?^)fHXf#FD@MEe=T$QujPuXMC zvqiJ+w+#Vp7-xQ9B#_6W$K zIkP(d?j5(5P!OKSc_04|%-7}u6o-O(VYQ^+_I}Gk59l9JGK`oQ0KDX0U?xu$k%Xhtbqs}N1-ERayXMt4eA&KwHV9sQv{QsOQbS8(W~k)S@n_I6f6Yb*&K zDa!@Y8mr-TmtJH6%hMf?ElFKeY(FlBbN@*ZrJne;e>u1oBN6DFh(DEN&T5B0MT)jD zR>Pms7r-sOls4F(pUGSx_K-9;){r^Z!yJRU3Jsm4an3cag+Ix3%&X*YXlb7OEJ?4U z!kCe`-35S{A{?tdfYd}`+&K|dr~V}p+5g-ukz)O0!(Q52<|)xUGH&^rtcK@iLfxXG zYdf(383OGLPg+O}c}>kCWEs2!o_gF2z3mAA&SPpz(U{hUTrlzCL(HWODkGEtv-w#E z7ZB(GgcB&(MO*UO!=L{LXk+I{{2_uLlP2H2ivGq^1W4)+o&H*Tham<6+D`UMq?*6b zD~Ij~I#g0Z59ko)fYmR*B|o>oVaipQKYKwQ-~8)P;pRfjoCKUcSy1ZG>Bh#*xc+rh z6VvPx2f9q!s*Z=)zKfD>PFFewYYB%1GyI6EuEW$j&;Afy0^Kbojan>egq%<=ef+8) zJ06&ttWZ;}QYxv{G<~0uAIX;%0+4UGl3?TNz}bLhompbw2?J;eR`6K*^zp4IevHNd z-3ldOlN&om$R3%8Y6Z$PAB$B~sSmyk%%lC$KWGzS|FZ_?nimFlm#w@Ps*8hjDv8JI z*1pO7iWZR1py|U6Zvjnn-z7+TGF?8#G=o%wZj5r47!AaCmQ`D}r$vxg^;akubi}Ed za{7&jEpGh;Y_?XvTPpw?<>?*xOZz{1g!>#xGgvT*j>orgUXf!Y5HAYx@BDOIDg0?` zhke-#W>4Qf^#P506Pr}(tk%S2uXmdn&6Gwsy&9zeIfs82j5j0d`ihx7t}Sncic!cAEm=D1GLj{dPx8~Uh?hwXPCmC%Qwc>6B9AsXjv2qLo=nr}m! z3e%ep(52_|8En3x-N{-9`Si_B5`t&6K?`#!rV7tK5S#j`YlGPYZ{ml;hC|i$QQUCF1 zv%7}S#QJ`_}Gt3C_FoLsj zaC*xlV^LD&K|%A0$yC?28^*tmYxT9ffq3P3(lvLZQw{+)nBz0Fuknshb&{YkJb6c| z)%gO?)a4yxmb1||yXUrC*>Uv;-_8#8A6Cm@jD8Y>m|;&lM@_mrv!F|-7A)k+fW{kl z9ev3~cKq;7Tdk}0eN8VHK-Kso6Ui>n_nEKC0PuQ4-m+yht~YJ@3XkeU3ifx_(FTh0 zb=Ism|t`Hj_w~!Qt_C0ibOsO8B#H~?9Y2H?Y<+NaKcHoX*U~!yM zG`~(BVVDJ+{cs`)ByF|N@SN;FLkaA5MTp=_~b}!0uo1p$`K&BDLuA@n75fUf4QCi{kuw zrePIQKeAlYC`k-XaSC*LC%C-~d4=R%wQ6_44lk~rlOZZ|6zne#@KO%r>-7G)`t081?FNhblWOW`v=V;BgNJ?&3W8O`1of5 z>%mF@I{F&J%Z9MDukPgjS9b+^bGig-6u{;Z^{Ox2X5QEDhS^%x*LaN&rVMMq=|59G znn@LYKPzNjX)b6&XVAntW^To?mgQzgXB(R5$CGQ-My-^WjB7VE<_(vD$H(UIw%s1HAw;r7D$||2QFiYvr=w-jtA3*WzCf8NMY?(Vq#>oNG;<2d2l8;l6sfVE0 zc1ifBGXz3MI#s{BaBECuqF0_zz5s04dM1~@BI-3AvnJsS@_<}%Z{}s+h$2BT2skDR z=+BZ6-n6J1hcJQv0urkks9~X?xt-tB=Dur2o`M6Fp(%j0n}rX~8~Gs1ztqn)6DjPy zs6Nn8U?LifM92X_z+Usme^vQpP>92hRh2S&2!Q3YHuLjqVrCpt4KPdx0GEIVCZ6(* z1KE&_24l_XhOA620c6)-YlNyu~lU@QD~$j!06SME<*_?m^8IEn`G+nge3JMw$wJ$B&@u zY*pcJ6snA($b(|!fjg%row{kom_amrV)^~Hzbs_=af#(ff#(v>*^sqz;YRl#`PUE3 zJUR{V3UNkqm=xY+kEKdeK!JZqB}wW^2(9?!b@71!6)AbT%K1k0!&ptI_AzwSXsW`_ zn4=pIuCqgcCA?Cu5NEY6- zoQdsw%$(_i^7Ah^RVMmJEgzeGJ1dWored>}3-?)M%CB^br242tyF=w^G4JbYl(q%e zk}c<8u9xtx^fjopY|=d?k)OOyrR6#sA&6+1qd)&iIzG@3#+j#CD>WTA&y%0Haj~*M zv$ETn5V}6QV;QgE$iv(8zYu7XM_fKzHvGwR6m$cjPBRdX(hWexvfsxPX_}6VquYTL zb?8<&={tGC@*l8qD?Ld%6*`}6?&^ORH}i=0|*oy=6tWH9?DB-50oLa z7)FBm+2U@$|L%#haCNg)`Bw`_)2t)Xtse1OBIT^+FzuuzFeRW#FK#HD0vnE&$oU;lI9-J$6l55^bN2C@81X>GLt5r zQRap{_akDobJ=wBk28LdM7qVW-w0-z#2xX=ou!Pvuygp5xllGXbE&U35g(VCdIj0V zF3U0&0~|ST>1*cA23)}5djMz}$;)XYzI9fs-{ZeMoe3r|FOHNg)~J)tkmQnMt6Tap zAT?Ww_a@z!iXt9W9H}j&V1alBc6YF)*moUX8z2G-=-U+UO2cQsKV2vwYizpr`uvLb zK?zbzp2CSJM>7VGSKknX8zY^n>#1F0PlY1f)b{K0)v0HskRk#i4W~V}Hewg(YD~hr zPwKTx*7D4-U>Jwq37DRhd zRW`V5VuD{>Z}?z`M~jaC^d`6k&|-!~fS8G1U!9IM(W?cLRE>ULUqQ9)AlfI=0Yj8jTp0>Ep`^8Fwli!I^!}DE%PjxwJ9T9lC0yDo zD?53AR`FXhV!FzQ$Nk;mi1KODo74^6m3Pd#OmDvlTyU(F=7wma1Q_6Vx zmlxMIb-$>;dc~`?Av%rV`c=)TEF$+Km-ym?>QbT-|K}8SgCuIldHw9q*(%Ae#9UY% za4N$b-Y9$U@cS=lY3bFl+ep|&#w5iCm2SWaa9lUAH=H8Mmd-P+L#Tf==+W2E9}YDB zAWDHi(hQ|AdPd!uw^H`bohuVM^5?}9HZ}K@uVs9A+W5%sK6vJ5o~w~4y}$rH4J9Nn zS!Vtlk0YNyIH{C^eJv{?u6B{*43U|Ckn(b>?CDt*rBEBc7F|J7WDWnO$&H8@(DE85 z(vOqsi-vRwkg|9uAcc+T&#~=LEZ!{=a(;dJ2}DZQ;j2t>6B(@fcBfq{kD=o%@wli5 z3dH=&s&sNg|M=ZJU6uZUcZU-50ANdqi;m3?Ua zttse{$OLBRbmzkj0BzAqf3JMbfyhQAF#-ETVp!#lsV)nu_cYE;V!x_UX8!@HJ`rPr zz7(hl^!oy$lUsLWRhILgcBQ#Q(mW3+L+?`0CRY+>8t}kv2IyS$8-X*%0^>d+pRZqt zKA2H5O(St5^}qjR_p6}tCGq$jdcG!eyL0HUa`z{ebJvd(?^ce+9vzVm41 z{a~;rL`E>8i|Q8{ZeIeo7d!$n@& zZ*Yl*cE9*@5!{J6nTa^_InB=I^?>MWf8O0XqbMBR$r6Ro{cGo-@02Dn;0TC{4UL*0 z*_5N0T&H6o_li}V>4U1m*^bLpt3KBuiH%fOqdM={~Wt!F?la^jr)H_(=t+r9Q5av)~P{Imz$ zC#BI>F1PumM`gi6{Cslm{`mo8@w}*nBG0u~KwJZ8_8%A3d8R}76rreFyA;}QXzm^i zaLq-qwjo|;p9;WMBW+W=$S`)I?Qrn>h>tj>@X(VvUcFMchoKlQc)Jc~p&9;_b4w049odeI%MSt3j z9qy$+tpp*xRdRWuldUSyFhQu-7n{DCBPaxR4gww;MSU7B-4u3uR!;y;c2o9lae4C! zdjP-jKH|1K4~mGE^U?hIm2~SXbK&;Jwb#Cs3tbbrn-{-1EpRFjQ5NK5Rn2l+8<0Z@ z4_%RbU>|KjAe6(~Yy0n&vQ>vpte5wb{PLfM#n_$@mtNpRSheywZxOY{-|#Wc1E1r^ zta~)Ep%1jwjN1+$R1AL?(+{jBbMDGw?qY^W_knO^uK8eMe7pBg*Y{$mLIj4$jDCgV z)i+Ug3G1|R_f;t-y{P2UbU*8+1YY!qKo#Q$Hp)m}B+#1GP&hks=PChLPPp(EDpxRD zrrfH7$~$*&2(DS!O0VPSOBl1Hdc1Zh&bJ|2%yJfi+s{7BlK^-6ytuG{NqZGU|vsEP%87@^Lt=qlQFJDyvmv)4093N(_ zu}muA_rLA5S+MIbm^+!1;%-i5Ug6)RHIL9!TnamDrY!wwZ1tuFITB|fzWF8b@th~H z>cUP)++86s9%(d6M+4Q`UPDXNTDvQ#4ddLgzNa;*?Q(M0X^@VY&orG!e)G+i;8e@k z$@O)vqE)np+@4rK=l{H`^BJmQL9k!8^sXHu0Ym$WuK0r}X6x(|Mzd2<2sT9?dBMlk z2}g$XjotPTIU+!N1hkov2Uy9X{$3Fe?}R@iPRgGSUp%3l6!vfR zcfA*x67tLLB9F!a6#Ec#j)f~{_l)DNsj?}YPi|+$7V98l7#=egR~){)DNXvjWjq+B zI={{Vz##Mrp~7B3E4AaG;XC92$UDKyGn=Bl^0}wMO2}Fw2yO|+o5PWt>sKkHVhbgL zO4p8&9BJ|!=weAQj<>K(bHAMH!nyNv|M>GCE&w76PGcy&LG5ZT*{l?gj*$5Q3eozU zq4#%~mvvh|uc0I~ykl<6{(5Sq%xd5JRY^LukxEN=+6cV{qSC@)B4b(A=mCn)cbig+ zT{JWuiC0-2w36JIa=6+I{w7qwOPY9UhP)baS5TGC$M-u%FV{=-) zWjFZf(*ET?JYqxY`VnF5Zqm+KlQBm~zYLep&+f9Rla?z-|5Bx>-@8BS6tGsyeY3f} z;I5Ov<%4d|Z`i4j6Zg=(V+ncx;*dpL=f4nZ13t_?iw|Xr@Ps3N}oiUbdFmgr-#l*t`(T&0ysBp<_zE5;h!3ok_4(_F(CwK!ciF9B(9 zuHy>gL~V(Fc=77y1(_4&Sehnef$|oJ&nAk24#ZDs0nYVdFfiQa0;{y+`}keFs9YsQ zJSrGx`9d1`w6uv`L_orv{51f$nvK!m{+3%-KR$J}Ude=3fGQn8R>_I9`we);pRYaR zYbWPer`UT>r^24Bu=n(#mj#KX)^oAk^jz#$0XR+dsCQ%lpQd3}?kc&xV(-%EgT<2FsNqI>$T<`HE#^ zw^#2>!Ku#f-u}7hf%{{rxb-}gKR?+NH*DK1pXDa}sw0s{%_7yUPiOK8MmFX;D-@`? z=L%kq%V@WCME7B{{$0r?bD9LjLgA#242=_h%o<(#7HB(fRa&%FMH#o7QED)%gnw&r z^RAu}(B>bLhV^fnD+Hngsr9LO*c%3N)f0lat|Dfnk3z=(V`AHTFP6!p-!^qUWu(L< z+=1@DyM>~4ZKk(|c&+kx)aVE0Cb#9RNdqf=cXX;gV~5AGnE8zI5Zvx6l9fsIgq>9T zcPULN96hXoKY-++*nAUN2ze%QU`+P!-z&jb_>H>?LTTZ!oOtY7Io@P$3FttpALN*?wXs@X0eteZs{q;b=Sg4}hmAhs%9OM<%D78?PSE?5aX)xK zEvz^)Wq?K|%bDu`djVQio`x9&zjT>Izs%#fc9h21yl75mbkejYiM1xvIsX!YzEGo> z1QzIb<$XBQv!URoQzK+C=ewUTm`oWXJawnU;1nyVy61DA==*9=PPG<34Dl&6Om5HD z(UOoEFA(wwf|kz@BTSQtA-Z>Yq+AvYb^V%gKdZU`I@P7}pJsJSEOiM*y0kRTFu$2< zZGDn)**=fH>2`AP=8h4}8$aI9`-?~154$355o<>H=DG!;o}!;U-Mw!&bY4Qc_}&w1 z{358kD| zJSJ5X4pO6}?4H6{JkBi<_n}JGpYvY4xB4(L+_eN9jF~*mfcK`>kHl_}^rY$znFf*+ zsY;$-(+u3p0+@HOjg#fCQ@hmGr#%<9&HxegVC}-<_`UIg;vjj?sE7Y2$DRwoWHNr` zi?}4^$wTptpYK(Ry8o#T_VZ2Z4XapAC#W-3c9qC6%z%o5el#AF#RRc4pq`HLUE~Hq zuVM9R#~)@V&;ehU9DTJ$_2eu$#WDwQN#I=s05`Y}R5wE0s{OMz#C-@`jM$7HeaKnl zC5fs+Qk1XFY1F)Ds_qN7XFDNMCwFW`*zZl*`}BXjb~oY2W?8jvs+(D|JO*{kAOM65 zTkDC{HDj6j2|=mK<>GVb(aU_Jp23sP%H0r0VUFpt{=X~l73&xXO!ZLewQhbvHO)sR z$QrY4Jzq(e9>@qz1XGLERR+z+bpZQ*-5Qi{tF21HvD@Xce*B4Oh*(`K-wJohzrvSs zQ=&WgVbAumG+k(ypdTrAnzp2{LgI3ikqNdKN!QNTNC+%@rGF`=4LCvUwpqFFX^@sm53fjeY4(vTNg>}4)Nwb;ZNs;*(eL3a zk%#FXEQocqn3#XVpS7Rzn(U#o3|9G{odd2v`r#Hab+Mf!^cxULU;MqokI~xUg+d$C zLbZt>se&O1Cp?P8_+`?IH@atoyc|u}%?^2kyR4yG29t9iw+n)SFxM=3jJs5~pSJpIJyAq5J?lehuC47~IVlx`l*|A|f`(g0*-|UK(si2z&_CXbi z$@XCr#~rG&MU^$x%}Sh(fb$EdX%09`ls4Y(3(wCD;D>l2T|h~lt7c?{K?C9!(HiM} z8ac2|d)7kU;?jEbL-Ay(61k}zvO@O-IFFaD`>Xx}!oA`j1Evr)_rj#hlE}JpH>Asu z)E}%`u>fXGt5{qyQF2TiIpezi(jZ-w5hd-UWyhGCF>NHT%^s@VCOYdczBw29wHM>k zXEre767}DAc9KM;2sOiL^Y2Udnv8fy^%+2)@?S8oh*qo&T?zh44B|Aj#FoyBgNr?J zwy<$YlPjmQY(x?{8BgbmUZn+4!d!+h1cwv4HXPUdX!1=?qpgRQkP zi1Qb}7E4N%om;IcJM?EV9W?W>`OZzl<<}B#!=l$KM(-FDW{IpmqdRCidQY2p8`>?j zBc7>ef9o~&jY_(52?3-W>5ng#_wuPPkO4weHESY-yN=fv$Z5{nuh>(kda38k`65xm z$*9W9DnbSU75^dpd8lg<;1Wx2zm&`+McOg(nNG;^VI(IVLx(_8p8v8d_Eo&W8k|um zR%Rbbkzlk9H8pXWRI^RCi$5Qpe+DQvYXZqrio_taiZ6L^&{$83{xeZCc=f18+guN% z_QB@(0y)3ZulsrMfrfri@UfI2ivbgq$#D0YMpgqHIL%rl1kwq5`djfG0i+Up9<@G6 z^XErbEV5#S$)Aa|2|~o8{nvLQNAzLf-m=(l@aD$PK|`N`@<0o#lmG+ zm9H7v0!_TR#3(KpIb|^W4*kri z^~nMKU~vpUE+PKYmFB{c4IJ=6Ze9DQStm-zUxcue_PjojZaqbLYfq3EMx9R+$#)U++OPC%DQ2LrYjZPaezB(4O7s&aTx!nCg-)Ztwk9HfRv7=fL?HcU0=}u#^maq6B zH!Dk5;h`x(Sjnv*)mHEaywN;=AS3c40I;#XsGqZXbxf;qAxNj>%eYb@Oe9_*I$*lu z)h1u3Y>7|4j(~}}oH+8%f}y3Zspo#pX(yFpA@6ce(8_9D+gSmlfnm8V*XaieS2pbX7XtM8&7bej>FK_Vuq{lwM=gt z2?wm@u4J}LSJzW9cSEO$!|Pdx%`_(9`De0oOLuwv{8qZ}=$JqhrGa%7?Ef_6q;i$K z=#TllbKU2m@($;>pHx5A0U#GH20Gn6>YM900R&F#yG2v=Q?5ZTd%ihq=x z<||*^CP{FkBaiOkgL|Arh@J}9#0lYZVdzoRm^vDvkaAi69b-t%2`{`Rj>MQXO*Ggv zXf>Xe7>hhY8%m>16rScqGqN%9G2NDB1t>&>)-#p0zrUxJ`K&IQd9`7Mem$H0Pwj^8 zXjqQwG2P!~+j&=0|0MzG*y<{0;b${l7XO)yrhyRz-6L>Qtb~Th1aSG*eww4-%gid*(`g$iF$lCz?mGIGT~0sipA zmWVh@6^)KY5$A1iH(eYj+gJ82G6nMYg#n7kQSn|kX?o%f$lEMmkvdLzGTgZHRpwfz zjS&l)jRF5Qf8{nIbCmL#!LfwIT`owps!O+VK%_&aCvNjSyWQy((n*R$WI*@6zT-g= zo3pdgK;*p2wQu?hRDnz8^7`>batv67Tf_r5 zrG|{hlLjv7J{ip@aEP`Cfwwc69p5!mEdWNkV8dEV+bfeU4Q3q`Gu|7gceF}dQJ^)s zKm0p(H{XEaLFoh|5{Kr6Vtm)g(tdwoEMNY5x$V)oMv;2H_VSBFkDbXnCOTOv%o79+ z2Q~Lvb&`75?K(t%hiz_!wXxqrn>4**1yjk`9J&8_Z(1NDw1jVS2$6>tYM?0i<BeH2P3`iRwqW{$40>?`lBY-u4DFdF>ZNlcgEd`MZBJrdG#Hb+xFy zX(>~7_%WGj$-icR=J(qhtCojo?_vyQ=Z1`JlOZVRM+3v?nf1295}25~WRgXCKnmE5 z=I(O)gK2Obi84LJTNAck2=^WcLw1LHt3XTW-Je1M=C&t1fx-|YwDuc-AJDtarY7De z#w4riuzDr3U+@=P`*Is_Br)};Qn`Br9*s|;RmC&0X?rRF7sS`yagks|wg2jH#koe- zYxO8^-Z|!dE|KtMZL1 z@I}huw#CZnG3$!ms$}f|vFH-_t}IAl{Dqy#$&&ql%)XIp%=b?@nwP&PM# z|3nP|@)##_VFlL(F%&{xGa#%W`(M3p$91R2*YYMk5%g|T=iJF5t zCcw!w_WSE@6sq=1^!4ugr57sv7%nG9U4lQL$8|V2L_T6TsG7HxP?fw%ixf1wBH8@) zcpZKyNLe7vz!G5};ny67UE-9rxko+Fs;cdkp*_CNPO>RnpN=7hsb^7y0S?~pGJ+r` z^{!)XjW0p0^-SIdL6aGIs-6EX|DJqy&L+z-a=P9#Jh~X`R6FRx>tI{&@+s(uJ+r5p zERzyR>L-WRGh9s9J(zUdh=4WgA+XiWw*`dkBi+(U`7RXrS;u4T$y0CG%25nTo6a0| zMLftQhKRH@@5!QyItnR*CtBdF|AH4^o}w7fN~OAT>@&1u^xx?=YP2jqX<46lDh^>& zyCrV1qFh2fVUKp7uP@DIULN@}nN>UO`N5g@+pnQYAGD@|E|fK(aC9?f!`a)`XbST# znp?@ucI%Zs^_>Kfz?rqGDsNkkjmke?Ivn-WtxZ^mt}WgvM$}GSPvB6nUf2Z_gv*+e zZX|wYSF&2p90NaR(kFc0kC8RAoboq|gh1qzq~>zPrf=UZ9!8V!j>r_78E%&P1KC36 z{|LzR%A{fc>!J2>`Xt04h#re&EuvM3Y%$_Z5-GKcui%Q~rIgcFwPc3&cZ{c>_N1KA zNH|c$9S|u#9@Bl={c}8lHiu65AN8aH9B1mf^)24BZb4geP~c8%q|-URq(6n61Fo5~ zOls@Ex}*XLoVa&t^lzHhfIy1`>?vKxs**{XjY1=2r+F2jf(rPJPnX^17z>4dsyaO> z!7m2En~dz7FUm*rPOjwT&W6GHrd2TUN$60@?qky2|E%5X9UbQ%Xdh>2TivUo#(3n1 z4#=!LF0KJ{9%lXlDsELqF;VSL7;Ucfr7LUbw-6fVwxZ-}gO3UQ4g4Is6Ere+fuRBn z|C=Mgxt*t9s@RwI1g~Sw1#~?_3Zp*zRD9ud$zV)bkNfWFK3T+9Mx;_G{8ch~GBHa; zB!9*?MIygD#TwC==NHgT6p;4X+AldjgS;B3s#Wf0j`>V$9im$-l)wCT>ut95>85cx z*DJM_jZkXOZ8oez40e7+!cat)V+I`A^PclAWwd0Z9y)MA6lfAT{zc>`It&^soz zJ@u}c-Y^OA*cS`|FKtLRJA)*N?tHB;59Ai7)9~HKV{^>V_pq(b=V#&`RPql1nLRSE z;}g4cI=kO&w*Dhs?(KLTNH>cbzKcEZN1S=!=j0FQrC1==q*sjFQZ!zZqQvMaY)r$u zFhGwi37~%j2w0JqsmF}U8n>Vs6QtYHtVlQ0@1>wvA)LDZGG2SRM%&tEfAEV5NvtI!oYstW(Q)EYi`3+ClD9+Yj&ycu4a`DQV>p65#5W_b za`Y1YN^nkA*1c`=cyI3rEXXFSnGv787&W#VW;$CLx@cQI%u(^1sQp5+kn-&-$q6k1 zV}(?50_)svgt66?mtH2n4i4savXE?<468M^ch}018|~lQ%>-Ll)})+0RVwhW0V8Y5 zF114%~~I|4itz(MK8B% z&IZagiQl1R!t9DPjQO&}Yqik*+>`2RcZ9_3Gdza=LZcdV5i^ER-t0%Ir3}`MZAS{y zL{;|kf{EQIe#<_D6cT+;u$`FvqqHW`n+RsH79t~%E9F*9sKU#aBIgVhGqNP%0sgk2ny#cH|MB@+tX@}!l)Md z>W(Zr#osNV>W?;GN37f&%1hgC1BG)ZPG03jcONm*M%ZOT^t$HlqHx%Bzp2;DNX4v{LHd)aL?dc-MFE<`%heRD9ib^8d*)u`ZTd4#~+= zer=O{FBXW>kxgKUOfyt;nNZE>RB$=n2{wk>kru&Q$!aE3gap_J*vA8idZARlNlz}E+b7>uS5jywC~0t!cpupY ziRQwK;p{>1T7catM@+m-6%Yf^2c9Hl4iDe#n&nbG(Eg`UU{&Q?I6vu{Xx_?1#>BX) zZwTSY58lku`#D+dT&`2QVJbaeP%(B;Yu=QjiGD@Q_)+1i)U$=VLruL?YUdqAr!|=r zwDsDfMZQ8RiPL?GF5y*7Lt9S1n`Hcnc={jt<}OBd&>~qZs4n;@xua3yJwQE^l9PxL zfsbl?jXc?mtSbaw~bFRIRi6Vn6oRaeW$n(6$j_1We{!0$|mHVU`mi{f)?Py z^K4Og*Al4yO$0w(Sg=9A0Pfj#ALRK`o)XnhouLzWy3_FXc2!LURj+!2?w20t?kZ?V z#RZ%-Sl$CxDpptDj`r#A-lFK)XKmv8hxKnVf7NWswRHsb#L~u5*r(>}&K2OE7o4M$ zJGSqu1)gI^q`W>lv~G^@(_BLyhovZY`b-p3;FiF`o=22hRO6bbVbm~>$z&qAk%W8HH>@ur95P1j8azg!{JOX zhmGf`gDnFk920$0aZ*_9UWF)J_G_$1EN>^Y z$HEquKmr^^FXT1$SvVaY^4chP!LQl2bct)Tw?|Dzx#Avr(dO}8+>ZnOu+g0qbh&PA z1(YvqJv|>P z&93Xm`=GpkSk}9mh4<8l#sP>4=$>1cf;xH6B55BO7uLDH8`As2^{D$!szv%ehb1b$ zwXWka5HW?v_9XLH7ujTzAY&SI^ZI8!Yma+t#|y!sR4Lxh-X+B?kC?}shi!d_z;u>& zcqgbtnJ^SBg(FFBx8P1z2K5kLLuF+!z8RleXU#fazJ62a8FPp8XVauciTbs(CPUj+ zbGX);d&>&ZK(fRj)VyGR!Z@a%REc_Ro_kK&0QdNvHz`+&MPY_D3P?eJx6e{M8j zSbq7VB!Q3VsL_+?Q6PVA~k2Djq-P=9WTus zYY0N6s8w=%eZq52&zAXmAKQmW3W07urX)RVW=u0%M?OrZZ-P1&}DAu>&W+ zWPh+2!)u$@&U0X<{2$`fvUwgIino4{L!wwYOK#_^^s^_jsPkJH3J6ZtQ6S1G9h9A19WWh#*{r%A z?HK!P@2%URV5^>V-C?C-YFXXK*af;p8{|{^{I|+t-nSP_>N{kuUASIp1`au#%(oZL zoy?x^-c@+QiR}+|DikgLv#;pR+0K;0bsB%T=WfMF9}tEu>*`_uqChbpUH_IRE)yU8 zJxoVLG)JBD{5)DjZ!7t=LkG&?81!aMqV2P3N_N9YqR ze8FnzxYr#%(+d$%bd|A|6232oy`+A=ja0yyqf3&i8Xm4KeSqtYZfc$pzHtT;S0jp6 zE2}3yb%|GZ86{_o+b_n+WKZDW(!AE8xe0FRLpsIpBmF0jcawVQ6hGWsYnR&F-ZwQhK>U}ZtM9*y08~@fnZ;=Gr2j#}C zM?nJ?Bxoj|w|ZVpGaPq-1#CqrwK? zV*el49y>IH{PdUtdA+x}HhfGbfQADZLT2zF45aFhA~A#nVaKO`!c!W`f1N2mr1(t| z*bUV`GxlF)y@)s&U@cGX5FbeL>*`Do6Zob(S3YdRs2SkZuU)>6qFT{A886*s+4pY? ztNpAW@bZ2!-0$Zc-O+e^hum74psTY&W=C~3#uljLjp&r(pG#t3-d$~lze_tunQO7& zW3PG#aIAz*M{|mMsc_JZj==7!4+>?TdLFtPUvcWcXR@eXPaBl2%@#)2)Ij%p6MGFrt*gIAC z*TNhglN{ur`PSCvbMdsy8>Md#K8W9;3QLwaM7GtryJW|2hQw4T$#2 z$TK~DsBxd}y&tWW zEjOTYVHbZ#vi6!4>hB{wFPsCl{4Jf0RhVcta^fjR`Zo$sVzoK@3z?j`E*X&2iqyQp zSohivahn4x3>dLjYrXzN0P%tWMGqjm?*9+06Mi{PF_74B?esVWDL_p$ERGi}RzXx8 z0kq!zS=c*#`qX!@-IHQLOw2p+3-Uf7=c-)%p!&>UP3>_HhTQOEETs4%9`=S_a?m4bvV(vZCd;HhxiK+3$;iSF2Xg~ zWJHmt#1&(+7PLs&1VU#%GqKz*-5043&adP!UdptC)U)7Qxs~5?A#;m`gWTHMNWW7y zPiUPGJw|8jj}p#OIy8+66Q3j~Q{Qb{4KAZ4=^W){QaUY#y4xbQvM(8DHL(-`tInrF zqzCaHh8t{;pUWQ| z#B-2jE3pPzBJ3LnjGoc=N8fd|&gX-_J+AE)4Ehhcq7s`fB%P_6(p4=rJ}uB9??yD~ zG+X;iw_?VoBxk!m7%SSvPQWtiHCg1|orv7-(ud5l&>#^eX%}p^Ly}=5B9tQE6Qvhljop&$VTty-54LRKKP4Trp6bYY6qGLyN1Y_RPcTaFes2V~AJ-+unlNbp}UEhQRyUk*VfJ6esLYMX=blH1pcpY_1i)Uy1s~Qn8%+}Ri&HN7wuoyzh^5a} zkJoO}pY@7ib(>0-k%p^e@w4qOu6T zb+~>bJ8?Y=(fESL(W94_{W^^$wWjnmYsl%4is#6fy-sV1U+-5O(i; zso#s82d?P0RG6nVQ_5l z6tjJDd(x%atFUvGR>rsgo)>_LFCIJz3IDk~S}FD&#%t@N3MqI!`HH~K+Wa5_@};cY zon>-vcDsuR>1d`dgu(C5^@h*l;rYa+_NEPu&`D}SiL3EMx~Js(AA41+5YqDO4=YLRJ753P4ebWW-u-wulT|A#m^=5Of9FX@K1`Ns1MF8m z*1WXK_f26}#BSV#VD@QL-w!T@a=iD-W}XWDRw`tOzG=9MoAdP;LUnFQYg{%sT#zf^ ziOoimMTEY|Jzd5|vJ6#Y86Rr*DM#Jz@-TaN#nPJDz-wl&0h$ zUNf>nEY=7gYkYqZeRG{{n>>t|!>6my#7fSHd<)L2Cd1QPfXy#vK<+!IyS@53_0iQJ zG0s|_;}qyn_ooP$sO8x5V!JqGFi$;t|CjzpH}b%pF`*Fs?ZTdUDhI3?pIMY)6frX~ z1<4m+{`K@;lJ^4)@`pT|ow8(13^HSxE+3G$=yZXtjh# zEbtnfqEK&Ou%Mm5Tqr-;8b*_?ZNb2{v24_Fb>^6T5<-lLtcHI-s*_K@CC z$MANRpJ;GUs_0g>hA5%45p$myZ^g$8kCK<<=UQkkiUy-4@MQE#3Q5Q)9i|<1bM|o+ zV`NZ*^3y8mTGktJxl}vh25qgxQa5seuVrcBJ6daNA`FxST zSpHbX>ch(VW){9;YDV9?dCpNl0r3_&wEL2xi{4#BZ2?gpvU}ZE&XOc_;%Y^6mVbiF zcHfXyfmi&<7SK0|#f;n#OX|{M{H_kB>y!`dzj4!na^Jr8eDj_!5`)%O1GA)(gE$`E zp%Vo~7=)+D!>Jm4HfR)vj00@BY3X1p6nD*`!O+y0&(ckr?Vmw7FDTr>X+=A7pK(vv zvS^A_IxGB#k0Ep9L~R>qFg4U*+YH2WsSoXj&MEBn(^Qaz6?u@4W!s=7c@4)oqGsZP|&cMRv7wFiq>5Xr z9hM1oBD|g7D#8}My5qK(Q~umlTck{p7hS<*K6@oXlPQ50VoYui<8rPMhn{Xun}>wS z3h5wg+h{CA&o>_bqyYXCd%x+RginZ_qXqjBzBkhIGW9ju zlCEs#+Mpr9MCG8xs$?>DKZZ+ydJ!s|DuT6aSO$`&zGaSd;>uL@bamrZR5MNP+U3387R-*M8P=6nr&S4Sd}ZzNYw0{H_5uaeRG=g zW13UcjuFKnO<+JbOY>zF^NzYE5*SX{=aLb)5L4UmmaA#3V4x1#s?5q*M2YRv0;`)K+@w8 z32!8Eo>6*10xAh?(38{Gt{V`;ZY~6V*t}kWapnznMwH9c?|3aCfk}d?he?)6YV)p+ zEsi+-o2TDtE)*_bRzV|-@=hryn8P?C<`xpwclI?d^HKRd?AHVC#Uk3vp?u$z=;6n#HI%;7vvXtnH1Ns$qX)j*@|p>P*I3Z5HMz&jHf9A^QbyusG2fJ{MT-@A zlq>c{rpfLZkZVGjOJvXhI2qlo$ryrgP5^2s!p2cAXi^gjGlPHg>}SD)tszYlPnn?J z&T&6u6Jqcq{O90`VIeLkcQQ2vr>!5TH|0&ep_l^mYQp z!#mt7j3OZs$YE7ll5-~UahE50i{<&8YR4Ztk(mYkPd+7&WTvpp!ko ziRe+`Fjn>}KTOi`&1qk>@ts&q4qflI>g$K$VZ{$-h_ZyK&x4z7wly zxIwjV=&g{)9nTf% z3BD#@p1Tfl$~1(Ir#PQPl?G34OsH;djAW~dmFdM$B+IukDzo*#nasRM6eh=IA%J+8 zVa(BH0dFNKf?9CXuQQ8@wGHG44`j;wF+7(wv_7aGPc_b~m;8doX@!jU(l@Q&r|5wD zHLCWD=^+D8!+kUW!++wN%TL^D!}0;m&&)H$#F&-;dCjbFRB)77?eP|_4Np*Tc&UWm zTWWSV1hwvzTca4vhUNt5{d1)(x}{QDIr~&%q!#Nu76+dtOLKn+=C)G&vd`JX=`0uk z(coBJP^stXm+uz}q1E_@svc{_(?a$I&yM-O@C#1%9G%3#c zU1Ysvcrb|w?tB^KeCxw`d&HVe(OPfH8j(5?X+jk+Ud;#$ebM^=Ucm9U28E##&(kbg z&q4Zc*9_Vf1~ut4O$vhT6S%a%*g=upndjX9pmb1MhsRq(u>!%i@+yUWH8tW7=9p{| zJznDtHxg^xh9d}2?g)HFjzh_o~{W}|zTSNRfTxD0Wd%c1+uKB0sMoKAjod=Z=#Q|!R}f+SsFxJy3`=Yyj^ zq34S{Dr;IlDYO;bF)GVY_YFRGtJz9wA^MMeV9j=D zSSZOQiJ$J|@XhD3;k|m3!X8+SoSItHQw_P4+<$ zajJMV*eqNVUD~hLgGsHJ`W?Oyit1zcdzx)J?T<59OH}R?^nHh9PhysR&f0n^Y{j+p zX)MR>@y1-3y-^2SsJ)>=XRtPLEN}w6>+Z+mfbD%2V@`JD_v8b*?a>I#%yLJ`4y&Q%dUyK zz-xTAZ^wM%NGJHowWpDDiEQu{(Ct0eEUgsjK@GrN@3JSSHj_bM%%dC3`c=W_1E%Tx z`Kk-3r**P_BQtbQKdn!8o}KcA6s0joNO!?hR;Cx^E7THIw*o4}BEI(Cd5WLj%dvN< z=f@Nlxh1-O>a@QuSpDnAxI*Ff$Od0^0qjAD%igv0sUH;deC*yCsL;naRA!OeUJpzu z)olb;EVjS`BToT&is#EKDf?U@umh6_01xxU5zA|e#9x2d5ZZYwVqaa+LxM$}Haibe zbuXfQB+oJ^MO7PJa_&@J)1zY&xz(wjWCW^4lpm(U?f4g@Lu)$S2g3RC(d|a>wInxk z(d#Uc1E1>SJ^SLBWdVHlUg$t#{IZNji{aqwcGM%IReQYPjbEwu8EyQbkeD2|#A5oR zNPD{={LjlB`QhI3+TpE?_*s`qu`xNWU9MDJLOLvff=&)K$uZ{`iYnd`G+Gu8WQ1Jz zq)VrQo%tFUzbx+{KOcam4yb^LoCo%04a;MxWz@o{K%fU-elJm!bCcL;;KVXz^~-N5 zRumT@*;x~Ag>hP+l;iCrlI)02Pv6VkOLtp+_Wb~aWevr>Yy$8%dDg4|?FUN>S>30m zcDdjaMF})!R{Z4p$B*%$TH~l2k^MWxMdUQ$jx>dFq=_RdlJqd^f;YMdKIopK2AJREnf!MUJ}X~+5ssN`4yheF`6NY#L#ts(j&Q( z8<>6B?Lgw4K~QJQOXLPVR~bQIcsXRWU8T4+FL+#)LZ!0-$EtrAudNf*<^*0x^(Q5SAWE0(bK16?>gY#Lh|>NnObI*i2L{Wk}UKPJ3)tEKM;QTii9-ne_A1E{AP z&bpg8sRMu;3T7O~}@-jFDS@FFe97ysHYQlnYYUnHct}Q#sTwL*GXKO>0 z{!1{xgm;bQ^f&QcL~r!0_%D65ZcyX0lWkl`^59nN^O{b6AkL;$6)jY>A+_ShD5-6SV5_l6Fw5Q9D1vAKblzAWmKHcE zY;j2Z=Y9Y@V{|{7?^_CBTP{os@&GM7yhrDj4Uj0m7fCETh7K5~JL+jV3FdQslA4w| z@r;!*E`LAXwiO1FWP_>BzRSH^gV1xg;6V7kko! zRJCi9jGs6DkE(MIXZrvDze6lJmcnu@vgCZoDQr<#&MC{85X#vwVo0c*=X@q4DI__c z&r?oAaz1M#8K!22@5}r8eg63U@7i_QUWe!N{(RhTw7db=tn}2}zyE2|Py1!OMR?!?{hCgt$7rBXQ(LOGCKh6t*vI!)YJl4i zCwTKhUQ&6eFW|S0zdIQnF3TL*>Ti&9Y$&R>v*%!q@=eqyBWZ)WyaWJcYpbkutXyqz zXiA)@D)s?m=3w)(wm(J$wNy?w!)LN*i)O?ZFuLji<|3rW>S zA3fuv?-f(=!khzos39_|jta()Z0sAMnTl!w0O_l>10J6rH1Qs-y#y?51w48=n|xx=<&RyMpKu%2?5jNXyTRAg`y zS^TP^I@NzGkdgJMf0zLt6beax)+9*~uF{T%QK?G5}^&17XS%9xA}0 zua*4!l;5?1@38PB0;*H8&=k*)Ulfhk#cc4#CC#YQUao)tmFSvN0q2&eQUkncYS81y z>0Cbgs(AjvZF2#!=JlJEQ>T?E{|;uGs?)>B5JTb@U&l`XPytK-q@(Ak?!`@`>TxAX zr#8)EX}-JuV8Ucalj8t{B@F@R(-l1s;>25A?7AzMm|(&PRoj6VNZyu<96jT;sHuya zNxV~a*z{}lWHJA@WGO%pQs(5-1-i4;%$YdXRSZE}TdpL=@(h3&Iv?bk`(w28Oze8x z>w!BiyMCHpfLNw&ZkemjMHG9=v=}UUP@!$%)d6B$p|K}vXM_rLXDfFE2OkXcfH2gl z7xdRcehpl4Ks*XPVEq2pj7MbYqMH^QkF?^ISdbKlbBnRs2 ztZj}4Z=%5p?-w`bq+Yo$pVC-)!+=_VOTC|!e|EQ8Zkol6 zOrL|N3>{vctk-Vqb(8OLtyn-nkI5^yEUG^X4A5SvpYFKS3ub!kw4g zWVi3Q$yE-vFbF%Jy^J8ly_+XW1wKI3QpDua9cJUhzEcZVt@80w4&Oj z)q!2yGP5DTYb!MZt)Goq=|c#8kAwh5^%(B;^jf~|i1PrPkep(ryjPQYJ5ReoSWwLs z_;!e^g5JvqYb)u!?07lkK?#@}2hu=LgZZp>mWy|a3f<7&^e>l~6Oi68s*lhfvAZiN zLEIyyFO{vBl|z6A)IXe?zzvbeS6B+9Ecc8KucOr9qV$u>hBzhl(MSL9!syrpb|T(x zZ+)Czmz&30F+Z;8xW>lg80P(Lq-Elh$Ao?_+HhG*kYa3mQRQKnupkebo;y|s0hn}Q zfeeekQ}YWA?~0C@|At`#pzJ7pGDnmA?M!e_4PhDH2Uf z6;+qwD1EaR;&FS^EK(!VL3ZS;9kGQ0}u$DL*ir1S_rRUm_Wc@R#f#cA`kp@3Ye zn;u=DM%W1Zqr38kSD8p&q9N=Oe9_GO?EM7KgIL$nPysGWkJteSJIohA3N|nESo|ki z=qrxbpy1bU?4EjBhX63rKkmpF!nM^%O`*VuWdq*`w?I7v zWwl;dM+0}{wztmU@yZvS7PW?KG_)`BvkWvVEOXYiw0rG3w?t2iW#3kM#=jvr!f z(goqP`LQo$GD@S@{m+$_Pmyc+h+MA(yUF3Gqqm+19j^q@uCQhxqUp4xBmQzNP`CY~ zE2u2YV#K$|4V^uxUrK+XR-o<$ZdvYVPgdOKX7thq{CwoVj096QRa^t`J(m>8FGnuX zp_Qpt?QMMB^a{m;hds14G*CX7gg(#Tqns?(es2Xot_4Ra^iH2RZ`(wutA7aE`KQzj z5bTdm9tPSUiQmwbu{slR#+cdU%Jmz@XC2Hn>!XD@&IX+6ym_003mE$MPM(&UlqtQalB!AZ!%Pd<1UpL&h{PJBRE&88!0~j>$#n|@Vmu%ed^{jN^Q{o z#>8AX!Zz<1TbKEF)-@+EscB47CcW(jZ8De4tFR6yAz2?Z;9P0`kNn&A_gUMI{|q{M z(k(S1d)W)WIX|eu1jrXtX(iaa>49Sf8dtB9;i_P!#Lqo!D=+oDpMs*K5U;TsE83{2 zt<IsDY`x9lmA z0wW1Lo0JToLM5`}ReY@|Jk}`rCcp6xJPV~j;BLm2&ab^K6@aN4=gZZuAq0+#J2=zY zV3!Z3ITED=q!8$svuosoYub@_i&Z;l;S|O~pV8Y;_{pcAj=^Iz{0GGk!Lv6kn~{Dx z^w#@7%je*lhW-6?oyit+)`Oy7}*4$)aU>w z8dUE^YfTSa*lx);ddyixRRJpCuhOHhpckhP-7P3$TOR4r!)SP5OwzoL9@vgPwBbFj zCwC7XfTZvA?BA|bPdO*8f&u7)OS5&6(t z*J#gSVV`zc-<`{r30;Pu->Qt>Bs4buz9rSv&-nJWr3U>ESTRTPtBrH_gV{e)qowXv zU&zVT5~AHI<=4O3Z`yuQ$w^$TYv^7(kBoopt(*+1ehn7YS#;FxszhKA)lHVLQtr)W zsDR^?#ltE;#ThuYr;4J_XS9dQzKIq?%f&zQ=CXuS9{0f)e?dSc3a=o(U(1FHrzjP9Efvs8!<9x-v|3p{wH-FKJwsEX zOhoheB>v_EPgU*Zip{M%`$$|!i4YBf@q|(xD}ueb=+Js*EzQ;i5>6kY<%q?fx~IbX z${QozMx=4aV7K07dtCV4mVS?oZsQwAS5xqE|3?9Cy}w^0YrZBHoAVVF8W7ihE!A97 zJr%|@86uQ|D+b#XKe8>4r%KEL3kpX3sqX17;Gceb@|*7fpFVA@vMOej`X#eE#kV+& z!mBe8<=Exo)Vv|RdRuWdJGNJ$jm+y&U-+LAkN5nkXzTFF-d^6nW&!k&Z{Aqm{zqp& zuQ;oGVfmxMoHz~DWtyM@Dmg2vCtJ8C6&U%x-0L9s_hxWswtd5e5w2d=gE4lB9)aK8 zv3ZmkPPruptbh8JGzIVBJQ;aBr&-mH?8~=GB!azYDGURj+xO`X&7E^6f-8Up<>TPZ zh0ufa&?zM+fVuR~Z^p<*Z7E-H(ct7BP7vBts=T&bhkTf7#6~RXxU0nU% zq09u;E^Y_Rdh0Z;V)Uky0qg8vpekDFIle3jw?%f!o2?c$txcwpC;Y8~8#28CWIB`L z*2h0|1ELEjUa6pu0kCrjBuCKz@`;&NvnNYMLhzICcLJyT30rr$t;hfVo*J_uzTmEj zR{w3^qCSGpO|-aWe+y(33srLLQ(L4A9y>1;jLY{QOx}Wd?Pp1+j1Fr*&>! zKQ#3WxdL{2f5Kx*L13ixLPX(vpoK?a0XR71CZhX4c6{}EK#$d-`D~ELZa90e-AS1c zNy2MCfbH9qF>8VLGTr$h&YyeTSStruc^0l&B@+W!lrs3s%?w|x_ zydumwlM^qtvrG85yPPX!s8?%(NXu>%r z9ygei7)VMNm<0p+jKjl6v%~v+IxL;ymCe=G=!3PR4{U3WUISevd^BxTJRRDpV87WkLDsH?u3wkTo$szyMXVFo_rCLm;5=~v$f&i%*uZd z=|#-l7l=qep4p^?2$ZziiRE@$W;JjUXO^aVjn8REpu7zYC4YmhHo~DhyD~O37M;s$ zYZzgKy2SF|K%7p2{Jio42f>=N*f1olFMgjYom2 zGlB)6%7IB6#}&(Y9ku22TdqdWEqvn+s=rBXA~LYB=iGTg<$^Hh&^12z&Ia6LI-9Tl zVQ6(_W9L$3tD(pA-A7H_GC}S<o|xr0nZ8&npV^J;j_CVnoU0zUxZuRL^5esGW< z(m)al@r>=)`}MZS>VWvDCY8BAS0fD=Z422}e}VHuz4(?IAK*j39Bbs)S*~1*uf>j@saN8o{Ue;~txtHIrpAj8D)u#;( zvw({kuUiR0ovy^Ub*teQ@O{b&xN}Q5n z>1XsnFZ`o;+ra&(X8e?2C^15CmV15~yjwTxqX*rgOxPYx9Gj}FzOrTHUFl;K0Lzc3 z1oT`&C_oChZG*krKJ;FH{OWxZWob<(l%#W52GYoV+<4Al9;flIVfbcgDVe0&A~W?A zqMgd{CP*%2oHd_COgq7!v-Z9H16&hz_q8o>KEImKCk^DGTf%||x+~KzRqyL|)-GlR zlNhL8O7xEJJt${_1NUj0G4zxTcf46HD&`A=TDY*RBRFXP}*-2-a z%v54oRqGXYwbC80o@6MZxwU9})3motLAwqu;bui!$FS%VZXiTsdsr~&G8q~MOuz60 z%B&O+`^SCeVWN?{xZKE(FgHn|ud;3RPi@h=6^i4E&-z+xLC8$S=mY_qcPoad^E@jg zLH@TA3Is1F+*~L6e(WDPC{x!b1E_stl=$4G$CdSC|ByFxJ-ZC7D_j0fqqodeX!!S= z*R!5w1;R3sF@u+R{VHxh=ZwmGD6JZ=(LMPeKeGU&{(duH4U^9xrC}voOI(lkl#j1~ z9;_xG{;PH@O;{OYy}S6d`mPV*xx@E*OdlWpLh1AMt8x%|hn{BAseJBeD{Gi-FYWV3 zoA%C$`p$C72SG}&a!aMgdhvA4+wG}2uQh};`hX3T!QBw8CC-0M?Z;x_8I}(p{wm~M zm1$@3io(o2XHWn6@Ne9oQ!kr#!}JE8>wbknfIi}6)VLn2Q*pPb1!Ymm1L=D@AW9!uN+gLexHt>YeYUI9We z(Fe&AL86YmU01z&xY>g9g~PIbkDhs$w&OvaDKt~GNoC>zbEz4MgYRM6 zlqk>cxN9Lv5=3?#RkiACf;(33tVRo09hC9G0Hfc{>m`=kI))nw{!0lz?#lhk>J8&d zv=M5hnj)ap#L;)Xsk=LB49(xY3_Ozu`)@y|b1&V(-an)}*r(r;n*Z7G^ry^Q9sI2r zg`l@qAus3Go@&MDC=f0mOgRmVB1UY^pbBCLS3+J&-A3eBsXU(dE;0hNfuY0CYN?xA-VYk{5Qh`fjR`Et*IurrV>6BKbQlF`*=}UQv887PR*!Hdl)YXlcbm!k@dC1tj&KWaVGUl(>>zu{?@ zPrB{0zPH|mN4FIjYhE)=p=2}V?lq?b{he}FVuqH!7S-hxvoe3S;ulu-T)98e9*SxBV)g z?>}?jXs0Or& z09D@AXn&-2IxPQ6%X`~LKR38H=t!JL1FxAIxgO>78%pt%Dk`S1FKFGwC$CH(Z0EYe z@2>GP5m>DJKwJkCjE;s+rZuyUhh;=f(XOi>PIQ$RVI{z0*aGct_fd93QggJ5r>s?d zi<`on(MynqsRf+7)HjhwRsjN9Ug25z6^$ok$C(c-HA%9@M_SJ}Ibl#)Daoquv`A*J z3m>FMoVXrNb3d^3As9nC1T1iqvE~jB7w*qr)rd1H%^0XHE0lJ5E)`N@E4HAfHJNQ$ zuUI#0SNKoz20{3OT4o6UcVT))b96nN^RYpvCi;RF;%fqn%?r; zDP*h@9<*ixQQ+T5{LE0f{e14bG5}pTj4%;cEZY3O;$fMY{yk*lUfO`DQGuJi>$*u$ z79Y6>PVd#z^{Z0(c#fs-_mlM}^YKzl`XCM`?LbUe_!B#CR%7q5o$K+-G6a)5tynpx znU+#Jo+d8t`}RlK+BS7)o5YQh z9H7afU_O6$YM1$`ro4KauW5w^RA5L7>nUoKizP7m&3kfgns_mX?HOjA!M<>G2A;(KH54^@@i~g&vo)RN{Fn)I) z!&?;n*}3Bb%K>)ws@YF07n(XWpZ@}f^Fs8FmA`<_*@Kqr%U-43ZS}>22$Lwb>hg_ClH8$)p_Tgp|Ew^GqG+V zFRV!BNa{z{BF>i6W}yMNg7ZUL?PI*FgP+4}r?>!DYJf;_awcV?4^4??IX&J~V*HF~ zvu=AZ3?)ZET^yhM5z*llCVp*FVE>gUIi&}2a7a-br3@}m2aiJI# z!CH8cm`!a4?pO57c-D{)yGFz1nv1 z#JvYDxLcHn>agS60aI>;lLC~H=vq@lm6FkY>aMxnrjg<~f?jZjkrnql(D+?j-|VQN z=x16Znh!5GR7nmpC>jtR$`v?|>s=0cD*MzUsgLgG^1Pa`zUM~1VsL-=G9r^~BHgIl zvUqN6%f`kmKss}U^Mva?sRc>RMEq=8zbSXKSHf$@xeJ@K2jHQr8|)ub8KYEi#qGGX+uw#6a1D&eC8n5s`^^hN4h{W@Ibwe3t>P9k zZ4OwQ2_Hbo=a?cUXQSjUO4*@+Ia4qF2fLXWi+kK>5zTjFlJ%39!Ol6Om3`A+m8NbL z)+|;zY)z*=d$2oD#Ik5nbvI2>QTB$QbgwW6d-tqIIecmxCJ9dswSj$@%W^GKZ$Z_ofD7NwKE6J4y^CAxWnpi-_tVV> zBh1w-V!bbu9T3Hm66ylWspiZ&F=C9j=5rJi!x=s)E>5P!a_kFn`>X*Yk}GF=TtC+O z;OusKy&OiocY->ZAf)_*@a+`qmUmGc^pUcwjRpRHzesZ}l95@3e;jWJ&Py~)uIHi` zwQ~Hg$}{H5G@OPNW8FKn3_iaE8E$tiGuB2!rbl( z^>;yRBcx$;mzhk% zMXoVWT{;;Y@4kzD#>~kpy}Set@U#~NU^ffjMjyc?q|Th0-H(f>dklu zigiP8S!9CG4pJn-pXQ+sx*9~iR2kP_-nrS}MWT15ME0;AImrHEu$zo=zcX@MQ5jHP zbML2r{ThcZWQ`4Ue>+!?Z0V6|L}@m`Y_FeO<=#e~I|_g2L)7`@>ddVFH+OSP(Fq?E z;}SHKF`2*W`z=!7E0e>Hv%~!(x9;~){uk2KMJsL@78w>)Tp1~sYWQYYZSTAG@EC+E z9(k^%=#S#1o%dF1GqaqY^yccs7oj0P)M%pTzdj0R>WeC2Rms*;nC_TXDXxbnf z(Nb+YVWKvJ@O9zZ3QHZXcJiJgZHTAMRZgml@LHB|td_SM6JcPq0-tTUln8XvletgA z1YaTA=t4AAxry5f-(zNTJ;EEP+sR=a^w;U6!X8v~ICy!p-Zw@ki*==4m9qnHUli)m z72}CzlnmM}pzrqW5eE@tKva1*1G-f`|5ys9w3hDrL%tK1Pf)&Mc8kRfmuaGow&{DM zT#Zb)I9vSA{+rjF$%M$P+IO{3(Kh_^~ zbpB+kYm{?bl*#)&RL&hStU0-ycI>6fV$=d2Cs!GZRGtckk59n0X{gihmc_rPwh9z5 z|InM!=bN5p*C*gPd+BU=@}{TjhPYpck`{TcA zl2prt-&ZNv`(3xH_*~ku#H0r)!hkdBRz_dYvP##PoxEgEVHyc%@9uKe=T>*ZZ}wj0 zi?L<4hxkz{(C0vs2MsRuflG}F8r_0~f_a9G0i)V!ZJt-+9E`X@>D31@;*dkGFI-5X zyF^aVM%fX!1pZ-T3R?+#agnK$cVzfqoFbJ-b7Drr>Rt&gV6Bn%3Yn_^>rb0o4z17C z{I_gkTUbd|;8oxJ5giBPm2lGxy67H+iwHxCSeNSOtJY80d4xd*FWLI|_=dOsGxb7B zW@aeOAq&O`&z-(m`jw0k9v$p^5>^WZRz2m%I)AuUiH}UvSy&D*$d)%)8+y_~%O1Gz~mTipWu+Tg(B~evPq+6#-8aL#Lz1P-mUbAT!zQ_~L5* z3xy-SW3g8YV!)R1*0qC%*$51bwfM3fqfkNnZw22;0P=E<idT36*|43U+&2~+W^ZXhYd%5VS(|se2~_% zRt3dZ_hSvA7AR41?bzG^#!JHAmv8ePRG8$*QCF_W0cc>Nh$zDAh9AH%R9JoCm|fsJ9}7Y=#RSw}meW&Xt`^4bDZ z9{b(Q4Kw%RllR#&fMQ(YqZP_gH12zMa=tReu(hW~cKy~yc}3%glPub{&GPo%bE+_n zwu4wSCQ6aRs283kH%)YA`AJH8lCv2=L6@*!FF)xvCthyrZGYPNCfelBt;Y*DE+fQ8 zbz-%&R}q&ktQ++jaG|}!piHF^f5+EJ^kDNxDo4m5y#&lBl@1D0JH4k?x;+cnR>8_LV1 zL-p*$FX-YR`U9O|D|F~{5qeX``Ya~&^X(O~6pT4aOH}{ZZGbX`!k6F+%s9&L$ zDPgrTWpYt^y(y3b&!lma@QUH2ncoLyxMG)4h%Kf!gBCCE@im`;gFBwdyrK6F1|3u~`@-qwgVB{6>CEJ0 zlIhdr3Z|LPIQ!({O~&S>h1V{;#}a3-ra5YOnHQ20U=)i+Amg}{r8aX{H(OI=rRSG% zbJdkzw)!~vC@5H-D)|bV8~i~sMJH+(TltCS`m$R8+u#bS;?m-ykq_*AjM_U)eOGx- z@YlPTJ_e~wEXu9c@bmXMDI9oQ@~n8Y$;=hN!X;NAO)JbacL-=8TaHH4;u+0ls_J{C zf`gOTt43*{;KLV6}YcY>F{OWF$FT^{Z3`up|)>UYc|z#E%JN+>+(D+g?bVzN0c!C z$Q+j$Df910)Wj2{;L-N;r-+o0R?UP*A{)~94SJ!eNu89W;>{UHx0%{vsM==w^i6md zJ&x=3`b~F3NQWNoFolA1@S1v#Y*jvr*}M(OFB>VMRJWESTts7@bbSlPf2c-ZkK>!| zm5pw6(n{FaTW4j~UwM@S!wi)xwr4l|aP`C-_g}K!=DfgcF z%5mS(|8sCchw^?H&DxN1vCIrnhn7pDCn*-$W8%Xo$zyzaEz^MSV;l{lR=*klkg^o< zdr**UB=;8@VpO7MBYIu#BIJ`O@6lvu*XplvOozu+jqT>WEYHN?i2k1>_0l+jgTNyYw%_QE8TyZdlZFx0?ch%dM4%bc4B)`kGl`h=1uaei*j}~<<_AN z4=v>WYBhHy8?vqHvrTugK^kam7OLHF^8R2bs=qIZ{EgpZ=brCCU_F;>dc%=xhC zpn{W`RoU87!Y&P^!+^nIe8TYP`I~_HgE(Iw6X~M|yh*85jY(z7Ti4@*bI}%y2gvZD zUDoo}3VwpxLYV4p5v@S%r`5ND#2EVC1}}_A0t7TGEk4X<##=g zSQe72iHjhwPAW|#dF+IO$+rU}9`2~1fk8%oODy>ayb(v(3>^x*!T&1o zQ$3DWa&kSqDVwaC5!R}zW3-YUQG@WXSsoKnTa_Ai1`Br)kEo`5uuyp>Liz*N~vq3NkjS?{^+~JJ5F(vJdzW(YmRU~2#S^Bos z=m{QG^~MGkQ`q;&?o}dx#5rqK%}f+*cwY`e7c1ENS{#k*H_WfAPeWv)G_}yXHM+G2 z?ZhYFmBCdmRU=WGAF@2lsj-opzW(bw_*+k%J|tVCf_|S0mBy5apjBb^sMN^nbj_Vt z@#WKP$D3{QB>HBczHLY&@oGnEkS^_e34QaXr(y88NiIoUyY#M{mW53{+>A9xktzlO z&-k46n1KdqPr=$A3if8Aj;5CfuMRS$nd&Z-9U2-P_M58S(>QXU;eoznaMkgH(D&d= zkzZ6H1ZLx%jdJw~ekrZFGO;S~$|16jH|$w54t&H#PvN7dI7>HI9nGFwRT(BgtX#Nx z5@Me;G7F-BI{LCJ>d>a873z24U0iOv`yJ1^Qo=B$)L-uJ zgh3M~*ZW4E)!h6JJn~teK)g>=oQBsMd`}RwP~hS-`W3CFWCRvwPW5`Xv&?o$r0Ccz z{e~^?SRhI2Xq{vV?MUY|-d9R&NE0DrIXr`2zFp0=aS2RxO%uc^C%b_1d! zM;h(X44ap&6j^sUaA7CP1EPT zUnOBY+p9E0?RX@uIuKkQQmioO`{D`B%k`a2OsA)gPvbJvBQF$;vnbP_7a?%IuXp4_ zimF6pb<+B;@oc5!^UK$##Fz6is!$z^BQyY}=~oe8Xru8=|3opYI zTe%o?wIKfMtGcqquMa9;^BVQWiLdU`FvG}phsw5S_y(pp!9;E(o`OLagv!+r1ke>4 zG#FBxWFQF?NZwahAaRCRU$$^3uRssFIcL~Ix1MRaQ2(9GBTXmw9p3N9-K1!@Exj$P z+^BO|=2j0;fIC^@m$CJ}n%l)J21rbjHbz^zzH#GB!f0C}UP`MV2CI`VqO?0{Ha+yv zrp|A6aR-L+9CAOS3P!#mn5gk`A{nRpD_iQh5=G!K2qXS8%K@(4ebK#%?>3GAE=h#BlP+|!|i^4*| z)1Xz2G!*d113Dh$tImOhSVumk=`)omT-`*EHhmj9p7Ed@G)+pXy{!W#n^aJVFMGZz zRn00XO_-=@gej<6fKw6qCXl*tybEs?DFmZYS_cf@z~pu-)SBN*tKu;cJNG8(S0LEL zrhSb)4Lt9P{OisWR(nB71nLGa&KnT^4hdbEo?2OF{H4Ug0NSkAdo?Ig(nKNEB)8SEvQ^utP?5phJ z&D(0SLyL03JWmGf$?r>dY}DSDD|pO=L!HVKcCojgW1Qt`#nNgx=|{=lm*5YMS_+I@oVQBmB&d;Cw{tgGOL6_F5)C*E5}YK-@$ZD%&R(;fi@e|& z9olqqbf^?I!9`&fo_YbxLBE6?-4o=52rGdJ%$^JqZaH$dKG$))Z^r5lmsMC^tSCcF zFD;4^+@8{Jy%lI}LB1f={J`e_b@)}U>0x8H{b;s2wBLLNVd<(qyN(G19Fs3A*;xn6y}4et zhL)9I$_j;5R{9w`uGIWvTQrKnTW-A%0gQ$Yq(I^Mhxk4VJT8IWqDXwUQzj}Ev9@@H zDaD$h@AnN4|M<*?)vh~q@J1iGDj2Kon}Sc&hs^~@<9j^;EENP)a377oWcT9^%}F7n z>JN@1w}qLUqa=01&KoRcTj^_xn)OEc;{@Q1ImvF}8%c3bF(bdivV4G4_p0B)TDlVA ztCim0f;Y%X{W(M8TvG1y7)#CzszP8Vy?G+Dei+R1)yh+0hdY_DU^&CY-6Dv!S{rpa z*}DUR&J0s*XSSnWZlWZioV<5B@{9jLylFJL?p%g-k=H?9jCcRn$hRPPL zk0313;&M|u5bTYU0R;g`Vop|a46^QjS-@F{gSk6d4|l-Rd~~tGWx3;Rw`+Loy9JqD ziF07}UUil0q37_w&xkmvkF!H#mDS2YXpD)5VO;Drzb`IcUyZF7%Wutg@sH>8eSdEF zq`y7Gj%I8EN3un2WCe%XrkWWmrzVIG)g^@<0R}|roWLiCRA$?st;k;RAQlrG``Ae= z*)7hQv5tW*?@g3OcYf?v^dB=|x2U?Fb+b#LMU2(y(P~g4ljm5?+(zlxY`fRdkFrnV zWdJ$2fa^-D(*F93ZFOtY3h~*80Tqgd)eAR72@cSyQr=`)L(ytFs?b!rXmC}SPKajy zC}d>JY(vUGy`0U;n<5JhVYba+eo7TR|2r)7$S8~2`=S}%7@xw1A@u+w$BVCdoB5;5 z`MkLj1X%9q@U-1!pTAgKlv?}^Y*X^BQsC0M*&_}6c4=F=c#}2SdaL~xpbrwfe64$a z8xm}Boh#?Mq=CNNMK_Jne~OA1*(GrppZOWYeL=-}p8M{~A&Qu?t4m z6w@P;TXR{K0Z56vObBkx@0mep$xQiTjjh9#-JJ`cxydr- zu1`}*D6qAt(d`|ZrLWERq+!{>FVK7xxn#Jf--T!T_AL@b?)e0Aywd7blmGYEn=u!IvN{@YywKU(*Q(RI(+APrt4B(QHAm!$J!p013+<`& zD+&LQj@&=rCq4h9bdY}GSr#+NXi+rlc;mLP^!g$4uDayCSUrV)6H8utyn$<%EEmnm z#l-=3@??ZaIi*yRAPp~d)i;~6I;#Fe1!ndQdKDi);2TM?AzwEn<2@vT9R#ErFiaNs zu4rap+(d1Mc*79&CZg8VCp&UAUI4v_l@<(M+xUg;|577jjo_t!SQ|_n?a*4QM4JH=1PAzl#K^Y`4S!; z!`|&hNVQS18bQmoyzx_i=zi@!VdDFE1~ck))0p+`S5h}`)p9cO+EtcCU-0V+xrS;t zVwOxr{qmdj{RTy9ArM5gV&CiXcrZ$@wV&9Y?Asn~tc0~v5+0{9f-Y)sze<*(Ke^Zq z7w_rKjVkHlW+&I3iyd{f0rYvxJG%B_2(|ZQv3Qg{Dol|0{AZV;Eykn3^lj_wLcU~D zB$FB$bZ$5KCVHptk}4{_a`)^Wcdly|YVBhxFP{%a2i?wY)Eo>0bh}gr7aBi%lFD3_ z-Zq3$E#Ch8rsWMzp_Lv#g#;rtATx01s$KnHb(CqlAnH(YEUp31Uj@<%OlyBc-G#5J z8mq}5T?g{=!(fb|j*2@OIGwJ)66AV9EU;RWVFPkTP6JoC>VoL+dn=uYI!9_6qMkK$ z_myDtQNGtw(Wo#4U@wp+;;u+ZQ$?)V+z0cKswHoeO#-fiL>zeXc1H|w-*mOPPb(H1 zIgV$y4oidg;k_vPD)u73`Bl(zNzqN#y%=Ej3}w~4QyD2z9$dR54TsLz8G|Reb~hZ8 zx_JU3apcJW%*V^>l#|4kP`0ZE_3g@uwfaI1yPERw%C65{%X-!`#M0l(5wZQ<^zK~D zttWq5n)({ul);ldMLUDiCqZ^r+H4k!Yb$%k?lT zS}W>Vh%47~(z%27o>K8&c;>ETkh{H~kdlxAU!4&Ai!t@E?d0&yhHoi)Y4xn69Ma*Q z3hIilw!BS$tIHm@?LemH==r_`w(A-_+w3yyGw3=A;x#L~`N@Dtap=j_>sC_edee4Z z4nz&PR7fCRQJbD!Vq_Ngs$qJ$Hpyp;F@XE{;a*+{1WNk6C^0|}dc!cjRngz)XWmDqnf!nZncjHTHw73l)wRRVn`PS18$olbvicK&a<%q%*k8v3G z27&d2;0ru=xgX3suG;=L%6%CRAyAre)2gAw+1jd%U!5iLZWb!ns~gJLSKxnLPu98X zOufDvUQ$cHrDs=qEwNa3q}lM-be{9yVdx3h5=_FR!+tuF5bzn{xCZH`$z?Oo?m2$_j%JAWPDHDks{0} zYKGc)fWiTwKJ9Zkj;q(en=f=w_^GKP(sgwoeVkf-0ebg_5;*lnaKZODniJRoi);Nr zaeJzs2Cm1Gan&3sb*#n-#@uS=uACk}bARn2`1E@9(ZdOvST*;T zje75@&An^gu#f#9XqUkZtb4-^lLF2^Fn`FHxih9UV9b?!4?*whXsgN)U;jd6?mb}L zAx2A2vOl|WW&3od<=tG=YWz3Avhsn&8~f8^AYE!m^Sk&wFz7FCYhIe;b8k%NJClv# z4;>P>FQgrylP1Oj^q2~|W4z;eq=XXO6Y9f=GCxDcwYHi}NV)GiCuuNwOvi{i?yqey zuj@Cz8uQ0m1Il_D<=ys<1l4LVl@jr+Us2V%u9iShFvur0R$98)%-)2&Z&K8(MBVm{ zGN=2NMxzdM{+T0}M$qTY^3bX}Aa!l*4OAQtw*CJXi_yBFh+4-VrPbefIWPTb_qE~n zn~zv+B68Y9QOAVUtMe}=Oiiu7ud1^MxnEgRy9-+A_V8g8MWHTUiHHiGFy*6E zW52xGz84+Cy|$tijPcOFR-~thzh`-dII>E&f91IXu@8UW`Pi{I|IEgQXhaPi6P|V# zr^s*#q(n%tA+a)Wz9@ID;BUj3Dua- z$7@D^BYQ3hoUrIbpTUsEuEy~6Dhkj3{6h2P5gnIxuZPd%F_0oGY$)xz*Np>((hGBr zIXLO|pCxs{MVkTQx%zDRvACKSv_K)4W@9Vl=*X#Kb z79BvfS)>(Y<0A~zyJgo!JN>%)D}m5?mNaC+@brnL5~IG}E84>So}H3SgduT!F1-R# zh?i;M0TOLffU|Q&$8(1z6eCWWltZ00f?yBssI@-Z5N8+tg4X?69Ix`wX`o(sd)f04 zlYpsqR7;RBGjaMdsAh5R4j{bkf%Gbmt1Wl6!=~i~NR#szq(dLd_c9}JfHxB+2&i*C zGB$h(9CL09e@!aK?)Q34Uz|jYaU)zHWU0t*WXKA>>2olB|~d_C!9`$fRUd72oaQLR+yYwyk6!M zp%MYE_(3a)blw8oPz3gRPYMg;fJ}oOj=_A|wym4kRUi`N6fS^b7hYyQe`4u|3ZPha zLqwKhwF0F@GRm*xb<6yXEk!q2er)hfYnj6$%ietU?P_P~NRX2fUz7G!J5A1F{h}dp zh=|uOgXxs*iI(|=ajjK+d{hfPq9*&I={?%{+*bi_BSN#WpGlMJRe@T#`fp!!N&@Eg z0R~xOg$h!$1!8$q5=`_ud&*yTaV_SKY+cPfTGD1Of2Lt|Ugdi>;i|I+G2!h(w1nBH zwWIJ8Tx4+B?ZY*7*o1rggS_6@7^+o*KmiKE9sy5utnh^Pxkk5^ZXAkA6$&Q#TL!AWIc*` zjHh<5B4mu%*|DK8+>%O&YrJ?=>N3MkKb~{LxTtHBPv8_!tw~0U`_LFc*kY7E=lw&aChFN z_7Y{B+e|4P13SQ&RE+p)!SLrS0u3aC@f+iD_f7 zqt0%Q=Cf!xzNCm-6lBi+wibxVC3Uhf7Sin)Pa;t|5%Y`zRY<6RE(l5nAJdxdTNdQM zCBxKD-p<^B80|J4r&X(HUD}OS(AQPZh6BaX$D@Tuj4AFwU9KrE+%=0o_X%LK)#YEc z-FtUycwW2xbf5{!NIM?#%dDH*1waOl2T$vm0j9=7c_3O~! zFDU!EmQh}kuhWu5#PEueX%cY9=UX=yvsW8#avTY^?spxY87lsA@gmPg*I?=?anZ!e430qzOTQ$;`yL);bmFF2%f+%2N6=G}Fd zl+ta6g?H?l^`*kzMc_Z>dNr&}@XXv#iI&sD@)7zjPrI2Xd0Q2$y7@a}t!mFz3)w3w z9Nw8LuGR|EAhUFh)KfqFbkkfK?!frxl){uemGps}t?lAWIRO>a?-Wk*1j;_BP^)1_3R}LP+8_IWpkRk{bN3)*u7CF$4vXZhL0DN0J zy!-Y=Ba^bu?q|)~HH7~UuSfZao)t_;PH~219N9)`u&lGV#uz=`a(KrA5+cC z&=@$aW6vSu8a~>}ISlCkFnhafTs|qri-^BK1ITz$d06YY~o7nyz7f;`N zDU={58>J--UQ#_ARlPV_%=p4y(mkQl+~&vg;2^^MgO$P;7QXSJqn|@{U?>SRXp!WE z3|%vloMxD0&wt#>4U^AD-n0%322cJmwEEpZ`NGm*AZFC(TU5O2?#V95FqUe?YWTC= zK9Hzs%bgEUgo$`AV&;?7N%gq{{Oo>9osc&9$^KFXh02u)igcc=OixT|ng@)}J`2%; zAYEEvvP!G2KZu}h0fFp)%69R8Hz>?KZCP=BH1PZk5sR)~_yrd_=;~vsg;hQE0?77H zEN6`VlK_tdB7EJx=#2Qw4((}hf%us28XR;0dqL+c#Ef!ImF2np#E!mZGjB?*_{m%= zd;{oIC^z(nx61^3ZI8a|1lo6)le!I1i*9Ty0KZL$7m3xGlN+9PM>@#+jOaH*bneEU0zc zsa@(Z5hVeh0r0x^MR|(pINJr33yn&$ozbz@38JKUF;= zMizw9`M+;?FGa+lo>+EcnTG4Sq5_y{ZF=d2TgJ`@cIEo9rfOXZKY&vrTj(sm2n?i^ z0Av~aZuZfAmR_9;=!&$_$`|jkRA0fh{_d9Qj8g3Mf@y0{6q4N`4d8+XUJ( zR2A;`QVd6yYKC?=#LcBYt#6+FxY$>r;`Znh^T&cJ+WesQ{Ey1nO4jWKlDQ+*AlZA< zZE0k}D>wh~Po3|-#jCJ0HHCY^=_pZFxBswDK5GZt9lMp5*#Mqr@RDY<+n4Al_B`Nh zC^`H)8z?|eIv++Jjv)L2(0hCCO>=U|1jWY{_nelt(wA1B1V*!R8}M;IxSk{D;4jC; zmojz}UWSj@j64C6yR-JKwA=ExSlmwdFR@Z*$7G zdWDrXl8i>G{>i8eb>H!M8=Pg@w;@FFbvtr{tBSEuFK$6@ox*`OE#+P$7H@qGPK#DCNuGA)i7=C}x$a8SD{{udLJ zd;v)4d^q&$T!@P69}5HLaTxG)B`f&T6ZN<2o>NP=J3qbjOB^h|j{Sy>fc8yok4&qy zRrq5Qnrs>uC`OPS(J_SX6+M8NpJ)yDi-zqMK`vrtg%mq365c17U;V>lrDIMPvi=sB zQ8rNEwLkP1BybH^%{+f%tdAk_QNt9~&>L7vBU@iG`sO4T4B(B+@o`ZsOYiC5Q>wf? zF32SZxA6z$f5R^s0+Z8{XunT>F?s+ z`xO`!88g!bPF^R3iwU#P2}jrGH@AO!E~d_UxY|l)gjbNV^3S7G0$;a1PBBQEh-+WE zH!Qb!Pm8MdEsvO;_j9hEJXEh~72w!+&h`Gwt>bg7|2U?&zIUEafnBys=UgcPC8kgb zrDDA&9WN>3>Ao3CTG4+1HbZ6Mr5h;_pJo0N)`?~=Ky{-yoenAM+-r!lJuz>0PLzlG zKVp<|E}s*8C^T?cBqzE`Ff!jt-JZMv>g6JyFoei>1?+`}$b_e<@ZsCKoPoPanUHql zXcUkvF(J#1NA%6VEVo8Mx_w#lcYfB9lgZIA6|>*VqG|ABGDld$Qdc1@=UfoY8#eh{ zsDeobHxhqkY?D2&JLVl6GlVPO(+L8KCGuz~bneSwl{^2`v2OU^>0Y$si%tpz6 zM8#12s`Y51Az7yQfzB)7+50n6N2^GVkU5;W%5}AAY{ETwRA(&w=a$30-rHewI%CP@ zhpFM5luQobL_O*RUM}@znDFL>L`j>!F_6PYMeEHr^f8m7Z6)CVR7~t^{8&|kOqiJb zW;1Q{BkH+t>a)MU>b0LT6($d|F%a`Vo1QyVoa<{Krg)J`xSkEKK4~l zNrTKFSF1!CZS7mcwDum}jZvl=_EsDS5Fd065}4JZ;xCi<-E)hLjf6MyOZzihdBV+O zjvX?wig3lg2McWnjPJ$%V))#6OaTbzz5j4vZ!B zhArkb$h&9q#e)iBvATK1L=5038?)BBp471hq7oN#etwZ%=XDzsF@fdJa zq>Jp_qS(Hl&rBfET%@G?tRUfu;puh&ZK(9+@+q%Q$xAjbP)mYCD8Cw`0zYu=W2RJj zeMP0j4@y7t@Ba^IyZ=I-#}WMmdKa6TDC>7`db6A+==rRY`%(`PH95=-NQvdm} zTSDfEOwWY{rA5X)sG(;shL4& z*{OkCXU2ly-yxMtUG+Ce{ugRPML)o@_#PST2YlZKIix7^CCWImo3q0I>)QaN%`_w; z?A*T}|IT?{nROkXqg>f4H=s?JzgDB-?&`tTM9>z<-x!soS5~`TACq?YJn~JM!gMzI zQUvtr>pRS*8LSUa=Dyi*n~-@--Un#n#TOou)UKt45t(=w4ezFPv*n(W0CG(=*q6;~ zbhEQpUiAr_w!3KZvIet@y-V8x(-h{Pr=+@_B4*hMG`5*yp-@tn8jVkX|4OpUe{;;= z%%!WRvj2Y;zX*PIxV!8|BhYQND8=DyHhFhEvt~e6`L}$tGSN2R(-BW@JmMZSLefXjhhXpAf!j~ z=lIsP>ALxG&Mp<>yT#GvxuS%zJq;tPD-&Zn7m_IP?136m$#~j1i^h(nuH+as82SZQ zf-SuTsUAkOwjT2twW!~kZLYtwHd;Z8*CvF)9(MAI*9Q)qLbjR~T$3LT*-%ady(f64 z#D}i@C*OiS81N8r^!@KAoRh+1?MUKOJZ{>=d811EF}vQx-NeQ(R~+;PTpsIYYxJ_i zaL2^$a-KV&Cm`Y}t8Ri!GH^vp+a3UAGcWeh@b54eaz{^n*GHav+S!jh8*&mm zdmb4Hiwa(-_ z>n8L_L7Jg)D=dCF_uey163*8qf0rI0yzeCj@lmrEV)B$3XJ$_mF*T3pBT}OC4Nj4ben#YX(Wo*KTpt&%o1{@WBM)*NLsh#xcw~RI@st6KYWKeP(o3;bBdVx# zg@R1tZq<9u08MSsdQE4rOnc3w>23G5no1R)c5HQY9h;;GlIISG1)r82^*(optb;%D z?Tpq6t1i~6?nKDy<@xVQ0n|-9XD-B+xAWiW2UN4;T*16AQ{%VT=>ip6&=%FgM}-42 zz+!1!ji_>ucpyUCiF!8K^flg{yfoQYZtJN#cg10^Ps99^6oJygl`HsuyJ0cu$nQ>u zi{am`z}99}iLg4?0{`HRSL%zxk^)OkkLoU5gOP>9QWAod;_hu*jE=}#sCULzp=u0= z@?;1eB1a`VU-ka{SkcPlv0l#dJ#apzPip5@YO(by3HL9VN(=W(^bQ;Yy7`6EYEHLe z&5Mw;hWw}4F6>-Gs6n1=W7tZ3JN z2)MSX=!o%EaGd$WVAnM}`_MMU&5k20!u?9;a~6umwNSWwhaJJz2L48vnOg;z5(C4| zeA?Xz^%HqD#a@CE%JIVS4qVRH`u-S=V*GSvyaYa?yW3Utqlg*W%S}xy%}Rxjka?b@ z)Ek{b|B1@aCm5KdN6VBj`_I=l{&r`HtiHc0Ih1fQ-h$mo;R?KM_;X05veMm=DQ-^) z&9zp>bvExy2*+5|f4Hc{=;8;37v3oK=1(m+JCJ0}TO~|?pQ)!?_Q!(D{bNh8cqOY| zqp&p1?y@6g9<4w=RHeq?NP3e~8`en~wvVfpiqaeHj{m~EfVg9_>l*?Lsa z&u2M#tHg9ST(@_>Uac4$c9RM@ra%Te2JdrAgt7R_{=H)AxC{gvmV2yu2={R*QzM+t z+UhLKrd97h$(UAnhq)U(aCYMP4K&PmMYo3MhCIe8+O*S$A2zfj4WmgP%5ly=jtEf4pckKVZo-BW_uKZ*WvwvH#X)@F$^^lg?if>dX+wv^j zZkK}=uHKqjQMi;9qIWf`^niCb^!|~JHnfQ6o!F6rT5kmzxa_pg=Ry?=-WO;g2df3} z`t#Mj)}yTs-4zT!58%$Jy%wQgTtCGVVWswZis$i`u!F3qRu>X~o1s1n47RR&eXRwC z&@*?F%muShJa@Yzs`4F@uQimrEogzJ6|_Bh9_ zZ~D0k7UC6rVNtPN(Rnd>@M7%NZ%fhNDyKPAoSgA>T2L~o7cG1{%qqZ;K$aS zXR)aFt80u(FOtJJt)5q#{s!kLRdGpL!cBNlAGCo{tSFIwP^(LI{o4w&aW&j3Jn`0d4 z$3wBKY5p#ykUMAW*F;3=DgKW@Z&drT+-9k12>>$MN0Bs$vg)qc3*;73?CwM|#;OTJ zfzQt$KIc+dgPePNS^U5Gvu302QZR92eXHm}@NS8({_L9~qplHKfe3+yrHz23*y1(o z;Bn@R9~nb!wL)dCBNdrG`a+A{HDium$hzPTcsP;Yg0!DjUEeK3X*%eE@dwLRP=+JQOvZHW12r-EcZxsvP2*t zADg~oO+)J0?T!7xTu8!x)p*b^SGw)|h>n z`zbFxNB>q|2MOQr1YEQ+H`369D(3SUv6Z|&` z^1WZAl}*LT(aV)0>m@)%RVXzs<*_z%fvnGb2sR8@_&IZd9n*B7?eNi=MVr~-7zjM% zeY`FQh6^T!Q=^Z*z}(p4mq%+GrRjUg-Z^yQ+1~i@aU3S>Y$+4+>y19ZKCPs1e_|~^ zt@dsARB&{=D?+%ln+q7V`_(7{rmYg0=Yi|7l#nH@|Nh96m;Hc_kZ6SoDu(r>1y9;7_y~aZn$=8@2Qc#aM0|g)1(q@EWTo_Y!8VAL>^eJdo||T2ZOBYnxcOGcoir7! zmz(-;MU36Vm|NLUYDtq7)#LbI0lX^=WUlC2@$SjGPEAc@=JirV6{F+X!@H>QGmq7_ zFk!Bj`kItvT%mdktWl5sHy(z*VX@a<)J@&xEc9LT+{N4Z0R`SiLY*r2z$y6x)cs85 zn_AqChINs#F*+6RwFD?<6HIBqzNP^eB$+WfJ|p*T$YcPF#G?S2TF)bD%=|;5Wz$Wk zUu(fN+g_hPs!y~l1gaC?@Pu1s_VwPMz3BCnLxk7{Mz4FS7j8Cs#+6hmmv$-gW&LfS z0sdSfM*F*943J1HHnn~{K4~p|FkpH&@+y=LB+c-L`Lp$z!SPUjSTk@OZgH%w8XTq} zoBxZu2VR`WD&6$q<@hAH##+~T3oQGWwl`qG*v^t2%`pemy|aMs%Yt!9Loax>%c}?{ zva(Due|`4O4Y8DSH8L*i-hN{)h_8l5`u625l7@ew^F%`t2@gT^WJEK>&sV({?Nj0Lf?PN@~=Sw+!o*HivI8Ho(KTt${7~Bbhu$ zuz9d}nkHW0#Cr=+cV7YipfAb4f9+XQ$=3`x{eM@-aPqE#YqWQ22c`PuDJ@)rR~XU$ zTju#zyj#+Eg)zQ(2}nN?J-WLIVF}8BWkq5$8=- zDvJwL?AmPA|4dP^2-|$vd9szVoWj?@X|zZmeE4!SfhG zKmxGQ(468e0g@HQF~6>`s{$E3u8kvblt&E;S_S88PDoOOE=<>=r4G`9U|5NO

<(~5nQt6#$XtV2<%mDxpSG%}bgeo~dXE_!b{9y}TvzjcDLyBzL-dDZDY<%ytW-*;*bFU?LG1)l%^sI)T=eJx?`8`%idGB zy@b(LD|)pk^5I7gLYY%ZGn(ffQ*1NLz(FK)#6y0r#1i+a@fw$q05{JoW}kR&T-Q6r z?gZBPY|ePo_S)=3yuvuD z-?rAIbfk2#NO3JIM&*63*ZoRSb0Ew-nzm>WFKMN?_uzbA2oExY*DJQPY?eQ*ulmdHhCaRm3DLY3 zHprn*CBe0Sc{vqIlScQnRLVxM)54IpL1`|yXq-UG%4zK26ysKSyl4Eiouc}4q1z!N z#)5m;N?Qr1!PGhAa0T#k58rkxe%wJ9fQeD3E%ZJoS7~Z?70L4UZi;$xIpj801`T@C zy@xlJ-(5UNDWVOp5TlY91}M(4hPSPL-{LWHXrL&$tPBb}b^YMvw?By>YDafN_0{=d z%WkQ^8E8^0OQ2o~I{+$q^aI~J`=Rs!zT`GD`$zNPd-iI%wm zQp%PnLVl3pH|%lCJ}>xOJm}fc!K${&bKe}jg=miovOtHEeE`o7D}CV$XDP2dE^pz0 zL{Ub*;jOI{2Jexee)t67h;n ztt(7uZG;4nC!?*R=VQx@o6&jPg;JjT%cJj49o4%tolfhO2r~)4d#lNDkw4@at?Kll zkIO3<)LUA#LLgrt^IwdLXw&0gI(mBwiM}c8Y(Z-rni=cq-|(*bpQ_Dzf?VeDr5`^l z(6uaQDb>TDQ%rhHJ{$}{$#pzpJNdf%`jg$Igd!Dz?v*pNE4D`pDe-i;!-7$s*3}Yv zW)&)^e>rxMtbpB^V(i&o(E|U_qM2o2oJHH*D#U&zLk^a}#4lJR5QMA(Ff{?mov}co z#peQROjZ_c_RO~W<%f>=Dzt^RP)~OgYO!tKC3bxVFs}lHAtTxE*;}WiK`hTS?x|IZ zSIJ%TkGP^1cUP}=oLCZ>2V zc>=+-Q}AG#)i2|2UUZWV7Yd&a)qc_^43XU-_ONklGQ6Zi6+8Q}9@wyerx`gTE2W)Y z%y-o1lu+J96+F~Zv0WiueiH|%Seq)ZDuooa;0%3J1@*K;W#gW3eFKyWd{!ybL7S_X zx~}Ez=@U2eq9J;Q60Ig$-pm-3ZH*WDhF*MFOr-6+42ZhGf>TAz-Uf@w>e;rG{l_SA=o+C=hiIz`psvK@s{1{LrmIgY8-!3=) zWQ(Xzpm<~K#Byj+X&MFN#$tkRuqd5rGyQIDbm{x}TIR#kVbD7bxgLXoTKdb<4!JE> z_4zrAmcpJBG10-r64Td%|-cBTz4Qn+k+x z45_p@ddt6Sd$Hv=WMj&uj8pR!xt^!IAG-1PpF&)nPGH~0LC--*>yH^wJBrsJ3>z3FVJNY123Oa#W6 zlR2X!O8Ob#@vi#2w%JVqJ%u!8^~`}@h~?H<8(zW$T*5|kiT`$ZTe3D3#UMVP3G5=k z>KY5tZapbaM@g$!5M(0jck~jwqs^g=uQQi#cW`Mc1 zFd2M4?BWGvGA7<5ViG8axJ{E;ci9RdOz6XosbaoeS%122NzcNS`B>=!XZ^$EW>MK# zYsS-fYesx$rGK%+0_hQ}-#8|eG*Z37qI*iGnictO&@6Z|j|rlmkFE@veQ&M}8Sb;v z%V*{aITTjiZ5^^5;MvvG^WGWZs0=8ap+uJJ7QPj8zuagXkJAQ^a3$Q)jL@Nr&Ql)6 zoKKz)ExN8kr%VWk0Rk6TS#w<|KA?8V&iUC5_>%zI=5!sKK3(fN#bOK5R!P{9;$E_= z)0DDAlu<8-on{}+=<|InV}wtO4r=fCA@?z;51@U<%u|yBHJ?7WyhA_5~t3IUA}Q-p$NWh>FdR8e&MKjR*18RE8pbFWTzMzdss+)Z<+q`!Cg zaG|3WQoQ+IKgLzX3*!Q9)=`45yVcGCpRt?+^5=VvL|`dNG5JWm`mT`cLVEkjg^n4e zHdE2wsMqQTAOaICWox`oE|TUrA8@*(%?)v5oG|ocbYXnPyjC#?w?lM@5NL{MWs>w> zJkR57AS4lZ*@f6lFy|GJpFSfgAe*40o+aWly0rXN%_4$z*T2wt%|hUGf`qGmlm3!S zA`lscqZ6P8KOVE{vN?BY!_ZV9b6AVTGZkXstGlI$Tl4ROIE~ycS4-htD*3|&wgi6C z(TP6suIz7nN=ZZyBRk<0eoZb4$BRKdzvv8kB`4uRPjkLXsK0H&i%6t4ML#ncs$hlS|lc|$>wZc8nmPWCywch7r;*~*; zy}qQefO&!Dn_HK?+)Lu&ySLZ0pV_KX7dXGgD53*AIDQ6j+&Tsn03b>&YjScuRP zdo2eEFT3z&Ji1+q*DMy?YLMrMt{@UN`5}Tn=zY|W6XW2v3~-?$_tNq!mJUEov+=F4 zM!8Hi=&y1XbXA%r;cZ)zGAsO9=g{dTW4m!A`*A73_X zB=(eW5U;ZBe~#P?{5(8?CB5aEveI9z3BaRs5?K&yyXS;HvW99q}gTqJsg#M9u#)> zxT{s)a$dBaeyJ+*L4r^qT{}V%LV^ha!ZldB<09d<}GWn zlkx)wApU@^?}b?A5=d`Pbi4#ys4Y{)N$A$p0t-&ujmph~i;nYlmk3q&>J)4h_|oqS z0++ALc|l9=NF_+V;yPz45k!qGK%qJSZ#&q)RCl_ANo9HM)cJ~+Yn`3ib1y~=yrtVL zA{k6PuQICDy}lmp=$5&aX~abQj)vnjCx7Str0diFrEopX|NefM5VbQ~y1{zE?rtBN3P&E+KIk+IhE+A#-RZ%h1LLWTZ{u2)>skRSFyie^F^Jok^V zywdVG=qQ<)x+@Di)^&iJ<5nAsM%=IiDls76y8il zZiu+QA1E}4+M&vuE~$UXFH*CRTgUTmO7oRLRi1NvjzOH14`M3A5=?}qo&JhSFO9=r z$E~F2zvl^mXL;ojfbmZJzL(z`R9D#3TMF|1t!mK0quxZxZ7tMLhgYRDj54+GPa8sK ze9t3QpU0Dp^cN!?o<`P0s1M)n2HN=BvVK{p1W1$3@$a>_7v4LIzNZs*z3g7JYi=1Z zcFz7WDAiicmaR%+y`CmVa`0{W9OT*e<-wI5CQMf{*x-d_FoJ2Q*enmM2>n2&@}QIN zq6%5W0lavyL_ivthq_u2@_1)VTjEseR*2NP#398K+!|~4BBPIuAk0iFR&K?w`FHhk zO-9LEo$FdO|GtkAg!lr1w4!i{gNY)5xmw_6ARw`xf|J;ftauaz%4wT$cHil=)mBdv zv^>~v92JP9>D{{zddDHGa7J}8a+Dt|1W#8rGRpF2*;jDdPv8w|U{VRTGQ>B;SvUWY zkn^`3+#+~C+qk)0BCndmEqc(kZc4{!xNYbyUf)-2eJ9}e9*{Xes61Xf9<2yk&W#Dgw4yFrjdS>RS0-9(>#o6?0#cKn8?CmN zaIN2MN=@213}3&#%XzJ5tj}+`$b)QA62JB^I9t+c-Eucw+9}&}ICX_f_ge_d0;$9> zc7cr$3WUbEb9Sc6@j8uU&M(I8>IC}@pNFG$5J8lV=y(-DABbuPpS+`R2cpKv*2!g` z;btJQzy$TDmBfSPKM3S;KMu1#9**Q9}6w2LTo*%kK$!!>^`^!T* zCnzbP^XwuVtvO+>TTrGULtz7&+@`g2Gxtx0H4yD$s<5v}Cqw7n{r@Z=HWmi$-`vPY zK1=tIPH}Dt(^$^Q?ZFM-RFQ(Xn4DjH@iUr>#Dtn=l@LSwZ@irgP}H+uzV-?G2hX4JdzL76UiGdVQ-qui;kT&+>ayW?gKT0Yz4^i8ni>QDCY{MNs zIIK}uG#;<%(0it)P9#X~Fo!)TD4bc-4chOEaoXh*L!M3PX}BfVaxK75sWjc(LnIlY zxu%5A5v6nuMMF#_(95I#p2ZOBJYb#D{JJKD6VY7P6SBpKOg8K0JwvwYn0=N;6@~QrH*@;F~|1@JD@YBiTw&cOMaJVOD z$-n)GPD5t;BSWg<_2Y(?&Wk3y{<={Gr(#&n54AS{mA~WqVCpBD``x|50K%@7Gz&fRqy}NMj%nh`VUxLc8ZPGJS zfMKK4u)J8yA`$j)Gz z{l)qWMEoKMLyu!d9;9+95&M$<>#K6hYR8y5Rq-(t17q?r278eYL&8|KJ0hH&-x=e& zB8*RznBtFEAZ@dW5!!8Lw$4&N`9ooEO|YZZNQijViEG%A5WnT+(OJfBtR`A>-Q9h- zla>P`jbX}E$v{3V9L;1c0=qj(dKn8D;9KihycWf^^d9BKpe=%0S3pfe@dLXg)uRQ~ zIwH%YwFt-JXQGK|BY<&dELa1;^zu-bgM+RTLte&0bfiwhLNs-tQb~%N!Zmp|-RUnj zIRx={v@A1VUoshWwPfb=`k7s0`pK7*&K3U4s~eL@nQ40Tpx^K3>e!>*3hjG~6LQrK zwgSyoXy2ywa+A#BBJM5VW#I*L49_BqEYIVpH~a+}JLt8V^n#;w+~ZNE_ z?%lG^jP7VK>5Q@oJ0hry8iL|20NcKiaqC71YRjbtN&W`PlHWVdI7rwkfs9w^|)eJB)ZEu+LUHu67V`Gt4nVi@^Jln(j0>|Em~=?MY`Qtg|jW zo3Q|D)$!_x6)8V_Ie!*@JW@e%xjsdPjfW~>^yennEL|tE3cc6lgJTJIOG`=x3qp~S zA`2GVK}$(nsyUQ3%XJ2g{Rqk^xg0Kr+ zZz~)Wke{_Q1(;xtg_aeCAGy9*&$KS|Uu-S(uI47qu4&O5?f<>j!C#GcELW>tvWydVZ6BdiFR>7kIe5Ag8`9L(|32+An z;&fE9U*?uu@Cm@!{38lZ4FQ%lxh8}rmHmYxq2q_w0lxs?dpXIz#-`j z$sX9}xp}$1qvoZ?_c+0o=d{i!TXL~%LF;I#;LFU%3s<>#mw{v^3Q-w-UJ`Lo`m}5D zl->al-oO~sA({zURul_dW)RC85aREnd5zfw#Sey=7aD+w-;Y%dpCeSE9c=NG$raO( z97(-BWvB~4=5WD<`ZbJxd#))Zt{-8$*XM%n4pEBuL1z#2lDen zR{O7$T|NPGqX#28`7efLO)>0nq3eeo_mq=#Q2UOo8=!HnW4Eph>pZp2Vb{|*#@k%B zS9O8EhA$er+hzajoxDN6jHQx;v-1wfPeH9f8A?txkZADaC+PfYSAJ8Q=xJ_b>f~x5 z5nwh7zsyp`+ z&fo}NDedv0w4JAcio;>M(R8NJh1sk(!ErMuNSz-U2-oY3Tl(H!Z6F};uqVEuSU$-a zL2hSr146mL9rWj#4Yb>cuBTn?sk|?iSO3`G8|2uHI5JN5f&+|%l*)~B5hGt`gs z*I~@RaE`$%^UpT^<#`YO84$oT(73PG(9{wwjAYA`zHj^Fhb7OwgjC)D*D+IgBqgAu z7V)fbtf4EU%=%y@(@FrLv(RvFqY_DtZXKW(z2{cjTQtmTqFAu-_drU?@m!_x;N>1w z*j>MavQB`(;a73Q2`_l-fY#|}3Ui#-{+hso2f2vm?3N*)%H|gBE7hY;svO_`x9nmU zH@FYTlTSEo5Vogm3>MB^h+-$xgQ;i&g`Cn@DwE!wUcSbF@O74dL;q1a2~=tN0sKqB6Rj&d^(k)$nuh^06`oO zlX1Gmiaw`Er(jHywxP(bNH4|_!^&kG;=AN@KzRX^aJ5xQGHHpT~Lg<4GX-BbE+VZ?gn`)yXR_O&bLNJufG87RWvwSTA5Bgp*Q0e=S z&n4K=-oaB4?E|uwWbXKJjqmk*{RgY{^-KOM%!ldmS|=g<6;)0@G!Jd)i6zC!kl^}` z{(!!8iF^APVIArhzFciFsLD!_T0NR@_{&!t;t^CmZ**5evo_VNV82U#u2%Zs8??wV zLDqkon-@Vvc>PfD^hR9<5xe6FQKn6I#Dr5bbe`Q31VC+WJQ%L<||J6T|%UY;aLahxWjBdUb3ah?Zb(xCpUIv7gDFI^aQ_Pz)TJ%FN=@|%FW zZJ$*Y%0c#IjcO-G&SF4P_!CRfQP#Eldmb?_)L1NjJTM4J10zBsisO0Jv`Rb2Zu?P) zCo@)VA#}6-wOMcx7trS+2Ze8WX`9~DWusjn@;g{-Lp~G!A>4ftleh0NCBd;KNslDx zvV}2wiiTZtzW6oaGEUz+p*PA_vtb&eQpl%-T#hx8Y@6(+1V{^Ib_o)w&SdxIC3ASH ztYZYBj+9o9MbhrKcHt)9I{K8uhjbPbev7tJMF&+yQ6GrEgoB2QnupJ@uf4PtI0?4C zWCtfd^q~3$FsEDc?zh+ToPGwPzdkb2rfgcHmNLIuhd-H!#vU0#cyqLzx;jreqsdXx z=Rdi5S#%b@+Y&Dfr6g;H-I@-z(Og!5LEZc1 zC4lFMOI7q8?^;@_?t)>1TUV)mumx^_TZ8Xqp9IBQbXk=po$Gqe^n9F3=k4%&1L_1~RRnlk5`u6EqBaqS zn3JI!J?NUqqDlB6D;DI=|jmdB$b=OEm-Nd zbjlgkL0s%`U`@D)9JZAR?Jo4!UUtmUS>Ing4;MdZ%vI()Qa5beh)~@dw(e3ef&v!$ z#?w-p>Un?-(FO)&E-r>v12714-PQ=CyoAqzfj`w$v+R)XZHN;(~vx zPoR5}-{~lmvaXCu?ZHt|<`k%3Zd77X-_Ba1IW~x7>dz11n(L7dJnehUi!rF=-=6;gInz06?_ zXq;-EBmu_w-{V+*pI&of7XE*$_H!l!#U$@{Xjz7)%N%N796!7q5Yqp|R4MZL(W~w! zd0i8Q1|FhkVIk6fpNJjd55x43R}Qq)C|bSE5(4Jib)!a@og`d9@a*wS<ren`lnkF|k~(JJs`g8=TehO0PT~<8JLOUFeo# zIaGMlq_Em-q~_J3$BhLZD$tjAWNl;rer{yHCMCq`LN2|S`QV4_Kr0uoc_NG#4Jqe< zP?j!Av7}g~VM!l8# z$CybT0Z+5r&_O>WE>QHUb{ZI{(nZdf-I;TFjFy27aj{2OP9Ef3_BV6vEVJ&UtHCeD z8(eI@Ig#OP3}1_Pk{;V)PZqn_BE)!vcfW6^1g67fS+&j>T`iW0y(C5Cxrcj29nP@5LrTn#PU`d|G zr;8V%h$C@}zsV->fB(GElKXauDyrB#Xi3zB7xSve7y_|9ClF8T5#e;@OIJX-IUpLR z#g~rX@nkS&^^;PoF36~UtC8Lh+xU1t2`A6VX{Fp)SOT;0s|L}xL+<6l`)`K)E8O?c zvNzZnn|wBCMr{&b(0aKdgij@+QrpNSc!CChh$7INwx>m3QUE+UY#O|M#UBIIYC;4!o=ln(IeF}SA7ROB-1_b_Lbz9-Km z!t@>2i{a43Umhb-KhDs>;(^)gBZl7lE@**&v zE{!k0G(m<4eeJ3dE^eWULR1Y_%~w;e5GzCMb`xFMUs_L|+>#`Aq_8%szFZZB+uh6Zq^xf;D@BBw0 zzI!@xI79upf|r(WB8%$(Nkf%**RZs9G%J7e^v#h4zJYGuC3iIZFx!+c>JDst2o# z*k23%yVUQz^2E^Cs^89uYLxt<8og*i_)Sz);w7%X{LtLKUJgkzWX6ddIXnL)}|qwKIk^stEwhrj7ljH9mkkSoT1 z{Yy(n87^I}AmxOEX>|ciXLYzTKU*Qq__-HcyAIUn-FmKRBp+Dhg^u0&4;`h=qiC6X zM$%CuoUm{Jn`|vul#AnCBR(>~7D9i9yk=zbOGqm%e-~8u_M?~gBQ_y5)q$FYSS7+3 zZoeXkK2BB3nD5yzA+@2{|LGq~&)(ZHwRla>tLkP-N{!n_#stoOb7i7g`dbdkPrl;K z7m64vdoM+dYcKJCza`s7b8>l~e?yns*w?4>M#$+xqWD)F-4Hh(JWI<}`wiF_P~sCa zFRn8)pj&OC%I7>2Kr?=#rmE&!^fGZ)6P{&_{EcDt-O3m0zg3%gR-xF;xR8A_tF|Mo zfa149*EAw>;w$~JB8KLQaqQE$0aqz%P!90+w{<_IFY4x=^1xFnz z_OW2e-(nlR%ZJ~U=ehach>i-$6T1En7&(T-xM5Y7=_*UMiukueOl49RoF;qI2k zFjqNEBK!^wd;m2kgB{JjBV5jbSU^&{g}mr%38HP+RSSb9&LU~G19h65THx*QvNEmz zf5c=EeVHR=UQ8&qB8UT;6ES$}-S|Yo-3{ZPodMT?&-64bbf1{ptS)w8ZITT32kD-D z$bQEv`Ro&ZQO0rN-qvx#Ka6u%bYyb&Y=8N+;6K@OP|QT7Sy0fMxtFrLr;=0=J<3PG z;Z5~8!C5MLv*V=8Zkj;o5&}LLk3Zw{vS7E#Wo`x7Yr~(f9T{`4%v5 znUQ|a*IndyJghldPM`dzplPGKm@g5y9>EnT7ANi^hZf=8`36-y6b98#I0`!&p8iYu z)eFFQk3Q@D&w@`e(;n}r<;9tt56N%V?^ii#6a7yIJ8PU}sv9*m@I94EhQ_}ha^Cr%pMAaWgZ44g$^HviNs-|FYxdLnLg|z7Adn=}p zX2UjFy3OUPD9M_y(=^4qgX--^AkSikqJvucc`$Is)T4?iSqn&I1lp{V=@Pz0?J3htr#=RvP&G*I9 zwxsB569(Md`Ny_&_jlx6f3V_HeHM?;>>;Z9Xnfd%-dRL>H_#eSK$4A`flj~ zw5~|+(cnZ78%cL^hbnDoSsy4rKbkHR;RCAh8gr&3%f}dH9SX4_!o6%M zY0VF*!d1Sa{EFKnrfmqi{u6AbC9-)PJwK=`@%wI1tqonJm%0{y7r)aN@2vVTX@SRl7G}&FLIJA=6>2XUtBe9E?#DkjeL6CAkZr2 z^AyfY77b*2C>5)woc#NgIdzYRlKRZNirp!BL4L`tH{JD|F!_psuu> zhOhaxNrr=$ORILg!(X)VNx!tM%%*eq6N2qHE6QgqHYP(QTzA8u{P7XCS_djOBVW&= z4qRMqPZY}p#eM<^&hVx)k~+K>wdiHC?B-s zQ2Eop2BKr4y71t92UA86CQvADfS3+VuN`t;&~~HV4UNHUFSHH!l3ah2M^9zHrCZT< z&;P2P53M)#o^7H&egxfeHQw9YZ_pbNj)V-3>`L6itfqWm=pRy7XlNG*aNc#vm<;>J za697U&Ya8P3uTob$0|*~o@@#nFEc8I5$nThNUZc_j28+(EY_xDHy++3uizDqTU3lRLQ+@e4<(AEpqO==bNxH zrnU!edq>yw5vCyON3ehZR02_LfRPnqU33KXuYzJ@P-t5xgmmR-y_%Mt>neZ1n^2iO zfQ5t08pw*ed)H0WME>SILF#B;D2Kje9ZAVD-c7B-QSbXK9gxRRiwD%aNsyl?NfYHuE?N9X1*z}J(=4TQH zzv%wHg^C4}1D1&2V5hOFpileQy)mnLm&$3M7~3dIPurmBLyQl>QI9{8r;TXc8B#uZ zXyG&Qg;=iL-C*bnvd6-Mx|BQUUdww7eQbH1)uU*x*{ znt0hOVxQyn*=>jt-Sus|b)mA31;SUhVmv`t;bKeAQ8C*eI++h$C64EIgy=cf?TxOx znpZd_+BS^i;W>noMjh?pA=y68h?n7}c<#i7! zRAMvwX>az|QPIe^+MnY+w)YM-xFcfiu|d*yKMH@nIt+2$eNo#m7cY243)HT0jEUea zuD%rsv2NpP)AN{xTuk}{5uW=;!giH%#p>smHAy&D{kBK z+RNW=wWQFqT&>6|Wg$tc@yMWOU5R7uIpV93nx0Jbv)MKT-~p*-k1-m1I-iWUlbXdoJsBN=_clDk^^N*h(SyFZ33+mQ*V z^oLm<56LQB2eZL{m!(rBy+u1@ZmndP*NkRIhU!H&@3XiJ9aCT`&QjYK-f}oemAPSu z8o$)NQ$0{@_;HmwqgYJ?GG`|cZ2;o9Rl!wn$gLXh%1CUZWdmHhY&Ju>7-Am~t4h|u z#pG}H7Rndb?sRSJaxE>V;p)3BHU=TqL?8yxrt3ERk5o z9kG7WnDHBHzaD1jRUf}r^3VC>oBah-<`-PLAOd?8w^>R;CKsngLu>2@f@(1c(7pd*0pSD9bh6++xzKhwTf_jjc~=aB8;?5V z1>^av-HvKk@2W6@m2G8JZGX9LF}V!3p;aR}SRN@zM$37&+w9w_`@R#*u<4(F50;;;Yt|yBGQ^?cNI8?PUJg(f{TbYy!)d|Q=!yL#eYPL**+F`;51~(gIwg_ZxRkLbFF?6 zdNm8TGVE~{?Y$7Au;Gf{eb6|Aq;D%0D^( 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 diff --git a/cake_problem_graph3.png b/cake_problem_graph3.png deleted file mode 100644 index ba0ca7be935963902525f99d7b14a5db5a0d3129..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104394 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¥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


gJ0{y2|0-0{RqJKnw`t`lgb&TTR@}toAt076j`P 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 diff --git a/debugging_air_cargo b/debugging_air_cargo deleted file mode 100644 index 669ee2cd7..000000000 --- a/debugging_air_cargo +++ /dev/null @@ -1,60 +0,0 @@ -Look at current goals - - Index = -1, len(self.graph.levels) = 3 - -Add action sets that lead to each goal in goal state into actions list (one of each of these actions must be true) - - (Pdb) print(action_list) - - [Unload(C2, P2, SFO), Unload(C1, P1, JFK)] -Get sets of actions such that each set has one action from each of these lists (i.e. the cartesian product, done with itertools.product) -Filter out mutex action pairs - - At this point, we NEED at least one set of actions to be non-mutex in order to find a valid way to get to that next state. - -Update self.solution with these new goal actions -Identify states that have these actions applicable. Add these states to "new_goals" - - Unload(C2, P2, SFO): [In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO)] - - Unload(C1, P1, JFK): [In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] - -(Pdb) print(new_goals) -[In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO), In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] - -self.extract_solution(new_goals, index - 1) - - [In(C2, P2), At(P2, SFO), Cargo(C2), Plane(P2), Airport(SFO), In(C1, P1), At(P1, JFK), Cargo(C1), Plane(P1), Airport(JFK)] -2 - - (Pdb) print(actions) -[[Load(C2, P2, JFK)], [Fly(P2, JFK, SFO)], [PCargo(C2)], [PPlane(P2)], [PAirport(SFO)], [Load(C1, P1, SFO)], [Fly(P1, SFO, JFK)], [PCargo(C1)], [PPlane(P1)], [PAirport(JFK)]] - -None are non-mutex !!!!!!!!!!!!!!!!!!!!!!!!!! DEBUG - -(Pdb) print(all_actions) -[(Load(C2, P2, JFK), Fly(P2, JFK, SFO), PCargo(C2), PPlane(P2), PAirport(SFO), Load(C1, P1, SFO), Fly(P1, SFO, JFK), PCargo(C1), PPlane(P1), PAirport(JFK))] - -(Pdb) print(list(action_pairs)) -[(Load(C1, P1, SFO), Load(C2, P2, JFK)), (Load(C1, P1, SFO), PAirport(JFK)), (PAirport(SFO), Fly(P2, JFK, SFO)), (PAirport(SFO), PCargo(C1)), (PAirport(SFO), PPlane(P2)), (PAirport(SFO), Fly(P1, SFO, JFK)), (PAirport(SFO), Load(C2, P2, JFK)), (PAirport(SFO), PAirport(JFK)), (Fly(P2, JFK, SFO), PCargo(C1)), (Fly(P2, JFK, SFO), PPlane(P2)), (Fly(P2, JFK, SFO), Fly(P1, SFO, JFK)), (Fly(P2, JFK, SFO), Load(C2, P2, JFK)), (Fly(P2, JFK, SFO), PAirport(JFK)), (PCargo(C1), PPlane(P2)), (PCargo(C1), Fly(P1, SFO, JFK)), (PCargo(C1), Load(C2, P2, JFK)), (PCargo(C1), PAirport(JFK)), (PPlane(P2), Fly(P1, SFO, JFK)), (PPlane(P2), Load(C2, P2, JFK)), (PPlane(P2), PAirport(JFK)), (Fly(P1, SFO, JFK), Load(C2, P2, JFK)), (Fly(P1, SFO, JFK), PAirport(JFK)), (Load(C2, P2, JFK), PAirport(JFK))] - - (Fly(P2, JFK, SFO), Fly(P1, SFO, JFK)) - -(Pdb) print(level.mutex) -[{Load(C2, P2, JFK), PAt(C2, JFK)}, {PAt(C1, SFO), Load(C1, P1, SFO)}, {Fly(P1, SFO, JFK), PAt(P1, SFO)}, {PAt(P2, JFK), Fly(P2, JFK, SFO)}, {Load(C2, P2, JFK), Fly(P2, JFK, SFO)}, {Fly(P1, SFO, JFK), Load(C1, P1, SFO)}] - - - - - - Observable issue: - -Final layer has state `At(C1, JFK) & At(C2, SFO)` non-mutex - -At(C1, JFK) requires Unload(C1, P1, JFK) -At(C2, SFO) requires Unload(C2, P2, SFO) - -These actions Unload(C1, P1, JFK) and Unload(C2, P2, SFO) are NOT mutex in action layer - -They rely on the following state at s_1 - - Unload(C2, P2, SFO): [In(C2, P2), At(P2, SFO),...] - - Unload(C1, P1, JFK): [In(C1, P1), At(P1, JFK),...] - -Preconditions, e.g. for Unload(C2, P2, SFO): - - In(C2, P2), At(P2, SFO) - - are mutex, but since they both exist in the state, we still apply the action anyway? When is this supposed to be caught? - - - -[{At(C1, SFO), In(C1, P1)}, {At(C1, SFO), NotAt(C1, SFO)}, {At(C2, JFK), In(C2, P2)}, {At(C2, JFK), NotAt(C2, JFK)}, {At(P1, SFO), At(P1, JFK)}, {At(P1, SFO), NotAt(P1, SFO)}, {At(P2, JFK), At(P2, SFO)}, {NotAt(P2, JFK), At(P2, JFK)}, {At(P1, JFK), In(C1, P1)}, {NotAt(P1, SFO), In(C1, P1)}, {At(P1, JFK), NotAt(C1, SFO)}, {NotAt(P1, SFO), NotAt(C1, SFO)}, {At(P2, SFO), In(C2, P2)}, {NotAt(P2, JFK), In(C2, P2)}, {NotAt(C2, JFK), At(P2, SFO)}, {NotAt(P2, JFK), NotAt(C2, JFK)}] - diff --git a/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md b/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md deleted file mode 100644 index 63e9a795c..000000000 --- a/pairwise_passing_but_group_goal_failure_causes_tennis_simple2_to_fail.md +++ /dev/null @@ -1,22 +0,0 @@ -# Goal States: -[ - At(A, LeftNet), - Returned(ball), - At(B, LeftNet) -] - -#Action sets that lead to goal states -[ - [PAt(A, LeftNet), Go(A, LeftNet, ball), Go(A, LeftNet, B), Go(A, LeftNet, RightNet)], - [Hit(A, ball, RightNet), Hit(B, ball, RightNet)], - [PAt(B, LeftNet), Go(B, LeftNet, ball), Go(B, LeftNet, A), Go(B, LeftNet, RightNet)] -] - -# Allegedly, all combinations are disjoint - -Hit(A, ball, RightNet), Hit(B, ball, RightNet) - - Requires either A or B to be in RightNet - - First list requires A to move to LeftNet - - Last list requires B to move to LeftNet - -These are disjoint in total, but none of the two are disjoint \ No newline at end of file diff --git a/planning.py b/planning.py index b46c840f0..eef22c9dc 100644 --- a/planning.py +++ b/planning.py @@ -276,420 +276,6 @@ def goal_test(goals, state): return all(kb.ask(q) is not False for q in goals) -def air_cargo(): - """ - [Figure 10.1] AIR-CARGO-PROBLEM - - An air-cargo shipment problem for delivering cargo to different locations, - given the starting location and airplanes. - - Example: - >>> from planning import * - >>> ac = air_cargo() - >>> ac.goal_test() - False - >>> ac.act(expr('Load(C2, P2, JFK)')) - >>> ac.act(expr('Load(C1, P1, SFO)')) - >>> ac.act(expr('Fly(P1, SFO, JFK)')) - >>> ac.act(expr('Fly(P2, JFK, SFO)')) - >>> ac.act(expr('Unload(C2, P2, SFO)')) - >>> ac.goal_test() - False - >>> ac.act(expr('Unload(C1, P1, JFK)')) - >>> ac.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK)', - goals='At(C1, JFK) & At(C2, SFO)', - actions=[Action('Load(c, p, a)', - precond='At(c, a) & At(p, a)', - effect='In(c, p) & ~At(c, a)', - domain='Cargo(c) & Plane(p) & Airport(a)'), - Action('Unload(c, p, a)', - precond='In(c, p) & At(p, a)', - effect='At(c, a) & ~In(c, p)', - domain='Cargo(c) & Plane(p) & Airport(a)'), - Action('Fly(p, f, to)', - precond='At(p, f)', - effect='At(p, to) & ~At(p, f)', - domain='Plane(p) & Airport(f) & Airport(to)')], - domain='Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)') - - -def spare_tire(): - """ - [Figure 10.2] SPARE-TIRE-PROBLEM - - A problem involving changing the flat tire of a car - with a spare tire from the trunk. - - Example: - >>> from planning import * - >>> st = spare_tire() - >>> st.goal_test() - False - >>> st.act(expr('Remove(Spare, Trunk)')) - >>> st.act(expr('Remove(Flat, Axle)')) - >>> st.goal_test() - False - >>> st.act(expr('PutOn(Spare, Axle)')) - >>> st.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(Flat, Axle) & At(Spare, Trunk)', - goals='At(Spare, Axle) & At(Flat, Ground)', - actions=[Action('Remove(obj, loc)', - precond='At(obj, loc)', - effect='At(obj, Ground) & ~At(obj, loc)', - domain='Tire(obj)'), - Action('PutOn(t, Axle)', - precond='At(t, Ground) & ~At(Flat, Axle)', - effect='At(t, Axle) & ~At(t, Ground)', - domain='Tire(t)'), - Action('LeaveOvernight', - precond='', - effect='~At(Spare, Ground) & ~At(Spare, Axle) & ~At(Spare, Trunk) & \ - ~At(Flat, Ground) & ~At(Flat, Axle) & ~At(Flat, Trunk)')], - domain='Tire(Flat) & Tire(Spare)') - - -def three_block_tower(): - """ - [Figure 10.3] THREE-BLOCK-TOWER - - A blocks-world problem of stacking three blocks in a certain configuration, - also known as the Sussman Anomaly. - - Example: - >>> from planning import * - >>> tbt = three_block_tower() - >>> tbt.goal_test() - False - >>> tbt.act(expr('MoveToTable(C, A)')) - >>> tbt.act(expr('Move(B, Table, C)')) - >>> tbt.goal_test() - False - >>> tbt.act(expr('Move(A, Table, B)')) - >>> tbt.goal_test() - True - >>> - """ - return PlanningProblem(initial='On(A, Table) & On(B, Table) & On(C, A) & Clear(B) & Clear(C)', - goals='On(A, B) & On(B, C)', - actions=[Action('Move(b, x, y)', - precond='On(b, x) & Clear(b) & Clear(y)', - effect='On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)', - domain='Block(b) & Block(y)'), - Action('MoveToTable(b, x)', - precond='On(b, x) & Clear(b)', - effect='On(b, Table) & Clear(x) & ~On(b, x)', - domain='Block(b) & Block(x)')], - domain='Block(A) & Block(B) & Block(C)') - -def logisticsPlanCustom(initial_state=None, goal_state=None): - if initial_state == None: - initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - if goal_state == None: - raise ValueError("Goal must be defined") - - planning_problem = \ - PlanningProblem(initial = initial_state, - goals = goal_state, - actions=[Action('PickUp(r, c, d)', - precond='In(r, d) & In (c, d) & ~Holding(r)', - effect='Holding(r) & ~In(c, d) & In(c, r)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('PutDown(r, c, d)', - precond='In(r, d) & In(c, r) & Holding(r)', - effect='~Holding(r) & ~In(c, r) & In(c, d)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('Move(r, d_start, d_end)', - precond='In(r,d_start)', - effect='~In(r, d_start) & In(r, d_end)', - domain='Robot(r) & Place(d_start) & Place(d_end)')], - domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') - - return planning_problem - - -def simple_blocks_world(): - """ - SIMPLE-BLOCKS-WORLD - - A simplified definition of the Sussman Anomaly problem. - - Example: - >>> from planning import * - >>> sbw = simple_blocks_world() - >>> sbw.goal_test() - False - >>> sbw.act(expr('ToTable(A, B)')) - >>> sbw.act(expr('FromTable(B, A)')) - >>> sbw.goal_test() - False - >>> sbw.act(expr('FromTable(C, B)')) - >>> sbw.goal_test() - True - >>> - """ - - return PlanningProblem(initial='On(A, B) & Clear(A) & OnTable(B) & OnTable(C) & Clear(C)', - goals='On(B, A) & On(C, B)', - actions=[Action('ToTable(x, y)', - precond='On(x, y) & Clear(x)', - effect='~On(x, y) & Clear(y) & OnTable(x)'), - Action('FromTable(y, x)', - precond='OnTable(y) & Clear(y) & Clear(x)', - effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) - - -def have_cake_and_eat_cake_too(): - """ - [Figure 10.7] CAKE-PROBLEM - - A problem where we begin with a cake and want to - reach the state of having a cake and having eaten a cake. - The possible actions include baking a cake and eating a cake. - - Example: - >>> from planning import * - >>> cp = have_cake_and_eat_cake_too() - >>> cp.goal_test() - False - >>> cp.act(expr('Eat(Cake)')) - >>> cp.goal_test() - False - >>> cp.act(expr('Bake(Cake)')) - >>> cp.goal_test() - True - >>> - """ - - return PlanningProblem(initial='Have(Cake) & ~Eaten(Cake)', - goals='Have(Cake) & Eaten(Cake)', - actions=[Action('Eat(Cake)', - precond='Have(Cake)', - effect='Eaten(Cake) & ~Have(Cake)'), - Action('Bake(Cake)', - precond='~Have(Cake)', - effect='Have(Cake)')]) - - -def shopping_problem(): - """ - SHOPPING-PROBLEM - - A problem of acquiring some items given their availability at certain stores. - - Example: - >>> from planning import * - >>> sp = shopping_problem() - >>> sp.goal_test() - False - >>> sp.act(expr('Go(Home, HW)')) - >>> sp.act(expr('Buy(Drill, HW)')) - >>> sp.act(expr('Go(HW, SM)')) - >>> sp.act(expr('Buy(Banana, SM)')) - >>> sp.goal_test() - False - >>> sp.act(expr('Buy(Milk, SM)')) - >>> sp.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(HW, Drill)', - goals='Have(Milk) & Have(Drill)', - actions=[Action('Buy(x, store)', - precond='At(store) & Sells(store, x)', - effect='Have(x)', - domain='Store(store) & Item(x)'), - Action('Go(x, y)', - precond='At(x)', - effect='At(y) & ~At(x)', - domain='Rplace(x) & Rplace(y)')], - domain='Rplace(Home) & Rplace(SM) & Rplace(HW) & Store(SM) & Store(HW) & ' - 'Item(Milk) & Item(Drill)') - - -def socks_and_shoes(): - """ - SOCKS-AND-SHOES-PROBLEM - - A task of wearing socks and shoes on both feet - - Example: - >>> from planning import * - >>> ss = socks_and_shoes() - >>> ss.goal_test() - False - >>> ss.act(expr('RightSock')) - >>> ss.act(expr('RightShoe')) - >>> ss.act(expr('LeftSock')) - >>> ss.goal_test() - False - >>> ss.act(expr('LeftShoe')) - >>> ss.goal_test() - True - >>> - """ - - return PlanningProblem(initial='', - goals='RightShoeOn & LeftShoeOn', - actions=[Action('RightShoe', - precond='RightSockOn', - effect='RightShoeOn'), - Action('RightSock', - precond='', - effect='RightSockOn'), - Action('LeftShoe', - precond='LeftSockOn', - effect='LeftShoeOn'), - Action('LeftSock', - precond='', - effect='LeftSockOn')]) - - -def double_tennis_problem_simple(): - return PlanningProblem( - initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', - goals='At(A, LeftBaseline) & Returned(ball)', - actions=[Action('Hit(actor, ball, loc)', - precond='Approaching(ball, loc) & At(actor, loc)', - effect='Returned(ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')], - domain="Loc(LeftBaseline)") - -def double_tennis_problem_simple2(): - return PlanningProblem( - initial='At(A, LeftNet) & At(B, LeftNet) & Approaching(ball, RightNet)', - goals='At(A, LeftNet) & Returned(ball) & At(B, LeftNet)', - actions=[Action('Hit(actor, ball, loc)', - precond='Approaching(ball, loc) & At(actor, loc)', - effect='Returned(ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - -def double_tennis_problem_simple3(): - return PlanningProblem( - initial='At(A, LeftNet) & Approaching(ball, RightNet)', - goals='At(A, LeftNet) & Returned(ball)', - actions=[Action('Hit(actor, ball, loc)', - precond='Approaching(ball, loc) & At(actor, loc)', - effect='Returned(ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - - -def double_tennis_problem(): - """ - [Figure 11.10] DOUBLE-TENNIS-PROBLEM - - A multiagent planning problem involving two partner tennis players - trying to return an approaching ball and repositioning around in the court. - - Example: - >>> from planning import * - >>> dtp = double_tennis_problem() - >>> goal_test(dtp.goals, dtp.initial) - False - >>> dtp.act(expr('Go(A, RightBaseLine, LeftBaseLine)')) - >>> dtp.act(expr('Hit(A, Ball, RightBaseLine)')) - >>> goal_test(dtp.goals, dtp.initial) - False - >>> dtp.act(expr('Go(A, LeftNet, RightBaseLine)')) - >>> goal_test(dtp.goals, dtp.initial) - True - >>> - """ - - # The authors mistakenly used `a` rather than `A`, and also set it to two locations? - # This is the original function, but it's faulty. Although, it does technically pass pytests? Just for some reason, not graphPlan... - # I believe this fails GraphPlan because of the way it extracts objects, which does not include objects that only exist in goal states? - # - Therefore the GraphPlan fails, but the pytests that manuallys solve pass? - # - To explain why At(a, LeftNet), At(a,RightNet) passes, perhaps since it doesn't see `a` in objects, it takes it as a variable? Where any object can make it true? Which A and B do? - """ - return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - """ - - """ - [Figure 11.10] DOUBLE-TENNIS-PROBLEM - - A multiagent planning problem involving two partner tennis players - trying to return an approaching ball and repositioning around in the court. - """ - - # This works, but adds extra unnecessary detail to the problem - """ - return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)', - domain='Player(actor) & CourtLoc(to) & CourtLoc(loc)')], - domain='Player(A) & Player(B) & Ball(Ball) & CourtLoc(LeftBaseLine) & CourtLoc(RightBaseLine) & CourtLoc(LeftNet) & CourtLoc(RightNet)' - ) - """ - - # THIS DOESNT WORK BECAUSE LeftNet isn't recognized as an object - """ - return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(A, LeftNet) & At(B, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - """ - - """ - return PlanningProblem( - initial='At(A, LeftBaseline) & At(B, RightNet) & Approaching(ball, RightBaseline)', - goals='At(A, LeftNet) & At(B, RightBaseline) & Returned(ball)', - actions=[Action('Hit(actor, ball, loc)', - precond='Approaching(ball, loc) & At(actor, loc) & CourtLoc(loc) & IsBall(ball) & isActor(actor)', - effect='Returned(ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc) & CourtLoc(loc) & CourtLoc(to) & IsActor(actor)', - effect='At(actor, to) & ~At(actor, loc)')], - domain='CourtLoc(LeftNet) & CourtLoc(RightNet) & CourtLoc(LeftBaseline) & CourtLoc(RightBaseline) & IsBall(ball) & IsActor(A) & IsActor(B)' - ) - """ - - return PlanningProblem( - initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', - goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', - actions=[Action('Hit(actor, ball, loc)', - precond='Approaching(ball, loc) & At(actor, loc)', - effect='Returned(ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')], - domain="Loc(LeftBaseline)") - - class ForwardPlan(search.Problem): """ [Section 10.2.1] @@ -955,75 +541,12 @@ def find_mutex(self): "This function is only entered after state, actions at this level are computed." "Therefore, we're computing it for the current state and current (state+1) action layer" - #breakpoint() self.state_mutexes = self.mutex # save state mutexes self.mutex = [] # clear out effects from state mutex prior computation - """ - # Technically correct version of Inconsistent effects, but introduces duplicates - ic1 = [] - # Inconsistent effects - one action adds a literal that another deletes - pos_nsl, neg_nsl = self.separate(self.next_state_links) - - for negeff in neg_nsl: - new_negeff = Expr(negeff.op[3:], *negeff.args) - for poseff in pos_nsl: - if new_negeff == poseff: - for a in self.next_state_links[poseff]: - for b in self.next_state_links[negeff]: - #if {a, b} not in self.mutex: - self.mutex.append({a, b}) - ic1.append({a,b}) - """ - - """ - # Version that we have implemented efficiently below - ic2 = [] - for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): - preconds_a1 = self.current_action_links.get(a1, []) - preconds_a2 = self.current_action_links.get(a2, []) - effects_a1 = self.next_action_links.get(a1, []) - effects_a2 = self.next_action_links.get(a2, []) - - # Check for interference - interference = False - # Check if effect of one action is negated by effect of other action (inconsistent effects?) - for e1 in effects_a1: - if e1.predicate_negate() in effects_a2: - interference = True - for e2 in effects_a2: - if e2.predicate_negate() in effects_a1: - interference = True - - if interference: - mutex_pair = {a1, a2} - #if mutex_pair not in self.mutex: # <-- avoid duplicates - ic2.append(mutex_pair) - """ - - - # Competing needs - preconditions of two actions are mutex at previous proposition layer - """ - pos_csl, neg_csl = self.separate(self.current_state_links) - # Why are we looking at syntactic components (negation)??? - breakpoint() - for pos_precond in pos_csl: - for neg_precond in neg_csl: - new_neg_precond = Expr(neg_precond.op[3:], *neg_precond.args) - if new_neg_precond == pos_precond: - for a in self.current_state_links[pos_precond]: - for b in self.current_state_links[neg_precond]: - if {a, b} not in self.mutex: - self.mutex.append({a, b}) - """ - - # Competing Needs - # self.current_state_links = map from current state vars -> actions applicable - # self.current_action_links = map from current actions -> starting states - # Implement here: Iterate over all valid pairs of actions, and if the states they come from are mutex (use self.state_mutexes), add a mutex pair to self.mutex # Competing Needs - two actions are mutex if any of their preconditions are mutex at the previous state level for a1, a2 in itertools.combinations(self.current_action_links.keys(), 2): - preconds_a1 = self.current_action_links[a1] # states + preconds_a1 = self.current_action_links[a1] preconds_a2 = self.current_action_links[a2] if any({p, q} in self.state_mutexes for p in preconds_a1 for q in preconds_a2): @@ -1031,67 +554,39 @@ def find_mutex(self): if mutex_pair not in self.mutex: self.mutex.append(mutex_pair) - # Interference AND Inconsistent Effects - # Example - in shopping, ensure Move(Home,HW) and Move(Home,SM) are both mutex in L0 - # current_action_links = current action -> current state map + # Interference AND Inconsistent Effects Mutex Calculation for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): preconds_a1 = self.current_action_links.get(a1, []) preconds_a2 = self.current_action_links.get(a2, []) effects_a1 = self.next_action_links.get(a1, []) effects_a2 = self.next_action_links.get(a2, []) - - #print(a1,a2) - #if "PickUp" in a1.op and "PickUp" in a2.op: - # breakpoint() - - # Check for interference + interference = False - # Check if a precondition of one action is negated by effect of another + # Interference Check for p1 in preconds_a1: if p1.predicate_negate() in effects_a2: interference = True for p2 in preconds_a2: if p2.predicate_negate() in effects_a1: interference = True - # Check if effect of one action is negated by effect of other action (inconsistent effects) + + # Inconsistent Effects Check for e1 in effects_a1: if e1.predicate_negate() in effects_a2: - interference = True # Technically inconsistent effects + interference = True for e2 in effects_a2: if e2.predicate_negate() in effects_a1: - interference = True # Technically inconsistent effects + interference = True if interference: mutex_pair = {a1, a2} - if mutex_pair not in self.mutex: # <-- avoid duplicates + if mutex_pair not in self.mutex: self.mutex.append(mutex_pair) - - #print([x for x in self.mutex if x not in savemutextemp]) - #breakpoint() - - # Inconsistent support - two props cannot be true given competing supporting actions - """ - state_mutex = [] - for pair in self.mutex: - next_state_0 = self.next_action_links[list(pair)[0]] - if len(pair) == 2: - next_state_1 = self.next_action_links[list(pair)[1]] - else: - next_state_1 = self.next_action_links[list(pair)[0]] - if (len(next_state_0) == 1) and (len(next_state_1) == 1): - state_mutex.append({next_state_0[0], next_state_1[0]}) - """ - - #breakpoint() - - def populate_prop_mutexes(self): "Compute the next level's proposition mutexes based on our current action mutexes" + # Inconsistent support - two props cannot be true given competing supporting actions - - # self.next_action_links is a map from {next_state: [actions_leading_there]} - # We want to choose two next states, and add a mutex if all actions leading there are mutex state_mutex = [] next_state_pairs = itertools.combinations(self.next_state_links.keys(), 2) for next_state_pair in list(next_state_pairs): @@ -1104,7 +599,6 @@ def populate_prop_mutexes(self): continue # if any two actions that lead to these states is not mutex, do not add a mutex to these states. - #if not any([{a1,a2} not in self.mutex and {a2,a1} not in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): if all([{a1,a2} in self.mutex or {a2,a1} in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): mutex_pair = {s1, s2} if mutex_pair not in state_mutex: @@ -1120,7 +614,6 @@ def populate_prop_mutexes(self): state_mutex.append(mutex_pair) - #breakpoint() self.next_state_mutexes = state_mutex return state_mutex @@ -1129,15 +622,12 @@ def prune_invalid_actions(self): to_remove = [] # Normalize state mutex set for fast membership checks: - # state_mutex_lookup contains frozenset pairs like frozenset({p,q}) state_mutex_lookup = set() for m in self.state_mutexes: - # m might already be a set/frozenset or possibly a tuple depending on other code state_mutex_lookup.add(frozenset(m)) for action, preconds in list(self.current_action_links.items()): invalid = False - # print(action, preconds, list(itertools.combinations(preconds, 2))) for p1, p2 in itertools.combinations(preconds, 2): if frozenset({p1, p2}) in state_mutex_lookup: @@ -1220,36 +710,11 @@ def build(self, actions, objects): def perform_actions(self): "Performs the necessary actions and returns a new Level" - # next_state_links.keys() will give the valid next states (the values would be all the actions that could cause it) new_kb = FolKB(list(set(self.next_state_links.keys()))) new_level = Level(new_kb) return new_level - """ - def deduplify(self): - "Remove duplicate entries from state, actions, links, and mutex lists." - - # --- Deduplicate state --- - self.current_state = list(dict.fromkeys(self.current_state)) # order-preserving unique - - # --- Deduplicate links (values are lists of actions/states) --- - for mapping in [self.current_action_links, self.current_state_links, - self.next_action_links, self.next_state_links]: - for k, v in mapping.items(): - mapping[k] = list(dict.fromkeys(v)) # unique but keep order - - # --- Deduplicate mutex pairs --- - seen = set() - unique_mutex = [] - for pair in self.mutex: - # turn {a,b} into a frozenset so it’s hashable - frozen = frozenset(pair) - if frozen not in seen: - seen.add(frozen) - unique_mutex.append(pair) - self.mutex = unique_mutex - """ class Graph: """ @@ -1298,61 +763,6 @@ def non_mutex_goals(self, goals, index): return False return True - """ - def non_mutex_goals(self, goals, index): - "Checks whether the goals are mutually exclusive recursively" - - #print(f"mutexcheck: {index} == layer {len(self.levels) + index}") - num_layers = len(self.levels) - - # Base case: no goals left or first level reached - if num_layers + index == 0 or not goals: - return True - - # Base case: level 0, assume persistence actions handle mutexes there - if num_layers + index == 0: - goal_perm = itertools.combinations(goals, 2) - for g in goal_perm: - if frozenset(g) in self.levels[0].mutex: - return False - return True - - # Check current level mutexes first - goal_perm = itertools.combinations(goals, 2) - for g in goal_perm: - if frozenset(g) in self.levels[index].mutex: - return False - - # Recursive check: ensure for each pair of goals there exist non-mutex actions in previous level - level = self.levels[index - 1] - - for goal in goals: - # if the goal has no supporting actions in previous level, can't satisfy - #breakpoint() - if goal not in level.next_state_links.keys(): - return False - - # Generate all combinations of supporting actions - supporting_actions_lists = [level.next_state_links[goal] for goal in goals] - for action_tuple in itertools.product(*supporting_actions_lists): - # Check if any pair of actions is mutex - mutex_found = False - for a1, a2 in itertools.combinations(action_tuple, 2): - if frozenset((a1, a2)) in level.mutex: - mutex_found = True - break - if not mutex_found: - # At least one combination works, recurse to previous level - prev_goals = [] - for act in action_tuple: - if act in level.current_action_links: - prev_goals += level.current_action_links[act] - if self.non_mutex_goals(prev_goals, index - 1): - return True - - # If no combination works, goals are mutex - return False - """ class GraphPlan: """ @@ -1392,10 +802,6 @@ def check_leveloff(self): if check: return True - - - - def _get_preconditions_for(self, action_set, level): #Collects all unique preconditions for a given set of actions in a level. all_preconditions = set() @@ -1409,7 +815,6 @@ def _get_preconditions_for(self, action_set, level): def _find_valid_action_sets(self, goals, level): #Finds sets of actions in the given level that are not mutually exclusive #and that collectively satisfy all the goals. - #This correctly replaces the flawed `itertools.product` logic. valid_sets = [] # 1. Map each goal to the list of actions that can achieve it. @@ -1448,16 +853,18 @@ def extract_solution(self, goals, level_index, root=False): # Place this within your GraphPlan class, replacing the previous version def _extract_solution_recursive(self, goals, level_index): - #Recursively searches for a plan backwards from a given level using negative indexing. + """ + Recursively searches for a plan backwards from a given level using negative indexing. + + Args: + goals (set): The set of goal propositions to satisfy. + level_index (int): level index + """ + + #BASE CASE: We've recursed back to the initial proposition layer (Level 0). + #The 'goals' at this point are the preconditions for the very first set of actions. + #We must check if they exist in the initial state. No further recursion is needed. - #Args: - # goals (set): The set of goal propositions to satisfy. - # level_index (int): level index - #print(level_index) - #breakpoint() - # BASE CASE: We've recursed back to the initial proposition layer (Level 0). - # The 'goals' at this point are the preconditions for the very first set of actions. - # We must check if they exist in the initial state. No further recursion is needed. if level_index == 0: #breakpoint() initial_state = set(self.graph.levels[0].current_state) @@ -1496,179 +903,6 @@ def _extract_solution_recursive(self, goals, level_index): self.no_goods.append(nogood_item) return None - - - """ - def extract_solution(self, goals, index, root=False): - "Extracts the solution" - - #print(f"ENTER extract_solution with goals: {goals}") - - level = self.graph.levels[index] - if not self.graph.non_mutex_goals(goals, index): - self.no_goods.append((level, goals)) - #print(" Level failed, goals are all mutex") - return - - level = self.graph.levels[index - 1] - # print(f" On level {index-1}") - # print(f" Mutexes: \n {level.mutex}") - - #breakpoint() - - # Create all combinations of actions that satisfy each goal - # `actions` will be a list of tuples, where each tuple is every action that satisfies one goal literal - actions = [] - for goal in goals: - actions.append(level.next_state_links[goal]) - - # `all_actions` selects elements from each list and creates a new list of actions that satisfies all goals at next level - #all_actions = list(itertools.product(*actions)) # Why only product? Why not all subsets of non-mutex preconditions? - #all_actions = powerset_product(actions) - print(len(list(itertools.product(*actions)))) - all_actions = [*list(itertools.product(*actions)), *(powerset_product(actions)[0:5])] - print(len(all_actions)) - - # Filter out non-mutex actions - non_mutex_actions = [] - for action_tuple in all_actions: - - #actlst = ["Move(R1, D2, D3)", "PIn(C2, D3)", "PHolding(R1)", "PIn(C3, R1)"] - #actlevellst = [str(repr(x)) for x in action_tuple] - #print(action_tuple) - #if all([x in actlevellst for x in actlst]): - #print("hi") - #breakpoint() - #print("hi") - - # Get all pairs of actions in our satisfactory action_tuple - action_pairs = itertools.combinations(list(set(action_tuple)), 2) - non_mutex_actions.append(list(set(action_tuple))) - #if not any(["PickUp" in str(x.op) for x in action_tuple]): - #breakpoint() - # acts = list(set(action_tuple)) - # print(f"CHECKING tuple {acts} at level {index-1}") - for pair in list(action_pairs): - if set(pair) in level.mutex: - #print(action_tuple, " failed due to ", pair, " in mutex") - non_mutex_actions.pop(-1) - break # If any actions are mutex, remove the entire tuple from our list - - if len(non_mutex_actions) == 0: - #print(" Level failed: No actions create state and are non-mutex") - return - - # At this point, the non_mutex_actions contains a list of lists of valid actions that are all non-mutex and satisfy our goal state - - # Recursion - - #print(f"Depth of solutions: {len(self.graph.levels)}, current level = {index-1}") - for action_list in non_mutex_actions: - if [action_list, index] not in self.solution: - self.solution.append([action_list, index]) - - new_goals = [] - for act in set(action_list): - if act in level.current_action_links: - new_goals = new_goals + level.current_action_links[act] - - if abs(index) + 1 == len(self.graph.levels): - return - elif (level, new_goals) in self.no_goods: - return - else: - #print(f" Goals achieved: {goals}, actions used: {action_list}") - #breakpoint() - self.extract_solution(new_goals, index - 1) # DFS search; goals at this layer, index of this layer - - - # Exit prior to computing solutions if we are not at the root. - if not root: - return - - #print(self.solution) - #breakpoint() - - if not self.solution: - return [] - - # 1. Determine the leaf level and the expected length of a valid plan. - leaf_level = min(item[1] for item in self.solution) - expected_plan_length = abs(leaf_level) - #print(f"DEBUG: Target leaf level: {leaf_level}, Expected plan length: {expected_plan_length}\n") - - - completed_plans = [] - current_path = [] - initial_state = set(self.graph.levels[0].current_state) - level_zero = self.graph.levels[0] - - # 2. Iterate through the ordered search log. - for i, item in enumerate(self.solution): - actions, level = item - #print(f"--- Iteration {i+1} ---") - #print(f"Processing Item: {item}") - #print(f"Path BEFORE changes: {current_path}") - - # 3. Rewind the current path to handle backtracks. - rewound = False - while current_path and level != current_path[-1][1] - 1: - if not rewound: - #print(f"-> Backtrack detected (Lvl {level} doesn't follow Lvl {current_path[-1][1]}). Rewinding path...") - rewound = True - popped_item = current_path.pop() - #print(f" ...Popped: {popped_item}") - - #if rewound: - # print(f"Path AFTER rewind: {current_path}") - - # 4. Append the current item to form the new active path. - current_path.append(item) - #print(f"Appending item. New Path is now: {current_path}\n") - - # 5. Check if the active path has a valid structure. - is_rooted = current_path[0][1] == -1 - is_grounded = current_path[-1][1] == leaf_level - is_contiguous = len(current_path) == expected_plan_length - - # Only proceed if the path is structurally sound. - if is_rooted and is_grounded and is_contiguous: - #print(f"-> Path is structurally valid. Performing final initial state check...") - - # 6. Final Check: Verify first actions' preconditions against the initial state. - initial_state_satisfied = True - first_actions_in_plan = set(current_path[-1][0]) - - for action in first_actions_in_plan: - preconditions = level_zero.current_action_links.get(action,None) - if preconditions is None: - initial_state_satisfied = False - preconditions = [] - preconditions = set(preconditions) - #print("Testing preconditions: ", preconditions, ", and initial_state: ", initial_state) - if not preconditions.issubset(initial_state): - initial_state_satisfied = False - #print(f" ❗️ Path failed validation. Action '{action}' preconditions {preconditions} are not met by initial state.") - break - - if initial_state_satisfied: - #print(f" ✅ Success! Plan fully verified and found: {current_path}\n") - completed_plans.append(list(current_path)) - - print(f"--- Loop Finished ---") - print(f"Found {len(completed_plans)} complete plan(s) before final formatting.") - - # Format the final solutions - solution = [] - for plan in completed_plans: - action_plan = [item[0] for item in plan] - action_plan.reverse() - solution.append(action_plan) - - return solution - """ - - def goal_test(self, kb): goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) # print(goal_achieved) @@ -1680,35 +914,20 @@ def execute(self): print("Forward Search") while True: self.graph.expand_graph() - #print(self.graph) - # print("Number of levels: ", len(self.graph.levels)) - #breakpoint() if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): - print("SOLVED, EXTRACTING SOLUTION") - #print(self.graph) - #breakpoint() - # print(self.graph.non_mutex_goals(self.graph.planning_problem.goals, -1)) - # self.graph.levels[-1](self.graph.planning_problem.actions, self.graph.objects) - # print(self.graph) - # print("Last level state:", self.graph.levels[-1].current_state) - # print("Last level mutexes:", self.graph.levels[-1].mutex) - # print("Next state links:", self.graph.levels[-1].next_state_links) - # print("Current action links:", self.graph.levels[-1].current_action_links) - # print(f"Extract Solution from {len(self.graph.levels)} levels, {len(self.graph.levels) - 1} actions") - #breakpoint() solution = self.extract_solution(self.graph.planning_problem.goals, -1, True) if solution: - print(f"SOLUTION::::!!!!!!!!!!!!!!!!\n{solution}") return [solution] - # print(len(self.graph.levels)) if len(self.graph.levels) >= 2 and self.check_leveloff(): - # breakpoint() return None class Linearize: + """ + + """ def __init__(self, planning_problem): self.planning_problem = planning_problem @@ -1751,9 +970,8 @@ def execute(self): graphPlan_solution = GraphPlan(self.planning_problem).execute() - for itr, possible_plan in enumerate(graphPlan_solution): + for possible_plan in graphPlan_solution: filtered_solution = self.filter(possible_plan) - #print(f"Trying filtered plan #{itr}: {filtered_solution}") ordered_solution = [] # planning_problem will maintain the current state as we iterate over levels, allowing test application of actions diff --git a/planning1.py b/planning1.py deleted file mode 100644 index 840fd6abb..000000000 --- a/planning1.py +++ /dev/null @@ -1,2077 +0,0 @@ -"""Planning (Chapters 10-11)""" - -import copy -import itertools -from collections import deque, defaultdict -from functools import reduce as _reduce - -import numpy as np - -import search -from csp import sat_up, NaryCSP, Constraint, ac_search_solver, is_constraint -from logic import FolKB, conjuncts, unify_mm, associate, SAT_plan, cdcl_satisfiable -from search import Node -from utils import Expr, expr, first - - -class PlanningProblem: - """ - Planning Domain Definition Language (PlanningProblem) used to define a search problem. - It stores states in a knowledge base consisting of first order logic statements. - The conjunction of these logical statements completely defines a state. - """ - - def __init__(self, initial, goals, actions, domain=None): - self.initial = self.convert(initial) if domain is None else self.convert(initial) + self.convert(domain) - self.goals = self.convert(goals) - self.actions = actions - self.domain = domain - - def convert(self, clauses): - """Converts strings into exprs""" - if not isinstance(clauses, Expr): - if len(clauses) > 0: - clauses = expr(clauses) - else: - clauses = [] - try: - clauses = conjuncts(clauses) - except AttributeError: - pass - - new_clauses = [] - for clause in clauses: - if clause.op == '~': - new_clauses.append(expr('Not' + str(clause.args[0]))) - else: - new_clauses.append(clause) - return new_clauses - - def expand_fluents(self, name=None): - - kb = None - if self.domain: - kb = FolKB(self.convert(self.domain)) - for action in self.actions: - if action.precond: - for fests in set(action.precond).union(action.effect).difference(self.convert(action.domain)): - if fests.op[:3] != 'Not': - kb.tell(expr(str(action.domain) + ' ==> ' + str(fests))) - - objects = set(arg for clause in set(self.initial + self.goals) for arg in clause.args) - fluent_list = [] - if name is not None: - for fluent in self.initial + self.goals: - if str(fluent) == name: - fluent_list.append(fluent) - break - else: - fluent_list = list(map(lambda fluent: Expr(fluent[0], *fluent[1]), - {fluent.op: fluent.args for fluent in self.initial + self.goals + - [clause for action in self.actions for clause in action.effect if - clause.op[:3] != 'Not']}.items())) - - expansions = [] - for fluent in fluent_list: - for permutation in itertools.permutations(objects, len(fluent.args)): - new_fluent = Expr(fluent.op, *permutation) - if (self.domain and kb.ask(new_fluent) is not False) or not self.domain: - expansions.append(new_fluent) - - return expansions - - def expand_actions(self, name=None): - """Generate all possible actions with variable bindings for precondition selection heuristic""" - - has_domains = all(action.domain for action in self.actions if action.precond) - kb = None - if has_domains: - kb = FolKB(self.initial) - for action in self.actions: - if action.precond: - kb.tell(expr(str(action.domain) + ' ==> ' + str(action))) - - objects = set(arg for clause in self.initial for arg in clause.args) - expansions = [] - action_list = [] - if name is not None: - for action in self.actions: - if str(action.name) == name: - action_list.append(action) - break - else: - action_list = self.actions - - for action in action_list: - for permutation in itertools.permutations(objects, len(action.args)): - bindings = unify_mm(Expr(action.name, *action.args), Expr(action.name, *permutation)) - if bindings is not None: - new_args = [] - for arg in action.args: - if arg in bindings: - new_args.append(bindings[arg]) - else: - new_args.append(arg) - new_expr = Expr(str(action.name), *new_args) - if (has_domains and kb.ask(new_expr) is not False) or ( - has_domains and not action.precond) or not has_domains: - new_preconds = [] - for precond in action.precond: - new_precond_args = [] - for arg in precond.args: - if arg in bindings: - new_precond_args.append(bindings[arg]) - else: - new_precond_args.append(arg) - new_precond = Expr(str(precond.op), *new_precond_args) - new_preconds.append(new_precond) - new_effects = [] - for effect in action.effect: - new_effect_args = [] - for arg in effect.args: - if arg in bindings: - new_effect_args.append(bindings[arg]) - else: - new_effect_args.append(arg) - new_effect = Expr(str(effect.op), *new_effect_args) - new_effects.append(new_effect) - expansions.append(Action(new_expr, new_preconds, new_effects)) - - return expansions - - def is_strips(self): - """ - Returns True if the problem does not contain negative literals in preconditions and goals - """ - return (all(clause.op[:3] != 'Not' for clause in self.goals) and - all(clause.op[:3] != 'Not' for action in self.actions for clause in action.precond)) - - def goal_test(self): - """Checks if the goals have been reached""" - return all(goal in self.initial for goal in self.goals) - - def act(self, action): - """ - Performs the action given as argument. - Note that action is an Expr like expr('Remove(Glass, Table)') or expr('Eat(Sandwich)') - """ - action_name = action.op - args = action.args - list_action = first(a for a in self.actions if a.name == action_name) - if list_action is None: - raise Exception("Action '{}' not found".format(action_name)) - if not list_action.check_precond(self.initial, args): - raise Exception("Action '{}' pre-conditions not satisfied".format(action)) - self.initial = list_action(self.initial, args).clauses - - -class Action: - """ - Defines an action schema using preconditions and effects. - Use this to describe actions in PlanningProblem. - action is an Expr where variables are given as arguments(args). - Precondition and effect are both lists with positive and negative literals. - Negative preconditions and effects are defined by adding a 'Not' before the name of the clause - Example: - precond = [expr("Human(person)"), expr("Hungry(Person)"), expr("NotEaten(food)")] - effect = [expr("Eaten(food)"), expr("Hungry(person)")] - eat = Action(expr("Eat(person, food)"), precond, effect) - """ - - def __init__(self, action, precond, effect, domain=None): - if isinstance(action, str): - action = expr(action) - self.name = action.op - self.args = action.args - self.precond = self.convert(precond) if domain is None else self.convert(precond) + self.convert(domain) - self.effect = self.convert(effect) - self.domain = domain - - def __call__(self, kb, args): - return self.act(kb, args) - - def __repr__(self): - return '{}'.format(Expr(self.name, *self.args)) - - def convert(self, clauses): - """Converts strings into Exprs""" - if isinstance(clauses, Expr): - clauses = conjuncts(clauses) - for i in range(len(clauses)): - if clauses[i].op == '~': - clauses[i] = expr('Not' + str(clauses[i].args[0])) - - elif isinstance(clauses, str): - clauses = clauses.replace('~', 'Not') - if len(clauses) > 0: - clauses = expr(clauses) - - try: - clauses = conjuncts(clauses) - except AttributeError: - pass - - return clauses - - def relaxed(self): - """ - Removes delete list from the action by removing all negative literals from action's effect - """ - return Action(Expr(self.name, *self.args), self.precond, - list(filter(lambda effect: effect.op[:3] != 'Not', self.effect))) - - def substitute(self, e, args): - """Replaces variables in expression with their respective Propositional symbol""" - - new_args = list(e.args) - for num, x in enumerate(e.args): - for i, _ in enumerate(self.args): - if self.args[i] == x: - new_args[num] = args[i] - return Expr(e.op, *new_args) - - def check_precond(self, kb, args): - """Checks if the precondition is satisfied in the current state""" - - if isinstance(kb, list): - kb = FolKB(kb) - for clause in self.precond: - if self.substitute(clause, args) not in kb.clauses: - return False - return True - - def act(self, kb, args): - """Executes the action on the state's knowledge base""" - - if isinstance(kb, list): - kb = FolKB(kb) - - if not self.check_precond(kb, args): - raise Exception('Action pre-conditions not satisfied') - for clause in self.effect: - kb.tell(self.substitute(clause, args)) - if clause.op[:3] == 'Not': - new_clause = Expr(clause.op[3:], *clause.args) - - if kb.ask(self.substitute(new_clause, args)) is not False: - kb.retract(self.substitute(new_clause, args)) - else: - new_clause = Expr('Not' + clause.op, *clause.args) - - if kb.ask(self.substitute(new_clause, args)) is not False: - kb.retract(self.substitute(new_clause, args)) - - return kb - - -def goal_test(goals, state): - """Generic goal testing helper function""" - - if isinstance(state, list): - kb = FolKB(state) - else: - kb = state - return all(kb.ask(q) is not False for q in goals) - - -def air_cargo(): - """ - [Figure 10.1] AIR-CARGO-PROBLEM - - An air-cargo shipment problem for delivering cargo to different locations, - given the starting location and airplanes. - - Example: - >>> from planning import * - >>> ac = air_cargo() - >>> ac.goal_test() - False - >>> ac.act(expr('Load(C2, P2, JFK)')) - >>> ac.act(expr('Load(C1, P1, SFO)')) - >>> ac.act(expr('Fly(P1, SFO, JFK)')) - >>> ac.act(expr('Fly(P2, JFK, SFO)')) - >>> ac.act(expr('Unload(C2, P2, SFO)')) - >>> ac.goal_test() - False - >>> ac.act(expr('Unload(C1, P1, JFK)')) - >>> ac.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK)', - goals='At(C1, JFK) & At(C2, SFO)', - actions=[Action('Load(c, p, a)', - precond='At(c, a) & At(p, a)', - effect='In(c, p) & ~At(c, a)', - domain='Cargo(c) & Plane(p) & Airport(a)'), - Action('Unload(c, p, a)', - precond='In(c, p) & At(p, a)', - effect='At(c, a) & ~In(c, p)', - domain='Cargo(c) & Plane(p) & Airport(a)'), - Action('Fly(p, f, to)', - precond='At(p, f)', - effect='At(p, to) & ~At(p, f)', - domain='Plane(p) & Airport(f) & Airport(to)')], - domain='Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)') - - -def spare_tire(): - """ - [Figure 10.2] SPARE-TIRE-PROBLEM - - A problem involving changing the flat tire of a car - with a spare tire from the trunk. - - Example: - >>> from planning import * - >>> st = spare_tire() - >>> st.goal_test() - False - >>> st.act(expr('Remove(Spare, Trunk)')) - >>> st.act(expr('Remove(Flat, Axle)')) - >>> st.goal_test() - False - >>> st.act(expr('PutOn(Spare, Axle)')) - >>> st.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(Flat, Axle) & At(Spare, Trunk)', - goals='At(Spare, Axle) & At(Flat, Ground)', - actions=[Action('Remove(obj, loc)', - precond='At(obj, loc)', - effect='At(obj, Ground) & ~At(obj, loc)', - domain='Tire(obj)'), - Action('PutOn(t, Axle)', - precond='At(t, Ground) & ~At(Flat, Axle)', - effect='At(t, Axle) & ~At(t, Ground)', - domain='Tire(t)'), - Action('LeaveOvernight', - precond='', - effect='~At(Spare, Ground) & ~At(Spare, Axle) & ~At(Spare, Trunk) & \ - ~At(Flat, Ground) & ~At(Flat, Axle) & ~At(Flat, Trunk)')], - domain='Tire(Flat) & Tire(Spare)') - - -def three_block_tower(): - """ - [Figure 10.3] THREE-BLOCK-TOWER - - A blocks-world problem of stacking three blocks in a certain configuration, - also known as the Sussman Anomaly. - - Example: - >>> from planning import * - >>> tbt = three_block_tower() - >>> tbt.goal_test() - False - >>> tbt.act(expr('MoveToTable(C, A)')) - >>> tbt.act(expr('Move(B, Table, C)')) - >>> tbt.goal_test() - False - >>> tbt.act(expr('Move(A, Table, B)')) - >>> tbt.goal_test() - True - >>> - """ - return PlanningProblem(initial='On(A, Table) & On(B, Table) & On(C, A) & Clear(B) & Clear(C)', - goals='On(A, B) & On(B, C)', - actions=[Action('Move(b, x, y)', - precond='On(b, x) & Clear(b) & Clear(y)', - effect='On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)', - domain='Block(b) & Block(y)'), - Action('MoveToTable(b, x)', - precond='On(b, x) & Clear(b)', - effect='On(b, Table) & Clear(x) & ~On(b, x)', - domain='Block(b) & Block(x)')], - domain='Block(A) & Block(B) & Block(C)') - - -def simple_blocks_world(): - """ - SIMPLE-BLOCKS-WORLD - - A simplified definition of the Sussman Anomaly problem. - - Example: - >>> from planning import * - >>> sbw = simple_blocks_world() - >>> sbw.goal_test() - False - >>> sbw.act(expr('ToTable(A, B)')) - >>> sbw.act(expr('FromTable(B, A)')) - >>> sbw.goal_test() - False - >>> sbw.act(expr('FromTable(C, B)')) - >>> sbw.goal_test() - True - >>> - """ - - return PlanningProblem(initial='On(A, B) & Clear(A) & OnTable(B) & OnTable(C) & Clear(C)', - goals='On(B, A) & On(C, B)', - actions=[Action('ToTable(x, y)', - precond='On(x, y) & Clear(x)', - effect='~On(x, y) & Clear(y) & OnTable(x)'), - Action('FromTable(y, x)', - precond='OnTable(y) & Clear(y) & Clear(x)', - effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) - - -def have_cake_and_eat_cake_too(): - """ - [Figure 10.7] CAKE-PROBLEM - - A problem where we begin with a cake and want to - reach the state of having a cake and having eaten a cake. - The possible actions include baking a cake and eating a cake. - - Example: - >>> from planning import * - >>> cp = have_cake_and_eat_cake_too() - >>> cp.goal_test() - False - >>> cp.act(expr('Eat(Cake)')) - >>> cp.goal_test() - False - >>> cp.act(expr('Bake(Cake)')) - >>> cp.goal_test() - True - >>> - """ - - return PlanningProblem(initial='Have(Cake)', - goals='Have(Cake) & Eaten(Cake)', - actions=[Action('Eat(Cake)', - precond='Have(Cake)', - effect='Eaten(Cake) & ~Have(Cake)'), - Action('Bake(Cake)', - precond='~Have(Cake)', - effect='Have(Cake)')]) - - -def shopping_problem(): - """ - SHOPPING-PROBLEM - - A problem of acquiring some items given their availability at certain stores. - - Example: - >>> from planning import * - >>> sp = shopping_problem() - >>> sp.goal_test() - False - >>> sp.act(expr('Go(Home, HW)')) - >>> sp.act(expr('Buy(Drill, HW)')) - >>> sp.act(expr('Go(HW, SM)')) - >>> sp.act(expr('Buy(Banana, SM)')) - >>> sp.goal_test() - False - >>> sp.act(expr('Buy(Milk, SM)')) - >>> sp.goal_test() - True - >>> - """ - - return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)', - goals='Have(Milk) & Have(Banana) & Have(Drill)', - actions=[Action('Buy(x, store)', - precond='At(store) & Sells(store, x)', - effect='Have(x)', - domain='Store(store) & Item(x)'), - Action('Go(x, y)', - precond='At(x)', - effect='At(y) & ~At(x)', - domain='Place(x) & Place(y)')], - domain='Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & ' - 'Item(Milk) & Item(Banana) & Item(Drill)') - - -def socks_and_shoes(): - """ - SOCKS-AND-SHOES-PROBLEM - - A task of wearing socks and shoes on both feet - - Example: - >>> from planning import * - >>> ss = socks_and_shoes() - >>> ss.goal_test() - False - >>> ss.act(expr('RightSock')) - >>> ss.act(expr('RightShoe')) - >>> ss.act(expr('LeftSock')) - >>> ss.goal_test() - False - >>> ss.act(expr('LeftShoe')) - >>> ss.goal_test() - True - >>> - """ - - return PlanningProblem(initial='', - goals='RightShoeOn & LeftShoeOn', - actions=[Action('RightShoe', - precond='RightSockOn', - effect='RightShoeOn'), - Action('RightSock', - precond='', - effect='RightSockOn'), - Action('LeftShoe', - precond='LeftSockOn', - effect='LeftShoeOn'), - Action('LeftSock', - precond='', - effect='LeftSockOn')]) - - -def double_tennis_problem(): - """ - [Figure 11.10] DOUBLE-TENNIS-PROBLEM - - A multiagent planning problem involving two partner tennis players - trying to return an approaching ball and repositioning around in the court. - - Example: - >>> from planning import * - >>> dtp = double_tennis_problem() - >>> goal_test(dtp.goals, dtp.initial) - False - >>> dtp.act(expr('Go(A, RightBaseLine, LeftBaseLine)')) - >>> dtp.act(expr('Hit(A, Ball, RightBaseLine)')) - >>> goal_test(dtp.goals, dtp.initial) - False - >>> dtp.act(expr('Go(A, LeftNet, RightBaseLine)')) - >>> goal_test(dtp.goals, dtp.initial) - True - >>> - """ - - return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - - -class ForwardPlan(search.Problem): - """ - [Section 10.2.1] - Forward state-space search - """ - - def __init__(self, planning_problem): - super().__init__(associate('&', planning_problem.initial), associate('&', planning_problem.goals)) - self.planning_problem = planning_problem - self.expanded_actions = self.planning_problem.expand_actions() - - def actions(self, state): - return [action for action in self.expanded_actions if all(pre in conjuncts(state) for pre in action.precond)] - - def result(self, state, action): - return associate('&', action(conjuncts(state), action.args).clauses) - - def goal_test(self, state): - return all(goal in conjuncts(state) for goal in self.planning_problem.goals) - - def h(self, state): - """ - Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that - by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be - easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic. - """ - relaxed_planning_problem = PlanningProblem(initial=state.state, - goals=self.goal, - actions=[action.relaxed() for action in - self.planning_problem.actions]) - try: - return len(linearize(GraphPlan(relaxed_planning_problem).execute())) - except: - return np.inf - - -class BackwardPlan(search.Problem): - """ - [Section 10.2.2] - Backward relevant-states search - """ - - def __init__(self, planning_problem): - super().__init__(associate('&', planning_problem.goals), associate('&', planning_problem.initial)) - self.planning_problem = planning_problem - self.expanded_actions = self.planning_problem.expand_actions() - - def actions(self, subgoal): - """ - Returns True if the action is relevant to the subgoal, i.e.: - - the action achieves an element of the effects - - the action doesn't delete something that needs to be achieved - - the preconditions are consistent with other subgoals that need to be achieved - """ - - def negate_clause(clause): - return Expr(clause.op.replace('Not', ''), *clause.args) if clause.op[:3] == 'Not' else Expr( - 'Not' + clause.op, *clause.args) - - subgoal = conjuncts(subgoal) - return [action for action in self.expanded_actions if - (any(prop in action.effect for prop in subgoal) and - not any(negate_clause(prop) in subgoal for prop in action.effect) and - not any(negate_clause(prop) in subgoal and negate_clause(prop) not in action.effect - for prop in action.precond))] - - def result(self, subgoal, action): - # g' = (g - effects(a)) + preconds(a) - return associate('&', set(set(conjuncts(subgoal)).difference(action.effect)).union(action.precond)) - - def goal_test(self, subgoal): - return all(goal in conjuncts(self.goal) for goal in conjuncts(subgoal)) - - def h(self, subgoal): - """ - Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that - by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be - easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic. - """ - relaxed_planning_problem = PlanningProblem(initial=self.goal, - goals=subgoal.state, - actions=[action.relaxed() for action in - self.planning_problem.actions]) - try: - return len(linearize(GraphPlan(relaxed_planning_problem).execute())) - except: - return np.inf - - -def CSPlan(planning_problem, solution_length, CSP_solver=ac_search_solver, arc_heuristic=sat_up): - """ - [Section 10.4.3] - Planning as Constraint Satisfaction Problem - """ - - def st(var, stage): - """Returns a string for the var-stage pair that can be used as a variable""" - return str(var) + "_" + str(stage) - - def if_(v1, v2): - """If the second argument is v2, the first argument must be v1""" - - def if_fun(x1, x2): - return x1 == v1 if x2 == v2 else True - - if_fun.__name__ = "if the second argument is " + str(v2) + " then the first argument is " + str(v1) + " " - return if_fun - - def eq_if_not_in_(actset): - """First and third arguments are equal if action is not in actset""" - - def eq_if_not_in(x1, a, x2): - return x1 == x2 if a not in actset else True - - eq_if_not_in.__name__ = "first and third arguments are equal if action is not in " + str(actset) + " " - return eq_if_not_in - - expanded_actions = planning_problem.expand_actions() - fluent_values = planning_problem.expand_fluents() - for horizon in range(solution_length): - act_vars = [st('action', stage) for stage in range(horizon + 1)] - domains = {av: list(map(lambda action: expr(str(action)), expanded_actions)) for av in act_vars} - domains.update({st(var, stage): {True, False} for var in fluent_values for stage in range(horizon + 2)}) - # initial state constraints - constraints = [Constraint((st(var, 0),), is_constraint(val)) - for (var, val) in {expr(str(fluent).replace('Not', '')): - True if fluent.op[:3] != 'Not' else False - for fluent in planning_problem.initial}.items()] - constraints += [Constraint((st(var, 0),), is_constraint(False)) - for var in {expr(str(fluent).replace('Not', '')) - for fluent in fluent_values if fluent not in planning_problem.initial}] - # goal state constraints - constraints += [Constraint((st(var, horizon + 1),), is_constraint(val)) - for (var, val) in {expr(str(fluent).replace('Not', '')): - True if fluent.op[:3] != 'Not' else False - for fluent in planning_problem.goals}.items()] - # precondition constraints - constraints += [Constraint((st(var, stage), st('action', stage)), if_(val, act)) - # st(var, stage) == val if st('action', stage) == act - for act, strps in {expr(str(action)): action for action in expanded_actions}.items() - for var, val in {expr(str(fluent).replace('Not', '')): - True if fluent.op[:3] != 'Not' else False - for fluent in strps.precond}.items() - for stage in range(horizon + 1)] - # effect constraints - constraints += [Constraint((st(var, stage + 1), st('action', stage)), if_(val, act)) - # st(var, stage + 1) == val if st('action', stage) == act - for act, strps in {expr(str(action)): action for action in expanded_actions}.items() - for var, val in {expr(str(fluent).replace('Not', '')): True if fluent.op[:3] != 'Not' else False - for fluent in strps.effect}.items() - for stage in range(horizon + 1)] - # frame constraints - constraints += [Constraint((st(var, stage), st('action', stage), st(var, stage + 1)), - eq_if_not_in_(set(map(lambda action: expr(str(action)), - {act for act in expanded_actions if var in act.effect - or Expr('Not' + var.op, *var.args) in act.effect})))) - for var in fluent_values for stage in range(horizon + 1)] - csp = NaryCSP(domains, constraints) - sol = CSP_solver(csp, arc_heuristic=arc_heuristic) - if sol: - return [sol[a] for a in act_vars] - - -def SATPlan(planning_problem, solution_length, SAT_solver=cdcl_satisfiable): - """ - [Section 10.4.1] - Planning as Boolean satisfiability - """ - - def expand_transitions(state, actions): - state = sorted(conjuncts(state)) - for action in filter(lambda act: act.check_precond(state, act.args), actions): - transition[associate('&', state)].update( - {Expr(action.name, *action.args): - associate('&', sorted(set(filter(lambda clause: clause.op[:3] != 'Not', - action(state, action.args).clauses)))) - if planning_problem.is_strips() - else associate('&', sorted(set(action(state, action.args).clauses)))}) - for state in transition[associate('&', state)].values(): - if state not in transition: - expand_transitions(expr(state), actions) - - transition = defaultdict(dict) - expand_transitions(associate('&', planning_problem.initial), planning_problem.expand_actions()) - - return SAT_plan(associate('&', sorted(planning_problem.initial)), transition, - associate('&', sorted(planning_problem.goals)), solution_length, SAT_solver=SAT_solver) - - -class Level: - """ - Contains the state of the planning problem - and exhaustive list of actions which use the - states as pre-condition. - """ - - def __init__(self, kb): - """Initializes variables to hold state and action details of a level""" - - self.kb = kb - # current state - self.current_state = kb.clauses - # current action to state link - self.current_action_links = {} - # current state to action link - self.current_state_links = {} - # current action to next state link - self.next_action_links = {} - # next state to current action link - self.next_state_links = {} - # mutually exclusive actions - self.mutex = [] - - def __call__(self, actions, objects): - self.build(actions, objects) - self.find_mutex() - - def separate(self, e): - """Separates an iterable of elements into positive and negative parts""" - - positive = [] - negative = [] - for clause in e: - if clause.op[:3] == 'Not': - negative.append(clause) - else: - positive.append(clause) - return positive, negative - - def find_mutex(self): - """Finds mutually exclusive actions""" - - # Inconsistent effects - pos_nsl, neg_nsl = self.separate(self.next_state_links) - - for negeff in neg_nsl: - new_negeff = Expr(negeff.op[3:], *negeff.args) - for poseff in pos_nsl: - if new_negeff == poseff: - for a in self.next_state_links[poseff]: - for b in self.next_state_links[negeff]: - if {a, b} not in self.mutex: - self.mutex.append({a, b}) - - # Interference will be calculated with the last step - pos_csl, neg_csl = self.separate(self.current_state_links) - - # Competing needs - for pos_precond in pos_csl: - for neg_precond in neg_csl: - new_neg_precond = Expr(neg_precond.op[3:], *neg_precond.args) - if new_neg_precond == pos_precond: - for a in self.current_state_links[pos_precond]: - for b in self.current_state_links[neg_precond]: - if {a, b} not in self.mutex: - self.mutex.append({a, b}) - - # Inconsistent support - state_mutex = [] - for pair in self.mutex: - next_state_0 = self.next_action_links[list(pair)[0]] - if len(pair) == 2: - next_state_1 = self.next_action_links[list(pair)[1]] - else: - next_state_1 = self.next_action_links[list(pair)[0]] - if (len(next_state_0) == 1) and (len(next_state_1) == 1): - state_mutex.append({next_state_0[0], next_state_1[0]}) - - self.mutex = self.mutex + state_mutex - - def build(self, actions, objects): - """Populates the lists and dictionaries containing the state action dependencies""" - - for clause in self.current_state: - p_expr = Expr('P' + clause.op, *clause.args) - self.current_action_links[p_expr] = [clause] - self.next_action_links[p_expr] = [clause] - self.current_state_links[clause] = [p_expr] - self.next_state_links[clause] = [p_expr] - - for a in actions: - num_args = len(a.args) - possible_args = tuple(itertools.permutations(objects, num_args)) - - for arg in possible_args: - if a.check_precond(self.kb, arg): - for num, symbol in enumerate(a.args): - if not symbol.op.islower(): - arg = list(arg) - arg[num] = symbol - arg = tuple(arg) - - new_action = a.substitute(Expr(a.name, *a.args), arg) - self.current_action_links[new_action] = [] - - for clause in a.precond: - new_clause = a.substitute(clause, arg) - self.current_action_links[new_action].append(new_clause) - if new_clause in self.current_state_links: - self.current_state_links[new_clause].append(new_action) - else: - self.current_state_links[new_clause] = [new_action] - - self.next_action_links[new_action] = [] - for clause in a.effect: - new_clause = a.substitute(clause, arg) - - self.next_action_links[new_action].append(new_clause) - if new_clause in self.next_state_links: - self.next_state_links[new_clause].append(new_action) - else: - self.next_state_links[new_clause] = [new_action] - - def perform_actions(self): - """Performs the necessary actions and returns a new Level""" - - new_kb = FolKB(list(set(self.next_state_links.keys()))) - return Level(new_kb) - - -class Graph: - """ - Contains levels of state and actions - Used in graph planning algorithm to extract a solution - """ - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - self.kb = FolKB(planning_problem.initial) - self.levels = [Level(self.kb)] - self.objects = set(arg for clause in self.kb.clauses for arg in clause.args) - - def __call__(self): - self.expand_graph() - - def expand_graph(self): - """Expands the graph by a level""" - - last_level = self.levels[-1] - last_level(self.planning_problem.actions, self.objects) - self.levels.append(last_level.perform_actions()) - - def non_mutex_goals(self, goals, index): - """Checks whether the goals are mutually exclusive""" - - goal_perm = itertools.combinations(goals, 2) - for g in goal_perm: - if set(g) in self.levels[index].mutex: - return False - return True - - -class GraphPlan: - """ - Class for formulation GraphPlan algorithm - Constructs a graph of state and action space - Returns solution for the planning problem - """ - - def __init__(self, planning_problem): - self.graph = Graph(planning_problem) - self.no_goods = [] - self.solution = [] - - def check_leveloff(self): - """Checks if the graph has levelled off""" - - check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) - - if check: - return True - - def extract_solution(self, goals, index): - """Extracts the solution""" - - level = self.graph.levels[index] - if not self.graph.non_mutex_goals(goals, index): - self.no_goods.append((level, goals)) - return - - level = self.graph.levels[index - 1] - - # Create all combinations of actions that satisfy the goal - actions = [] - for goal in goals: - actions.append(level.next_state_links[goal]) - - all_actions = list(itertools.product(*actions)) - - # Filter out non-mutex actions - non_mutex_actions = [] - for action_tuple in all_actions: - action_pairs = itertools.combinations(list(set(action_tuple)), 2) - non_mutex_actions.append(list(set(action_tuple))) - for pair in action_pairs: - if set(pair) in level.mutex: - non_mutex_actions.pop(-1) - break - - # Recursion - for action_list in non_mutex_actions: - if [action_list, index] not in self.solution: - self.solution.append([action_list, index]) - - new_goals = [] - for act in set(action_list): - if act in level.current_action_links: - new_goals = new_goals + level.current_action_links[act] - - if abs(index) + 1 == len(self.graph.levels): - return - elif (level, new_goals) in self.no_goods: - return - else: - self.extract_solution(new_goals, index - 1) - - # Level-Order multiple solutions - solution = [] - for item in self.solution: - if item[1] == -1: - solution.append([]) - solution[-1].append(item[0]) - else: - solution[-1].append(item[0]) - - for num, item in enumerate(solution): - item.reverse() - solution[num] = item - - return solution - - def goal_test(self, kb): - return all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) - - def execute(self): - """Executes the GraphPlan algorithm for the given problem""" - - while True: - self.graph.expand_graph() - if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( - self.graph.planning_problem.goals, -1)): - solution = self.extract_solution(self.graph.planning_problem.goals, -1) - if solution: - return solution - - if len(self.graph.levels) >= 2 and self.check_leveloff(): - return None - - -def print_nested_list(nested_list, indent=0): - """Recursively prints a nested list with indentation to show structure.""" - for item in nested_list: - if isinstance(item, list): # If item is a list, recurse deeper - print(" " * indent + "- List:") - print_nested_list(item, indent + 4) - else: - print(" " * indent + f"- {item}") - -pnl = print_nested_list - - -class Linearize: - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - - def filter(self, solution): - """Filter out persistence actions from a solution""" - - new_solution = [] - for section in solution[0]: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution - - def orderlevel(self, level, planning_problem): - """Return valid linear order of actions for a given level""" - - for permutation in itertools.permutations(level): - temp = copy.deepcopy(planning_problem) - count = 0 - ## print(f"PERMUTATION: {permutation}") ## Bill's hack - for action in permutation: - try: - # print(f"TRY ACTION: {action}") ## Bill's hack - temp.act(action) - count += 1 - # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack - except: - # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack - count = 0 - temp = copy.deepcopy(planning_problem) - continue ##break - if count == len(permutation): - print(f"SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack - return list(permutation), temp - print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack - return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem - - def execute(self): - """Finds total-order solution for a planning graph""" - - graphPlan_solution = GraphPlan(self.planning_problem).execute() - - ## Bill's stuff from playing around - ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack - ## pnl(graphPlan_solution) - ## for possible_plan in graphPlan_solution: - ## possible_plan = [possible_plan] - ## filtered_possible_plan = self.filter(possible_plan) - ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack - ## flattened_graphplan = self.filter(graphPlan_solution) - ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack - ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack - ## flattened_graphplan = [flattened_graphplan] - ## graphPlan_solution = [flattened_graphplan] ## Bill's hack - ## pnl(flattened_graphplan) - - ## I think I have to go over all permutations of possbile partial graphplans - - for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack - - ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list - ## filtered_solution = self.filter(graphPlan_solution) # original - - filtered_solution = self.filter(possible_plan) # my mod - - ## filtered_solution = self.filter(possible_plan) # mod - ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack - ## pnl(filtered_solution) - ## filtered_solution = possible_plan - - ordered_solution = [] - planning_problem = self.planning_problem - for level in filtered_solution: - - ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack - - ## the below is a key line, the key line - level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied - if not level_solution: # This checks if level_solution is None or an empty list - continue ## Bill's hack!! if empty, continue looking. - - print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack - print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack - ## for action in level_solution: - ## print(f"APPLY ACTION: {action}") ## Bill's hack - ## planning_problem.act(action) # complete guess, apply action to the problem and keep going - - ## I think we need to apply the plan to the planning problem and modify it - for element in level_solution: - ordered_solution.append(element) - - if not ordered_solution: - continue - else: - break - - return ordered_solution - - - - -def linearize(solution): - """Converts a level-ordered solution into a linear solution""" - - linear_solution = [] - for section in solution[0]: - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - linear_solution.append(operation) - - return linear_solution - - -class PartialOrderPlanner: - """ - [Section 10.13] PARTIAL-ORDER-PLANNER - - Partially ordered plans are created by a search through the space of plans - rather than a search through the state space. It views planning as a refinement of partially ordered plans. - A partially ordered plan is defined by a set of actions and a set of constraints of the form A < B, - which denotes that action A has to be performed before action B. - To summarize the working of a partial order planner, - 1. An open precondition is selected (a sub-goal that we want to achieve). - 2. An action that fulfils the open precondition is chosen. - 3. Temporal constraints are updated. - 4. Existing causal links are protected. Protection is a method that checks if the causal links conflict - and if they do, temporal constraints are added to fix the threats. - 5. The set of open preconditions is updated. - 6. Temporal constraints of the selected action and the next action are established. - 7. A new causal link is added between the selected action and the owner of the open precondition. - 8. The set of new causal links is checked for threats and if found, the threat is removed by either promotion or - demotion. If promotion or demotion is unable to solve the problem, the planning problem cannot be solved with - the current sequence of actions or it may not be solvable at all. - 9. These steps are repeated until the set of open preconditions is empty. - """ - - def __init__(self, planning_problem): - self.tries = 1 - self.planning_problem = planning_problem - self.causal_links = [] - self.start = Action('Start', [], self.planning_problem.initial) - self.finish = Action('Finish', self.planning_problem.goals, []) - self.actions = set() - self.actions.add(self.start) - self.actions.add(self.finish) - self.constraints = set() - self.constraints.add((self.start, self.finish)) - self.agenda = set() - for precond in self.finish.precond: - self.agenda.add((precond, self.finish)) - self.expanded_actions = planning_problem.expand_actions() - - def find_open_precondition(self): - """Find open precondition with the least number of possible actions""" - - number_of_ways = dict() - actions_for_precondition = dict() - for element in self.agenda: - open_precondition = element[0] - possible_actions = list(self.actions) + self.expanded_actions - for action in possible_actions: - for effect in action.effect: - if effect == open_precondition: - if open_precondition in number_of_ways: - number_of_ways[open_precondition] += 1 - actions_for_precondition[open_precondition].append(action) - else: - number_of_ways[open_precondition] = 1 - actions_for_precondition[open_precondition] = [action] - - number = sorted(number_of_ways, key=number_of_ways.__getitem__) - - for k, v in number_of_ways.items(): - if v == 0: - return None, None, None - - act1 = None - for element in self.agenda: - if element[0] == number[0]: - act1 = element[1] - break - - if number[0] in self.expanded_actions: - self.expanded_actions.remove(number[0]) - - return number[0], act1, actions_for_precondition[number[0]] - - def find_action_for_precondition(self, oprec): - """Find action for a given precondition""" - - # either - # choose act0 E Actions such that act0 achieves G - for action in self.actions: - for effect in action.effect: - if effect == oprec: - return action, 0 - - # or - # choose act0 E Actions such that act0 achieves G - for action in self.planning_problem.actions: - for effect in action.effect: - if effect.op == oprec.op: - bindings = unify_mm(effect, oprec) - if bindings is None: - break - return action, bindings - - def generate_expr(self, clause, bindings): - """Generate atomic expression from generic expression given variable bindings""" - - new_args = [] - for arg in clause.args: - if arg in bindings: - new_args.append(bindings[arg]) - else: - new_args.append(arg) - - try: - return Expr(str(clause.name), *new_args) - except: - return Expr(str(clause.op), *new_args) - - def generate_action_object(self, action, bindings): - """Generate action object given a generic action and variable bindings""" - - # if bindings is 0, it means the action already exists in self.actions - if bindings == 0: - return action - - # bindings cannot be None - else: - new_expr = self.generate_expr(action, bindings) - new_preconds = [] - for precond in action.precond: - new_precond = self.generate_expr(precond, bindings) - new_preconds.append(new_precond) - new_effects = [] - for effect in action.effect: - new_effect = self.generate_expr(effect, bindings) - new_effects.append(new_effect) - return Action(new_expr, new_preconds, new_effects) - - def cyclic(self, graph): - """Check cyclicity of a directed graph""" - - new_graph = dict() - for element in graph: - if element[0] in new_graph: - new_graph[element[0]].append(element[1]) - else: - new_graph[element[0]] = [element[1]] - - path = set() - - def visit(vertex): - path.add(vertex) - for neighbor in new_graph.get(vertex, ()): - if neighbor in path or visit(neighbor): - return True - path.remove(vertex) - return False - - value = any(visit(v) for v in new_graph) - return value - - def add_const(self, constraint, constraints): - """Add the constraint to constraints if the resulting graph is acyclic""" - - if constraint[0] == self.finish or constraint[1] == self.start: - return constraints - - new_constraints = set(constraints) - new_constraints.add(constraint) - - if self.cyclic(new_constraints): - return constraints - return new_constraints - - def is_a_threat(self, precondition, effect): - """Check if effect is a threat to precondition""" - - if (str(effect.op) == 'Not' + str(precondition.op)) or ('Not' + str(effect.op) == str(precondition.op)): - if effect.args == precondition.args: - return True - return False - - def protect(self, causal_link, action, constraints): - """Check and resolve threats by promotion or demotion""" - - threat = False - for effect in action.effect: - if self.is_a_threat(causal_link[1], effect): - threat = True - break - - if action != causal_link[0] and action != causal_link[2] and threat: - # try promotion - new_constraints = set(constraints) - new_constraints.add((action, causal_link[0])) - if not self.cyclic(new_constraints): - constraints = self.add_const((action, causal_link[0]), constraints) - else: - # try demotion - new_constraints = set(constraints) - new_constraints.add((causal_link[2], action)) - if not self.cyclic(new_constraints): - constraints = self.add_const((causal_link[2], action), constraints) - else: - # both promotion and demotion fail - print('Unable to resolve a threat caused by', action, 'onto', causal_link) - return - return constraints - - def convert(self, constraints): - """Convert constraints into a dict of Action to set orderings""" - - graph = dict() - for constraint in constraints: - if constraint[0] in graph: - graph[constraint[0]].add(constraint[1]) - else: - graph[constraint[0]] = set() - graph[constraint[0]].add(constraint[1]) - return graph - - def toposort(self, graph): - """Generate topological ordering of constraints""" - - if len(graph) == 0: - return - - graph = graph.copy() - - for k, v in graph.items(): - v.discard(k) - - extra_elements_in_dependencies = _reduce(set.union, graph.values()) - set(graph.keys()) - - graph.update({element: set() for element in extra_elements_in_dependencies}) - while True: - ordered = set(element for element, dependency in graph.items() if len(dependency) == 0) - if not ordered: - break - yield ordered - graph = {element: (dependency - ordered) - for element, dependency in graph.items() - if element not in ordered} - if len(graph) != 0: - raise ValueError('The graph is not acyclic and cannot be linearly ordered') - - def display_plan(self): - """Display causal links, constraints and the plan""" - - print('Causal Links') - for causal_link in self.causal_links: - print(causal_link) - - print('\nConstraints') - for constraint in self.constraints: - print(constraint[0], '<', constraint[1]) - - print('\nPartial Order Plan') - print(list(reversed(list(self.toposort(self.convert(self.constraints)))))) - - def execute(self, display=True): - """Execute the algorithm""" - - step = 1 - while len(self.agenda) > 0: - step += 1 - # select from Agenda - try: - G, act1, possible_actions = self.find_open_precondition() - except IndexError: - print('Probably Wrong') - break - - act0 = possible_actions[0] - # remove from Agenda - self.agenda.remove((G, act1)) - - # For actions with variable number of arguments, use least commitment principle - # act0_temp, bindings = self.find_action_for_precondition(G) - # act0 = self.generate_action_object(act0_temp, bindings) - - # Actions = Actions U {act0} - self.actions.add(act0) - - # Constraints = add_const(start < act0, Constraints) - self.constraints = self.add_const((self.start, act0), self.constraints) - - # for each CL E CausalLinks do - # Constraints = protect(CL, act0, Constraints) - for causal_link in self.causal_links: - self.constraints = self.protect(causal_link, act0, self.constraints) - - # Agenda = Agenda U {: P is a precondition of act0} - for precondition in act0.precond: - self.agenda.add((precondition, act0)) - - # Constraints = add_const(act0 < act1, Constraints) - self.constraints = self.add_const((act0, act1), self.constraints) - - # CausalLinks U {} - if (act0, G, act1) not in self.causal_links: - self.causal_links.append((act0, G, act1)) - - # for each A E Actions do - # Constraints = protect(, A, Constraints) - for action in self.actions: - self.constraints = self.protect((act0, G, act1), action, self.constraints) - - if step > 200: - print("Couldn't find a solution") - return None, None - - if display: - self.display_plan() - else: - return self.constraints, self.causal_links - - -def spare_tire_graphPlan(): - """Solves the spare tire problem using GraphPlan""" - return GraphPlan(spare_tire()).execute() - - -def three_block_tower_graphPlan(): - """Solves the Sussman Anomaly problem using GraphPlan""" - return GraphPlan(three_block_tower()).execute() - - -def air_cargo_graphPlan(): - """Solves the air cargo problem using GraphPlan""" - return GraphPlan(air_cargo()).execute() - - -def have_cake_and_eat_cake_too_graphPlan(): - """Solves the cake problem using GraphPlan""" - return [GraphPlan(have_cake_and_eat_cake_too()).execute()[1]] - - -def shopping_graphPlan(): - """Solves the shopping problem using GraphPlan""" - return GraphPlan(shopping_problem()).execute() - - -def socks_and_shoes_graphPlan(): - """Solves the socks and shoes problem using GraphPlan""" - return GraphPlan(socks_and_shoes()).execute() - - -def simple_blocks_world_graphPlan(): - """Solves the simple blocks world problem""" - return GraphPlan(simple_blocks_world()).execute() - - -class HLA(Action): - """ - Define Actions for the real-world (that may be refined further), and satisfy resource - constraints. - """ - unique_group = 1 - - def __init__(self, action, precond=None, effect=None, duration=0, consume=None, use=None): - """ - As opposed to actions, to define HLA, we have added constraints. - duration holds the amount of time required to execute the task - consumes holds a dictionary representing the resources the task consumes - uses holds a dictionary representing the resources the task uses - """ - precond = precond or [None] - effect = effect or [None] - super().__init__(action, precond, effect) - self.duration = duration - self.consumes = consume or {} - self.uses = use or {} - self.completed = False - # self.priority = -1 # must be assigned in relation to other HLAs - # self.job_group = -1 # must be assigned in relation to other HLAs - - def do_action(self, job_order, available_resources, kb, args): - """ - An HLA based version of act - along with knowledge base updation, it handles - resource checks, and ensures the actions are executed in the correct order. - """ - if not self.has_usable_resource(available_resources): - raise Exception('Not enough usable resources to execute {}'.format(self.name)) - if not self.has_consumable_resource(available_resources): - raise Exception('Not enough consumable resources to execute {}'.format(self.name)) - if not self.inorder(job_order): - raise Exception("Can't execute {} - execute prerequisite actions first". - format(self.name)) - kb = super().act(kb, args) # update knowledge base - for resource in self.consumes: # remove consumed resources - available_resources[resource] -= self.consumes[resource] - self.completed = True # set the task status to complete - return kb - - def has_consumable_resource(self, available_resources): - """ - Ensure there are enough consumable resources for this action to execute. - """ - for resource in self.consumes: - if available_resources.get(resource) is None: - return False - if available_resources[resource] < self.consumes[resource]: - return False - return True - - def has_usable_resource(self, available_resources): - """ - Ensure there are enough usable resources for this action to execute. - """ - for resource in self.uses: - if available_resources.get(resource) is None: - return False - if available_resources[resource] < self.uses[resource]: - return False - return True - - def inorder(self, job_order): - """ - Ensure that all the jobs that had to be executed before the current one have been - successfully executed. - """ - for jobs in job_order: - if self in jobs: - for job in jobs: - if job is self: - return True - if not job.completed: - return False - return True - - -class RealWorldPlanningProblem(PlanningProblem): - """ - Define real-world problems by aggregating resources as numerical quantities instead of - named entities. - - This class is identical to PDDL, except that it overloads the act function to handle - resource and ordering conditions imposed by HLA as opposed to Action. - """ - - def __init__(self, initial, goals, actions, jobs=None, resources=None): - super().__init__(initial, goals, actions) - self.jobs = jobs - self.resources = resources or {} - - def act(self, action): - """ - Performs the HLA given as argument. - - Note that this is different from the superclass action - where the parameter was an - Expression. For real world problems, an Expr object isn't enough to capture all the - detail required for executing the action - resources, preconditions, etc need to be - checked for too. - """ - args = action.args - list_action = first(a for a in self.actions if a.name == action.name) - if list_action is None: - raise Exception("Action '{}' not found".format(action.name)) - self.initial = list_action.do_action(self.jobs, self.resources, self.initial, args).clauses - - def refinements(self, library): # refinements may be (multiple) HLA themselves ... - """ - State is a Problem, containing the current state kb library is a - dictionary containing details for every possible refinement. e.g.: - { - 'HLA': [ - 'Go(Home, SFO)', - 'Go(Home, SFO)', - 'Drive(Home, SFOLongTermParking)', - 'Shuttle(SFOLongTermParking, SFO)', - 'Taxi(Home, SFO)' - ], - 'steps': [ - ['Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)'], - ['Taxi(Home, SFO)'], - [], - [], - [] - ], - # empty refinements indicate a primitive action - 'precond': [ - ['At(Home) & Have(Car)'], - ['At(Home)'], - ['At(Home) & Have(Car)'], - ['At(SFOLongTermParking)'], - ['At(Home)'] - ], - 'effect': [ - ['At(SFO) & ~At(Home)'], - ['At(SFO) & ~At(Home)'], - ['At(SFOLongTermParking) & ~At(Home)'], - ['At(SFO) & ~At(SFOLongTermParking)'], - ['At(SFO) & ~At(Home)'] - ]} - """ - indices = [i for i, x in enumerate(library['HLA']) if expr(x).op == self.name] - for i in indices: - actions = [] - for j in range(len(library['steps'][i])): - # find the index of the step [j] of the HLA - index_step = [k for k, x in enumerate(library['HLA']) if x == library['steps'][i][j]][0] - precond = library['precond'][index_step][0] # preconditions of step [j] - effect = library['effect'][index_step][0] # effect of step [j] - actions.append(HLA(library['steps'][i][j], precond, effect)) - yield actions - - def hierarchical_search(self, hierarchy): - """ - [Figure 11.5] - 'Hierarchical Search, a Breadth First Search implementation of Hierarchical - Forward Planning Search' - The problem is a real-world problem defined by the problem class, and the hierarchy is - a dictionary of HLA - refinements (see refinements generator for details) - """ - act = Node(self.initial, None, [self.actions[0]]) - frontier = deque() - frontier.append(act) - while True: - if not frontier: - return None - plan = frontier.popleft() - # finds the first non primitive hla in plan actions - (hla, index) = RealWorldPlanningProblem.find_hla(plan, hierarchy) - prefix = plan.action[:index] - outcome = RealWorldPlanningProblem( - RealWorldPlanningProblem.result(self.initial, prefix), self.goals, self.actions) - suffix = plan.action[index + 1:] - if not hla: # hla is None and plan is primitive - if outcome.goal_test(): - return plan.action - else: - for sequence in RealWorldPlanningProblem.refinements(hla, hierarchy): # find refinements - frontier.append(Node(outcome.initial, plan, prefix + sequence + suffix)) - - def result(state, actions): - """The outcome of applying an action to the current problem""" - for a in actions: - if a.check_precond(state, a.args): - state = a(state, a.args).clauses - return state - - def angelic_search(self, hierarchy, initial_plan): - """ - [Figure 11.8] - A hierarchical planning algorithm that uses angelic semantics to identify and - commit to high-level plans that work while avoiding high-level plans that don’t. - The predicate MAKING-PROGRESS checks to make sure that we aren’t stuck in an infinite regression - of refinements. - At top level, call ANGELIC-SEARCH with [Act] as the initialPlan. - - InitialPlan contains a sequence of HLA's with angelic semantics - - The possible effects of an angelic HLA in initialPlan are: - ~ : effect remove - $+: effect possibly add - $-: effect possibly remove - $$: possibly add or remove - """ - frontier = deque(initial_plan) - while True: - if not frontier: - return None - plan = frontier.popleft() # sequence of HLA/Angelic HLA's - opt_reachable_set = RealWorldPlanningProblem.reach_opt(self.initial, plan) - pes_reachable_set = RealWorldPlanningProblem.reach_pes(self.initial, plan) - if self.intersects_goal(opt_reachable_set): - if RealWorldPlanningProblem.is_primitive(plan, hierarchy): - return [x for x in plan.action] - guaranteed = self.intersects_goal(pes_reachable_set) - if guaranteed and RealWorldPlanningProblem.making_progress(plan, initial_plan): - final_state = guaranteed[0] # any element of guaranteed - return RealWorldPlanningProblem.decompose(hierarchy, final_state, pes_reachable_set) - # there should be at least one HLA/AngelicHLA, otherwise plan would be primitive - hla, index = RealWorldPlanningProblem.find_hla(plan, hierarchy) - prefix = plan.action[:index] - suffix = plan.action[index + 1:] - outcome = RealWorldPlanningProblem( - RealWorldPlanningProblem.result(self.initial, prefix), self.goals, self.actions) - for sequence in RealWorldPlanningProblem.refinements(hla, hierarchy): # find refinements - frontier.append( - AngelicNode(outcome.initial, plan, prefix + sequence + suffix, prefix + sequence + suffix)) - - def intersects_goal(self, reachable_set): - """ - Find the intersection of the reachable states and the goal - """ - return [y for x in list(reachable_set.keys()) - for y in reachable_set[x] - if all(goal in y for goal in self.goals)] - - def is_primitive(plan, library): - """ - checks if the hla is primitive action - """ - for hla in plan.action: - indices = [i for i, x in enumerate(library['HLA']) if expr(x).op == hla.name] - for i in indices: - if library["steps"][i]: - return False - return True - - def reach_opt(init, plan): - """ - Finds the optimistic reachable set of the sequence of actions in plan - """ - reachable_set = {0: [init]} - optimistic_description = plan.action # list of angelic actions with optimistic description - return RealWorldPlanningProblem.find_reachable_set(reachable_set, optimistic_description) - - def reach_pes(init, plan): - """ - Finds the pessimistic reachable set of the sequence of actions in plan - """ - reachable_set = {0: [init]} - pessimistic_description = plan.action_pes # list of angelic actions with pessimistic description - return RealWorldPlanningProblem.find_reachable_set(reachable_set, pessimistic_description) - - def find_reachable_set(reachable_set, action_description): - """ - Finds the reachable states of the action_description when applied in each state of reachable set. - """ - for i in range(len(action_description)): - reachable_set[i + 1] = [] - if type(action_description[i]) is AngelicHLA: - possible_actions = action_description[i].angelic_action() - else: - possible_actions = action_description - for action in possible_actions: - for state in reachable_set[i]: - if action.check_precond(state, action.args): - if action.effect[0]: - new_state = action(state, action.args).clauses - reachable_set[i + 1].append(new_state) - else: - reachable_set[i + 1].append(state) - return reachable_set - - def find_hla(plan, hierarchy): - """ - Finds the the first HLA action in plan.action, which is not primitive - and its corresponding index in plan.action - """ - hla = None - index = len(plan.action) - for i in range(len(plan.action)): # find the first HLA in plan, that is not primitive - if not RealWorldPlanningProblem.is_primitive(Node(plan.state, plan.parent, [plan.action[i]]), hierarchy): - hla = plan.action[i] - index = i - break - return hla, index - - def making_progress(plan, initial_plan): - """ - Prevents from infinite regression of refinements - - (infinite regression of refinements happens when the algorithm finds a plan that - its pessimistic reachable set intersects the goal inside a call to decompose on - the same plan, in the same circumstances) - """ - for i in range(len(initial_plan)): - if plan == initial_plan[i]: - return False - return True - - def decompose(hierarchy, plan, s_f, reachable_set): - solution = [] - i = max(reachable_set.keys()) - while plan.action_pes: - action = plan.action_pes.pop() - if i == 0: - return solution - s_i = RealWorldPlanningProblem.find_previous_state(s_f, reachable_set, i, action) - problem = RealWorldPlanningProblem(s_i, s_f, plan.action) - angelic_call = RealWorldPlanningProblem.angelic_search(problem, hierarchy, - [AngelicNode(s_i, Node(None), [action], [action])]) - if angelic_call: - for x in angelic_call: - solution.insert(0, x) - else: - return None - s_f = s_i - i -= 1 - return solution - - def find_previous_state(s_f, reachable_set, i, action): - """ - Given a final state s_f and an action finds a state s_i in reachable_set - such that when action is applied to state s_i returns s_f. - """ - s_i = reachable_set[i - 1][0] - for state in reachable_set[i - 1]: - if s_f in [x for x in RealWorldPlanningProblem.reach_pes( - state, AngelicNode(state, None, [action], [action]))[1]]: - s_i = state - break - return s_i - - -def job_shop_problem(): - """ - [Figure 11.1] JOB-SHOP-PROBLEM - - A job-shop scheduling problem for assembling two cars, - with resource and ordering constraints. - - Example: - >>> from planning import * - >>> p = job_shop_problem() - >>> p.goal_test() - False - >>> p.act(p.jobs[1][0]) - >>> p.act(p.jobs[1][1]) - >>> p.act(p.jobs[1][2]) - >>> p.act(p.jobs[0][0]) - >>> p.act(p.jobs[0][1]) - >>> p.goal_test() - False - >>> p.act(p.jobs[0][2]) - >>> p.goal_test() - True - >>> - """ - resources = {'EngineHoists': 1, 'WheelStations': 2, 'Inspectors': 2, 'LugNuts': 500} - - add_engine1 = HLA('AddEngine1', precond='~Has(C1, E1)', effect='Has(C1, E1)', duration=30, use={'EngineHoists': 1}) - add_engine2 = HLA('AddEngine2', precond='~Has(C2, E2)', effect='Has(C2, E2)', duration=60, use={'EngineHoists': 1}) - add_wheels1 = HLA('AddWheels1', precond='~Has(C1, W1)', effect='Has(C1, W1)', duration=30, use={'WheelStations': 1}, - consume={'LugNuts': 20}) - add_wheels2 = HLA('AddWheels2', precond='~Has(C2, W2)', effect='Has(C2, W2)', duration=15, use={'WheelStations': 1}, - consume={'LugNuts': 20}) - inspect1 = HLA('Inspect1', precond='~Inspected(C1)', effect='Inspected(C1)', duration=10, use={'Inspectors': 1}) - inspect2 = HLA('Inspect2', precond='~Inspected(C2)', effect='Inspected(C2)', duration=10, use={'Inspectors': 1}) - - actions = [add_engine1, add_engine2, add_wheels1, add_wheels2, inspect1, inspect2] - - job_group1 = [add_engine1, add_wheels1, inspect1] - job_group2 = [add_engine2, add_wheels2, inspect2] - - return RealWorldPlanningProblem( - initial='Car(C1) & Car(C2) & Wheels(W1) & Wheels(W2) & Engine(E2) & Engine(E2) & ~Has(C1, E1) & ~Has(C2, ' - 'E2) & ~Has(C1, W1) & ~Has(C2, W2) & ~Inspected(C1) & ~Inspected(C2)', - goals='Has(C1, W1) & Has(C1, E1) & Inspected(C1) & Has(C2, W2) & Has(C2, E2) & Inspected(C2)', - actions=actions, - jobs=[job_group1, job_group2], - resources=resources) - - -def go_to_sfo(): - """Go to SFO Problem""" - - go_home_sfo1 = HLA('Go(Home, SFO)', precond='At(Home) & Have(Car)', effect='At(SFO) & ~At(Home)') - go_home_sfo2 = HLA('Go(Home, SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') - drive_home_sfoltp = HLA('Drive(Home, SFOLongTermParking)', precond='At(Home) & Have(Car)', - effect='At(SFOLongTermParking) & ~At(Home)') - shuttle_sfoltp_sfo = HLA('Shuttle(SFOLongTermParking, SFO)', precond='At(SFOLongTermParking)', - effect='At(SFO) & ~At(SFOLongTermParking)') - taxi_home_sfo = HLA('Taxi(Home, SFO)', precond='At(Home)', effect='At(SFO) & ~At(Home)') - - actions = [go_home_sfo1, go_home_sfo2, drive_home_sfoltp, shuttle_sfoltp_sfo, taxi_home_sfo] - - library = { - 'HLA': [ - 'Go(Home, SFO)', - 'Go(Home, SFO)', - 'Drive(Home, SFOLongTermParking)', - 'Shuttle(SFOLongTermParking, SFO)', - 'Taxi(Home, SFO)' - ], - 'steps': [ - ['Drive(Home, SFOLongTermParking)', 'Shuttle(SFOLongTermParking, SFO)'], - ['Taxi(Home, SFO)'], - [], - [], - [] - ], - 'precond': [ - ['At(Home) & Have(Car)'], - ['At(Home)'], - ['At(Home) & Have(Car)'], - ['At(SFOLongTermParking)'], - ['At(Home)'] - ], - 'effect': [ - ['At(SFO) & ~At(Home)'], - ['At(SFO) & ~At(Home)'], - ['At(SFOLongTermParking) & ~At(Home)'], - ['At(SFO) & ~At(SFOLongTermParking)'], - ['At(SFO) & ~At(Home)']]} - - return RealWorldPlanningProblem(initial='At(Home)', goals='At(SFO)', actions=actions), library - - -class AngelicHLA(HLA): - """ - Define Actions for the real-world (that may be refined further), under angelic semantics - """ - - def __init__(self, action, precond, effect, duration=0, consume=None, use=None): - super().__init__(action, precond, effect, duration, consume, use) - - def convert(self, clauses): - """ - Converts strings into Exprs - An HLA with angelic semantics can achieve the effects of simple HLA's (add / remove a variable) - and furthermore can have following effects on the variables: - Possibly add variable ( $+ ) - Possibly remove variable ( $- ) - Possibly add or remove a variable ( $$ ) - - Overrides HLA.convert function - """ - lib = {'~': 'Not', - '$+': 'PosYes', - '$-': 'PosNot', - '$$': 'PosYesNot'} - - if isinstance(clauses, Expr): - clauses = conjuncts(clauses) - for i in range(len(clauses)): - for ch in lib.keys(): - if clauses[i].op == ch: - clauses[i] = expr(lib[ch] + str(clauses[i].args[0])) - - elif isinstance(clauses, str): - for ch in lib.keys(): - clauses = clauses.replace(ch, lib[ch]) - if len(clauses) > 0: - clauses = expr(clauses) - - try: - clauses = conjuncts(clauses) - except AttributeError: - pass - - return clauses - - def angelic_action(self): - """ - Converts a high level action (HLA) with angelic semantics into all of its corresponding high level actions (HLA). - An HLA with angelic semantics can achieve the effects of simple HLA's (add / remove a variable) - and furthermore can have following effects for each variable: - - Possibly add variable ( $+: 'PosYes' ) --> corresponds to two HLAs: - HLA_1: add variable - HLA_2: leave variable unchanged - - Possibly remove variable ( $-: 'PosNot' ) --> corresponds to two HLAs: - HLA_1: remove variable - HLA_2: leave variable unchanged - - Possibly add / remove a variable ( $$: 'PosYesNot' ) --> corresponds to three HLAs: - HLA_1: add variable - HLA_2: remove variable - HLA_3: leave variable unchanged - - - example: the angelic action with effects possibly add A and possibly add or remove B corresponds to the - following 6 effects of HLAs: - - - '$+A & $$B': HLA_1: 'A & B' (add A and add B) - HLA_2: 'A & ~B' (add A and remove B) - HLA_3: 'A' (add A) - HLA_4: 'B' (add B) - HLA_5: '~B' (remove B) - HLA_6: ' ' (no effect) - - """ - - effects = [[]] - for clause in self.effect: - (n, w) = AngelicHLA.compute_parameters(clause) - effects = effects * n # create n copies of effects - it = range(1) - if len(effects) != 0: - # split effects into n sublists (separate n copies created in compute_parameters) - it = range(len(effects) // n) - for i in it: - if effects[i]: - if clause.args: - effects[i] = expr(str(effects[i]) + '&' + str( - Expr(clause.op[w:], clause.args[0]))) # make changes in the ith part of effects - if n == 3: - effects[i + len(effects) // 3] = expr( - str(effects[i + len(effects) // 3]) + '&' + str(Expr(clause.op[6:], clause.args[0]))) - else: - effects[i] = expr( - str(effects[i]) + '&' + str(expr(clause.op[w:]))) # make changes in the ith part of effects - if n == 3: - effects[i + len(effects) // 3] = expr( - str(effects[i + len(effects) // 3]) + '&' + str(expr(clause.op[6:]))) - - else: - if clause.args: - effects[i] = Expr(clause.op[w:], clause.args[0]) # make changes in the ith part of effects - if n == 3: - effects[i + len(effects) // 3] = Expr(clause.op[6:], clause.args[0]) - - else: - effects[i] = expr(clause.op[w:]) # make changes in the ith part of effects - if n == 3: - effects[i + len(effects) // 3] = expr(clause.op[6:]) - - return [HLA(Expr(self.name, self.args), self.precond, effects[i]) for i in range(len(effects))] - - def compute_parameters(clause): - """ - computes n,w - - n = number of HLA effects that the angelic HLA corresponds to - w = length of representation of angelic HLA effect - - n = 1, if effect is add - n = 1, if effect is remove - n = 2, if effect is possibly add - n = 2, if effect is possibly remove - n = 3, if effect is possibly add or remove - - """ - if clause.op[:9] == 'PosYesNot': - # possibly add/remove variable: three possible effects for the variable - n = 3 - w = 9 - elif clause.op[:6] == 'PosYes': # possibly add variable: two possible effects for the variable - n = 2 - w = 6 - elif clause.op[:6] == 'PosNot': # possibly remove variable: two possible effects for the variable - n = 2 - w = 3 # We want to keep 'Not' from 'PosNot' when adding action - else: # variable or ~variable - n = 1 - w = 0 - return n, w - - -class AngelicNode(Node): - """ - Extends the class Node. - self.action: contains the optimistic description of an angelic HLA - self.action_pes: contains the pessimistic description of an angelic HLA - """ - - def __init__(self, state, parent=None, action_opt=None, action_pes=None, path_cost=0): - super().__init__(state, parent, action_opt, path_cost) - self.action_pes = action_pes diff --git a/planning_envs.py b/planning_envs.py new file mode 100644 index 000000000..4b7663201 --- /dev/null +++ b/planning_envs.py @@ -0,0 +1,348 @@ +from planning import * + +def air_cargo(): + """ + [Figure 10.1] AIR-CARGO-PROBLEM + + An air-cargo shipment problem for delivering cargo to different locations, + given the starting location and airplanes. + + Example: + >>> from planning import * + >>> ac = air_cargo() + >>> ac.goal_test() + False + >>> ac.act(expr('Load(C2, P2, JFK)')) + >>> ac.act(expr('Load(C1, P1, SFO)')) + >>> ac.act(expr('Fly(P1, SFO, JFK)')) + >>> ac.act(expr('Fly(P2, JFK, SFO)')) + >>> ac.act(expr('Unload(C2, P2, SFO)')) + >>> ac.goal_test() + False + >>> ac.act(expr('Unload(C1, P1, JFK)')) + >>> ac.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK)', + goals='At(C1, JFK) & At(C2, SFO)', + actions=[Action('Load(c, p, a)', + precond='At(c, a) & At(p, a)', + effect='In(c, p) & ~At(c, a)', + domain='Cargo(c) & Plane(p) & Airport(a)'), + Action('Unload(c, p, a)', + precond='In(c, p) & At(p, a)', + effect='At(c, a) & ~In(c, p)', + domain='Cargo(c) & Plane(p) & Airport(a)'), + Action('Fly(p, f, to)', + precond='At(p, f)', + effect='At(p, to) & ~At(p, f)', + domain='Plane(p) & Airport(f) & Airport(to)')], + domain='Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)') + + +def spare_tire(): + """ + [Figure 10.2] SPARE-TIRE-PROBLEM + + A problem involving changing the flat tire of a car + with a spare tire from the trunk. + + Example: + >>> from planning import * + >>> st = spare_tire() + >>> st.goal_test() + False + >>> st.act(expr('Remove(Spare, Trunk)')) + >>> st.act(expr('Remove(Flat, Axle)')) + >>> st.goal_test() + False + >>> st.act(expr('PutOn(Spare, Axle)')) + >>> st.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(Flat, Axle) & At(Spare, Trunk)', + goals='At(Spare, Axle) & At(Flat, Ground)', + actions=[Action('Remove(obj, loc)', + precond='At(obj, loc)', + effect='At(obj, Ground) & ~At(obj, loc)', + domain='Tire(obj)'), + Action('PutOn(t, Axle)', + precond='At(t, Ground) & ~At(Flat, Axle)', + effect='At(t, Axle) & ~At(t, Ground)', + domain='Tire(t)'), + Action('LeaveOvernight', + precond='', + effect='~At(Spare, Ground) & ~At(Spare, Axle) & ~At(Spare, Trunk) & \ + ~At(Flat, Ground) & ~At(Flat, Axle) & ~At(Flat, Trunk)')], + domain='Tire(Flat) & Tire(Spare)') + + +def three_block_tower(): + """ + [Figure 10.3] THREE-BLOCK-TOWER + + A blocks-world problem of stacking three blocks in a certain configuration, + also known as the Sussman Anomaly. + + Example: + >>> from planning import * + >>> tbt = three_block_tower() + >>> tbt.goal_test() + False + >>> tbt.act(expr('MoveToTable(C, A)')) + >>> tbt.act(expr('Move(B, Table, C)')) + >>> tbt.goal_test() + False + >>> tbt.act(expr('Move(A, Table, B)')) + >>> tbt.goal_test() + True + >>> + """ + return PlanningProblem(initial='On(A, Table) & On(B, Table) & On(C, A) & Clear(B) & Clear(C)', + goals='On(A, B) & On(B, C)', + actions=[Action('Move(b, x, y)', + precond='On(b, x) & Clear(b) & Clear(y)', + effect='On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)', + domain='Block(b) & Block(y)'), + Action('MoveToTable(b, x)', + precond='On(b, x) & Clear(b)', + effect='On(b, Table) & Clear(x) & ~On(b, x)', + domain='Block(b) & Block(x)')], + domain='Block(A) & Block(B) & Block(C)') + +def logisticsPlanCustom(initial_state=None, goal_state=None): + if initial_state == None: + initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' + if goal_state == None: + raise ValueError("Goal must be defined") + + planning_problem = \ + PlanningProblem(initial = initial_state, + goals = goal_state, + actions=[Action('PickUp(r, c, d)', + precond='In(r, d) & In (c, d) & ~Holding(r)', + effect='Holding(r) & ~In(c, d) & In(c, r)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('PutDown(r, c, d)', + precond='In(r, d) & In(c, r) & Holding(r)', + effect='~Holding(r) & ~In(c, r) & In(c, d)', + domain='Robot(r) & Place(d) & Container(c)'), + Action('Move(r, d_start, d_end)', + precond='In(r,d_start)', + effect='~In(r, d_start) & In(r, d_end)', + domain='Robot(r) & Place(d_start) & Place(d_end)')], + domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') + + return planning_problem + + +def simple_blocks_world(): + """ + SIMPLE-BLOCKS-WORLD + + A simplified definition of the Sussman Anomaly problem. + + Example: + >>> from planning import * + >>> sbw = simple_blocks_world() + >>> sbw.goal_test() + False + >>> sbw.act(expr('ToTable(A, B)')) + >>> sbw.act(expr('FromTable(B, A)')) + >>> sbw.goal_test() + False + >>> sbw.act(expr('FromTable(C, B)')) + >>> sbw.goal_test() + True + >>> + """ + + return PlanningProblem(initial='On(A, B) & Clear(A) & OnTable(B) & OnTable(C) & Clear(C)', + goals='On(B, A) & On(C, B)', + actions=[Action('ToTable(x, y)', + precond='On(x, y) & Clear(x)', + effect='~On(x, y) & Clear(y) & OnTable(x)'), + Action('FromTable(y, x)', + precond='OnTable(y) & Clear(y) & Clear(x)', + effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) + + +def have_cake_and_eat_cake_too(): + """ + [Figure 10.7] CAKE-PROBLEM + + A problem where we begin with a cake and want to + reach the state of having a cake and having eaten a cake. + The possible actions include baking a cake and eating a cake. + + Example: + >>> from planning import * + >>> cp = have_cake_and_eat_cake_too() + >>> cp.goal_test() + False + >>> cp.act(expr('Eat(Cake)')) + >>> cp.goal_test() + False + >>> cp.act(expr('Bake(Cake)')) + >>> cp.goal_test() + True + >>> + """ + + return PlanningProblem(initial='Have(Cake) & ~Eaten(Cake)', + goals='Have(Cake) & Eaten(Cake)', + actions=[Action('Eat(Cake)', + precond='Have(Cake)', + effect='Eaten(Cake) & ~Have(Cake)'), + Action('Bake(Cake)', + precond='~Have(Cake)', + effect='Have(Cake)')]) + + +def shopping_problem(): + """ + SHOPPING-PROBLEM + + A problem of acquiring some items given their availability at certain stores. + + Example: + >>> from planning import * + >>> sp = shopping_problem() + >>> sp.goal_test() + False + >>> sp.act(expr('Go(Home, HW)')) + >>> sp.act(expr('Buy(Drill, HW)')) + >>> sp.act(expr('Go(HW, SM)')) + >>> sp.act(expr('Buy(Banana, SM)')) + >>> sp.goal_test() + False + >>> sp.act(expr('Buy(Milk, SM)')) + >>> sp.goal_test() + True + >>> + """ + + return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(HW, Drill)', + goals='Have(Milk) & Have(Drill)', + actions=[Action('Buy(x, store)', + precond='At(store) & Sells(store, x)', + effect='Have(x)', + domain='Store(store) & Item(x)'), + Action('Go(x, y)', + precond='At(x)', + effect='At(y) & ~At(x)', + domain='Rplace(x) & Rplace(y)')], + domain='Rplace(Home) & Rplace(SM) & Rplace(HW) & Store(SM) & Store(HW) & ' + 'Item(Milk) & Item(Drill)') + + +def socks_and_shoes(): + """ + SOCKS-AND-SHOES-PROBLEM + + A task of wearing socks and shoes on both feet + + Example: + >>> from planning import * + >>> ss = socks_and_shoes() + >>> ss.goal_test() + False + >>> ss.act(expr('RightSock')) + >>> ss.act(expr('RightShoe')) + >>> ss.act(expr('LeftSock')) + >>> ss.goal_test() + False + >>> ss.act(expr('LeftShoe')) + >>> ss.goal_test() + True + >>> + """ + + return PlanningProblem(initial='', + goals='RightShoeOn & LeftShoeOn', + actions=[Action('RightShoe', + precond='RightSockOn', + effect='RightShoeOn'), + Action('RightSock', + precond='', + effect='RightSockOn'), + Action('LeftShoe', + precond='LeftSockOn', + effect='LeftShoeOn'), + Action('LeftSock', + precond='', + effect='LeftSockOn')]) + + +def double_tennis_problem_simple(): + return PlanningProblem( + initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', + goals='At(A, LeftBaseline) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')], + domain="Loc(LeftBaseline)") + +def double_tennis_problem_simple2(): + return PlanningProblem( + initial='At(A, LeftNet) & At(B, LeftNet) & Approaching(ball, RightNet)', + goals='At(A, LeftNet) & Returned(ball) & At(B, LeftNet)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + +def double_tennis_problem_simple3(): + return PlanningProblem( + initial='At(A, LeftNet) & Approaching(ball, RightNet)', + goals='At(A, LeftNet) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')]) + + +def double_tennis_problem(): + """ + [Figure 11.10] DOUBLE-TENNIS-PROBLEM + + A multiagent planning problem involving two partner tennis players + trying to return an approaching ball and repositioning around in the court. + + Example: + >>> from planning import * + >>> dtp = double_tennis_problem() + >>> goal_test(dtp.goals, dtp.initial) + False + >>> dtp.act(expr('Go(A, RightBaseLine, LeftBaseLine)')) + >>> dtp.act(expr('Hit(A, Ball, RightBaseLine)')) + >>> goal_test(dtp.goals, dtp.initial) + False + >>> dtp.act(expr('Go(A, LeftNet, RightBaseLine)')) + >>> goal_test(dtp.goals, dtp.initial) + True + >>> + """ + + return PlanningProblem( + initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', + goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', + actions=[Action('Hit(actor, ball, loc)', + precond='Approaching(ball, loc) & At(actor, loc)', + effect='Returned(ball)'), + Action('Go(actor, to, loc)', + precond='At(actor, loc)', + effect='At(actor, to) & ~At(actor, loc)')], + domain="Loc(LeftBaseline)") + diff --git a/submission1.py b/submission1.py index 35d95410a..2609a799e 100644 --- a/submission1.py +++ b/submission1.py @@ -6,6 +6,7 @@ from logic import * from submission1_test import verify_solution +from planning_envs import * # Problem 4: Planning diff --git a/submission1_test.py b/submission1_test.py index e30255474..a79985075 100644 --- a/submission1_test.py +++ b/submission1_test.py @@ -1,6 +1,7 @@ import sys, os import collections from planning import * +from planning_envs import * from logic import * import pytest @@ -108,3 +109,6 @@ def test_double_tennis_problem_simple3(): def test_double_tennis_problem(): P = double_tennis_problem() verify_solution(P) + +def test_failing_plan(): + pass \ No newline at end of file diff --git a/understanding_mutexes.md b/understanding_mutexes.md deleted file mode 100644 index b1b0499e2..000000000 --- a/understanding_mutexes.md +++ /dev/null @@ -1,195 +0,0 @@ -Actions: Buy, Go - -Go(Home, SM) -Go(Home, HW) - -It includes Place, Store, Item, Sells in state (?) - -Level 0: - -Correctly identifies it can go to HW, SM, adds as mutexes - - Relies on At(Home) precondition, notes this - -Level 1: - -Adds Place(SM), Place(HW) into state, adds NotAt(Home) to state (we still have At(Home) - - Says no mutexes or actions - hasn't been generated yet. - -Graph: - -Level 1 is updated to have all applicable actions? Large mutex state: - -Has prior current state - - - Adds Buy(all, hw/sm appropriate) - - Mutex: - - not at home and at home - - Go(Home, HW), At(Home) ? GPT tells me this means that Go deletes the At(Home), so in the next state, these are disjoint. (makes sense) - - A mutex, therefore, means that two states or results of actions or intertwined, cannot have effects or states in the next state concurrently. - - - Mutex: - {{PNotAt(Home), PAt(Home)}, - {Go(Home, HW), PAt(Home)}, - {Go(Home, SM), PAt(Home)}, - {Go(HW, Home), PNotAt(Home)}, - {Go(HW, Home), Go(Home, HW)}, - {Go(HW, Home), Go(Home, SM)}, - {Go(SM, Home), PNotAt(Home)}, - {Go(SM, Home), Go(Home, HW)}, #duplicate? - {Go(SM, Home), Go(Home, SM)}, - {PAt(HW), Go(HW, Home)}, - {PAt(HW), Go(HW, SM)}, - {Go(HW, SM), Go(Home, HW)}, - {Go(HW, Home), Go(SM, HW)}, - {Go(HW, SM), Go(SM, HW)}, - {Go(SM, Home), PAt(SM)}, - {Go(SM, HW), PAt(SM)}, - {Go(Home, SM), Go(SM, HW)}, {Go(HW, SM), Go(SM, Home)}, {PNotAt(Home), Go(Home, HW)}, {PNotAt(Home), Go(Home, SM)}, {NotAt(Home), At(Home)}} # duplicate - - All seem well, and NOT sufficient - - - - - - -The issue is that: - - -At layer 1 (index -2), we have: - -print(self.levels[index].mutex) -[{PAt(Home), PNotAt(Home)}, {Go(Home, HW), PAt(Home)}, {Go(Home, SM), PAt(Home)}, {Go(HW, Home), PNotAt(Home)}, {Go(Home, HW), Go(HW, Home)}, {Go(Home, SM), Go(HW, Home)}, {PNotAt(Home), Go(SM, Home)}, {Go(Home, HW), Go(SM, Home)}, {Go(Home, SM), Go(SM, Home)}, {Go(HW, Home), PAt(HW)}, {PAt(HW), Go(HW, SM)}, {Go(Home, HW), Go(HW, SM)}, {Go(HW, Home), Go(SM, HW)}, {Go(SM, HW), Go(HW, SM)}, {Go(SM, HW), PAt(SM)}, {Go(SM, Home), PAt(SM)}, {Go(SM, Home), Go(HW, SM)}, {Go(Home, SM), Go(SM, HW)}, {Go(Home, HW), PNotAt(Home)}, {Go(Home, SM), PNotAt(Home)}, {At(Home), NotAt(Home)}] - -And our goal permutations is: - -print(list(goal_perm)) -[(At(SM), Sells(SM, Milk)), (At(SM), Store(SM)), (At(SM), Item(Milk)), (At(SM), At(SM)), (At(SM), Sells(SM, Banana)), (At(SM), Store(SM)), (At(SM), Item(Banana)), (At(SM), At(HW)), (At(SM), Sells(HW, Drill)), (At(SM), Store(HW)), (At(SM), Item(Drill)), (Sells(SM, Milk), Store(SM)), (Sells(SM, Milk), Item(Milk)), (Sells(SM, Milk), At(SM)), (Sells(SM, Milk), Sells(SM, Banana)), (Sells(SM, Milk), Store(SM)), (Sells(SM, Milk), Item(Banana)), (Sells(SM, Milk), At(HW)), (Sells(SM, Milk), Sells(HW, Drill)), (Sells(SM, Milk), Store(HW)), (Sells(SM, Milk), Item(Drill)), (Store(SM), Item(Milk)), (Store(SM), At(SM)), (Store(SM), Sells(SM, Banana)), (Store(SM), Store(SM)), (Store(SM), Item(Banana)), (Store(SM), At(HW)), (Store(SM), Sells(HW, Drill)), (Store(SM), Store(HW)), (Store(SM), Item(Drill)), (Item(Milk), At(SM)), (Item(Milk), Sells(SM, Banana)), (Item(Milk), Store(SM)), (Item(Milk), Item(Banana)), (Item(Milk), At(HW)), (Item(Milk), Sells(HW, Drill)), (Item(Milk), Store(HW)), (Item(Milk), Item(Drill)), (At(SM), Sells(SM, Banana)), (At(SM), Store(SM)), (At(SM), Item(Banana)), (At(SM), At(HW)), (At(SM), Sells(HW, Drill)), (At(SM), Store(HW)), (At(SM), Item(Drill)), (Sells(SM, Banana), Store(SM)), (Sells(SM, Banana), Item(Banana)), (Sells(SM, Banana), At(HW)), (Sells(SM, Banana), Sells(HW, Drill)), (Sells(SM, Banana), Store(HW)), (Sells(SM, Banana), Item(Drill)), (Store(SM), Item(Banana)), (Store(SM), At(HW)), (Store(SM), Sells(HW, Drill)), (Store(SM), Store(HW)), (Store(SM), Item(Drill)), (Item(Banana), At(HW)), (Item(Banana), Sells(HW, Drill)), (Item(Banana), Store(HW)), (Item(Banana), Item(Drill)), (At(HW), Sells(HW, Drill)), (At(HW), Store(HW)), (At(HW), Item(Drill)), (Sells(HW, Drill), Store(HW)), (Sells(HW, Drill), Item(Drill)), (Store(HW), Item(Drill))] - -Notably, including - -(At(SM), At(HW)) - -But, since we don't include our persistance state, it doesn't recognize the issue with this. - - - -Then - -we go to index -3, layer 0 - -print(supporting_actions_lists) -[[Go(Home, SM)], [PSells(SM, Milk)], [PStore(SM)], [PItem(Milk)], [Go(Home, SM)], [PSells(SM, Banana)], [PStore(SM)], [PItem(Banana)], [Go(Home, HW)], [PSells(HW, Drill)], [PStore(HW)], [PItem(Drill)]] - -our supporting actions includes - -[Go(Home, SM)], [Go(Home, HW)] - -But our mutexes only include: -[{Go(Home, HW), PAt(Home)}, {Go(Home, SM), PAt(Home)}] - -Shouldn't we have {Go(Home, HW), Go(Home, SM)} ? This would solve the issue... - - - - -WHY do we not have a {Go(Home, HW), Go(Home, SM)} mutex? - - - -Forward Search - - Objects: {RightBaseline, LeftNet, LeftBaseline, RightBaseLine, B, LeftBaseLine, RightNet, Ball, A} -Level 0: - - Current State: - - {At(A, LeftBaseLine), At(B, RightNet), Approaching(Ball, RightBaseLine), Partner(A, B), Partner(B, A), CourtLoc(LeftNet), CourtLoc(RightNet), CourtLoc(LeftBaseline), CourtLoc(RightBaseline)} - - Actions: - - { - PAt(A, LeftBaseLine), - PAt(B, RightNet), - PApproaching(Ball, RightBaseLine), - PPartner(A, B), PPartner(B, A), - PCourtLoc(LeftNet), PCourtLoc(RightNet), PCourtLoc(LeftBaseline), PCourtLoc(RightBaseline), - - Go(B, RightBaseline, RightNet), Go(B, LeftNet, RightNet), Go(B, LeftBaseline, RightNet), Go(B, RightBaseLine, RightNet), Go(B, LeftBaseLine, RightNet), Go(B, Ball, RightNet), Go(B, A, RightNet), Go(A, RightBaseline, LeftBaseLine), Go(A, LeftNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine), Go(A, B, LeftBaseLine), Go(A, RightNet, LeftBaseLine), Go(A, Ball, LeftBaseLine)} - -# Too unconstrained - - Can go to ball? - - Duplicate actions - - Mutex: - - {{Go(B, RightBaseline, RightNet), PAt(B, RightNet)}, {Go(B, LeftNet, RightNet), PAt(B, RightNet)}, {Go(B, LeftBaseline, RightNet), PAt(B, RightNet)}, {Go(B, RightBaseLine, RightNet), PAt(B, RightNet)}, {Go(B, LeftBaseLine, RightNet), PAt(B, RightNet)}, {Go(B, Ball, RightNet), PAt(B, RightNet)}, {Go(B, A, RightNet), PAt(B, RightNet)}, {PAt(A, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, B, LeftBaseLine), PAt(A, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, RightNet, LeftBaseLine)}, {PAt(A, LeftBaseLine), Go(A, Ball, LeftBaseLine)}, {Go(B, LeftNet, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftBaseline, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, Ball, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, A, RightNet), Go(B, RightBaseline, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, RightBaseLine, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, LeftNet, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, Ball, RightNet)}, {Go(B, LeftNet, RightNet), Go(B, A, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, Ball, RightNet), Go(B, LeftBaseline, RightNet)}, {Go(B, LeftBaseline, RightNet), Go(B, A, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, RightBaseLine, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, Ball, RightNet)}, {Go(B, RightBaseLine, RightNet), Go(B, A, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, Ball, RightNet)}, {Go(B, LeftBaseLine, RightNet), Go(B, A, RightNet)}, {Go(B, Ball, RightNet), Go(B, A, RightNet)}, {Go(A, LeftNet, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, LeftBaseline, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, RightBaseline, LeftBaseLine)}, {Go(A, LeftNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, LeftNet, LeftBaseLine)}, {Go(A, RightBaseLine, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, LeftBaseline, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, Ball, LeftBaseLine), Go(A, RightBaseLine, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, RightNet, LeftBaseLine)}, {Go(A, B, LeftBaseLine), Go(A, Ball, LeftBaseLine)}, {Go(A, RightNet, LeftBaseLine), Go(A, Ball, LeftBaseLine)}} - -![alt text]() - -1. We don't have !Eaten as a starting propostion, or ever .. should we? Do we need this? Note - we miss a mutex here b/c of it. -2. We have (Bake, Have) in our mutexes, they do not. Is this valid? -3. We have an invalid mutex {have} .... ? -4. We are missing (have, eaten) -5. Can we differentiate between different types of mutexes? I.e. state-state vs action-state, etc.? -6. We have duplicate (have, notHave) - - - -When I add in !Eaten in our start state - - -file:///home/carwyn/Pictures/Screenshots/Screenshot%20from%202025-09-28%2011-14-54.png - -1. We dont' have mutexes between (have, eaten), (!have, !eaten) in S1. - - Something is going wrong (lacking) in our inconsistent support checking - - Two propositions a,b should be mutex if every actions that produce a is mutex with every action that can produce b. -2. (bake, have) in a2 shouldn't exist - - This is correct - overriding SBU slides -3. (eat, !have) in a2 shouldn't exist - - This is correct - overriding SBU slides - - -https://www3.cs.stonybrook.edu/~sael/teaching/cse537/Slides/chapter10b.pdf -TODO: - - DONE: Remove my recursive backwards checker - it should be enough to just check final state mutexes - - Fix inconsistent support check - - Validate improvement on cake problem, where I expect to see mutexes between (have, eaten), (!have, !eaten) in S1 - - Debug shopping problem - - - - -ISSUE IDENTIFIED IN INCONSISTENT SUPPORT CHECK: -file:///home/carwyn/Pictures/Screenshots/Screenshot%20from%202025-09-28%2021-02-27.png - -Now I'm getting these concerning (incorrect) mutexes on level 2: - -{Eaten(Cake), Have(Cake)} -{Have(Cake)}, -{Eaten(Cake), NotHave(Cake)}, -{NotHave(Cake)} - -1. Enforce no single atom mutexes -2. Identify where these incorrect mutexes are coming in (note - they are valid on layer 1 ...) - -Level 1: - - Current State: {NotEaten(Cake), Eaten(Cake), Have(Cake), NotHave(Cake)} - Actions: {PNotEaten(Cake), PEaten(Cake), PHave(Cake), PNotHave(Cake), Eat(Cake), Bake(Cake)} - Mutex: {{PEaten(Cake), PNotEaten(Cake)}, {Eat(Cake), PNotEaten(Cake)}, {PNotHave(Cake), PHave(Cake)}, {Eat(Cake), PHave(Cake)}, {PNotHave(Cake), Bake(Cake)}, {Bake(Cake), Eat(Cake)}, {Bake(Cake), PHave(Cake)}, {PNotHave(Cake), Eat(Cake)}, {NotEaten(Cake), Eaten(Cake)}, {NotEaten(Cake), NotHave(Cake)}, {Have(Cake), NotHave(Cake)}, {Eaten(Cake), Have(Cake)}, {Have(Cake)}, {Eaten(Cake), NotHave(Cake)}, {NotHave(Cake)}} - - - Mutex: {{PEaten(Cake), PNotEaten(Cake)}, {Eat(Cake), PNotEaten(Cake)}, {PNotHave(Cake), PHave(Cake)}, {Eat(Cake), PHave(Cake)}, {PNotHave(Cake), Bake(Cake)}, {Eat(Cake), Bake(Cake)}, {Bake(Cake), PHave(Cake)}, {PNotHave(Cake), Eat(Cake)}, {Eaten(Cake), NotEaten(Cake)}, {NotEaten(Cake), NotHave(Cake)}, {Eaten(Cake), Have(Cake)}, {Have(Cake), NotHave(Cake)}} - - Probably issue: - - propositions are maintained in mutexes similarly to actions. I dont' think I'm accounting for this difference when I move to the next state level - - do we even have the correct logic for moving from action levels to state levels? - - - I think we conclude at s2 because we can satisfy with eat -> bake - - - - It's frustrating that they don't differentiate between state and action levels \ No newline at end of file From c6ce67c413a159e51d0d892a708944d0837dc0ee Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 4 Oct 2025 23:22:43 -0400 Subject: [PATCH 14/19] Cleanup and pytest configuration work --- README.md | 4 +- planning.py | 41 +------ planning_envs.py | 241 ++++++++++++++++++++++++++++++++++++++-- requirements.txt | 5 +- submission1.py | 19 ++-- submission1_test.py | 114 ------------------- tests/test_graphplan.py | 217 ++++++++++++++++++++++++++++++++++++ tests/test_planning.py | 4 +- 8 files changed, 471 insertions(+), 174 deletions(-) delete mode 100644 submission1_test.py create mode 100644 tests/test_graphplan.py diff --git a/README.md b/README.md index 17f1d6085..bc5aac813 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,7 @@ git submodule init git submodule update ``` -Wait for the datasets to download, it may take a while. Once they are downloaded, you need to install `pytest`, so that you can run the test suite: - -`pip install pytest` +Wait for the datasets to download, it may take a while. Then to run the tests: diff --git a/planning.py b/planning.py index eef22c9dc..8765fa9ec 100644 --- a/planning.py +++ b/planning.py @@ -507,7 +507,6 @@ def __init__(self, kb, is_first_layer=False): def __call__(self, actions, objects): self.build(actions, objects) self.find_mutex() - #self.deduplify() def __str__(self): state_str = ", ".join(str(s) for s in self.current_state) @@ -794,7 +793,7 @@ def __str__(self): __repr__ = __str__ def check_leveloff(self): - """Checks if the graph has levelled off""" + """Checks if the graph has leveled off""" check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) and \ self.graph.levels[-1].mutex == self.graph.levels[-2].mutex @@ -866,7 +865,6 @@ def _extract_solution_recursive(self, goals, level_index): #We must check if they exist in the initial state. No further recursion is needed. if level_index == 0: - #breakpoint() initial_state = set(self.graph.levels[0].current_state) if goals.issubset(initial_state): return [] # Success! Return the empty plan to be built upon. @@ -926,7 +924,7 @@ def execute(self): class Linearize: """ - + Problem wrapper / coordinator that linearizes partially ordered solutions generated by GraphPlan object. """ def __init__(self, planning_problem): @@ -1314,41 +1312,6 @@ def execute(self, display=True): return self.constraints, self.causal_links -def spare_tire_graphPlan(): - """Solves the spare tire problem using GraphPlan""" - return GraphPlan(spare_tire()).execute() - - -def three_block_tower_graphPlan(): - """Solves the Sussman Anomaly problem using GraphPlan""" - return GraphPlan(three_block_tower()).execute() - - -def air_cargo_graphPlan(): - """Solves the air cargo problem using GraphPlan""" - return GraphPlan(air_cargo()).execute() - - -def have_cake_and_eat_cake_too_graphPlan(): - """Solves the cake problem using GraphPlan""" - return [GraphPlan(have_cake_and_eat_cake_too()).execute()[1]] - - -def shopping_graphPlan(): - """Solves the shopping problem using GraphPlan""" - return GraphPlan(shopping_problem()).execute() - - -def socks_and_shoes_graphPlan(): - """Solves the socks and shoes problem using GraphPlan""" - return GraphPlan(socks_and_shoes()).execute() - - -def simple_blocks_world_graphPlan(): - """Solves the simple blocks world problem""" - return GraphPlan(simple_blocks_world()).execute() - - class HLA(Action): """ Define Actions for the real-world (that may be refined further), and satisfy resource diff --git a/planning_envs.py b/planning_envs.py index 4b7663201..0f032ac5d 100644 --- a/planning_envs.py +++ b/planning_envs.py @@ -59,7 +59,7 @@ def spare_tire(): >>> st.goal_test() False >>> st.act(expr('PutOn(Spare, Axle)')) - >>> st.goal_test() + >>> st.goal_test( True >>> """ @@ -169,6 +169,52 @@ def simple_blocks_world(): Action('FromTable(y, x)', precond='OnTable(y) & Clear(y) & Clear(x)', effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) + + +def blocks_world(initial, goals, blocks): + """ + GENERALIZED-BLOCKS-WORLD-PROBLEM + + A flexible constructor for creating blocks-world planning problems. + You can specify any initial and goal configuration for a given set of blocks. + + Example: + >>> from planning import * + >>> # Let's define the classic Sussman Anomaly + >>> initial_state = 'On(C, A) & On(A, Table) & On(B, Table) & Clear(C) & Clear(B)' + >>> goal_state = 'On(A, B) & On(B, C)' + >>> block_names = ['A', 'B', 'C'] + >>> sussman_anomaly = blocks_world(initial_state, goal_state, block_names) + >>> + >>> sussman_anomaly.goal_test() + False + >>> # A sequence of moves to solve it + >>> sussman_anomaly.act(expr('MoveToTable(C, A)')) + >>> sussman_anomaly.act(expr('Move(B, Table, C)')) + >>> sussman_anomaly.act(expr('Move(A, Table, B)')) + >>> sussman_anomaly.goal_test() + True + >>> + """ + # Dynamically generate the domain knowledge based on the list of blocks + domain_knowledge = ' & '.join([f'Block({b})' for b in blocks]) + + # Define the fundamental actions for moving blocks + actions = [ + Action('Move(b, x, y)', + precond='On(b, x) & Clear(b) & Clear(y)', + effect='On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)', + domain='Block(b) & Block(y)'), # 'x' can be another block or 'Table' + Action('MoveToTable(b, x)', + precond='On(b, x) & Clear(b)', + effect='On(b, Table) & Clear(x) & ~On(b, x)', + domain='Block(b) & Block(x)') # 'x' must be a block + ] + + return PlanningProblem(initial=initial, + goals=goals, + actions=actions, + domain=domain_knowledge) def have_cake_and_eat_cake_too(): @@ -226,8 +272,8 @@ def shopping_problem(): >>> """ - return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(HW, Drill)', - goals='Have(Milk) & Have(Drill)', + return PlanningProblem(initial='At(Home) & Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)', + goals='Have(Milk) & Have(Banana) & Have(Drill)', actions=[Action('Buy(x, store)', precond='At(store) & Sells(store, x)', effect='Have(x)', @@ -235,10 +281,9 @@ def shopping_problem(): Action('Go(x, y)', precond='At(x)', effect='At(y) & ~At(x)', - domain='Rplace(x) & Rplace(y)')], - domain='Rplace(Home) & Rplace(SM) & Rplace(HW) & Store(SM) & Store(HW) & ' - 'Item(Milk) & Item(Drill)') - + domain='Place(x) & Place(y)')], + domain='Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & ' + 'Item(Milk) & Item(Banana) & Item(Drill)') def socks_and_shoes(): """ @@ -346,3 +391,185 @@ def double_tennis_problem(): effect='At(actor, to) & ~At(actor, loc)')], domain="Loc(LeftBaseline)") + +def rush_hour(): + """ + RUSH-HOUR-PROBLEM (Non-Numeric Version) + + A planning problem for the Rush Hour sliding block puzzle. The goal is to + maneuver the RedCar to the exit. This version uses non-numeric symbols for + grid positions (e.g., R1, C1) instead of integers. + + This specific instance uses: + - RedCar (2x1, horizontal) starting at (R3, C1) + - GreenTruck (3x1, vertical) starting at (R1, C4) + - BlueCar (2x1, vertical) starting at (R5, C2) + """ + # Initial state: Define vehicle locations and clear spots using non-numeric identifiers. + initial_state = 'At(RedCar, R3, C1) & At(GreenTruck, R1, C4) & At(BlueCar, R5, C2) & ' \ + 'IsHorizontal(RedCar) & IsVertical(GreenTruck) & IsVertical(BlueCar) & ' \ + 'Clear(R1, C1) & Clear(R1, C2) & Clear(R1, C3) & Clear(R1, C5) & Clear(R1, C6) & ' \ + 'Clear(R2, C1) & Clear(R2, C2) & Clear(R2, C3) & Clear(R2, C5) & Clear(R2, C6) & ' \ + 'Clear(R3, C3) & Clear(R3, C4) & Clear(R3, C5) & Clear(R3, C6) & ' \ + 'Clear(R4, C1) & Clear(R4, C2) & Clear(R4, C3) & Clear(R4, C4) & Clear(R4, C5) & Clear(R4, C6) & ' \ + 'Clear(R5, C1) & Clear(R5, C3) & Clear(R5, C4) & Clear(R5, C5) & Clear(R5, C6) & ' \ + 'Clear(R6, C1) & Clear(R6, C3) & Clear(R6, C4) & Clear(R6, C5) & Clear(R6, C6)' + + # Goal state: The RedCar's left-most part is at column C5. + goal_state = 'At(RedCar, R3, C5)' + + # Domain: Define objects, types (Row, Col), and adjacency relationships. + domain_knowledge = 'Vehicle(RedCar) & Vehicle(GreenTruck) & Vehicle(BlueCar) & ' \ + 'Car(RedCar) & Truck(GreenTruck) & Car(BlueCar) & ' \ + 'Row(R1) & Row(R2) & Row(R3) & Row(R4) & Row(R5) & Row(R6) & ' \ + 'Col(C1) & Col(C2) & Col(C3) & Col(C4) & Col(C5) & Col(C6) & ' \ + 'NextTo(R1, R2) & NextTo(R2, R3) & NextTo(R3, R4) & NextTo(R4, R5) & NextTo(R5, R6) & ' \ + 'NextTo(C1, C2) & NextTo(C2, C3) & NextTo(C3, C4) & NextTo(C4, C5) & NextTo(C5, C6)' + + actions = [ + # --- CAR ACTIONS (length 2) --- + Action('MoveRightCar(v, r, c1, c2, c3)', + precond='At(v, r, c1) & Car(v) & IsHorizontal(v) & NextTo(c1, c2) & NextTo(c2, c3) & Clear(r, c3)', + effect='At(v, r, c2) & ~At(v, r, c1) & Clear(r, c1) & ~Clear(r, c3)', + domain='Vehicle(v) & Row(r) & Col(c1) & Col(c2) & Col(c3)'), + Action('MoveLeftCar(v, r, c1, c2, c3)', + precond='At(v, r, c2) & Car(v) & IsHorizontal(v) & NextTo(c1, c2) & NextTo(c2, c3) & Clear(r, c1)', + effect='At(v, r, c1) & ~At(v, r, c2) & Clear(r, c3) & ~Clear(r, c1)', + domain='Vehicle(v) & Row(r) & Col(c1) & Col(c2) & Col(c3)'), + Action('MoveDownCar(v, r1, r2, r3, c)', + precond='At(v, r1, c) & Car(v) & IsVertical(v) & NextTo(r1, r2) & NextTo(r2, r3) & Clear(r3, c)', + effect='At(v, r2, c) & ~At(v, r1, c) & Clear(r1, c) & ~Clear(r3, c)', + domain='Vehicle(v) & Row(r1) & Row(r2) & Row(r3) & Col(c)'), + Action('MoveUpCar(v, r1, r2, r3, c)', + precond='At(v, r2, c) & Car(v) & IsVertical(v) & NextTo(r1, r2) & NextTo(r2, r3) & Clear(r1, c)', + effect='At(v, r1, c) & ~At(v, r2, c) & Clear(r3, c) & ~Clear(r1, c)', + domain='Vehicle(v) & Row(r1) & Row(r2) & Row(r3) & Col(c)'), + + # --- TRUCK ACTIONS (length 3) --- + Action('MoveRightTruck(v, r, c1, c2, c3, c4)', + precond='At(v, r, c1) & Truck(v) & IsHorizontal(v) & NextTo(c1, c2) & NextTo(c2, c3) & NextTo(c3, c4) & Clear(r, c4)', + effect='At(v, r, c2) & ~At(v, r, c1) & Clear(r, c1) & ~Clear(r, c4)', + domain='Vehicle(v) & Row(r) & Col(c1) & Col(c2) & Col(c3) & Col(c4)'), + Action('MoveLeftTruck(v, r, c1, c2, c3, c4)', + precond='At(v, r, c2) & Truck(v) & IsHorizontal(v) & NextTo(c1, c2) & NextTo(c2, c3) & NextTo(c3, c4) & Clear(r, c1)', + effect='At(v, r, c1) & ~At(v, r, c2) & Clear(r, c4) & ~Clear(r, c1)', + domain='Vehicle(v) & Row(r) & Col(c1) & Col(c2) & Col(c3) & Col(c4)'), + Action('MoveDownTruck(v, r1, r2, r3, r4, c)', + precond='At(v, r1, c) & Truck(v) & IsVertical(v) & NextTo(r1, r2) & NextTo(r2, r3) & NextTo(r3, r4) & Clear(r4, c)', + effect='At(v, r2, c) & ~At(v, r1, c) & Clear(r1, c) & ~Clear(r4, c)', + domain='Vehicle(v) & Row(r1) & Row(r2) & Row(r3) & Row(r4) & Col(c)'), + Action('MoveUpTruck(v, r1, r2, r3, r4, c)', + precond='At(v, r2, c) & Truck(v) & IsVertical(v) & NextTo(r1, r2) & NextTo(r2, r3) & NextTo(r3, r4) & Clear(r1, c)', + effect='At(v, r1, c) & ~At(v, r2, c) & Clear(r4, c) & ~Clear(r1, c)', + domain='Vehicle(v) & Row(r1) & Row(r2) & Row(r3) & Row(r4) & Col(c)') + ] + + return PlanningProblem(initial=initial_state, + goals=goal_state, + actions=actions, + domain=domain_knowledge) + + +def rush_hour_optimized(): + """ + RUSH-HOUR-PROBLEM (Optimized Version) + + This version optimizes the planning problem by creating vehicle-specific + actions. Since each vehicle's orientation is fixed, we can remove generic + predicates like `IsHorizontal` and create actions that only apply to the + correct vehicle on its fixed axis of movement. This drastically reduces + the number of permutations the planner needs to generate and check. + """ + # Initial state is simpler as orientation is now baked into the actions. + initial_state = 'At(RedCar, R3, C1) & At(GreenTruck, R1, C4) & At(BlueCar, R5, C2) & ' \ + 'Clear(R1, C1) & Clear(R1, C2) & Clear(R1, C3) & Clear(R1, C5) & Clear(R1, C6) & ' \ + 'Clear(R2, C1) & Clear(R2, C2) & Clear(R2, C3) & Clear(R2, C5) & Clear(R2, C6) & ' \ + 'Clear(R3, C3) & Clear(R3, C4) & Clear(R3, C5) & Clear(R3, C6) & ' \ + 'Clear(R4, C1) & Clear(R4, C2) & Clear(R4, C3) & Clear(R4, C4) & Clear(R4, C5) & Clear(R4, C6) & ' \ + 'Clear(R5, C1) & Clear(R5, C3) & Clear(R5, C4) & Clear(R5, C5) & Clear(R5, C6) & ' \ + 'Clear(R6, C1) & Clear(R6, C3) & Clear(R6, C4) & Clear(R6, C5) & Clear(R6, C6)' + + # Goal state remains the same. + goal_state = 'At(RedCar, R3, C5)' + + # Domain knowledge defines the grid and vehicles. + domain_knowledge = 'Vehicle(RedCar) & Vehicle(GreenTruck) & Vehicle(BlueCar) & ' \ + 'Row(R1) & Row(R2) & Row(R3) & Row(R4) & Row(R5) & Row(R6) & ' \ + 'Col(C1) & Col(C2) & Col(C3) & Col(C4) & Col(C5) & Col(C6) & ' \ + 'NextTo(R1, R2) & NextTo(R2, R3) & NextTo(R3, R4) & NextTo(R4, R5) & NextTo(R5, R6) & ' \ + 'NextTo(C1, C2) & NextTo(C2, C3) & NextTo(C3, C4) & NextTo(C4, C5) & NextTo(C5, C6)' + + # Optimized Actions: Specific to each vehicle and its fixed orientation. + actions = [ + # RedCar is horizontal on Row 3, length 2 + Action('MoveRedCarRight(c1, c2, c3)', + precond='At(RedCar, R3, c1) & NextTo(c1, c2) & NextTo(c2, c3) & Clear(R3, c3)', + effect='At(RedCar, R3, c2) & ~At(RedCar, R3, c1) & Clear(R3, c1) & ~Clear(R3, c3)', + domain='Col(c1) & Col(c2) & Col(c3)'), + Action('MoveRedCarLeft(c1, c2, c3)', + precond='At(RedCar, R3, c2) & NextTo(c1, c2) & NextTo(c2, c3) & Clear(R3, c1)', + effect='At(RedCar, R3, c1) & ~At(RedCar, R3, c2) & Clear(R3, c3) & ~Clear(R3, c1)', + domain='Col(c1) & Col(c2) & Col(c3)'), + + # GreenTruck is vertical on Column 4, length 3 + Action('MoveGreenTruckDown(r1, r2, r3, r4)', + precond='At(GreenTruck, r1, C4) & NextTo(r1, r2) & NextTo(r2, r3) & NextTo(r3, r4) & Clear(r4, C4)', + effect='At(GreenTruck, r2, C4) & ~At(GreenTruck, r1, C4) & Clear(r1, C4) & ~Clear(r4, C4)', + domain='Row(r1) & Row(r2) & Row(r3) & Row(r4)'), + Action('MoveGreenTruckUp(r1, r2, r3, r4)', + precond='At(GreenTruck, r2, C4) & NextTo(r1, r2) & NextTo(r2, r3) & NextTo(r3, r4) & Clear(r1, C4)', + effect='At(GreenTruck, r1, C4) & ~At(GreenTruck, r2, C4) & Clear(r4, C4) & ~Clear(r1, C4)', + domain='Row(r1) & Row(r2) & Row(r3) & Row(r4)'), + + # BlueCar is vertical on Column 2, length 2 + Action('MoveBlueCarDown(r1, r2, r3)', + precond='At(BlueCar, r1, C2) & NextTo(r1, r2) & NextTo(r2, r3) & Clear(r3, C2)', + effect='At(BlueCar, r2, C2) & ~At(BlueCar, r1, C2) & Clear(r1, C2) & ~Clear(r3, C2)', + domain='Row(r1) & Row(r2) & Row(r3)'), + Action('MoveBlueCarUp(r1, r2, r3)', + precond='At(BlueCar, r2, C2) & NextTo(r1, r2) & NextTo(r2, r3) & Clear(r1, C2)', + effect='At(BlueCar, r1, C2) & ~At(BlueCar, r2, C2) & Clear(r3, C2) & ~Clear(r1, C2)', + domain='Row(r1) & Row(r2) & Row(r3)'), + ] + + return PlanningProblem(initial=initial_state, + goals=goal_state, + actions=actions, + domain=domain_knowledge) + + +#### For pytests + +def spare_tire_graphPlan(): + """Solves the spare tire problem using GraphPlan""" + return GraphPlan(spare_tire()).execute() + + +def three_block_tower_graphPlan(): + """Solves the Sussman Anomaly problem using GraphPlan""" + return GraphPlan(three_block_tower()).execute() + + +def air_cargo_graphPlan(): + """Solves the air cargo problem using GraphPlan""" + return GraphPlan(air_cargo()).execute() + + +def have_cake_and_eat_cake_too_graphPlan(): + """Solves the cake problem using GraphPlan""" + return GraphPlan(have_cake_and_eat_cake_too()).execute() + + +def shopping_graphPlan(): + """Solves the shopping problem using GraphPlan""" + return GraphPlan(shopping_problem()).execute() + + +def socks_and_shoes_graphPlan(): + """Solves the socks and shoes problem using GraphPlan""" + return GraphPlan(socks_and_shoes()).execute() + + +def simple_blocks_world_graphPlan(): + """Solves the simple blocks world problem""" + return GraphPlan(simple_blocks_world()).execute() diff --git a/requirements.txt b/requirements.txt index dd6b1be8a..1241f7f67 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,8 +11,9 @@ numpy opencv-python pandas pillow -pytest-cov qpsolvers scipy sortedcontainers -tensorflow \ No newline at end of file +tensorflow +pytest +pytest-cov \ No newline at end of file diff --git a/submission1.py b/submission1.py index 2609a799e..614f4cb12 100644 --- a/submission1.py +++ b/submission1.py @@ -98,9 +98,9 @@ def logisticsPlan(): #P = air_cargo() #P = double_tennis_problem() #P = have_cake_and_eat_cake_too() - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + #init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" #goal_state = "In(C1,D1)" - goal_state = "In(C2, D3) & In(C3, D3)" + #goal_state = "In(C2, D3) & In(C3, D3)" #goal_state = "In(C1, D3) & In(C2, D3) & In(C3, D3)" # putdown(c1), pickup(c2), move(d3), putdown(c2), move(d2), pickup(c3), move(d3), putdown(c3) @@ -109,14 +109,14 @@ def logisticsPlan(): #goal_state = "In(C3, D3)" # putdown c1, move r1 to d2, pickup c3 in d2, move robot to d1, putdown c3 #goal_state = "In(C1, D2) & In(C3, D3)" - P = logisticsPlanCustom(init, goal_state) + #P = logisticsPlanCustom(init, goal_state) # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. """ P = PlanningProblem(initial = init, goals = goal_state, - actions=[Action('PickUp(r, c, d)', - precond='In(r, d) & In (c, d) & ~Holding(r)', + precond='In(r, d) & In (c, d) & ~H + olding(r)', effect='Holding(r) & ~In(c, d) & In(c, r)', domain='Robot(r) & Place(d) & Container(c)'), Action('PutDown(r, c, d)', @@ -130,9 +130,14 @@ def logisticsPlan(): domain='Container(C1) & Container(C2) & Place(D1) & Place(D2) & Robot(R1)') """ #P = double_tennis_problem_simple2() - #GraphPlan(P).execute() - print(Linearize(P).execute()) + + #P = rush_hour() + P = rush_hour_optimized() #verify_solution(P) + + #GraphPlan(P).execute() + #print(Linearize(P).execute()) + verify_solution(P) """ diff --git a/submission1_test.py b/submission1_test.py deleted file mode 100644 index a79985075..000000000 --- a/submission1_test.py +++ /dev/null @@ -1,114 +0,0 @@ -import sys, os -import collections -from planning import * -from planning_envs import * -from logic import * - -import pytest - -def test_blocksworld_manual(): - sbw = simple_blocks_world() - assert sbw.goal_test() == False - sbw.act(expr('ToTable(A, B)')) - sbw.act(expr('FromTable(B, A)')) - assert sbw.goal_test() == False - sbw.act(expr('FromTable(C, B)')) - assert sbw.goal_test() == True - - -def test_logistics_manual(): - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - goal_state = "In(C2, D3) & In(C3, D3)" - P = logisticsPlanCustom(init, goal_state) - assert P.goal_test() == False - P.act(expr('PutDown(R1, C1, D1)')) - P.act(expr('PickUp(R1, C2, D1)')) - P.act(expr('Move(R1, D1, D3)')) - P.act(expr('PutDown(R1, C2, D3)')) - P.act(expr('Move(R1, D3, D2)')) - P.act(expr('PickUp(R1, C3, D2)')) - P.act(expr('Move(R1, D2, D3)')) - assert P.goal_test() == False - P.act(expr('PutDown(R1, C3, D3)')) - assert P.goal_test() == True - - -def verify_solution(P): - sol = Linearize(P).execute() - print(sol) - assert P.goal_test() == False - for act in sol: - P.act(expr(act)) - assert P.goal_test() == True - -def test_air_cargo(): - P = air_cargo() - verify_solution(P) - -def test_spare_tire(): - P = spare_tire() - verify_solution(P) - -def test_three_block_tower(): - P = three_block_tower() - verify_solution(P) - -def test_simple_blocks_world(): - P = simple_blocks_world() - verify_solution(P) - -def test_shopping_problem(): - P = shopping_problem() - verify_solution(P) - -def test_socks_and_shoes(): - P = socks_and_shoes() - verify_solution(P) - -@pytest.mark.parametrize("goal_state", [ - "In(C1, D1)", - "In(C1, D2)", - "In(C1, D1) & In(R1, D2)", - "In(R1, D2) & In(C1, D1)", - "In(C1, D1) & In(C3, R1)", - "In(C1, D1) & In(C3, R1) & In(R1, D3)", - "In(C1, D1) & In(R1, D3) & In(C3, R1)", - "In(C1, D1) & In(C3, D3)", - "In(C1, D1) & In(R1, D2) & In(C3, R1)", - "In(C1, D1) & In(C3, R1) & In(R1, D3)", - "In(C1, D1) & In(C2, D3)", - "In(C3, D1)", - "In(C2, D3)", - "In(C2, D3) & In(C3, D3)", \ - "In(C3, D3) & In(C2, D3)", \ - "In(C1, D2) & In(C3, D3)", - "In(C1, D3) & In(C2, D3) & In(C3, D3)", \ - "In(C1, D2) & In(C3, D3) & In(C2, D1)", - "In(C3, D3)", - "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)" \ -]) -def test_logistics_plan_valid(goal_state): - """These should yield a valid (non-crashing) plan, even if empty.""" - init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - P = logisticsPlanCustom(init, goal_state) - verify_solution(P) - -def test_double_tennis_problem_simple(): - P = double_tennis_problem_simple() - verify_solution(P) - - -def test_double_tennis_problem_simple2(): - P = double_tennis_problem_simple2() - verify_solution(P) - -def test_double_tennis_problem_simple3(): - P = double_tennis_problem_simple3() - verify_solution(P) - -def test_double_tennis_problem(): - P = double_tennis_problem() - verify_solution(P) - -def test_failing_plan(): - pass \ No newline at end of file diff --git a/tests/test_graphplan.py b/tests/test_graphplan.py new file mode 100644 index 000000000..ddadf6026 --- /dev/null +++ b/tests/test_graphplan.py @@ -0,0 +1,217 @@ +import sys, os +import collections +from multiprocessing import Process, Queue +from planning import * +from planning_envs import * +from logic import * + +import pytest + +def test_blocksworld_manual(): + sbw = simple_blocks_world() + assert sbw.goal_test() == False + sbw.act(expr('ToTable(A, B)')) + sbw.act(expr('FromTable(B, A)')) + assert sbw.goal_test() == False + sbw.act(expr('FromTable(C, B)')) + assert sbw.goal_test() == True + + +def test_logistics_manual(): + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + goal_state = "In(C2, D3) & In(C3, D3)" + P = logisticsPlanCustom(init, goal_state) + assert P.goal_test() == False + P.act(expr('PutDown(R1, C1, D1)')) + P.act(expr('PickUp(R1, C2, D1)')) + P.act(expr('Move(R1, D1, D3)')) + P.act(expr('PutDown(R1, C2, D3)')) + P.act(expr('Move(R1, D3, D2)')) + P.act(expr('PickUp(R1, C3, D2)')) + P.act(expr('Move(R1, D2, D3)')) + assert P.goal_test() == False + P.act(expr('PutDown(R1, C3, D3)')) + assert P.goal_test() == True + + + +def test_generalized_blocksworld_manual(): + """ + Manual test for the generalized Blocks World problem constructor. + This test case involves stacking four blocks (A, B, C, D) into a single tower. + """ + # 1. Define the problem parameters + initial_state = 'On(A, Table) & On(B, Table) & On(C, Table) & On(D, Table) & Clear(A) & Clear(B) & Clear(C) & Clear(D)' + goal_state = 'On(A, B) & On(B, C) & On(C, D)' + block_names = ['A', 'B', 'C', 'D'] + + bw_problem = blocks_world(initial_state, goal_state, block_names) + assert bw_problem.goal_test() == False + bw_problem.act(expr('Move(C, Table, D)')) + assert bw_problem.goal_test() == False + bw_problem.act(expr('Move(B, Table, C)')) + assert bw_problem.goal_test() == False + bw_problem.act(expr('Move(A, Table, B)')) + assert bw_problem.goal_test() == True + + +def verify_solution(P): + sol = Linearize(P).execute() + print(sol) + assert P.goal_test() == False + for act in sol: + P.act(expr(act)) + assert P.goal_test() == True + +def test_air_cargo(): + P = air_cargo() + verify_solution(P) + +def test_spare_tire(): + P = spare_tire() + verify_solution(P) + +def test_three_block_tower(): + P = three_block_tower() + verify_solution(P) + +def test_simple_blocks_world(): + P = simple_blocks_world() + verify_solution(P) + +def test_shopping_problem(): + P = shopping_problem() + verify_solution(P) + +def test_socks_and_shoes(): + P = socks_and_shoes() + verify_solution(P) + +@pytest.mark.parametrize("goal_state", [ + "In(C1, D1)", + "In(C1, D2)", + "In(C1, D1) & In(R1, D2)", + "In(R1, D2) & In(C1, D1)", + "In(C1, D1) & In(C3, R1)", + "In(C1, D1) & In(C3, R1) & In(R1, D3)", + "In(C1, D1) & In(R1, D3) & In(C3, R1)", + "In(C1, D1) & In(C3, D3)", + "In(C1, D1) & In(R1, D2) & In(C3, R1)", + "In(C1, D1) & In(C3, R1) & In(R1, D3)", + "In(C1, D1) & In(C2, D3)", + "In(C3, D1)", + "In(C2, D3)", + "In(C2, D3) & In(C3, D3)", \ + "In(C3, D3) & In(C2, D3)", \ + "In(C1, D2) & In(C3, D3)", + "In(C1, D3) & In(C2, D3) & In(C3, D3)", \ + "In(C1, D2) & In(C3, D3) & In(C2, D1)", + "In(C3, D3)", + "In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)" \ +]) +def test_logistics_plan_valid(goal_state): + """These should yield a valid (non-crashing) plan, even if empty.""" + init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" + P = logisticsPlanCustom(init, goal_state) + verify_solution(P) + +def test_double_tennis_problem_simple(): + P = double_tennis_problem_simple() + verify_solution(P) + + +def test_double_tennis_problem_simple2(): + P = double_tennis_problem_simple2() + verify_solution(P) + +def test_double_tennis_problem_simple3(): + P = double_tennis_problem_simple3() + verify_solution(P) + +def test_double_tennis_problem(): + P = double_tennis_problem() + verify_solution(P) + +def test_rush_hour_manual_alt_sequence(): + """ + Provides an alternative manual test for the Rush Hour problem. + + This solution is less efficient but still valid. It interleaves + the movements of different vehicles and includes an unnecessary move + to verify that the actions correctly modify the game state without + breaking the rules. + """ + # Initialize the problem + problem = rush_hour() + + # Initial state is not the goal + assert not problem.goal_test() + + # Step 1: Make an unnecessary move with the BlueCar to show it works. + # Move BlueCar from (R5, C2) down to (R6, C2). + # Note: The BlueCar occupies R5 and R6, so we must move it up first to free R6. + # Let's move it from R5,C2 -> R4,C2 instead. + problem.act(expr('MoveUpCar(BlueCar, R4, R5, R6, C2)')) + assert not problem.goal_test(), "Moving the BlueCar should not solve the puzzle." + + # Step 2: Start clearing the main path by moving the GreenTruck. + # Move GreenTruck down once: R1,C4 -> R2,C4 + problem.act(expr('MoveDownTruck(GreenTruck, R1, R2, R3, R4, C4)')) + + # Step 3: Move the RedCar into the newly available space. + # Move RedCar right once: R3,C1 -> R3,C2 + problem.act(expr('MoveRightCar(RedCar, R3, C1, C2, C3)')) + assert not problem.goal_test() + + # Step 4: Continue clearing the path. + # Move GreenTruck down again: R2,C4 -> R3,C4 + problem.act(expr('MoveDownTruck(GreenTruck, R2, R3, R4, R5, C4)')) + # Move RedCar right again: R3,C2 -> R3,C3 + problem.act(expr('MoveRightCar(RedCar, R3, C2, C3, C4)')) + assert not problem.goal_test() + + # Step 5: Final moves to solve the puzzle. + # Move GreenTruck a final time to completely clear the row: R3,C4 -> R4,C4 + problem.act(expr('MoveDownTruck(GreenTruck, R3, R4, R5, R6, C4)')) + + # Move RedCar to the goal position. + problem.act(expr('MoveRightCar(RedCar, R3, C3, C4, C5)')) + problem.act(expr('MoveRightCar(RedCar, R3, C4, C5, C6)')) + + # The sequence of actions should now result in the goal state. + assert problem.goal_test() + + +# Fails due to massive search space (hangs during building layer 1 maps) +""" +def test_rush_hour(): + P = rush_hour() + verify_solution(P) +""" + +def test_rush_hour_optimized(): + P = rush_hour_optimized() + verify_solution(P) + + +def test_planner_handles_failure_gracefully(): + def run_planner_in_queue(problem, queue): + queue.put(Linearize(problem).execute()) + + P = blocks_world( + 'On(A, Table) & On(B, Table) & On(C, Table) & Clear(A) & Clear(B) & Clear(C)', + 'On(A, B) & On(B, C) & On(C, A)', + ['A', 'B', 'C'] + ) + + result_queue = Queue() + proc = Process(target=run_planner_in_queue, args=(P, result_queue)) + proc.start() + proc.join(timeout=10) + + if proc.is_alive(): + proc.terminate() + proc.join() + else: + result = result_queue.get() + assert result is None or result == [] or result == [[]] \ No newline at end of file diff --git a/tests/test_planning.py b/tests/test_planning.py index a39152adc..24f019099 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -3,6 +3,7 @@ import pytest from planning import * +from planning_envs import * from search import astar_search from utils import expr from logic import FolKB, conjuncts @@ -229,8 +230,7 @@ def test_graphPlan(): shopping_problem_solution = shopping_graphPlan() shopping_problem_solution = linearize(shopping_problem_solution) - assert expr('Go(Home, HW)') in shopping_problem_solution - assert expr('Go(Home, SM)') in shopping_problem_solution + assert expr('Go(Home, HW)') in shopping_problem_solution or expr('Go(Home, SM)') in shopping_problem_solution assert expr('Buy(Drill, HW)') in shopping_problem_solution assert expr('Buy(Banana, SM)') in shopping_problem_solution assert expr('Buy(Milk, SM)') in shopping_problem_solution From 82e061b693ef4b149752b339aab8cab393e1b8de Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sat, 4 Oct 2025 23:35:53 -0400 Subject: [PATCH 15/19] More cleanup, removed unnecessary functions --- debug_logistics_err.py | 157 -------------------------------------- graphplan_debugger.py | 133 -------------------------------- logistics_trace1.txt | 17 ----- planning.py | 6 +- plotter.py | 60 --------------- submission1.py | 167 ----------------------------------------- utils.py | 32 -------- 7 files changed, 1 insertion(+), 571 deletions(-) delete mode 100644 debug_logistics_err.py delete mode 100644 graphplan_debugger.py delete mode 100644 logistics_trace1.txt delete mode 100644 plotter.py delete mode 100644 submission1.py diff --git a/debug_logistics_err.py b/debug_logistics_err.py deleted file mode 100644 index 5c55f3f88..000000000 --- a/debug_logistics_err.py +++ /dev/null @@ -1,157 +0,0 @@ - -# In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) -# In(C3, D3) - -# Sol should be: -# putdown(c1), move(r1, d2), pickup c3, move d3, putdown d3a - - -ISSUE: - PickUp(R1, C1, D2), - PickUp(R1, C3, D2), -in same layer. - -[ - [ - [ - PHolding(R1), - PContainer(C3), - PIn(C1, R1), - PPlace(D2), - PPlace(D3), - PContainer(C1), - PRobot(R1), - Move(R1, D1, D2), - PIn(C3, D2), - ], - [ - PutDown(R1, C1, D2), - PContainer(C3), - PPlace(D2), - PPlace(D3), - PIn(R1, D2), - PContainer(C1), - PRobot(R1), - PIn(C3, D2), - ], - [ - PContainer(C3), - PPlace(D2), - PPlace(D3), - PickUp(R1, C1, D2), - PIn(R1, D2), - PRobot(R1), - PickUp(R1, C3, D2), - ], - [ - PHolding(R1), - PContainer(C3), - Move(R1, D2, D3), - PPlace(D3), - PIn(C3, R1), - PRobot(R1), - ], - [PutDown(R1, C3, D3)], - ], - [ - [ - PutDown(R1, C1, D1), - PContainer(C3), - PPlace(D2), - PPlace(D3), - PIn(R1, D1), - PPlace(D1), - PRobot(R1), - PIn(C3, D2), - ], - [ - PContainer(C3), - PPlace(D2), - PPlace(D3), - PRobot(R1), - PNotHolding(R1), - Move(R1, D1, D2), - PIn(C3, D2), - ], - [ - PContainer(C3), - PPlace(D2), - PPlace(D3), - PIn(R1, D2), - PRobot(R1), - PickUp(R1, C3, D2), - ], - [ - PHolding(R1), - PContainer(C3), - Move(R1, D2, D3), - PPlace(D3), - PIn(C3, R1), - PRobot(R1), - ], - [PutDown(R1, C3, D3)], - ], -] - - - - - - -goal: -[Robot(R1), In(C3, R1), Place(D3), In(R1, D3), Container(C3), In(R1, D3), In(C1, D3), NotHolding(R1), Robot(R1), Place(D3), Container(C1), In(C2, D3)] - -These non mutex actions that lead to above - -[[PRobot(R1), PIn(C3, R1), PPlace(D3), PIn(R1, D3), PContainer(C3), PickUp(R1, C1, D3), PIn(C2, D3)]] - - - - - -# Why is `PIn(C3, R1)` not mutex with `PickUp(R1, C1, D3)`? - - -Technically, no direct precondition error -PIn(C3,R1) required a PickUp(R1, C3, ?) at some point, - - -[PRobot(R1)], [PPlace(D3)], [PContainer(C3)], PHolding(R1), [PIn(C2, D3)] [ Move(R1, D2, D3), Move(R1, D1, D3)]], PIn(C3, R1) - -# (PHolding(R1), PIn(C2, D3)) is mutex @ -3 level - -""" -goal state -1 -putdown layer -previous_layer -2 -wacky_actions - (PHolding(R1), PIn(C2, D3)) is mutex - shoudl be move to d3 -previous_layer -3 - (Holding(R1), In(C2, D3)) is mutex -should be pickup(c3) - - - -Not inconsistent effects -Not interference -Has to be competing needs - preconditions are mutex - - Therefore, (Holding(R1), In(C2, D3)) is likely mutex - it is - -Why are these mutex? Props are only mutex if actions that cause it in prior layer are ... - - (pickup anything, holding(r1)), (In(C2, D3), putdown(d2,d3)) - - Pickup(R1, C3, D2), PIn(C2, D3) shouldn't be mutex, but it is - - - -""" - -PickUp(R1, C1, D2), PickUp(R1, C3, D2) are not mutex -Why? -Preconds: - In(r, d) & In (c, d) & ~Holding(r) -Effects: - Holding(r) & ~In(c, d) & In(c, r) - - -They negate the same precondition? One makes the others precondition false - - -(PIn(C2, D3), Move(R1, D2, D3), PIn(C3, R1), PHolding(R1), PRobot(R1), PPlace(D3), PContainer(C3)) failed due to (PIn(C2, D3), PHolding(R1)) in mutex - -mutex (PHolding(R1), PIn(C2, D3)) excludes our action set from being applicable. diff --git a/graphplan_debugger.py b/graphplan_debugger.py deleted file mode 100644 index 6691a06df..000000000 --- a/graphplan_debugger.py +++ /dev/null @@ -1,133 +0,0 @@ -import re -from typing import List, Set, Any -from logic import expr, Expr - - -""" -PlanDebugger.run("logistics_trace1.txt", self.graph) -""" - -def rund(graph): - return PlanDebugger.run("logistics_trace1.txt", graph) - - -class PlanLevel: - def __init__(self, current_state: Set[Any], actions: Set[Any], next_state: Set[Any]): - self.current_state = current_state - self.actions = actions - self.next_state = next_state - - def __repr__(self): - return (f"\n" - f" Current State: {self.current_state}\n" - f" Actions: {self.actions}\n" - f" Next State: {self.next_state}\n") - -class PlanDebugger: - """ - Utility to parse a plan trace from file and check it against a GraphPlan graph. - """ - - - @staticmethod - def parse_plan_file(filename: str) -> List[PlanLevel]: - plan_levels = [] - current_level = None - - state_prefixes = ('In(', 'Holding(', 'NotHolding(') # , 'PIn(', 'PHolding(' - - with open(filename, 'r') as f: - for line in f: - line = line.strip() - if not line: - continue - - tokens = [expr(tok.strip()) for tok in line.split("&") if tok.strip()] - - # Heuristic: starts with state prefixes → state line - if all(str(t).startswith(state_prefixes) for t in tokens): - # Start a new level - if current_level is not None: - # Assign previous level's next_state - current_level.next_state = set(tokens) - plan_levels.append(current_level) - - current_level = PlanLevel(current_state=set(tokens), actions=set(), next_state=set()) - - else: - # Action line → assign to current level - if current_level is None: - raise ValueError("File starts with actions before any state.") - current_level.actions = set(tokens) - - # Append the last level - if current_level is not None: - plan_levels.append(current_level) - - return plan_levels - - - @staticmethod - def check_plan_against_graph(plan_levels: List[PlanLevel], graph) -> str: - - for i, plan_level in enumerate(plan_levels): - plan_states = plan_level.current_state - plan_actions = plan_level.actions - next_plan_states = plan_level.next_state - - level = graph.levels[i] - print("# Levels: ", len(plan_levels)) - - # --- State check --- - graph_states = set(level.current_state) - missing_states = plan_states - graph_states - #print("PLAN_STATES: ", plan_states, "\nGRAPH_STATES: ", graph_states) - if missing_states: - return (f"❌ Divergence at LEVEL {i}: plan states not in graph level. " - f"Missing states: {missing_states}") - - # --- Action check --- - if plan_actions: - # Check applicability - for act in plan_actions: - if act not in level.next_action_links: - print(f"At level {i}, {level}") - return f"❌ Divergence at LEVEL {i}: action {act} not applicable" - - # Check mutex - if i == 7: - print(level.mutex) - for a1 in plan_actions: - for a2 in plan_actions: - if a1 != a2 and {a1, a2} in level.mutex: - return f"❌ Divergence at LEVEL {i}: actions {a1} and {a2} are mutex" - - # Verify successor states - successor_states = set() - for act in plan_actions: - if act in level.next_action_links: - successor_states.update(level.next_action_links[act]) - missing_next_states = next_plan_states - successor_states - if missing_next_states: - return (f"❌ Divergence at LEVEL {i}: next states don’t match action effects. " - f"Missing next states: {missing_next_states}") - - # --- State mutex check --- - for s1 in plan_states: - for s2 in plan_states: - if s1 != s2 and {s1, s2} in level.state_mutexes: - return f"❌ Divergence at LEVEL {i}: states {s1} and {s2} are mutex" - - return "✅ Plan is valid against the graph!" - - - @staticmethod - def run(filename: str, graph) -> str: - """ - Convenience wrapper to parse a plan file and check it against a graph. - """ - plan_levels = PlanDebugger.parse_plan_file(filename) - print("Plan: ", plan_levels) - result = PlanDebugger.check_plan_against_graph(plan_levels, graph) - return result - \ No newline at end of file diff --git a/logistics_trace1.txt b/logistics_trace1.txt deleted file mode 100644 index 7666425db..000000000 --- a/logistics_trace1.txt +++ /dev/null @@ -1,17 +0,0 @@ -In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) -PutDown(R1, C1, D1) & PIn(C2, D1) & PIn(C3, D2) & PIn(R1, D1) -In(C1, D1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & NotHolding(R1) -PickUp(R1, C2, D1) & PIn(C1, D1) & PIn(C3, D2) & PIn(R1, D1) -In(C1, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) & In(C2, R1) -Move(R1, D1, D3) & PIn(C1, D1) & PIn(C3, D2) & PHolding(R1) & PIn(C2, R1) -In(C1, D1) & In(C3, D2) & In(C2, R1) & In(R1, D3) & Holding(R1) -PutDown(R1, C2, D3) & PIn(C1, D1) & PIn(C3, D2) & PIn(R1, D3) -In(C1, D1) & In(C3, D2) & In(R1, D3) & NotHolding(R1) & In(C2, D3) -Move(R1, D3, D2) & PIn(C1, D1) & PIn(C3, D2) & PIn(C2, D3) & PNotHolding(R1) -In(C1, D1) & In(C3, D2) & In(R1, D2) & NotHolding(R1) & In(C2, D3) -PickUp(R1, C3, D2) & PIn(C1, D1) & PIn(C2, D3) & PIn(R1, D2) -In(C1, D1) & In(C2, D3) & In(R1, D2) & Holding(R1) & In(C3, R1) -Move(R1, D2, D3) & PIn(C1, D1) & PIn(C2, D3) & PHolding(R1) & PIn(C3, R1) -In(C1, D1) & In(C2, D3) & In(C3, R1) & In(R1, D3) & Holding(R1) -PutDown(R1, C3, D3) & PIn(C1, D1) & PIn(C2, D3) & PIn(R1, D3) -In(C1, D1) & In(C2, D3) & In(C3, D3) & In(R1, D3) & NotHolding(R1) \ No newline at end of file diff --git a/planning.py b/planning.py index 8765fa9ec..cdb49faff 100644 --- a/planning.py +++ b/planning.py @@ -4,17 +4,13 @@ import itertools from collections import deque, defaultdict from functools import reduce as _reduce - import numpy as np import search from csp import sat_up, NaryCSP, Constraint, ac_search_solver, is_constraint from logic import FolKB, conjuncts, unify_mm, associate, SAT_plan, cdcl_satisfiable from search import Node -from utils import Expr, expr, first, powerset_product - -from plotter import * -from graphplan_debugger import * +from utils import Expr, expr, first class PlanningProblem: """ diff --git a/plotter.py b/plotter.py deleted file mode 100644 index e058d58ff..000000000 --- a/plotter.py +++ /dev/null @@ -1,60 +0,0 @@ -import matplotlib.pyplot as plt -import networkx as nx - -class GraphVisualizer: - @staticmethod - def plot_graph(graph_obj): - """ - Plot a GraphPlan graph with levels alternating between state and action nodes. - Left-to-right layout, edges show applicability (state → action). - """ - G = nx.DiGraph() - - # Assign positions explicitly for left-to-right layout - pos = {} - x_offset = 0 - y_spacing = 1.5 # vertical spacing - - for i, level in enumerate(graph_obj.levels): - # Place states at even i, actions at odd i - y_offset = 0 - if i % 2 == 0: # state layer - for j, state in enumerate(level.current_state): - node_id = f"S{i}_{j}" - G.add_node(node_id, label=str(state), type="state") - pos[node_id] = (x_offset, -j * y_spacing) - - # connect to actions in this level - for action, preconds in level.current_action_links.items(): - act_id = f"A{i}_{str(action)}" - if act_id not in G: - G.add_node(act_id, label=str(action), type="action") - pos[act_id] = (x_offset + 1.5, -len(G.nodes) * 0.1) - - # draw edges from preconditions to this action - for pre in preconds: - for sid, attrs in G.nodes(data=True): - if attrs.get("label") == str(pre): - G.add_edge(sid, act_id) - - x_offset += 3 # shift to the right for next level - - # Draw - node_colors = [ - "skyblue" if data["type"] == "state" else "lightgreen" - for _, data in G.nodes(data=True) - ] - nx.draw( - G, - pos, - with_labels=True, - labels=nx.get_node_attributes(G, "label"), - node_size=2000, - node_color=node_colors, - font_size=8, - arrows=True, - arrowsize=10, - ) - - plt.title("GraphPlan Levels") - plt.show() \ No newline at end of file diff --git a/submission1.py b/submission1.py deleted file mode 100644 index 614f4cb12..000000000 --- a/submission1.py +++ /dev/null @@ -1,167 +0,0 @@ -import sys -#sys.path.append('/opt/homebrew/lib/python3.9/site-packages') - -import collections, os -from planning import * -from logic import * - -from submission1_test import verify_solution -from planning_envs import * - -# Problem 4: Planning - -""" **IMPORTANT** Reflection (4 pts) -Please *breifly* report your findings and reflect on what they mean: -As I worked on 4b, I found that it was interesting that I needed to specify that certain tiles were adjacent when I constructed my response. -Then, I realized that when the planning problem is generalizing, it needs to be able to handle all different types of locations and plans. -Therefore, telling the algorithm whether two spaces are adjacent or not becomes relevant. -I think my output is incorrect because when I printed the output, it was a list of two actions: -[PutDown(R1, C3, D3), PutDown(R1, C2, D3)]. I believe this output is incorrect because these two actions can't both -be performed back to back when the robot isn't holding a package. -Planning algorithms are very useful for generalizing these issues and having the machine solve logic problems like these ones using planning. -I liked how easy it was to write and run this planning algorithm, especially compared to the searching in the last project. -Abstracting this algorithm, machines can solve lots of these type of problems very easily. -""" - -# Blocks world modification -def blocksWorldModPlan(): - # BEGIN_YOUR_CODE (make modifications to the initial and goal states) - initial_state = 'On(A, B) & Clear(A) & OnTable(B) & On(C,D) & Clear(C) & OnTable(D)' - goal_state = 'On(B, A) & On(C, B) & On(D, C)' - # END_YOUR_CODE - - planning_problem = \ - PlanningProblem(initial=initial_state, - goals=goal_state, - actions=[Action('ToTable(x, y)', - precond='On(x, y) & Clear(x)', - effect='~On(x, y) & Clear(y) & OnTable(x)'), - Action('FromTable(y, x)', - precond='OnTable(y) & Clear(y) & Clear(x)', - effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) - - return linearize(GraphPlan(planning_problem).execute()) - -""" -def logisticsPlan(): - # BEGIN_YOUR_CODE (use the previous problem as a guide and uncomment the starter code below if you want!) - initial_state = 'RobotIn(R1,D1) & RobotCarrying(R1,C1) & ContainerAt(C2,D1) & ContainerAt(C3,D1) & Adjacent(D1,D2) & Adjacent(D1,D3) & Adjacent(D2,D3) & Adjacent(D2,D1) & Adjacent(D3,D1) & Adjacent(D3,D2)' - goal_state = 'ContainerAt(C1,D3) & ContainerAt(C2,D3) & ContainerAt(C3,D3)' - planning_problem = \ - PlanningProblem(initial=initial_state, - goals=goal_state, - actions=[Action('PickUp(robot,container,location)', - precond='RobotNotCarrying(robot) & RobotIn(robot,location) & ContainerAt(container,location)', - effect='~ContainerAt(container,location) & ~RobotNotCarrying(robot) & RobotCarrying(robot,container)'), - Action('PutDown(robot,container,location)', - precond='RobotIn(robot,location) & RobotCarrying(robot,container)', - effect='~RobotCarrying(robot,container) & RobotNotCarrying(robot) & ContainerAt(container,location)'), - Action('RobotMove(robot,location1,location2)', - precond='RobotIn(robot,location1) & Adjacent(location1,location2)', - effect='~RobotIn(robot,location1) & RobotIn(robot,location2)')]) - # END_YOUR_CODE - - return linearize(GraphPlan(planning_problem).execute()) -""" - - -if __name__ == "__main__": - - """ - Call the above functions here with initial/goal states for testing your code. - """ - - #initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - #goal_state = 'In(C1, D2)' - #print(logisticsPlanCustom(initial_state, goal_state)) - - #initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - #goal_state = "In(C1, D1) & In(C3, R1) & In(R1, D3)" - #print(logisticsPlanCustom(initial_state, goal_state)) - - # NOW WORKS: issue was in problem domain definition - #P = double_tennis_problem() - #print(GraphPlan(P).execute()) - - #P = shopping_problem() - #gplan = GraphPlan(P).execute() - #print(gplan) - #print(Linearize(P).execute()) - """ - [[[PItem(Milk), PSells(SM, Milk), PSells(SM, Banana), PStore(HW), - PItem(Banana), PStore(SM), Go(Home, HW), PSells(HW, Drill), - PItem(Drill), Go(Home, SM)], - [Buy(Drill, HW), Buy(Banana, SM), Buy(Milk, SM)]]] - """ - - #P = shopping_problem() - #P = air_cargo() - #P = double_tennis_problem() - #P = have_cake_and_eat_cake_too() - #init = "In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)" - #goal_state = "In(C1,D1)" - #goal_state = "In(C2, D3) & In(C3, D3)" - #goal_state = "In(C1, D3) & In(C2, D3) & In(C3, D3)" - # putdown(c1), pickup(c2), move(d3), putdown(c2), move(d2), pickup(c3), move(d3), putdown(c3) - - #goal_state = "In(C3, D1)" - #goal_state = "In(C2, D3)" - #goal_state = "In(C3, D3)" - # putdown c1, move r1 to d2, pickup c3 in d2, move robot to d1, putdown c3 - #goal_state = "In(C1, D2) & In(C3, D3)" - #P = logisticsPlanCustom(init, goal_state) - - # PickUp(R1, C2, D2) in level 1 is NOT (shouldn't be) POSSIBLE due to mutexes. - """ - P = PlanningProblem(initial = init, - goals = goal_state, - precond='In(r, d) & In (c, d) & ~H - olding(r)', - effect='Holding(r) & ~In(c, d) & In(c, r)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('PutDown(r, c, d)', - precond='In(r, d) & In(c, r) & Holding(r)', - effect='~Holding(r) & ~In(c, r) & In(c, d)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('Move(r, d_start, d_end)', - precond='In(r,d_start)', - effect='~In(r, d_start) & In(r, d_end)', - domain='Robot(r) & Place(d_start) & Place(d_end)')], - domain='Container(C1) & Container(C2) & Place(D1) & Place(D2) & Robot(R1)') - """ - #P = double_tennis_problem_simple2() - - #P = rush_hour() - P = rush_hour_optimized() - #verify_solution(P) - - #GraphPlan(P).execute() - #print(Linearize(P).execute()) - verify_solution(P) - - -""" -Standard logistics environment -Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1) - -Start: -In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1) - -Goal: -In(C1, D1) & In(C3, R1) & In(R1, D3) - -Start: - - C1 is in R1 - - C2 is in D1 - - C3 is in D2 - - R1 is in D1 - - R1 is currnetly holding - -How to get to: - - C1 in D1 (just put it down) - - C3 in R1 (robot must move to D2, Pick up C3) - - R1 in D3 (robot must move to D3) - -So a valid solution is: -["PutDown(R1, C1, D1)", "Move(R1, D1, D2)", "PickUp(R1, C3, D2)", "Move(R1, D2, D3)"] -""" \ No newline at end of file diff --git a/utils.py b/utils.py index 4a891ecac..182f7888a 100644 --- a/utils.py +++ b/utils.py @@ -800,35 +800,3 @@ class Bool(int): T = Bool(True) F = Bool(False) - - - - -def powerset_product(list_of_lists): - """ - Computes the Cartesian product of the power sets of the inner lists. - - Args: - list_of_lists: A list of lists, e.g., [[1, 2], ['a', 'b']]. - - Returns: - A list of lists, where each inner list is a combination of subsets. - """ - - # Helper function to generate the power set for a single iterable - def powerset(iterable): - s = list(iterable) - # chain.from_iterable() flattens the list of tuples from combinations - # combinations(s, r) gives all subsets of length r - return list(chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))) - - # 1. Generate the power set for each inner list - all_power_sets = [powerset(sublist) for sublist in list_of_lists] - - # 2. Compute the Cartesian product of the power sets - cartesian_prod = itertools.product(*all_power_sets) - - # 3. Combine the tuples of tuples into a single list for each result - result = [list(chain.from_iterable(item)) for item in cartesian_prod] - - return result From 4a24a2ebef70f1359fda10041bb48de35f497fae Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sun, 5 Oct 2025 00:09:09 -0400 Subject: [PATCH 16/19] Further cleanup --- PR_UPDATES_GRAPHPLAN.MD | 57 ------- aima_8puzzle.py | 21 --- aima_my_tsp.py | 93 ----------- linearize.py | 108 ------------- logistics-test-probs.py | 46 ------ planning.py | 100 +++++------- submission-2a.py | 332 ---------------------------------------- utils.py | 1 - 8 files changed, 40 insertions(+), 718 deletions(-) delete mode 100644 PR_UPDATES_GRAPHPLAN.MD delete mode 100644 aima_8puzzle.py delete mode 100644 aima_my_tsp.py delete mode 100644 linearize.py delete mode 100644 logistics-test-probs.py delete mode 100644 submission-2a.py diff --git a/PR_UPDATES_GRAPHPLAN.MD b/PR_UPDATES_GRAPHPLAN.MD deleted file mode 100644 index 840568fc3..000000000 --- a/PR_UPDATES_GRAPHPLAN.MD +++ /dev/null @@ -1,57 +0,0 @@ -# Improvements / Necessary Fixes to GraphPlan in AIMA - -## Fixes to the double tennis environment - - - Original env used `a`, `b` in goals rather than `A`, `B` as defined in initial. - - IIRC, `a` and `b`, that is, lowercase variables, can be satisfied by any other variable? Hence, the test still passed, but it was probably not the intention - - Environment failed to search `LeftNet` because it doesn't show up in initial or domain, only goal. - - Original env: - """ - return PlanningProblem( - initial='At(A, LeftBaseLine) & At(B, RightNet) & Approaching(Ball, RightBaseLine) & Partner(A, B) & Partner(B, A)', - goals='Returned(Ball) & At(a, LeftNet) & At(a, RightNet)', - actions=[Action('Hit(actor, Ball, loc)', - precond='Approaching(Ball, loc) & At(actor, loc)', - effect='Returned(Ball)'), - Action('Go(actor, to, loc)', - precond='At(actor, loc)', - effect='At(actor, to) & ~At(actor, loc)')]) - """ - - Note - this passed the pytest manual tests, but not GraphPlan algorithm natively (although that was broken in general ...) - - -## Explicit state and action mutexes - - - In the original implementation, state and action layers, as well as state (proposition) and action mutexes were jumbled together, with no differentiation. - - Technically, I'm not certain that an issue existed with this presentation, but it doesn't follow any of the learner-friendly material on GraphPlan that exists. - - I repurposed the `GraphPlan.graph.levels[i].mutex` to refer to action mutexes, and added a `state_mutexes` attribute to refer to state mutexes. - -## No Interference Computation - - - In the original implementation, I don't see interference (one action deletes the precondition of another) being computed anywhere. - - I have added interference explicitly. - -## Linearization Error? - - - TODO - -## Level compute/expand issue - - - In the original implementation, mutexes were computed after expanding a level and performing goal tests. Therefore, the goal test would not be able to test the goals until one extra layer had been expanded. I reordered the `expand_graph` method to expand a layer, and populate `state_mutexes` before the goal test. - -## Extract_Solution Issue - - - `extract_solution` is a method with the purpose of expanding the graph backwards to the start, identifying subgoals for each next layer, and selecting a set of actions that fulfill this layers subgoals, proceeding to the next layer with the preconditions of those actions as new subgoals. However, the authors wrote this implementation with `itertools.product(*actions)`, which chooses combinations of specifically one action that satisfies each goal. Unfortunately, this is not satisfactory, and certain combinations may not provide necessary support for later layers, despite not having explicit mutexes for these dependencies. - - I have replaced this with a full recursive DFS backwards search, with early exiting. This is required to make it efficient, as technically now this backwards search is a Cartesian product of the powerset of actions, which is 2^(2n) different action sets to test (infeasible) - -## Added debugging tools - -## Added actual GraphPlan tests - - - Currently tests exist for environments, with hardcoded solutions encoded to verify that the goal state actually is achievable. - - However, there are no GraphPlan algorithm tests (?) - - I've created a pytest file and added it to the test dir to improve reliability (and for my own debugging) - - -## Separated Environments from Algorithms - diff --git a/aima_8puzzle.py b/aima_8puzzle.py deleted file mode 100644 index 2d7229983..000000000 --- a/aima_8puzzle.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -Demo for A* with EightPuzzle -For use with the AIMA codebase: https://github.com/aimacode/aima-python -CMSC 421 - Fall 2025 -""" -from time import time -from search import EightPuzzle, astar_search - -# INITIAL_STATE = (1, 2, 3, 4, 5, 6, 7, 8, 0) # already solved -INITIAL_STATE = (1, 2, 3, 4, 5, 6, 7, 0, 8) # just one swap to solve -# INITIAL_STATE = (1, 2, 3, 4, 0, 6, 7, 5, 8) # just two swaps to solve -# INITIAL_STATE = (1, 2, 3, 0, 4, 6, 7, 5, 8) # just three swaps to solve -# INITIAL_STATE = (8, 3, 2, 4, 5, 7, 1, 6, 0) # more complex initial state - -EP = EightPuzzle(INITIAL_STATE) -print('Initial State: ' + str(INITIAL_STATE)) -print('Initial State solvable: ' + str(EP.check_solvability(INITIAL_STATE))) -print('Running A*...') -t0 = time() -astar_search(EP, display=True) -print('Solved in %f seconds'%(time()-t0)) \ No newline at end of file diff --git a/aima_my_tsp.py b/aima_my_tsp.py deleted file mode 100644 index 737bbf7fa..000000000 --- a/aima_my_tsp.py +++ /dev/null @@ -1,93 +0,0 @@ -""" -Code skeleton for A* with TSP -For use with the AIMA codebase: https://github.com/aimacode/aima-python -CMSC 421 - Fall 2025 -""" -from time import time -import numpy as np -from search import Problem, astar_search -from scipy.sparse import csgraph - -### Define TSP ### - -class MyTSP(Problem): - - # NOTE: This is just a suggestion for setting up your __init__, - # you can use any design you want - def __init__(self, weights, initial=(0,), goal=None): - super().__init__(initial, goal) - self.weights = weights - self.num_cities = weights.shape[0] - self.cities = list(range(0, self.num_cities)) - - def actions(self, state): - """Return the actions that can be executed in the given - state. The result would typically be a list, but if there are - many actions, consider yielding them one at a time in an - iterator, rather than building them all at once.""" - raise NotImplementedError - # TODO: your code here - - # NOTE: If you make your state a list object, you'll wind - # up with an error like this: TypeError: unhashable type: 'list' - # One work-around is the make your states tuples instead. - def result(self, state, action): - """Return the state that results from executing the given - action in the given state. The action must be one of - self.actions(state).""" - raise NotImplementedError - # TODO: your code here - - def goal_test(self, state): - """Return True if the state is a goal. The default method compares the - state to self.goal or checks for state in self.goal if it is a - list, as specified in the constructor. Override this method if - checking against a single self.goal is not enough.""" - raise NotImplementedError - # TODO: your code here - - # NOTE: Remember the full cost includes the round trip back to the starting city! - # So if you are adding the final city to the path, you should also add the cost - # for the final edge too. - def path_cost(self, c, state1, action, state2): - """Return the cost of a solution path that arrives at state2 from - state1 via action, assuming cost c to get up to state1. If the problem - is such that the path doesn't matter, this function will only look at - state2. If the path does matter, it will consider c and maybe state1 - and action. The default method costs 1 for every step in the path.""" - raise NotImplementedError - # TODO: your code here - - def value(self, state): - """For optimization problems, each state has a value. Hill Climbing - and related algorithms try to maximize this value.""" - raise NotImplementedError - # TODO: your code here - - # NOTE: For debugging purposes, you can use h(n)=0 while writing and testing - # the rest of your code - def h(self, node): - """Return the heuristic value for a given state. astar_search will - look for this heuristic function when run.""" - raise NotImplementedError - # TODO: your code here - -### Run A* ### - -# NOTE: select a weight matrix to load, depending on where you unzipped them -MATRIX_FILE = '/home/carwyn/dev/phd/ta/aima/aima-python/aima-data/mats_911/5_random_adj_mat_0.txt' - -MAT = np.loadtxt(MATRIX_FILE) -print('Loaded road cost matrix:') -print(MAT) -MTSP = MyTSP(MAT) - -print('Running A*...') -t0 = time() -tsp_sol = astar_search(MTSP, display=True) -print('Solved in %f seconds'%(time()-t0)) - -tsp_sol = tsp_sol.state -print('Solution Path: ' + str(tsp_sol)) -sol_cost = MTSP.value(tsp_sol) -print('Solution Cost: ' + str(sol_cost)) diff --git a/linearize.py b/linearize.py deleted file mode 100644 index 6fc6065c8..000000000 --- a/linearize.py +++ /dev/null @@ -1,108 +0,0 @@ - -class Linearize: - - def __init__(self, planning_problem): - self.planning_problem = planning_problem - - def filter(self, solution): - """Filter out persistence actions from a solution""" - - new_solution = [] - for section in solution[0]: - new_section = [] - for operation in section: - if not (operation.op[0] == 'P' and operation.op[1].isupper()): - new_section.append(operation) - new_solution.append(new_section) - return new_solution - - def orderlevel(self, level, planning_problem): - """Return valid linear order of actions for a given level""" - - for permutation in itertools.permutations(level): - print(f"TRYING PARTIAL PLAN: {permutation}") ## Bill's hack - temp = copy.deepcopy(planning_problem) - count = 0 - ## print(f"PERMUTATION: {permutation}") ## Bill's hack - for action in permutation: - try: - # print(f"TRY ACTION: {action}") ## Bill's hack - temp.act(action) - count += 1 - # print(f"TRY ACTION: {action} SUCCESS!") ## Bill's hack - except: - # print(f"TRY ACTION: {action} FAIL!") ## Bill's hack - count = 0 - temp = copy.deepcopy(planning_problem) - continue ##break - if count == len(permutation): - print(f"\nSUCCESSFUL PARTIAL PLAN ORDERING: {permutation}") ## Bill's hack - return list(permutation), temp - print(f"NO SUCCESSFUL PARTIAL PLAN: {level}") ## Bill's hack - return None, planning_problem ## added planning_problem... its gotta return a planning problem and start over if it fails, but maybe this is saying return fail and the unsolved planning problem - - def execute(self): - """Finds total-order solution for a planning graph""" - - graphPlan_solution = GraphPlan(self.planning_problem).execute() - - ## Bill's stuff from playing around - ## print(f"UNFILTERED PLAN: {graphPlan_solution}") ## Bill's hack - ## pnl(graphPlan_solution) - ## for possible_plan in graphPlan_solution: - ## possible_plan = [possible_plan] - ## filtered_possible_plan = self.filter(possible_plan) - ## print(f"POSSIBLE PLAN: {filtered_possible_plan}") ## Bill's hack - ## flattened_graphplan = self.filter(graphPlan_solution) - ## flattened_graphplan = sum(graphPlan_solution, []) ## Bill's hack - ## flattened_graphplan = sum(flattened_graphplan, []) ## Bill's hack - ## flattened_graphplan = [flattened_graphplan] - ## graphPlan_solution = [flattened_graphplan] ## Bill's hack - ## pnl(flattened_graphplan) - - ## I think I have to go over all permutations of possbile partial graphplans - - for possible_plan in itertools.permutations(graphPlan_solution): ## Bill's hack - - ## possible_plan = [possible_plan] ## Bill's hack, stuff below expect a list with one element which is also a list - ## filtered_solution = self.filter(graphPlan_solution) # original - - filtered_solution = self.filter(possible_plan) # my mod - - print(f"TRYING FILTERED PLAN: {filtered_solution}") ## Bill's hack - - ## filtered_solution = self.filter(possible_plan) # mod - ## print(f"\nFILTERED PLAN: {filtered_solution}") ## Bill's hack - ## pnl(filtered_solution) - ## filtered_solution = possible_plan - - ordered_solution = [] - planning_problem = self.planning_problem - for level in filtered_solution: - - ## print(f"TRYING SOLUTION LEVEL: {level}") ## Bill's hack - - ## the below is a key line, the key line - level_solution, planning_problem = self.orderlevel(level, planning_problem) ## actions get applied - if not level_solution: # This checks if level_solution is None or an empty list - print(f"PLAN FAIL: {filtered_solution}") ## Bill's hack - continue ## Bill's hack!! if empty, continue looking. - - print(f"LEVEL SOLUTION: {level_solution}") ## Bill's hack - ##print(f"CURRENT STATE: {planning_problem.initial}\n") ## Bill's hack - ## for action in level_solution: - ## print(f"APPLY ACTION: {action}") ## Bill's hack - ## planning_problem.act(action) # complete guess, apply action to the problem and keep going - - ## I think we need to apply the plan to the planning problem and modify it - for element in level_solution: - ordered_solution.append(element) - - if not ordered_solution: - continue ## no plan possible from the partial plan at the level - else: - print(f"WORKING SOL'N: {ordered_solution}") ## Bill's hack - break - - return ordered_solution - diff --git a/logistics-test-probs.py b/logistics-test-probs.py deleted file mode 100644 index c70933c3b..000000000 --- a/logistics-test-probs.py +++ /dev/null @@ -1,46 +0,0 @@ - - -## initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - -logisticsPlan('In(C1, D1)') - -logisticsPlan('In(C1,D2)') - -logisticsPlan('In(C1, D1) & In(R1, D2)') -logisticsPlan('In(R1, D2) & In(C1, D1)') - -logisticsPlan('In(C1, D1) & In(C3, R1)') -logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') - -logisticsPlan('In(C1, D1) & In(R1, D3) & In(C3, R1)') -logisticsPlan('In(C1, D1) & In(C3, D3)') - -logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') - -logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') - -logisticsPlan('In(C1, D1) & In(C2, D3)') - - -logisticsPlan('In(C3, D1)') - -logisticsPlan('In(C2, D3)') - -logisticsPlan('In(C3, D3)') - - -#no plans for these below -logisticsPlan('In(C2, D3) & In(C3, D3)') - -logisticsPlan('In(C3, D3) & In(C2, D3)') - -logisticsPlan('In(C1, D2) & In(C3, D3)') - -logisticsPlan('In(C1, D3) & In(C2, D3) & In(C3, D3)') ## homework?? - -logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D1)') - - -#kaboom... didn't stop? -logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)') - diff --git a/planning.py b/planning.py index cdb49faff..050b8745f 100644 --- a/planning.py +++ b/planning.py @@ -468,7 +468,7 @@ class Level: states as pre-condition. """ - def __init__(self, kb, is_first_layer=False): + def __init__(self, kb): """Initializes variables to hold state and action details of a level""" self.kb = kb @@ -493,12 +493,12 @@ def __init__(self, kb, is_first_layer=False): # mutually exclusive actions self.mutex = [] - - self.is_first_layer = is_first_layer - self.next_state_mutexes = [] - + # mutually exclusive states self.state_mutexes = [] + + # mutually exclusive next states + self.next_state_mutexes = [] def __call__(self, actions, objects): self.build(actions, objects) @@ -533,9 +533,7 @@ def separate(self, e): def find_mutex(self): "Finds mutually exclusive actions" - "This function is only entered after state, actions at this level are computed." - "Therefore, we're computing it for the current state and current (state+1) action layer" - + self.state_mutexes = self.mutex # save state mutexes self.mutex = [] # clear out effects from state mutex prior computation @@ -543,12 +541,12 @@ def find_mutex(self): for a1, a2 in itertools.combinations(self.current_action_links.keys(), 2): preconds_a1 = self.current_action_links[a1] preconds_a2 = self.current_action_links[a2] - + if any({p, q} in self.state_mutexes for p in preconds_a1 for q in preconds_a2): mutex_pair = {a1, a2} if mutex_pair not in self.mutex: self.mutex.append(mutex_pair) - + # Interference AND Inconsistent Effects Mutex Calculation for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): preconds_a1 = self.current_action_links.get(a1, []) @@ -577,7 +575,7 @@ def find_mutex(self): mutex_pair = {a1, a2} if mutex_pair not in self.mutex: self.mutex.append(mutex_pair) - + def populate_prop_mutexes(self): "Compute the next level's proposition mutexes based on our current action mutexes" @@ -588,11 +586,11 @@ def populate_prop_mutexes(self): s1, s2 = list(next_state_pair) acts_to_s1 = self.next_state_links.get(s1, []) acts_to_s2 = self.next_state_links.get(s2, []) - + # ensure our mutexes only apply to pairs, not single states. if acts_to_s1 == [] or acts_to_s2 == []: continue - + # if any two actions that lead to these states is not mutex, do not add a mutex to these states. if all([{a1,a2} in self.mutex or {a2,a1} in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): mutex_pair = {s1, s2} @@ -607,7 +605,6 @@ def populate_prop_mutexes(self): mutex_pair = {s1, s2} if mutex_pair not in state_mutex: state_mutex.append(mutex_pair) - self.next_state_mutexes = state_mutex return state_mutex @@ -668,7 +665,7 @@ def build(self, actions, objects): self.next_action_links[p_expr] = [clause] self.current_state_links[clause] = [p_expr] self.next_state_links[clause] = [p_expr] - + for a in actions: num_args = len(a.args) possible_args = tuple(itertools.permutations(objects, num_args)) @@ -706,9 +703,7 @@ def perform_actions(self): "Performs the necessary actions and returns a new Level" new_kb = FolKB(list(set(self.next_state_links.keys()))) - new_level = Level(new_kb) - - return new_level + return Level(new_kb) class Graph: @@ -720,12 +715,12 @@ class Graph: def __init__(self, planning_problem): self.planning_problem = planning_problem self.kb = FolKB(planning_problem.initial) - self.levels = [Level(self.kb, True)] + self.levels = [Level(self.kb)] self.objects = set(arg for clause in self.kb.clauses for arg in clause.args) def __call__(self): self.expand_graph() - + def __str__(self): levels_str = "\n".join( f"Level {i}:\n{str(level)}" for i, level in enumerate(self.levels) @@ -748,7 +743,6 @@ def expand_graph(self): new_level.mutex = last_level.populate_prop_mutexes() # Populate the mutexes for the next state level to come self.levels.append(new_level) - def non_mutex_goals(self, goals, index): "Checks whether the goals are mutually exclusive" @@ -757,7 +751,7 @@ def non_mutex_goals(self, goals, index): if set(g) in self.levels[index].mutex: return False return True - + class GraphPlan: """ @@ -771,9 +765,6 @@ def __init__(self, planning_problem): self.no_goods = [] self.solution = [] - global isFirstLayer - isFirstLayer = True - def __str__(self): sol_str = ( "No solution found" @@ -791,6 +782,7 @@ def __str__(self): def check_leveloff(self): """Checks if the graph has leveled off""" + # TODO: This check is not satisfactory check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) and \ self.graph.levels[-1].mutex == self.graph.levels[-2].mutex @@ -798,68 +790,58 @@ def check_leveloff(self): return True def _get_preconditions_for(self, action_set, level): - #Collects all unique preconditions for a given set of actions in a level. + """Collects all unique preconditions for a given set of actions in a level""" all_preconditions = set() for action in action_set: - # Assumes level.current_action_links maps an action to its preconditions preconditions = level.current_action_links.get(action, []) all_preconditions.update(preconditions) return all_preconditions - def _find_valid_action_sets(self, goals, level): - #Finds sets of actions in the given level that are not mutually exclusive - #and that collectively satisfy all the goals. + """ + Finds sets of actions in the given level that are not mutually exclusive + and that collectively satisfy all the goals. + """ valid_sets = [] - - # 1. Map each goal to the list of actions that can achieve it. - actions_for_goal = {g: level.next_state_links.get(g, []) for g in goals} - # 2. Generate combinations of actions that could potentially satisfy the goals. - # This creates a list of lists, where each inner list contains potential achievers for one goal. + actions_for_goal = {g: level.next_state_links.get(g, []) for g in goals} potential_action_groups = [actions_for_goal[g] for g in goals] - - # The cartesian product gives us tuples, where each tuple contains one action - # choice for each goal. + for action_combination in itertools.product(*potential_action_groups): - # We only need the unique actions in the combination. action_set = set(action_combination) - # 3. Check for mutexes within this set of actions. is_mutex = False for a1, a2 in itertools.combinations(action_set, 2): if {a1, a2} in level.mutex: is_mutex = True break - - # 4. If the set is non-mutex and we haven't already added it, it's a valid option. + if not is_mutex and action_set not in valid_sets: valid_sets.append(action_set) - + return valid_sets - # Place this within your GraphPlan class - def extract_solution(self, goals, level_index, root=False): - #Primary method to start the solution extraction process. - #It calls the recursive helper and returns the final plan. - # Start the recursive search from the level where goals must be true - final_plan = self._extract_solution_recursive(set(goals), len(self.graph.levels)-1) - return final_plan + def extract_solution(self, goals): + """ + Primary method to start the solution extraction process. + It calls the recursive helper and returns the final plan. + """ + return self._extract_solution_recursive(set(goals), len(self.graph.levels)-1) # Place this within your GraphPlan class, replacing the previous version def _extract_solution_recursive(self, goals, level_index): """ Recursively searches for a plan backwards from a given level using negative indexing. - + Args: goals (set): The set of goal propositions to satisfy. level_index (int): level index """ - + #BASE CASE: We've recursed back to the initial proposition layer (Level 0). #The 'goals' at this point are the preconditions for the very first set of actions. #We must check if they exist in the initial state. No further recursion is needed. - + if level_index == 0: initial_state = set(self.graph.levels[0].current_state) if goals.issubset(initial_state): @@ -899,19 +881,17 @@ def _extract_solution_recursive(self, goals, level_index): def goal_test(self, kb): goal_achieved = all(kb.ask(q) is not False for q in self.graph.planning_problem.goals) - # print(goal_achieved) return goal_achieved def execute(self): "Executes the GraphPlan algorithm for the given problem" - print("Forward Search") while True: self.graph.expand_graph() if (self.goal_test(self.graph.levels[-1].kb) and self.graph.non_mutex_goals( self.graph.planning_problem.goals, -1)): - solution = self.extract_solution(self.graph.planning_problem.goals, -1, True) + solution = self.extract_solution(self.graph.planning_problem.goals) if solution: return [solution] @@ -963,10 +943,10 @@ def execute(self): "Finds a total-order solution for a planning graph. Possibly not the only linearization possible." graphPlan_solution = GraphPlan(self.planning_problem).execute() - + for possible_plan in graphPlan_solution: filtered_solution = self.filter(possible_plan) - + ordered_solution = [] # planning_problem will maintain the current state as we iterate over levels, allowing test application of actions planning_problem = self.planning_problem @@ -984,12 +964,12 @@ def execute(self): continue ## no plan possible from the partial plan at the level else: break - + return ordered_solution def linearize(solution): """Converts a level-ordered solution into a linear solution""" - + linear_solution = [] for section in solution[0]: for operation in section: diff --git a/submission-2a.py b/submission-2a.py deleted file mode 100644 index 322b8cdd0..000000000 --- a/submission-2a.py +++ /dev/null @@ -1,332 +0,0 @@ -import collections, sys, os -from logic import * -from planning import * - -############################################################ -# Problem 1: propositional logic -# Convert each of the following natural language sentences into a propositional -# logic formula. See rainWet() in examples.py for a relevant example. - -# Sentence: "If it's summer and we're in California, then it doesn't rain." -def formula1a(): - # Predicates to use: - Summer = Atom('Summer') # whether it's summer - California = Atom('California') # whether we're in California - Rain = Atom('Rain') # whether it's raining - # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) - return Implies(And(Summer, California),Not(Rain)) - # END_YOUR_CODE - -# Sentence: "It's wet if and only if it is raining or the sprinklers are on." -def formula1b(): - # Predicates to use: - Rain = Atom('Rain') # whether it is raining - Wet = Atom('Wet') # whether it it wet - Sprinklers = Atom('Sprinklers') # whether the sprinklers are on - # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) - return And(Implies(Wet,Or(Rain, Sprinklers)), Implies(Or(Rain, Sprinklers),Wet)) - # END_YOUR_CODE - -# Sentence: "Either it's day or night (but not both)." -def formula1c(): - # Predicates to use: - Day = Atom('Day') # whether it's day - Night = Atom('Night') # whether it's night - # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) - return Or(And(Day, Not(Night)), And(Not(Day),Night)) - # END_YOUR_CODE - -############################################################ -# Problem 2: first-order logic - -# Sentence: "Every person has a mother." -def formula2a(): - # Predicates to use: - def Person(x): return Atom('Person', x) # whether x is a person - def Mother(x, y): return Atom('Mother', x, y) # whether x's mother is y - - # Note: You do NOT have to enforce that the mother is a "person" - # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) - return Forall('$x', Implies(Person('$x'), Exists('$y', Mother('$x', '$y')))) - # END_YOUR_CODE - -# Sentence: "At least one person has no children." -def formula2b(): - # Predicates to use: - def Person(x): return Atom('Person', x) # whether x is a person - def Child(x, y): return Atom('Child', x, y) # whether x has a child y - - # Note: You do NOT have to enforce that the child is a "person" - # BEGIN_YOUR_CODE (our solution is 1 line of code, but don't worry if you deviate from this) - return Not(Forall('$x', Implies(Person('$x'), Exists('$y', Child('$x', '$y'))))) - # END_YOUR_CODE - -# Return a formula which defines Daughter in terms of Female and Child. -# See parentChild() in examples.py for a relevant example. -def formula2c(): - # Predicates to use: - def Female(x): return Atom('Female', x) # whether x is female - def Child(x, y): return Atom('Child', x, y) # whether x has a child y - def Daughter(x, y): return Atom('Daughter', x, y) # whether x has a daughter y - # BEGIN_YOUR_CODE (our solution is 4 lines of code, but don't worry if you deviate from this) - return Forall('$x', Forall('$y', Equiv(And(Female('$x'), Child('$y', '$x')), Daughter('$y', '$x')))) - # END_YOUR_CODE - -# Return a formula which defines Grandmother in terms of Female and Parent. -# Note: It is ok for a person to be her own parent -def formula2d(): - # Predicates to use: - def Female(x): return Atom('Female', x) # whether x is female - def Parent(x, y): return Atom('Parent', x, y) # whether x has a parent y - def Grandmother(x, y): return Atom('Grandmother', x, y) # whether x has a grandmother y - # BEGIN_YOUR_CODE (our solution is 5 lines of code, but don't worry if you deviate from this) - - return Forall('$gen1', Forall('$gen3', Equiv(Exists( '$gen2',And(And(Female('$gen1'), Parent('$gen2', '$gen1')), Parent('$gen3', '$gen2'))), Grandmother('$gen3', '$gen1')))) - # END_YOUR_CODE - -############################################################ -# Problem 3: Liar puzzle - -# Facts: -# 0. John: "It wasn't me!" -# 1. Susan: "It was Nicole!" -# 2. Mark: "No, it was Susan!" -# 3. Nicole: "Susan's a liar." -# 4. Exactly one person is telling the truth. -# 5. Exactly one person crashed the server. -# Query: Who did it? -# This function returns a list of 6 formulas corresponding to each of the -# above facts. -# Hint: You might want to use the Equals predicate, defined in logic.py. This -# predicate is used to assert that two objects are the same. -# In particular, Equals(x,x) = True and Equals(x,y) = False iff x is not equal to y. -def liar(): - def TellTruth(x): return Atom('TellTruth', x) - def CrashedServer(x): return Atom('CrashedServer', x) - john = Constant('john') - susan = Constant('susan') - nicole = Constant('nicole') - mark = Constant('mark') - formulas = [] - # We provide the formula for fact 0 here. - formulas.append(Equiv(TellTruth(john), Not(CrashedServer(john)))) - - # You should add 5 formulas, one for each of facts 1-5. - # BEGIN_YOUR_CODE (our solution is 11 lines of code, but don't worry if you deviate from this) - formulas.append(Equiv(TellTruth(susan), CrashedServer(nicole))) - formulas.append(Equiv(TellTruth(mark), CrashedServer(susan))) - formulas.append(Equiv(TellTruth(nicole), Not(TellTruth(susan)))) - formulas.append(Or(And(TellTruth(john), And(Not(TellTruth(susan)), And(Not(TellTruth(nicole)), Not(TellTruth(mark))))), - Or(And(Not(TellTruth(john)), And(TellTruth(susan), And(Not(TellTruth(nicole)), Not(TellTruth(mark))))), - Or(And(Not(TellTruth(john)), And(Not(TellTruth(susan)), And(TellTruth(nicole), Not(TellTruth(mark))))), - And(Not(TellTruth(john)), And(Not(TellTruth(susan)), And(Not(TellTruth(nicole)), TellTruth(mark)))))))) - formulas.append( - Or(And(CrashedServer(john), And(Not(CrashedServer(susan)), And(Not(CrashedServer(nicole)), Not(CrashedServer(mark))))), - Or(And(Not(CrashedServer(john)), And(CrashedServer(susan), And(Not(CrashedServer(nicole)), Not(CrashedServer(mark))))), - Or(And(Not(CrashedServer(john)), And(Not(CrashedServer(susan)), And(CrashedServer(nicole), Not(CrashedServer(mark))))), - And(Not(CrashedServer(john)), And(Not(CrashedServer(susan)), And(Not(CrashedServer(nicole)), CrashedServer(mark)))))))) - # END_YOUR_CODE - query = CrashedServer('$x') - return (formulas, query) - - -############################################################ -# Problem 4: Planning - -# Blocks world modification -def blocksWorldModPlan(): - # BEGIN_YOUR_CODE (make modifications to the initial and goal states) - initial_state = 'On(A, B) & Clear(A) & OnTable(B) & OnTable(D) & On(C,D) & Clear(C)' - goal_state = 'On(B, A) & On(C, B) & On(D,C)' - # END_YOUR_CODE - - planning_problem = \ - PlanningProblem(initial=initial_state, - goals=goal_state, - actions=[Action('ToTable(x, y)', - precond='On(x, y) & Clear(x)', - effect='~On(x, y) & Clear(y) & OnTable(x)'), - Action('FromTable(y, x)', - precond='OnTable(y) & Clear(y) & Clear(x)', - effect='~OnTable(y) & ~Clear(x) & On(y, x)')]) - print(linearize(GraphPlan(planning_problem).execute())) - return linearize(GraphPlan(planning_problem).execute()) - - # BEGIN_YOUR_CODE (use the previous problem as a guide and uncomment the starter code below if you want!) - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = 'In(C1, D3) & In(C2, D3) & In(C3, D3)' - # doesn't work: [PutDown(R1, C2, D3), PutDown(R1, C3, D3)] - - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = logisticsPlan('In(C1,D2)') - # works: [Move(R1, D1, D2), PutDown(R1, C1, D2)] - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = logisticsPlan('In(C1, D1) & In(R1, D2)') - # works: [Move(R1, D1, D2), PutDown(R1, C1, D1)] but backwards - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') - # works: [Move(R1, D1, D2), PutDown(R1, C1, D1), PickUp(R1, C3, D2)] but wrong order - - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = 'In(C1, D2) & In(C3, D3)' - # doesn't work: [Move(R1, D1, D2), Move(R1, D1, D3), PutDown(R1, C1, D2)] - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = 'In(C1, D1) & In(C3, R1)' - # works, subset of above, but wrong order: [Move(R1, D1, D2), PutDown(R1, C1, D1), PickUp(R1, C3, D2)] - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = 'In(C1, D1) & In(C3, R1) & In(R1, D3)' - # seems to work, wrong order: [Move(R1, D1, D2), PutDown(R1, C1, D1), Move(R1, D1, D3), PickUp(R1, C3, D2)] - - - # initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - # goal_state = 'In(C1, D1) & In(C2, D3)' - # kaboom - - # goal_state = 'In(C1, D3) & In(C2, D3) & In(C3, D3)' - -def logisticsPlan(the_goal_state): # - initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - goal_state = the_goal_state ## 'In(C1, D1) & In(C2, D3)' - - planning_problem = \ - PlanningProblem(initial = initial_state, - goals = goal_state, - actions=[Action('PickUp(r, c, d)', - precond='In(r, d) & In (c, d) & ~Holding(r)', - effect='Holding(r) & ~In(c, d) & In(c, r)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('PutDown(r, c, d)', - precond='In(r, d) & In(c, r) & Holding(r)', - effect='~Holding(r) & ~In(c, r) & In(c, d)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('Move(r, d_start, d_end)', - precond='In(r,d_start)', - effect='~In(r, d_start) & In(r, d_end)', - domain='Robot(r) & Place(d_start) & Place(d_end)')], - domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1)') - # END_YOUR_CODE - - return Linearize(planning_problem).execute() - -return GraphPlan(planning_problem).execute() - - - -## initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - -logisticsPlan('In(C1, D1)') - -logisticsPlan('In(C1,D2)') - -logisticsPlan('In(C1, D1) & In(R1, D2)') -logisticsPlan('In(R1, D2) & In(C1, D1)') - -logisticsPlan('In(C1, D1) & In(C3, R1)') -logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') - -logisticsPlan('In(C1, D1) & In(R1, D3) & In(C3, R1)') -logisticsPlan('In(C1, D1) & In(C3, D3)') - -logisticsPlan('In(C1, D1) & In(R1, D2) & In(C3, R1)') - -logisticsPlan('In(C1, D1) & In(C3, R1) & In(R1, D3)') - -logisticsPlan('In(C1, D1) & In(C2, D3)') - - -logisticsPlan('In(C3, D1)') - -logisticsPlan('In(C2, D3)') - -logisticsPlan('In(C3, D3)') - - -#no plans for these below -logisticsPlan('In(C2, D3) & In(C3, D3)') - -logisticsPlan('In(C3, D3) & In(C2, D3)') - -logisticsPlan('In(C1, D2) & In(C3, D3)') - -logisticsPlan('In(C1, D3) & In(C2, D3) & In(C3, D3)') ## homework?? - -logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D1)') - - -#kaboom... didn't stop? -logisticsPlan('In(C1, D2) & In(C3, D3) & In(C2, D3) & In(R1, D1)') - - - - - -def logisticsPlan(the_goal_state): - initial_state = 'In(C1, R1) & In(C2, D1) & In(C3, D2) & In(R1, D1) & Holding(R1)' - goal_state = the_goal_state ## 'In(C1, D1) & In(C2, D3)' - planning_problem = \ - PlanningProblem(initial = initial_state, - goals = goal_state, - actions=[Action('PickUp(r, c, d)', - precond='In(r, d) & In (c, d) & ~Holding(r)', - effect='Holding(r) & ~In(c, d) & In(c, r)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('PutDown(r, c, d)', - precond='In(r, d) & In(c, r) & Holding(r)', - effect='~Holding(r) & ~In(c, r) & In(c, d)', - domain='Robot(r) & Place(d) & Container(c)'), - Action('Move(r, d_start, d_end)', - precond='In(r, d_start)', - effect='~In(r, d_start) & In(r, d_end)', - domain='Connected(d_start, d_end) & Robot(r) & Place(d_start) & Place(d_end)')], - domain='Container(C1) & Container(C2) & Container(C3) & Place(D1) & Place(D2) & Place(D3) & Robot(R1) & Connected(D1,D2) & Connected(D2,D3)') - # END_YOUR_CODE - - return linearize(GraphPlan(planning_problem).execute()) - -logisticsPlan('In(C1, D1) & In(C2, D3)') - - - #return GraphPlan(planning_problem).execute() - -# the_plan = " " - # new_line_symbol = " " - # linear_plan = " " - # the_pop_plan = " " - # the_plan = GraphPlan(planning_problem).execute() - # new_line_symbol = "| |" - # linear_plan = linearize(the_plan) - # the_pop_plan = PartialOrderPlanner(planning_problem).execute() - # plan_output = f"{the_plan}{new_line_symbol}{linear_plan}{new_line_symbol}{the_pop_plan}" - # return plan_output - -## |[PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), Move(R1, D1, D3), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D3), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), Move(R1, D1, D2), PickUp(R1, C2, D1), PickUp(R1, C3, D2), PutDown(R1, C2, D3)]' - -""" **IMPORTANT** Reflection (4 pts) - For this problem I have three different defined actions- pick up, put down, and move. Pick up changes the location of a container - from in a room to inside a robot, making sure to update the appropriate states so it is no longer inside the room and is inside the - robot. I also use a variable that states whether or not the robot is already holding something as the robot can only carry one thing - at a time. This variable is also used in the action PutDown since it must check what the robot is holding and changes the location of - the container from inside the robot to inside the room. Finally in moving the robot, it changes the location of the robot from it's - starting position to the ending position. Any time a location changes, the previous location predicate is negated to ensure that - an object is only in one area at a time. I also included domains specifying whether the variables are containers, places, or a robot - so that the algorithm doesn't try something like put a container in a container and move that instead of a robot. - The output for this algorithm is incorrect however, I believe this is because there appears to be an issue in updating the states as - it doesn't always seem to correctly check the preconditions for each action. It also may be due to issues in removing mutually exclusive - actions, or in removing repeated actions when the environment is in different states, in the planning algorithm due to the need to - repeatedly enter the same room. The true action that should be recorded are - - Move[R1, D1, D3], PutDown[R1, C1, D3], Move[R1, D3, D1], PickUp[R1, C2, D1], Move[R1, D1, D3], PutDown[R1, C2, D3], Move[R1, D3, D2], - PickUp[R1, C3, D2], Move[R1, D2, D3], PutDown[R1, C3, D3] - - or - - Move[R1, D1, D3], PutDown[R1, C1, D3], Move[R1, D3, D2], PickUp[R1, C3, D2], Move[R1, D2, D3], PutDown[R1, C3, D3], Move[R1, D3, D1], - PickUp[R1, C2, D1], Move[R1, D1, D3], PutDown[R1, C2, D3] -""" diff --git a/utils.py b/utils.py index 182f7888a..d05d2756e 100644 --- a/utils.py +++ b/utils.py @@ -9,7 +9,6 @@ import os.path import random from itertools import chain, combinations -import itertools from statistics import mean import numpy as np From 497414c33ac99ac3c0a103f7ec703a19a0db37b2 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sun, 5 Oct 2025 10:30:45 -0400 Subject: [PATCH 17/19] Issue identified. Leveloff condition failing to check for mutex equivalence between prior layers. Furthermore, my mutex handling of overwriting with state mutexes causes this to fail anyway --- planning.py | 21 +++++++++++++++------ tests/test_graphplan.py | 42 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/planning.py b/planning.py index 050b8745f..398a30a75 100644 --- a/planning.py +++ b/planning.py @@ -303,6 +303,7 @@ def h(self, state): actions=[action.relaxed() for action in self.planning_problem.actions]) try: + # Relies upon GraphPlan exiting when leveled off return len(linearize(GraphPlan(relaxed_planning_problem).execute())) except: return np.inf @@ -781,13 +782,21 @@ def __str__(self): def check_leveloff(self): """Checks if the graph has leveled off""" + if len(self.graph.levels) < 2: + return False + + level = self.graph.levels[-1] + prev_level = self.graph.levels[-2] - # TODO: This check is not satisfactory - check = (set(self.graph.levels[-1].current_state) == set(self.graph.levels[-2].current_state)) and \ - self.graph.levels[-1].mutex == self.graph.levels[-2].mutex + same_state = set(level.current_state) == set(prev_level.current_state) + + level_mutex = set(frozenset(m) for m in level.mutex) + prev_mutex = set(frozenset(m) for m in prev_level.mutex) + same_mutex = level_mutex == prev_mutex + + print(f"leveloff, state_equality={same_state}, mutex_equality={same_mutex}, level_m_size={len(level_mutex)}, prev_level_m_size={len(prev_mutex)}") - if check: - return True + return same_state and same_mutex def _get_preconditions_for(self, action_set, level): """Collects all unique preconditions for a given set of actions in a level""" @@ -895,7 +904,7 @@ def execute(self): if solution: return [solution] - if len(self.graph.levels) >= 2 and self.check_leveloff(): + if self.check_leveloff(): return None class Linearize: diff --git a/tests/test_graphplan.py b/tests/test_graphplan.py index ddadf6026..2d2ecc4f9 100644 --- a/tests/test_graphplan.py +++ b/tests/test_graphplan.py @@ -207,11 +207,49 @@ def run_planner_in_queue(problem, queue): result_queue = Queue() proc = Process(target=run_planner_in_queue, args=(P, result_queue)) proc.start() - proc.join(timeout=10) + proc.join(timeout=3) if proc.is_alive(): proc.terminate() proc.join() + assert False else: result = result_queue.get() - assert result is None or result == [] or result == [[]] \ No newline at end of file + breakpoint() + assert result is None or result == [] or result == [[]] + + +def impossible_cake_problem(): + """ + An impossible planning problem to demonstrate GraphPlan's level-off detection. + + The goal is to both Have(Cake) and Eaten(Cake). However, the only available + action, Eat(Cake), has the effect of ~Have(Cake). The propositions + Have(Cake) and Eaten(Cake) will become mutually exclusive at the first + level, and the graph will quickly level off, proving the goal is unreachable. + """ + return PlanningProblem( + initial='Have(Cake) & ~Eaten(Cake)', + goals='Have(Cake) & Eaten(Cake)', + actions=[ + Action('Eat(Cake)', + precond='Have(Cake)', + effect='Eaten(Cake) & ~Have(Cake)') + ] + ) + +def test_impossible_cake_exits_early(): + """ + Verify that GraphPlan terminates and returns None for the impossible cake problem. + """ + problem = impossible_cake_problem() + # For an impossible problem that levels off, execute() should return None. + solution = GraphPlan(problem).execute() + + print(f"\nTesting impossible_cake_problem...") + if solution is None: + print("SUCCESS: The algorithm correctly determined the problem is unsolvable and leveled off.") + else: + print(f"FAILURE: A solution was found, which should be impossible. Solution: {solution}") + + assert solution is None \ No newline at end of file From b16e8629677ca32162c942a1ed8da6ef6e158319 Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Sun, 5 Oct 2025 12:01:24 -0400 Subject: [PATCH 18/19] Differentiated between state and action mutexes. Fixed leveloff function. Made previous tests coherent with updates --- planning.py | 36 ++++++++++---------- planning_envs.py | 14 ++++---- tests/test_graphplan.py | 75 ++++++++++++++++++++++------------------- tests/test_planning.py | 9 +++-- 4 files changed, 70 insertions(+), 64 deletions(-) diff --git a/planning.py b/planning.py index 398a30a75..8679810d7 100644 --- a/planning.py +++ b/planning.py @@ -493,13 +493,10 @@ def __init__(self, kb): self.next_state_links = {} # mutually exclusive actions - self.mutex = [] + self.action_mutexes = [] # mutually exclusive states self.state_mutexes = [] - - # mutually exclusive next states - self.next_state_mutexes = [] def __call__(self, actions, objects): self.build(actions, objects) @@ -508,13 +505,12 @@ def __call__(self, actions, objects): def __str__(self): state_str = ", ".join(str(s) for s in self.current_state) action_str = ", ".join(str(a) for a in self.current_action_links.keys()) - mutex_str = ", ".join([str(m) for m in self.mutex]) + mutex_str = ", ".join([str(m) for m in self.action_mutexes]) return ( f"\n" f" Current State: {{{state_str}}}\n" f" Actions: {{{action_str}}}\n" f" Mutex: {{{mutex_str}}}\n" - f" Next state mutexes: {{{self.next_state_mutexes}}}\n" ) __repr__ = __str__ @@ -535,8 +531,7 @@ def separate(self, e): def find_mutex(self): "Finds mutually exclusive actions" - self.state_mutexes = self.mutex # save state mutexes - self.mutex = [] # clear out effects from state mutex prior computation + self.action_mutexes = [] # clear out effects from state mutex prior computation # Competing Needs - two actions are mutex if any of their preconditions are mutex at the previous state level for a1, a2 in itertools.combinations(self.current_action_links.keys(), 2): @@ -545,8 +540,8 @@ def find_mutex(self): if any({p, q} in self.state_mutexes for p in preconds_a1 for q in preconds_a2): mutex_pair = {a1, a2} - if mutex_pair not in self.mutex: - self.mutex.append(mutex_pair) + if mutex_pair not in self.action_mutexes: + self.action_mutexes.append(mutex_pair) # Interference AND Inconsistent Effects Mutex Calculation for a1, a2 in itertools.combinations(self.next_action_links.keys(), 2): @@ -574,8 +569,8 @@ def find_mutex(self): if interference: mutex_pair = {a1, a2} - if mutex_pair not in self.mutex: - self.mutex.append(mutex_pair) + if mutex_pair not in self.action_mutexes: + self.action_mutexes.append(mutex_pair) def populate_prop_mutexes(self): "Compute the next level's proposition mutexes based on our current action mutexes" @@ -593,7 +588,7 @@ def populate_prop_mutexes(self): continue # if any two actions that lead to these states is not mutex, do not add a mutex to these states. - if all([{a1,a2} in self.mutex or {a2,a1} in self.mutex for a1 in acts_to_s1 for a2 in acts_to_s2]): + if all([{a1,a2} in self.action_mutexes or {a2,a1} in self.action_mutexes for a1 in acts_to_s1 for a2 in acts_to_s2]): mutex_pair = {s1, s2} if mutex_pair not in state_mutex: state_mutex.append(mutex_pair) @@ -607,7 +602,6 @@ def populate_prop_mutexes(self): if mutex_pair not in state_mutex: state_mutex.append(mutex_pair) - self.next_state_mutexes = state_mutex return state_mutex def prune_invalid_actions(self): @@ -741,7 +735,7 @@ def expand_graph(self): last_level(self.planning_problem.actions, self.objects) # populate state/actions/mutexes last_level.prune_invalid_actions() new_level = last_level.perform_actions() # Create new level - new_level.mutex = last_level.populate_prop_mutexes() # Populate the mutexes for the next state level to come + new_level.state_mutexes = last_level.populate_prop_mutexes() # Populate the mutexes for the next state level to come self.levels.append(new_level) def non_mutex_goals(self, goals, index): @@ -749,7 +743,7 @@ def non_mutex_goals(self, goals, index): goal_perm = itertools.combinations(goals, 2) for g in goal_perm: - if set(g) in self.levels[index].mutex: + if set(g) in self.levels[index].state_mutexes: return False return True @@ -790,8 +784,8 @@ def check_leveloff(self): same_state = set(level.current_state) == set(prev_level.current_state) - level_mutex = set(frozenset(m) for m in level.mutex) - prev_mutex = set(frozenset(m) for m in prev_level.mutex) + level_mutex = set(frozenset(m) for m in level.state_mutexes) + prev_mutex = set(frozenset(m) for m in prev_level.state_mutexes) same_mutex = level_mutex == prev_mutex print(f"leveloff, state_equality={same_state}, mutex_equality={same_mutex}, level_m_size={len(level_mutex)}, prev_level_m_size={len(prev_mutex)}") @@ -821,7 +815,7 @@ def _find_valid_action_sets(self, goals, level): is_mutex = False for a1, a2 in itertools.combinations(action_set, 2): - if {a1, a2} in level.mutex: + if {a1, a2} in level.action_mutexes: is_mutex = True break @@ -953,6 +947,10 @@ def execute(self): graphPlan_solution = GraphPlan(self.planning_problem).execute() + # Exit if no plan found + if graphPlan_solution is None: + return None + for possible_plan in graphPlan_solution: filtered_solution = self.filter(possible_plan) diff --git a/planning_envs.py b/planning_envs.py index 0f032ac5d..6e2c8ac63 100644 --- a/planning_envs.py +++ b/planning_envs.py @@ -239,7 +239,7 @@ def have_cake_and_eat_cake_too(): >>> """ - return PlanningProblem(initial='Have(Cake) & ~Eaten(Cake)', + return PlanningProblem(initial='Have(Cake)', goals='Have(Cake) & Eaten(Cake)', actions=[Action('Eat(Cake)', precond='Have(Cake)', @@ -370,27 +370,25 @@ def double_tennis_problem(): >>> dtp = double_tennis_problem() >>> goal_test(dtp.goals, dtp.initial) False - >>> dtp.act(expr('Go(A, RightBaseLine, LeftBaseLine)')) + >>> dtp.act(expr('Go(A, RightBaseLine, LeftNet)')) >>> dtp.act(expr('Hit(A, Ball, RightBaseLine)')) >>> goal_test(dtp.goals, dtp.initial) False - >>> dtp.act(expr('Go(A, LeftNet, RightBaseLine)')) + >>> dtp.act(expr('Go(A, LeftBaseLine, RightBaseLine)')) >>> goal_test(dtp.goals, dtp.initial) True - >>> """ return PlanningProblem( - initial='At(A, LeftNet) & At(B, RightNet) & Approaching(ball, RightBaseline)', - goals='At(A, LeftBaseline) & At(B, LeftNet) & Returned(ball)', + initial='At(A, LeftNet) & At(B, RightNet) & Approaching(Ball, RightBaseLine)', + goals='At(A, LeftBaseLine) & At(B, LeftNet) & Returned(Ball)', actions=[Action('Hit(actor, ball, loc)', precond='Approaching(ball, loc) & At(actor, loc)', effect='Returned(ball)'), Action('Go(actor, to, loc)', precond='At(actor, loc)', effect='At(actor, to) & ~At(actor, loc)')], - domain="Loc(LeftBaseline)") - + domain="Loc(LeftBaseLine)") def rush_hour(): """ diff --git a/tests/test_graphplan.py b/tests/test_graphplan.py index 2d2ecc4f9..b241a77f1 100644 --- a/tests/test_graphplan.py +++ b/tests/test_graphplan.py @@ -32,7 +32,19 @@ def test_logistics_manual(): assert P.goal_test() == False P.act(expr('PutDown(R1, C3, D3)')) assert P.goal_test() == True - + +def test_double_tennis_manual(): + p = double_tennis_problem() + + assert not p.goal_test() + p.act(expr('Go(A, RightBaseLine, LeftNet)')) + assert not p.goal_test() + p.act(expr('Hit(A, Ball, RightBaseLine)')) + assert not p.goal_test() + p.act(expr('Go(A, LeftBaseLine, RightBaseLine)')) + assert not p.goal_test() + p.act(expr('Go(B, LeftNet, RightNet)')) + assert p.goal_test() def test_generalized_blocksworld_manual(): @@ -87,6 +99,10 @@ def test_socks_and_shoes(): P = socks_and_shoes() verify_solution(P) +def test_have_cake_and_eat_cake_too(): + P = have_cake_and_eat_cake_too() + verify_solution(P) + @pytest.mark.parametrize("goal_state", [ "In(C1, D1)", "In(C1, D2)", @@ -194,7 +210,7 @@ def test_rush_hour_optimized(): verify_solution(P) -def test_planner_handles_failure_gracefully(): +def test_planner_leveloff(): def run_planner_in_queue(problem, queue): queue.put(Linearize(problem).execute()) @@ -212,44 +228,35 @@ def run_planner_in_queue(problem, queue): if proc.is_alive(): proc.terminate() proc.join() - assert False + assert False # Ran for 3 seconds and didn't exit in leveloff else: result = result_queue.get() - breakpoint() assert result is None or result == [] or result == [[]] - -def impossible_cake_problem(): - """ - An impossible planning problem to demonstrate GraphPlan's level-off detection. - - The goal is to both Have(Cake) and Eaten(Cake). However, the only available - action, Eat(Cake), has the effect of ~Have(Cake). The propositions - Have(Cake) and Eaten(Cake) will become mutually exclusive at the first - level, and the graph will quickly level off, proving the goal is unreachable. - """ - return PlanningProblem( - initial='Have(Cake) & ~Eaten(Cake)', - goals='Have(Cake) & Eaten(Cake)', - actions=[ - Action('Eat(Cake)', - precond='Have(Cake)', - effect='Eaten(Cake) & ~Have(Cake)') - ] - ) - -def test_impossible_cake_exits_early(): +def test_impossible_cake_exits_via_leveloff(): """ Verify that GraphPlan terminates and returns None for the impossible cake problem. """ - problem = impossible_cake_problem() - # For an impossible problem that levels off, execute() should return None. - solution = GraphPlan(problem).execute() - - print(f"\nTesting impossible_cake_problem...") - if solution is None: - print("SUCCESS: The algorithm correctly determined the problem is unsolvable and leveled off.") - else: - print(f"FAILURE: A solution was found, which should be impossible. Solution: {solution}") + def impossible_cake_problem(): + """ + An impossible planning problem to demonstrate GraphPlan's level-off detection. + + The goal is to both Have(Cake) and Eaten(Cake). However, the only available + action, Eat(Cake), has the effect of ~Have(Cake). The propositions + Have(Cake) and Eaten(Cake) will become mutually exclusive at the first + level, and the graph will quickly level off, proving the goal is unreachable. + """ + return PlanningProblem( + initial='Have(Cake) & ~Eaten(Cake)', + goals='Have(Cake) & Eaten(Cake)', + actions=[ + Action('Eat(Cake)', + precond='Have(Cake)', + effect='Eaten(Cake) & ~Have(Cake)') + ] + ) + + problem = impossible_cake_problem() + solution = Linearize(problem).execute() assert solution is None \ No newline at end of file diff --git a/tests/test_planning.py b/tests/test_planning.py index 24f019099..c24f13174 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -514,9 +514,12 @@ def test_double_tennis(): p = double_tennis_problem() assert not goal_test(p.goals, p.initial) - solution = [expr('Go(A, RightBaseLine, LeftBaseLine)'), - expr('Hit(A, Ball, RightBaseLine)'), - expr('Go(A, LeftNet, RightBaseLine)')] + solution = [ + expr('Go(A, RightBaseLine, LeftNet)'), + expr('Hit(A, Ball, RightBaseLine)'), + expr('Go(A, LeftBaseLine, RightBaseLine)'), + expr('Go(B, LeftNet, RightNet)') + ] for action in solution: p.act(action) From dabd9bd6a02186b276e5ff07a31fc70d9b4fd6ef Mon Sep 17 00:00:00 2001 From: carwyn987 Date: Mon, 6 Oct 2025 10:44:25 -0400 Subject: [PATCH 19/19] Remove lingering print statement --- planning.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/planning.py b/planning.py index 8679810d7..35c2ef70d 100644 --- a/planning.py +++ b/planning.py @@ -788,8 +788,6 @@ def check_leveloff(self): prev_mutex = set(frozenset(m) for m in prev_level.state_mutexes) same_mutex = level_mutex == prev_mutex - print(f"leveloff, state_equality={same_state}, mutex_equality={same_mutex}, level_m_size={len(level_mutex)}, prev_level_m_size={len(prev_mutex)}") - return same_state and same_mutex def _get_preconditions_for(self, action_set, level):