scheme - SICP:为什么 process-forget-value 会调用 process-new-value?

标签 scheme lisp constraints sicp

此代码来自 SICP,3.3.5 Propagation of Constraints .我似乎无法弄清楚为什么 process-forget-value 需要调用 process-new-value 作为最后一步。

文本说,“最后一步的原因是一个或多个连接器可能仍然有一个值(也就是说,一个连接器可能有一个最初不是由加法器设置的值),并且这些值可能需要通过加法器传回。”

可以证明为什么需要 (process-new-value) 的最简单的约束网络是什么?谢谢!

(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)

最佳答案

这是我从加法器中删除 process-new-value 所做的测试。你会看到行为是不同的。

(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

如果您使用正确的版本执行此操作。

> (has-value? b)
#t

第二次也是。正如他们所说,当 adder1 告诉 b 忘记它的值时。 ac作为常量还是会有值的,adder2中的最后一个process-new-value,将再次将 b 设置为 0。如果您对 ac 使用 set-value!,这也将起作用.

关于scheme - SICP:为什么 process-forget-value 会调用 process-new-value?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26201599/

相关文章:

macros - 如何改进用于照应 -> 或 ->> 宏的 Racket 代码?

scheme - Scheme/Lisp 内置二进制转换

recursion - clojure 递归 conj 列表

SQL Server 2008-获取表约束

sql - 我需要验证表中的数据,其中 1 列有多个值,但 1 个值只能通过唯一键出现在 1 行中

scheme - Mac OS X 10.5.8 上的 Racket 6.2

java - 使用 Lisp 或 Scheme 进行 Java 程序的运行时配置

lisp - 寻求对 SICP 练习 1.5 的一些解释

algorithm - 如何根据简化语法解析单词列表?

ios - 调整按钮大小以适应任何屏幕的限制 - Xcode swift