;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; This is the file ps6-code.scm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; GENERIC ARITHMETIC OPERATIONS ;;; GN = ({number} X RepNum) U ({rational} X RepRat) U ({polynomial} X RepPoly) ;;; (GN, GN) --> GN (define (add x y) (apply-generic 'add x y)) (define (sub x y) (apply-generic 'sub x y)) (define (mul x y) (apply-generic 'mul x y)) (define (div x y) (apply-generic 'div x y)) ;;; GN --> GN (define (negate x) (apply-generic 'negate x)) ;;; GN --> Bool (define (=zero? x) (apply-generic '=zero? x)) (define (equ? x y) (apply-generic 'equ? x y)) ;;; a sample compound generic operation ;;; GN --> GN (define (square x) (mul x x)) ;;; the ordinary number package (define (install-number-package) (define (tag x) (attach-tag 'number x)) (define (negate x) (tag (- x))) (define (zero? x) (= x 0)) (define (add x y) (tag (+ x y))) (define (sub x y) (tag (- x y))) (define (mul x y) (tag (* x y))) (define (div x y) (tag (/ x y))) (put 'make 'number tag) (put 'negate '(number) negate) (put '=zero? '(number) zero?) (put 'add '(number number) add) (put 'sub '(number number) sub) (put 'mul '(number number) mul) (put 'div '(number number) div) 'done) ;;; Number Package User Interface ;;; A convenient external procedure for building a generic ;;; ordinary number from Scheme numbers. ;;; Sch-Num --> ({number} X RepNum) (define (create-number x) ((get 'make 'number) x)) ;;; the rational number package (define (install-rational-package) (define (make-rat n d) (cons n d)) (define (numer x) (car x)) (define (denom x) (cdr x)) (define (add-rat x y) (make-rat (add (mul (numer x) (denom y)) (mul (denom x) (numer y))) (mul (denom x) (denom y)))) (define (sub-rat x y) (make-rat (sub (mul (numer x) (denom y)) (mul (denom x) (numer y))) (mul (denom x) (denom y)))) (define (mul-rat x y) (make-rat (mul (numer x) (numer y)) (mul (denom x) (denom y)))) (define (div-rat x y) (make-rat (mul (numer x) (denom y)) (mul (denom x) (numer y)))) (define (tag x) (attach-tag 'rational x)) (define (make-rational n d) (tag (make-rat n d))) (define (add-rational x y) (tag (add-rat x y))) (define (sub-rational x y) (tag (sub-rat x y))) (define (mul-rational x y) (tag (mul-rat x y))) (define (div-rational x y) (tag (div-rat x y))) (put 'make 'rational make-rational) (put 'add '(rational rational) add-rational) (put 'sub '(rational rational) sub-rational) (put 'mul '(rational rational) mul-rational) (put 'div '(rational rational) div-rational) 'done) ;;; Rational Package User Interface ;;; A convenient procedure for building a generic rational ;;; from generic numbers. ;;; (GN, GN) --> ({rational} X RepRat) (define (create-rational n d) ((get 'make 'rational) n d)) ;;; ((RepRat,RepRat) --> T) --> ((RepNum,RepRat) --> T) (define (RRmethod->NRmethod method) (lambda (num rat) (method (repnum->reprat num) rat))) ;;; the generic polynomial package (define (install-polynomial-package) (define (tag poly) (attach-tag 'polynomial poly)) (define (make-polynomial var terms) (tag (make-poly var terms))) (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) (define (add-poly p1 p2) (if (same-variable? (variable p1) (variable p2)) (make-poly (variable p1) (add-termlists (term-list 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-termlists (term-list p1) (term-list p2))) (error "Polys not in same var -- MUL-POLY" (list p1 p2)))) (define (add-polynomial p1 p2) (tag (add-poly p1 p2))) (define (mul-polynomial p1 p2) (tag (mul-poly p1 p2))) (put 'make 'polynomial make-polynomial) (put 'add '(polynomial polynomial) add-polynomial) (put 'mul '(polynomial polynomial) mul-polynomial) 'done) ;;; addition of termlists (define (add-termlists L1 L2) (cond ((empty-termlist? L1) L2) ((empty-termlist? L2) L1) (else (let ((t1 (first-term L1)) (t2 (first-term L2))) (cond ((> (order t1) (order t2)) (adjoin-term t1 (add-termlists (rest-terms L1) L2))) ((< (order t1) (order t2)) (adjoin-term t2 (add-termlists L1 (rest-terms L2)))) (else (adjoin-term (make-term (order t1) (add (coeff t1) (coeff t2))) (add-termlists (rest-terms L1) (rest-terms L2))))))))) ;;; multiplication of termlists (define (mul-termlists L1 L2) (if (or (empty-termlist? L1) (empty-termlist? L2)) (make-empty-termlist) (add-termlists (mul-term-by-all-terms (first-term L1) L2) (mul-termlists (rest-terms L1) L2)))) ;;; create a polynomial (define (create-polynomial var terms) ((get 'make 'polynomial) var terms)) (define (mul-term-by-all-terms t1 tlist) (map-terms (lambda (term) (mul-terms t1 term)) tlist)) (define (mul-terms t1 t2) (make-term (+ (order t1) (order t2)) (mul (coeff t1) (coeff t2)))) (define (apply-polynomial p generic-number) (apply-term (term-list (contents p)) generic-number)) (define (apply-term term generic-number) (mul (coeff term) (power generic-number (order term)))) (define (power n k) (if (< k 1) (create-number 1) (mul n (power n (- k 1))))) ;; representation of terms and term lists (define (adjoin-term term term-list) (if (=zero? (coeff term)) term-list (cons term term-list))) (define (make-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)) (define (coeff term) (cadr term)) (define (make-poly variable term-list) (cons variable term-list)) (define (variable p) (car p)) (define (term-list p) (cdr p)) (define p2 (create-polynomial 'z (adjion-term (make-term 2 p1) (adjoin-term (make-term 1 (create-number 5)) (adjoin-term (make-term 0 (create-number 3)) (make-empty-termlist))))))