5

Iteration

5.1.   Modeling Systems

5.1.2.   Iterative Evaluation

(define (count-down n)
   (do ((i n (- i 1))      ; declaration
       ((< i 0) 'blast-off!)   ; exit clause
       (display i)      ; body
       (newline)))      ; body

5.1.3.   Control Loops

(define (control-loop init-state)
   (do ((state init-state (update state)))
       ((final? state) state)))

(define (control-loop init-state final? update)
   (do ((state init-state (update state)))
       ((final? state) state)))

(define
   (control-loop init-state final? update . trace)
      (do ((state init-state (update state))
           (cycle 0 (+ cycle 1)))
           ((final? state) state)
           (if (not (null? trace))                         
            (begin
             (writeln "cycle = " cycle)
             (writeln "state = " state)))))

5.1.4.   Example: A Digital Clock

(define (make-time hour min sec)
   (vector hour min sec))

(define (hour time) (vector-ref time 0))
(define (minute time) (vector-ref time 1))
(define (second time) (vector-ref time 2))

; = time 1 second after input time
(define (update-time time)
   (update-hour (update-min (update-sec time))))

(define (update-sec time)
   (make-time (hour time)
         (minute time)
         (mod60+ 1 (second time))))

(define (update-min time)
   (if (zero? (second time))
       (make-time (hour time)
            (mod60+ 1 (minute time))
            (second time))
          time))

(define (update-hour time)
   (if (and (zero? (minute time))
       (zero? (second time)))
      (make-time (mod24+ 1 (hour time))
            (minute time)
            (second time))
          time))

(define (mod24+ x y) (modulo (+ x y) 24))
(define (mod60+ x y) (modulo (+ x y) 60))

(define (alarm? time)
   (and (= (hour time) 6)
       (= (minute time) 30)
       (= (second time) 0)))

5.1.5.   Example: Compound Interest

(define (new-debt debt)
   (round (- (* debt rate+1) pmt)))

(define rate+1 (+ 1 rate))

(define (paid? debt) (< debt pmt))

5.1.6.   Example: A Simple Interactive System

; = new value of count
(define (exec-cmmd count)

   ; prompt user and read command
   (define cmmd (get-cmmd))

   (case cmmd
      ((inc) (modulo (+ count 1) max-int))
      ((dec) (modulo (- count 1) max-int))
      ((get) (writeln "count = " count) count)
      ((set) 0)
      ((q quit exit) 'bye)
      (else
         (writeln "unrecognized command: " cmmd)
         count)))

; prompts user & returns command read
(define (get-cmmd)
   (writeln "command menu: ")
   (writeln #\tab "inc" #\tab "increments count")
   (writeln #\tab "dec" #\tab "decrements count")
   (writeln #\tab "get" #\tab "displays count")
   (writeln #\tab "set" #\tab "resets count to 0")
   (writeln #\tab "quit" #\tab "to quit")
   (display "command-> ")
   (read))

(define (bye? state) (eq? state 'bye))

5.1.7.   Example: Guess and Test

Solving Equations

; = #t if guess is small, i.e. close to 0
(define (good-enuf? guess)
   (<= (abs (f guess)) delta))

(define delta 1e-10)

; = a better guess at f's solution than input
(define (improve guess)
   (- guess (/ (f guess) (df guess))))

(define (df x)
   (/ (- (f (+ x delta)) (f x)) delta))

Computing Square Roots

(define (f x) (- (* x x) n))

(define (sqrt n)

   (define (f x)
      (- (* x x) n))

   (define delta 0.00001)

   (define (df x)
      (/ (- (f (+ x delta)) (f x)) delta))

   (define (good-enuf? guess)
      (< (abs (f guess)) delta))

   (define (improve guess)
      (- guess (/ (f guess) (df guess))))

   (control-loop 1 good-enuf? improve))

Computing Nth Roots

(define (solve f)

   (define delta 0.00001)

   (define (df x)
      (/ (- (f (+ x delta)) (f x)) delta))
   (define (good-enuf? guess)
      (< (abs (f guess)) delta))

   (define (improve guess)
      (- guess (/ (f guess) (df guess))))

   (control-loop 1 good-enuf? improve))

(define (cube-root n)

   (define (f x)
      (- (* x x x) n))

   (solve f))

5.2.   Computations as Data

5.2.1.   Predicting the Future

(define init-state 1)   ; = size of initial population

; = population after one reproductive cycle
(define (update state) (* 2 state))

; = state of system S after n cycles
(define (state n)
   (if (zero? n)
       init-state
       (update (state (- n 1)))))

5.2.2.   Measuring Computations

5.2.3.   Measuring Efficiency

5.2.4.   The Tyranny of Growth Rate

5.3.   Finding Iterative Solutions

(define (state n)
   (do ((count 0 (+ count 1))
       (result init-state (update result)))
       ((<= n count) result)))

; = the length n list (val ... val)
(define (make-list n val)
   (if (not (natural? n))
       (error "bad input" make-list n)
       (do ((count 0 (+ count 1))
            (result '() (cons val result)))
          ((<= n count) result))))

; = b^n
(define (nat-expt b n)
   (if (not (and (number? b) (natural? n)))
       (error "bad input(s)" nat-expt b n)
       (do ((count 0 (+ count 1))
            (result 1 (* b result)))
          ((<= n count) result))))

5.4.   Tail Recursion: Are do-loops Necessary?

(define (iter count result)
   (if (<= n count)
       result
       (iter (+ count 1) (update result))))

(define (control-loop init final? update)

   (define (iter state)
      (if (final? state)
          state
          (iter (update state))))

   (iter init))

(define (state n)

   (define (iter count result)      
      (if (>= count n)
          result
          (iter (+ count 1) (update result))))

   (if (not (natural? n))
       (error "bad input" state n)
       (iter 0 1)))

; = the length n list (val ... val)
(define (make-list n val)

   (define (iter count result)
      (if (<= n count)
          result
          (iter (+ count 1) (cons val result))))

   (if (not (natural? n))
       (error "bad input" make-list n)
       (iter 0 '())))

; = b^n
(define (nat-expt b n)

   (define (iter count result)
      (if (<= n count)
          result
          (iter (+ count 1) (* b result))))

   (if (not (and (number? b) (natural? n)))
       (error "bad input(s)" nat-expt b n)
       (iter 0 1)))

5.5.   Finding Elementary Solutions

(define init-state 1)   ; = initial state of system S

; = next state of system S
(define (update state)
   (- (* 4 state) 1))

; = state of system S after n cycles
(define (state n)
   (if (zero? n)
       init-state
       (update (state (- n 1)))))

; = next state of system S after n cycles
(define (state n) (/ (expt 2 (+ (* 2 n) 1)) 3))

Appendices

Appendix 5.1.    The Hyper Exponential Hierarchy

; = 2^n
(define (exp2 n)
   (if (zero? n)
       1
       (double (exp2 (- n 1)))))

(define (double n) (* 2 n))

(define (hyper-exp n)
   (if (zero? n)
       1
       (exp2 (hyper-exp (- n 1)))))

(define (hyper^2-exp n)
   (if (zero? n)
       1
       (hyper-exp (hyper^2-exp (- n 1)))))

(define (hyper^3-exp n)
   (if (zero? n)
       1
       (hyper^2-exp (hyper^3-exp (- n 1)))))

; = hyper^m-exp n)
(define (exp* m n)
   (cond ((zero? n) 1)
         ((zero? m) (exp2 n))
         (else (exp* (- m 1) (exp* m (- n 1))))))

(define (ack n) (exp* n n))

(define (hyper-ack n)
   (if (zero? n)
       1
       (ack (hyper-ack (- n 1)))))

Appendix 5.2.    Undecidability

(define (diag proc)
   (if (convergent? proc proc)
       (undef)
       'done))

(define (undef) (undef))   ; runs forever

(define (id p) p)   ; the identity procedure

Appendix 5.3.    Chaos

Example: The Devil's Pitchfork

; = next state of system S
(define (logistic state)
   (* const (- 1 state) state))

; = displays attractor of logistic procedure
(define (show-log-attractor const)

   ; the logistic function
   (define (logistic state)
      (* const (- 1 state) state))

   ; 0 <= init-state <= 1 & init-state <> .5
   (define init-state .2)

   ; control-loop:
   (do ((cycle 0 (+ cycle 1))
       (state init-state (logistic state)))
       ((> cycle 520) 'done)
       (if (> cycle 500)
          (show-state const state))))

(define (show-state const state)
   (display (cons const state))
   (newline))

(define (show-state const state)
   (put-pixel (cons const state) 'white))

(define (pitchfork start finish)

   (define slices 75)   ; # of attractors shown

   (define delta (/ (- finish start) slices))

   (init-graph)      ; enter graphics mode

   (do ((const start (+ const delta)))
       ((< finish const) ‘done)
       (show-log-attractor const)))

Problems