Plan-Space Planning and Partial-Order Planning (POP)

Search over partial plans, not states — causal links, threats, promotion/demotion, and the elegant answer to the Sussman anomaly

The Simplest Explanation

Goal-stack planning forces a goal order and stumbles on the Sussman anomaly. Plan-space planning refuses to commit:

Search the space of partial plans. A plan is finished only when it has no flaws — unresolved goals or unhandled threats. Ordering constraints get added only when a threat forces them.

Remember This

Π = ⟨A, O, L, B⟩: Actions, Orderings, causal Links, Bindings. Two flaw types: open goals (unsupported preconditions) and threats (actions that might delete a protected fact). Solve flaws until none remain.

The Partial Plan Tuple

ComponentMeaning
AApartially instantiated operators (variables written ?x)
OOordering links ai≺aja_i \prec a_j
LLcausal links ai→paja_i \xrightarrow{p} a_j — "aia_i guarantees p for aja_j"
BBbinding constraints (?x=A?x = A, ?x≠?y?x \neq ?y)

Initial plan Π0\Pi_0: just two dummy actions —

  • a0a_0: no preconditions; effects = start state
  • a∞a_\infty: preconditions = goal; no effects

plus one ordering a0≺a∞a_0 \prec a_\infty. This "empty plan" compactly represents every possible linear plan at once.

Flaws and Their Repairs

FlawDefinitionRepairs
Open goalprecondition p of aja_j unsupported by any causal linkreuse an existing producer (add link + order), or insert a new action that adds p
Threataction ata_t deletes p on link ai→paja_i \xrightarrow{p} a_j and could be ordered between themPromotion at≺aia_t \prec a_i, Demotion aj≺ata_j \prec a_t, or Separation (variable binding)

Worked Example (the lecture's full trace)

Start: On(B,C), OnTable(C), OnTable(A), Clear(A), Clear(B), ArmEmpty. Goal: OnTable(B) ∧ On(A,B).

  1. Π0\Pi_0: two open goals — OnTable(B), On(A,B)
  2. Resolve On(A,B): insert Stack(A,B) → new open goals Holding(A), Clear(B); link Stack →On(A,B)a∞\xrightarrow{On(A,B)} a_\infty
  3. Clear(B): true in start → link a0→Clear(B)a_0 \xrightarrow{Clear(B)} Stack(A,B)
  4. Holding(A): insert Pickup(A) (A is on table) → opens OnTable(A), Clear(A), ArmEmpty — all satisfied by links from a0a_0
  5. OnTable(B): insert Putdown(B) → opens Holding(B)
  6. Holding(B): insert Unstack(B,C) → its preconditions all from a0a_0

Now all goals closed — but three threats appear:

ThreatThreatenerEndangered link
T1Stack(A,B) deletes Clear(B)a0→Clear(B)a_0 \xrightarrow{Clear(B)} Unstack(B,C)
T2Pickup(A) deletes ArmEmptya0→ArmEmptya_0 \xrightarrow{ArmEmpty} Unstack(B,C)
T3Putdown(B) deletes ArmEmptya0→ArmEmptya_0 \xrightarrow{ArmEmpty} Pickup(A)

All resolved by demotion (push threat after consumer):

Unstack(B,C)≺Stack(A,B),Unstack(B,C)≺Pickup(A),Putdown(B)≺Pickup(A)\text{Unstack(B,C)} \prec \text{Stack(A,B)}, \quad \text{Unstack(B,C)} \prec \text{Pickup(A)}, \quad \text{Putdown(B)} \prec \text{Pickup(A)}

Linearizing yields the 4-step plan: Unstack(B,C) → Putdown(B) → Pickup(A) → Stack(A,B).

Why This Beats Goal Stack Here

GSP would chase OnTable(B) first or On(A,B) first and clobber itself (Sussman pattern). POP never chose an order — the threats themselves discovered that Unstack(B,C) must precede both other actions. Non-serializable subgoals are handled naturally.

Properties

PropertyValue
Search spacepartial plans (usually smaller than state spaces)
Soundnessyes — every step's preconditions protected by causal links
Non-serializable goalshandled via interleaving forced by threats
Least-commitmentorderings exist only where conflicts demand them
QuizAn 'open goal' in POP is...
QuizA threat exists when action a_t...