SICP 5.1 Computing with Register Machines: Designing Register Machines
2024-12-24 Tue (Updated on 2025-01-09 Thu; 2025-01-30 Thu)

Exercise 5.1

Exercise:

Design a register machine to compute factorials using the iterative algorithm specified by the following procedure. Draw data-path and controller diagrams for this machine.

(define (factorial n)
  (define (iter product counter)
    (if (> counter n)
        product
        (iter (* counter product)
              (+ counter 1))))
  (iter 1 1))

Answer:

                 Data paths                                                                Controller

      /\--------------------------------+
     /  \                               |                                                    start
+---/ 1  \                             (x) 1->n                                                |
|  /      \                   -----     |                                                      |
| ----------       --------->(  >  )    |                                                      V
|       \         /           -----     |                                                 +-----------+
|  1->c (x)      /              ^       |                                                 |  1->c     |
|         \     /               |       |                                                 |           |
|          V   /                |       V                                                 +-----------+
|     +----------+            +-+---------+            +------------+                          |
|     | counter  |            |     n     |            | product    |                          |
|     |          |            |           |            |            |                          V
|     +----------+            +-----------+            +------------+                     +-----------+
|      |   \    ^                                       /      ^                          |  1->n     |
|      |    \   +------------------------+             /       |                          |           |
|      |     \                           |            /        |                          +-----------+
|      |      \                          |           /         |                               |
|      |       \               +---------+-----------          |                               |
|      |        \              |         |                     |                               V
|      |         V             V         |                     |                               /\
|      |      \-------------------/      |                     |                              /  \
|      |       \                 /       |                    (x) *->p                       /    \     yes
|      |        \       *       /        |                     |                     +----> /  >   \----------> done
|      |         \             /         |                     |                     |      \      /
|      |          \           /          |                     |                     |       \    /
|      |           -----+-----           |                     |                     |        \  /
|      |                |                |                     |                     |         \/
|      +------------+   |                |                     |                     |         |
|                   |   -----------------+---------------------+                     |         |
+---------------+   |                    |                                           |         |no
                |   |                    |                                           |         |
                V   V                    |                                           |         |
              \-------------------/      |                                           |         V
               \                 /       |                                           |    +-----------+
                \       +       /        |                                           |    |  *->p     |
                 \             /        (x) +->c                                     |    |           |
                  \           /          |                                           |    +-----------+
                   -----+-----           |                                           |         |
                        |                |                                           |         |
                        |                |                                           |         V
                        +----------------+                                           |    +-----------+
                                                                                     |    |  +->c     |
                                                                                     |    |           |
                                                                                     |    +----+------+
                                                                                     |         |
                                                                                     |         |
                                                                                     +---------+
      The result is stored in the product register.

Exercise 5.2

Exercise:

Use the register-machine language to describe the iterative factorial machine of Exercise 5.1

Answer:

(controller
 (assign counter (const 1))
 (assign n (const 1))
test-counter-n
 (test (op >) (reg counter) (reg n))
 (branch (label factorial-done))
 (assign product (op *) (reg counter) (reg product))
 (assign counter (op +) (reg counter) (const 1))
 (goto (label test-counter-n))
factorial-done)

Exercise 5.3

Exercise:

Design a machine to compute square roots using Newton's method, as described in section 1.1.7.

(define (sqrt x)
  (define (good-enough? guess)
    (< (abs (- (square guess) x)) 0.001))
  (define (improve guess)
    (average guess (/ x guess)))
  (define (sqrt-iter guess)
    (if (good-enough? guess)
        guess
        (sqrt-iter (improve guess))))
  (sqrt-iter 1.0))

Begin by assuming that good-enough? and improve operations are available as primitives. Then show how to expand these in terms of arithmetic operations. Describe each version of the sqrt machine design by drawing a data-path diagram and writing a controller definition in the register-machine language.

Answer:

First version of sqrt machine:

Data paths:

      /\
     /  \                                -----------------------
    /    \                               \                     /
   /      \                               \      read         /
  /   1.0  \                               \                 /
 /          \                               \               /
/            \                               ----+---------/
------+-------                                   |
      |    g<-1                                  |
      +----(x)-----+                   +----------
                   |                   |
                   V                   v
          +--------------+       +------+-----+
          |              |       |            |
          |    guess     |       |      x     |
          |              |       |            |
          +----------+---+       +------------+
             |       | ^
             |       | |          g<-i
             |       | +-----------(x)--------+
             V       |                        |
          -------    +--------------+         |
        -/       \-                 V         |
       /           \            --------------+---------
       |good-enough|             \                    /
       \           /              \    improve       /
        -\       /-                \                /
          -------                   \--------------/

