Navigation  without Java Scripts

Source 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.