看起来z3表达式有hash()
方法但不是__hash__()
。是否有理由不使用__hash__()
?这允许表达式可以清除。
答案 0 :(得分:2)
没有理由不调用它__hash__()
。我称之为hash()
因为我是Python的新手。我将在下一个版本中添加__hash__()
(Z3 4.2)。
编辑:正如评论中所指出的,我们还需要__eq__
或__cmp__
才能将Z3对象用作Python字典中的键。不幸的是,__eq__
方法(在ExprRef
定义)用于构建Z3表达式。也就是说,如果a
和b
引用Z3表达式,则a == b
将返回表示表达式a = b
的Z3表达式对象。这个“特性”便于在Python中编写Z3示例,但它有一个令人讨厌的副作用:Python字典类将假设所有Z3表达式彼此相等。实际上,更糟糕的是,因为Python字典仅为具有相同哈希码的对象调用方法__eq__
。因此,如果我们定义__hash__()
,我们可能会使用Z3表达式对象作为Python词典中的键是安全的。因此,我不会在课程__hash__()
中加入AstRef
。
想要在字典中使用Z3表达式作为键的用户可以使用以下技巧:
from z3 import *
class AstRefKey:
def __init__(self, n):
self.n = n
def __hash__(self):
return self.n.hash()
def __eq__(self, other):
return self.n.eq(other.n)
def askey(n):
assert isinstance(n, AstRef)
return AstRefKey(n)
x = Int('x')
y = Int('y')
d = {}
d[askey(x)] = 10
d[askey(y)] = 20
d[askey(x + y)] = 30
print d[askey(x)]
print d[askey(y)]
print d[askey(x + y)]
n = simplify(x + 1 + y - 1)
print d[askey(n)]