z3 produces unknown for assertions without quantifiers - z3

I have some simple constraints involving multiplication of reals in z3 that are producing unknown. The problem seems to be that they are wrapped in a datatype, as the unwrapped version produces sat.
Here is a simplified case:
(declare-datatypes () ((T (NUM (n Real)))))
(declare-const a T)
(declare-const b T)
(declare-const c T)
(assert (is-NUM a))
(assert (is-NUM b))
(assert (is-NUM c))
(assert (= c (NUM (* (n a) (n b)))))
(check-sat)
;unknown
And without the datatype:
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
(assert (= c (* a b)))
(check-sat)
;sat
I'm using z3 3.2, but this also is reproducible in the web interface.

Yes, Z3 can return unknown in quantifier-free problems.
Here are the main reasons:
Run out of time or memory
The quantifier-free fragment is undecidable (e.g., nonlinear integer arithmetic)
The quantifier-free fragment is too expensive, and/or the procedure implemented in Z3 is incomplete.
Your problems are in a decidable fragment, and the unknown is due to the incomplete procedure for nonlinear arithmetic used in Z3. Z3 4.0 has a complete procedure for nonlinear real arithmetic, but it is still not integrated with the other theories. So, it will not help in the first problem.
The different in behavior in the first and second queries is due to different strategies used for each query. Z3 has a new framework for defining custom strategies. You can get sat for the first query by using the command
(check-sat-using (then simplify solve-eqs smt))
instead of
(check-sat)
The first command forces Z3 to eliminate variables by solving equalities (i.e., tactic solve-eqs). It will eliminate the equality (= c (NUM (* (n a) (n b)))). This tactic is automatically used in the second problem in Z3 3.x. Note that this tactic will not help if we replace the equality with (>= c (NUM (* (n a) (n b)))).
Moreover, the second problem contains only nonlinear arithmetic. So, in Z3 4.0, the new (and complete) solver for nonlinear real arithmetic will be automatically used.
You can learn about the new strategy framework at http://rise4fun.com/Z3/tutorial/strategies, http://rise4fun.com/Z3Py/tutorial/strategies

Your examples are in non-linear arithmetic. Z3 4.0 is able to solve problems with only non-linear arithmetic assertions, but not along with uninterpreted functions and other theories. That explains why it produces unknown in the first example. This limitation is likely to be addressed in Z3's future versions.

Related

Get fractional part of real in QF_UFNRA

