Presentation is loading. Please wait.

Presentation is loading. Please wait.

Induction in CEGAR for Detecting Counterexamples

Similar presentations


Presentation on theme: "Induction in CEGAR for Detecting Counterexamples"— Presentation transcript:

1 Induction in CEGAR for Detecting Counterexamples
Chao Wang, Aarti Gupta, Franjo Ivancic NEC Laboratories America Thanks for the introduction. This is a joint work with Aarti Gupta and Franjo Ivancic.

2 Background Detecting long counterexamples is a hard problem
Bounded model checking [Biere et al 1999] Counterexample guided abstraction refinement (CEGAR) [Kurshan 1994] [Clarke et al. 2000] [Ball et al. 2001] Interpolation [McMillan 2003] Induction has been used in model checking for finding proofs To prove the absence of counterexample [Sheeran et al. 2000] [Gupta et al. 2003] [de Moura et al. 2003] It has never been used for finding bugs We use induction to prove the existence of counterexamples Target counterexamples that are long and can be captured by regular patterns Related works [Bjesse & Kukula 2004] [Nashi & Somenzi 2006] [Kroening & Weissenbacher 2006] [Ball, Kupferman, Sagiv 2007] Detecting long counterexamples is known to be a hard problem in model checking. If the counterexample is short, for instance, bounded model checking would be very well suited. But if the bug is deep, BMC becomes inefficient, and the same thing happens to counterexample guided abstraction refinement and interpolation. In the presentation, I will show you the use of induction for finding very deep bugs, whose counterexamples are long and yet can be captured by regular patterns. Induction has already been used in model checking for finding proofs. To our knowledge, it has never been used for finding bugs.

3 A simple and yet representative bug (e.g., array bound violation)
A Motivating Example A simple and yet representative bug (e.g., array bound violation) P: (i<n) First, a motivating example. Since the condition of the while loop is (I <= n), and the assertion condition is (i<n), there is going to be an assertion failure at the very end. Because n=10,000, this is a very long counterexample. It’s hard to find by using existing model checking techniques. For example, when predicate abstraction and refinement is used, you would have to add more than predicates before finding this counterexample. Clearly not efficient. P: (i<n) P1: (i+1<n) P2: (i+2<n)

4 A Motivating Example Our Observations:
Counterexample exists regardless of the value of ‘n’ Counterexample has a regular pattern Our main observations are: first, a counterexample exists regardless of the value of ‘n’. For n=1, 10, 100, there will always be a corresponding counterexample. Second, the counterexample follow a regular pattern. So, if we can prove that a counterexample of this regular pattern exists for all n>=1, by using induction, then it follows that there exists a counterexample for n=10000. The hope is that, under certain conditions induction proof is much cheaper to accomplish that symbolically executing the loop 10,000 times.

5 Outline Background Identifying the Counterexample Pattern
Proving the Existence of Counterexample Experiments Conclusions So there will be two main problems: first, how to automatically identify the counterexample pattern? Second, how to prove the existence of counterexample by induction.

6 Parameterized Counterexamples
induction parameter prefix recurring segment suffix First, let me define the parameterized counterexample. It consists of a finite-length prefix starting from the initial state, a finite-length suffix leading to the error state, and in the middle a recurring segment. Here n is the number of copies of the recurring segment, which, in the following, we will also call it the induction parameter.

7 Identifying Counterexample Pattern
Idea: look at the spurious counterexamples produced by CEGAR Spurious counterexamples in CEGAR: (1)(2)(3)(4)(5) (6)(7) (1)(2)(3)(4)(5) (6)(7)(8) (6)(7) (1)(2)(3)(4)(5) (6)(7)(8) (6)(7)(8) (6)(7) (1)(2)(3)(4)(5) {(6)(7)(8)}n (6)(7) prefix recurring segment suffix Given a model and a property, how do we identify the counterexample pattern? The idea is, look at the spurious counterexamples produced by CEGAR. For those who are not yet familiar with CEGAR, I will explain in the next slide. If you look at the example, after predicate abstraction, the first spurious counterexample would be 1-5,6-7, because the conditions are abstracted away. Next round, the counterexample would be 1-5,678,6-7, and so on. If you look at these counterexamples hard enough, they all follow the same pattern: a finite prefix, a finite suffix, and a recurring segment. The real question is, how to identify it automatically?

