Z3py 中的 If 子句没有 else

If clause in Z3py without the else

如果我们没有 'else' 部分,我们如何在 Z3py 中编写 If('condition', x, y) 子句?

请记住,Z3 表达式是 first-order 逻辑公式,而不是语句。如果 xy 是布尔值,则 If(b,x,y) 等价于 b && x || !b && y。省略 y 相当于用 true 替换它,也相当于 b ==> x,即 Z3py 中的 Implies(b, x)

如果 xy 不是布尔值,那么思考会更复杂,但是,例如整数。在这种情况下,条件本质上是三元运算符 b ? x : y。由于函数(以及运算符)在 SMT 中是总计的,因此您不能简单地省略 y(如果 b 为假,b ? x 的计算结果是什么?)。

在这种情况下,您可以使用未指定的变量:声明一个新的 SMT 变量 z 并通过 Implies(b, z == x) 对其进行约束。这样,如果 b 为真,则 zx,如果 b 为假,则 z 有一些未知值。

z3 中的所有表达式都产生一个值;将其视为一种函数式编程语言,而不是命令式语言。因此,您必须提供else子句。

在 z3 中对命令式语言建模时,通常会出现这种情况;类似于:

foo = expr1
if cond:
   foo = expr2

对此建模的正确方法是使用所谓的 SSA form,并“保留”旧值,即上面的内容变为:

foo0 = expr1
foo1 = If(cond, expr2, foo0)

请注意,对“相同”变量的每次赋值都会获得一个新名称(foo0foo1 等),并且当值未通过条件更改时,我们只是保持它的旧值。大多数 symbolic-simulation 系统(如 Klee 或其他 higher-level API)都会在后台为您执行此操作。请注意,根据 foo 的类型,提出正确的分配虽然可以自动进行,但可能会很棘手。 (如果是列表呢?)

为了解决您的编程需求,最好询问您需要此构造的特定实例;否则答案必然是概括性的。也就是说,虽然以上是一般策略,但您的特定问题可能有更简单的解决方案。但是,如果没有关于您要实现的目标的更多详细信息,就不可能知道。