Enhancing Modular OO Verification with Separation Logic

Slides:



Advertisements
Similar presentations
Chapter 13 Abstraction and inheritance. This chapter discusses n Implementing abstraction. u extension u inheritance n Polymorphism/dynamic binding. n.
Advertisements

The Spec# programming system K. Rustan M. Leino Microsoft Research, Redmond, WA, USA Lunch seminar, Praxis Bath, UK 6 Dec 2005 joint work with Mike Barnett,
Writing specifications for object-oriented programs K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 21 Jan 2005 Invited talk, AIOOL 2005 Paris,
Challenges in increasing tool support for programming K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 23 Sep 2004 ICTAC Guiyang, Guizhou, PRC joint.
Design by Contract.
OO Programming in Java Objectives for today: Overriding the toString() method Polymorphism & Dynamic Binding Interfaces Packages and Class Path.
An Abstract Interpretation Framework for Refactoring P. Cousot, NYU, ENS, CNRS, INRIA R. Cousot, ENS, CNRS, INRIA F. Logozzo, M. Barnett, Microsoft Research.
Chapter 1 Inheritance University Of Ha’il.
Inheritance Inheritance Reserved word protected Reserved word super
Inheritance and object compatibility Object type compatibility An instance of a subclass can be used instead of an instance of the superclass, but not.
CSE341: Programming Languages Lecture 26 Subtyping for OOP Dan Grossman Fall 2011.
1 Inheritance. 2 One class inherits from another if it describes a specialized subset of objects Terminology: inheritschild class subclass –the class.
ECI 2007: Specification and Verification of Object-Oriented Programs Lecture 2 Courtesy: K. Rustan M. Leino and Wolfram Schulte.
Lecture 2 Towards a Verifying Compiler: Logic of Object oriented Programs Wolfram Schulte Microsoft Research Formal Methods 2006 Objects, references, heaps,
Liskov Substitution Principle
Separation logic for OO Stephan van Staden. Introduction OO languages are popular and widely used We need to reason about OO programs Some (problematic)
Aalborg Media Lab 23-Jun-15 Inheritance Lecture 10 Chapter 8.
Harvey SiyPrinciples of Object-Oriented Software Development by Eliens Slide 1 Behavioral Refinement Principles of Object-Oriented Software Development.
Reasoning about Multiple Related Abstractions with MultiStar Stephan van Staden, Cristiano Calcagno Chair of Software Engineering.
Subclasses and Subtypes CMPS Subclasses and Subtypes A class is a subclass if it has been built using inheritance. ▫ It says nothing about the meaning.
Procedure specifications CSE 331. Outline Satisfying a specification; substitutability Stronger and weaker specifications - Comparing by hand - Comparing.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
OOPs Object oriented programming. Based on ADT principles  Representation of type and operations in a single unit  Available for other units to create.
CISC6795: Spring Object-Oriented Programming: Polymorphism.
1 Abstraction  Identify important aspects and ignore the details  Permeates software development programming languages are abstractions built on hardware.
CSE 425: Object-Oriented Programming I Object-Oriented Programming A design method as well as a programming paradigm –For example, CRC cards, noun-verb.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Cristian Gherghina 1, Cristina David 1, Shengchao Qin 2, Wei-Ngan Chin 1 1 National University of Singapore 2 University of Teesside Structured Specifications.
Objects & Dynamic Dispatch CSE 413 Autumn Plan We’ve learned a great deal about functional and object-oriented programming Now,  Look at semantics.
A Universe-Type-Based Verification Technique for Mutable Static Fields and Methods Alexander J Summers Sophia Drossopoulou Imperial College London Peter.
CSC 480 Software Engineering Design by Contract. Detail Design Road Map Begin with architectural models  Class model: domain classes  Overall state.
Inheritance (Part 5) Odds and ends 1. Static Methods and Inheritance  there is a significant difference between calling a static method and calling a.
Inheritance. Inheritance is a fundamental object-oriented design technique used to create and organize reusable classes Chapter 8 focuses on: deriving.
11th Nov 2004PLDI Region Inference for an Object-Oriented Language Wei Ngan Chin 1,2 Joint work with Florin Craciun 1, Shengchao Qin 1,2, Martin.
Inheritance. Inheritance - Introduction Idea behind is to create new classes that are built on existing classes – you reuse the methods and fields and.
Object-Oriented Programming Chapter Chapter
CSCI-383 Object-Oriented Programming & Design Lecture 24.
CSSE501 Object-Oriented Development. Chapter 10: Subclasses and Subtypes  In this chapter we will explore the relationships between the two concepts.
FEN 2014UCN Teknologi/act2learn1 Object-Oriented Programming “ The Three Pillars of OOP”: Encapsulation Inheritance Polymorphism The Substitution Principle.
CMSC 202 Polymorphism. 10/20102 Topics Binding (early and late) Upcasting and downcasting Extensibility The final modifier with  methods  classes.
Cs2220: Engineering Software Class 13: Behavioral Subtyping Fall 2010 University of Virginia David Evans.
Types and Programming Languages Lecture 10 Simon Gay Department of Computing Science University of Glasgow 2006/07.
DBC NOTES. Design By Contract l A contract carries mutual obligations and benefits. l The client should only call a routine when the routine’s pre-condition.
 Description of Inheritance  Base Class Object  Subclass, Subtype, and Substitutability  Forms of Inheritance  Modifiers and Inheritance  The Benefits.
Design issues for Object-Oriented Languages
Modern Programming Tools And Techniques-I
Object-oriented Programming in Java
Inheritance Based on slides by Ethan Apter
Inheritance and Polymorphism
Adaptive Code Via C#
Type Abstraction SWE Spring 2009.
Stateful Manifest Contracts
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Winter 2013.
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Spring 2016.
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Autumn 2018.
Type Abstraction Liskov, Chapter 7.
Advanced Java Programming
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Autumn 2017.
Java – Inheritance.
Verified Subtyping with Traits and Mixins
Java Inheritance.
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Zach Tatlock Winter 2018.
COMPUTER 2430 Object Oriented Programming and Data Structures I
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Spring 2017.
Respectful Type Converters
Lecture 13: Subtyping Rules Killer Bear Climber
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Spring 2013.
Type Abstraction SWE Spring 2013.
A Considerate Specification of the Composite Pattern
CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping Dan Grossman Spring 2019.
Presentation transcript:

Enhancing Modular OO Verification with Separation Logic Wei-Ngan Chin1,2 Cristina David1 Huu Hai Nguyen2 Shengchao Qin3 1 National University of Singapore 2 Singapore-MIT Alliance 3 Durham University POPL 2008

Challenges of OO Verification Must support behavioral subtyping. Must support class inheritance. Must support casting. Good to support class invariants. Good to support super/direct calls. precision efficiency (minimize code re-verification) Tokyo 2008

Separation Logic and Abstraction [Parkinson&Bierman, POPL’05] Introduces abstract predicate family allows a definition for each class type very powerful idea Re-verification when method inherited Cannot handle super calls Specs may be imprecise Tokyo 2008

Separation Logic Foundations: O’Hearn and Pym, “The Logic of Bunched Implications”, Bulletin of Symbolic Logic 1999 Reynolds, “Separation Logic: A Logic for Shared Mutable Data Structures”, LICS 2002 Extension to Hoare logic to reason about shared mutable data structures p1 * p2: the heap can be split into two disjoint parts (p1 holds for one part and p2 holds for the other) Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Behavioral Subtyping Liskov's Substitutivity Principle (1988) : an object of a subclass can always be passed to a location where an object of its superclass is expected enforce behavioral subtyping with a subsumption relation In order to introduce the specification subsumption relation that we use and which takes advantage of separation logic, I will first present the behavioral subtyping requirement required by the oo paradigm and the subsumption relation for hoare logic. Tokyo 2008

