X-Git-Url: https://git.rkrishnan.org/?p=sicp.git;a=blobdiff_plain;f=src%2Fsicp%2Famb-eli.rkt;fp=src%2Fsicp%2Famb-eli.rkt;h=737fd824953cb5a621e92a50f31488864ac6f2fb;hp=0000000000000000000000000000000000000000;hb=16ffd75b36a5dbfbda3da703c2732f8f49208c11;hpb=ef9bb63c4d3fa21f9964c3a5e612bfc519406744 diff --git a/src/sicp/amb-eli.rkt b/src/sicp/amb-eli.rkt new file mode 100644 index 0000000..737fd82 --- /dev/null +++ b/src/sicp/amb-eli.rkt @@ -0,0 +1,42 @@ +#lang racket +(provide amb assert) + +(define failures null) + +(define (fail) + (if (pair? failures) + ((first failures)) + (error "no more choices!"))) + +(define (amb/thunks choices) + (let/cc k (set! failures (cons k failures))) + (if (pair? choices) + (let ([choice (first choices)]) + (set! choices (rest choices)) + (choice)) + (begin (set! failures (rest failures)) + (fail)))) + +(define-syntax-rule (amb E ...) + (amb/thunks (list (lambda () E) ...))) + +(define (assert condition) + (unless condition (fail))) + +(define (collect/thunk n thunk) + (define results null) + (let/cc too-few + (set! failures (list too-few)) + (define result (thunk)) + (set! results (cons result results)) + (set! n (sub1 n)) + (unless (zero? n) (fail))) + (set! failures null) + (reverse results)) + +(define-syntax collect + (syntax-rules () + ;; collect N results + [(_ N E) (collect/thunk N (lambda () E))] + ;; collect all results + [(_ E) (collect/thunk -1 (lambda () E))]))