Using smtlib I would like to make something like modulo using QF_UFNRA. This disables me from using mod, to_int, to_real an such things.
In the end I want to get the fractional part of z in the following code:
(set-logic QF_UFNRA)
(declare-fun z () Real)
(declare-fun z1 () Real)
(define-fun zval_1 ((x Real)) Real
x
)
(declare-fun zval (Real) Real)
(assert (= z 1.5));
(assert (=> (and (<= 0.0 z) (< z 1.0)) (= (zval z) (zval_1 z))))
(assert (=> (>= z 1.0) (= (zval z) (zval (- z 1.0)))))
(assert (= z1 (zval z)))
Of course, as I am asking this question here, implies, that it didn't work out.
Has anybody got an idea how to get the fractional part of z into z1 using logic QF_UFNRA?
This is a great question. Unfortunately, what you want to do is not possible in general if you restrict yourself to QF_UFNRA.
If you could encode such functionality, then you can decide arbitrary Diophantine equations. You would simply cast a given Diophantine equation over reals, compute the "fraction" of the real solution with this alleged method, and assert that the fraction is 0. Since reals are decidable, this would give you a decision procedure for Diophantine equations, accomplishing the impossible. (This is known as Hilbert's 10th problem.)
So, as innocent as the task looks, it is actually not doable. But that doesn't mean you cannot encode this with some extensions, and possibly have the solver successfully decide instances of it.
If you allow quantifiers and recursive functions
If you allow yourself quantifiers and recursive-functions, then you can write:
(set-logic UFNRA)
(define-fun-rec frac ((x Real)) Real (ite (< x 1) x (frac (- x 1))))
(declare-fun res () Real)
(assert (= (frac 1.5) res))
(check-sat)
(get-value (res))
To which z3 responds:
sat
((res (/ 1.0 2.0)))
Note that we used the UFNRA logic allowing quantification, which is required here implicitly due to the use of the define-fun-rec construct. (See the SMTLib manual for details.) This is essentially what you tried to encode in your question, but instead using the recursive-function-definition facilities instead of implicit encoding. There are several caveats in using recursive functions in SMTLib however: In particular, you can write functions that render your system inconsistent rather easily. See Section 4.2.3 of http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.5-draft.pdf for details.
If you can use QF_UFNIRA
If you move to QF_UFNIRA, i.e., allow mixing reals and integers, the encoding is easy:
(set-logic QF_UFNIRA)
(declare-fun z () Real)
(declare-fun zF () Real)
(declare-fun zI () Int)
(assert (= z (+ zF zI)))
(assert (<= 0 zF))
(assert (< zF 1))
(assert (= z 1.5))
(check-sat)
(get-value (zF zI))
z3 responds:
sat
((zF (/ 1.0 2.0))
(zI 1))
(You might have to be careful about the computation of zI when z < 0, but the idea is the same.)
Note that just because the encoding is easy doesn't mean z3 will always be able to answer the query successfully. Due to mixing of Real's and Integer's, the problem remains undecidable as discussed before. If you have other constraints on z, z3 might very well respond unknown to this encoding. In this particular case, it happens to be simple enough so z3 is able to find a model.
If you have sin and pi:
This is more of a thought experiment than a real alternative. If SMTLib allowed for sin and pi, then you can check whether sin (zI * pi) is 0, for a suitably constrained zI. Any satisfying model to this query would ensure that zI is integer. You can then use this value to extract the fractional part by subtracting zI from z.
But this is futile as SMTLib neither allows for sin nor pi. And for good reason: Decidability would be lost. Having said that, maybe some brave soul can design a logic that supported sin, pi, etc., and successfully answered your query correctly, while returning unknown when the problem becomes too hard for the solver. This is already the case for nonlinear arithmetic and the QF_UFNIRA fragment: The solver may give up in general, but the heuristics it employs might solve problems of practical interest.
Restriction to Rationals
As a theoretical aside, it turns out that if you restrict yourself to rationals only (instead of actual reals) then you can indeed write a first-order formula to recognize integers. The encoding is not for the faint of heart, however: http://math.mit.edu/~poonen/papers/ae.pdf. Furthermore, since the encoding involves quantifiers, it's probably quite unlikely that SMT solvers will do well with a formulation based on this idea.
[Incidentally, I should extend thanks to my work colleagues; this question made for a great lunch-time conversation!]

Mixing theories in SMT

I would like to construct an SMT formula having a number of assertions over integer linear arithmetic and Boolean variables as well as some assertions over real non-linear arithmetic and again Boolean variables. The assertions over integers and reals share only the Boolean variables. As an example, consider the following formula:
(declare-fun b () Bool)
(assert (= b true))
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (or (not b) (>= (+ x y) (- x (+ (* 2 z) 1)))))
(declare-fun r () Real)
(assert (or (not b) (= (+ (* r r) (* 3 r) (- 4)) 0)))
If I feed z3 with this formula, it immediately reports "unknown". But if I remove the integer part of it, I get the solution right away, which satisfies the constraint with variable "r". I presume this means that the non-linear constraint on its own is not hard for the solver. The issue should be in mixing (linear) constraints over integers and (non-linear) constraints over reals.
So my question is the following. What is the correct way to handle this kind of mixed formulas using z3 (if there is any)? My understanding of DPLL(T) is that it should be able to deal with such formulas using different theory solvers for different constraints. Please, correct me if I am wrong.
As George said in his comment, the non-linear solver in Z3 is rather fragile and the out-of-the-box performance isn't great. That said, there are a number of questions and answers about this problem here on stackoverflow, e.g., see these:
Z3 Performance with Non-Linear Arithmetic
How does Z3 handle non-linear integer arithmetic?
Z3 : strange behavior with non linear arithmetic
Non-linear arithmetic and uninterpreted functions
Z3 Theorem Prover: Pythagorean Theorem (Non-Linear Artithmetic)
Which techniques are used to handle Non-linear Integer Real problems in z3?
Satisfiablity checking in non-linear integer arithmetic by approximation

