$=

The farmer, the wolf, the goat and the cabbage

\prologindex{state space search} An explicit representation of the state space is used in the problem of the farmer, the wolf, the goat and the cabbage. A farmer has to carry a wolf, a goat and a cabbage accross a river. The farmer has only a very small boat, so he can transport only one item at a time. However, when left alone, the wolf would eat the goat and the goat would eat the cabbage. The problem is to design an order in which this cannot occur. In our solution, states will be represented by terms of the form []
state(Farmer, Wolf, Goat, Cabbage) where all arguments can take the values w or e, corresponding to the west and east side of the river, indicating the location of the actors in our play. First, to be able to decide whether a state is safe, we define the following clauses. \pprog{safe}{
  unsafe(state(X,Y,Y,C)):- opposite(X,Y).
  unsafe(state(X,W,Y,Y)):- opposite(X,Y).
  
  opposite(w,e).
  opposite(e,w).
  
  safe(X):- not(unsafe(X)).
  
} For example, we can now derive that the
state(w,e,e,w), where the wolf may eat the goat, is unsafe by using the first clause. Obviously, a state is safe if it is not unsafe. Next, we define how to make the transition from a safe state to another safe state, that is a successor state of the given state. \pprog{move}{
  move( state(X,X,G,C), state(Y,Y,G,C)):-
  	opposite(X,Y),
  	safe( state(Y,Y,G,C) ).
  
  move( state(X,W,X,C), state(Y,W,Y,C)):-
  	opposite(X,Y),
  	safe( state(Y,W,Y,C) ).
  
  move( state(X,W,G,X), state(Y,W,G,Y)):-
  	opposite(X,Y),
  	safe( state(Y,W,G,Y) ).
  
  move( state(X,W,G,C), state(Y,W,G,C)):-
  	opposite(X,Y),
  	safe( state(Y,W,G,C) ).
  
} The reader is invited to check that our description of safe state transitions is complete. Having dealt with the preliminaries of defining safe states and transitions between safe states we define a predicate
depthfirst(Current,Path,Goal,Solution) that enables us to find a goal state starting from an initial state. The first argument of the predicate depthfirst represents the initial or current state. The second argument represents the path, that is the sequence of states, traversed to reach the current state from the initial state. If the current state is the initial state then this path is empty. The path is stored in reversed order to be able to access it conveniently as a list. The third argument represents the goal state that must be reached for finding a solution, and the fourth argument is used to deliver the solution, that is the path traversed to reach the goal state. The following clauses implement such a depth-first search procedure. \pprog{depthfirst}{
  depthfirst( Goal, Path, Goal, [Goal|Path]).
  depthfirst( Current, Path, Goal, Sol ) :-
  	move(Current,Next),
  	not( member(Next, Path) ),
  	depthfirst( Next, [Current|Path], Goal, Sol ).
  
} The first clause of depthfirst states that a solution is found whenever the current state is identical to the goal state. When the current state is not identical to the goal state a transition is made to a successor state of the given state that does not already occur on the path leading to the current state. Then a recursive call to depthfirst is made with the selected state as the current state. Evaluating the goal ?- depthfirst(state(w,w,w,w),[],state(e,e,e,e),Sol). will bind Sol to the sequence of states connecting the initial
state(w,w,w,w) to the goal state(e,e,e,e).