0

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?

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
dewtell
  • 1,402
  • 10
  • 14

1 Answers1

0

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))));
dewtell
  • 1,402
  • 10
  • 14