Example JML Specification field specification public class Animal
Example JML Specification field specification public class Animal implements Gendered { protected /*@ spec_public @*/ int age = 0; /*@ requires 0 < yrs; @ ensures age == old(age + yrs); @*/ method behavior specification public void older(final int yrs) { age = age + yrs; }
Behavioral Interface Specification JML Specification Syntactic Interface Functional Behavior Java Code
Behavioral Interface Specification /*@ requires 0 < yrs; @ ensures age == old(age + yrs); @*/ public void older(final int yrs); requires yrs > 0; ensures age == old(age + yrs); public void older(final int yrs) { age = age + yrs; }
Open Research Community • 23 groups, worldwide • Over 130 papers See jmlspecs. org for details
Many Tools, One Language JML Annotated Java jmldoc Web pages jmlunit Unit tests jmlc Class file XVP public class Animal implements Gendered { //. . . protected /*@ spec_public @*/ int age = 0; /*@ requires 0 <= a && a <= 150; @ ensures age == a; @ also @ requires a < 0; @ ensures age == old(age); @*/ public void set. Age(final int a) { if (0 <= a) { age = a; } } } Bogor Model checking Warnings ESC/Java 2 Daikon Data trace file JACK, Jive, Krakatoa, Ke. Y, LOOP Correctness proof
How JML can Help Modular Specification, Verification • Recording functional behavior for modules • Specifying subtypes • Verification with OO features
Problem 1: Recording Detailed Designs • Precise, sequential behavior • Hide details Approach • Model fields • Assertions
Model Fields, Ensures public interface Gendered { //@ model instance String gender; //@ ensures result == gender. equals(“female”); /*@ pure @*/ boolean is. Female(); }
Represents Clauses public class Animal implements Gendered, /*…*/ { protected boolean gen; //@ in gender; /*@ protected represents gender @ <- (gen ? “female” : “male”); @*/ //. . .
Use of Model Fields public class Animal implements Gendered, /*…*/ { protected boolean gen; //@ in gender; /*@ protected represents gender @ <- (gen ? “female” : “male”); @*/ public /*@ pure @*/ boolean
Correctness with Model Fields gender: “female” is. Female’s specification represents gen: true == is. Female’s code true
Requires Clauses public class Animal implements Gendered, /*…*/ { protected boolean gen; //@ in gender; /*@ protected represents gender @ <- (gen ? “female” : “male”); @*/ //@ requires g. equals(“female”)||g. equals(“male”);
Model of Method Specifications public interface T { //@ requires pre; //@ ensures post; void m(); } T ⊳ (pre, post)
Model of Method Specifications output post-state post m() pre input pre-state
spec_public Shorthand Instead of: //@ public model int age; protected int _age = 0; //@ in age; //@ protected represents age < - _age; Write: protected /*@ spec_public @*/ int age = 0;
Type Specifications: Invariants import java. util. *; public class Patient extends Animal { //@ public invariant 0 <= age && age <= 150; protected /*@ spec_public @*/ List log; /*@ public invariant (forall int i; @ 0 <= i && i <
Invariants • Hold in visible states – Method pre- & post-, Constructor poststates
Initially public class Patient extends Animal { //. . . protected /*@ spec_public @*/ List log; //@ public initially log. size() == 0; • True in constructor post-states • Basis for datatype induction
History Constraints [LW 94] public class Patient extends Animal { //. . . /*@ public constraint @ old(log. size()) <= log. size(); @ public constraint @ (forall int i; @ 0 <= i && i < old(log. size()); @ log. get(i). equals(old(log. get(i))));
History Constraints • Relate pre-states and post-states • Inductive step for datatype induction
Problem 2: Specifying Subtypes • Avoid repetition • (Force behavioral subtyping) Approach • Specification Inheritance – Fields, type specifications – Method specification cases
Multiple Inheritance Gendered Age Normal. Set. Age Exceptional. Set. Age Animal
Age and Normal. Set. Age public interface Age { //@ model instance int age; } public interface Normal. Set. Age implements Age { /*@ requires 0 <= a && a <= 150; @ ensures age == a; @*/ public void set. Age(final int a); }
Exceptional. Set. Age public interface Exceptional. Set. Age implements Age { /*@ requires a < 0; @ ensures age == old(age); @*/ void set. Age(final int a); }
What about Animal? • It’s both • Should obey both specifications Normal. Set. Age Exceptional. Set. Age Animal
Join of Specification Cases post && post′ pre pre && pre′
Join of Specification Cases, ‘also’ requires 0 <= a && a <= 150; ensures age == a; also requires a < 0; ensures age == old(age); means requires (0 <= a && a <= 150) || a<0; ensures (old(0 <= a && a <=
Join of Specification Cases, ⊔S If T′ ⊳ (pre′, post′ ), T ⊳ (pre, post ), S ≤ T′, S ≤ T, then (pre′, post′ ) ⊔S (pre, post ) = ( p, q) where p = pre′ || pre and q = (old(pre′ ) ==> post′ ) && (old(pre) ==> post ) and S ⊳ (p, q)
Inheritance of Type Specifications Obeyed by all subtypes: • Invariants • Initially clauses • History constraints
Subtypes Not a Sugar [LW 94] Animal Tortoise Patient invariant 0 <= age && age <= 150; Female. Patient
Model of Inheritance T’s Added Specifications Declared in T added_inv. T added_hc. T TT added_init added_spec m (without inheritance): invariant history constraint initially predicate m’s specification Other Notations supers(T ) = {U | T U } methods(T ) = { m | m declared in T T }
Specification Inheritance’s Meaning: Extended Specification of T • Methods: for all m T U ext_spec added_specm methods(supers(T)) m = ⊔T { U supers(T) } • Invariant: | ext_inv. T = ⋀ { added_inv. U | U supers(T) } • History constraint: T U
Method Specification Inheritance: Supertype’s added_spec public interface Normal. Set. Age implements Age { /*@ requires 0 <= a && a <= 150; @ ensures age == a; @*/ public void set. Age(final int a); } public interface Exceptional. Set. Age implements Age { /*@ @ requires a < 0; ensures age == old(age); @*/
Method Specification Inheritance: Subtype’s added_spec public class Patient extends Animal { // … protected /*@ spec_public @*/ boolean age. Discount = false; //@ in age; /*@ also @ requires 0 <= a && a <= 150 || a < 0; @ ensures 65 <= age ==>
Method Specification Inheritance: Extended Specification Patient ext_specset. Age = ⊔Patient { Normal. Set. Age added_spec set. Age Exceptional. Set. Age added_spec set. Age Patient added_spec set. Age , , }
Method Specification Inheritance: Extended Specification requires 0 <= a && a <= 150; ensures age == a; also requires a < 0; ensures age == old(age); also requires 0 <= a && a <= 150 || a < 0; ensures 65 <= age ==> age. Discount;
Problem 3: Verification with OO features • Subtyping • Dynamic Dispatch Approach [LN 06] • Supertype abstraction • Validity: – Assumptions about Invariants, etc. , – Behavioral subtyping • Behavioral subtyping from specification inheritance
Supertype Abstraction Reasoning about dynamic dispatch: Gendered e = (Gendered)elems. next(); if (e. is. Female()) { //@ assert e. gender. equals(“female”); //. . . } Supertype abstraction:
Static Type’s Specification public interface Gendered { //@ model instance String gender; //@ ensures result == gender. equals(“female”); /*@ pure @*/ boolean is. Female(); }
Supertype Abstraction Reasoning about dynamic dispatch: Gendered e = (Gendered)elems. next(); if (e. is. Female()) { //@ assert e. gender. equals(“female”); //. . . } Supertype abstraction:
Supertype Abstraction in General Use static type’s specifications to reason about: • Method calls, • Invariants, • History constraints, • Initially predicates
Supertype Abstraction in General T o = /* create a new object */; //@ assume o. ext_init. T && o. ext_inv. T; /* … */ T o. ext_prem //@ assert ; T o. m(); o. ext_postm //@ assume ; //@ assume o. ext_inv. T && o. ext_hc. T;
Supertype Abstraction’s Soundness Valid if: • Invariants etc. hold as needed (in pre -states), and • Each subtype is a behavioral subtype
Validity of Supertype Abstraction: Client (Supertype) view T o = /* create a new object */; //@ assume o. ext_init. T && o. ext_inv. T; /* … */ T o. ext_prem //@ assert ; T o. m(); o. ext_postm //@ assume ; //@ assume o. ext_inv. T && o. ext_hc. T;
Abstraction: Implementation (Subtype) View T o = new T′ (); //@ assert o. ext_init. T′ && o. ext_inv. T′; /* … */ T′ o. ext_pre m //@ assume ; T′ o. m(); o. ext_postm //@ assert ; //@ assert o. ext_inv. T′ && o. ext_hc. T′ ;
Behavioral Subtyping for JML Definition. Suppose T′ ≤ T. Then T′ is a strong behavioral subtype of T if and only if: T′ ext_specm T ext_specm for all instance methods m in T, ⊒T′ and whenever this has type T′ : ext_inv. T′ ext_inv. T, ext_hc. T′ ext_hc. T, and
Method Specification Refinement with respect to T′ Notation: (pre′, post′ ) ⊒T′ (pre, post )
Refinement with respect to T′ post pre
Refinement with respect to T′ post pre′ pre
Refinement with respect to T′ post pre′ pre
Proving Method Refinements Theorem 1. Suppose T′ ≤ T, and T′ ⊳ (pre′, post′ ), T ⊳ (pre, post ) specify m. Then (pre′, post′ ) ⊒T′ (pre, post ) if and only if: Spec(T′ ) |- pre && (this instanceof T′ ) pre′, and
Making Behavioral Subtyping Automatic • Specification inheritance must make behavioral subtypes – Methods – Invariants – Initally – History constraints
also Makes Refinements Theorem 2. Suppose old is monotonic. Suppose T′ ≤ T, and T′ ⊳ (pre′, post′ ), T ⊳ (pre, post ) specify m. Then (pre′, post′ ) ⊔T′ (pre, post ) ⊒T′ (pre, post ).
also Makes Refinements post && post′ pre′ pre && pre′
Specification Inheritance Forces Behavioral Subtyping Theorem 3. Suppose T′ ≤ T. Then the extended specification of T′ is a strong behavioral subtype of the extended specification of T. Proof: Use Theorem 2 and definition of extended specification.
Discussion • Every subtype inherits • Every subtype is a behavioral subtype – Not all satisfiable – Supertype must allow refinement
Unsatisfiable Refinements post && post′ pre′ pre && pre′
Unrefinable Binary Method Specification /*@ also @ ensures obj instanceof Gendered @ ==> (result @ == gender. equals( @ ((Gendered)obj). gender)); @*/ public /*@ pure @*/ boolean equals(/*@ nullable @*/ Object obj);
Unrefinable Binary Method Specification true false (f, f) (m, m) (f, m) (m, f)
Better, Refinable Binary Method Specification /*@ also @ ensures obj instanceof Gendered @ ==> (result @ ==> gender. equals( @ ((Gendered)obj). gender)); @*/ public /*@ pure @*/ boolean equals(/*@ nullable @*/ Object obj);
Better, Refinable Binary Method Specification true false Allowed result (f, f) (m, m) (f, m) (m, f)
Related Work • Work with Naumann [LN 06], basis for this talk. Proved exact conditions on behavioral subtyping for validity of supertype abstraction • Liskov and Wing [LW 94] “subtype requirement” like supertype abstraction. Abstraction functions implicit in JML. • Several program logics for Java, [Mül 02] [Par 05] [Pie 06] [PHM 99],
More Related Work • Wills’s Fresco [Wil 92] introduced specification inheritance. • Wing’s dissertation [Win 83] combined specification cases like also. • Eiffel [Mey 97] has behavioral subtyping and a form of specification inheritance. • America [Ame 87] [Ame 91] first
Future Work • Warn if attempt to strengthen preconditions [FF 01]. • Warn if subtype is unsatisfiable. • Methodology for – history constraints and – initially predicates
Conclusions • Supertype abstraction allows modular reasoning. • Supertype abstraction is valid if: – methodology enforced, and – subtypes are behavioral subtypes. • JML’s also makes refinements. • Specification inheritance in JML forces behavioral subtyping. • Supertype abstraction
Acknowledgments Thanks to David Naumann, William Weihl, Krishna Kishore Dhara, Cesare Tinelli, Don Pigiozzi, Barbara Liskov, Jeannette Wing, Yoonsik Cheon, Al Baker, Clyde Ruby, Tim Wahls, Patrice Chalin, Curtis Clifton, David Cok, Joseph Kiniry,
Future Work on JML • Tools – Java 1. 5 support – Eclipse support • Documentation • Concurrency support • Semantic details • Theorem proving tie-ins, Static analysis tie-ins • Inference of specifications
My Future Work (outside JML) • Aspect-oriented software development – Language design and semantics (ownership, etc. ) – Specification and Verification • Extending the reach of formal methods – Security related topics – Time and space • Blending – Annotation-based specification
Reasoning without Supertype Abstraction? Case analysis: • Case for each potential dynamic type • Can exploit dynamic type’s specifications
Case Analysis + Supertype Abstraction • Use instanceof for case analysis • Downcast, use supertype abstraction /*@ requires p instanceof Doctor @ || p instanceof Nurse; @*/ public boolean is. Head(final Staff p) { if (p instanceof Doctor) { Doctor doc = (Doctor) p; return doc. get. Title(). starts. With(“Head”); } else { Nurse nrs = (Nurse) p; return nrs. is. Chief();
References [Ame 87] Pierre America. Inheritance and subtyping in a parallel object-oriented language. In Jean Bezivin et al. , editors, ECOOP ’ 87, European Conference on Object-Oriented Programming, Paris, France , pages 234– 242, New York, NY, June 1987. Springer-Verlag. Lecture Notes in Computer Science, volume 276. [Ame 91] Pierre America. Designing an object-oriented programming language with behavioural subtyping. In J. W. de Bakker, W. P. de Roever, and G. Rozenberg, editors, Foundations of Object-Oriented Languages, REX School/Workshop, Noordwijkerhout, The Netherlands, May/June 1990 , volume 489 of Lecture Notes in Computer Science, pages 60– 90. Springer-Verlag, New York, NY, 1991. [BCC+05] Lilian Burdy, Yoonsik Cheon, David R. Cok, Michael D. Ernst, Joeseph R. Kiniry, Gary T. Leavens, K. Rustan M. Leino, and Erik Poll. An overview of JML tools and applications. International Journal on Software Tools for Technology Transfer, 7(3): 212– 232, June 2005. [DL 96] Krishna Kishore Dhara and Gary T. Leavens. Forcing behavioral subtyping through specification inheritance. In Proceedings of the 18 th International Conference on Software Engineering, Berlin, Germany , pages 258– 267. IEEE Computer Society Press, March 1996. A corrected version is ISU CS TR #95 -20 c, rlhttp: //tinyurl. com/s 2 krg. [FF 01] Robert Bruce Findler and Matthias Felleisen. Contract soundness for object-oriented languages. In OOPSLA ’ 01 Conference Proceedings, Object-Oriented Programming, Systems, Languages, and Applications, October 14 -18, 2001, Tampa Bay, Florida, USA, pages 1– 15, October 2001. [Hoa 69] C. A. R. Hoare. An axiomatic basis for computer programming. Communications of the ACM, 12(10): 576– 580, 583, October 1969. [Hoa 72] C. A. R. Hoare. Proof of correctness of data representations. Acta Informatica, 1(4): 271– 281, 1972. [LD 00] Gary T. Leavens and Krishna Kishore Dhara. Concepts of behavioral subtyping and a sketch of their extension to component-based systems. In Gary T. Leavens and Murali Sitaraman, editors, Foundations of Component-Based Systems, chapter 6, pages 113– 135. Cambridge University Press, 2000. [Lei 98] K. Rustan M. Leino. Data groups: Specifying the modification of extended state. In OOPSLA ’ 98 Conference Proceedings, volume 33(10) of ACM SIGPLAN Notices, pages 144– 153. ACM, October 1998. [LN 06] Gary T. Leavens and David A. Naumann. Behavioral subtyping, specification inheritance, and modular reasoning. Technical Report 06 -20 b, Department of Computer Science, Iowa State University, Ames, Iowa, 50011, September 2006. [LW 94] Barbara H. Liskov and Jeannette M. Wing. A behavioral notion of subtyping. ACM Transactions on Programming Languages and Systems, 16(6): 1811– 1841, November 1994. [Mey 97] Bertrand Meyer. Object-oriented Software Construction. Prentice Hall, New York, NY, second edition, 1997. [MPHL 06] Peter Müller, Arnd Poetzsch-Heffter, and Gary T. Leavens. Modular invariants for layered object structures. Science of Computer Programming, 62(3): 253– 286, October 2006. [Mül 02] Peter Müller. Modular Specification and Verification of Object-Oriented Programs , volume 2262 of Lecture Notes in Computer Science. Springer-Verlag, 2002. [Par 05] Matthew J. Parkinson. Local reasoning for Java. Technical Report 654, University of Cambridge Computer Laboratory, November 2005. The author’s Ph. D. dissertation. [PHM 99] A. Poetzsch-Heffter and P. Müller. A programming logic for sequential Java. In S. D. Swierstra, editor, European Symposium on Programming (ESOP ’ 99), volume 1576 of Lecture Notes in Computer Science , pages 162– 176. Springer -Verlag, 1999.
- Slides: 71