Z3有除法的烦恼吗?

Does Z3 have troubles with division?

在做项目的过程中,遇到了一个无法解释的现象。它在下面的最小示例(使用 Z3Py)中被归结为不饱和但 returns 模型。

from z3 import *

solver = Solver()

x = Int("x")

# The next proposition is clearly unsatisfiable
solver.add(And(x > 0, (x + 1) * (1 / (x + 1)) != 1))
solver.add(x == 1)

# Still, Z3 provides a "model"
print(solver.check())
print(solver.model())

有什么我遗漏的吗?是否禁止在某些情况下使用除法?

Z3版本:4.8.14 Python版本:3.9

请注意,当您对整数使用 / 时,结果本身就是一个整数。即,我们使用整数除法;在 SMTLib 中,它被定义为欧几里得之一。有关详细信息,请参阅 https://smtlib.cs.uiowa.edu/theories-Ints.shtml

这意味着表达式 1 / (1+1) 减少为 0,因为除法产生一个整数。所以你最终得到 0 != 1,这是真的,因此你的问题是可满足的。

如果你想让除法产生实数,那么你应该从实数 x(即 x = Real("x"))开始,在这种情况下你的问题将是 unsat;或者通过 ToReal(x) 形式的表达式将参数转换为实数;这将再次为您的问题产生 unsat

因此,在第一种情况下,您的修改将是:

x = Real('x')

将问题转化为实数。或者,如果你想保留 x 一个整数,但要除以实数,你应该使用:

solver.add(And(x > 0, ToReal(x + 1) * (1 / ToReal(x + 1)) != 1))

哪个进行转换。

我应该注意,以这种方式混合整数和实数通常会导致难题,求解器可能最终会报告 unknown。但这不是您在这里提出的特定问题的重点。