0

I am emulating an array with simple function (Tab) and it doesn't work as expected. If I code it in SMT2, it works well, but in Z3py it doesn't work.

from z3 import *

A = BitVec('A', 8)
B1 = BitVec('B1', 8)
B2 = BitVec('B2', 8)
B3 = BitVec('B3', 8)
B4 = BitVec('B4', 8)

# Emulate Array
def Tab(N):
  if N == 0x01: return B1
  if N == 0x02: return B2
  if N == 0x03: return B3
  if N == 0x04: return B4

s = Solver()
s.add(A == 0x01)
s.add(Tab(A + 0x02) == 0x09 )
s.check()
m = s.model()

print (m)
print("Pos:", m.eval(A + 0x02))
print("Tab(3a):", m.eval(Tab(A + 0x02)))
print("Tab(3):", m.eval(Tab(0x03)))
print("B1: ", m[B1])
print("B2: ", m[B2])
print("B3: ", m[B3])
print("B4: ", m[B4])
print("B3n:", m.eval(B3))

Output:

[B1 = 9, A = 1] <- Model
Pos: 3          <- this is OK
Tab(3a): 9      <- this is OK (based on our condition)
Tab(3):  B3     <- why does this return name B3? (should return None or 9)
B1:  9          <- this is BAD, here should be None
B2:  None
B3:  None       <- this is BAD, here should be 9
B4:  None
B3n: B3         <- why does this return name B3?! (should return None or 9)

From the output we see that Tab always returns B1 for parameter 0x03 instead of B3. It looks like A + 0x02 is calculated as 0x01 where it's used as a parameter. Am I doing something wrong, or is it some Z3py implementation error? Or does this have to do with how BitVec terms work?

mtrberzi
  • 215
  • 2
  • 10
z3_test
  • 19
  • 6

1 Answers1

0

This looks like the same problem as in this post: How to correctly use Solver() command in Python API of Z3 with declared function.

The problem is that if N == 0x01: ... does not create a Z3 if-then-else expression; it literally check whether N is a Python-int with concrete value 1. To get the desired expression you need to use Z3's If(...) function.

Community
  • 1
  • 1
Christoph Wintersteiger
  • 8,234
  • 1
  • 16
  • 30
  • Thank you, you are right, IF THEN was inside Python environment, and should be inside Z3. Solution is: ` return z3.If(N == 0x01, B1,` `z3.If(N == 0x02, B2,` `z3.If(N == 0x03, B3, B4)))` – z3_test Oct 18 '15 at 17:17