第178回 素人くさいSICP読書会(at 三田某所)
- 会場提供ありがとうございました
- 参加者はついに2名。記録更新
- 理論上はこれ以上減りようがない
- Common Lispの人は風邪だったそうです。お大事に
- 参加者が何人だろうが最後まで問題をやり抜くだけですよ
- 問題5.12
- Haskell Nightのあと、無性にコードが書きたくなって夜中に書き上げたやつ
- 基本的にはassembleが吐くinstsを変形していくだけ
- 長いんで第二倉庫に貼った→ここ
- 実行結果はこんな感じ↓
instructions: ((assign val (reg n)) (assign val (op +) (reg val) (reg n)) (assign n (reg val)) (assign continue (label afterfib-n-2)) (assign n (op -) (reg n) (const 2)) (assign n (op -) (reg n) (const 1)) (assign continue (label afterfib-n-1)) (assign continue (label fib-done)) (test (op <) (reg n) (const 2)) (branch (label immediate-answer)) (goto (reg continue)) (goto (label fib-loop)) (save val) (save continue) (save n) (restore continue) (restore val) (restore n))
label registers: (continue)
stacked registers: (val continue n)
assign sources: ((val ((op +) (reg val) (reg n)) (reg n)) (n ((op -) (reg n) (const 1)) ((op -) (reg n) (const 2)) (reg val)) (continue (label fib-done) (label afterfib-n-1) (label afterfib-n-2)))
done
- 問題5.13
- 引っかけ問題。問題5.12と関係あるように見えて、実は関係ない
- 最初、5.12の情報を使おうとしてうまくいかず
- なぜか。5.12の情報はassembleが終わらないと得られないが、assembleの過程で既にレジスタが必要になるため
- 問題文の「命令のアセンブリ中に,初めて見る度に,レジスタを割り当てる」が最大のヒント
- 答えは、make-machineのレジスター関連の部分を削除して、make-new-machineの中のlookup-registerを以下のように書き換えるだけ
(define (lookup-register name) (let ((val (assoc name register-table))) (if val (cadr val) (begin (allocate-register name) (cadr (assoc name register-table))))))
- 問題5.14
- 基本的には本文のコードを写経して動かしてみるだけの問題
- こんなコードを用意↓
(define fact-machine (make-machine '(n val continue) (list (list '= =) (list '- -) (list '* *)) '( (perform (op initialize-stack)) 中略 (perform (op print-stack-statistics))))) (define (test-fact-til n) (define (iter count) (if (> count n) 'done (begin (set-register-contents! fact-machine 'n count) (display (list 'n '= count)) (start fact-machine) (newline) (iter (+ count 1))))) (iter 2))
- 動かすとこんな感じ↓
(test-fact-til 6) (n = 2) (total-pushes = 2 maximum-depth = 2) (n = 3) (total-pushes = 4 maximum-depth = 4) (n = 4) (total-pushes = 6 maximum-depth = 6) (n = 5) (total-pushes = 8 maximum-depth = 8) (n = 6) (total-pushes = 10 maximum-depth = 10) done
- total-pushesとmaximum-depthの値は一般には異なるけど、factは単純にガーッと積んでガーッと取ってくるだけなんで、両者の値は一致する
- すなわち「(n - 1) * 2」
- 1日で3問も進んだ。近年まれに見る進捗具合
- 来週はもうちょっと来てほしいなあ