1
Verification of object-oriented
programswith invariantsMike Barnett, Robert DeLine,
Manuel Fahndrich, K. Rustan M. Leino,
Wolfram Schulte
ECOOP 2003 workshop on Formal Techniques for Java-like Programs
Encapsulation Seminar TAU 2005Presented by Yossi Peery
2
Agenda
Introduction Motivation and Background Object Invariants and Information Hiding
Solution Basic Methodology Concepts Adding Components and Subclasses Modifies Clause and Dynamic Dispatching Examples
Conclusion
3
Why Use Object Invariants
Definition:
“A relation on an object’s data that the programmer intends for to hold”
Detect and prevent Data corruption errors Misuse of the object data
Formal methods allow automatic static verification of program invariants
4
Background Hoare’s 1972
“Proof of correctness of data representations”
Eiffel Pioneer Design by Contract technique Dynamically checks invariants at run-time
Peter Muller 2001 An OO language providing useful guarantees about
when object invariants hold Uses “Universe Type System” as an ownership model Object invariants modeled by a boolean function on the
object’s data
5
Reentrancy Problem
public method P (…)
{
…
M ();
…
}
6
Invariant Misconception
General View:An invariant is an implicit post-condition on every constructor and an implicit pre- and post-condition on every public method
Misconception: Callers of an object’s methods do not need to
establish the implicit pre-condition of the invariant.
It is sufficient to restrict modifications of the invariant to methods of an object and establish it before the method ends
7
Explicit Invariant Condition
It will not be possible to call M from a function P that doesn’t ensure its invariant. Or,
It will not be possible to call a function P that ensure the invariant from the middle of M
8
Problem of Information Hiding
Invariants are conditions on the internal representation of objects
Explicit pre- and post-conditions are a breach of good information hiding
Conflict between revealing implementation details and the need for clients to know whether the object invariant holds
Same problem exists for modifies clause
9
Basic Methodology Concept
Provide an explicit representation of when object invariants are known to hold Add special public field st to every object.
o.st = Invalid o is invalid
o.st = Valid o is valid An object’s invariant holds whenever the object is valid
Restrictions st can appear only in routine specifications st can be modified only by special new statements:
pack & unpack Objects are allocated with o.st = Invalid
10
Basic Methodology Concept InvT(o) :
predicate to indicate that the invariant of object o of class T holds.
Using class T from previous example:
11
Basic Methodology Concept
12
Restrictions and Validity
Object field updates can break invariant: Field update statements: o.f := E Permitted only where o.st = Invalid InvT(o) can depend only on internal fields of o
If the above restrictions hold then the following is a program invariant:
where o ranges over non-null objects of type T Proof by induction over structure of program
statements
13
Components
Objects are usually built in a hierarchy of layered abstractions A “Buffered Input Stream” can be implemented
in terms of a cache and a file reader objects
Program correctness may depend on relations between fields of an objects and fields of its components
Need to expend previous restrictions
14
Components
If t.f = u then update of u.g breaks T’s invariant Need to make sure that:
u.st = Invalid => t.st = Invalid
t.st = Valid => u.st = Committed
15
Ownership
Committed state indicates Ownership If t.f.st = Commited then t owns t.f Creates hierarchy of owned objects
Use rep modifier to indicate that a field is a component:
private rep f : U;Object invariants can now depend on
this.f0.f1.f2. … .g where fi are declared with the rep modifier
16
Components
st : { Invalid , Valid, Committed }
CompT(o) = { o.f : f is a rep field in T }
17
Components
Program Invariant:
Unique Ownership:
Ownership Transfer:
18
Subclasses
Object divided into class frames
Each frame can be valid or invalid possible subsets
Consider only nonempty prefixes { object } { object, A } { object, A, B }
n2
19
New Encoding
Instead of st: Special field inv holds type of most derived valid class Special field committed is boolean indicating if object is
committed
committed = TRUE => inv = type(o)
New objects of type T should return from the constructor as:
inv = T & !commited
Field updates of subclass allowed if object is “sufficiently unpacked”
Invariants may contain fields of subclasses
20
New Encoding
T extends S
o is any subclass of T
21
Soundness Theorem
The following are program invariants
(ranges over non-null objects; <: is the subclass relationship)
Proof shows the conditions are maintained for all actions that extend the quantification range or change values of object fields
22
Modifies Clause
Model access to an object field by changes to the program heap: Heap is a global 2 dimensional array indexed
by object references and field names Location if o.f is modeled by Heap[o,f]
Modifies Clause contains a set of heap locations the routine is allowed to modify
Routines are allowed to allocate new objects and modify their state Special field alloc denotes allocated objects
23
Modifies Clause
Post-condition for modifies clause W:
Innovation: allow every routine to modify fields of commited objects:
Implementation Hiding Use special expression E.{ T } T = { class name, type(o) for object-valued expression o } Denotes all regular fields of object E declared in class T
and its super classes
24
Dynamic Dispatch
pack and unpack statements need to specify which type they are unpacking Need to state the exact value of inv as a precondition Limits use of dynamic dispatching
Innovation: Use special expression: inv = 1 For caller 1 means type(this) For implementation in class T, 1 means T
How can this be sound?
25
Dynamic Dispatch Soundness:
For declaration of dynamic dispatched method M, introduce a procedure named M with specification:
inv = type(this) For implementation of M in class T introduce a procedure
M@T with specification: inv = T Body of procedure M looks at type of this and calls
corresponding procedure M@type(this) Body of M@T is like that of method M in T except that any
call for super class, super.M(…) is replaced with M@S Every class must supply an implementation for every
dynamically dispatched method declared in the class or its super class
Extend 1 for the modifies clause: E.{1}
26
Examples
Can be used as a super class or a component Subclass implementation can modify all regular
fields of super class.
27
Examples
Constructor must copy char array
28
Examples
Constructor can capture the reader
29
Examples
Lexer can relinquish the underlying reader Reader must be relinquished in an uncommitted
state Implementation leaves Lexer in an inconsistent
state so that GetToken can no longer be invoked
30
Conclusions
Programmer must be aware at which points an object invariant can be relied upon
Presented method that provides programmers with a flexible and precise way to specify their intensions about object invariants
Ownership method allows a single valid owner per object at a time but doesn’t confine object aliasing and allows multiple read access
Methodology allows for both static verification and dynamic checking
31
Current Work
Spec # Extension of C# with method contracts Compiler and static verifier tools integrate with
visual studio .NET
Boogie Spec# static program verifier
WebSitehttp://research.microsoft.com/foundations