我正在修改使用Z3(特别是Python API)来解决位向量约束的工具。我需要使用一个特定的外部SAT求解器而不是内部的Z3求解器,因此我首先使用该策略进行爆破
Then('simplify', 'bit-blast', 'tseitin-cnf')
之后我可以相对轻松地将子句转储到DIMACS文件中。问题是将得到的命题模型映射回原始约束的模型:据我所知,Python API没有提供访问对应于策略的模型转换器的方法。这是真的?如果是这样,是否可以使用不同的API完成,或者是否有更简单的方法?基本上我只需要知道最终CNF子句中的命题变量如何与原始的bitvector变量相对应。
答案 0 :(得分:3)
这听起来很特别。最简单的可能是你使用goal2sat转换(并重新编译Z3)来保存 文件中的翻译表。我认为通过API公开的任何功能都不会为您提供此信息。
答案 1 :(得分:1)
我有同样的问题,并在不修改Z3的情况下解决了它。这是python中的一个例子。 (基于莱昂纳多的example。)
from z3 import BitVec, BitVecSort, Goal, If, Then, Bool, solve
import math
x = BitVec('x', 16)
y = BitVec('y', 16)
z = BitVec('z', 16)
g = Goal()
bitmap = {}
for i in range(16):
bitmap[(x,i)] = Bool('x'+str(i))
mask = BitVecSort(16).cast(math.pow(2,i))
g.add(bitmap[(x,i)] == ((x & mask) == mask))
g.add(x == y, z > If(x < 0, x, -x))
print g
# t is a tactic that reduces a Bit-vector problem into propositional CNF
t = Then('simplify', 'bit-blast', 'tseitin-cnf')
subgoal = t(g)
assert len(subgoal) == 1
# Traverse each clause of the first subgoal
for c in subgoal[0]:
print c
solve(g)
对于位向量x的每个位置i,我们引入一个新的布尔变量xi,并要求xi等于位向量的第i个位置。在钻头爆破期间保留了布尔变量的名称。