I noticed some strange behavior with Z3 4.3.1 when working with .smt2 files.
If I do (assert (= 0 0.5))
it will be satisfiable. However, if I switch the order and do (assert (= 0.5 0))
it's not satisfiable.
My guess as to what is happening is that if the first parameter is an integer, it casts both of them to integers (rounding 0.5 down to 0), then does the comparison. If I change "0" to "0.0" it works as expected. This is in contrast to most programming languages I've worked with where if either of the parameters is a floating-point number, they are both cast to floating-point numbers and compared. Is this really the expected behavior in Z3?
Do not rely on the implicit type conversion of any solver. Instead, use
to_real
andto_int
to do explicit type conversions. Only send well-typed formulas to the solver. Then Mohamed Iguernelala's examples become the following.Both of these return UNSAT in Z3 and CVC4. If instead, you really wanted to find the model where
x = 1
you should have instead used one of the following.Both of these return SAT with
x = 1
in Z3 and CVC4.Once you make all the type conversions explicit and deal only in well-typed formulas, the order of arguments to equality no longer matters (for correctness).
One possible solution is
and the output is
I think this is a consequence of lack of type-checking; z3 is being too lenient. It should simply reject such queries as they are simply not well formed.
According to the SMT-Lib standard, v2 (http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.0-r10.12.21.pdf); page 30; the core theory is defined thusly:
So, by definition equality requires the input sorts to be the same; and hence the aforementioned query should be rejected as invalid.
There might be a switch to z3 or some other setting that forces more strict type-checking than it does by default; but I would've expected this case to be caught even with the most relaxed of the implementations.
Jochen Hoenicke gived the answer (on SMT-LIB mailing list) regarding "mixing reals and integers". Here it is:
One of our interns, who worked on a conservative extension of SMT2 with polymorphism has noticed the same strange behavior, when he tried the understand how formulas mixing integers and reals are type-checked:
z3 (http://rise4fun.com/z3) says that the following example is SAT, and finds a model x = 1
But, it says that the following "equivalent" example in UNSAT
So, this does not comply with the symmetric property of equality predicate. So, I think it's a bug.
Strictly speaking, Z3 is not SMT 2.0 compliant by default, and this is one of those cases. We can add
and then this query is indeed rejected correctly.