Interleaving Vs. Non-interleaving Of Sub-plan Steps
Interleaving vs. Non-Interleaving of Sub-Plan Steps: Given a conjunctive goal, G1 ^ G2, if the steps that solve G1 must either all come before or all come after the steps that solve G2, then the planner is called a non-interleaving planner. Otherwise, the planner allows interleaving of sub-plan steps. This constraint is different from the issue of partial-order vs. total-order planners. STRIPS is a non-interleaving planner because of its use of a stack to order goals to be achieved.
	Partial-Order Planner (POP) Algorithm
	function pop(initial-state, conjunctive-goal, operators)
	// non-deterministic algorithm
	plan = make-initial-plan(initial-state, conjunctive-goal);
	loop:
	begin
	if solution?(plan) then return plan;
	(S-need, c) = select-subgoal(plan) ; // choose an unsolved goal
	choose-operator(plan, operators, S-need, c);
	// select an operator to solve that goal and revise plan
	resolve-threats(plan); // fix any threats created
	end
	end
	function solution?(plan)
	if causal-links-establishing-all-preconditions-of-all-steps(plan)
	and all-threats-resolved(plan)
	and all-temporal-ordering-constraints-consistent(plan)
	and all-variable-bindings-consistent(plan)
	then return true;
	else return false;
	end
	function select-subgoal(plan)
	pick a plan step S-need from steps(plan) with a precondition c
	that has not been achieved;
	return (S-need, c);
	end
	procedure choose-operator(plan, operators, S-need, c)
	// solve "open precondition" of some step
	choose a step S-add by either
	Step Addition: adding a new step from operators that
	has c in its Add-list
	or Simple Establishment: picking an existing step in Steps(plan)
	that has c in its Add-list;
	if no such step then return fail;
	add causal link "S-add --->c S-need" to Links(plan);
	d temporal ordering constrainS-add < S-need" to Orderings(plan);
	adt " if S-add is a newly added step then
	begin
	add S-add to Steps(plan);
	add "Start < S-add" and "S-add < Finish" to Orderings(plan);
	end
	end
	procedure resolve-threats(plan)
	foreach S-threat that threatens link "Si --->c Sj" in Links(plan)
	begin // "declobber" threat
	choose either
	Demotion: add "S-threat < Si" to Orderings(plan)
	or Promotion: add "Sj < S-threat" to Orderings(plan);
	if not(consistent(plan)) then return fail;
	end
end
Plan Modification Operations: The above algorithm uses four basic plan modification operations to revise a plan, two for solving a goal and two for fixing a threat:
- Establishment -- "Solve an Open Precondition" (i.e., unsolved goal) If a precondition p of a step S does not have a causal link to it, then it is not yet solved. This is called an open precondition. Two ways to solve:
o Simple Establishment Find an existing step T prior to S in which p is necessarily true (i.e., it's in the Effects list of T). Then add causal link from T to S.
o Step Addition Add a new plan step T that contains in its Effects list p. Then add causal link from T to S.
- Declobbering -- Threat Removal A threat is a relationship between a step S3 and a causal link S1 --->p S2, where p is a precondition in step S2, that has the following form:
- -------> S1 --------->p S2 |
- | -------> S3 ~p
	That is, step S3 has effect ~p and from the temporal links could possibly occur in-between steps S1 and S2, which have a causal link between them. If this occurred, then S3 would "clobber" the goal p "produced" by S1 before it can be "consumed" by S2. Fix by ensuring that S3 cannot occur in the "protection interval" in between S1 and S2 by doing either of the following:
	Promotion Force threatening step to come after the causal link. I.e., add temporal link S2 < S3.
	Demotion Force threatening step to come before the causal link. I.e., add temporal link S3 < S1.