Skip to content

Conversation

carwyn987
Copy link

@carwyn987 carwyn987 commented Oct 5, 2025

TL;DR Fixed GraphPlan algorithm. Changes were made to mutex calculation, representation of state vs actions, linearization. A test suite was added to comprehensively test the algorithm, which passes. These updates do not break any of the other tests.


Notable Changes / Additions

check_leveloff Function

The function used to compute whether the search has leveled off (i.e. stagnated) only checked that the current and prior state were equivalent, but failed to check the state mutexes for equivalency - a necessary condition.

  • This function has been updated to include mutex checks.

No Interference Computation

In the original implementation, Interference (one action deletes the precondition of another) seems to be ignored in our mutex calculations.

  • I have added interference explicitly.

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.

  • I repurposed the planning code to differentiate explicitly between state and action mutexes. This more directly follows from the literature and learner perspective, and is necessary for leveloff calculations.

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.

Expanded GraphPlan tests

Currently tests are more focused on the environments than the algorithm. I've added a set of tests for GraphPlan to ensure functionality.

  • I've created a pytest file and added it to the test dir to improve reliability (and for my own debugging)

Fixes to the double tennis environment

Original env used a, b in goals rather than A, B as defined in initial.
-Lowercase variables (e.g. a and b) can be satisfied by any other variable, so the original test did pass with this formulation, but it likely was not the intention of the original authors.

  • Environment failed to search LeftNet because it doesn't show up in initial or domain, only goal. It seems like all objects must exist within either the initial state or domain for the algorithm to search them.
  • These have been updated.

Potential Future Issues Identified

Extract_Solution Issue

extract_solution is a method with the purpose of expanding the graph backwards from the goal state to the start state, identifying sub-goals for each layer along the way, and selecting a set of actions that fulfill this layers sub-goals, proceeding to the prior layer with the preconditions of those actions as new sub-goals. However, the authors wrote this implementation with itertools.product(*actions) (Cartesian product), which chooses combinations of specifically one action that satisfies each goal. I'm not sure that this is theoretically guaranteed to identify a solution if one exists. However, the alternative of computing the cartesian product on all sets of actions that satisfy the goals (not just one action for each goal) is intractable with respect to compute resources.

Memoization Improvement

In extract_solution, we use memoization to avoid searching for solutions to sub-problems that have already been proven unsolvable. However, we use an equality check, and do not consider solutions that are a superset of this subproblem. Adding this check could improve performance.

Screenshots of tests:

Screenshot from 2025-10-06 11-09-38 Screenshot from 2025-10-06 11-10-10

Note - the two failing tests are not related to this PR or GraphPlan. These are not caused to fail from these modifications, they fail for me on a bare-bones clone. This proves to show that all relevant existing tests pass (i.e. tests/test_planning.py), are not damaged by these updates, and the new GraphPlan test file tests/test_graphplan.py passes.

…opriate 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).
… 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.
…ut tests seem to pass??? Not sure if actually correct or my drowsiness is making it look like greeon on my screen
…set of possible action tuples for each goal (but implemented efficiently with DFS recursive early-exit search
…ring_and_compute_prop_mutexes_on_expand_graph

Experimental/revert ordering and compute prop mutexes on expand graph
…alence between prior layers. Furthermore, my mutex handling of overwriting with state mutexes causes this to fail anyway
…ion. Made previous tests coherent with updates
@carwyn987 carwyn987 marked this pull request as ready for review October 6, 2025 15:14
@carwyn987 carwyn987 marked this pull request as draft October 6, 2025 15:16
@carwyn987 carwyn987 marked this pull request as ready for review October 6, 2025 15:17
@carwyn987
Copy link
Author

Not sure how to add reviewers, so I'll @ people here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant