Finding BitVec weight efficently (aka access to bits of a bitvector) in z3

十年热恋 提交于 2021-01-28 12:35:50

问题


I'm currently computing the weight of bitvectors using the python api for z3.

After searching through the python API for more straight forward method, I'm implementing the weight function for a bitvector st1 in the following manner:

Sum([( (st1 & (2**(i)))/(2**(i)) ) for i in range(bits)])

My question is relatively straight-forward, is there an easier/more efficient way?

I have problems which contain 1500+ of these weight constraints and would like to make sure I'm doing things as efficiently as possible.

Edit: I'll add the following clarification, what I'm attempting to calculate has a name (it's the Hamming Weight), I know there are ultra efficient ways of implementing the functionality in imperative languages, but ultimately what I'm looking for is if there are any underlying methods to access individual bits of a z3 bitvector.


回答1:


I played a little bit with the example you posted in the question:

  • z3 pseudo-randomly hangs while parsing through a SAT Model

I believe the unsat instances are hard to solve because the problem seems to have many symmetries. If that is the case, we can improve the performance by including "symmetry breaking constraints". Z3 can't break the symmetries automatically for this kind of problem.

Here is a minor encoding improvement. The expression ((st1 & (2**(i)))/(2**(i)) is essentially extracting the i-th bit. We can use Extract(i, i, st1) to extract the i-th bit. The result is a Bit-vector of size 1. Then, we have to "expand" it to avoid overflows. The bit-vectors in your problem have at most 28 bits. So, 5 bits is enough to avoid overflows. Therefore, we can use ZeroExt(4, Extract(i, i, st1)). That is, we replace

Sum([( (st1 & (2**(i)))/(2**(i)) ) for i in range(bits)])

with

Sum([ ZeroExt(4, Extract(i,i,st1)) for i in range(bits) ])

I get a modest 2x speedup. So, Z3 still cannot solve the 6 bits unsat instance :(




回答2:


You should try with recursive method and maybe you could take a look at this Dynamic programming



来源:https://stackoverflow.com/questions/14731028/finding-bitvec-weight-efficently-aka-access-to-bits-of-a-bitvector-in-z3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!