Session 18 Automatic Programming A HEURISTIC APPROACH TO PROGRAM VERIFICATION Shmuel M. Katz and Zohar Manna Department of Applied Mathematics The Weizmann I n s t i t u t e of Science Rehovot, Israel Abstract We present various heuristic techniques for use in proving the correctness of computer programs. The techniques are designed to obtain automatically the "inductive assertions" attached to the loops of the program which previously required human "understanding" of the program's performance. We distinguish between two general approaches: one in which we obtain the inductive assertion by analyzing predicates which are known to be true at the entrances and exits of the loop (top-down approach), and another in which we generate the inductive assertion directly from the statements of the loop (bottom-up approach). I. Introduction The desirability of proving that a given program is correct has been noted repeatedly in the computer literature, Floyd [1967] has provided a proof method for showing partial correctness of iterative (flow- chart) programs, that is, it shows that if the program terminates, a given input-output relation is satisfied. The method involves cutting each loop of the program, attaching to each cutpoint an "inductive assertion" (which Is a predicate in first-order predicate calcul- us), and constructing verification conditions for each path from one assertion to another (or back to itself). The program is partially correct if all the verifica- tion conditions are valid. Elements of these tech- niques have been shown amenable to mechanization. King [1969], for example, has actually written a 'veri- fier' program which, given the proper inductive asser- tions for programs written in a simplified Algol-like language, can prove partial correctness. Thus, it is fairly clear that the parts of this method which in- volve generating verification conditions from inductive assertions and then proving or disproving their vali- d i t y is a d i f f i c u l t but programmable problem. However, as King puts it, finding a set of assertions to 'cut' each loop of the program "depends on our deep under- standing of the program's performance and requires some sophisticated intellectual endeavor". In this paper we show some general heuristic tech- niques for automatically finding a set of inductive assertions which will allow proving partial correct- ness of a given program. More precisely, we are given a flowchart program with input variables x (which are not changed during execution), program variables y (used as temporary storage during the execution of the program), and output variables z (which are assigned values only at the end of the execution). In addition, we are given "input predicate" $(x), which puts re- strictions on the input variables, and "output predi- cate" <Kx,z), which indicates the desired relation be- tween the input and output variables. Given a set of cutpoints which cut all the loops, our task is to at- tach an appropriate inductive assertion Q i to each cutpoint i. We distinguish between two general approaches: (a) top-down approach in which we obtain the Induct- ive assertion inside a loop by analyzing the predicates which are known to be true at the entrances and exits of the loop, and (b) bottom-up approach in which we generate the in- ductive assertion of a loop directly from the state- ments of the loop. For "toy" examples, having only a single loop, it is generally clear that the top-down approach is the natural method to use. However, this is definitely not the case for real (non-trivial) programs with more com- plex loop structure. In this case some bottom-up tech- niques were found indispensible. Most commonly we have found it necessary to combine the two techniques, with the bottom-up methods dominant. Preliminary attempts to attack the problem of find- ing assertions have been made by Floyd [private commun- i c a t i o n ] , and Cooper [ 1 9 7 1 ] . Heuristic rules basically similar to some of our top-down rules have been discov- ered Independently by Wegbreit [1973]. Elspas, et al. [1972], used "difference equations" derived from the program's statements which is, in essence, a bottom-up approach. We handle programs with arrays separately, since generating assertions involving quantification over the indices of arrays requires special treatment. Thus in Section II we discuss heuristic techniques for flow- chart programs without arrays, while in Section III we extend the treatment to programs with arrays. In Sec- tion IV (conclusion) we discuss open problems and pos- sible implications of our techniques. Related problems where these approaches seem applicable include proving termination of programs, and discovering the input and 500