SICP解答メモ&解説 (問題1.9〜問題1.10)

問題1.9

以下の手続きを考える。

(define (+ a b)
  (if (= a 0)
	  b
	  (inc (+ (dec a) b))))

(define (+ a b)
  (if (= a 0)
	  b
	  (+ (dec a ) (inc b))))

一つ目の手続きを置き換えると


(inc (+ (dec 4) 5))
(inc (inc (+ (dec 3) 5)))
(inc (inc (inc (+ (dec 2) 5))))
(inc (inc (inc (inc (+ (dec 1) 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9
になり線形再帰プロセスになることがわかる。

二つ目の手続きを置き換えると


(+ (dec 4) (inc 5))
(+ (dec 3) (inc 6))
(+ (dec 2) (inc 7))
(+ (dec 1) (inc 8))
9
になり、線形反復プロセスになることがわかる。

再帰プロセスと反復プロセスの違い

今のところの理解で言えば、再帰プロセスはステップ数(計算量)、解釈系が使用する記憶量が線形に増えるプロセスのことである。


例として、この問題を使って、ステップ数、記憶量をグラフにしてみた。xは、問題で定義した「+」の第一引数の値である。(逆に言えば、第二引数はステップ数、記憶量は関係しないと言える。)




また反復プロセスはステップ数は、線形的に増加してしまうが、解釈系が使用する記憶量はある値に固定(末尾再帰的)になる。


再帰プロセスと同じように第一引数xの値とステップ数、記憶量の関係をグラフにしてみた。




このような結果から、計算を行うときは反復プロセスにした方がリソースの節約になっていいと言える(今のところだけど)。

問題1.10

Ackermann関数を元にした手続きの「数学的定義」とか言われても正直わかりません。というか今の私では手に負えないですね。しかしなにもしないのもシャクなので、Ackermann関数についてちょっと調べてみました。


Ackermann関数は

  • 定義

ackermann

アッカーマン関数 - Wikipedia

ということなどがわかった。


とりあえず、プログラミングの手法としてはあまり関係なそうなので今回は深く考えずパスすることにする。