问题
The Concat() function in the z3 python interface allows you to concatenate arbitrary bit vectors. Our application is using the C++ interface, though. Is there an easy way to get the same effect with the C++ interface? I'm trying to build up an output bitvector expression out of sub-expressions. I can do it with shift and or operations, but I'd like something simpler if it exists.
For example, one of the things I want to do is create a 4-bit bitvector representing the odd bits of an input 8-bit bitvector expression. The following works:
expr getOddBits8to4(context &c, expr &in) {
expr result = ite(in.extract(1, 1) == c.bv_val(1, 1), c.bv_val(1, 4), c.bv_val(0, 4)) |
ite(in.extract(3, 3) == c.bv_val(1, 1), c.bv_val(2, 4), c.bv_val(0, 4)) |
ite(in.extract(5, 5) == c.bv_val(1, 1), c.bv_val(4, 4), c.bv_val(0, 4)) |
ite(in.extract(7, 7) == c.bv_val(1, 1), c.bv_val(8, 4), c.bv_val(0, 4));
return result;
}
but I would rather be able to write something like:
expr result = Concat(in.extract(1,1), in.extract(3,3), in.extract(5,5), in.extract(7,7));
As far as I can tell, this is only available in the Python interface. Is there a way to create something similar from the C++ interface, or even just to simplify the above expression?
回答1:
Based on the hint by Nikolaj Bjorner, I've come up with the following wrapper function that seems to work until an official version can be supplied.
inline expr concat(expr const & a, expr const & b) {
check_context(a, b);
assert(a.is_bv() && b.is_bv());
Z3_ast r = Z3_mk_concat(a.ctx(), a, b);
a.check_error();
return expr(a.ctx(), r);
}
Using this, my odd bit example can be written:
expr result = concat(in.extract(1, 1), concat(in.extract(3, 3), concat(in.extract(5, 5), in.extract(7, 7))));
来源:https://stackoverflow.com/questions/30135216/is-there-a-form-of-bitvector-concat-in-the-z3-c-interface