mirror of
https://github.com/Z3Prover/z3
synced 2025-08-25 12:35:59 +00:00
working on reconciling perf for arithmetic solvers
this update integrates inferences to smt.arith.solver=6 related to grobner basis computation and handling of div/mod axioms to reconcile performance with smt.arith.solver=2. The default of smt.arth.nl.grobner_subs_fixed is changed to 1 to make comparison with solver=2 more direct. The selection of cluster equalities for solver=6 was reconciled with how it is done for solver=2.
This commit is contained in:
parent
9d9414c111
commit
b68af0c1e5
19 changed files with 357 additions and 282 deletions
|
@ -80,14 +80,12 @@ void theory_arith<Ext>::mark_dependents(theory_var v, svector<theory_var> & vars
|
|||
if (is_fixed(v))
|
||||
return;
|
||||
column & c = m_columns[v];
|
||||
typename svector<col_entry>::iterator it = c.begin_entries();
|
||||
typename svector<col_entry>::iterator end = c.end_entries();
|
||||
for (; it != end; ++it) {
|
||||
if (it->is_dead() || already_visited_rows.contains(it->m_row_id))
|
||||
for (auto& ce : c) {
|
||||
if (ce.is_dead() || already_visited_rows.contains(ce.m_row_id))
|
||||
continue;
|
||||
TRACE("non_linear_bug", tout << "visiting row: " << it->m_row_id << "\n";);
|
||||
already_visited_rows.insert(it->m_row_id);
|
||||
row & r = m_rows[it->m_row_id];
|
||||
TRACE("non_linear_bug", tout << "visiting row: " << ce.m_row_id << "\n";);
|
||||
already_visited_rows.insert(ce.m_row_id);
|
||||
row & r = m_rows[ce.m_row_id];
|
||||
theory_var s = r.get_base_var();
|
||||
// ignore quasi base vars... actually they should not be used if the problem is non linear...
|
||||
if (is_quasi_base(s))
|
||||
|
@ -97,14 +95,10 @@ void theory_arith<Ext>::mark_dependents(theory_var v, svector<theory_var> & vars
|
|||
// was eliminated by substitution.
|
||||
if (s != null_theory_var && is_free(s) && s != v)
|
||||
continue;
|
||||
typename vector<row_entry>::const_iterator it2 = r.begin_entries();
|
||||
typename vector<row_entry>::const_iterator end2 = r.end_entries();
|
||||
for (; it2 != end2; ++it2) {
|
||||
if (!it2->is_dead() && !is_fixed(it2->m_var))
|
||||
mark_var(it2->m_var, vars, already_found);
|
||||
if (!it2->is_dead() && is_fixed(it2->m_var)) {
|
||||
TRACE("non_linear", tout << "skipped fixed\n";);
|
||||
}
|
||||
for (auto& re : r) {
|
||||
if (!re.is_dead() && !is_fixed(re.m_var))
|
||||
mark_var(re.m_var, vars, already_found);
|
||||
CTRACE("non_linear", !re.is_dead() && is_fixed(re.m_var), tout << "skipped fixed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +113,7 @@ void theory_arith<Ext>::get_non_linear_cluster(svector<theory_var> & vars) {
|
|||
return;
|
||||
var_set already_found;
|
||||
row_set already_visited_rows;
|
||||
|
||||
for (theory_var v : m_nl_monomials) {
|
||||
expr * n = var2expr(v);
|
||||
if (ctx.is_relevant(n))
|
||||
|
@ -130,9 +125,9 @@ void theory_arith<Ext>::get_non_linear_cluster(svector<theory_var> & vars) {
|
|||
TRACE("non_linear", tout << "marking dependents of: v" << v << "\n";);
|
||||
mark_dependents(v, vars, already_found, already_visited_rows);
|
||||
}
|
||||
TRACE("non_linear", tout << "variables in non linear cluster:\n";
|
||||
for (theory_var v : vars) tout << "v" << v << " ";
|
||||
tout << "\n";);
|
||||
TRACE("non_linear", tout << "variables in non linear cluster: ";
|
||||
for (theory_var v : vars) tout << "v" << v << " "; tout << "\n";
|
||||
for (theory_var v : m_nl_monomials) tout << "non-linear v" << v << " " << mk_pp(var2expr(v), m) << "\n";);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1740,22 +1735,21 @@ grobner::monomial * theory_arith<Ext>::mk_gb_monomial(rational const & _coeff, e
|
|||
*/
|
||||
template<typename Ext>
|
||||
void theory_arith<Ext>::add_row_to_gb(row const & r, grobner & gb) {
|
||||
TRACE("non_linear", tout << "adding row to gb\n"; display_row(tout, r););
|
||||
TRACE("grobner", tout << "adding row to gb\n"; display_row(tout, r););
|
||||
ptr_buffer<grobner::monomial> monomials;
|
||||
v_dependency * dep = nullptr;
|
||||
m_tmp_var_set.reset();
|
||||
typename vector<row_entry>::const_iterator it = r.begin_entries();
|
||||
typename vector<row_entry>::const_iterator end = r.end_entries();
|
||||
for (; it != end; ++it) {
|
||||
if (!it->is_dead()) {
|
||||
rational coeff = it->m_coeff.to_rational();
|
||||
expr * m = var2expr(it->m_var);
|
||||
TRACE("non_linear", tout << "monomial: " << mk_pp(m, get_manager()) << "\n";);
|
||||
grobner::monomial * new_m = mk_gb_monomial(coeff, m, gb, dep, m_tmp_var_set);
|
||||
TRACE("non_linear", tout << "new monomial:\n"; if (new_m) gb.display_monomial(tout, *new_m); else tout << "null"; tout << "\n";);
|
||||
if (new_m)
|
||||
monomials.push_back(new_m);
|
||||
}
|
||||
for (auto& re : r) {
|
||||
if (re.is_dead())
|
||||
continue;
|
||||
rational coeff = re.m_coeff.to_rational();
|
||||
expr * m = var2expr(re.m_var);
|
||||
grobner::monomial * new_m = mk_gb_monomial(coeff, m, gb, dep, m_tmp_var_set);
|
||||
if (new_m)
|
||||
monomials.push_back(new_m);
|
||||
TRACE("grobner",
|
||||
tout << "monomial: " << mk_pp(m, get_manager()) << "\n";
|
||||
tout << "new monomial: "; if (new_m) gb.display_monomial(tout, *new_m); else tout << "null"; tout << "\n";);
|
||||
}
|
||||
gb.assert_eq_0(monomials.size(), monomials.data(), dep);
|
||||
}
|
||||
|
@ -2158,8 +2152,9 @@ bool theory_arith<Ext>::get_gb_eqs_and_look_for_conflict(ptr_vector<grobner::equ
|
|||
eqs.reset();
|
||||
gb.get_equations(eqs);
|
||||
TRACE("grobner", tout << "after gb\n";
|
||||
std::function<void(std::ostream& out, expr* v)> _fn = [&](std::ostream& out, expr* v) { out << "v" << expr2var(v); };
|
||||
for (grobner::equation* eq : eqs)
|
||||
gb.display_equation(tout, *eq);
|
||||
gb.display_equation(tout, *eq, _fn);
|
||||
);
|
||||
for (grobner::equation* eq : eqs) {
|
||||
if (is_inconsistent(eq, gb) || is_inconsistent2(eq, gb)) {
|
||||
|
@ -2259,7 +2254,9 @@ typename theory_arith<Ext>::gb_result theory_arith<Ext>::compute_grobner(svector
|
|||
ptr_vector<grobner::equation> eqs;
|
||||
|
||||
do {
|
||||
TRACE("non_linear_gb", tout << "before:\n"; gb.display(tout););
|
||||
TRACE("grobner", tout << "before grobner:\n";
|
||||
std::function<void(std::ostream& out, expr* v)> _fn = [&](std::ostream& out, expr* v) { out << "v" << expr2var(v); };
|
||||
gb.display(tout, _fn));
|
||||
compute_basis(gb, warn);
|
||||
update_statistics(gb);
|
||||
TRACE("non_linear_gb", tout << "after:\n"; gb.display(tout););
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue