Presentation is loading. Please wait.

Presentation is loading. Please wait.

Modular Verification of Higher-Order Methods in JML Gary T. Leavens, Steve Shaner, and David A. Naumann Support from US NSF grant CCF-0429567.

Similar presentations


Presentation on theme: "Modular Verification of Higher-Order Methods in JML Gary T. Leavens, Steve Shaner, and David A. Naumann Support from US NSF grant CCF-0429567."— Presentation transcript:

1 Modular Verification of Higher-Order Methods in JML Gary T. Leavens, Steve Shaner, and David A. Naumann Support from US NSF grant CCF-0429567

2 Summary Problem How to reason about higher-order methods? Approach Greybox [Büchi-Weck97,99] specifications, Copy rule / substitution [Morgan88], Structurally-restricted refinement Contribution Structural matching for refinement Integration with JMLJML

3 Setting JML Pre- and postcondition specifications Several verification tools: ESC/Java2 Jack, LOOP, … Java Libraries: Swing I/O frameworks Jakarta Commons

4 Background: Higher-Order Methods A higher-order method (HOM) makes mandatory calls to weakly-specified methods

5 Example (part 1) Class with a `method parameter public class Counter { protected /*@ spec_public @*/ int count = 0; protected /*@ spec_public @*/ Listener lnr; //@ assignable this.lnr; //@ ensures this.lnr == lnr; public Counter(Listener lnr) { // parameter this.lnr = lnr; }

6 Example (part 2): HOM public void bump() { this.count = this.count + 1; this.lnr.actionPerformed(this.count); }

7 Mandatory Calls are Weakly Specified public interface Listener { //@ assignable this.objectState; void actionPerformed(int x); }

8 Subtype of Listener public class LastVal implements Listener { private /*@ spec_public @*/ int val = 0; //@ in objectState; //@ ensures \result == this.val; public /*@ pure @*/ int getVal() { return this.val; } //@ also //@ assignable objectState; //@ ensures this.val == x; public void actionPerformed(int x) { this.val = x; } }

9 Subtype of Listener public class LastVal implements Listener { private /*@ spec_public @*/ int val = 0; //@ in objectState; //@ ensures \result == this.val; public /*@ pure @*/ int getVal() { return this.val; } //@ also //@ assignable objectState; //@ ensures this.val == x; public void actionPerformed(int x) { this.val = x; } }

10 Reasoning Problem: Want strong conclusions LastVal lv = new LastVal(); //@ assert lv.val == 0; Counter c = new Counter(lv); //@ assert c.lnr == lv && c.count == 0; c.bump(); //@ assert lv.val == 1;

11 Why is strong conclusion valid? Copy rule and substitutions LastVal lv = new LastVal(); //@ assert lv.val == 0; Counter c = new Counter(lv); //@ assert c.lnr == lv && c.count == 0; c.count = c.count+1; c.lnr.actionPerformed(c.count); //@ assert lv.val == 1;

12 Problem Summary Specification of higher-order methods (challenge 8 in [Leavens-Leino-Müller06]) Abstract Specifies mandatory calls Suppress other details Allows strong conclusions (challenge 9) Copy rule and substitution Soundness Must make mandatory calls

13 Use of Higher-Order Methods Key in design patterns [Gamma-etal95]: Observer Template Method Chain of Responsibility Clients of design patterns: Interpreter Command State Strategy Visitor

14 How to Specify HOMs? Standard Pre/Post … /*@ assignable this.count, lnr.objectState; @ ensures this.count ==\old(this.count+1); @*/ public void bump() { this.count = this.count + 1; this.lnr.actionPerformed(this.count); }

15 … Is Not Enough LastVal lv = new LastVal(); //@ assert lv.val == 0; Counter c = new Counter(lv); //@ assert c.lnr == lv && c.count == 0; c.bump(); //@ assume c.count == 1; //@ hence_by (* ??? *); //@ assert lv.val == 1;

16 Higher-Order Specifications? E.g., [Ernst-Navlakhla-Ogden82]: /*@ forall int x; @ requires \req(this.lnr.actionPerformed)(x); @ assignable this.count, @ \asgn(this.lnr.actionPerformed); @ ensures this.count ==\old(this.count+1) @ &&\ens(this.lnr.actionPerformed)(this.count); @*/ public void bump() { /* … */ }

17 Problems with Higher-Order Specifications Often longer and more complex than code Harder to learn and teach Harder for tools to work with? Calls are not mandatory

18 Greybox (Ref. Calc.) Approach [Büchi–Weck97, 99] vs. Better: lnr.actionPerformed() c.count++

19 /*@ public model_program { @ normal_behavior @ assignable this.count; @ ensures this.count ==\old(this.count+1); @ @ this.lnr.actionPerformed(this.count); @ } @*/ public void bump() { /* … */ } Greybox Approach in JML: Model Program Specification

20 Reasoning About HOM Calls LastVal lv = new LastVal(); //@ assert lv.val == 0; Counter c = new Counter(lv); //@ assert c.lnr == lv && c.count == 0; c.bump(); //@ assert lv.val == 1;

21 Approach: Model Program Copy Rule and Substitution LastVal lv = new LastVal(); //@ assert lv.val == 0; Counter c = new Counter(lv); //@ assert c.lnr == lv && c.count == 0; /*@ normal_behavior @ assignable c.count; @ ensures c.count == \old(c.count+1); @*/ c.lnr.actionPerformed(c.count); //@ assert lv.val == 1;

22 Rule for HOM Calls (Copy Rule + Substitution) P { y.m(z); } Q y: T, methType(T,m) = x:S -> void, specFor(T,m) = C, C = C [y,z/this,x], P { C } Q

23 Rule for Higher-Order Calls (Copy Rule + Substitution) P A { y.m(z); } Q y: T, methType(T,m) = x:S -> void, SpecFor(T,m) = C, C = C [y,z/this,x], P A { C } Q

24 Strong Conclusions from Copy + Contextual Knowledge //@ assert c.lnr == lv; c.bump(); Copy/Substitute model program /*@ normal_behavior @ assignable c.count; @ ensures c.count == \old(c.count+1); @*/ c.lnr.actionPerformed(c.count); Context lv.actionPerformed(c.count); +

25 Soundness from Restricting Implementations For soundness of HOM call rule: (copy rule) body refines model program (use of context) restrict refinement so mandatory calls must happen in specified states

26 Notion of Refinement with Mandatory Calls in Given States Need to define structure-preserving refinement Approach: Restrict implementations Pattern matching Model program vs. Implementation

27 Kinds of Patterns Refinable (holes, wildcards) Specification statements (normal_behavior) Mandatory Calls Everything else

28 Pattern Matching normal_behavior … following normal_behavior … { C } Model program Method implementation m();

29 Implementing Higher-Order Methods /*@ public model_program { @ normal_behavior @ assignable this.count; @ ensures this.count == \old(this.count+1); @ this.lnr.actionPerformed(this.count); @ } @*/ public void bump() { /*@ following normal_behavior @ assignable this.count; @ ensures this.count == \old(this.count+1);@*/ { this.count = this.count+1; } this.lnr.actionPerformed(this.count); }

30 Refinement P C iff C pattern matches against P The resulting following statements are provable

31 Rule for following P { following normal_behavior requires P; ensures Q; C } Q P ==> P, Q ==> Q, P { C } Q

32 Rule for following P A { following normal_behavior requires P; assignable A; ensures Q; C } Q P ==> P, locs(A) locs(A), Q ==> Q, P { C } Q

33 Future Work Soundness argument Connection to Büchi and Wecks work (refinement of traces) Case studies Implementation in JML tools Exceptions Concurrency

34 Related Work Büchi and Weck (1997, 99): Idea of greybox approach Trace semantics Doesnt focus on reasoning about calls Needs definition of structure preservation Morgan (1988): Uses adaptation and substitution for procedures

35 Related Work Ernst, Navlakhla, and Ogden (1982): Higher-order logic specifications Harder to write and use Mandatory calls might not be made Soundarajan and Fridella (2004): Higher-order trace-based specifications Can ensure mandatory calls are made Harder to write and use

36 Conclusions Greybox (refinement-style) model programs Clear specification of HOMs Allow strong conclusions Soundness: Restrictions on refinement Use of pattern matching


Download ppt "Modular Verification of Higher-Order Methods in JML Gary T. Leavens, Steve Shaner, and David A. Naumann Support from US NSF grant CCF-0429567."

Similar presentations


Ads by Google