(* From the SML/NJ benchmark suite. *) signature BMARK = sig val doit : int -> unit val testit : TextIO.outstream -> unit end; structure Main : BMARK = struct fun map f [] = [] | map f (a::x) = f a :: map f x exception ex_undefined of string fun error str = raise ex_undefined str fun accumulate f = let fun foldf a [] = a | foldf a (b::x) = foldf (f a b) x in foldf end fun filter p = let fun consifp x a = if p a then a::x else x in rev o accumulate consifp [] end fun exists p = let fun existsp [] = false | existsp (a::x) = if p a then true else existsp x in existsp end fun equal a b = (a = b) fun member x a = exists (equal a) x fun C f x y = f y x fun cons a x = a::x fun revonto x = accumulate (C cons) x fun length x = let fun count n a = n+1 in accumulate count 0 x end fun repeat f = let fun rptf n x = if n=0 then x else rptf(n-1)(f x) fun check n = if n<0 then error "repeat<0" else n in rptf o check end fun copy n x = repeat (cons x) n [] fun spaces n = concat (copy n " ") local fun lexordset [] = [] | lexordset (a::x) = lexordset (filter (lexless a) x) @ [a] @ lexordset (filter (lexgreater a) x) and lexless(a1:int,b1:int)(a2,b2) = if a2=xstart andalso y>=ystart in fun plot coordlist = plotfrom(xstart,ystart) "" (filter good coordlist) end infix 6 at fun coordlist at (x:int,y:int) = let fun move(a,b) = (a+x,b+y) in map move coordlist end val rotate = map (fn (x:int,y:int) => (y,~x)) val glider = [(0,0),(0,2),(1,1),(1,2),(2,1)] val bail = [(0,0),(0,1),(1,0),(1,1)] fun barberpole n = let fun f i = if i=n then (n+n-1,n+n)::(n+n,n+n)::nil else (i+i,i+i+1)::(i+i+2,i+i+1)::f(i+1) in (0,0)::(1,0):: f 0 end val genB = mkgen(glider at (2,2) @ bail at (2,12) @ rotate (barberpole 4) at (5,20)) fun nthgen g 0 = g | nthgen g i = nthgen (mk_nextgen_fn neighbours g) (i-1) val gun = mkgen [(2,20),(3,19),(3,21),(4,18),(4,22),(4,23),(4,32),(5,7),(5,8),(5,18), (5,22),(5,23),(5,29),(5,30),(5,31),(5,32),(5,36),(6,7),(6,8),(6,18), (6,22),(6,23),(6,28),(6,29),(6,30),(6,31),(6,36),(7,19),(7,21),(7,28), (7,31),(7,40),(7,41),(8,20),(8,28),(8,29),(8,30),(8,31),(8,40),(8,41), (9,29),(9,30),(9,31),(9,32)] fun show pr = (app (fn s => (pr s; pr "\n"))) o plot o alive fun doit () = show (fn _ => ()) (nthgen gun 25000) val doit = fn size => let fun loop n = if n = 0 then () else (doit(); loop(n-1)) in loop size end fun testit strm = show (fn c => TextIO.output (strm, c)) (nthgen gun 50) end (* Life *)