5.7 Exercise 5.7
We can simulate the recursive and iterative exponentiation machines by wrapping them in make-machine declarations. This can be done mechanically.
First, the recursive machine:
(define recursive-exponentiation-machine (make-machine '(b n continue val) (list (list '= =) (list '- -) (list '* *)) '(start-machine (assign continue (label expt-done)) expt-loop (test (op =) (reg n) (const 0)) (branch (label base-case)) (save continue) (assign n (op -) (reg n) (const 1)) (save n) (assign continue (label after-expt)) (goto (label expt-loop)) after-expt (restore n) (restore continue) (assign val (op *) (reg b) (reg val)) (goto (reg continue)) base-case (assign val (const 1)) (goto (reg continue)) expt-done)))
Verifying that it works:
> (set-register-contents! recursive-exponentiation-machine 'b 3) |
'done |
> (set-register-contents! recursive-exponentiation-machine 'n 10) |
'done |
> (start recursive-exponentiation-machine) |
'done |
> (get-register-contents recursive-exponentiation-machine 'val) |
59049 |
Next, the iterative machine:
(define iterative-exponentiation-machine (make-machine '(b n val counter product) (list (list '= =) (list '- -) (list '* *)) '(start-machine (assign counter (reg n)) (assign product (const 1)) expt-iter (test (op =) (reg counter) (const 0)) (branch (label after-expt)) (assign counter (op -) (reg counter) (const 1)) (assign product (op *) (reg b) (reg product)) (goto (label expt-iter)) after-expt (assign val (reg product)) (goto (label expt-done)) expt-done)))
Verifying that it also works:
> (set-register-contents! iterative-exponentiation-machine 'b 3) |
'done |
> (set-register-contents! iterative-exponentiation-machine 'n 10) |
'done |
> (start iterative-exponentiation-machine ) |
'done |
> (get-register-contents iterative-exponentiation-machine 'val) |
59049 |
Of course, if we use the builtin expt function, we can see that this result is correct:
> (expt 3 10) |
59049 |