%farmer, wolf, goat, cabbage go :- path(st(w,w,w,w),st(e,e,e,e)). path(Start, Goal) :- empty(EmptyBeen), push(Start,EmptyBeen,Been), path1(Start, Goal, Been). path1(Goal, Goal, Been) :- nl, nl, write('Solution is: '), nl, writeR(Been). path1(Start, Goal, Been) :- mv(Start, Next), not(memberSt(Next, Been)), push(Next, Been, Newbeen), path1(Next, Goal, Newbeen). %move predicates %take the wolf mv(st(X,X,G,C), st(Y,Y,G,C)) :- opp(X,Y), not(unsafe(st(Y,Y,G,C))). %take the goat mv(st(X,W,X,C), st(Y,W,Y,C)) :- opp(X,Y), not(unsafe(st(Y,W,Y,C))). %take the cabbage mv(st(X,W,G,X), st(Y,W,G,Y)) :- opp(X,Y), not(unsafe(st(Y,W,G,Y))). %return alone mv(st(X,W,G,C), st(Y,W,G,C)) :- opp(X,Y), not(unsafe(st(Y,W,G,C))). %unsafe if the wolf and the goat are together without the farmer unsafe(st(X,Y,Y,C)) :- opp(X,Y), writelist(['unsafe, look out: ',X,Y,Y,C]). %unsafe if the goat and the cabbage are together without the farmer unsafe(st(X,W,Y,Y)) :- opp(X,Y), writelist(['unsafe, look out: ',X,W,Y,Y]). opp(e,w). opp(w,e). %stack empty([]). push(Top, Stack, [Top|Stack]). pop(Top, Stack, [Top|Stack]). memberSt(Elt, Stack) :- mem(Elt,Stack). writeR(Stack) :- empty(Stack). writeR(Stack) :- pop(Top, Rest, Stack), writeR(Rest), write(Top), nl. %membership in a list that is used by stack mem(Elt,[Elt|_]). mem(Elt,[_|Tail]) :- mem(Elt,Tail). %write out a list writelist([]). writelist([H|T]) :- write(H), nl, writelist(T).