|
26 | 26 | -- m_fresh_k2xt_terms: when a fresh definitions is created for a variable k in row s then the triple |
27 | 27 | (k,xt,(t,s)) is added to m_fresh_k2xt_terms, where xt is the fresh variable, and t it the term defining the substitution: something like k - xt + 5z + 6y = 0. |
28 | 28 | The set of pairs (k, xt) is a one to one mapping |
29 | | - m_row2fresh_defs[i]: is the list of all xt that were defined for row m_e_matrix[i]. |
| 29 | + m_row2fresh_defs[i]: is the list of all fresh xt that were defined for row m_e_matrix[i]. |
30 | 30 | Invariant: Every xt in m_row2fresh[i] must have a corresponding entry in m_fresh_k2xt_terms |
31 | 31 |
|
32 | 32 | The mapping between the columns of lar_solver and m_e_matrix is controlled by m_var_register. |
@@ -733,12 +733,20 @@ namespace lp { |
733 | 733 | eliminate_last_term_column(); |
734 | 734 | remove_last_row_in_matrix(m_l_matrix); |
735 | 735 | remove_last_row_in_matrix(m_e_matrix); |
736 | | - while (m_l_matrix.column_count() && m_l_matrix.m_columns.back().size() == 0) { |
| 736 | + // Recalculate rows that still reference fresh vars defined by the removed row. |
| 737 | + auto it = m_row2fresh_defs.find(i); |
| 738 | + if (it != m_row2fresh_defs.end()) |
| 739 | + for (unsigned xt : it->second) |
| 740 | + if (xt < m_e_matrix.column_count()) |
| 741 | + for (const auto& p : m_e_matrix.m_columns[xt]) |
| 742 | + m_changed_rows.insert(p.var()); |
| 743 | + |
| 744 | + while (m_l_matrix.column_count() && m_l_matrix.m_columns.back().size() == 0) |
737 | 745 | m_l_matrix.m_columns.pop_back(); |
738 | | - } |
739 | | - while (m_e_matrix.column_count() && m_e_matrix.m_columns.back().size() == 0) { |
| 746 | + |
| 747 | + while (m_e_matrix.column_count() && m_e_matrix.m_columns.back().size() == 0) |
740 | 748 | m_e_matrix.m_columns.pop_back(); |
741 | | - } |
| 749 | + |
742 | 750 | m_var_register.shrink(m_e_matrix.column_count()); |
743 | 751 |
|
744 | 752 | remove_irrelevant_fresh_defs_for_row(i); |
|
0 commit comments