Title: Well-cooked Spaghetti: Weakest-Precondition of Unstructured Programs
1Well-cooked SpaghettiWeakest-Precondition of
Unstructured Programs
- Mike Barnett and Rustan Leino
- Microsoft Research
- Redmond, WA, USA
2Spec Programming System
Spec
runtime monitoring
Spec compiler
MSIL (bytecode)
Spec program verifier
translator
inference engine
Boogie PL
V.C. generator
verification condition
automatictheorem prover
correct or list of errors
3Spec demo
4Spec Demo What It Showed
- Non-null type system
- Pre- and postconditions
- Object invariants
- Dynamic monitoring
- Static verification
5Verification Condition
- First-order logical formula
- Valid if and only if program meets its
specification - This leaves a lot of room for engineering
6General Problem
- Duplication of postconditions for if-statements
wp( if (b) x else x-- , p ? null )
(b ? wp( x , p ? null )) ? (b ?wp( x-- ,
p ? null ))
7Definition of Language
Program Block Block BlockId Stmt
goto BlockId Stmt VarId Expr havoc
VarId assert Expr assume Expr Stmt
Stmt skip
8Example
if (E) Selse T
z x
z1 x0
goto S,T
x
x
x1
x2
x1 x3 x1
x2 x3 x2
assume ES
assume ET
y x
y1 x3
9The recipe
- 0. Cut Loops
- Consider arbitrary loop iteration
- 1. Passify the program
- Combine control flow and data flow
- 2. Construct weakest precondition formula
- Connect the program to its semantics
10Cutting Loops the general idea
havoc x
x
Without a loop invariant, this loses all
information about x.
11Cut Loops Sub-steps
- 0.0. assert P assert P assume P
- 0.1. Push asserts up-stream.
- 0.2. Delete back edges after havoc-ing loop
targets.
12Cutting the loops Putting the steps together
assert J
Note how this corresponds to the classical notion
of a loop invariant checking it in two places
allows you to assume it at the top of the loop.
assert J
assert J assume J
assume J
havoc x assume J
x
x assert J
13Passification
z x
z1 x0
assume z1 x0
x
x
x1
x2
x1 x3 x1
x2 x3 x2
assume x1 assume x3 x1
assume x2 assume x3 x2
y x
y1 x3
assume y1 x3
14Weakest Precondition
- For each block A, Aok holds when all executions
starting at A are okay. - Block Equation for each block A (BEA)
- VC (semantics of entire program)
- VC is obviously linear (in size of the passive
program)
Aok wp(S, (? B ? Succ(A) Bok))
(? A BEA) ? Startok
15Example
int M(int x) requires 100 lt x ensures
result 0 while (0 lt x) invariant 0 lt
x x x 1 return x
16CFG
Start
precondition
assume 100 x
loop invariant
LoopHead
assert 0 x
loop guard
Body
assume 0 lt xx x 1
negation of guard
After
assume (0 lt x)r xassert r 0
postcondition
17Loop-Free CFG
Start
assume 100 xassert 0 x
LoopHead
havoc xassume 0 x
Body
assume 0 lt xx x 1assert 0 x
After
assume (0 lt x)r xassert r 0
18Passive Program
Start
assume 100 x0assert 0 x0
LoopHead
skipassume 0 x1
Body
assume 0 lt x1assume x2 x1 1assert 0 x2
After
assume (0 lt x1)assume r1 x1assert r1 0
19Block Equations
Startok 100 x0 ? 0 x0? LoopHeadok
LoopHeadok 0 x1 ? Bodyok ? Afterok
Bodyok 0 lt x1 ? x2 x1 1 ? 0 x2 ? true
Afterok (0 lt x1) ? r1 x1?r1 0 ? true
20Verification Condition
Startok 100 x0 ? 0 x0? LoopHeadok
?
LoopHeadok 0 x1 ? Bodyok ? Afterok
?
Bodyok 0 lt x1 ? x2 x1 1 ? 0 x2 ? true
?
Afterok (0 lt x1) ? r1 x1?r1 0 ? true
?
Startok
21Related Work
- Distribution via wlp We could have done this too
(it is ESC/Javas technique), but converting to a
structured program leads to a blow up (and
requires heuristics). - Possibly could have used a target language with
S!T (and raise) for exceptional composition.
22Conclusion
- Room for more improvement
- Recent experiments on directing theorem prover
along certain paths. - Useful even for systems that use structured
programs.