SMT solvers for real closed fields (e.g., trascendentals and infinitesimals) in practise? Z3, MetiTarski, dReal - z3

I would like to delve into the capability of SMT solvers to deal with trascendental and infinitesimal elements.
Thus, I just read the paper on computing in real closed fields https://www.cl.cam.ac.uk/~gp351/infinitesimals.pdf and I would like to practise some of its examples, such as (pg 13):
msqrt2, sqrt2 = MkRoots([-2, 0, 1])
print(sqrt2)
>> root(x^2 + -2, (0, +oo), {})
However, the link to the code they offer (http://z3.codeplex.com/wikipage?title=CADE24) is not active. Also, in Z3-Py, declarations like MkRoots do not exist.
Any idea? In case this paper is out-to-date, how are trascendentals and infinitesimals treated in Z3 nowadays?
The paper also states that MetiTarski "uses the nlsat nonlinear solver in Z3", which confuses me, since I thought MetiTarski (https://www.cl.cam.ac.uk/~lp15/papers/Arith/) was a separated automatic theorem prover). Indeed, they talk about MetiTarski in related work but do not mention Z3 (also, in MetiTarski's paper https://www.cl.cam.ac.uk/~lp15/papers/Arith/MetiTarski-jar.pdf Z3 is neither mentioned).
Would you recommend any other SMT-paradigm interesting for this? Any tools to prove benchmars as the one above? Any other reading? I already know dReal, but the aforementioned paper says that "their methods are incomplete even for ∃RCF", so I would be interested in complete methods if possible.

Z3's RCF related functions are in the z3.z3rcf module path, so simply import that first:
from z3 import *
from z3.z3rcf import *
msqrt2, sqrt2 = MkRoots([-2, 0, 1])
print(sqrt2)
This prints:
root(x^2 + -2, (0, +oo), {})
MetiTarski does indeed use z3: It's download page even mentions this dependency explicitly: https://www.cl.cam.ac.uk/~lp15/papers/Arith/download.html
My understanding is that reasoning with transcendentals is beyond the capability of current SMT solvers. (dReal is all about approximations, not exact solutions.) If your goal is to work on transcendentals, then your best bet is to use theorem provers. I believe there has been significant amount of work in ACL2, Coq, and Isabelle; and google results in many hits. Expecting a lot of automation would be unreasonable though, so you should be prepared to writing proofs by hand and hopefully these systems are mature enough to help you along with custom tactics and as they branch to z3 for "simpler" subgoals.

Related

z3 alternative for Gecode branch() function?

In constraint solver like Gecode , We can control the exploration of search space with help of branching function. for e.g. branch(home , x , INT_VAL_MIN ) This will start exploring the search space from the minimum possible value of variable x in its domain and try to find solution.(There are many such alternatives .)
For z3, do we have this kind of flexibility in-built ?? Any alternative possible??
SMT solvers usually do not allow for these sorts of "hints" to be given, they act more as black-boxes.
Having said that, each solver uses a ton of internal heuristics, and z3 itself has a number of settings that you can play with to give it hints. If you run:
z3 -pd
it will display all the options you can provide, and there are literally over 600 of them! Unfortunately, these options are not really well documented, and how they impact the solver is rather cryptic. The only reliable way to find out would be to study the source code and see what they do, which isn't for the faint of heart. But in any case, it will not be as obvious as the branch feature you cite for gecode.
There are, however, other tricks one can use to speed up solving for SMT-solvers, unfortunately, these things are usually very problem-specific. If you post specific instances, you might get better suggestions.

How to understand what z3 is doing when it loops?

I'm having trouble figuring out how to debug z3. Is there a way to see what the SMT engine is "trying" to make it easier to understand why it's failing to see a solution that seems obvious and where it's devoting it's time instead?
As an example in my particular circumstance, I'm working with a recursive function and setting z3 to find inputs where the function has a certain result. SMT was timing out, yadda yadda yadda, turns out the thing I was recursing on had a base case of 0, but if it ever went negative, it'd recurse forever. Z3 didn't know not to pick a negative number, so it'd get stuck. I figured that out by staring at the code, but if I had some output somewhere that said "trying i == -10, trying i == -11, etc" it'd be very obvious what was going wrong.
I'm continuing to have less obvious issues, and I suspect Z3 is still getting stuck in loops. How can I see the loop it's getting stuck in?
It is unfortunately very difficult to find out why exactly Z3 is running forever, but typical culprits are matching loops due to bad patterns (a quantifier instantiations yields new ground terms that trigger another instantiations, and so on) and non-linear arithmetic.
The Z3 axiom profiler, described in this paper can help with identifying problems due to too many quantifier instantiations.

Setting logic for solver in Z3 (API)

I notice that the Z3 C++ (and C) API allows you to supply the logic to be used.
I have two questions about this that I couldn't answer by looking online:
Are these supposed to be the standard SMT-LIB logics i.e. QF_LRA
When are these worth supplying i.e. when will Z3 actually use this information
My context is mainly QF no BV but everything else possible, I am using the SMT solver incrementally and I can always work out what logic I will be in at the start.
Z3 will also try to figure out what the logic is (when run with default options), but it doesn't have custom tactics for all combinations of theories (see default_tactic.cpp and smt_strategic_solver.cpp). When you are not sure what Z3 will decide to do, then it's best to set the tactic right up front, so that you will get errors if you try to use things that are not in that logic. It will also use that information to set up the smt kernel, e.g., enabling various preprocessors, various solver features, and chosing heuristics (see e.g., smt_setup.cpp).
Try it out and see!
Usually it does make a big difference. Setting the logic means the solver will use a specialized tactic to solve the formula, instead of going through the generic loop. Z3 will also try to guess the logic, but it's usually better to just provide it upfront.

Getting a counterexample from µZ3 (Horn solver)

Using Z3's Horn clause solver:
If the answer is SAT, one can get a satisfying assignment to the unknown predicates (which, in most applications, correspond to inductive invariants of some kind of transition system or procedure call system).
If the answer is unsat, then this means the exists an unfolding of the Horn clauses and an assignment to the universally quantified variables in the Horn clauses such that at least one of the safety conditions (the clauses with a false head) is violated. This constitutes a concrete witness why the system had no solution.
I suspect that if Z3 can conclude unsat, then it has some form of such witness internally (and this anyway is the case in PDR, if I remember well). Is there a way to print it out?
Maybe I badly read the documentation, but I can't find a way. (get-proof) prints something unreadable, and, besides, (set-option :produce-proofs true) makes some problems intractable.
The refutation that Z3 produces for HORN logic problems is in the form of a tree of unit-resulting resolution steps. The counterexample you're looking for is hiding in the conclusions of the unit-resolution steps. These conclusions (the last arguments of the rules) are ground facts that correspond to program states (or procedure summaries or whatever) in the counterexample. The variable bindings that produce these facts can be found in "quant-inst" rules.
Obviously, this is not human readable, and actually is pretty hard to read by machine. For Boogie I implemented a more regular format, but it is currently only available with the duality engine and only for the fixedpoint format using "rule" and "query". You can get this using the following command.
(query :engine duality :print-certificate true)

HORN Clause Z3 Documentation

I am trying to encode some imperative program using HORN logic of Z3 (set-logic HORN) but getting some difficulties of defining clause (using SMT2). Could anyone tell me where can I find a good source of documentations for this feature of Z3?
Well, there's more to it when it comes to "encoding" a program in horn clauses.
First you need to check an appropriate proof rule: does the program has recursive functions, should you do function summarization? and so on.
There are a few papers on the subject, but I don't think there's any tutorial on VC gen.
You may also want to take a look to some benchmarks in Horn SMT format to draw inspiration: https://svn.sosy-lab.org/software/sv-benchmarks/trunk/clauses/
Feel free to ask if you have a specific question.

Resources