在Z3Python中散列表达式

时间:2012-09-18 13:52:13

标签: python z3

看起来z3表达式有hash()方法但不是__hash__()。是否有理由不使用__hash__()?这允许表达式可以清除。

1 个答案:

答案 0 :(得分:2)

没有理由不调用它__hash__()。我称之为hash()因为我是Python的新手。我将在下一个版本中添加__hash__()(Z3 4.2)。

编辑:正如评论中所指出的,我们还需要__eq____cmp__才能将Z3对象用作Python字典中的键。不幸的是,__eq__方法(在ExprRef定义)用于构建Z3表达式。也就是说,如果ab引用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)]