
    %  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 */

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

/* Goal                a
                       b       */

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

%  Good towers.

goodTower(a,S) :- ontable(b,S).
goodTower(b,S) :- on(a,b,S), goodTower(b,S).

/*
?- goal(S).
S = do(moveToTable(b), do(move(a, b), do(move(b, a), _G241)))
*/

/* definizione dei piani come sequenze di azioni */

:- op(950, xfy, [:]).   /* Action sequence */

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).

/*
?- solution_plan(P).
P = move(a, b)
*/

