Lecture #7

28
בבבב בבבבב1 Lecture #7

description

Lecture #7. Constructor:. Selectors:. The rational number abstraction. Wishful thinking:. ( make-rat ) Creates a rational number . ( numer ) Returns the numerator of . ( denom ) Returns the denominator of . - PowerPoint PPT Presentation

Transcript of Lecture #7

Page 1: Lecture #7

מבוא מורחב1

Lecture #7

Page 2: Lecture #7

מבוא מורחב2

The rational number abstraction

Wishful thinking:

(make-rat <n> <d>) Creates a rational number <r>

(numer <r>) Returns the numerator of <r>

(denom <r>) Returns the denominator of <r>

Constructor:

Selectors:

Page 3: Lecture #7

מבוא מורחב3

A contract

(numer (make-rat <n> <d>))

(denom (make-rat <n> <d>))= <n>

<d>

How do we do it ?

Page 4: Lecture #7

מבוא מורחב5

Using pairs

(define (make-rat n d) (cons n d))

(define (numer x) (car x))

(define (denom x) (cdr x))

Page 5: Lecture #7

מבוא מורחב6

Alternative implementation

(define (add-rat x y) (make-rat (+ (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y))))

(define (add-rat x y) (cons (+ (* (car x) (cdr y)) (* (car y) (cdr x))) (* (cdr x) (cdr y))))

AbstractionViolation

Page 6: Lecture #7

מבוא מורחב7

Reducing to lowest terms

(define (make-rat n d) (let ((g (gcd n d))) (cons (/ n g) (/ d g))))

Page 7: Lecture #7

מבוא מורחב8

Abstraction barriers

Programs that use rational numbers

add-rat sub-rat …….

make-rat numer denom

car cdr cons

Page 8: Lecture #7

מבוא מורחב9

How can we implement pairs ?

