SICP 読み (122) 3.3.5 制約の拡散

問題 3.36 はポイント高い、と思いつつも前提がその前の 3.35 なのかどうか微妙なんでとりあえずスルー (を

問題 3.37

例示されているナニをまず試験。

#!/usr/bin/env gosh

(use test.unit)
(require "3.3.5")

(define-test-suite "3.3.5"

  ("text"
   ("sample"
    (let ((a (make-connector))
	  (b (make-connector)))
      (set-value! a 3 'user)
      (set-value! b 2 'user)
      (assert-equal 5 (get-value (c+ a b)))
      )
    )
   )
  )

とりあえず、c- から始めてみる。試験は以下か。

  ("c-"
   ("3 - 2"
    (let ((a (make-connector))
	  (b (make-connector)))
      (set-value! a 3 'user)
      (set-value! b 2 'user)
      (assert-equal 1 (get-value (c- a b)))
      )
    )
   )

実装はこんな感じですか。他に解があるんかな。ある訳ゃないか。

(define (c- x y)
  (let ((z (make-connector)))
    (adder y z x)
    z))

引き続き乗算の試験。

  ("c*"
   ("3 * 2"
    (let ((a (make-connector))
	  (b (make-connector)))
      (set-value! a 3 'user)
      (set-value! b 2 'user)
      (assert-equal 6 (get-value (c* a b)))
      )
    )
   )

乗算の実装は楽。

(define (c* x y)
  (let ((z (make-connector)))
    (multiplier x y z)
    z))

ラスト問題なのに楽だな、というのはダウトで cv が微妙なんだろうな。余計な文句はホドホドにしておいて次は除算の試験。

  ("c/"
   ("6 / 2"
    (let ((a (make-connector))
	  (b (make-connector)))
      (set-value! a 6 'user)
      (set-value! b 2 'user)
      (assert-equal 3 (get-value (c/ a b)))
      )
    )
   )

一応以下の実装で試験パス。

(define (c/ x y)
  (let ((z (make-connector)))
    (multiplier y z x)
    z))

次が一番ポイント高いと予想した定数のソレなんですが、試験は以下で。

  ("cv"
   ("set 6"
    (assert-equal 6 (get-value (cv 6)))
    )
   )

以下の実装で試験パス。

(define (cv c)
  (let ((z (make-connector)))
    (constant c z)
    z))

これで例示されているナニが動くはずだな。

  ("celsius-fahrenheit-converter"
   ("set-value! x 25 returns 77"
    (let ((a (make-connector)))
      (set-value! a 25 'user)
      (assert-equal 77 (get-value (celsius-fahrenheit-converter a)))
      )
    )
   )

実装は例示されている通りで以下。

(define (celsius-fahrenheit-converter x)
  (c+ (c* (c/ (cv 9) (cv 5))
	  x)
      (cv 32)))

なんかすんごい easy だったんですが、ナチュラルなボケをカマしてるのかなぁ。(とほほほ