Presentation is loading. Please wait.

Presentation is loading. Please wait.

Representation Invariants and Abstraction Functions.

Similar presentations


Presentation on theme: "Representation Invariants and Abstraction Functions."— Presentation transcript:

1 Representation Invariants and Abstraction Functions

2 Outline Reasoning about ADTs Representation invariants (rep invariants) Representation exposure Checking rep invariants Abstraction functions 2

3 Designing Data Structures From domain concept E.g., the math concept of a polynomial, an integer set, the concept of a library item, etc. through ADT Describes domain concept in terms specification fields and abstract operations to implementation Implements ADT with representation fields and concrete operations 3

4 Specifying an ADT 4

5 Example: Python Datatypes Tuples (e.g., (1,”John”))Lists (e.g., [1,2]) are immutableare mutable[j] len(t)len(l)[j:k]+* l.append(e) l.reverse() 5

6 Why ADTs? Bridges gap between domain concept and implementation Formalizes domain concept. We can reason about correctness of the implementation Shields client from implementation. Imple- mentation can vary without affecting client! 6

7 Reasoning About ADTs ADT is a specification, a set of operations E.g., contains(int i), add(int i), etc., (the IntSet ADT) add(Poly q), mul(Poly q), etc., (the Poly ADT) When specifying ADTs, there is no mention of data representation! When implementing the ADT, we must select a specific data representation 7

8 Implementation of an ADT is Provided by a Class To implement the ADT We must select the representation, the rep Implement operations in terms of that rep E.g., the rep of our Poly can be a) int[] coeffs or b) List terms Choose representation such that It is possible to implement all operations Most frequently used operations are efficient 8

9 Connecting Implementation to Specification Representation invariant: Object  boolean Indicates whether data representation is well- formed. Only well-formed representations are meaningful Defines the set of valid values Abstraction function: Object  abstract value What the data structure really means E.g., array [2, 3, -1] represents –x 2 + 3x + 2 How the data structure is to be interpreted 9

10 IntSet ADT /** Overview: An IntSet is a mutable set * of integers. E.g., { x 1, x 2, … x n }, {}. * There are no duplicates. */ // effects: makes a new empty IntSet public IntSet(); // modifies: this // effects: this post = this pre U { x } public void add(int x); // modifies: this // effects: this post = this pre - { x } public void remove(int x) // returns: (x in this) public boolean contains(int x) // reruns: cardinality of this public int size() 10

11 One Possible Implementation class IntSet { private List data = new ArrayList (); public void add(int x) { data.add(x); } public void remove(int x) { data.remove(new Integer(x)); } public boolean contains(int x) { return data.contains(x); } public int size() { return data.size(); } } 11 The representation (the rep)

