
%% direttive iniziali
:- [golog_swi, util].
:- discontiguous atRobby/2, at/3, free/2, carry/3.

%  Primitive Action Declarations.
primitive_action(go(_,_)).    
primitive_action(pick(_,_,_)).    
primitive_action(drop(_,_,_)).    

% restore suppressed situation arguments
restoreSitArg(atRobby(X),S,atRobby(X,S)).
restoreSitArg(at(X,Y),S,at(X,Y,S)).
restoreSitArg(free(X),S,free(X,S)).
restoreSitArg(carry(X,Y),S,carry(X,Y,S)).

%  Action Precondition Axioms.
poss(go(X,Y),S) :-  atRobby(X,S), location(Y), \+ X=Y.
poss(pick(X,Y,Z),S) :- atRobby(Y,S), at(X,Y,S), free(Z,S).
poss(drop(X,Y,Z),S) :- atRobby(Y,S), carry(X,Z,S).

%  Successor State Axioms.
atRobby(X,do(A,S)) :- A = go(_,X) ; (atRobby(X,S), \+ A = go(X,_)).
at(X,Y,do(A,S)) :- A = drop(X,Y,_) ; (at(X,Y,S), \+ A = pick(X,Y,_)).
free(X,do(A,S)) :- A = drop(_,_,X) ; (free(X,S), \+ A = pick(_,_,X)).
carry(X,Y,do(A,S)) :- A = pick(X,_,Y) ; (carry(X,Y,S), \+ A = drop(X,_,Y)).

% static predicates
location(X) :- member(X,[a,b]).
gripper(X) :- member(X,[left,right]).
ball(X) :- member(X,[1,2,3,4,5]).

%  Initial Situation 
atRobby(a,s0).
at(X,a,s0) :- ball(X).
free(X,s0) :- gripper(X).

% procedure
%% vai
proc(vai(To),
     ?(atRobby(To)) #
    pi(x,go(x,To))).
% oppure:
proc(vai_star(To),
     star(pi(x,go(x,To)))).

%% carica
proc(carica(Loc),
     ?(atRobby(Loc)) :
     ?(all(x,gripper(x) => -free(x)) v
      -some(x,ball(x) & at(x,Loc))) #
    pi(g,pi(x,pick(x,Loc,g))) : carica(Loc)).
% oppure:
proc(carica_star(Loc),
    ?(atRobby(Loc)) :
    star(pi(g,pi(x,pick(x,Loc,g)))) :
    ?(all(x,gripper(x) => -free(x)) v
      -some(x,ball(x) & at(x,Loc)))).

%% scarica
proc(scarica(Loc),
     ?(all(x,gripper(x) => free(x))) #
    pi(g,pi(x,drop(x,Loc,g))) : scarica(Loc)).
% oppure
proc(scarica_star(Loc),
     star(pi(g,pi(x,drop(x,Loc,g)))) :
     ?(all(x,gripper(x) => free(x)))).

%% sposta
proc(sposta(From,To),
     ?(-some(x,ball(x) & at(x,From))) #
    vai(From) : carica(From) : vai(To) :
    scarica(To) : sposta(From,To)).
%% La versione con star :
proc(sposta_star(From,To),
     star(vai(From) : carica(From) : vai(To) :
	 scarica(To)) :
    ?(-some(x,ball(x) & at(x,From)))).    
% non va bene, perche' le soluzioni successive alla prima iniziano sempre come
% la prima stessa, e poi proseguono con il robot che va da To a From, poi da
% From a To, poi da To a From ....
%% Questo avviene perche' carica e scarica non falliscono quando non c'e' niente
% da caricare o scaricare.
