λ1.1節

問題 1.1  問題 1.2  問題 1.3  問題 1.4  問題 1.5 
問題 1.6  問題 1.7  問題 1.8 

問題 1.1
10 ==> 10

(+ 5 3 4) ==> 12

(- 9 1) ==> 8

(/ 6 2) ==> 3

(+ (* 2 4) (- 4 6)) ==> 6

(define a 3)

(define b (+ a 1))

(+ a b (* a b)) ==> 19

(= a b) ==> false

(if (and (> b a) (< b (* a b)))
    b
    a) ==> 4

(cond ((= a 4) 6)
      ((= b 4) (+ 6 7 a))
      (else 25)) ==> 16

(+ 2 (if (> b a) b a)) ==> 6

(* (cond ((> a b) a)
         ((< a b) b)
         (else -1))
   (+ a 1)) ==> 16
問題 1.2
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
   (* 3 (- 6 2) (- 2 7)))
問題 1.3
(define (sumsqr a b c)
 (cond ((and (>= b a) (>= c a)) (+ (* b b) (* c c)))
       ((and (>= c b) (>= a b)) (+ (* c c) (* a a)))
       ((and (>= a c) (>= b c)) (+ (* a a) (* b b)))))

または
(define (sumsqr a b c)
 (if (> a b) 
     (+ (* a a) (if (> b c) (* b b) (* c c)))
     (+ (* b b) (if (> a c) (* a a) (* c c)))))

または
(define (sumsqr a b c)
 (+ (* a a) (* b b) (* c c) 
    (- (* (min a b c) (min a b c)))))
問題 1.4
(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))
の本体は, まず演算子のif式が最初に評価され, b>0なら+, そうでなければ-が返る. 
従って本体の式は b>0 なら (+ a b) そうでなければ (- a b)となる.
例えば
(a-plus-abs-b 3 5) ==> 8
(a-plus-abs-b 3 -5) ==> 8
問題 1.5
作用的順序で(test 0 (p))を評価すると, 引数0と(p)の評価にとりかかる. pは(p)と定
義されているから, この評価は終らない. 従って(test 0 (p))の評価も終らない.

一方, 正規的順序の評価では, xとyは評価されないままtestに渡される. 

testの中のif式の述語(= x 0)の評価でxが必要になった時にxが評価され, xは0であるこ
とが分り, 述語は真となり, 帰結部0が返される. yは評価されない.
問題 1.6
述語(good-enough? guess x)が真になっても, new-ifは代替部
(sqrt-iter (impreve guess x) x)
を評価しようとするので, 停止しない. 
問題 1.7
本文にあるsqrtのプログラムでは

(sqrt 2) ==> 1.4142156862745097

(sqrt 0.02) ==> .1444238094866232

(sqrt 0.0002) ==> .03335281609280434

また大きい方は

(sqrt 200000000000000000000) good-enough?が真にならず停止しなくなる. 
そこで相対誤差による評価に変更する. 

(define (sqrt x)
  (define (improve guess)
    (define (average x y)
      (/ (+ x y) 2))
    (average guess (/ x guess)))
  (define (sqrt-iter last-guess next-guess)
    (define (good-enough?)
      (< (abs (/ (- last-guess next-guess) next-guess))
         0.001))
    (if (good-enough?)
        next-guess
        (sqrt-iter next-guess (improve next-guess))))
  (sqrt-iter 1.0 (improve 1.0)))

この改良プログラムでは

(sqrt 0.0002) ==> 1.4142135623738401e-2

(sqrt 0.000002)  ==> 1.4142135626178485e-3

(sqrt 20000000000000000.0)  ==> 141421356.23732778

と無事に計算出来る. 

問題 1.8
(define (cube-root x)
  (define (good-enough? guess x)
    (< (abs (- (* guess guess guess) x)) 0.001))
  (define (improve guess x)
    (/ (+ (/ x guess guess) guess guess) 3))
  (define (cube-root-iter guess x)
    (if (good-enough? guess x)
        guess
        (cube-root-iter (improve guess x) x)))
  (cube-root-iter 1.0 x))

(cube-root 8)  ==> 2.000004911675504

(cube-root 1729)  ==> 12.00231441503121