调用检查两次应该工作吗?

时间:2013-01-07 17:29:49

标签: python z3

请参阅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版本得到了相同的结果。

附加背景:

该程序是一个较大的程序的简化,使用合并的nlsatbool解算器,遵循答案的伟大建议:Z3 real arithmetics and data types theories integrating not that well

请注意,该方法似乎运行良好,但在尝试添加更多约束并重用解算器时会出现此问题。也许它误解了解决方法?

1 个答案:

答案 0 :(得分:2)

默认的求解器对象Solver()本质上是一个求解器组合。它还尝试检测使用模式(增量或非增量)。如果执行了多个check(),则假定用户处于“增量”模式,并使用通用增量求解器,该求解器对于非线性算术不完整。

要强制Z3始终使用nlsat,我们应该使用

创建求解器对象
solver = Tactic('qfnra-nlsat').solver()

如果我们这样做,我们仍然可以使用push()pop(),多个check()。但是,nlsat不会“重复使用”之前check()次调用的工作。 Here is the new version of your script