Convert formula to CNF - z3

Is there a way to use z3 to convert a formula to CNF (using Tseitsin-style encoding)? I am looking for something like the simplify command, but guaranteeing that the returned formula is CNF.

You can use the apply command for doing it. We can provide arbitrary tactics/strategies to this command. For more information about tactics and strategies in Z3 4.0, check the tutorial http://rise4fun.com/Z3/tutorial/strategies
The command (help-tactic) can be used to display all available tactics in Z3 4.0 and their parameters. The programmatic is more convenient to use and flexible. Here is a tutorial based on the new Python API: http://rise4fun.com/Z3Py/tutorial/strategies.
The same capabilities are available in the .Net and C/C++ APIs.
The following script demonstrates how to convert a formula into CNF using this framework:
http://rise4fun.com/Z3/TEu6

The example link #Leonardo provided is broken now. Found the code using wayback machine. Posting it here so future seekers may make use of it:
(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(assert (iff (> x 0) (> y 0)))
(assert (or (and (= x 0) (= y 0)) (and (= x 1) (= y 1)) (and (= x 2) (= y 2))))
(assert (if (> x 0) (= y x) (= y (- x 1))))
(assert (> z (if (> x 0) (- x) x)))
(apply (then (! simplify :elim-and true) elim-term-ite tseitin-cnf))
(echo "Trying again without using distributivity...")
(apply (then (! simplify :elim-and true) elim-term-ite (! tseitin-cnf :distributivity false)))

Related

Z3 support for exponentials

I'm new to Z3 and I'm trying to understand how it works, and what it can and cannot do. I know that Z3 has at least some support for exponentials through the power (^) operator (see Z3py returns unknown for equation using pow() function, How to represent logarithmic formula in z3py, and Use Z3 and SMT-LIB to define sqrt function with a real number). What I'm unclear on is how extensive this support is, and what kind of inferences z3 can make about exponentials.
Here's a simple example involving exponentials which z3 can analyze. We define an exponential function, and then ask it to verify that exp(0) == 1:
(define-fun exp ((x Real)) Real
(^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (=> (= x1 0.0) (= y1 1.0))))
(check-sat)
(exit)
Z3 returns unsat, as expected. On the other hand, here's a simple example which Z3 can't analyze:
(define-fun exp ((x Real)) Real
(^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (< y1 0.0)))
(check-sat)
(exit)
This should be satisfiable, since literally any value for x1 would give y1 > 0. However, Z3 returns unknown. Naively I might have expected that Z3 would be able to analyze this, given that it could analyze the first example.
I realize this question is a bit broad, but: can anyone give me any insight into how Z3 handles exponentials, and (more specifically) why it can solve the first example I gave but not the second?
It is hard to say in general, since non-linear solving is challenging, but the case you presented is actually not so mysterious. You wrote:
(assert (= y (exp x)))
(assert (not (=> (= x 0) (= y 1))))
Z3 is going to simplify the second assertion, yielding:
(assert (= y (exp x)))
(assert (= x 0))
(assert (not (= y 1)))
Then it will propagate the first equality, yielding:
(assert (= y (exp 0)))
(assert (not (= y 1)))
Now when exp is expanded, you have a case of constant^constant, which Z3 can handle (for integer exponents, etc).
For the second case, you are asking it a very very basic question about variable exponents, and Z3 immediately barfs. That's not too odd, since so many questions about variable exponents are either known uncomputable or unknown but hard.

z3 4.3.2 fails to find a model for Why3-generated (satisfiable) goals

I'm trying to use Why3's Z3 back-end in order to retrieve models that can then be used to derive test cases exhibiting bugs in programs. However, Z3 version 4.3.2 seems unable to answer sat for any Why3 goal. It looks like some of the axiomatic definitions used by Why3 somehow confuse Z3. For instance, the following example (which is a tiny part of what Why3 generates)
(declare-fun abs1 (Int) Int)
;; abs_def
(assert
(forall ((x Int)) (ite (<= 0 x) (= (abs1 x) x) (= (abs1 x) (- x)))))
(check-sat)
results in timeout with the following command line:
z3 -smt2 model.partial=true file.smt2 -T:10
On the other hand, changing the definition to
(declare-fun abs1 (Int) Int)
;; abs_def
(assert
(forall ((x Int)) (=> (<= 0 x) (= (abs1 x) x))))
(assert
(forall ((x Int)) (=> (> 0 x) (= (abs1 x) (- x)))))
will get me a model (which looks pretty reasonable)
(model
(define-fun abs1 ((x!1 Int)) Int
(ite (>= x!1 0) x!1 (* (- 1) x!1)))
)
but if I try to add the next axiom present in the original Why3 file, namely
;; Abs_pos
(assert (forall ((x Int)) (<= 0 (abs1 x))))
again Z3 answers timeout.
Is there something I'm missing in the configuration of Z3? Moreover, in previous versions of Why3, there was an option MODEL_ON_TIMEOUT, which allowed to retrieve a model in such circumstances. Even though there was no guarantee that this was a real model since Z3 could not finish to check it, in practice such models generally contained all the information I needed. However, I haven't found a similar option in 4.3.2. Does it still exist?
Update The last axiom Abs_pos was wrong (I toyed a bit with Why3's output before posting here and ended up pasting an incorrect version of the issue). This is now fixed.
The additional axiom
(assert (not (forall ((x Int)) (<= 0 (abs1 x)))))
makes the problem unsatisfiable, since abs1 always returns a non-negative integer and with the additional axiom you require the existence of a negative result for abs1 for some x. The web version of Z3 returns unsat as expected, see here.

Can Z3 output "anything" for unconstrained values of UF?

Some values of uninterpreted functions can be unconstrained during the search. For example, if in smt query only f(1) is called, then f(2), f(3) can be anything. Is there a way (some option may be) to know which values were not used during the solving and therefore can be anything?
For quantifier free problems, you can achieve that by using the option :model-partial to true.
Here is an example (also available here):
(set-option :model-partial true)
(declare-fun f (Int) Int)
(assert (> (f 0) 0))
(assert (< (f 1) 0))
(check-sat)
(get-model)
In this example, we get the output:
sat
(model
(define-fun f ((x!1 Int)) Int
(ite (= x!1 0) 1
(ite (= x!1 1) (- 1)
#unspecified)))
)
BTW, in the next release (Z3 4.3.2), this option is renamed to :model.partial. In the next release, the options are grouped in modules.

simplification in Z3

(declare-datatypes () ((SE BROKEN ON OFF)))
(declare-const s SE)
(declare-const a Int)
(simplify (or (= s ON) (= s OFF) (= s BROKEN)))
(simplify (and (> a 0) (> a 1)))
The result is:
(or (= s ON) (= s OFF) (= s BROKEN))
(and (not (<= a 0)) (not (<= a 1)))
But the expected result was:
1
> a 1
Is it possible to simplify such expressions (the combinations of such expressions) in Z3?
Thank you!
The simplify command is just a bottom-up rewriter. It is fast, but will fail to simplify expressions such as the ones in your post. Z3 allows users to define their own simplification strategies using tactics. They are described in this article, and the Z3 tutorials (Python and SMT 2.0). The following posts also have additional information:
t>=1 or t>=2 => t>=1
Asymmetric behavior in ctx-solver-simplify
what's the difference between "simplify" and "ctx-solver-simplify" in z3
The first query in your example can be simplified using the tactic ctx-solver-simplify (also available online here).
(declare-datatypes () ((SE BROKEN ON OFF)))
(declare-const s SE)
(declare-const a Int)
(assert (or (= s ON) (= s OFF) (= s BROKEN)))
(assert (and (> a 0) (> a 1)))
(apply ctx-solver-simplify)
The command apply applies the tactic ctx-solver-simplify over the set of assertions, and displays the resulting set of goals. Note that, this tactic is way more expensive than the command simplify.

How to get "stronger" simplifications of conjunctions in Z3?

Using Z3 version 2.18, I am trying to simplify formulas such as:
(and (> (- (- x 1) 1) 0) (> x 0))
(or (> (- (- x 1) 1) 0) (> x 0))
hoping to get something like: (> x 2) and (> x 0).
I am running Z3 with the following input file where F is one of the above formulas:
(set-option set-param "STRONG_CONTEXT_SIMPLIFIER" "true")
(declare-const x Int)
(simplify F)
It works well with the disjunction where I get the following output:
(let (($x35 (<= x 0)))
(not $x35))
However, with the conjunction, I get:
(not (or (<= x 0) (<= x 2)))
Is there a way to force Z3 to simplify even more the above formula ? I would hope to be able to get (not (<= x 2)).
PS: Is there a way to force Z3 to inline its output (i.e. having (not (<= x 0)) instead of (let (($x35 (<= x 0))) (not $x35)))
Thanks,
Gus
No, you can't do that on Z3 2.x.
Z3 3.x has a new (fully compliant) SMT 2.0 front-end.
Z3 3.x has several new features such as a "strategy specification language" based on tactics and tacticals. I'm not "advertising" that yet because it is working in progress. The basic idea is described in this slide deck. This language can be used to do what you want. You just have to write:
(declare-const x Int)
(assert (not (or (<= x 0) (<= x 2))))
(apply (and-then simplify propagate-bounds))
You can find all available tactics by using the commands:
(help-strategy)
(help apply)
(help check-sat-using)

Resources