<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>LibPoly: A Library for Reasoning about Polynomials</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Dejan Jovanovic</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Bruno Dutertre</string-name>
        </contrib>
      </contrib-group>
      <abstract>
        <p>LibPoly is a C library for computing with polynomials. It provides data structures to represent multivariate polynomials, and algorithms ranging from simple arithmetic and GCD computation, to root isolation and computation with algebraic numbers. The goal of the library is to be simple and extensible, and it is targeting tools that reason in nonlinear arithmetic. LibPoly is already successfully used in the Yices 2 nonlinear arithmetic solver. The library is freely available under a permissive open-source license. We present the basic functionality of LibPoly through the Python interface, and we describe a simple implementation of a classical cylindrical algebraic decomposition algorithm.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <p>The interface to the library is designed to support both the traditional, purely symbolic
algorithms, and the more recent model-driven methods. Therefore, LibPoly supports operations
not usually considered in traditional symbolic computer algebra systems, such as a variable
order that can change freely between various operations.</p>
      <p>
        To present the functionality of LibPoly, we go through a simple implementation of a
cylindrical algebraic decomposition (CAD) algorithm [
        <xref ref-type="bibr" rid="ref4 ref8">7</xref>
        ] using the Python API to LibPoly.2
We then discuss current status and future plans. We present the basic functionalities that
are needed for implementing a CAD-based reasoning system, but the library supports more
advanced features, such as computing with polynomial over modular arithmetic,
2
      </p>
    </sec>
    <sec id="sec-2">
      <title>Usage and Examples</title>
      <p>We will go through a Python implementation of the CAD construction algorithm by relying on
LibPoly's Python bindings. We rst demonstrate the basics of polynomial construction and
manipulation. Then we show how to isolate and manipulate roots of univariate polynomials
and construct the sign table of a univariate polynomial. Finally, we extend the sign-table
construction to the multivariate case, by relying on CAD projections, resulting in a simple
implementation of CAD construction.3
2.1</p>
      <sec id="sec-2-1">
        <title>Basic Operations</title>
        <p>Variables. A variable in LibPoly is an object representing real-valued variables. Internally,
it has an associated printable name and a unique numerical ID. The following example imports
the LibPoly library in Python and creates three variables x, y, and z.
1 import polypy # Import the library
2 x = polypy . Variable ( 'x ') # Variable x
3 [y , z] = [ polypy . Variable (s) for s in [ 'y ', 'z ']] # Variables y and z</p>
        <p>Variable Order. An important feature of LibPoly is a exible order over the variables. By
default, variables are ordered by numerical ID's (i.e., in order of creation), but this order can
be changed dynamically. The order is updated by manipulating the order list that changes the
variable order according to the following semantics:
variables in the order list are smaller than the variables not in the order list;
variables in the order list are ordered according to the list order; and
variables not in the order list are ordered according to their numerical ID's.</p>
        <p>The following example illustrates the order manipulation.
1 order = polypy . variable_order # order = [] , x &lt; y &lt; z
2 order . push (z) # order = [z] , z &lt; x &lt; y
3 order . push (y) # order = [z , y], z &lt; y &lt; x
4 order . pop () # order = [z] , z &lt; x &lt; y
5 order . push (x) # order = [z , x], z &lt; x &lt; y</p>
        <p>2The presentation focuses on the Python API for clarity, but the library is implemented in C and provides
a C API with equivalent functionality.</p>
        <p>3Complete examples are available at https://github.com/SRI-CSL/libpoly/tree/master/examples.
Polynomials. Polynomials in LibPoly always have integer coe cients. They can be
created and combined using the standard Python arithmetic operators over variables and integer
constants. The following example creates two polynomials f = (x2 2x + 1)(x2 2) and
g = z(x2 y2).
1 f = (x **2 - 2* x + 1) *( x **2 - 2) # Univariate polynomial
2 g = z *( x **2 - y **2) # Multivariate polynomial</p>
        <p>The internal representation of polynomials is recursive: a polynomial is a list of coe cients in
