*  true.ref

* Missionaries and Cannibals

$ENTRY Go {
  = <Prout <MissCann (( ) ('mmmccc') ( )) 
                     (CC C CC C MM MC MM C CC M MC)>> <Card >;
}

*  Start
MissCann {
  (e.left) (MM e.path) = 
         <Miss (MM) (<Move MM L (e.left) (( ) ( ) ( ))>) (e.path)>;

  (e.left) (MC e.path) = 
         <Miss (MC) (<Move MC L (e.left) (( ) ( ) ( ))>) (e.path)>;

  (e.left) (CC e.path) = 
         <Miss (CC) (<Move CC L (e.left) (( ) ( ) ( ))>) (e.path)>;

  (e.left) (M  e.path) = 
         <Miss (M ) (<Move M  L (e.left) (( ) ( ) ( ))>) (e.path)>;

  (e.left) (C  e.path) = 
         <Miss (C ) (<Move C  L (e.left) (( ) ( ) ( ))>) (e.path)>;
 }

Miss {
 (s.last) (s.l (Imposs) (e.right)) (e.path) = Imposs;
 (s.last) (s.l (e.left) (Imposs )) (e.path) = Imposs;

* (s.last) (R (( ) ( ) ( ))    (e.right)) (e.path) = T ;
 (s.last) (R (( ) ( ) ( ))    (e.right)) (e.path) = T (e.path);

* (s.last) (s.l (e.left) (e.right)) ( ) = F s.l (e.right);
 (s.last) (s.l (e.left) (e.right)) ( ) = <RI >;

 (MM) (s.l (e.left) (e.right)) (MM e.path) = <Repeat >;
 (MC) (s.l (e.left) (e.right)) (MC e.path) = <Repeat >;
 (CC) (s.l (e.left) (e.right)) (CC e.path) = <Repeat >;
 (M ) (s.l (e.left) (e.right)) (M  e.path) = <Repeat >;
 (C ) (s.l (e.left) (e.right)) (C  e.path) = <Repeat >;

 (s.last) (s.l (e.left) (e.right)) (MM e.path) = 
      <Miss (MM) (<Move MM s.l (e.left) (e.right)>) (e.path)>;

 (s.last) (s.l (e.left) (e.right)) (MC e.path) = 
      <Miss (MC) (<Move MC s.l (e.left) (e.right)>) (e.path)>;

 (s.last) (s.l (e.left) (e.right)) (CC e.path) = 
      <Miss (CC) (<Move CC s.l (e.left) (e.right)>) (e.path)>;

 (s.last) (s.l (e.left) (e.right)) (M  e.path) = 
      <Miss (M ) (<Move M  s.l (e.left) (e.right)>) (e.path)>;

 (s.last) (s.l (e.left) (e.right)) (C  e.path) = 
      <Miss (C ) (<Move C s.l (e.left) (e.right)>) (e.path)>;
 }


RI     { RI = RI; }
Repeat { Repeat = Repeat; }

Move {
* Boat on left bank
  s.l L (e.left) (e.right) = R (<Minus s.l e.left>) (<Plus  s.l e.right>);
* Boat on right bank
  s.l R (e.left) (e.right) = L (<Plus  s.l e.left>) (<Minus s.l e.right>);
 }

Minus {
* MM crossing
   MM  (e.m 'mm') (e.p) ( ) = (e.m) (e.p) ( );
   MM  ( ) ('mmcc') ( ) = ( ) ( ) ('cc');
   MM  ('m') ('mc') ( ) = ( ) ( ) ('c');
* CC crossing
   CC  ( ) ( ) ('cc' e.c) = ( ) ( ) (e.c);
   CC  (e.m) ('mm' e.p 'cc') ( ) = (e.m 'mm') (e.p) ( );
* MC crossing
   MC  (e.m) ('m' e.p 'c') ( ) = (e.m) (e.p) ( );
* M crossing
   M   ( ) ('mc') ( ) = ( ) ( ) ('c');
   M   (e.m 'm') (e.p) ( ) = (e.m) (e.p) ( );
* C crossing
   C   ( ) ( ) ('c' e.c) = ( ) ( ) (e.c);
   C   (e.m) ('m' e.p 'c') ( ) = (e.m 'm') (e.p) ( );
 }

Plus {
* MM crossing
   MM  ( ) ( ) ('cc') = ( ) ('mmcc') ( );
   MM  ( ) ( ) ('c')  = ('m') ('mc') ( );
   MM  (e.m) (e.p) ( ) = (e.m 'mm') (e.p) ( );
* CC crossing
   CC  (e.m 'mm') (e.p) ( ) = (e.m) ('mm' e.p 'cc') ( );
   CC  ( ) ( ) (e.c)  = ( ) ( ) ('cc' e.c);
* MC crossing
   MC  (e.m) (e.p) ( ) = (e.m) ('m' e.p 'c') ( );
* M crossing
   M  ( ) ( ) ('c') = ( ) ('mc') ( );
   M  (e.m) (e.p) ( ) = (e.m 'm') ( e.p) ( );
* C crossing
   C  (e.m 'm') (e.p) ( ) = (e.m) ('m' e.p 'c') ( );
   C  ( ) ( ) (e.c) = ( ) ( ) ('c' e.c);
 }