SICP問題1.18

(define (square n)
  (* n n))
(define (double n)
  (+ n n))
(define (halve n)
  (/ n 2))
(define (even? n)
  (= (remainder n 2) 0))

; 1.16 のべき乗
(define (my-expt b n)
  (define (my-iter-expt b n a)
    (cond ((= n 0) a)
          ((even? n) (my-iter-expt (square b) (/ n 2) a))
          (else (my-iter-expt b (- n 1) (* b a))))
  )
(my-iter-expt b n 1)
)
; 1.17 の乗算
(define (my-* x y)
  (cond ((= y 0) 0)
        ((even? y) (double (my-* x (halve y))))
        (else (+ x (my-* x (- y 1)))))
)

これらの結果を使用して加算, 二倍, 二分による対数的ステップ数の二つの整数を乗算を行う反復的プロセスを工夫せよ。とのことなので

(define (my-iter-* x y)
  (define (iter x y a)
    (cond ((= y 0) a)
          ((even? y) (iter (double x) (halve y) a))
          (else (iter x (- y 1) (+ a x))))
  )
  (iter x y 0)
)

んーと1.16関係ないような気が…。

SICP問題1.19

T^1 の時の a
  bq + aq + ap
T^2 の時の a
(bp + aq)q + (bq + aq + ap)q + (bq + aq + ap)p
= bpq + a(q^2) + b(q^2) + a(q^2) + apq + bpq + apqq + a(p^2)
= 2a(q^2) + 2apq + 2bpq + b(q^2) + a(p^2)
= b((q^2) + 2pq)) + a((q^2) + 2pq) + a((p^2) + (q^2))

T^1 の時の b
  bp + aq
T^2 の時の b
(bp + aq)p + (bq + aq + ap)q
= b(p^2) + apq + b(q^2) + a(q^2) + apq
= a(q^2) + 2apq + b(p^2) + b(q^2)
= b((p^2) + (q^2)) + a((q^2) + 2pq)

よって
p' = (p^2) + (q^2)
q' = (q^2) + 2pq

このことから定義する手続きは

(define (fib n)
  (fib-iter 1 0 0 1 n)
)
(define (fib-iter a b p q count)
  (cond ((= count 0) b)
        ((even? count)
         (fib-iter a
                   b
                   (+ (square p) (square q))
                   (+ (square q) (double (* p q)))
                   (/ count 2)))
        (else (fib-iter (+ (* b q) (* a q) (* a p))
                        (+ (* b p) (* a q))
                        p
                        q
                        (- count 1))))
)

となる。