Skip to content

Instantly share code, notes, and snippets.

@blrB
Last active October 31, 2019 12:40
Show Gist options
  • Save blrB/b6620479bd1b46f46b102bf91a0eefb7 to your computer and use it in GitHub Desktop.
Save blrB/b6620479bd1b46f46b102bf91a0eefb7 to your computer and use it in GitHub Desktop.
Farmer Crosses River Puzzle(farmer wants to cross a river and take with him a wolf, a goat, and a cabbage) - SWI Prolog
#!/usr/bin/swipl -f -q
/* function for work with list - BEGIN*/
writenlist([]):-
nl.
writenlist([H|T]):-
write(H),
write(' '),
writenlist(T).
reverse_writenllist([]).
reverse_writenllist([H|T]):-
reverse_writenllist(T),
write(H),
nl.
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
/* function for work with list - END*/
/* change value from e (East) to w (West) */
opposite(e,w).
/* change value from w (West) to e (East) */
opposite(w,e).
/* wolf eats goat */
unsafe(state(X, Y, Y, _)) :-
opposite(X,Y).
/* goat eats cabbage */
unsafe(state(X, _, Y, Y)) :-
opposite(X,Y).
/* farmer takes wolf to other side */
move(state(X, X, G, C), state(Y, Y, G, C)):-
opposite(X,Y),
not(unsafe(state(Y, Y, G, C))),
writenlist(['Try farmer takes wolf ', Y, Y, G, C]).
/* farmer takes goat to other side */
move(state(X, W, X, C), state(Y, W, Y, C)):-
opposite(X,Y),
not(unsafe(state(Y, W, Y, C))),
writenlist(['Try farmer takes goat ', Y, W, Y, C]).
/* farmer takes cabbage to other side */
move(state(X, W, G, X), state(Y, W, G, Y)):-
opposite(X, Y),
not(unsafe(state(Y, W, G, Y))),
writenlist(['Try farmer takes cabbage ', Y, W, G, Y]).
/* farmer takes himself to other side */
move(state(X, W, G, C), state(Y, W, G, C)):-
opposite(X, Y),
not(unsafe(state(Y,W,G,C))),
writenlist(['Try farmer takes self ', Y, W, G, C]).
/* gets here when none of the above fires, system predicate ‘fail’ causes a backtrack*/
move(state(F, W, G, C), state(F, W, G, C)):-
writenlist([' Bactrack from: ', F, W, G, C]),
fail.
/* write solution, if start state = goal */
path(Goal, Goal, List):-
write('Solution Path is: '),
nl,
reverse_writenllist(List).
/* make move */
path(State, Goal, List):-
move(State, NextState),
not(member(NextState, List)),
path(NextState, Goal, [NextState|List]),
!.
/* run program */
:-
path(state(e,e,e,e), state(w,w,w,w),[state(e,e,e,e)]),
halt(0).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment