Representation invariants and abstraction functions CSE 331 UW CSE.

Slides:



Advertisements
Similar presentations
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Advertisements

David Evans CS201J: Engineering Software University of Virginia Computer Science Lecture 6: Reasoning about Data Abstractions.
Data Abstraction II SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
Object Oriented Design An object combines data and operations on that data (object is an instance of class) data: class variables operations: methods Three.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION ABSTRACT DATA TYPES II Autumn 2011.
CSE503: SOFTWARE ENGINEERING COMPLEXITY, PROVING ADTS David Notkin Spring 2011.
Abstraction Functions. Announcements Exam 1 on Tuesday March 3 rd Closed book/phone/laptop 2 cheat pages allowed (handwritten or typed) 1 double-sided.
CSE 331 Software Design & Implementation Dan Grossman Fall 2014 Data Abstraction: Abstract Data Types (ADTs) (Based on slides by Mike Ernst, David Notkin,
Slides by Vinod Rathnam with material from Alex Mariakakis Kellen Donohue, David Mailhot, and Hal Perkins Midterm Review.
Computer Science 340 Software Design & Testing Design By Contract.
Ranga Rodrigo. Class is central to object oriented programming.
Procedure specifications CSE 331. Outline Satisfying a specification; substitutability Stronger and weaker specifications - Comparing by hand - Comparing.
Cs2220: Engineering Software Class 8: Implementing Data Abstractions Fall 2010 University of Virginia David Evans.
1 Abstraction  Identify important aspects and ignore the details  Permeates software development programming languages are abstractions built on hardware.
Cs205: engineering software university of virginia fall 2006 Data Abstraction David Evans
23-Oct-15 Abstract Data Types. 2 Data types A data type is characterized by: a set of values a data representation, which is common to all these values,
13-1 Sets, Bags, and Tables Exam 1 due Friday, March 16 Wellesley College CS230 Lecture 13 Thursday, March 15 Handout #23.
These courseware materials are to be used in conjunction with Software Engineering: A Practitioner’s Approach, 6/e and are provided with permission by.
Reasoning about programs March CSE 403, Winter 2011, Brun.
(c) University of Washington15-1 CSC 143 Java List Implementation via Arrays Reading: 13.
Data Abstractions EECE 310: Software Engineering.
CSE 331 Software Design & Implementation Hal Perkins Autumn 2012 Abstract Data Types – Examples / Summary (Based on slides by Mike Ernst and David Notkin)
Data Abstraction SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
Testing CSE 160 University of Washington 1. Testing Programming to analyze data is powerful It’s useless (or worse!) if the results are not correct Correctness.
SWE 4743 Abstract Data Types Richard Gesick. SWE Abstract Data Types Object-oriented design is based on the theory of abstract data types Domain.
Understanding ADTs CSE 331 University of Washington.
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
CSE 331 Software Design & Implementation Dan Grossman Fall 2014 Abstraction Functions (Based on slides by Mike Ernst, David Notkin, Hal Perkins)
Iteration Abstraction SWE Software Construction Fall 2009.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION ABSTRACT DATA TYPES Autumn 2011.
David Evans CS201J: Engineering Software University of Virginia Computer Science Lecture 7: A Tale of Two Graphs (and.
David Evans CS201J: Engineering Software University of Virginia Computer Science Lecture 5: Implementing Data Abstractions.
Zach Tatlock / Winter 2016 CSE 331 Software Design and Implementation Lecture 6 Representation Invariants.
Representation Invariants and Abstraction Functions.
Reasoning and Design (and Assertions). How to Design Your Code The hard way: Just start coding. When something doesn’t work, code some more! The easier.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Prof. I. J. Chung Data Structure #1 Professor I. J. Chung.
Slides by Alex Mariakakis Section 5: Midterm Review.
CSE 331 Software Design & Implementation Hal Perkins Autumn 2012 Data Abstraction: Abstract Data Types (ADTs) (Based on slides by Mike Ernst and David.
EECE 310: Software Engineering
EECE 310: Software Engineering
CSE 331 Software Design & Implementation
CSE 331 Software Design & Implementation
CSE 331 Software Design and Implementation
Testing UW CSE 160 Winter 2017.
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Specifications Liskov Chapter 9
Testing UW CSE 160 Spring 2018.
CSE 331 Software Design and Implementation
CSE 331 Software Design and Implementation
Abstraction functions, Reasoning About ADTs
Testing UW CSE 160 Winter 2016.
CSE 331 Software Design & Implementation
CSE 331 Software Design and Implementation
CSE 331 Software Design and Implementation
Data Abstraction David Evans cs205: engineering software
CSE 373 Data Structures and Algorithms
SWE 619 Software Construction Last Modified, Fall 2015 Paul Ammann
Lecture 7: A Tale of Two Graphs CS201j: Engineering Software
Lecture 4: Data Abstraction CS201j: Engineering Software
CSE 331 Software Design & Implementation
EECE 310: Software Engineering
CSE 331 Software Design and Implementation
CSE 331 Software Design & Implementation
CSE 331 Software Design & Implementation
CSE 331 Software Design & Implementation
Computer Science 340 Software Design & Testing
Lists CMSC 202, Version 4/02.
Software Specifications
Presentation transcript:

Representation invariants and abstraction functions CSE 331 UW CSE

ADTs and specifications Specification: only in terms of the abstraction Never mentions the representation An ADT is more than just a data structure data structure + a set of conventions Why do we need to relate the specification to the representation?

Connecting specifications and implementations Representation invariant: Object → boolean Indicates whether a data structure is well-formed Defines the set of valid values of the data structure Abstraction function: Object → abstract value What the data structure means (as an abstract value) How the data structure is to be interpreted How do you compute the inverse, abstract value → Object ?

A data abstraction is defined by a specification A collection of procedural abstractions Not a collection of procedures Together, these procedural abstractions provide A set of values All the ways of directly using that set of values Creating Manipulating Observing Creators and producers: make new values Mutators: change the value (but don’t affect == ) Observers: allow one to tell values apart

Implementation of an ADT is provided by a class To implement a data abstraction - Select the representation of instances, the rep - Implement operations in terms of that rep Choose a representation so that - It is possible to implement operations - The most frequently used operations are efficient But which will these be? Abstraction allows the rep to change later

CharSet Abstraction // Overview: A CharSet is a finite mutable set of Characters // effects: creates a fresh, empty CharSet public CharSet ( ) // modifies: this // effects: this post = this pre U {c} public void insert (Character c); // modifies: this // effects: this post = this pre - {c} public void delete (Character c); // returns: (c ∈ this) public boolean member (Character c); // returns: cardinality of this public int size ( );

A CharSet implementation. What client code will expose the error? class CharSet { private List elts = new ArrayList (); public void insert(Character c) { elts.add(c); } public void delete(Character c){ elts.remove(c); } public boolean member(Cha return elts.contains(c) } public int size() { return elts.size(); } } CharSet s = new CharSet(); Character a = new Character(‘a’); s.insert(a); s.insert(a); s.delete(a); if (s.member(a)) // print “wrong”; else // print “right”;

Where Is the Error? The answer to this question tells you what needs to be fixed Perhaps delete is wrong It should remove all occurrences Perhaps insert is wrong It should not insert a character that is already there How can we know? The representation invariant tells us

The representation invariant States data structure well-formedness Captures information that must be shared across implementations of multiple operations Write it this way: class CharSet { // Rep invariant: elts has no nulls and no duplicates private List elts; ( Or, if you are the pedantic sort: ∀ indices i of elts. elts.elementAt(i) ≠ null ∀ indices i, j of elts. i ≠ j ⇒ ¬ elts.elementAt(i).equals(elts.elementAt(j))

Now, we can locate the error // Rep invariant: // elts has no nulls and no duplicates public void insert(Character c) { elts.add(c); } public void delete(Character c) { elts.remove(c); }

Another rep invariant example class Account { private int balance; // history of all transactions private List transactions; … } // real-world constraints: balance ≥ 0 balance = Σ i transactions.get(i).amount // implementation-related constraints: transactions ≠ null no nulls in transactions

Listing the elements of a CharSet Consider adding the following method to CharSet // returns: a List containing the members of this public List getElts(); Consider this implementation: // Rep invariant: elts has no nulls and no duplicates public List getElts() { return elts; } Does the implementation of getElts preserve the rep invariant? … sort of

Representation exposure Consider the client code (outside the CharSet implementation) CharSet s = new CharSet(); Character a = new Character(‘a’); s.insert(a); s.getElts().add(a); s.delete(a); if (s.member(a)) … Representation exposure is external access to the rep Representation exposure is almost always evil If you do it, document why and how And feel guilty about it!

Ways to avoid rep exposure 1.Exploit immutability Character choose() { return elts.elementAt(0); } Character is immutable. 2.Make a copy List getElts() { return new ArrayList (elts); // or: return (ArrayList ) elts.clone(); } Mutating a copy doesn’t affect the original. Don’t forget to make a copy on the way in! 3.Make an immutable copy List getElts() { return Collections.unmodifiableList (elts); } Client cannot mutate Still need to make a copy on the way in

Checking rep invariants Should code check that the rep invariant holds? - Yes, if it’s inexpensive - Yes, for debugging (even when it’s expensive) - It’s quite hard to justify turning the checking off - Some private methods need not check (Why?)

Checking the rep invariant Rule of thumb: check on entry and on exit (why?) public void delete(Character c) { checkRep(); elts.remove(c) // Is this guaranteed to get called? // See handouts for a less error-prone way to check at exit. checkRep(); } … /** Verify that elts contains no duplicates. */ private void checkRep() { for (int i = 0; i < elts.size(); i++) { assert elts.indexOf(elts.elementAt(i)) == i; } }

Practice defensive programming Assume that you will make mistakes Write and incorporate code designed to catch them On entry: Check rep invariant Check preconditions (requires clause) On exit: Check rep invariant Check postconditions Checking the rep invariant helps you discover errors Reasoning about the rep invariant helps you avoid errors Or prove that they do not exist! We will discuss such reasoning, later in the term

The rep invariant constrains structure, not meaning New implementation of insert that preserves the rep invariant: public void insert(Character c) { Character cc = new Character(encrypt(c)); if (!elts.contains(cc)) elts.addElement(cc); } public boolean member(Character c) { return elts.contains(c); } The program is still wrong Clients observe incorrect behavior What client code exposes the error? Where is the error? We must consider the meaning The abstraction function helps us CharSet s = new CharSet(); Character a = new Character(‘a’)); s.insert(a); if (s.member(a)) // print “right”; else // print “wrong”;

Abstraction function: rep → abstract value The abstraction function maps the concrete representation to the abstract value it represents AF: Object → abstract value AF(CharSet this) = { c | c is contained in this.elts } “set of Characters contained in this.elts” Typically not executable The abstraction function lets us reason about behavior from the client perspective Our real goal is to satisfy the specification of insert: // modifies: this // effects: this post = this pre U {c} public void insert (Character c); Once again we can place the blame Applying the abstraction function to the result of the call to insert yields AF(elts) U {encrypt(‘a’)} What if we used this abstraction function? AF(this) = { c | encrypt(c) is contained in this.elts } AF(this) = { decrypt(c) | c is contained in this.elts }

Placing the blame Our real goal is to satisfy the specification of insert: // modifies: this // effects: this post = this pre U {c} public void insert (Character c); The AF tells us what the rep means (and lets us place the blame) AF(CharSet this) = { c | c is contained in this.elts } Consider a call to insert: On entry, the meaning is AF(this pre ) ≈ elts pre On exit, the meaning is AF(this post ) = AF(this pre ) U {encrypt(‘a’)} What if we used this abstraction function? AF(this) = { c | encrypt(c) is contained in this.elts } = { decrypt(c) | c is contained in this.elts }

Benevolent side effects Different implementation of member: boolean member(Character c1) { int i = elts.indexOf(c1); if (i == -1) return false; // move-to-front optimization Character c2 = elts.elementAt(0); elts.set(0, c1); elts.set(i, c2); return true; } AF r a op r’ ⇒ Move-to-front speeds up repeated membership tests Mutates rep, but does not change abstract value AF maps both reps to the same abstract value

The abstraction function is a function Q: Why do we map concrete to abstract rather than vice versa? 1. It’s not a function in the other direction. E.g., lists [a,b] and [b,a] each represent the set {a, b} 2. It’s not as useful in the other direction. Can construct objects via the provided operators

Writing an abstraction function The domain: all representations that satisfy the rep invariant The range: can be tricky to denote For mathematical entities like sets: easy For more complex abstractions: give them fields AF defines the value of each “specification field” The overview section of the specification should provide a way of writing abstract values A printed representation is valuable for debugging

Summary Rep invariant Which concrete values represent abstract values Abstraction function For each concrete value, which abstract value it represents Together, they modularize the implementation Can examine operators one at a time Neither one is part of the abstraction (the ADT) In practice Always write a representation invariant Write an abstraction function when you need it Write an informal one for most non-trivial classes A formal one is harder to write and usually less useful