Download Recitation 9

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
‫מבוא מורחב למדעי המחשב‬
‫בשפת ‪Scheme‬‬
‫תרגול ‪9‬‬
Data directed programming
Section 2.4, pages 169-187
2.5.1,2.5.2 pages 187-197
(but with a different example)
Multiple Representations of
Abstract Data
Example: geometrical figures
• Package for handling geometrical figures
• Each figure has a unique data representation
• Support of Generic Operations on figures, such as:
• Compute figure area
• Compute figure circumference
• Print figure parameters, etc.
3
Implementation #1: tagged data
• Main idea: add a tag (symbol) to every figure instance
• Generic procedures dispatch on parameter type
(define (area fig)
(cond ((eq? 'rectange (type-tag fig))
(area-rect (contents fig)))
((eq? 'circle (type-tag fig))
(area-circle (contents fig)
.
.))
The system is not additive/modular
The generic procedures must know about all types.
If we want to add a new type we need to
add it to all of the operations, be careful with name
clashes.
4
Implementation #2: data directed programming
• Main idea: work with a table.
• Keep a pointer to the right procedure to call in
the table, keyed by the operation/type combination
Generic operations
types
Circle
Rectangle
Square
circumference circumference-circle circumference-rect circumference-square
area
area-circle
area-rect
area-square
fig-display
fig-display-circle
fig-display-rect
fig-display-square
5
Circle implementation
(define (install-circle-package)
;; Implementation
(define PI 3.1415926)
(define (radius circle) (car circle))
(define (circumference circle)
(* 2 PI (radius circle)))
(define (area circle)
(let ((r (radius circle))
(* PI r r)))
(define (fig-display circle)
(my-display “Circle: radius”, (radius circle)))
(define (make-circle radius)
(attach-tag 'circle (list radius)))
;; Interface to the rest of the system
(put 'circumference 'circle circumference)
(put 'area 'circle area)
(put 'fig-display 'circle fig-display)
(put 'make-fig 'circle make-circle)
'done)
6
Generic procedures
(define (circumference fig)
(apply-generic 'circumference fig))
(define (area fig)
(apply-generic 'area fig))
(define (fig-display fig)
(apply-generic 'fig-display fig))
(define (apply-generic op arg)
(let ((tag (type-tag arg)))
(let ((proc (get op tag)))
(if proc
(proc (contents arg))
(error
"No operation for these types -- APPLY-GENERIC"
(list op tag))))))
7
Summary: Data Directed programming
•
Data Directed programming is more modular:
1. To add a representation, we only need to write
a package for the new representation without
changing generic procedures. (Execute the
install procedure once).
2. Changes are local.
3. No name clashes.
install-polar-package
install-rectangular-package
..
•
Can be extended to support multi-parameter
generic operations.
8
Generic Arithmetic System
Programs that use numbers
add sub mul div
Generic arithmetic package
add-rat sub-rat
mul-rat div-rat
Rational
arithmetic
+,-,*,/
add-poly sub-poly
mul-poly div-poly
Ordinary
arithmetic
Polynomial
arithmetic
List structure and primitive machine arithmetic
9
Rational numbers
Constructor
(define (make-rat n d)
(let ((g (gcd n d)))
(cons (/ n g) (/ d g))))
Selectors
(define (numer x) (car x))
(define (denom x) (cdr x))
10
Rational Operators
(define (add-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))))
11
Rational Package
(define (install-rational-package)
;; internal procedures
(define (numer x) (car x))
(define (denom x) (cdr x))
(define (make-rat n d)...)
(define (add-rat x y)...)
(define (mul-rat x y)...)
...
;; 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))))
(put 'mul '(rational rational) (lambda (x y) (tag (mul-rat x y))))
...
(put 'make 'rational (lambda (n d) (tag (make-rat n d))))
'done)
(define (make-rational n d) ((get 'make 'rational) n d))
12
Scheme Numbers Package
;; ordinary numbers package
(define (install-scheme-number-package)
;; interface to rest of the system
(define (tag x) (attach-tag ’scheme-number x))
(put 'add '(scheme-number scheme-number)
(lambda (x y) (tag (+ x y))))
(put 'mul '(scheme-number scheme-number)
(lambda (x y) (tag (* x y))))
...
(put 'make 'scheme-number (lambda (x) (tag x)))
'done)
(define (make-scheme-number n)
((get 'make 'scheme-number) n))
13
Polynomials
5 x  3x  7
in x
5y  3y  7
in y
2
2
( y  1) x  (2 y) x  1
2
3
in x
polynomial coefficients
coefficients are polynomials in y
(4  3i) x  (5i) x  3  i
2
in x
complex coefficients
x  2 x  1 12 x  5 17
1 3
2
3
9
rational coefficients
2
in x
14
Representation
Dense
x 5  2 x 4  3x 2  2 x  5
(1 2 0 3 –2 –5)
Sparse
x100  3 x 2  5
((100 1) (2 3) (0 5))
Implementation
(make-polynomial 'x '((100 1) (2 3) (0 5)))
=>(polynomial x (100 1) (2 3) (0 5))
15
Data Abstraction
• Constructor
(define (make-poly variable term-list)
(cons variable term-list))
• Selectors
(define (variable p) (car p))
(define (term-list p) (cdr p))
• Predicates
(define (variable? x) (symbol? x))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2)
(eq? v1 v2)))
16
Polynomial Addition
(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))))
17
Polynomial Multiplication
(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))))
18
Term list – Data Abstraction
• Constructors
(define (adjoin-term term term-list)
(if (=zero? (coeff term)) term-list
(cons term term-list)))
(define (the-empty-termlist) '())
• Selectors
(define (first-term term-list)
(car term-list))
(define (rest-terms term-list)
(cdr term-list))
• Predicate
(define (empty-termlist? term-list)
(null? term-list))
19
Term – Data Abstraction
• Constructor
(define (make-term order coeff)
(list order coeff))
• Selectors
(define (order term) (car term))
(define (coeff term) (cadr term))
20
Term-list Addition
(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)))))))))
21
Term-list Multiplication
(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))))
22
Term-list Multiplication
(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))))))
23
Polynomial package
(define (install-polynomial-package)
;; internal procedures
(define (make-poly variable term-list)
(cons variable term-list))
(define (variable p) (car p))
(define (term-list p) (cdr p))
(define (variable? x) ...)
(define (same-variable? v1 v2) ...)
(define (adjoin-term term term-list) ...)
.......
(define (coeff term) ...)
(define (add-poly p1 p2) ...)
<procedures used by add-poly>
(define (mul-poly p1 p2) ...)
<procedures used by mul-poly>
representation of
poly
representation of
terms
and term lists
24
Polynomial package (cont.)
;; 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))))
(put 'mul '(polynomial polynomial)
(lambda (p1 p2) (tag (mul-poly p1 p2))))
(put 'make 'polynomial
(lambda (var terms)
(tag (make-poly var terms))))
'done)
(define (make-polynomial var terms)
((get 'make 'polynomial) var terms))
25
Applications
• Operators:
(define (add obj1 obj2)
(apply-generic ‘add obj1 obj2))
(define (mul obj1 obj2)
(apply-generic ‘mul obj1 obj2))
(define (=zero obj)
(apply-generic ‘=zero obj))
• Types:
rational numbers
scheme-numbers
polynomials
26
How does it work?
(add obj1 obj2)
(apply-generic ‘add obj1 obj2)
proc = (get ‘add (type-of-obj1 type-of-obj2))
Apply proc on contents of objects
Returns a data type with an appropriate tag
Same for mul and =zero
constructor procedures work different (why?)
(make-rat num den)
constructor = (get ‘make ‘rat)
Apply constructor on num and den
Returns an abstract data type with a ‘rat tag
27
Apply Generic - Class Version
(define (apply-generic op arg)
(let ((type (type-tag arg)))
(let ((proc (get op type)))
(if proc
(proc (contents arg))
(error
"No method for these types -APPLY-GENERIC"
(list op type))))))
28
Apply Generic - Book version
(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))))))
29
Dotted tail notation
(define (proc m1 m2 . opt) <body> )
Mandatory Arguments:
m1, m2
List of optional arguments:
opt
Sum of squares – using lists
(define (sum-of-squares l)
(accumulate + 0 (map square l)))
(define (sum-of-squares . l)
(accumulate + 0 (map square l)))
Sum of squares – recursive
(define (sum-of-squares l)
(if (null? l) 0
(+ (square (car l))
(sum-of-squares (cdr l)))))
(define (sum-of-squares . l)
(if (null? l) 0
(+ (square (car l))
(sum-of-squares (cdr l)))))
Apply
(apply <proc> <arg list>)
Invokes a procedure with given arguments:
“(proc (car args) (cadr args) ….)”
(define (sum-of-squares . l)
(if (null? l) 0
(+ (square (car l))
(apply sum-of-squares (cdr l)))))
Apply Generic - Book version
(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))))))
34
Do we really need to construct
numbers?
• Replace
(define (type-tag datum) (car datum))
• With
(define (type-tag datum)
(cond ((pair? datum) (car datum))
((number? datum) 'scheme-number)
(else
(error "Bad tagged datum -- TYPE-TAG" datum))))
• Replace
(define (contents datum) (cdr datum))
• With
(define (contents datum)
(cond ((pair? datum) (cdr datum))
((number? datum) datum)
(else
(error "Bad tagged datum -- TYPE-TAG" datum)))) 35
Constructing numbers (cont.)
• Replace (inside number package)
(define (tag x) (attach-tag ’scheme-number x))
•
With
(define (tag x) x)
• Alternative:
Replace
(define (attach-tag type-tag contents)
(cons type-tag contents))
•
With
(define (attach-tag type-tag contents)
(if (eq? type-tag ‘scheme-number)
contents
(cons type-tag contents)))
36
Related documents