Skip to content

Commit 80f00f1

Browse files
fix #7572 and fix #7574
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
1 parent 8df45b4 commit 80f00f1

26 files changed

+213
-152
lines changed

src/api/api_ast.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,8 @@ extern "C" {
12571257
case OP_EXT_ROTATE_LEFT: return Z3_OP_EXT_ROTATE_LEFT;
12581258
case OP_EXT_ROTATE_RIGHT: return Z3_OP_EXT_ROTATE_RIGHT;
12591259
case OP_INT2BV: return Z3_OP_INT2BV;
1260-
case OP_BV2INT: return Z3_OP_BV2INT;
1260+
case OP_UBV2INT: return Z3_OP_BV2INT;
1261+
case OP_SBV2INT: return Z3_OP_SBV2INT;
12611262
case OP_CARRY: return Z3_OP_CARRY;
12621263
case OP_XOR3: return Z3_OP_XOR3;
12631264
case OP_BIT2BOOL: return Z3_OP_BIT2BOOL;

src/api/api_bv.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
140140
else {
141141
expr * _n = to_expr(n);
142142
parameter p(to_sort(int_s));
143-
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
143+
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_UBV2INT, 1, &p, 1, &_n);
144144
mk_c(c)->save_ast_trail(a);
145145
check_sorts(c, a);
146146
RETURN_Z3(of_ast(a));

src/api/z3_api.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -367,13 +367,11 @@ typedef enum
367367
368368
- Z3_OP_EXT_ROTATE_RIGHT (extended) Right rotation. Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one.
369369
370-
- Z3_OP_INT2BV Coerce integer to bit-vector. NB. This function
371-
is not supported by the decision procedures. Only the most
372-
rudimentary simplification rules are applied to this function.
370+
- Z3_OP_INT2BV Coerce integer to bit-vector.
373371
374-
- Z3_OP_BV2INT Coerce bit-vector to integer. NB. This function
375-
is not supported by the decision procedures. Only the most
376-
rudimentary simplification rules are applied to this function.
372+
- Z3_OP_BV2INT Coerce bit-vector to integer.
373+
374+
- Z3_OP_SBV2INT Coerce signed bit-vector to integer.
377375
378376
- Z3_OP_CARRY Compute the carry bit in a full-adder.
379377
The meaning is given by the equivalence
@@ -1106,6 +1104,7 @@ typedef enum {
11061104
Z3_OP_BIT2BOOL,
11071105
Z3_OP_INT2BV,
11081106
Z3_OP_BV2INT,
1107+
Z3_OP_SBV2INT,
11091108
Z3_OP_CARRY,
11101109
Z3_OP_XOR3,
11111110

src/ast/bv_decl_plugin.cpp

+61-21
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ void bv_decl_plugin::finalize() {
143143
DEC_REF(m_ext_rotate_right);
144144

145145
DEC_REF(m_int2bv);
146-
DEC_REF(m_bv2int);
146+
DEC_REF(m_ubv2int);
147+
DEC_REF(m_sbv2int);
147148
for (auto& ds : m_bit2bool)
148149
DEC_REF(ds);
149150
DEC_REF(m_mkbv);
@@ -228,36 +229,54 @@ func_decl * bv_decl_plugin::mk_int2bv(unsigned bv_size, unsigned num_parameters,
228229
force_ptr_array_size(m_int2bv, bv_size + 1);
229230

230231
if (arity != 1) {
231-
m_manager->raise_exception("expecting one argument to int2bv");
232+
m_manager->raise_exception("expecting one argument to int_to_bv");
232233
return nullptr;
233234
}
234235

235236
if (m_int2bv[bv_size] == 0) {
236237
sort * s = get_bv_sort(bv_size);
237-
m_int2bv[bv_size] = m_manager->mk_func_decl(symbol("int2bv"), domain[0], s,
238+
m_int2bv[bv_size] = m_manager->mk_func_decl(symbol("int_to_bv"), domain[0], s,
238239
func_decl_info(m_family_id, OP_INT2BV, num_parameters, parameters));
239240
m_manager->inc_ref(m_int2bv[bv_size]);
240241
}
241242

242243
return m_int2bv[bv_size];
243244
}
244245

245-
func_decl * bv_decl_plugin::mk_bv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
246+
func_decl * bv_decl_plugin::mk_ubv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
246247
unsigned arity, sort * const * domain) {
247-
force_ptr_array_size(m_bv2int, bv_size + 1);
248+
force_ptr_array_size(m_ubv2int, bv_size + 1);
248249

249250
if (arity != 1) {
250-
m_manager->raise_exception("expecting one argument to bv2int");
251+
m_manager->raise_exception("expecting one argument to ubv_to_int");
251252
return nullptr;
252253
}
253254

254-
if (m_bv2int[bv_size] == 0) {
255-
m_bv2int[bv_size] = m_manager->mk_func_decl(symbol("bv2int"), domain[0], m_int_sort,
256-
func_decl_info(m_family_id, OP_BV2INT));
257-
m_manager->inc_ref(m_bv2int[bv_size]);
255+
if (m_ubv2int[bv_size] == 0) {
256+
m_ubv2int[bv_size] = m_manager->mk_func_decl(symbol("ubv_to_int"), domain[0], m_int_sort,
257+
func_decl_info(m_family_id, OP_UBV2INT));
258+
m_manager->inc_ref(m_ubv2int[bv_size]);
258259
}
259260

260-
return m_bv2int[bv_size];
261+
return m_ubv2int[bv_size];
262+
}
263+
264+
func_decl * bv_decl_plugin::mk_sbv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
265+
unsigned arity, sort * const * domain) {
266+
force_ptr_array_size(m_sbv2int, bv_size + 1);
267+
268+
if (arity != 1) {
269+
m_manager->raise_exception("expecting one argument to sbv_to_int");
270+
return nullptr;
271+
}
272+
273+
if (m_sbv2int[bv_size] == 0) {
274+
m_sbv2int[bv_size] = m_manager->mk_func_decl(symbol("sbv_to_int"), domain[0], m_int_sort,
275+
func_decl_info(m_family_id, OP_SBV2INT));
276+
m_manager->inc_ref(m_sbv2int[bv_size]);
277+
}
278+
279+
return m_sbv2int[bv_size];
261280
}
262281

263282
func_decl * bv_decl_plugin::mk_unary_pred(ptr_vector<func_decl> & decls, decl_kind k, char const * name, unsigned bv_size) {
@@ -552,8 +571,10 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
552571
return mk_bit2bool(bv_size, num_parameters, parameters, arity, domain);
553572
case OP_INT2BV:
554573
return mk_int2bv(bv_size, num_parameters, parameters, arity, domain);
555-
case OP_BV2INT:
556-
return mk_bv2int(bv_size, num_parameters, parameters, arity, domain);
574+
case OP_UBV2INT:
575+
return mk_ubv2int(bv_size, num_parameters, parameters, arity, domain);
576+
case OP_SBV2INT:
577+
return mk_sbv2int(bv_size, num_parameters, parameters, arity, domain);
557578
case OP_CONCAT:
558579
if (!get_concat_size(arity, domain, r_size))
559580
m_manager->raise_exception("invalid concat application");
@@ -780,8 +801,11 @@ void bv_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const
780801
op_names.push_back(builtin_name("ext_rotate_left",OP_EXT_ROTATE_LEFT));
781802
op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT));
782803
op_names.push_back(builtin_name("int2bv",OP_INT2BV));
783-
op_names.push_back(builtin_name("bv2int",OP_BV2INT));
784-
op_names.push_back(builtin_name("bv2nat",OP_BV2INT));
804+
op_names.push_back(builtin_name("int_to_bv",OP_INT2BV));
805+
op_names.push_back(builtin_name("bv2int",OP_UBV2INT));
806+
op_names.push_back(builtin_name("bv2nat",OP_UBV2INT));
807+
op_names.push_back(builtin_name("ubv_to_int",OP_UBV2INT));
808+
op_names.push_back(builtin_name("sbv_to_int",OP_SBV2INT));
785809
op_names.push_back(builtin_name("mkbv",OP_MKBV));
786810
}
787811
}
@@ -878,10 +902,8 @@ bool bv_recognizers::is_repeat(expr const * e, expr*& arg, unsigned& n) const {
878902
}
879903

