2016/01/15
SICP 問題 4.52
利用者が失敗を捉えることができるif-failを実装する.
(define (analyze exp)
(cond ((self-evaluating? exp) (analyze-self-evaluating exp))
((quoted? exp) (analyze-quoted exp))
((variable? exp) (analyze-variable exp))
((assignment? exp) (analyze-assignment exp))
((permanent-assignment? exp) (analyze-permanent-assignment exp))
((definition? exp) (analyze-definition exp))
((amb? exp) (analyze-amb exp))
((ramb? exp) (analyze-ramb exp))
((if? exp) (analyze-if exp))
((if-fail? exp) (analyze-if-fail exp))
((lambda? exp) (analyze-lambda exp))
((let? exp) (analyze (let->combination exp)))
((begin? exp) (analyze-sequence (begin-actions exp)))
((cond? exp) (analyze (cond->if exp)))
((application? exp) (analyze-application exp))
(else (error "Unknown expression type: ANALYZE" exp))))
(define (if-fail? exp) (tagged-list? exp 'if-fail))
(define (analyze-if-fail exp)
(let ((proc (analyze (cadr exp)))
(fail-proc (analyze (caddr exp))))
(lambda (env succeed fail)
(proc env succeed
(lambda ()
(announce-output output-prompt)
(user-print (fail-proc env succeed fail))
(driver-loop))))))
test
;;; Amb-Eval input:
(if-fail (let ((x (an-element-of '(1 3 5))))
(require (even? x))
x)
'all-odd)
;;; Starting a new problem
;;; Amb-Eval value:
'all-odd
;;; Amb-Eval input:
(if-fail (let ((x (an-element-of '(1 3 5 8))))
(require (even? x))
x)
'all-odd)
;;; Starting a new problem
;;; Amb-Eval value:
8