mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
remove the fresh definition when removing its column
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
17d68c18aa
commit
dcd5783232
|
@ -46,7 +46,8 @@
|
||||||
the i-th entry.
|
the i-th entry.
|
||||||
*/
|
*/
|
||||||
namespace lp {
|
namespace lp {
|
||||||
template <typename T, typename K> bool contains(const T& t, K j) {
|
template <typename T, typename K>
|
||||||
|
bool contains(const T& t, K j) {
|
||||||
return t.find(j) != t.end();
|
return t.find(j) != t.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +55,8 @@ namespace lp {
|
||||||
mpq m_coeff;
|
mpq m_coeff;
|
||||||
unsigned m_j;
|
unsigned m_j;
|
||||||
lpvar var() const { return m_j; }
|
lpvar var() const { return m_j; }
|
||||||
const mpq & coeff() const { return m_coeff; }
|
const mpq& coeff() const { return m_coeff; }
|
||||||
mpq & coeff() { return m_coeff; }
|
mpq& coeff() { return m_coeff; }
|
||||||
iv() {}
|
iv() {}
|
||||||
iv(const mpq& v, unsigned j) : m_coeff(v), m_j(j) {}
|
iv(const mpq& v, unsigned j) : m_coeff(v), m_j(j) {}
|
||||||
};
|
};
|
||||||
|
@ -75,7 +76,7 @@ namespace lp {
|
||||||
return m_rev_map.find(b)->second;
|
return m_rev_map.find(b)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size() const {return static_cast<unsigned>(m_map.size());}
|
unsigned size() const { return static_cast<unsigned>(m_map.size()); }
|
||||||
|
|
||||||
void erase_val(unsigned b) {
|
void erase_val(unsigned b) {
|
||||||
VERIFY(contains(m_rev_map, b) && contains(m_map, m_rev_map[b]));
|
VERIFY(contains(m_rev_map, b) && contains(m_map, m_rev_map[b]));
|
||||||
|
@ -132,14 +133,12 @@ namespace lp {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class bij_map {
|
struct bij_map {
|
||||||
// We store T indexed by 'b' in an std::unordered_map, and use bijection to map from 'a' to 'b'.
|
// We store T indexed by 'b' in an std::unordered_map, and use bijection to map from 'a' to 'b'.
|
||||||
|
|
||||||
bijection m_bij;
|
bijection m_bij;
|
||||||
std::unordered_map<unsigned, T> m_data;
|
std::unordered_map<unsigned, T> m_data;
|
||||||
|
|
||||||
public:
|
|
||||||
// Adds a->b in m_bij, associates val with b.
|
// Adds a->b in m_bij, associates val with b.
|
||||||
void add(unsigned a, unsigned b, const T& val) {
|
void add(unsigned a, unsigned b, const T& val) {
|
||||||
// You might have some method in bijection such as 'insert(a, b)'
|
// You might have some method in bijection such as 'insert(a, b)'
|
||||||
|
@ -155,7 +154,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase_by_second_key(unsigned b) {
|
void erase_by_second_key(unsigned b) {
|
||||||
VERIFY(m_bij.has_val(b));
|
SASSERT(m_bij.has_val(b));
|
||||||
m_bij.erase_val(b);
|
m_bij.erase_val(b);
|
||||||
auto it = m_data.find(b);
|
auto it = m_data.find(b);
|
||||||
VERIFY(it != m_data.end());
|
VERIFY(it != m_data.end());
|
||||||
|
@ -163,7 +162,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_key(unsigned j) const { return m_bij.has_key(j); }
|
bool has_key(unsigned j) const { return m_bij.has_key(j); }
|
||||||
bool has_second_key(unsigned j) const { return m_bij.has_val(j);}
|
bool has_second_key(unsigned j) const { return m_bij.has_val(j); }
|
||||||
// Get the data by 'a', look up b in m_bij, then read from m_data
|
// Get the data by 'a', look up b in m_bij, then read from m_data
|
||||||
const T& get_by_key(unsigned a) const {
|
const T& get_by_key(unsigned a) const {
|
||||||
unsigned b = m_bij[a]; // relies on operator[](unsigned) from bijection
|
unsigned b = m_bij[a]; // relies on operator[](unsigned) from bijection
|
||||||
|
@ -246,7 +245,7 @@ namespace lp {
|
||||||
|
|
||||||
std::ostream& print_S(std::ostream& out) {
|
std::ostream& print_S(std::ostream& out) {
|
||||||
out << "S:\n";
|
out << "S:\n";
|
||||||
for (const auto & p: m_k2s.m_map) {
|
for (const auto& p : m_k2s.m_map) {
|
||||||
print_entry(p.second, out);
|
print_entry(p.second, out);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -258,11 +257,10 @@ namespace lp {
|
||||||
[](int j) -> std::string { return "x" + std::to_string(j); }, out);
|
[](int j) -> std::string { return "x" + std::to_string(j); }, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// used for debug only
|
// used for debug only
|
||||||
std::ostream& print_lar_term_L(const std_vector<iv>& t, std::ostream& out) const {
|
std::ostream& print_lar_term_L(const std_vector<iv>& t, std::ostream& out) const {
|
||||||
vector<std::pair<mpq, unsigned>> tp;
|
vector<std::pair<mpq, unsigned>> tp;
|
||||||
for (const auto & p : t) {
|
for (const auto& p : t) {
|
||||||
tp.push_back(std::make_pair(p.coeff(), p.var()));
|
tp.push_back(std::make_pair(p.coeff(), p.var()));
|
||||||
}
|
}
|
||||||
return print_linear_combination_customized(
|
return print_linear_combination_customized(
|
||||||
|
@ -343,7 +341,7 @@ namespace lp {
|
||||||
// used for debug only
|
// used for debug only
|
||||||
lar_term to_term() const {
|
lar_term to_term() const {
|
||||||
lar_term r;
|
lar_term r;
|
||||||
for (const auto& p: m_data) {
|
for (const auto& p : m_data) {
|
||||||
r.add_monomial(p.coeff(), p.var());
|
r.add_monomial(p.coeff(), p.var());
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
@ -384,7 +382,7 @@ namespace lp {
|
||||||
int idx = m_index[j];
|
int idx = m_index[j];
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
// Insert a new monomial { a, j } into m_data
|
// Insert a new monomial { a, j } into m_data
|
||||||
m_data.push_back({ a, j });
|
m_data.push_back({a, j});
|
||||||
m_index[j] = static_cast<int>(m_data.size() - 1);
|
m_index[j] = static_cast<int>(m_data.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
// Accumulate the coefficient
|
// Accumulate the coefficient
|
||||||
|
@ -417,8 +415,7 @@ namespace lp {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Check that var() in m_data[idx] matches j
|
// Check that var() in m_data[idx] matches j
|
||||||
if (idx < 0 || static_cast<unsigned>(idx) >= m_data.size()) {
|
if (idx < 0 || static_cast<unsigned>(idx) >= m_data.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -446,20 +443,19 @@ namespace lp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
for (const auto& p: m_data) {
|
for (const auto& p : m_data) {
|
||||||
m_index[p.var()] = -1;
|
m_index[p.var()] = -1;
|
||||||
}
|
}
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
SASSERT(invariant());
|
SASSERT(invariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
term_with_index m_l_terms_workspace;
|
term_with_index m_l_terms_workspace;
|
||||||
term_with_index m_substitution_workspace;
|
term_with_index m_substitution_workspace;
|
||||||
|
|
||||||
bijection m_k2s;
|
bijection m_k2s;
|
||||||
bij_map<lar_term> m_fresh_k2xt_terms;
|
bij_map<std::pair<lar_term, unsigned>> m_fresh_k2xt_terms;
|
||||||
// m_row2fresh_defs[i] is the set of all fresh variables xt
|
// m_row2fresh_defs[i] is the set of all fresh variables xt
|
||||||
// such that pairs (xt, m_fresh_k2xt_terms[xt]) is a fresh definition introduced for row i
|
// such that pairs (xt, m_fresh_k2xt_terms[xt]) is a fresh definition introduced for row i
|
||||||
// When row i is changed all entries depending on m_fresh_k2xt_terms[xt] should be recalculated,
|
// When row i is changed all entries depending on m_fresh_k2xt_terms[xt] should be recalculated,
|
||||||
|
@ -472,7 +468,6 @@ namespace lp {
|
||||||
// m_column_to_terms[j] is the set of all k such lra.get_term(k) depends on j
|
// m_column_to_terms[j] is the set of all k such lra.get_term(k) depends on j
|
||||||
std::unordered_map<unsigned, std::unordered_set<unsigned>> m_columns_to_terms;
|
std::unordered_map<unsigned, std::unordered_set<unsigned>> m_columns_to_terms;
|
||||||
|
|
||||||
|
|
||||||
unsigned m_conflict_index = -1; // the row index of the conflict
|
unsigned m_conflict_index = -1; // the row index of the conflict
|
||||||
unsigned m_max_of_branching_iterations = 0;
|
unsigned m_max_of_branching_iterations = 0;
|
||||||
unsigned m_number_of_branching_calls;
|
unsigned m_number_of_branching_calls;
|
||||||
|
@ -513,13 +508,13 @@ namespace lp {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void undo_add_term_method(const lar_term *t) {
|
void undo_add_term_method(const lar_term* t) {
|
||||||
TRACE("d_undo", tout << "t:"<< t<<", t->j():"<< t->j() << std::endl;);
|
TRACE("d_undo", tout << "t:" << t << ", t->j():" << t->j() << std::endl;);
|
||||||
TRACE("dioph_eq", lra.print_term(*t, tout); tout << ", t->j() =" << t->j() << std::endl;);
|
TRACE("dioph_eq", lra.print_term(*t, tout); tout << ", t->j() =" << t->j() << std::endl;);
|
||||||
if (!contains(m_active_terms, t)) {
|
if (!contains(m_active_terms, t)) {
|
||||||
for (int i = static_cast<int>(m_added_terms.size() - 1); i >= 0; --i) {
|
for (int i = static_cast<int>(m_added_terms.size() - 1); i >= 0; --i) {
|
||||||
if (m_added_terms[i] != t) continue;
|
if (m_added_terms[i] != t) continue;
|
||||||
if ((unsigned)i != m_added_terms.size() -1)
|
if ((unsigned)i != m_added_terms.size() - 1)
|
||||||
m_added_terms[i] = m_added_terms.back();
|
m_added_terms[i] = m_added_terms.back();
|
||||||
m_added_terms.pop_back();
|
m_added_terms.pop_back();
|
||||||
break; // all is done since the term has not made it to m_active_terms
|
break; // all is done since the term has not made it to m_active_terms
|
||||||
|
@ -527,8 +522,8 @@ namespace lp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// deregister the term that has been activated
|
// deregister the term that has been activated
|
||||||
for (const auto & p: t->ext_coeffs()) {
|
for (const auto& p : t->ext_coeffs()) {
|
||||||
TRACE("dio_reg", tout << "derigister p.var():" << p.var() <<"->" << t->j() << std::endl; );
|
TRACE("dio_reg", tout << "derigister p.var():" << p.var() << "->" << t->j() << std::endl;);
|
||||||
auto it = m_columns_to_terms.find(p.var());
|
auto it = m_columns_to_terms.find(p.var());
|
||||||
SASSERT(it != m_columns_to_terms.end());
|
SASSERT(it != m_columns_to_terms.end());
|
||||||
it->second.erase(t->j());
|
it->second.erase(t->j());
|
||||||
|
@ -539,22 +534,14 @@ namespace lp {
|
||||||
SASSERT(std::find(m_added_terms.begin(), m_added_terms.end(), t) == m_added_terms.end());
|
SASSERT(std::find(m_added_terms.begin(), m_added_terms.end(), t) == m_added_terms.end());
|
||||||
SASSERT(contains(m_active_terms, t));
|
SASSERT(contains(m_active_terms, t));
|
||||||
m_active_terms.erase(t);
|
m_active_terms.erase(t);
|
||||||
TRACE("dioph_eq",
|
TRACE("dioph_eq", tout << "the deleted term column in m_l_matrix" << std::endl; for (auto p : m_l_matrix.column(t->j())) { tout << "p.coeff():" << p.coeff() << ", row " << p.var() << std::endl; } tout << "m_l_matrix has " << m_l_matrix.column_count() << " columns" << std::endl; tout << "and " << m_l_matrix.row_count() << " rows" << std::endl; print_lar_term_L(*t, tout); tout << "; t->j()=" << t->j() << std::endl;);
|
||||||
tout << "the deleted term column in m_l_matrix" << std::endl;
|
|
||||||
for (auto p: m_l_matrix.column(t->j())) {
|
|
||||||
tout << "p.coeff():" << p.coeff()<< ", row " << p.var() << std::endl;
|
|
||||||
}
|
|
||||||
tout << "m_l_matrix has " << m_l_matrix.column_count() << " columns"<< std::endl;
|
|
||||||
tout << "and " << m_l_matrix.row_count() << " rows" << std::endl;
|
|
||||||
print_lar_term_L(*t, tout); tout << "; t->j()=" << t->j() << std::endl;
|
|
||||||
);
|
|
||||||
shrink_matrices();
|
shrink_matrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct undo_add_term : public trail {
|
struct undo_add_term : public trail {
|
||||||
imp& m_s;
|
imp& m_s;
|
||||||
const lar_term* m_t;
|
const lar_term* m_t;
|
||||||
undo_add_term(imp& s, const lar_term *t): m_s(s), m_t(t) {}
|
undo_add_term(imp& s, const lar_term* t) : m_s(s), m_t(t) {}
|
||||||
|
|
||||||
void undo() {
|
void undo() {
|
||||||
m_s.undo_add_term_method(m_t);
|
m_s.undo_add_term_method(m_t);
|
||||||
|
@ -569,7 +556,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size() const {
|
unsigned size() const {
|
||||||
return m_q.size();
|
return (unsigned)m_q.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(unsigned j) {
|
void push(unsigned j) {
|
||||||
|
@ -591,7 +578,7 @@ namespace lp {
|
||||||
imp& m_imp;
|
imp& m_imp;
|
||||||
unsigned m_j; // the column that has been added
|
unsigned m_j; // the column that has been added
|
||||||
const mpq m_fixed_val;
|
const mpq m_fixed_val;
|
||||||
undo_fixed_column(imp& s, unsigned j) : m_imp(s), m_j(j) , m_fixed_val(s.lra.get_lower_bound(j).x) {
|
undo_fixed_column(imp& s, unsigned j) : m_imp(s), m_j(j), m_fixed_val(s.lra.get_lower_bound(j).x) {
|
||||||
SASSERT(s.lra.column_is_fixed(j));
|
SASSERT(s.lra.column_is_fixed(j));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,18 +600,18 @@ namespace lp {
|
||||||
// change only the rows in m_l_matrix, and update m_e_matrix lazily
|
// change only the rows in m_l_matrix, and update m_e_matrix lazily
|
||||||
unsigned j = m_l_matrix.column_count() - 1;
|
unsigned j = m_l_matrix.column_count() - 1;
|
||||||
make_sure_j_is_in_the_last_row_of_l_matrix();
|
make_sure_j_is_in_the_last_row_of_l_matrix();
|
||||||
const auto &last_e_row = m_l_matrix.m_rows.back();
|
const auto& last_e_row = m_l_matrix.m_rows.back();
|
||||||
mpq alpha;
|
mpq alpha;
|
||||||
for (const auto& p: last_e_row) {
|
for (const auto& p : last_e_row) {
|
||||||
if (p.var() == j) {
|
if (p.var() == j) {
|
||||||
alpha = p.coeff();
|
alpha = p.coeff();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned last_row_index= m_l_matrix.row_count() - 1;
|
unsigned last_row_index = m_l_matrix.row_count() - 1;
|
||||||
m_l_matrix.divide_row(last_row_index, alpha); // divide the last row by alpha
|
m_l_matrix.divide_row(last_row_index, alpha); // divide the last row by alpha
|
||||||
|
|
||||||
auto &column = m_l_matrix.m_columns[j];
|
auto& column = m_l_matrix.m_columns[j];
|
||||||
int pivot_col_cell_index = -1;
|
int pivot_col_cell_index = -1;
|
||||||
for (unsigned k = 0; k < column.size(); k++) {
|
for (unsigned k = 0; k < column.size(); k++) {
|
||||||
if (column[k].var() == last_row_index) {
|
if (column[k].var() == last_row_index) {
|
||||||
|
@ -645,7 +632,7 @@ namespace lp {
|
||||||
m_l_matrix.m_rows[c.var()][c.offset()].offset() = pivot_col_cell_index;
|
m_l_matrix.m_rows[c.var()][c.offset()].offset() = pivot_col_cell_index;
|
||||||
}
|
}
|
||||||
while (column.size() > 1) {
|
while (column.size() > 1) {
|
||||||
auto & c = column.back();
|
auto& c = column.back();
|
||||||
SASSERT(c.var() != last_row_index);
|
SASSERT(c.var() != last_row_index);
|
||||||
m_l_matrix.pivot_row_to_row_given_cell(last_row_index, c, j);
|
m_l_matrix.pivot_row_to_row_given_cell(last_row_index, c, j);
|
||||||
m_changed_rows.insert(c.var());
|
m_changed_rows.insert(c.var());
|
||||||
|
@ -654,9 +641,9 @@ namespace lp {
|
||||||
|
|
||||||
void make_sure_j_is_in_the_last_row_of_l_matrix() {
|
void make_sure_j_is_in_the_last_row_of_l_matrix() {
|
||||||
unsigned j = m_l_matrix.column_count() - 1;
|
unsigned j = m_l_matrix.column_count() - 1;
|
||||||
const auto &last_e_row = m_l_matrix.m_rows.back();
|
const auto& last_e_row = m_l_matrix.m_rows.back();
|
||||||
mpq alpha;
|
mpq alpha;
|
||||||
for (const auto& p: last_e_row) {
|
for (const auto& p : last_e_row) {
|
||||||
if (p.var() == j) {
|
if (p.var() == j) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -671,10 +658,10 @@ namespace lp {
|
||||||
eliminate_last_term_column();
|
eliminate_last_term_column();
|
||||||
remove_last_row_in_matrix(m_l_matrix);
|
remove_last_row_in_matrix(m_l_matrix);
|
||||||
remove_last_row_in_matrix(m_e_matrix);
|
remove_last_row_in_matrix(m_e_matrix);
|
||||||
while(m_l_matrix.column_count() && m_l_matrix.m_columns.back().size() == 0) {
|
while (m_l_matrix.column_count() && m_l_matrix.m_columns.back().size() == 0) {
|
||||||
m_l_matrix.m_columns.pop_back();
|
m_l_matrix.m_columns.pop_back();
|
||||||
}
|
}
|
||||||
while(m_e_matrix.column_count() && m_e_matrix.m_columns.back().size() == 0) {
|
while (m_e_matrix.column_count() && m_e_matrix.m_columns.back().size() == 0) {
|
||||||
m_e_matrix.m_columns.pop_back();
|
m_e_matrix.m_columns.pop_back();
|
||||||
}
|
}
|
||||||
m_var_register.shrink(m_e_matrix.column_count());
|
m_var_register.shrink(m_e_matrix.column_count());
|
||||||
|
@ -688,16 +675,15 @@ namespace lp {
|
||||||
m_sum_of_fixed.pop_back();
|
m_sum_of_fixed.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void remove_last_row_in_matrix(static_matrix<mpq, mpq>& m) {
|
void remove_last_row_in_matrix(static_matrix<mpq, mpq>& m) {
|
||||||
auto & last_row = m.m_rows.back();
|
auto& last_row = m.m_rows.back();
|
||||||
for (unsigned k = static_cast<unsigned>(last_row.size()); k-- > 0;) {
|
for (unsigned k = static_cast<unsigned>(last_row.size()); k-- > 0;) {
|
||||||
m.remove_element(last_row, last_row[k]);
|
m.remove_element(last_row, last_row[k]);
|
||||||
}
|
}
|
||||||
m.m_rows.pop_back();
|
m.m_rows.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_entry_index(std::list<unsigned> & l, unsigned ei) {
|
void remove_entry_index(std::list<unsigned>& l, unsigned ei) {
|
||||||
auto it = std::find(l.begin(), l.end(), ei);
|
auto it = std::find(l.begin(), l.end(), ei);
|
||||||
if (it != l.end())
|
if (it != l.end())
|
||||||
l.erase(it);
|
l.erase(it);
|
||||||
|
@ -714,7 +700,7 @@ namespace lp {
|
||||||
std_vector<constraint_index> m_explanation_of_branches;
|
std_vector<constraint_index> m_explanation_of_branches;
|
||||||
void add_term_callback(const lar_term* t) {
|
void add_term_callback(const lar_term* t) {
|
||||||
unsigned j = t->j();
|
unsigned j = t->j();
|
||||||
TRACE("dioph_eq", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl; );
|
TRACE("dioph_eq", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl;);
|
||||||
if (!lra.column_is_int(j)) {
|
if (!lra.column_is_int(j)) {
|
||||||
TRACE("dioph_eq", tout << "ignored a non-integral column" << std::endl;);
|
TRACE("dioph_eq", tout << "ignored a non-integral column" << std::endl;);
|
||||||
return;
|
return;
|
||||||
|
@ -737,13 +723,13 @@ namespace lp {
|
||||||
return;
|
return;
|
||||||
m_changed_columns.insert(j);
|
m_changed_columns.insert(j);
|
||||||
auto undo = undo_fixed_column(*this, j);
|
auto undo = undo_fixed_column(*this, j);
|
||||||
lra.trail().push(undo) ;
|
lra.trail().push(undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
imp(int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
|
imp(int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
|
||||||
lra.m_add_term_callback=[this](const lar_term*t){add_term_callback(t);};
|
lra.m_add_term_callback = [this](const lar_term* t) { add_term_callback(t); };
|
||||||
lra.m_update_column_bound_callback = [this](unsigned j){update_column_bound_callback(j);};
|
lra.m_update_column_bound_callback = [this](unsigned j) { update_column_bound_callback(j); };
|
||||||
}
|
}
|
||||||
term_o get_term_from_entry(unsigned i) const {
|
term_o get_term_from_entry(unsigned i) const {
|
||||||
term_o t;
|
term_o t;
|
||||||
|
@ -765,14 +751,13 @@ namespace lp {
|
||||||
|
|
||||||
void register_columns_to_term(const lar_term& t) {
|
void register_columns_to_term(const lar_term& t) {
|
||||||
TRACE("dioph_eq", tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
|
TRACE("dioph_eq", tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
|
||||||
for (const auto &p: t.ext_coeffs()) {
|
for (const auto& p : t.ext_coeffs()) {
|
||||||
auto it = m_columns_to_terms.find(p.var());
|
auto it = m_columns_to_terms.find(p.var());
|
||||||
TRACE("dio_reg", tout << "register p.var():" << p.var() <<"->" << t.j() << std::endl; );
|
TRACE("dio_reg", tout << "register p.var():" << p.var() << "->" << t.j() << std::endl;);
|
||||||
|
|
||||||
if (it != m_columns_to_terms.end()) {
|
if (it != m_columns_to_terms.end()) {
|
||||||
it->second.insert(t.j());
|
it->second.insert(t.j());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
std::unordered_set<unsigned> s;
|
std::unordered_set<unsigned> s;
|
||||||
s.insert(t.j());
|
s.insert(t.j());
|
||||||
m_columns_to_terms[p.var()] = s;
|
m_columns_to_terms[p.var()] = s;
|
||||||
|
@ -782,16 +767,16 @@ namespace lp {
|
||||||
// the term has form sum(a_i*x_i) - t.j() = 0,
|
// the term has form sum(a_i*x_i) - t.j() = 0,
|
||||||
void fill_entry(const lar_term& t) {
|
void fill_entry(const lar_term& t) {
|
||||||
TRACE("dioph_eq", print_lar_term_L(t, tout) << std::endl;);
|
TRACE("dioph_eq", print_lar_term_L(t, tout) << std::endl;);
|
||||||
unsigned entry_index = (unsigned) m_e_matrix.row_count();
|
unsigned entry_index = (unsigned)m_e_matrix.row_count();
|
||||||
m_sum_of_fixed.push_back(mpq(0));
|
m_sum_of_fixed.push_back(mpq(0));
|
||||||
mpq & e = m_sum_of_fixed.back();
|
mpq& e = m_sum_of_fixed.back();
|
||||||
SASSERT(m_l_matrix.row_count() == m_e_matrix.row_count());
|
SASSERT(m_l_matrix.row_count() == m_e_matrix.row_count());
|
||||||
// fill m_l_matrix row
|
// fill m_l_matrix row
|
||||||
m_l_matrix.add_row();
|
m_l_matrix.add_row();
|
||||||
// todo: consider to compress variables t.j() by using a devoted var_register for term columns
|
// todo: consider to compress variables t.j() by using a devoted var_register for term columns
|
||||||
m_l_matrix.add_columns_up_to(t.j());
|
m_l_matrix.add_columns_up_to(t.j());
|
||||||
m_l_matrix.add_new_element(entry_index, t.j(), mpq(1));
|
m_l_matrix.add_new_element(entry_index, t.j(), mpq(1));
|
||||||
// fill E-entry
|
// fill E-entry
|
||||||
m_e_matrix.add_row();
|
m_e_matrix.add_row();
|
||||||
|
|
||||||
SASSERT(m_e_matrix.row_count() == m_e_matrix.row_count());
|
SASSERT(m_e_matrix.row_count() == m_e_matrix.row_count());
|
||||||
|
@ -814,7 +799,7 @@ namespace lp {
|
||||||
if (ei >= m_e_matrix.row_count()) return;
|
if (ei >= m_e_matrix.row_count()) return;
|
||||||
// q is the queue of variables that can be substituted in ei
|
// q is the queue of variables that can be substituted in ei
|
||||||
protected_queue q;
|
protected_queue q;
|
||||||
for (const auto& p: m_e_matrix.m_rows[ei]) {
|
for (const auto& p : m_e_matrix.m_rows[ei]) {
|
||||||
if (can_substitute(p.var()))
|
if (can_substitute(p.var()))
|
||||||
q.push(p.var());
|
q.push(p.var());
|
||||||
}
|
}
|
||||||
|
@ -823,23 +808,24 @@ namespace lp {
|
||||||
SASSERT(entry_invariant(ei));
|
SASSERT(entry_invariant(ei));
|
||||||
}
|
}
|
||||||
|
|
||||||
void substitute_on_q_with_entry_in_S(protected_queue& q, unsigned ei, unsigned j, const mpq & alpha) {
|
void substitute_on_q_with_entry_in_S(protected_queue& q, unsigned ei, unsigned j, const mpq& alpha) {
|
||||||
unsigned ei_to_sub = m_k2s[j];
|
unsigned ei_to_sub = m_k2s[j];
|
||||||
int sign_j = get_sign_in_e_row(ei_to_sub, j);
|
int sign_j = get_sign_in_e_row(ei_to_sub, j);
|
||||||
// we need to eliminate alpha*j in ei's row
|
// we need to eliminate alpha*j in ei's row
|
||||||
add_two_entries(-mpq(sign_j)*alpha, ei_to_sub, ei);
|
add_two_entries(-mpq(sign_j) * alpha, ei_to_sub, ei);
|
||||||
for (const auto& p: m_e_matrix.m_rows[ei]) {
|
for (const auto& p : m_e_matrix.m_rows[ei]) {
|
||||||
unsigned jj = p.var();
|
unsigned jj = p.var();
|
||||||
if (can_substitute(jj))
|
if (can_substitute(jj))
|
||||||
q.push(jj);
|
q.push(jj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void substitute_with_fresh_def(protected_queue& q, unsigned ei, unsigned j, const mpq & alpha) {
|
void substitute_with_fresh_def(protected_queue& q, unsigned ei, unsigned j, const mpq& alpha) {
|
||||||
const lar_term& sub_term = m_fresh_k2xt_terms.get_by_key(j);
|
const lar_term& sub_term = m_fresh_k2xt_terms.get_by_key(j).first;
|
||||||
|
TRACE("dioph_eq", print_lar_term_L(sub_term, tout) << std::endl;);
|
||||||
SASSERT(sub_term.get_coeff(j).is_one());
|
SASSERT(sub_term.get_coeff(j).is_one());
|
||||||
// we need to eliminate alpha*j in ei's row
|
// we need to eliminate alpha*j in ei's row
|
||||||
add_term_to_entry(- alpha, sub_term, ei);
|
add_term_to_entry(-alpha, sub_term, ei);
|
||||||
for (const auto& p: m_e_matrix.m_rows[ei]) {
|
for (const auto& p : m_e_matrix.m_rows[ei]) {
|
||||||
unsigned jj = p.var();
|
unsigned jj = p.var();
|
||||||
if (can_substitute(jj))
|
if (can_substitute(jj))
|
||||||
q.push(jj);
|
q.push(jj);
|
||||||
|
@ -847,7 +833,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// q is the queue of variables that can be substituted in ei
|
// q is the queue of variables that can be substituted in ei
|
||||||
void substitute_on_q(protected_queue & q, unsigned ei) {
|
void substitute_on_q(protected_queue& q, unsigned ei) {
|
||||||
while (!q.empty()) {
|
while (!q.empty()) {
|
||||||
unsigned j = q.pop_front();
|
unsigned j = q.pop_front();
|
||||||
mpq alpha = get_coeff_in_e_row(ei, j);
|
mpq alpha = get_coeff_in_e_row(ei, j);
|
||||||
|
@ -860,23 +846,23 @@ namespace lp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool term_is_in_range(const lar_term& t) const {
|
bool term_is_in_range(const lar_term& t) const {
|
||||||
for (const auto & p: t) {
|
for (const auto& p : t) {
|
||||||
if (p.var() >= m_e_matrix.column_count())
|
if (p.var() >= m_e_matrix.column_count())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// adds the term multiplied by coeff to m_e_matrix row i
|
// adds the term multiplied by coeff to m_e_matrix row i
|
||||||
void add_term_to_entry(const mpq& coeff, const lar_term& t, unsigned i ) {
|
void add_term_to_entry(const mpq& coeff, const lar_term& t, unsigned i) {
|
||||||
SASSERT(term_is_in_range(t));
|
SASSERT(term_is_in_range(t));
|
||||||
m_e_matrix.add_term_to_row(coeff, t, i);
|
m_e_matrix.add_term_to_row(coeff, t, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds entry i0 multiplied by coeff to entry i1
|
// adds entry i0 multiplied by coeff to entry i1
|
||||||
void add_two_entries(const mpq& coeff, unsigned i0, unsigned i1 ) {
|
void add_two_entries(const mpq& coeff, unsigned i0, unsigned i1) {
|
||||||
m_e_matrix.add_rows(coeff, i0, i1);
|
m_e_matrix.add_rows(coeff, i0, i1);
|
||||||
m_l_matrix.add_rows(coeff, i0, i1);
|
m_l_matrix.add_rows(coeff, i0, i1);
|
||||||
m_sum_of_fixed[i1] += coeff* m_sum_of_fixed[i0];
|
m_sum_of_fixed[i1] += coeff * m_sum_of_fixed[i0];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool all_vars_are_int(const lar_term& term) const {
|
bool all_vars_are_int(const lar_term& term) const {
|
||||||
|
@ -885,26 +871,24 @@ namespace lp {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return lia.column_is_int(term.j());
|
return lia.column_is_int(term.j());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_e_row(unsigned ei) {
|
void clear_e_row(unsigned ei) {
|
||||||
auto & row = m_e_matrix.m_rows[ei];
|
auto& row = m_e_matrix.m_rows[ei];
|
||||||
while (row.size() > 0) {
|
while (row.size() > 0) {
|
||||||
auto& c = row.back();
|
auto& c = row.back();
|
||||||
m_e_matrix.remove_element(row, c);
|
m_e_matrix.remove_element(row, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void recalculate_entry(unsigned ei) {
|
void recalculate_entry(unsigned ei) {
|
||||||
TRACE("dioph_eq", print_entry(ei, tout) << std::endl;);
|
TRACE("dioph_eq", print_entry(ei, tout) << std::endl;);
|
||||||
mpq &c = m_sum_of_fixed[ei];
|
mpq& c = m_sum_of_fixed[ei];
|
||||||
c = mpq(0);
|
c = mpq(0);
|
||||||
open_l_term_to_work_vector(ei, c);
|
open_l_term_to_work_vector(ei, c);
|
||||||
clear_e_row(ei);
|
clear_e_row(ei);
|
||||||
mpq denom(1);
|
mpq denom(1);
|
||||||
for (const auto & p: m_substitution_workspace.m_data) {
|
for (const auto& p : m_substitution_workspace.m_data) {
|
||||||
unsigned lj = add_var(p.var());
|
unsigned lj = add_var(p.var());
|
||||||
m_e_matrix.add_columns_up_to(lj);
|
m_e_matrix.add_columns_up_to(lj);
|
||||||
m_e_matrix.add_new_element(ei, lj, p.coeff());
|
m_e_matrix.add_new_element(ei, lj, p.coeff());
|
||||||
|
@ -935,31 +919,48 @@ namespace lp {
|
||||||
for (const auto& p : m_e_matrix.column(this->lar_solver_to_local(j))) {
|
for (const auto& p : m_e_matrix.column(this->lar_solver_to_local(j))) {
|
||||||
m_changed_rows.insert(p.var()); // TODO: is it necessary?
|
m_changed_rows.insert(p.var()); // TODO: is it necessary?
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_irrelevant_fresh_defs_for_row(unsigned ei) {
|
void remove_irrelevant_fresh_defs_for_row(unsigned ei) {
|
||||||
auto it = m_row2fresh_defs.find(ei);
|
auto it = m_row2fresh_defs.find(ei);
|
||||||
if (it == m_row2fresh_defs.end()) return;
|
if (it == m_row2fresh_defs.end()) return;
|
||||||
for (unsigned xt: it->second) {
|
for (unsigned xt : it->second) {
|
||||||
|
if (m_fresh_k2xt_terms.has_second_key(xt))
|
||||||
m_fresh_k2xt_terms.erase_by_second_key(xt);
|
m_fresh_k2xt_terms.erase_by_second_key(xt);
|
||||||
}
|
}
|
||||||
m_row2fresh_defs.erase(it);
|
m_row2fresh_defs.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_irrelevant_fresh_defs() {
|
void remove_irrelevant_fresh_defs() {
|
||||||
|
std_vector<unsigned> xt_to_remove;
|
||||||
|
std_vector<unsigned> rows_to_remove_the_defs_from;
|
||||||
|
for (const auto& p : m_fresh_k2xt_terms.m_bij.m_rev_map) {
|
||||||
|
unsigned xt = p.first;
|
||||||
|
if (xt >= m_e_matrix.column_count()) {
|
||||||
|
xt_to_remove.push_back(xt);
|
||||||
|
rows_to_remove_the_defs_from.push_back(m_fresh_k2xt_terms.get_by_val(xt).second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned xt : xt_to_remove) {
|
||||||
|
m_fresh_k2xt_terms.erase_by_second_key(xt);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned ei : m_changed_rows) {
|
for (unsigned ei : m_changed_rows) {
|
||||||
remove_irrelevant_fresh_defs_for_row(ei);
|
remove_irrelevant_fresh_defs_for_row(ei);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned ei : rows_to_remove_the_defs_from) {
|
||||||
|
remove_irrelevant_fresh_defs_for_row(ei);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_changed_columns() {
|
void process_changed_columns() {
|
||||||
|
|
||||||
find_changed_terms_and_more_changed_rows();
|
find_changed_terms_and_more_changed_rows();
|
||||||
for (unsigned j : m_changed_terms) {
|
for (unsigned j : m_changed_terms) {
|
||||||
if (j >= m_l_matrix.column_count()) continue;
|
if (j >= m_l_matrix.column_count()) continue;
|
||||||
for (const auto & cs: m_l_matrix.column(j)) {
|
for (const auto& cs : m_l_matrix.column(j)) {
|
||||||
m_changed_rows.insert(cs.var());
|
m_changed_rows.insert(cs.var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -971,7 +972,7 @@ namespace lp {
|
||||||
if (it == m_row2fresh_defs.end()) continue;
|
if (it == m_row2fresh_defs.end()) continue;
|
||||||
for (unsigned xt : it->second) {
|
for (unsigned xt : it->second) {
|
||||||
SASSERT(var_is_fresh(xt));
|
SASSERT(var_is_fresh(xt));
|
||||||
for (const auto &p :m_e_matrix.m_columns[xt]) {
|
for (const auto& p : m_e_matrix.m_columns[xt]) {
|
||||||
more_changed_rows.push_back(p.var());
|
more_changed_rows.push_back(p.var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -981,12 +982,9 @@ namespace lp {
|
||||||
m_changed_rows.insert(ei);
|
m_changed_rows.insert(ei);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_irrelevant_fresh_defs();
|
for (unsigned ei : m_changed_rows) {
|
||||||
|
|
||||||
|
|
||||||
for(unsigned ei : m_changed_rows) {
|
|
||||||
if (ei >= m_e_matrix.row_count())
|
if (ei >= m_e_matrix.row_count())
|
||||||
continue;;
|
continue;
|
||||||
recalculate_entry(ei);
|
recalculate_entry(ei);
|
||||||
if (m_e_matrix.m_columns.back().size() == 0) {
|
if (m_e_matrix.m_columns.back().size() == 0) {
|
||||||
m_e_matrix.m_columns.pop_back();
|
m_e_matrix.m_columns.pop_back();
|
||||||
|
@ -997,6 +995,8 @@ namespace lp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_irrelevant_fresh_defs();
|
||||||
|
|
||||||
eliminate_substituted_in_changed_rows();
|
eliminate_substituted_in_changed_rows();
|
||||||
m_changed_columns.reset();
|
m_changed_columns.reset();
|
||||||
SASSERT(m_changed_columns.size() == 0);
|
SASSERT(m_changed_columns.size() == 0);
|
||||||
|
@ -1006,20 +1006,20 @@ namespace lp {
|
||||||
|
|
||||||
int get_sign_in_e_row(unsigned ei, unsigned j) const {
|
int get_sign_in_e_row(unsigned ei, unsigned j) const {
|
||||||
const auto& row = m_e_matrix.m_rows[ei];
|
const auto& row = m_e_matrix.m_rows[ei];
|
||||||
auto it = std::find_if (row.begin(), row.end(), [j](const auto& p) {return p.var() == j;} );
|
auto it = std::find_if(row.begin(), row.end(), [j](const auto& p) { return p.var() == j; });
|
||||||
SASSERT(it != row.end() && abs(it->coeff()) == mpq(1));
|
SASSERT(it != row.end() && abs(it->coeff()) == mpq(1));
|
||||||
return it->coeff().is_pos()? 1:-1;
|
return it->coeff().is_pos() ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpq get_coeff_in_e_row (unsigned ei, unsigned j) {
|
mpq get_coeff_in_e_row(unsigned ei, unsigned j) {
|
||||||
const auto& row = m_e_matrix.m_rows[ei];
|
const auto& row = m_e_matrix.m_rows[ei];
|
||||||
auto it = std::find_if (row.begin(), row.end(), [j](const auto& p) {return p.var() == j;} );
|
auto it = std::find_if(row.begin(), row.end(), [j](const auto& p) { return p.var() == j; });
|
||||||
if (it == row.end()) return mpq(0);
|
if (it == row.end()) return mpq(0);
|
||||||
return it->coeff();
|
return it->coeff();
|
||||||
}
|
}
|
||||||
|
|
||||||
void eliminate_substituted_in_changed_rows() {
|
void eliminate_substituted_in_changed_rows() {
|
||||||
for (unsigned ei: m_changed_rows)
|
for (unsigned ei : m_changed_rows)
|
||||||
subs_entry(ei);
|
subs_entry(ei);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,7 +1058,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
if (belongs_to_f(ei)) {
|
if (belongs_to_f(ei)) {
|
||||||
// see that all vars are substituted
|
// see that all vars are substituted
|
||||||
const auto & row = m_e_matrix.m_rows[ei];
|
const auto& row = m_e_matrix.m_rows[ei];
|
||||||
for (const auto& p : row) {
|
for (const auto& p : row) {
|
||||||
if (m_k2s.has_key(p.var())) {
|
if (m_k2s.has_key(p.var())) {
|
||||||
/*
|
/*
|
||||||
|
@ -1078,7 +1078,6 @@ namespace lp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1092,7 @@ namespace lp {
|
||||||
m_lra_level = 0;
|
m_lra_level = 0;
|
||||||
|
|
||||||
process_changed_columns();
|
process_changed_columns();
|
||||||
for (const lar_term* t: m_added_terms) {
|
for (const lar_term* t : m_added_terms) {
|
||||||
m_active_terms.insert(t);
|
m_active_terms.insert(t);
|
||||||
fill_entry(*t);
|
fill_entry(*t);
|
||||||
register_columns_to_term(*t);
|
register_columns_to_term(*t);
|
||||||
|
@ -1161,7 +1160,7 @@ namespace lp {
|
||||||
// The function returns true if and only if there is no conflict. In the case of a conflict a branch
|
// The function returns true if and only if there is no conflict. In the case of a conflict a branch
|
||||||
// can be returned as well.
|
// can be returned as well.
|
||||||
bool normalize_e_by_gcd(unsigned ei, mpq& g) {
|
bool normalize_e_by_gcd(unsigned ei, mpq& g) {
|
||||||
mpq & e = m_sum_of_fixed[ei];
|
mpq& e = m_sum_of_fixed[ei];
|
||||||
TRACE("dioph_eq", print_entry(ei, tout) << std::endl;);
|
TRACE("dioph_eq", print_entry(ei, tout) << std::endl;);
|
||||||
g = gcd_of_coeffs(m_e_matrix.m_rows[ei], false);
|
g = gcd_of_coeffs(m_e_matrix.m_rows[ei], false);
|
||||||
if (g.is_zero() || g.is_one()) {
|
if (g.is_zero() || g.is_one()) {
|
||||||
|
@ -1196,14 +1195,13 @@ namespace lp {
|
||||||
t.c() = -c.rhs();
|
t.c() = -c.rhs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void subs_front_in_indexed_vector_by_fresh(unsigned k, protected_queue& q) {
|
||||||
void subs_front_in_indexed_vector_by_fresh(unsigned k, protected_queue &q) {
|
const lar_term& e = m_fresh_k2xt_terms.get_by_key(k).first;
|
||||||
const lar_term& e = m_fresh_k2xt_terms.get_by_key(k);
|
|
||||||
TRACE("dioph_eq", tout << "k:" << k << ", in ";
|
TRACE("dioph_eq", tout << "k:" << k << ", in ";
|
||||||
print_term_o(create_term_from_ind_c(), tout) << std::endl;
|
print_term_o(create_term_from_ind_c(), tout) << std::endl;
|
||||||
tout << "subs with e:";
|
tout << "subs with e:";
|
||||||
print_lar_term_L(e, tout) << std::endl;);
|
print_lar_term_L(e, tout) << std::endl;);
|
||||||
mpq coeff = - m_substitution_workspace[k]; // need to copy since it will be zeroed
|
mpq coeff = -m_substitution_workspace[k]; // need to copy since it will be zeroed
|
||||||
m_substitution_workspace.erase(k); // m_work_vector_1[k] = 0;
|
m_substitution_workspace.erase(k); // m_work_vector_1[k] = 0;
|
||||||
|
|
||||||
SASSERT(e.get_coeff(k).is_one());
|
SASSERT(e.get_coeff(k).is_one());
|
||||||
|
@ -1212,7 +1210,7 @@ namespace lp {
|
||||||
unsigned j = p.var();
|
unsigned j = p.var();
|
||||||
if (j == k)
|
if (j == k)
|
||||||
continue;
|
continue;
|
||||||
m_substitution_workspace.add(p.coeff()*coeff, j);
|
m_substitution_workspace.add(p.coeff() * coeff, j);
|
||||||
// do we need to add j to the queue?
|
// do we need to add j to the queue?
|
||||||
if (!var_is_fresh(j) && m_substitution_workspace.has(j) && can_substitute(j))
|
if (!var_is_fresh(j) && m_substitution_workspace.has(j) && can_substitute(j))
|
||||||
q.push(j);
|
q.push(j);
|
||||||
|
@ -1225,7 +1223,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_l_row_to_term_with_index(const mpq& coeff, unsigned ei) {
|
void add_l_row_to_term_with_index(const mpq& coeff, unsigned ei) {
|
||||||
for (const auto & p: m_l_matrix.m_rows[ei]) {
|
for (const auto& p : m_l_matrix.m_rows[ei]) {
|
||||||
m_l_terms_workspace.add(coeff * p.coeff(), p.var());
|
m_l_terms_workspace.add(coeff * p.coeff(), p.var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1288,7 @@ namespace lp {
|
||||||
|
|
||||||
lar_term l_term_from_row(unsigned k) const {
|
lar_term l_term_from_row(unsigned k) const {
|
||||||
lar_term ret;
|
lar_term ret;
|
||||||
for (const auto & p: m_l_matrix.m_rows[k])
|
for (const auto& p : m_l_matrix.m_rows[k])
|
||||||
ret.add_monomial(p.coeff(), p.var());
|
ret.add_monomial(p.coeff(), p.var());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1357,7 +1355,7 @@ namespace lp {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned j: cleanup) {
|
for (unsigned j : cleanup) {
|
||||||
m_changed_terms.remove(j);
|
m_changed_terms.remove(j);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1428,25 +1426,8 @@ namespace lp {
|
||||||
// term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c())))
|
// term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c())))
|
||||||
// enable_trace("dioph_eq");
|
// enable_trace("dioph_eq");
|
||||||
|
|
||||||
TRACE("dioph_eq_deb_subs", tout << "after subs\n";
|
TRACE("dioph_eq_deb_subs", tout << "after subs\n"; print_term_o(create_term_from_ind_c(), tout) << std::endl; tout << "term_to_tighten:"; print_lar_term_L(term_to_tighten, tout) << std::endl; tout << "m_tmp_l:"; print_lar_term_L(m_l_terms_workspace.to_term(), tout) << std::endl; tout << "open_ml:"; print_lar_term_L(open_ml(m_l_terms_workspace.to_term()), tout) << std::endl; tout << "term_to_tighten + open_ml:"; print_term_o(term_to_tighten + open_ml(m_l_terms_workspace.to_term()), tout) << std::endl; term_o ls = fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term())); tout << "ls:"; print_term_o(ls, tout) << std::endl; term_o rs = term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c())); tout << "rs:"; print_term_o(rs, tout) << std::endl; term_o diff = ls - rs; if (!diff.is_empty()) {
|
||||||
print_term_o(create_term_from_ind_c(), tout) << std::endl;
|
tout << "diff:"; print_term_o(diff, tout ) << std::endl; });
|
||||||
tout << "term_to_tighten:";
|
|
||||||
print_lar_term_L(term_to_tighten, tout) << std::endl;
|
|
||||||
tout << "m_tmp_l:"; print_lar_term_L(m_l_terms_workspace.to_term(), tout) << std::endl;
|
|
||||||
tout << "open_ml:";
|
|
||||||
print_lar_term_L(open_ml(m_l_terms_workspace.to_term()), tout) << std::endl;
|
|
||||||
tout << "term_to_tighten + open_ml:";
|
|
||||||
print_term_o(term_to_tighten + open_ml(m_l_terms_workspace.to_term()), tout)
|
|
||||||
<< std::endl;
|
|
||||||
term_o ls = fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term()));
|
|
||||||
tout << "ls:"; print_term_o(ls,tout) << std::endl;
|
|
||||||
term_o rs = term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c()));
|
|
||||||
tout << "rs:"; print_term_o(rs, tout ) << std::endl;
|
|
||||||
term_o diff = ls - rs;
|
|
||||||
if (!diff.is_empty()) {
|
|
||||||
tout << "diff:"; print_term_o(diff, tout ) << std::endl;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
SASSERT(
|
SASSERT(
|
||||||
fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term())) ==
|
fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term())) ==
|
||||||
|
@ -1574,7 +1555,8 @@ namespace lp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> u_dependency* explain_fixed_in_meta_term (const T& t) {
|
template <typename T>
|
||||||
|
u_dependency* explain_fixed_in_meta_term(const T& t) {
|
||||||
return explain_fixed(open_ml(t));
|
return explain_fixed(open_ml(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1591,7 +1573,8 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
lia_move process_f() {
|
lia_move process_f() {
|
||||||
while (rewrite_eqs()) {}
|
while (rewrite_eqs()) {
|
||||||
|
}
|
||||||
if (m_conflict_index != UINT_MAX) {
|
if (m_conflict_index != UINT_MAX) {
|
||||||
lra.stats().m_dio_rewrite_conflicts++;
|
lra.stats().m_dio_rewrite_conflicts++;
|
||||||
return lia_move::conflict;
|
return lia_move::conflict;
|
||||||
|
@ -1636,10 +1619,10 @@ namespace lp {
|
||||||
mpq c = m_sum_of_fixed[ei];
|
mpq c = m_sum_of_fixed[ei];
|
||||||
for (const auto& p : m_e_matrix.m_rows[m_k2s[j]]) {
|
for (const auto& p : m_e_matrix.m_rows[m_k2s[j]]) {
|
||||||
if (p.var() == j) {
|
if (p.var() == j) {
|
||||||
const mpq & j_coeff = p.coeff();
|
const mpq& j_coeff = p.coeff();
|
||||||
SASSERT(j_coeff.is_one() || j_coeff.is_minus_one());
|
SASSERT(j_coeff.is_one() || j_coeff.is_minus_one());
|
||||||
c += j_coeff * lra.get_lower_bound(local_to_lar_solver(j)).x;
|
c += j_coeff * lra.get_lower_bound(local_to_lar_solver(j)).x;
|
||||||
TRACE("dio_br", tout << "the value of the vixed var is:" << lra.get_lower_bound(local_to_lar_solver(j)).x<<", m_sum_of_fixed[" << ei << "]:" << m_sum_of_fixed[ei] << ", new free coeff c:" << c << std::endl;);
|
TRACE("dio_br", tout << "the value of the vixed var is:" << lra.get_lower_bound(local_to_lar_solver(j)).x << ", m_sum_of_fixed[" << ei << "]:" << m_sum_of_fixed[ei] << ", new free coeff c:" << c << std::endl;);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (g.is_zero()) {
|
if (g.is_zero()) {
|
||||||
|
@ -1649,7 +1632,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
if (g.is_one()) return lia_move::undef;
|
if (g.is_one()) return lia_move::undef;
|
||||||
}
|
}
|
||||||
if (!(c/g).is_int()) {
|
if (!(c / g).is_int()) {
|
||||||
return lia_move::conflict;
|
return lia_move::conflict;
|
||||||
}
|
}
|
||||||
return lia_move::undef;
|
return lia_move::undef;
|
||||||
|
@ -1662,7 +1645,8 @@ namespace lp {
|
||||||
*/
|
*/
|
||||||
if (m_k2s.has_key(j)) { // j is substituted but using an entry
|
if (m_k2s.has_key(j)) { // j is substituted but using an entry
|
||||||
TRACE("dio_br",
|
TRACE("dio_br",
|
||||||
tout << "fixed j:" << j <<", was substited by "; print_entry(m_k2s[j], tout););
|
tout << "fixed j:" << j << ", was substited by ";
|
||||||
|
print_entry(m_k2s[j], tout););
|
||||||
if (check_fixing(j) == lia_move::conflict) {
|
if (check_fixing(j) == lia_move::conflict) {
|
||||||
for (auto ci : lra.flatten(explain_fixed_in_meta_term(m_l_matrix.m_rows[m_k2s[j]]))) {
|
for (auto ci : lra.flatten(explain_fixed_in_meta_term(m_l_matrix.m_rows[m_k2s[j]]))) {
|
||||||
m_explanation_of_branches.push_back(ci);
|
m_explanation_of_branches.push_back(ci);
|
||||||
|
@ -1674,7 +1658,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo_branching() {
|
void undo_branching() {
|
||||||
while (m_lra_level --) {
|
while (m_lra_level--) {
|
||||||
lra.pop();
|
lra.pop();
|
||||||
}
|
}
|
||||||
lra.find_feasible_solution();
|
lra.find_feasible_solution();
|
||||||
|
@ -1697,14 +1681,14 @@ namespace lp {
|
||||||
} else {
|
} else {
|
||||||
lra.add_var_bound(b.m_j, lconstraint_kind::GE, b.m_rs + mpq(1));
|
lra.add_var_bound(b.m_j, lconstraint_kind::GE, b.m_rs + mpq(1));
|
||||||
}
|
}
|
||||||
TRACE("dio_br", lra.print_column_info(b.m_j, tout) <<"add bound" << std::endl;);
|
TRACE("dio_br", lra.print_column_info(b.m_j, tout) << "add bound" << std::endl;);
|
||||||
if (lra.column_is_fixed(b.m_j)) {
|
if (lra.column_is_fixed(b.m_j)) {
|
||||||
unsigned local_bj;
|
unsigned local_bj;
|
||||||
if (! m_var_register.external_is_used(b.m_j, local_bj))
|
if (!m_var_register.external_is_used(b.m_j, local_bj))
|
||||||
return lia_move::undef;
|
return lia_move::undef;
|
||||||
|
|
||||||
if (fix_var(local_bj) == lia_move::conflict) {
|
if (fix_var(local_bj) == lia_move::conflict) {
|
||||||
TRACE("dio_br", tout << "conflict in fix_var" << std::endl;) ;
|
TRACE("dio_br", tout << "conflict in fix_var" << std::endl;);
|
||||||
return lia_move::conflict;
|
return lia_move::conflict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1731,7 +1715,6 @@ namespace lp {
|
||||||
if (this->lra.constraints().valid_index(ci))
|
if (this->lra.constraints().valid_index(ci))
|
||||||
m_infeas_explanation.push_back(ci);
|
m_infeas_explanation.push_back(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lia_move branching_on_undef() {
|
lia_move branching_on_undef() {
|
||||||
|
@ -1800,7 +1783,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_number_of_int_inf() const {
|
unsigned get_number_of_int_inf() const {
|
||||||
return (unsigned) std::count_if(
|
return (unsigned)std::count_if(
|
||||||
lra.r_basis().begin(), lra.r_basis().end(),
|
lra.r_basis().begin(), lra.r_basis().end(),
|
||||||
[this](unsigned j) {
|
[this](unsigned j) {
|
||||||
return lia.column_is_int_inf(j);
|
return lia.column_is_int_inf(j);
|
||||||
|
@ -1826,7 +1809,6 @@ namespace lp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
branch create_branch() {
|
branch create_branch() {
|
||||||
unsigned bj = UINT_MAX;
|
unsigned bj = UINT_MAX;
|
||||||
double score = std::numeric_limits<double>::infinity();
|
double score = std::numeric_limits<double>::infinity();
|
||||||
|
@ -1868,11 +1850,11 @@ namespace lp {
|
||||||
|
|
||||||
bool columns_to_terms_is_correct() const {
|
bool columns_to_terms_is_correct() const {
|
||||||
std::unordered_map<unsigned, std::unordered_set<unsigned>> c2t;
|
std::unordered_map<unsigned, std::unordered_set<unsigned>> c2t;
|
||||||
for (unsigned k = 0; k < lra.terms().size(); k ++ ) {
|
for (unsigned k = 0; k < lra.terms().size(); k++) {
|
||||||
const lar_term* t = lra.terms()[k];
|
const lar_term* t = lra.terms()[k];
|
||||||
if (!all_vars_are_int(*t)) continue;
|
if (!all_vars_are_int(*t)) continue;
|
||||||
SASSERT(t->j() != UINT_MAX);
|
SASSERT(t->j() != UINT_MAX);
|
||||||
for (const auto& p: (*t).ext_coeffs()) {
|
for (const auto& p : (*t).ext_coeffs()) {
|
||||||
unsigned j = p.var();
|
unsigned j = p.var();
|
||||||
auto it = c2t.find(j);
|
auto it = c2t.find(j);
|
||||||
if (it == c2t.end()) {
|
if (it == c2t.end()) {
|
||||||
|
@ -1882,42 +1864,25 @@ namespace lp {
|
||||||
} else {
|
} else {
|
||||||
it->second.insert(t->j());
|
it->second.insert(t->j());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto & p : c2t) {
|
for (const auto& p : c2t) {
|
||||||
unsigned j = p.first;
|
unsigned j = p.first;
|
||||||
const auto it = m_columns_to_terms.find(j);
|
const auto it = m_columns_to_terms.find(j);
|
||||||
if (it == m_columns_to_terms.end()) {
|
if (it == m_columns_to_terms.end()) {
|
||||||
TRACE("dioph_eq", tout << "column j" << j << " is not registered" << std::endl;
|
TRACE("dioph_eq", tout << "column j" << j << " is not registered" << std::endl; tout << "the column belongs to the the following terms:"; for (unsigned tj : p.second) { tout << " " << tj; } tout << std::endl;);
|
||||||
tout << "the column belongs to the the following terms:";
|
|
||||||
for (unsigned tj : p.second) {
|
|
||||||
tout << " " << tj;
|
|
||||||
}
|
|
||||||
tout << std::endl;
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (it->second != p.second) {
|
if (it->second != p.second) {
|
||||||
TRACE("dioph_eq_deb", tout << "m_columns_to_terms[" << j << "] has to be ";
|
TRACE("dioph_eq_deb", tout << "m_columns_to_terms[" << j << "] has to be "; tout << "{"; for (unsigned lll : p.second) { tout << lll << ", "; } tout << "}, \nbut it is {"; for (unsigned lll : it->second) { tout << lll << ", "; }; tout << "}" << std::endl;
|
||||||
tout << "{";
|
|
||||||
for(unsigned lll : p.second) {
|
|
||||||
tout << lll << ", ";
|
|
||||||
}
|
|
||||||
tout << "}, \nbut it is {";
|
|
||||||
for (unsigned lll : it->second) {
|
|
||||||
tout << lll << ", ";
|
|
||||||
};
|
|
||||||
tout << "}" << std::endl;
|
|
||||||
|
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reverse inclusion
|
// reverse inclusion
|
||||||
for (const auto & p : m_columns_to_terms) {
|
for (const auto& p : m_columns_to_terms) {
|
||||||
unsigned j = p.first;
|
unsigned j = p.first;
|
||||||
const auto it = c2t.find(j);
|
const auto it = c2t.find(j);
|
||||||
if (it == c2t.end()) {
|
if (it == c2t.end()) {
|
||||||
|
@ -1941,10 +1906,10 @@ namespace lp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++ ) {
|
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++) {
|
||||||
auto it = m_row2fresh_defs.find(ei);
|
auto it = m_row2fresh_defs.find(ei);
|
||||||
if (it != m_row2fresh_defs.end()) {
|
if (it != m_row2fresh_defs.end()) {
|
||||||
for (unsigned xt: it->second) {
|
for (unsigned xt : it->second) {
|
||||||
if (!m_fresh_k2xt_terms.has_second_key(xt))
|
if (!m_fresh_k2xt_terms.has_second_key(xt))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1970,7 +1935,7 @@ namespace lp {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
SASSERT(ret == lia_move::undef);
|
SASSERT(ret == lia_move::undef);
|
||||||
m_max_of_branching_iterations = (unsigned)m_max_of_branching_iterations/2;
|
m_max_of_branching_iterations = (unsigned)m_max_of_branching_iterations / 2;
|
||||||
|
|
||||||
return lia_move::undef;
|
return lia_move::undef;
|
||||||
}
|
}
|
||||||
|
@ -2021,7 +1986,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
bool j_sign_is_correct(unsigned ei, unsigned j, int j_sign) {
|
bool j_sign_is_correct(unsigned ei, unsigned j, int j_sign) {
|
||||||
const auto& row = m_e_matrix.m_rows[ei];
|
const auto& row = m_e_matrix.m_rows[ei];
|
||||||
auto it = std::find_if (row.begin(), row.end(), [j](const auto& p) {return p.var() == j;} );
|
auto it = std::find_if(row.begin(), row.end(), [j](const auto& p) { return p.var() == j; });
|
||||||
if (it == row.end()) return false;
|
if (it == row.end()) return false;
|
||||||
return (it->coeff() == mpq(1) && j_sign == 1) ||
|
return (it->coeff() == mpq(1) && j_sign == 1) ||
|
||||||
(it->coeff() == mpq(-1) && j_sign == -1);
|
(it->coeff() == mpq(-1) && j_sign == -1);
|
||||||
|
@ -2030,7 +1995,7 @@ namespace lp {
|
||||||
// a coefficient equal to j_sign which is +-1
|
// a coefficient equal to j_sign which is +-1
|
||||||
void eliminate_var_in_f(unsigned ei, unsigned j, int j_sign) {
|
void eliminate_var_in_f(unsigned ei, unsigned j, int j_sign) {
|
||||||
SASSERT(belongs_to_s(ei));
|
SASSERT(belongs_to_s(ei));
|
||||||
const auto & e = m_sum_of_fixed[ei];
|
const auto& e = m_sum_of_fixed[ei];
|
||||||
SASSERT(j_sign_is_correct(ei, j, j_sign));
|
SASSERT(j_sign_is_correct(ei, j, j_sign));
|
||||||
TRACE("dioph_eq", tout << "eliminate var:" << j << " by using:";
|
TRACE("dioph_eq", tout << "eliminate var:" << j << " by using:";
|
||||||
print_entry(ei, tout) << std::endl;);
|
print_entry(ei, tout) << std::endl;);
|
||||||
|
@ -2040,7 +2005,7 @@ namespace lp {
|
||||||
[ei](const auto& cell) {
|
[ei](const auto& cell) {
|
||||||
return cell.var() == ei;
|
return cell.var() == ei;
|
||||||
});
|
});
|
||||||
unsigned pivot_col_cell_index = (unsigned) std::distance(column.begin(), it);
|
unsigned pivot_col_cell_index = (unsigned)std::distance(column.begin(), it);
|
||||||
if (pivot_col_cell_index != 0) {
|
if (pivot_col_cell_index != 0) {
|
||||||
// swap the pivot column cell with the head cell
|
// swap the pivot column cell with the head cell
|
||||||
auto c = column[0];
|
auto c = column[0];
|
||||||
|
@ -2067,8 +2032,8 @@ namespace lp {
|
||||||
print_entry(i, tout) << std::endl;);
|
print_entry(i, tout) << std::endl;);
|
||||||
m_sum_of_fixed[i] -= j_sign * coeff * e;
|
m_sum_of_fixed[i] -= j_sign * coeff * e;
|
||||||
m_e_matrix.pivot_row_to_row_given_cell_with_sign(ei, c, j, j_sign);
|
m_e_matrix.pivot_row_to_row_given_cell_with_sign(ei, c, j, j_sign);
|
||||||
//m_sum_of_fixed[i].m_l -= j_sign * coeff * e.m_l;
|
// m_sum_of_fixed[i].m_l -= j_sign * coeff * e.m_l;
|
||||||
m_l_matrix.add_rows( -j_sign*coeff, ei, i);
|
m_l_matrix.add_rows(-j_sign * coeff, ei, i);
|
||||||
TRACE("dioph_eq", tout << "after pivoting c_row:";
|
TRACE("dioph_eq", tout << "after pivoting c_row:";
|
||||||
print_entry(i, tout););
|
print_entry(i, tout););
|
||||||
CTRACE(
|
CTRACE(
|
||||||
|
@ -2114,7 +2079,7 @@ namespace lp {
|
||||||
bool is_eliminated_from_f(unsigned j) const {
|
bool is_eliminated_from_f(unsigned j) const {
|
||||||
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++) {
|
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++) {
|
||||||
if (!belongs_to_f(ei)) continue;
|
if (!belongs_to_f(ei)) continue;
|
||||||
const auto &row = m_e_matrix.m_rows[ei];
|
const auto& row = m_e_matrix.m_rows[ei];
|
||||||
for (const auto& p : row) {
|
for (const auto& p : row) {
|
||||||
if (p.var() == j) {
|
if (p.var() == j) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2145,7 +2110,7 @@ namespace lp {
|
||||||
get_sign_in_e_row(ei, j);
|
get_sign_in_e_row(ei, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &p: m_e_matrix.m_rows[ei]) {
|
for (const auto& p : m_e_matrix.m_rows[ei]) {
|
||||||
if (!p.coeff().is_int()) {
|
if (!p.coeff().is_int()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2155,20 +2120,20 @@ namespace lp {
|
||||||
term_to_lar_solver(remove_fresh_vars(get_term_from_entry(ei))) ==
|
term_to_lar_solver(remove_fresh_vars(get_term_from_entry(ei))) ==
|
||||||
fix_vars(open_ml(m_l_matrix.m_rows[ei]));
|
fix_vars(open_ml(m_l_matrix.m_rows[ei]));
|
||||||
|
|
||||||
CTRACE( "dioph_deb_eq", !ret,
|
CTRACE("dioph_deb_eq", !ret,
|
||||||
{
|
{
|
||||||
tout << "get_term_from_entry(" << ei << "):";
|
tout << "get_term_from_entry(" << ei << "):";
|
||||||
print_term_o(get_term_from_entry(ei), tout) << std::endl;
|
print_term_o(get_term_from_entry(ei), tout) << std::endl;
|
||||||
tout << "ls:";
|
tout << "ls:";
|
||||||
print_term_o(remove_fresh_vars(get_term_from_entry(ei)), tout)
|
print_term_o(remove_fresh_vars(get_term_from_entry(ei)), tout)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
tout << "e.m_l:"; print_lar_term_L(l_term_from_row(ei), tout) << std::endl;
|
tout << "e.m_l:";
|
||||||
|
print_lar_term_L(l_term_from_row(ei), tout) << std::endl;
|
||||||
tout << "open_ml(e.m_l):";
|
tout << "open_ml(e.m_l):";
|
||||||
print_lar_term_L(open_ml(l_term_from_row(ei)), tout) << std::endl;
|
print_lar_term_L(open_ml(l_term_from_row(ei)), tout) << std::endl;
|
||||||
tout << "rs:";
|
tout << "rs:";
|
||||||
print_term_o(fix_vars(open_ml(m_l_matrix.m_rows[ei])), tout) << std::endl;
|
print_term_o(fix_vars(open_ml(m_l_matrix.m_rows[ei])), tout) << std::endl;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2183,7 +2148,7 @@ namespace lp {
|
||||||
}
|
}
|
||||||
while (!q.empty()) {
|
while (!q.empty()) {
|
||||||
unsigned xt = q.pop_front(); // xt is a fresh var
|
unsigned xt = q.pop_front(); // xt is a fresh var
|
||||||
const lar_term& fresh_t = m_fresh_k2xt_terms.get_by_val(xt);
|
const lar_term& fresh_t = m_fresh_k2xt_terms.get_by_val(xt).first;
|
||||||
TRACE("dioph_eq", print_lar_term_L(fresh_t, tout););
|
TRACE("dioph_eq", print_lar_term_L(fresh_t, tout););
|
||||||
SASSERT(fresh_t.get_coeff(xt).is_minus_one());
|
SASSERT(fresh_t.get_coeff(xt).is_minus_one());
|
||||||
if (!t.contains(xt))
|
if (!t.contains(xt))
|
||||||
|
@ -2196,7 +2161,6 @@ namespace lp {
|
||||||
q.push(p.j());
|
q.push(p.j());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -2206,7 +2170,8 @@ namespace lp {
|
||||||
return print_lar_term_L(opened_ml, out);
|
return print_lar_term_L(opened_ml, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> term_o open_ml(const T& ml) const {
|
template <typename T>
|
||||||
|
term_o open_ml(const T& ml) const {
|
||||||
term_o r;
|
term_o r;
|
||||||
for (const auto& p : ml) {
|
for (const auto& p : ml) {
|
||||||
r += p.coeff() * (lra.get_term(p.var()) - lar_term(p.var()));
|
r += p.coeff() * (lra.get_term(p.var()) - lar_term(p.var()));
|
||||||
|
@ -2216,11 +2181,11 @@ namespace lp {
|
||||||
|
|
||||||
void open_l_term_to_work_vector(unsigned ei, mpq& c) {
|
void open_l_term_to_work_vector(unsigned ei, mpq& c) {
|
||||||
m_substitution_workspace.clear();
|
m_substitution_workspace.clear();
|
||||||
for (const auto & p: m_l_matrix.m_rows[ei]) {
|
for (const auto& p : m_l_matrix.m_rows[ei]) {
|
||||||
const lar_term& t = lra.get_term(p.var());
|
const lar_term& t = lra.get_term(p.var());
|
||||||
for (const auto & q: t.ext_coeffs()) {
|
for (const auto& q : t.ext_coeffs()) {
|
||||||
if (is_fixed(q.var())) {
|
if (is_fixed(q.var())) {
|
||||||
c += p.coeff()*q.coeff()*lia.lower_bound(q.var()).x;
|
c += p.coeff() * q.coeff() * lia.lower_bound(q.var()).x;
|
||||||
} else {
|
} else {
|
||||||
m_substitution_workspace.add(p.coeff() * q.coeff(), q.var());
|
m_substitution_workspace.add(p.coeff() * q.coeff(), q.var());
|
||||||
}
|
}
|
||||||
|
@ -2268,7 +2233,7 @@ namespace lp {
|
||||||
fresh_t.add_monomial(-mpq(1), xt);
|
fresh_t.add_monomial(-mpq(1), xt);
|
||||||
fresh_t.add_monomial(mpq(1), k);
|
fresh_t.add_monomial(mpq(1), k);
|
||||||
for (const auto& i : m_e_matrix.m_rows[h]) {
|
for (const auto& i : m_e_matrix.m_rows[h]) {
|
||||||
const mpq &ai = i.coeff();
|
const mpq& ai = i.coeff();
|
||||||
if (i.var() == k)
|
if (i.var() == k)
|
||||||
continue;
|
continue;
|
||||||
q = machine_div_rem(ai, ahk, r);
|
q = machine_div_rem(ai, ahk, r);
|
||||||
|
@ -2276,7 +2241,7 @@ namespace lp {
|
||||||
fresh_t.add_monomial(q, i.var());
|
fresh_t.add_monomial(q, i.var());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fresh_k2xt_terms.add(k, xt, fresh_t);
|
m_fresh_k2xt_terms.add(k, xt, std::make_pair(fresh_t, h));
|
||||||
SASSERT(var_is_fresh(xt));
|
SASSERT(var_is_fresh(xt));
|
||||||
register_var_in_fresh_defs(h, xt);
|
register_var_in_fresh_defs(h, xt);
|
||||||
eliminate_var_in_f_with_term(fresh_t, k, 1);
|
eliminate_var_in_f_with_term(fresh_t, k, 1);
|
||||||
|
@ -2297,8 +2262,9 @@ namespace lp {
|
||||||
print_deps(out, explain_fixed_in_meta_term(l_term));
|
print_deps(out, explain_fixed_in_meta_term(l_term));
|
||||||
out << "}\n";
|
out << "}\n";
|
||||||
}
|
}
|
||||||
if (belongs_to_f(i)) { out << "in F\n"; }
|
if (belongs_to_f(i)) {
|
||||||
else {
|
out << "in F\n";
|
||||||
|
} else {
|
||||||
unsigned j = m_k2s.get_key(i);
|
unsigned j = m_k2s.get_key(i);
|
||||||
if (local_to_lar_solver(j) == UINT_MAX) {
|
if (local_to_lar_solver(j) == UINT_MAX) {
|
||||||
out << "FRESH\n";
|
out << "FRESH\n";
|
||||||
|
@ -2332,7 +2298,7 @@ namespace lp {
|
||||||
mpq the_smallest_ahk;
|
mpq the_smallest_ahk;
|
||||||
unsigned kh;
|
unsigned kh;
|
||||||
int kh_sign;
|
int kh_sign;
|
||||||
for (unsigned ei=0; ei < m_e_matrix.row_count(); ei++) {
|
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++) {
|
||||||
if (belongs_to_s(ei)) continue;
|
if (belongs_to_s(ei)) continue;
|
||||||
if (m_e_matrix.m_rows[ei].size() == 0) {
|
if (m_e_matrix.m_rows[ei].size() == 0) {
|
||||||
if (m_sum_of_fixed[ei].is_zero()) {
|
if (m_sum_of_fixed[ei].is_zero()) {
|
||||||
|
@ -2355,7 +2321,7 @@ namespace lp {
|
||||||
m_conflict_index = ei;
|
m_conflict_index = ei;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!gcd.is_one()){
|
if (!gcd.is_one()) {
|
||||||
ahk /= gcd;
|
ahk /= gcd;
|
||||||
if (ahk.is_one()) {
|
if (ahk.is_one()) {
|
||||||
TRACE("dioph_eq", tout << "push to S:\n"; print_entry(ei, tout););
|
TRACE("dioph_eq", tout << "push to S:\n"; print_entry(ei, tout););
|
||||||
|
@ -2408,7 +2374,6 @@ namespace lp {
|
||||||
SASSERT(!ret || m_var_register.local_to_external(j) == UINT_MAX);
|
SASSERT(!ret || m_var_register.local_to_external(j) == UINT_MAX);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
// Constructor definition
|
// Constructor definition
|
||||||
dioph_eq::dioph_eq(int_solver& lia) {
|
dioph_eq::dioph_eq(int_solver& lia) {
|
||||||
|
@ -2427,4 +2392,3 @@ namespace lp {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lp
|
} // namespace lp
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue