Optimize Solver Tactics for Circuit SAT - z3

I am using the Z3 solver with Python API to tackle a Circuit SAT problem.
It consists of many Xor expressions with up to 21 inputs and three-input And expressions. Z3 is able to solve my smaller examples but does not cope with the bigger ones.
Rather than creating the Solver object with
s = Solver()
I tried to optimize the solver tactics like in
t = Then('simplify', 'symmetry-reduce', 'aig', 'tseitin-cnf', 'sat' )
s = t.solver()
I got the tactics list via describe_tactics()
Unfortunately, my attempts have not been fruitful. The default sequence of tactics seems to do a pretty good job. The tactics tutorial previously available in rise4fun is no longer accessible.
Another attempt - without visible effect - was to set the phase parameter, as I am expecting the majority of my variables to have false values. (cf related post)
set_option("sat.phase", "always-false")
What sequence of tactics is recommended for Circuit SAT problems?

Related

Some questions about incremental SAT in Z3: can it be deactivated? Which techniques are used inside?

I am still in the process of learning the guts of Z3 (Python).
It was brought to my attention that Z3 performs incremental SAT solving by default (see SAT queries are slowing down in Z3-Python: what about incremental SAT?): specifically, every time you use the s.add command (where s is a solver), it means that it adds that clause to s, but it does not forget everything you have learned before.
First question: can non-incremental SAT solving be done in Z3? That is, somehow 'deactivate' the incremental solving. What would this mean? That we are creating a new solver for each enlarged formula?
For instance, this approach would be Z3-default-incremental:
...
phi = a_formula
s = Solver()
s.add(phi)
while s.check() == sat:
s.check()
m = s.model()
phi = add_modelNegation(m)
s.add(phi) #in order not to explore the same model again
...
That is, once we get a model, we attach the negated model to the same solver.
While this one is 'forcing' Z3 to be non-incremental:
...
phi_st = a_formula
s = Solver()
s.add(phi_st)
negatedModelsStack = []
while s.check() == sat:
m = s.model()
phi_n = add_modelNegation(m)
negatedModelsStack.append(phi_n)
original_plus_negated = And(phi_st, And(negatedModelsStack))
s = Solver()
s.add(original_plus_negated) #in order not to explore the same model again
...
That is, once we get a model, we attach the obtained models to a new solver.
Am I right?
On the other hand, in the attached link, the following is stated:
Compare this to, for instance, CVC4; which is by default not incremental. If you want to use CVC4 in incremental mode, you have to pass a specific command line argument
Does this mean in CVC4 you must create a new solver every time? Like in the second code?
Second question: how can I know exactly what techniques I am using to do incremental solving in Z3? I have been reading about incremental SAT theory and I see that one of those techniques is 'CDCL' (http://www.cril.univ-artois.fr/~audemard/slidesMontpellier2014.pdf), is this used in Z3's incremental search?
References: In order not to inundate Stack with similar questions, which readings do you recommend for incremental SAT in general and Z3's incremental SAT in particular? Also, is the incremental SAT of Z3 similar to the ones of other solvers such as MiniSAT or PySAT?
I'm not sure why you're trying to get z3 to act in a non-incremental way. But, if that's your goal, simply do not call check more than once: That's equivalent to being non-incremental. (Think of being incremental an "additional feature." You don't have to use it. The only difference between z3 and cvc4 is that the latter requires you to tell it ahead of time that you intend to use it in an incremental fashion, while the former is incremental by default.) As an end user you don't really need to know or care about the difference.
Side note If you start cvc4 without telling it to be incremental and call check twice, it'll complain. z3 won't. But otherwise the experience should be the same.
I don't think knowing how solvers implement incrementally is really helpful from a programming perspective. (It's of course paramount if you are implementing your own SMT solver.) There are many papers online for many aspects of SMT, though if you want to study the topic from scratch I recommend Daniel and Ofer's book on decision procedures: http://www.decision-procedures.org

Obtaining representation of SMT formula as SAT formula

I've come up with an SMT formula in Z3 which outputs one solution to a constraint solving problem using only BitVectors and IntVectors of fixed length. The logic I use for the IntVectors is only simple Presburger arithmetic (of the form (x[i] - x[i + 1] <=/>= z) for some x and z). I also take the sum of all of the bits in the bitvector (NOT the binary value), and set that value to be within a range of [a, b].
This works perfectly. The only problem is that, as z3 works by always taking the easiest path towards determining satisfiability, I always get the same answer back, whereas in my domain I'd like to find a variety of substantially different solutions (I know for a fact that multiple, very different solutions exist). I'd like to use this nifty tool I found https://bitbucket.org/kuldeepmeel/weightgen, which lets you uniformly sample a constrained space of possibilities using SAT. To use this though, I need to convert my SMT formula into a SAT formula.
Do you know of any resources that would help me learn how to perform Presburger arithmetic and adding the bits of a bitvector as a SAT instance? Alternatively, do you know of any SMT solver which as an intermediate step outputs a readable description of the problem as a SAT instance?
Many thanks!
[Edited to reflect the fact that I really do need the uniform sampling feature.]

Control the solving strategy of Z3

So lets assume I have a large Problem to solve in Z3 and if i try to solve it in one take, it would take too much time. So i divide this problem in parts and solve them individually.
As a toy example lets assume that my complex problem is to solve those 3 equations:
eq1: x>5
eq2: y<6
eq3: x+y = 10
So my question is whether for example it would be possible to solve eq1 and eq2 first. And then using the result solve eq3.
assert eq1
assert eq2
(check-sat)
assert eq3
(check-sat)
(get-model)
seems to work but I m not sure whether it makes sense performancewise?
Would incremental solving maybe help me out there? Or is there any other feature of z3 that i can use to partition my problem?
The problems considered are usually satisfiability problems, i.e., the goal is to find one solution (model). A solution (model) that satisfies eq1 does not necessarily satisfy eq3, thus you can't just cut the problem in half. We would have to find all solutions (models) for eq1 so that we can replace x in eq3 with that (set of) solutions. (For example, this is what happens in Gaussian elimination after the matrix is diagonal.)

Optimising z3 input

I am trying to optimize z3 python input that is generated from my models. I am able to run it on models up 15k constraints (200 states) and then z3 stops finishing in reasonable time (<10 minutes). Is there a way to optimize the constraints that are generated from my models ?
Model for 3 states:
http://pastebin.com/EHZ1P20C
The performance of the script http://pastebin.com/F5iuhN42 can be improved by using a custom strategy. Z3 allows users to define custom strategies/solvers. This tutorial shows how to define strategies/tactics using the Z3 Python API. In the script http://pastebin.com/F5iuhN42, if we replace the line
s = Solver()
with
s = Then('simplify', 'elim-term-ite', 'solve-eqs', 'smt').solver()
the runtime will decrease from 30 secs to 1 sec (on my machine).
The procedure Then is creating a strategy/tactic composed of 4 steps:
Simplifier (i.e., a rewriter that applies rules such as x + 1 - x + y ==> 1 + y
Elimination of expressions of the form If(a, b, c) where b and c are not Boolean. The script makes extensive use this kind of expression. The tactic elim-term-ite will apply transformations that eliminate this kind of expression.
Equational solver. It applies transformations such as x = a And F[x] ==> F[a]. In the script above, this tactic can eliminate more than 1000 variables.
The tactic smt invokes a general purpose SMT solver in Z3.
The method .solver() converts a Z3 tactic/strategy into a solver object that provides the add and check methods. The tutorial that I included in the beginning of the message has more details.

Symbolic variables in z3

Is there a way to make z3 solver emit "symbolic" solutions? For example, for equation:
1+x=c
the solution is x=c-1, but z3 always emits a specific model, like [c = 0, x = -1]. How to "define" c as a symbolic variable?
Unfortunately, Z3 does not expose this kind of functionality. Although we use solvers internally, they are not exposed in the API. In future versions, we want to expose internal components such as: solver, Grobner bases procedures, etc. In the current version, we have a tactic called solve-eqs (see http://rise4fun.com/Z3Py/tutorial/strategies). It eliminates variables using a generalization of Gaussian elimination. However, this is a preprocessing step, and you do not have any control over which variables are eliminated.

Resources