% Monkey and bananas planning problem, adapted from Eyelet's
% input/monkey-bananas.pl.
%
% A state is [bananas_location, monkey_location, box_location, on_box,
% has_bananas].  The query searches bounded move lists and derives successful
% plans.

memoize(reachable, 3).

plan(Moves) :-
  candidate_plan(Moves),
  initial_state(I),
  goal_state(G),
  reachable(I, Moves, G).

candidate_plan([_, _, _]).
candidate_plan([_, _, _, _]).
candidate_plan([_, _, _, _, _]).

reachable(S, [], S).
reachable(S1, [M|L], S3) :-
  legal_move(S1, M, S2),
  reachable(S2, L, S3).

initial_state([loc1, loc2, loc3, n, n]).
goal_state([_, _, _, _, y]).

legal_move([B, M, M, n, H], climb_on, [B, M, M, y, H]).
legal_move([B, M, M, y, H], climb_off, [B, M, M, n, H]).
legal_move([B, B, B, y, n], grab, [B, B, B, y, y]).
legal_move([B, M, M, n, H], push(X), [B, X, X, n, H]) :-
  member(X, [loc1, loc2, loc3]),
  neq(X, M).
legal_move([B, M, L, n, H], go(X), [B, X, L, n, H]) :-
  member(X, [loc1, loc2, loc3]),
  neq(X, M).

triple(monkeyBananas, plan, Moves) :- plan(Moves).
triple(monkeyBananas, solved, true) :- plan(_Moves).