its topmost variable, where each coe cient is a polynomial in the remaining variables. This
representation is updated dynamically to respect the variable order. For example, if the variable
order is x &lt; y &lt; z, then g is a polynomial in Z[x; y; z], with z as top variable. Therefore, g is
represented as g = ( y2 + x2) z. On the other hand, if the variable order is z &lt; y &lt; x, then x
is the top variable, and g = z x2 + ( z) y2.
1 order . set ([x , y , z ]) # z is the top variable , i.e. g in Z[x ,y ,z]
2 print g # Out : ( -1* y **2 + (1* x **2) )*z
3 order . set ([z , y ]) # x is the top variable , i.e. g in Z[z ,y ,x]
4 print g # Out : (1* z)*x **2 + (( -1* z)*y **2)</p>
        <p>Several operations give access to this recursive structure: The var() method returns the top
variable of the polynomial in the current order, the degree() method returns the degree of the
polynomial in its top variables, and the coefficients() method returns the list of polynomial
coe cients with respect to its top variable (in decreasing degree order). The derivative
() method computes the derivative of the polynomial with respect to its top variable. The
factor_square_free() method returns a factorization of the polynomial where no factor is a
square and the factors are pairwise co-prime.4
1 g. var () # Out : Variable ('x ')
2 g. degree () # Out : 2
3 g. coefficients () # Out : [( -1* z)*y **2 , 0, 1* z]
4 g. derivative () # Out : (2* z)*x
5 f. factor_square_free () # Out : [(1* x **2 - 2, 1) , (1* x - 1, 2) ]
6 g. factor_square_free () # Out : [(1*z , 1) , (1* x **2 + ( -1* y **2) , 1) ]</p>
        <p>In the example above, f is factored (over Z) into irreducible polynomials (x2 2)(x
polynomial g is factored into g = z:(x2 y2). This is not a full factorization as (x2
be further decomposed but the factorization is square free.
1)2. The
y2) could
2.2</p>
      </sec>
      <sec id="sec-2-2">
        <title>Constructing a Sign Table</title>
        <p>
          Root Isolation. When analyzing the behavior of a polynomial f 2 Z[~x; y], the basic operation
is nding the roots of f . A root of f , given an assignment of variables ~x to values ~a, is a
value b such that f (~a; b) = 0. The ordered list of roots of f can be obtained by calling the
roots_isolate() method on the polynomial f .
1 m = polypy . Assignment ()
2 r = f. roots_isolate (m)
3 print r [0] # Out : &lt;1*x **2 + ( -2) , ( -3/2 , -5/4) &gt;
4 print r [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ] # Out : 1
5 print r [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ] # Out : &lt;1*x **2 + ( -2) , (5/4 , 3/2) &gt;
        </p>
        <p>In the example above, we rst create an empty Assignment object, and then obtain the roots
of f = (x2 2)(x 1) 2 Z[x]. The result is the list p2; 1; p2 . LibPoly displays p2 and
p2 as algebraic numbers as explained in the following paragraph.</p>
        <p>
          4This is not a full factorization, but it is su cient for most purposes where factoring is useful. Complete
factorization, although potentially useful, is not necessary for CAD and is currently not available in LibPoly.
Working with Values. The real values (including roots) in LibPoly are represented as value
objects and are either integers, dyadic rationals5, or algebraic numbers such as p2. Algebraic
numbers are represented symbolically as pairs hf; Ii, where f is a univariate polynomial f , and
I is an real interval in which f has a unique root. The algebraic number hf; Ii is the root of f
that occurs in interval I. In the previous example, the algebraic number p2 is represented as
the pair hx2 2; ( 45 ; 32 )i.
1 r [0]. to_double () # Out : -1.41421356237
2 r [0] &lt; r [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ] # Out : True
3 r [0]. get_value_between (r [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ]) # Out : 0
4 m. set_value (x , 0) # Set x -&gt; 0
5 f. sgn (m) # Out : -1
6 m. set_value (x , r [0]) # Set x -&gt; -sqrt (2)
7 f. sgn (m) # Out : 0
        </p>
        <p>The snippet above illustrates the basic operations on real values. Real values can be
