230 likes | 371 Views
Predicate Abstraction for Software Verification. Cormac Flanagan Shaz Qadeer. Verifying a Procedure. Given: Precondition Postcondition Loop Invariants specified for all loops Generate a Logical Formula (F) for the procedure And, Prove (using a decision Procedure)
E N D
Predicate Abstraction for Software Verification Cormac Flanagan Shaz Qadeer
Verifying a Procedure • Given: • Precondition • Postcondition • Loop Invariants specified for all loops • Generate a Logical Formula (F) for the procedure • And, Prove (using a decision Procedure) • Precondition && F => Postcondition
This paper… • Specifying Pre & Post conditions of procedures is a useful documentation. • Specifying Loop Invariants is tedious and difficult (and “useless”) • Infer Loop Invariants, using Predicate Abstraction
Outline of Presentation • Symbolic Simulation using Strongest Postconditions • Assuming Loop Invariants are given • Infer Loop Invariants using Predicate Abstraction
Symbolic Simulation • Convert Java to a Guarded Command Language • Starting from the Precondition, determine the Strongest Postcondition
Strongest Postconditions • Given Q a formula, S a statement • Norm(Q,S) • Given that Q is true before S • Norm(Q,S) is true after Normal Execution of S • Wrong(Q,S) • Given that Q is true before S • Wrong(Q,S) is true when S fails
Strongest Postcondition Semantics • Norm(Q, assert P) = Q && P • Wrong(Q, assert P) = Q && !P • When assert P fails we know !P is true • Norm(Q, assume P) = Q && P • Wrong(Q, assume P) = false • assume P never fails
Strongest Postcondition Semantics (2) • Norm(Q,A;B) = Norm(Norm(Q,A), B) • Norm(Q, A;B) • Norm(Q,A) is true after A • This is the Precondition for B • Wrong(Q,A;B) • Either A fails => Wrong(Q,A) is true • Or A succeeds but B fails => Wrong(Norm(Q,A), B) is true • Wrong(Q,A;B) = Wrong(Q,A) || Wrong(Norm(Q,A), B)
Strongest Postcondition Semantics (3) • Norm(Q, AB) = Norm(Q,A) || Norm(Q,B) • Wrong(Q, AB) = Wrong(Q,A) || Wrong(Q,B) • If(e) x:=y+1 else x:=y+2 • => (assume e; x:=y+1) (assume !e; x:=y+2) • Norm: e && x=y+1 || !e && x=y+2
Strongest Postcondition Semantics (4) • Assignments • Wrong(Q, x:=e) is false • As assignments can never fail • Norm(Q, x:=e) • Introduce x’ to represent old value of x • Replace all occurrences of x in Q, e with x’ • After the assignment Q is true and x=e is true • Norm: x’. x = e(x x’) && Q(x x’)
Strongest Postcondition Semantics (5) • For While loops • Requires the loop invariant, I • Replace the while loop with its Desugar. • I: (i<=n) while( i < n ) { i := i+1; } • assert I; i = y; assume I; ( (assume i<n; i:=i+1; assert I; assume false) assume !(i < n))
Strongest Postcondition Semantics (6) • Norm of the desugar: • i’.i’<=n && (i<=n) && !(i<n) • Loop Inv holds at the beginning • Loop Inv and !(Loop Condn) holds at the end • Wrong of the desugar: • !(i<=n) || i’.i’<=n && i”.i”<n && i=i”+1 && !(i<=n) • Loop Inv fails at the beginning • Loop Inv fails at the end of the loop body
i=0; n=100 T, F, T i=1; n=100 F, F, T i=2; n=100 F, T, F i=99; n=100 i=100; n=100 Predicate Abstraction Example n := 100; i := 0; while( i < n ) { i := i+1; } Predicates: i=0 i=n i<n
Predicate Abstraction • Given a Concrete System of states. • Use a Set of n Predicates Pi to map a concrete state to an abstract state • An abstract state contains n bits • Bit i represents if Pi is true/false in that state • Set of Concrete states Mapped to a Set of Abstract states ( == Boolean Function)
Using Predicate Abstraction to find the Loop Invariant • Think of the loop body as a “transition” fn. • Starting with a set of concrete states, • Symbolically execute the loop, • Combine the new states with the init states • Repeat till you reach a fixed point = Set of all “reachable” concrete states • Doing the iteration in finite Abstract domain guarantees termination • Loop Invariant = Strongest Predicate true for all reachable concrete states.
Predicate Abstraction Algorithm • - Abstraction function • - Concretization function (the inverse) • C; while e do B end; • r = ( Norm(true, C) ) • Do(Till Fixed Point of r ){ Current Concrete Set J = ( r ) Symbolically Execute: C; Havoc(targets(B)); assume e && J; B Let Q be the new Concrete Set r = r || ( Q ) }
Problems with Predicate Abstraction • Determining the set of Predicates is key • Expensive • Exponential Calls to a Decision Procedure • Each call might take (super) exponential time • Abstraction is conservative • Property P holds in AbsDomain • Concrete version of the P holds in ConcDomain • If P does not hold in AbsDomain • P may or may not hold in ConcDomain • Difficult to debug if the program has bugs.
Heuristics to Pick Predicates • For reference p, p != null • For an integer i, i is increasing/decreasing • For skolemized constant sc, 0 <= sc, sc < i, a[sc] != null • Not sure if it works for anything other than the examples.
Optimize Calls to the Decision Procedure • Query for maximal clause m, only if implied by r • Find strongest clause c, that is implied by r • A divide and conquer algorithm that “works in practice”
Results • Seemingly (??) better than previous approaches • Predicate Guessing works for 90% of 396 loops in Javafe benchmark
Conclusion • Problems with the paper • Alias Analysis? • Interprocedural Analysis? • Do not mention any domain where their approach holds