Title: Verification of Programs with Inspector Methods
1Verification of Programs with Inspector Methods
- Bart Jacobs and Frank Piessens
- Dept. CS, K.U.Leuven, Belgium
2Goal
- Specification and verification
- Of object-oriented modules
- Using inspector methods
- For information hiding
- In method contracts and object invariants
3Difficulties
- The combination of
- Aliasing
- Information hiding
- Method effect framing
- Sound first-order logic verification condition
generation
4Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
5Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
6Single-ObjectInspector Methods
- class Cell
- int x
- inspector int getX()
- return x
- Cell(int x)
- ensures getX() x this.x x
- Cell c1 new Cell(1)
- Cell c2 new Cell(2)
- assert c1.getX() 1
7Background Predicates
- get(set(s,f,v),f) v
- f1!f2gtget(set(s,f1,v),f2) get(s,f2)
- get2(s,f1,f2) get(get(s,f1),f2))
- set2(s,f1,f2,v) set(s, f1, set(get(s, f1), f2,
v))
8Single-ObjectInspector Methods
- (forall H, o
- Cell_getX(o, get(H,o)) get2(H,o,Cell_x))
- gt
- H1 set2(H0,this,Cell_x,x)
- gt
- Cell_getX(this,get(H1,this)) x
class Cell int x inspector int getX()
return x Cell(int x) ensures getX()
x this.x x
9Single-ObjectInspector Methods
- get2(H0,c1,alloc) false gt
- H1 set2(H0,c1,alloc,true) gt
- (forall o get2(H1,o,alloc) gtget2(H2,o,alloc)
(o ! c1 gt get(H2, o) get(H1,o))) gt - Cell_getX(c1,get(H2,c1)) 1 gt
- get2(H2,c2,alloc) false gt
- H3 set2(H2,c2,alloc,true) gt
- (forall o get2(H3,o,alloc) gt
get2(H4,o,alloc) (o ! c2 gt get(H4,o)
get(H3,o))) gt - Cell_getX(c2,get(H4,c2)) 2 gt
- Cell_getX(c1,get(H4,c1)) 1
Cell c1 new Cell(1) Cell c2 new
Cell(2) assert c1.getX() 1
10Single-ObjectInspector Methods
- When verifying mutator methods the abstraction
relation is assumed - When verifying client code frame conditions on
object states are assumed - Inspector method functions take the receivers
state as an argument
11Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
12Object Invariantsand Ownership
- class List
- rep int elems
- int count
- invariant 0 lt count
- invariant count lt elems.length
- inspector int getCount()
- return count
- inspector int getItem(int index)
- requires 0 lt index
- requires index lt getCount()
- return elemsindex
- derived_invariant 0 lt getCount()
- void add(int x)
- requires !committed inv
- modifies this.
- ensures !committed inv
- ensures
- getCount() old(getCount()) 1
- ensures
- forallint i in old((0getCount()))
- getItem(i) old(getItem(i))
- ensures
- getItem(old(getCount())) x
-
- unpack this
- count
- EnsureCapacity(count)
- elemscount 1 x
- pack this
13Object Invariants in the Boogie Methodology
- Each object gets an inv bit
- Updating o.f requires !o.inv
- pack o checks os declared invariant Inv(o) and
sets o.inv true - unpack o sets o.inv false
- It follows that if o.inv, then Inv(o)
- if o.inv is true, then o is valid otherwise o
is mutable
14Object Ownership in the Boogie Methodology
- Ownership allows inspector methods and object
invariants to depend on objects other than the
receiver - The ownership relation is dynamic
- An object owns its rep objects (i.e. the objects
pointed to by its rep fields) whenever it is
valid - pack o
- requires that os rep objects are not owned by
any object - causes o to take ownership of its rep objects and
sets their committed bits - unpack o causes o to release ownership of its
rep objects and clears their committed bits - It follows
- that an object has at most one owner
- that o.committed iff o has an owner
15Object Ownership in the Boogie Methodology
- Committed objects can be unpacked and modified
only by first unpacking their owner - os inspector methods and object invariant may
depend on os rep objects
16Encoding of Inspector Method Calls
- List l1 new List()
- List l2 new List()
- l1.add(5)
- l2.add(6)
- assert l1.getItem(0) 5
- ... gt
- List_getItem(l1, get(H5,l1),0) 5 gt
- (forall o get2(H5,o,alloc) gt
- (get2(H6,o,alloc)
- (!get2(H5,o,committed) o ! l2 gt
- get(H6,o) get(H5,o)))) gt
- List_getItem(l1, get(H6,l1),0) 5
- unpack this
- count
- EnsureCapacity(count)
- elemscount 1 x
- pack this
- assert getItem(getCount() - 1) x
- assert !committed !inv
- assert !elems.committed elems.inv
- assert 0 lt count count lt elems.length
- inv true
- elems.committed true
- elems_state Helems
- (forall H,o,i Reachable(H) gt
- get2(H,o,alloc) gt get2(H,o,inv) gt
- 0 lt i i lt List_getCount(o,get(H,o)) gt
- List_getItem(o,get(H,o),i)
- get(get(get(H,o),List_elems_state),i))
17Encoding of Inspector Method Calls
- To make method effect framing work, inspector
method functions continue to take just the state
of the receiver object as an argument - However, they may depend on owned objects as well
- Solution When packing an object, the state of
each rep object o.f is copied into a special
field o.f_state
18Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
19Multi-dependent Inspector Methods
- class IntCell
- inspector int get() ...
- void set(int value) ...
-
- class IntSet
- inspector bool contains(state IntCell c)
... - void add(IntCell c)
- ensures forallstate IntCell c2
- contains(c2)
- (old(contains(c2)) c2.get()
c.get()) - ...
20Termination of Inspector Methods
- An inspector methods receiver is implicitly
unpacked for the duration of the call - Also, object creations and explicit packs or
unpacks are not allowed in inspector methods - Therefore, the number of valid objects decreases
at each nested call
21Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
22Subclassing
- class Cell
- int x
- invariant 0 lt x
- inspector int getX() return x
- derived_invariant 0 lt getX()
- dynamic_invariant 0 lt getX()
- void setX(int x)
- requires !committed inv
- requires 0 lt x
- modifies this.
- ensures !committed inv
- ensures getX() x
- unpack this this.x x pack this
- class MyCell extends Cell
- invariant 1 lt super.getX()
- inspector int getX()
- return super.getX() 1
- void setX(int x)
- requires !committed inv
- requires 0 lt x
- modifies this.
- ensures !committed inv
- ensures getX() x
-
- unpack this
- super.setX(x 1)
- pack this
-
23Subclassing Encoding
- c1.x --gt get3(H,c1,Cell,Cell_x)
- c1.getX() --gt Cell_getX_dyn(c1,get2(H,c1,typeof(c1
))) - super.getX() --gt Cell_getX(c1,get2(H,c1,Cell))
- (forall o typeof(o) Cell gt
Cell_getX_dyn(o,s) Cell_getX(o,s)) - (forall o typeof(o) MyCell gt
Cell_getX_dyn(o,s) MyCell_getX(o,s)) - pack (MyCell)o --gt ... H set3(H,o,MyCell,supe
r_state, get2(H,o,Cell))
24Outline of the Talk
- Single-object inspector methods
- Object invariants and ownership
- Multi-dependent inspector methods
- Subclassing
- Related work, future work, conclusion
25Related Work
- Boogie methodology
- Method calls in specifications
- State abstraction in ownership systems
- Ownership-free approaches
26Relation toBoogie Methodology
- Based on Barnett, DeLine, Fähndrich, Leino,
Schulte 2004 - Differences
- Heap maps object refs to object states
- pack o copies owned object states
- Frame conditions are object-granular
- inv and committed bits are per frame
27Method Calls in Specifications
- Discussed by Darvas, Müller 2005
- Does not deal with framing issue
28State Abstraction in Ownership Systems
- Read and write effects in ownership type systems
(e.g. Boyapati 2004) - Model fields and the Universe type system Müller
2002 - Also supports visibility-based dependencies on
peers - Model fields on top of the Boogie methodology
Leino, Müller 2006
29Ownership-free Approaches
- Dynamic frames Kassios 2005
- Abstract predicates in separation logic
Parkinson 2005 - More flexible
- Not implemented in automatic program verifier
(but Smallfoot)
30Future Work
- Soundness proof
- Visibility-based dependencies
31Conclusion
- State abstraction for OO programs
- Supports standard coding pattern
- Implemented in automatic program verifier
- Supports multi-dependent inspector methods,
quantification over object states, subclassing