理系学生日記

おまえはいつまで学生気分なのか

問題3-34 (3.3.5 Propagation of Constraints)

(define (squarer a b)
  (multiplier a a b))

There is a serious flaw in this idea. Explain.

という問題.

とりあえずやってみるといいですね.
まずは squarer の a に対して値を設定する.

(define (squarer a b)
  (multiplier a a b))

(define a (make-connector))
(define b (make-connector))

(probe "A" a)
(probe "B" b)

(squarer a b)
(set-value! a 10 'kiririrmode)
; Probe: B = 100
; Probe: A = 10done

あれ,正常動作だ!

次は b に値を設定してみる.

(squarer a b)
(set-value! b 100 'kiririrmode)
; Probe: B = 100done

ふむ,A の値が計算されてない.

まぁ,この動作は multiplier の定義を見れば当然という感じ.

(define (multiplier m1 m2 product)
  (define (process-new-value)
    (cond ((or (and (has-value? m1) (= (get-value m1) 0))
               (and (has-value? m2) (= (get-value m2) 0)))
           (set-value! product 0 me))
          ((and (has-value? m1) (has-value? m2))
           (set-value! product
                       (* (get-value m1) (get-value m2))
                       me))
          ((and (has-value? product) (has-value? m1))
           (set-value! m2
                       (/ (get-value product) (get-value m1))
                       me))
          ((and (has-value? product) (has-value? m2))
           (set-value! m1
                       (/ (get-value product) (get-value m2))
                       me))))
  ; 略

squarer は multiplier の m1, m2 にともに同じ connector を渡す.
multiplier は,3 つある端子のうち,2 つに値が設定されて初めて動作する.
結局,squarer の b にのみ値を設定したときは,multiplier の端子に 1 つしか値が設定されていない状態だから,動作しない..