Download presentation
Presentation is loading. Please wait.
Published byRiley Bruce Modified over 11 years ago
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.