1 ! Copyright (C) 2008 William Schlieper
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
4 USING: kernel continuations combinators sequences quotations arrays namespaces
\r
5 fry summary assocs math math.order macros ;
\r
11 ERROR: amb-failure ;
\r
13 M: amb-failure summary drop "Backtracking failure" ;
\r
16 failure get [ continue ]
\r
17 [ amb-failure ] if* ;
\r
22 MACRO: checkpoint ( quot -- quot' )
\r
24 '[ '[ failure set _ continue ] callcc0
\r
25 _ failure set @ ] callcc0 ] ;
\r
27 : number-from ( from -- from+n )
\r
28 [ 1 + number-from ] checkpoint ;
\r
32 : preserve ( quot var -- ) [ get [ call ] dip ] keep set ; inline
\r
34 : amb-preserve ( quot -- ) failure preserve ; inline
\r
36 : unsafe-number-from-to ( to from -- to from+n )
\r
37 2dup = [ [ 1 + unsafe-number-from-to ] checkpoint ] unless ;
\r
39 : number-from-to ( to from -- to from+n )
\r
40 2dup < [ fail ] when unsafe-number-from-to ;
\r
42 : amb-integer ( seq -- int )
\r
43 length 1 - 0 number-from-to nip ;
\r
45 MACRO: unsafe-amb ( seq -- quot )
\r
47 [ first 1quotation ]
\r
48 [ [ first ] [ rest ] bi
\r
49 '[ _ [ drop _ unsafe-amb ] checkpoint ] ] if ;
\r
53 : amb-lazy ( seq -- elt )
\r
54 [ amb-integer ] [ nth ] bi ;
\r
56 : amb ( seq -- elt )
\r
58 [ unsafe-amb ] if-empty ; inline
\r
60 MACRO: amb-execute ( seq -- quot )
\r
61 [ length 1 - ] [ <enum> [ 1quotation ] assoc-map ] bi
\r
62 '[ _ 0 unsafe-number-from-to nip _ case ] ;
\r
64 : if-amb ( true false -- ? )
\r
67 [ '[ @ require t ] ]
\r
70 ] amb-preserve ; inline
\r
75 : amb-all ( quot -- )
\r
76 [ { t f } amb [ call fail ] [ drop ] if ] amb-preserve ; inline
\r
78 : bag-of ( quot -- seq )
\r
79 V{ } clone [ '[ @ _ push ] amb-all ] keep ; inline
\r