Aligator.jl - A Julia Package for Loop Invariant Generation
aa r X i v : . [ c s . S C ] A ug Aligator.jl – A Julia Package for Loop InvariantGeneration ⋆ Andreas Humenberger , Maximilian Jaroschek , , and Laura Kov´acs , TU Wien [email protected] JKU Linz Chalmers
Abstract.
We describe the
Aligator.jl software package for automat-ically generating all polynomial invariants of the rich class of extendedP-solvable loops with nested conditionals.
Aligator.jl is written in theprogramming language Julia and is open-source.
Aligator.jl transformsprogram loops into a system of algebraic recurrences and implementstechniques from symbolic computation to solve recurrences, derive closedform solutions of loop variables and infer the ideal of polynomial invari-ants by variable elimination based on Gr¨obner basis computation.
In [2] we described an automated approach for generating loop invariants asa conjunction of polynomial equalities for a family of loops, called extendedP-solvable loops. For doing so, we abstract loops to a system of algebraic re-currences over the loop counter and program variables and compute polynomialequalities among loop variables from the closed form solutions of the recurrences.
Why Julia?
Our work was previously implemented in the
Aligator softwarepackage [4], within the Mathematica system [8]. While Mathematica provideshigh-speed implementations of symbolic computation techniques, it is a propri-etary software which is an obstacle for using
Aligator in applications of invariantgeneration. The fact that Mathematica provides no possibility to parse and mod-ify program code was also a reason to move to another environment. To make
Aligator better suited for program analysis, we decided to redesign
Aligator in the Julia programming language [3]. Julia provides a simple and efficient in-terface for calling C/C ++ and Python code. This allows us to resort to alreadyexisting computer algebra libraries, such as Singular [1] and SymPy [5]. Julia alsoprovides a built-in package manager that eases the use of other packages andenables others to use Julia packages, including our Aligator.jl tool. Before com-mitting to Julia, we also considered the computer algebra system SageMath [7] ⋆ All authors are supported by the ERC Starting Grant 2014 SYMCAR 639270. Wealso acknowledge funding from the Wallenberg Academy Fellowship 2014 TheProSE,the Swedish VR grant GenPro D0497701, and the Austrian FWF research projectsRiSE S11409-N23 and W1255-N23. Maximilian Jaroschek is also supported by theFWF project Y464-N18. nd an implementation directly in C/C ++ as options for redesigning Aligator .The former hosts its own Python version which makes the installation of otherPython packages (e.g. for parsing source code) tedious and error-prone. WhileC/C ++ is very efficient and provides a large ecosystem on existing libraries, de-veloping C/C ++ projects requires more effort than Julia packages. We thereforebelieve that Julia provides the perfect mix between efficiency, extensibility andconvenience in terms of programming and symbolic computations. Aligator.jl . This paper overviews
Aligator.jl and details its main components.The code of
Aligator.jl is available open-source at: https://github.com/ahumenberger/Aligator.jl .All together,
Aligator.jl consists of about 1250 lines of Julia code. We evalu-ated
Aligator.jl on challenging benchmarks on invariant generation. Our ex-perimental results are available at the above mentioned link and demonstratethe efficiency of
Aligator.jl . Contributions.
Our new tool
Aligator.jl significantly extends and improvesthe existing software package
Aligator as follows: – Unlike
Aligator , Aligator.jl is open-source and easy to integrate into othersoftware packages. – Aligator.jl implements symbolic computation techniques directly in Juliafor extracting and solving recurrences and generates polynomial dependen-cies among exponential sequences. – Contrarily to
Aligator , Aligator.jl handles not only linear recurrences withconstant coefficients, called C-finite recurrences. Rather,
Aligator.jl alsosupports hypergeometric sequences and sums and term-wise products of C-finite and hypergeometric recurrences [2]. – Aligator.jl is complete. That is, a finite basis of the polynomial invariantideal is always computed.
Aligator.jl computes polynomial invariants of so-called extended P-solvableloops [2]. Loop guards and test conditions are ignored in such loops and denotedby . . . or true , yielding non-deterministic loops with sequencing and condition-als. Program variables V = { v , . . . , v m } of extended P-solvable loops have nu-meric values, abstracted to be rational numbers. The assignments of extended P-solvable loops are of the form v i := P mj =0 c i v j + c m +1 with constants c , . . . , c m +1 ,or v i := r ( n ) v i , where r ( n ) is a rational function in the loop counter n . We givean example of an extended P-solvable loops in Figure 1.In correspondence to V, the initial values of the variables are given by the set V := { v (0) , . . . , v m (0) } ; that is, v i (0) is the initial value of v i . In what follows,we consider V and V fixed and state all definitions relative to them. Givenan extended P-solvable loop as input, Aligator.jl generates all its polynomialquality invariants. By a polynomial equality invariant, in the sequel simplypolynomial invariant, we mean the equality: p ( v , . . . , v m , v (0) , . . . , v m (0)) = 0 , (1)where p is a polynomial in V ∪ V with rational number coefficients. In whatfollows, we also refer to the polynomial p in (1) as a polynomial invariant. For n ∈ N \ { } and a loop variable v i , we write v i ( n ) to denote the value of v i afterthe n th loop iteration. As (1) is a loop invariant, we have: p ( v ( n ) , . . . , v m ( n ) , v (0) , . . . , v m (0)) = 0 for n > . As shown in [6,2], the set of polynomial while . . . doif . . . then r := r − v ; v := v + 2 else r := r + u ; u := u + 2 end ifend while Fig. 1: An extended P-solvableloop. invariants in V , w.r.t. the initial values V ,forms a polynomial ideal, called the poly-nomial invariant ideal. Given an extendedP-solvable loop, Aligator.jl computes all its polynomial invariants as it computes abasis of the polynomial invariant ideal, afinite set of polynomials { b , . . . , b k } . Anypolynomial invariant can be written as alinear combination p b + · · · + p k b k forsome polynomials p , . . . , p k . Aligator.jl
Inputs to
Aligator.jl are extended P-solvable loops and are fed to
Aligator.jl as String in the Julia syntax. We illustrate the use of
Aligator.jl on our examplefrom Figure 1:
Example 1.
Figure 1 is specified as a Julia string as follows: julia> loopstr = """while trueif truer = r - v; v = v + 2elser = r + u; u = u + 2endend"""
Polynomial loop invariants are inferred using
Aligator.jl by calling the function aligator(str::String) with a string input containing the loop as its argument. julia> aligator(loopstr)Singular Ideal over Singular Polynomial Ring (QQ),(r_0,v_0,u_0,r,v,u)with generators (v_0^2-u_0^2-v^2+u^2+4*r_0-2*v_0+2*u_0-4*r+2*v-2*u) he result of
Aligator.jl is a Gr¨obner basis of the polynomial invariant ideal. Itis represented as an object of type
Singular.sideal that is defined in the Singularpackage. For Figure 1,
Aligator.jl reports that the polynomial invariant ideal isgenerated by the polynomial invariant { v − u − v + u + 4 r − v + 2 u − r +2 v − u = 0 } in variables r , v , u , r, v, u , where r , v , u denote respectivelythe initial values of r, v, u .We now overview the main parts of Aligator.jl : (i) extraction of recurrenceequations, (ii) recurrence solving and (iii) computing the polynomial invariantideal.
Extraction of Recurrences.
Given an extended P-solvable loop as a Juliastring,
Aligator.jl creates the abstract syntax tree of this loop. This tree isthen traversed in order to extract loop paths (in case of a multi-path loop) andthe corresponding loop assignments. The resulting structure is then flattened inorder to get a loop with just one layer of nested loops. Within
Aligator.jl this isobtained via the method extract_loop(str::String) . As a result, the extractedrecurrences are represented in
Aligator by an object of type
Aligator.MultiLoop ,in case the input is a multi-path loop; otherwise, the returned object is of type
Aligator.SingleLoop . Example 2.
Using Example 1,
Aligator.jl derives the loop and its correspondingsystems of recurrences: julia> loop = extract_loop(loopstr)2-element Aligator.MultiLoop:[r(n1+1) = r(n1) - v(n1), v(n1+1) = v(n1) + 2, u(n1+1) = u(n1)][r(n2+1) = r(n2) + u(n2), u(n2+1) = u(n2) + 2, v(n2+1) = v(n2)]
As loop paths are translated into single-path loops,
Aligator.jl introduces aloop counter for each path and computes the recurrence equations of the loopvariables r, v, u with respect to the loop counters n and n . Recurrence Solving.
For each single-path loop, its system of recurrencesis solved.
Aligator.jl performs various simplifications on the extracted recur-rences, for example by eliminating cyclic dependencies introduced by auxiliaryvariables and uncoupling mutually dependent recurrences. The resulting, simpli-fied recurrences represent sums and term-wise products of C-finite or hyperge-ometric sequences.
Aligator.jl computes closed forms solutions of such recur-rences by calling the method closed_forms and using the symbolic manipulationcapabilities of
SymPy.jl : Example 3.
For Example 2, we get the following systems of closed forms: julia> cforms = closed_forms(loop)2-element Array{Aligator.ClosedFormSystem,1}:[v(n1) = 2*n1+v(0), u(n1) = u(0), r(n1) = -n1^2-n1*(v(0)-1)+r(0)][u(n2) = 2*n2+u(0), v(n2) = v(0), r(n2) = n2^2+n2*(u(0)-1)+r(0)]
The returned value is an array of type
Aligator.ClosedFormSystem . nvariant Ideal Computation. Using the closed form solutions for (each)single-path loop,
Aligator.jl next derives a basis of the polynomial invariantideal of the (multi-path) extended P-solvable loop. To this end,
Aligator.jl usesthe
Singular.jl package for Gr¨obner basis computations in order to eliminatevariables in the loop counter(s) from the system of closed forms. For multi-pathloops,
Aligator.jl relies on iterative Gr¨obner basis computations until a fixedpoint is derived representing a Gr¨obner basis of the polynomial invariant ideal– see [2] for theoretical details.Computing polynomial invariants within
Aligator.jl is performed by thefunction invariants(cforms::Array{ClosedFormSystem,1}) . The result is an ob-ject of type
Singular.sideal and represents a Gr¨obner basis of the polynomialinvariant ideal in the loop variables.
Example 4.
For Example 3,
Aligator.jl generates the following Gr¨obner basis,as already described on page 4: julia> ideal = invariants(cforms)Singular Ideal over Singular Polynomial Ring (QQ),(r_0,v_0,u_0,r,v,u)with generators (v_0^2-u_0^2-v^2+u^2+4*r_0-2*v_0+2*u_0-4*r+2*v-2*u)
Our approach to invariant generation was shown to outperform state-of-the-art tools on invariant generation for multi-path loops with polynomial arith-metic [2]. In this section we focus on the performance of our new implementationin
Aligator.jl and compare results to
Aligator [4]. In our experiments, we usedbenchmarks from [2]. Our experiments were performed on a machine with a 2.9GHz Intel Core i5 and 16 GB LPDDR3 RAM. When using
Aligator.jl , theinvariant ideal computed by
Aligator.jl was non-empty for each example; thatis, for each example we were able to find non-trivial invariants.Tables (1a) and (1b) show the results for a set of single- and multi-pathloops respectively. In both tables the first column shows the name of the instance,whereas columns two and three depict the running times (in seconds) of
Aligator and
Aligator.jl , respectively.By design,
Aligator.jl is at least as strong as
Aligator concerning the qual-ity of the output. When it comes to efficiency though, we note that
Aligator.jl is slower than
Aligator . We expected this result as
Aligator uses the highly opti-mized algorithms of Mathematica. When taking a closer look at how much timeis spent in the different parts of
Aligator.jl , we observed that the most time in
Aligator.jl is consumed by symbolic manipulations. Experiments indicate thatwe can improve the performance of
Aligator.jl considerably by using the Juliapackage
SymEngine.jl instead of
SymPy.jl . We believe that our initial experi-ments with
Aligator.jl are promising and demonstrate the use of our efforts inmaking our invariant generation open-source. able 1: Experimental evaluation of
Aligator.jl .(a)
Single-path
Aligator Aligator.jlcohencu .
072 2 . freire1 .
016 1 . freire2 .
062 2 . petter1 .
015 0 . petter2 .
026 1 . petter3 .
035 2 . petter4 .
042 3 .
620 (b)
Multi-path
Aligator Aligator.jldivbin .
134 1 . euclidex .
433 3 . fermat .
045 2 . knuth .
791 12 . lcm .
051 2 . mannadiv .
022 1 . wensley .
124 1 . We introduced the new package
Aligator.jl for loop invariant generation in theprogramming language Julia. Our
Aligator.jl tool is an open-source softwarepackage for invariant generation using symbolic computation and can easily beintegrated with other libraries and tools.
References
1. Decker, W., Greuel, G.M., Pfister, G., Sch¨onemann, H.:
Singular (2016)2. Humenberger, A., Jaroschek, M., Kov´acs, L.: Invariant Generation forMulti-Path Loops with Polynomial Assignments. In: VMCAI. LectureNotes in Computer Science, vol. 10747, pp. 226–246. Springer (2018).https://doi.org/10.1007/978-3-319-73721-8 113. Julia: https://julialang.org/4. Kov´acs, L.: Aligator: A Mathematica Package for Invariant Generation (SystemDescription). In: IJCAR. Lecture Notes in Computer Science, vol. 5195, pp. 275–282. Springer (2008)5. Meurer, A., Smith, C.P., Paprocki, M., ˇCert´ık, O., Kirpichev, S.B., Rocklin, M.,Kumar, A., Ivanov, S., Moore, J.K., Singh, S., Rathnayake, T., Vig, S., Granger,B.E., Muller, R.P., Bonazzi, F., Gupta, H., Vats, S., Johansson, F., Pedregosa, F.,Curry, M.J., Terrel, A.R., Rouˇcka, v., Saboo, A., Fernando, I., Kulal, S., Cimrman,R., Scopatz, A.: SymPy: symbolic computing in Python. PeerJ Computer Science , e103 (2017). https://doi.org/10.7717/peerj-cs.1036. Rodr´ıguez-Carbonell, E., Kapur, D.: Generating all polynomial invariantsin simple loops. Journal of Symbolic Computation