3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-06 06:03:23 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-02-02 14:49:19 -08:00
parent d77a2ed567
commit 28c827fb69
5 changed files with 52 additions and 16 deletions

View file

@ -312,8 +312,10 @@ void static_features::update_core(expr * e) {
case OP_IDIV: case OP_IDIV:
case OP_REM: case OP_REM:
case OP_MOD: case OP_MOD:
if (!is_numeral(to_app(e)->get_arg(1), r) || r.is_zero()) if (!is_numeral(to_app(e)->get_arg(1), r) || r.is_zero()) {
m_num_uninterpreted_functions++;
m_num_non_linear++; m_num_non_linear++;
}
break; break;
} }
} }

View file

@ -837,10 +837,7 @@ namespace smt {
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
break; break;
case AS_NEW_ARITH: case AS_NEW_ARITH:
if (st.m_num_non_linear != 0 && st.m_has_int) setup_lra_arith();
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));
else
setup_lra_arith();
break; break;
default: default:
m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params));

View file

@ -39,7 +39,7 @@ namespace smt {
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::found_underspecified_op(app * n) { void theory_arith<Ext>::found_underspecified_op(app * n) {
context& ctx = get_context(); context& ctx = get_context();
m_underspecified_ops.push_back(n); m_underspecified_ops.push_back(n);
ctx.push_trail(push_back_vector<context, ptr_vector<app>>(m_underspecified_ops)); ctx.push_trail(push_back_vector<context, ptr_vector<app>>(m_underspecified_ops));
if (!m_found_underspecified_op) { if (!m_found_underspecified_op) {
@ -65,6 +65,7 @@ namespace smt {
e = m_util.mk_power0(n->get_arg(0), n->get_arg(1)); e = m_util.mk_power0(n->get_arg(0), n->get_arg(1));
} }
if (e) { if (e) {
ast_manager& m = get_manager();
literal lit = mk_eq(e, n, false); literal lit = mk_eq(e, n, false);
ctx.mark_as_relevant(lit); ctx.mark_as_relevant(lit);
ctx.assign(lit, nullptr); ctx.assign(lit, nullptr);
@ -160,6 +161,10 @@ namespace smt {
case OP_IDIV: case OP_IDIV:
case OP_REM: case OP_REM:
case OP_MOD: case OP_MOD:
case OP_DIV0:
case OP_IDIV0:
case OP_REM0:
case OP_MOD0:
return true; return true;
default: default:
break; break;
@ -3316,8 +3321,8 @@ namespace smt {
}); });
m_factory = alloc(arith_factory, get_manager()); m_factory = alloc(arith_factory, get_manager());
m.register_factory(m_factory); m.register_factory(m_factory);
compute_epsilon();
if (!m_model_depends_on_computed_epsilon) { if (!m_model_depends_on_computed_epsilon) {
compute_epsilon();
refine_epsilon(); refine_epsilon();
} }
} }

View file

@ -659,6 +659,7 @@ rational theory_arith<Ext>::get_value(theory_var v, bool & computed_epsilon) {
inf_numeral const & val = get_value(v); inf_numeral const & val = get_value(v);
if (!val.get_infinitesimal().is_zero() && !computed_epsilon) { if (!val.get_infinitesimal().is_zero() && !computed_epsilon) {
compute_epsilon(); compute_epsilon();
refine_epsilon();
computed_epsilon = true; computed_epsilon = true;
m_model_depends_on_computed_epsilon = true; m_model_depends_on_computed_epsilon = true;
} }

View file

@ -468,12 +468,39 @@ class theory_lra::imp {
} }
} }
void found_not_handled(expr* n) { void found_unsupported(expr* n) {
m_not_handled = n; std::cout << "unsupported: " << mk_pp(n, m) << "\n";
ctx().push_trail(value_trail<context, expr*>(m_not_handled));
m_not_handled = n;
}
void found_underspecified(expr* n) {
if (is_app(n) && is_underspecified(to_app(n))) { if (is_app(n) && is_underspecified(to_app(n))) {
TRACE("arith", tout << "Unhandled: " << mk_pp(n, m) << "\n";); TRACE("arith", tout << "Unhandled: " << mk_pp(n, m) << "\n";);
m_underspecified.push_back(to_app(n)); m_underspecified.push_back(to_app(n));
} }
expr* e = nullptr;
if (a.is_div(n)) {
e = a.mk_div0(to_app(n)->get_arg(0), to_app(n)->get_arg(1));
}
else if (a.is_idiv(n)) {
e = a.mk_idiv0(to_app(n)->get_arg(0), to_app(n)->get_arg(1));
}
else if (a.is_rem(n)) {
e = a.mk_rem0(to_app(n)->get_arg(0), to_app(n)->get_arg(1));
}
else if (a.is_mod(n)) {
e = a.mk_mod0(to_app(n)->get_arg(0), to_app(n)->get_arg(1));
}
else if (a.is_power(n)) {
e = a.mk_power0(to_app(n)->get_arg(0), to_app(n)->get_arg(1));
}
if (e) {
literal lit = th.mk_eq(e, n, false);
ctx().mark_as_relevant(lit);
ctx().assign(lit, nullptr);
}
} }
bool is_numeral(expr* term, rational& r) { bool is_numeral(expr* term, rational& r) {
@ -584,7 +611,7 @@ class theory_lra::imp {
// already handled // already handled
} }
else if (a.is_idiv(n, n1, n2)) { else if (a.is_idiv(n, n1, n2)) {
if (!a.is_numeral(n2, r) || r.is_zero()) found_not_handled(n); if (!a.is_numeral(n2, r) || r.is_zero()) found_underspecified(n);
m_idiv_terms.push_back(n); m_idiv_terms.push_back(n);
app * mod = a.mk_mod(n1, n2); app * mod = a.mk_mod(n1, n2);
ctx().internalize(mod, false); ctx().internalize(mod, false);
@ -594,18 +621,18 @@ class theory_lra::imp {
if (!ctx().relevancy()) mk_idiv_mod_axioms(n1, n2); if (!ctx().relevancy()) mk_idiv_mod_axioms(n1, n2);
} }
else if (a.is_rem(n, n1, n2)) { else if (a.is_rem(n, n1, n2)) {
if (!a.is_numeral(n2, r) || r.is_zero()) found_not_handled(n); if (!a.is_numeral(n2, r) || r.is_zero()) found_underspecified(n);
if (!ctx().relevancy()) mk_rem_axiom(n1, n2); if (!ctx().relevancy()) mk_rem_axiom(n1, n2);
} }
else if (a.is_div(n, n1, n2)) { else if (a.is_div(n, n1, n2)) {
if (!a.is_numeral(n2, r) || r.is_zero()) found_not_handled(n); if (!a.is_numeral(n2, r) || r.is_zero()) found_underspecified(n);
if (!ctx().relevancy()) mk_div_axiom(n1, n2); if (!ctx().relevancy()) mk_div_axiom(n1, n2);
} }
else if (a.is_power(n)) { else if (!a.is_div0(n) && !a.is_mod0(n) && !a.is_idiv0(n) && !a.is_rem0(n)) {
found_not_handled(n); found_unsupported(n);
} }
else { else {
found_not_handled(n); // no-op
} }
} }
else { else {
@ -709,6 +736,10 @@ class theory_lra::imp {
case OP_IDIV: case OP_IDIV:
case OP_REM: case OP_REM:
case OP_MOD: case OP_MOD:
case OP_DIV0:
case OP_IDIV0:
case OP_REM0:
case OP_MOD0:
return true; return true;
default: default:
break; break;
@ -1012,7 +1043,7 @@ public:
} }
else { else {
TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";); TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";);
found_not_handled(atom); found_unsupported(atom);
return true; return true;
} }
if (is_int(v) && !r.is_int()) { if (is_int(v) && !r.is_int()) {