220 likes | 238 Views
Learn about the Spec# programming system by Microsoft Research. Discover its components and how it aids in program verification, monitoring, and compilation. Explore examples and theoretical foundations.
E N D
Well-cooked Spaghetti:Weakest-Precondition of Unstructured Programs Mike Barnett and Rustan Leino Microsoft Research Redmond, WA, USA
Spec# 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
Spec# Demo: What It Showed • Non-null type system • Pre- and postconditions • Object invariants • Dynamic monitoring • Static verification
Verification Condition • First-order logical formula • Valid if and only if program meets its specification • This leaves a lot of room for engineering…
General 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 ))
Definition of Language Program ::= Block+ Block ::= BlockId : Stmt;goto BlockId* Stmt ::= VarId := Expr | havoc VarId | assert Expr | assume Expr | Stmt ; Stmt | skip
Example if (E){ S;}else{ T; } goto S,T; z := x z1 := x0 assume E;S; x := … x1 := … x1 := …x3 := x1 assume ¬E;T; x := … x2 := … x2 := …x3 := x2 … y1 := … x3 … y := … x …
The 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
Cutting Loops: the general idea havoc x; x := … Without a loop invariant, this loses all information about x.
Cut Loops: Sub-steps 0.0. assert Passert P; assume P 0.1. Push asserts up-stream. 0.2. Delete back edges after “havoc”-ing loop targets.
Cutting 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;
Passification assume z1 = x0 z := x z1 := x0 assume x1 = …assume x3 = x1 x := … x1 := … x1 := …x3 := x1 assume x2 = …assume x3 = x2 x := … x2 := … x2 := …x3 := x2 assume y1 = … x3 … y1 := … x3 … y := … x …
Weakest 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
Example int M(int x)requires 100 <= x;ensures result == 0;{while (0 < x)invariant 0 <= x; { x = x – 1; }return x;}
CFG Start precondition assume 100 ≤ x; LoopHead loop invariant assert 0 ≤ x; loop guard Body negation of guard assume 0 < x;x := x – 1; After assume¬(0 < x);r := x;assert r = 0; postcondition
Loop-Free CFG Start assume 100 ≤ x;assert 0 ≤ x; LoopHead havoc x;assume 0 ≤ x; Body assume 0 < x;x := x – 1;assert 0 ≤ x; After assume¬(0 < x);r := x;assert r = 0;
Passive Program Start assume 100 ≤ x0;assert 0 ≤ x0; LoopHead skip;assume 0 ≤ x1; Body assume 0 < x1;assume x2 = x1 – 1;assert 0 ≤ x2; After assume¬(0 < x1);assume r1 = x1;assert r1 = 0;
Block Equations Startok≡ 100 ≤ x0⇒ 0 ≤ x0∧ LoopHeadok LoopHeadok≡ 0 ≤ x1⇒ Bodyok ∧ Afterok Bodyok≡ 0 < x1⇒ x2 = x1 – 1 ⇒ 0 ≤ x2∧ true Afterok≡ ¬(0 < x1) ⇒ r1 = x1⇒r1 = 0 ∧ true
Verification Condition Startok≡ 100 ≤ x0⇒ 0 ≤ x0∧ LoopHeadok ∧ LoopHeadok≡ 0 ≤ x1⇒ Bodyok ∧ Afterok ∧ Bodyok≡ 0 < x1⇒ x2 = x1 – 1 ⇒ 0 ≤ x2∧ true ∧ Afterok≡ ¬(0 < x1) ⇒ r1 = x1⇒r1 = 0 ∧ true ⇒ Startok
Related Work • Distribution via wlp: We could have done this too (it is ESC/Java’s 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.
Conclusion • Room for more improvement • Recent experiments on directing theorem prover along certain paths. • Useful even for systems that use structured programs.