Controller:

(controller
 (assign guess (const 1.0))
 (assign x (op read))
test-ge
 (test (op good-enough) (reg guess))
 (branch (label sqr-done))
 (assign guess (op improve) (reg guess))
 (goto (label test-ge))
sqr-done)

Second version of the sqrt machine (without the good-enough and the improve abstractions):

Data paths:

            /\
           /  \
          /    \
         /      \
        /  1.0   \
       /          \
       -----+------
            |
            |
            |
            +-----------------------------+
                                          |
                                          |
                                          |
                                          V
                              ----------------------------                                                          |---------------------------|
                              |                          |                                                          |                           |
                              |                          |                                                          |                           |
                              |         guess            |                                                          |             x             |
                              |                          |                                                          |                           |
                              |                          |                                                          |                           |
                              ----------------------------                                                          |                           |
                                 |                 ^  |                                                             -----------------------------
                                 |                 |  |                                                                          |             |
                                 |                 |  +------------------------------------+                                     |             |
                                 |                 |                                       |                                     |             |
                                 |                 |                                       |          +--------------------------+             |
                                 |                 |                                       |          |                                        |
                                 |                 |                                       |          |                                        |
                                 |                 |                                       V          V                                        |
                                 |                 |                               ------------------------                                    |
                                 V                 |                                \                    /                                     |
                   |-----------------------------  |                                 \        /         /                                      |
                   |                            |  |                                  \                /                                       |
                   |                            |<-+-----------------------------+     \              /     +-----------+                      |
-------------------|          tmp               |  |                             |      --------------      |           |                      |
|                  |                            |--+---------------------+       |            |    |        |           V                      |
|                  |                            |  |                     |       +------------+    +--------+     ------------------------     |
|                  |-----------------------------  |                     |                                         \                    /      |
|                    ^   |   ^  ^  |   |           |                     |                                          \     average      /       |
|          +---------+   |   |  |  |   |           |                     +-----------------------------------------> \                /        |
|          |    +--------+   |  |  |   |           |                                                                  ----------------         |
|          |    |  +---------+  |  |   |           |                                                                         |                 |
|          |    |  |            |  |   |           +-------------------------------------------------------------------------+                 |
|          |    |  |  +---------+  |   +----------------------------------------+                                                              |
|          |    |  |  |            V                                            |                  +-------------------------------------------+
|          |    |  |  | -------------------------------                         V                  V
|          |    |  |  | \                            /                 -------------------------------
|          |    |  |  |  \                          /                  \                             /
|          |    |  |  |   \       square           /                    \                           /
|          |    |  |  |    \                      /                      \           -             /
|          |    |  |  |     \                    /                        \                       /
|          |    |  |  |      --------------------                          \                     /
|          |    |  |  |            |                                         -------------------
|          |    |  |  |            |                                                  |
|          |    |  |  |            |                                                  |
|          |    |  |  +------------+                                                  |
|          |    |  |                                                                  |
|          |    |  |                                                                  |
|          |    |  +------------------------------------------------------------------+
|          |    |
|          |    |
|          |    +---------------------------------+
|          |                                      |
|          |                                      |
|          |                                      V
|          |                           --------------------------
|          |                           |                        |
|          |                           |                        |
|          |                           |        abs             |
|          |                           |                        |
|          |                           |                        |
|          |                           --------------------------
|          |                                       |
|          |                                       |
|          +---------------------------------------+
|
|
|                                                               /\
|                              -------                         /  \
|                            -/       \-                      /    \
|                           /           \                    /      \
|-------------------------> |     <     | <-----------------/        \
                            \           /                  /  0.001   \
                             -\       /-                  /            \
                               -------                    --------------

Controller:

(controller
  (assign guess (const 1.0))
test-ge
  (assign tmp (reg guess))
  (assign tmp (op square) (reg tmp))
  (assign tmp (op -) (reg tmp) (reg x))
  (assing tmp (op abs) (reg tmp))
  (test (op <) (reg tmp) (const 0.001))
  (branch (label sqrt-done))
  (assign tmp (op /) (reg x) (reg guess))
  (assign guess (op average) (reg guess) (reg tmp))
sqrt-done)

Exercise 5.4

Exercise:

Specify register machines that implement each of the following procedures. For each machine, write a controller instruction sequence and draw a diagram showing the data paths.

a. Recursive exponentiation:

