    %  Prolog Clauses for a Simple Blocks World

:- discontiguous clear/2,
	on/3,
	ontable/2.

%  Action Precondition Axioms.

poss(move(X,Y),S) :- clear(X,S), clear(Y,S), not(X = Y).
poss(moveToTable(X),S) :- clear(X,S), not(ontable(X,S)).

%  Successor State Axioms.

clear(X,do(A,S)) :- (A = move(Y,_) ; A = moveToTable(Y)), on(Y,X,S) ;
                    clear(X,S), not(A = move(Y,X)).
on(X,Y,do(A,S)) :- A = move(X,Y) ;
                   on(X,Y,S), not(A = moveToTable(X)), not(A = move(X,_)).
ontable(X,do(A,S)) :- A = moveToTable(X) ;
                      ontable(X,S), not(A = move(X,_)).

          %  A Blocks World Problem

/* Initial Situation   a
                       b c */

ontable(b,s0). ontable(c,s0). on(a,b,s0). clear(a,s0). clear(c,s0).

/* Goal                a
                       b
                       c */

goal(S) :- ontable(c,S), on(a,b,S), on(b,c,S), clear(a,S).


/* definizione dei piani come sequenze di azioni */

do(E,S,do(E,S)) :- primitive_action(E), poss(E,S).
do(E1 : E2,S,S1) :- do(E1,S,S2), do(E2,S2,S1).


/* definizione delle azioni primitive per il dominio dei blocchi */
primitive_action(move(_,_)).
primitive_action(moveToTable(_)).

/* ricerca della soluzione */
solution_plan(P) :- do(P,s0,S), goal(S).
