3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-28 19:01:29 +00:00

suppress witness subs optimization

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2026-02-23 09:59:08 -10:00
parent 2ea86d94dc
commit cf3552c029
4 changed files with 19 additions and 5 deletions

View file

@ -55,6 +55,8 @@ namespace nlsat {
unsigned m_level = 0; // current level being processed
unsigned m_spanning_tree_threshold = 3; // minimum both-side count for spanning tree
bool m_no_sign_lc = false;
bool m_no_sign_disc = false;
unsigned m_l_rf = UINT_MAX; // position of lower bound in m_rel.m_rfunc
unsigned m_u_rf = UINT_MAX; // position of upper bound in m_rel.m_rfunc, UINT_MAX in section case
@ -260,6 +262,8 @@ namespace nlsat {
m_I.emplace_back(m_pm);
m_spanning_tree_threshold = m_solver.lws_spt_threshold();
m_no_sign_lc = m_solver.lws_no_sign_lc();
m_no_sign_disc = m_solver.lws_no_sign_disc();
}
// Handle a polynomial whose every coefficient evaluates to zero at the sample.
@ -443,7 +447,7 @@ namespace nlsat {
lc = m_pm.coeff(p, x, deg);
TRACE(lws, m_pm.display(tout << " adding lc: ", lc) << "\n";);
request_factorized(lc);
if (add_nzero_coeff && lc && sign(lc))
if (add_nzero_coeff && !m_no_sign_lc && lc && sign(lc))
add_nzero_coeff = false;
}
@ -455,7 +459,7 @@ namespace nlsat {
// If p is nullified at some point then at this point discriminant well be evaluated
// to zero, as can be seen from the Sylvester matrix which would
// have at least one zero row.
if (add_nzero_coeff && sign(disc)) // we can avoid adding a nonzero_coeff if sign(disc) != 0
if (add_nzero_coeff && !m_no_sign_disc && sign(disc)) // we can avoid adding a nonzero_coeff if sign(disc) != 0
add_nzero_coeff = false;
}
}
@ -1165,7 +1169,7 @@ namespace nlsat {
// No need for an additional coefficient witness in this case.
polynomial_ref witness = m_witnesses[i];
if (add_lc && witness && !is_const(witness))
if (lc && !is_zero(lc) && sign(lc))
if (lc && !is_zero(lc) && !m_no_sign_lc && sign(lc))
witness = polynomial_ref(m_pm);
add_projection_for_poly(p, m_level, witness, add_lc, add_disc);
@ -1309,14 +1313,14 @@ namespace nlsat {
bool add_lc = true;
if (!poly_has_roots(i))
if (lc && !is_zero(lc) && sign(lc))
if (lc && !is_zero(lc) && !m_no_sign_lc && sign(lc))
add_lc = false;
// if the leading coefficient is already non-zero at the sample
// AND we're adding lc, we do not need to project an additional non-null coefficient witness.
polynomial_ref witness = m_witnesses[i];
if (add_lc && witness && !is_const(witness))
if (lc && !is_zero(lc) && sign(lc))
if (lc && !is_zero(lc) && !m_no_sign_lc && sign(lc))
witness = polynomial_ref(m_pm); // zero the witnsee as lc will be the witness
add_projection_for_poly(p, m_n, witness, add_lc, true); //true to add the discriminant
}

View file

@ -24,5 +24,7 @@ def_module_params('nlsat',
('known_sat_assignment_file_name', STRING, "", "the file name of a known solution: used for debugging only"),
('lws', BOOL, True, "apply levelwise."),
('lws_spt_threshold', UINT, 4, "minimum both-side polynomial count to apply spanning tree optimization; < 2 disables spanning tree"),
('lws_no_sign_lc', BOOL, False, "suppress sign() call on leading coefficient in add_projection_for_poly"),
('lws_no_sign_disc', BOOL, False, "suppress sign() call on discriminant in add_projection_for_poly"),
('canonicalize', BOOL, True, "canonicalize polynomials.")
))

View file

@ -251,6 +251,8 @@ namespace nlsat {
bool m_apply_lws;
bool m_last_conflict_used_lws = false; // Track if last conflict explanation used levelwise
unsigned m_lws_spt_threshold = 3;
bool m_lws_no_sign_lc = false;
bool m_lws_no_sign_disc = false;
imp(solver& s, ctx& c):
m_ctx(c),
m_solver(s),
@ -312,6 +314,8 @@ namespace nlsat {
m_debug_known_solution_file_name = p.known_sat_assignment_file_name();
m_apply_lws = p.lws();
m_lws_spt_threshold = p.lws_spt_threshold(); // 0 disables spanning tree
m_lws_no_sign_lc = p.lws_no_sign_lc();
m_lws_no_sign_disc = p.lws_no_sign_disc();
m_check_lemmas |= !(m_debug_known_solution_file_name.empty());
m_ism.set_seed(m_random_seed);
@ -4718,4 +4722,6 @@ namespace nlsat {
}
bool solver::apply_levelwise() const { return m_imp->m_apply_lws; }
unsigned solver::lws_spt_threshold() const { return m_imp->m_lws_spt_threshold; }
bool solver::lws_no_sign_lc() const { return m_imp->m_lws_no_sign_lc; }
bool solver::lws_no_sign_disc() const { return m_imp->m_lws_no_sign_disc; }
};

View file

@ -249,6 +249,8 @@ namespace nlsat {
assignment& sample();
bool apply_levelwise() const;
unsigned lws_spt_threshold() const;
bool lws_no_sign_lc() const;
bool lws_no_sign_disc() const;
void reset();
void collect_statistics(statistics & st);
void reset_statistics();