8 Using Induction in the CEGAR Loop
CEGAR: [Kushan 1994] [Clarke et al. 2000] [Ball and Rajamani 2000] Induction to prove existence of CEX found CEX yes Bug found no found CEX Proved no Concretize abstract counterexample concrete CEX Bug found yes Refinement Model Checking Abstraction Step1. identify pattern Step2. induction proof yes Here is a brief introduction to CEGAR. We propose the use of induction inside CEGAR. After concretization fails, we use induction to try to find deep bugs. If we succeed, we are done! Otherwise, we fall back to standard CEGAR. There will be two steps: first, identify the counterexample pattern – we propose to do it inside the concretization test.

9 Concretization Test (standard)
Abstract counterexample First, let me show you how standard concretization test works. Assume there is a sequence of abstract states from the initial state to a bad state E. In standard concretization test, you can start from E, and compute the concrete pre-condition (or pre-image). If eventually you can reach the initial state, then it’s a real counterexample. If somewhere in the middle it becomes empty, then you declare it as a spurious counterexample. Notice that, in order to succeed, the abstract counterexample need to have the same depth as the concrete counterexample – that’s where all the inefficiency comes from. Concrete pre-condition computation

10 Concretization with Back-leaping
Here is an improvement we suggested. If the precondition becomes empty at index i, we do not declare it as spurious counterexample right away; instead, we searching for two indexes k and j, such that the precondition from index k intersects the abstract state s_j. After that, we continue the concretization procedure from this shaded area. This will avoid the strictly state-by-state matching of the abstract and concrete counterexamples. Also, the segment from k to j is a good candidate of the recurring segment. At the failing index i such that Find two indexes k and j such that and

11 Identifying the Induction Parameter
Parameterized counterexample: (1)(2)(3)(4)(5) {(6)(7)(8)}n (6)(7) tail of recurring segment head of suffix (i <= n) After identifying the recurring segment, we need to pick an induction parameter. If you look at the transition from the tail of the recurring segment, which is 8, to the head of the suffix, which is 6, this transition is guarded by the condition (i<=n). In principle, variables in the transition support of this condition may be a candidate. For n to be the induction parameter, it has to satisfy another requirement: that is, all the guards inside the recurring segment (in this example, lines 6-8) must be monotonic with respect to n. Such a requirement allows us to get the induction proof, because if they are monotonic, then guards valid for n=k are also valid for n=k+1. This is a heurstic (to be verified by induction proof)

12 Parameterized Traces In prefix, find assignment to n n = expr ;
Rewrite it into n = k ; We can set the symbolic value k = 1, 2, 3, … Once we identify the pattern, it’s easy to rewrite the original program and get a parameterized version. Here we simply search for assignment to n in the finite prefix (which is line 1-5), and rewrite the assignment to n=k (k is a symbolic value). If we set k=1, for instance, we can use model checking to find a concrete counterexample (because it’s short). That can serve as the base case for induction proof.

13 Outline Background Identifying the Counterexample Pattern
Proving the Existence of Counterexample Experiments Conclusions

14 Using Induction in the CEGAR Loop
Induction to prove existence of CEX found CEX yes Bug found no found CEX Proved no Concretize abstract counterexample concrete CEX Bug found yes Refinement Model Checking Abstraction Step1. identify pattern Step2. induction proof yes The next step is, assume that a counterexample exists for n=k, and prove that it also exists for n=k+1.

15 What’s easy / hard to compute?
Pre-condition computation Post-condition computation Transitive Pre- and Post-condition Easy to compute Hard to compute Before explain the induction proof, let’s agree upon what’s easy to compute, and what’s hard to compute? Here I have listed three transitive pre- and post-conditions. The first one is the post-condition of the initial state I, over the finite prefix. The second is the post-condition of the initial state, over the finite prefix and the parameterized recurring segment. The third one is the precondition of the error state S_E over the finite suffix. We assume that G and B are easy to compute, since they involve finite sequences only. F is hard since it’s over parameterized traces. We should not attempt to directly computer F. never directly compute F