Why Z3 always return unknown when assertions have power?

Here is the input
Example 1
(declare-var a Int)
(declare-var b Int)
(declare-var n Int)
(assert (= b (* a a)))
(assert (not (= b (^ a 2))))
(check-sat)
Example 2
(declare-var a Int)
(declare-var b Int)
(declare-var n Int)
(assert (= b (* (^ a n) a)))
(assert (not (= b (^ a (+ n 1)))))
(check-sat)
It returns unknown almost instantaneously.
Your problem falls into the fragment known as non-linear integer arithmetic, which is undecidable. That is, there is no decision procedure to determine the satisfiability of your query. (Non-linear means, basically, there is a multiplicative term involving at least two variables.)
Having said that, most solvers do have heuristics to answer queries involving non-linear arithmetic, and Z3 is no exception. Of course, being a heuristic, it may or may not produce an answer. This is what you are observing, alas it appears the default tactics Z3 uses is just not sufficient for your problems.
As a common trick, you can try Z3's non-linear real-arithmetic solver for these sorts of problems. Instead of check-sat, use:
(check-sat-using qfnra-nlsat)
In this case, Z3 tries to solve the benchmark assuming the inputs are reals, and sees if the solution is actually integer. This trick can successfully resolve some integer-nonlinear arithmetic queries, though of course not always. For instance, if you try qfnra-nlsat on your first example you'll see that it successfully solves it, but it still answers unknown for the second one.
For details on non-linear integer arithmetic and Z3, see here: How does Z3 handle non-linear integer arithmetic?

Non-linear arithmetic and uninterpreted functions

(declare-const x Real)
(declare-fun f (Real) Real)
(assert (= (f 1.0) 0.0))
(assert (= (* x x) (* 1.0 1.0)))
(check-sat)
(get-model)
I have two independent assertions one in non-linear arithmetic and other uninterpreted functions. Z3 gives a "model is not available" to the problem above. Is there a way to set the logic to something that can handle both at the same time? Thank you.
The new nonlinear solver is not integrated with other theories (arrays, unintepreted functions, bit-vectors) yet. In Z3 4.0, it can only be used to solve problems that contain only nonlinear arithmetic assertions. This is will change in future versions.

Equivalent Quantifier Free Formulas

I want to know if Z3 can show equivalent formulas after Quantifier Elimination.
Example (exists k) (i x k) = 1 and k > 5
is equivalent to
i > 0 and 5 i - 1 < 0.
Here, quantifier k has been eliminated.
Is this possible?
Thanks,
Kaustubh.
Yes, Z3 can check whether two formulas are equivalent. To check whether p and q are equivalent. We must check whether (not (iff p q)) is unsatisfiable.
Your example uses nonlinear arithmetic i*k. The quantifier elimination module in Z3 has limited support for nonlinear real arithmetic. It is based on virtual term substitution, which is not complete. However, it is sufficient for your example.
We must enable the quantifier elimination module in Z3, and the nonlinear extensions (i.e., virtual term substitution).
Here is how we can encode your example in Z3: http://rise4fun.com/Z3/rXfi
In general, the result of eliminating quantifiers can be obtained. For instance by entering the following into rise4fun:
(declare-const i Real)
(assert (exists ((k Real)) (and (= (* i k) 1.0) (> k 5.0))))
(apply qe)
This case involves non-linear arithmetic, and Z3 does not eliminate the quantifier.

Resources