From 896b3ccf6909859f534e17617a8b9e51d42fecee Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 21 Nov 2025 21:02:44 -0800 Subject: [PATCH] enable inequalities that are not normal form Signed-off-by: Nikolaj Bjorner --- src/smt/theory_lra.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 50e2860e4..73f821a32 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -885,6 +885,9 @@ public: mk_is_int_axiom(n); } + ptr_vector m_delay_ineqs; + unsigned m_delay_ineqs_qhead = 0; + bool internalize_atom(app * atom, bool gate_ctx) { TRACE(arith_internalize, tout << bpp(atom) << "\n";); SASSERT(!ctx().b_internalized(atom)); @@ -915,6 +918,11 @@ public: internalize_is_int(atom); return true; } + else if (a.is_le(atom) || a.is_ge(atom)) { + m_delay_ineqs.push_back(atom); + ctx().push_trail(push_back_vector>(m_delay_ineqs)); + return true; + } else { TRACE(arith, tout << "Could not internalize " << mk_pp(atom, m) << "\n";); found_unsupported(atom); @@ -2176,6 +2184,8 @@ public: unsigned total_conflicts = ctx().get_num_conflicts(); if (total_conflicts < 10) return true; + if (m_delay_ineqs_qhead < m_delay_ineqs.size()) + return true; double f = static_cast(m_num_conflicts)/static_cast(total_conflicts); return f >= adaptive_assertion_threshold(); } @@ -2185,7 +2195,8 @@ public: } bool can_propagate_core() { - return m_asserted_atoms.size() > m_asserted_qhead || m_new_def || lp().has_changed_columns(); + return m_asserted_atoms.size() > m_asserted_qhead || m_new_def || lp().has_changed_columns() || + m_delay_ineqs_qhead < m_delay_ineqs.size(); } bool propagate() { @@ -2200,6 +2211,29 @@ public: return true; if (!can_propagate_core()) return false; + + for (; m_delay_ineqs_qhead < m_delay_ineqs.size() && !ctx().inconsistent() && m.inc(); ++m_delay_ineqs_qhead) { + auto atom = m_delay_ineqs[m_delay_ineqs_qhead]; + ctx().push_trail(value_trail(m_delay_ineqs_qhead)); + if (!ctx().is_relevant(atom)) + continue; + expr *x, *y; + if (a.is_le(atom, x, y)) { + auto lit1 = mk_literal(atom); + auto lit2 = mk_literal(a.mk_le(a.mk_sub(x, y), a.mk_numeral(rational(0), a.is_int(x->get_sort())))); + mk_axiom(~lit1, lit2); + mk_axiom(lit1, ~lit2); + } + else if (a.is_ge(atom, x, y)) { + auto lit1 = mk_literal(atom); + auto lit2 = mk_literal(a.mk_ge(a.mk_sub(x, y), a.mk_numeral(rational(0), a.is_int(x->get_sort())))); + mk_axiom(~lit1, lit2); + mk_axiom(lit1, ~lit2); + } + else { + UNREACHABLE(); + } + } m_new_def = false; while (m_asserted_qhead < m_asserted_atoms.size() && !ctx().inconsistent() && m.inc()) {