Rewrite require as a special form (Exercise 4.54)

Tested this with the "liars" problem, and the result is the same.
This commit is contained in:
Oliver Payne 2024-02-01 22:57:51 +00:00
parent 7a16a3efd8
commit e57c374c38
2 changed files with 16 additions and 4 deletions

View File

@ -6,10 +6,7 @@
(define amb-utilities-program
'((define (require p)
(if (not p) (amb)))
(define (an-element-of items)
'((define (an-element-of items)
(require (not (null? items)))
(amb (car items) (an-element-of (cdr items))))

View File

@ -21,6 +21,9 @@
(define (amb-form exp) (car exp)) ; amb or ramb
(define (amb-choices exp) (cdr exp))
(define (require? exp) (tagged-list? exp 'require))
(define (require-predicate exp) (cadr exp))
;; analyze from 4.1.6, with clause from 4.3.3 added
;; and also support for Let
(define (analyze exp)
@ -39,6 +42,7 @@
((let? exp) (analyze (let->combination exp))) ;**
((amb? exp) (analyze-amb exp)) ;**
((ramb? exp) (analyze-amb exp))
((require? exp) (analyze-require exp))
((application? exp) (analyze-application exp))
(else
(error "Unknown expression type -- ANALYZE" exp))))
@ -229,6 +233,17 @@
(try-next (rest-choices choices)))))))
(try-next cprocs))))
(define (analyze-require exp)
(let ((pproc (analyze (require-predicate exp))))
(lambda (env succeed fail)
(pproc env
(lambda (pred-value fail2)
(if (false? pred-value)
(fail)
(succeed 'ok fail2)))
fail))))
;; if-fail is used to catch failure of an expression
(define (analyze-if-fail exp)
(let ((tproc (analyze (if-fail-test exp)))