I haven’t had much opportunity to work with logic programming languages, so I attempted this simple planning problem in Prolog:
A farmer is returning to his farm after a long day of working in the fields. He has with him a fox, a chicken, and some grain. He must cross a small stream on his way back to the barn. At the stream, there is a canoe, in which he can transport at most one item across at a time. However, he cannot leave the fox alone with the chicken, or the fox will eat the chicken. Similarly, he cannot leave the chicken alone with the grain because the chicken will eat the grain. Devise a plan (sequence of actions) that the farmer can take to safely bring all of his possessions across the stream and continue on his way home.
I wrote the following solution using gprolog. Both gprolog and the other prolog available on Debian systems, swi-prolog, have really horrible programming environments. I can see why many people would skip over prolog given such poor implementations.
initial(X) :- sort([farmer,fox,chicken,grain],X).
% exclude invalid combinations
check_invalid([chicken, fox]) :- !, fail.
check_invalid([chicken, grain]) :- !, fail.
check_invalid([chicken, fox, grain]) :- !,fail.
check_invalid(_) :- true.
% check if we have reached the goal
find_solution(Goal,Goal,_, Moves,Plan) :-
% try to make a move, check whether the result is valid
% and check the history to see if we are repeating a move
find_solution(Initial,Goal,History, Moves, Plan) :-
find_solution([SNear,SFar], Goal, [[SNear,SFar] | History], [ Move | Moves], Plan).
% cross from Near to Far side
cross1([Near,Far],Result, Move, forward).
% cross from Far to Near side
cross1([Far,Near],[NF,NN], Move, backward).
% let the farmer cross alone
Move = [Direction, farmer, ].
% let the farmer cross with one Animal/grain
Move = [Direction, farmer, [Animal]].