
:- [golog_swi,util].

%% dichiarazioni discontiguous per i fluenti
:- discontiguous at/3, on/3.

% Restore suppressed situation arguments.
restoreSitArg(at(X,Y),S,at(X,Y,S)).
restoreSitArg(on(X,Y),S,on(X,Y,S)).

% Dichiarazione azioni primitive
primitive_action(drive(_,_,_,_)).
primitive_action(go(_,_,_)).
primitive_action(geton(_,_,_)).
primitive_action(getoff(_,_,_)). 

% Preconditions for Primitive Actions.
poss(drive(R,V,X,Y),S) :-
	robby(R), vehicle(V), loc(X), loc(Y),
	on(R,V,S), at(V,X,S), \+ X=Y.
poss(go(R,X,Y),S) :-
	robby(R), loc(X), loc(Y),
	at(R,X,S), \+ X=Y.
poss(geton(R,V,X),S) :-
	robby(R), vehicle(V), loc(X),
	at(R,X,S), at(V,X,S), \+ on(_,V,S). % veicolo vuoto
poss(getoff(R,V,X),S) :-
	robby(R), vehicle(V), loc(X),
	at(V,X,S), on(R,V,S).

% Successor State Axioms for Primitive Fluents.
at(X,Y,do(A,S)) :-
	(A=drive(_,X,_,Y);
	    A=go(X,_,Y); A=getoff(X,_,Y));
	(at(X,Y,S),
	    \+ (A=drive(_,X,Y,_);
		   A=go(X,Y,_); A=geton(X,_,Y))).
on(R,V,do(A,S)) :-
	A=geton(R,V,_) ;
	(on(R,V,S), \+ A=getoff(R,V,_)).

% Stato iniziale
at(car,centro,s0).
at(truck,stazione,s0).
at(r1,aereoporto,s0).
at(r2,stazione,s0).
at(r3,stazione,s0).

% predicati statici per tipizzare gli oggetti
robby(r1). robby(r2). robby(r3).
vehicle(car). vehicle(truck).
loc(stazione). loc(aereoporto). loc(centro).
loc(periferia).

% procedura sposta
%% sottoprocedura: fa salire il robot R sul veicolo V
proc(faisalire(R,V),
     ?(on(R,V)) #
    /* il robot puo' essere gia' nel posto in cui si trova il veicolo
       oppure no. Possiamo distinguere i due casi esplicitamente:
       pi(x, ?(at(V,x)) : geton(R,V,x) #
            pi(y, go(R,y,x)): geton(R,V,x))).
       oppure utilizzare la ripetizione di 0 o piu' volte: */
    pi(x, ?(at(V,x)) :
      pi(y, star(go(R,y,x))): geton(R,V,x))).

proc(sposta(V,X),
     pi(r, faisalire(r,V) :
           pi(x,drive(r,V,x,X)) :
           getoff(r,V,X))).

% procedura spostatutti
proc(spostatutti(Dest),
     % sposta i veicoli
     while(some(v,vehicle(v) & -at(v,Dest)),
	   pi(v,sposta(v,Dest))) :
     % fa scendere i robot che si trovano su veicoli in Dest
    while(some(r,robby(r) & some(v,on(r,v) & at(v,Dest))),
	  pi(r,pi(v,getoff(r,v,Dest)))) :
    % gli altri robot vanno a piedi
    while(some(r,robby(r) & -at(r, Dest)),
	  pi(r,pi(x,go(r,x,Dest))))).
