给定Z3
中的位向量,我想知道如何总结这个向量的每个位?
如,
a = BitVecVal(3, 2)
sum_all_bit(a) = 2
是否有任何预先实现的API /函数支持此功能?谢谢!
答案 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位一样多。 (但是你不应该从那里推断到任何有意义的复杂性度量,因为你在每个循环中进行算术,这可能是昂贵的。对所有这些算法都是如此。)
话虽如此,如果你的输入是完全符号的,你就不能真正击败简单的迭代算法,因为你不能缩短迭代次数。如果输入具有具体位,则上述方法可以更快地工作。