Skip to content

Commit 1131d52

Browse files
committed
fix a bug in tracking the changes in dio
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent d289495 commit 1131d52

File tree

1 file changed

+51
-51
lines changed

1 file changed

+51
-51
lines changed

src/math/lp/dioph_eq.cpp

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -783,18 +783,20 @@ namespace lp {
783783
std_vector<variable_branch_stats> m_branch_stats;
784784
std_vector<branch> m_branch_stack;
785785
std_vector<constraint_index> m_explanation_of_branches;
786-
bool term_has_big_number(const lar_term& t) const {
786+
// it is a non-const function : it can set m_some_terms_are_ignored to true
787+
bool term_has_big_number(const lar_term& t) {
787788
for (const auto& p : t) {
788-
if (p.coeff().is_big())
789-
return true;
790-
if (is_fixed(p.var()) && lra.get_lower_bound(p.var()).x.is_big())
789+
if (abs(p.coeff()) > mpq(5) || p.coeff().is_big() || (is_fixed(p.var()) && lra.get_lower_bound(p.var()).x.is_big())) {
790+
m_some_terms_are_ignored = true;
791791
return true;
792+
}
792793
}
793794
return false;
794795
}
795796

796797
bool ignore_big_nums() const { return lra.settings().dio_ignore_big_nums(); }
797-
798+
799+
// we add all terms, even those with big numbers, but we might choose to non process the latter.
798800
void add_term_callback(const lar_term* t) {
799801
unsigned j = t->j();
800802
TRACE("dio", tout << "term column t->j():" << j << std::endl; lra.print_term(*t, tout) << std::endl;);
@@ -803,14 +805,7 @@ namespace lp {
803805
m_some_terms_are_ignored = true;
804806
return;
805807
}
806-
807808
CTRACE("dio", !lra.column_has_term(j), tout << "added term that is not associated with a column yet" << std::endl;);
808-
809-
if (ignore_big_nums() && term_has_big_number(*t)) {
810-
TRACE("dio", tout << "term_has_big_number\n";);
811-
m_some_terms_are_ignored = true;
812-
return;
813-
}
814809
m_added_terms.push_back(t);
815810
mark_term_change(t->j());
816811
auto undo = undo_add_term(*this, t);
@@ -825,13 +820,10 @@ namespace lp {
825820
void update_column_bound_callback(unsigned j) {
826821
if (!lra.column_is_int(j))
827822
return;
828-
if (lra.column_has_term(j) &&
829-
ignore_big_nums() && !term_has_big_number(lra.get_term(j)))
823+
if (lra.column_has_term(j))
830824
m_terms_to_tighten.insert(j); // the boundary of the term has changed: we can be successful to tighten this term
831825
if (!lra.column_is_fixed(j))
832826
return;
833-
if (ignore_big_nums() && lra.get_lower_bound(j).x.is_big())
834-
return;
835827
TRACE("dio", tout << "j:" << j << "\n"; lra.print_column_info(j, tout););
836828
m_changed_f_columns.insert(j);
837829
lra.trail().push(undo_fixed_column(*this, j));
@@ -861,7 +853,7 @@ namespace lp {
861853
}
862854

863855
void register_columns_to_term(const lar_term& t) {
864-
TRACE("dio_reg", tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
856+
CTRACE("dio_reg", t.j() == 1337, tout << "register term:"; lra.print_term(t, tout); tout << ", t.j()=" << t.j() << std::endl;);
865857
for (const auto& p : t.ext_coeffs()) {
866858
auto it = m_columns_to_terms.find(p.var());
867859
TRACE("dio_reg", tout << "register p.var():" << p.var() << "->" << t.j() << std::endl;);
@@ -1062,20 +1054,28 @@ namespace lp {
10621054
}
10631055
}
10641056

1065-
void process_changed_columns(std_vector<unsigned> &f_vector) {
1057+
// this is a non-const function - it can set m_some_terms_are_ignored to true
1058+
bool is_big_term_or_no_term(unsigned j) {
1059+
return
1060+
j >= lra.column_count()
1061+
||
1062+
!lra.column_has_term(j)
1063+
||
1064+
(ignore_big_nums() && term_has_big_number(lra.get_term(j)));
1065+
}
1066+
1067+
// Processes columns that have changed due to variables becoming fixed/unfixed or terms being updated.
1068+
// It identifies affected terms and rows, recalculates entries, removes irrelevant fresh definitions,
1069+
// and ensures substituted variables are properly eliminated from changed F entries, m_e_matrix.
1070+
// The function maintains internal consistency of data structures after these updates.
1071+
void process_m_changed_f_columns(std_vector<unsigned> &f_vector) {
10661072
find_changed_terms_and_more_changed_rows();
10671073
for (unsigned j: m_changed_terms) {
1068-
if (j >= lra.column_count() ||
1069-
!lra.column_has_term(j) ||
1070-
(ignore_big_nums() && term_has_big_number(lra.get_term(j)))
1071-
)
1072-
continue;
1073-
m_terms_to_tighten.insert(j);
1074-
if (j < m_l_matrix.column_count()) {
1075-
for (const auto& cs : m_l_matrix.column(j)) {
1076-
m_changed_rows.insert(cs.var());
1077-
}
1078-
}
1074+
if (!is_big_term_or_no_term(j))
1075+
m_terms_to_tighten.insert(j);
1076+
if (j < m_l_matrix.column_count())
1077+
for (const auto& cs : m_l_matrix.column(j))
1078+
m_changed_rows.insert(cs.var());
10791079
}
10801080

10811081
// find more entries to recalculate
@@ -1085,39 +1085,34 @@ namespace lp {
10851085
if (it == m_row2fresh_defs.end()) continue;
10861086
for (unsigned xt : it->second) {
10871087
SASSERT(var_is_fresh(xt));
1088-
for (const auto& p : m_e_matrix.m_columns[xt]) {
1088+
for (const auto& p : m_e_matrix.m_columns[xt])
10891089
more_changed_rows.push_back(p.var());
1090-
}
10911090
}
10921091
}
10931092

1094-
for (unsigned ei : more_changed_rows) {
1093+
for (unsigned ei : more_changed_rows)
10951094
m_changed_rows.insert(ei);
1096-
}
1097-
1095+
10981096
for (unsigned ei : m_changed_rows) {
10991097
if (ei >= m_e_matrix.row_count())
11001098
continue;
11011099
if (belongs_to_s(ei))
11021100
f_vector.push_back(ei);
1101+
11031102
recalculate_entry(ei);
11041103

11051104
if (m_e_matrix.m_columns.back().size() == 0) {
11061105
m_e_matrix.m_columns.pop_back();
11071106
m_var_register.shrink(m_e_matrix.column_count());
11081107
}
1109-
if (m_l_matrix.m_columns.back().size() == 0) {
1108+
if (m_l_matrix.m_columns.back().size() == 0)
11101109
m_l_matrix.m_columns.pop_back();
1111-
}
11121110
}
1113-
11141111
remove_irrelevant_fresh_defs();
1115-
11161112
eliminate_substituted_in_changed_rows();
11171113
m_changed_f_columns.reset();
11181114
m_changed_rows.reset();
11191115
m_changed_terms.reset();
1120-
SASSERT(entries_are_ok());
11211116
}
11221117

11231118
int get_sign_in_e_row(unsigned ei, unsigned j) const {
@@ -1185,7 +1180,7 @@ namespace lp {
11851180
m_lra_level = 0;
11861181
reset_conflict();
11871182

1188-
process_changed_columns(f_vector);
1183+
process_m_changed_f_columns(f_vector);
11891184
for (const lar_term* t : m_added_terms) {
11901185
m_active_terms.insert(t);
11911186
f_vector.push_back(m_e_matrix.row_count()); // going to add a row in fill_entry
@@ -1543,7 +1538,7 @@ namespace lp {
15431538
// print_bounds(tout);
15441539
);
15451540
for (unsigned j : sorted_changed_terms) {
1546-
if (ignore_big_nums() && term_has_big_number(lra.get_term(j))) {
1541+
if (is_big_term_or_no_term(j)) {
15471542
m_terms_to_tighten.remove(j);
15481543
continue;
15491544
}
@@ -1578,24 +1573,30 @@ namespace lp {
15781573
m_c = mpq(0);
15791574
m_lspace.clear();
15801575
m_lspace.add(mpq(1), lar_t.j());
1576+
bool ret = true;
15811577
SASSERT(get_extended_term_value(lar_t).is_zero());
15821578
for (const auto& p : lar_t) {
15831579
if (is_fixed(p.j())) {
15841580
const mpq& b = lia.lower_bound(p.j()).x;
1585-
if (ignore_big_nums() && b.is_big())
1586-
return false;
1581+
if (ignore_big_nums() && b.is_big()) {
1582+
ret = false;
1583+
break;
1584+
}
15871585
m_c += p.coeff() * b;
15881586
}
15891587
else {
15901588
unsigned lj = lar_solver_to_local(p.j());
1591-
SASSERT(!p.coeff().is_big());
1589+
if (ignore_big_nums() && p.coeff().is_big()) {
1590+
ret = false;
1591+
break;
1592+
}
15921593
m_espace.add(p.coeff(), lj);;
15931594
if (can_substitute(lj))
15941595
q.push(lj);
15951596
}
15961597
}
15971598
SASSERT(subs_invariant(lar_t.j()));
1598-
return true;
1599+
return ret;
15991600
}
16001601

16011602
unsigned lar_solver_to_local(unsigned j) const {
@@ -2239,8 +2240,6 @@ namespace lp {
22392240
for (unsigned k = 0; k < lra.terms().size(); k++) {
22402241
const lar_term* t = lra.terms()[k];
22412242
if (!lia.column_is_int(t->j())) continue;
2242-
if (ignore_big_nums() && term_has_big_number(*t))
2243-
continue;
22442243
SASSERT(t->j() != UINT_MAX);
22452244
for (const auto& p : (*t).ext_coeffs()) {
22462245
unsigned j = p.var();
@@ -2288,11 +2287,12 @@ namespace lp {
22882287
bool is_in_sync() const {
22892288
for (unsigned j = 0; j < m_e_matrix.column_count(); j++) {
22902289
unsigned external_j = m_var_register.local_to_external(j);
2291-
if (external_j == UINT_MAX) continue;
2292-
if (external_j >= lra.column_count() && m_e_matrix.m_columns[j].size()) {
2293-
// It is OK to have an empty column in m_e_matrix.
2290+
if (external_j == UINT_MAX)
2291+
continue;
2292+
if (external_j >= lra.column_count() && m_e_matrix.m_columns[j].size())
22942293
return false;
2295-
}
2294+
// It is OK to have an empty column in m_e_matrix.
2295+
22962296
}
22972297

22982298
for (unsigned ei = 0; ei < m_e_matrix.row_count(); ei++) {

0 commit comments

Comments
 (0)