問題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の中身自体も修正する必要がある?)