Memra

Planning: STRIPS & the frame problem

Planning as state-space search; STRIPS precondition/add/delete operators and the STRIPS assumption that solves the frame problem.

Planning is state-space search

Planning finds a *sequence of actions* that turns a start state into a goal state — which is exactly state-space search: states are world descriptions, operators are actions, and a plan is a solution path. So BFS, DFS, and A\* from Modules 3–4 all apply. What is new is that a state is no longer an atomic symbol but a *collection of predicates* about the world (e.g. on(C,A), clear(B), handempty), and that creates a hard problem.

The frame problem

When an action changes part of the world, a planner must know which parts *stay the same*. Naively you would write a frame axiom for every (action, predicate) pair that does not change — *"unstacking C from A does not change the colour of the table, the lighting, B's position..."* The number of such axioms blows up. This is the frame problem: representing the non-effects of actions is exponentially expensive.

STRIPS operators solve it

STRIPS represents each operator with three lists:

- Preconditions — what must be true to apply it. - Add list — predicates it makes true. - Delete list — predicates it makes false.

The STRIPS assumption is the key trick: *any predicate not in the add or delete list is assumed unchanged.* That single convention replaces all the frame axioms — you specify only what an action *changes*, and everything else persists automatically. For example:

unstack(X, Y):
  pre:    on(X,Y), clear(X), handempty
  add:    holding(X), clear(Y)
  delete: on(X,Y), clear(X), handempty

Everything not mentioned (the table, other blocks) simply carries over. This is the closed-world assumption applied to *change*.

Worked example — blocks-world plan by BFS

Start with C on A, and A, B on the table; goal on(B, A). We BFS over states, applying every legal STRIPS operator and never revisiting a state. The planner must first clear A (which is blocked by C) before it can stack B:

unstack(C,A) → putdown(C) → pickup(B) → stack(B,A)

Notice the planner *discovers* it must move C out of the way: that interaction between subgoals (clearing A is a precondition of the real goal) is the non-linearity that makes planning harder than plain search. The Python below runs this exact search and prints the plan.

NORMAL ~/memra/learn/comp-456/strips-planning-frame-problem utf-8 LF