Presentation is loading. Please wait.

Presentation is loading. Please wait.

EECE 310: Software Engineering

Similar presentations


Presentation on theme: "EECE 310: Software Engineering"— Presentation transcript:

1 EECE 310: Software Engineering
Data Abstractions EECE 310: Software Engineering

2 What will we learn ? Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Reasoning about the correctness of data abstractions and their implementations Equality testing and mutability

3 Data Abstraction Introduction of a new type in the language
Type can be abstract or concrete Has one of more constructors and operations Type can be used like a language type Both the code and the data associated with the type is encapsulated in the type specification No need to expose the representation to clients Clients do not depend on implementation Advantages: locality & modifiability

4 Why do we need new types ? Imagine we want to hold information about dates E.g. year, month, day, hours, minutes, seconds, day of week. Could use integer arrays, see right But suppose we then decide years need 4 digits rather than 2 (i.e. ,2001 instead of 01) We have to change every part of the program that uses dates e.g. if we used arrays of byte for date & time: byte today[3]; byte lecture1_time[3]; today[0] = 10; today[1] = 10; today[2] = 11; lecture1_time[0] = 17; lecture1_time[1] = 0; lecture1_time[2] = 0;

5 What does data abstraction provide?
Extending programming language Locality & Modifiability Deferring decision on data representation Changing implementation details

6 Isn’t this OOP ? NO, though OOP is one way to implement it
OOP is a way of organizing programs into classes and objects. Data abstraction is a way of introducing new types with meanings. Encapsulation is a goal shared by both. But data abstraction is more than creating classes. In Java, every data abstraction can be implemented by a class declaration. But every class declaration is not a data abstraction.

7 Difference between Data Abstraction and OOP
A data-structure representing a set of Integers may be a data abstraction (IntSet) Data type has a well-defined meaning Can be used in variable declarations An object may hold many unrelated data-structures in a program (IntSet and List) Convenient for code organization and reuse But does not necessarily have a clear meaning

8 Example: IntSet Consider a IntSet Data type that we wish to introduce in the language. What should it have Constructors to create the data-type from scratch or from other data types (e.g., lists) Operations: insert, remove, size and isIn A specification of what the data type represents Internal representation to implement the type

