Title: Verifying invariants in objectoriented programs
1Verifying invariants in object-oriented
programs
- K. Rustan M. Leino Microsoft Research,
Redmond, WA, USA
Joint work with Mike Barnett, Robert DeLine,
Manuel Fahndrich, and Wolfram Schulte
?
Computer Science ColloquiumETH Zurich24 Nov 2003
2Vision
Record design decisions Utilize automatic
checking Detect errors and improve
maintainability
3A and BoogieProgrammer's view
A
A compiler
Other .NETcompilers
C
C compiler
MSIL
Boogie
Warnings
4Boogie under the hood
MSIL
translator
Inferenceengine
BoogiePL
weakest-preconditiongenerator
verification condition
Theoremprover
Warnings
5Boogie 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
6Invariants straw man
Object invariants hold on public method
boundaries and are shorthands for
pre/post-conditions
- class T // field declarations ...
- invariant J
- T(...) requires P modifies v ensures
Q - method m(...) requires R modifies
w ensures T -
class T // field declarations
... T(...) requires P modifies v ensures
Q ? J method m(...) requires R ? J
modifies w ensures T ? J
7Invariants, example
- class T
- private int x, y invariant 0 ? x lt 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 lt y x 0 y 1
public method m() requires 0 ? x lt y
modifies x, y ensures 0 ? x lt y
assert y-x ? 0 x x 3 y 4
y
8Invariants, problems
- class T
- private int x, y invariant 0 ? x lt 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 lt y x 0 y 1
public method m() requires 0 ? x lt y
modifies x, y ensures 0 ? x lt y
assert y-x ? 0 x x 3 y 4
y
callers are expected to establish property about
internal data structure
9Invariants, problems
- class T
- private int x, y invariant 0 ? x lt 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 lt y x 0 y 1
public method m() requires 0 ? x lt y
modifies x, y ensures 0 ? x lt y
assert y-x ? 0 x x 3 y 4
y
possible solution (?) callers dont need to be
checked for this preconditionit holds
automatically!
10Invariants, problems
- class T
- private int x, y invariant 0 ? x lt 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 lt y x 0 y 1
public method m() requires 0 ? x lt y
modifies x, y ensures 0 ? x lt y
assert y-x ? 0 x x 3 y 4
y
invariant does not hold here
11Invariants, problems
- class T
- private int x, y invariant 0 ? x lt 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 lt y x 0 y 1
public method m() requires 0 ? x lt y
modifies x, y ensures 0 ? x lt y
assert y-x ? 0 x x 3 p(...)
y 4 y
invariant does not hold here, so what if p calls
m?!
12The 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
13The 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 (?) dont need to declare
modifications of private stateit cant be
observed anyhow
14The 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?!
15Soundness 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
16Methodology
- object invariant declaration
- class T int x, y invariant x lt y
- special variable st Invalid, Valid
- Idea program invariant (?o ? o.st Invalid
? Inv(o)) - st is changed by commands pack and unpack
for any o T, we writeInv(o) o.x lt o.y
holds at everyprogram point!
17pack and unpack
- pack o assert o.st Invalid assert
Inv(o) o.st Valid - unpack o assert o.st Valid o.st
Invalid
18Example
receiver parameter(this, self, current)
- class T int x, y invariant 0 ? x lt y
- method init(t)? requires t.st
Invalid modifies t.st, t.x, t.y ensures t.st
Valid t.x 0 t.y 1 pack t - method m(t) requires t.st Valid modifies
t.x, t.y unpack t t.x t.x 3 t.y
4 t.y pack t
19Program 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
20Methodology, summary
- invariant ...
- st Invalid, Valid
- pack, unpack
- modifications of o.f require o.stInvalid
- Inv(o) can mention only the fields of o
- (?o ? o.st Invalid ? Inv(o))
21Methodology, extended
- component declarations
- class Kitchen component Stove s
- st Invalid, Valid, Committed
- Idea program invariant (?o ? o.stInvalid ?
(Inv(o) ? (?p?Comp(o) ?
p.stCommitted))) - pack o and unpack o change st for o and
o's components
for any k Kitchen, we havek.s ? Comp(k)
22pack and unpack, extended
- pack o assert o.st Invalid ? Inv(o)
assert (?p ? Comp(o) ? p.stValid) o.st
Valid foreach p ? Comp(o) do p.st Committed
- unpack o assert o.st Valid foreach p ?
Comp(o) do p.stValid o.st Invalid
23Example
class Stove method Wipe(s) requires
s.stValid
- class Kitchen method SpiffUp(k) requires
k.stValid unpack k k.d.Clean()
k.s.Wipe() pack k -
Committed
Committed
Dishes
Committed
Committed
Stove
s
d
Committed
k
Kitchen
Valid
24Example
class Stove method Wipe(s) requires
s.stValid
- class Kitchen method SpiffUp(k) requires
k.stValid unpack k k.d.Clean()
k.s.Wipe() pack k -
Committed
Committed
Dishes
Committed
Committed
Valid
Stove
s
d
Committed
Valid
k
Kitchen
Valid
Invalid
25Program invariant
- (?o ? o.stInvalid ? (Inv(o) ? (?p?Comp(o) ?
p.stCommitted))) - x new(T) ... assume x.stInvalid
- pack o, unpack o
- o.f E assert o.stInvalid ...
- Inv(o) can mention only the fields of o andof
o.p for any component field p
26Extended methodology, summary
- invariant ...
- component ...
- st Invalid, Valid, Committed
- pack, unpack
- modifications of o.f require o.stInvalid
- Inv(o) can mention only the fields of o and of
o.p for any component field p - (?o ? o.stInvalid ? (Inv(o) ? (?p?Comp(o) ?
p.stCommitted)))
27Verification system
- We let st be used in method specifications
(requires, modifies, ensures) - We must address the Problem of Specifying
Modifications
28A heap model
- Heap is a two-dimensional array
- class T f U g V ...
- x o.f x Heapo, f
- o.f E Heapo, f E
29Meaning of modifies
viewed as set of object/field-name pairs
- modifies w modifies Heap ensures
(?o,f ? Heapo,f Heap0o,f
? (o,f) ? w0 )
30Meaning of modifies
- modifies w modifies Heap ensures
(?o,f ? Heapo,f Heap0o,f ? (o,f) ? w0
? ?Heap0o,alloc )
31Meaning of modifies
- modifies w modifies Heap ensures
(?o,f ? Heapo,f Heap0o,f ? (o,f) ? w0
? ?Heap0o,alloc ? Heap0o,stCommitted )
32Example
class Stove method Wipe(s) requires
s.stValid modifies s.foodPieces
- class Kitchen method SpiffUp(k) requires
k.stValid modifies k.hasGarbage unpack k
k.d.Clean() k.hasGarbage false
k.s.Wipe() assert ?k.hasGarbage pack
k -
33Another example
- method m(p) requires p.stCommitted var y, z
in y p.x z sqrt(49) assert y
p.x end
34Soundness
- Pre- and postconditions are the same for callers
and callees, so verification system is sound!
35Related 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
?
36Conclusions
- 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 referencesobjects
(pointers) can freely be copied - Fields can freely be read
- No additional features of abstraction needed to
support the specification of modifications - Sound
?
37Further research challenges
- experience, understanding of limits
- extensions to support more good programs(joint
work with Peter Muller)
?