converted to oating point with the to_double() method, and they can be compared to each
other with the usual comparison operators in Python. Given two values v1 and v2, method
get_value_between() returns the a value in the interval (v1; v2). The method picks the
\simplest" possible value, namely a dyadic rational in the interval with the smallest value of m.
In particular, the method will return an integer if one exists in (v1; v2). Method set_value()
assigns a value to a variable, while unset_value() clears the value. Method sgn() computes
the sign of a polynomial at a point given by a full assignment.</p>
        <p>Constructing a Sign Table. We now have all the ingredients to compute sign tables of
univariate polynomials. For a set of univariate polynomials F a sign table of F is a
decomposition of R into intervals I1; : : : ; In, such that, in each interval Ik, the polynomials in F are
sign-invariant on Ik (i.e., they don't change sign). To construct a sign table of F , we rst
isolate the roots of all f 2 F , then we sort the computed roots by increasing value, and, nally,
we evaluate the sign of the polynomials in the intervals delimited by the roots. In each such
interval, Ik, the polynomials of F do not change sign, so we can evaluate the sign of each f 2 F
on Ik by evaluating the sign of f at a single evaluation point of Ik.</p>
        <p>A Python function that constructs a sign table using LibPoly is presented in Figure 1.
Applying this function to polynomials f = x2 2 and g = x2 3 will result in a sign table that
resembles the following.</p>
        <p>f
g
( 1;
1
1
p3)
p3</p>
        <p>In the univariate case, building a sign table is a complete method for determining if a set of
polynomial constraints has a solution. For example, we can solve the constraint (f &gt; 0)^(g &lt; 0)
by examining the sign table. It is clear that the solutions are in the set ( p3; p2) [ (p2; p3).
Moreover, in order to perform such an analysis, we only need to keep track of one evaluation
point per interval. Figure 2 plots the two polynomials f and g of our example, and shows the
evaluation points (red dots).
2.3</p>
      </sec>
      <sec id="sec-2-3">
        <title>Cylindrical Algebraic Decomposition</title>
        <p>A sign table that we computed in the previous section decomposes R into nitely many regions.
Each region is either an open interval or a point, and in each region, the polynomials of F are</p>
        <p>5Rationals of the form 2nm .
1 def sign_table (x , polys , m):
2 # Get the roots and print the header
3 roots = set () # Set of roots
4 output (" poly / int ")
5 for f in polys :
6 output (f)
7 f_roots = f.roots isolate(m)
8 roots . update ( f_roots )
9 stdout . write ("\n")
10 # Sort the roots and add infinities
11 roots = [ polypy . INFINITY_NEG ] + sorted(roots) + [ polypy . INFINITY_POS ]
12 # Print intervals and signs in the intervals
13 root_i , root_j = itertools . tee ( roots )
14 next ( root_j )
15 for r1 , r2 in itertools . izip ( root_i , root_j ):
16 output (( r1 . to_double () , r2 . to_double () ))
17 # The interval (r1 , r2 )
18 v = r1.get value between(r2);
using the Python built-in sorted() function that compares values using value comparison
functionality from LibPoly.
x**2 - 2
x**2 - 3
2
1
0
-1
-2
-3
-3
-2
-1
1
2</p>
        <p>
          3
0
x
sign-invariant. The sign table completely characterizes the behavior of F on R. A natural
question arises: can we extend the concept of sign table (with evaluation points) to the multivariate
case, so that we can solve polynomials constraints with several variables ? The answer to this
question is positive, and the generalization of sign tables to Rn is called cylindrical algebraic
decomposition (CAD) [
          <xref ref-type="bibr" rid="ref4 ref8">7</xref>
          ].
        </p>
        <p>CAD Lifting. A nave attempt at constructing a CAD (sign table) would be to extend the
sign-tabling as follows. Let F Z[x1; : : : ; xn] be a set of polynomials. We partition F according
to the top variable of each polynomial:</p>
        <p>F = F1 [ F2 [
[ Fn :
Every polynomial f 2 Fk contains only variables x1; : : : ; xk, and xk is the top variable of f .
With this setup, we can directly extend the sign_table() function of Figure 1 into a recursive
procedure that builds the CAD of F one variable at a time. We do so by building a sign table
T1 for polynomials in F1. Then, for each evaluation point in T1, we build a sign table T ;2
for polynomials in F2, and so on. In CAD terminology this procedure is called lifting.</p>
        <p>The function lift() from Figure 3 takes as input a map poly_map that maps xk to Fk as
above, and a list vars of variables [x1; : : : ; xn]. The function outputs the computed evaluation
points. It shouldn't be too hard to see that this lifting procedure on its own does not produce
1.5
0.5
2
1
0
-0.5
-1.5
-1
-2
y
1</p>
        <p>1
lift x1: Since F1 is empty, the set of roots for x1 is also empty, and we can choose any value in
( 1; +1) as evaluation point for x1. For example, let x1 7! 2 be the evaluation point
for x1.
lift x2: F2 = ff g, and we search for the roots of the polynomial f when x1 7! 2. This amounts
for nding the roots of f (2; x2) = x22 + 3. Since this polynomial does not have roots in
x2, we can, as before, pick any evaluation point. We choose x2 7! 0.</p>
        <p>In the above example, the procedures computes a single evaluation point, namely, (x1; x2) =
(2; 0). At this point, f has positive sign/ This single evaluation point clearly does not capture
the behavior of f over R2, since f is not uniformly positive.</p>
        <p>
          CAD Projection. The above example shows that building sign tables variable by variable is
not in itself su cient to construct a proper sign-invariant decomposition for a set of polynomials
F . The problem lies in the fact that the lower-level polynomial sets Fk do not capture enough
information about the behavior of the whole set F , and the sign-tabling can miss important
evaluation points. We can x this, while keeping the same overall procedure, by adding carefully
crafted polynomials to the sets Fk. These additional polynomials will \guide" the construction
of sign tables to cover all possible behaviors of the original set F . In the seminal paper on CAD
construction [
          <xref ref-type="bibr" rid="ref4 ref8">7</xref>
          ], George Collins showed how to do this completion, by projecting polynomials
from higher levels into the lower levels.
        </p>
        <p>De nition 2.1 (Collins Projection). Given a set of polynomials F
Z[~y; x], the Collins
projector operator Pc(F ; x) is de ned as
[</p>
        <p>coe (f; x) [
f2F
[
f2F
g2R (f;x)
psc(g; gx0; x) [</p>
        <p>psc(gi; gj ; x) :
[
i&lt;j
gi2R (fi;x)
gj2R (fj;x)</p>
        <p>
          The projection operator above, when applied to F , introduces enough additional
polynomials that capture the necessary missing behavior. The individual operations in Pc are advanced
polynomial operations (for more details see, e.g., [
          <xref ref-type="bibr" rid="ref3 ref7">3, 6</xref>
          ]), that are all available in LibPoly.
The set of coe cients coe (f; x) can be obtained with the coefficients() method, while the
derivative can be obtained with the derivative() method. A reductum6 R(f; x) of a
polynomial can be obtained using the reductum() method, and the principal subresultant coe cients
psc(f; g) of two polynomials can be obtained with the psc() method.
        </p>
        <p>Before de ning the projection function, we rst de ne two utility function. First, we de ne
a function that, given a polynomial f , returns all non-constant reductums of f in variable x.
1 # Returns reductum closure of f , excluding constants
2 def get_reductums (f , x):
3 R = []
4 while f.var() == x: R. append (f); f = f.reductum()
5 return R</p>
        <p>Additionally, instead of adding polynomials directly to the sets Fk, we will add them trough
the following proxy function that performs factorization rst. The square-free factorization
simpli es the polynomials and ensures that some unnecessary complexity is removed.
We are now ready to de ne our overall projection function project(). This function projects
the sets Fn; : : : ; F1 in sequence by applying the projection operator Pc to each of them.
1 # Add polynomials to projection map
2 def add_polynomial ( poly_map , f):
3 # Factor the polynomial f
4 for ( f_factor , multiplicity ) in f.factor square free():
# Add non - constant polynomials to poly_map
if (f factor.degree() &gt; 0) :
x = f factor.var()
if (x not in poly_map ): poly_map [x] = set ()
poly_map [x ]. add ( f_factor )
# Add a collection of polynomials to projection map
def add_polynomials ( poly_map , polys ):</p>
        <p>
          for f in polys : add_polynomial ( poly_map , f)
1 # Project : go down the variable stack and project
2 def project ( poly_map , vars ):
3 for x in reversed ( vars ):
4 # Project variable x
5 x_polys = poly_map [x]
6 # [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ] coeff (f) for f in poly [x]
7 for f in x_polys :
8 add_polynomials ( poly_map , f.coefficients())
9 # [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ] psc (g , g ') for f in poly [x], g in R(f , x)
10 for f in x_polys :
11 for g in get_reductums (f , x):
12 g_d = f.derivative()
13 if ( g_d . var () == x):
14 add_polynomials ( poly_map , g.psc(g d))
# [
          <xref ref-type="bibr" rid="ref3">3</xref>
          ] psc (g1 , g2 ) for f1 , f2 in poly [x], g1 in R(f1 , x) , g2 in R(f2 , x)
for (f1 , f2 ) in itertools . combinations ( x_polys , 2) :
f1_R = get_reductums (f1 , x)
f2_R = get_reductums (f2 , x)
6Reductum of a polynomial f is f without its highest-degree term.
19
20
for (g1 , g2 ) in itertools . product ( f1_R , f2_R ):
        </p>
        <p>add_polynomial ( poly_map , g1.psc(g2))
eAxpapmlypilneg, rtehseultpsroinjeFctb(e)infguenncltaiorgnedtotothFe =poflyxn21om1i;axl21s+etxF22 =1gf.xT12h+e xn22ewly1ga,ddfreodmpothlyenofamilieadl
adds two critical roots to the sign table of x1, which allows the lifting to succeed in CAD
construction.</p>
        <p>CAD Construction. All the tools are now in place for a full CAD construction. The main
CAD construction routine cad() takes a list of polynomials and outputs the evaluation points
corresponding to the CAD of the polynomials. The CAD is constructed by rst projecting the
input polynomials, and then constructing the CAD evaluation points over the projects set using
the lifting procedure.
1 # Run the CAD construction
2 def cad ( polys , vars ):
3 polypy . variable_order . set ( vars )
4 poly_map = {}
5 add_polynomials ( poly_map , polys )
6 project ( poly_map , vars )
7 lift ( poly_map , vars )</p>
        <p>Applying the procedure above on our example set F = fx2 + y2
points depicted in Figure 4.
1g results in the evaluation
3</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Current Status and Plans for Further Development</title>
      <p>
        LibPoly is freely available on GitHub7 under the LGPL license, with more information
available at the LibPoly web page.8 The implementation is about 15KLOC of C code, with the
only external dependency being the widely used GMP library [
        <xref ref-type="bibr" rid="ref19">18</xref>
        ]. The library is stable and
is currently used successfully in the yices2 [
        <xref ref-type="bibr" rid="ref17">16</xref>
        ] SMT solver to back the nonlinear reasoning
capabilities through the native C API (see e.g. [
        <xref ref-type="bibr" rid="ref22">21</xref>
        ]).
      </p>
      <p>
        Although the library is e cient9, there are many parts of the library that could bene t
from algorithmic improvements or new features. For example, more e cient algorithms for
polynomial factorization and GCD computation, and more e cient computation with algebraic
numbers (and support of in nitesimal numbers [
        <xref ref-type="bibr" rid="ref14">13</xref>
        ]). As the library is open source, we invite
contributions and suggestions for future development at the LibPoly GitHub page.
      </p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>J.</given-names>
            <surname>Abbott</surname>
          </string-name>
          and
          <string-name>
            <given-names>A. M.</given-names>
            <surname>Bigatti</surname>
          </string-name>
          . CoCoALib: a C+
          <article-title>+ library for computations in commutative algebra... and beyond</article-title>
          .
          <source>In International Congress on Mathematical Software</source>
          , pages
          <volume>73</volume>
          {
          <fpage>76</fpage>
          . Springer,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>G.</given-names>
            <surname>Barthe</surname>
          </string-name>
          ,
          <string-name>
            <given-names>E.</given-names>
            <surname>Fagerholm</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Fiore</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Mitchell</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Scedrov</surname>
          </string-name>
          , and
          <string-name>
            <given-names>B.</given-names>
            <surname>Schmidt</surname>
          </string-name>
          .
          <article-title>Automated analysis of cryptographic assumptions in generic group models</article-title>
          .
          <source>In International Cryptology Conference</source>
          , pages
          <volume>95</volume>
          {
          <fpage>112</fpage>
          . Springer,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>S.</given-names>
            <surname>Basu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Pollack</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.-F.</given-names>
            <surname>Roy</surname>
          </string-name>
          .
          <article-title>Algorithms in real algebraic geometry</article-title>
          , volume
          <volume>20033</volume>
          . Springer,
          <year>1996</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          7https://github.com/SRI-CSL/libpoly 8http://sri-csl.
          <article-title>github.io/libpoly/ 9yices2 has won the nonlinear divisions (QF NRA, QF NIA) of the 2016 SMT competition</article-title>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>C.</given-names>
            <surname>Bauer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Frink</surname>
          </string-name>
          , and
          <string-name>
            <given-names>R.</given-names>
            <surname>Kreckel</surname>
          </string-name>
          .
          <article-title>Introduction to the GiNaC framework for symbolic computation within the C++ programming language</article-title>
          .
          <source>Journal of Symbolic Computation</source>
          ,
          <volume>33</volume>
          (
          <issue>1</issue>
          ):1{
          <fpage>12</fpage>
          ,
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [5]
          <string-name>
            <surname>C. W. Brown. QEPCAD</surname>
          </string-name>
          <article-title>B: a program for computing with semi-algebraic sets using CADs</article-title>
          .
          <source>ACM SIGSAM Bulletin</source>
          ,
          <volume>37</volume>
          (
          <issue>4</issue>
          ):
          <volume>97</volume>
          {
          <fpage>108</fpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>B.</given-names>
            <surname>Buchberger</surname>
          </string-name>
          , G. E. Collins,
          <string-name>
            <given-names>R.</given-names>
            <surname>Loos</surname>
          </string-name>
          , and R. Albrecht, editors.
          <source>Computer algebra. Symbolic and algebraic computation</source>
          . Springer,
          <year>1982</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>G. E.</given-names>
            <surname>Collins</surname>
          </string-name>
          .
          <article-title>Quanti er elimination for real closed elds by cylindrical algebraic decompostion</article-title>
          .
          <source>In Automata Theory and Formal Languages 2nd GI Conference Kaiserslautern, May</source>
          <volume>20</volume>
          {
          <fpage>23</fpage>
          ,
          <year>1975</year>
          , pages
          <fpage>134</fpage>
          {
          <fpage>183</fpage>
          . Springer,
          <year>1975</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>G. E.</given-names>
            <surname>Collins</surname>
          </string-name>
          .
          <source>History of SACLIB</source>
          .
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>G. E.</given-names>
            <surname>Collins</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Encarnacion</surname>
          </string-name>
          ,
          <string-name>
            <given-names>H.</given-names>
            <surname>Hong</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Johnson</surname>
          </string-name>
          , W. Krandick,
          <string-name>
            <given-names>A.</given-names>
            <surname>Mandache</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Neubacher</surname>
          </string-name>
          , and
          <string-name>
            <given-names>H.</given-names>
            <surname>Vielhaber</surname>
          </string-name>
          .
          <article-title>SACLIB user's guide</article-title>
          .
          <source>RISC Linz</source>
          , Johannes Kepler University, Linz,
          <year>1993</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>M. A.</given-names>
            <surname>Colon</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Sankaranarayanan</surname>
          </string-name>
          , and
          <string-name>
            <given-names>H. B.</given-names>
            <surname>Sipma</surname>
          </string-name>
          .
          <article-title>Linear invariant generation using non-linear constraint solving</article-title>
          .
          <source>In International Conference on Computer Aided Veri cation</source>
          , pages
          <volume>420</volume>
          {
          <fpage>432</fpage>
          . Springer,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>E.</given-names>
            <surname>Darulova</surname>
          </string-name>
          and
          <string-name>
            <given-names>V.</given-names>
            <surname>Kuncak</surname>
          </string-name>
          .
          <article-title>Sound compilation of reals</article-title>
          .
          <source>Acm Sigplan Notices</source>
          ,
          <volume>49</volume>
          (
          <issue>1</issue>
          ):
          <volume>235</volume>
          {
          <fpage>248</fpage>
          ,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [12]
          <string-name>
            <surname>L. De Moura</surname>
            and
            <given-names>N.</given-names>
          </string-name>
          <article-title>Bj rner. Satis ability modulo theories: introduction and applications</article-title>
          .
          <source>Communications of the ACM</source>
          ,
          <volume>54</volume>
          (
          <issue>9</issue>
          ):
          <volume>69</volume>
          {
          <fpage>77</fpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [13]
          <string-name>
            <surname>L. De Moura</surname>
            and
            <given-names>G. O.</given-names>
          </string-name>
          <string-name>
            <surname>Passmore</surname>
          </string-name>
          .
          <article-title>Computation in real closed in nitesimal and transcendental extensions of the rationals</article-title>
          .
          <source>In International Conference on Automated Deduction</source>
          , pages
          <volume>178</volume>
          {
          <fpage>192</fpage>
          . Springer,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>W.</given-names>
            <surname>Denman</surname>
          </string-name>
          and
          <string-name>
            <surname>C.</surname>
          </string-name>
          <article-title>Mun~oz. Automated real proving in pvs via metitarski</article-title>
          .
          <source>In International Symposium on Formal Methods</source>
          , pages
          <volume>194</volume>
          {
          <fpage>199</fpage>
          . Springer,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>A.</given-names>
            <surname>Dolzmann</surname>
          </string-name>
          and
          <string-name>
            <given-names>T.</given-names>
            <surname>Sturm</surname>
          </string-name>
          . Redlog:
          <article-title>Computer algebra meets computer logic</article-title>
          .
          <source>Acm Sigsam Bulletin</source>
          ,
          <volume>31</volume>
          (
          <issue>2</issue>
          ):2{
          <issue>9</issue>
          ,
          <year>1997</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [16]
          <string-name>
            <given-names>B.</given-names>
            <surname>Dutertre</surname>
          </string-name>
          .
          <article-title>Yices 2.2</article-title>
          . In International Conference on Computer Aided Veri cation, pages
          <volume>737</volume>
          {
          <fpage>744</fpage>
          . Springer,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [17] W. ecker, G.
          <string-name>
            <surname>-M. Greuel</surname>
            ,
            <given-names>G.</given-names>
          </string-name>
          <article-title>P ster, and</article-title>
          <string-name>
            <given-names>H.</given-names>
            <surname>Scho</surname>
          </string-name>
          <article-title>nemann. Singular 4-1-0 | A computer algebra system for polynomial computations</article-title>
          . http://www.singular.uni-kl.de,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>T.</given-names>
            <surname>Granlund</surname>
          </string-name>
          et al.
          <source>GNU MP 6.0 Multiple Precision Arithmetic Library</source>
          .
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>W.</given-names>
            <surname>Hart</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Johansson</surname>
          </string-name>
          , and
          <string-name>
            <given-names>S.</given-names>
            <surname>Pancratz</surname>
          </string-name>
          .
          <source>FLINT: Fast Library for Number Theory</source>
          ,
          <year>2016</year>
          . Version 2.4.0, http://flintlib.org.
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>X.</given-names>
            <surname>Huang</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Kwiatkowska</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Wang</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Wu</surname>
          </string-name>
          .
          <article-title>Safety veri cation of deep neural networks</article-title>
          .
          <source>arXiv preprint arXiv:1610.06940</source>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [21]
          <string-name>
            <given-names>D.</given-names>
            <surname>Jovanovic</surname>
          </string-name>
          .
          <article-title>Solving nonlinear integer arithmetic with MCSAT</article-title>
          .
          <source>In International Conference on Veri cation, Model Checking, and Abstract Interpretation</source>
          , pages
          <volume>330</volume>
          {
          <fpage>346</fpage>
          . Springer,
          <year>2017</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [22]
          <string-name>
            <given-names>D.</given-names>
            <surname>Jovanovic</surname>
          </string-name>
          and L. De Moura.
          <article-title>Solving non-linear arithmetic</article-title>
          .
          <source>In International Joint Conference on Automated Reasoning</source>
          , pages
          <volume>339</volume>
          {
          <fpage>354</fpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          [23]
          <string-name>
            <given-names>G.</given-names>
            <surname>Katz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Barrett</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Dill</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Julian</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Kochenderfer</surname>
          </string-name>
          . Reluplex:
          <article-title>An e cient smt solver for verifying deep neural networks</article-title>
          .
          <source>arXiv preprint arXiv:1702.01135</source>
          ,
          <year>2017</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref25">
        <mixed-citation>
          [24]
          <string-name>
            <given-names>J.</given-names>
            <surname>Leike</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Heizmann</surname>
          </string-name>
          .
          <article-title>Ranking templates for linear loops</article-title>
          .
          <source>In International Conference on Tools and Algorithms for the Construction and Analysis of Systems</source>
          , pages
          <fpage>172</fpage>
          {
          <fpage>186</fpage>
          . Springer,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref26">
        <mixed-citation>
          [25]
          <string-name>
            <given-names>J.</given-names>
            <surname>Leike</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Tiwari</surname>
          </string-name>
          .
          <article-title>Synthesis for polynomial lasso programs</article-title>
          .
          <source>In International Conference on Veri cation, Model Checking, and Abstract Interpretation</source>
          , pages
          <volume>434</volume>
          {
          <fpage>452</fpage>
          . Springer,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref27">
        <mixed-citation>
          [26] The PARI Group,
          <source>Univ. Bordeaux. PARI/GP version 2.9.0</source>
          ,
          <year>2016</year>
          . available from http://pari. math.u-bordeaux.fr/.
        </mixed-citation>
      </ref>
      <ref id="ref28">
        <mixed-citation>
          [27]
          <string-name>
            <given-names>A.</given-names>
            <surname>Platzer</surname>
          </string-name>
          ,
          <string-name>
            <surname>J.-D. Quesel</surname>
            , and
            <given-names>P.</given-names>
          </string-name>
          <string-name>
            <surname>Ru</surname>
          </string-name>
          <article-title>mmer. Real world veri cation</article-title>
          .
          <source>In International Conference on Automated Deduction</source>
          , pages
          <volume>485</volume>
          {
          <fpage>501</fpage>
          . Springer,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref29">
        <mixed-citation>
          [28]
          <string-name>
            <given-names>V.</given-names>
            <surname>Shoup</surname>
          </string-name>
          . NTL:
          <article-title>A library for doing number theory</article-title>
          ,
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>