在 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()
的调用次数。此实现的性能影响很难衡量,但它可能会稍微快一些。
可能是一个与 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()
的调用次数。此实现的性能影响很难衡量,但它可能会稍微快一些。