Upload
aaliyah-fitzgerald
View
215
Download
1
Tags:
Embed Size (px)
Citation preview
Joint work with Mike Barnett, Robert DeLine, Manuel Fahndrich, and Wolfram Schulte
Verifying invariants inVerifying invariants in object-oriented programs object-oriented programs Verifying invariants inVerifying invariants in object-oriented programs object-oriented programs
K. Rustan M. Leino Microsoft Research, Redmond, WA, USA
Computer Science ColloquiumETH Zurich24 Nov 2003
‥
Vision
Record design decisions+ Utilize automatic checking
= Detect errors and improve maintainability
A# and Boogie:Programmer's view
Boogie
C# compiler
A# compiler
A#
C#
MSIL
Warnings
Other .NETcompilers
Boogie: under the hood
Theoremprover
weakest-preconditiongenerator
translator
MSIL
BoogiePL
verification condition
Warnings
Inferenceengine
Boogie technologyand research
• Programming methodology– model for writing code and specifications
• Inference– abstract domains over heap structures
• Verification-condition generation– formulas that are “efficient” for theorem
prover
Invariants: straw man
class T {// field declarations ...
invariant J ;
T(...)requires Pmodifies vensures Q
{…
}
method m(...)requires Rmodifies wensures T
{…
}
…
class T {// field declarations ...
T(...)requires Pmodifies vensures Q ∧ J
{…
}
method m(...)requires R ∧ J
modifies wensures T ∧ J
{…
}
…
Object invariants hold on public method boundaries and are shorthands for pre/post-conditions
Invariants, exampleclass T {
private int x, y ;invariant 0 ≦ x < y ;
public T(){
x = 0 ; y = 1 ;}
public method m()modifies x, y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
class T {
private int x, y ;
public T()ensures 0 ≦ x < y
{x = 0 ; y = 1 ;
}
public method m()requires 0 ≦ x < y modifies x, y ensures 0 ≦ x < y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
Invariants, problemsclass T {
private int x, y ;invariant 0 ≦ x < y ;
public T(){
x = 0 ; y = 1 ;}
public method m()modifies x, y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
class T {
private int x, y ;
public T()ensures 0 ≦ x < y
{x = 0 ; y = 1 ;
}
public method m()requires 0 ≦ x < y modifies x, y ensures 0 ≦ x < y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
callers are expected to establish property about internal data structure
Invariants, problemsclass T {
private int x, y ;invariant 0 ≦ x < y ;
public T(){
x = 0 ; y = 1 ;}
public method m()modifies x, y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
class T {
private int x, y ;
public T()ensures 0 ≦ x < y
{x = 0 ; y = 1 ;
}
public method m()requires 0 ≦ x < y modifies x, y ensures 0 ≦ x < y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
possible solution (?): callers don’t need to be checked for this precondition—it holds automatically!
Invariants, problemsclass T {
private int x, y ;invariant 0 ≦ x < y ;
public T(){
x = 0 ; y = 1 ;}
public method m()modifies x, y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
class T {
private int x, y ;
public T()ensures 0 ≦ x < y
{x = 0 ; y = 1 ;
}
public method m()requires 0 ≦ x < y modifies x, y ensures 0 ≦ x < y
{assert y-x ≧ 0 ;x = x + 3 ;
y = 4 * y ;}
…
invariant does not hold here
Invariants, problemsclass T {
private int x, y ;invariant 0 ≦ x < y ;
public T(){
x = 0 ; y = 1 ;}
public method m()modifies x, y
{assert y-x ≧ 0 ;x = x + 3 ;y = 4 * y ;
}
…
class T {
private int x, y ;
public T()ensures 0 ≦ x < y
{x = 0 ; y = 1 ;
}
public method m()requires 0 ≦ x < y modifies x, y ensures 0 ≦ x < y
{assert y-x ≧ 0 ;x = x + 3 ;p(...) ;y = 4 * y ;
}
…
invariant does not hold here, so what if p calls m?!
The problem of specifying modifications
class Kitchen {private Dishes d ;private bool hasGarbage ;private Stove s ;private Light l ; ...public method SpiffUp()
modifies hasGarbage, s.foodPieces, s.big.sufaceColor,
…{
d.Clean() ;hasGarbage = false ;s.Wipe() ;l.TurnOff() ;...
}
class Stove {private Burner big ;private Burner small ;private int foodPieces ;private Knob[] knobs ;...public method Wipe()
modifies foodPieces, big.surfaceColor, …
{big.Polish() ;small.Polish() ;foodPieces = 0 ;...
}these lists are long, and they mention private state
The problem of specifying modifications
class Kitchen {private Dishes d ;private bool hasGarbage ;private Stove s ;private Light l ; ...public method SpiffUp()
modifies hasGarbage, s.foodPieces, s.big.sufaceColor,
…{
d.Clean() ;hasGarbage = false ;s.Wipe() ;l.TurnOff() ;...
}
class Stove {private Burner big ;private Burner small ;private int foodPieces ;private Knob[] knobs ;...public method Wipe()
modifies foodPieces, big.surfaceColor, …
{big.Polish() ;small.Polish() ;foodPieces = 0 ;...
}possible solution (?): don’t need to declare modifications of private state—it can’t be observed anyhow
The problem of specifying modifications
class Kitchen {private Dishes d ;private bool hasGarbage ;private Stove s ;private Light l ; ...public method SpiffUp()
modifies
{d.Clean() ;hasGarbage = false ;s.Wipe() ;assert ¬ hasGarbage ;l.TurnOff() ;...
}
class Stove {private Burner big ;private Burner small ;private int foodPieces ;private Knob[] knobs ;...public method Wipe()
modifies
{big.Polish() ;small.Polish() ;foodPieces = 0 ;...
}
SpiffUp treats Wipe as if Wipe modified nothing, so what if Wipe calls a method in Kitchen that sets hasGarbage to true?!
Soundness of verification• Soundness = verification finds all
errors• Soundness follows from:
– pre- and postconditions are the same for caller and callee
• Note: In addition to soundness, we want something usable
Methodology• object invariant declaration
– class T {int x, y ;invariant x < y ;
• special variable st: {Invalid, Valid}• Idea: program invariant
(∀o ・ o.st = Invalid ∨ Inv(o))• st is changed by commands pack and
unpack
holds at everyprogram point!
for any o: T, we writeInv(o) ≡ o.x < o.y
pack and unpack• pack o ≡
assert o.st = Invalid ;assert Inv(o) ;o.st := Valid
• unpack o ≡ assert o.st = Valid ;o.st := Invalid
Exampleclass T {
int x, y ;invariant 0 ≦ x < y ;method init(t)
requires t.st = Invalidmodifies t.st, t.x, t.yensures t.st = Valid
{t.x := 0 ; t.y := 1 ;pack t
}method m(t)
requires t.st = Validmodifies t.x, t.y
{unpack t ;t.x := t.x + 3 ; t.y := 4 * t.y ;pack t
}
receiver parameter(“this”, “self”, “current”)
Program invariant(∀o ・ o.st = Invalid ∨ Inv(o))
• x := new(T) ≡... ; assume x.st = Invalid
• pack o ≡... ; assert Inv(o) ; o.st := Valid
• unpack o ≡ ... ; o.st := Invalid
• o.f := E ≡assert o.st = Invalid ; ...
• Inv(o) can mention only the fields of o
Methodology, summary• invariant ...• st: {Invalid, Valid}• pack, unpack• modifications of o.f require
o.st=Invalid• Inv(o) can mention only the fields of o• (∀o ・ o.st = Invalid ∨ Inv(o))
Methodology, extended• component declarations
– class Kitchen {component Stove s ;
• st: {Invalid, Valid, Committed}• Idea: program invariant
(∀o ・ o.st=Invalid ∨ (Inv(o) ∧ (∀p∈Comp(o) ・ p.st=Committed)))
• pack o and unpack o change st for o and o's components
for any k: Kitchen, we havek.s ∈ Comp(k)
pack and unpack, extended• pack o ≡
assert o.st = Invalid ∧ Inv(o) ;assert (∀p ∈ Comp(o) ・ p.st=Valid) ;o.st := Valid ;foreach p ∈ Comp(o) do
p.st :=Committed ;
• unpack o ≡ assert o.st = Valid ;foreach p ∈ Comp(o) do p.st=Valid ;o.st := Invalid ;
Exampleclass Kitchen {
method SpiffUp(k)requires k.st=Valid …
{unpack k ;k.d.Clean() ;k.s.Wipe() ;pack k
}
class Stove {method Wipe(s) requires s.st=Valid …
sd
Kitchenk
Stove
Dishes
Valid
Committed
Committed
Committed
Committed
Committed
ValidInvalid
Exampleclass Kitchen {
method SpiffUp(k)requires k.st=Valid …
{unpack k ;k.d.Clean() ;k.s.Wipe() ;pack k
}
class Stove {method Wipe(s) requires s.st=Valid …
sd
Kitchenk
Stove
Dishes
Committed
Committed
Committed
Committed
Committed
Valid
Valid
Program invariant
(∀o ・ o.st=Invalid ∨ (Inv(o) ∧ (∀p∈Comp(o) ・
p.st=Committed)))
• x := new(T) ≡ ... ; assume x.st=Invalid• pack o, unpack o• o.f := E ≡ assert o.st=Invalid ; ...• Inv(o) can mention only the fields of o and
of o.p for any component field p
Extended methodology, summary• invariant ...• component ...• st: {Invalid, Valid, Committed}• pack, unpack• modifications of o.f require o.st=Invalid• Inv(o) can mention only the fields of o and
of o.p for any component field p• (∀o ・ o.st=Invalid ∨
(Inv(o) ∧ (∀p∈Comp(o) ・p.st=Committed)))
Verification system• We let st be used in method
specifications (requires, modifies, ensures)
• We must address the Problem of Specifying Modifications
A heap model
• Heap is a two-dimensional “array”
class T { f: U; g: V; ... }• x := o.f = x := Heap[o, f]• o.f := E = Heap[o, f] := E
Meaning of modifies
• modifies w =modifies Heapensures (∀o,f ・ Heap[o,f] =
Heap0[o,f] ∨ (o,f) ∈ w0 )
viewed as set of object/field-name pairs
Meaning of modifies
• modifies w =modifies Heapensures (∀o,f ・ Heap[o,f] =
Heap0[o,f]∨ (o,f) ∈ w0 ∨ ¬ Heap0[o,alloc] )
Meaning of modifies
• modifies w =modifies Heapensures (∀o,f ・ Heap[o,f] = Heap0[o,f]
∨ (o,f) ∈ w0 ∨ ¬ Heap0[o,alloc] ∨
Heap0[o,st]=Committed )
Example
class Kitchen {method SpiffUp(k)
requires k.st=Validmodifies k.hasGarbage
{unpack k ;k.d.Clean() ;k.hasGarbage := false ;k.s.Wipe() ;assert ¬ k.hasGarbage ;pack k
}
class Stove {method Wipe(s) requires s.st=Valid modifies s.foodPieces
Another example
method m(p)requires p.st=Committed
{var y, z in
y := p.x ;z := sqrt(49) ;assert y = p.x
end}
Soundness• Pre- and postconditions are the
same for callers and callees, so verification system is sound!
Related work• rep types in CLU• dynamically checked invariants in Eiffel• valid idiom in ESC/Modula-3• universe types and invariants in Muller's
thesis• invariant declarations in ESC/Java and JML• (implicit) pack/unpack operations in Vault and
Fugue• capability calculus• ownership types• locking and monitor disciplines in concurrent
programming
‥
Conclusions• Invariants different from pre/post-conditions• Resulting program invariants hold at every
program point• Uses pack/unpack commands, but good
defaults can be constructed for these• No linear type system• Components are not unique references—
objects (pointers) can freely be copied• Fields can freely be read• No additional features of abstraction needed
to support the specification of modifications• Sound
‥
Further research challenges• experience, understanding of
limits• extensions to support more good
programs(joint work with Peter Muller)
‥