1 / 36

Carlos Varela RPI Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL

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. Abstract data types. A datatype is a set of values and an associated set of operations

fauve
Télécharger la présentation

Carlos Varela RPI Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 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 S0E} 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. 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 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 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

  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 name N1==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} 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 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 VI proc {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} 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 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 XsA} case Xs of X|Xr then {Sum XrA+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 XsA} case Xs of X|Xr then {Sum XrA+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? An unbound variable X C A cell C is created with initial value 5 X is bound to C 5 X C The cell C, which X is bound to, is assigned the value 6 6 X C. Varela; Adapted w/permission from S. Haridi and P. Van Roy

  22. What is explicit state: Example? An unbound variable X • 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 C A cell C is created with initialvalue 5 X is bound to C 5 X C The cell C, which X is bound to, is assigned the value 6 6 X 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 0 X 5 X Y 10 X 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 10 X 10 Y 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 0 X 5 X Y 10 X 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 = 1 u = 2 x 1: w 2: x .... .... single assignment store 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 the content 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 Exchange: bind xto the old content of cand set the content of the cell cto y proc {Assign C X} {Exchange C _ X} end fun {Access C} X in{Exchange C X X}X end 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 endend • 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 endend • 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} incase {Access C} of X|S then {Assign C S} X endendfun {IsEmpty S} {Access {Unwrap W}}==nil endend • 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 C. Varela; Adapted w/permission from S. Haridi and P. Van Roy

More Related