16 Induction Proof Assume the counterexample exists for n=k, we’d like to prove it also exists for n=k+1. Comparing these two traces, we find that they differ only in the finite suffixes. If we define F,B,F’,B’ as follows, then this is what we want to establish. Except that directly computing F and F’ are infeasible in practice.

17 Induction: handling the prefixes
F and F’ differ only in the valuations of Vb The basic idea is to focus on G and G’, instead of F and F’. First of all, we can directly compute G and G’. Then we would like to find a sufficient condition under which the induction requirement on F and F’ can be implied by the requirement on G and G’. In particular, if we can partition the set of program variables into V_a and V_b, such that V_b does not appear anywhere in the recurring segments, and at the same time the only difference of G and G’ is in the valuations of V_b. Then F and F’ differ only in the valuations of V_b.

18 Induction: handling the suffixes
F and F’ differ only in the valuations of Vb Theorem 1 C0 C1 So we can focus on the valuations of V_b in G and G’. At the same time, if the backward reachable states B and B’ satisfy the following condition, then according to Theorem 1 in our paper, we have the induction proof.

19 The Running Example finite-length prefix finite-length suffixes
Let’s look at the running example: In this example, we partition the program variables into V_a = {i}, and V_b={n}. These are the results of G and G’. Note that they have a common part which is (i=0). There are the results of B and B’. If we conjoin G_b and B, and quantify out V_b, we get i=k, which is the same as i+1=k+1. That’s the induction proof.

20 Outline Background Identifying the Counterexample Pattern
Proving the Existence of Counterexample Experiments Conclusions

21 About Implementation: pre*( )
[cf. Dijkstra 1976] Let me say a few words about the implementation: the pre and post condition can be computed relatively efficiently, because we are focusing on a single path. For pre, we use the weakest liberal precondition.

22 About Implementation: existential quantification
Finite domain: BDD (smooth) Linear integer: Polyhedral (F-M elimination) With both: Combination of BDD and Polyhedra [Yang et al. MEMOCODE 2006] For existential quantification, if all variables are in finite domains, then we can use BDDs which is relatively simple. For unbounded integers, existential quantification can be implemented as F-M elimination. When there are both finite and infinite integers, we use a composite symbolic representation in which there are both BDDs and polyhedra. For such representation, existential quantification can be done efficiently.

23 Experiments … 256 Induction finds this counterexample in 10 seconds
The GNU bc example with standard CEGAR This is a Linux example, the GNU bc command line calculator. In an older version, there is a array bound violation. As you can see, arrays is initialized with a_count elements, but it’s accessed with v_count. When a_count is set to 256, there is no way for standard CEGAR to find this counterexample. When a_count is set to 1, 2, 3, it’s possible – but the run time goes up very quickly. With induction, we can prove the existence of a parameterized counterexample within 10 seconds. Induction finds this counterexample in 10 seconds 256

24 Experiments bc: GNU bc example Aeon:
Aeon-0.02a, Linux mail transfer agent ftpd: wu-ftpd-2.6.2, the ftp daemon Besides the GNU bc example, we also tried Aeon and ftpd, and observed similar results. run time of standard CEGAR (x-axis: values of the induction parameters)

25 Conclusions Induction in CEGAR for detecting long counterexamples
Concretization algorithm to identify counterexample pattern Induction to prove the existence of counterexamples Complementary to standard CEGAR (which itself is good for finding proofs) Well-suited for finding deep bugs Better than searching for a state-by-state match of the concrete counterexamples e.g., BMC, predicate abstraction, interpolation Future work Static analysis to improve the counterexample pattern identification In conclusion, we presented an induction based method in CEGAR for detecting bugs. The new method is effective in proving the existence of long counterexamples that follows regular patterns. It has complementary strength compared to standard CEGAR, which itself is well suited for finding proofs. For future work, we’d like to use more static analysis techniques to improve the identification of counterexample pattern.


Download ppt "Induction in CEGAR for Detecting Counterexamples"

Similar presentations


Ads by Google