170 likes | 293 Views
Chair of Software Engineering. Reasoning about Multiple Related Abstractions with MultiStar. Stephan van Staden , Cristiano Calcagno. Introduction. Broad topic: reasoning about the correctness of OO programs In particular: well-behaved invariants Data abstractions pervade OO programs:
E N D
Chair of Software Engineering Reasoning about Multiple Related Abstractions with MultiStar Stephan van Staden, Cristiano Calcagno
Introduction Broad topic: reasoning about the correctness of OO programs In particular: well-behaved invariants Data abstractions pervade OO programs: • Language constructs: classes • Concepts: account, counter, person, stack
Abstract Predicate Families (APF) Purpose: data abstraction E.g. d + 100 < b x.deposits = d ˄x.balance = b APF predicate x.A(deps: d, bal: b) • Logical abstractions of data • APF predicate arguments are the only visible properties of the abstraction • Think in terms of interface and implementation. This enforces high-level reasoning • APF predicates can have different implementations in different classes • Inheritance-aware
Related abstractions Abstractions are often related:x.A(deps: d, bal: b) x.C(cnt: d) * x.R(bal: b) Possible implementations: One class Client Inheritance Counter c: int Counter c: int Balance b: int Account d: int b: int Account d: Counter b: Balance Balance b: int Account
The opportunity Correctness of code often depends on such relationships, but the original proof system allows only to pass APF predicates around Assume library routine use_counter(x) {x.C(cnt: d)}_{x.C(cnt: d+20)} Client reasoning: {x.A(deps: d, bal: b)} {x.C(cnt: d) * x.R(bal: b)} use_counter(x) {x.C(cnt: d+20) * x.R(bal: b)} // Code that assumes x.A(deps: d+20, bal: b) Client infers an A-based specification for use_counter Access control & call protocols: x.A(deps: d, bal: b) x.C(cnt: d) * x.R(bal: b) x.A(deps: d, bal: b) x.C(cnt: d) * x.R(bal: b)
The problem Original APF system lacks ways to • Specify relationships among abstractions • Verify them • Reason about code that relies on them Solutions must be flexible, since a property may apply to • Instances of particular classes • A whole class hierarchy Further requirements: soundness, modularity, simplicity
Our approach We use two new specification mechanisms • Export clauses for properties of individual classes • Axiom clauses for properties of entire class hierarchies Export clauses • Class C contains export P • Verification checks whether P follows from the APF assumptions of C • Clients can assume P • The paper contains examples
Our approach Axiom clauses • Class C contains axiom l: P • C and all its subclasses must implement axiom l • Subclasses can refine (i.e. strengthen) an axiom • Clients can assume ∀x <: C P[x/Current] • Dynamic type information is not necessary to use this axiom information E.g. axiom a1: A(deps: d, bal: b) C(cnt: d) * R(bal: b) Method body verification can use export and axiom information of all classes
More examples Impose representation constraints on subclasses • axiom C(cnt: c) CAccount(cnt: c) • All subclasses are forced to implement the C abstraction in the same way as class Account Diamond inheritance & view shifting • In class StudentMusician:axiom S(age: a, exm: e) * R1(pfm: p) M(age: a, pfm: p) * R2(exm: e) • Ownership transfer rule • Separation logic can express disjointness and sharing Person age: int Student exm: int Musician pfm: int StudentMusician
More examples Relationships between predicate arguments • axiom A(deps: d, bal: b) d + 100 < b Properties of predicate arguments E.g. The number of deposits is non-negative • axiom A(deps: d, bal: b) 0 ≤ dInclude 0 ≤ d in A predicate definitions:define x.AAccount(deps: d, bal: b) as 0 ≤ d ˄ …
More examples Axioms for aggregate structures that rely on other axioms For the Counter hierarchy:axiom cnt_non_neg: C(cnt: c) 0 ≤ c In class Account:define x.AAccount(deps: d, bal: b) as∃y x.f↦ y * y.C(cnt: d) * …axiom deps_nn: A(deps: d, bal: b) 0 ≤ d relies on Counter.cnt_non_neg Account f: Counter … Counter c: int
Observations Export/axiom information can be seen as well-behaved, operation-independent invariants of OO programs They are universal invariants – always hold Logical, not operational: cannot be violated by adding new methods (cf. class invariants) Idea is not to impose a methodology Only use exports and axioms where you really want them
MultiStar Automated tool for verification Part of EVE, the Eiffel Verification Environment Front-end for Eiffel and back-end based on jStar Back-end reasoning enhancements • Export and axiom clauses • Shared multiple inheritance (including interface inheritance, handling abstract classes and methods) Demonstration
Case study with MultiStar Gobo data structure library’s iterator hierarchy Axiom of container hierarchy: ElementAt(iter: i1, elem: e1, content: c1, iters: i) * ElementAt(iter: i2, elem: e2, content: c1, iters: i) * Replaced(iter: i1, value: e2, newcontent: c2, oldcontent: c1, iters: i) * Replaced(iter: i2, value: e1, newcontent: c3, oldcontent: c2, iters: i) Swapped(iter1: i1, iter2: i2, newcontent: c3, oldcontent: c1, iters: i)
Other work Other work in the paper: • MultiStar implementation details • Formalization, proof of soundness • Related work
In conclusion • Two new specification mechanisms: export and axiom clauses • Simple, well-behaved and powerful • Sound proof system incorporating exports and axioms, based on separation logic and APFs • Accommodates shared multiple inheritance and interfaces • Implementation: MultiStar verification tool
What about class invariants? Axioms are universal representation invariants Class invariants are properties which methods must preserve Further comparison: