Microsoft Z3 Dot Net API, Cloning Solver - z3

I want to run my z3 code on multiple threads parallelly. In my program structure, I initialize my Z3 solver first with all assertions and then ask for satisfiable solution.
Is there any way to clone Z3 solver, so that I can create multiple clones and pass the clone to multiple threads?
My idea is...
Solver slvr1;
//initialize and add all assertions on solver 1.
//then create N number of clone solvers.
//Finally run each solver clone on each thread.
I can offcourse create the clone myself my creating an array of solver and assert in each of them during the assertion process, but I don't want to do that, as that may not be efficient.
I am using dot net API. So if anyone can answer me in dot net api context, it would be more helpful.

There is a method to translate solvers between contexts. Use this.
https://github.com/Z3Prover/z3/blob/master/src/api/dotnet/Solver.cs
Remember that contexts are not thread safe, so use different contexts in different threads.

Related

Skolem functions in SMT and ATPs

While reading Extending Sledgehammer with SMT solvers I read the following:
In the original Sledgehammer architecture, the available lemmas were rewritten
to clause normal form using a naive application of distributive laws before the relevance filter was invoked. To avoid clausifying thousands of lemmas on each invocation, the clauses were kept in a cache. This design was technically incompatible with the (cache-unaware) smt method, and it was already unsatisfactory for ATPs, which include custom polynomial-time clausifiers.
My understanding of SMT so far is as follows: SMTs don't work over clauses. Instead, they try to build a model for the quantifier-free part of a problem. The search is refined by instantiating quantifiers according to some set of active terms. Thus, indeed no clausal form is needed for SMT solvers.
We rewrote the relevance filter so that it operates on arbitrary HOL formulas, trying to simulate the old behavior. To mimic the penalty associated with Skolem functions in the clause-based code, we keep track of polarities and detect quantifiers that give rise to Skolem functions.
What's the penalty associated with Skolem functions? I could understand they are not good for SMTs, but here it seems that they are bad for ATPs too...
First, SMT solvers do work over clauses and there is definitely some (non-naive) normalization internally (e.g., miniscoping). But you do not need to do the normalization before calling the SMT solver (especially, since it will be more naive and generate a larger number of clauses).
Anyway, Section 6.6.7 explains why skolemization was done on the Isabelle side. To summarize: it is not possible to introduce polymorphic constants in a proof in Isabelle; hence it must be done before starting the proof.
It seems likely that, when writing the paper, not changing the filtering lead to worse performance and, hence, the penalty was added. However, I tried to find the relevant code simulating clausification in Sledgehammer, so I don't believe that this happens anymore.

Z3: combining optimization and fixedpoints

I can explain to whatever depth is necessary, but the long story short is that my project uses Z3's optimizer to find the maximal solution to what is effectively a SAT problem with weights associated to the boolean variables. Separately to that, another part of my project effectively implements a rule-based saturation engine, which I've lately been considering rewriting using the fixedpoint solver. I thought I could consider the two parts of the problem separately, but it turns out that there is a chicken-and-egg issue where the rule engine requires the solution to the SAT instance in order for its input and output to be correct and meaningful, and that the SAT instance itself is derived from the output of the rule engine. Therefore, I thought I might try to combine Fixedpoint and Optimize. Is this possible? Does it even make sense?

Can I set the priority of boolean variables in z3?

Since the question is a little hard to describe, I will use a small example to describe my question.
Suppose there is a propositional formula set whose elements are Boolean variables a,b and c.
When using z3 to get a truth assignment of this formula set, does there exist some way to set the priority of the variables? I mean that if the priority is a>b>c, then during the searching process z3 firstly assumes a is true and if a is impossible to be true it assumes b is true and so on. In another words, if z3 gives a truth assignment: not a,b,c under the aforementioned priority it means a is impossible to be true because a is high-priority compared with b. Hope I describe the question clearly.
There is not easy way to do it in the current release (v4.3.1). The only way I can see is to hack/modify the Z3 source code (http://z3.codeplex.com). We agree that setting priorities is a useful feature for some applications, however there are some problems.
First, Z3 applies several transformations (aka preprocessing steps) before solving a problem. Variables are created and eliminated. Thus, a case-split priority for the original problem may be meaningless for the actual problem (the one generated after applying all transformations) that is solved by Z3.
One dramatic example is a formula containing only Bit-vectors. By default, Z3 will reduce this formula into Propositional logic and invoke a Propositional SAT solver. In this reduction, all Bit-vector variables are eliminated.
Z3 is a collection of solvers and preprocessors. By default, Z3 will select a solver automatically for the user. Some of these solvers use completely different algorithms. So, the provided priority may be useless for the solver being used.
As GManNickG pointed out, it is possible to set the phase selection strategy for a particular solver. See the post provided in his comment for additional details.

Is it possible to quantify over SMT models?

I need to check whether every satisfying instance of some smt problem has a matching instance from some other smt problem.
i.e. "forall instances of A exists instances of B s.t. ...." where A and B are sat models generated from some smt-lib code.
I've been thinking about this a lot but can't figure how to do it

Has anyone tried proving Z3 with Z3 itself?

Has anyone tried proving Z3 with Z3 itself?
Is it even possible, to prove that Z3 is correct, using Z3?
More theoretical, is it possible to prove that tool X is correct, using X itself?
The short answer is: “no, nobody tried to prove Z3 using Z3 itself” :-)
The sentence “we proved program X to be correct” is very misleading.
The main problem is: what does it mean to be correct.
In the case of Z3, one could say that Z3 is correct if, at least, it never returns “sat” for an unsatisfiable problem, and “unsat” for a satisfiable one.
This definition may be improved by also including additional properties such as: Z3 should not crash; the function X in the Z3 API has property Y, etc.
After we agree on what we are supposed to prove, we have to create models of the runtime, programming language semantics (C++ in the case of Z3), etc.
Then, a tool (aka verifier) is used to convert the actual code into a set of formulas that we should check using a theorem prover such as Z3.
We need the verifier because Z3 does not “understand” C++.
The Verifying C Compiler (VCC) is an example of this kind of tool.
Note that, proving Z3 to be correct using this approach does not provide a definitive guarantee that Z3 is really correct since our models may be incorrect, the verifier may be incorrect, Z3 may be incorrect, etc.
To use verifiers, such as VCC, we need to annotate the program with the properties we want to verify, loop invariants, etc. Some annotations are used to specify what code fragments are supposed to do. Other annotations are used to "help/guide" the theorem prover. In some cases, the amount of annotations is bigger than the program being verified. So, the process is not completely automatic.
Another problem is cost, the process would be very expensive. It would be much more time consuming than implementing Z3.
Z3 has 300k lines of code, some of this code is based on very subtle algorithms and implementation tricks.
Another problem is maintenance, we are regularly adding new features and improving performance. These modifications would affect the proof.
Although the cost may be very high, VCC has been used to verify nontrivial pieces of code such as the Microsoft Hyper-V hypervisor.
In theory, any verifier for programming language X can be used to prove itself if it is also implemented in language X.
The Spec# verifier is an example of such tool.
Spec# is implemented in Spec#, and several parts of Spec# were verified using Spec#.
Note that, Spec# uses Z3 and assumes it is correct. Of course, this is a big assumption.
You can find more information about these issues and Z3 applications on the paper:
http://research.microsoft.com/en-us/um/people/leonardo/ijcar10.pdf
No, it is not possible to prove that a nontrivial tool is correct using the tool itself. This was basically stated in Gödel's second incompleteness theorem:
For any formal effectively generated theory T including basic arithmetical truths and also certain truths about formal provability, if T includes a statement of its own consistency then T is inconsistent.
Since Z3 includes arithmetic, it cannot prove its own consistency.
Because it was mentioned in a comment above: Even if the user provides invariants, Gödels's theorem still applies. This is not a question of computability. The theorem states that no such prove can exist in a consistent system.
However you could verify parts of Z3 with Z3.
Edit after 5 years:
Actually the argument is easier than Gödel's incompleteness theorem.
Let's say Z3 is correct if it only returns UNSAT for unsatisfiable formulas.
Assume we find a formula A, such that if A is unsatisfiable then Z3 is correct (and we somehow have proven this relation).
We can give this formula to Z3, but
if Z3 returns UNSAT it could be because Z3 is correct or because of a bug in Z3. So we have not verified anything.
if Z3 returns SAT and a countermodel, we might be able to find a bug in Z3 by analyzing the model
otherwise we don't know anything.
So we can use Z3 to find bugs in Z3 and to improve confidence about Z3 (to an extremely high level), but not to formally verify it.

Resources