Lazy Abstraction with Interpolants Ken McMillan (CAV’06) Based on presentation by Yakir Vizel Automatic verification, June 26, 2017 Lecture 12
• Previous work develops lazy abstraction for hardware – Models describe hardware – Visible-variables abstraction • This work presents lazy abstraction for software – Models describe software – Kind-of predicate abstraction
Modeling Programs • Programs are represented as a Control Flow Graph (CFG) • Sets of states are represented by formulas of the First Order Logic (FOL) over program variables, denoted L(S) • A transition formula is a formula in L(S U S’) – Example: x’ = x + 1 • (n) is at time n – variables in are primed n times
Modeling Programs • A program is a tuple ( , Δ , l i ,l f ) where – is a finite set of program locations – Δ is a set of actions – l i is the initial location – l f is the error location (l i , l f are both in ) • An action is a triple (l,T,m) where l,m are respectively the entry and exit locations of the action and T is a transition formula
Modeling Programs • A path π of a program is a sequence of transitions of the form (l 0 ,T 0 ,l 1 ), (l 1 ,T 1 ,l 2 ), …,(l n-1 ,T n-1 ,l n ) • π is an error path if l 0 =l i and l n =l f • The unfolding U( π ) of path π is the sequence of formulas: T 0 (0) ,T 1 (1) ,…,T n-1 (n-1) (i) is shifted i time units into the future T i • A path π is feasible when U( π ) is consistent
Example do{ L=0 lock(); [L!=0] old = new; L=1; old=new if(*){ unlock(); new++; L=0; [new!=old] new++ } } while (new != old); [new==old] control-flow graph program fragment lock: set L; unlock: reset L; Initially L=0 Specification: L is always 0 on entry to lock
Example do{ L=0 lock(); [L!=0] old = new; L=1; old=new if(*){ unlock(); new++; L=0; [new!=old] new++ } } while (new != old); [new==old] control-flow graph program fragment Λ U( π ) = (L=0) Λ (L’=1 Λ old’=new) Λ True Λ (new = old’) Λ U( π ) = (L=0) Λ ( L’=1 Λ old’=new) Λ (L’’=0 Λ new’ = new + 1) Λ (new’ != old’ ) Λ (L’’ != 0)
Program Models • A program is safe if every error path of the program is in feasible • An inductive invariant of a program is a map F: L(S) such that: – F(l i ) = TRUE – For every action (l,T,m) in Δ , F(l) T implies F(m) ’ • A safety invariant of a program is an inductive invariant such that F(l f ) = FALSE • Note: Existence of a safety invariant for a program implies that the program is safe
Program Unwinding • An unwinding of a program A = ( , Δ , l i , l f ) is a quadruple (V,E,M v ,M e ), where – (V,E) is a directed tree rooted at ε , – M v : V is the vertex map, and – M e : E Δ is the edge map such that: – M v ( ε ) = l i – For every non-leaf vertex v in V, for every action (M v (v),T,m) in Δ , there exists an edge (v,w) in E such that M v (w) = m and M e (v,w) = T
Program Unwinding • For two vertices v and w of a tree, w < v denotes that w is a proper ancestor of v
Unwinding the CFG • An unwinding is a tree with an embedding in the CFG M v M e 0 L=0 L=0 [L!=0] [L!=0] 2 1 L=1; old=new L=1; old=new 3 L=0; L=0; new++ [new!=old] new++ 4 8 [new==old]
Expansion • Every non-leaf vertex of the unwinding must be fully expanded... If this is not a leaf... M v 0 M e L=0 L=0 ...and this exists... ...then this exists. 1 ...but we allow unexpanded leaves (i.e., we are building a finite prefix of the infinite unwinding)
Program Unwinding • A labeled unwinding of a program A=( , Δ ,l i ,l f ) is (U, ψ ,C) where – U = (V,E,M v ,M e ) is an unwinding of A – Ψ :V L(S) is called the vertex labeling , and – C is a relation in V x V, called the covering relation • A vertex v is covered iff there exists (w,x) in C such that w ≤ v.
Program Unwinding • Unwinding is safe iff for all vertices v in V, M v (v)=l f implies Ψ (v) ≡ FALSE • Unwinding is complete iff every leaf v in V is covered
Labeled unwinding T 0 • A labeled unwinding is equipped L=0 F with: [L!=0] L=0 2 1 – a labeling function : V L (S) L=1; (T here is True) old=new 3 T – a covering relation C in V x V L=0; new++ ... L=0 4 [new!=old] [new==old] F [L!=0] L=0 T 5 6 7 ... These two nodes are covered . (have a ancestor at the tail of a covering arc)
Labeled Program Unwinding • A labeled unwinding (U, ψ ,C) of a program A = ( , Δ , l i ,l f ) where U = (V,E,M v ,M e ), is well- labeled iff: – Ψ ( ε ) ≡ TRUE, and – For every edge (v,w) in E, Ψ (v) M e (v,w) implies Ψ (w)’ , and – For all (v,w) in C, Ψ (v) Ψ (w), and w is not covered
Labeled Program Unwinding Main Theorem: If there exists a safe, complete, well-labeled unwinding of program A, then A is safe Recall: A program is safe if every error path of the program is in feasible
Well-Labeled Unwinding • An unwinding is well-labeled when – ( ) = True – every edge is a valid Hoare triple – if (x,y) in C then y is not covered T 0 L=0 F [L!=0] L=0 2 1 L=1; old=new 3 T L=0; new++ L=0 4 [new!=old] [new==old] F [L!=0] L=0 T 5 6 7
Safe and Complete safe if every error vertex is labeled False complete if every non-terminal leaf is covered T 0 L=0 F [L!=0] L=0 2 1 L=1; old=new 3 T old=new L=0; new++ T old=new L=0 4 8 [new!=old] [new==old] [new!=old] T F F L=0 T [L!=0] [L!=0] T 5 9 6 7 9 10 T F ... ... Theorem: A CFG with a safe complete unwinding is safe.
Why a Covered Vertex Cannot Cover? • y covers x, w covers v y is covered (v ≤ y) – Ψ (x) Ψ (y) • Every state reachable from x is reachable from y. – Ψ (v) Ψ (w) • Every state reachable from v is reachable w v from w. p p • Any state reachable from y should be y x z reachable from w through its p T T descendent z. • NOT every state reachable from x is also reachable from z. • z is the only vertex that is not covered.
Interpolants for Sequences • To handle program paths, a generalization of interpolant is needed • Given a sequence of formulas Γ = A 1 ,A 2 ,…,A n , we say that Ā 0 , Ā 1 ,…, Ā n is an interpolant for Γ when: – Ā 0 = TRUE and Ā n = FALSE, – For all 1 ≤ i ≤ n, Ā i-1 A i implies Ā i , and – For all 1 ≤ i ≤ n, Ā i is in L(A 1 ,…,A i ) ∩ L(A i+1 ,…,A n ) • If Γ is quantifier-free we can derive a quantifier- free interpolant for Γ (from the refutation of Γ )
Interpolants for Sequences • An intuition… ... A 1 A 2 A 3 A k True False ... Ā 1 Ā 2 Ā 3 Ā k-1 • So this is a structured refutation of A 1 ,…,A k
Interpolants as Floyd-Hoare proofs True x 1 = y 0 x=y; 1. Each formula implies the next x 1 =y 0 2. Each is over common symbols of y 1 =y 0 +1 y++; prefix and suffix y 1 >x 1 3. Begins with true, ends with false x 1 y 1 [x=y] False Path refinement procedure proof structured SSA Path Prover proof sequence Refinement Interpolation
Lazy PA with Interpolants • Procedure Expand (v in V) if v is uncovered leaf then for all actions (M v (v),T,m) in Δ add a new vertex w to V and a new edge (v,w) to E; M v (w) = m and ψ (w) = True ; M e (v,w) = T;
Lazy PA with Interpolants • Procedure Refine (v in V) if M v (v) = l f and ψ (v) != FALSE then let π = (v 0 ,T 0 ,v 1 )…(v n-1 ,T n-1 ,v n ) be the unique path from ε to v. if U( π ) has an interpolant A’ 0 ,…,A’ n then for i=0…n: let Φ = A’ i \* remove primes (-i) if ψ (v i ) does not imply Φ then remove all pairs ( ,v i ) from C set ψ (v i ) = ψ (v i ) Φ
The Example do{ L=0 [L!=0] lock(); old = new; L=1; old=new if(*){ unlock(); new++; L=0; [new!=old] new++ } } while (new != old); [new==old] control-flow graph program fragment • Property: lock() is not called if the lock is already being held
Unwinding the CFG T 0 L=0 L=0 [L!=0] F T L=0 T [L!=0] 2 1 L=1; old=new Label error state with false, by L=0; refining labels on path [new!=old] new++ [new==old] control-flow graph
Unwinding the CFG T 0 L=0 L=0 [L!=0] F [L!=0] L=0 2 1 L=1; old=new L=1; old=new 3 T old=new L=0; L=0; new++ [new!=old] new++ T L=0 4 [new!=old] [new==old] F T [L!=0] T L=0 5 6 control-flow graph Covering: state 5 is subsumed by state 1.
Unwinding the CFG T 0 L=0 L=0 [L!=0] F [L!=0] L=0 2 1 L=1; old=new L=1; old=new 3 old=new old=new L=0; L=0; new++ [new!=old] new++ T old=new L=0 4 8 [new!=old] [new==old] [new!=old] [new==old] T F F [L!=0] L=0 T [L!=0] T 5 10 6 7 9 11 T F control-flow graph Another cover. Unwinding is now complete.
Covering Step • If (x) (y)... – add covering arc (x, y) to C – remove all (z, w) in C for w descendant of y x=y x ≤ y X We restrict covers to be descending in a suitable total order on vertices. This prevents covering from diverging.
Recommend
More recommend