Reputation: 494
Thanks to this question I know how to see the model in an easier way. At this point how can I get the expected values for a
and another
?
If possible I'd like the example code using pyz3.
Clarification:
Having the following smt file:
(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) ) )
) ) ) ) ) )
I would like to have the value for a
and another
that are 77
and 12
What is the best way?
At the moment my approach is:
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)
The output is 77
as expected :)
Thanks
Upvotes: 1
Views: 1769
Reputation: 30460
The sort of usage you have here is extremely brittle. The line:
a = m[m.decls()[0]]
assumes the model will have the a
value in the very first slot. It might work for this particular SMT file; but there's no guarantee that it'll always hold.
Your code can be simplified. But I think that's missing the point that this isn't the proper way to use z3. I'd recommend either sticking to SMTLib only or coding in z3py directly. Mixing those two interfaces is just going to add to confusion for no obvious benefit, and as I mentioned, is going to be extremely brittle.
Since you already seem to have something else generating SMTLib; why not just stick to that format? You can use SMTLib's eval
command to extract arbitrary values from your model. Or, recode everythin in z3py, and use those facilities directly. Also, it is not clear why you're modeling a
and another
as arrays to start with: Seems like you're only interested in the [0]
'th element of those arrays? If that's the case, simply use a 32-bit vector instead of an array.
Upvotes: 1
Reputation: 8392
As shown in the original question, the model values for arrays are functions that map indices to values. So, an example value for a
is [3 -> 1, else -> 1]
, which is the function that maps index 3
to value 1
and all other indices to value 1
.
Upvotes: 1