Predicate Abstraction for Software Verification
Cormac FlanaganShaz 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
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
Predicate Abstraction
Predicate Abstraction Example
i=0; n=100
i=1; n=100
i=2; n=100
i=99; n=100
i=100; n=100
Predicates: i=0 i=n i<n
T, F, T
F, F, T
n := 100; i := 0; while( i < n ) { i := i+1; }
F, T, F
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
Top Related