880904

881-
bool bv_recognizers::is_bv2int(expr const* e, expr*& r) const {
882-
if (!is_bv2int(e)) return false;
883-
r = to_app(e)->get_arg(0);
884-
return true;
905+
bool bv_recognizers::is_ubv2int(expr const* e, expr*& r) const {
906+
return is_ubv2int(e) && (r = to_app(e)->get_arg(0), true);
885907
}
886908

887909
bool bv_recognizers::is_bit2bool(expr* e, expr*& bv, unsigned& idx) const {
@@ -934,10 +956,28 @@ unsigned bv_util::get_int2bv_size(parameter const& p) {
934956
return static_cast<unsigned>(sz);
935957
}
936958

937-
app * bv_util::mk_bv2int(expr* e) const {
959+
app * bv_util::mk_ubv2int(expr* e) const {
960+
sort* s = m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT);
961+
parameter p(s);
962+
return m_manager.mk_app(get_fid(), OP_UBV2INT, 1, &p, 1, &e);
963+
}
964+
965+
app * bv_util::mk_sbv2int(expr* e) const {
938966
sort* s = m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT);
939967
parameter p(s);
940-
return m_manager.mk_app(get_fid(), OP_BV2INT, 1, &p, 1, &e);
968+
return m_manager.mk_app(get_fid(), OP_SBV2INT, 1, &p, 1, &e);
969+
}
970+
971+
app* bv_util::mk_sbv2int_as_ubv2int(expr* e) {
972+
// if e <_s 0 then ubv2int(e) - 2^n else ubv2int(e)
973+
app* r = mk_ubv2int(e);
974+
arith_util autil(m_manager);
975+
unsigned sz = get_bv_size(e);
976+
expr_ref zero(mk_numeral(rational::zero(), sz), m_manager);
977+
r = m_manager.mk_ite(mk_slt(e, zero),
978+
autil.mk_sub(r, autil.mk_numeral(rational::power_of_two(sz), true)),
979+
r);
980+
return r;
941981
}
942982

943983
app* bv_util::mk_int2bv(unsigned sz, expr* e) const {

src/ast/bv_decl_plugin.h

+14-6
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ enum bv_op_kind {
109109
OP_BIT2BOOL, // predicate
110110
OP_MKBV, // bools to bv
111111
OP_INT2BV,
112-
OP_BV2INT,
112+
OP_UBV2INT,
113+
OP_SBV2INT,
113114

114115
OP_CARRY,
115116
OP_XOR3,
@@ -225,7 +226,8 @@ class bv_decl_plugin : public decl_plugin {
225226
ptr_vector<func_decl> m_ext_rotate_left;
226227
ptr_vector<func_decl> m_ext_rotate_right;
227228

228-
ptr_vector<func_decl> m_bv2int;
229+
ptr_vector<func_decl> m_ubv2int;
230+
ptr_vector<func_decl> m_sbv2int;
229231
ptr_vector<func_decl> m_int2bv;
230232
vector<ptr_vector<func_decl> > m_bit2bool;
231233
ptr_vector<func_decl> m_mkbv;
@@ -250,7 +252,9 @@ class bv_decl_plugin : public decl_plugin {
250252
bool get_extract_size(unsigned num_parameters, parameter const * parameters,
251253
unsigned arity, sort * const * domain, int & result);
252254

253-
func_decl * mk_bv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
255+
func_decl * mk_ubv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
256+
unsigned arity, sort * const * domain);
257+
func_decl * mk_sbv2int(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
254258
unsigned arity, sort * const * domain);
255259

256260
func_decl * mk_int2bv(unsigned bv_size, unsigned num_parameters, parameter const * parameters,
@@ -337,7 +341,8 @@ class bv_recognizers {
337341
unsigned get_extract_low(expr const * n) const { SASSERT(is_extract(n)); return get_extract_low(to_app(n)->get_decl()); }
338342
bool is_extract(expr const * e, unsigned & low, unsigned & high, expr * & b) const;
339343
bool is_repeat(expr const * e, expr*& arg, unsigned& n) const;
340-
bool is_bv2int(expr const * e, expr * & r) const;
344+
bool is_ubv2int(expr const * e, expr * & r) const;
345+
bool is_sbv2int(expr const * e, expr * & r) const;
341346
bool is_bv_add(expr const * e) const { return is_app_of(e, get_fid(), OP_BADD); }
342347
bool is_bv_sub(expr const * e) const { return is_app_of(e, get_fid(), OP_BSUB); }
343348
bool is_bv_mul(expr const * e) const { return is_app_of(e, get_fid(), OP_BMUL); }
@@ -378,7 +383,8 @@ class bv_recognizers {
378383
bool is_uge(expr const * e) const { return is_app_of(e, get_fid(), OP_UGEQ); }
379384
bool is_sge(expr const * e) const { return is_app_of(e, get_fid(), OP_SGEQ); }
380385
bool is_bit2bool(expr const * e) const { return is_app_of(e, get_fid(), OP_BIT2BOOL); }
381-
bool is_bv2int(expr const* e) const { return is_app_of(e, get_fid(), OP_BV2INT); }
386+
bool is_ubv2int(expr const* e) const { return is_app_of(e, get_fid(), OP_UBV2INT); }
387+
bool is_sbv2int(expr const* e) const { return is_app_of(e, get_fid(), OP_SBV2INT); }
382388
bool is_int2bv(expr const* e) const { return is_app_of(e, get_fid(), OP_INT2BV); }
383389
bool is_mkbv(expr const * e) const { return is_app_of(e, get_fid(), OP_MKBV); }
384390
bool is_bv_ashr(expr const * e) const { return is_app_of(e, get_fid(), OP_BASHR); }
@@ -549,7 +555,9 @@ class bv_util : public bv_recognizers {
549555
app * mk_bv_ashr(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_BASHR, arg1, arg2); }
550556
app * mk_bv_lshr(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_BLSHR, arg1, arg2); }
551557

552-
app * mk_bv2int(expr* e) const;
558+
app * mk_ubv2int(expr* e) const;
559+
app * mk_sbv2int(expr* e) const;
560+
app * mk_sbv2int_as_ubv2int(expr* e);
553561
app * mk_int2bv(unsigned sz, expr* e) const;
554562

555563
app* mk_bv_rotate_left(expr* arg1, expr* arg2) { return m_manager.mk_app(get_fid(), OP_EXT_ROTATE_LEFT, arg1, arg2); }

src/ast/rewriter/bit2int.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ void bit2int::operator()(expr * n, expr_ref & result, proof_ref& p) {
4646

4747
unsigned bit2int::get_b2i_size(expr* n) {
4848
expr* arg = nullptr;
49-
VERIFY(m_bv_util.is_bv2int(n, arg));
49+
VERIFY(m_bv_util.is_ubv2int(n, arg));
5050
return m_bv_util.get_bv_size(arg);
5151
}
5252

@@ -83,7 +83,7 @@ bool bit2int::extract_bv(expr* n, unsigned& sz, bool& sign, expr_ref& bv) {
8383
numeral k;
8484
bool is_int;
8585
expr* r = nullptr;
86-
if (m_bv_util.is_bv2int(n, r)) {
86+
if (m_bv_util.is_ubv2int(n, r)) {
8787
bv = r;
8888
sz = m_bv_util.get_bv_size(bv);
8989
sign = false;
@@ -123,7 +123,7 @@ bool bit2int::mk_add(expr* e1, expr* e2, expr_ref& result) {
123123
tmp2 = m_rewriter.mk_zero_extend(1, tmp2);
124124
SASSERT(m_bv_util.get_bv_size(tmp1) == m_bv_util.get_bv_size(tmp2));
125125
tmp3 = m_rewriter.mk_bv_add(tmp1, tmp2);
126-
result = m_rewriter.mk_bv2int(tmp3);
126+
result = m_rewriter.mk_ubv2int(tmp3);
127127
return true;
128128
}
129129
return false;
@@ -168,7 +168,7 @@ bool bit2int::mk_mul(expr* e1, expr* e2, expr_ref& result) {
168168

169169
SASSERT(m_bv_util.get_bv_size(tmp1) == m_bv_util.get_bv_size(tmp2));
170170
tmp3 = m_rewriter.mk_bv_mul(tmp1, tmp2);
171-
result = m_rewriter.mk_bv2int(tmp3);
171+
result = m_rewriter.mk_ubv2int(tmp3);
172172
if (sign1 != sign2) {
173173
result = m_arith_util.mk_uminus(result);
174174
}
@@ -183,13 +183,13 @@ bool bit2int::is_bv_poly(expr* n, expr_ref& pos, expr_ref& neg) {
183183
numeral k;
184184
bool is_int;
185185
todo.push_back(n);
186-
neg = pos = m_rewriter.mk_bv2int(m_bit0);
186+
neg = pos = m_rewriter.mk_ubv2int(m_bit0);
187187

188188
while (!todo.empty()) {
189189
n = todo.back();
190190
todo.pop_back();
191191
expr* arg1 = nullptr, *arg2 = nullptr;
192-
if (m_bv_util.is_bv2int(n)) {
192+
if (m_bv_util.is_ubv2int(n)) {
193193
VERIFY(mk_add(n, pos, pos));
194194
}
195195
else if (m_arith_util.is_numeral(n, k, is_int) && is_int) {
@@ -208,16 +208,16 @@ bool bit2int::is_bv_poly(expr* n, expr_ref& pos, expr_ref& neg) {
208208
}
209209
else if (m_arith_util.is_mul(n, arg1, arg2) &&
210210
m_arith_util.is_numeral(arg1, k, is_int) && is_int && k.is_minus_one() &&
211-
m_bv_util.is_bv2int(arg2)) {
211+
m_bv_util.is_ubv2int(arg2)) {
212212
VERIFY(mk_add(arg2, neg, neg));
213213
}
214214
else if (m_arith_util.is_mul(n, arg1, arg2) &&
215215
m_arith_util.is_numeral(arg2, k, is_int) && is_int && k.is_minus_one() &&
216-
m_bv_util.is_bv2int(arg1)) {
216+
m_bv_util.is_ubv2int(arg1)) {
217217
VERIFY(mk_add(arg1, neg, neg));
218218
}
219219
else if (m_arith_util.is_uminus(n, arg1) &&
220-
m_bv_util.is_bv2int(arg1)) {
220+
m_bv_util.is_ubv2int(arg1)) {
221221
VERIFY(mk_add(arg1, neg, neg));
222222
}
223223
else {
@@ -251,7 +251,7 @@ void bit2int::visit(app* n) {
251251
m_arith_util.is_lt(n) || m.is_eq(n);
252252
expr_ref result(m);
253253
for (unsigned i = 0; !has_b2i && i < num_args; ++i) {
254-
has_b2i = m_bv_util.is_bv2int(args[i]);
254+
has_b2i = m_bv_util.is_ubv2int(args[i]);
255255
}
256256
if (!has_b2i) {
257257
result = m.mk_app(f, num_args, args);
@@ -367,7 +367,7 @@ void bit2int::visit(app* n) {
367367
tmp2 = e2bv;
368368
align_sizes(tmp1, tmp2);
369369
tmp3 = m_rewriter.mk_bv_urem(tmp1, tmp2);
370-
result = m_rewriter.mk_bv2int(tmp3);
370+
result = m_rewriter.mk_ubv2int(tmp3);
371371
cache_result(n, result);
372372
return;
373373
}
@@ -393,7 +393,7 @@ void bit2int::visit(app* n) {
393393
tmp2 = e2bv;
394394
align_sizes(tmp1, tmp2);
395395
tmp3 = m_rewriter.mk_bv_urem(tmp1, tmp2);
396-
result = m_rewriter.mk_bv2int(tmp3);
396+
result = m_rewriter.mk_ubv2int(tmp3);
397397

398398
cache_result(n, result);
399399
}

src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
548548
case OP_BIT2BOOL:
549549
case OP_MKBV:
550550
case OP_INT2BV:
551-
case OP_BV2INT:
551+
case OP_UBV2INT:
552+
case OP_SBV2INT:
552553
return BR_FAILED;
553554
default:
554555
TRACE("bit_blaster", tout << "non-supported operator: " << f->get_name() << "\n";

src/ast/rewriter/bv2int_translator.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void bv2int_translator::translate_app(app* e) {
164164
expr* r = m.mk_app(f, m_args);
165165
if (has_bv_sort) {
166166
ctx.push(push_back_vector(m_vars));
167-
r = bv.mk_bv2int(r);
167+
r = bv.mk_ubv2int(r);
168168
}
169169
set_translated(e, r);
170170
return;
@@ -424,7 +424,7 @@ void bv2int_translator::translate_bv(app* e) {
424424
ctx.push(push_back_vector(m_int2bv));
425425
r = arg(0);
426426
break;
427-
case OP_BV2INT:
427+
case OP_UBV2INT:
428428
m_bv2int.push_back(e);
429429
ctx.push(push_back_vector(m_bv2int));
430430
r = umod(e->get_arg(0), 0);

0 commit comments

Comments
 (0)