% A SIMPLE STRIPS PLANNER USING STRIPS NOTATION

%achieve(Gs,S0,S1,U0,U1) is true if goal G can be
%   achieved  going from state S0 to state S1.
% U0 is the bound on the number of actions going into achieve_all 
%   and U1 is the limit coming out

achieve(true,S,S,U,U).
achieve((A & B),S0,S2,U0,U2) <-
   achieve(A,S0,S1,U0,U1) &
   achieve(B,S1,S2,U1,U2).
achieve(H,S0,S1,U0,U1) <-          % derived predicate
   (H <= B) &
   achieve(B,S0,S1,U0,U1).
achieve(A \= B,W,W,U,U) <-         % inequality constraints
   A \= B.
achieve(G,W,W,U,U) <-              % goals already true
   primitive(G) &
   true_in(G,W).
achieve(G,W0,do(Act,W1),U0,U2) <-  % primitive relations
   primitive(G) &
   U0>0 &
   U1 is U0-1 &
   addlist(Act,AL) &
   member(G,AL) &
   preconditions(Act,PreAct) &
   achieve(PreAct,W0,W1,U1,U2).

% true_in(Goal,State) is true if primitive Goal is true in State.
true_in(G,init) <-
   holds(G,init).
true_in(G,do(A,_)) <-
   addlist(A,AL) &
   member(G,AL).
true_in(G,do(A,S)) <-
   deletelist(A,DL) &
   notin(G,DL) &
   true_in(G,S).

% member(E,L) is true if E is a member of list L
member(E,[E|R]).
member(E,[H|R]) <-
   member(E,R).

% notin(E,L) is true if E is not a member of list L
notin(E,[]).
notin(E,[H|R]) <-
   E \= H &
   notin(E,R).

% TRY THE FOLLOWING QUERIES with delrob_strips.pl:
% ask achieve(carrying(rob,k1),init,S,10,_).
% ask achieve(at(k1,lab2),init,S,6,N).
% ask achieve(carrying(rob,parcel)& sitting_at(rob,lab2),init,S,10,N).
% ask achieve(sitting_at(rob,lab2) & carrying(rob,parcel),init,S,10,N).
%    is the plan returned correct?
