/*-------------------------------------------------------------------------
  program: the game of the urn
  file:    urn
  date:    December 97
  author:  Pablo Lopez (lopez@lcc.uma.es)
           Dept. of CS
           University of Malaga, SPAIN

  notes:   Given an urn containing B black balls and W white balls
           (B+W >= 2), extract the balls according to the following
           rule:

                  1. randomly extract two balls B1 and B2
                  2. if B1 and B2 are the same color 
                     then insert a black ball
                     else insert a white ball

           Apply this extraction rule until the urn contains one ball only.
           Now it arises the following question: is this last ball either
           black or white ?

           Hint: use the concept of invariant

           The game above was originally proposed by E. W. Dijkstra.

           This is one of my favourite problems. I find it to be a suitable
           performance/expressiveness benchmark for logic languages in
           general, and for linear logic programming languages in particular.
           I've coded it in Prolog, lambda Prolog, and Lygon. Now it's time
           to give to Forum a choice. Notice that multiset rewriting provides
           an elegant and concise coding of the problem.

  sample goals:
           black # white # black # white.
           go1.
           b(black) # b(white) # b(black) # b(white).
           go2.
-------------------------------------------------------------------------*/

module urn.

% solution 1

black # black *- black.
white # white *- black.
black # white *- white.

black <= printf("black\n").
white <= printf("white\n").

go1 <= black # black # black # black # black # black # black #
       white # white # white # white # white # white # white.

% solution 2

b(X) # b(X) *- b(black).
b(X) # b(Y) *- X \= Y *- b(white).

b(X) <= printf("%w\n", [X]).

go2 <= b(white) # b(white) # b(white) # b(white) # b(white) # b(white) #
       b(black) # b(black) # b(black) # b(black) # b(black) # b(black).
