Consider a set of constraints F = [a + b > 10, a*a + b + 10 < 50].
When I run it using:
s = Solver()
s.add(F)
s.check()
I get sat
solution.
If I run it with:
s = Solver()
s.check(F)
I get an unknown
solution. Can someone explain why this is happening?
Let's see:
from z3 import *
a = Int('a')
b = Int('b')
F = [a + b > 10, a*a + b + 10 < 50]
s = Solver()
s.add(F)
print (s.check())
print (s.model())
This prints:
sat
[b = 15, a = -4]
That looks good to me.
Let's try your second variant:
from z3 import *
a = Int('a')
b = Int('b')
F = [a + b > 10, a*a + b + 10 < 50]
s = Solver()
print (s.check(F))
print (s.model())
This prints:
sat
[b = 7, a = 4]
That looks good to me too.
So, I don't know how you're getting the unknown
answer. Maybe you have an old version of z3; or you've some other things in your program you're not telling us about.
The important thing to note, however, is that s.add(F); s.check()
AND s.check(F)
are different operations:
s.add(F); s.check()
means: Assert the constraints in F
; check that they are satisfiable.
s.check(F)
means: Check that all the other constraints are satisfiable, assuming F is. In particular, it does not assert F
. (This is important if you do further asserts/checks later on.)
So, in general these two different ways of using check
are used for different purposes; and can yield different answers. But in the presence of no other assertions around, you'll get a solution for both, though of course the models might be different.
Aside One reason you can get unknown
is in the presence of non-linear constraints. And your a*a+b+10 < 50
is non-linear, since it does have a multiplication of a variable by itself. You can deal with that either by using a bit-vector instead of an Int
(if applicable), or using the nonlinear-solver; which can still give you unknown
, but might perform better. But just looking at your question as you asked it, z3 is just fine handling it.