如何将信息添加到 BitVec 变量并使用 get_vars() 取回该变量?

How to add information to BitVec variable and get that variable back with get_vars()?

在下面的代码中,我尝试向 BitVec 变量添加一些额外信息,然后创建一些条件,然后使用 get_vars 取回 x 变量,但它是总是不同,因为这个小片段的输出是 False。我希望是同一个对象,但似乎在执行 x > 3 时,会创建 BoolRefx 会丢失。另外,我预计 x.astvar.ast 相同,但实例不同。

from z3 import BitVec
from z3.z3util import get_vars

x = BitVec('x', 256)
x.foo = 1

some_cond = x > 3

for var in get_vars(some_cond):
    print(var is x)
    print(hasattr(var, 'foo'))

我想将 z3.BitVec 函数包装在扩展 z3.BitVecRef 的 class 中,但这会很痛苦,因为我需要包装所有其他函数,例如 z3.If, z3.And, z3.Or, 等等

我可以在 z3.BitVecname 中包含信息,但它会更慢,因为我需要稍后解析该字符串。

所以,我的问题是是否有任何其他方法可以将信息添加到 z3.BitVec 并稍后在有或没有 get_vars 的情况下获取该信息?

谢谢!

这里的问题是,当 z3 处理这些变量时,它 "internalizes" 它们并将它们转换为 BitVecRef;当您使用 is 构造时,它不再与您拥有的原件相符。

不幸的是,这在 z3 和 z3py 的工作方式中是硬编码的,因此您无法真正解决它。但是,如果您愿意自己创建并跟踪变量列表,那么您可以像这样有效地模拟它:

from z3 import BitVec, Or
from z3.z3util import get_vars

x = BitVec('x', 256)
x.foo = 1

y = BitVec('y', 256)
y.foo = 2

z = BitVec('z', 256)

some_cond = Or([x > 3, y < 1, z > 12])

def my_get_attribute(var, attrib, allMyVariables):
    for known in allMyVariables:
        if var == known:
           if hasattr(known, attrib):
              return getattr(known, attrib)
           else:
              raise Exception("Can't find attribute '{}' on variable '{}'".format(attrib, var))
    raise Exception("Can't find variable '{}', make sure allMyVariables is kept up-to-date.".format(var))

for var in get_vars(some_cond):
    print("var: {}, foo: {}".format(var, my_get_attribute(var, 'foo', [x, y, z])))

当我 运行 这个时,我得到:

var: x, foo: 1
var: y, foo: 2
Traceback (most recent call last):
  File "a.py", line 24, in <module>
    print("var: {}, foo: {}".format(var, my_get_attribute(var, 'foo', [x, y, z])))
  File "a.py", line 20, in my_get_attribute
    raise Exception("Can't find attribute '{}' on variable '{}'".format(attrib, var))
Exception: Can't find attribute 'foo' on variable 'z'

这并不理想,因为它显然需要您跟踪变量;但我怀疑如果您首先添加属性,您可能已经拥有它了。希望这对您有所帮助!