如何访问钻头爆破时使用的变量映射?

时间:2015-06-18 16:57:51

标签: z3 z3py

我正在修改使用Z3(特别是Python API)来解决位向量约束的工具。我需要使用一个特定的外部SAT求解器而不是内部的Z3求解器,因此我首先使用该策略进行爆破

Then('simplify', 'bit-blast', 'tseitin-cnf')

之后我可以相对轻松地将子句转储到DIMACS文件中。问题是将得到的命题模型映射回原始约束的模型:据我所知,Python API没有提供访问对应于策略的模型转换器的方法。这是真的?如果是这样,是否可以使用不同的API完成,或者是否有更简单的方法?基本上我只需要知道最终CNF子句中的命题变量如何与原始的bitvector变量相对应。

2 个答案:

答案 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个位置。在钻头爆破期间保留了布尔变量的名称。