Download (define a (cons 1 2))

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Data Abstraction.
Pairs and Lists.
(SICP Sections 2.1.1 – 2.2.1)
1
Procedural abstraction
• Publish:
name, number and type of arguments
(and conditions they must satisfy)
type of procedure’s return value
• Guarantee: the behavior of the procedure
Interface
Implementation
• Hide:
local variables and procedures,
way of implementation,
internal details, etc.
Export only what is needed.
2
Data-object abstraction
• Publish:
constructors, selectors
• Guarantee: the behavior
Interface
Implementation
• Hide:
local variables and procedures,
way of implementation,
internal details, etc.
Export only what is needed.
3
An example: Rational numbers
We would like to represent rational numbers.
A rational number is a quotient a/b of two integers.
Constructor:
(make-rat a b)
Selectors:
(numer r)
(denom r)
Guarantee:
(numer (make-rat a b)) = a
(denom (make-rat a b)) = b
4
An example: Rational numbers
We would like to represent rational numbers.
A rational number is a quotient a/b of two integers.
Constructor:
(make-rat a b)
Selectors:
(numer r)
(denom r)
A better
Guarantee:
(numer (make-rat a b))
=
(denom (make-rat a b))
a
b
A weaker condition, but still sufficient!
5
We can now use the constructors and
selectors to implement operations on rational
numbers:
(add-rat x y)
(sub-rat x y)
(mul-rat x y)
(div-rat x y)
(equal-rat? x y)
(print-rat x)
A form of wishful thinking: we don’t know how
make-rat numer and denom are implemented, but
we use them.
6
Implementing the operations
(define (add-rat x y)
;n1/d1 + n2/d2 = (n1.d2 + n2.d1) / (d1.d2)
(make-rat (+ (* (numer x) (denom y))
(* (numer y) (denom x)))
(* (denom x) (denom y))))
(define (sub-rat x y) …
(define (mul-rat x y)
(make-rat (* (numer x) (numer y))
(* (denom x) (denom y))))
(define (div-rat x y)
(make-rat (* (numer x) (denom y))
(* (denom x) (numer y))))
(define (equal-rat? x y)
(= (* (numer x) (denom y)) (* (numer y) (denom x))))
7
Using the rational package
(define (print-rat x)
(newline)
(display (numer x))
(display ”/”)
(display (denom x)))
(define one-half (make-rat 1 2))
(print-rat one-half)  1/2
(define one-third (make-rat 1 3))
(print-rat (add-rat one-half one-third))  5/6
(print-rat (add-rat one-third one-third))  6/9
8
Abstraction barriers
Programs that use rational numbers
rational numbers in problem domain
add-rat sub-rat mul-rat…
rational numbers as numerators and denumerators
make-rat numer denom
9
Gluing things together
We still have to implement
numer, denom, and make-rat
We need a way to glue things together…
A pair:
(define x (cons 1 2))
(car x)  1
(cdr x)  2
10
Pair: A primitive data type.
Constructor: (cons a b)
Selectors:
(car p)
(cdr p)
Guarantee:
(car (cons a b)) = a
(cdr (cons a b)) = b
Abstraction barrier: We say nothing about the
representation or implementation of pairs.
11
Pairs
(define x (cons 1 2))
(define y (cons 3 4))
(define z (cons x y))
(car (car z))  1 ;(caar z)
(car (cdr z))  3 ;(cadr z)
12
Implementing make-rat, numer, denom
(define (make-rat n d) (cons n d))
(define (numer x) (car x))
(define (denom x) (cdr x))
13
Abstraction barriers
Programs that use rational numbers
rational numbers in problem domain
add-rat sub-rat mul-rat...
rational numbers as numerators and denumerators
make-rat numer denom
rational numbers as pairs
cons car cdr
7 ‫מבוא מורחב שיעור‬
14
Alternative implementation for add-rat
(define (add-rat x y)
(cons (+ (* (car x) (cdr y))
(* (car y) (cdr x)))
(* (cdr x) (cdr y))))
Abstraction
Violation
If we bypass an abstraction barrier,
changes to one level may affect many levels above it.
Maintenance becomes more difficult.
15
Rationals - Alternative Implementation
In our current implementation we keep 10000/20000
as such and not as 1/2.
This:
• Makes the computation more expensive.
• Prints out clumsy results.
A solution: change the constructor
(define (make-rat a b)
(let ((g (gcd a b)))
(cons (/ a g) (/ b g))))
No other changes are required!
16
Reducing to lowest terms, another way
(define (make-rat n d)
(cons n d))
(define (numer x)
(let ((g (gcd (car x) (cdr x))))
(/ (car x) g)))
(define (denom x)
(let ((g (gcd (car x) (cdr x))))
(/ (cdr x) g)))
17
How can we implement pairs? (first solution –
“lazy” implementation)
(define (cons x y)
(lambda (f) (f x y)))
(define (car z)
(z (lambda (x y) x)))
(define (cdr z)
(z (lambda (x y) y)))
18
How can we implement pairs? (first solution, cont’)
Name
> (define p (cons 1 2))
Value
(lambda(f) (f 1 2))
p
> (car p)
( (lambda(f) (f 1 2)) (lambda (x y) x))
( (lambda(x y) x) 1 2 )
>1
(define (cons x y)
(lambda (f) (f x y)))
(define
(car z)
(z (lambda (x y) x)))
(define (cdr z)
(z (lambda (x y) y)))
19
How can we implement pairs?
(Second solution: “eager” implementation)
(define (cons x
(lambda (m)
(cond ((= m
((= m
(else
y)
0) x)
1) y)
(error "Argument not 0 or
1 -- CONS" m))))))
(define (car z) (z 0))
(define (cdr z) (z 1))
20
Implementing pairs (second solution, cont’)
> (define p (cons 3 4))
Name
p
> (car p)
Value
(lambda(m)
(cond ((= m 0) 3)
((= m 1) 4)
(else ..)))
((lambda(m) (cond ..)) 0)
(cond ((= 0 0) 3) ((= 0 1) 4) (else
>3
(define (cons x y)
(lambda (m)
...)))
(cond ((= m 0) x)
((= m 1) y)
(else ...)))
(define (car z)
(z 0))
(define (cdr z)
(z 1))
21
Box and Pointer Diagram
(define a (cons 1 2))
a
2
1
A pair can be implemented directly using two “pointers”.
Originally on IBM 704:
(car a) Contents of Address part of Register
(cdr a) Contents of Decrement part of Register
23
Box and pointer diagrams (cont.)
(cons (cons 1 (cons 2 3)) 4)
4
3
1
2
24
Compound Data
A closure property: 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.
3
Pairs have the closure property:
We can pair pairs, pairs of pairs etc.
2
(cons (cons 1 2) 3)
1
25
The empty list (a.k.a.
null or nill)
Lists
(cons 1 (cons 3 (cons 2 ’() )))
1
3
2
Syntactic sugar: (list 1 3 2)
26
Formal Definition of a List
A list is either
• ’() -- The empty list
• A pair whose cdr is a list.
Lists are closed under the operations cons and cdr:
• If lst is a non-empty list,
then (cdr lst) is a list.
• If lst is a list and x is arbitrary,
then (cons x lst) is a list.
7 ‫מבוא מורחב שיעור‬
27
Lists
(list <x1> <x2> ... <xn>)
is syntactic sugar for
(cons <x1> (cons <x2> ( … (cons <xn> ’() ))))
…
<x1>
<x2>
<xn>
28
Lists (examples)
The following expressions all result in the same structure:
(cons 3 (list 1 2))
(cons 3 (cons 1 (cons 2 ’() )))
(list 3 1 2)
and similarly the following
1
3
2
(cdr (list 1 2 3))
(cdr (cons 1 (cons 2 (cons 3 ’() ))))
(cons 2 (cons 3 ’() ))
(list 2 3)
2
3
29
More Elaborate Lists
(list 1 2 3 4)
Prints as (1 2 3 4)
1
2
3
4
(cons (list 1 2) (list 3 4))
Prints as ((1 2) 3 4)
3
1
2
1
2
4
(list (list 1 2) (list 3 4))
Prints as ((1 2) (3 4))
3
4
31
Yet More Examples
 (define p (cons 1 2))
p
(1 . 2)
p1
 (define p1 (cons 3 p)
3
 p1
(3 1 . 2)
p
1 2
 (define p2 (list p p))
 p2
( (1 . 2) (1 . 2) )
p2
32
The Predicate Null?
null? : anytype -> boolean
(null? <z>)
#t if <z> evaluates to empty list
#f otherwise
(null? 2)
 #f
(null? (list 1))
 #f
(null? (cdr (list 1)))  #t
’())
 #t
(null? null)
 #t
(null?
33
The Predicate Pair?
pair? : anytype -> boolean
(pair? <z>)
#t if <z> evaluates to a pair
#f otherwise.
(pair? (cons 1 2))  #t
(pair? (cons 1 (cons 1 2)))  #t
(pair? (list 1))
 #t
(pair? ’())  #f
(pair? 3)  #f
(pair? pair?)  #f
34
The Predicate Atom?
atom? : anytype -> boolean
(define (atom? z)
(and (not (pair? z))
(not (null? z))))
(define (square x) (* x x))
(atom? square) 
#t
(atom? 3)

#t
(atom? (cons 1 2))  #f
35
More examples
(define digits (list 1 2 3 4 5 6 7 8 9))
(define digits1 (cons 0 digits))
digits1
? 1 2 3 4 5 6 7 8 9)
(0
(define l (list 0 digits))
l
? (1 2 3 4 5 6 7 8 9))
(0
36
The procedure length
(define digits (list 1 2 3 4 5 6 7 8 9))
(length digits)
9
(define l null)
(length l)
0
(define l (cons 1 l))
(length l)
1
(define (length l)
(if (null? l)
0
(+ 1 (length (cdr l)))))
37
The procedure append
(define (append list1 list2)
(cond ((null? list1) list2) ; base
(else
(cons (car list1)
; recursion
(append (cdr list1) list2)))))
38
Constructor
• Type: Number * T -> LIST(T)
> (make-list 7 ’foo)
(foo foo foo foo foo foo foo)
> (make-list 5 1)
(1 1 1 1 1)
39
List type
• Pairs:
• For every type assignment TA and type expressions
S,S1,S2:
• TA |- cons:[S1*S2 -> PAIR(S1,S2)]
• TA |- car:[PAIR(S1,S2) -> S1]
• TA |- cdr:[PAIR(S1,S2) -> S2]
• TA |- pair?:[S -> Boolean]
• TA |- equal?:[PAIR(S1,S2)*PAIR(S1,S2) -> Boolean]
40
For every type environment TA and type expression S:
TA |- list:[Unit -> LIST(S)]
TA |- cons:[T*LIST(S) -> LIST(S)]
TA |- car:[LIST(S) -> S]
TA |- cdr:[LIST(S) -> LIST(S)]
TA |- null?:[LIST(S) -> Boolean]
TA |- list?:[S -> Boolean]
TA |- equal?:[LIST(S)*LIST(S) -> Boolean]
41
Cont.
•
•
•
•
•
•
•
•
For every type environment TA and type expression S:
TA |- list:[Unit -> LIST]
TA |- cons:[S*LIST -> LIST]
TA |- car:[LIST -> S]
TA |- cdr:[LIST -> LIST]
TA |- null?:[LIST -> Boolean]
TA |- list?:[S -> Boolean]
TA |- equal?:[LIST*LIST -> Boolean]
42
Related documents