Z3位向量中所有位的总和

时间:2016-09-02 18:51:20

标签: z3 z3py

给定Z3中的位向量,我想知道如何总结这个向量的每个位?

如,

a = BitVecVal(3, 2)
sum_all_bit(a) = 2

是否有任何预先实现的API /函数支持此功能?谢谢!

3 个答案:

答案 0 :(得分:2)

它不是位向量操作的一部分。 您可以按如下方式创建表达式:

def sub(b):
    n = b.size()
    bits = [ Extract(i, i, b) for i in range(n) ]
    bvs  = [ Concat(BitVecVal(0, n - 1), b) for b in bits ]
    nb   = reduce(lambda a, b: a + b, bvs)
    return nb


print sub(BitVecVal(4,7))

当然,如果您愿意,结果的log(n)位就足够了。

答案 1 :(得分:2)

因此,您正在计算位向量的汉明权重。根据我之前的问题,一名开发人员使用了this answer。根据原来的答案,这就是我今天要做的:

def HW(bvec):
    return Sum([ ZeroExt(int(ceil(log2(bvec.size()))), Extract(i,i,bvec)) for i in range(bvec.size())])

答案 2 :(得分:1)

页面:

https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive

有各种算法来计算比特;我想这可以相对容易地翻译成Z3 / Python。

我最喜欢的是:https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan

具有nice属性,它循环的次数与输入中的set位一样多。 (但是你不应该从那里推断到任何有意义的复杂性度量,因为你在每个循环中进行算术,这可能是昂贵的。对所有这些算法都是如此。)

话虽如此,如果你的输入是完全符号的,你就不能真正击败简单的迭代算法,因为你不能缩短迭代次数。如果输入具有具体位,则上述方法可以更快地工作。