計算機プログラムの構造と解釈 第二版 P174 問題3.35
squarerを基本制約として作ってみようという問題。
そんなに難しく考える必要はなくて、
p171のaddr、もしくは、p172のmultiplierを参考につくる。
まず考えるべきは<代替部1>だけど、これは根をセットする部分だ。
if式になっているからちょっとあせるが、よく見てaにset-value!する式を書いた。
次に<代替部2>ここに書くべきは、
bが値を持っていなくて、aが値を持っているケースだとおもうので
if式からつけたしつつ、あとはよく見て、bにset-value!する式を書けばいい。
<本体1>に関してはほぼ写しただけ。
aとbにforget-value!して忘れさせてやって、process-new-valueした。
<本体2>にいたっては、エラーメッセージを変えただけだ。
そんな感じでできた。
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 (squarer a b) (define (process-new-value) (if (has-value? b) (if (< (get-value b) 0) (error "square less than 0 -- SQUARER" (get-value b)) (set-value! a (sqrt (get-value b)) me)) (if (has-value? a) (set-value! b (* (get-value a) (get-value a)) me)))) (define (process-forget-value) (forget-value! a me) (forget-value! b me) (process-new-value)) (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 -- SQUARER" request)))) (connect a me) (connect b me) me) (define a (make-connector)) (define b (make-connector)) (squarer a b) (probe "input" a) (probe "squarer" b) ;; main (define (main args) (print "(set-value! a 5 'user)") (set-value! a 5 'user) (newline) (newline) (print "(forget-value! a 'user)") (forget-value! a 'user) (newline) (newline) (print "(set-value! b 100 'user)") (set-value! b 100 'user) (newline) (newline) 0)
実行
(set-value! a 5 'user) Probe: input = 5 Probe: squarer = 25 (forget-value! a 'user) Probe: input = ? Probe: squarer = ? (set-value! b 100 'user) Probe: squarer = 100 Probe: input = 10.0
できている。と思う。