在 Z3Py 中获取布尔表达式的所有解决方案永无止境

Getting all solutions of a boolean expression in Z3Py never ends

可能是一个与 Z3 相关的基本问题:我正在尝试获取布尔表达式的所有解决方案,例如对于 a OR b,我想得到 {(true, true),(false,true),(true,false)}

基于找到的其他回复,例如Z3: finding all satisfying models,我有以下代码:

a = Bool('a')
b = Bool('b')

f1=Or(a,b)
s=Solver()
s.add(f1)

while s.check() == sat:
  print s
  s.add(Not(And(a == s.model()[a], b == s.model()[b])))

问题是它在第二次迭代时进入无限循环:约束 a == s.model()[a] 被评估为 false b/c s.model()[a] 不再存在。

谁能告诉我哪里做错了?

我建议您尝试像这样编写循环:

from z3 import *

a = Bool('a')
b = Bool('b')

f1 = Or(a,b)
s = Solver()
s.add(f1)

while s.check() == sat:

    m = s.model()

    v_a = m.eval(a, model_completion=True)
    v_b = m.eval(b, model_completion=True)

    print("Model:")
    print("a := " + str(v_a))
    print("b := " + str(v_b))

    bc = Or(a != v_a, b != v_b)
    s.add(bc)

输出为:

Model:
a := True
b := False
Model:
a := False
b := True
Model:
a := True
b := True

参数 model_completion=True 是必要的,否则 m.eval(x) 的行为就像任何 x 布尔变量的恒等关系 不关心 当前模型中的值 m,结果 returns x 而不是 True/False。 (See related Q/A)


注意: 因为 z3 请标记 不关心 布尔变量,另一种选择是写你的自己的模型生成器,可以自动完成任何部分模型。这将减少对 s.check() 的调用次数。此实现的性能影响很难衡量,但它可能会稍微快一些。