Exercise 4.51.  Implement a new kind of assignment called permanent-set! 
that is not undone upon failure. For example, we can choose two distinct 
elements from a list and count the number of trials required to make a 
successful choice as follows:

(define count 0)
(let ((x (an-element-of '(a b c)))
      (y (an-element-of '(a b c))))
  (permanent-set! count (+ count 1))
  (require (not (eq? x y)))
  (list x y count))
;;; Starting a new problem
;;; Amb-Eval value:
(a b 2)
;;; Amb-Eval input:
try-again
;;; Amb-Eval value:
(a c 3)

What values would have been displayed if we had used set! here rather 
than permanent-set! ? 

————————————————————————————————————————————————————————————————————————

If set! was used, the displayed count will always be 1, since the 
computation will be rolled back to the beginning, where count is 0, 
before each additional result is found.

We can implement permanent-set! more simply than set!, which goes to 
some trouble to undo the assignment while propagating failure.  The 
result comes out much like analyze-definition.

(define (analyze-permanent-assignment exp)
  (let ((var (permanent-assignment-var exp))
        (vproc (analyze (permanent-assignment-value exp))))
    (lamdba (env succeed fail)
      (vproc env
             (lambda (val fail2)
               (set-variable-value! var val)
               (succeed 'ok fail2))
             fail))))
