# SICP 2.5 exercises cont. 3

2.89

```(define (install-dense-polynomial-package)
(if (same-variable? (variable p1) (variable p2))
(make-poly (variable p1)
(term-list p2)))
(error "Polys not in same var -- ADD-POLY"
(list p1 p2))))
(define (mul-poly p1 p2)
(if (same-variable? (variable p1) (variable p2))
(make-poly (variable p1)
(mul-terms (term-list p1)
(term-list p2)))
(error "Polys not in same var -- MUL-POLY"
(list p1 p2))))

;; internal procedures
;; representation of poly
(define (make-poly variable term-list)
(cons variable term-list))
(define (variable p) (car p))
(define (variable? x) (symbol? x))
(define (term-list p) (cdr p))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))

(cons term term-list))
(define (the-empty-termlist) '())
(define (first-term term-list) (car term-list))
(define (rest-terms term-list) (cdr term-list))
(define (empty-termlist? term-list) (null? term-list))
(define (make-term order coeff) (list order coeff))
(define (order term) (car term))

(cond ((empty-termlist? L1) L2)
((empty-termlist? L2) L1)
((> (length L1) (length L2)) (adjoin-term (first-term L1) (add-terms (rest-terms L1) L2)))
((< (length L1) (length L2)) (adjoin-term (first-term L2) (add-terms L1 (rest-terms L2))))
(else
(let ((t1 (first-term L1)) (t2 (first-term L2)))

(define (mul-terms L1 L2)
(if (empty-termlist? L1)
(the-empty-termlist)
(add-terms (mul-term-by-all-terms (length L1) (car L1) L2)
(mul-terms (rest-terms L1) L2))))

(define (mul-term-by-all-terms t1-order t1-coeff L)
(cond ((and (= t1-order 1) (empty-termlist? L)) (the-empty-termlist))
((empty-termlist? L) (cons 0 (mul-term-by-all-terms (- t1-order 1) t1-coeff L)))
(else (cons (* t1-coeff (car L)) (mul-term-by-all-terms t1-order t1-coeff (cdr L))))))

(define (zero-terms? term-list)
(cond ((empty-termlist? term-list) #t)
((not (= 0 (coeff (first-term term-list)))) #f)
(else (zero-terms? (rest-terms term-list)))))

(define (negate-terms term-list)
(if (empty-termlist? term-list)
(the-empty-termlist)
(cons (- (first-term term-list))
(negate-terms (rest-terms term-list)))))
(define (negate-poly p)
(make-polynomial (variable p) (negate-terms (term-list p))))
;; interface to rest of the system
(define (tag p) (attach-tag 'polynomial p))
(lambda (p1 p2) (tag (add-poly p1 p2))))
(put 'mul '(polynomial polynomial)
(lambda (p1 p2) (tag (mul-poly p1 p2))))
(put 'make 'polynomial
(lambda (var terms) (tag (make-poly var terms))))
(put '=zero? '(polynomial) (lambda (p) (zero-terms? (term-list p))))
(put 'negate '(polynomial) negate-poly)
'done)
```

Slow progress now, but these are challenging exercises and I’m behind on a lot of real life work.