factor/extra/backtrack/backtrack.factor

80 lines
1.9 KiB
Factor
Raw Normal View History

2008-07-08 13:22:18 -04:00
! Copyright (C) 2008 William Schlieper
! See http://factorcode.org/license.txt for BSD license.
2008-07-16 05:16:50 -04:00
USING: kernel continuations combinators sequences quotations arrays namespaces
fry summary assocs math math.order macros ;
2008-07-08 13:22:18 -04:00
IN: backtrack
SYMBOL: failure
2008-07-16 05:16:50 -04:00
ERROR: amb-failure ;
M: amb-failure summary drop "Backtracking failure" ;
2008-07-08 13:22:18 -04:00
: fail ( -- )
failure get [ continue ]
[ amb-failure ] if* ;
2008-07-08 13:22:18 -04:00
: require ( ? -- )
[ fail ] unless ;
2008-07-16 05:16:50 -04:00
MACRO: checkpoint ( quot -- quot' )
2008-09-10 23:11:40 -04:00
'[ failure get _
'[ '[ failure set _ continue ] callcc0
_ failure set @ ] callcc0 ] ;
2008-07-16 05:16:50 -04:00
: number-from ( from -- from+n )
[ 1 + number-from ] checkpoint ;
<PRIVATE
: preserve ( quot var -- ) [ get [ call ] dip ] keep set ; inline
: amb-preserve ( quot -- ) failure preserve ; inline
: unsafe-number-from-to ( to from -- to from+n )
2dup = [ [ 1 + unsafe-number-from-to ] checkpoint ] unless ;
2008-07-16 05:16:50 -04:00
: number-from-to ( to from -- to from+n )
2dup < [ fail ] when unsafe-number-from-to ;
2008-07-16 05:16:50 -04:00
: amb-integer ( seq -- int )
length 1 - 0 number-from-to nip ;
MACRO: unsafe-amb ( seq -- quot )
dup length 1 =
[ first 1quotation ]
[ [ first ] [ rest ] bi
2008-09-10 23:11:40 -04:00
'[ _ [ drop _ unsafe-amb ] checkpoint ] ] if ;
2008-07-16 05:16:50 -04:00
PRIVATE>
: amb-lazy ( seq -- elt )
[ amb-integer ] [ nth ] bi ;
: amb ( seq -- elt )
2008-09-06 18:15:25 -04:00
[ fail f ]
[ unsafe-amb ] if-empty ; inline
2008-07-16 05:16:50 -04:00
MACRO: amb-execute ( seq -- quot )
[ length 1 - ] [ <enum> [ 1quotation ] assoc-map ] bi
2008-09-10 23:11:40 -04:00
'[ _ 0 unsafe-number-from-to nip _ case ] ;
2008-07-16 05:16:50 -04:00
: if-amb ( true false -- ? )
2008-07-16 05:16:50 -04:00
[
[ { t f } amb ]
[ '[ @ require t ] ]
[ '[ @ f ] ]
tri* if
] amb-preserve ; inline
2008-07-16 05:16:50 -04:00
2008-08-09 22:33:58 -04:00
: cut-amb ( -- )
f failure set ;
2009-05-24 09:43:28 -04:00
: amb-all ( quot -- )
[ { t f } amb [ call fail ] [ drop ] if ] amb-preserve ; inline
: bag-of ( quot -- seq )
V{ } clone [ '[ @ _ push ] amb-all ] keep ; inline