開発環境
- OS X Mavericks - Apple(OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- Scheme (プログラミング言語)
- Gauche (処理系)
計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の2(データによる抽象の構築)、2.1(データ抽象入門)、2.1.4(拡張問題: 区間算術演算)、問題 2.9.を解いてみる。
その他参考書籍
- Instructor's Manual to Accompany Structure & Interpretation of Computer Programs
- プログラミングGauche (Kahuaプロジェクト (著), 川合 史朗 (監修), オライリージャパン)
問題 2.9.
区間の幅の定義。
(define (width x) (/ (- (upper-bound x) (lower-bound x)) 2))
区間x、yの和
(make-interval (+ (lower-bound x) (lower-bound y)) (+ (upper-bound x) (upper-bound y)))
区間x、yの和の幅
(/ (- (+ (upper-bound x) (upper-bound y)) (+ (lower-bound x) (lower-bound y))) 2) (/ (+ (- (upper-bound x) (lower-bound x)) (- (upper-bound y) (lower-bound y))) 2) (+ (/ (- (upper-bound x) (lower-bound x)) 2) (/ (- (upper-bound y) (lower-bound y)) 2)) (+ (width x) (width y))
よって、区間x、yの和の幅は、区間x、yの幅だけの関数である。
区間x、yの差
(make-interval (- (lower-bound x) (upper-bound y)) (- (upper-bound x) (lower-bound y)))
区間x、yの差の幅
(/ (- (- (upper-bound x) (lower-bound y)) (- (lower-bound x) (upper-bound y))) 2) (/ (+ (- (upper-bound x) (lower-bound x)) (- (upper-bound y) (lower-bound y))) 2) (+ (/ (- (upper-bound y) (lower-bound y)) 2) (/ (- (upper-bound x) (lower-bound x)) 2)) (+ (width y) (width x))
よって、区間x、yの差の幅は、区間x、yの幅だけの関数である。
区間x、yの積の幅について。
xを[0, 10]、yを[0、20]とすると、区間x、yの積は[0, 200]、幅は100。
xを[10, 20]、yを[10, 30]とすると、区間x、yの積は[100, 600]、幅は250。
幅が同じ区間の積の幅が異なっているので、積では区間の幅だけの関数にはならない。
xを[0, 10]、yを[0、20]とすると、区間x、yの商は区間[0, 10]と区間[1/20, -∞]の積、すなわち[-∞, 1/2]。
xを[10, 20]、yを[10, 30]とすると、区間x、yの商は区間[10, 20]と区間[1/30, 1/10]の積、すなわち[1/3, 2]。
幅が同じ区間の商の幅が異なっているので、商では区間の幅だけの関数にはならない。
和、差の場合は成り立つことと、乗算、除算では成り立たないことを確認。
コード(BBEdit, Emacs)
sample.scm
#!/usr/bin/env gosh ;; -*- coding: utf-8 -*- ;; これまでに書いた手続き (load "./procedures.scm") ;; 区間の幅 (define (width x) (/ (- (upper-bound x) (lower-bound x)) 2)) (define i1 (make-interval 0 5)) (define i2 (make-interval 0 10)) (define i3 (make-interval 5 10)) (define i4 (make-interval 5 15)) (define intervals (list i1 i2 i3 i4)) (print "和") (for-each (lambda (i1) (for-each (lambda (i2) (print (width i1) ", " (width i2) ": " (width (add-interval i1 i2)))) intervals)) intervals) (print "差") (for-each (lambda (i1) (for-each (lambda (i2) (print (width i1) ", " (width i2) ": " (width (sub-interval i1 i2)))) intervals)) intervals) (print "積") (for-each (lambda (i1) (for-each (lambda (i2) (print (width i1) ", " (width i2) ": " (width (mul-interval i1 i2)))) intervals)) intervals) (print "商") (for-each (lambda (i1) (for-each (lambda (i2) (print (width i1) ", " (width i2) ": " (width (div-interval i1 i2)))) intervals)) intervals)
入出力結果(Terminal(gosh), REPL(Read, Eval, Print, Loop))
$ ./sample.scm 和 5/2, 5/2: 5 5/2, 5: 15/2 5/2, 5/2: 5 5/2, 5: 15/2 5, 5/2: 15/2 5, 5: 10 5, 5/2: 15/2 5, 5: 10 5/2, 5/2: 5 5/2, 5: 15/2 5/2, 5/2: 5 5/2, 5: 15/2 5, 5/2: 15/2 5, 5: 10 5, 5/2: 15/2 5, 5: 10 差 5/2, 5/2: 5 5/2, 5: 15/2 5/2, 5/2: 5 5/2, 5: 15/2 5, 5/2: 15/2 5, 5: 10 5, 5/2: 15/2 5, 5: 10 5/2, 5/2: 5 5/2, 5: 15/2 5/2, 5/2: 5 5/2, 5: 15/2 5, 5/2: 15/2 5, 5: 10 5, 5/2: 15/2 5, 5: 10 積 5/2, 5/2: 25/2 5/2, 5: 25 5/2, 5/2: 25 5/2, 5: 75/2 5, 5/2: 25 5, 5: 50 5, 5/2: 50 5, 5: 75 5/2, 5/2: 25 5/2, 5: 50 5/2, 5/2: 75/2 5/2, 5: 125/2 5, 5/2: 75/2 5, 5: 75 5, 5/2: 125/2 5, 5: 100 商 5/2, 5/2: +inf.0 5/2, 5: +inf.0 5/2, 5/2: 0.5 5/2, 5: 0.5 5, 5/2: +inf.0 5, 5: +inf.0 5, 5/2: 1.0 5, 5: 1.0 5/2, 5/2: +inf.0 5/2, 5: +inf.0 5/2, 5/2: 0.75 5/2, 5: 0.8333333333333334 5, 5/2: +inf.0 5, 5: +inf.0 5, 5/2: 1.25 5, 5: 1.3333333333333333 $
0 コメント:
コメントを投稿