310 likes | 431 Views
Verification of Programs with Inspector Methods. Bart Jacobs and Frank Piessens Dept. CS, K.U.Leuven, Belgium. Goal. Specification and verification Of object-oriented modules Using inspector methods For information hiding In method contracts and object invariants. Difficulties.
E N D
Verification of Programs with Inspector Methods Bart Jacobs and Frank Piessens Dept. CS, K.U.Leuven, Belgium
Goal • Specification and verification • Of object-oriented modules • Using inspector methods • For information hiding • In method contracts and object invariants
Difficulties • The combination of • Aliasing • Information hiding • Method effect framing • Sound first-order logic verification condition generation
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
class Cell { int x; inspectorint 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; Single-ObjectInspector Methods
Background Predicates • get(set(s,f,v),f) == v • f1!=f2==>get(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))
Single-ObjectInspector Methods (forall H, o :: Cell_getX(o, get(H,o)) == get2(H,o,Cell_x)) ==> H1 == set2(H0,this,Cell_x,x) ==> Cell_getX(this,get(H1,this)) == x class Cell { int x; inspectorint getX() { return x; } Cell(int x) ensures getX() == x; { this.x = x; } }
Single-ObjectInspector Methods get2(H0,c1,alloc) == false ==> H1 == set2(H0,c1,alloc,true) ==> (forall o :: get2(H1,o,alloc) ==>get2(H2,o,alloc) && (o != c1 ==> get(H2, o) == get(H1,o))) ==> Cell_getX(c1,get(H2,c1)) == 1 ==> get2(H2,c2,alloc) == false ==> H3 = set2(H2,c2,alloc,true) ==> (forall o :: get2(H3,o,alloc) ==> get2(H4,o,alloc) && (o != c2 ==> get(H4,o) == get(H3,o))) ==> Cell_getX(c2,get(H4,c2)) == 2 ==> Cell_getX(c1,get(H4,c1)) == 1 Cell c1 = new Cell(1); Cell c2 = new Cell(2); assert c1.getX() == 1;
Single-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 receiver’s state as an argument
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
class List { rep int[] elems; int count; invariant 0 <= count; invariant count <= elems.length; inspector int getCount() { return count; } inspector int getItem(int index) requires 0 <= index; requires index < getCount(); { return elems[index]; } derived_invariant 0 <= getCount(); void add(int x) requires !committed && inv; modifiesthis.*; ensures !committed && inv; ensures getCount() = old(getCount()) + 1; ensures forall{int i inold((0:getCount())); getItem(i) == old(getItem(i))}; ensures getItem(old(getCount())) == x; { unpackthis; count++; EnsureCapacity(count); elems[count – 1] = x; packthis; } Object Invariantsand Ownership
Object Invariants in the Boogie Methodology • Each object gets an inv bit • Updating o.f requires !o.inv • pack o; checks o’s 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”
Object 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 o’s 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
Object Ownership in the Boogie Methodology • Committed objects can be unpacked and modified only by first unpacking their owner • o’s inspector methods and object invariant may depend on o’s rep objects
List l1 = new List(); List l2 = new List(); l1.add(5); l2.add(6); assert l1.getItem(0) == 5; ... ==> List_getItem(l1, get(H5,l1),0) == 5 ==> (forall o :: get2(H5,o,alloc) ==> (get2(H6,o,alloc) && (!get2(H5,o,committed) && o != l2 ==> get(H6,o) == get(H5,o)))) ==> List_getItem(l1, get(H6,l1),0) == 5 unpackthis; count++; EnsureCapacity(count); elems[count – 1] = x; packthis; assert getItem(getCount() - 1) == x; assert !committed && !inv; assert !elems.committed && elems.inv; assert 0 <= count && count <= elems.length; inv = true; elems.committed = true; elems_state = H[elems]; (forall H,o,i :: Reachable(H) ==> get2(H,o,alloc) ==> get2(H,o,inv) ==> 0 <= i && i <= List_getCount(o,get(H,o)) ==> List_getItem(o,get(H,o),i) == get(get(get(H,o),List_elems_state),i)) Encoding of Inspector Method Calls
Encoding 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
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
Multi-dependent Inspector Methods class IntCell { inspectorint get() { ... } void set(int value) { ... } } class IntSet { inspectorbool contains(state IntCell c) { ... } void add(IntCell c) ensuresforall{state IntCell c2; contains(c2) == (old(contains(c2)) || c2.get() == c.get())}; { ... } }
Termination of Inspector Methods • An inspector method’s 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
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
class Cell { int x; invariant 0 <= x; inspectorint getX() { return x; } derived_invariant 0 <= getX(); dynamic_invariant 0 <= getX(); void setX(int x) requires !committed && inv; requires 0 <= x; modifies this.*; ensures !committed && inv; ensures getX() == x; {unpackthis; this.x = x; packthis;} } class MyCell extends Cell { invariant 1 <= super.getX(); inspectorint getX() { returnsuper.getX() – 1; } void setX(int x) requires !committed && inv; requires 0 <= x; modifiesthis.*; ensures !committed && inv; ensures getX() == x; { unpack this; super.setX(x + 1); pack this; } } Subclassing
Subclassing: Encoding • c1.x --> get3(H,c1,Cell,Cell_x) • c1.getX() --> Cell_getX_dyn(c1,get2(H,c1,typeof(c1))) • super.getX() --> Cell_getX(c1,get2(H,c1,Cell)) • (forall o :: typeof(o) == Cell ==> Cell_getX_dyn(o,s) == Cell_getX(o,s)) • (forall o :: typeof(o) == MyCell ==> Cell_getX_dyn(o,s) == MyCell_getX(o,s)) • pack (MyCell)o; --> ... H’ == set3(H,o,MyCell,super_state, get2(H,o,Cell)) …
Outline of the Talk • Single-object inspector methods • Object invariants and ownership • Multi-dependent inspector methods • Subclassing • Related work, future work, conclusion
Related Work • Boogie methodology • Method calls in specifications • State abstraction in ownership systems • Ownership-free approaches
Relation 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
Method Calls in Specifications • Discussed by [Darvas, Müller 2005] • Does not deal with framing issue
State 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]
Ownership-free Approaches • Dynamic frames [Kassios 2005] • Abstract predicates in separation logic [Parkinson 2005] • More flexible • Not implemented in automatic program verifier (but: Smallfoot)
Future Work • Soundness proof • Visibility-based dependencies
Conclusion • State abstraction for OO programs • Supports standard coding pattern • Implemented in automatic program verifier • Supports multi-dependent inspector methods, quantification over object states, subclassing