Skip to content

Commit 66f8820

Browse files
committed
bug fixes with tableau
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
1 parent 62ea6fb commit 66f8820

File tree

1 file changed

+68
-47
lines changed

1 file changed

+68
-47
lines changed

src/math/lp/dioph_eq.cpp

+68-47
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <queue>
77

88
namespace lp {
9+
int glb = 0;
910
// This class represents a term with an added constant number c, in form sum {x_i*a_i} + c.
1011
class dioph_eq::imp {
1112
class term_o:public lar_term {
@@ -64,6 +65,13 @@ namespace lp {
6465
}
6566
return out;
6667
}
68+
std::ostream& print_F(std::ostream & out) {
69+
out << "F:\n";
70+
for (unsigned i : m_f) {
71+
print_eprime_entry(i, out);
72+
}
73+
return out;
74+
}
6775

6876
std::ostream& print_lar_term_L(const lar_term & t, std::ostream & out) const {
6977
return print_linear_combination_customized(t.coeffs_as_vector(),
@@ -76,8 +84,17 @@ namespace lp {
7684
return out;
7785
}
7886
bool first = true;
79-
for (const auto p : term) {
80-
mpq val = p.coeff();
87+
// Copy term to a vector and sort by p.j()
88+
std::vector<std::pair<mpq, unsigned>> sorted_term;
89+
sorted_term.reserve(term.size());
90+
for (const auto& p : term) {
91+
sorted_term.emplace_back(p.coeff(), p.j());
92+
}
93+
std::sort(sorted_term.begin(), sorted_term.end(),
94+
[](const auto& a, const auto& b) { return a.second < b.second; });
95+
96+
// Print the sorted term
97+
for (auto& [val, j] : sorted_term) {
8198
if (first) {
8299
first = false;
83100
}
@@ -93,20 +110,25 @@ namespace lp {
93110
else if (val != numeric_traits<mpq>::one())
94111
out << T_to_string(val);
95112
out << "x";
96-
if (is_fresh_var(p.j())) out << "~";
97-
out << p.j();
113+
if (is_fresh_var(j)) out << "~";
114+
out << j;
98115
}
99116

117+
// Handle the constant term separately
100118
if (!term.c().is_zero()) {
101-
if (term.c().is_pos())
102-
out << " + " << term.c();
103-
else
104-
out << " - " << -term.c();
119+
if (!first) {
120+
if (term.c().is_pos())
121+
out << " + ";
122+
else
123+
out << " - ";
124+
}
125+
out << abs(term.c());
105126
}
106127

107128
return out;
108129
}
109130

131+
110132
/*
111133
An annotated state is a triple ⟨E′, λ, σ⟩, where E′ is a set of pairs ⟨e, ℓ⟩ in which
112134
e is an equation and ℓ is a linear combination of variables from L
@@ -166,7 +188,7 @@ namespace lp {
166188
for (const auto & p: row) {
167189
if (lia.is_fixed(p.var())) {
168190
c += p.coeff()*lia.lower_bound(p.var()).x;
169-
e.m_l = lra.mk_join(lra.get_bound_constraint_witnesses_for_column(p.var()), e.m_l);
191+
e.m_l = lra.mk_join(e.m_l, lra.get_bound_constraint_witnesses_for_column(p.var()));
170192
}
171193
else {
172194
m_e_matrix.add_new_element(row_index, p.var(), lcm * p.coeff());
@@ -211,6 +233,7 @@ namespace lp {
211233
}
212234
fill_eprime_entry(row, i);
213235
TRACE("dioph_eq", print_eprime_entry(static_cast<unsigned>(i), tout););
236+
// print_eprime_entry(static_cast<unsigned>(i), std::cout);
214237
}
215238

216239
}
@@ -297,14 +320,12 @@ namespace lp {
297320
!has_fresh_var(ep.m_row_index))
298321
prepare_lia_branch_report(ep, g, c_g);
299322
return false;
300-
301323
}
302324

303325
// returns true if no conflict is found and false otherwise
304326
bool normalize_by_gcd() {
305327
for (unsigned l: m_f) {
306328
if (!normalize_e_by_gcd(l)) {
307-
std::cout << "dioconflict\n";
308329
m_conflict_index = l;
309330
return false;
310331
}
@@ -530,7 +551,9 @@ namespace lp {
530551
// tout << "bound_dep:\n";print_dep(tout, dep) << std::endl;);
531552
}
532553
public:
533-
lia_move check() {
554+
lia_move check() {
555+
if (++glb > 10) exit(0);
556+
std::cout << "check\n";
534557
init();
535558
while(m_f.size()) {
536559
if (!normalize_by_gcd()) {
@@ -586,38 +609,27 @@ namespace lp {
586609
// }
587610
// }
588611

612+
589613
std::tuple<mpq, unsigned, int> find_minimal_abs_coeff(unsigned row_index) const {
590-
bool first = true, first_fresh = true;
591-
mpq ahk, ahk_fresh;
592-
unsigned k, k_fresh;
593-
int k_sign, k_sign_fresh;
614+
bool first = true;
615+
mpq ahk;
616+
unsigned k;
617+
int k_sign;
594618
mpq t;
595619
for (const auto& p : m_e_matrix.m_rows[row_index]) {
596620
t = abs(p.coeff());
597-
if (first_fresh || t < ahk_fresh) {
598-
ahk_fresh = t;
599-
k_sign_fresh = p.coeff().is_pos() ? 1 : -1;
600-
k_fresh = p.var();
601-
first_fresh = false;
602-
} else if (first || t < ahk) {
621+
if (first || t < ahk || (t == ahk && p.var() < k)) { // tre last condition is for debug
603622
ahk = t;
604623
k_sign = p.coeff().is_pos() ? 1 : -1;
605624
k = p.var();
606625
first = false;
607-
if (ahk.is_one())
608-
break;
609-
626+
// if (ahk.is_one()) // uncomment later
627+
// break;
610628
}
611629
}
612-
if (first_fresh) // did not find any fresh variables
613-
return std::make_tuple(ahk, k, k_sign);
614-
if (first) // only fresh vars
615-
return std::make_tuple(ahk_fresh, k_fresh, k_sign_fresh);
616-
SASSERT(!first && !first_fresh);
617-
if (ahk <= ahk_fresh) {
618-
return std::make_tuple(ahk, k, k_sign);
619-
}
620-
return std::make_tuple(ahk_fresh, k_fresh, k_sign_fresh);
630+
631+
std::cout << "find_minimal_abs_coeff:" << " ahk:" << ahk <<", k:" << k << ", k_sign:" << k_sign << std::endl;
632+
return std::make_tuple(ahk, k, k_sign);
621633
}
622634

623635
term_o get_term_to_subst(const term_o& eh, unsigned k, int k_sign) {
@@ -666,9 +678,9 @@ namespace lp {
666678
}
667679
SASSERT(c.var() != piv_row_index);
668680
mpq coeff = m_e_matrix.get_val(c);
669-
TRACE("dioph_eq", tout << "c_row:" << c.var(); print_e_row(c.var(), tout) << std::endl;);
670-
m_e_matrix.pivot_row_to_row_given_cell_with_sign(piv_row_index, c, j, j_sign);
671-
m_eprime[c.var()].m_c -= j_sign* coeff*m_eprime[piv_row_index].m_c;
681+
TRACE("dioph_eq", tout << "m_e:" << c.var(); print_e_row(c.var(), tout) << std::endl;);
682+
m_eprime[c.var()].m_c -= j_sign * coeff*m_eprime[piv_row_index].m_c;
683+
m_e_matrix.pivot_row_to_row_given_cell_with_sign(piv_row_index, c, j, -j_sign);
672684
m_eprime[c.var()].m_l = lra.mk_join(m_eprime[c.var()].m_l, m_eprime[piv_row_index].m_l);
673685
TRACE("dioph_eq", tout << "after pivoting c_row:"; print_eprime_entry(c.var(), tout););
674686
cell_to_process--;
@@ -689,14 +701,14 @@ namespace lp {
689701
}
690702
// k is the variable to substitute
691703
void fresh_var_step(unsigned e_index, unsigned k, const mpq& ahk) {
704+
std::cout << "fresh_var_step:" << "e_index:" << e_index << " k:" << k << std::endl;
692705
move_row_to_work_vector(e_index);
693706
// step 7 from the paper
694707
// xt is the fresh variable
695708
unsigned xt = m_e_matrix.column_count();
696709
unsigned fresh_row = m_e_matrix.row_count();
697710
m_e_matrix.add_row(); // for the fresh variable definition
698711
m_e_matrix.add_column(); // the fresh variable itself
699-
m_eprime.push_back({fresh_row, nullptr, mpq(0), entry_status::S});
700712
// Add a new row for the fresh variable definition
701713
/* Let eh = sum(ai*xi) + c. For each i != k, let ai = qi*ahk + ri, and let c = c_q * ahk + c_r.
702714
eh = ahk*(x_k + sum{qi*xi|i != k} + c_q) + sum {ri*xi|i!= k} + c_r.
@@ -707,7 +719,8 @@ namespace lp {
707719
mpq q, r;
708720
q = machine_div_rem(e.m_c, ahk, r);
709721
e.m_c = r;
710-
m_eprime.back().m_c = q;
722+
m_eprime.push_back({fresh_row, nullptr, q, entry_status::S});
723+
711724
unsigned h = e.m_row_index;
712725
m_e_matrix.add_new_element(h, xt, ahk);
713726
m_e_matrix.add_new_element(fresh_row, xt, -mpq(1));
@@ -724,10 +737,13 @@ namespace lp {
724737
}
725738

726739
// add entry to S
727-
m_eprime.push_back({fresh_row, nullptr, mpq(0), entry_status::S});
728-
this->m_s.push_back(fresh_row);
740+
unsigned last_in_s = m_eprime.size() - 1;
741+
m_s.push_back(last_in_s);
742+
m_k2s[k] = last_in_s;
729743
TRACE("dioph_eq", tout << "changed entry:"; print_eprime_entry(e_index, tout)<< std::endl;
730-
tout << "added to S:\n"; print_eprime_entry(m_eprime.size()-1, tout););
744+
tout << "added to S:\n"; print_eprime_entry(last_in_s, tout););
745+
std::cout << "changed entry:"; print_eprime_entry(e_index, std::cout)<< std::endl;
746+
std::cout << "added to S:\n"; print_eprime_entry(last_in_s, std::cout);
731747
eliminate_var_in_f(m_eprime.back(), k, 1);
732748
}
733749

@@ -738,11 +754,11 @@ namespace lp {
738754

739755
std::ostream& print_eprime_entry(const eprime_entry& e, std::ostream& out, bool print_dep = true) {
740756
out << "{\n";
741-
print_term_o(get_term_from_e_matrix(e.m_row_index), out << "\trow:") << "\n";
742-
out << "\tstatus:" << (int)e.m_entry_status;
757+
print_term_o(get_term_from_e_matrix(e.m_row_index), out << "\tm_e:") << ",\n";
758+
//out << "\tstatus:" << (int)e.m_entry_status;
743759
if (print_dep)
744-
this->print_dep(out<< "\n\tdep:", e.m_l);
745-
out << "\n}";
760+
this->print_dep(out<< "\tm_l:", e.m_l) << "\n";
761+
out << "}\n";
746762
return out;
747763
}
748764

@@ -764,14 +780,19 @@ namespace lp {
764780
auto eh_it = pick_eh();
765781
auto& eprime_entry = m_eprime[*eh_it];
766782
TRACE("dioph_eq", print_eprime_entry(*eh_it, tout););
783+
std::cout << "rewrite_eqs\n"; print_eprime_entry(*eh_it, std::cout);
767784
auto [ahk, k, k_sign] = find_minimal_abs_coeff(eprime_entry.m_row_index);
768785
TRACE("dioph_eq", tout << "ahk:" << ahk << ", k:" << k << ", k_sign:" << k_sign << std::endl;);
769786
if (ahk.is_one()) {
770787
TRACE("dioph_eq", tout << "push to S:\n"; print_eprime_entry(*eh_it, tout););
771788
move_entry_from_f_to_s(k, eh_it);
772789
eliminate_var_in_f(eprime_entry, k , k_sign);
790+
print_F(std::cout);
791+
print_S(std::cout);
773792
} else {
774-
fresh_var_step(*eh_it, k, ahk);
793+
fresh_var_step(*eh_it, k, ahk*mpq(k_sign));
794+
print_F(std::cout);
795+
print_S(std::cout);
775796
}
776797
}
777798
public:

0 commit comments

Comments
 (0)