12 The Representation Invariant s = new IntSet(); s.add(1); s.add(1); s.remove(1); The representation invariant tells us what’s wrong with this code: class IntSet { // Rep invariant: // data has no nulls and no duplicates private List data; … 12

13 The Representation Invariant States data structure well-formedness E.g., IntSet objects, whose data array contains duplicates, e.g., [1,1], are not well- formed Must hold before and after every concrete operation! Correctness of implementation depends on it 13

14 The Representation Invariant class IntSet { // Rep invariant: // data has no nulls and no duplicates private List data = new ArrayList (); public void add(int x) { data.add(x); } // Rep invariant may not hold after add! } 14

15 The Representation Invariant class IntSet { // Rep invariant: // data has no nulls and no duplicates private List data = new ArrayList (); public void add(int x) { if (!contains(x)) data.add(x); } // If rep invariant holds before add, it // holds after add too } 15

16 The Representation Invariant Rep invariant excludes ill-formed concrete values class LineSegment { // Rep invariant: !(x1 = x2 && y1 = y2) float x1, y1; // start point float x2, y2; // end point Conceptually, a line segment is defined by two distinct points. Thus, values with same start and end point (e.g., x1=x2=1, y1=y2=2), are meaningless. Rep invariant excludes them 16

17 The Representation Invariant Rep invariant excludes ill-formed concrete values class RightTriangle { // Rep invariant: 0 o < angle < 90 o && // base > 0 && base = hypot * cos(toRadians(angle)) float base, hypot, angle; // Objects that don’t meet the above constraints are // not right triangles 17

18 Additionally… Rep invariant states constraints imposed by specific data structures and algorithms E.g., Tree has no cycles, array must be sorted Rep invariant states constraints between fields that are synchronized with each other E.g., degree and coeffs fields in Poly (if we choose the array data representation) In general, rep invariant states correctness constraints --- if not met, things can go into terrible mess 18

19 Rep Invariant Example class Account { // Rep invariant: // transactions != null // no nulls in transactions // balance >= 0 // balance = Σ i transactions.get(i).amount private int balance; // history of transactions private List transactions; … } 19

20 Another Rep Invariant Example class NameList { //Rep invariant: 0 ≤ index < names.length int index; String[] names; … void addName(String name) { index++; if (index < names.length) names[index] = name; } 20 Where is the bug?

21 More Rep Invariant Examples class Poly { //Rep. invariant: degree = coeffs.length-1 // … and more … private int degree; private int[] coeffs; // operations add, sub, mul, eval, etc. } 21 class Poly { //Rep. invariant: //E(terms.get(i)) > E(terms.get(i+1)) … private List terms; // operations add, sub, mul, eval, etc. }

22 Representation Exposure Suppose we add this operation to our IntSet ADT // returns: a List containing the elements public List getElements(); Suppose we decide on the following implementation public List getElements() { return data; } What can go wrong with this implementation? 22

23 Representation Exposure 23

24 Representation Exposure Make a copy on the way out: public List getElements() { return new ArrayList (data); } Mutating a copy does not affect IntSet ’s rep IntSet s = new IntSet(); s.add(1); List li = s.getElements(); li.add(1); // mutates new copy, not IntSet’s rep 24

25 Representation Exposure Make a copy on the way in too: public IntSet(ArrayList elts) { data = new ArrayList (elts); … } Why? 25

26 Representation Exposure How about this: class Movie { private String title; … public String getTitle() { return title; } } Technically, there is representation exposure Representation exposure is dangerous when the rep is mutable If the rep is immutable, it’s ok 26

27 Immutability, again Suppose we add an iterator // returns: an Iterator over the IntSet public Iterator iterator(); Suppose the following implementation: public Iterator iterator() { return new Iterator(data); } 27

28 Immutability, again class Iterator { private List theData; private int next; public Iterator(List data) { theData = data; next = 0; } public boolean hasNext() { return (next < theData.size()); } public int next() { return theData.get(next++); } 28

29 Checking Rep Invariant checkRep() or repOK() Always check if rep invariant holds when debugging Leave checks anyway, if they are inexpensive Checking rep invariant of IntSet private void checkRep() { for (int i=0; i<data.size; i++) if (data.indexOf(data.elementAt(i)) != i) throw RuntimeException(“duplicates!”); } 29

30 Checking Rep Invariant checkRep() or repOK() Checking “no duplicates” rep invariant of IntSet private void checkRep() { for (int i=0; i<data.size; i++) if (data.indexOf(data.elementAt(i)) != i) throw RuntimeException(“duplicates!”); } Always check if rep invariant holds when debugging Leave checks anyway, if they are inexpensive 30

31 Connecting Implementation to Specification Representation invariant: Object  boolean Indicates whether data representation is well- formed. Only well-formed representations are meaningful Defines the set of valid values Abstraction function: Object  abstract value What the data representation really means E.g., array [2, 3, -1] represents –x 2 + 3x + 2 How the data structure is to be interpreted 31

32 Rep Invariant Excludes Meaningless Concrete Values Disallows meaningless values E.g., a RightTriangle cannot have base = -2 Ensures fields are properly synchronized volume and contents in BallContainer amount and transactions list in Account degree and coeffs array in Poly Ensures specific data structure constraints A Tree cannot have cycles Other correctness constraints 0 <= index < names.length, names!=null 32

33 Practice Defensive Programming Assume that you will make mistakes Write code to catch them On method entry Check rep invariant (i.e., call checkRep()) Check preconditions (requires clause) On method exit Check rep invariant (call checkRep()) Check postconditions Checking rep invariant helps find bugs Reasoning about rep invariant helps avoid bugs 33

34 Abstraction Function: rep  abstract value The abstraction function maps valid concrete data representation to the abstract value it represents AF: Object  abstract value The abstraction function lets us reason about behavior from the client perspective 34

35 Abstraction Function Example class Poly { // Rep invariant: … private int[] coeffs; private int degree; // Abstraction function: coeffs [a 0,a 1,…a degree ] // represents polynomial // a degree x degree + … + a 1 x + a 0 // E.g., array [-2,1,3]  3x 2 + x - 2 // Empty array represents the 0 polynomial … 35 The valid rep is the domain of the AF The polynomial, described in terms of (abstract) specification fields, is the range of the AF

36 Another Abstraction Function Example class IntSet { // Rep invariant: // data contains no nulls and no duplicates private List data; // Abstraction function: List [a 1,a 2,…a n ] // represents the set { a 1, a 2, … a n }. // Empty list represents {}. … public IntSet() … 36

37 Abstraction Function: mapping rep to abstract value Abstraction function: Object  abstract value I.e., the object’s rep maps to abstract value IntSet e.g.: list [2, 3, 1]  { 1, 2, 3 } Many concrete reps map to the same abstract value IntSet e.g.: [2, 3, 1]  { 1, 2, 3 } and [3, 1, 2]  { 1, 2, 3 } and [1, 2, 3]  { 1, 2, 3 } Not a function in the opposite direction One abstract value maps to many objects 37

38 The IntSet Implementation class IntSet { // Rep invariant: // data has no nulls and no duplicates private List data = new ArrayList (); public void add(int x) { if (!contains(x)) data.add(x); } public void remove(int x) { data.remove(new Integer(x)); } public boolean contains(int x) { return data.contains(x) } public int size() { return data.size(); } } 38 The representation (the rep)

39 Another (Implementation of) IntSet What if we dropped the “no duplicates” constraint from the rep invariant class IntSet { // Rep invariant: data contains no nulls private List data; … Can we still represent the concept of the IntSet ? (Remember, an IntSet is a mutable set of integers with no duplicates.) 39

40 Yes. But we must change the abstraction function class IntSet { // Rep invariant: data contains no nulls private List data; // Abstraction function: List data // represents the smallest set // { a 1, a 2, … a n } such that each a i is // in data. Empty list represents {}. … public IntSet() … 40

41 Another IntSet class IntSet { // Rep invariant: data contains no nulls private List data; … [1,1,2,3]  { 1, 2, 3 } [1,2,3,1]  { 1, 2, 3 } etc. There are many objects that correspond to the same abstract value 41

42 Another IntSet We must change the implementation of the concrete operations as well What is the implication for add(int x) and remove(int x) ? For size() ? add(int x) no longer needs to check contains(x). Why? remove(int x) must remove all occurrences of x in data. Why? What about size() ? What else? 42

43 Correctness Abstraction function allows us to reason about correctness of the implementation 43 Concrete objectConcrete object’ Abstract valueAbstract value’ AF: Abstract operation: Concrete operation (i.e., our implementation of operation):

44 IntSet Example 44 [2,1,1,2,3] AF: abstract remove(1): this – { 1 } Concrete remove(1) [2,2,3] { 1,2,3 }{ 2,3 } Creating concrete object: Establish rep invariant Establish abstraction function After every operation: Maintains rep invariant Maintains abstraction function

45 Aside: the Rep Invariant Which implementation is better class IntSet { // Rep invariant: // data has no nulls and no duplicates … // methods establish, maintain invariant, // maintain consistency w.r.t. original AF or class IntSet { // Rep invariant: data has no nulls … // methods maintain this weaker invariant, // maintain consistency w.r.t. to new AF 45

46 Aside: the Rep Invariant Often the rep invariant simplifies the abstraction function (specifically, it simplifies the domain of the abstraction function) Consequently, rep invariant simplifies implementation and reasoning! 46

47 Benevolent Side Effects Another implementation of IntSet.contains : public boolean contains(int x) { int i = data.indexOf(x); if (i == -1) return false; // move-to front optimization // speeds up repeated membership tests Integer y = data.elementAt(0); data.set(0,x); data.set(i,y); } Mutates rep, but does not change abstract value! 47

48 ADT is a Specification Specification of contains remains // returns: (x in this) boolean contains(int x); The specification reflects modification/effects on abstract state (i.e., specification fields), not concrete state (i.e., representation fields)! 48

49 Another Example: String.hashCode() // returns: the hashCode value of this string public int hashCode() { int h = this.hash; // rep. field hash if (h == 0) { // caches the hashcode char[] val = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[i]; } this.hash = h; // modifies rep. field } return h; } 49

50 Writing an Abstraction Function The domain is all representations that satisfy the rep invariant Rep invariant simplifies the AF by restricting its domain The range is the set of abstract values Denoted with specification fields and derived spec fields Relatively easy for mathematical concepts like sets Trickier for “real-world” ADTs (e.g., Person, Meeting) Specification fields and derived specification fields help describe abstract values 50

51 Specification Fields Describe abstract values. Think of the abstract value as if it were an object with fields E.g., math concept of a LineSegment start-point and end-point are specification fields length is a derived specification field Can be derived from spec fields but it’s useful to have Range of AF and specs of operations are in terms of specification fields 51

52 Specification Fields Often abstract values aren’t clean mathematical objects E.g., concept of Customer, Meeting, Item Define those in terms of specification fields: e.g., a Meeting can be specified with specification fields date, location, attendees In general, specification fields (the specification) are different from the representation fields (the implementation) 52

53 ADTs and Java Language Features Java classes Make operations of the ADT public methods Make other operations private Clients can only access the ADT operations Java interfaces Clients only see the ADT operations, nothing else Multiple implementations, no code in common Cannot include creators (constructors) or fields 53

54 ADTs and Java Language Features Both classes and interfaces can apply Write and rely upon careful specifications When coding, prefer interface types over specific class types E.g., we used List data not ArrayList data. Why? 54

55 Implementing an ADT: Summary Rep invariant Defines the set of valid objects (concrete values) Abstraction function Defines, for each valid object, which abstract value it represents Together they modularize the implementation Can reason about operations in isolation Neither is part of the ADT abstraction!!! 55

56 Implementing an ADT: Summary In practice Always write a rep invariant! Write an abstraction function when you need it Write a precise but informal abstraction function A formal one is hard to write, and often not that useful As always with specs: we look for the balance between what is “formal enough to do reasoning” and what is “humanly readable and useful” 56

57 Exercise The mathematical concept of the LineSegment Choose spec fields (abstraction) Choose rep fields Write rep invariant Write abstraction function 57

58 Exercise Suppose we decided to represent our polynomial with a list of terms: private List terms; Write the abstraction function Use e(terms[i]) to refer to exponent of i th term Use c(terms[i]) to refer to coefficient of i th term Be concise and precise 58

59 Review Problems: IntMap Specification The Overview: /** An IntMap is a mapping from integers to integers. * It implements a subset of the functionality of Map. * All operations are exactly as specified in the documentation * for Map. * * IntMap can be thought of as a set of key-value pairs: * * @specfield pairs = {,,,... } */ 59

60 Review Problems: IntMap Specification interface IntMap { /** Associates specified value with specified key in this map. */ bool put(int key, int val); /** Removes the mapping for the key from this map if it is present. */ int remove(int key); /** Returns true if this map contains a mapping for the specified key. */ bool containsKey(int key); /** Returns the value to which specified key is mapped, or 0 if this map contains no mapping for the key. */ int get(int key); } 60

61 Review Problems: IntStack Specification /** * An IntStack represents a stack of ints. * It implements a subset of the functionality of Stack. * All operations are exactly as specified in the documentation * for Stack. * * IntStack can be thought of as an ordered list of ints: * * @specfield stack = [a_0, a_1, a_2,..., a_k] */ 61

62 Review Problems: IntStack Specification interface IntStack { /** Pushes an item onto the top of this stack. * If stack_pre = [a_0, a_1, a_2,..., a_(k-1), a_k] * then stack_post = [a_0, a_1, a_2,..., a_(k-1), a_k, val]. */ void push(int val); /** * Removes the int at the top of this stack and returns that int. * If stack_pre = [a_0, a_1, a_2,..., a_(k-1), a_k] * then stack_post = [a_0, a_1, a_2,..., a_(k-1)] * and the return value is a_k. */ int pop(); } 62

63 Review Problems: Rep Invariants and Abstraction Functions Willy Wazoo wants to write an IntMap but only knows how to use an IntStack ! So he starts like this before he gets stuck class WillysIntMap implements IntMap { private IntStack theRep; … Help Willy write the rep invariant and abstraction function 63

64 Review Problems Now help Willy implement an IntStack with an IntMap class WillysIntStack implements IntStack { private IntMap theRep; int size; … Write a rep invariant and abstraction function 64


Download ppt "Representation Invariants and Abstraction Functions."

Similar presentations


Ads by Google