我是Z3py的初学者,我一直在努力解决这个问题近一个星期......我找不到足够的信息来帮助我在教程中找到一个好的例子(功能存在)可以帮我。
答案 0 :(得分:4)
免责声明:如果您的问题完全您正在努力使用Z3py对问题进行编码,那么我的建议不会帮助您,因为它们是不关于Z3py。但是,我认为你的问题实际上更为根本。
答案:对Z3 / SMTLIB中的列表进行公理化并不是直截了当的,特别是因为你的公理化需要一个良好的触发策略(模式),(forall-quantified)公理,这样你的公理化就不会产生匹配的循环。
我建议查看Boogie prelude of Dafny,看看 序列的公理化是怎样的。 Dafny是一个自动软件验证程序,Boogie是一种中间验证语言。 Boogie的语法很容易理解(对于熟悉SMTLIB语法的人来说),你应该能够用表达序列排列的公理(或多个公理)来扩展现有的序列公理化。
答案 1 :(得分:-1)
W̶o̶w̶,̶̶w̶h̶a̶t̶̶t̶h̶e̶̶h̶e̶c̶k̶.̶.̶.̶.̶̶T̶h̶a̶t̶̶l̶i̶t̶e̶r̶a̶t̶u̶r̶e̶̶l̶i̶i̶nrognrogive这个问题是否要求进行纯粹的符号比较?如果不是这样,这个(更基本的)答案可能会提供一些有用的信息。
如果您只想找到唯一值的已知列表的特定排列,则可能无需进行公理化就可以删除。
只需生成O(n²)对等式,然后将它们成组添加为n
形式的AtLeast(…, 1)
约束。代码示例会更好地解释:
from itertools import combinations
import z3
solver = z3.Solver()
source_list = ['tau', 'eta', 'mu']
permuted = z3.Strings(['X', 'Y', 'Z'])
for var1, var2 in combinations(permuted, 2):
solver.add(var1 != var2)
#-- here's where we do O(n²) pairwise EQs
for var_ref in permuted:
possible_assigns = [(var_ref == z3.StringVal(s)) for s in source_list]
solver.add(z3.AtLeast(*possible_assigns, 1))
#-- TODO: add here the rest of constraints that matter to you
#-- start search
while solver.check() == z3.sat:
model = solver.model()
print(model)
this_solution = z3.And(*[
var_ref == z3.StringVal(model[var_ref].as_string())
for var_ref in permuted
])
solver.append(z3.Not(this_solution))
print("No more solutions.")
#-- output:
# [Z = tau, X = mu, Y = eta]
# [Z = tau, X = eta, Y = mu]
# [Z = mu, X = eta, Y = tau]
# [Z = eta, X = mu, Y = tau]
# [Z = mu, X = tau, Y = eta]
# [Z = eta, X = tau, Y = mu]
# No more solutions.
如果允许permuted
列表包含重复项,则需要进行一些调整。
如果两个列表都位于“ in-z3”中,则此方法将无效。有关该情况,请参阅Malte的答案。