問題2-87〜88

「2.5.3 例:記号代数」に入りました。多項式の算術演算を扱えるパッケージを定義します。polynominal型の構成要素は、一つの不定元と、各次数に関連づけられている係数の組み合わせのリストです。
本書に書いてあるパッケージ手続きを愚直に書いた上で、問題2-87に取り組みました。=zero?を定義するわけですが、これは、termlistの中身を一つずつ調べて、全ての係数がゼロならば、全体もゼロだと仮定しました。

(define (install-polynomial-package)
  ;;...other code
  (define (=zero?-polynomial z1)
    (define (termlist-iter t)
      (cond ((empty-termlist? t) #t)
            ((= 0 (coeff (first-term t)))
             (termlist-iter (rest-terms t)))
            (else #f)))
    (termlist-iter (term-list z1)))
  ;;...other code
  (put '=zero? 'polynomial
       (lambda (z1) (=zero?-polynomial z1)))
  ;;...other code
  'done)

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

次の問題2-88では、多項式の減算を定義します。「汎用符号反転演算を定義するのが有用だ」というヒントがありました。これは、後方の多項式の符号を全て反転すれば、多項式の加算をそのまま使えるのではと判断しました。

(define (install-polynomial-package)
  ;;...other code
  (define (sub-poly p1 p2)
    (if (same-variable? (variable p1) (variable p2))
        (add-poly p1 (make-poly (variable p2)
                                (reverse-termlist-sign (term-list p2))))))
  
  (define (reverse-termlist-sign t)
    (if (empty-termlist? t)
        '()
        (cons (make-term (order (first-term t))
                         (* -1 (coeff (first-term t))))
              (reverse-termlist-sign (rest-terms t)))))
  ;;...other code
  (put 'sub '(polynomial polynomial)
       (lambda (p1 p2) (tag (sub-poly p1 p2))))
  ;;...other code
  'done)

(define p1 (make-polynomial 'x '((2 1) (0 3))))
(define p2 (make-polynomial 'x '((3 1) (2 2) (0 1))))
(define p3 (make-polynomial 'x '()))
(define p4 (make-polynomial 'x '((3 2) (1 5) (0 4))))

(sub p1 p2)  ;=>(polynomial x (3 -1) (2 -1) (0 2))
(sub p3 p4)  ;=>(polynomial x (3 -2) (1 -5) (0 -4))

上記reverse-termlist-signは、渡されたtermlistの各係数に-1を掛けながら、符号が反転したtermlistを返します。
問題2-89〜90は飛ばします。濃い多項式に適しているtermlistを作成せよという問題です。最初はmake-termやorder/coeffだけを修正すればいいのではと思っていましたが、どうやら修正すべき範囲はもっと大きくなってしまいそうです。(add-termの中身自体も修正する必要がある?)