プログラミング再入門

プログラミングをもう一度ちゃんと勉強する読書ノート

SICP 5.2 A Register-Machine Simulator

いよいよ本題な感じ。

ノート

Exercise 5.7

実装してみないことには何も分からないので、先の節の実装を写経してシムレータを作成してから実行してみる。
Racketではペアはimmutableでset-cdr!は使えないので、instructionのペアのメソッドを以下の様にmpairを使った実装に差し替える。

(define (make-instruction text)
  (mcons text '()))
(define (instruction-text inst)
  (mcar inst))
(define (instruction-execution-proc inst)
  (mcdr inst))
(define (set-instruction-execution-proc! inst proc)
  (set-mcdr! inst proc))

GCDの例で動作確認

> (set-register-contents! gcd-machine 'a 206)
'done
> (set-register-contents! gcd-machine 'b 40)
'done
> (start gcd-machine)
'done
> (get-register-contents gcd-machine 'a)
2
> 

動いていそう。

早速a.の再帰パターン

(define expt-machine-a
  (make-machine
   '(continue b n result)
   (list (list '= =)
         (list '- -)
         (list '* *))
   '(controller
     (assign continue (label expt-done))
     (save continue)
     expt-prep
     (test (op =) (reg n) (const 0))
     (branch (label expt-init))
     (assign n (op -) (reg n) (const 1))
     (assign continue (label expt-calc))
     (save continue)
     (goto (label expt-prep))
     expt-init
     (assign result (const 1))
     (restore continue)
     (goto (reg continue))
     expt-calc
     (assign result (op *) (reg result) (reg b))
     (restore continue)
     (goto (reg continue))
     expt-done)))

実行してみる

> (set-register-contents! expt-machine-a 'b 2)
'done
> (set-register-contents! expt-machine-a 'n 3)
'done
> (start expt-machine-a)
'done
> (get-register-contents expt-machine-a 'result)
8
> 

動いた。

b.の繰り返しパターン

(define expt-machine-b
  (make-machine
   '(b n count product)
   (list (list '= =)
         (list '- -)
         (list '* *))
   '(controller
     (assign count (reg n))
     (assign product (const 1))
     expt-iter
     (test (op =) (reg count) (const 0))
     (branch (label expt-done))
     (assign count (op -) (reg count) (const 1))
     (assign product (op *) (reg product) (reg b))
     (goto (label expt-iter))
     expt-done)))

実行してみる

> (set-register-contents! expt-machine-b 'b 2)
'done
> (set-register-contents! expt-machine-b 'n 3)
'done
> (start expt-machine-b)
'done
> (get-register-contents expt-machine-b 'product)
8
> 

どちらも一発で動いてくれて少し感動。