mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
fix choosing rows for horner's schem
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
7cf23c1a32
commit
aef26598e5
|
@ -173,7 +173,7 @@ void emonomials::remove_cg_mon(const monomial& m) {
|
||||||
lpvar u = m.var(), w;
|
lpvar u = m.var(), w;
|
||||||
// equivalence class of u:
|
// equivalence class of u:
|
||||||
if (m_cg_table.find(u, w)) {
|
if (m_cg_table.find(u, w)) {
|
||||||
TRACE("nla_solver", tout << "erase << " << m << "\n";);
|
TRACE("nla_solver_mons", tout << "erase << " << m << "\n";);
|
||||||
m_cg_table.erase(u);
|
m_cg_table.erase(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ bool emonomials::elists_are_consistent(std::unordered_map<unsigned_vector, std::
|
||||||
c.insert(e.var());
|
c.insert(e.var());
|
||||||
auto it = lists.find(m.rvars());
|
auto it = lists.find(m.rvars());
|
||||||
|
|
||||||
CTRACE("nla_solver", it->second != c,
|
CTRACE("nla_solver_mons", it->second != c,
|
||||||
tout << "m = " << m << "\n";
|
tout << "m = " << m << "\n";
|
||||||
tout << "c = " ; print_vector(c, tout); tout << "\n";
|
tout << "c = " ; print_vector(c, tout); tout << "\n";
|
||||||
if (it == lists.end()) {
|
if (it == lists.end()) {
|
||||||
|
@ -249,7 +249,7 @@ void emonomials::insert_cg_mon(monomial & m) {
|
||||||
lpvar v = m.var(), w;
|
lpvar v = m.var(), w;
|
||||||
if (m_cg_table.find(v, w)) {
|
if (m_cg_table.find(v, w)) {
|
||||||
if (v == w) {
|
if (v == w) {
|
||||||
TRACE("nla_solver", tout << "found " << v << "\n";);
|
TRACE("nla_solver_mons", tout << "found " << v << "\n";);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned v_idx = m_var2index[v];
|
unsigned v_idx = m_var2index[v];
|
||||||
|
@ -257,11 +257,11 @@ void emonomials::insert_cg_mon(monomial & m) {
|
||||||
unsigned max_i = std::max(v_idx, w_idx);
|
unsigned max_i = std::max(v_idx, w_idx);
|
||||||
while (m_u_f.get_num_vars() <= max_i)
|
while (m_u_f.get_num_vars() <= max_i)
|
||||||
m_u_f.mk_var();
|
m_u_f.mk_var();
|
||||||
TRACE("nla_solver", tout << "merge " << v << " idx " << v_idx << ", and " << w << " idx " << w_idx << "\n";);
|
TRACE("nla_solver_mons", tout << "merge " << v << " idx " << v_idx << ", and " << w << " idx " << w_idx << "\n";);
|
||||||
m_u_f.merge(v_idx, w_idx);
|
m_u_f.merge(v_idx, w_idx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TRACE("nla_solver", tout << "insert " << m << "\n";);
|
TRACE("nla_solver_mons", tout << "insert " << m << "\n";);
|
||||||
m_cg_table.insert(v);
|
m_cg_table.insert(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ bool emonomials::is_visited(monomial const& m) const {
|
||||||
class of equal up-to var_eqs monomials.
|
class of equal up-to var_eqs monomials.
|
||||||
*/
|
*/
|
||||||
void emonomials::add(lpvar v, unsigned sz, lpvar const* vs) {
|
void emonomials::add(lpvar v, unsigned sz, lpvar const* vs) {
|
||||||
TRACE("nla_solver", tout << "v = " << v << "\n";);
|
TRACE("nla_solver_mons", tout << "v = " << v << "\n";);
|
||||||
unsigned idx = m_monomials.size();
|
unsigned idx = m_monomials.size();
|
||||||
m_monomials.push_back(monomial(v, sz, vs, idx));
|
m_monomials.push_back(monomial(v, sz, vs, idx));
|
||||||
lpvar last_var = UINT_MAX;
|
lpvar last_var = UINT_MAX;
|
||||||
|
@ -376,17 +376,17 @@ void emonomials::merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_va
|
||||||
}
|
}
|
||||||
|
|
||||||
void emonomials::after_merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
|
void emonomials::after_merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
|
||||||
TRACE("nla_solver", tout << r2 << " <- " << r1 << "\n";);
|
TRACE("nla_solver_mons", tout << r2 << " <- " << r1 << "\n";);
|
||||||
if (m_ve.find(~r1) == m_ve.find(~r2)) { // the other sign has also been merged
|
if (m_ve.find(~r1) == m_ve.find(~r2)) { // the other sign has also been merged
|
||||||
m_use_lists.reserve(std::max(r2.var(), r1.var()) + 1);
|
m_use_lists.reserve(std::max(r2.var(), r1.var()) + 1);
|
||||||
TRACE("nla_solver", tout << "rehasing " << r1.var() << "\n";);
|
TRACE("nla_solver_mons", tout << "rehasing " << r1.var() << "\n";);
|
||||||
merge_cells(m_use_lists[r2.var()], m_use_lists[r1.var()]);
|
merge_cells(m_use_lists[r2.var()], m_use_lists[r1.var()]);
|
||||||
rehash_cg(r1.var());
|
rehash_cg(r1.var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void emonomials::unmerge_eh(signed_var r2, signed_var r1) {
|
void emonomials::unmerge_eh(signed_var r2, signed_var r1) {
|
||||||
TRACE("nla_solver", tout << r2 << " -> " << r1 << "\n";);
|
TRACE("nla_solver_mons", tout << r2 << " -> " << r1 << "\n";);
|
||||||
if (m_ve.find(~r1) != m_ve.find(~r2)) { // the other sign has also been unmerged
|
if (m_ve.find(~r1) != m_ve.find(~r2)) { // the other sign has also been unmerged
|
||||||
unmerge_cells(m_use_lists[r2.var()], m_use_lists[r1.var()]);
|
unmerge_cells(m_use_lists[r2.var()], m_use_lists[r1.var()]);
|
||||||
rehash_cg(r1.var());
|
rehash_cg(r1.var());
|
||||||
|
|
|
@ -27,9 +27,20 @@ namespace nla {
|
||||||
typedef intervals::interval interv;
|
typedef intervals::interval interv;
|
||||||
horner::horner(core * c) : common(c), m_intervals(c, c->reslim()) {}
|
horner::horner(core * c) : common(c), m_intervals(c, c->reslim()) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool horner::row_has_monomial_to_refine(const T& row) const {
|
||||||
|
for (const auto& p : row) {
|
||||||
|
if (c().m_to_refine.contains(p.var()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
// Returns true if the row has at least two monomials sharing a variable
|
// Returns true if the row has at least two monomials sharing a variable
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool horner::row_is_interesting(const T& row) const {
|
bool horner::row_is_interesting(const T& row) const {
|
||||||
|
TRACE("nla_solver", m_core->print_term(row, tout););
|
||||||
|
SASSERT(row_has_monomial_to_refine(row));
|
||||||
std::unordered_set<lpvar> seen;
|
std::unordered_set<lpvar> seen;
|
||||||
for (const auto& p : row) {
|
for (const auto& p : row) {
|
||||||
lpvar j = p.var();
|
lpvar j = p.var();
|
||||||
|
@ -98,7 +109,8 @@ void horner::horner_lemmas() {
|
||||||
unsigned r = c().random();
|
unsigned r = c().random();
|
||||||
unsigned sz = rows.size();
|
unsigned sz = rows.size();
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
if (lemmas_on_row(matrix.m_rows[(i + r) % sz]))
|
unsigned row_index = rows[(i + r) % sz];
|
||||||
|
if (lemmas_on_row(matrix.m_rows[row_index]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,6 +125,7 @@ nex horner::nexvar(lpvar j) const {
|
||||||
nex e(expr_type::MUL);
|
nex e(expr_type::MUL);
|
||||||
for (lpvar k : m.vars()) {
|
for (lpvar k : m.vars()) {
|
||||||
e.add_child(nex::var(k));
|
e.add_child(nex::var(k));
|
||||||
|
CTRACE("nla_horner", c().is_monomial_var(k), c().print_var(k, tout) << "\n";);
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,5 +46,8 @@ public:
|
||||||
void set_interval_for_scalar(intervals::interval&, const rational&);
|
void set_interval_for_scalar(intervals::interval&, const rational&);
|
||||||
void set_var_interval(lpvar j, intervals::interval&);
|
void set_var_interval(lpvar j, intervals::interval&);
|
||||||
bool lemmas_on_expr(nex &);
|
bool lemmas_on_expr(nex &);
|
||||||
|
|
||||||
|
template <typename T> // T has an iterator of (coeff(), var())
|
||||||
|
bool row_has_monomial_to_refine(const T&) const;
|
||||||
}; // end of horner
|
}; // end of horner
|
||||||
}
|
}
|
||||||
|
|
|
@ -1238,7 +1238,7 @@ void core::negate_relation(unsigned j, const rational& a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core:: conflict_found() const {
|
bool core::conflict_found() const {
|
||||||
for (const auto & l : * m_lemma_vec) {
|
for (const auto & l : * m_lemma_vec) {
|
||||||
if (l.is_conflict())
|
if (l.is_conflict())
|
||||||
return true;
|
return true;
|
||||||
|
@ -1246,11 +1246,11 @@ bool core:: conflict_found() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core:: done() const {
|
bool core::done() const {
|
||||||
return m_lemma_vec->size() >= 10 || conflict_found();
|
return m_lemma_vec->size() >= 10 || conflict_found();
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool core:: inner_check(bool derived) {
|
lbool core::inner_check(bool derived) {
|
||||||
if (derived && (lp_settings().st().m_nla_calls % m_settings.horner_frequency() == 0))
|
if (derived && (lp_settings().st().m_nla_calls % m_settings.horner_frequency() == 0))
|
||||||
m_horner.horner_lemmas();
|
m_horner.horner_lemmas();
|
||||||
if (done()) {
|
if (done()) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ bool intervals::check_interval_for_conflict_on_zero_upper(const interval & i) {
|
||||||
svector<lp::constraint_index> expl;
|
svector<lp::constraint_index> expl;
|
||||||
m_dep_manager.linearize(i.m_upper_dep, expl);
|
m_dep_manager.linearize(i.m_upper_dep, expl);
|
||||||
_().current_expl().add_expl(expl);
|
_().current_expl().add_expl(expl);
|
||||||
TRACE("nla_cn", print_lemma(tout););
|
TRACE("nla_solver", print_lemma(tout););
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ bool intervals::check_interval_for_conflict_on_zero_lower(const interval & i) {
|
||||||
svector<lp::constraint_index> expl;
|
svector<lp::constraint_index> expl;
|
||||||
m_dep_manager.linearize(i.m_lower_dep, expl);
|
m_dep_manager.linearize(i.m_lower_dep, expl);
|
||||||
_().current_expl().add_expl(expl);
|
_().current_expl().add_expl(expl);
|
||||||
TRACE("nla_cn_lemmas", print_lemma(tout););
|
TRACE("nla_solver", print_lemma(tout););
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue