2013年10月31日木曜日

開発環境

計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の4(超言語的抽象)、4.4(論理型プログラミング)、4.4.4(質問システムの実装)、4.4.4.1(駆動ループと具体化)、4.4.4.2(評価器)、単純質問、合成質問、フィルタ、4.4.4.3(パターンマッチにより表明を見つける)、ドット末尾を持つパターン、4.4.4.4(規則とユニフィケーション)、4.4.4.5(データベースの保守)、問題 4.70を解いてみる。

その他参考書籍

問題 4.70

手続きadd-assertion!とadd-rule!のlet束縛の目的は、問題のようにletにより束縛しないと、cons-streamの第2引数の式の評価はdelayにより遅延されることになるので、THE-ASSERTIONSやTHE-RULESへ意図と違う値が代入されてしまうから。(具体的には無限ループに陥る。)

単純な例で手動で確認。

;; stream、aの定義
(define a (1 2 3 4 5 …))

;; let束縛有りの場合

(let ((old-a (1 2 3 4 5)))
  (set! a (cons-stream 0 old-a)))

;; この時点でold-aは(1 2 3 4 5)

;; aの先頭の値を取り出す。
(stream-ref a 0)

0
;; aの先頭の次の値を取り出す
(stream-ref a 1)

1

;; let束縛が無しの場合
(set! a (cons-stream 0 a))

;; aの先頭の値を取り出す
(stream-ref a 0)

0
;; aの先頭の次の値を取り出す(ここで違いが出現)
(stream-ref a 1)
;; ここで(cons-streamの第2引数のaが評価されて、そのaの先頭の値は0。よって
0

;; なので、let束縛が無いと、永遠に0が取り出されることになる。(無限ストリームになる。)

実際に簡単な例での違いを確認。

コード(BBEdit)

sample.scm

(define ones (cons-stream 1 ones))

(define a (cons-stream 1 (add-streams ones a)))

(define b (cons-stream 1 (add-streams ones b)))

;; ストリームの先頭に0を追加
;; let束縛有りの場合
(let ((old-a a))
  (set! a (cons-stream 0 old-a)))

;; let束縛無しの場合
(set! b (cons-stream 0 b))

入出力結果(Terminal, REPL(Read, Eval, Print, Loop))

$ scheme
MIT/GNU Scheme running under MacOSX
Type `^C' (control-C) followed by `H' to obtain information about interrupts.

Copyright (C) 2011 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Image saved on Saturday October 26, 2013 at 11:02:50 PM
  Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/C 4.118
  Edwin 3.116

1 ]=> (load "./sample.scm")

;Loading "./sample.scm"... done
;Value 2: (1 . #[promise 3])

1 ]=> (stream-ref a 0)

;Value: 0

1 ]=> (stream-ref a 1)

;Value: 1

1 ]=> (stream-ref b 0)

;Value: 0

1 ]=> (stream-ref b 1)

;Value: 0

1 ]=> ^D
End of input stream reached.
Moriturus te saluto.
$

0 コメント:

コメントを投稿