Skip to content

Commit 5a72117

Browse files
committed
debug dio
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent 0027ae2 commit 5a72117

File tree

6 files changed

+153
-63
lines changed

6 files changed

+153
-63
lines changed

src/math/lp/dioph_eq.cpp

+145-16
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,29 @@ namespace lp {
285285
struct undo_add_term : public trail {
286286
imp& m_s;
287287
const lar_term* m_t;
288-
undo_add_term(imp& s, const lar_term *t): m_s(s), m_t(t) {
289-
TRACE("dioph_eq", m_s.print_lar_term_L(*t, tout); tout << "t->j()=" << t->j() << std::endl;);
288+
unsigned m_l_column_count;
289+
unsigned m_row_count;
290+
unsigned m_e_column_count;
291+
undo_add_term(imp& s, const lar_term *t):
292+
m_s(s),
293+
m_t(t),
294+
m_l_column_count(m_s.m_l_matrix.column_count()),
295+
m_row_count(m_s.m_l_matrix.row_count()),
296+
m_e_column_count(m_s.m_e_matrix.column_count()) {
297+
TRACE("dioph_eq", m_s.print_lar_term_L(*t, tout); tout << "t->j()=" << t->j() << std::endl;);
290298
}
291299
void undo () {
300+
SASSERT(m_s.entries_are_ok());
292301
TRACE("dioph_eq", m_s.lra.print_term(*m_t, tout); tout << ", m_t->j() =" << m_t->j() << std::endl;);
293302
if (!contains(m_s.m_active_terms, m_t)) {
294303
for (int i = m_s.m_added_terms.size() - 1; i >= 0; --i) {
295304
if (m_s.m_added_terms[i] != m_t) continue;
296305
// the address is the same
297-
if (i != m_s.m_added_terms.size() -1) m_s.m_added_terms[i] = m_s.m_added_terms.back();
306+
if (i != m_s.m_added_terms.size() -1)
307+
m_s.m_added_terms[i] = m_s.m_added_terms.back();
298308
m_s.m_added_terms.pop_back();
309+
SASSERT(m_s.m_l_matrix.row_count() == m_row_count && m_s.m_l_matrix.column_count() == m_l_column_count
310+
&& m_s.m_e_matrix.column_count() == m_e_column_count);
299311
return; // all is done since the term has not made it to entries, etc
300312
}
301313
}
@@ -307,18 +319,22 @@ namespace lp {
307319
if (it->second.size() == 0) {
308320
m_s.m_columns_to_terms.erase(it);
309321
}
310-
311322
}
323+
SASSERT(std::find(m_s.m_added_terms.begin(), m_s.m_added_terms.end(), m_t) == m_s.m_added_terms.end());
324+
SASSERT(contains(m_s.m_active_terms, m_t));
325+
m_s.m_active_terms.erase(m_t);
326+
std::cout << ++ lp_settings::ddd << std::endl;
312327
TRACE("dioph_eq",
313328
tout << "the deleted term column in m_l_matrix" << std::endl;
314329
for (auto p: m_s.m_l_matrix.column(m_t->j())) {
315-
tout << p.coeff()<< ", row " << p.var() << std::endl;
330+
tout << "p.coeff():" << p.coeff()<< ", row " << p.var() << std::endl;
316331
}
317-
tout << "m_l_matrix has " << m_s.m_l_matrix.column_count() << std::endl;
318-
tout << "and" << m_s.m_l_matrix.row_count() << " rows" << std::endl;
332+
tout << "m_l_matrix has " << m_s.m_l_matrix.column_count() << " columns"<< std::endl;
333+
tout << "and " << m_s.m_l_matrix.row_count() << " rows" << std::endl;
334+
m_s.print_lar_term_L(*m_t, tout); tout << "; m_t->j()=" << m_t->j() << std::endl;
319335
);
320-
NOT_IMPLEMENTED_YET();
321-
}
336+
m_s.shrink_L_to_size(m_row_count, m_l_column_count, m_e_column_count, m_t);
337+
}
322338
};
323339

324340

@@ -335,6 +351,105 @@ namespace lp {
335351
}
336352
};
337353