(define (cons x y) (lambda (m) (cond ((= m 0) x) ((= m 1) y) (else (error "Argument not 0 or

1 -- CONS" m))))))

(define (car z) (z 0))

(define (cdr z) (z 1))

Page 9: Lecture #7

מבוא מורחב10

The pair constructed by (cons 6 9) is the procedure

(lambda (m)

(cond ((= m 0) 6)

((= m 1) 9)

(else (error “Argument not 0 or 1 -- CONS” m))))

Page 10: Lecture #7

מבוא מורחב11

In the book:

(define (cons x y) (define (dispatch m) (cond ((= m 0) x) ((= m 1) y) (else (error "Argument not 0 or

1 -- CONS" m)))) dispatch)

(define (car z) (z 0))

(define (cdr z) (z 1))

Page 11: Lecture #7

מבוא מורחב12

Compound data

• Ideally want the result of this “gluing” to have the property of closure:

• “the result obtained by creating a compound data structure can itself be treated as a primitive object and thus be input to the creation of another compound object”

Page 12: Lecture #7

מבוא מורחב13

Box and pointer diagram

• Note how pairs have the property of closure – we can use the result of a pair as an element of a new pair:

• (cons (cons 1 2) 3)

3

2

1

Page 13: Lecture #7

מבוא מורחב14

Box and pointer diagram

4

1

3

2

(cons (cons 1 (cons 2 3)) 4)

Page 14: Lecture #7

מבוא מורחב15

Lists

1 3 2

(cons 1 (cons 3 (cons 2 ‘())))

Page 15: Lecture #7

מבוא מורחב16

lists

• A list is either• ‘() (The empty list)• A pair whose cdr is a list.

• Note that lists are closed under operations of cons and cdr.

Page 16: Lecture #7

מבוא מורחב17

Lists

•(list <el1> <el2> ... <eln>)

• Same as

(cons <el1>

(cons <el2> (cons … (cons <eln> ‘()))))

<el1> <el2> <eln>

Page 17: Lecture #7

מבוא מורחב18

Lists

• Predicates

; null? anytype -> boolean(null? <z>) ==> #t if <z> evaluates to empty list

; pair? anytype -> boolean(pair? <z>) ==> #t if <z> evaluates to a pair

; atom? anytype -> boolean(define (atom? z)

(and (not (pair? z)) (not (null? z))))

Page 18: Lecture #7

מבוא מורחב19

Lists -- examples

(define one-to-four (list 1 2 3 4))

one-to-four ==> (1 2 3 4)

(1 2 3 4) ==> error

(car one-to-four) ==>

(car (cdr one-to-four)) ==>

1

2

(cadr one-to-four) ==> 2

(caddr one-to-four) ==> 3

Page 19: Lecture #7

מבוא מורחב20

Common Pattern #1: cons’ing up a list

(define (enumerate-interval from to) (if (> from to) nil (cons from (enumerate-interval (+ 1 from) to))))

(e-i 2 4)(if (> 2 4) nil (cons 2 (e-i (+ 1 2) 4)))(if #f nil (cons 2 (e-i 3 4)))(cons 2 (e-i 3 4))(cons 2 (cons 3 (e-i 4 4)))(cons 2 (cons 3 (cons 4 (e-i 5 4))))(cons 2 (cons 3 (cons 4 nil)))(cons 2 (cons 3 ))

(cons 2 )

==> (2 3 4)

4

3 4

2 3 4

Page 20: Lecture #7

מבוא מורחב21

Common Pattern #2: cdr’ing down a list

(define (list-ref lst n) (if (= n 0) (car lst) (list-ref (cdr lst) (- n 1))))

(define squares (list 1 4 9 16 25))

(list-ref squares 3) ==> 16

Page 21: Lecture #7

מבוא מורחב22

Common Pattern #2: cdr’ing down a list

(define (length lst) (if (null? lst) 0 (+ 1 (length (cdr lst)))))

(define odds (list 1 3 5 7))

(length odds) ==> 4

Page 22: Lecture #7

מבוא מורחב23

Iterative length

(define (length items)

(define (length-iter a count)

(if (null? a)

count

(length-iter (cdr a) (+ 1 count))))

(length-iter items 0))

Page 23: Lecture #7

24

Cdr’ing and Cons’ing Examples

(define (append list1 list2) (cond ((null? list1) list2) ; base (else (cons (car list1) ; recursion (append (cdr list1) list2)))))

(append (list 1 2) (list 3 4))(cons 1 (append (2) (3 4)))(cons 1 (cons 2 (append () (3 4))))(cons 1 (cons 2 (3 4)))

==> (1 2 3 4)

T(n) = (n)

Page 24: Lecture #7

26

Reverse

(reverse (list 1 2 3 4)) ==> (4 3 2 1)

(define (reverse lst)(cond ((null? lst) lst)(else (append (reverse (cdr lst)) (list (car lst)))))))

(reverse (list 1 2 3))(append (reverse (2 3)) (1))(append (append (reverse (3)) (2)) (1))(append (append (append (reverse ()) (3)) (2)) (1))

Append: T(n) = c*n (n) Reverse: T(n) = c*(n-1) + c*(n-2) … c*1 (n2)

Page 25: Lecture #7

מבוא מורחב27

Shall we have some real fun ..

Lets write a procedure scramble..

(scramble (list 0 1 0 2)) ==> (0 0 0 1)

(scramble (list 0 0 0 2 3 1 0 0 8 1)) ==> (0 0 0 0 0 3 0 0 0 8)

(scramble (list 0 1 2 3 4 5 6 7)) ==> (0 0 0 0 0 0 0 0)

(scramble (list 0 1 2 1 2 1 2 1 2)) ==> ( 0 0 0 2 2 2 2 2 2)

Page 26: Lecture #7

מבוא מורחב28

Ok ok

Each number in the argument is treated as backword index from its own position to a point earlier in the tup.

The result at each position is found by counting backward from the current position according to this index

==> No number can be greater than its index

Page 27: Lecture #7

מבוא מורחב29

tup = (0 1 2 1) rev-pre = () (cons 0 ….

tup = (1 2 1) rev-pre = (0) (cons 0 (cons 0

tup = (2 1) rev-pre = (1 0) (cons 0 (cons 0 (cons 0

tup = (1) rev-pre = (2 1 0) (cons 0 (cons 0 (cons 0 (cons 2

tup = ( ) rev-pre = (1 2 1 0) (cons 0 (cons 0 (cons 0 (cons 2 ()))))

Page 28: Lecture #7

מבוא מורחב30

list-ref

scramble-i

(define (scramble-i tup rev-pre) (if (null? tup) '() (cons ( (cons (car tup) rev-pre)

(car tup)) ( (cdr tup)

(cons (car tup) rev-pre)))))

(define (scramble tup) (scramble-b tup '()))