
/* una soluzione diretta del problema del mondo dei blocchi */ 


/* base di dati / situazione iniziale) */

is_on(a,b).
is_on(b,table).
is_on(c,table).

/* un oggetto (blocco o tavoilo e` libero) */

is_free(table).
is_free(Blk) :- not(is_on(_Any_BlK,Blk)).

/* free libera un blocco */
/* un solo blocco da spostare */
free(Blk) :- is_on(Any_Blk,Blk),
             put_on(Any_Blk,table). 
/* due blocchi da spostare */
free(Blk) :- is_on(Any_Blk,Any_Blk),
             is_on(Other_Blk,Blk), 
             put_on(Other_Blk,table),
             put_on(Any_Blk,table). 

/* aggiorna Base di conoscenza */

aggiorna_db(Blk1,Blk2) :-
   retract(is_on(Blk1,_Actual_Position)),
   assert(is_on(Blk1,Blk2)),
   write(sposta(Blk1 -> Blk2)), nl.

/* mette Blk1 su Blk2 - entrambi devono essere liberi */


put_on(Blk1,Blk2):-
     is_free(Blk1),
     is_free(Blk2),
     aggiorna_db(Blk1,Blk2).


/* mette Blk1 su Blk2 */

on(X,Y) :- is_on(X,Y).

on(X,table) :- put_on(X,table).
on(X,table) :- free(X),
               put_on(X,table).

on(X,Y) :- put_on(X,Y).
on(X,Y) :- free(X),put_on(X,Y).
on(X,Y) :- free(X), free(Y), 
           put_on(X,Y).

goal(A,B,C) :- 
               write('Stato Iniziale'), nl,
               listing(is_on),nl,
               write('Mosse'),nl,
               on(C,table),
               on(B,c),
               on(A,b). 

/*   esempio di esecuzione


12 ?- goal(a,b,c).

sposta((a -> table))
sposta((b -> c))
sposta((a -> b))

Yes



*/