Specification Subsumption Relation class A { t mn(..) where preA *! postA {...} } class B extends A { t mn(..) where preB *! postB {...} Spec (preB *! postB) is a subtype of (preA *! postA) if: (preB *! postB) <:B (preA *! postA) preA ) preB old(preA)Æ postB ) postA Liskov&Wing(TOPLAS’94) Castagna(TOPLAS’95):When the method is overriden, the parameters that determine the selection must be covariantly overridden (the corresponding parameters in the overriding method must have a lesser type) (and those that are not taken into account for selection must be contravariantly overriden). In order to enforce the behavioral subtyping requirement from the previous slide for OO programs, method specifications must satisfy a specification subsumption relation. Leavens: Actually is old(preB): refers to the values of preB in the prestate of a call. The idea is that the behavior of the subtype’s method does not need to be constrained when the supertype’s precondition does not hold in the pre-state. The postcondition of A.mn does not have to hold when its precond does not hold. ------------ Hai: As the two specifications come from different classes, we can add the subtyping relation… ------------- Leavens’ improvement: B.mn can end in a state not satisfying postA as long as it does not start in a state satisfying preA. covariance contravariance Leavens&Naumann(‘06) Tokyo 2008

Enhanced Specification Subsumption `{P} c {Q} `{P * } c {Q * } With the help of frame rule Spec (preB *! postB) is a subtype of (preA *! postA) if: ) preB postB (preB*!postB) <:B (preA*!postA) preA *   * ) postA Ætype(this)<:B As our approach is based on sep logic, we want to use the frame rule of this logic, which allows local reasoning:the specification of a command mentions only what is actually used by the command; by using the frame rule, one can move from local to non-local sopecifications. ---------------------------------------------------------------------------------------------------------------------- There is a side condition requiring that command c does not modify the stack variables in \Delta (as * only describes the separation of heap locations and not variables). the frame rule allows local reasoning: the specification of a command mentions only what is actually used by the command; by using the frame rule, one can move from local to non-local sopecifications by adding the additional state (denoted by \Delta). -------------------------------------------------------------------------------------------------------------------------- (The frame rule can be used to allow the additional state to be preserved by the call.) --------------------------------------------------------------------------------------------------------------------------- \Delta does not contain any primed variables (primed vars are used to denote the latest version of vars and might appear in postconditions). Castagna(TOPLAS‘95) Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion I’ll go on with an example illustrating the use of static and dynamic specs in our approach. Tokyo 2008

Static and Dynamic Spec A static spec: describes just a single method used for statically-dispatched calls (e.g. super/direct) can be very precise A dynamic spec: describes a method and its overriding methods used for dynamically-dispatched calls less precise You’ve seen before the same distinction between static & dynamic specs in Matthew’s talk, who independently from us developed a similar approach to OO verification together with Gavin Bierman. However, they use the abstract predicate families, while we try to enforce the behavioral subtyping requirement by weakening the specification. Tokyo 2008

Static and Dynamic Specs : Example class Cnt { int val; Cnt(int v) {this.val:=v} void tick() {this.val:=this.val+1} int get() {this.val} void set(int x) {this.val:=x} } class FastCnt extends Cnt { FastCnt(int v) {this.val:=v} void tick() {this.val:=this.val+2} } class PosCnt extends Cnt inv this.val¸0 { PosCnt(int v) {this.val:=v} void set(int x) {if x¸0 then this.val:=x else error()} } static this::Cnt<n>$ *! this::Cnt<n+1>$ dynamic this::Cnt<n>$ *! this::Cnt<b>$ - Mirrors Captures in a precise manner the behavior of the method ------------------------------------------------------------------------------- In most of the previous techniques each method was given one spec which was supposed to enforce behavioral subtyping. However, as we try to achieve both precision and reuse we need two specs: ... The $ symbol is a shorthand signifying the fact that our object representation captures all the fields of the subclass. ---- Overriding methods weaken the spec of the overriden method by strengthening the precond and wekening the postcond. Therefore, we advocate the use of the more accurate static spec whenever possible. Tokyo 2008

