+ All Categories
Home > Documents > מבוא מורחב למדעי המחשב בשפת Scheme תרגול 7. Data directed programming...

מבוא מורחב למדעי המחשב בשפת Scheme תרגול 7. Data directed programming...

Date post: 19-Dec-2015
Category:
View: 229 times
Download: 1 times
Share this document with a friend
Popular Tags:
36
בבבב בבבבב בבבבב בבבבב בבבבScheme בבבבב7
Transcript

מבוא מורחב למדעי המחשבSchemeבשפת

7תרגול

Data directed programming

Section 2.4, pages 169-1872.5.1,2.5.2 pages 187-197

(but with a different example)

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

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

Implementation #2: data directed programmingG

ener

ic o

pera

tions

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

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)

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

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

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

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

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

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

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

Polynomials

1)2()1( 32 xyxy

ixixi 3)5()34( 2

71

212

923

31 512 xxx

in x

in y

in x

coefficients are polynomials in y

complex coefficients

in x

in xrational coefficients

polynomial coefficients

735 2 xx

735 2 yy

15

RepresentationDense

(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))

5232 245 xxxx

53 2100 xx

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

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

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

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

Term – Data Abstraction

• Constructor(define (make-term order coeff)

(list order coeff))

• Selectors(define (order term) (car term))

(define (coeff term) (cadr term))

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

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

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

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 termsand term lists

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

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 numbersscheme-numberspolynomials

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

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

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))))))

Dotted tail notation

)define (proc m1 m2 . opt) <body( <

Mandatory Arguments:m1, m2

Mandatory Arguments:m1, m2

List of optional arguments:opt

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(<

(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

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

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

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)))


Recommended