9 Data Type Specification
IntSet Example public class IntSet { // An IntSet is a mutable, bounded set of Integers. // A typical IntSet is {x1, x2, …. , xn } // constructors public IntSet(); // Mutators public void insert( int x ); public void remove( int x ); // Observers public int size(); } Class declaration Overview of data type Constructors Operations (only public ones) * Mutators Observers Producers

10 Data Type Overview Specification at the top of the class declaration
Explains what is the data-type being modeled Whether instances are mutable (can be changed) Whether it is bounded What is a typical example of the data-type Example: // An IntSet is a mutable, bounded set of Integers. // A typical IntSet is written as {x1, x2, …. , xn }

11 Constructors Initializes the data-type instance (this)
public IntSet( ) { // EFFECTS: Initializes this to be the empty set Initialization can be from one of the following Nothing Primitive types (e.g., singleton set) Other objects (e.g., another IntSet)

12 Operations Mutators Observers Modify the state of the object instance
Cannot be specified for immutable types Example: public void remove(int x) { // MODIFIES: this // EFFECTS: Removes x from // this, this_post = this – { x } Do not modify the state of the object Can be specified for both mutable & immutable types Example: public int size() { // MODIFIES: None // EFFECTS: Returns the // cardinality of this

13 Putting it together: IntSet Specification
public class IntSet { //OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all integeres // Constructors public IntSet(); //EFFECTS: Initializes this to be the empty set // Mutators public void insert (int x); // MODIFIES: this // EFFECTS: adds x to the set this, i.e, this_post = this u {x} public void remove (int x); // EFFECTS: this_post = this - {x} //Observers public boolean isIn(int x); // EFFECTS: returns true if x e this, false otherwise public int size(); // EFFECTS: Returns the cardinality of this }

14 Using ADTs: Rules Must be based on the specification of the data abstraction and not its implementation Implementation can change without notice Can perform the following operations: Use constructors to create new objects Can access object’s state through public methods Can change object’s state only if it is mutable

15 Using ADTs: Example public static IntSet populateElements (int [ ] a) throws NullPointerException { // EFFECTS: If a is null throws NullPointerException, // else returns a set containing an entry // for each distinct element of a. IntSet s = new IntSet( ); for (int i =0; i < a.length; ++i) { s.insert(a[i]); } return s; }

16 W7

17 [last time] Data Abstraction Specifying Abstract Data Types
Implementing Abstract Data Types

18 A big program can have thousands of procedures
Managing Complexity Procedural Abstraction Divide problem into procedures Use specifications to separate what from how A big program can have thousands of procedures

19 Data Abstraction Organize program around abstract data types (ADT)
Group procedures by the data they manipulate Hide how data is represented from how it is used

20 Abstract Data Types Separate what you (can) do with data from how it is represented Client interacts with data through provided operations according to their specifications Implementation chooses how to represent data and implement its operations What should the specification of a datatype look like?

21 Specifying Abstract Data Types
Overview: what does the type represent Mutability/Immutability e.g., A String is an immutable sequence of characters. Introduce Abstract Notation e.g., A typical Set is { x1, …, xn }. Operations: specifications for constructors and methods clients use Describe in terms of abstract notation introduced in overview.

22 Example: StringStack public class StringStack
Note: Java provides java.util.Stack, but we’ll implement our own Stack datatype. public class StringStack OVERVIEW: A StringStack represents a mutable last-in-first-out stack where all elements are Strings. A typical stack is [ e_n-1, e_n-2, ..., e_1, e_0 ] where e_n-1 is the top of the stack.

23 public class StringStack
OVERVIEW: A StringStack represents a mutable last-in-first-out stack where all elements are Strings. A typical stack is [ e_n-1, e_n-2, ..., e_1, e_0 ] where e_n-1 is the top of stack. public StringStack() EFFECTS: Initializes this as an empty stack. public void push(String s) MODIFIES: this EFFECTS: Pushes s on the top of this. For example, if this_pre = [ e_n-1, e_n-2, ..., e_1, e_0 ], this_post = [ s, e_n-1, e_n-2, ..., e_1, e_0 ] public String pop() throws EmptyStackException EFFECTS: If this is empty, throws EmptyStackException. Otherwise, returns the element on top of this and removes that element from this. this_post = [ e_n-2, ..., e_1, e_0 ] and the result is e_n-1. public String toString() EFFECTS: Returns a string representation of this.

24 Components of Data Abstractions
Ways to create new objects of the type Constructors: create new objects of the ADT from parameters of other types Producers: create new objects of the ADT from parameters of the ADT type (and other types) Ways to observe properties: observers Ways to change properties: mutators Which of these must all (useful) types have?

25 public class StringStack
OVERVIEW: A StringStack represents a mutable last-in-first-out stack where all elements are Strings. A typical stack is [ e_n-1, e_n-2, ..., e_1, e_0 ] where e_n-1 is the top of the stack. public StringStack() EFFECTS: Initializes this as an empty stack. public void push(String s) MODIFIES: this EFFECTS: Pushes s on the top of this. For example, if this_pre = [ e_n-1, e_n-2, ..., e_1, e_0 ], this_post = [ s, e_n-1, e_n-2, ..., e_1, e_0 ] public String pop() throws EmptyStackException EFFECTS: If this is empty, throws EmptyStackException. Otherwise, returns the element on top of this and removes that element from this. this_post = [ e_n-2, ..., e_1, e_0 ] and the result is e_n-1. public String toString() EFFECTS: Returns a string representation of this. Constructor Mutator Observer and Mutator Observer A producer?

26 What will we learn ? Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Proving correctness of data abstractions Equality testing and mutability

27 Abstraction vs. Representation
Mapping between abstract objects and their representation Every abstract object must have a representation Several representations might map to the same abstraction { 1, 2, 3 } 1 2 3 rep objects abstract objects Abstraction Representation

28 IntSet Specification public class IntSet { //OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all int // Constructors public IntSet(); //EFFECTS: Initializes this to be the empty set // Mutators public void insert (int x); // MODIFIES: this // EFFECTS: adds x to the set this, // i.e, this_post = this u {x} public void remove (int x); // EFFECTS: this_post = this - {x} //Observers public boolean IsIn(int x); // EFFECTS: returns true if x e this, false otherwise public int size(); // EFFECTS: Returns the cardinality of this }

29 IntSet: Implementation Strategies
Unsorted vector Rep: Vector of Integers, for each element of set called elems Insert, delete and membership require a linear scan of the array and can take O(N) time Size() takes O(1) time Bitmap Rep: Vector of Boolean, for each possible Integer value, called elems Insert, delete and membership take O(1) time on average, i.e., simple array indexing Size() can take O(N) time Tradeoffs: Does representation allow duplicates? Sort the vector?

30 Representation <-> Abstraction
N Vector ‘elems’ of size N Vector directly holds the set elements if integer e is in the set, there exists 0 <= i < N, such that elems[i] = e Similarly, if an integer e is in the vector, then e belongs to the set Vector is a bitmap for denoting set elements If integer i is in the set, then elems[i] = True, else elems[i] = False Cannot represent integers outside range [0, N - 1]

31 Abstraction Function Mapping between abstraction (abstract state) and the representation (concrete state) Captures designer’s intent in choosing the rep Describes what instance variables to use How do the variables relate to the abstract object that they are intended to represent ? Makes this mapping explicit as code comments

32 IntSet: Abstraction Function
Unsorted Array Boolean Vector AF ( c ) = { c.elems[i].intValue 0 <= i < c.elems.size } AF( c ) = { j | 0 <= j < 100 && c.elems[j] } Can be implemented by the member function: toString public void toString() { // EFFECTS: Converts the representation to a string // that represents the abstraction e.g., {x1, x2… xn} }

33 Implementation public class IntSet {
// OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all integers Vector<Integer> elems; // Rep // AF(c) = { c.elems[i].intValue // <= i < c.elems.size // } public class IntSet { // OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all integers Vector<Boolean> elems; // Rep // AF( c ) = { // j | 0 <= j < 100 && // c.elems[j].booleanValue // }

34 Abstraction Function: Points to Note
The abstraction function is defined for concrete instances of the class ‘c’, and only includes the instance variables of the class The abstraction function implicitly assumes that the representation is valid What happens if the vector contains duplicate entries in the first scenario ? What happens if the bitmap contains values other than 0 or 1 ?

35 Representation Invariant
Captures formally the assumptions on which the abstraction function is based Defines whether a particular representation is legal – invariant holds only for legal reps. Q: Should representation satisfy the representation invariant at all times Yes: except when executing the ADT’s methods

36 IntSet: Representation Invariant
Unsorted Arrays Boolean Vector c.elems != null && (there are no duplicates in c.elems i.e., for 0<=i, j <N,) c.elems[i].intValue = c.elems[j].intValue=> i = j. c.elements != null && c.elements.size = 100 Can be implemented by the member function: repOK public void repOK() { // EFFECTS: Return true if the repInvariant is //satisfied, false otherwise }

37 Implementation public class IntSet {
//OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all integers Vector<Integer> elems; // Rep // AF(c) = { c.elems[i].intValue // <= i < c.elems.size // } // RI = c.elems != NULL && // c.elems has no duplicates public class IntSet { //OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn}, where xi are all integers Vector<Boolean> elems // Rep // AF( c ) = { // j | 0 <= j < 100 && // c.elems[j].booleanValue // } // RI = c.elems != NULL && // c.elems.size = 100 // ???

38 Rep Invariant: Important Points
Rep invariant always holds before and after the execution of the ADT’s operations Can be violated while executing the ADT’s operations When should you define rep invariant? Before any operation of ADT is implemented Right after you write the Abstraction Function (AF) How much shall the rep invariant constrain? Just enough for different developers to implement different operations AND not talk to each other No need to repeat what is in the type signature

39 Implementation RepOK function toString function
Public method to check if the rep invariant holds Useful for testing/debugging public boolean repOK() { // EFFECTS: Returns true // if the rep invariant holds, // Returns false otherwise } Public method to convert a valid rep to a String form Useful for debugging/printing public String toString( ) { // EFFECTS: Returns a string // containing the abstraction // represented by the rep.

40 One more quiz-like question: For the class specified below chose the representation, write the representation function, the representation invariant; write the toString and repOk methods public class StringStack OVERVIEW: A StringStack represents a mutable last-in-first-out stack where all elements are Strings. A typical stack is [ e_n-1, e_n-2, ..., e_1, e_0 ] where e_n-1 is the top of stack. public StringStack() EFFECTS: Initializes this as an empty stack. public void push(String s) MODIFIES: this EFFECTS: Pushes s on the top of this. For example, if this_pre = [ e_n-1, e_n-2, ..., e_1, e_0 ], this_post = [ s, e_n-1, e_n-2, ..., e_1, e_0 ] public String pop() throws EmptyStackException EFFECTS: If this is empty, throws EmptyStackException. Otherwise, returns the element on top of this and removes that element from this. this_post = [ e_n-2, ..., e_1, e_0 ] and the result is e_n-1.

41 One more Consider a Polynomial data type represented as an array. The co-efficients of the term xi are stored in the ith element of trms array. Write its abstraction function Write its rep-invariant Write the repOK and toString functions. How would your answer change if the polynomial was represented as a list ?

42 Menu Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Exposing the rep Equality testing and mutability Proving correctness of data abstractions

43 Is it a good idea to make the representation available so that it can be modified (outside of using clas’ instance methods)?

44 Mistakes that lead to exposing the rep - 1
Making rep components public public class IntSet { public Vector<Integer> elements; Your rep must always be private. Otherwise, all bets are off. Hopefully, your code will not have this bug ….

45 Mistakes that lead to exposing the rep - 2
public class IntSet { //OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn} private Vector<Integer> elems; // no duplicates in vector public Vector<Integer> allElements (){ //EFFECTS: Returns a vector containing the elements of this, // each exactly once, in arbitrary order return elems; } }; intSet = new IntSet(); intSet.allElements().add( new Integer(5) ); intSet.allElements().add( new Integer(5) ); // RI violated – duplicates !

46 Mistakes that lead to exposing the rep - 3
public class IntSet { //OVERVIEW: IntSets are mutable, unbounded sets of integers. // A typical IntSet is {x1, …xn} private Vector<Integer> elems; //constructors public IntSet (Vector<Integer> els) throws NullPointerException { //EFFECTS: If els is null, throws NullPointerException, else // initializes this to contain as elements all the ints in els. if (els == null) throw new NullPointerException(); elems = els; } }; Vector<Integer> someVector = new Vector(); intSet = new IntSet(someVector); someVector.add( new Integer(5) ); someVector.add( new Integer(5) ); // RI violated – duplicates !

47 Summary of mistakes that expose the Rep
NOT making rep components private Returning a reference to the rep’s mutable components Initializing rep components with a reference to an “outside” mutable object NOT performing deep copy of rep elements Use clone method instead Perform manual copies

48 What will we learn ? Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Proving correctness of data abstractions Equality testing and mutability

49 Mutable objects Objects whose abstract state can be modified
Applies to the abstraction, not the representation Mutable objects: Can be modified once they are created e.g., IntSet, IntList etc. Immutable objects: Cannot be modified Examples: Polynomials, Strings

50 Equality: Equals Method
All objects are inherited from object which has a method “Boolean equals(Object o)” Returns true if object o is the same as the current Returns false otherwise Note that equals tests whether two objects have the same state If a and b are different objects, a.equals(b) will return false even if they are functionally identical

51 Equality: IntSet Example
IntSet a = new IntSet(); a.insert(1); a.insert(2); a.insert(3); IntSet b = new IntSet(); b.insert(1); b.insert(2); b.insert(3); if ( a.equals(b) ) { System.out.println(“Equal”); } What is printed by the above code ?

52 Equality: IntSet Example
It prints nothing. Why ? Because the intsets are different objects and the object.equals method only compares their hash Therefore, a.equals(b) returns false But this is in fact the correct behavior ! To see this, assume that you added an element to a but not b after the equals comparison a.equals(b) would no longer be true, even if you have not changed the references to a or b

53 Rule of Object Equality
Two objects should be equal if it is impossible to distinguish between them using any sequence of calls to the object’s methods Corollary: Once two objects are equal, they should always be equal. Otherwise it is possible to distinguish between them using some combination of the object’s methods.

54 IntSet Example: Revisited
In the IntSet example, you could distinguish between two IntSets by adding different elements to each set after the comparison. Therefore, they are NOT equal. However, if the objects are immutable AND have the same state, then the equality check should return true, i.e., in Equals method

55 Immutable Abstractions
ADT does not change once created No mutator methods Producer methods to create new objects Appropriate for modeling objects that do not change during their existence Mathematical entities such as Rational numbers Certain objects may be implemented more efficiently e.g., Strings

56 Why use immutable ADTs ? Safety Efficiency Ease of Implementation
Don’t need to worry about accidental changes Can be assured that rep doesn’t change Efficiency May hurt efficiency if you need to copy the object In some cases, it may be more efficient by sharing representations across objects e.g., Strings Ease of Implementation May be easier for concurrency control

57 Immutable ADT: Example - 1
public class Rational { // A typical rational is n/d private int num; private int denom; // AF ( c ) = c.num / c.denom // Rep Inv: c.denom > 0 Rational(int n, int d) throws ZeroException { // EFFECTS: … if (d == 0) throw new ZeroException; num = n; denom = d; } …

58 Immutable ADT: Example - 2
// Does this change the abstraction ? private void reduce( ) { // REQUIRES: this.num =/= 0 // MODIFIES: this // EFFECTS: Changes this to reduced form int temp = num; if (num < 0) temp = -num; int g = Num.gcd( temp, denom ); num = num / g; denom = denom / g; }

59 Immutable ADT: Example - 3
// Check if two Rationals are equal in reduced forms public void equals(Rational r) { if (r == null) return false; if (num ==0 || r.num == 0) return (num == r.num); reduce(); r.reduce(); return (r.num == num && r.denom == denom); }

60 Benevolent side effects
The equals method changes the representation but not the abstraction Hence, it is said to have a “benevolent” side effect Benevolent side-effect is a modification that is not visible outside implementation of the ADT Possible only when AF is many-to-one All side-effects of immutable abstractions must be benevolent (assuming a mutable rep)

61 Equality: Immutable objects
Immutable objects should define their own equals method Return true if the abstract state matches, even if the internal state is different Methods of an Immutable object can modify its rep, but not the abstraction Such methods said to have benevolent side effects

62 Summary Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Equality testing and mutability Proving correctness of data abstractions

63 Reasoning about ADTs - 1 ADTs have state in the form of representation
Need to consider what happens over a sequence of operations on the abstraction Correctness of one operation depends on correctness of previous operations We need to reason inductively over the operations of the ADT Show that constructor is correct Show that each operation is correct

64 Reasoning about ADTs - 2 First, need to show that the rep invariant is maintained by the constructor & operations Then, show that the implementation of the abstraction matches the specification Assume that the rep invariant is maintained Use the abstraction function to map the representation to the abstraction

65 Why show that Rep Invariant is maintained ?
Consider the implementation of the IntSet using the unsorted vector representation. We wish to compute the size of the set (i.e., its cardinality). public int size() { return elems.size(); } Is the above implementation correct ?

66 Why show that Rep Invariant is maintained ?
Yes, but only if the Rep Invariant holds ! c.elems != Null && c.elems has no duplicates Otherwise, size can return a value >= cardinality public int size() { return elems.size(); }

67 Showing Rep Invariant is maintained: Data Type Induction
Show that the constructor establishes the Rep Invariant For all other operations, Assume at the time of the call the invariant holds for this and all argument objects of the type Demonstrate that the invariant holds on return for this for returned objects of the type A Valid Rep Function Body Another Valid Rep

68 IntSet : getIndex Assume that IntSet has the following private function. private int getIndex( int x ) { // EFFECTS: If x is in this, returns index // where x appears in the Vector elems // else return -1 (do NOT throw an exception) for (int i = 0; i < els.size( ); i ++ ) if ( x == elements.get(i).intValue() ) return i; return –1; }

69 IntSet: Constructor RI: c.elems != NULL && c.elems has no duplicates
Show that the RI is true at the end of the constructor public IntSet( ) { // EFFECTS: Initializes this to be empty elems = new Vector<Integer>(); } RI: c.elems != NULL && c.elems has no duplicates Proof: Clause 1 is satisfied because the elems vector is initialized by constructor Clause 2 is satisfied because elems has no elements (and hence no duplicates)

70 IntSet: Insert RI: c.elems != NULL && c.elems has no duplicates
Show that if RI holds at the beginning, it holds at the end. public void insert (int x) { // MODIFIES: this // EFFECTS: adds x to the set such that this_post = this u {x} if ( getIndex(x) < 0 ) elems.add( new Integer(x) ); } RI: c.elems != NULL && c.elems has no duplicates Proof: If clause 1 holds at the beginning, it holds at the end of the procedure. - Because c.elems is not changed by the procedure. If clause 2 holds at the beginning, it holds at the end of the procedure - Because getIndex() prevents duplicate elements from being added to the vector

71 IntSet:Remove RI: c.elems != NULL && c.elems has no duplicates
Show that if RI holds at the beginning, it holds at the end. pubic void remove(int x) { // MODIFIES: this // EFFECTS: this_post = this - {x} int i = getIndex(x); if (i < 0) return; // Not found elems.set(i, elems.lastElement() ); elems.remove(elems.size() – 1); } RI: c.elems != NULL && c.elems has no duplicates

72 Other operations Show that if RI holds at the beginning, it holds at the end. public int size() { return elems.size(); } Proof: Both clauses hold because the operation does not modify the rep. public boolean isIn(int x) { return getIndex(x) > 0; } Proof: Both clauses hold because the operation does not modify the rep. RI: c.elems != NULL && c.elems has no duplicates

73 Rep Invariant Thus, we have shown that the RI is established by the constructor and holds for each operation (i.e., if RI is true at the beginning, it is true at the end). Can we stop here ? No. To see why not, consider an implementation of the operators that does nothing. Such an implementation will satisfy the rep invariant, but is clearly wrong !!! To complete the proof, we need to show that the Abstraction provided by the ADT is correct. For this, we use the (now proven) fact that the RI holds and use the AF to show that the rep satisfies the AF’s abstraction after each operation.

74 Abstraction Function: IntSet
Show that the implementation matches the ADT’s specification (i.e., its abstraction) Pre-Rep Abstraction function Pre-Abstraction Function Spec Function Implementation Abstraction function Post- Rep Post-Abstraction

75 Abstraction Function: Constructor
AF ( c ) = { c.elems[i].intValue | 0 <= i < c.elems.size } public IntSet( ) { // EFFECTS: Initializes this to be empty elems = new Vector<Integer>() ; } AF Empty vector Empty Set Proof: Constructor creates an empty set, so it is correct.

76 Abstraction Function: Size
AF ( c ) = { c.elems[i].intValue | 0 <= i < c.elems.size } public int size() { // EFFECTS: Returns the cardinality of this return elems.size( ); } AF Number of elements in vector Cardinality of the set (Why ?) Proof: Because the rep invariant guarantees that there are no duplicates in the vector, the number of elements in the vector denotes the cardinality of the set.

77 Abstraction Function: Insert
AF ( c ) = { c.elems[i].intValue | 0 <= i < c.elems.size } AF public void insert (int x) { // MODIFIES: this // EFFECTS: adds x to the set // such that this_post = this U {x} if ( getIndex(x) < 0 ) elems.add(new Integer(x)); } Vector this Implementation Vector with element added if and only if it did not already exist this_post = this U {x} AF

78 Abstraction Function: Remove
AF ( c ) = { c.elems[i].intValue| 0 <= i < c.elems.size } Vector this public void remove (int x) { // MODIFIES: this // EFFECTS: this_post = this - {x} int i = getIndex(x); if (i < 0) return; // Not found // Move last element to the index i elems.set(i, elems.lastElement() ); elems.remove(elems.size() – 1); } Vector with first instance of element removed if it exists this_post = this - {x}

79 Abstraction Function: IsIn
AF ( c ) = { c.elems[i].intValue| 0 <= i < c.elems.size } public boolean isIn(int x) { // EFFECTS: Returns true if x belongs to // this, false otherwise return getIndex(x) > 0; } vector this True if and only if x is present in the vector True if x belongs to this, False otherwise

80 Proof Summary This completes the proof. Thus, we’ve shown that the ADT implements it spec correcltly. This method is called “Data type induction”, because it proceeds using induction. Step 0: Write the implementation of the ADT Step 1: Show that the RI is maintained by the ADT Step 2: Assuming that the RI is maintained, show using the AF that the translation from the rep to the abstraction matches the method’s spec.

81 Group Exercise Write the implementation of the Polynomial data type discussed earlier. Write its RI and AF. Show using data-type induction that the ADT’s implementation matches its specification.

82 Summary Data abstractions Implementing data abstractions
What are they and how to specify them ? How to use them Implementing data abstractions Rep Invariant and Abstraction Functions Proving correctness of data abstractions Equality testing and mutability


Download ppt "EECE 310: Software Engineering"

Similar presentations


Ads by Google