diff --git a/src/math/lp/horner.cpp b/src/math/lp/horner.cpp index 6fa6e2f06..3bb84f9c7 100644 --- a/src/math/lp/horner.cpp +++ b/src/math/lp/horner.cpp @@ -241,7 +241,7 @@ void horner::add_linear_to_vector(const nex& e, vector v.back().second) { smallest_j = v.back().second; a_index = v.size() - 1; } } } + TRACE("nla_horner_details", tout << "a_index = " << a_index << ", v="; print_vector(v, tout) << "\n";); a = v[a_index].first; lp::lar_term t; @@ -277,7 +278,8 @@ lp::lar_term horner::expression_to_normalized_term(nex& e, rational& a, rational } } TRACE("nla_horner_details", tout << a << "* ("; - lp::lar_solver::print_term_as_indices(t, tout) << ") + " << b << std::endl;); + lp::lar_solver::print_term_as_indices(t, tout) << ") + " << b << std::endl;); + SASSERT(t.is_normalized()); return t; } @@ -346,7 +348,7 @@ interv horner::interval_of_sum(const nex& e) { TRACE("nla_horner_details", tout << "e=" << e << "\n";); SASSERT(e.is_sum()); interv i_e = interval_of_sum_no_terms(e); - if (e.sum_is_linear()) { + if (e.sum_is_a_linear_term()) { interv i_from_term ; if (interval_from_term(e, i_from_term) && diff --git a/src/math/lp/lar_solver.cpp b/src/math/lp/lar_solver.cpp index 182bd3fb3..c489aed15 100644 --- a/src/math/lp/lar_solver.cpp +++ b/src/math/lp/lar_solver.cpp @@ -2376,13 +2376,17 @@ void lar_solver::register_normalized_term(const lar_term& t, lpvar j) { lar_term normalized_t = t.get_normalized_by_min_var(); TRACE("lar_solver_terms", tout << "t="; print_term_as_indices(t, tout); tout << ", normalized_t="; print_term_as_indices(normalized_t, tout) << "\n";); - lp_assert(m_normalized_terms_to_columns.find(normalized_t) == m_normalized_terms_to_columns.end()); - m_normalized_terms_to_columns[normalized_t] = j; + if (m_normalized_terms_to_columns.find(normalized_t) == m_normalized_terms_to_columns.end()) { + m_normalized_terms_to_columns[normalized_t] = j; + } else { + TRACE("lar_solver_terms", tout << "the term has been seen already\n";); + } } void lar_solver::deregister_normalized_term(const lar_term& t) { + TRACE("lar_solver_terms", tout << "deregister term "; + print_term_as_indices(t, tout) << "\n";); lar_term normalized_t = t.get_normalized_by_min_var(); - lp_assert(m_normalized_terms_to_columns.find(normalized_t) != m_normalized_terms_to_columns.end()); m_normalized_terms_to_columns.erase(normalized_t); } @@ -2395,9 +2399,15 @@ void lar_solver::register_existing_terms() { } unsigned lar_solver::fetch_normalized_term_column(const lar_term& c) const { + TRACE("lar_solver_terms", tout << "looking for term "; + print_term_as_indices(c, tout) << "\n";); + lp_assert(c.is_normalized()); auto it = m_normalized_terms_to_columns.find(c); - if (it != m_normalized_terms_to_columns.end()) + if (it != m_normalized_terms_to_columns.end()) { + TRACE("lar_solver_terms", tout << "got " << it->second << "\n" ;); return it->second; + } + TRACE("lar_solver_terms", tout << "have not found\n";); return -1; } } // namespace lp diff --git a/src/math/lp/lar_term.h b/src/math/lp/lar_term.h index 469e34f22..108325045 100644 --- a/src/math/lp/lar_term.h +++ b/src/math/lp/lar_term.h @@ -23,6 +23,7 @@ namespace lp { class lar_term { // the term evaluates to sum of m_coeffs + typedef unsigned lpvar; u_map m_coeffs; public: lar_term() {} @@ -149,8 +150,41 @@ public: bool operator!=(const self_type &other) const { return !(*this == other); } }; - - const_iterator begin() const { return m_coeffs.begin();} - const_iterator end() const { return m_coeffs.end(); } + bool is_normalized() const { + lpvar min_var = -1; + mpq c; + for (const auto & p : *this) { + if (p.var() < min_var) { + min_var = p.var(); + } + } + lar_term r; + for (const auto & p : *this) { + if (p.var() == min_var) { + return p.coeff().is_one(); + } + } + lp_unreachable(); + return false; + } + + // a is the coefficient by which we diveded the term to normalize it + lar_term get_normalized_by_min_var(mpq& a) const { + a = m_coeffs.begin()->second; + if (a.is_one()) { + return *this; + } + lar_term r; + auto it = m_coeffs.begin(); + r.add_var(it->first); + it++; + for(;it != m_coeffs.end(); it++) { + r.add_coeff_var(it->second / a, it->first); + } + return r; + } + const_iterator begin() const { return const_iterator(m_coeffs.begin());} + const_iterator end() const { return const_iterator(m_coeffs.end()); } + }; } diff --git a/src/math/lp/lp_utils.h b/src/math/lp/lp_utils.h index cef119168..9a8dc3fd3 100644 --- a/src/math/lp/lp_utils.h +++ b/src/math/lp/lp_utils.h @@ -102,9 +102,7 @@ std::ostream& print_linear_combination_customized(const vector 1) return false; if (d > degree) degree = d; + if (!e.is_scalar()) + number_of_non_scalars++; } - return degree == 1; + return degree == 1 && number_of_non_scalars > 1; } int get_degree() const {