Skip to content

Commit b75367f

Browse files
port improvements to arith rewriter
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent a7bfdcd commit b75367f

File tree

2 files changed

+29
-28
lines changed

2 files changed

+29
-28
lines changed

src/ast/rewriter/arith_rewriter.cpp

+28-27
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu
11191119
return BR_REWRITE3;
11201120
}
11211121
}
1122-
if (divides(arg1, arg2, result)) {
1122+
if (get_divides(arg1, arg2, result)) {
11231123
expr_ref zero(m_util.mk_int(0), m);
11241124
result = m.mk_ite(m.mk_eq(zero, arg2), m_util.mk_idiv(arg1, zero), result);
11251125
return BR_REWRITE_FULL;
@@ -1137,7 +1137,7 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu
11371137
//
11381138
// implement div ab ac = floor( ab / ac) = floor (b / c) = div b c
11391139
//
1140-
bool arith_rewriter::divides(expr* num, expr* den, expr_ref& result) {
1140+
bool arith_rewriter::get_divides(expr* num, expr* den, expr_ref& result) {
11411141
expr_fast_mark1 mark;
11421142
rational num_r(1), den_r(1);
11431143
expr* num_e = nullptr, *den_e = nullptr;
@@ -1229,70 +1229,71 @@ static rational symmod(rational const& a, rational const& b) {
12291229
if (2*r > b) r -= b;
12301230
return r;
12311231
}
1232-
1232+
12331233
br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & result) {
12341234
set_curr_sort(arg1->get_sort());
1235-
numeral x, y;
1236-
bool is_num_x = m_util.is_numeral(arg1, x);
1237-
bool is_num_y = m_util.is_numeral(arg2, y);
1238-
if (is_num_x && is_num_y && !y.is_zero()) {
1239-
result = m_util.mk_int(mod(x, y));
1235+
numeral v1, v2;
1236+
bool is_int;
1237+
bool is_num1 = m_util.is_numeral(arg1, v1, is_int);
1238+
bool is_num2 = m_util.is_numeral(arg2, v2, is_int);
1239+
1240+
if (is_num1 && is_num2 && !v2.is_zero()) {
1241+
result = m_util.mk_numeral(mod(v1, v2), is_int);
12401242
return BR_DONE;
12411243
}
12421244

1243-
if (is_num_y && y.is_int() && (y.is_one() || y.is_minus_one())) {
1245+
if (is_num2 && is_int && (v2.is_one() || v2.is_minus_one())) {
12441246
result = m_util.mk_numeral(numeral(0), true);
12451247
return BR_DONE;
12461248
}
12471249

1248-
if (arg1 == arg2 && !is_num_y) {
1250+
if (arg1 == arg2 && !is_num2) {
12491251
expr_ref zero(m_util.mk_int(0), m);
12501252
result = m.mk_ite(m.mk_eq(arg2, zero), m_util.mk_mod(zero, zero), zero);
12511253
return BR_DONE;
12521254
}
12531255

12541256
// mod is idempotent on non-zero modulus.
12551257
expr* t1, *t2;
1256-
if (m_util.is_mod(arg1, t1, t2) && t2 == arg2 && is_num_y && y.is_int() && !y.is_zero()) {
1257-
result = arg1;
1258-
return BR_DONE;
1259-
}
1260-
1261-
rational lo, hi;
1262-
if (is_num_y && get_range(arg1, lo, hi) && 0 <= lo && hi < y) {
1258+
if (m_util.is_mod(arg1, t1, t2) && t2 == arg2 && is_num2 && is_int && !v2.is_zero()) {
12631259
result = arg1;
12641260
return BR_DONE;
12651261
}
12661262

12671263
// propagate mod inside only if there is something to reduce.
1268-
if (is_num_y && y.is_int() && y.is_pos() && (is_add(arg1) || is_mul(arg1))) {
1264+
if (is_num2 && is_int && v2.is_pos() && (is_add(arg1) || is_mul(arg1))) {
12691265
TRACE("mod_bug", tout << "mk_mod:\n" << mk_ismt2_pp(arg1, m) << "\n" << mk_ismt2_pp(arg2, m) << "\n";);
12701266
expr_ref_buffer args(m);
12711267
bool change = false;
12721268
for (expr* arg : *to_app(arg1)) {
12731269
rational arg_v;
1274-
if (m_util.is_numeral(arg, arg_v) && mod(arg_v, y) != arg_v) {
1270+
if (m_util.is_numeral(arg, arg_v) && mod(arg_v, v2) != arg_v) {
12751271
change = true;
1276-
args.push_back(m_util.mk_numeral(mod(arg_v, y), true));
1272+
args.push_back(m_util.mk_numeral(mod(arg_v, v2), true));
12771273
}
12781274
else if (m_util.is_mod(arg, t1, t2) && t2 == arg2) {
12791275
change = true;
12801276
args.push_back(t1);
12811277
}
1282-
else if (m_util.is_mul(arg, t1, t2) && m_util.is_numeral(t1, arg_v) && symmod(arg_v, y) != arg_v) {
1278+
else if (m_util.is_mul(arg, t1, t2) && m_util.is_numeral(t1, arg_v) && symmod(arg_v, v2) != arg_v) {
12831279
change = true;
1284-
args.push_back(m_util.mk_mul(m_util.mk_numeral(symmod(arg_v, y), true), t2));
1280+
args.push_back(m_util.mk_mul(m_util.mk_numeral(symmod(arg_v, v2), true), t2));
12851281
}
12861282
else {
12871283
args.push_back(arg);
12881284
}
12891285
}
1290-
if (!change) {
1291-
return BR_FAILED; // did not find any target for applying simplification
1286+
if (change) {
1287+
result = m_util.mk_mod(m.mk_app(to_app(arg1)->get_decl(), args.size(), args.data()), arg2);
1288+
TRACE("mod_bug", tout << "mk_mod result: " << mk_ismt2_pp(result, m) << "\n";);
1289+
return BR_REWRITE3;
12921290
}
1293-
result = m_util.mk_mod(m.mk_app(to_app(arg1)->get_decl(), args.size(), args.data()), arg2);
1294-
TRACE("mod_bug", tout << "mk_mod result: " << mk_ismt2_pp(result, m) << "\n";);
1295-
return BR_REWRITE3;
1291+
}
1292+
1293+
expr* x, *y;
1294+
if (is_num2 && v2.is_pos() && m_util.is_mul(arg1, x, y) && m_util.is_numeral(x, v1, is_int) && divides(v1, v2)) {
1295+
result = m_util.mk_mul(x, m_util.mk_mod(y, m_util.mk_int(v2/v1)));
1296+
return BR_REWRITE1;
12961297
}
12971298

12981299
return BR_FAILED;

src/ast/rewriter/arith_rewriter.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class arith_rewriter : public poly_rewriter<arith_rewriter_core> {
104104
expr_ref neg_monomial(expr * e);
105105
expr * mk_sin_value(rational const & k);
106106
app * mk_sqrt(rational const & k);
107-
bool divides(expr* d, expr* n, expr_ref& result);
107+
bool get_divides(expr* d, expr* n, expr_ref& result);
108108
expr_ref remove_divisor(expr* arg, expr* num, expr* den);
109109
void flat_mul(expr* e, ptr_buffer<expr>& args);
110110
void remove_divisor(expr* d, ptr_buffer<expr>& args);

0 commit comments

Comments
 (0)