(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))
        ((if? exp)                   (analyze-if exp))
        ((if-fail? exp)              (analyze-if-fail exp))
        ((let? exp)                  (analyze (let->combination exp)))
        ((lambda? exp)               (analyze-lambda exp))
        ((begin? exp)                (analyze-sequence (begin-actions exp)))
        ((cond? exp)                 (analyze (cond->if exp)))
        ((amb? exp)                  (analyze-amb exp))
        ((application? exp)          (analyze-application exp))
        (else (error "Unknown expression type -- ANALYZE" exp))))

(define (if-fail? exp) (tagged-list? exp 'if-fail))
(define (if-fail-try exp) (cadr exp))
(define (if-fail-fail exp) (caddr exp))
(define (analyze-if-fail exp)
  (let ((try-proc (analyze (if-fail-try exp)))
        (fail-proc (analyze (if-fail-fail exp))))
    (lambda (env succeed fail)
      (try-proc env
                succeed
                (lambda () (fail-proc env succeed 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))
        ((if? exp)                   (analyze-if exp))
        ((if-fail? exp)              (analyze-if-fail exp))
        ((let? exp)                  (analyze (let->combination exp)))
        ((lambda? exp)               (analyze-lambda exp))
        ((begin? exp)                (analyze-sequence (begin-actions exp)))
        ((cond? exp)                 (analyze (cond->if exp)))
        ((amb? exp)                  (analyze-amb exp))
        ((application? exp)          (analyze-application exp))
        (else (error "Unknown expression type -- ANALYZE" exp))))

(define (if-fail? exp) (tagged-list? exp 'if-fail))
(define (if-fail-try exp) (cadr exp))
(define (if-fail-fail exp) (caddr exp))
(define (analyze-if-fail exp)
  (let ((try-proc (analyze (if-fail-try exp)))
        (fail-proc (analyze (if-fail-fail exp))))
    (lambda (env succeed fail)
      (try-proc env
                succeed
                (lambda () (fail-proc env succeed fail))))))