SICP 読み (56) 2.5.1 汎用算術演算

とりあえず、提示されているコードの試験を検討。
まず、make-scheme-number から。以下が確認できれば OK か。

  • 戻されるリストの car は 'scheme-number であること
  • 戻されるリストの cdr は make-scheme-number に渡した値であること

で、以下。

#!/usr/bin/env gosh

(use test.unit)
(require "2.5.1")

(define-test-suite "2.5.1"

 ("make-scheme-number test"
  (setup (lambda () (install-scheme-number-package)))
  ("make-scheme-number test"
   (assert-equal 'scheme-number (car (make-scheme-number 5)))
   (assert-equal '5 (cdr (make-scheme-number 5)))
   )
 )
)

当たり前ですが試験パス。次は各演算について。

  • 戻されるリストの car が 'scheme-number であること
  • 戻されるリストの cdr が 演算結果と同じ値であること

になるのかな?? add だと以下か。

 ("add test"
  (setup (lambda () (install-scheme-number-package)))
  ("add test"
   (assert-equal 'scheme-number (car (add (make-scheme-number 1)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (add (make-scheme-number 1)
                             (make-scheme-number 2))))
   )
  )

他も同様に。

 ("sub test"
  (setup (lambda () (install-scheme-number-package)))
  ("add test"
   (assert-equal 'scheme-number (car (sub (make-scheme-number 5)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (sub (make-scheme-number 5)
                             (make-scheme-number 2))))
   )
  )

 ("mul test"
  (setup (lambda () (install-scheme-number-package)))
  ("add test"
   (assert-equal 'scheme-number (car (mul (make-scheme-number 3)
                                          (make-scheme-number 2))))
   (assert-equal 6 (cdr (mul (make-scheme-number 3)
                             (make-scheme-number 2))))
   )
  )

 ("div test"
  (setup (lambda () (install-scheme-number-package)))
  ("add test"
   (assert-equal 'scheme-number (car (div (make-scheme-number 6)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (div (make-scheme-number 6)
                             (make-scheme-number 2))))
   )
  )

ってこれ、こんな形でコード載せてるとすごい量になりそうだ。
ま、いいや。次は有理数か。先に試験を書いてしまえ。
あ、これって試験はまとめて以下のような感じで書けるな。

(define-test-suite "2.5.1"

 ("scheme-number test"
  (setup (lambda () (install-scheme-number-package)))
  ("make-scheme-number test"
   (assert-equal 'scheme-number (car (make-scheme-number 5)))
   (assert-equal '5 (cdr (make-scheme-number 5)))
   )

  ("add test"
   (assert-equal 'scheme-number (car (add (make-scheme-number 1)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (add (make-scheme-number 1)
                             (make-scheme-number 2))))
   )

  ("sub test"
   (assert-equal 'scheme-number (car (sub (make-scheme-number 5)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (sub (make-scheme-number 5)
                             (make-scheme-number 2))))
   )

  ("mul test"
   (assert-equal 'scheme-number (car (mul (make-scheme-number 3)
                                          (make-scheme-number 2))))
   (assert-equal 6 (cdr (mul (make-scheme-number 3)
                             (make-scheme-number 2))))
   )

  ("div test"
   (assert-equal 'scheme-number (car (div (make-scheme-number 6)
                                          (make-scheme-number 2))))
   (assert-equal 3 (cdr (div (make-scheme-number 6)
                             (make-scheme-number 2))))
   )
  )
)

試験の書き方としてはどちらが良いのだろうか。上記の場合だと test-case がいっこだけ、という風になってしまうな。

$ test/run-test.scm -vv
- (test suite) 2.5.1
-- (test case) scheme-number test: .....

5 tests, 10 assertions, 10 successes, 0 failures, 0 errors
Testing time: 0.001067
$

とりあえずこの書き方で以下。

 ("rational test"
  (setup (lambda () (install-rational-package)))
  ("make-scheme-rational test"
   (assert-equal 'rational (car (make-rational 1 5)))
   (assert-equal '1 (cadr (make-rational 1 5)))
   (assert-equal '5 (cddr (make-rational 1 5)))
   )

  ("add test"
   (assert-equal 'rational (car (add (make-rational 1 3)
                                     (make-rational 2 5))))
   (assert-equal 11 (cadr (add (make-rational 1 3)
                              (make-rational 2 5))))
   (assert-equal 15 (cddr (add (make-rational 1 3)
                               (make-rational 2 5))))
   )

  ("sub test"
   (assert-equal 'rational (car (sub (make-rational 1 2)
                                     (make-rational 1 3))))
   (assert-equal 1 (cadr (sub (make-rational 1 2)
                              (make-rational 1 3))))
   (assert-equal 6 (cddr (sub (make-rational 1 2)
                              (make-rational 1 3))))
   )

  ("mul test"
   (assert-equal 'rational (car (mul (make-rational 2 3)
                                     (make-rational 1 2))))
   (assert-equal 1 (cadr (mul (make-rational 2 3)
                             (make-rational 1 2))))
   (assert-equal 3 (cddr (mul (make-rational 2 3)
                             (make-rational 1 2))))
   )

  ("div test"
   (assert-equal 'rational (car (div (make-rational 1 6)
                                     (make-rational 1 2))))
   (assert-equal 1 (cadr (div (make-rational 1 6)
                              (make-rational 1 2))))
   (assert-equal 3 (cddr (div (make-rational 1 6)
                              (make-rational 1 2))))
   )
  )

1/3 と 2/5 の和を 8/15 としていた (恥

それは良いとして試験はパス。次は複素数ですが、これは 2.4.3 のソレを持ってこないといけない模様。で、試験の検討をば。

と言いつつ、complex な試験、以下のパターンを盛り込もうとして力尽きつつある。

  • rectangular と rectangular
  • polar と polar
  • rectangular と polar
  • polar と rectangular

現時点で sub までは上記のパターンの試験が書けた。assert してる値が本当に正しいのかどうなのかも微妙。
駄目だ。パワーないなぁ。るりま方面へのナニとか言ってるが、こんなんじゃ以前の本のレビューみたいになるのは火を見るより明らかそげ。

次の問題 2.77 もオモロそうなんですがねぇ。