When Z3 is run with no logic specified, and (check-sat) is issued, the logic in default_tactic.cpp is used to conditionally invoke the "best" solver. I would like to access this default tactic from the SMT-LIB 2 interface.
I tried translating the logic from default_tactic.cpp into SMT-LIB, and I came up with this:
(check-sat-using (and-then simplify
(cond is-qfbv qfbv
(cond is-qflia qflia
(cond is-qflra qflra
(cond is-qfnra qfnra
(cond is-qfnia qfnia
(cond is-nra nra
(cond is-lira lira
(cond is-qffpabv qffpa
smt))))))))))
This "almost" works, in that, if you delete the lines with nra, lira, and qffpa, then Z3 will execute this without issue. It seems that those three tactics are not exposed with the SMT-LIB 2 interface of Z3 4.4.1. Another problem with this, though, is that if the default tactic is updated in a future revision of Z3, then any hard-coded strategy like what I wrote above would not be updated.
What I would really like to do is issue a command like (check-sat-using default), or something similar, and get the same result as as obtained with (check-sat). Is this possible?
The file you refer to is very old. Z3 has since moved to GitHub and the latest version of default_tactic.cpp is here.
The default tactic for QF_FP is now called qffp, the lira tactic has since been exported as well and I just exported nra as well (as of this commit).
Edit: As of this commit, the default tactic has also been exported, so it's now possible to write (check-sat-using default) as requested.
Related
There are several posts regarding the conversion of bit vectors
to integers (and vice versa) in z3. See for example here,
here and here.
The documentation says that Z3_mk_bv2int is uninterpreted:
"...This function is essentially treated as uninterpreted.
So you cannot expect Z3 to precisely reflect the semantics of this
function when solving constraints with this function..."
However, I could not find a simple example where it does fail
to reflect the expected semantics.
For instance, whenever I use queries like this:
(declare-const s String)
(declare-const someBitVec10 (_ BitVec 10))
(assert (= s "74g\x00!!#2#$$"))
(assert (str.in.re (str.at s (bv2int someBitVec10)) (re.range "1" "3")))
(check-sat)
(get-value (s someBitVec10))
I get a correct answer (index should 7, and it is)
sat
((s "74g\x00!!#2#$$")
(someBitVec10 #b0000000111))
Could anyone please provide a simple example where z3's
bv2int and/or int2bv fail?? thanks!
This issue is now resolved, as it turns out that both int2bv and bv2int are indeed interpreted. The documentation hasn't been updated, and this might have caused the confusion (at least in my case it did). All the details are in this GitHub/z3/issues post.
I am experimenting with Z3, and more specifically with muZ, however some queries fail, and I don't understand why.
For example this definition of implication
(declare-rel imp (Bool Bool))
(declare-var post Bool)
(rule (imp false post))
(rule (=> (imp true post) post))
(query (imp true false) :print-certificate true)
gives the error (error "query failed: Illegal head. The head predicate needs to be uninterpreted and registered (as recursive) (= (:var 0) true)")
Much larger examples, with many parameters defined with the same structure work as expected. Furthermore by removing the second rule I get the error ERROR: certificates are not supported for datalog which makes me suspect that for some reason this problem is being incorrectly interpreted as datalog, and the larger problems are being interpreted as fixedpoints.
What makes this query fail?
The format form rules generally assumes that rules have uninterpreted predicates in the head. The second rule has a bound variable in the head.
If you add non-propositional features to the datalog rules, such as arithmetic,
the fixedpoint engine will seek to dispatch an engine that understands such features. You can control the engine by specifying (set-option :fixedpoint.engine 'engine-name'), where 'engine-name' is datalog/duality/pdr, etc. Support for certificates and answers vary among the engines.
Is there a way to pass assumptions from (check-sat ...) statement of SMT2 formula into the solver ?
Consider the following example formula stored in ex.smt2:
# cat ex.smt2
(declare-fun p () Bool)
(assert (not p))
(check-sat p)
Running z3 on it gives unsat, as expected. Now, I'd like to solve with assumptions (p) through z3py interface:
In [30]: ctx = z3.Context()
In [31]: s = z3.Solver(ctx=ctx)
In [32]: f = z3.parse_smt2_file("ex.smt2", ctx=ctx)
In [33]: s.add(f)
In [34]: s.check()
Out[34]: sat
Is there an API to get assumptions (i.e. (p) in this example) from the parser ? Or even better, just tell the solver to solve with the assumptions read from the input file ?
No, there is no such API. The parse_smt2_file API is very simple, and only provides access to the assertions in the input file. Extending this API is in the TODO list, but nobody is currently working on that.
I am trying to solve a SAT problem with 12000+ boolean variables using Z3.
I expect that most of the variables will evaluate to false in the solution.
Is there a way to guide or hint Z3 as SAT solver to try "polarity false" first?
I've tried it with cryptominisat 2 and got good results.
Z3 is a collection of solvers and preprocessors. We can provide hints for some of the solvers.
When the command (check-sat) is used, Z3 will select the solver automatically for us.
We should (check-sat-using <strategy>) if we want to select the solver ourselves.
For example, the following command will instruct Z3 to use a Boolean SAT solver.
(check-sat-using sat)
We can force it to always try "polarity false" first by using:
(check-sat-using (with sat :phase always-false))
We can also control the preprocessing steps. If we want to put the formula in CNF before invoking sat, we should use:
(check-sat-using (then tseitin-cnf (with sat :phase always-false)))
EDIT: if you are using the DIMACS input format and Z3 v4.3.1, then you can't set parameters for all available solvers using the command line. The next release will address this limitation. In the meantime, you can download the work-in-progress branch using:
git clone https://git01.codeplex.com/z3 -b unstable
and compile Z3. Then, to force polarity false, we use the command line option
sat.phase=always_false
The command z3 -pm:sat will display all available options for this module.
END EDIT
Here is a complete example in SMT 2.0 (also available online):
(declare-const p Bool)
(declare-const q Bool)
(declare-const r Bool)
(declare-const s Bool)
(assert (or (not p) (not q) (not r)))
(assert (or r s))
(assert (or r (not s)))
(assert (or r (and p q)))
(echo "With always false")
(check-sat-using (then tseitin-cnf (with sat :phase always-false)))
(get-model)
(echo "With always true")
(check-sat-using (then tseitin-cnf (with sat :phase always-true)))
(get-model)
While debugging UNSAT query I noticed an interesting difference in the query status. The query structure is:
assert(...)
(push) ; commenting any of these two calls
(check-sat) ; makes the whole query UNSAT, otherwise it is SAT
assert(...)
(check-sat) ; SAT or UNSAT depending on existence of previous call
(exit)
There are no pop calls in the query. The query that triggers this behaviour is here.
Ideas why?
Note: I don't actually need incrementality, it is for debugging purposes only. Z3 version is 3.2.
This is a bug in one of the quantifier reasoning engines. This bug will be fixed. In the meantime, you can avoid the bug by using datatypes instead of uninterpreted sorts + cardinality constraints. That is, you declare Q and T as:
(declare-datatypes () ((Q q_accept_S13 q_T0_init q_accept_S7
q_accept_S6 q_accept_S5 q_accept_S4 q_T0_S3 q_accept_S12 q_accept_S10
q_accept_S9 q_accept_all)))
(declare-datatypes () ((T t_0 t_1 t_2 t_3 t_4 t_5 t_6 t_7)))
The declarations above are essentially defining two "enumeration" types.
With these declarations, you will get a consistent answer for the second query.