Created
September 1, 2013 14:13
-
-
Save yakreved/6404697 to your computer and use it in GitHub Desktop.
sicp 2.86
This file contains 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
;-------------put-get----------------------------------------- | |
(define global-array '()) | |
(define (make-entry k v) (list k v)) | |
(define (key entry) (car entry)) | |
(define (value entry) (cadr entry)) | |
(define (put op type item) | |
(define (put-helper k array) | |
(cond ((null? array) (list(make-entry k item))) | |
((equal? (key (car array)) k) array) | |
(else (cons (car array) (put-helper k (cdr array)))))) | |
(set! global-array (put-helper (list op type) global-array))) | |
(define (get op type) | |
(define (get-helper k array) | |
(cond ((null? array) #f) | |
((equal? (key (car array)) k) (value (car array))) | |
(else (get-helper k (cdr array))))) | |
(get-helper (list op type) global-array)) | |
;-------------put-get-coercion----------------------------------------- | |
(define coercion-registry '()) | |
(define (put-coercion t1 t2 fn) (set! coercion-registry (cons (list t1 t2 fn) coercion-registry))) | |
(define (get-coercion t1 t2) | |
(define (rec entry . reg) | |
(define t1-entry car) | |
(define t2-entry cadr) | |
(define fn-entry caddr) | |
(cond ((and (eq? t1 (t1-entry entry)) | |
(eq? t2 (t2-entry entry))) (fn-entry entry)) | |
((null? reg) #f) | |
(else (apply rec reg)))) | |
(apply rec coercion-registry)) | |
;-------------tag type---------------------------------------- | |
(define (type-tag datum) | |
(cond ((pair? datum) (car datum)) | |
((number? datum) 'scheme-number) | |
(else (error "Bad tagged datum -- TYPE-TAG" datum)))) | |
(define (contents datum) | |
(cond ((pair? datum) (cdr datum)) | |
((number? datum) datum) | |
(else (error "Bad tagged datum -- CONTENTS" datum)))) | |
(define (attach-tag type-tag contents) | |
(cons type-tag contents)) | |
;------------------------------------------------------------- | |
(define (apply-generic op . args) | |
(define (rise-to a type) | |
(cond | |
((eq? (type-tag a) type) a) | |
(else (raise1 a)) | |
) | |
) | |
(let ((type-tags (map type-tag args))) | |
(let ((proc (get op type-tags))) | |
(if proc | |
(apply proc (map contents args)) | |
(if (= (length args) 2) | |
(let ((type1 (car type-tags)) | |
(type2 (cadr type-tags)) | |
(a1 (car args)) | |
(a2 (cadr args))) | |
(if (eq? type1 type2) | |
(error "NO METHOD FOR THIS TYPE3" | |
(list op type-tags))) | |
(if (eq? (rise-to a1 type2) #f) (rise-to a2 type1) (rise-to a1 type2)) | |
) | |
(error "NO METHOD FOR THIS TYPE2" | |
(list op type-tags))))))) | |
;--------------------------------- | |
(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 (raise1 x) (apply-generic 'raise1 x)) | |
(define (project x) (apply-generic 'project x)) | |
(define (sine x) (apply-generic 'sine x)) | |
(define (cosine x) (apply-generic cosine x)) | |
;------------------------------------------- | |
(define (install-scheme-number-package) | |
(define (tag x) | |
(attach-tag 'scheme-number x)) | |
(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 'make 'scheme-number | |
(lambda (x) (tag x))) | |
(put 'equ? '(scheme-number scheme-number) (lambda (x y) (= x y))) | |
(put '=zero? '(scheme-number) (lambda (x) (= x 0))) | |
(put 'raise1 '(scheme-number) (lambda (x) (make-rational x 1))) | |
(put 'raise1 'scheme-number (lambda (x) (make-rational x 1))) | |
(put 'sine 'scheme-number | |
(lambda (x) (tag (sin x)))) | |
(put 'cosine 'scheme-number | |
(lambda (x) (tag (cos x)))) | |
'done) | |
;---------- | |
(define (make-scheme-number n) | |
((get 'make 'scheme-number) n)) | |
;------------------------------------------- | |
(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)))) | |
;; interface | |
(define (tag x) (attach-tag 'rational x)) | |
(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 'make 'rational | |
(lambda (n d) (tag (make-rat n d)))) | |
(put '=zero? '(rational) | |
(lambda (x) (and (= (numer x) 0) (= (denom x) 0)))) | |
(put 'raise1'(rational) | |
(lambda (r) (make-real (/ (numer r) (denom r))))) | |
(put 'project '(rational) | |
(lambda (x) (make-scheme-number (round (/ (numer x) (denom x)))))) | |
(put 'project 'rational | |
(lambda (x) (make-scheme-number (round (/ (numer x) (denom x)))) )) | |
(put 'equ? '(rational rational) | |
(lambda (x y) (and (= (numer x) (numer y)) (= (denom x) (denom y))))) | |
(put 'sine '(rational) (lambda (x) (attach-tag 'rational (sin (/ (car x) (cdr x)))))) | |
(put 'cosine '(rational) (lambda (x) (attach-tag 'rational (cos (/ (car x) (cdr x)))))) | |
'done) | |
(define (make-rational n d) | |
((get 'make 'rational) n d)) | |
;------------------real------------------------------- | |
(define (install-real-package) | |
(define (tag x) | |
(attach-tag 'real x)) | |
(put 'add '(real real) | |
(lambda (x y) (tag (+ x y)))) | |
(put 'sub '(real real) | |
(lambda (x y) (tag (- x y)))) | |
(put 'mul '(real real) | |
(lambda (x y) (tag (* x y)))) | |
(put 'div '(real real) | |
(lambda (x y) (tag (/ x y)))) | |
(put 'equ? '(real real) =) | |
(put '=zero? '(real) | |
(lambda (x) (= 0 x))) | |
(put 'make 'real | |
(lambda (x) (if (real? x) | |
(tag x) | |
(error "non-real value" x)))) | |
(put 'raise1 '(real) | |
(lambda (r) (make-complex-from-real-imag r 0))) | |
(put 'project 'real | |
(lambda (x) | |
(let ((rat (rationalize | |
(inexact->exact x) 1/100))) | |
(make-rational | |
(numerator rat) | |
(denominator rat))))) | |
'done) | |
(define (make-real n) | |
((get 'make 'real) n)) | |
;----------------------------------------------------- | |
(define (install-polar-package) | |
;; âíóòðåííèå ïðîöåäóðû | |
(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 (imag-part z) | |
(* (magnitude z) (sin (angle z)))) | |
(define (make-from-real-imag x y) | |
(cons (sqrt (+ (square x) (square y))) | |
(atan y x))) | |
;; èíòåðôåéñ ê îñòàëüíîé ñèñòåìå | |
(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)))) | |
(put 'sine 'rational | |
(lambda (x) (tag (sin x)))) | |
(put 'cosine 'rational | |
(lambda (x) (tag (cos x)))) | |
'done) | |
;----------------------------------------------------- | |
(define (install-rectangular-package) | |
;; âíóòðåííèå ïðîöåäóðû | |
(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)))) | |
;; èíòåðôåéñ ê îñòàëüíîé ñèñòåìå | |
(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-complex-package) | |
;; ïðîöåäóðû, èìïîðòèðóåìûå èç äåêàðòîâà | |
;; è ïîëÿðíîãî ïàêåòîâ | |
(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)) | |
;; âíóòðåííèå ïðîöåäóðû | |
(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 (real-part z) (apply-generic 'real-part z)) | |
(define (imag-part z) (apply-generic 'imag-part z)) | |
(define (magnitude z) (apply-generic 'magnitude z)) | |
(define (angle z) (apply-generic 'angle z)) | |
;; èíòåðôåéñ ê îñòàëüíîé ñèñòåìå | |
(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 'make-from-real-imag 'complex | |
(lambda (x y) (tag (make-from-real-imag x y)))) | |
(put 'make-from-mag-ang 'complex | |
(lambda (r a) (tag (make-from-mag-ang r a)))) | |
(put 'real-part '(complex) real-part) | |
(put 'imag-part '(complex) imag-part) | |
(put 'magnitude '(complex) magnitude) | |
(put 'angle '(complex) angle) | |
(put '=zero? '(complex) (lambda (x) (and (= (real-part x) 0) (= (imag-part x) 0)))) | |
(put 'equ? '(complex complex) | |
(lambda (x y) (and (= (real-part x) (real-part y)) (= (imag-part x) (imag-part y))))) | |
(put 'project '(complex) | |
(lambda (x) (make-real (real-part x)))) | |
'done) | |
(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)) | |
;----------------corrections------------------------- | |
(define (scheme-number->complex n) | |
(make-complex-from-real-imag (contents n) 0)) | |
(put-coercion 'scheme-number 'complex scheme-number->complex) | |
(define (scheme-number->rational n) | |
(make-rational (contents n) 1)) | |
(put-coercion 'scheme-number 'rational scheme-number->rational) | |
;------------------------------------------------------ | |
(install-polar-package) | |
(install-rectangular-package) | |
(install-scheme-number-package) | |
(install-rational-package) | |
(install-real-package) | |
(install-complex-package) | |
(sine (make-rational 4 1)) | |
(add (make-complex-from-real-imag (make-rational 4 1) (make-rational 4 1)) | |
(make-complex-from-real-imag (make-rational 4 1) (make-rational 4 1)) | |
) | |
;(type-tag 1) | |
;results: | |
;(rational . -0.7568024953079282) | |
;(complex rectangular (rational 8 . 1) rational 8 . 1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment