Transcript Slides
Lecture 6: Reasoning about Data Abstractions CS201J: Engineering Software University of Virginia Computer Science David Evans http://www.cs.virginia.edu/evans Requests • By 5pm tomorrow send any questions you have about Java programming to [email protected] – We’ll go over questions raised in class Thursday or section Friday • Please don’t harass the Assistant Coaches! – If they are not in Small Hall, don’t bother them with 201J questions. They have their own work to do also. 16 September 2003 CS 201J Fall 2003 2 Rep Invariant • The Representation Invariant expresses properties all legitimate objects of the ADT must satisfy I: C → Boolean Function from concrete representation to a Boolean. • Helps us reason about correctness of methods independently 16 September 2003 CS 201J Fall 2003 3 Reasoning with Rep Invariants • Prove all objects satisfy the invariant before leaving the implementation code • Assume all objects passed in satisfy the invariant REQUIRES: Rep Invariant is true for this (and any other reachable ADT objects) EFFECTS: Rep Invariant is true for all new and modified ADT object on exit. 16 September 2003 CS 201J Fall 2003 4 Preserving the Rep Invariant clients Cannot manipulate rep directly Abstract Type Concrete Representation StringSet () class implementation 16 September 2003 Constructors must initialize this in a way that satisfies the rep invariant CS 201J Fall 2003 insert (String s) Mutators: assume rep invariant holds on entry, ensure that it holds on all exits 5 Rep Invariant for StringSet public class StringSet { // OVERVIEW: StringSets are unbounded, // mutable sets of Strings. // A typical StringSet is {x1, ..., xn} // Representation: private Vector rep; // RepInvariant (c) = // c contains no duplicates // && c != null && all elements are Strings 16 September 2003 CS 201J Fall 2003 6 Implementing Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } Possibly correct implementation: we need to know how to map rep to abstraction notation to know if this_post = this_pre U { s } 16 September 2003 CS 201J Fall 2003 7 Abstraction Function • The Abstraction Function maps a concrete state to an abstract state: AF: C → A Function from concrete representation to the abstract notation introduced in overview specification. • Range is concrete states for which rep invariant is true 16 September 2003 CS 201J Fall 2003 8 Abstraction Function for StringSet public class StringSet { // OVERVIEW: StringSets are unbounded, // mutable sets of Strings. // A typical StringSet is {x1, ..., xn} // Representation: private Vector rep; // AF (c) = // { AFString (c.rep[i]) | 0 <= i < c.rep.size () } 16 September 2003 CS 201J Fall 2003 9 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } Use abstraction function to show if add implements its specification, the AF(rep_post) = AF(rep_pre) U {AFString(s)} 16 September 2003 CS 201J Fall 2003 10 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } Path 1: isIn (s) is true this is not modified, this_post = this_pre public boolean isIn (String s) // EFFECTS: Returns true iff s is an element of this. So, if isIn (s) returns true, we know sthis_pre. sx x s = x Hence, this_post = this_pre = this_pre s AF(rep_post) = AF(rep_pre) U {AFString(s)} 16 September 2003 CS 201J Fall 2003 11 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } Path 2: isIn (s) is false this_post = this_pre.add (s) If isIn (s) returns false, we know s this_pre. So, we need to know that AF(rep_pre.add(s)) = AF(rep_pre) U {AFString(s)} What does add do? 16 September 2003 CS 201J Fall 2003 12 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } boolean add (Object o) // Modifies: this // Effects: Appends o to the end of this. // this_post.size = this_pre.size + 1 // this_post[i] = this_pre[i] // forall 0 <= i < this_pre.size // this_post[this_pre.size] = o 16 September 2003 CS 201J Fall 2003 13 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } java.util.Vector.add (Object o) // Modifies: this // Effects: Adds o to the end of this. // this_post.size = this_pre.size + 1 // this_post[i] = this_pre[i] // forall 0 <= i < this_pre.sze // this_post[this_pre.size] = o So, after rep.add (s): rep_post.size = rep_pre.size + 1 rep_post[i] = rep_pre[i] forall 0 <= i < rep_pre.size rep_post[rep_pre.size] = s 16 September 2003 CS 201J Fall 2003 14 Correctness of Insert public void insert (String s) { // MODIFIES: this // EFFECTS: Adds s to the elements of this: // this_post = this_pre U { s } if (!isIn (s)) { rep.add (s); } } AF (c) = { AFString (c.rep[i]) | 0 <= i < c.rep.size () } rep_post.size == rep_pre.size + 1 rep_post[i] = rep_pre[i] forall 0 <= i < rep_pre.size rep_post[rep_pre.size] = s AF (rep_post) = { AFString (rep_post[i]) | 0 <= i < rep_post.size } = { rep_post[0], rep_post[1], …, rep_post[rep_post.size – 1] } = { rep_post[0], rep_post[1], …, rep_post[rep_post.size – 1] } = { rep_pre[0], rep_pre[1], …, rep_pre[rep_post.size – 1], s } = AF (rep_pre) U { s } 16 September 2003 CS 201J Fall 2003 15 Reality Check • Writing abstraction functions, rep invariants, testing code thoroughly, reasoning about correctness, etc. for a big program is a ridiculous amount of work! • Does anyone really do this? – Yes (and a lot more), but usually only when its really important to get things right: • Cost per line of code: – Small, unimportant projects: $1-5/line – WindowsNT: about $100/line – FAA’s Automation System (1982-1994): $900/line 16 September 2003 CS 201J Fall 2003 16 PS2 Wagering Strategy • How did you decide what to wager? • How should you have decided what to wager? 16 September 2003 CS 201J Fall 2003 17 Commerce School Strategy If p is the probability your code is correct, Expected Return = wp – 2w (1-p) = 3wp - 2w If p < 2/3, maximize with w = 0. If p = 2/3, expected return is 0 regardless of wager. If p > 2/3, expected return increases with w, bet maximum. 16 September 2003 CS 201J Fall 2003 18 Psychological Strategies • Expected return is a bad model, since the value is non-linear – If my ps was worth 90 without wager, 1/3 change of getting a 50 is not worth 2/3 chance of getting 110. • Dave is probably crazy for asking such a question, so I have no clue how this will be graded 16 September 2003 CS 201J Fall 2003 19 Why Confidence Matters? • Incorrect code, no confidence – Worthless, no one can use it (but if they do, they get what they deserve) • Correct code, no confidence – Worthless, no one can use it (but if they do, they get lucky) • Incorrect code, high confidence – Dangerous! • Correct code, high confidence – Valuable 16 September 2003 CS 201J Fall 2003 20 Easy way to get 100 on PS 2: • Get full credit for questions 1-4 • Answer question 5 (specify name trends) badly (0): static public void main (String args[]) // REQUIRES: false // EFFECTS: Prints out a correct proof of // P = NP. 16 September 2003 CS 201J Fall 2003 21 Remaining Answers 6. Implement program that satisfies spec: static public void main (String args[]) { // REQUIRES: false // EFFECTS: Prints out a correct proof of P = NP. System.err.println (“Ha ha ha!”) } 7. Testing Strategy • No testing necessary, no way to satisfy requires 8. Bet: 20 16 September 2003 Note: I didn’t actually want you to do this! CS 201J Fall 2003 22 Charge • Remember to email your Java programming questions to [email protected] • PS3 is due 1 week from today – I have office hours now 16 September 2003 CS 201J Fall 2003 23