2022-02-07 11:46:42 +00:00
|
|
|
#lang sicp
|
|
|
|
|
|
|
|
|
|
|
|
;;;from section 1.2.5, for Section 2.1.1
|
|
|
|
(define (gcd a b)
|
|
|
|
(if (= b 0)
|
|
|
|
a
|
|
|
|
(gcd b (remainder a b))))
|
|
|
|
|
|
|
|
;;;-----------
|
|
|
|
;;;from section 3.3.3 for section 2.4.3
|
|
|
|
;;; to support operation/type table for data-directed dispatch
|
|
|
|
|
|
|
|
(define (assoc key records)
|
|
|
|
(cond ((null? records) false)
|
|
|
|
((equal? key (caar records)) (car records))
|
|
|
|
(else (assoc key (cdr records)))))
|
|
|
|
|
|
|
|
(define (make-table)
|
|
|
|
(let ((local-table (list '*table*)))
|
|
|
|
(define (lookup key-1 key-2)
|
|
|
|
(let ((subtable (assoc key-1 (cdr local-table))))
|
|
|
|
(if subtable
|
|
|
|
(let ((record (assoc key-2 (cdr subtable))))
|
|
|
|
(if record
|
|
|
|
(cdr record)
|
|
|
|
false))
|
|
|
|
false)))
|
|
|
|
(define (insert! key-1 key-2 value)
|
|
|
|
(let ((subtable (assoc key-1 (cdr local-table))))
|
|
|
|
(if subtable
|
|
|
|
(let ((record (assoc key-2 (cdr subtable))))
|
|
|
|
(if record
|
|
|
|
(set-cdr! record value)
|
|
|
|
(set-cdr! subtable
|
|
|
|
(cons (cons key-2 value)
|
|
|
|
(cdr subtable)))))
|
|
|
|
(set-cdr! local-table
|
|
|
|
(cons (list key-1
|
|
|
|
(cons key-2 value))
|
|
|
|
(cdr local-table)))))
|
|
|
|
'ok)
|
|
|
|
(define (dispatch m)
|
|
|
|
(cond ((eq? m 'lookup-proc) lookup)
|
|
|
|
((eq? m 'insert-proc!) insert!)
|
|
|
|
(else (error "Unknown operation -- TABLE" m))))
|
|
|
|
dispatch))
|
|
|
|
|
|
|
|
(define operation-table (make-table))
|
|
|
|
(define get (operation-table 'lookup-proc))
|
|
|
|
(define put (operation-table 'insert-proc!))
|
|
|
|
|
2022-02-07 19:45:40 +00:00
|
|
|
(define coercion-table (make-table))
|
|
|
|
(define get-coercion (coercion-table 'lookup-proc))
|
|
|
|
(define put-coercion (coercion-table 'insert-proc!))
|
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
;; Apply generic
|
|
|
|
|
2022-02-07 19:45:40 +00:00
|
|
|
;;(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))
|
|
|
|
;; (error
|
|
|
|
;; "No method for these types -- APPLY-GENERIC"
|
|
|
|
;; (list op type-tags))))))
|
|
|
|
|
2022-02-18 20:41:52 +00:00
|
|
|
;; Number tower. Ignores possibility of one of the arguments
|
|
|
|
;; not being in the tower. Maybe fix later.
|
|
|
|
(define (lower-in-tower? t1 t2)
|
2022-03-06 22:41:01 +00:00
|
|
|
(define tower '(integer rational scheme-number complex))
|
2022-02-18 20:41:52 +00:00
|
|
|
(define (tower-iter tower)
|
|
|
|
(cond ((null? tower)
|
|
|
|
(error "Not in tower" (list t1 t2)))
|
|
|
|
((eq? (car tower) t1) #t)
|
|
|
|
((eq? (car tower) t2) #f)
|
|
|
|
(else (tower-iter (cdr tower)))))
|
|
|
|
(if (eq? t1 t2)
|
|
|
|
#f
|
|
|
|
(tower-iter tower)))
|
2022-02-08 22:38:46 +00:00
|
|
|
|
2022-03-12 16:23:22 +00:00
|
|
|
|
2022-03-12 20:20:29 +00:00
|
|
|
(define tower '(integer rational scheme-number complex))
|
2022-03-12 16:23:22 +00:00
|
|
|
|
|
|
|
(define (transform-type x tower)
|
2022-03-12 20:20:29 +00:00
|
|
|
(define (next-type type tower)
|
|
|
|
(cond ((or (null? tower)
|
|
|
|
(null? (cdr tower))) '())
|
|
|
|
((eq? type (car tower)) (cadr tower))
|
|
|
|
(else (next-type type (cdr tower)))))
|
2022-03-12 16:23:22 +00:00
|
|
|
(and (type-tagged? x)
|
|
|
|
(let* ((type (type-tag x))
|
|
|
|
(proj-type (next-type type tower)))
|
2022-03-12 20:20:29 +00:00
|
|
|
(if (null? proj-type)
|
|
|
|
'()
|
|
|
|
((get-coercion type proj-type) (contents x))))))
|
2022-03-12 16:23:22 +00:00
|
|
|
|
|
|
|
(define (raise x)
|
|
|
|
(transform-type x tower))
|
|
|
|
|
|
|
|
(define (project x)
|
|
|
|
(transform-type x (reverse tower)))
|
|
|
|
|
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (apply-generic op . args)
|
2022-02-08 22:38:46 +00:00
|
|
|
(define (coerce-to t)
|
2022-02-18 20:41:52 +00:00
|
|
|
(letrec ((coerce (lambda (arg)
|
|
|
|
(cond ((eq? (type-tag arg) t) arg)
|
|
|
|
((lower-in-tower?
|
|
|
|
(type-tag arg)
|
|
|
|
t)
|
|
|
|
(coerce (raise arg)))
|
|
|
|
(else '())))))
|
|
|
|
coerce))
|
2022-02-08 22:38:46 +00:00
|
|
|
(define (any-empty-list l)
|
|
|
|
(cond ((null? l) #f)
|
|
|
|
((eq? (car l) '()) #t)
|
|
|
|
(else (any-empty-list (cdr l)))))
|
2022-02-13 17:54:57 +00:00
|
|
|
(define (coerce-args args type-tags)
|
|
|
|
(if (null? type-tags)
|
|
|
|
'()
|
|
|
|
(let* ((type (car type-tags))
|
|
|
|
(coerced-args (map (coerce-to type) args)))
|
|
|
|
(if (not (any-empty-list coerced-args))
|
|
|
|
coerced-args
|
|
|
|
(coerce-args args (cdr type-tags))))))
|
2022-02-24 20:40:03 +00:00
|
|
|
(let* ((type-tags (map type-tag args))
|
2022-02-25 22:47:34 +00:00
|
|
|
(proc (get op type-tags))
|
|
|
|
(result
|
|
|
|
(if proc
|
2022-03-06 19:58:08 +00:00
|
|
|
(begin
|
|
|
|
(display "Applying ")
|
|
|
|
(display (list op args))
|
|
|
|
(newline)
|
|
|
|
(apply proc (map contents args)))
|
2022-02-25 22:47:34 +00:00
|
|
|
(if (> (length args) 1)
|
|
|
|
(let ((coerced-args (coerce-args args type-tags)))
|
|
|
|
(if (not (null? coerced-args))
|
2022-03-06 19:58:08 +00:00
|
|
|
(begin
|
|
|
|
(display "Applying with coerced args ")
|
|
|
|
(display (list op coerced-args))
|
|
|
|
(newline)
|
|
|
|
(apply apply-generic (cons op coerced-args)))
|
2022-02-25 22:47:34 +00:00
|
|
|
(error "Can't coerce arguments to a common type"
|
|
|
|
(list op type-tags))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(error "No matching operator for args" op args)))))
|
2022-02-25 22:47:34 +00:00
|
|
|
(if (and (pair? result)
|
|
|
|
(not (or (eq? op 'raise)
|
2022-03-06 19:58:08 +00:00
|
|
|
(eq? op 'project)
|
|
|
|
(eq? op 'real-part)
|
|
|
|
(eq? op 'imag-part)
|
|
|
|
(eq? op 'angle)
|
|
|
|
(eq? op 'magnitude))))
|
|
|
|
(begin
|
|
|
|
(display "Drop ")
|
|
|
|
(display result)
|
|
|
|
(newline)
|
|
|
|
(drop result))
|
|
|
|
(begin
|
|
|
|
(display "Result ")
|
|
|
|
(display result)
|
|
|
|
(newline)
|
|
|
|
result))))
|
2022-02-08 22:38:46 +00:00
|
|
|
|
2022-03-11 20:04:29 +00:00
|
|
|
;; scheme-number is for reals only
|
|
|
|
(define (scheme-number? x)
|
|
|
|
(and (real? x)
|
|
|
|
(not (integer? x))))
|
2022-02-13 17:54:57 +00:00
|
|
|
|
2022-03-06 19:58:08 +00:00
|
|
|
(define (attach-tag type-tag contents)
|
2022-03-12 20:21:23 +00:00
|
|
|
(cond ((eq? type-tag 'scheme-number) contents)
|
2022-03-10 22:43:45 +00:00
|
|
|
(else (cons type-tag contents))))
|
2022-03-06 19:58:08 +00:00
|
|
|
|
|
|
|
(define (type-tag datum)
|
2022-03-12 20:21:23 +00:00
|
|
|
(cond ((number? datum) 'scheme-number)
|
2022-03-10 22:43:45 +00:00
|
|
|
((pair? datum) (car datum))
|
2022-03-06 19:58:08 +00:00
|
|
|
(else (error "Bad tagged datum -- TYPE-TAG" datum))))
|
|
|
|
|
|
|
|
(define (contents datum)
|
2022-03-10 22:43:45 +00:00
|
|
|
(cond ((number? datum) datum)
|
|
|
|
((pair? datum) (cdr datum))
|
2022-03-06 19:58:08 +00:00
|
|
|
(else (error "Bad tagged datum -- CONTENTS" datum))))
|
|
|
|
|
2022-03-11 20:04:29 +00:00
|
|
|
(define type-tagged?
|
|
|
|
(lambda (x)
|
|
|
|
(or (number? x) (pair? x))))
|
2022-03-06 19:58:08 +00:00
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
;; Scheme numbers
|
|
|
|
|
|
|
|
(define (install-scheme-number-package)
|
|
|
|
(define (tag x)
|
|
|
|
(attach-tag 'scheme-number x))
|
2022-02-07 19:45:40 +00:00
|
|
|
(define (exp x y) (apply-generic 'exp x y))
|
2022-02-07 11:46:42 +00:00
|
|
|
(put 'add '(scheme-number scheme-number)
|
|
|
|
(lambda (x y) (tag (+ x y))))
|
2022-02-09 20:59:10 +00:00
|
|
|
(put 'add3 '(scheme-number scheme-number scheme-number)
|
|
|
|
(lambda (x y z) (tag (+ x y z))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'negate '(scheme-number)
|
2022-03-06 22:41:01 +00:00
|
|
|
(lambda (x) (tag (* -1 x))))
|
|
|
|
(put 'sine '(scheme-number)
|
|
|
|
(lambda (x) (tag (sin x))))
|
|
|
|
(put 'cosine '(scheme-number)
|
|
|
|
(lambda (x) (tag (cos x))))
|
|
|
|
(put 'square-root '(scheme-number)
|
|
|
|
(lambda (x) (tag (sqrt x))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(put 'equ? '(scheme-number scheme-number) =)
|
|
|
|
(put '=zero? '(scheme-number)
|
|
|
|
(lambda (x) (= x 0)))
|
2022-03-12 16:23:22 +00:00
|
|
|
(put-coercion 'scheme-number 'complex
|
|
|
|
(lambda (x)
|
|
|
|
(make-complex-from-real-imag
|
|
|
|
(tag x)
|
|
|
|
(tag 0))))
|
|
|
|
(put-coercion 'scheme-number 'rational
|
|
|
|
(lambda (x)
|
|
|
|
(make-rational
|
|
|
|
(round (* x 1000))
|
|
|
|
1000)))
|
2022-02-07 19:45:40 +00:00
|
|
|
(put 'exp '(scheme-number scheme-number)
|
|
|
|
(lambda (x y) (tag (expt x y))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(put 'make 'scheme-number
|
|
|
|
(lambda (x) (tag x)))
|
|
|
|
'done)
|
|
|
|
|
2022-02-13 20:10:54 +00:00
|
|
|
;; Integers
|
|
|
|
|
|
|
|
(define (install-integer-package)
|
|
|
|
(define (tag x)
|
|
|
|
(attach-tag 'integer x))
|
2022-02-26 20:29:58 +00:00
|
|
|
(define (raise-int x)
|
|
|
|
(make-rational x 1))
|
2022-02-13 20:10:54 +00:00
|
|
|
|
2022-03-10 22:37:16 +00:00
|
|
|
(put 'add '(integer integer)
|
|
|
|
(lambda (x y)
|
|
|
|
(make-integer (+ x y))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'sub '(integer integer)
|
|
|
|
(lambda (x y)
|
|
|
|
(make-integer (- x y))))
|
|
|
|
(put 'div '(integer integer)
|
|
|
|
(lambda (x y)
|
|
|
|
(make-integer (/ x y))))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'mul '(integer integer)
|
|
|
|
(lambda (x y)
|
|
|
|
(make-integer (* x y))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'negate '(integer)
|
|
|
|
(lambda (x) (* -1 x)))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'sine '(integer)
|
2022-03-12 16:23:22 +00:00
|
|
|
(lambda (x) (make-scheme-number (sin x))))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'cosine '(integer)
|
2022-03-12 16:23:22 +00:00
|
|
|
(lambda (x) (cos x)))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'square-root '(integer)
|
2022-03-12 16:23:22 +00:00
|
|
|
(lambda (x) (make-scheme-number (sqrt x))))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'arctan '(integer integer)
|
2022-03-12 16:23:22 +00:00
|
|
|
(lambda (x y) (make-scheme-number (atan x y))))
|
2022-03-10 22:37:16 +00:00
|
|
|
(put 'equ? '(integer integer)
|
|
|
|
(lambda (x y)
|
|
|
|
(= x y)))
|
2022-03-12 16:23:22 +00:00
|
|
|
(put-coercion 'integer 'rational raise-int)
|
2022-02-13 20:10:54 +00:00
|
|
|
(put 'make 'integer
|
2022-03-10 22:37:16 +00:00
|
|
|
(lambda (x) (tag (round x))))
|
|
|
|
'done)
|
2022-02-13 20:10:54 +00:00
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
;; Rationals
|
|
|
|
|
|
|
|
(define (install-rational-package)
|
|
|
|
;; internal procedures
|
|
|
|
(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 (eq-rat x y)
|
|
|
|
(and (= (numer x) (numer y))
|
|
|
|
(= (denom x) (denom y))))
|
2022-02-26 20:29:58 +00:00
|
|
|
(define (raise-rat x)
|
2022-03-06 22:41:01 +00:00
|
|
|
(make-scheme-number (/ (numer x) (denom x))))
|
2022-02-07 11:46:42 +00:00
|
|
|
;; interface to rest of the system
|
|
|
|
(define (tag x) (attach-tag 'rational x))
|
|
|
|
(put 'add '(rational rational)
|
|
|
|
(lambda (x y) (tag (add-rat x y))))
|
2022-02-09 20:59:10 +00:00
|
|
|
(put 'add3 '(rational rational rational)
|
|
|
|
(lambda (x y z) (tag (add-rat x (add-rat y z)))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'negate '(rational)
|
|
|
|
(lambda (x)
|
|
|
|
(make-rational (* -1 (numer x)) (denom x))))
|
2022-02-26 20:29:58 +00:00
|
|
|
(put 'sine '(rational)
|
|
|
|
(lambda (x) (sine (raise-rat x))))
|
|
|
|
(put 'cosine '(rational)
|
|
|
|
(lambda (x) (cosine (raise-rat x))))
|
|
|
|
(put 'square-root '(rational)
|
|
|
|
(lambda (x) (square-root (raise-rat x))))
|
|
|
|
(put 'arctan '(rational rational)
|
|
|
|
(lambda (x y) (arctan (raise-rat x)
|
|
|
|
(raise-rat y))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(put 'equ? '(rational rational) eq-rat)
|
|
|
|
(put '=zero? '(rational)
|
2022-03-06 19:58:08 +00:00
|
|
|
(lambda (x) (equ? (numer x) (make-integer 0))))
|
2022-03-12 16:23:22 +00:00
|
|
|
(put-coercion 'rational 'scheme-number raise-rat)
|
|
|
|
(put-coercion 'rational 'integer
|
|
|
|
(lambda (x)
|
|
|
|
(make-integer
|
|
|
|
(/ (numer x) (denom x)))))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
2022-02-25 22:47:34 +00:00
|
|
|
(put 'make 'rational
|
2022-02-07 11:46:42 +00:00
|
|
|
(lambda (n d) (tag (make-rat n d))))
|
|
|
|
'done)
|
|
|
|
|
|
|
|
;;;-----------
|
|
|
|
;;;SECTION 2.4.3
|
|
|
|
|
|
|
|
;; uses get/put (from 3.3.3) -- see ch2support.scm
|
|
|
|
|
|
|
|
(define (install-rectangular-package)
|
|
|
|
;; internal procedures
|
|
|
|
(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)
|
2022-02-26 20:29:58 +00:00
|
|
|
(square-root (add (square (real-part z))
|
|
|
|
(square (imag-part z)))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (angle z)
|
2022-02-26 20:29:58 +00:00
|
|
|
(arctan (imag-part z) (real-part z)))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (make-from-mag-ang r a)
|
2022-02-26 20:29:58 +00:00
|
|
|
(cons (mul r (cosine a))
|
|
|
|
(mul r (sine a))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(define (negate z)
|
|
|
|
(make-from-real-imag
|
2022-03-06 22:41:01 +00:00
|
|
|
(mul (make-scheme-number -1) (real-part z))
|
|
|
|
(mul (make-scheme-number -1) (imag-part z))))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
;; interface to the rest of the system
|
|
|
|
(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)
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'negate '(rectangular)
|
|
|
|
(lambda (z) (tag (negate z))))
|
|
|
|
;;(put 'project '(rectangular)
|
|
|
|
;; (lambda (z) (real-part z)))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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 procedures
|
|
|
|
(define (magnitude z) (car z))
|
|
|
|
(define (angle z) (cdr z))
|
|
|
|
(define (make-from-mag-ang r a) (cons r a))
|
|
|
|
(define (real-part z)
|
2022-02-26 20:29:58 +00:00
|
|
|
(mul (magnitude z) (cosine (angle z))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (imag-part z)
|
2022-02-26 20:29:58 +00:00
|
|
|
(mul (magnitude z) (sine (angle z))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (make-from-real-imag x y)
|
2022-02-26 20:29:58 +00:00
|
|
|
(cons (square-root (add (square x) (square y)))
|
|
|
|
(arctan y x)))
|
2022-03-06 22:41:01 +00:00
|
|
|
(define pi (make-scheme-number (* 2 (asin 1))))
|
2022-03-06 19:58:08 +00:00
|
|
|
(define (negate z)
|
|
|
|
(make-from-mag-ang
|
|
|
|
(magnitude z)
|
|
|
|
(add pi (angle z))))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
;; interface to the rest of the system
|
|
|
|
(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)
|
2022-03-06 19:58:08 +00:00
|
|
|
(put 'negate '(polar)
|
|
|
|
(lambda (z) (tag (negate z))))
|
|
|
|
;;(put 'project '(polar)
|
|
|
|
;;(lambda (z) real-part z))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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)
|
|
|
|
;; imported procedures from rectangular and polar packages
|
|
|
|
(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 procedures
|
|
|
|
(define (add-complex z1 z2)
|
2022-03-06 19:58:08 +00:00
|
|
|
(make-from-real-imag (add (real-part z1) (real-part z2))
|
|
|
|
(add (imag-part z1) (imag-part z2))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (sub-complex z1 z2)
|
2022-03-06 19:58:08 +00:00
|
|
|
(make-from-real-imag (sub (real-part z1) (real-part z2))
|
|
|
|
(sub (imag-part z1) (imag-part z2))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (mul-complex z1 z2)
|
2022-03-06 19:58:08 +00:00
|
|
|
(make-from-mag-ang (mul (magnitude z1) (magnitude z2))
|
|
|
|
(add (angle z1) (angle z2))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (div-complex z1 z2)
|
2022-03-06 19:58:08 +00:00
|
|
|
(make-from-mag-ang (div (magnitude z1) (magnitude z2))
|
|
|
|
(sub (angle z1) (angle z2))))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
;; interface to rest of the system
|
|
|
|
(define (tag z) (attach-tag 'complex z))
|
|
|
|
(put 'add '(complex complex)
|
|
|
|
(lambda (z1 z2) (tag (add-complex z1 z2))))
|
2022-02-09 20:59:10 +00:00
|
|
|
(put 'add3 '(complex complex complex)
|
|
|
|
(lambda (z1 z2 z3) (tag (add-complex z1 (add-complex z2 z3)))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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)
|
2022-03-06 19:58:08 +00:00
|
|
|
(and (equ? (real-part z1) (real-part z2))
|
|
|
|
(equ? (imag-part z1) (imag-part z2)))))
|
2022-02-07 11:46:42 +00:00
|
|
|
(put '=zero? '(complex)
|
2022-03-06 22:41:01 +00:00
|
|
|
(lambda (z) (equ? (magnitude z) (make-scheme-number 0))))
|
2022-03-06 19:58:08 +00:00
|
|
|
;;(put 'negate '(complex)
|
|
|
|
;;(lambda (z) (tag (negate z))))
|
|
|
|
(put 'negate '(complex)
|
|
|
|
(lambda (z)
|
|
|
|
(tag
|
|
|
|
(make-from-real-imag
|
2022-03-06 22:41:01 +00:00
|
|
|
(mul (real-part z) (make-scheme-number -1))
|
|
|
|
(mul (imag-part z) (make-scheme-number -1))))))
|
2022-03-06 19:58:08 +00:00
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
(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))))
|
2022-03-12 16:23:22 +00:00
|
|
|
(put-coercion 'complex 'scheme-number
|
|
|
|
(lambda (z)
|
|
|
|
(real-part z)))
|
2022-02-07 11:46:42 +00:00
|
|
|
'done)
|
|
|
|
|
2022-03-01 21:57:43 +00:00
|
|
|
;; *incomplete* skeleton of package
|
|
|
|
(define (install-polynomial-package)
|
|
|
|
;; internal procedures
|
|
|
|
;; representation of poly
|
|
|
|
(define (make-poly variable term-list)
|
|
|
|
(cons variable term-list))
|
|
|
|
(define (variable p) (car p))
|
|
|
|
(define (term-list p) (cdr p))
|
|
|
|
;;[procedures same-variable? and variable? from section 2.3.2]
|
|
|
|
(define (variable? x) (symbol? x))
|
|
|
|
|
|
|
|
(define (same-variable? v1 v2)
|
|
|
|
(and (variable? v1) (variable? v2) (eq? v1 v2)))
|
|
|
|
|
|
|
|
;; representation of terms and term lists
|
|
|
|
;;[procedures adjoin-term ... coeff from text below]
|
|
|
|
(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 (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 (order t1)
|
|
|
|
(add (coeff t1) (coeff t2)))
|
|
|
|
(add-terms (rest-terms L1)
|
|
|
|
(rest-terms L2)))))))))
|
|
|
|
|
|
|
|
(define (mul-terms L1 L2)
|
|
|
|
(if (empty-termlist? L1)
|
|
|
|
(the-empty-termlist)
|
|
|
|
(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 (+ (order t1) (order t2))
|
|
|
|
(mul (coeff t1) (coeff t2)))
|
|
|
|
(mul-term-by-all-terms t1 (rest-terms L))))))
|
|
|
|
|
|
|
|
;;(define (add-poly p1 p2) ... )
|
|
|
|
;;[procedures used by add-poly]
|
|
|
|
(define (add-poly p1 p2)
|
|
|
|
(if (same-variable? (variable p1) (variable p2))
|
|
|
|
(make-poly (variable p1)
|
|
|
|
(add-terms (term-list p1)
|
|
|
|
(term-list p2)))
|
|
|
|
(error "Polys not in same var -- ADD-POLY"
|
|
|
|
(list p1 p2))))
|
|
|
|
|
|
|
|
;;(define (mul-poly p1 p2) ... )
|
|
|
|
;;[procedures used by mul-poly]
|
|
|
|
(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))))
|
|
|
|
|
2022-03-12 20:51:45 +00:00
|
|
|
(define (negate-poly p)
|
|
|
|
(define (negate-term term)
|
|
|
|
(make-term (order term)
|
|
|
|
(negate (coeff term))))
|
|
|
|
(make-poly (variable p)
|
|
|
|
(map negate-term (term-list p))))
|
|
|
|
|
2022-03-06 19:58:08 +00:00
|
|
|
(define (=zero-poly? p)
|
|
|
|
(let ((terms (term-list p)))
|
|
|
|
(if (null? terms)
|
|
|
|
#t
|
|
|
|
(and (= (coeff (first-term terms)) 0)
|
|
|
|
(=zero-poly? (rest-terms terms))))))
|
|
|
|
|
2022-03-01 21:57:43 +00:00
|
|
|
;; interface to rest of the system
|
|
|
|
(define (tag p) (attach-tag 'polynomial p))
|
|
|
|
(put 'add '(polynomial polynomial)
|
|
|
|
(lambda (p1 p2) (tag (add-poly p1 p2))))
|
2022-03-12 20:51:45 +00:00
|
|
|
(put 'sub '(polynomial polynomial)
|
|
|
|
(lambda (p1 p2) (tag (add-poly p1 (negate-poly p2)))))
|
2022-03-01 21:57:43 +00:00
|
|
|
(put 'mul '(polynomial polynomial)
|
|
|
|
(lambda (p1 p2) (tag (mul-poly p1 p2))))
|
2022-03-12 20:51:45 +00:00
|
|
|
(put 'negate '(polynomial)
|
|
|
|
(lambda (p) (tag (negate-poly p))))
|
2022-03-01 21:57:43 +00:00
|
|
|
(put '=zero? '(polynomial)
|
|
|
|
(lambda (p) (empty-termlist? (term-list p))))
|
|
|
|
|
|
|
|
(put 'make 'polynomial
|
|
|
|
(lambda (var terms) (tag (make-poly var terms))))
|
|
|
|
'done)
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
;; Generic constructors
|
|
|
|
|
|
|
|
(define (make-scheme-number n)
|
|
|
|
((get 'make 'scheme-number) n))
|
|
|
|
|
2022-02-13 20:10:54 +00:00
|
|
|
(define (make-integer x)
|
|
|
|
((get 'make 'integer) x))
|
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
(define (make-rational n d)
|
|
|
|
((get 'make 'rational) n d))
|
|
|
|
|
|
|
|
(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))
|
|
|
|
|
2022-03-01 21:57:43 +00:00
|
|
|
(define (make-polynomial var terms)
|
|
|
|
((get 'make 'polynomial) var terms))
|
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
;; Generic selectors
|
|
|
|
|
|
|
|
(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))
|
|
|
|
|
|
|
|
(put 'real-part '(complex) real-part)
|
|
|
|
(put 'imag-part '(complex) imag-part)
|
|
|
|
(put 'magnitude '(complex) magnitude)
|
|
|
|
(put 'angle '(complex) angle)
|
|
|
|
|
|
|
|
;; Generic operators
|
|
|
|
|
|
|
|
(define (add x y) (apply-generic 'add x y))
|
2022-02-18 20:41:52 +00:00
|
|
|
(define (add3 x y z) (apply-generic 'add3 x y z))
|
2022-02-07 11:46:42 +00:00
|
|
|
(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))
|
2022-02-26 20:29:58 +00:00
|
|
|
(define (sine x) (apply-generic 'sine x))
|
|
|
|
(define (cosine x) (apply-generic 'cosine x))
|
|
|
|
(define (square-root x) (apply-generic 'square-root x))
|
|
|
|
(define (arctan x y) (apply-generic 'arctan x y))
|
2022-03-06 19:58:08 +00:00
|
|
|
(define (negate x) (apply-generic 'negate x))
|
2022-02-26 20:29:58 +00:00
|
|
|
(define (square x) (mul x x))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
(define (equ? x y) (apply-generic 'equ? x y))
|
|
|
|
;;(put 'equ? '(complex complex) equ?)
|
|
|
|
|
|
|
|
(define (=zero? x) (apply-generic '=zero? x))
|
2022-02-07 19:45:40 +00:00
|
|
|
(define (exp x y) (apply-generic 'exp x y))
|
2022-02-07 11:46:42 +00:00
|
|
|
|
2022-02-24 20:42:29 +00:00
|
|
|
|
|
|
|
(define (drop x)
|
2022-02-25 22:47:34 +00:00
|
|
|
(and (type-tagged? x)
|
|
|
|
(let ((p (project x)))
|
2022-03-06 19:58:08 +00:00
|
|
|
(begin
|
|
|
|
(display "drop: ")
|
|
|
|
(display x)
|
|
|
|
(newline)
|
|
|
|
(cond ((null? p)
|
|
|
|
(display "drop: p Null ")
|
|
|
|
(newline)
|
|
|
|
x)
|
|
|
|
((equ? x (raise p))
|
|
|
|
(display "drop: x equal to raise p, dropping ")
|
|
|
|
(display p)
|
|
|
|
(newline)
|
|
|
|
(drop p))
|
|
|
|
(else
|
|
|
|
(display "drop: returning ")
|
|
|
|
(display x)
|
|
|
|
(newline)
|
|
|
|
x))))))
|
2022-02-13 20:10:54 +00:00
|
|
|
|
2022-02-07 11:46:42 +00:00
|
|
|
(install-scheme-number-package)
|
2022-02-13 20:10:54 +00:00
|
|
|
(install-integer-package)
|
2022-02-07 11:46:42 +00:00
|
|
|
(install-rational-package)
|
|
|
|
(install-polar-package)
|
|
|
|
(install-rectangular-package)
|
|
|
|
(install-complex-package)
|
2022-03-01 21:57:43 +00:00
|
|
|
(install-polynomial-package)
|
2022-02-07 11:46:42 +00:00
|
|
|
|
|
|
|
|
2022-02-07 19:45:40 +00:00
|
|
|
;; Coercion
|
|
|
|
|
|
|
|
|
|
|
|
(define (scheme-number->complex n)
|
|
|
|
(make-complex-from-real-imag (contents n) 0))
|
2022-02-13 15:45:40 +00:00
|
|
|
(define (scheme-number->rational n)
|
|
|
|
(make-rational n 1))
|
2022-02-07 19:45:40 +00:00
|
|
|
|
|
|
|
(define (scheme-number->scheme-number n) n)
|
|
|
|
(define (complex->complex z) z)
|
|
|
|
|
|
|
|
;; 2.81a: If we call exp with two complex arguments, apply-generic fails to find an
|
|
|
|
;; operation with the correct argument list, so tries to coerce t1->t2.
|
|
|
|
;; b: If the arguments are of the same type, and if there isn't an operation defined for
|
|
|
|
;; that combination of arguments, then apply-generic will try to coerce a type to itself,
|
|
|
|
;; so there is a need change it.
|
2022-02-13 17:54:57 +00:00
|
|
|
|
|
|
|
;; 2.82: The approach of coercing to a common type would not work where there is a function
|
|
|
|
;; that takes mixed types. For example, if we have an operator to add a complex to a rational.
|
|
|
|
;; It isn't possible to coerce from one to the other, so a mixed-type operator is needed, and this
|
|
|
|
;; approach would fail.
|
2022-02-13 20:10:54 +00:00
|
|
|
|
2022-03-06 19:58:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|