See the PyZ3 program at http://rise4fun.com/Z3Py/GTYu. The first call to check() works fine, but if we add a constraint to the solver and call check() again, we get an inconsistent model!
sy_i = Bool('sy_i')
s0_v, s1_v, s2_v, sx_v, sy_v = Reals('s0_v s1_v s2_v sx_v sy_v')
c = [s0_v >= 1,
sx_v >= 1,
s1_v >= s0_v * sx_v,
sy_v >= 1,
Or(Not(sy_i), s1_v == RealVal(0.0)),
s2_v >= s1_v * sy_v
]
solver = Solver()
solver.add(c)
print solver.check()
print solver.model()
solver.add(True)
solver.check()
print solver.model()
Somebody knows what is going on?
The unstable Z3 version gets the same result.
Additional context:
The program is a simplification of a bigger one that uses the combined nlsat and bool solvers, following the great advice of the answer: Z3 real arithmetics and data types theories integrating not that well
Note that the method seems to work very well, but when trying to add more constraints and reuse the solver this problem arises. Maybe it misdetects the solving method?
The default solver object
Solver()is essentially a portfolio of solvers. It also tries to detect the usage pattern (incremental or non-incremental). If more than onecheck()is executed, it assumes the user is in “incremental” mode, and uses a general purpose incremental solver which is not complete for non-linear arithmetic.To force Z3 to always use
nlsat, we should create the solver object usingIf we do that, we can still use
push(),pop(), multiplecheck()‘s. However,nlsatwill not “reuse” work from previouscheck()calls. Here is the new version of your script.