Presentation is loading. Please wait.

Presentation is loading. Please wait.

PPL Pairs, lists and data abstraction. Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know.

Similar presentations


Presentation on theme: "PPL Pairs, lists and data abstraction. Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know."— Presentation transcript:

1 PPL Pairs, lists and data abstraction

2 Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know how to use it, but we don’t know how it’s implemented. Motivation: better software design, modularity, less maintenance and more!

3 Data Abstractions in Scheme? Of course, but first we need to present 2 new data types in Scheme: – Pairs – Lists

4 Pairs Combines two data entities into a single unit Scheme provides built in primitives: – Value constructor: cons – Selectors: car, cdr – Identify predicate: pair? – Equality: equal?

5 Pairs > (define x (cons 1 2)) > (car x) 1 > (cdr x) 2 > x (1. 2) “toString” of pair

6 Pairs Each data entity can be anything! > (define y (cons x (quote a))) > (car y) (1. 2) > (cdr y) 'a > y ((1. 2). a) Recall that x is the pair (cons 1 2)

7 Pairs Do not confuse (cons 1 2) with (1. 2) !! 1 st is a Scheme expression (syntax) and 2 nd is the ‘toString’ of the value

8 Pairs Type constructor: PAIR [T 1 *T 2 -> PAIR(T 1,T 2 )] (λ (x y) (cons x y))

9 Recursive Pairs (define rec-pairs (λ (n) (if (= n 1) 1 (cons n (rec-pairs (- n 1)))))) > (rec-pairs 5) (5 4 3 2. 1) ;(cons 5 (cons 4 (cons 3 (cons 2 (cons 1)))))

10 Recursive Pairs We can also represent binary trees! (cons (cons 1 2) (cons (cons 3 4) (cons 5 6))) ((1. 2) (3. 4) 5. 6)