Static and Dynamic Specs : Example class Cnt { int val; Cnt(int v) {this.val:=v} void tick() {this.val:=this.val+1} int get() {this.val} void set(int x) {this.val:=x} } class FastCnt extends Cnt { FastCnt(int v) {this.val:=v} void tick() {this.val:=this.val+2} } class PosCnt extends Cnt inv this.val¸0 { PosCnt(int v) {this.val:=v} void set(int x) {if x¸0 then this.val:=x else error()} } static this::Cnt<n>$ *! this::Cnt<n+1>$ dynamic this::Cnt<n>$ *! this::Cnt<b>$ Æ n¸0 Æ n+1·b·n+2 Æ n+1·b·n+2 Æ b=n+1 Cnt.tick is overridden ) weaken the postcond PosCnt has inv this.val¸0 ) strengthen the precond Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Key Principles Static spec must be given for each new method. Code verification is done only for static spec. Dynamic spec is either given or derived. Subsumption relations: Static-Spec(A.mn) Dyn-Spec(A.mn) <: min. re-verification class A { // defines mn } Tokyo 2008

Key Principles Static spec must be given for each new method. Code verification is done only for static spec. Dynamic spec is either given or derived. Subsumption relations: Static-Spec(A.mn) Dyn-Spec(A.mn) <: min. re-verification class A { // defines mn } class B extends A { // overrides mn Dyn-Spec(B.mn) <: ensures behavioral subtyping Tokyo 2008

Key Principles Static spec must be given for each new method. Code verification is done only for static spec. Dynamic spec is either given or derived. Subsumption relations: Static-Spec(A.mn) Dyn-Spec(A.mn) <: min. re-verification class A { // defines mn } class B extends A { // overrides mn class C extends A { // inherits mn Dyn-Spec(B.mn) <: ensures behavioral subtyping Static-Spec(C.mn) min. re- verification <: A similar approach was proposed independently by Parkinson & Bierman in the same proceeding. If this subsumption relation does not hold we just proceed with body verification. Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Object Representation extension record for the extra fields of B fields of A fields of B class A { // fields v1..n .... } y::A<t,v1..n,q>*q::Ext<B,w1..m,p> upcast downcast class B extends A { // fields w1..m .... } y::B<t,v1..n,w1..m,p> actual type extension fields Tokyo 2008

Object Representation class A { // fields v1..n .... } y::A<t,v1..n,q>*q::Ext<B,w1..m,p> upcast downcast class B extends A { // fields w1..m .... } y::B<t,v1..n,w1..m,p> LOSSLESS CASTING Tokyo 2008

Partial and Full Views Partial view: Full view: x Static specs Seen as a c-class obj (actual type t) Fields v1..n of c-class Other fields w1..m of subclass t of c x Partial view: - x::c<t,v1..n,p> - no extension records - shorthand x::c<v1..n> Static specs Improves precision Full view: - x::c<t,v1..n,p> * p::ExtAll<c,t> - ExtAll<c,t> captures all the extensions of subclass t of c - shorthand x::c<v1..n>$ Dynamic specs Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Ensuring Class Invariants Q: How and when to check for class inv? class PosCnt extends Cnt inv this.val¸0 { ... } Invariant-enhanced predicate: root::PosCnt#I<t,v,p> == root::PosCnt<t,v,p> * v¸0 Tokyo 2008

Invariant-Enhanced Predicate : Example inv is temporarily broken class PosCnt extends Cnt inv this.val¸0 { ... void set(int x) static this::PosCnt<v> Æ x¸0 *! this::PosCnt#I<x> void tick() static this::PosCnt#I<v> *! this::PosCnt#I<v+1> } Tokyo 2008

Invariant-Enhanced Predicate : Example inv is temporarily broken class PosCnt extends Cnt inv this.val¸0 { ... void set(int x) static this::PosCnt<v> Æ x¸0 *! this::PosCnt#I<x> void tick() static this::PosCnt#I<v> *! this::PosCnt#I<v+1> } inv enforced at each call site assumed at the beginning of method decl Tokyo 2008

Invariant-Enhanced Predicate : Example inv is temporarily broken class PosCnt extends Cnt inv this.val¸0 { ... void set(int x) static this::PosCnt<v> Æ x¸0 *! this::PosCnt#I<x> void tick() static this::PosCnt#I<v> *! this::PosCnt#I<v+1> } inv enforced at the end of the method decl assumed after each call site inv enforced at each call site assumed at the beginning of method decl Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Re-verification of Inherited Methods class A { // fields v* ... t mn(…) static spA { ..body .. } } Is there a need to re-verify spB against body of mn? class B extends A { // fields w* .. t mn(…) static spB // method mn is inherited } Tokyo 2008

Statically-Inherited Method: Intuition Seen as a c-class obj (actual type t) Fields v1..n of c-class Other fields w1..m of subclass t of c this Will a call this.mn(...) modify w*? NO YES B.mn is statically inherited NOT statically inherited Tokyo 2008

Statically-Inherited Method: Definition class A { // fields v* ... t mn(…) static spA { ... this.mn2(); ... } } A.mn is statically-inherited into B if: it is not overridden in B class B extends A { // fields w* .. t mn(…) static spB // method mn is inherited } Tokyo 2008

Statically-Inherited Method: Definition class A { // fields v* // defines mn2 ... t mn(…) static spA { ... this.mn2(); ... } } A.mn is statically-inherited into B if: it is not overridden in B for all the calls this.mn2(..) with mnmn2, B.mn2 is statically-inherited from A.mn2 class B extends A { // fields w* // inherits mn2 .. t mn(…) static spB // method mn is inherited } Tokyo 2008

Re-verification of Inherited Methods Q: Verify spB against the body of A.mn? B.mn statically inherited or full views used? YES NO spB inherited? NO YES  - is the tradeoff of using partial views which although improve precision, make the reverification needed NO VERIFICATION spA<:spB verify spB against the body of A.mn Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Deriving Specs (1) Too many specs to write? Derive dynamic specs from static counterparts Refine dynamic specs to meet behavioral subtyping spec specialization (from superclass) spec abstraction (from subclass) Inherit static specs This is not a core part of our work and therefore, I don’t give more details. Tokyo 2008

Deriving Specs (2) Specification Specialization strengthen dynamic spec of overriding method with the dynamic spec of overridden method intersection type Specification Abstraction weaken dynamic spec of overridden method with dynamic spec of the overriding method union type Tokyo 2008

Outline Introduction Our Approach Enhanced Spec Subsumption Static & Dynamic Specs Key Principles Object Representation Class Invariants Avoiding Re-verification Deriving Specs Experimental Results Conclusion Tokyo 2008

Initial Experiment Code Verification > Spec Subsumption Checking Tokyo 2008

Conclusion Must support: Advocate co-existence of static and dynamic specs Key principles: use static spec where possible ) precision keep code re-verifications to a minimum ) efficiency Slight emphasis on static specs: can derive dynamic specs Must support: behavioral subtyping, class inheritance, casting Good to support: class invariants, super/direct calls Danger: lose precision, efficiency Tokyo 2008

Thank you! Questions? Tokyo 2008

Spec Subsumption Checking Static_spec(Cnt.set) <: Dyn_spec(Cnt.set) this::Cnt<t,v,p>*->this::Cnt<t,x,p> <: this::Cnt<t,v,q>*q::ExtAll<Cnt,t> /\ x>=0 *->this::Cnt<t,x,q>*q::ExtAll<Cnt,t> Contravariance on precond: this::Cnt<t,v,q>*q::ExtAll<Cnt,t> /\ x>=0 |-this::Cnt<t,v,p>*  = p::ExtAll<Cnt,t> /\ x>=0 Covariance on postcond: this::Cnt<t,x,p>* |- this::Cnt<t,x,q>*q::ExtAll<Cnt,t> Tokyo 2008

Spec Subsumption Checking Dyn_spec(PosCnt.set) <: Dyn_spec(Cnt.set) this::PosCnt<v>$ *! this::PosCnt#I<x>$ <: this::Cnt<v>$ /\ x>=0 /\ (type(this)<:PosCnt) *! this::Cnt<x>$ Contravariance on precond: this::Cnt<v>$ /\ x>=0 /\ (type(this)<:PosCnt)|-this::PosCnt<v>$ *   = x>=0 Covariance on postcond: this::PosCnt#I<x>$ *  |- this::Cnt<t,x,q>$ Tokyo 2008