RosettaCodeData/Task/Amb/M2000-Interpreter/amb-1.m2000
2023-07-01 13:44:08 -04:00

77 lines
2.7 KiB
Text

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