ppl pairs, lists and data abstraction. data abstraction? an interface: separate implementation from...

47
PPL Pairs, lists and data abstraction

Upload: ruby-richard

Post on 24-Dec-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

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

PPL

Pairs, lists and data abstraction

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

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!

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

Data Abstractions in Scheme?

• Of course, but first we need to present 2 new data types in Scheme:– Pairs– Lists

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

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?

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

Pairs

> (define x (cons 1 2))> (car x)1> (cdr x)2> x(1 . 2)

“toString” of pair

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

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)

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

Pairs

Do not confuse (cons 1 2) with (1 . 2) !!

1st is a Scheme expression (syntax) and 2nd is the ‘toString’ of the value

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

Pairs

Type constructor: PAIR

[T1*T2 -> PAIR(T1,T2)]

(λ (x y) (cons x y))

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

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

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

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)

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

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

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

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

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

Visual Representation

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

Lists

• Finite sequence <v1, …, vn> (v1 … vn)

• v1 is head, (v2 … vn) is tail• Value constructors: cons and list– Empty: (list)– Non-empty:• (cons head tail) – tail must be a list!• (list e1 … en)

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

Lists

• Both will create the same list:(list 1 2 3)

(cons 1 (cons 2 (cons 3 (list))))

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

Lists

• Selectors:– car: head– cdr: tail

• Predicates:– list?– null?– equal?

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

Visual Representation

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

Lists and Types

• Homogenous– Examples: (1 2 3), ((1 2) (3)) – LIST(Number), LIST(T), …

• Heterogeneous– Examples: (1 #f 3), ((1 2) 3)– LIST

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

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)

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

Selector: list-ref

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

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

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

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

Iterative length

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

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

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

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

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

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

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

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

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:

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

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

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

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

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

Type Correctness with Pairs and Lists

• cons and list are primitives (not special forms!)

• So we need more axioms.

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

Pairs

For every type environment _Tenv and type expressions _S,_S1,_S2:

Tenv |- cons:[S1*S2 -> PAIR(S1,S2)]

Tenv |- car:[PAIR(S1,S2) -> S1]

Tenv |- cdr:[PAIR(S1,S2) -> S2]

Tenv |- pair?:[S -> Boolean]Tenv |- equal?:[PAIR(S1,S2)*PAIR(S3,S4) -> Boolean]

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

Homogenous Lists

For every type environment Tenv and type expression S:Tenv |- list:[Empty -> LIST(S)]Tenv |- list:[S* ...*S -> LIST(S)] n >0Tenv |- 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]

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

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]

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

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 level2. Supplier level

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

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)

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

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

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

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 rType: [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 dType: [T -> Binary-Tree]

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

Binary Tree ADT: SelectorsSignature: left-tree(r), right-tree(r)Purpose: (left-tree <t>): Returns the left sub-tree

of the binary-tree <t>.(right-tree <t>): Returns the right sub-tree of the

binary-tree <t>.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 <t>.Type: [Binary-Tree -> T]Pre-condition: leaf?(t)

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

Binary Tree ADT: PredicatesSignature: 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 bymake-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]

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

Binary Tree ADT: Invariants

leaf-data(make-leaf(d)) = dleft-tree(make-binary-tree(l,r)) = lright-tree(make-binary-tree(l,r)) = rleaf?(make-leaf(d)) = trueleaf?(make-binary-tree(l,r)) = falsecomposite-binary-tree?(make-binary-tree(l,r)) = true

composite-binary-tree?(make-leaf(d)) = false

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

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

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

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

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

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

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

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!

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

Tagged Data ADTSignature: attach-tag(x,tag)Purpose: Construct a tagged-

data valueType: [T*Symbol -> Tagged-

data(T)]

Signature: get-tag(tagged)Purpose: Select the tag from a

tagged-data valueType: [Tagged-data(T) ->

Symbol]

Signature: get-content(tagged)Purpose: Select the data from a

tagged-data valueType: [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]

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

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

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

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…

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

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