123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- (define $fail
- (make-fluid (make-cell
- (lambda ()
- (error "call to FAIL outside WITH-NONDETERMINISM")))))
- (define (with-nondeterminism thunk)
- (let-fluid $fail
- (make-cell (lambda ()
- (error "nondeterminism ran out of choices")))
- thunk))
- (define (fail)
- ((fluid-cell-ref $fail)))
- (define-syntax either
- (syntax-rules ()
- ((either) (fail))
- ((either x) x)
- ((either x y ...)
- (%either (lambda () x) (lambda () (either y ...))))))
- (define (%either thunk1 thunk2)
- (let ((save (fluid-cell-ref $fail)))
- ((call-with-current-continuation
- (lambda (k)
- (fluid-cell-set! $fail
- (lambda ()
- (fluid-cell-set! $fail save)
- (k thunk2)))
- thunk1)))))
- (define-syntax one-value
- (syntax-rules ()
- ((one-value x) (%one-value (lambda () x)))))
- (define (%one-value thunk)
- (let ((save (fluid-cell-ref $fail)))
- (call-with-values thunk
- (lambda args
- (fluid-cell-set! $fail save)
- (apply values args)))))
- (define-syntax all-values
- (syntax-rules ()
- ((all-values x) (%all-values (lambda () x)))))
- (define (%all-values thunk)
- (let ((results '()))
- (either (let ((new-result (thunk)))
- (set! results (cons new-result results))
- (fail))
- (reverse results))))
|