Presentation is loading. Please wait.

Presentation is loading. Please wait.

C. Varela; Adapted w/permission from S. Haridi and P. Van Roy1 Data Abstraction and State Abstract Data Types (3.7) State/Data Abstraction(6.1, 6.3, 6.4.1,

Similar presentations


Presentation on theme: "C. Varela; Adapted w/permission from S. Haridi and P. Van Roy1 Data Abstraction and State Abstract Data Types (3.7) State/Data Abstraction(6.1, 6.3, 6.4.1,"— Presentation transcript:

1 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy1 Data Abstraction and State Abstract 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

2 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy2 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

3 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy3 Example: A Stack Assume we want to define a new datatype  stack T  whose elements are of any type T fun {NewStack}:  Stack T  fun {Push  Stack T   T  }:  Stack T  fun {Pop  Stack T   T  }:  Stack T  fun {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

4 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy4 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

5 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy5 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

6 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy6 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

7 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy7 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

8 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy8 Implementation fun {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 fun {Domain Ds} {Map Ds fun {$ K#_} K end} end

9 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy9 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.

10 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy10 Secure abstract data types: Stack is not secure 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

11 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy11 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?

12 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy12 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 name N1==N2 : returns true or false

13 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy13 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 We want to « wrap » and « unwrap » values Let us use names to define a wrapper & unwrapper

14 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy14 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} end fun {Push S E} {Wrap E|{Unwrap S}} end fun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end end fun {IsEmpty S} {Unwrap S}==nil end end

15 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy15 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

16 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy16 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 ?

17 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy17 Secure abstract datatypes VI proc {NewWrapper ?Wrap ?Unwrap} Key={NewName} in fun {Wrap X} {NewChunk foo(Key:X)} end fun {Unwrap C} C.Key end

18 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy18 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} end fun {Push S E} {Wrap E|{Unwrap S}} end fun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end end fun {IsEmpty S} {Unwrap S}==nil end end

19 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy19 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 {Browse {Sum [1 2 3 4] 0}}

20 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy20 What is implicit state? The two arguments Xs and A represent an implicit state XsA [1 2 3 4]0 [2 3 4]1 [3 4]3 [4]6 nil10 fun {Sum Xs A } case Xs of X|Xr then {Sum Xr A+X } [] nil then A end {Browse {Sum [1 2 3 4] 0}}

21 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy21 What is explicit state: Example? X An unbound variable X A cell C is created with initial value 5 X is bound to C 5 X The cell C, which X is bound to, is assigned the value 6 6 C C

22 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy22 What is explicit state: Example? X An unbound variable X A cell C is created with initialvalue 5 X is bound to C 5 X The 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 not change

23 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy23 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

24 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy24 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

25 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy25 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

26 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy26 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

27 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy27 The model extended with cells Semantic stack w = f(x) z = person(a:y) y =  1 u =  2 x  1: w  2: x.... single assignment store mutable store

28 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy28 The stateful model  s  ::= skip empty statement |  s 1   s 2  statement sequence |... | {NewCell  x   c  } cell creation |{Exchange  c   x   y  } cell exchange Exchange: bind  x  to the old content of  c  and set the content of the cell  c  to  y 

29 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy29 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 the content of the cell  c  to  y  C := X is syntactic sugar for {Assign C X} @C is syntactic sugar for {Access C}

30 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy30 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

31 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy31 Stack: Open, declarative, and unbundled Here is the basic stack, as we saw it before: 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 This is completely unprotected. Where is it useful? Primarily, in small programs in which expressiveness is more important than security.

32 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy32 Stack: Secure, declarative, and unbundled We can make the declarative stack secure by using a wrapper: local Wrap Unwrap in {NewWrapper Wrap Unwrap} fun {NewStack} {Wrap nil} end fun {Push S E} {Wrap E|{Unwrap S}} end fun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end end fun {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.

33 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy33 Stack: Secure, stateful, and bundled This is the simplest way to make a secure stateful stack: proc {NewStack ?Push ?Pop ?IsEmpty} C={NewCell nil} in proc {Push X} {Assign C X|{Access C}} end fun {Pop} case {Access C} of X|S then {Assign C S} X end end fun {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

34 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy34 Stack: Secure, stateful, and unbundled Let us combine the wrapper with state: local Wrap Unwrap in {NewWrapper Wrap Unwrap} fun {NewStack} {Wrap {NewCell nil}} end proc {Push W X} C={Unwrap W} in {Assign C X|{Access C}} end fun {Pop W} C={Unwrap W} in case {Access C} of X|S then {Assign C S} X end end fun {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.

35 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy35 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.

36 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy36 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


Download ppt "C. Varela; Adapted w/permission from S. Haridi and P. Van Roy1 Data Abstraction and State Abstract Data Types (3.7) State/Data Abstraction(6.1, 6.3, 6.4.1,"

Similar presentations


Ads by Google