我正在用Python玩Z3来生成解散难题的解决方案。我以前没有使用SAT / SMT求解器或Z3的经验,甚至我的Python仍处于pidgin级。所以请保持温柔。
在我的方法中,我有两个Bools的xs和ys列表。从其他约束条件中我知道,在两个列表的每个列表中,最多一个条目为True,其他所有条目为False。每个列表为零或一个True条目。
我想添加一个约束来比较两个列表是否都为True或全为false。
所以我想要类似or(all_the_xs)==or(all_the_ys)
的东西。我觉得这应该是Z3的本能,但我不知道如何声明。
我通过使用z3.Sum([z3.If(x,1,0) for x in xs])
比较True值的计数来做到这一点,但这确实使它脱离了简单布尔值的领域。感觉也很优雅,效率也较低。
以下是使用Sum()
的我的合并代码的代表性独立示例:
import z3
solver = z3.Solver()
xs = [ z3.Bool("x_{i}".format(i=i)) for i in range(0,10) ]
ys = [ z3.Bool("y_{i}".format(i=i)) for i in range(0,10) ]
xsum = z3.Sum([z3.If(x,1,0) for x in xs])
ysum = z3.Sum([z3.If(x,1,0) for x in ys])
solver.add(xsum == ysum)
solver.check()
print(solver.model())
您能帮我以更漂亮,更友好的Z3形式重述吗?还是向我保证一切正常?
感谢您的阅读和思考, 玛丽安
答案 0 :(得分:2)
您很幸运! z3py随附Or
,其中包含布尔值列表:
import z3
solver = z3.Solver()
xs = [ z3.Bool("x_{i}".format(i=i)) for i in range(0,10) ]
ys = [ z3.Bool("y_{i}".format(i=i)) for i in range(0,10) ]
solver.add(z3.Or(xs) == z3.Or(ys))
solver.check()
print(solver.model())
此打印:
[x_0 = False,
x_1 = False,
x_2 = False,
x_3 = False,
x_4 = False,
x_5 = False,
x_6 = False,
x_7 = False,
x_8 = False,
x_9 = False,
y_0 = False,
y_1 = False,
y_2 = False,
y_3 = False,
y_4 = False,
y_5 = False,
y_6 = False,
y_7 = False,
y_8 = False,
y_9 = False]
不是最有趣的模型,但是我相信这正是您要寻找的!