11 Recursive Pairs We have trees! How about searching a tree? (define member ? (lambda (el pair) (cond ((and (pair? (car pair)) (member? el (car pair))) #t) ((eq? el (car pair)) #t) ((and (pair? (cdr pair)) (member? el (cdr pair))) #t) ((eq? el (cdr pair)) #t) (else #f))))

12 Recursive Pairs How about counting number of leaves? (define count-leaves (λ (t) (if (not (pair? t)) 1 (+ (count-leaves (car t)) (count-leaves (cdr t))))))

13 Visual Representation

14 Lists Finite sequence  (v 1 … v n ) v 1 is head, (v 2 … v n ) is tail Value constructors: cons and list – Empty: (list) – Non-empty: (cons head tail) – tail must be a list! (list e 1 … e n )

15 Lists Both will create the same list: (list 1 2 3) (cons 1 (cons 2 (cons 3 (list))))

16 Lists Selectors: – car : head – cdr : tail Predicates: – list? – null? – equal?

17 Visual Representation

18 Lists and Types Homogenous – Examples: (1 2 3), ((1 2) (3)) – LIST(Number), LIST(T), … Heterogeneous – Examples: (1 #f 3), ((1 2) 3) – LIST

19 Useful List Operations car + cdr: > (define x (list 5 6 8 2)) > (car x) 5 > (cdr x) (6 8 2) > (car (cdr x)) 6 > (cadr x) 6 > (cddr x) (8 2)

20 Selector: list-ref n th element of a list: (define list-ref (λ (l n) (if (= n 0) (car l) (list-ref (cdr l) (- n 1))))) (define squares (list 1 4 9 16 25 36)) (list-ref squares 4)

21 Operator: length (define length (λ (l) (if (null? l) 0 (+ 1 (length (cdr l)))))) (define squares (list 1 4 9 16 25 36)) (length squares) 6

22 Iterative length (define length (λ (l) (letrec ((iter (λ (l c) (if (null? l) c (iter (cdr l) (+ c 1)))))) (iter l 0))))

23 Operator: append (define append (λ (l1 l2) (if (null? l1) l2 (cons (car l1) (append (cdr l1) l2))))) (append (list 1 2 3) (list 3 4))

24 Iterative append ;; Type: [LIST * LIST -> LIST] (define append (λ (l1 l2) (letrec ((iter (λ (l1 l2 c) (if (null? l1) (c l2) (iter (cdr l1) l2 (λ (app-cdr-l1) (c (cons (car l1) app-cdr-l1)))))))) (iter l1 l2 (lambda (x) x)))))

25 Constructor make-list Builds a list of given with given values (define make-list (λ (l v) (if (= l 0) (list) (cons v (make-list (- l 1) v)))))

26 Using Lists to Represent Trees Very much like pairs, but better: – Empty tree () – Leaf is just value – Non-empty tree – non-empty list Example: (1 (2 3)) is the tree:

27 Using Lists to Represent Trees How can we add data to non-leaf nodes? (i.e. labeled tree) : each node is also a list! ((1) ((2) (3))) Now we can create labled trees: (1 (0) (3 (2) (4)))

28 Leaves Count Unlabeled tree (define count-leaves (λ (t) (cond ((null? t) 0) ((not (list? t)) 1) (else (+ (count-leaves (car t)) (count-leaves (cdr t)))))))

29 Type Correctness with Pairs and Lists cons and list are primitives (not special forms!) So we need more axioms.

30 Pairs For every type environment _Tenv and type expressions _S,_S 1,_S 2 : Tenv |- cons:[S 1 *S 2 -> PAIR(S 1,S 2 )] Tenv |- car:[PAIR(S 1,S 2 ) -> S 1 ] Tenv |- cdr:[PAIR(S 1,S 2 ) -> S 2 ] Tenv |- pair?:[S -> Boolean] Tenv |- equal?:[PAIR(S 1,S 2 )*PAIR(S 3,S 4 ) -> Boolean]

31 Homogenous Lists For every type environment Tenv and type expression S: Tenv |- list:[Empty -> LIST(S)] Tenv |- list:[S*...*S -> LIST(S)] n >0 Tenv |- cons:[S*LIST(S) -> LIST(S)] Tenv |- car:[LIST(S) -> S] Tenv |- cdr:[LIST(S) -> LIST(S)] Tenv |- null?:[LIST(S) -> Boolean] Tenv |- list?:[S -> Boolean] Tenv |- equal?:[LIST(S)*LIST(S) -> Boolean]

32 Heterogeneous Lists For every type environment Tenv and type expression S: Tenv |- list:[Empty -> LIST] Tenv |- cons:[S*LIST -> LIST] Tenv |- car:[LIST -> S] Tenv |- cdr:[LIST -> LIST] Tenv |- null?:[LIST -> Boolean] Tenv |- list?:[S -> Boolean] Tenv |- equal?:[LIST*LIST -> Boolean]

33 What About Data Abstraction? An interface: separation between usage (client) and implementation (supplier) Supplier gives getters, setters and other operators, and client uses them. Order of development: 1.Client level 2.Supplier level

34 ADT It’s a new type with a difference: type is semantic while ADT is syntactic Signature of constructor Signature of operators Invariants (see later)

35 So Why start with Pairs and Lists? Pairs and lists will be our implementation! The client will not know we used pairs and lists, she will just use the operations we give her! Example next slide

36 Binary Tree ADT: Constructors Signature: make-binary-tree(l,r) Purpose: Returns a binary tree whose left sub- tree is l and whose right sub-tree is r Type: [Binary-Tree*Binary-Tree -> Binary-Tree] Pre-condition: binary-tree?(l) and binary- tree?(r) Signature: make-leaf(d) Purpose: Returns a leaf binary-tree whose data element is d Type: [T -> Binary-Tree]

37 Binary Tree ADT: Selectors Signature: left-tree(r), right-tree(r) Purpose: (left-tree ): Returns the left sub- tree of the binary-tree. (right-tree ): Returns the right sub-tree of the binary-tree. Type: [Binary-Tree -> Binary-Tree] Pre-condition: composite-binary-tree?(t) Signature: leaf-data(r) Purpose: Returns the data element of the leaf binary-tree. Type: [Binary-Tree -> T] Pre-condition: leaf?(t)

38 Binary Tree ADT: Predicates Signature: leaf?(t) Type: [T -> Boolean] Post-condition: true if t is a leaf -- constructed by make-leaf Signature: composite-binary-tree?(t) Type: [T -> Boolean] Post-condition: true if t is a composite binary-tree -- constructed by make-binary-tree Signature: binary-tree?(t) Type: [T -> Boolean] Post-condition: result = (leaf?(t) or composite-binary-tree?(t) ) Signature: equal-binary-tree?(t1, t2) Type: [Binary-Tree*Binary-Tree -> Boolean]

39 Binary Tree ADT: Invariants leaf-data(make-leaf(d)) = d left-tree(make-binary-tree(l,r)) = l right-tree(make-binary-tree(l,r)) = r leaf?(make-leaf(d)) = true leaf?(make-binary-tree(l,r)) = false composite-binary-tree?(make-binary- tree(l,r)) = true composite-binary-tree?(make-leaf(d)) = false

40 Binary Tree ADT: Client Level ;Signature: count-leaves(tree) ;Purpose: Count the number of leaves of ’tree’ ;Type: [binary-Tree -> number] (define count-leaves (lambda (tree) (if (composite-binary-tree? tree) (+ (count-leaves (left-tree tree)) (count-leaves (right-tree tree))) 1)))

41 Binary Tree ADT: Implementation ;Signature: make-binary- tree(l,r) ;Type: [(LIST union T1)*(LIST union T2) ; -> LIST] ;Pre-condition: binary-tree?(l) ; and binary-tree?(r) (define make-binary-tree (lambda (l r) (list l r))) ;Signature: make-leaf(d) ;Type: [T -> T] (define make-leaf (lambda (d) d)) ;Signature: left-tree(t) ;Type: [LIST -> LIST union T] ;Pre-condition: composite- binary-tree?(t) (define left-tree (lambda (t) (car t))) ;Signature: right-tree(t) ;Type: [LIST -> LIST union T] ;Pre-condition: composite- binary-tree?(t) (define right-tree (lambda (t) (cadr t)))

42 Binary Tree ADT: Implementation ;Signarture: leaf-data(t) ;Type: [T -> T] ;Pre-condition: leaf?(t) (define leaf-data (lambda (t) t)) ;Signarture: leaf?(t) ;Type: [T -> Boolean] (define leaf? (lambda (t) #t)) ;Signarture: composite-binary-tree?(t) ;Type: [T -> Boolean] (define composite-binary-tree? (lambda (t) (and (list? t) (list? (cdr t)) (null? (cddr t)) (binary-tree? (left-tree t)) (binary-tree? (right-tree t)))

43 Binary Tree ADT: Invariants Seems ok, but look: > (leaf? (make-leaf (list 5 6))) #t > (has-leaf? (list 5 6) (make-leaf (list 5 6))) #f We have no way to distinct composite leaves from tree… We need a better implementation: tagged-data!

44 Tagged Data ADT Signature: attach-tag(x,tag) Purpose: Construct a tagged- data value Type: [T*Symbol -> Tagged- data(T)] Signature: get-tag(tagged) Purpose: Select the tag from a tagged-data value Type: [Tagged-data(T) -> Symbol] Signature: get-content(tagged) Purpose: Select the data from a tagged-data value Type: [Tagged-data(T) -> T] Signature: tagged-data?(datum) Purpose: Identify tagged-data values Type: [T -> Boolean] Signature: tagged-by? (tagged,tag) Purpose: Identify tagged-data values Type: [T*Symbol -> Boolean]

45 Binary Tree ADT: Implementation using Tagged-Data ;Signature: make-binary-tree(l,r) ;Type: [(LIST union T1)*(LIST union T2) ; -> Tagged-data(LIST)] ;Pre-condition: binary-tree?(l) ; and binary-tree?(r) (define make-binary-tree (lambda (l r) (attach-tag (list l r) ’composite-binary-tree))) ;Signature: make-leaf(d) ;Type: [T -> Tagged-data(T)] (define make-leaf (lambda (d) (attach-tag d ’leaf))) ;Signature: left-tree(t) ;Type: [Tagged-data(LIST) ; -> Tagged-data(LIST union T)] ;Pre-condition: composite-binary- tree?(t) (define left-tree (lambda (t) (car (get-content t)))) ;Signature: right-tree(t) ;Type: [Tagged-data(LIST) -> Tagged-data(LIST union T)] ;Pre-condition: composite-binary- tree?(t) (define right-tree (lambda (t) (cadr (get-content t))))

46 Tagged-Data Implementation Have you noticed that we didn’t implement the tagged-data ADT? That’s the whole idea! We are clients! We don’t have to know the implementation! But we’ll give it anyway…

47 Tagged-Data ADT Implementation ;Signature: attach-tag(x,tag) ;Type: [Symbol*T -> PAIR(Symbol, T)] (define attach-tag (λ (x tag) (cons tag x))) ;Signature: get-tag(tagged) ;Type: PAIR(Symbol,T) -> Symbol (define get-tag (λ (tagged) (car tagged))) ;Signature: get-content(tagged) ;Type: [PAIR(Symbol,T) -> T] (define get-content (λ (tagged) (cdr tagged))) ;Signature: tagged-data?(datum) ;Type: [T -> Boolean] (define tagged-data? (λ (datum) (and (pair? datum) (symbol? (car datum))))) ;Signature: tagged-by?(tagged,tag) ;Type: [T*Symbol -> Boolean] (define tagged-by? (λ (tagged tag) (and (tagged-data? tagged) (eq? (get-tag tagged) tag))))


Download ppt "PPL Pairs, lists and data abstraction. Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know."

Similar presentations


Ads by Google