问题
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