mirror of
https://github.com/Z3Prover/z3
synced 2025-06-23 14:23:40 +00:00
stronger lemmas to avoid branching
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
580ebead79
commit
63e62ec1bb
8 changed files with 156 additions and 62 deletions
|
@ -1974,7 +1974,7 @@ public:
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
expr_ref_vector ts(m);
|
expr_ref_vector ts(m);
|
||||||
rational rhs = c.m_right_side;
|
rational rhs = c.m_right_side;
|
||||||
for (auto cv : c.get_left_side_coefficients()) {
|
for (auto cv : c.coeffs()) {
|
||||||
ts.push_back(multerm(cv.first, var2expr(cv.second)));
|
ts.push_back(multerm(cv.first, var2expr(cv.second)));
|
||||||
}
|
}
|
||||||
switch (c.m_kind) {
|
switch (c.m_kind) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ inline std::string lconstraint_kind_string(lconstraint_kind t) {
|
||||||
struct lar_base_constraint {
|
struct lar_base_constraint {
|
||||||
lconstraint_kind m_kind;
|
lconstraint_kind m_kind;
|
||||||
mpq m_right_side;
|
mpq m_right_side;
|
||||||
virtual vector<std::pair<mpq, var_index>> get_left_side_coefficients() const = 0;
|
virtual vector<std::pair<mpq, var_index>> coeffs() const = 0;
|
||||||
lar_base_constraint() {}
|
lar_base_constraint() {}
|
||||||
lar_base_constraint(lconstraint_kind kind, const mpq& right_side) :m_kind(kind), m_right_side(right_side) {}
|
lar_base_constraint(lconstraint_kind kind, const mpq& right_side) :m_kind(kind), m_right_side(right_side) {}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ struct lar_base_constraint {
|
||||||
|
|
||||||
struct lar_var_constraint: public lar_base_constraint {
|
struct lar_var_constraint: public lar_base_constraint {
|
||||||
unsigned m_j;
|
unsigned m_j;
|
||||||
vector<std::pair<mpq, var_index>> get_left_side_coefficients() const override {
|
vector<std::pair<mpq, var_index>> coeffs() const override {
|
||||||
vector<std::pair<mpq, var_index>> ret;
|
vector<std::pair<mpq, var_index>> ret;
|
||||||
ret.push_back(std::make_pair(one_of_type<mpq>(), m_j));
|
ret.push_back(std::make_pair(one_of_type<mpq>(), m_j));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -71,7 +71,7 @@ struct lar_var_constraint: public lar_base_constraint {
|
||||||
|
|
||||||
struct lar_term_constraint: public lar_base_constraint {
|
struct lar_term_constraint: public lar_base_constraint {
|
||||||
const lar_term * m_term;
|
const lar_term * m_term;
|
||||||
vector<std::pair<mpq, var_index>> get_left_side_coefficients() const override {
|
vector<std::pair<mpq, var_index>> coeffs() const override {
|
||||||
return m_term->coeffs_as_vector();
|
return m_term->coeffs_as_vector();
|
||||||
}
|
}
|
||||||
unsigned size() const override { return m_term->size();}
|
unsigned size() const override { return m_term->size();}
|
||||||
|
@ -95,6 +95,6 @@ public:
|
||||||
return static_cast<unsigned>(m_coeffs.size());
|
return static_cast<unsigned>(m_coeffs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<std::pair<mpq, var_index>> get_left_side_coefficients() const override { return m_coeffs; }
|
vector<std::pair<mpq, var_index>> coeffs() const override { return m_coeffs; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ bool lar_solver::the_relations_are_of_same_type(const vector<std::pair<mpq, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
void lar_solver::register_in_map(std::unordered_map<var_index, mpq> & coeffs, const lar_base_constraint & cn, const mpq & a) {
|
void lar_solver::register_in_map(std::unordered_map<var_index, mpq> & coeffs, const lar_base_constraint & cn, const mpq & a) {
|
||||||
for (auto & it : cn.get_left_side_coefficients()) {
|
for (auto & it : cn.coeffs()) {
|
||||||
unsigned j = it.second;
|
unsigned j = it.second;
|
||||||
auto p = coeffs.find(j);
|
auto p = coeffs.find(j);
|
||||||
if (p == coeffs.end())
|
if (p == coeffs.end())
|
||||||
|
@ -1332,7 +1332,7 @@ std::ostream& lar_solver::print_terms(std::ostream& out) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& lar_solver::print_left_side_of_constraint(const lar_base_constraint * c, std::ostream & out) const {
|
std::ostream& lar_solver::print_left_side_of_constraint(const lar_base_constraint * c, std::ostream & out) const {
|
||||||
print_linear_combination_of_column_indices(c->get_left_side_coefficients(), out);
|
print_linear_combination_of_column_indices(c->coeffs(), out);
|
||||||
mpq free_coeff = c->get_free_coeff_of_left_side();
|
mpq free_coeff = c->get_free_coeff_of_left_side();
|
||||||
if (!is_zero(free_coeff))
|
if (!is_zero(free_coeff))
|
||||||
out << " + " << free_coeff;
|
out << " + " << free_coeff;
|
||||||
|
@ -1371,7 +1371,7 @@ std::ostream& lar_solver::print_term_as_indices(lar_term const& term, std::ostre
|
||||||
|
|
||||||
mpq lar_solver::get_left_side_val(const lar_base_constraint & cns, const std::unordered_map<var_index, mpq> & var_map) const {
|
mpq lar_solver::get_left_side_val(const lar_base_constraint & cns, const std::unordered_map<var_index, mpq> & var_map) const {
|
||||||
mpq ret = cns.get_free_coeff_of_left_side();
|
mpq ret = cns.get_free_coeff_of_left_side();
|
||||||
for (auto & it : cns.get_left_side_coefficients()) {
|
for (auto & it : cns.coeffs()) {
|
||||||
var_index j = it.second;
|
var_index j = it.second;
|
||||||
auto vi = var_map.find(j);
|
auto vi = var_map.find(j);
|
||||||
lp_assert(vi != var_map.end());
|
lp_assert(vi != var_map.end());
|
||||||
|
|
|
@ -598,6 +598,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& print_column_info(unsigned j, std::ostream& out) const {
|
||||||
|
return m_mpq_lar_core_solver.m_r_solver.print_column_info(j, out);
|
||||||
|
}
|
||||||
|
|
||||||
bool has_int_var() const;
|
bool has_int_var() const;
|
||||||
bool has_inf_int() const {
|
bool has_inf_int() const {
|
||||||
for (unsigned j = 0; j < column_count(); j++) {
|
for (unsigned j = 0; j < column_count(); j++) {
|
||||||
|
|
|
@ -108,6 +108,7 @@ struct stats {
|
||||||
unsigned m_patches_success;
|
unsigned m_patches_success;
|
||||||
unsigned m_hnf_cutter_calls;
|
unsigned m_hnf_cutter_calls;
|
||||||
unsigned m_hnf_cuts;
|
unsigned m_hnf_cuts;
|
||||||
|
unsigned m_nla_calls;
|
||||||
stats() { reset(); }
|
stats() { reset(); }
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -495,6 +495,7 @@ struct solver::imp {
|
||||||
break;
|
break;
|
||||||
case llc::NE:
|
case llc::NE:
|
||||||
r = explain_lower_bound(t, rs + rational(1), exp) || explain_upper_bound(t, rs - rational(1), exp);
|
r = explain_lower_bound(t, rs + rational(1), exp) || explain_upper_bound(t, rs - rational(1), exp);
|
||||||
|
CTRACE("nla_solver", r, tout << "ineq:"; print_ineq(ineq(cmp, t, rs), tout); print_explanation(exp, tout << ", "););
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SASSERT(false);
|
SASSERT(false);
|
||||||
|
@ -510,7 +511,6 @@ struct solver::imp {
|
||||||
void mk_ineq(lp::lar_term& t, llc cmp, const rational& rs, lemma& l) {
|
void mk_ineq(lp::lar_term& t, llc cmp, const rational& rs, lemma& l) {
|
||||||
TRACE("nla_solver", m_lar_solver.print_term(t, tout << "t = "););
|
TRACE("nla_solver", m_lar_solver.print_term(t, tout << "t = "););
|
||||||
if (explain_ineq(t, cmp, rs)) {
|
if (explain_ineq(t, cmp, rs)) {
|
||||||
TRACE("nla_solver", tout << "explained\n";);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lar_solver.subs_term_columns(t);
|
m_lar_solver.subs_term_columns(t);
|
||||||
|
@ -710,6 +710,7 @@ struct solver::imp {
|
||||||
// abs_vars_key is formed by m_vars_equivalence.get_abs_root_for_var(k), where
|
// abs_vars_key is formed by m_vars_equivalence.get_abs_root_for_var(k), where
|
||||||
// k runs over m.
|
// k runs over m.
|
||||||
void generate_sign_lemma_model_based(const monomial& m, const monomial& n, const rational& sign) {
|
void generate_sign_lemma_model_based(const monomial& m, const monomial& n, const rational& sign) {
|
||||||
|
TRACE("nla_solver",);
|
||||||
add_empty_lemma();
|
add_empty_lemma();
|
||||||
if (sign.is_zero()) {
|
if (sign.is_zero()) {
|
||||||
// either m or n has to be equal zero, but it is not the case
|
// either m or n has to be equal zero, but it is not the case
|
||||||
|
@ -776,29 +777,50 @@ struct solver::imp {
|
||||||
return sign;
|
return sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_zero_lemma(const monomial& m) {
|
void negate_strict_sign(lpvar j) {
|
||||||
unsigned zero_j = -1;
|
SASSERT(!vvr(j).is_zero());
|
||||||
for (unsigned j : m.vars()){
|
mk_ineq(j, (rat_sign(vvr(j)) == 1? llc::LE : llc::GE), current_lemma());
|
||||||
if (vvr(j).is_zero()){
|
|
||||||
zero_j = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SASSERT(zero_j + 1);
|
|
||||||
mk_ineq(zero_j, llc::NE, m_lemma_vec->back());
|
|
||||||
mk_ineq(m.var(), llc::EQ, m_lemma_vec->back());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we know here that the value one of the vars of each monomial is zero
|
void generate_strict_case_zero_lemma(const monomial& m, unsigned zero_j, int sign_of_zj) {
|
||||||
// so the value of each monomial has to be zero
|
// we know all the signs
|
||||||
bool sign_lemma_for_zero_on_list(const unsigned_vector& mon_list) {
|
for (unsigned j : m){
|
||||||
for (unsigned i : mon_list) {
|
if (j == zero_j) {
|
||||||
if (!vvr(m_monomials[i]).is_zero()) {
|
mk_ineq(j, (sign_of_zj == 1? llc::GT : llc::LT), current_lemma());
|
||||||
generate_zero_lemma(m_monomials[i]);
|
}
|
||||||
return true;
|
else {
|
||||||
|
negate_strict_sign(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
negate_strict_sign(m.var());
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_zero_lemma(const monomial& m) {
|
||||||
|
SASSERT(!vvr(m).is_zero());
|
||||||
|
int sign = rat_sign(vvr(m));
|
||||||
|
unsigned zero_j = -1;
|
||||||
|
for (unsigned j : m){
|
||||||
|
const rational & v = vvr(j);
|
||||||
|
if (v.is_zero()){
|
||||||
|
if (zero_j + 1 == 0) {
|
||||||
|
zero_j = j;
|
||||||
|
} else {
|
||||||
|
sign = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sign *= rat_sign(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("nla_solver", tout << "sign = " << sign << "\n";);
|
||||||
|
|
||||||
|
SASSERT(zero_j + 1);
|
||||||
|
if (sign == 0) {
|
||||||
|
mk_ineq(zero_j, llc::NE, current_lemma());
|
||||||
|
mk_ineq(m.var(), llc::EQ, current_lemma());
|
||||||
|
} else {
|
||||||
|
generate_strict_case_zero_lemma(m, zero_j, sign);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rational rat_sign(const monomial& m) const {
|
rational rat_sign(const monomial& m) const {
|
||||||
|
@ -967,19 +989,14 @@ struct solver::imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & print_var(lpvar j, std::ostream & out) const {
|
std::ostream & print_var(lpvar j, std::ostream & out) const {
|
||||||
bool is_monomial = false;
|
|
||||||
out << "[" << j << "] = ";
|
out << "[" << j << "] = ";
|
||||||
for (const monomial & m : m_monomials) {
|
auto it = m_var_to_its_monomial.find(j);
|
||||||
if (j == m.var()) {
|
if (it != m_var_to_its_monomial.end()) {
|
||||||
is_monomial = true;
|
print_monomial(m_monomials[it->second], out);
|
||||||
print_monomial(m, out);
|
|
||||||
out << " = " << vvr(j);;
|
out << " = " << vvr(j);;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!is_monomial)
|
m_lar_solver.print_column_info(j, out) <<";";
|
||||||
out << m_lar_solver.get_variable_name(j) << " = " << vvr(j);
|
|
||||||
out <<";";
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1585,7 +1602,11 @@ struct solver::imp {
|
||||||
m_rm_table.init_to_refine(ref);
|
m_rm_table.init_to_refine(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned random() {return m_lar_solver.settings().random_next();}
|
lp::lp_settings& settings() {
|
||||||
|
return m_lar_solver.settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned random() {return settings().random_next();}
|
||||||
|
|
||||||
// use basic multiplication properties to create a lemma
|
// use basic multiplication properties to create a lemma
|
||||||
bool basic_lemma(bool derived) {
|
bool basic_lemma(bool derived) {
|
||||||
|
@ -1683,7 +1704,7 @@ struct solver::imp {
|
||||||
m_vars_equivalence.create_tree();
|
m_vars_equivalence.create_tree();
|
||||||
TRACE("nla_solver", tout << "number of equivs = " << m_vars_equivalence.size(););
|
TRACE("nla_solver", tout << "number of equivs = " << m_vars_equivalence.size(););
|
||||||
|
|
||||||
SASSERT((m_lar_solver.settings().random_next() % 100) || tables_are_ok());
|
SASSERT((settings().random_next() % 100) || tables_are_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vars_table_is_ok() const {
|
bool vars_table_is_ok() const {
|
||||||
|
@ -1756,12 +1777,34 @@ struct solver::imp {
|
||||||
out << "\n}";
|
out << "\n}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_monomial_stats(const monomial& m, std::ostream& out) {
|
||||||
|
if (m.size() == 2) return;
|
||||||
|
monomial_coeff mc = canonize_monomial(m);
|
||||||
|
for(unsigned i = 0; i < mc.vars().size(); i++){
|
||||||
|
if (abs(vvr(mc.vars()[i])) == rational(1)) {
|
||||||
|
auto vv = mc.vars();
|
||||||
|
vv.erase(vv.begin()+i);
|
||||||
|
auto it = m_rm_table.map().find(vv);
|
||||||
|
if (it == m_rm_table.map().end()) {
|
||||||
|
out << "nf length" << vv.size() << "\n"; ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_stats(std::ostream& out) {
|
||||||
|
// for (const auto& m : m_monomials)
|
||||||
|
// print_monomial_stats(m, out);
|
||||||
|
m_rm_table.print_stats(out);
|
||||||
|
}
|
||||||
|
|
||||||
void register_monomials_in_tables() {
|
void register_monomials_in_tables() {
|
||||||
for (unsigned i = 0; i < m_monomials.size(); i++)
|
for (unsigned i = 0; i < m_monomials.size(); i++)
|
||||||
register_monomial_in_tables(i);
|
register_monomial_in_tables(i);
|
||||||
|
|
||||||
m_rm_table.fill_rooted_monomials_containing_var();
|
m_rm_table.fill_rooted_monomials_containing_var();
|
||||||
m_rm_table.fill_proper_factors();
|
m_rm_table.fill_proper_factors();
|
||||||
|
TRACE("nla_solver", print_stats(tout););
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
|
@ -1866,9 +1909,42 @@ struct solver::imp {
|
||||||
TRACE("nla_solver", print_lemma(tout););
|
TRACE("nla_solver", print_lemma(tout););
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_set<lpvar> collect_vars( const lemma& l) {
|
||||||
|
std::unordered_set<lpvar> vars;
|
||||||
|
for (const auto& i : current_lemma().ineqs()) {
|
||||||
|
for (const auto& p : i.term()) {
|
||||||
|
lpvar j = p.var();
|
||||||
|
vars.insert(j);
|
||||||
|
auto it = m_var_to_its_monomial.find(j);
|
||||||
|
if (it != m_var_to_its_monomial.end()) {
|
||||||
|
for (lpvar k : m_monomials[it->second])
|
||||||
|
vars.insert(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& p : current_expl()) {
|
||||||
|
const auto& c = m_lar_solver.get_constraint(p.second);
|
||||||
|
for (const auto& r : c.coeffs()) {
|
||||||
|
lpvar j = r.second;
|
||||||
|
vars.insert(j);
|
||||||
|
auto it = m_var_to_its_monomial.find(j);
|
||||||
|
if (it != m_var_to_its_monomial.end()) {
|
||||||
|
for (lpvar k : m_monomials[it->second])
|
||||||
|
vars.insert(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
void print_lemma(std::ostream& out) {
|
void print_lemma(std::ostream& out) {
|
||||||
print_ineqs(current_lemma(), out);
|
print_ineqs(current_lemma(), out);
|
||||||
print_explanation(current_expl(), out);
|
print_explanation(current_expl(), out);
|
||||||
|
std::unordered_set<lpvar> vars = collect_vars(current_lemma());
|
||||||
|
|
||||||
|
for (lpvar j : vars) {
|
||||||
|
print_var(j, out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_cd_signs_for_ol(const rational& c, const rational& d, int& c_sign, int & d_sign) const {
|
bool get_cd_signs_for_ol(const rational& c, const rational& d, int& c_sign, int & d_sign) const {
|
||||||
|
@ -2503,7 +2579,7 @@ struct solver::imp {
|
||||||
|
|
||||||
void generate_tang_plane(const rational & a, const rational& b, lpvar jx, lpvar jy, bool below, lpvar j, const rational& j_sign) {
|
void generate_tang_plane(const rational & a, const rational& b, lpvar jx, lpvar jy, bool below, lpvar j, const rational& j_sign) {
|
||||||
add_empty_lemma();
|
add_empty_lemma();
|
||||||
lemma& l = m_lemma_vec->back();
|
lemma& l = current_lemma();
|
||||||
negate_relation(jx, a, l);
|
negate_relation(jx, a, l);
|
||||||
negate_relation(jy, b, l);
|
negate_relation(jy, b, l);
|
||||||
// If "below" holds then ay + bx - ab < xy, otherwise ay + bx - ab > xy,
|
// If "below" holds then ay + bx - ab < xy, otherwise ay + bx - ab > xy,
|
||||||
|
@ -2634,7 +2710,8 @@ struct solver::imp {
|
||||||
|
|
||||||
|
|
||||||
lbool check(vector<lemma>& l_vec) {
|
lbool check(vector<lemma>& l_vec) {
|
||||||
TRACE("nla_solver", tout << "check of nla";);
|
settings().st().m_nla_calls++;
|
||||||
|
TRACE("nla_solver", tout << "calls = " << settings().st().m_nla_calls << "\n";);
|
||||||
m_lemma_vec = &l_vec;
|
m_lemma_vec = &l_vec;
|
||||||
if (!(m_lar_solver.get_status() == lp::lp_status::OPTIMAL || m_lar_solver.get_status() == lp::lp_status::FEASIBLE )) {
|
if (!(m_lar_solver.get_status() == lp::lp_status::OPTIMAL || m_lar_solver.get_status() == lp::lp_status::FEASIBLE )) {
|
||||||
TRACE("nla_solver", tout << "unknown because of the m_lar_solver.m_status = " << lp_status_to_string(m_lar_solver.get_status()) << "\n";);
|
TRACE("nla_solver", tout << "unknown because of the m_lar_solver.m_status = " << lp_status_to_string(m_lar_solver.get_status()) << "\n";);
|
||||||
|
@ -2646,13 +2723,13 @@ struct solver::imp {
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
init_search();
|
init_search();
|
||||||
lbool ret = inner_check(false);
|
lbool ret = inner_check(true);
|
||||||
// if (ret == l_undef)
|
if (ret == l_undef)
|
||||||
// ret = inner_check(false);
|
ret = inner_check(false);
|
||||||
|
|
||||||
TRACE("nla_solver", tout << "ret = " << ret;);
|
TRACE("nla_solver_c", tout << "ret = " << ret;);
|
||||||
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monomials(verbose_stream());});
|
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monomials(verbose_stream());});
|
||||||
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monomials(tout););
|
CTRACE("nla_solver_c", ret == l_undef, tout << "Monomials\n"; print_monomials(tout););
|
||||||
SASSERT(ret != l_false || no_lemmas_hold());
|
SASSERT(ret != l_false || no_lemmas_hold());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ typedef nla::variable_map_type variable_map_type;
|
||||||
auto& pm = m_nlsat->pm();
|
auto& pm = m_nlsat->pm();
|
||||||
auto k = c.m_kind;
|
auto k = c.m_kind;
|
||||||
auto rhs = c.m_right_side;
|
auto rhs = c.m_right_side;
|
||||||
auto lhs = c.get_left_side_coefficients();
|
auto lhs = c.coeffs();
|
||||||
auto sz = lhs.size();
|
auto sz = lhs.size();
|
||||||
svector<polynomial::var> vars;
|
svector<polynomial::var> vars;
|
||||||
rational den = denominator(rhs);
|
rational den = denominator(rhs);
|
||||||
|
|
|
@ -74,6 +74,18 @@ struct rooted_mon_table {
|
||||||
// maps the indices of the regular monomials to the rooted monomial indices
|
// maps the indices of the regular monomials to the rooted monomial indices
|
||||||
std::unordered_map<unsigned, index_with_sign> m_reg_to_rm;
|
std::unordered_map<unsigned, index_with_sign> m_reg_to_rm;
|
||||||
|
|
||||||
|
void print_stats(std::ostream& out) const {
|
||||||
|
static double ratio = 1;
|
||||||
|
double s = 0;
|
||||||
|
for (const auto& p : m_map) {
|
||||||
|
s += m_vector[p.second].m_mons.size();
|
||||||
|
}
|
||||||
|
double r = s /m_map.size();
|
||||||
|
if (r > ratio) {
|
||||||
|
ratio = r;
|
||||||
|
out << "rooted mons " << m_map.size() << ", ratio = " << r << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const svector<unsigned>& to_refine() { return m_to_refine; }
|
const svector<unsigned>& to_refine() { return m_to_refine; }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue