在 z3 中定义有界整数

Defining bounded integers in z3

在 Z3 中有定义有界整数的聪明方法吗?

例如,假设我想定义一个整数变量 "x",它可以从 [1,4] 中获取值。我可以执行以下操作(我正在使用 Java API)

IntExpr x = ctx.mkIntConst("x");
solver.add(ctx.mkGT(x, ctx.mkInt(0))); // (assert (> x 0))
solver.add(ctx.mkLT(x, ctx.mkInt(5))); // (assert (< x 5))

但是,我想知道是否有更聪明的方法来做到这一点?可以在声明时自动将 upper/lower 限制在变量上的东西。我遇到了枚举,但我不确定这是否是最佳选择。

谢谢

如果是2的幂,就用位向量。否则没有简单的方法来做到这一点(即,你做对了)。

遗憾的是,没有 "good" 方法来模拟此类约束。 Bitvectors 走得很远,假设你对机器算术(即模块化)没问题并且你的范围很合适,如前所述。这是之前的相关讨论:Is there an UnsignedIntSort in Z3?.

要正确支持您想要的内容,需要谓词子类型化。 PVS 和 Yices 的旧版本(1.X 系列中的 SMTLib 之前的变体)等定理证明器支持这种奇特的类型,具有不同程度的自动化。不幸的是,如果您需要坚持使用现代 SMT 求解器,您别无选择,只能在您的代码中添加大量边界约束。当然,它很快就会变得非常丑陋,因为您必须在每次操作后检查边界并定义它对 over/underflow 的含义。如果必须遵守边界,则合适的定理证明器可能是更好的选择。