diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index f841f573c95..a4d024488f3 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1118,6 +1118,17 @@ namespace z3 { friend expr min(expr const& a, expr const& b); friend expr max(expr const& a, expr const& b); + friend expr bv2int(expr const& a, bool is_signed); + friend expr int2bv(expr const& a, unsigned n); + friend expr bvadd_no_overflow(expr const& a, expr const& b); + friend expr bvadd_no_underflow(expr const& a, expr const& b); + friend expr bvsub_no_overflow(expr const& a, expr const& b); + friend expr bvsub_no_underflow(expr const& a, expr const& b); + friend expr bvsdiv_no_overflow(expr const& a, expr const& b); + friend expr bvneg_no_overflow(expr const& a); + friend expr bvmul_no_overflow(expr const& a, expr const& b, bool is_signed); + friend expr bvmul_no_underflow(expr const& a, expr const& b); + expr rotate_left(unsigned i) { Z3_ast r = Z3_mk_rotate_left(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); } expr rotate_right(unsigned i) { Z3_ast r = Z3_mk_rotate_right(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); } expr repeat(unsigned i) { Z3_ast r = Z3_mk_repeat(ctx(), i, *this); ctx().check_error(); return expr(ctx(), r); } @@ -1625,6 +1636,7 @@ namespace z3 { return expr(a.ctx(), r); } + /** \brief Create the if-then-else expression ite(c, t, e) @@ -1740,6 +1752,41 @@ namespace z3 { */ inline expr zext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_zero_ext(a.ctx(), i, a)); } + /** + \brief bit-vector and integer conversions. + */ + inline expr bv2int(expr const& a, bool is_signed) { Z3_ast r = Z3_mk_bv2int(a.ctx(), a, is_signed); a.check_error(); return expr(a.ctx(), r); } + inline expr int2bv(expr const& a, unsigned n) { Z3_ast r = Z3_mk_intbv2(a.ctx(), a, n); a.check_error(); return expr(a.ctx(), r); } + + /** + \brief bit-vector overflow/underflow checks + */ + inline expr bvadd_no_overflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvadd_no_overflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvadd_no_underflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvadd_no_underflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvsub_no_overflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvsub_no_overflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvsub_no_underflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvsub_no_underflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvsdiv_no_overflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvsdiv_no_overflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvneg_no_overflow(expr const& a) { + Z3_ast r = Z3_mk_bvneg_no_overflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvmul_no_overflow(expr const& a, expr const& b, bool is_signed) { + check_context(a, b); Z3_ast r = Z3_mk_bvmul_no_overflow(a.ctx(), a, b, is_signed); a.check_error(); return expr(a.ctx(), r); + } + inline expr bvmul_no_underflow(expr const& a, expr const& b) { + check_context(a, b); Z3_ast r = Z3_mk_bvmul_no_underflow(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); + } + + /** \brief Sign-extend of the given bit-vector to the (signed) equivalent bitvector of size m+i, where m is the size of the given bit-vector. */ diff --git a/src/api/z3_api.h b/src/api/z3_api.h index a575ec9a473..673d22a9af6 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -2989,6 +2989,7 @@ extern "C" { of \c t1 and \c t2 does not overflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvadd_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) */ @@ -2999,6 +3000,7 @@ extern "C" { of \c t1 and \c t2 does not underflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvadd_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) */ @@ -3009,6 +3011,7 @@ extern "C" { of \c t1 and \c t2 does not overflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvsub_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) */ @@ -3019,6 +3022,7 @@ extern "C" { of \c t1 and \c t2 does not underflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvsub_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) */ @@ -3029,6 +3033,7 @@ extern "C" { of \c t1 and \c t2 does not overflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvsdiv_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) */ @@ -3039,6 +3044,7 @@ extern "C" { \c t1 is interpreted as a signed bit-vector. The node \c t1 must have bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvneg_no_overflow', AST, (_in(CONTEXT), _in(AST))) */ @@ -3049,6 +3055,7 @@ extern "C" { of \c t1 and \c t2 does not overflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvmul_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) */ @@ -3059,6 +3066,7 @@ extern "C" { of \c t1 and \c t2 does not underflow. The nodes \c t1 and \c t2 must have the same bit-vector sort. + The returned node is of sort Bool. def_API('Z3_mk_bvmul_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) */