c. varela; adapted w/permission from s. haridi and p. van roy1 data abstraction and state abstract...
Post on 19-Dec-2015
213 Views
Preview:
TRANSCRIPT
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 1
Data Abstraction and StateAbstract Data Types (3.7)
State/Data Abstraction(6.1, 6.3, 6.4.1, 6.4.2)
Carlos Varela
RPI
Adapted with permission from:
Seif Haridi
KTH
Peter Van Roy
UCL
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 2
Abstract data types
• A datatype is a set of values and an associated set of operations
• A datatype is abstract if only it is completely described by its set of operations regradless of its implementation
• This means that it is possible to change the implementation of the datatype without changing its use
• The datatype is thus described by a set of procedures
• These operations are the only thing that a user of the abstraction can assume
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 3
Example: A Stack
• Assume we want to define a new datatype stack T whose elements are of any type T
fun {NewStack}: Stack Tfun {Push Stack T T }: Stack Tfun {Pop Stack T T }: Stack Tfun {IsEmpty Stack T }: Bool
• These operations normally satisfy certain conditions:{IsEmpty {NewStack}} = true
for any E and S0, S1={Push S0 E} and S0 ={Pop S1 E} hold
{Pop {NewStack} E} raises error
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 4
Stack (implementation)
fun {NewStack} nil end
fun {Push S E} E|S end
fun {Pop S E} case S of X|S1 then E = X S1 end end
fun {IsEmpty S} S==nil end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 5
Stack (another implementation)
fun {NewStack} nil end
fun {Push S E} E|S end
fun {Pop S E} case S of X|S1 then E = X S1 end end
fun {IsEmpty S} S==nil end
fun {NewStack} emptyStack end
fun {Push S E} stack(E S) end
fun {Pop S E} case S of stack(X S1) then E = X S1 end end
fun {IsEmpty S} S==emptyStack end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 6
Dictionaries
• The datatype dictionary is a finite mapping from a set T to value, where T is either atom or integer
• fun {NewDictionary}– returns an empty mapping
• fun {Put D Key Value}– returns a dictionary identical to D except Key is mapped to
Value• fun {CondGet D Key Default}
– returns the value corresponding to Key in D, otherwise returns Default
• fun {Domain D}– returns a list of the keys in D
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 7
Implementation
fun {h} nil end fun {Put Ds Key Value} case Ds of nil then [Key#Value] [] (K#V)|Dr andthen Key==K then (Key#Value) | Dr [] (K#V)|Dr andthen K>Key then (Key#Value)|(K#V)|Dr [] (K#V)|Dr andthen K<Key then (K#V)|{Put Dr Key Value} end end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 8
Implementationfun {CondGet Ds Key Default} case Ds of nil then Default [] (K#V)|Dr andthen Key==K then V [] (K#V)|Dr andthen K>Key then Default [] (K#V)|Dr andthen K<Key then {CondGet Dr Key Default} end end fun {Domain Ds} {Map Ds fun {$ K#_} K end} end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 9
Further implementations
• Because of abstraction, we can replace the dictionary ADT implementation using a list, whose complexity is linear (i.e., O(n)), for a binary tree implementation with logarithmic operations (i.e., O(log(n)).
• Data abstraction makes clients of the ADT unaware (other than through perceived efficiency) of the internal implementation of the data type.
• It is important that clients do not use anything about the internal representation of the data type (e.g., using {Length Dictionary} to get the size of the dictionary). Using only the interface (defined ADT operations) ensures that different implementations can be used in the future.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 10
Secure abstract data types:Stack is not secure
fun {NewStack} nil endfun {Push S E} E|S endfun {Pop S E}
case S of X|S1 then E=X S1 endendfun {IsEmpty S} S==nil end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 11
Secure abstract data types II
• The representation of the stack is visible:
[a b c d]
• Anyone can use an incorrect representation, i.e., by passing other language entities to the stack operation, causing it to malfunction (like a|b|X or Y=a|b|Y)
• Anyone can write new operations on stacks, thus breaking the abstraction-representation barrier
• How can we guarantee that the representation is invisible?
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 12
Secure abstract data types III
• It is not possible to build secure abstract data types in the declarative model we have seen so far (think about it!)
• The model has to be extended. Here are two ways:– By adding a new basic type, an unforgeable constant called a name– By adding encapsulated state.
• A name is like an atom except that it cannot be typed in on a keyboard or printed!– The only way to have a name is if one is given it explicitly
• There are just two operations on names:N={NewName} : returns a fresh nameN1==N2 : returns true or false
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 13
Secure abstract datatypes IV
proc {NewWrapper ?Wrap ?Unwrap} Key={NewName} in fun {Wrap X} fun {$ K} if K==Key then X end end end fun {Unwrap C} {C Key} end end
• We want to « wrap » and « unwrap » values• Let us use names to define a wrapper & unwrapper
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 14
Secure abstract data types:A secure stack
With the wrapper & unwrapper we can build a secure stack
local Wrap Unwrap in{NewWrapper Wrap Unwrap}fun {NewStack} {Wrap nil} endfun {Push S E} {Wrap E|{Unwrap S}} endfun {Pop S E}
case {Unwrap S} of X|S1 then E=X {Wrap S1} endendfun {IsEmpty S} {Unwrap S}==nil end
end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 15
Capabilities and security• We say a computation is secure if it has well-defined and controllable
properties, independent of the existence of other (possibly malicious) entities (either computations or humans) in the system
• What properties must a language have to be secure?• One way to make a language secure is to base it on capabilities
– A capability is an unforgeable language entity (« ticket ») that gives its owner the right to perform a particular action and only that action
– In our model, all values are capabilities (records, numbers, procedures, names) since they give the right to perform operations on the values
– Having a procedure gives the right to call that procedure. Procedures are very general capabilities, since what they do depends on their argument
– Using names as procedure arguments allows very precise control of rights; for example, it allows us to build secure abstract data types
• Capabilities originated in operating systems research– A capability can give a process the right to create a file in some directory
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 16
Secure abstract datatypes V
• We add two new concepts to the computation model
• {NewChunk Record}– returns a value similar to record but its arity cannot be inspected
– recall {Arity foo(a:1 b:2)} is [a b]
• {NewName}– a function that returns a new symbolic (unforgeable, i.e. cannot be
guessed) name
– foo(a:1 b:2 {NewName}:3) makes impossible to access the third component, if you do not know the arity
• {NewChunk foo(a:1 b:2 {NewName}:3) }– Returns what ?
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 17
Secure abstract datatypes VIproc {NewWrapper ?Wrap ?Unwrap} Key={NewName} in fun {Wrap X} {NewChunk foo(Key:X)} end fun {Unwrap C} C.Key end end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 18
Secure abstract data types:Another secure stack
With the new wrapper & unwrapper we can build another secure stack (since we only use the interface to wrap and unwrap, the code is identical to the one using higher-order programming)
local Wrap Unwrap in{NewWrapper Wrap Unwrap}fun {NewStack} {Wrap nil} endfun {Push S E} {Wrap E|{Unwrap S}} endfun {Pop S E}
case {Unwrap S} of X|S1 then E=X {Wrap S1} endendfun {IsEmpty S} {Unwrap S}==nil end
end
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 19
What is state?
• State is a sequence of values in time that contains the intermediate results of a desired computation
• Declarative programs can also have state according to this definition
• Consider the following program
fun {Sum Xs A} case Xs of X|Xr then {Sum Xr A+X} [] nil then A end end
{Browse {Sum [1 2 3 4] 0}}
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 20
What is implicit state?
The two arguments Xs and A
represent an implicit state
Xs A
[1 2 3 4] 0
[2 3 4] 1
[3 4] 3
[4] 6
nil 10
fun {Sum Xs A} case Xs of X|Xr then {Sum Xr A+X} [] nil then A end end
{Browse {Sum [1 2 3 4] 0}}
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 21
What is explicit state: Example?
XAn unboundvariable
XA cell C is created with initial value 5X is bound to C
5
XThe cell C, which X is bound to, is assigned the value 6
6
C
C
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 22
What is explicit state: Example?
XAn unboundvariable
XA cell C is created with initialvalue 5X is bound to C
5
XThe cell C, which X is bound to, is assigned the value 6
6
C
C
• The cell is a value container with a unique identity• X is really bound to the identity of the cell• When the cell is assigned, X does notchange
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 23
What is explicit state?
• X = {NewCell I}– Creates a cell with initial value I
– Binds X to the identity of the cell
• Example: X = {NewCell 0}
• {Assign X J}– Assumes X is bound to a cell C (otherwise exception)
– Changes the content of C to become J
• Y = {Access X}– Assumes X is bound to a cell C (otherwise exception)
– Binds Y to the value contained in C
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 24
Examples
• X = {NewCell 0}
• {Assign X 5}
• Y = X
• {Assign Y 10}
• {Access X} == 10 % returns true
• X == Y % returns true
X 0
X 5
Y
X 10
Y
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 25
Examples
• X = {NewCell 10}Y = {NewCell 10}
• X == Y % returns false
• Because X and Y refer to different cells, with different identities
• {Access X} == {Access Y}returns true
X 10
Y 10
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 26
Examples
• X = {NewCell 0}
• {Assign X 5}
• Y = X
• {Assign Y 10}
• X == 10 % returns false• {Access X} == 10 %
returns true
X 0
X 5
Y
X 10
Y
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 27
The model extended with cells
Semantic stack
w = f(x)z = person(a:y)y = 1u = 2x
1: w2: x........
single assignmentstore
mutable store
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 28
The stateful model
s::= skip empty statement| s1 s2 statement sequence
| ... | {NewCell x c} cell creation| {Exchange c x y} cell exchange
Exchange: bind x to the old content of c and set thecontent of the cell c to y
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 29
The stateful model
| {NewCell x c} cell creation| {Exchange c x y} cell exchange
proc {Assign C X} {Exchange C _ X} end
fun {Access C} X in{Exchange C X X}X end
Exchange: bind x to the old content of c and set thecontent of the cell c to y
C := X is syntactic sugar for {Assign C X}@C is syntactic sugar for {Access C}
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 30
Abstract data types (revisited)
• For a given functionality, there are many ways to package the ADT. We distinguish three axes.
• Open vs. secure ADT: is the internal representation visible to the program or hidden?
• Declarative vs. stateful ADT: does the ADT have encapsulated state or not?
• Bundled vs. unbundled ADT: is the data kept together from the operations or is it separable?
• Let us see what our stack ADT looks like with some of these possibilities
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 31
Stack:Open, declarative, and unbundled
• Here is the basic stack, as we saw it before:
fun {NewStack} nil endfun {Push S E} E|S endfun {Pop S E} case S of X|S1 then E=X S1 end endfun {IsEmpty S} S==nil end
• This is completely unprotected. Where is it useful? Primarily, in small programs in which expressiveness is more important than security.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 32
Stack:Secure, declarative, and unbundled
• We can make the declarative stack secure by using a wrapper:
local Wrap Unwrapin
{NewWrapper Wrap Unwrap}fun {NewStack} {Wrap nil} endfun {Push S E} {Wrap E|{Unwrap S}} endfun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end
endfun {IsEmpty S} {Unwrap S} ==nil end
end
• Where is this useful? In large programs where we want to protect the implementation of a declarative component.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 33
Stack:Secure, stateful, and bundled
• This is the simplest way to make a secure stateful stack:
proc {NewStack ?Push ?Pop ?IsEmpty}C={NewCell nil}
inproc {Push X} {Assign C X|{Access C}} endfun {Pop} case {Access C} of X|S then {Assign C S} X end endfun {IsEmpty} {Access C} ==nil end
end• Compare the declarative with the stateful versions: the declarative
version needs two arguments per operation, the stateful version uses higher-order programming (instantiation)
• With some syntactic support, this is object-based programming
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 34
Stack:Secure, stateful, and unbundled
• Let us combine the wrapper with state:local Wrap Unwrapin
{NewWrapper Wrap Unwrap}fun {NewStack} {Wrap {NewCell nil}} endproc {Push W X} C={Unwrap W} in {Assign C X|{Access C}} endfun {Pop W} C={Unwrap W} in
case {Access C} of X|S then {Assign C S} X endendfun {IsEmpty S} {Access {Unwrap W}}==nil end
end• This version is stateful but lets us store the stack separate from the
operations. The same operations work on all stacks.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 35
Four ways to package a stack
• Open, declarative, and unbundled: the usual declarative style, e.g., in Prolog and Scheme
• Secure, declarative, and unbundled: use wrappers to make the declarative style secure
• Secure, stateful, and bundled: the usual object-oriented style, e.g., in Smalltalk and Java
• Secure, stateful, and unbundled: an interesting variation on the usual object-oriented style
• Other possibilities: there are four more possibilities! Exercise: Try to write all of them.
C. Varela; Adapted w/permission from S. Haridi and P. Van Roy 36
Exercises
• Write the higher-order function Map used by the Domain function in the Dictionary ADT.
• Solve problem 17 in Section 3.10 (pg. 232). You do not need to implement it using gump, simply specify how you would add currying to Oz (syntax and semantics).
• Do exercise 2 in Section 6.10 (pg. 482).
• Read Sections 2.8.3 and 6.4.4
top related