Neural Termination Analysis
Total Page:16
File Type:pdf, Size:1020Kb
Neural Termination Analysis Mirco Giacobbe 1 Daniel Kroening 2 Julian Parsert 1 Abstract Program We introduce a novel approach to the automated termination analysis of computer programs: we train neural networks to act as ranking functions. Ranking functions map program states to values 99, 42, 56 57 Execution Neural that are bounded from below and decrease as < traces 99, 43, 34 56 network the program runs. The existence of a valid rank- < ing function proves that the program terminates. 99, 44, -3 55 < 98, 44, 20 54 While in the past ranking functions were usu- . ally constructed using static analysis, our method . learns them from sampled executions. We train a neural network so that its output decreases along 1. Trace 2. Learn 3. Verify execution traces as a ranking function would; then, we use formal reasoning to verify whether it gen- Figure 1: Schema of our procedure. eralises to all possible executions. We present a custom loss function for learning lexicographic ranking functions and use satisfiability modulo The standard way to argue that a program terminates is to theories for verification. Thanks to the ability of present a ranking function (Floyd, 1967). Ranking functions neural networks to generalise well, our method map program states to values that (i) decrease by a discrete succeeds over a wide variety of programs. This amount after every loop iteration and (ii) are bounded from includes programs that use data structures from below. They are certificates of termination: if a ranking standard libraries. We built a prototype analyser function exists, then the program terminates for every possi- for Java bytecode and show the efficacy of our ble input. Previous methods construct termination proofs by method over a standard dataset of benchmarks. relying on the soundness of the underlying algorithm (Arts & Giesl, 2000; Bradley et al., 2005a; Cook et al., 2006b). However, finding a proof is much harder than checking that a given candidate proof is valid. When attempting to argue 1. Introduction that a given program terminates, humans would look for Software is a complex artefact. Programming is prone to decreasing patterns among the variables over fictional runs error and some bugs are hard to find even after extensive of the program. Then, they would guess a ranking function arXiv:2102.03824v1 [cs.LG] 7 Feb 2021 testing. Bugs may cause crashes, undesirable outputs, but that fits these patterns. also may prevent a program from responding at all. Termi- Our procedure imitates the human approach. We take a nation analysis addresses the question of whether, for every program as input and proceed in three steps (see Fig.1). possible input, a program halts. This is unsolvable in gen- First, we sample multiple inputs for the program and ex- eral, yet tools that work in practice have been developed by ecute it with each of these inputs. As the program runs, industry and academia (Cook et al., 2006a; Heizmann et al., we trace the values of its variables and collect the respec- 2013; Brockschmidt et al., 2016; Giesl et al., 2017; Le et al., tive sequences of valuations. Second, using a custom loss 2020). Previous tools exclusively rely on formal reasoning, function (see Sect.4), we train a neural network so that its and the use of machine learning for termination analysis is output decreases along these sequences. For programs with rare. In this paper, we introduce a novel technique that trains nested loops, we train it so that it descends a lexicographic neural networks to act as formal proofs of termination. order. We use a neural architecture that is naturally bounded All authors contributed equally 1Department of Computer Sci- from below, thus we obtain networks that act as ranking ence, University of Oxford 2Amazon, Inc. This work was done functions with respect to the sampled traces. Finally, we prior to joining Amazon. verify whether this candidate neural ranking function also Neural Termination Analysis 100 1 Iterator<Integer> i = list.iterator(); 2 while (i.hasNext()) { 50 3 Integer e = i.next(); list.size 4 if (e < 0) 0 i.nextIndex 5 i.remove(); e −50 6 } 0 20 40 60 80 Figure 2: Program removing the negative elements of a list. Figure 3: Execution trace for the program in Fig.2. decreases along every possible execution. To this end, we We obtain multiple sequences of n-dimensional vectors of SMT solve over a symbolic encoding of the program. Upon values, where n is the number of traced variables. For an affirmative verification result, our procedure concludes presentation, we select three key variables along one trace, that the program terminates for every possible input. list.size, i.nextIndex, and e, and plot them in Fig.3. Note Learning candidate ranking functions from execution traces that this is a real trace, and these member variables appear is agnostic with respect to the programming language. Our in the current implementation of java.util.LinkedList’s 1 method requires no information about the program other iterator in OpenJDK . than the traces to form the loss function. It thus applies To learn a neural ranking function for this example, we without modifications to a broad variety of programs, rang- employ the simple neural network realising the function ing from toy examples that manipulate numerical counters to software that uses data structures. We implemented a fθ(x) = ReLU(w1 · list:size + ··· + wn · e); (1) prototype analyser for Java bytecode. Using a neural archi- x = ( : ;:::; ) 2 n tecture with one hidden layer and a straight-forward training where the input list size e R is a θ = routine, our method discovered ranking functions for 47% vector of variables valuations, and the parameter (w ; : : : ; w ) 2 n of the benchmarks in a standard problem set for termination 1 n R is a vector of learnable weights. This is n analysis (Giesl et al., 2019; Beyer, 2020). Moreover, it is a neural network with input neurons, one output neuron able to discover ranking functions for programs that use with ReLU activation function, and no hidden layers. The heap-allocated data structures such as linked lists. input neurons are fully connected to the output neuron. This function has a lower bound (zero) and is thus bounded from Methods for learning termination arguments from traces below. The final step to obtain a candidate ranking func- have been studied before using automata and template ex- tion is to learn a parameter θ so that fθ decreases along all pressions as learning models (Lee et al., 2012; Nori & sampled execution traces. Sharma, 2013; Heizmann et al., 2014; Urban et al., 2016). Recently, neural networks have been used for discovering We train the parameters of this neural network so that its δ > 0 loop invariants (Si et al., 2018). Also, they have been ap- output value decreases by after every consecutive plied to the stability analysis of dynamical systems (Chang pair of program states. For this purpose, we collect all (x; y) 2 n × n y et al., 2019; Abate et al., 2021). Our method builds upon all pairs R R such that appears immediately x these ideas and, for the first time, neural networks are used after in some trace. This results in the dataset of pairs f(x(i); y(i))gk for termination analysis. i=1. To train our neural network, we solve the minimisation problem k 2. Illustrative Example 1 X (i) (i) arg min maxffθ(y ) − fθ(x ) + δ; 0g (2) n k The reason why a program terminates can be subtle, and θ2R i=1 the Java program in Fig.2 is an exemplar. This program using standard optimisation algorithms. Provided that the operates on a list, which implies that the termination analysis traces are well sampled, the optimal parameter θ? yields the requires reasoning about the heap. However, there is a function termination argument that only uses integer sequences. This is hidden within the implementation but can be spotted by fθ? (x) = ReLU(list:size − i:nextIndex); (3) examining the traces we obtain when running the program. after an appropriate filtering of the numerical noise in θ?. We create a variety of lists with random length and random The formal verifier confirms that fθ? is a valid ranking func- elements and, using each of them as input, perform multiple tion for the program in Fig.2. Thus this program terminates runs of the program. We record the values of all integer vari- for every possible input list. ables that appear in the program, including object members, 1 every time the program reaches line 2 (the loop header). https://github.com/openjdk/jdk Neural Termination Analysis L1 1 while (i < k) 1 while (i > k) iload_0 1 while (i < k) { _ if icmpge L6 iload_2 2 2 L6 L2 i++; i++; 2 j = 0; iconst_0 istore_1 (a) (b) 3 while (j < i) { L3 iload_1 4 j++; iload_0 L4 Figure 4: Terminating and non-terminating programs. iinc 1,1 5 } if_icmpge L5 goto L3 L5 6 i++; iinc 0,1 7 } goto L1 By examining the numerical data in the execution traces our (a) (b) method can discover termination arguments for programs that use data structures in the same manner as for numerical Figure 5: Program with nested counting and its CFG. programs. For many practical problems, this implies that we do not require any heap-specific reasoning machinery. rational numbers with a minimum, but can also be maps to 3. Termination Analysis tuples with lower-bounded lexicographic orders. Programs and Transition Systems A computer program Our program model can be seen as the operational semantics is a list of instructions that, together with the machine in- of an imperative programming language, where every state terpreting them, defines a state transition system over the is associated to a control location (by the program counter) state space of the machine.