请参阅http://rise4fun.com/Z3Py/GTYu处的PyZ3计划。对check()
的第一次调用工作正常,但如果我们向求解器添加约束并再次调用check()
,我们会得到一个不一致的模型!
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()
有人知道发生了什么事吗?
不稳定的Z3版本得到了相同的结果。
附加背景:
该程序是一个较大的程序的简化,使用合并的nlsat
和bool
解算器,遵循答案的伟大建议:Z3 real arithmetics and data types theories integrating not that well
请注意,该方法似乎运行良好,但在尝试添加更多约束并重用解算器时会出现此问题。也许它误解了解决方法?
答案 0 :(得分:2)
默认的求解器对象Solver()
本质上是一个求解器组合。它还尝试检测使用模式(增量或非增量)。如果执行了多个check()
,则假定用户处于“增量”模式,并使用通用增量求解器,该求解器对于非线性算术不完整。
要强制Z3始终使用nlsat
,我们应该使用
solver = Tactic('qfnra-nlsat').solver()
如果我们这样做,我们仍然可以使用push()
,pop()
,多个check()
。但是,nlsat
不会“重复使用”之前check()
次调用的工作。 Here is the new version of your script