Using history invariants to verify observers

# Using history invariants to verify observers

## Using history invariants to verify observers

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
##### Presentation Transcript

1. Using history invariants to verify observers K. Rustan M. Leino and Wolfram Schulte Microsoft Research, Redmond ESOP 2007Braga, Portugal28 March 2007

2. Overall goal • Specify and statically verify programs • Use modular verification (local reasoning)These require: • Invariants of data structures • Support for common programming patterns

3. In this talk:Observer pattern Observer Subject Observer Observer

4. In this talk:Observer pattern or: Collection / Iterator pattern Iterator Collection Iterator Iterator

5. Review of the heap logic of theBoogie methodology class C {int x, y;invariant x ≤ y; void M() { expose (this) { x++; P(); y++; }} Object is valid Object is mutable Program invariant:( o o.valid Inv(o)) Invariant checked here

6. Review:Representation (rep) objects classFastDictionary {rep Dictionary d;rep Cache c;invariant contents = d.contentsc.keys  contents; :Fast-Dictionary d c :Dictionary :Cache Program invariant, for any rep field d:( o o.valid o.d.valid)

7. Review:Visibility-based invariants class Node {Node next, prev;invariant (next = null  next.prev = this) (prev = null  prev.next = this); next next next :Node :Node :Node :Node prev prev prev

8. Subject, observers :MyObserver class Subject {int data; List<Observer> observers; …} interface Observer { void Update(); } classMyObserver : Observer { Subject s; int d; invariant d = s.data; … } classYourObserver : Observer { Subject s; int d; invariant d ≤ s.data; … } Note that scannotbe a rep field,because one observer cannot be the sole owner of the subject :MyObserver :Subject :YourObserver

9. Modular verification problem :MyObserver :MyObserver class Subject {int data; List<Observer> observers; void Inc() {expose (this) { data++;foreach (o in observers) {o.Update(); } }} } interface Observer { void Update(); } :Subject :YourObserver Program invariant:( o o.valid Inv(o))

10. Modular verification problem :MyObserver :MyObserver class Subject {int data; List<Observer> observers; void Inc() {expose (this) {expose (all o in observers) { data++;foreach (o in observers) {o.Update(); } } }} } interface Observer { void Update(); } :Subject :YourObserver … or check the observer “update guards” here? How to check invariantsof the observers here?

11. Our solution • Declare (monotonic) evolution of the subject data: class Subject {int data;history invariant old(data) ≤ data; • … and let observer invariants depend on the subject data, provided these invariants are automatically maintained under the evolution of the subject data: classSomeObserver : Observer {subject Subject s; int data;invariantdata ≤ s.data;

12. History invariants • 2-state predicateshistory invariant R(this)σ,τ; • Holds of ordered pairs of states:  valid Program invariant: (σ,τ σ ≤ τ  ( o  R(o)σ,τ)) Program invariant: (σ,τ σ ≤ τ ( o  [o.valid]σ [o.valid]τ R(o)σ,τ))

13. Checking history invariants • Checked to be reflexive and transitive • Checked in the states that bracket expose statements: στ expose (o) { … } Check R(o)σ,τ here

14. Observer invariants • class Subject { historyinvariant R(this)σ,τ; … }class Observer {subjectSubject s;invariant Inv(this); Program invariant:( o o.valid o.s.valid Inv(o)) expose (o) { … } check o.s.valid Inv(o) here

15. Checking observer invariants • class Subject { historyinvariant R(this)σ,τ; … }class Observer {subjectSubject s;invariant Inv(this); • Checked to satisfy: (σ,τ σ ≤ τ ( o  [o.valid]σ ( f  [o.f]σ = [o.f]τ)  [o.s.valid]σ [o.s.valid]τ  R(o.s)σ,τ  [Inv(o)]τ))

16. Soundness theorems Program invariant, for any history invariant R: (σ,τ σ ≤ τ ( o  [o.valid]σ [o.valid]τ R(o)σ,τ)) • Proofs: see paper Program invariant, for any object invariant Inv:( o o.valid o.s.valid Inv(o))

17. Specification idiom • class Subject {intver; T data;historyinvariantold(ver) = ver old(data)  data; • class Observer {subjectSubject s;intver; T data;invariant s.ver = ver  s.data  data; temporal relation spatial relation

18. Example: Iterator classIterator {intver;subject Collection c;invariant ... c ...; T Next()requires this.validc.validthis.ver == c.ver;{ ...}

19. Related work • History invariants are used elsewhere • assume / guarantee • constraints [Liskov & Wing 1994] • … • Visibility-based invariants [e.g., Leino & Müller 2004] • Update guards [Barnett & Naumann 2004] • Separation logic [e.g., Parkinson & Bierman 2005] • could also benefit from history invariants • Static class invariants [Leino & Müller 2005] • multiple-”owner” situation

20. Conclusion • Local reasoning for observer invariants • Future work: implementation (in Spec#)