如何从z3模型中获得数组的示例值?

时间:2018-11-13 07:08:21

标签: python z3 z3py

感谢this question,我知道如何以更简单的方式查看模型。此时,如何获得aanother的期望值?

如果可能,我希望使用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) ) ) 
) ) ) ) ) )

我希望有aanother的{​​{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) :)

谢谢

2 个答案:

答案 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中重新编码所有内容,然后直接使用这些功能。另外,不清楚为什么将aanother建模为以数组开头的对象:似乎您只对这些数组的第[0]个元素感兴趣?如果是这种情况,只需使用32位向量而不是数组即可。