Chapter 2.1
Exercise 2.1
(define (make-rat n d)
(define (cons-rat n d)
(let ((g (gcd n d))) (cons (/ n g) (/ d g))))
(if (< (* n d) 0) (cons-rat (- (abs n)) (abs d))
(cons-rat (abs n) (abs d))))
Exercise 2.2
(define (average x y) (/ (+ x y) 2))
(define (make-segment p q) (cons p q))
(define (start-segment seg) (car seg))
(define (end-segment seg) (cdr seg))
(define (make-point x y) (cons x y))
(define (x-point p) (car p))
(define (y-point p) (cdr p))
(define (midpoint-segment s)
(let ((p (start-segment s))
(q (end-segment s)))
(make-point (average (x-point p) (x-point q))
(average (y-point p) (y-point q)))))
Exercise 2.3
Exercise 2.4
; cons,car,cdrを手続きで表現する
(define (cons2 x y) (lambda (m) (m x y)))
(define (car2 z) (z (lambda (a d) a)))
(define (cdr2 z) (z (lambda (a d) d)))
Exercise 2.5
- 非負整数のペアを
で表現する
(define (count-factor factor num cnt)
(if (= (remainder num factor) 0)
(count-factor factor (/ num factor) (+ cnt 1)) cnt))
(define (cons3 a b)
(if (and (> a 0) (> b 0)) (* (expt 2 a) (expt 3 b)) 0))
(define (car3 z) (count-factor 2 z 0))
(define (cdr3 z) (count-factor 3 z 0))
Exercise 2.6
(define zero (lambda (f) (lambda (x) x)))
(define (succ n) (lambda (f) (lambda (x) (f ((n f) x)))))
; (succ zero)
; (lambda (f) (lambda (x) (f ((zero f) x))))
; (lambda (f) (lambda (x) (f ((lambda (x) x) x))))
(define one (lambda (f) (lambda (x) (f x))))
; (succ one)
; (lambda (f) (lambda (x) (f ((one f) x))))
; (lambda (f) (lambda (x) (f ((lambda (x) (f x)) x))))
(define two (lambda (f) (lambda (x) (f (f x)))))
; PLUS := λm n f x. m f (n f x)
(define (plus m n)
(lambda (f) (lambda (x) ((m f) ((n f) x)))))
; ついで, Church数から普通の整数に変換
(define (church-to-number n)
(define (inc x) (+ x 1))
((n inc) 0))
- Church numeral
- ラムダ計算
- 0 := λfx.x == λf.(λx.x)
- 1 := λfx.fx
- 2 := λfx.f(fx)
- succ := λnfx.f((n f) x)
- nとは, fを受け取ってfをn回適用する手続き
Exercise 2.7
(define (l-b i) (min (car i) (cdr i)))
(define (u-b i) (max (car i) (cdr i)))
;(car i)<(cdr i)の関係が保証されているとするなら
(define (lower-bound i) (car i)) (define (upper-bound i) (cdr i))
Exercise 2.8
(define (sub-interval x y)
(add-interval x (make-interval
(* -1 (upper-bound y)) (* -1 (lower-bound y)))))
Exercise 2.9
(define (width x) (/ (- (upper-bound x) (lower-bound x)) 2))
和差
- x1 := [l1,u1], x2 := [l2,u2]
- width(x1)+width(x2) = (u1-l1)/2 + (u2-l2)/2
- x1 + x2 = [l1+l2,u1+u2]
- width(x1+x2)={(u1+u2)-(l1+l2)}/2=(u1-l1)/2 + (u2-l2)/2
- x1 - x2 = [l1-u2,u1-l2]
- width(x1-x2)={(u1-l2)-(l1-u2)}/2=(u1-l1)/2 + (u2-l2)/2
積商
- x1 := [6,8], x2 := [1,2]
- width(x1)=1, width(x2)=1/2
- x1 * x2 = [6,16]
- width(x1 * x2) = (16-6)/2 = 5
- width(x1) * width(x2) = 1/2
- x1 / x2 = [3,8]
- width(x1 / x2) = (8-3)/2 = 5/2
- width(x1) / width(x2) = 2
Exercise 2.10
(define (div-interval x y)
(define span (and (<= (lower-bound y) 0) (<= 0 (upper-bound y))))
(if span
(error "perhaps division by zero")
(mul-interval x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y))))))
Exercise 2.11
Exercise 2.12
; intervalをcenterと誤差(percent)で定義する
;
(define (make-center-percent c per)
(let ((err (/ (* c per) 100.0)))
(make-interval (- c err) (+ c err))))
(define (center i) (/ (+ (upper-bound i) (lower-bound i)) 2))
(define (width i) (/ (- (upper-bound i) (lower-bound i)) 2))
(define (percent i) (/ (* 100.0 (width i)) (center i)))
Exercise 2.13
演算結果はそれぞれ次のものと同値
;par1
(make-interval (/ (* (lower-bound r1) (lower-bound r2)) (+ (upper-bound r1) (upper-bound r2)))
(/ (* (upper-bound r1) (upper-bound r2)) (+ (lower-bound r1) (lower-bound r2))))
;par2
(make-interval (/ (* (lower-bound r1) (lower-bound r2)) (+ (lower-bound r1) (lower-bound r2)))
(/ (* (upper-bound r1) (upper-bound r2)) (+ (upper-bound r1) (upper-bound r2))))