|
18 | 18 | lar_term is just a sum of monomials |
19 | 19 | -- entry : has a dependency lar_term, keeping the history of the entry |
20 | 20 | updates, the rational constant of the corresponding term_o, and the entry |
21 | | - status that is in {F,S, NO_S_NO_F}. The entry status is used for efficiency |
| 21 | + status that is in {F,S, FRESH}. The entry status is used for efficiency |
22 | 22 | reasons. It allows quickly check if an entry belongs to F, S, or neither. |
23 | 23 | dioph_eq::imp main fields are |
24 | 24 | -- lra: pointer to lar_solver. |
@@ -204,7 +204,7 @@ namespace lp { |
204 | 204 | // |
205 | 205 | enum class entry_status { F, |
206 | 206 | S, |
207 | | - NO_S_NO_F |
| 207 | + FRESH |
208 | 208 | }; |
209 | 209 | struct entry { |
210 | 210 | //lar_term m_l; the term is taken from matrix m_l_matrix of the index entry |
@@ -600,6 +600,7 @@ namespace lp { |
600 | 600 | m_l_matrix.multiply_row(ei, denom); |
601 | 601 | m_e_matrix.multiply_row(ei, denom); |
602 | 602 | } |
| 603 | + move_entry_from_s_to_f(ei); |
603 | 604 | SASSERT(entry_invariant(ei)); |
604 | 605 | } |
605 | 606 |
|
@@ -680,8 +681,7 @@ namespace lp { |
680 | 681 | for(unsigned k : entries_to_recalculate) { |
681 | 682 | if (k >= m_entries.size()) |
682 | 683 | continue;; |
683 | | - recalculate_entry(k); |
684 | | - move_entry_from_s_to_f(k); |
| 684 | + recalculate_entry(k); |
685 | 685 | if (m_e_matrix.m_columns.back().size() == 0) { |
686 | 686 | m_e_matrix.m_columns.pop_back(); |
687 | 687 | m_var_register.shrink(m_e_matrix.column_count()); |
@@ -747,18 +747,26 @@ namespace lp { |
747 | 747 | } |
748 | 748 | else it++; |
749 | 749 | } |
| 750 | + |
750 | 751 | for (unsigned k = 0; k < m_k2s.size(); k++) { |
751 | 752 | if (m_k2s[k] != UINT_MAX && contains(entries_to_recalculate, m_k2s[k])) { |
752 | 753 | m_k2s[k] = -1; |
753 | 754 | } |
754 | 755 | } |
| 756 | + |
755 | 757 | for (unsigned ei: entries_to_recalculate) { |
756 | 758 | SASSERT(std::find(m_f.begin(), m_f.end(), ei) == m_f.end()); |
| 759 | + SASSERT(!is_substituted(ei)); |
757 | 760 | m_f.push_back(ei); |
758 | 761 | m_entries[ei].m_entry_status = entry_status::F; |
759 | 762 | } |
760 | 763 | } |
761 | 764 |
|
| 765 | + // returns true if a variable j is substituted |
| 766 | + bool is_substituted(unsigned j) const { |
| 767 | + return std::find(m_k2s.begin(), m_k2s.end(), j) != m_k2s.end(); |
| 768 | + } |
| 769 | + |
762 | 770 | bool entries_are_ok() { |
763 | 771 | for (unsigned ei = 0; ei < m_entries.size(); ei++) { |
764 | 772 | if (entry_invariant(ei) == false) { |
@@ -903,7 +911,7 @@ namespace lp { |
903 | 911 | if (m_indexed_work_vector[k].is_zero()) |
904 | 912 | return; |
905 | 913 | const entry& e = entry_for_subs(k); |
906 | | - SASSERT(e.m_entry_status == entry_status::S); |
| 914 | + SASSERT(e.m_entry_status != entry_status::F); |
907 | 915 | TRACE("dioph_eq", tout << "k:" << k << ", in "; |
908 | 916 | print_term_o(create_term_from_ind_c(), tout) << std::endl; |
909 | 917 | tout << "subs with e:"; |
@@ -1721,6 +1729,12 @@ namespace lp { |
1721 | 1729 | } |
1722 | 1730 |
|
1723 | 1731 | bool entry_invariant(unsigned ei) const { |
| 1732 | + const auto & e= m_entries[ei]; |
| 1733 | + if ((e.m_entry_status == entry_status::F && is_substituted(ei)) || |
| 1734 | + (e.m_entry_status != entry_status::F && !is_substituted(ei))) |
| 1735 | + return false; |
| 1736 | + |
| 1737 | + |
1724 | 1738 | for (const auto &p: m_e_matrix.m_rows[ei]) { |
1725 | 1739 | if (!p.coeff().is_int()) { |
1726 | 1740 | return false; |
@@ -1842,7 +1856,7 @@ namespace lp { |
1842 | 1856 | e.m_c = r; |
1843 | 1857 | m_e_matrix.add_new_element(h, xt, ahk); |
1844 | 1858 |
|
1845 | | - m_entries.push_back({q, entry_status::NO_S_NO_F}); |
| 1859 | + m_entries.push_back({q, entry_status::FRESH}); |
1846 | 1860 | m_e_matrix.add_new_element(fresh_row, xt, -mpq(1)); |
1847 | 1861 | m_e_matrix.add_new_element(fresh_row, k, mpq(1)); |
1848 | 1862 | for (unsigned i : m_indexed_work_vector.m_index) { |
|
0 commit comments