(define (expt b n)
  (if (= n 0)
      1
      (* b (expt b (- n 1)))))

b. Iterative exponentiation:

(define (expt b n)
  (define (expt-iter counter product)
    (if (= counter 0)
        product
        (expt-iter (- counter 1) (* b product))))
  (expt-iter n 1))

Answer:

Recursive exponentiation:

;; - example: (expt 2 3); initial values:
;;   - register b is set to 2
;;   - register n is set to 3

(controller
   (assign continue (label fact-done))
 expt-loop
   (test (op =) (reg n) (const 0))
   (branch (label base-case))
   (save continue)
   (save n)
   ;; no need to save b since it always holds the same val
   (assign n (op -) (reg n) (const 1))
   (assign continue (label after-expt))
   (goto (label expt-loop))
 after-expt
   (restore n)
   (restore continue)
   (assign val (op *) (reg b) (reg val))
   (goto continue)
 base-case
   (assign val (const 1))
   (goto (reg continue))
 expt-done)

Iterative exponentiation:

;; - example: (expt 2 3); initial values:
;;   - register b is set to 2
;;   - register counter is set to 3
;;   - register product is set to 1

(controller
 expt-loop
   (test (op =) (reg counter) (const 0))
   (branch expt-done)
   (assign counter (op -) (reg counter) (const 1))
   (assign product (op *) (reg b) (reg product))
   (goto expt-loop)
   expt-done)

Exercise 5.5

Exercise:

Hand-simulate the factorial and Fibonacci machines, using some nontrivial input (requiring execution of at least one recursive call). Show the contents of the stack at each significant point in the execution.

Answer:

  • Relevant contents of the stack when computing the factorial of 5 (the stack grows backwards):

                                                      []
                                           [5|fact-done]
                              [4|after-fact|5|fact-done]
                 [3|after-fact|4|after-fact|5|fact-done]
    [2|after-fact|3|after-fact|4|after-fact|5|fact-done]
                 [3|after-fact|4|after-fact|5|fact-done]
                              [4|after-fact|5|fact-done]
                                           [5|fact-done]
                                                      []
    
  • Relevant contents of the stack when computing the fib of 2:

              []  (starting point)
    [2|fib-done]  (when setting up the computation of fib(n-1))
              []  (before setting up the computation of fib(n-2))
    [1|fib-done]  (setting up the computation of fib(n-2))
              []  (before computing fib(n-1) + fib(n-2))
    

Exercise 5.6

Exercise:

Ben Bitdiddle observes that the Fibonacci machine's controller sequence has an extra `save' and an extra `restore', which can be removed to make a faster machine. Where are these instructions?

Answer:

Those two instructions are the (restore continue) and (save continue) in after-fib-n-2. Here I create a fib-machine without those two instructions and show that it works nonetheless:

;; racket repl in emacs provided by racket-mode.el

repl.rkt> (define fib-machine
            (make-machine
             '(continue n val)
             (list (list '+ +) (list '< <) (list '- -))
             '(
               (assign continue (label fib-done))
               fib-loop
               (test (op <) (reg n) (const 2))
               (branch (label immediate-answer))
               (save continue)
               (assign continue (label afterfib-n-1))
               (save n)
               (assign n (op -) (reg n) (const 1))
               (goto (label fib-loop))
               afterfib-n-1
               (restore n)
               ;; (restore continue) <----------------------------------
               (assign n (op -) (reg n) (const 2))
               ;; (save continue)    <----------------------------------
               (assign continue (label afterfib-n-2))
               (save val)
               (goto (label fib-loop))
               afterfib-n-2
               (assign n (reg val))
               (restore val)
               (restore continue)
               (assign val
                       (op +) (reg val) (reg n))
               (goto (reg continue))
               immediate-answer
               (assign val (reg n))
               (goto (reg continue))
               fib-done)))
repl.rkt> (set-register-contents! fib-machine 'n 4)
'done
repl.rkt> (start fib-machine)
'done
repl.rkt> (get-register-contents fib-machine 'val)
3
repl.rkt> (set-register-contents! fib-machine 'n 5)
'done
repl.rkt> (start fib-machine)
'done
repl.rkt> (get-register-contents fib-machine 'val)
5
repl.rkt> (set-register-contents! fib-machine 'n 6)
'done
repl.rkt> (start fib-machine)
'done
repl.rkt> (get-register-contents fib-machine 'val)
8
repl.rkt>

Send me an email for comments.

Created with Emacs 30.0.60 (Org mode 9.7.9)