在布尔列表上创建或约束

时间:2019-03-09 09:35:12

标签: python z3 z3py

我正在用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形式重述吗?还是向我保证一切正常?

感谢您的阅读和思考, 玛丽安

1 个答案:

答案 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]

不是最有趣的模型,但是我相信这正是您要寻找的!