Module AmbFunction { Function Amb (failure) { // get an array of s items, return an array of 1 item // we do this so we forget the type of element getitem=lambda (n, c) -> { dim z(1) :link c to c() stock c(n) keep 1, z(0) // copy from c(n) to z(0) one item =z() } read a c1=lambda a, getitem (i, &any, &ret) ->{ any=getitem(i, a) ret=any =true } m=stack.size if m=0 then Error "At least two arrays needed" c=c1 while m>1 { read b c1=lambda c2=c, j=0, m=len(a), b, failure, getitem (i, &any, &ret) ->{ any=getitem(i, b) ret=(,) : ok=false : anyother=(,) do if c2(j, &anyother, &ret) then if not failure(any, anyother) then ok=true ret=cons(ret, any) end if end if j++ until ok or j=m if j=m then j=0 =ok } c=c1 : a=b : m-- } read b amb1=lambda c2=c, j=0, m=len(a), b, failure, getitem (&ret) ->{ ret=(,) : ok=false: anyother=(,) k=each(b) while k any=getitem(k^, b) do if c2(j, &anyother, &ret) then if not failure(any, anyother) then ok=true ret=cons(ret, any) end if end if j++ until ok or j=m if j=m then j=0 if ok then exit end while =ok } ret=(,) if amb1(&ret) then =ret else =(,) ' default return value } a=(1, 2, 3) b=(7, 6, 4, 5) failure=lambda (a,b)->{ =a#val(0)*b#val(0)<>8 } Print amb(failure, a, b)#str$() a=("the", "that", "a") b=("frog", "elephant", "thing") c=("walked", "treaded", "grows") d=("slowly", "quickly") failure=lambda (a,b)->{ =left$(a#val$(0),1)<>right$(b#val$(0),1) } Print amb(failure, a, b, c, d)#str$() } AmbFunction