感谢this question,我知道如何以更简单的方式查看模型。此时,如何获得a
和another
的期望值?
如果可能,我希望使用pyz3的示例代码。
说明:
具有以下smt文件:
(set-option :produce-models true)
(set-logic QF_AUFBV )
(declare-fun a () (Array (_ BitVec 32) (_ BitVec 8) ) )
(declare-fun another () (Array (_ BitVec 32) (_ BitVec 8) ) )
(assert (and (= true (= (_ bv77 32) (concat (select a (_ bv3 32)
) (concat (select a (_ bv2 32) ) (concat (select a (_ bv1 32) )
(select a (_ bv0 32) ) ) ) ) ) ) (= true (= (_ bv12 32) (concat
(select another (_ bv3 32) ) (concat (select another (_ bv2 32) )
(concat (select another (_ bv1 32) ) (select another (_ bv0 32) ) )
) ) ) ) ) )
我希望有a
和another
的{{1}}和77
的值
什么是最好的方法?
目前我的方法是:
12
预期输出为import z3
import binascii
z3.set_param('model_compress', False)
s = z3.Solver()
s.from_file("first.smt")
s.check()
m = s.model()
print(m)
a = m[m.decls()[0]]
print(a)
b = bytearray(a.num_entries())
for x in range(a.num_entries()):
index = a.entry(x).as_list()[0]
value = a.entry(x).as_list()[1]
print(index, value)
b[a.num_entries()-index.as_long()-1] = value.as_long()
expected = int(binascii.hexlify(b),16)
print(expected)
:)
谢谢
答案 0 :(得分:1)
如原始问题所示,数组的模型值是将索引映射到值的函数。因此,a
的示例值是[3 -> 1, else -> 1]
,该函数将索引3
映射到值1
,并将所有其他索引映射到值1
。
答案 1 :(得分:1)
您在这里使用的这种方法非常脆弱。该行:
a = m[m.decls()[0]]
假定模型在第一个插槽中将具有a
值。它可能适用于此特定的SMT文件。但不能保证它会一直存在。
您的代码可以简化。但是我认为这遗漏了一点,即这不是使用z3的正确方法。我建议只坚持使用SMTLib或直接在z3py中进行编码。混合这两个接口只会增加混乱,而没有明显的好处,而且正如我提到的那样,这将非常脆弱。
由于您似乎已经有了其他生成SMTLib的东西;为什么不只坚持那种格式?您可以使用SMTLib的eval
命令从模型中提取任意值。或者,在z3py中重新编码所有内容,然后直接使用这些功能。另外,不清楚为什么将a
和another
建模为以数组开头的对象:似乎您只对这些数组的第[0]
个元素感兴趣?如果是这种情况,只需使用32位向量而不是数组即可。