【发布时间】:2019-03-09 09:35:12
【问题描述】:
我正在使用 Python 中的 Z3 来生成解散难题的解决方案。我之前没有使用 SAT/SMT 求解器或 Z3 的经验,甚至我的 Python 仍处于 pidgin 级别。所以请温柔一点。
在我的方法中,我有两个布尔值列表 xs 和 ys。我从其他约束中知道,在两个列表中的每一个中,最多一个条目是 True,而所有其他条目都是 False。每个列表有 0 个或 1 个 True 条目。
我想添加一个约束来比较两个列表是否都具有 True 条目或都为 False。
所以我想要or(all_the_xs)==or(all_the_ys) 之类的东西。我觉得这应该是 Z3 的原生语言,但我不知道该怎么说。
我设法通过使用z3.Sum([z3.If(x,1,0) for x in xs]) 比较真值的计数来做到这一点,但这确实使它超出了简单布尔值的范围。它也让人觉得不优雅,效率也越来越低。
这是我使用 Sum() 的 bodged 代码的一个有代表性的自包含示例:
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 的形式重申这一点吗?或者向我保证它没问题?
感谢您的阅读和思考, 玛丽安
【问题讨论】:
-
基础 Python:
any(all_the_xes) == any(all_the_ys) -
好吧,如果您已经知道在任何给定时间只有一个布尔变量可以为真,那么根本不需要计算变量。只需写
or(x_0, ..., x_N) <=> or(y_0, ...., y_M),其中<=>是双重含义,使用适当的z3py语法。 -
谢谢三人组。对不起,不够清楚。
solver.add(any(xs) == any(ys))“符号表达式不能转换为具体的布尔值。”这些是 z3 Bool 变量,求解器被要求找到满足所有约束的有效组合。不是具有特定值的 Python 布尔值列表。 -
谢谢帕特里克。找出合适的 z3py 语法正是我的问题:-)。