
%%%%% definizioni necessarie per la rappresentazione di un dominio

%%%%%%%%%%%%%%% direttive iniziali

:- [golog_swi].

%%% direttive discontiguous per i fluenti
%%% esempio
%%%% :- discontiguous currentFloor/2, on/2.
:- discontiguous atR/3, at/3.

%%%%%%%%%%% dichiarazione delle azioni primitive
%% esempio
%%% primitive_action(move(_,_)).
primitive_action(move(_,_,_)).
primitive_action(prende(_,_,_)).
primitive_action(lascia(_,_,_)).


%%%%%% Restore suppressed situation arguments.
%% (un fatto per ogni fluente).
%% esempio
%% restoreSitArg(on(X,Y),S,on(X,Y,S)).
restoreSitArg(atR(R,P),S,atR(R,P,S)).
restoreSitArg(at(X,Y),S,at(X,Y,S)).

%%%%%%% definizione di eventuali predicati statici
%% esempio
%% top(10).
connesso(X,corridoio):- stanza(X).
connesso(corridoio,X) :- stanza(X).
connesso(X,Y) :-
	stanza(X), stanza(Y),
	(X is Y+2 ; X is Y-2).
robot(pippo). robot(pluto).
stanza(X) :- member(X,[1,2,3,4,5,6]).
oggetto(X) :- member(X,[libro,quaderno, penna, matita, cellulare, lampada]).

%%%%%%% Action precondition axioms
%% esempio
%%% poss(move(X,Y),S) :- clear(X,S), clear(Y,S), not(X = Y).
poss(move(R,X,Y),S) :-
	atR(R,X,S), connesso(X,Y).
poss(prende(R,X,P),S) :-
	atR(R,P,S), at(X,P,S).
poss(lascia(R,X,P),S) :-
	atR(R,P,S), at(X,R,S).

%%%%%%% Successor state axioms
%% esempio
%% on(X,Y,do(A,S)) :- A = move(X,Y) ;
%%                   on(X,Y,S), not(A = moveToTable(X)), not(A = move(X,_)).
atR(R,P,do(A,S)) :-
	A=move(R,_,P) ;
	atR(R,P,S), \+ A=move(R,P,_).
at(X,Y,do(A,S)) :-
	A=prende(Y,X,_); A=lascia(_,X,Y);
	at(X,Y,S), \+ (A=prende(_,X,Y); A=lascia(Y,X,_)).

%%%% Initial situation
%% esempio
%% on(b,c,s0). on(c,a,s0). on(a,d,s0). ontable(d,s0). clear(b,s0).
atR(X,1,s0) :- robot(X).
at(X,4,s0) :- oggetto(X).

%%% Sintassi del Golog
%%% sequenze di azioni: A1 : A2
%%% test: ?(Formula)
%%%         congiunzione: F & G
%%%         disgiunzione: F v G
%%%         implicazione: F => G
%%%         doppia implicazione: F <=> G
%%%         negazione: - F
%%%         quantificatore universale: all(V,F)
%%%         quantificatore esistenziale: some(V,F)
%%% scelta non deterministica di due azioni: A1 # A2
%%% if-then-else: if(Cond,A1,A2)
%%% ciclo: while(Cond,A)
%%% scelta non deterministica dell'argomento di un'azione:
%%%             pi(x,A)
%%% procedure: proc(Testa,Corpo)
%%%          parametri della procedura: variabili prolog

%% procedura ausiliaria che sposta il robot R nel posto P
proc(va(R,P),
     ?(atR(R,P)) #
    (?(-atR(R,P)):
    pi(p,?(atR(R,p)):
       (move(R,p,P) # (move(R,p,corridoio):move(R,corridoio,P)))))).

%%% si assume che R non abbia X in mano

proc(porta(R,X,P),
     at(X,P) #
     (?(-at(X,P)):
     pi(x, ?(at(X,x)):va(R,x):
       prende(R,X,x) :
       va(R,P) : lascia(R,X,P)))).

%% predicato di utilita'
/* da una situazione ==> lista di azioni */
esegui(A,L) :-
	do(A,s0,S),
	azioni(S,L).
azioni(s0,[]).
azioni(do(A,S),L) :-
	azioni(S,L1),
	append(L1,[A],L).

	 
	 