如何将信息添加到 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
时,会创建 BoolRef
而 x
会丢失。另外,我预计 x.ast
与 var.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.BitVec
的 name
中包含信息,但它会更慢,因为我需要稍后解析该字符串。
所以,我的问题是是否有任何其他方法可以将信息添加到 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'
这并不理想,因为它显然需要您跟踪变量;但我怀疑如果您首先添加属性,您可能已经拥有它了。希望这对您有所帮助!
在下面的代码中,我尝试向 BitVec
变量添加一些额外信息,然后创建一些条件,然后使用 get_vars
取回 x
变量,但它是总是不同,因为这个小片段的输出是 False
。我希望是同一个对象,但似乎在执行 x > 3
时,会创建 BoolRef
而 x
会丢失。另外,我预计 x.ast
与 var.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.BitVec
的 name
中包含信息,但它会更慢,因为我需要稍后解析该字符串。
所以,我的问题是是否有任何其他方法可以将信息添加到 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'
这并不理想,因为它显然需要您跟踪变量;但我怀疑如果您首先添加属性,您可能已经拥有它了。希望这对您有所帮助!