Is it possible to use Z3 excluding SAT? - z3

Z3 supports the SMT-lib set-logic statement to restrict to specific fragments. In a program using (set-logic QF_LRA) for example, quantifier-free linear real arithmetic is enabled. If multiple theories are enabled, it makes sense to me that SAT would be required. However, it's not clear to me if it's possible to enable a single theory and guarantee that SAT is never run, thereby reducing Z3 purely to a solver for that single theory alone. This would be useful for example to claim that a tool honors the particular performance bound of the solver for a given theory.
Is there a way to do this in SMT-lib, or directly in Z3? Or is guaranteeing that the SAT solver is disabled impossible?

The Nelson-Oppen theory combination algorithm that many SMT solvers essentially implement crucially relies on the SAT solver: In a sense, the SAT solver is the engine that solves your SMT query, consulting the theory solvers to make sure the conflicts it finds are propagated/resolved according to the theory rules. So, it isn't really possible to talk about an SMT solver without an underlying SAT engine, and neither SMTLib nor any other tool I'm aware of allows you to "turn off" SAT. It's an integral piece of the whole system that cannot be turned on/off at will. Here's a nice set of slides for Nelson-Oppen: https://web.stanford.edu/class/cs357/lecture11.pdf
I suppose it would be possible to construct an SMT solver that did not use this architecture; but then every theory solver would need to essentially have a SAT solver embedded into itself. So, even in that scenario, extracting the "SAT" bits out is really not possible.
If you're after precise measurements of what part of the solver spends what amount of time, your best bet is to instrument the solver to collect statistics on where it spends its time. Even then, precisely calling which parts belong to the SAT solver, which parts belong to the theory solver, and which parts go to their combination will be tricky.

Related

How to debug SMT scripts that have quantifiers?

Currently, I have a somewhat superficial understanding of how SMT solvers work (the basics of algorithms like E-matching, MBQI, and CVC4/5's inductive reasoning). However, it's very frustrating to debug by trial-and-error.
Is there any guidance on how to debug SMT scripts that make heavy use of quantifiers?
A badly-written script often goes into infinite loop but I cannot tell if it's my mistake, or it's just taking too long to respond.
The SMT solvers tend to hide internals from users, so it's quite hard to figure out why it's stuck. Is there any way to print the "solving context"?
Or maybe I'm using SMT solvers the wrong way? I should design my own verification algorithm, only employing SMT solvers for local decisions?
Any help is appreciated!
This is a very subjective question, and largely opinion based. But a couple of general remarks:
Don't directly program in SMTLib. It is not meant to be for human-consumption. Instead, use a higher-level API, and script them from a language that you're more familiar with. There are bindings available from any number of languages, including C/C++/Java/Python/O'Caml/Haskell/Scala etc. Just doing this will get rid of most of the mundane mistakes you make.
Turn on verbosity output of the solver. You might be able to notice patterns in the log output. Unfortunately this is very solver specific, and can be hard to decipher; but can also indicate if, for instance, you're stuck in an e-matching loop in the presence of quantifiers.
If there's a custom algorithm for your verification problem (Hoare triples, separation logic, abstract interpretation, ...), then you first have to apply these techniques and delegate local/sub-lemmas to an SMT solver. Do not expect the SMT solver to be able to do large proofs, and anything that requires actual induction out-of-the box.
Try reducing complexity by putting in over-constraints and see which ones help. Based on your findings you might be able to do a case-split, for instance, if the over-constraints enumerate a reasonably small search-space.
Again, these are very general remarks and whether they'll apply for your specific problem is anyone's guess. But I'd start with coding in a higher-level API if you aren't already doing so.

Will Z3 adaptively change strategy in solving linear real arithmetic constraints?

I have a huge set of linear real arithmetic constraints to solve, and I am incrementally feeding them to the solver. Z3 always seems to get stuck after a while. Is Z3 internally going to change its strategy in solving the constraints, such as moving away from the Simplex algorithm and try others, etc. Or do I have to explicitly instruct Z3 to do so? I am using Z3py.
Without further details it's impossible to answer this question precisely.
Generally, with no logic being set and the default tactic being run or (check-sat) being called without further options, Z3 will switch to a different solver the first time it sees a push command; prior to that it can use a non-incremental solver.
The incremental solver comes with all the positives and negatives of incremental solvers, i.e., it may be faster initially, but it may not be able to exploit previously learned lemmas after some time, and it may simply remember too many irrelevant facts. Also, the heuristics may 'remember' information that doesn't apply at a later time, e.g., a 'good' variable ordering may change into a bad one after everything is popped and a different problem over the same variables is pushed. In the past, some users found it works better for them to use the incremental solver for some number of queries, but to start from scratch when it becomes too slow.

Calling external SAT solver from Z3

In the company I work at, we have access to multiple SAT Solvers.
We would like to analyze how each the SAT solvers affect the performance of the Z3 SMT solver.
Is it possible to call an external SAT solver from Z3?
If not, where should the Z3 be modified to call an external solver?
I don't think this would be an easy task, because Z3 uses a tightly integrated internal SAT solver. The necessary tight integration with the SAT solver means that Z3 would have to interact via the low-level API of the external SAT solver, e.g. with push and pop functionality. These APIs are not standardized, so the task of integrating e.g. with MiniSat would be different than e.g. the task of integrating with Lingeling. I don't say it's not possible, because Z3 has a modular architecture that is meant to be extended, but I think this would be a major work effort.
It might be that one of the Z3 devs shows up and proves me wrong, though.

possible to extract an unsat core when using 'nlsat' solver

In the previous question solve nonlinear constraints, I asked whether z3 could give a sound and complete result when using nlsat solver to handle polynomial constraints on nonlinear real arithmetic. As Taylor answered, the nksat solver is complete and sound.
Z3 supports unsat core extraction when solving constraints on LRA. I want to know that whether
it possible to extract an unsat core when using the nlsat solver? If z3 does not support,
can I implement it on top of z3? A further question is how large problem it can handle.
The solver for non-linear constraints does not support core extraction so you will not be able to retrieve a core directly. You can implement a bisection search (quick-explain) on top of Z3 for a (minimal) core. It will require several calls so it depends on your application if it is going to
be practical.

Incorrect Behavior for tactic solver for timeout

I am trying to use tactic solver in Z3, to solver a problem of some X constraints as opposed to general purpose solver.
I am using the following tactics -
simplify purify-arith elim-term-ite reduce-args propagate-values solve-eqs symmetry-reduce smt sat sat-preprocess
I apply the tactics one after another to the problem by using Z3_tactic_and_then API.
Also I am using this technique in order to configure the time-out for the solver.
Now, for the same problem if I use a general solver, it times out for the query for the specified time-out. However, if I use the mentioned tactics for the solver, then it does not time-out in the given time. It runs much longer.
For example, I specified a timeout of 180*1000 milliseconds, but it timed out in 730900 milliseconds.
I tried to remove a few tactics mentioned above, but the behaviour was still the same.
Z3 version 4.1
Unfortunately, not every tactic respects the timeout. The tactic smt is a big "offender". This tactic wraps a very old solver implemented in Z3. Unfortunately, this solver cannot be interrupted during some expensive computations because it would leave the system in a corrupted state. That is, Z3 would crash in future operations. When this solver was implemented, a very simplistic design was used. If we want to interrupt the process: kill it. Of course, this is not acceptable when using Z3 embedded in bigger applications. New code is usually much more responsive to timeouts, and we try to avoid this kind of poor design.

Resources