mirror of
https://github.com/Z3Prover/z3
synced 2025-06-03 04:41:21 +00:00
going over niil_solver (#79)
* change conflict to th_axiom Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * going over niil_solver Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a9a45b7b47
commit
e16d8118ac
4 changed files with 138 additions and 118 deletions
|
@ -1332,13 +1332,11 @@ std::ostream& lar_solver::print_term(lar_term const& term, std::ostream & out) c
|
||||||
mpq val = p.coeff();
|
mpq val = p.coeff();
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
|
} else if (is_pos(val)) {
|
||||||
|
out << " + ";
|
||||||
} else {
|
} else {
|
||||||
if (is_pos(val)) {
|
out << " - ";
|
||||||
out << " + ";
|
val = -val;
|
||||||
} else {
|
|
||||||
out << " - ";
|
|
||||||
val = -val;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (val == -numeric_traits<mpq>::one())
|
if (val == -numeric_traits<mpq>::one())
|
||||||
out << " - ";
|
out << " - ";
|
||||||
|
@ -1367,8 +1365,7 @@ mpq lar_solver::get_left_side_val(const lar_base_constraint & cns, const std::u
|
||||||
|
|
||||||
std::ostream& lar_solver::print_constraint(const lar_base_constraint * c, std::ostream & out) const {
|
std::ostream& lar_solver::print_constraint(const lar_base_constraint * c, std::ostream & out) const {
|
||||||
print_left_side_of_constraint(c, out);
|
print_left_side_of_constraint(c, out);
|
||||||
out << " " << lconstraint_kind_string(c->m_kind) << " " << c->m_right_side << std::endl;
|
return out << " " << lconstraint_kind_string(c->m_kind) << " " << c->m_right_side << std::endl;
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lar_solver::fill_var_set_for_random_update(unsigned sz, var_index const * vars, vector<unsigned>& column_list) {
|
void lar_solver::fill_var_set_for_random_update(unsigned sz, var_index const * vars, vector<unsigned>& column_list) {
|
||||||
|
|
|
@ -115,6 +115,7 @@ private:
|
||||||
public :
|
public :
|
||||||
unsigned terms_start_index() const { return m_terms_start_index; }
|
unsigned terms_start_index() const { return m_terms_start_index; }
|
||||||
const vector<lar_term*> & terms() const { return m_terms; }
|
const vector<lar_term*> & terms() const { return m_terms; }
|
||||||
|
lar_term const& term(unsigned i) const { return *m_terms[i]; }
|
||||||
const vector<lar_base_constraint*>& constraints() const {
|
const vector<lar_base_constraint*>& constraints() const {
|
||||||
return m_constraints;
|
return m_constraints;
|
||||||
}
|
}
|
||||||
|
@ -479,16 +480,13 @@ public:
|
||||||
|
|
||||||
std::string get_variable_name(var_index vi) const;
|
std::string get_variable_name(var_index vi) const;
|
||||||
|
|
||||||
// print utilities
|
// ********** print region start
|
||||||
|
|
||||||
std::ostream& print_constraint(constraint_index ci, std::ostream & out) const;
|
std::ostream& print_constraint(constraint_index ci, std::ostream & out) const;
|
||||||
|
|
||||||
std::ostream& print_constraints(std::ostream& out) const ;
|
std::ostream& print_constraints(std::ostream& out) const ;
|
||||||
|
|
||||||
std::ostream& print_terms(std::ostream& out) const;
|
std::ostream& print_terms(std::ostream& out) const;
|
||||||
|
|
||||||
std::ostream& print_left_side_of_constraint(const lar_base_constraint * c, std::ostream & out) const;
|
|
||||||
|
|
||||||
std::ostream& print_term(lar_term const& term, std::ostream & out) const;
|
std::ostream& print_term(lar_term const& term, std::ostream & out) const;
|
||||||
|
|
||||||
std::ostream& print_term_as_indices(lar_term const& term, std::ostream & out) const;
|
std::ostream& print_term_as_indices(lar_term const& term, std::ostream & out) const;
|
||||||
|
|
|
@ -29,14 +29,12 @@ typedef lp::var_index lpvar;
|
||||||
|
|
||||||
struct hash_svector {
|
struct hash_svector {
|
||||||
size_t operator()(const svector<unsigned> & v) const {
|
size_t operator()(const svector<unsigned> & v) const {
|
||||||
size_t seed = 0;
|
return svector_hash<unsigned_hash>()(v);
|
||||||
for (unsigned t : v)
|
|
||||||
hash_combine(seed, t);
|
|
||||||
return seed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TBD: already defined on vector template class
|
||||||
bool operator==(const svector<unsigned> & a, const svector<unsigned> & b) {
|
bool operator==(const svector<unsigned> & a, const svector<unsigned> & b) {
|
||||||
if (a.size() != b.size())
|
if (a.size() != b.size())
|
||||||
return false;
|
return false;
|
||||||
|
@ -47,40 +45,42 @@ bool operator==(const svector<unsigned> & a, const svector<unsigned> & b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct solver::imp {
|
struct solver::imp {
|
||||||
struct vars_equivalence {
|
|
||||||
struct equiv {
|
|
||||||
lpvar m_i;
|
|
||||||
lpvar m_j;
|
|
||||||
int m_sign;
|
|
||||||
lpci m_c0;
|
|
||||||
lpci m_c1;
|
|
||||||
equiv(lpvar i, lpvar j, int sign, lpci c0, lpci c1) :
|
|
||||||
m_i(i),
|
|
||||||
m_j(j),
|
|
||||||
m_sign(sign),
|
|
||||||
m_c0(c0),
|
|
||||||
m_c1(c1)
|
|
||||||
{
|
|
||||||
SASSERT(i > j);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct eq_var {
|
struct equiv {
|
||||||
lpvar m_var;
|
lpvar m_i;
|
||||||
int m_sign;
|
lpvar m_j;
|
||||||
expl_set m_explanation;
|
int m_sign;
|
||||||
eq_var(const equiv& e) :
|
lpci m_c0;
|
||||||
m_var(e.m_j),
|
lpci m_c1;
|
||||||
m_sign(e.m_sign) {
|
equiv(lpvar i, lpvar j, int sign, lpci c0, lpci c1) :
|
||||||
m_explanation.insert(e.m_c0); m_explanation.insert(e.m_c1);
|
m_i(i),
|
||||||
}
|
m_j(j),
|
||||||
void improve(const equiv & e) {
|
m_sign(sign),
|
||||||
SASSERT(e.m_j > m_var);
|
m_c0(c0),
|
||||||
m_var = e.m_j;
|
m_c1(c1)
|
||||||
m_sign *= e.m_sign;
|
{
|
||||||
m_explanation.insert(e.m_c0); m_explanation.insert(e.m_c1);
|
SASSERT(i > j);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct eq_var {
|
||||||
|
lpvar m_var;
|
||||||
|
int m_sign;
|
||||||
|
expl_set m_explanation;
|
||||||
|
eq_var(const equiv& e) :
|
||||||
|
m_var(e.m_j),
|
||||||
|
m_sign(e.m_sign) {
|
||||||
|
m_explanation.insert(e.m_c0); m_explanation.insert(e.m_c1);
|
||||||
|
}
|
||||||
|
void improve(const equiv & e) {
|
||||||
|
SASSERT(e.m_j > m_var);
|
||||||
|
m_var = e.m_j;
|
||||||
|
m_sign *= e.m_sign;
|
||||||
|
m_explanation.insert(e.m_c0); m_explanation.insert(e.m_c1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vars_equivalence {
|
||||||
|
|
||||||
std::unordered_map<lpvar, eq_var> m_map; // the resulting mapping
|
std::unordered_map<lpvar, eq_var> m_map; // the resulting mapping
|
||||||
vector<equiv> m_equivs; // all equivalences extracted from constraints
|
vector<equiv> m_equivs; // all equivalences extracted from constraints
|
||||||
|
@ -90,15 +90,17 @@ struct solver::imp {
|
||||||
m_map.clear();
|
m_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return m_map.size();
|
||||||
|
}
|
||||||
|
|
||||||
size_t size() const { return m_map.size(); }
|
void add_equivalence_maybe(lp::lar_term const& t, lpci c0, lpci c1) {
|
||||||
void add_equivalence_maybe(const lp::lar_term *t, lpci c0, lpci c1) {
|
if (t.size() != 2 || !t.m_v.is_zero())
|
||||||
if (t->size() != 2 || ! t->m_v.is_zero())
|
|
||||||
return;
|
return;
|
||||||
bool seen_minus = false;
|
bool seen_minus = false;
|
||||||
bool seen_plus = false;
|
bool seen_plus = false;
|
||||||
lpvar i = -1, j;
|
lpvar i = -1, j;
|
||||||
for(const auto & p : *t) {
|
for (const auto & p : t) {
|
||||||
const auto & c = p.coeff();
|
const auto & c = p.coeff();
|
||||||
if (c == 1) {
|
if (c == 1) {
|
||||||
seen_plus = true;
|
seen_plus = true;
|
||||||
|
@ -113,10 +115,8 @@ struct solver::imp {
|
||||||
j = p.var();
|
j = p.var();
|
||||||
}
|
}
|
||||||
SASSERT(i != j && i != static_cast<lpvar>(-1));
|
SASSERT(i != j && i != static_cast<lpvar>(-1));
|
||||||
if (i < j) { // swap
|
if (i < j) {
|
||||||
lpvar tmp = i;
|
std::swap(i, j);
|
||||||
i = j;
|
|
||||||
j = tmp;
|
|
||||||
}
|
}
|
||||||
int sign = (seen_minus && seen_plus)? 1 : -1;
|
int sign = (seen_minus && seen_plus)? 1 : -1;
|
||||||
m_equivs.push_back(equiv(i, j, sign, c0, c1));
|
m_equivs.push_back(equiv(i, j, sign, c0, c1));
|
||||||
|
@ -128,13 +128,13 @@ struct solver::imp {
|
||||||
if (!s.term_is_used_as_row(ti))
|
if (!s.term_is_used_as_row(ti))
|
||||||
continue;
|
continue;
|
||||||
lpvar j = s.external2local(ti);
|
lpvar j = s.external2local(ti);
|
||||||
if (!s.column_has_upper_bound(j) ||
|
|
||||||
!s.column_has_lower_bound(j))
|
if (s.column_has_upper_bound(j) &&
|
||||||
continue;
|
s.column_has_lower_bound(j) &&
|
||||||
if (s.get_upper_bound(j) != lp::zero_of_type<lp::impq>() ||
|
s.get_upper_bound(j) == lp::zero_of_type<lp::impq>() &&
|
||||||
s.get_lower_bound(j) != lp::zero_of_type<lp::impq>())
|
s.get_lower_bound(j) == lp::zero_of_type<lp::impq>()) {
|
||||||
continue;
|
add_equivalence_maybe(s.term(i), s.get_column_upper_bound_witness(j), s.get_column_lower_bound_witness(j));
|
||||||
add_equivalence_maybe(s.terms()[i], s.get_column_upper_bound_witness(j), s.get_column_lower_bound_witness(j));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,14 +148,13 @@ struct solver::imp {
|
||||||
if (it == m_map.end()) {
|
if (it == m_map.end()) {
|
||||||
m_map.emplace(i, eq_var(e));
|
m_map.emplace(i, eq_var(e));
|
||||||
progress = true;
|
progress = true;
|
||||||
} else {
|
} else if (it->second.m_var > e.m_j) {
|
||||||
if (it->second.m_var > e.m_j) {
|
it->second.improve(e);
|
||||||
it->second.improve(e);
|
progress = true;
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(progress);
|
}
|
||||||
|
while (progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(const lp::lar_solver& s) {
|
void init(const lp::lar_solver& s) {
|
||||||
|
@ -252,8 +251,9 @@ struct solver::imp {
|
||||||
return r == model_val;
|
return r == model_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief <TBD say what this function does>
|
||||||
|
*/
|
||||||
bool generate_basic_lemma_for_mon_sign_var_other_mon(
|
bool generate_basic_lemma_for_mon_sign_var_other_mon(
|
||||||
unsigned i_mon,
|
unsigned i_mon,
|
||||||
unsigned j_var,
|
unsigned j_var,
|
||||||
|
@ -286,12 +286,21 @@ struct solver::imp {
|
||||||
m_vars_equivalence.add_explanation_of_reducing_to_mininal_monomial(m, eset);
|
m_vars_equivalence.add_explanation_of_reducing_to_mininal_monomial(m, eset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_monomial(const mon_eq& m, std::ostream& out) {
|
std::ostream& print_monomial(const mon_eq& m, std::ostream& out) {
|
||||||
out << m_lar_solver.get_column_name(m.var()) << " = ";
|
out << m_lar_solver.get_column_name(m.var()) << " = ";
|
||||||
for (unsigned j : m) {
|
for (unsigned j : m) {
|
||||||
out << m_lar_solver.get_column_name(j) << "*";
|
out << m_lar_solver.get_column_name(j) << "*";
|
||||||
}
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& print_explanation(std::ostream& out) {
|
||||||
|
for (auto &p : *m_expl) {
|
||||||
|
m_lar_solver.print_constraint(p.second, out) << "\n";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// the monomials should be equal by modulo sign, but they are not equal in the model module sign
|
// the monomials should be equal by modulo sign, but they are not equal in the model module sign
|
||||||
void fill_explanation_and_lemma_sign(const mon_eq& a, const mon_eq & b, int sign) {
|
void fill_explanation_and_lemma_sign(const mon_eq& a, const mon_eq & b, int sign) {
|
||||||
expl_set expl;
|
expl_set expl;
|
||||||
|
@ -300,25 +309,23 @@ struct solver::imp {
|
||||||
add_explanation_of_reducing_to_mininal_monomial(b, expl);
|
add_explanation_of_reducing_to_mininal_monomial(b, expl);
|
||||||
m_expl->clear();
|
m_expl->clear();
|
||||||
m_expl->add(expl);
|
m_expl->add(expl);
|
||||||
TRACE("niil_solver",
|
TRACE("niil_solver", print_explanation(tout););
|
||||||
for (auto &p : *m_expl)
|
|
||||||
m_lar_solver.print_constraint(p.second, tout); tout << "\n";
|
|
||||||
);
|
|
||||||
lp::lar_term t;
|
lp::lar_term t;
|
||||||
t.add_monomial(rational(1), a.var());
|
t.add_monomial(rational(1), a.var());
|
||||||
t.add_monomial(rational(- sign), b.var());
|
t.add_monomial(rational(- sign), b.var());
|
||||||
TRACE("niil_solver",
|
TRACE("niil_solver",
|
||||||
m_lar_solver.print_term(t, tout);
|
m_lar_solver.print_term(t, tout) << "\n";
|
||||||
tout << "\n";
|
print_monomial(a, tout) << "\n";
|
||||||
print_monomial(a, tout);
|
print_monomial(b, tout) << "\n";
|
||||||
tout << "\n";
|
|
||||||
print_monomial(b, tout);
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ineq in(lp::lconstraint_kind::NE, t);
|
ineq in(lp::lconstraint_kind::NE, t);
|
||||||
m_lemma->push_back(in);
|
m_lemma->push_back(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief <TBD say what this function does>
|
||||||
|
*/
|
||||||
bool generate_basic_lemma_for_mon_sign_var(unsigned i_mon,
|
bool generate_basic_lemma_for_mon_sign_var(unsigned i_mon,
|
||||||
unsigned j_var, const svector<lpvar>& mon_vars, int sign) {
|
unsigned j_var, const svector<lpvar>& mon_vars, int sign) {
|
||||||
auto it = m_var_lists.find(j_var);
|
auto it = m_var_lists.find(j_var);
|
||||||
|
@ -436,7 +443,7 @@ struct solver::imp {
|
||||||
for (lpvar j : m.m_vs) {
|
for (lpvar j : m.m_vs) {
|
||||||
int s = get_mon_sign_zero_var(j, strict);
|
int s = get_mon_sign_zero_var(j, strict);
|
||||||
if (s == 2)
|
if (s == 2)
|
||||||
return 2;;
|
return 2;
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
return 0;
|
return 0;
|
||||||
sign *= s;
|
sign *= s;
|
||||||
|
@ -480,12 +487,11 @@ struct solver::imp {
|
||||||
m_lemma->push_back(in);
|
m_lemma->push_back(in);
|
||||||
TRACE("niil_solver",
|
TRACE("niil_solver",
|
||||||
tout << "used constraints:\n";
|
tout << "used constraints:\n";
|
||||||
for (auto &p : *m_expl)
|
print_explanation(tout);
|
||||||
m_lar_solver.print_constraint(p.second, tout);
|
|
||||||
tout << "derived constraint ";
|
tout << "derived constraint ";
|
||||||
m_lar_solver.print_term(t, tout);
|
m_lar_solver.print_term(t, tout);
|
||||||
tout << " " << lp::lconstraint_kind_string(kind) << " 0\n";
|
tout << " " << lp::lconstraint_kind_string(kind) << " 0\n";
|
||||||
print_monomial(m_monomials[i_mon], tout); tout << "\n";
|
print_monomial(m_monomials[i_mon], tout) << "\n";
|
||||||
lpvar mon_var = m_monomials[i_mon].var();
|
lpvar mon_var = m_monomials[i_mon].var();
|
||||||
|
|
||||||
tout << m_lar_solver.get_column_name(mon_var) << " = " << m_lar_solver.get_column_value(mon_var);
|
tout << m_lar_solver.get_column_name(mon_var) << " = " << m_lar_solver.get_column_value(mon_var);
|
||||||
|
@ -495,6 +501,9 @@ struct solver::imp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief <TBD say what this function does>
|
||||||
|
*/
|
||||||
bool get_one_of_var(unsigned i, lpvar j, mono_index_with_sign & mi) {
|
bool get_one_of_var(unsigned i, lpvar j, mono_index_with_sign & mi) {
|
||||||
lpci lci;
|
lpci lci;
|
||||||
lpci uci;
|
lpci uci;
|
||||||
|
@ -526,9 +535,9 @@ struct solver::imp {
|
||||||
vector<mono_index_with_sign> ret;
|
vector<mono_index_with_sign> ret;
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
mono_index_with_sign mi;
|
mono_index_with_sign mi;
|
||||||
if (!get_one_of_var(i, vars[i], mi))
|
if (get_one_of_var(i, vars[i], mi)) {
|
||||||
continue;
|
ret.push_back(mi);
|
||||||
ret.push_back(mi);
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -537,31 +546,33 @@ struct solver::imp {
|
||||||
void get_large_and_small_indices_of_monomimal(const mon_eq& m,
|
void get_large_and_small_indices_of_monomimal(const mon_eq& m,
|
||||||
vector<unsigned> & large,
|
vector<unsigned> & large,
|
||||||
vector<unsigned> & _small) {
|
vector<unsigned> & _small) {
|
||||||
|
|
||||||
for (unsigned i = 0; i < m.m_vs.size(); i++) {
|
for (unsigned i = 0; i < m.m_vs.size(); ++i) {
|
||||||
unsigned j = m.m_vs[i];
|
unsigned j = m.m_vs[i];
|
||||||
lp::constraint_index lci = -1, uci = -1;
|
lp::constraint_index lci = -1, uci = -1;
|
||||||
rational lb, ub;
|
rational lb, ub;
|
||||||
bool is_strict;
|
bool is_strict;
|
||||||
if (m_lar_solver.has_lower_bound(j, lci, lb, is_strict)) {
|
if (m_lar_solver.has_lower_bound(j, lci, lb, is_strict) && !is_strict) {
|
||||||
SASSERT(!is_strict);
|
|
||||||
if (lb >= rational(1)) {
|
if (lb >= rational(1)) {
|
||||||
large.push_back(i);
|
large.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_lar_solver.has_upper_bound(j, uci, ub, is_strict)) {
|
if (m_lar_solver.has_upper_bound(j, uci, ub, is_strict) && !is_strict) {
|
||||||
SASSERT(!is_strict);
|
|
||||||
if (ub <= -rational(1)) {
|
if (ub <= -rational(1)) {
|
||||||
large.push_back(i);
|
large.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_set(lci) && is_set(uci) && -rational(1) <= lb && ub <= rational(1))
|
if (is_set(lci) && is_set(uci) && -rational(1) <= lb && ub <= rational(1)) {
|
||||||
_small.push_back(i);
|
_small.push_back(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// v is the value of monomial, vars is the array of reduced to minimum variables of the monomial
|
/**
|
||||||
|
* \brief <TBD say what this function does>
|
||||||
|
* v is the value of monomial, vars is the array of reduced to minimum variables of the monomial
|
||||||
|
*/
|
||||||
bool generate_basic_neutral_for_reduced_monomial(const mon_eq & m, const rational & v, const svector<lpvar> & vars) {
|
bool generate_basic_neutral_for_reduced_monomial(const mon_eq & m, const rational & v, const svector<lpvar> & vars) {
|
||||||
vector<mono_index_with_sign> ones_of_mon = get_ones_of_monomimal(vars);
|
vector<mono_index_with_sign> ones_of_mon = get_ones_of_monomimal(vars);
|
||||||
|
|
||||||
|
@ -575,7 +586,9 @@ struct solver::imp {
|
||||||
|
|
||||||
return process_ones_of_mon(m, ones_of_mon, vars, v);
|
return process_ones_of_mon(m, ones_of_mon, vars, v);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* \brief <TBD say what this function does>
|
||||||
|
*/
|
||||||
bool generate_basic_lemma_for_mon_neutral(unsigned i_mon) {
|
bool generate_basic_lemma_for_mon_neutral(unsigned i_mon) {
|
||||||
std::cout << "generate_basic_lemma_for_mon_neutral\n";
|
std::cout << "generate_basic_lemma_for_mon_neutral\n";
|
||||||
const mon_eq & m = m_monomials[i_mon];
|
const mon_eq & m = m_monomials[i_mon];
|
||||||
|
@ -629,16 +642,12 @@ struct solver::imp {
|
||||||
for (unsigned k : mask) {
|
for (unsigned k : mask) {
|
||||||
add_explanation_of_one(ones_of_monomial[k]);
|
add_explanation_of_one(ones_of_monomial[k]);
|
||||||
}
|
}
|
||||||
TRACE("niil_solver",
|
TRACE("niil_solver", print_explanation(tout););
|
||||||
for (auto &p : *m_expl)
|
|
||||||
m_lar_solver.print_constraint(p.second, tout); tout << "\n";
|
|
||||||
);
|
|
||||||
lp::lar_term t;
|
lp::lar_term t;
|
||||||
t.add_monomial(rational(1), m.var());
|
t.add_monomial(rational(1), m.var());
|
||||||
t.add_monomial(rational(- sign), j);
|
t.add_monomial(rational(- sign), j);
|
||||||
TRACE("niil_solver",
|
TRACE("niil_solver",
|
||||||
m_lar_solver.print_term(t, tout);
|
m_lar_solver.print_term(t, tout) << "\n";
|
||||||
tout << "\n";
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ineq in(lp::lconstraint_kind::EQ, t);
|
ineq in(lp::lconstraint_kind::EQ, t);
|
||||||
|
@ -652,7 +661,7 @@ struct solver::imp {
|
||||||
svector<unsigned> mask(ones_of_monomial.size(), (unsigned) 0);
|
svector<unsigned> mask(ones_of_monomial.size(), (unsigned) 0);
|
||||||
auto vars = min_vars;
|
auto vars = min_vars;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
// We crossing out the ones representing the mask from vars
|
// We cross out the ones representing the mask from vars
|
||||||
do {
|
do {
|
||||||
for (unsigned k = 0; k < mask.size(); k++) {
|
for (unsigned k = 0; k < mask.size(); k++) {
|
||||||
if (mask[k] == 0) {
|
if (mask[k] == 0) {
|
||||||
|
@ -674,7 +683,8 @@ struct solver::imp {
|
||||||
vars.push_back(min_vars[ones_of_monomial[k].m_i]); // vars becomes unsorted
|
vars.push_back(min_vars[ones_of_monomial[k].m_i]); // vars becomes unsorted
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(true);
|
}
|
||||||
|
while(true);
|
||||||
return false; // we exhausted the mask and did not find the compliment monomial
|
return false; // we exhausted the mask and did not find the compliment monomial
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,7 +800,7 @@ struct solver::imp {
|
||||||
to_refine.push_back(i);
|
to_refine.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_refine.size() == 0)
|
if (to_refine.empty())
|
||||||
return l_true;
|
return l_true;
|
||||||
|
|
||||||
TRACE("niil_solver", tout << "to_refine.size() = " << to_refine.size() << std::endl;);
|
TRACE("niil_solver", tout << "to_refine.size() = " << to_refine.size() << std::endl;);
|
||||||
|
@ -815,17 +825,32 @@ lbool solver::check(lp::explanation & ex, lemma& l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void solver::push(){
|
}; // end of imp
|
||||||
m_imp->push();
|
|
||||||
}
|
|
||||||
void solver::pop(unsigned n) {
|
|
||||||
m_imp->pop(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void solver::add_monomial(lpvar v, unsigned sz, lpvar const* vs) {
|
||||||
|
m_imp->add(v, sz, vs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool solver::need_check() { return true; }
|
||||||
|
|
||||||
|
lbool solver::check(lp::explanation & ex, lemma& l) {
|
||||||
|
return m_imp->check(ex, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::push(){
|
||||||
|
m_imp->push();
|
||||||
|
}
|
||||||
|
|
||||||
solver::solver(lp::lar_solver& s, reslimit& lim, params_ref const& p) {
|
void solver::pop(unsigned n) {
|
||||||
m_imp = alloc(imp, s, lim, p);
|
m_imp->pop(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
solver::solver(lp::lar_solver& s, reslimit& lim, params_ref const& p) {
|
||||||
|
m_imp = alloc(imp, s, lim, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
solver::~solver() {
|
||||||
|
dealloc(m_imp);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@ typedef vector<ineq> lemma;
|
||||||
|
|
||||||
// nonlinear integer incremental linear solver
|
// nonlinear integer incremental linear solver
|
||||||
class solver {
|
class solver {
|
||||||
public:
|
|
||||||
struct imp;
|
struct imp;
|
||||||
imp* m_imp;
|
imp* m_imp;
|
||||||
|
public:
|
||||||
void add_monomial(lp::var_index v, unsigned sz, lp::var_index const* vs);
|
void add_monomial(lp::var_index v, unsigned sz, lp::var_index const* vs);
|
||||||
solver(lp::lar_solver& s, reslimit& lim, params_ref const& p);
|
solver(lp::lar_solver& s, reslimit& lim, params_ref const& p);
|
||||||
imp* get_imp();
|
~solver();
|
||||||
void push();
|
void push();
|
||||||
void pop(unsigned scopes);
|
void pop(unsigned scopes);
|
||||||
bool need_check();
|
bool need_check();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue