-- L.A. Computer Science, Monash University, LML 11 Sept 1987

--   Using continuations as generators:
--      L. Allison.
--      Continuations Implement Generators and Streams.
--      The Computer Journal, V33 No5 pp460-465 1990.

--   Cont = partial solution -> solution list
--   Generator = Cont -> Cont

--   fin :Cont
--   success, fail :Generator
--   literal :*t -> Generator
--   choose :Int -> Generator
--   either, pipe :Generator -> Generator -> Generator
--   doo :Int -> Generator -> Generator
--   run :Generator -> output

let rec
    fin     L = [L]

and success cont = cont
and fail    cont L = []

and literal n cont L = cont (n.L)

and either  gen1 gen2 cont L = (gen1 cont L) @ (gen2 cont L)  -- ***

and pipe    gen1 gen2 cont = gen1 (gen2 cont)

and filter p cont L = if p L then cont L else []

and run     gen =  map (reduce (@) "\n")
                   (map (map (\n." "@(itos n))) (gen fin []))

and choose  n = if n=0 then fail else either (literal n) (choose(n-1))

and doo     n gen = if n=0 then success else pipe (doo(n-1)gen) gen

------------------------------------------------------------------------------
-- n queens

and valid []    = true ||
    valid (h.t) =   let rec v col []     = true ||
                            v col (a.b) =
                               if (h=a) | (h=a+col) | (h=a-col)
                                  then false
                                  else v (col+1) b
                     in v 1 t

and queens n = doo n ( pipe (choose n) (filter valid) )       -- ***

in  run (queens 5)

--\fB N-queens using Continuations for Generators. \fP
