%Program for Farmer-Lion-Goat-Cabbage Puzzle % f=0, c=1, g=2, l=3 achievable(s([0,1,2,3],[]),L). achievable(s(L1,L2),Visited) :- chooseFarmerSide(L1,L2,L3,FS),chooseOtherSide(L1,L2,L4,OS), getPassenger(X,L3), myDelete(0,L3,L5),myDelete(X,L5,L6),noDestruction(L6),orderlyInsert(0,L4,L7),orderlyInsert(X,L7,L8), leftSide(L6,FS,L8,OS,L9), rightSide(L6,FS,L8,OS,L10), nott(inList(s(L9,L10),Visited)), write(s(L1,L2)),nl, achievable(s(L9,L10),[s(L1,L2)|Visited]). chooseFarmerSide(L1,L2,L1,left):- inList(0,L1). chooseFarmerSide(L1,L2,L2,right):- inList(0,L2). chooseOtherSide(L1,L2,L1,left):- inList(0,L2). chooseOtherSide(L1,L2,L2,right):- inList(0,L1). getPassenger(X,L) :- inList(X,L), X =\= 0. getPassenger(4,L). noDestruction(L):- nott(goatAndCabbage(L)), nott(goatAndLion(L)). goatAndCabbage(L):- inList(2,L),inList(1,L). goatAndLion(L):- inList(2,L),inList(3,L). leftSide(L1,left,L2,X,L1). leftSide(L1,X,L2,left,L2). rightSide(L1,right,L2,X,L1). rightSide(L1,X,L2,right,L2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%utility relations size([],0). size([X|L],Y) :- size(L,Y2), Y is Y2 + 1. %List Membership inList(X,[X|Tail]). inList(X,[Head|Tail]) :- inList(X,Tail). % concatenation of two lists concat([],L,L). concat([X|L], L2, [X|L3]):- concat(L,L2,L3). %defining negation nott(P) :- P,!,fail;true. %when one list is a prefix of another prefix([],L). prefix([X | L1], [X | L2]) :- prefix(L1,L2). % deleting from a list myDelete(4,L,L). myDelete(X,[X | L],L):- X < 4. myDelete(X, [Y|L1],[Y|L2]):- X < 4, myDelete(X,L1,L2). % adding to the end of a list addListEnd(X,[],[X]). addListEnd(X,[Y|L1],[Y|L2]):- addListEnd(X,L1,L2). %inserting an integer in numerical order orderlyInsert(4,L,L). orderlyInsert(X,[],[X]):- X < 4. orderlyInsert(X,[Y|L1],[X,Y|L1]):- X < 4,X =< Y. orderlyInsert(X,[Y|L1],[Y|L2]):- X < 4,X >Y, orderlyInsert(X,L1,L2). prefSize(L1,L2,N):- prefix(L1,L2),size(L1,N). prefSize(L1,L2,0). myMax(N1,N2,N1) :- N1 >= N2. myMax(N1,N2,N2) :- N2 >= N1. maxPref(L1,[],0). maxPref([],L,0). maxPref(L1,[X|L2],N):- prefSize(X,L1,S1), maxPref(L1,L2,S2), myMax(S1,S2,N).