% This is the monkey and bananas as a planning problem,
% using the situation calculus.

% This works with the plan predicate with four moves
% but does not work with bplan, because of the way
% has_bananas is defined.

% The bananas, monkey, and box are at different locations.
% The monkey is not on the box and has no bananas.
initial_state([]).

% A is a possible action to perform in situation S.
legal_move(S,A,[A|S]):- poss(A,S).

% The goal is any state where the monkey has the bananas.
goal_state(S) :- has_bananas(S).

% fluent for the location of the box
location(box,loc3,[]). %initial state clause
location(box,L,[push(L)|_]). % successor state clause
location(box,L,[A|S]) :- \+A=push(_),location(box,L,S). % ss cl.

% fluent for the location of the bananas
location(bananas,loc1,[]). % The initial location
location(bananas,L,[_|S]) :- location(bananas,L,S).
%More concisely: location(bananas,loc1,_).

% fluent for the location of the monkey
location(monkey,loc2,[]).
location(monkey,L,[push(L)|_]).
location(monkey,L,[go(L)|_]).
location(monkey,L,[A|S]) :- 
   \+ A=push(_), \+ A=go(_), location(monkey,L,S).

% fluent for the monkey holding the bananas
has_bananas([grab|_]).
has_bananas([_|S]) :- has_bananas(S). % The monkey keeps them!

% fluent for the monkey being on the box
on_box([climb_on|_]).
on_box([A|S]) :- \+ A=climb_off, on_box(S).
 
% poss(a,s) if a is a possible action to perform in situation s
% action precondition clauses:
poss(climb_off,S) :- on_box(S).
poss(go(_),S) :- \+on_box(S).
poss(grab,S) :- 
  on_box(S), location(box,L,S), location(bananas,L,S).
poss(push(_),S) :-poss(climb_on,S).
poss(climb_on,S) :-
  \+ on_box(S), location(box,L,S), location(monkey,L,S).