chapter 8 properties of counters abstract datatypes
play

Chapter 8 Properties of counters Abstract Datatypes We might also - PDF document

Ch.8: Abstract Datatypes Ch.8: Abstract Datatypes Plan Plan Chapter 8 Properties of counters Abstract Datatypes We might also require that our representation should satisfy some obvious properties. The following should hold for any counters


  1. Ch.8: Abstract Datatypes Ch.8: Abstract Datatypes Plan Plan Chapter 8 Properties of counters Abstract Datatypes We might also require that our representation should satisfy some obvious properties. The following should hold for any counters c1 and An abstract data type is a description of a common representation of c2 : data. Abstract data types are one of the most important concepts in all is_zero(make_counter()) programming, because they allow building representations for complex data from simpler parts. not is_zero(inc c) Also, looking at abstract data types gives us an opportunity to review c1 = c2 iff inc(c1) = inc(c2) concepts such as functions on lists, datatypes, polymorphism, currying, higher-order functions and show some the functional implementation of c1 = c2 implies that dec(c1) = dec(c2) some algorithms. c1 = dec(inc(counter)) A simple example: A counter. We need a few operations: Questions: • make_counter : () -> counter • do the requirements above allow us to show that inc(c1) = c1 holds • inc : counter -> counter for no counter c1 ? • dec : counter -> counter • does the requirements above state everything we would like to be true for counters? To keep things simple, assume that when a counter reaches zero, it stays at zero if we keep decrementing it. More operations: • is_zero : counter -> bool • = : counter * counter -> bool Let’s assume that counters can be compared for equality. Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.1 Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.2 FP FP Ch.8: Abstract Datatypes Plan Ch.8: Abstract Datatypes Plan Implementing counters Counters as lists We could do something more imaginative: type counter = int type counter = unit list fun make_counter () = 0 fun inc c = c+1 fun make_counter () = [] fun dec c = if c = 0 then 0 else c-1 fun inc c = ()::[] fun is_zero c = c = 0 fun dec c = if c = [] then [] else tl c (Check that this representation satisfies the requirements) fun is_zero c = null c Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.3 Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.4

  2. Ch.8: Abstract Datatypes Ch.8: Abstract Datatypes Plan Plan A datatype for counters Odd integers for counters Something even more imaginative: type counter = int datatype counter = fun make_counter () = 1 EmptyCounter | UnitCounter of counter fun inc c = c+2 fun dec c = if c = 1 then 1 else c-2 fun make_counter () = EmptyCounter fun is_zero c = c = 1 fun inc c = UnitCounter c fun dec (EmptyCounter) = EmptyCounter Now, note that none of the representations offer any mechanism for | dec (UnitCounter c) = c protecting the data from misuse. fun is_zero (EmptyCounter) = true | is_zero (UnitCounter c) = false Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.5 Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.6 FP FP Ch.8: Abstract Datatypes Plan Ch.8: Abstract Datatypes Plan Why abstract datatypes? What is an abstraction (in Computer Science)? A way to introduce new concepts that are meaningful to humans. Useful to make a datatype abstract when Examples: files, data structures, procedure calls, other programming constructs. • the implementation of the datatype is complex, • there are many ways to implement the datatype, or (We think of files as something real, but files don’t exist, they are just a bunch of bits on a hard drive. Come to think of it, bits don’t exist either, • you want to keep the datatype separate from the rest of the code. they are just magnetic fluctuations on the surface of the disk platters.) • The datatype represents a natural abstraction. Abstract datatypes are often a good way to split a program into parts that can be understood individually. What is an abstraction (in Computer Science)? Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.7 Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.8

  3. Ch.8: Abstract Datatypes Ch.8: Abstract Datatypes 8.1. An abstract datatype for stacks 8.1. An abstract datatype for stacks 8.1. An abstract datatype for stacks ‘Formal’ semantics isEmptyStack emptyStack = true Stacks of objects of type α : α stack ∀ v,S : isEmptyStack (push v S) = false top emptyStack = ... error ... Operations ∀ v,S : top (push v S) = v pop emptyStack = ... error ... value emptyStack ∀ v,S : pop (push v S) = S TYPE: α stack VALUE: the empty stack function isEmptyStack S Question: Do the properties above state everything we need to know TYPE: α stack → bool about stacks? Is there any other property you would like to add? PRE: (none) POST: true if S is empty false otherwise function push v S TYPE: α → α stack → α stack PRE: (none) POST: the stack S with v added as new top element function top S TYPE: α stack → α PRE: S is non-empty POST: the top element of S function pop S TYPE: α stack → α stack PRE: S is non-empty POST: the stack S without its top element Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.9 Sven-Olof Nystr¨ om/IT Dept/Uppsala University 8.10 FP FP Ch.8: Abstract Datatypes 8.2. Realisation of the stack abstract datatype Ch.8: Abstract Datatypes 8.2. Realisation of the stack abstract datatype 8.2. Realisation of the stack abstract datatype Version 2 Definition of a new constructed type using the list type: Version 1 datatype α stack = Stack of α list REPRESENTATION CONVENTION: the head of the list is the top of Representation of a stack by a list : the stack, the 2nd element of the list is the element below the top, etc type α stack = α list REPRESENTATION CONVENTION: the head of the list is the top of the stack, the 2nd element of the list is the element below the top, etc Realisation of the operations Realisation of the operations (stack1.sml) val emptyStack = Stack [ ] fun isEmptyStack (Stack S) = (S = [ ]) val emptyStack = [ ] fun push v (Stack S) = Stack (v::S) fun isEmptyStack S = (S = [ ]) fun top (Stack [ ]) = error "top: empty stack" fun push v S = v::S | top (Stack (x::xs)) = x fun top [ ] = error "top: empty stack" fun pop (Stack [ ]) = error "pop: empty stack" | top (x::xs) = x | pop (Stack (x::xs)) = Stack xs fun pop [ ] = error "pop: empty stack" | pop (x::xs) = xs • The operations are now only defined for stacks • It is still possible to access the elements of the stack • This realisation does not force the usage of the stack type without using the operations specified above, • The operations can also be used with objects of type α list , namely by pattern matching even if they do not represent stacks! • It is possible to access the elements of the stack without using the operations specified above: no encapsulation! Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.11 Sven-Olof Nystr¨ om/IT Dept/Uppsala University FP 8.12

Recommend


More recommend