[m-users.] Program questions and inquiry

Mark Green mgreen at brookes.ac.uk
Sun May 5 10:48:25 AEST 2013

```Hi,

Nice to see that the mailing lists are still going, will Mercury still be
OK after the move away from Melbourne?

As a learning exercise I have been trying to implement a solver for the
"river crossing" problem in several logic languages. Below is my attempt in
Mercury, however, it has a strange problem - namely, it only outputs an
empty list. Can anyone tell me what's wrong?

:- module river.
:- interface.
:- import_module io.
:- import_module list.
:- import_module solutions.

:- type object ---> chicken; fox; grain; nothing.
:- type side ---> left; right.
:- type riverstate ---> state(list(object), list(object), side).

:- pred eats(object::in,object::in) is semidet.
:- pred safe(list(object)::in) is semidet.
:- pred unsafe(list(object)::in) is semidet.
:- pred doMove(riverstate::in, object::in, riverstate::out) is nondet.
:- pred canMove(riverstate::in, object::out) is multi.
:- pred moveSafe(riverstate::in, object::out) is nondet.
:- pred solves(riverstate::in, riverstate::in, list(object)::out,
list(riverstate)::in) is nondet.
:- pred main(io::di, io::uo) is det.

:- implementation.

eats(fox,chicken).
eats(chicken,grain).

safe(List) :- eats(A,B), member(A,List), member(B,List).

unsafe(List) :- not(safe(List)).

doMove(state(L,R,left),nothing,state(L,R,right)).
doMove(state(L,R,right),nothing,state(L,R,left)).
doMove(state(Left,Right,left), Item, state(NewLeft, NewRight, right)) :-
not (Item = nothing),
delete(Left,Item,NewLeft),
sort([Item|Right],NewRight).
doMove(state(Left,Right,right), Item, state(NewLeft, NewRight, left)) :-
not (Item = nothing),
delete(Right,Item,NewRight),
sort([Item|Left],NewLeft).

canMove(_,nothing).
canMove(state(Left,_,left),Move) :- member(Move,Left).
canMove(state(_,Right,right),Move) :- member(Move,Right).

moveSafe(State,Move) :-
canMove(State,Move),
doMove(State,Move,state(Left,Right,Side)),
(
(Side = left, safe(Right));
(Side = right, safe(Left))
).

solves(State,Target,[],_) :- State = Target.

solves(State,Target,[Move|SubPath],History) :-
not(State = Target),
moveSafe(State,Move),
doMove(State,Move,NewState),
not(member(NewState,History)),
solves(NewState,Target,SubPath,[State|History]).

main(!IO) :-
solutions( (pred(X::out) is nondet :- solves(
state([chicken,fox,grain],[],left), state([],[chicken,fox,grain],right), X,
[])),Result),
write(Result,!IO).

Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20130505/20d9c79d/attachment.html>
```