Program verification via iterated specialization

E. De Angelis, F. Fioravanti, A. Pettorossi, M. Proietti
2014 Science of Computer Programming  
We present a method for verifying properties of imperative programs by using techniques based on the specialization of constraint logic programs (CLP). We consider a class of imperative programs with integer variables and we focus our attention on safety properties, stating that no error configuration can be reached from any initial configuration. We introduce a CLP program I that encodes the interpreter of the language and defines a predicate unsafe equivalent to the negation of the safety
more » ... erty to be verified. Then, we specialize the CLP program I with respect to the given imperative program and the given initial and error configurations, with the objective of deriving a new CLP program I sp that either contains the fact unsafe (and in this case the imperative program is proved unsafe) or contains no clauses with head unsafe (and in this case the imperative program is proved safe). If I sp enjoys neither of these properties, we iterate the specialization process with the objective of deriving a CLP program where we can prove unsafety or safety. During the various specializations we may apply different strategies for propagating information (either propagating forward from an initial configuration to an error configuration, or propagating backward from an error configuration to an initial configuration) and different operators (such as the widening and the convex hull operators) for generalizing predicate definitions. Each specialization step is guaranteed to terminate, but due to the undecidability of program safety, the iterated specialization process may not terminate. By an experimental evaluation carried out on a significant set of examples taken from the literature, we show that our method improves the precision of program verification with respect to state-of-the-art software model checkers. abstract initial configuration, then the program is proved to be safe (see [32] for a general abstract reachability algorithm). Notable abstractions are those based on convex polyhedra [10] , that is, conjunctions of linear inequalities (also called constraints in this paper). Constraint Logic Programming (CLP) is a very suitable framework for the analysis of imperative programs, because it provides a very convenient way of representing symbolic program executions and also, by using constraints, program abstractions (see, for instance, [29, 31, 40, 41] ). In the context of CLP-based program analysis, the problem of verifying imperative programs can be transformed into the problem of analyzing CLP programs by using CLP program specialization [40] . By following the approach presented in [40] , first the semantics of the language in which the imperative programs are written is defined in terms of a CLP program I which is the interpreter of that language, and then I is specialized with respect to: (i) the CLP representation P of the input imperative program P, and (ii) the CLP representation F of the safety property F that should be checked. The result of this specialization is a CLP program I sp that is semantically equivalent to I ∪ P ∪ F . Thus, in order to prove some given properties of the imperative program P, we can analyze the CLP program I sp by applying, for instance, techniques based on the above mentioned polyhedral abstractions. It has also been pointed out that CLP program specialization can be used as a technique for software model checking on its own [12] . Indeed, by specializing I sp with respect to the constraints characterizing the input values of P (that is, the precondition of P), in some cases one can derive a new CLP program I sp whose least model M(I sp ) can be computed in finite time because I sp can be represented by a finite (possibly empty) set of constraints. Thus, in these cases it is possible to verify whether or not P is safe by simply inspecting that model. However, due to the undecidability of safety, it is impossible to devise a specialization technique that always terminates and produces a specialized CLP program whose least model can be finitely computed. Thus, the best one can do is to propose a verification technique based on some heuristics and show that it works well in practice. This is what we have done in this paper. In particular, we have proposed a method, called the iterated specialization, that is based on the repeated application of program specialization. By iterated specialization we can produce a sequence of CLP programs of the form I, I sp , I 1 sp , I 2 sp , . . . Each program specialization step terminates and has the effect of modifying the structure of the CLP program and explicitly adding new constraints that denote invariants of the computation. Thus, the effect of the iterated specialization is the propagation of these constraints from one program version to the next, and since each new iteration starts from the output of the previous one, we can refine program analysis and possibly increase the level of precision. Iterated specialization terminates at step k, if a lightweight analysis based on a simple inspection of the CLP program I k sp is able to decide safety or unsafety. In order to validate the heuristics used in our verification method from an experimental point of view, we have implemented a prototype verification system called VeriMAP [15] . We have performed verification tests on a significant set of over 200 programs taken from various publicly available benchmarks. The precision of our system, that is the ratio of successfully verified programs over the total number of programs, is about 85 percent. We have also compared the results we have obtained using the VeriMAP system with the results we have obtained using other state-of-the-art software model checking systems, such as ARMC [41] , HSF(C) [23], and TRACER [30]. These results show that our verification system has a considerably higher precision. Let us summarize here the main contributions of our paper. (i) The adaptation and the integration of various techniques for specializing and transforming constraint logic programs into the novel iterated specialization method for verifying imperative programs. This adaptation has required: (i.1) The customization of general purpose unfolding and generalization strategies (such as those in [17, 39] ) to the specific task of specializing the interpreter of the programming language under consideration, as well as the CLP programs derived from the interpreter in subsequent iterations of the method. In particular, we have adapted to our context suitable strategies, based on operators often used in static program analysis such as widening and convex hull [7, 10], for the automatic discovery of loop invariants of the imperative programs to be verified. (i.2) The customization of general purpose transformations for inverting the order of computation [5] , so that iterated program specialization can exploit in a particularly good way the information present in the initial and in the error configurations. (ii) The implementation of our iterated specialization method into a prototype automatic tool [15] . (iii) The experimental evaluation of our proposed method and its comparison with respect to state-of-the-art software model checkers.
doi:10.1016/j.scico.2014.05.017 fatcat:5th77b243fdhdpcwvoyhtuzmp4