Classical Planning
Classical planning represents a problem in a factored language, PDDL: states are sets of ground fluents, and actions are lifted schemas with a precondition and an effect. That structure turns planning into search — forward through states or backward through goals — and lets a program read heuristics straight off the schemas by relaxing the problem.
╌╌╌╌
We have already met two agents that choose their actions by looking ahead. The search agent finds a sequence of actions leading to a goal, but it works over atomic states — opaque labels with no internal parts — so it needs a hand-built heuristic to move well. The logical agent of first-order logic reasons about the structure of the world, but inference over ground sentences gets swamped once there are many objects and time steps. Classical planning keeps the best of each: a representation structured enough that a program can derive its own heuristics, yet restricted enough that search stays tractable.1
The difference is the factored representation. Instead of naming each state, we describe it by a collection of variables — which cargo is where, which plane is at which airport — and describe each action by the small set of variables it changes. A single action schema then stands for thousands of ground actions, and a program can inspect that schema and reason about it. This lesson covers fully observable, deterministic, static environments with a single agent; uncertainty and multiple agents come later.
The PDDL representation
Planning problems are written in PDDL, the Planning Domain Definition Language. PDDL specifies the four things a search needs: the initial state, the actions available in a state, the result of applying an action, and the goal test.2
A state is a conjunction of fluents that are ground, functionless atoms — for example, . Three conventions keep states finite and unambiguous. The closed-world assumption says any fluent not mentioned is false. The unique-names assumption says distinct constant names denote distinct objects. And a state may be read two ways: as a conjunction to be manipulated by logical inference, or as a set of fluents to be manipulated by set operations — the set semantics is often easier. Certain fluents are barred: is not allowed (non-ground), nor is (a negation), nor (a function symbol).
Actions are described by action schemas. A schema is a lifted representation — it lifts reasoning from propositional logic up to a restricted fragment of first-order logic — consisting of an action name, the variables it uses, a precondition, and an effect:
An action is applicable in a state when entails the precondition: . Formally, , where the variables in are treated as universally quantified, free to be instantiated to any objects. A schema with variables in a domain with object names has possible ground instantiations, which is why we keep it lifted rather than enumerating them.
The result of executing an applicable action in is defined by removing the fluents that appear as negative literals in the effect (the delete list, ) and adding those that appear as positive literals (the add list, ):
This is the classical answer to the frame problem. The schema mentions only what changes; everything the effect does not touch is assumed to stay the same, so we never have to write down the vast list of facts that an action leaves alone. A requirement of every schema is that any variable in the effect also appears in the precondition, so once the precondition is matched against a ground state, all variables are bound and produces only ground atoms.
A set of schemas defines a planning domain; adding an initial state (a conjunction of ground atoms) and a goal (a conjunction of literals, possibly with variables read existentially) defines a specific problem. The problem is solved by any sequence of actions ending in a state that entails the goal.
Example: air cargo transport
The air cargo domain moves cargo between airports by loading it onto planes, flying, and unloading. Two predicates carry the state: (cargo is inside plane ) and (object , plane or cargo, is at airport ). Three schemas act on them.
Some care is needed so the predicates stay correct: when a plane flies, the
cargo inside it goes along, but basic PDDL has no universal quantifier to say so.
Instead, cargo ceases to be anywhere while it is a plane, and
becomes the new airport only when unloaded — so means available for use at a given location.
For the problem with cargo at SFO bound for JFK and
at JFK bound for SFO, one solution is
Example: the blocks world
The blocks world is one of the oldest planning domains: cube-shaped blocks on a
table, stackable one atop another, moved by a robot arm that lifts one block at a
time. We write for block resting on (a block or the table). Since
PDDL has no quantifier to say nothing is on ,
we introduce a predicate
, true when has a clear space to hold a block. The schema
slides a block from to when both and are clear; a companion
handles moving a block onto the table, so that is maintained
correctly when the table is involved.3
The delete list carries the bookkeeping here. adds and , and deletes and — the block leaves its old support (which becomes clear) and covers its new one (which stops being clear). The figure below shows the state transition on a three-block tower.
The complexity of planning
Two decision problems fix the difficulty. PlanSAT asks whether any plan solves a problem; Bounded PlanSAT asks whether one of length or less exists (useful for finding optimal plans). Both are decidable for classical planning because the number of states is finite — but add function symbols and the state space becomes infinite, at which point PlanSAT is only semidecidable. Both problems sit in PSPACE, harder than NP. Even severe restrictions barely help: disallowing negative effects keeps both NP-hard, though also disallowing negative preconditions drops PlanSAT to P.
These worst-case results are less discouraging than they sound. Agents are rarely asked to plan for arbitrary instances; they face specific domains — blocks world, air cargo — that are often far easier than the theoretical worst case. For many such domains Bounded PlanSAT is NP-complete while PlanSAT is in P, so finding some plan is easy and finding an optimal one is the hard part. Good heuristics matter most in that gap, and this is the advantage of the classical formalism: its structured representation has enabled very accurate domain-independent heuristics, where logic-based successor-state systems have had much less success.
Planning as state-space search
A planning problem is a search problem: an initial state, an function, a function, and a goal test. The declarative schema representation additionally lets us search from either end — forward from the initial state toward a goal, or backward from the goal toward the initial state.
Forward (progression) search
Forward search maps a planning problem onto any of the heuristic search algorithms we already have — A*, for example — provided we record the actions used to reach each state. It was long assumed impractical, for two reasons.
First, forward search explores irrelevant actions. To buy a copy of a book from an online seller, the domain might have a schema with effect ; with ten-digit ISBNs that is ten billion ground actions, and an uninformed forward search would start enumerating all of them. Second, planning problems have huge state spaces. In an air cargo problem with 10 airports, each holding 5 planes and 20 pieces of cargo (50 planes and 200 packages in all), the average branching factor runs to roughly 2000 actions per state: every plane can fly to any of 9 other airports, and every one of 200 packages can be loaded or unloaded. The search graph down to the obvious solution has on the order of nodes.
Even this modest instance is hopeless without an accurate heuristic. Forward search is practical because strong domain-independent heuristics can be derived automatically — the subject of the next section.
A forward-search trace
For example, run forward search by hand on a two-plane air-cargo instance small enough to follow completely. The objects are two planes , two cargoes , and two airports . The initial state is
together with the static facts , which no action ever changes. The goal is : swap the two cargoes. At each step we apply the three schemas from the air-cargo domain and, guided by a heuristic that prefers actions moving a cargo toward its destination, commit to one action. The static facts are omitted from each state below since they never change.
The trace runs six actions deep. Starting from , is applicable because and both hold; applying it deletes and adds . The chosen sequence and the resulting states:
The trace shows two details. When fires between and , the cargo inside has no fluent at all — it is recorded only by — so nothing needs to be said about carrying it along; this is the / encoding from the domain definition. And the goal is tested by entailment, not equality: contains four fluents but the goal names only two, and holds regardless of where the planes ended up. A heuristic that miscounts here — say, one that ignored the two steps as irrelevant — would still find this plan, because forward search commits to whole actions and checks applicability at every step.
Backward (regression) relevant-states search
Backward search — also called relevant-states search — starts at the goal and applies actions in reverse until it reaches the initial state. As in belief-state search, each node is a set of states, described by a conjunction of literals: the goal describes every state in which is false and is true, with all other fluents free. With ground fluents there are states but descriptions, since each fluent can be positive, negative, or unmentioned.
Backward search only works when we can regress from a state description to its predecessor, and PDDL was designed to make that easy. Given a ground goal description and a ground action , the regression of over is
The effects the action added need not have held before, and the preconditions must have held or the action could not have fired. does not appear: we know those fluents are false after the action, but we can say nothing about whether they held before, so we leave them out.
The actions worth regressing over are the relevant ones — those that could be the last step of a plan reaching the current goal.
To get the full benefit of backward search we regress over partially instantiated actions, not just ground ones. For the goal , the schema regresses to the description , quantifying implicitly over — any plane will do, and we never commit to which. This is the advantage of the lifted representation: one description covers any choice of plane. Backward search keeps the branching factor lower than forward search for most domains, but because it reasons over state sets rather than individual states, good heuristics are harder to come by. That is the main reason most current systems favor forward search.
A backward-search trace
Running regression by hand on the same instance the forward trace used shows the mechanics. Take the two-plane air-cargo problem again — planes , cargoes , airports — with the goal
and work backward, one action at a time, until a description reaches something the initial state already entails. Each node is a conjunction of literals standing for a set of states, and at each step we pick a relevant action — one whose effect supplies a goal literal without deleting another — and regress the goal through it using . We regress over partially instantiated schemas, leaving the plane variable open where the goal does not force it.
Start at . Only two schema instances can produce or as a final step, and neither deletes the other's goal, so both are relevant. Regress over first: it adds , so that literal drops out of the goal and the unload's preconditions come in, quantified over the open plane .
Read the trace from down and each step regresses over the action named on the arrow:
- , over . The action adds (removed from the goal) and requires (added). The static conditions come in too but are omitted here since supplies them for any plane. The plane stays open — the partial instantiation described above.
- , over 's sibling . It supplies and demands , with a second open plane.
- , over . To get we regress the fly: its effect leaves, and its precondition enters. is untouched — flying does not disturb loaded cargo — so it rides along.
- , over , symmetrically turning into the requirement .
- , over . Loading adds (leaves) and needs ; the cargo's airport fact enters the description.
- , over , the last regression: leaves and enters.
Now compare against the initial state . The cargo literals and match directly. The two open planes are bound by and : taking and makes entailed by . Search halts, and reading the arrow labels bottom to top recovers a plan,
the same six-action solution the forward trace found, differing only in the order of the two independent steps. The trace shows two things. The plane variables and stay uncommitted for the whole regression and are pinned only at the last matching step, so a single backward path stands in for all ways of assigning the two planes — the branching that forward search would have paid for at . And never enters a regressed description: when is regressed, its delete effect is simply dropped, because the precondition already asserts that holds in the predecessor. The cost is that every node describes a set of states, which is why accurate heuristics — the subject of the next section — are harder to attach here than in the forward direction.
Domain-independent heuristics from relaxed problems
Neither search direction is efficient without a good heuristic estimating the distance from to the goal. From informed search we know that an admissible heuristic — one that never overestimates — is obtained by defining a relaxed problem that is easier to solve, then using its exact solution cost as the heuristic. The informed search lesson invented such relaxations by hand, one clever insight per domain. Planning's factored representation changes that: a program can relax the schemas mechanically, so the heuristic comes for free.
Think of the search space as a graph whose nodes are states and whose edges are actions. There are two ways to make it easier: add edges (so paths get shorter), or merge nodes into an abstraction with fewer states.
Ignore preconditions. The ignore-preconditions heuristic drops every precondition from every action, so each action is applicable in every state and any unsatisfied goal fluent can be achieved in one step (if some action achieves it at all). This almost implies the heuristic is the number of unsatisfied goals, but not quite: one action may achieve several goals, and one action may undo another. Accounting for the first and ignoring the second, we relax further — remove all effects except the goal literals — and count the minimum number of actions whose effects together cover the goal. That is the set-cover problem, which is NP-hard; a greedy approximation runs in polynomial time and comes within a factor of of the true minimum, at the cost of admissibility.
It is also possible to ignore only selected preconditions. For the sliding-block puzzle encoded with a schema, dropping the preconditions gives the misplaced-tiles heuristic; dropping only gives Manhattan distance. Both classic heuristics fall out of the same schema by deleting preconditions — the ease of manipulating schemas is the advantage of the factored representation.
Ignore delete lists. Assume goals and preconditions contain only positive literals. The ignore-delete-lists heuristic removes every negative literal from every effect, so no action ever undoes another's progress. The relaxed problem makes monotonic progress toward the goal: once a fluent becomes true it stays true. Finding the optimal relaxed solution is still NP-hard, but an approximate one is found in polynomial time by hill-climbing, because the relaxed state space has no local minima and no dead ends — a wide, downhill path to every goal.4
A live system built on this idea is FF (FastForward): a forward searcher that computes the ignore-delete-lists heuristic with the help of a planning graph, then runs hill-climbing modified to keep the plan, falling back to iterated deepening when it hits a plateau.
State abstraction. Relaxing the actions does nothing to shrink the number of states, and many problems have of them. A state abstraction is a many-to-one map from ground states to abstract ones. The simplest kind ignores some fluents. In an air cargo problem where all packages happen to share a destination and sit at 5 airports, dropping every fluent except those for one plane and one package at each airport cuts states to about ; the abstract solution is shorter (hence admissible) and extends back to the original by inserting the missing and actions.
Decomposition. A conjunctive goal can be split into subgoals solved independently, their costs combined. Taking the maximum subgoal cost is always admissible. Taking the sum — the subgoal independence assumption — is more accurate but admissible only when the subplans do not interact: it is optimistic when one subplan deletes another's goal, pessimistic when two subgoals share an action. Which combination is safe depends on how the subproblems interact, and planning graphs, next, help estimate that.
Where this continues
The relaxations above — ignore preconditions, ignore delete lists, decompose into subgoals — each give a heuristic, but each can be badly inaccurate, and none of them can estimate how subplans interact. A single data structure does better: a polynomial-size approximation to the problem that both sharpens the heuristic and can be searched directly for a plan.
This continues in Planning Heuristics and GraphPlan, which builds the planning graph, reads an admissible heuristic off its level costs and mutex structure, extracts a plan with GraphPlan, and closes with SATPlan, partial-order planning, and the central trade-off of classical planning.
Footnotes
- AIMA, Ch. 10 — Classical Planning, introduction and §10.1: planning as a middle ground between atomic-state search and ground first-order inference, on fully observable, deterministic, static, single-agent problems. ↩
- AIMA, §10.1 — Definition of Classical Planning: the PDDL representation, states as conjunctions of ground fluents under closed-world and unique-names assumptions, action schemas with precondition and effect, and the semantics. ↩
- AIMA, §10.1.3 — Example: The Blocks World: the / encoding, the and schemas, and why a predicate substitutes for the missing universal quantifier. ↩
- AIMA, §10.2.3 — Heuristics for Planning: ignore-preconditions (reducing to set cover), ignore-delete-lists (monotonic progress, hill-climbable), selected-precondition relaxations for the sliding-block puzzle, state abstraction, and subgoal decomposition. ↩
╌╌ END ╌╌