3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-31 16:33:18 +00:00

patching can break monomials, so rerun nla

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2023-06-09 13:34:12 -07:00
parent 37ec667102
commit aafc9656e1
4 changed files with 62 additions and 3 deletions

View file

@ -58,9 +58,9 @@ struct bound_simplifier::rw : public rewriter_tpl<rw_cfg> {
br_status bound_simplifier::reduce_app(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result, proof_ref& pr) { br_status bound_simplifier::reduce_app(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result, proof_ref& pr) {
rational N, hi, lo; rational N, hi, lo;
if (a.is_mod(f) && num_args == 2 && a.is_numeral(args[1], N)) { if (a.is_mod(f) && num_args == 2 && a.is_numeral(args[1], N)) {
expr* x = args[0];
auto& im = m_interval; auto& im = m_interval;
scoped_dep_interval i(im); scoped_dep_interval i(im);
expr* x = args[0];
get_bounds(x, i); get_bounds(x, i);
if (im.upper_is_inf(i) || im.lower_is_inf(i)) if (im.upper_is_inf(i) || im.lower_is_inf(i))
return BR_FAILED; return BR_FAILED;
@ -83,7 +83,55 @@ br_status bound_simplifier::reduce_app(func_decl* f, unsigned num_args, expr* co
} }
IF_VERBOSE(2, verbose_stream() << "potentially missed simplification: " << mk_pp(x, m) << " " << lo << " " << hi << " not reduced\n"); IF_VERBOSE(2, verbose_stream() << "potentially missed simplification: " << mk_pp(x, m) << " " << lo << " " << hi << " not reduced\n");
} }
return BR_FAILED;
expr_ref_buffer new_args(m);
expr_ref new_arg(m);
bool change = false;
for (unsigned i = 0; i < num_args; ++i) {
expr* arg = args[i];
change = reduce_arg(arg, new_arg) || change;
new_args.push_back(new_arg);
}
if (!change)
return BR_FAILED;
result = m.mk_app(f, num_args, new_args.data());
return BR_DONE;
}
bool bound_simplifier::reduce_arg(expr* arg, expr_ref& result) {
result = arg;
expr* x, *y;
rational N, lo, hi;
bool strict;
if ((a.is_le(arg, x, y) && a.is_numeral(y, N)) ||
(a.is_ge(arg, y, x) && a.is_numeral(y, N))) {
if (has_upper(x, hi, strict) && !strict && N >= hi) {
result = m.mk_true();
return true;
}
if (has_lower(x, lo, strict) && !strict && N < lo) {
result = m.mk_false();
return true;
}
return false;
}
if ((a.is_le(arg, y, x) && a.is_numeral(y, N)) ||
(a.is_ge(arg, x, y) && a.is_numeral(y, N))) {
if (has_lower(x, lo, strict) && !strict && N <= lo) {
result = m.mk_true();
return true;
}
if (has_upper(x, hi, strict) && !strict && N > hi) {
result = m.mk_false();
return true;
}
return false;
}
return false;
} }
void bound_simplifier::reduce() { void bound_simplifier::reduce() {

View file

@ -77,8 +77,12 @@ class bound_simplifier : public dependent_expr_simplifier {
return v; return v;
} }
bool reduce_arg(expr* arg, expr_ref& result);
br_status reduce_app(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result, proof_ref& pr); br_status reduce_app(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result, proof_ref& pr);
void assert_lower(expr* x, rational const& n, bool strict); void assert_lower(expr* x, rational const& n, bool strict);
void assert_upper(expr* x, rational const& n, bool strict); void assert_upper(expr* x, rational const& n, bool strict);

View file

@ -416,8 +416,9 @@ namespace smt {
unsigned r_id = mk_row(); unsigned r_id = mk_row();
scoped_row_vars _sc(m_row_vars, m_row_vars_top); scoped_row_vars _sc(m_row_vars, m_row_vars_top);
check_app(arg1, m); check_app(arg1, m);
if (reflection_enabled()) if (reflection_enabled()) {
internalize_term_core(to_app(arg0)); internalize_term_core(to_app(arg0));
}
theory_var v = internalize_mul_core(to_app(arg1)); theory_var v = internalize_mul_core(to_app(arg1));
add_row_entry<true>(r_id, val, v); add_row_entry<true>(r_id, val, v);
enode * e = mk_enode(m); enode * e = mk_enode(m);
@ -1535,6 +1536,9 @@ namespace smt {
TRACE("arith", tout << "assume_eqs(), ok: " << ok << "\n";); TRACE("arith", tout << "assume_eqs(), ok: " << ok << "\n";);
break; break;
default: default:
TRACE("arith", ctx.display(tout));
ctx.display(verbose_stream());
exit(0);
ok = process_non_linear(); ok = process_non_linear();
TRACE("arith", tout << "non_linear(), ok: " << ok << "\n";); TRACE("arith", tout << "non_linear(), ok: " << ok << "\n";);
break; break;

View file

@ -2252,6 +2252,9 @@ public:
// verbose_stream() << "not done\n"; // verbose_stream() << "not done\n";
return FC_CONTINUE; return FC_CONTINUE;
} }
st = check_nla();
if (st != FC_DONE)
return st;
} }
return st; return st;