| CARVIEW |
Select Language
HTTP/2 200
server: GitHub.com
content-type: application/xml
last-modified: Tue, 16 Dec 2025 13:49:46 GMT
access-control-allow-origin: *
etag: W/"6941637a-1fb38"
expires: Mon, 29 Dec 2025 08:44:49 GMT
cache-control: max-age=600
content-encoding: gzip
x-proxy-cache: MISS
x-github-request-id: E252:1F53DD:886A77:99429D:69523D28
accept-ranges: bytes
age: 0
date: Mon, 29 Dec 2025 08:34:49 GMT
via: 1.1 varnish
x-served-by: cache-bom-vanm7210081-BOM
x-cache: MISS
x-cache-hits: 0
x-timer: S1766997289.068209,VS0,VE222
vary: Accept-Encoding
x-fastly-request-id: faa5f4f5462305683638cd375e1f56b389e3ce45
content-length: 17959
Leonardo de Moura
Leonardo de Moura's blog
https://leodemoura.github.io
-
Nightly builds for Z3
<h1 id="nightly-builds-for-z3">Nightly builds for Z3</h1>
<p>We are now providing Z3 nightly builds for all major platforms (Windows, OSX, Linux and FreeBSD).
<a href="https://research.microsoft.com/en-us/people/cwinter/">Christoph Wintersteiger</a> and I implemented a new infrastructure that automatically builds and tests Z3 every night.
If it passes the tests, we upload the compiled binaries to <a href="https://z3.codeplex.com">codeplex</a>.
This feature is useful for users that found bugs, and do not want to wait the next official release.
So far, these users would have to download the source code from the <a href="https://z3.codeplex.com/SourceControl/list/changesets?branch=unstable">“work-in-progress” branch</a> and build Z3 themselves.
Note that these nightly builds are <strong>not</strong> official releases.
They are built using the <a href="https://z3.codeplex.com/SourceControl/list/changesets?branch=unstable">“work-in-progress” branch</a>, but our infrastructure only uploads them if they pass the basic set of regression tests we have.
Since they are not official releases, we include the <a href="https://www.git-scm.com/book/en/Git-Basics-Viewing-the-Commit-History">git hash</a> associated with the commit we used to build the binaries.
That is why the zip files have funny names such as <em>z3-4.3.2.5e72cf0123f6-x64-osx-10.8.2.zip</em>. The value <em>5e72cf0123f6</em> is the first 12 digits of the git hash. The hash is also embedded in the z3 executable. We can retrieve it by executing <code class="language-plaintext highlighter-rouge">z3 -h</code>. Users using nightly builds should include this hash when reporting bugs and/or problems. Given a hash such as <em>5e72cf0123f6</em>, we can use the command <code class="language-plaintext highlighter-rouge">git checkout 5e72cf0123f6</code> to retrieve the source code.</p>
<p>Here are the instructions for downloading a nightly build</p>
<ul>
<li>Go to the <a href="https://z3.codeplex.com/releases">Z3 Downloads page</a></li>
<li>Click the <strong>Planned</strong> link</li>
</ul>
<p><img src="https://leodemoura.github.io/images/z3-planned.png" /></p>
<p>We provide pre-compiled binaries for the following platforms:</p>
<ul>
<li>Windows 32 and 64 bit (Windows 7 and 8)</li>
<li>OSX (version 10.8.2)</li>
<li>Linux Ubuntu 32 and 64 bit (version 12.04)</li>
<li>Linux Debian 64 bit (version 6.0.6)</li>
<li>FreeBSD 64 bit (version 9.0)</li>
</ul>
Fri, 15 Feb 2013 00:00:00 +0000
https://leodemoura.github.io/blog/2013/02/15/precompiled.html
https://leodemoura.github.io/blog/2013/02/15/precompiled.html
-
Computing with field extensions
<h1 id="computing-with-field-extensions">Computing with field extensions</h1>
<p>After we released the Z3 source code, a friend of mine made the
following comment: “you have so many different representations for
numbers in Z3”. He is correct, we have Naturals, Integers, Rationals,
binary Rationals, multiple precision floating and fixed point, and
Algebraic numbers.
Binary rationals are just rational numbers of the form \(\frac{a}{2 ^ k}\). The basic operations (addition, multiplication, comparison) with binary Rationals are much more efficient than the respective ones with Rational numbers.
Algebraic numbers are Real numbers that are roots of polynomials with integer coefficients.
For example, the square root of 2 is an Algebraic number because it is a root of the polynomial
<span>\(x ^ 2 - 2\)</span>. Some Algebraic numbers cannot be represented using radicals. For example, the single
Real root of \(x ^ 5 - x - 1\). Nonetheless, we can compute with and compare them, and they are used in
the <a href="https://research.microsoft.com/en-us/um/people/leonardo/files/IJCAR2012.pdf">nonlinear solver nlsat</a> that is available in Z3.</p>
<p>In this post, I describe yet another representation that <a href="https://www.cl.cam.ac.uk/~gp351/">Grant Passmore</a>
and I developed. <em>It supports infinitesimal, transcendental and algebraic extensions of the Rational numbers</em>.
That is, we can perform precise computations using multiple precision Rational numbers <em>and</em> elements such as
\( \sqrt{2},\, \pi,\, e,\, \sqrt[5]{3},\, \epsilon,\, \ldots \)
The new package subsumes the existing Algebraic number package in Z3, and is orders of magnitude more efficient.
It is already available in the Z3 C and Python APIs. We can also <a href="https://rise4fun.com/z3rcf">play with it online at rise4fun</a>.</p>
<p>Decision methods for nonlinear real arithmetic are essential to the formal verication of cyber-physical systems and formalized mathematics.
Classically, these decision methods operate over the <em>theory of real closed fields</em> (RCF). What is a RCF?
Every RCF is a <a href="https://en.wikipedia.org/wiki/Field_%28mathematics%29">field</a>,
that is, addition and multiplication are associative and commutative,
multiplication distributes over addition,
additive and multiplicative inverses for non-zero elements exist, etc.
The Real and Rational numbers are fields, but the Integers are not
because only 1 and -1 have multiplicative inverses. For example, there is no integer \(a\) s.t. \(3 a = 1\).
A RCF is also an ordered field, i.e., it is a field equipped with a total order upon its elements.
The Reals and Rational numbers are ordered fields. A RCF also has two additional properties, every positive number is a square</p>
<div>
\[
\forall x y \ \left(0 \leq x \Rightarrow \exists y (x =
y^2)\right)\!,
\]
</div>
<p>and second, all polynomials of odd degree have a root. This latter
property is expressed using an axiom scheme, with one axiom for each <em>n</em>.</p>
<div>
\[
\forall a_0 a_1 \ldots a_{2n} \exists z \left( z^{2n+1} + a_{2n}
z^{2n} + \ldots + a_1 z + a_0 = 0 \right)\!.
\]
</div>
<p>So, the Rational numbers are not a RCF, but the Real and Algebraic numbers are.
The set of Algebraic numbers is countable with computable operations,
and thus provides a logically sufficient computational substructure for making
RCF decision procedures. Note that the Algebraic numbers do not contain transcendental
elements such as \( \pi \mbox{ and } e \). Indeed, a Real number is
transcendental precisely when it is not Algebraic.</p>
<p>When implementing an RCF decision procedure, one is free to compute over any RCF while
still being sure that the resulting computations are valid over the Reals.
This is important from a computational point of view, as Reals are
uncountable with uncomputable basic operations.
On the one hand, this lack of transcendental elements seems logically inconsequential and even
computationally desirable, as transcendentals are undefinable over RCF and almost all of them
are uncomputable. However, various new applications have given rise to a need for computing
in real closed fields containing transcendentals. This need is especially apparent when one considers
cyber-physical systems, or mainstream efforts in formalized mathematics, such as Thomas Hales’s
<a href="https://code.google.com/p/flyspeck/">Flyspeck project</a>.</p>
<h2 id="infinitesimals">Infinitesimals</h2>
<p>In addition to RCFs containing common transcendental constants,
there is also a need for computing in RCFs containing infinitesimals. Our package allows users to create
an arbitrary number of infinitesimal extensions. Each extension adds a new positive element \(\epsilon\) that is smaller
than all existing positive elements in the current ordered field \(\mathbb{K}\).</p>
<div>
\[ \epsilon > 0 \ \wedge \ \forall k \in
\mathbb{K} \ \left(k > 0 \ \Rightarrow \
\epsilon < k\right). \]
</div>
<p>Note that, \(\frac{1}{\epsilon}\) is an <em>infinite</em> element, that is, it is bigger than any element in \(\mathbb{K}\).
Infinitesimals are a very useful abstraction, and simplify the implementation of decision procedures.
For example, <a href="https://www.csl.sri.com/users/bruno/">Bruno Dutertre</a> and I used infinitesimals to implement a
<a href="https://research.microsoft.com/en-us/um/people/leonardo/files/cav06.pdf">decision procedure for linear real arithmetic</a>.
The basic idea was to treat a strict inequality \(p < 0\), where \(p\) is a linear polynomial as
a non-strict inequality \(p \leq \epsilon\), where \(\epsilon\) is an infinitesimal.
Note that, in this application, infinitesimals could be easily encoded because we considered only the linear fragment.</p>
<p>The PSPACE and singly exponential procedures of Canny,
Grigor’ev-Vorobjov, and Basu-Pollack-Roy for the existential fragment
of nonlinear real arithmetic also rely on infinitesimal elements.
Most of these procedures were never fully implemented. The lack of a
viable library for computing with real closed fields containing
infinitesimals has been an impediment to this line of research</p>
<p>Grant and I are also using infinitesimals to implement a new procedure for nonlinear programming (aka optimization).
Suppose we are trying to minimize a nonlinear polynomial \(p\) subject to a set of nonlinear polynomial constraints.
We say \(p\) is an <em>objective function</em>.
In this project, we use infinitesimals in two different places. To show that \(p\) is <em>unbounded</em> by constructing
a solution where \(p\) evaluates to \(-\frac{1}{\epsilon}\), and to show that \(p\) has no minimum, but an infimum
value \(a\), by constructing a solution where \(p\) evaluates to \(a + \epsilon\), and proving that there is no solution \(\leq a\).</p>
<h2 id="examples">Examples</h2>
<p>The Python API for our package is very simple. It provides the object <code class="language-plaintext highlighter-rouge">RCFNum</code> that is a wrapper for the internal representation
used in our package. This object overloads the usual operations <code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge"><</code>, etc.
We also provide the operations <code class="language-plaintext highlighter-rouge">MkInfinitesimal()</code> for creating a new infinitesimal element, <code class="language-plaintext highlighter-rouge">Pi()</code> and <code class="language-plaintext highlighter-rouge">E()</code> for obtaining the
transcendental constants \(\pi\) and \(e\), and <code class="language-plaintext highlighter-rouge">MkRoots([a_0, ..., a_n])</code> that returns the roots of the polynomial
\(a_0 + a_1 x + \ldots + a_n x ^ n\).
In the following example, I use <code class="language-plaintext highlighter-rouge">MkRoots</code> to “build” \(-\sqrt{2}\) and \(\sqrt{2}\).</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">msqrt2</span><span class="p">,</span> <span class="n">sqrt2</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="n">msqrt2</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="o">-</span><span class="n">oo</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">{})</span>
<span class="k">print</span><span class="p">(</span><span class="n">sqrt2</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span></code></pre></figure>
<p>The actual encoding used to represent the numbers is described in the following <a href="https://research.microsoft.com/en-us/um/people/leonardo/files/rcf.pdf">draft</a>.
In the example above we distinguish \(-\sqrt{2}\) and \(\sqrt{2}\) using the intervals <code class="language-plaintext highlighter-rouge">(-oo, 0)</code> and <code class="language-plaintext highlighter-rouge">(0, +oo)</code>.
For example <code class="language-plaintext highlighter-rouge">root(x^2 + -2, (0, +oo), {})</code> is the single root of \(x ^ 2 - 2\) in the interval \((0, \infty)\).
The method <code class="language-plaintext highlighter-rouge">RCFNum.decimal(k)</code> displays a number in decimal notation using <code class="language-plaintext highlighter-rouge">k</code> decimal places.
The contract in our package only guarantees that the decimal representation can be produced when the number does not depend on
infinitesimal extensions.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">print</span><span class="p">(</span><span class="n">sqrt2</span><span class="p">.</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">1.4142135623</span><span class="err">?</span></code></pre></figure>
<p>The <code class="language-plaintext highlighter-rouge">?</code> in the output above is used to denote that the result is truncated.
Now, we show that \(\frac{1}{\sqrt{2}}\) is equal to \(\frac{\sqrt{2}}{2}\), and compute \(\sqrt{2} ^ 5 + 1\)</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">print</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="n">sqrt2</span> <span class="o">==</span> <span class="n">sqrt2</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="k">print</span><span class="p">(</span><span class="n">sqrt2</span><span class="o">**</span><span class="mi">5</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="o">>></span> <span class="mi">4</span><span class="o">*</span><span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">((</span><span class="n">sqrt2</span><span class="o">**</span><span class="mi">5</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">6.6568542494</span><span class="err">?</span></code></pre></figure>
<p>Now, we compute the roots of the polynomial \( \pi - \sqrt{2} x + x ^ 5 \).</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">pi</span> <span class="o">=</span> <span class="n">Pi</span><span class="p">()</span>
<span class="n">rs</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="n">pi</span><span class="p">,</span> <span class="o">-</span> <span class="n">sqrt2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">rs</span><span class="p">))</span>
<span class="o">>></span> <span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="n">rs</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">5</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span> <span class="n">x</span> <span class="o">+</span> <span class="n">pi</span><span class="p">,</span> <span class="p">(</span><span class="o">-</span><span class="n">oo</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">{})</span>
<span class="k">print</span><span class="p">(</span><span class="n">rs</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">decimal</span><span class="p">())</span>
<span class="o">>></span> <span class="o">-</span><span class="mf">1.3852383884</span><span class="err">?</span></code></pre></figure>
<p>Actually, the polynomial has only one root: -1.3852383884?. The output produced also suggests that our representation is recursive.
The previous Algebraic number package in Z3 used a “flat” data-structure where every number is encoded using a polynomial with integer coefficients.
The main problem in this flat representation is that the polynomials grow really fast.
For example, \(\sqrt[11]{2} + \sqrt[7]{2}\) can be compactly encoded in our new package</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="p">[</span><span class="n">r1</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="p">[</span><span class="n">r2</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="n">r1</span> <span class="o">+</span> <span class="n">r2</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">7</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span> <span class="o">+</span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">11</span> <span class="o">+</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span>
<span class="k">print</span><span class="p">((</span><span class="n">r1</span> <span class="o">+</span> <span class="n">r2</span><span class="p">).</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">2.1691306031</span><span class="err">?</span></code></pre></figure>
<p>On the other hand, if we try to represent this value as the root of a polynomial with integer coefficients, we have to use the following polynomial
of degree 77. Actually, it is the minimal polynomial (with integer coefficients) for defining this value.</p>
<div>
\[
\begin{array}{l}
-2176 - 19712 x - 670208 x^2 - 2050048 x^3 - 295680 x^4 +
96233984 x^5 - 495599104 x^6 + 11264 x^7 - \\
198253440 x^8 - 20646191104 x^9 - 650890240 x^{10} + 448 x^{11} -
38011467648 x^{12} + 171371574528 x^{13} - \\
28160 x^{14} - 37166976 x^{15} - 1268310460032 x^{16} -
11504100608 x^{17} + 34723106880 x^{19} - \\
2544211567744 x^{20} + 42240 x^{21} - 672 x^{22} -
1992710577088 x^{23} - 43405281920 x^{24} - 186825408 x^{26} + \\
4024746461120 x^{27} - 42240 x^{28} - 120170824928 x^{30} -
50308241984 x^{31} + 560 x^{33} - 850951467520 x^{34} + 29568 x^{35} - \\
155813504 x^{37} - 20052576544 x^{38} + 20445649840 x^{41} -
14784 x^{42} - 280 x^{44} - 2670956288 x^{45} - 25531352 x^{48} + \\
5280 x^{49} - 97853448 x^{52} + 84 x^{55} - 1320 x^{56} - 544236 x^{59} +
220 x^{63} - 14 x^{66} - 22 x^{70} + x^{77}
\end{array}
\]
</div>
<p>We can try these examples online <a href="https://rise4fun.com/Z3RCF/D">here</a>.</p>
<p>In nonlinear solvers such as nlsat, a procedure such as <code class="language-plaintext highlighter-rouge">MkRoots</code> is extensively used.
To demonstrate the basic idea, let us consider a very simple system of polynomial equations in
<em>triangular form</em>.</p>
<div>
\begin{eqnarray*}
-1 - x + x^5 & = & 0 \\
-197 + 3131 x - 31 x^2 y^2 + x y^7 & = & 0 \\
-735 x y + 7 y^2 z - 1231 x^3 z^2 + y z^5 & = & 0
\end{eqnarray*}
</div>
<p>We say the system is in triangular form because the first polynomial equation contains only
one variable, the second contains two, and so on. We can solve this kind of system using
<code class="language-plaintext highlighter-rouge">MkRoots</code> and “plug-in” the solutions up to step <em>i</em> when solving step <em>i+1</em>. This system has only one solution,
and we can find it using</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="p">[</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">197</span><span class="p">,</span> <span class="mi">3131</span><span class="p">,</span> <span class="o">-</span><span class="mi">31</span><span class="o">*</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">x</span><span class="p">])</span>
<span class="p">[</span><span class="n">z</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">735</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">y</span><span class="p">,</span> <span class="mi">7</span><span class="o">*</span><span class="n">y</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">1231</span><span class="o">*</span><span class="n">x</span><span class="o">**</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">1.1673039782</span><span class="err">?</span>
<span class="k">print</span><span class="p">(</span><span class="n">y</span><span class="p">.</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">0.0629726948</span><span class="err">?</span>
<span class="k">print</span><span class="p">(</span><span class="n">z</span><span class="p">.</span><span class="n">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="o">>></span> <span class="mf">31.4453571397</span><span class="err">?</span></code></pre></figure>
<p>This example in instantaneously solved using
our new package. We can try it online <a href="https://rise4fun.com/Z3RCF/1">here</a>.</p>
<p>We can also try to solve it using Mathematica <code class="language-plaintext highlighter-rouge">Root</code> primitive that is
roughly equivalent to <code class="language-plaintext highlighter-rouge">MkRoots</code>. However, Mathematica builds a “flat”
representation like the old Algebraic package in Z3, and takes
approximately 10min to find the solution on my machine. The solution for <em>z</em>
is encoded using a polynomial with integer coefficients of degree 175 that is too big to display here.
Here is the Mathematica script I used</p>
<figure class="highlight"><pre><code class="language-pascal" data-lang="pascal"><span class="n">x</span> <span class="p">=</span> <span class="n">Root</span><span class="p">[#^</span><span class="m">5</span> <span class="p">-</span> <span class="p">#</span> <span class="p">-</span> <span class="m">1</span> <span class="p">&,</span> <span class="m">1</span><span class="p">]</span>
<span class="n">y</span> <span class="p">=</span> <span class="n">Root</span><span class="p">[</span><span class="n">x</span> <span class="p">#^</span><span class="m">7</span> <span class="p">-</span> <span class="m">31</span> <span class="n">x</span><span class="p">^</span><span class="m">2</span> <span class="p">#^</span><span class="m">2</span> <span class="p">+</span> <span class="m">3131</span> <span class="p">#</span> <span class="p">-</span> <span class="m">197</span> <span class="p">&,</span> <span class="m">1</span><span class="p">]</span>
<span class="n">z</span> <span class="p">=</span> <span class="n">Root</span><span class="p">[</span><span class="n">y</span> <span class="p">#^</span><span class="m">5</span> <span class="p">-</span> <span class="m">1231</span> <span class="n">x</span><span class="p">^</span><span class="m">3</span> <span class="p">#^</span><span class="m">2</span> <span class="p">+</span> <span class="m">7</span> <span class="n">y</span><span class="p">^</span><span class="m">2</span> <span class="p">#</span> <span class="p">-</span> <span class="m">735</span> <span class="n">x</span> <span class="n">y</span> <span class="p">&,</span> <span class="m">1</span><span class="p">]</span></code></pre></figure>
<p>In the next example, we create infinitesimal elements, and perform
some basic operations with them.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">eps</span> <span class="o">=</span> <span class="n">MkInfinitesimal</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="n">eps</span> <span class="o"><</span> <span class="mf">0.000000000000001</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="k">print</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="n">eps</span> <span class="o">></span> <span class="mi">10000000000000000000000</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="k">print</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="n">eps</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">></span> <span class="mi">1</span><span class="o">/</span><span class="n">eps</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="k">print</span><span class="p">(</span><span class="n">eps</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="o">/</span><span class="n">eps</span><span class="p">)</span>
<span class="o">>></span> <span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">eps</span><span class="o">**</span><span class="mi">2</span> <span class="o"><</span> <span class="n">eps</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="c1"># r is the cubic root of eps
</span><span class="p">[</span><span class="n">r</span><span class="p">]</span> <span class="o">=</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="n">eps</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span> <span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{})</span>
<span class="k">print</span><span class="p">(</span><span class="n">r</span> <span class="o">></span> <span class="n">eps</span><span class="p">)</span>
<span class="o">>></span> <span class="bp">True</span>
<span class="c1"># We need to use sign conditions to distinguish the roots of
</span><span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">MkRoots</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="n">eps</span><span class="p">,</span> <span class="o">-</span><span class="n">eps</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">eps</span><span class="o">**</span><span class="mi">2</span><span class="p">]):</span>
<span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">5</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="o">-</span><span class="n">oo</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">{})</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">5</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{</span><span class="mi">60</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">6</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span> <span class="o">></span> <span class="mi">0</span><span class="p">})</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">5</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{</span><span class="mi">60</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">^</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">6</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span> <span class="o"><</span> <span class="mi">0</span><span class="p">})</span>
<span class="c1"># The irreducible polynomial: eps x^3 - 6x^2 + 9x - 1
# has three infinite positive roots
</span><span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">MkRoots</span><span class="p">([</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span> <span class="n">eps</span><span class="p">]):</span>
<span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">6</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">9</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{</span><span class="mi">3</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">9</span> <span class="o">></span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span> <span class="o">></span> <span class="mi">0</span><span class="p">})</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">6</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">9</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{</span><span class="mi">3</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">9</span> <span class="o">></span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span> <span class="o"><</span> <span class="mi">0</span><span class="p">})</span>
<span class="o">>></span> <span class="n">root</span><span class="p">(</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">3</span> <span class="o">+</span> <span class="o">-</span><span class="mi">6</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">9</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">+</span><span class="n">oo</span><span class="p">),</span> <span class="p">{</span><span class="mi">3</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">9</span> <span class="o"><</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="o">*</span><span class="n">eps</span><span class="err">!</span><span class="mi">1</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="o">-</span><span class="mi">12</span> <span class="o"><</span> <span class="mi">0</span><span class="p">})</span></code></pre></figure>
<p>Note that <code class="language-plaintext highlighter-rouge">1/eps</code> is an “infinite” value, and we use <a href="https://en.wikipedia.org/wiki/Rational_function">Rational functions</a>
to represent elements of infinitesimal (and transcendental) extensions.
For example, <code class="language-plaintext highlighter-rouge">eps**2 + 1/eps</code> is internally encoded as \(\frac{\epsilon ^ 3 + 1}{\epsilon}\). Finally, we use <em>sign conditions</em>
to identify the roots of \(1 - \epsilon x ^ 2 - \epsilon x ^ 3 + \epsilon ^ 2 x ^ 5\) and \(-1 + 9 x - 6 x ^ 2 + \epsilon x ^ 3 \).
We cannot identify them using just intervals with binary Rational end-points because these roots are infinite values.
A similar problem occur when we have roots that are infinitely close to each other.
Thom’s lemma guarantees that we can always identify the roots of a polynomial using the signs of its derivatives.
In our implementation, we minimize the number of sign conditions needed using the intervals whenever possible.
For example, our package did not use sign conditions to encode the negative root of \(1 - \epsilon x ^ 2 - \epsilon x ^ 3 + \epsilon ^ 2 x ^ 5\).
Moreover, it only needed the sign of one derivative to identify the two positive roots.
In principle, we can use the signs of arbitrary polynomials to identify/discriminate the different roots of a polynomial \(p\),
Thom’s lemma just says we can find these polynomials by checking the derivatives of \(p\).
We can try this example online <a href="https://rise4fun.com/Z3RCF/Do">here</a>.
Many other examples are available at <a href="https://rise4fun.com/Z3RCF">rise4fun</a>.
Well, we hope you will find new applications for this kind of package. The source code is available online at <a href="https://z3.codeplex.com">codeplex</a>.
I think Grant would agree that we had \(\frac{1}{\epsilon}\) fun working on this package :)</p>
Sat, 02 Feb 2013 00:00:00 +0000
https://leodemoura.github.io/blog/2013/02/02/inf-trans.html
https://leodemoura.github.io/blog/2013/02/02/inf-trans.html
-
Complex Numbers in Z3
<h1 id="complex-numbers-in-z3">Complex Numbers in Z3</h1>
<p>A user recently asked me if Z3 had support for Complex numbers.
Unfortunately, it does not. This is on my TODO list, but it is
has very low priority at this moment. Internally, Z3 already has a
lot of machinery for supporting Complex numbers, but there is a lot of
“plumbing” missing, such as extending the parsers, simplifiers,
models, and root isolation procedures. Most of this work is not really fun.</p>
<p>In the meantime, we can encode Complex numbers on top of the Real numbers
provided by Z3. The basic idea is to represent a Complex number as a pair
of Real numbers. This is not the most efficient way of implementing a decision
procedure for the theory of Complex numbers, but it is simple and allows us
to handle problems that mix Real and Complex number reasoning.
Moreover, we can decide the resulting problem using the new nonlinear arithmetic
solver <a href="https://research.microsoft.com/en-us/um/people/leonardo/files/IJCAR2012.pdf">nlsat</a> that is available in Z3.</p>
<p>We can represent a complex number</p>
<div>
\[ a + b i \]
</div>
<p>as a pair of real numbers</p>
<div>
\[ (a, b) \]
</div>
<p>Then the operations on Complex numbers can be easily encode on top of the operations on Real numbers provided by Z3.
Here is the encoding of the main operations.</p>
<div>
\begin{eqnarray*}
(a_1, b_1) + (a_2, b_2) & = & (a_1 + a_2,\, b_1 + b_2) \\
(a_1, b_1) - (a_2, b_2) & = & (a_1 - a_2,\, b_1 - b_2) \\
(a_1, b_1) \times (a_2, b_2) & = & (a_1 a_2 - b_1 b_2,\, a_1 b_2 + b_1 a_2) \\
(a, b)^{-1} & = & (\frac{a}{a^2 + b^2}, -\frac{b}{a^2 + b^2}) \mbox { if } a \neq 0 \vee b \neq 0 \\
(a_1, b_1) \div (a_2, b_2) & = & (a_1, b_1) \times (a_2, b_2)^{-1} \mbox { if } a \neq 0 \vee b \neq 0 \\
\end{eqnarray*}
</div>
<p>The definition of the multiplicative inverse follows from basic algebraic manipulation</p>
<div>
\[
\frac{1}{a + b i} = \frac{a - b i}{(a + b i)(a - b i)} = \frac{a - b i}{a^2 + b^2} = \frac{a}{a^2 + b^2} - \frac{b}{a^2 + b^2} i
\]
</div>
<p>It is straightforward to implement the operations above using the Z3 Python API. We can even create a class <code class="language-plaintext highlighter-rouge">ComplexExpr</code>
to wrap the pair of Z3 real expressions and overload the usual operators <code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">/</code>. This class has two
fields <code class="language-plaintext highlighter-rouge">.r</code> (the real part) and <code class="language-plaintext highlighter-rouge">.i</code> (the imaginary part). The auxiliary function <code class="language-plaintext highlighter-rouge">_to_complex</code> is used to convert <code class="language-plaintext highlighter-rouge">a</code> into a
Z3 “Complex” number if it is not already one.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">_to_complex</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">ComplexExpr</span><span class="p">):</span>
<span class="k">return</span> <span class="n">a</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">RealVal</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_is_zero</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span> <span class="ow">and</span> <span class="n">a</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">is_rational_value</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="ow">and</span> <span class="n">a</span><span class="p">.</span><span class="n">numerator_as_long</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">ComplexExpr</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">=</span> <span class="n">r</span>
<span class="bp">self</span><span class="p">.</span><span class="n">i</span> <span class="o">=</span> <span class="n">i</span>
<span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">+</span> <span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span> <span class="o">+</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__radd__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">r</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__sub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">-</span> <span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span> <span class="o">-</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__rsub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">r</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="o">*</span><span class="n">other</span><span class="p">.</span><span class="n">r</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="o">*</span><span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="o">*</span><span class="n">other</span><span class="p">.</span><span class="n">i</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="o">*</span><span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">-</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">+</span> <span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">inv</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">den</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="o">/</span><span class="n">den</span><span class="p">,</span> <span class="o">-</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="o">/</span><span class="n">den</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__div__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">inv_other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">).</span><span class="n">inv</span><span class="p">()</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">__mul__</span><span class="p">(</span><span class="n">inv_other</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__rdiv__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">inv</span><span class="p">().</span><span class="n">__mul__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="n">_to_complex</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">And</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__neq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Not</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">simplify</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">simplify</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">),</span> <span class="n">simplify</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">repr_i</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="n">is_rational_value</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">):</span>
<span class="k">return</span> <span class="s">"%s*I"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">.</span><span class="n">i</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"(%s)*I"</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="n">_is_zero</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">i</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">_is_zero</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">repr_i</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"%s + %s"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">repr_i</span><span class="p">())</span></code></pre></figure>
<p>The function <code class="language-plaintext highlighter-rouge">Complex(a)</code> creates a new “Complex” variable. Actually, it creates two real variables named <code class="language-plaintext highlighter-rouge">a.r</code> and <code class="language-plaintext highlighter-rouge">a.i</code>.
The constant <code class="language-plaintext highlighter-rouge">I</code> is just an alias for the pair <code class="language-plaintext highlighter-rouge">(0, 1)</code>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">Complex</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">Real</span><span class="p">(</span><span class="s">'%s.r'</span> <span class="o">%</span> <span class="n">a</span><span class="p">),</span> <span class="n">Real</span><span class="p">(</span><span class="s">'%s.i'</span> <span class="o">%</span> <span class="n">a</span><span class="p">))</span>
<span class="n">I</span> <span class="o">=</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">RealVal</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">RealVal</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span></code></pre></figure>
<p>The function <code class="language-plaintext highlighter-rouge">evaluate_cexpr</code> “retrieves” the value of a Complex expression <code class="language-plaintext highlighter-rouge">e</code> in the model <code class="language-plaintext highlighter-rouge">m</code>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">evaluate_cexpr</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ComplexExpr</span><span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">r</span><span class="p">],</span> <span class="n">m</span><span class="p">[</span><span class="n">e</span><span class="p">.</span><span class="n">i</span><span class="p">])</span></code></pre></figure>
<p>Now, we have all the pieces we need to solve our first problem. Find a root of <code class="language-plaintext highlighter-rouge">x*x + 2</code>.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">x</span> <span class="o">=</span> <span class="n">Complex</span><span class="p">(</span><span class="s">"x"</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">Tactic</span><span class="p">(</span><span class="s">'qfnra-nlsat'</span><span class="p">).</span><span class="n">solver</span><span class="p">()</span>
<span class="n">s</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">check</span><span class="p">())</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">model</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">'x = %s'</span> <span class="o">%</span> <span class="n">evaluate_cexpr</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">x</span><span class="p">))</span></code></pre></figure>
<p>In the example above, I used <code class="language-plaintext highlighter-rouge">Tactic('qfnra-nlsat').solver()</code> to create a solver based on nlsat.
Note that, the problem above is unsatisfiable on the Reals.
<a href="https://rise4fun.com/Z3Py/uepl">We can try this example online at rise4fun</a>.</p>
Sat, 26 Jan 2013 00:00:00 +0000
https://leodemoura.github.io/blog/2013/01/26/complex.html
https://leodemoura.github.io/blog/2013/01/26/complex.html
-
Z3 for Java
<h1 id="z3-for-java">Z3 for Java</h1>
<p><a href="https://z3.codeplex.com">Z3</a> now provides support for <a href="https://en.wikipedia.org/wiki/Java_\(programming_language\)">Java</a>.
The new Java bindings are based on the .Net bindings developed by Christoph Wintersteiger.
They will be included in the next official release. In the meantime, we can already try them using the <a href="https://z3.codeplex.com/SourceControl/changeset/view/8bfbdf1e680d"><code class="language-plaintext highlighter-rouge">unstable</code></a> branch.
Please try the new Java bindings and <a href="https://z3.codeplex.com/WorkItem/Create">submit problems and bugs</a>.</p>
<p>Here are the instructions to build the Z3 Java bindings.</p>
<p>First, we have to clone the <code class="language-plaintext highlighter-rouge">unstable</code> branch from <a href="https://z3.codeplex.com/SourceControl/changeset/view/8bfbdf1e680d">codeplex</a>.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git clone https://git01.codeplex.com/z3 <span class="nt">-b</span> unstable</code></pre></figure>
<p>CodePlex requires <a href="https://git-scm.com/">git</a> 1.7.10 or later to avoid HTTPS cloning errors. If we get a cloning error, we should use the instructions
found <a href="https://z3.codeplex.com/wikipage?title=Git%20HTTPS%20cloning%20errors">here</a>.</p>
<p>Next, we have to checkout the <code class="language-plaintext highlighter-rouge">z3-java</code> tag. This tag “points” to a fairly stable commit in the <code class="language-plaintext highlighter-rouge">unstable</code> branch.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">cd </span>z3
git checkout z3-java</code></pre></figure>
<p>Next, we generate the Z3 make file with the option <code class="language-plaintext highlighter-rouge">--java</code>.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">python scripts/mk_make.py <span class="nt">--java</span></code></pre></figure>
<p>Now, we build Z3 and the example applications.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">cd </span>build
make all examples</code></pre></figure>
<p>That is it. Now, we can execute the example located at <a href="https://z3.codeplex.com/SourceControl/changeset/view/8bfbdf1e680d#examples%2fjava%2fJavaExample.java"><code class="language-plaintext highlighter-rouge">examples/java/JavaExample.java</code></a> using:</p>
<ul>
<li>
<p><code class="language-plaintext highlighter-rouge">java -cp com.microsoft.z3.jar;. JavaExample</code> (on Windows)</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH=. java -cp com.microsoft.z3.jar:. JavaExample</code> (on Linux and FreeBSD)</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">java -cp com.microsoft.z3.jar:. JavaExample</code> (on OSX)</p>
</li>
</ul>
Mon, 10 Dec 2012 00:00:00 +0000
https://leodemoura.github.io/blog/2012/12/10/z3-for-java.html
https://leodemoura.github.io/blog/2012/12/10/z3-for-java.html
-
External contributions
<h1 id="external-contributions">External contributions</h1>
<p>Today, we started to accept external contributions to the Z3 code base.
First, I’d like to emphasize that Z3 does not have a liberal license such as GPL or Apache.
The source code is available, but it cannot be used for commercial purposes.
Moreover, if we read the <a href="https://z3.codeplex.com/license">license</a> carefully, item 3
says that Microsoft can use external contributions for commercial purposes.
It is understandable that some may think this is a <em>unfair</em> clause.
If you do not agree with the license terms, please do not contribute any code.</p>
<p>We initially did not want to accept external contributions. The main issue was that some Z3 internal users have strict
rules against external contributions. They can only use code bases that were implemented by Microsoft employees and/or contractors.
However, as we gained experience with <a href="https://git-scm.com/">git</a>, it became clear that we can easily maintain a <code class="language-plaintext highlighter-rouge">pure</code> branch
containing only internal contributions, and the <code class="language-plaintext highlighter-rouge">master</code> branch with internal and <em>external</em> contributions.
Now, the 4 main branches in the Z3 project are</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">master</code> the official branch containing internal and external contributions.</li>
<li><code class="language-plaintext highlighter-rouge">pure</code> the official branch for internal users that cannot use external contributions.</li>
<li><code class="language-plaintext highlighter-rouge">unstable</code> the branch for working in progress being done by the Z3 team.</li>
<li><code class="language-plaintext highlighter-rouge">contrib</code> the branch for new external contributions and new changes from <code class="language-plaintext highlighter-rouge">unstable</code>.</li>
</ul>
<p><em>Remark</em>: We also have other branches for experimental features we are working on.</p>
<p>Our plan is to use the following work-flow. The Z3 team works on the <code class="language-plaintext highlighter-rouge">unstable</code> branch. When the code in the <code class="language-plaintext highlighter-rouge">unstable</code> branch becomes “stable”,
it is merged into the <code class="language-plaintext highlighter-rouge">pure</code> branch. External contributors submit “pull requests” to the <code class="language-plaintext highlighter-rouge">contrib</code> branch. When the changes in <code class="language-plaintext highlighter-rouge">pure</code> and <code class="language-plaintext highlighter-rouge">contrib</code> are stable, they are merged into the <code class="language-plaintext highlighter-rouge">master</code> branch.</p>
<p>The Z3 code base is big and not very well documented. So, it is hard to make contributions to the main engines.
At this point, it is more realistic to target contributions such as</p>
<ul>
<li>Bindings for other programming languages (e.g., Java).</li>
<li>New functionality on top of the existing API (e.g., maxsat, allsat, etc).</li>
<li>New examples using the Z3 API.</li>
<li>Regression tests</li>
</ul>
<p>In future blog posts, I’m planning to describe the main data-structures used in Z3, and how to add more complicated functionality.</p>
<p>I suggest anybody interested in submitting code to contact a Z3 team member before investing time working on it.<br />
The idea is to coordinate where the contribution will fit in the project, the scope, and how it will integrate with the other components.</p>
<p><strong>Important:</strong> Please, do not submit bug fixes using pull requests. Instead submit a bug report using the <a href="https://z3.codeplex.com/WorkItem/Create">issue tracker</a>. Feel free to describe a potential fix.</p>
<p>Here are some instructions on how to fork, modify and submit your modifications to the Z3 project.</p>
<ul>
<li>
<p>Make sure you have <a href="https://git-scm.com/">git</a> installed in your system.</p>
</li>
<li>
<p><a href="https://www.codeplex.com/site/login?RedirectUrl=http%3a%2f%2fwww.codeplex.com%2f">Create an account at Codeplex</a>.</p>
</li>
<li>
<p>Fork the <a href="https://z3.codeplex.com/SourceControl/list/changesets?branch=contrib">Z3 code base</a>. You just have to click the Fork link as described below.</p>
</li>
</ul>
<p><img src="https://leodemoura.github.io/images/fork1.png" /></p>
<ul>
<li>Name your fork. In the following example, I used the name <code class="language-plaintext highlighter-rouge">z3exp</code>.</li>
</ul>
<p><img src="https://leodemoura.github.io/images/fork2.png" /></p>
<ul>
<li>Retrieve your fork using <code class="language-plaintext highlighter-rouge">git</code>. In the following command, the option <code class="language-plaintext highlighter-rouge">-b contrib</code> is used to retrieve the <code class="language-plaintext highlighter-rouge">contrib</code> branch. Note that you have to replace <code class="language-plaintext highlighter-rouge">leodemoura</code> with your username, and <code class="language-plaintext highlighter-rouge">z3exp</code> with the name you used for your Fork.</li>
</ul>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git clone https://git01.codeplex.com/forks/leodemoura/z3exp <span class="nt">-b</span> contrib</code></pre></figure>
<p><em>Remark:</em> CodePlex requires git 1.7.10 or later to avoid HTTPS cloning errors.
If you are using an older version of git, you might get an error.
If that is your case, here are some <a href="https://z3.codeplex.com/wikipage?title=Git%20HTTPS%20cloning%20errors">instructions</a> on how to fix it.</p>
<ul>
<li>Perform your modifications and commit them and submit to codeplex. This is your Fork. You can make changes locally and save them at codeplex.</li>
</ul>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">... modify/create files ...
git commit <span class="nt">-a</span> <span class="nt">-s</span> <span class="nt">-m</span> <span class="s2">"my modifications"</span>
git push</code></pre></figure>
<ul>
<li>After you implemented and tested your contribution, you can submit a pull request to the Z3 code base.</li>
</ul>
<p><img src="https://leodemoura.github.io/images/fork3.png" /></p>
<p>You are essentially submitting your changes in the <code class="language-plaintext highlighter-rouge">contrib</code> branch (in your Fork) to the <code class="language-plaintext highlighter-rouge">contrib</code> branch in the Z3 code base.
You have to make sure that the <code class="language-plaintext highlighter-rouge">from</code> and <code class="language-plaintext highlighter-rouge">to</code> branches are selected correctly like in the following example.</p>
<p><img src="https://leodemoura.github.io/images/fork4.png" /></p>
Mon, 19 Nov 2012 00:00:00 +0000
https://leodemoura.github.io/blog/2012/11/19/external-contrib.html
https://leodemoura.github.io/blog/2012/11/19/external-contrib.html
-
Reorganizing the Z3 code base
<h1 id="reorganizing-the-z3-code-base">Reorganizing the Z3 code base</h1>
<p>Today, we release <a href="https://z3.codeplex.com/SourceControl/changeset/view/a6db55d21f22">Z3 4.3.0</a>. This release contains many bug fixes, a new build system, and, more importantly, a complete reorganization of the code base. Now, the code is organized in sub-directories under the directory <code class="language-plaintext highlighter-rouge">src</code>. It is much easier to find the module we are interested in. For example, if we want to read the <strong>nlsat</strong> source code, we just have to go to the directory <code class="language-plaintext highlighter-rouge">src/nlsat</code>. The new code reorganization also allow us to easily create binaries/libraries that contain only a subset of the components available in <a href="https://z3.codeplex.com">Z3</a>.</p>
<p>We are also officially switching to a three number naming scheme for version numbers. The plan is to have more frequent releases.
We skipped version 4.2 because the binary tagged as 4.1.2 was reporting version 4.2. Many thanks to Claude Marche for reporting this problem.</p>
<p>Moreover, we realized that it does not make sense to provide zip files with source code at <a href="https://z3.codeplex.com">codeplex</a>.
Codeplex provides a “Download” button that automatically creates the zip file for any version/branch/commit.
We just have to go to the <a href="https://z3.codeplex.com/SourceControl/changeset/view/a6db55d21f22#">“Source Code” tab</a>, select the version we want and click “Download”.</p>
<p><img src="https://leodemoura.github.io/images/z3-download-page.png" /></p>
<p>The <code class="language-plaintext highlighter-rouge">master</code> branch is the <strong>official branch</strong>. We use the <code class="language-plaintext highlighter-rouge">unstable</code> branch for work-in-progress that will be included in the next release.
Finally, we re-started to provide <a href="https://z3.codeplex.com/releases">pre-compiled binaries for Windows</a>. The new binary distribution is much simpler,
it is just a zip file with the binaries, DLLs, and include files. We have a zip file for <a href="https://z3.codeplex.com/downloads/get/528588">32</a> and <a href="https://z3.codeplex.com/downloads/get/528578">64 bits</a>.</p>
<p>One bad news is that the ML bindings are still not working in this version, but we will fix that in future releases.</p>
<h1 id="building-z3">Building Z3</h1>
<p>The new build system is based on python. The script <code class="language-plaintext highlighter-rouge">scripts/mk_make.py</code> creates the Makefile, generates bindings for .Net and Python, DLL definitions, etc.
It can also optionally create an auxiliary Visual Project file for people that cannot live without Visual Studio intellisense.
The generated Makefiles can be compiled using Visual Studio <code class="language-plaintext highlighter-rouge">nmake</code> or GNU <code class="language-plaintext highlighter-rouge">make</code>.
By default, the script <code class="language-plaintext highlighter-rouge">scripts/mk_make.py</code> generates the Makefile in the subdirectory <code class="language-plaintext highlighter-rouge">build</code>.</p>
<h2 id="building-z3-on-windows">Building Z3 on Windows</h2>
<p>To compile Z3 on a Windows machine, we should open a Visual Studio Command Prompt (All Programs > Microsoft Visual Studio 20xx > Visual Studio Tools), go to the directory where the Z3 source code is located, and type</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">python scripts/mk_make.py
<span class="nb">cd </span>build
nmake</code></pre></figure>
<h2 id="building-z3-on-linux-osx-and-cygwin">Building Z3 on Linux, OSX (and cygwin)</h2>
<p>In other platforms, we just have to execute the following commands.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">autoconf
./configure
python scripts/mk_make.py
<span class="nb">cd </span>build
make</code></pre></figure>
<p>The example applications can be built using</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">make examples</code></pre></figure>
<p>Z3 can be installed in these platforms using the standard</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>make <span class="nb">install</span></code></pre></figure>
<p>The binaries and libraries are installed in the “prefix” specified in the <code class="language-plaintext highlighter-rouge">./configure</code> script. The default “prefix” is <code class="language-plaintext highlighter-rouge">/usr</code>.
To uninstall, we just have to execute</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>make uninstall</code></pre></figure>
<h2 id="custom-builds">Custom builds</h2>
<p>To list all command line options available in <code class="language-plaintext highlighter-rouge">scripts/mk_make.py</code>, we just have to execute</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">python scripts/mk_make.py <span class="nt">--help</span></code></pre></figure>
<p>For example, the option <code class="language-plaintext highlighter-rouge">--debug</code> generates a Makefile that builds Z3 in debug mode.
The file <code class="language-plaintext highlighter-rouge">scripts/mk_project.py</code> defines all existing modules and dependencies between them.</p>
Sun, 11 Nov 2012 00:00:00 +0000
https://leodemoura.github.io/blog/2012/11/11/reorg-z3.html
https://leodemoura.github.io/blog/2012/11/11/reorg-z3.html
-
Releasing the Z3 source code
<h1 id="releasing-the-z3-source-code">Releasing the Z3 source code</h1>
<strike>Z3 is now open source.</strike>
<p>Z3 source code is now available.
The source code is available under the MSR-LA
license. This is the same license used to distribute the Z3
binaries. The source code can be used for non-commercial purposes. The
license allows users to redistribute, copy and modify Z3.
For more information see
<a href="https://z3.codeplex.com/license">https://z3.codeplex.com/license</a>.</p>
<p><strong><em>EDIT</em></strong> <em>MSR-LA is not as “open” as GPL, Apache or BSD, but it
allows users to read, copy, redistribute, modify, and experiment with Z3 source code.
I believe MSR-LA matches academic openness and transparency.
The main restriction is that the source code cannot be used for commercial purposes.</em>
<strong><em>END EDIT</em></strong></p>
<p>Nikolaj Bjorner, Christoph Wintersteiger and I wrote several papers
describing new algorithms and heuristics for SMT solvers. Some of
them are non trivial and hard to reproduce. I believe the source code
complements these papers, and may help others to clarify
misunderstandings, dispute claims made in our papers, experiment new
ideas, reproduce our results, and advance the state-of-the-art.
Perhaps, the actual implementation is as important as the abstract
procedures described in our papers.</p>
<p>By having the source code available, some features become obsolete.
For example, the theory plugin API is not needed anymore. Now, users
can directly implement their extensions inside the Z3 code base.</p>
<p>I think the code is quite readable, but it was not originally written
for external consumption. We wrote the code for ourselves. Several
parts have been rewritten several times, and some duplication
exists. Anyway, I will try to cleanup the code in the future. Please,
fell free to bug me if you are interested in hacking and/or
understanding the source code. All important files are located in the
directory <code class="language-plaintext highlighter-rouge">lib</code>.</p>
<p>The source code can be compiled in all major platforms.
I tried on Windows (using Visual Studio) and Linux (using g++).
If you find a problem, please contact me, and I will fix it.</p>
Tue, 02 Oct 2012 00:00:00 +0000
https://leodemoura.github.io/blog/2012/10/02/open-z3.html
https://leodemoura.github.io/blog/2012/10/02/open-z3.html