354+
355+
void remove_last_entry() {
356+
unsigned ei = m_entries.size() - 1;
357+
358+
if (m_entries.back().m_entry_status == entry_status::F) {
359+
remove_entry_index(this->m_f, ei);
360+
} else {
361+
remove_entry_index(this->m_s, ei);
362+
}
363+
}
364+
void shrink_L_to_size(unsigned row_count, unsigned l_column_count, unsigned e_column_count, const lar_term* t) {
365+
while (row_count < m_l_matrix.row_count()) {
366+
shrink_L_one_size(t);
367+
}
368+
SASSERT(entries_are_ok());
369+
SASSERT(l_column_count == m_l_matrix.column_count() && e_column_count == m_e_matrix.column_count());
370+
}
371+
372+
void remove_last_row_column_in_matrix(static_matrix<mpq, mpq>& m) {
373+
auto & last_row = m.m_rows.back();
374+
for (unsigned k = last_row.size(); k-- > 0;) {
375+
m.remove_element(last_row, last_row[k]);
376+
}
377+
SASSERT(m.m_columns.back().size() == 0);
378+
m.m_rows.pop_back();
379+
m.m_columns.pop_back();
380+
}
381+
382+
void shrink_L_one_size(const lar_term*t) {
383+
unsigned j = m_l_matrix.column_count() - 1; // the last column
384+
unsigned i = m_l_matrix.row_count() - 1; // the last row
385+
auto last_col = m_l_matrix.column(j);
386+
TRACE("dioph_eq", tout << "the last entry: i:" << i <<std::endl;
387+
print_entry(i, tout);
388+
tout << "t->j()="<< t->j() << " is mapped to " << lar_solver_to_local(t->j()) << std::endl;
389+
);
390+
SASSERT(t->j() == j);
391+
392+
bool row_i_found = false;
393+
// prepare for pivoting
394+
395+
std_vector<unsigned> entries_to_change;
396+
397+
for (const auto p : last_col ) {
398+
entries_to_change.push_back(p.var()); ;
399+
if (p.var() == i) {
400+
row_i_found = true;
401+
}
402+
}
403+
SASSERT(row_i_found);
404+
405+
for (unsigned ei : entries_to_change)
406+
move_entry_from_s_to_f(ei);
407+
408+
// find the coefficient before the term variable, k, in the last row of m_e_matrix
409+
unsigned k = lar_solver_to_local(j);
410+
auto &last_e_row = m_e_matrix.m_rows.back();
411+
mpq alpha;
412+
for (const auto p: last_e_row) {
413+
if (p.var() == k) {
414+
alpha = p.coeff();
415+
break;
416+
}
417+
}
418+
this->m_e_matrix.divide_row(i, alpha);
419+
this->m_l_matrix.divide_row(i, alpha);
420+
this->m_entries[i].m_c /= alpha;
421+
SASSERT(entry_invariant(i));
422+
eliminate_var_in_f(i, k, 1);
423+
TRACE("dioph_eq", tout << "last row before removal\n" ;
424+
print_entry(m_entries.size() -1, tout) << std::endl);
425+
remove_last_row_column_in_matrix(m_l_matrix);
426+
remove_last_row_column_in_matrix(m_e_matrix);
427+
m_entries.pop_back();
428+
remove_entry_index(m_f, i);
429+
remove_entry_index(m_s, i);
430+
auto it = std::find_if(m_fresh_definitions.begin(), m_fresh_definitions.end(), [i](auto const& fe) {
431+
return fe.m_origin == i;
432+
});
433+
if (it != m_fresh_definitions.end())
434+
m_fresh_definitions.erase(it);
435+
for (unsigned k = 0; k < m_k2s.size() ; k++) {
436+
if (m_k2s[k] == i) {
437+
m_k2s[k] = -1;
438+
}
439+
}
440+
441+
m_var_register.shrink(m_e_matrix.column_count());
442+
}
443+
444+
445+
void remove_entry_index(std::list<unsigned> & l, unsigned ei) {
446+
auto it = std::find(l.begin(), l.end(), ei);
447+
if (it != l.end())
448+
l.erase(it);
449+
}
450+
451+
452+
338453
std::unordered_set<unsigned> m_changed_columns;
339454
// m_column_to_terms[j] is the set of all k such lra.get_term(k) depends on j
340455
std::unordered_map<unsigned, std::unordered_set<unsigned>> m_columns_to_terms;
@@ -377,8 +492,8 @@ namespace lp {
377492

378493
public:
379494
imp(int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
380-
lra.register_add_term_delegate([this](const lar_term*t){add_term_delegate(t);});
381-
lra.register_update_column_bound_delegate([this](unsigned j) {update_column_bound_delegate(j);});
495+
lra.m_add_term_callback=[this](const lar_term*t){add_term_delegate(t);};
496+
lra.m_update_column_bound_callback = [this](unsigned j){update_column_bound_delegate(j);};
382497
}
383498
term_o get_term_from_entry(unsigned i) const {
384499
term_o t;
@@ -428,6 +543,7 @@ namespace lp {
428543
m_l_matrix.add_new_element(entry_index, t.j(), mpq(1));
429544
// fill E-entry
430545
m_e_matrix.add_row();
546+
431547
SASSERT(m_e_matrix.row_count() == m_entries.size());
432548

433549
for (const auto& p : t.ext_coeffs()) {
@@ -552,6 +668,7 @@ namespace lp {
552668
}
553669
}
554670
for (unsigned ei: entries_to_recalculate) {
671+
SASSERT(std::find(m_f.begin(), m_f.end(), ei) == m_f.end());
555672
m_f.push_back(ei);
556673
m_entries[ei].m_entry_status = entry_status::F;
557674
}
@@ -560,7 +677,7 @@ namespace lp {
560677
bool entries_are_ok() {
561678
for (unsigned ei = 0; ei < m_entries.size(); ei++) {
562679
if (entry_invariant(ei) == false) {
563-
TRACE("dioph_eq", tout << "bad entry:"; print_entry(ei, tout););
680+
TRACE("dioph_deb_eq", tout << "bad entry:"; print_entry(ei, tout););
564681
return false;
565682
}
566683
}
@@ -1446,10 +1563,10 @@ namespace lp {
14461563
std::ostream& print_e_row(unsigned i, std::ostream& out) {
14471564
return print_term_o(get_term_from_entry(i), out);
14481565
}
1449-
// j is the variable to eliminate, it appears in row e.m_e_matrix with
1450-
// a coefficient equal to +-1
1566+
// j is the variable to eliminate, it appears in row ei of m_e_matrix with
1567+
// a coefficient equal to j_sign which is +-1
14511568
void eliminate_var_in_f(unsigned ei, unsigned j, int j_sign) {
1452-
entry& e = m_entries[ei];
1569+
const auto & e = m_entries[ei];
14531570
TRACE("dioph_eq", tout << "eliminate var:" << j << " by using:";
14541571
print_entry(ei, tout) << std::endl;);
14551572
auto& column = m_e_matrix.m_columns[j];
@@ -1515,7 +1632,7 @@ namespace lp {
15151632
term_to_lar_solver(remove_fresh_vars(get_term_from_entry(ei))) ==
15161633
fix_vars(open_ml(m_l_matrix.m_rows[ei]));
15171634

1518-
CTRACE( "dioph_eq", !ret,
1635+
CTRACE( "dioph_deb_eq", !ret,
15191636
{
15201637
tout << "get_term_from_entry(" << ei << "):";
15211638
print_term_o(get_term_from_entry(ei), tout) << std::endl;
@@ -1687,6 +1804,18 @@ namespace lp {
16871804
return out;
16881805
}
16891806

1807+
void move_entry_from_s_to_f(unsigned ei) {
1808+
if (m_entries[ei].m_entry_status == entry_status::F) return;
1809+
m_entries[ei].m_entry_status = entry_status::F;
1810+
for (unsigned l = 0; l < m_k2s.size(); l++) {
1811+
if (m_k2s[l] == ei) {
1812+
m_k2s[l] = -1;
1813+
}
1814+
}
1815+
m_s.remove(ei);
1816+
m_f.push_back(ei);
1817+
}
1818+
16901819
// k is the index of the variable that is being substituted
16911820
void move_entry_from_f_to_s(unsigned k, unsigned h) {
16921821
SASSERT(m_entries[h].m_entry_status == entry_status::F);

src/math/lp/lar_solver.cpp

+5-12
Original file line numberDiff line numberDiff line change
@@ -1599,13 +1599,7 @@ namespace lp {
15991599
bool lar_solver::external_is_used(unsigned v) const {
16001600
return m_var_register.external_is_used(v);
16011601
}
1602-
void lar_solver::register_add_term_delegate(const std::function<void(const lar_term*)>& f) {
1603-
this->m_add_term_callbacks.push_back(f);
1604-
}
1605-
void lar_solver::register_update_column_bound_delegate(const std::function<void(unsigned)>& f) {
1606-
this->m_update_column_bound_callbacks.push_back(f);
1607-
}
1608-
1602+
16091603
void lar_solver::add_non_basic_var_to_core_fields(unsigned ext_j, bool is_int) {
16101604
register_new_external_var(ext_j, is_int);
16111605
m_mpq_lar_core_solver.m_column_types.push_back(column_type::free_column);
@@ -1702,8 +1696,8 @@ namespace lp {
17021696
lp_assert(m_var_register.size() == A_r().column_count());
17031697
if (m_need_register_terms)
17041698
register_normalized_term(*t, A_r().column_count() - 1);
1705-
for (const auto & f: m_add_term_callbacks)
1706-
f(t);
1699+
if (m_add_term_callback)
1700+
m_add_term_callback(t);
17071701
return ret;
17081702
}
17091703

@@ -1990,9 +1984,8 @@ namespace lp {
19901984

19911985

19921986
TRACE("lar_solver_feas", tout << "j = " << j << " became " << (this->column_is_feasible(j) ? "feas" : "non-feas") << ", and " << (this->column_is_bounded(j) ? "bounded" : "non-bounded") << std::endl;);
1993-
for (const auto &f: m_update_column_bound_callbacks) {
1994-
f(j);
1995-
}
1987+
if (m_update_column_bound_callback)
1988+
m_update_column_bound_callback(j);
19961989
}
19971990

19981991
void lar_solver::insert_to_columns_with_changed_bounds(unsigned j) {

src/math/lp/lar_solver.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,10 @@ class lar_solver : public column_namer {
405405
}
406406
}
407407

408-
void register_add_term_delegate(const std::function<void (const lar_term*)>&);
409-
void register_update_column_bound_delegate(const std::function<void (unsigned)>&);
410408

411-
private:
412-
std_vector<std::function<void (const lar_term*)>> m_add_term_callbacks;
413-
std_vector<std::function<void (unsigned)>> m_update_column_bound_callbacks;
414409
public:
410+
std::function<void (const lar_term*)> m_add_term_callback;
411+
std::function<void (unsigned)> m_update_column_bound_callback;
415412
bool external_is_used(unsigned) const;
416413
void pop(unsigned k);
417414
unsigned num_scopes() const { return m_trail.get_num_scopes(); }

src/math/lp/lar_term.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class lar_term {
3636
lpvar j() const { return m_j; }
3737
void set_j(unsigned j) {
3838
m_j = j;
39-
}
39+
}
4040
void add_monomial(const mpq& c, unsigned j) {
4141
if (c.is_zero())
4242
return;

src/math/lp/static_matrix.h

-4
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,6 @@ class static_matrix
149149

150150
void add_columns_up_to(unsigned j) { while (j >= column_count()) add_column(); }
151151

152-
void forget_last_columns(unsigned how_many_to_forget);
153-
154-
void remove_last_column(unsigned j);
155-
156152
void remove_element(std_vector<row_cell<T>> & row, row_cell<T> & elem_to_remove);
157153

158154
void multiply_column(unsigned column, T const & alpha) {

src/math/lp/static_matrix_def.h

-25
Original file line numberDiff line numberDiff line change
@@ -193,31 +193,6 @@ template <typename T, typename X> unsigned static_matrix<T, X>::lowest_row_in_co
193193
return ret;
194194
}
195195

196-
template <typename T, typename X> void static_matrix<T, X>::forget_last_columns(unsigned how_many_to_forget) {
197-
SASSERT(m_columns.size() >= how_many_to_forget);
198-
unsigned j = column_count() - 1;
199-
for (; how_many_to_forget-- > 0; ) {
200-
remove_last_column(j --);
201-
}
202-
}
203-
204-
template <typename T, typename X> void static_matrix<T, X>::remove_last_column(unsigned j) {
205-
column_strip & col = m_columns.back();
206-
for (auto & it : col) {
207-
auto & row = m_rows[it.var()];
208-
unsigned offset = row.size() - 1;
209-
for (auto row_it = row.rbegin(); row_it != row.rend(); row_it ++) {
210-
if (row_it.var() == j) {
211-
row.erase(row.begin() + offset);
212-
break;
213-
}
214-
offset--;
215-
}
216-
}
217-
m_columns.pop_back();
218-
m_work_vector_of_row_offsets.pop_back();
219-
}
220-
221196
template <typename T, typename X> void static_matrix<T, X>::set(unsigned row, unsigned col, T const & val) {
222197
if (numeric_traits<T>::is_zero(val)) return;
223198
SASSERT(row < row_count() && col < column_count());

0 commit comments

Comments
 (0)