z3: What might be the reason for timeout - z3

What might be the reason for timeout for the following program in z3.
http://rise4fun.com/Z3/pbEOw
(declare-const a Int)
(declare-const a2 Int)
(declare-const b Int)
(assert (> b 0))
(assert (>= a a2))
(assert (< (div a b) (div a2 b)))
(check-sat)
(get-model)

The second operand of the division operator is a variable.
This makes the constraints non-linear and the search for satisfying interpretations of non-linear constraints is in general not terminating (it is also undecidable in general).

Related

Z3 should be able to verify this program?

I am a beginner user of Z3. Recently, I have been using z3 to verify some problems. Here is one problem I tried: (x < 0 && y < 0) implies x/y >= 0, below are the programs I wrote:
(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
(and (< x 0) (< y 0))
)
(define-fun predicate() Bool
(<= 0 (div x y))
)
(assert (not (=> assumption predicate)))
(check-sat)
When I use 'z3 -smt2 filename' to verify this program, it works and return unsat. However, when I later modify the program to:
(declare-const x Int)
(declare-const y Int)
(define-fun assumption() Bool
(and (< x 0) (< y 0))
)
(define-fun predicate() Bool
(<= 0 (div (* -1 x) (* -1 y)))
)
(assert (not (=> assumption predicate)))
(check-sat)
This cause z3 to timeout when I changed 'x/y' to (-1 * x)/(-1 * y) and somehow I need to add -1 there. I am confused why this happened and why multiplied by a constant makes this problem more complex.
Can somebody help figure out why this happened?
Thank you!
There is very limited support for non-linear arithmetic, such as division where the divisor is a variable.
So Z3 will do a best effort, but in no way be sure to provide decisions on every formula with non-linear arithmetical operations. So for example, you can enter Diophantine equations into Z3, but not expect it to provide sat/unsat answers.
Rather than trying some infinite search, Z3 may prefer to give up and return unknown.
(Note: This is just a comment instead of an answer. I have to do so because I don't have sufficient reputation to add a comment.)
Here is the quote from the Z3 guide about integer division, modulo and reminder operators:
Z3 also has support for division, integer division, modulo and remainder operators. Internally, they are all mapped to multiplication.
(declare-const a Int)
(declare-const r1 Int)
(declare-const r2 Int)
(declare-const r3 Int)
(declare-const r4 Int)
(declare-const r5 Int)
(declare-const r6 Int)
(assert (= a 10))
(assert (= r1 (div a 4))) ; integer division
(assert (= r2 (mod a 4))) ; mod
(assert (= r3 (rem a 4))) ; remainder
(assert (= r4 (div a (- 4)))) ; integer division
(assert (= r5 (mod a (- 4)))) ; mod
(assert (= r6 (rem a (- 4)))) ; remainder
(declare-const b Real)
(declare-const c Real)
(assert (>= b (/ c 3.0)))
(assert (>= c 20.0))
(check-sat)
(get-model)
In Z3, division by zero is allowed, but the result is not specified. Division is not a partial function. Actually, in Z3 all functions are total, although the result may be underspecified in some cases like division by zero.
It is unclear what is the behavior when the arguments are negative. In other words, the mapping to multiplication for these operations is not clear.

Why is Z3 not able to solve this instance without a seemingly trivial modification?

The original problem is:
(declare-const a Real)
(declare-const b Bool)
(declare-const c Int)
(assert (distinct a 0.))
(assert (= b (distinct (* a a) 0.)))
(assert (= c (ite b 1 0)))
(assert (not (distinct c 0)))
(check-sat)
The result is unknown.
But the last two constraints, taken together, are equivalent to (assert (= b false)), and after performing this rewrite by hand
(declare-const a Real)
(declare-const b Bool)
(declare-const c Int)
(assert (distinct a 0.))
(assert (= b (distinct (* a a) 0.)))
(assert (= b false))
;(assert (= c (ite b 1 0)))
;(assert (not (distinct c 0)))
(check-sat)
Z3 is now able to solve this instance (it is unsat).
Why can Z3 solve the second instance but not the first one, even though the first instance can be simplified to the second?
edit:
While locating the problem I found something very strange.
Z3 solves the following instance and returns "unsat":
(declare-fun a() Real)
(declare-fun b() Bool)
(declare-fun c() Int)
(assert (distinct a 0.0))
(assert (= b (distinct (* a a) 0.0)))
(assert (= b false))
;(assert (= c 0))
(check-sat)
But if I uncomment (assert (= c 0)), the solver returns "unknown", even though c=0 has nothing to do with the above assertions.
The problem here is that expressions like (* a a) are non-linear and Z3's default solver for non-linear problems gives up because it thinks it's too hard. Z3 does have another solver, but that one has very limited theory combination, i.e., you won't be able to use it for mixed Boolean, bit-vector, array, etc, problems, but only for arithmetic problems. It's easy to test by replacing the (check-sat) command with (check-sat-using qfnra-nlsat).

Z3 : strange behavior with non linear arithmetic

I am just starting to use Z3 (v4.4.0), and I wanted to try one of the tutorial examples :
(declare-const a Int)
(assert (> (* a a) 3))
(check-sat)
(get-model)
(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)
As said, the second example fails with "unknown", and by increasing the verbose level (to 3) I think I understand why : some problem with the simplifying process, then the tactic fails.
In order to have a better idea of the problem (and a shorter output), I decided to remove the first part of the code to test only the failed part :
(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)
But magically, now I get "sat". I am not sure about how Z3 chooses its tactic when it is about non linear arithmetic, but can the problem be from Z3 choosing a tactic for the first formula that is useless for the second one ?
Thanks in advance
The second encoding is not equivalent to the first, hence the different behavior. The second encoding does not include the constraint (assert (> (* a a) 3)), so Z3 can find it is satisfiable that b^3 + b*c = 3 for some choice of reals b and c. However, when it has the constraint that a^2 > 3 for some integer a, it fails to find it's satisfiable, even though the two assertions are independent from one another.
For this problem, it's essentially that Z3 by default will not use the nonlinear real arithmetic solver (which is complete) when it encounters reals mixed with integers. Here's an example of how to force it using qfnra-nlsat (rise4fun link: http://rise4fun.com/Z3/KDRP ):
(declare-const a Int)
;(assert (> (* a a) 3))
;(check-sat)
;(get-model)
(echo "Z3 will fail in the next example...")
(declare-const b Real)
(declare-const c Real)
(push)
(assert (and (> (* a a) 3) (= (+ (* b b b) (* b c)) 3.0)))
(check-sat)
(check-sat-using qfnra-nlsat) ; force using nonlinear solver for nonlinear real arithimetic (coerce integers to reals)
(get-model)
(pop)
(assert (= (+ (* b b b) (* b c)) 3.0))
(check-sat)
(get-model)
Likewise, if you just change (declare-const a Int) to (declare-const a Real), it will by default pick the correct solver that can handle this. So yes, in essence this has to do with what solver is getting picked, which is determined in part by the sorts of the underlying terms.
Related Q/A: Combining nonlinear Real with linear Int

Should Z3 prove monotonicity of <= (with respect to multiplication)?

This is the reduction of a more interesting problem, in which the missing property was (for positive k,M and N), that ((k % M) * N) < M*N. Below is an encoding of the simpler problem that a <= b ==> (a*c) <= (b*c). Such a query succeeds (we get unsat), but if the expression b is replaced by b+1 (as in the second query below) then we get unknown, which seems surprising. Is this the expected behaviour? Are there options to improve the handling of such inequalities? I tried with and without configuration options, and various versions of Z3, including the current unstable branch. Any tips would be much appreciated!
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
(check-sat)
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
(check-sat)
This falls into nonlinear integer arithmetic (which has an undecidable decision problem, see, e.g., How does Z3 handle non-linear integer arithmetic? ), so it's actually not too surprising Z3 returns unknown for some examples, although I guess a bit surprising that it toggled between unsat and unknown for quite similar examples.
If it works for your application, you can try a type coercion: encode the constants as Real instead of Int. This will allow you to use Z3's complete solver for nonlinear real arithmetic and returns unsat with check-sat.
Alternatively, you can force Z3 to use the nonlinear solver even for the integer encoding with (check-sat-using qfnra-nlsat) as in the following based on your example (rise4fun link: http://rise4fun.com/Z3/87GW ):
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(assert (> a 0))
(assert (> b 0))
(assert (> c 0))
(assert (<= a b))
(assert (not (<= (* a c) (* b c))))
;(check-sat)
(check-sat-using qfnra-nlsat) ; unsat
(assert (<= a (+ b 1)))
(assert (not (<= (* a c) (* (+ b 1) c))))
; (check-sat)
(check-sat-using qfnra-nlsat) ; unsat
Some more questions and answers on similar subjects:
Combining nonlinear Real with linear Int
z3 fails with this system of equations
Using Z3Py online to prove that n^5 <= 5 ^n for n >= 5
Can z3 always give result when handling nonlinear real arithmetic
Z3 Theorem Prover: Pythagorean Theorem (Non-Linear Artithmetic)

Quantifier in Z3

Basically, I want to ask Z3 to give me an arbitrary integer whose value is greater than 10. So I write the following statements:
(declare-const x (Int))
(assert (forall ((i Int)) (> i 10)))
(check-sat)
(get-value(x))
How can I apply this quantifier to my model? I know you can write (assert (> x 10)) to achieve this. But I mean I want a quantifier in my model so every time I declare an integer constant whose value is guaranteed to be over 10. So I don't have to insert statement (assert (> x 10)) for every integer constant that I declared.
When you use (assert (forall ((i Int)) (> i 10))), i is a bounded variable and the quantified formula is equivalent to a truth value, which is false in this case.
I think you want to define a macro using quantifiers:
(declare-fun greaterThan10 (Int) Bool)
(assert (forall ((i Int)) (= (greaterThan10 i) (> i 10))))
And you can use them to avoid code repetition:
(declare-const x (Int))
(declare-const y (Int))
(assert (greaterThan10 x))
(assert (greaterThan10 y))
(check-sat)
It is essentially the way to define macros using uninterpreted functions when you're working with Z3 API. Note that you have to set (set-option :macro-finder true) in order that Z3 replaces universal quantifiers with bodies of those functions.
However, if you're working with the textual interface, the macro define-fun in SMT-LIB v2 is an easier way to do what you want:
(define-fun greaterThan10 ((i Int)) Bool
(> i 10))

Resources