3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

fix merge

This commit is contained in:
Jakob Rath 2022-07-01 17:16:40 +02:00
parent e5e79c1d4b
commit 003896991d
6 changed files with 129 additions and 141 deletions

View file

@ -18,6 +18,7 @@ Author:
#include "math/polysat/interval.h"
#include "math/polysat/search_state.h"
#include "math/polysat/univariate/univariate_solver.h"
#include <iostream>
namespace polysat {

View file

@ -226,7 +226,7 @@ namespace polysat {
numeral base_coeff = 0;
numeral value = 0;
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
if (v == base_var)
base_coeff = e.coeff();
@ -281,11 +281,13 @@ namespace polysat {
row r = base2row(v);
numeral b = row2base_coeff(r);
unsigned tz_b = m.trailing_zeros(b);
for (auto col : M.col_entries(v)) {
if (r.id() == col.get_row().id())
auto col_it = M.col_begin(v);
auto const col_end = M.col_end(v);
for (; col_it != col_end; ++col_it) {
if (r.id() == col_it.get_row().id())
continue;
numeral value_v = value(v);
if (!eliminate_var(r, col, tz_b, value_v))
if (!eliminate_var(r, col_it, tz_b, value_v))
return false;
}
return true;
@ -315,12 +317,12 @@ namespace polysat {
else {
unsigned tz = UINT_MAX;
numeral coeff;
for (auto c : M.col_entries(var)) {
unsigned tzc = m.trailing_zeros(c.get_row_entry().coeff());
for (auto [r2, r2_entry] : M.get_col(var)) {
unsigned tzc = m.trailing_zeros(r2_entry->coeff());
if (tzc < tz) {
r = c.get_row();
r = r2;
tz = tzc;
coeff = c.get_row_entry().coeff();
coeff = r2_entry->coeff();
if (tz == 0)
break;
}
@ -362,11 +364,10 @@ namespace polysat {
// R.value += delta*v_coeff
// s.value = - R.value / s_coeff
//
for (auto c : M.col_entries(v)) {
row r = c.get_row();
for (auto [r, r_entry] : M.get_col(v)) {
row_info& ri = m_rows[r.id()];
var_t s = ri.m_base;
ri.m_value += delta * c.get_row_entry().coeff();
ri.m_value += delta * r_entry->coeff();
set_base_value(s);
add_patch(s);
}
@ -432,7 +433,7 @@ namespace polysat {
numeral delta_best = 0;
bool best_in_bounds = false;
for (auto const& r : M.row_entries(r)) {
for (auto const& r : M.get_row(r)) {
var_t y = r.var();
numeral const& b = r.coeff();
if (x == y)
@ -497,7 +498,7 @@ namespace polysat {
unsigned max = get_num_vars();
var_t result = max;
row r = base2row(x);
for (auto const& c : M.col_entries(r)) {
for (auto const& c : M.get_col(r)) {
var_t y = c.var();
if (x == y || y >= result)
continue;
@ -710,8 +711,8 @@ namespace polysat {
unsigned tz1 = m.trailing_zeros(b);
if (tz1 == 0)
return true;
for (auto col : M.col_entries(y)) {
numeral c = col.get_row_entry().coeff();
for (auto [_, r_entry] : M.get_col(y)) {
numeral c = r_entry->coeff();
unsigned tz2 = m.trailing_zeros(c);
if (tz1 > tz2)
return false;
@ -739,7 +740,7 @@ namespace polysat {
SASSERT(is_base(x));
auto r = base2row(x);
mod_interval<numeral> range(0, 1);
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
numeral const& c = e.coeff();
range += m_vars[v] * c;
@ -767,7 +768,7 @@ namespace polysat {
return false;
numeral fixed = 0;
unsigned parity = UINT_MAX;
for (auto const& e : M.row_entries(row(r))) {
for (auto const& e : M.get_row(row(r))) {
var_t v = e.var();
auto c = e.coeff();
if (is_fixed(v))
@ -841,13 +842,15 @@ namespace polysat {
unsigned tz_b = m.trailing_zeros(b);
for (auto const& col : M.col_entries(y)) {
row r_z = col.get_row();
auto col_it = M.col_begin(y);
auto const col_end = M.col_end(y);
for (; col_it != col_end; ++col_it) {
auto r_z = col_it.get_row();
unsigned rz = r_z.id();
if (rz == rx)
continue;
TRACE("fixplex", display_row(tout << "eliminate ", r_z, false) << "\n";);
VERIFY(eliminate_var(r_x, col, tz_b, old_value_y));
VERIFY(eliminate_var(r_x, col_it, tz_b, old_value_y));
TRACE("fixplex", display_row(tout << "eliminated ", r_z, false) << "\n";);
add_patch(row2base(r_z));
}
@ -904,7 +907,7 @@ namespace polysat {
SASSERT(is_base(v));
auto row = base2row(v);
ptr_vector<u_dependency> todo;
for (auto const& e : M.row_entries(row)) {
for (auto const& e : M.get_row(row)) {
var_t v = e.var();
todo.push_back(m_vars[v].m_lo_dep);
todo.push_back(m_vars[v].m_hi_dep);
@ -926,8 +929,8 @@ namespace polysat {
template<typename Ext>
int fixplex<Ext>::get_num_non_free_dep_vars(var_t x_j, int best_so_far) {
int result = is_non_free(x_j);
for (auto const& col : M.col_entries(x_j)) {
var_t s = row2base(col.get_row());
for (auto [r, _] : M.get_col(x_j)) {
var_t s = row2base(r);
result += is_non_free(s);
if (result > best_so_far)
return result;
@ -1104,7 +1107,7 @@ namespace polysat {
y = null_var;
if (!row_is_integral(r))
return false;
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
if (is_fixed(v))
continue;
@ -1130,8 +1133,7 @@ namespace polysat {
return;
var_t z, u;
numeral cz, cu;
for (auto c : M.col_entries(x)) {
auto r2 = c.get_row();
for (auto [r2, _] : M.get_col(x)) {
if (r1.id() == r2.id())
continue;
if (!is_offset_row(r2, cz, z, cu, u))
@ -1299,7 +1301,7 @@ namespace polysat {
mod_interval<numeral> range(0, 1);
numeral free_c = 0;
var_t free_v = null_var;
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
numeral const& c = e.coeff();
if (is_free(v)) {
@ -1320,7 +1322,7 @@ namespace polysat {
SASSERT(in_bounds(free_v));
return res;
}
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
SASSERT(!is_free(v));
auto range1 = range - m_vars[v] * e.coeff();
@ -1406,7 +1408,7 @@ namespace polysat {
template<typename Ext>
u_dependency* fixplex<Ext>::row2dep(row const& r) {
u_dependency* d = nullptr;
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
d = m_deps.mk_join(m_vars[v].m_lo_dep, d);
d = m_deps.mk_join(m_vars[v].m_hi_dep, d);
@ -1461,7 +1463,7 @@ namespace polysat {
template<typename Ext>
std::ostream& fixplex<Ext>::display_row(std::ostream& out, row const& r, bool values) const {
out << r.id() << " := " << pp(row2value(r)) << " : ";
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
var_t v = e.var();
if (e.coeff() != 1)
out << pp(e.coeff()) << " * ";
@ -1502,7 +1504,7 @@ namespace polysat {
VERIFY(m_vars[s].m_is_base);
numeral sum = 0;
numeral base_coeff = row2base_coeff(r);
for (auto const& e : M.row_entries(r)) {
for (auto const& e : M.get_row(r)) {
sum += value(e.var()) * e.coeff();
SASSERT(s != e.var() || base_coeff == e.coeff());
}

View file

@ -76,13 +76,13 @@ namespace simplex {
scoped_eps_numeral value(em), tmp(em);
row_iterator it = M.row_begin(r), end = M.row_end(r);
for (; it != end; ++it) {
var_t v = it->var();
var_t v = it->m_var;
if (v == base_var) {
m.set(base_coeff, it->coeff());
m.set(base_coeff, it->m_coeff);
}
else {
SASSERT(!is_base(v));
em.mul(m_vars[v].m_value, it->coeff(), tmp);
em.mul(m_vars[v].m_value, it->m_coeff, tmp);
em.add(value, tmp, value);
}
}
@ -97,8 +97,8 @@ namespace simplex {
bool first = true;
for (; it2 != end; ++it2) {
if (!first) tout << " + ";
tout << "v" << it2->var() << " * ";
m.display(tout, it2->coeff()); tout << " ";
tout << "v" << it2->m_var << " * ";
m.display(tout, it2->m_coeff); tout << " ";
first = false;
}
tout << "\n";
@ -176,7 +176,7 @@ namespace simplex {
new_value = vi.m_value;
}
// need to move var such that old_base comes in bound.
update_and_pivot(old_base, var, re.coeff(), new_value);
update_and_pivot(old_base, var, re.m_coeff, new_value);
SASSERT(is_base(var));
SASSERT(m_vars[var].m_base2row == r.id());
SASSERT(!below_lower(old_base) && !above_upper(old_base));
@ -285,10 +285,10 @@ namespace simplex {
void simplex<Ext>::display_row(std::ostream& out, row const& r, bool values) {
row_iterator it = M.row_begin(r), end = M.row_end(r);
for (; it != end; ++it) {
m.display(out, it->coeff());
out << "*v" << it->var() << " ";
m.display(out, it->m_coeff);
out << "*v" << it->m_var << " ";
if (values) {
var_info const& vi = m_vars[it->var()];
var_info const& vi = m_vars[it->m_var];
out << em.to_string(vi.m_value);
out << " [";
if (vi.m_lower_valid) out << em.to_string(vi.m_lower); else out << "-oo";
@ -405,7 +405,7 @@ namespace simplex {
for (; it != end; ++it) {
row r_k = it.get_row();
if (r_k.id() != r_i) {
a_kj = it.get_row_entry().coeff();
a_kj = it.get_row_entry().m_coeff;
a_kj.neg();
M.mul(r_k, a_ij);
M.add(r_k, a_kj, row(r_i));
@ -439,7 +439,7 @@ namespace simplex {
var_t s = m_row2base[r.id()];
var_info& si = m_vars[s];
scoped_eps_numeral delta2(em);
numeral const& coeff = it.get_row_entry().coeff();
numeral const& coeff = it.get_row_entry().m_coeff;
em.mul(delta, coeff, delta2);
em.div(delta2, si.m_base_coeff, delta2);
delta2.neg();
@ -555,9 +555,9 @@ namespace simplex {
row_iterator it = M.row_begin(r), end = M.row_end(r);
for (; it != end; ++it) {
var_t x_j = it->var();
var_t x_j = it->m_var;
if (x_i == x_j) continue;
numeral const & a_ij = it->coeff();
numeral const & a_ij = it->m_coeff;
bool is_neg = is_below ? m.is_neg(a_ij) : m.is_pos(a_ij);
bool is_pos = !is_neg;
@ -618,8 +618,8 @@ namespace simplex {
row r(m_vars[x_i].m_base2row);
row_iterator it = M.row_begin(r), end = M.row_end(r);
for (; it != end; ++it) {
var_t x_j = it->var();
numeral const & a_ij = it->coeff();
var_t x_j = it->m_var;
numeral const & a_ij = it->m_coeff;
bool is_neg = is_below ? m.is_neg(a_ij) : m.is_pos(a_ij);
if (x_i != x_j && ((!is_neg && above_lower(x_j)) || (is_neg && below_upper(x_j)))) {
SASSERT(!is_base(x_j));
@ -749,7 +749,7 @@ namespace simplex {
//
var_t s = m_row2base[it.get_row().id()];
var_info& vs = m_vars[s];
numeral const& coeff = it.get_row_entry().coeff();
numeral const& coeff = it.get_row_entry().m_coeff;
numeral const& base_coeff = vs.m_base_coeff;
SASSERT(!m.is_zero(coeff));
bool base_to_lower = (m.is_pos(coeff) != m.is_pos(base_coeff)) == to_lower;
@ -801,9 +801,9 @@ namespace simplex {
bool inc_y = false;
for (; it != end; ++it) {
var_t x = it->var();
var_t x = it->m_var;
if (x == v) continue;
bool inc_x = m.is_pos(it->coeff()) == m.is_pos(m_vars[v].m_base_coeff);
bool inc_x = m.is_pos(it->m_coeff) == m.is_pos(m_vars[v].m_base_coeff);
if ((inc_x && at_upper(x)) || (!inc_x && at_lower(x))) {
TRACE("simplex", tout << "v" << x << " pos: " << inc_x
<< " at upper: " << at_upper(x)
@ -867,7 +867,7 @@ namespace simplex {
row r = it.get_row();
var_t s = m_row2base[r.id()];
var_info& vi = m_vars[s];
numeral const& a_ij = it.get_row_entry().coeff();
numeral const& a_ij = it.get_row_entry().m_coeff;
numeral const& a_ii = vi.m_base_coeff;
bool sign_eq = (m.is_pos(a_ii) == m.is_pos(a_ij));
bool inc_s = sign_eq != inc_x_j;
@ -1013,9 +1013,9 @@ namespace simplex {
row_iterator it = M.row_begin(r), end = M.row_end(r);
scoped_eps_numeral sum(em), tmp(em);
for (; it != end; ++it) {
em.mul(m_vars[it->var()].m_value, it->coeff(), tmp);
em.mul(m_vars[it->m_var].m_value, it->m_coeff, tmp);
sum += tmp;
SASSERT(s != it->var() || m.eq(m_vars[s].m_base_coeff, it->coeff()));
SASSERT(s != it->m_var || m.eq(m_vars[s].m_base_coeff, it->m_coeff));
}
if (!em.is_zero(sum)) {
IF_VERBOSE(0, M.display_row(verbose_stream(), r););

View file

@ -32,19 +32,15 @@ namespace simplex {
typedef typename Ext::manager manager;
typedef unsigned var_t;
class row_entry {
friend class sparse_matrix;
struct row_entry {
numeral m_coeff;
var_t m_var;
public:
row_entry(numeral && c, var_t v) : m_coeff(std::move(c)), m_var(v) {}
inline numeral const& coeff() const { return m_coeff; }
inline var_t var() const { return m_var; }
};
private:
struct column;
struct stats {
unsigned m_add_rows;
@ -69,7 +65,7 @@ namespace simplex {
};
_row_entry(numeral && c, var_t v) : row_entry(std::move(c), v), m_col_idx(0) {}
_row_entry() : row_entry(numeral(), dead_id), m_col_idx(0) {}
bool is_dead() const { return row_entry::var() == dead_id; }
bool is_dead() const { return row_entry::m_var == dead_id; }
};
/**
@ -87,7 +83,8 @@ namespace simplex {
col_entry(): m_row_id(0), m_row_idx(0) {}
bool is_dead() const { return (unsigned) m_row_id == dead_id; }
};
struct column;
/**
\brief A row contains a base variable and set of
@ -111,31 +108,29 @@ namespace simplex {
int get_idx_of(var_t v) const;
};
/**
\brief A column stores in which rows a variable occurs.
The column may have free/dead entries. The field m_first_free_idx
is a reference to the first free/dead entry.
\brief A column stores in which rows a variable occurs.
The column may have free/dead entries. The field m_first_free_idx
is a reference to the first free/dead entry.
*/
struct column {
svector<col_entry> m_entries;
unsigned m_size;
unsigned m_size;
int m_first_free_idx;
mutable unsigned m_refs;
column() :m_size(0), m_first_free_idx(-1), m_refs(0) {}
column():m_size(0), m_first_free_idx(-1), m_refs(0) {}
unsigned size() const { return m_size; }
unsigned num_entries() const { return m_entries.size(); }
void reset();
void compress(vector<_row>& rows);
void compress_if_needed(vector<_row>& rows);
void compress(vector<_row> & rows);
void compress_if_needed(vector<_row> & rows);
//void compress_singleton(vector<_row> & rows, unsigned singleton_pos);
col_entry const* get_first_col_entry() const;
col_entry& add_col_entry(int& pos_idx);
col_entry const * get_first_col_entry() const;
col_entry & add_col_entry(int & pos_idx);
void del_col_entry(unsigned idx);
};
manager& m;
vector<_row> m_rows;
svector<unsigned> m_dead_rows; // rows to recycle
@ -209,17 +204,17 @@ namespace simplex {
row_iterator row_begin(row const& r) { return row_iterator(m_rows[r.id()], true); }
row_iterator row_end(row const& r) { return row_iterator(m_rows[r.id()], false); }
class row_vars {
class row_entries_t {
friend class sparse_matrix;
sparse_matrix& s;
row r;
row_vars(sparse_matrix& s, row r): s(s), r(r) {}
row_entries_t(sparse_matrix& s, row r): s(s), r(r) {}
public:
row_iterator begin() { return s.row_begin(r); }
row_iterator end() { return s.row_end(r); }
};
row_vars get_row(row r) { return row_vars(*this, r); }
row_entries_t get_row(row r) { return row_entries_t(*this, r); }
unsigned column_size(var_t v) const { return m_columns[v].size(); }
@ -232,53 +227,57 @@ namespace simplex {
column const& m_col;
vector<_row>& m_rows;
void move_to_used() {
while (m_curr < col().num_entries() && col().m_entries[m_curr].is_dead()) {
while (m_curr < m_col.num_entries() && m_col.m_entries[m_curr].is_dead()) {
++m_curr;
}
}
col_iterator(column const& c, vector<_row>& r, bool begin):
m_curr(0), m_col(c), m_rows(r) {
++m_col.m_refs;
if (begin)
if (begin) {
move_to_used();
else
}
else {
m_curr = m_col.num_entries();
}
}
public:
~col_iterator() {
--col().m_refs;
}
col_iterator(col_iterator const& other):
m_curr(other.m_curr),
m_var(other.m_var),
m_sm(other.m_sm) {
++m_col.m_refs;
--m_col.m_refs;
}
row get_row() const {
return row(m_col.m_entries[m_curr].m_row_id);
return row(m_col.m_entries[m_curr].m_row_id);
}
row_entry& get_row_entry() {
row_entry& get_row_entry() const {
col_entry const& c = m_col.m_entries[m_curr];
int row_id = c.m_row_id;
return m_sm.m_rows[row_id].m_entries[c.m_row_idx];
return m_rows[row_id].m_entries[c.m_row_idx];
}
std::pair<row, row_entry*> operator*() { return std::make_pair(get_row(), &get_row_entry()); }
col_iterator & operator++() { ++m_curr; move_to_used(); return *this; }
col_iterator operator++(int) { col_iterator tmp = *this; ++*this; return tmp; }
bool operator==(col_iterator const & it) const { return m_curr == it.m_curr; }
bool operator!=(col_iterator const & it) const { return m_curr != it.m_curr; }
col_iterator& operator*() { return *this; }
bool operator!=(col_iterator const & it) const { return m_curr != it.m_curr; }
};
col_iterator col_begin(int v) { return col_iterator(m_columns[v], m_rows, true); }
col_iterator col_end(int v) { return col_iterator(m_columns[v], m_rows, false); }
class col_entries_t {
friend class sparse_matrix;
sparse_matrix& m;
int v;
col_entries_t(sparse_matrix& m, int v): m(m), v(v) {}
public:
col_iterator begin() { return m.col_begin(v); }
col_iterator end() { return m.col_end(v); }
};
col_entries_t get_col(int v) { return col_entries_t(*this, v); }
class var_rows {
friend class sparse_matrix;
sparse_matrix& s;
@ -330,9 +329,10 @@ namespace simplex {
return row.m_coeff;
return m_zero;
}
void display(std::ostream& out);
void display_row(std::ostream& out, row const& r) const;
void display_row(std::ostream& out, row const& r);
bool well_formed() const;
manager& get_manager() { return m; }
@ -357,4 +357,4 @@ namespace simplex {
typedef unsynch_mpq_inf_manager eps_manager;
};
}
};

View file

@ -99,10 +99,10 @@ namespace simplex {
if (i != j) {
_row_entry & t2 = m_entries[j];
m.swap(t2.m_coeff, t1.m_coeff);
t2.m_var = t1.var();
t2.m_var = t1.m_var;
t2.m_col_idx = t1.m_col_idx;
SASSERT(!t2.is_dead());
column & col = cols[t2.var()];
column & col = cols[t2.m_var];
col.m_entries[t2.m_col_idx].m_row_idx = j;
}
j++;
@ -138,8 +138,8 @@ namespace simplex {
unsigned idx = 0;
for (auto const& e : m_entries) {
if (!e.is_dead()) {
result_map[e.var()] = idx;
idxs.push_back(e.var());
result_map[e.m_var] = idx;
idxs.push_back(e.m_var);
}
++idx;
}
@ -150,7 +150,7 @@ namespace simplex {
int sparse_matrix<Ext>::_row::get_idx_of(var_t v) const {
unsigned idx = 0;
for (auto const& e : m_entries) {
if (!e.is_dead() && e.var() == v)
if (!e.is_dead() && e.m_var == v)
return idx;
++idx;
}
@ -199,8 +199,9 @@ namespace simplex {
*/
template<typename Ext>
inline void sparse_matrix<Ext>::column::compress_if_needed(vector<_row> & rows) {
if (size() * 2 < num_entries() && m_refs == 0)
if (size() * 2 < num_entries() && m_refs == 0) {
compress(rows);
}
}
template<typename Ext>
@ -344,10 +345,6 @@ namespace simplex {
r_entry.m_var = v; \
m.set(r_entry.m_coeff, it->m_coeff); \
_SET_COEFF_; \
if (m.is_zero(r_entry.m_coeff)) { \
r1.del_row_entry(row_idx); \
continue; \
} \
column & c = m_columns[v]; \
int col_idx; \
col_entry & c_entry = c.add_col_entry(col_idx); \
@ -358,7 +355,7 @@ namespace simplex {
else { \
/* variable v is in row1 */ \
_row_entry & r_entry = r1.m_entries[pos]; \
SASSERT(r_entry.var() == v); \
SASSERT(r_entry.m_var == v); \
_ADD_COEFF_; \
if (m.is_zero(r_entry.m_coeff)) { \
del_row_entry(r1, pos); \
@ -394,11 +391,11 @@ namespace simplex {
template<typename Ext>
void sparse_matrix<Ext>::del_row_entry(_row& r, unsigned pos) {
_row_entry & r_entry = r.m_entries[pos];
var_t v = r_entry.var();
var_t v = r_entry.m_var;
int col_idx = r_entry.m_col_idx;
r.del_row_entry(pos);
column & c = m_columns[v];
c.del_col_entry(col_idx);
c.del_col_entry(col_idx);
c.compress_if_needed(m_rows);
}
@ -407,8 +404,11 @@ namespace simplex {
*/
template<typename Ext>
void sparse_matrix<Ext>::neg(row r) {
for (auto& r : row_entries(r))
m.neg(r.m_coeff);
row_iterator it = row_begin(r);
row_iterator end = row_end(r);
for (; it != end; ++it) {
m.neg(it->m_coeff);
}
}
/**
@ -424,25 +424,11 @@ namespace simplex {
neg(r);
}
else {
bool has0 = false;
row_iterator it = row_begin(r);
row_iterator end = row_end(r);
for (; it != end; ++it) {
m.mul(it->m_coeff, n, it->m_coeff);
has0 |= m.is_zero(it->m_coeff);
}
if (has0) {
unsigned idx = 0;
unsigned_vector idxs;
_row& row = m_rows[r.id()];
for (auto const& e : row.m_entries) {
if (!e.is_dead() && m.is_zero(e.m_coeff))
idxs.push_back(idx);
++idx;
}
for (unsigned idx : idxs)
del_row_entry(row, idx);
}
}
}
}
@ -471,12 +457,12 @@ namespace simplex {
g.reset();
row_iterator it = row_begin(r), end = row_end(r);
for (; it != end && !m.is_one(g); ++it) {
if (!m.is_int(it->coeff())) {
if (!m.is_int(it->m_coeff)) {
g = numeral(1);
break;
}
if (m.is_zero(g)) g = it->m_coeff;
else m.gcd(g, it->coeff(), g);
else m.gcd(g, it->m_coeff, g);
}
if (m.is_zero(g)) {
g = numeral(1);
@ -515,15 +501,15 @@ namespace simplex {
if (e.is_dead()) {
dead.insert(i);
continue;
}
}
DEBUG_CODE(
SASSERT(!vars.contains(e.var()));
SASSERT(!vars.contains(e.m_var));
SASSERT(!m.is_zero(e.m_coeff));
SASSERT(e.var() != dead_id);
col_entry const& c = m_columns[e.var()].m_entries[e.m_col_idx];
SASSERT(e.m_var != dead_id);
col_entry const& c = m_columns[e.m_var].m_entries[e.m_col_idx];
SASSERT((unsigned)c.m_row_id == row_id);
SASSERT((unsigned)c.m_row_idx == i););
vars.insert(e.var());
vars.insert(e.m_var);
}
int idx = r.m_first_free_idx;
while (idx != -1) {
@ -552,7 +538,7 @@ namespace simplex {
DEBUG_CODE(
_row const& row = m_rows[c.m_row_id];
_row_entry const& r = row.m_entries[c.m_row_idx];
SASSERT(r.var() == v);
SASSERT(r.m_var == v);
SASSERT((unsigned)r.m_col_idx == i););
rows.insert(c.m_row_id);
}
@ -581,18 +567,17 @@ namespace simplex {
template<typename Ext>
void sparse_matrix<Ext>::display(std::ostream& out) {
for (unsigned i = 0; i < m_rows.size(); ++i) {
if (m_rows[i].size() != 0)
display_row(out, row(i));
if (m_rows[i].size() == 0) continue;
display_row(out, row(i));
}
}
template<typename Ext>
void sparse_matrix<Ext>::display_row(std::ostream& out, row const& r) const {
for (auto const& e : m_rows[r.id()].m_entries) {
if (!e.is_dead()) {
m.display(out, e.coeff());
out << "*v" << e.var() << " ";
}
void sparse_matrix<Ext>::display_row(std::ostream& out, row const& r) {
row_iterator it = row_begin(r), end = row_end(r);
for (; it != end; ++it) {
m.display(out, it->m_coeff);
out << "*v" << it->m_var << " ";
}
out << "\n";
}