計算機プログラムの構造と解釈 第二版 P174 問題3.37

制約を扱い易くしちゃおうという。


c+は既に問題に解答がのってる。
c*はc+のadderをmultiplierに変えればいい。
cvはc+の引数を減らして、adderをconstantに変えればいい


問題はc- とc+なんだけど、これはコネクタを引数としてとる部分の位置を変えるだけで実現できる。
僕は考えるときにp169図3.28みたいな図を思い浮かべながらやってみましたよ。


そんな感じで、実装です。


constraint.scmは
http://d.hatena.ne.jp/unlearned/20100606/1275873184
と同様。

#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

(use ggc.debug.trace)
(use math.mt-random)

(load "./constraints.scm")

;;;
; 実行
;;;

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

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

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

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

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



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


(define C (make-connector))
(define F (celsius-fahrenheit-converter C)) 


(probe "Celsius temp" C)
(probe "Fahrenheit temp" F)

;; main
(define (main args)

  (print "(set-value! C 25 'user)")
  (set-value! C 25 'user)
  (newline)
  (newline)

  ;  (print "(set-value! F 212 'user)")
  ;  (set-value! F 212 'user)
  ;(newline)
  ;(newline)

  (print "(forget-value! C 'user)")
  (forget-value! C 'user)
  (newline)
  (newline)

  (print "(set-value! F 212 'user)")
  (set-value! F 212 'user)
  (newline)
  (newline)

  0)

実行

(set-value! C 25 'user)

Probe: Celsius temp = 25
Probe: Fahrenheit temp = 77

(forget-value! C 'user)

Probe: Celsius temp = ?
Probe: Fahrenheit temp = ?

(set-value! F 212 'user)

Probe: Fahrenheit temp = 212
Probe: Celsius temp = 100

うまくいった。