SICP: Why does the forget-value-process call the new-value process?
This code is from SICP 3.3.5 Restriction Propagation . I can't figure out why process-forget-value
it needs to be called process-new-value
as the last step.
The text says, "The reason for this last step is that one or more connectors may still have a value (that is, a connector may have a value that was not originally set by the adder), and those values ββmay need to be multiplied back across adder".
What is the simplest web of constraints that can show why it is required (process-new-value)
? Thank!
(define (adder a1 a2 sum)
(define (process-new-value)
(cond ((and (has-value? a1) (has-value? a2))
(set-value! sum
(+ (get-value a1) (get-value a2))
me))
((and (has-value? a1) (has-value? sum))
(set-value! a2
(- (get-value sum) (get-value a1))
me))
((and (has-value? a2) (has-value? sum))
(set-value! a1
(- (get-value sum) (get-value a2))
me))))
(define (process-forget-value)
(forget-value! sum me)
(forget-value! a1 me)
(forget-value! a2 me)
(process-new-value)) ;;; * WHY * ???
(define (me request)
(cond ((eq? request 'I-have-a-value)
(process-new-value))
((eq? request 'I-lost-my-value)
(process-forget-value))
(else
(error "Unknown request -- ADDER" request))))
(connect a1 me)
(connect a2 me)
(connect sum me)
me)
source to share
This is the test I removed process-new-value
from the adder. You will see that the behavior is different.
(define c (make-connector))
(define a (make-connector))
(define b (make-connector))
(define d (make-connector))
(constant 10 a)
(constant 10 c)
(constant 10 d)
(define adder1 (adder a b c))
(define adder2 (adder a b d))
> (has-value? b)
#t
> (get-value b)
0
> (forget-value! b adder1)
'done
> (has-value? b)
#f
If you do it with the correct version.
> (has-value? b)
#t
Second time. As they say, when adder1
informs b
forget its meaning. a
and c
will be permanent, and the last process-new-value
to adder2
re-install b
to 0. This will also work if you are using set-value!
for a
and c
.
source to share