記号代数にゼロ判定を実装

暇なので SICP の復習の続きでもやりますか。ゲームばっかやってたらダメダメですw

問題 2.87

polynomial パッケージの I/F に =zero? 手続きを追加します。ゼロ判定手続きから =zero? を呼び出さないといけないので、手続き名は =zero-polynomial? にしておきます。同じ名前でも本来は問題ないのですが、同じ名前にすると内部のゼロ判定手続きから generic な =zero? 手続きが呼び出せなくなってしまうからです。

  ;; システムの他の部分とのインターフェース
  (put '=zero? '(polynomial)
       (lambda (p) (=zero-polynomial? p)))

同パッケージの内部手続きとして =zero-polynomial? を実装します。多項式の各項の係数がすべて 0 ならば、多項式全体としてゼロと判定すれば良いでしょう。

  ;; 内部手続き
  (define (=zero-polynomial? p)
    (define (iter t)
      (cond ((empty-termlist? t) #t)
            ((not (=zero? (coeff (first-term t)))) #f)
            (else (iter (rest-terms t)))))
    (iter (term-list p)))

実装は以上です。動作をみてみます。単純な多項式から。

gosh> (=zero? (make-polynomial 'x '((2 3) (1 4) (0 5))))
#f
gosh> (=zero? (make-polynomial 'x '((2 0) (1 0) (0 0))))
#t

次は多項式の係数に多項式を含む場合です。リストの生成にアポストロフィ「'」を使ってしまうと係数に手続きが書けなくなってしまうので、 list 手続きを使います。

gosh> (=zero? (make-polynomial 'x (list (list 2 (make-polynomial 'x (list (list 2 1) (list 1 2)))))))
#f
gosh> (=zero? (make-polynomial 'x (list (list 2 (make-polynomial 'x (list (list 2 0) (list 1 0)))))))
#t

多項式の係数に多項式再帰的に現れる複雑な多項式についても、ゼロ判定を行うことができます。

gosh> (=zero? (make-polynomial 'x (list (list 2 (make-polynomial 'x (list (list 2 0) (list 1 (make-polynomial 'x '((5 0))))))))))
#t

問題なさそうです。