Download presentation
Presentation is loading. Please wait.
1
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 7
2
Data directed programming Section 2.4, pages 169-187 2.5.1,2.5.2 pages 187-197 (but with a different example)
3
3 Multiple Representations of Abstract Data 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. Example: geometrical figures
4
4 Implementation #1: tagged data Main idea: add a tag (symbol) to every figure instance Generic procedures dispatch on parameter type The system is not additive/modular ( define (area fig) (cond ((eq? 'rectange (type-tag fig)) (area-rect (contents fig))) ((eq? 'circle (type-tag fig)) (area-circle (contents fig)..)) 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.
5
5 Implementation #2: data directed programming Generic operations circumference area fig-display types Circle Rectangle circumference-circle area-circle fig-display-circle circumference-rect area-rect fig-display-rect Square circumference-square area-square fig-display-square Main idea: work with a table. Keep a pointer to the right procedure to call in the table, keyed by the operation/type combination
6
6 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))) ;; I nterface 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)
7
7 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))))))
8
8 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.
9
9 add sub mul div Programs that use numbers Generic Arithmetic System Generic arithmetic package List structure and primitive machine arithmetic Rational arithmetic Ordinary arithmetic Polynomial arithmetic add-rat sub-rat mul-rat div-rat +,-,*,/add-poly sub-poly mul-poly div-poly
10
10 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))
11
11 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))))
12
12 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))
13
13 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))
14
14 Polynomials in x in y in x coefficients are polynomials in y complex coefficients in x rational coefficients polynomial coefficients
15
15 Representation Dense (1 2 0 3 –2 –5) Sparse ((100 1) (2 3) (0 5)) Implementation (make-polynomial 'x '((100 1) (2 3) (0 5))) =>(polynomial x (100 1) (2 3) (0 5))
16
16 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)))
17
17 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))))
18
18 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))))
19
19 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))
20
20 Term – Data Abstraction Constructor (define (make-term order coeff) (list order coeff)) Selectors (define (order term) (car term)) (define (coeff term) (cadr term))
21
21 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)))))))))
22
22 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))))
23
23 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))))))
24
24 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)...) (define (mul-poly p1 p2)...) representation of poly representation of terms and term lists
25
25 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))
26
26 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
27
27 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
28
28 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))))))
29
29 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))))))
30
Dotted tail notation (define (proc m1 m2. opt) ) Mandatory Arguments: m1, m2 Mandatory Arguments: m1, m2 List of optional arguments: opt List of optional arguments: opt
31
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)))
32
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)))))
33
Apply (apply ) (define (sum-of-squares. l) (if (null? l) 0 (+ (square (car l)) (apply sum-of-squares (cdr l))))) Invokes a procedure with given arguments: “(proc (car args) (cadr args) ….)” Invokes a procedure with given arguments: “(proc (car args) (cadr args) ….)”
34
34 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))))))
35
35 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))))
36
36 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)))
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.