Created
December 7, 2015 09:18
-
-
Save ruandao/0380964063b00a48bc22 to your computer and use it in GitHub Desktop.
2.90
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;#lang planet neil/sicp | |
| #lang racket | |
| (require (planet soegaard/sicp:2:1/sicp)) | |
| (define wave einstein) | |
| (define (put x) x) | |
| (define (get x) x) | |
| (define (get-coercion x) x) | |
| (define (put-coercion x) x) | |
| (define (square x) (* x x)) | |
| ;; type-tag, contents, attach-tag | |
| (define (attach-tag tag contents) | |
| (if (number? contents) | |
| contents | |
| (cons tag contents))) | |
| (define (type-tag value) | |
| (cond ((number? value) 'scheme-number) | |
| ((and (pair? value) | |
| (symbol? (car value))) | |
| (car value)) | |
| (else (error "Unknown tag -- TYPE-TAG" value)))) | |
| (define (contents value) | |
| (cond ((number? value) value) | |
| ((and (pair? value) | |
| (symbol? (car value))) | |
| (cdr value)) | |
| (else (error "Unknown contents -- CONTENTS" value)))) | |
| (define (same-type? t1 t2) (eq? t1 t2)) | |
| (define (same-types? types) | |
| (define (same-types-1? types type) | |
| (cond | |
| ((null? types) true) | |
| ((eq? (car types) type) (same-types-1? (cdr types) type)) | |
| (else false))) | |
| (cond | |
| ((> (length types) 1) | |
| (same-types-1? types (car types))) | |
| (else false))) | |
| (define (install-scheme-number-package) | |
| (define (tag x) | |
| (attach-tag 'scheme-number x)) | |
| (define (raise scheme-number) | |
| ((get 'make 'rational) (contents scheme-number) 1)) | |
| (put 'add '(scheme-number scheme-number) (lambda (x y) (tag (+ x y)))) | |
| (put 'sub '(scheme-number scheme-number) (lambda (x y) (tag (- x y)))) | |
| (put 'mul '(scheme-number scheme-number) (lambda (x y) (tag (* x y)))) | |
| (put 'div '(scheme-number scheme-number) (lambda (x y) (tag (/ x y)))) | |
| (put 'equ? '(scheme-number scheme-number) (lambda (x y) (= x y))) | |
| (put '=zero? '(scheme-number) (lambda (x) (= x 0))) | |
| (put 'level 'scheme-number 1) | |
| (put 'raise 'scheme-number raise) | |
| ;; interface | |
| (put 'make 'scheme-number | |
| (lambda (x) (tag x))) | |
| 'done) | |
| (define (install-rational-package) | |
| (define (numer x) (car x)) | |
| (define (denom x) (cdr x)) | |
| (define (make-rat n d) | |
| (let ((g (gcd n d))) | |
| (cons (/ n g) (/ d g)))) | |
| (define (add-rat x y) | |
| (make-rat (+ (* (numer x) (denom y)) | |
| (* (numer y) (denom x))) | |
| (* (denom x) (denom y)))) | |
| (define (sub-rat x y) | |
| (make-rat (- (* (numer x) (denom y)) | |
| (* (numer y) (denom x))) | |
| (* (denom x) (denom y)))) | |
| (define (mul-rat x y) | |
| (make-rat (* (numer x) (numer y)) | |
| (* (denom x) (denom y)))) | |
| (define (div-rat x y) | |
| (make-rat (* (numer x) (denom y)) | |
| (* (denom x) (numer y)))) | |
| (define (equ? x y) | |
| (and (= (numer x) (numer y)) | |
| (= (denom x) (denom y)))) | |
| (define (raise rational) | |
| (let ((x (contents rational))) | |
| ((get 'make-from-real-imag 'complex) (/ (numer x) (denom x)) 0))) | |
| (define (project rational-number) | |
| (let ((x (contents rational-number))) | |
| ((get 'make 'scheme-number) (/ (numer x) (denom x))))) | |
| (define (tag x) | |
| (attach-tag 'rational x)) | |
| ;; interface | |
| (put 'add '(rational rational) (lambda (x y) (tag (add-rat x y)))) | |
| (put 'sub '(rational rational) (lambda (x y) (tag (sub-rat x y)))) | |
| (put 'mul '(rational rational) (lambda (x y) (tag (mul-rat x y)))) | |
| (put 'div '(rational rational) (lambda (x y) (tag (div-rat x y)))) | |
| (put 'equ? '(rational rational) (lambda (x y) (equ? x y))) | |
| (put '=zero? '(rational) (lambda (x) (=zero? x))) | |
| (put 'make 'rational (lambda (n d) (tag (make-rat n d)))) | |
| (put 'raise '(scheme-number) raise) | |
| (put 'project '(rational) project) | |
| (put 'level 'rational (lambda () (+ (get 'level 'scheme-number) 1))) | |
| 'done) | |
| (define (install-rectangle-package) | |
| ;; internal | |
| (define (real-part z) (car z)) | |
| (define (imag-part z) (cdr z)) | |
| (define (make-from-real-imag x y) (cons x y)) | |
| (define (magnitude z) | |
| (sqrt (+ (square (real-part z)) | |
| (square (imag-part z))))) | |
| (define (angle z) | |
| (atan (imag-part z) (real-part z))) | |
| (define (make-from-mag-ang r a) | |
| (cons (* r (cos a)) (* r (sin a)))) | |
| ;; interface | |
| (define (tag x) (attach-tag 'rectangular x)) | |
| (put 'real-part '(rectangular) real-part) | |
| (put 'imag-part '(rectangular) imag-part) | |
| (put 'magnitude '(rectangular) magnitude) | |
| (put 'angle '(rectangular) angle) | |
| (put 'make-from-real-imag 'rectangular (lambda (x y) (tag (make-from-real-imag x y)))) | |
| (put 'make-from-mag-ang 'rectangular (lambda (r a) (tag (make-from-mag-ang r a)))) | |
| 'done) | |
| (define (install-polar-package) | |
| ;; internal | |
| (define (magnitude z) (car z)) | |
| (define (angle z) (cdr z)) | |
| (define (make-from-mag-ang r a) (cons r a)) | |
| (define (real-part z) | |
| (* (magnitude z) (cos (angle z)))) | |
| (define (make-from-real-imag x y) | |
| (cons (sqrt (+ (square x) (square y))) | |
| (atan y x))) | |
| ;; interface | |
| (define (tag x) (attach-tag 'polar x)) | |
| (put 'real-part '(polar) real-part) | |
| (put 'imag-part '(polar) imag-part) | |
| (put 'magnitude '(polar) magnitude) | |
| (put 'angle '(polar) angle) | |
| (put 'make-from-real-imag 'polar (lambda (x y) (tag (make-from-real-imag x y)))) | |
| (put 'make-from-mag-ang 'polar (lambda (r a) (tag (make-from-mag-ang r a)))) | |
| 'done) | |
| (define (install-complex-package) | |
| ;; import | |
| (define (make-from-real-imag x y) | |
| ((get 'make-from-real-imag 'rectangular) x y)) | |
| (define (make-from-mag-ang r a) | |
| ((get 'make-from-mag-ang 'polar) r a)) | |
| ;; internal | |
| (define (add-complex z1 z2) | |
| (make-from-real-imag (add (real-part z1) (real-part z2)) | |
| (add (imag-part z1) (imag-part z2)))) | |
| (define (sub-complex z1 z2) | |
| (make-from-real-imag (sub (real-part z1) (real-part z2)) | |
| (sub (imag-part z1) (imag-part z2)))) | |
| (define (mul-complex z1 z2) | |
| (make-from-mag-ang (mul (magnitude z1) (magnitude z2)) | |
| (add (angle z1) (angle z2)))) | |
| (define (div-complex z1 z2) | |
| (make-from-mag-ang (div (magnitude z1) (magnitude z2)) | |
| (sub (angle z1) (angle z2)))) | |
| (define (equ? z1 z2) | |
| (and (= (real-part z1) (real-part z2)) | |
| (= (imag-part z1) (imag-part z2)))) | |
| (define (=zero? z) | |
| (= (real-part z) 0)) | |
| (define (project complex) | |
| (let ((x (contents complex))) | |
| ((get 'make 'rational) (real-part x) 1))) | |
| ;; interface | |
| (define (tag z) (attach-tag 'complex z)) | |
| (put 'add '(complex complex) (lambda (z1 z2) (tag (add-complex z1 z2)))) | |
| (put 'sub '(complex complex) (lambda (z1 z2) (tag (sub-complex z1 z2)))) | |
| (put 'mul '(complex complex) (lambda (z1 z2) (tag (mul-complex z1 z2)))) | |
| (put 'div '(complex complex) (lambda (z1 z2) (tag (div-complex z1 z2)))) | |
| (put 'equ? '(complex complex) (lambda (z1 z2) (equ? z1 z2))) | |
| (put '=zero? '(complex) (lambda (z) (=zero? z))) | |
| (put 'real-part '(complex) real-part) | |
| (put 'imag-part '(complex) imag-part) | |
| (put 'magnitude '(complex) magnitude) | |
| (put 'angle '(complex) angle) | |
| (put 'make-from-real-imag 'complex (lambda (x y) (tag (make-from-real-imag x y)))) | |
| (put 'make-from-mag-ang 'complex (lambda (x y) (tag (make-from-mag-ang x y)))) | |
| (put 'level 'complex (lambda () (+ (get 'level 'real) 1))) | |
| (put 'project 'complex project) | |
| 'done) | |
| (define (make-rational n d) ((get 'make 'rational) n d)) | |
| (define (make-scheme-number n) ((get 'make 'scheme-number) n)) | |
| (define (make-complex-from-real-imag x y) ((get 'make-from-real-imag 'complex) x y)) | |
| (define (make-complex-from-mag-ang r a) ((get 'make-from-mag-ang 'complex) r a)) | |
| (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)) | |
| (define (equ? x y)(apply-generic 'equ? x y)) | |
| (define (=zero? x)(apply-generic '=zero? x)) | |
| (define (project x) (apply-generic 'project x)) | |
| (define (project? x) (get 'project (type-tag x))) | |
| (define (drop x) | |
| (if (project? x) | |
| (if (equ? (raise (project x)) x) | |
| (drop x) | |
| x) | |
| x)) | |
| (define (height? x y) | |
| (> (get 'level x) (get 'level y))) | |
| (define (heightest-type types) | |
| (define (heightest-type-1 types type) | |
| (cond | |
| ((null? types) type) | |
| ((height? type (car types)) (heightest-type-1 (cdr types) type)) | |
| (else (heightest-type-1 (cdr types) (car types))))) | |
| (heightest-type-1 types (car types))) | |
| (define (raise-to-type arg type) | |
| (cond | |
| ((same-types? (cons (type-tag arg) type)) arg) | |
| (else (raise-to-type (raise arg) type)))) | |
| (define (raise-to-same-type args) | |
| (let ((htype (heightest-type (map type-tag args)))) | |
| (map (lambda (x) (raise-to-type x htype)) args))) | |
| (define (apply-generic op . args) | |
| (let ((type-tags (map type-tag args))) | |
| (let ((proc (get op type-tags))) | |
| (if proc | |
| (apply proc (map contents args)) | |
| (if (>= (length args) 2) | |
| (if (not (same-types? type-tags)) | |
| (let ((same-type-args (raise-to-same-type (map drop args)))) | |
| (if same-type-args | |
| (apply apply-generic (cons op args)) | |
| (error "No method for these types" | |
| (list op type-tags)))) | |
| (error "No method for these types" | |
| (list op type-tags))) | |
| (error "No method for these types" | |
| (list op type-tags))))))) | |
| (define (make-polynomial var terms) | |
| ((get 'make 'polynomial) var terms)) | |
| (define (negation x) | |
| (apply-generic 'negation x)) | |
| (define (install-poly-package) | |
| (define (make-poly variable term-list) | |
| (cons variable term-list)) | |
| (define (add-terms 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-terms (rest-terms L1) L2))) | |
| ((< (order t1) (order t2)) | |
| (adjoin-term | |
| t2 (add-terms L1 (rest-terms L2)))) | |
| (else | |
| (adjoin-term | |
| (make-term (type-tag L1) | |
| (order t1) | |
| (add (coeff t1) (coeff t2))) | |
| (add-terms (rest-terms L1) | |
| (rest-terms L2))))))))) | |
| (define (sub-terms L1 L2) | |
| (add-terms L1 (negation L2))) | |
| (define (mul-terms L1 L2) | |
| (if (empty-termlist? L1) | |
| (the-empty-termlist (type-tag L1)) | |
| (add-terms (mul-term-by-all-terms (first-term L1) L2) | |
| (mul-terms (rest-terms L1) L2)))) | |
| (define (mul-term-by-all-terms t1 L) | |
| (if (empty-termlist? L) | |
| (the-empty-termlist) | |
| (let ((t2 (first-term L))) | |
| (adjoin-term | |
| (make-term (type-tag t1) | |
| (+ (order t1) (order t2)) | |
| (mul (coeff t1) (coeff t2))) | |
| (mul-term-by-all-terms t1 (rest-terms L)))))) | |
| ;; interface | |
| (define (empty-termlist? x) | |
| (apply-generic 'empty-termlist? x)) | |
| (define (first-term term-list) | |
| (apply-generic 'first-term term-list)) | |
| (define (rest-terms term-list) | |
| (apply-generic 'rest-terms term-list)) | |
| (define (order term) | |
| (apply-generic 'order term)) | |
| (define (coeff term) | |
| (apply-generic 'coeff term)) | |
| (define (adjoin-term term term-list) | |
| (apply-generic 'adjoin-term term term-list)) | |
| (define (make-term type order coeff) | |
| ((get 'make-term type) order coeff)) | |
| (define (the-empty-termlist type) | |
| ((get 'the-empty-termlist type))) | |
| 'done) | |
| (define (install-spare-poly-package) | |
| (define (negation L) | |
| (cond | |
| ((empty-termlist? L) L) | |
| (else (map (lambda (x) (make-term (order x) (- (coeff x)))) L)))) | |
| (define (adjoin-term term term-list) | |
| (if (=zero? (coeff term)) | |
| term-list | |
| (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)) | |
| (define (coeff term) (cadr term)) | |
| (define (tag x) | |
| (attach-tag 'poly-spare x)) | |
| (put 'empty-termlist? '(poly-spare) (lambda(term-list) (empty-termlist? term-list))) | |
| (put 'negation 'poly-spare (lambda (x) (tag (negation x)))) | |
| (put 'first-term '(poly-spare) (lambda (term-list) (tag (first-term term-list)))) | |
| (put 'rest-terms '(poly-spare) (lambda (term-list) (tag (rest-terms term-list)))) | |
| (put 'order '(poly-spare) order) | |
| (put 'coeff '(poly-spare) coeff) | |
| (put 'adjoin-term '(poly-spare poly-spare) (lambda (term term-list) (tag (adjoin-term term term-list)))) | |
| (put 'make-term 'poly-spare (lambda (order coeff) (tag (make-term order coeff)))) | |
| (put 'the-empty-termlist 'poly-spare (lambda () (tag (the-empty-termlist)))) | |
| 'done) | |
| (define (install-dense-poly-package) | |
| (define (adjoin-term term term-list) | |
| (let ((len-term (length term)) | |
| (len-list (length term-list))) | |
| (cond | |
| ((= 0 len-term) term-list) | |
| ((= 0 len-list) term) | |
| ((> len-term len-list) (cons (car term) (adjoin-term (cdr term) term-list))) | |
| ((< len-term len-list) (cons (car term-list) (adjoin-term term (cdr term-list)))) | |
| ((= len-term len-list) (cons (add (car term) (car term-list)) (adjoin-term (cdr term) (cdr term-list))))))) | |
| (define (the-empty-termlist) '(0)) | |
| (define (first-term term-list) (make-term (length term-list) (car term-list))) | |
| (define (rest-terms term-list) (cdr term-list)) | |
| (define (empty-termlist? term-list) | |
| (and (= (length term-list) 0) | |
| (= (car term-list) 0))) | |
| (define (make-term order coeff) | |
| (if (< order 0) | |
| '() | |
| (cons coeff (make-term (- order 1) 0)))) | |
| (define (order term) (- (length term) 1)) | |
| (define (coeff term) (car term)) | |
| ;; interface | |
| (define (tag x) | |
| (attach-tag 'poly-dense x)) | |
| (put 'empty-termlist? '(poly-dense) (lambda (term-list) (empty-termlist? term-list))) | |
| (put 'negation 'poly-dense (lambda (x) (tag (negation x)))) | |
| (put 'first-term '(poly-dense) (lambda (term-list) (tag (first-term term-list)))) | |
| (put 'rest-terms '(poly-dense) (lambda (term-list) (tag (rest-terms term-list)))) | |
| (put 'order '(poly-dense) order) | |
| (put 'coeff '(poly-dense) coeff) | |
| (put 'adjoin-term '(poly-dense poly-dense) (lambda (term term-list) (tag (adjoin-term term term-list)))) | |
| (put 'make-term 'poly-dense (lambda (order coeff) (tag (make-term order coeff)))) | |
| 'done) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment