mirror of
https://github.com/Z3Prover/z3
synced 2026-08-02 12:13:25 +00:00
nla: add LP-based nonlinear bound optimization for cross-nested confl… (#10180)
…icts Add core::optimize_nl_bounds() (gated by arith.nl.optimize_bounds) which runs LP max/min over monomial leaf variables inside core::propagate(), analogous to solver=2's max_min_nl_vars, so nla (arith.solver=6) can detect cross-nested conflicts previously missed. Collect improved bounds first, then apply them and re-establish feasibility once; reconcile the core solver via find_feasible_solution before the raw maximize solves to preserve inf_heap_is_correct(). Skip null witnesses in get_dependencies_of_maximum for implied/unconditional bounds. On FStar-UInt128-divergence solver=6 this yields unsat in 2 final-checks, seed-insensitive (seeds 1-10). Copilot-Session: ac36bb84-de91-4e6c-86df-6008c7396ceb --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac36bb84-de91-4e6c-86df-6008c7396ceb Copilot-Session: 96a14756-2ffe-4cc3-87e7-49fda1b6113a
This commit is contained in:
parent
53fa8f9cc4
commit
aba41d026f
13 changed files with 370 additions and 292 deletions
|
|
@ -1349,7 +1349,6 @@ public:
|
|||
literal eqz = mk_literal(m.mk_eq(q, zero));
|
||||
literal mod_ge_0 = mk_literal(a.mk_ge(mod, zero));
|
||||
|
||||
|
||||
// q = 0 or p = (p mod q) + q * (p div q)
|
||||
// q = 0 or (p mod q) >= 0
|
||||
// q >= 0 or (p mod q) + q <= -1
|
||||
|
|
@ -1746,6 +1745,7 @@ public:
|
|||
IF_VERBOSE(12, verbose_stream() << "final-check " << lp().get_status() << "\n");
|
||||
lbool is_sat = l_true;
|
||||
SASSERT(lp().ax_is_correct());
|
||||
propagate_nla();
|
||||
if (!lp().is_feasible() || lp().has_changed_columns())
|
||||
is_sat = make_feasible();
|
||||
final_check_status st = FC_DONE;
|
||||
|
|
@ -2126,7 +2126,6 @@ public:
|
|||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
TRACE(arith, tout << "is_lower: " << is_lower << " pos " << pos << "\n";);
|
||||
expr_ref atom(m);
|
||||
// TBD utility: lp::lar_term term = mk_term(ineq.m_poly);
|
||||
// then term is used instead of ineq.m_term
|
||||
|
|
@ -2135,6 +2134,7 @@ public:
|
|||
else
|
||||
// create term >= 0 (or term <= 0)
|
||||
atom = mk_bound(ineq.term(), ineq.rs(), is_lower);
|
||||
TRACE(arith, tout << "is_lower: " << is_lower << " pos " << pos << " " << atom << "\n";);
|
||||
return literal(ctx().get_bool_var(atom), pos);
|
||||
}
|
||||
|
||||
|
|
@ -2265,7 +2265,6 @@ public:
|
|||
bool propagate_core() {
|
||||
m_model_is_initialized = false;
|
||||
flush_bound_axioms();
|
||||
propagate_nla();
|
||||
if (ctx().inconsistent())
|
||||
return true;
|
||||
if (!can_propagate_core())
|
||||
|
|
@ -2329,12 +2328,14 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void propagate_nla() {
|
||||
bool propagate_nla() {
|
||||
bool propagated = false;
|
||||
if (m_nla) {
|
||||
m_nla->propagate();
|
||||
propagated = m_nla->propagate() || propagated;
|
||||
add_lemmas();
|
||||
lp().collect_more_rows_for_lp_propagation();
|
||||
}
|
||||
return propagated;
|
||||
}
|
||||
|
||||
void add_equality(lpvar j, rational const& k, lp::explanation const& exp) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue