Sourse Code for Farmer, Wolf, Goat and Cabbage
DOMAINS
LOC = east ; west
STATE = state(LOC farmer,LOC wolf,LOC goat,LOC cabbage)
PATH = STATE*
PREDICATES
go(STATE,STATE) % Start of the algorithm
path(STATE,STATE,PATH,PATH) % Finds a path from one state to another
nondeterm move(STATE,STATE) % Transfer a system from one side to another
opposite(LOC,LOC) % Gives a location on the opposite side
nondeterm unsafe(STATE) % Gives the unsafe states
nondeterm member(STATE,PATH) % Checks if the state is already visited
write_path(PATH)
write_move(STATE,STATE)
GOAL
go(state(east,east,east,east),state(west,west,west,west)),
write("solved").
CLAUSES
go(StartState,GoalState):-
path(StartState,GoalState,[StartState],Path),
write("A solution is:\n"),
write_path(Path).
path(StartState,GoalState,VisitedPath,Path):-
move(StartState,NextState), % Find a move
not( unsafe(NextState) ), % Check that it is not unsage
not( member(NextState,VisitedPath) ), % Check that we have not had this situation before
path( NextState,GoalState,[NextState|VisitedPath],Path),!.
path(GoalState,GoalState,Path,Path). % The final state is reached
move(state(X,X,G,C),state(Y,Y,G,C)):-opposite(X,Y). % Move FARMER + WOLF
move(state(X,W,X,C),state(Y,W,Y,C)):-opposite(X,Y). % Move FARMER + GOAT
move(state(X,W,G,X),state(Y,W,G,Y)):-opposite(X,Y). % Move FARMER + CABBAGE
move(state(X,W,G,C),state(Y,W,G,C)):-opposite(X,Y). % Move ONLY FARMER
opposite(east,west).
opposite(west,east).
unsafe( state(F,X,X,_) ):- opposite(F,X),!. % The wolf eats the goat
unsafe( state(F,_,X,X) ):- opposite(F,X),!. % The goat eats the cabbage
member(X,[X|_]):-!.
member(X,[_|L]):-member(X,L).
write_path( [H1,H2|T] ) :-
write_move(H1,H2),
write_path([H2|T]).
write_path( [] ).
write_move( state(X,W,G,C), state(Y,W,G,C) ) :-!,
write("The farmer crosses the river from ",X," to ",Y),nl.
write_move( state(X,X,G,C), state(Y,Y,G,C) ) :-!,
write("The farmer takes the Wolf from ",X," of the river to ",Y),nl.
write_move( state(X,W,X,C), state(Y,W,Y,C) ) :-!,
write("The farmer takes the Goat from ",X," of the river to ",Y),nl.
write_move( state(X,W,G,X), state(Y,W,G,Y) ) :-!,
write("The farmer takes the cabbage from ",X," of the river to ",Y),nl.