2.1.4 拡張問題:区間算術演算(1)

Alyssaの最初の仮定は、抵抗の上限値と下限値を「区間オブジェクト」として扱うことです。二つの抵抗の区間の和を求める場合(R1 + R2)は、それぞれの上限値と下限値を足した値を、合成区間オブジェクトの上限値と下限値としています。二つの抵抗の区間の積(R1 * R2)は、それぞれの上限値・下限値の積の中での最小値と最大値が求めたい結果となります。「R1 / R2」の場合は、R2の逆数とR1を掛け合わしています。
問題2-7は、一つの区間オブジェクトから、上限値と下限値を取得するための手続きを定義する問題です。make-intervalの第一引数が下限値、第二引数が上限値だと仮定しています。

(define (make-interval a b) (cons a b))

(define (upper-bound r) (cdr r))

(define (lower-bound r) (car r))

問題2-8では、二つの抵抗の区間の差を求める(R1 - R2)を求める手続きを作成します。R1とR2の大小を考慮すべきかどうかはわかりませんが、とりあえず単純にR1からR2へ、それぞれの上限値・下限値を引く手続きを書きました。

(define (sub-interval x y)
  (make-interval (- (lower-bound x) (lower-bound y))
                 (- (upper-bound x) (upper-bound y))))

問題2-9では、「区間の幅」を取り扱っています。ここでは、「区間の幅」を区間の上限値と下限値の差の半分と定義されています。例えば、以下のようになると考えられます。

  • 10パーセントの許容誤差で6.8オーム(R1)
    • 上限値は、6.8 + 0.68 = 7.48
    • 下限値は、6.8 - 0.68 = 6.12
    • 区間の幅は、(7.48 - 6.12) / 2 = 0.68
  • 10パーセントの許容誤差で4.7オーム(R2)
    • 上限値は、4.7 + 0.47 = 5.17
    • 下限値は、4.7 - 0.47 = 4.23
    • 区間の幅は、(5.17 - 4.23) / 2 = 0.47

この二つの抵抗の区間を足した場合、上限値は12.65、下限値は10.35となり、区間の幅は(12.65 - 10.35) / 2 = 1.15となります。この値は、上記二つの抵抗の「区間の幅」と一致しています。一方、区間の積の場合はどうかを調べてみると、

  • 上限値は、38.6716
  • 下限値は、25.8876
  • 区間の幅は、(38.6716 - 25.8876) / 2 = 6.392

となります。元の抵抗の区間の幅を単純に掛け合わせると、0.68 * 0.47 = 0.3196になり、区間の積を求めた後の区間の幅と一致しません。よって、区間の幅だけによる関数は作れないということが言えます。
問題2-10では、Ben Bitdiddleからゼロを跨がる区間について調べよという指令が出されます。というわけで、

  • 20パーセントの許容誤差で5オーム(R3)
    • 上限値は、5.0 + 1.0 = 6.0
    • 下限値は、5.0 - 1.0 = 4.0

という抵抗があると仮定して、R2との差分を取ることでゼロを跨がる区間オブジェクトを生成します。この場合区間の差は、上限値が0.83で、下限値が-0.23となります。この区間オブジェクトをR4とし、「R4 / R1」と「R1 / R4」を計算してみます。

  • R4 / R1
    • 上限値は、0.13562091503267976
    • 下限値は、-0.037581699346405296
  • R1 / R4
    • 上限値は、9.012048192771084
    • 下限値は、-32.521739130434725

これらの値が正しいのかどうかを判別するところまでは考えられていません。まだ取り組んでいませんが問題2-11との兼ね合いもあると考えられます。上限値と下限値が逆転してしまうのが問題だとは思うのですが、このあたりについては後日考察してみようと思います。