6
6
#include < queue>
7
7
8
8
namespace lp {
9
+ int glb = 0 ;
9
10
// This class represents a term with an added constant number c, in form sum {x_i*a_i} + c.
10
11
class dioph_eq ::imp {
11
12
class term_o :public lar_term {
@@ -64,6 +65,13 @@ namespace lp {
64
65
}
65
66
return out;
66
67
}
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
+ }
67
75
68
76
std::ostream& print_lar_term_L (const lar_term & t, std::ostream & out) const {
69
77
return print_linear_combination_customized (t.coeffs_as_vector (),
@@ -76,8 +84,17 @@ namespace lp {
76
84
return out;
77
85
}
78
86
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) {
81
98
if (first) {
82
99
first = false ;
83
100
}
@@ -93,20 +110,25 @@ namespace lp {
93
110
else if (val != numeric_traits<mpq>::one ())
94
111
out << T_to_string (val);
95
112
out << " x" ;
96
- if (is_fresh_var (p. j () )) out << " ~" ;
97
- out << p. j () ;
113
+ if (is_fresh_var (j )) out << " ~" ;
114
+ out << j ;
98
115
}
99
116
117
+ // Handle the constant term separately
100
118
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 ());
105
126
}
106
127
107
128
return out;
108
129
}
109
130
131
+
110
132
/*
111
133
An annotated state is a triple ⟨E′, λ, σ⟩, where E′ is a set of pairs ⟨e, ℓ⟩ in which
112
134
e is an equation and ℓ is a linear combination of variables from L
@@ -166,7 +188,7 @@ namespace lp {
166
188
for (const auto & p: row) {
167
189
if (lia.is_fixed (p.var ())) {
168
190
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 ()));
170
192
}
171
193
else {
172
194
m_e_matrix.add_new_element (row_index, p.var (), lcm * p.coeff ());
@@ -211,6 +233,7 @@ namespace lp {
211
233
}
212
234
fill_eprime_entry (row, i);
213
235
TRACE (" dioph_eq" , print_eprime_entry (static_cast <unsigned >(i), tout););
236
+ // print_eprime_entry(static_cast<unsigned>(i), std::cout);
214
237
}
215
238
216
239
}
@@ -297,14 +320,12 @@ namespace lp {
297
320
!has_fresh_var (ep.m_row_index ))
298
321
prepare_lia_branch_report (ep, g, c_g);
299
322
return false ;
300
-
301
323
}
302
324
303
325
// returns true if no conflict is found and false otherwise
304
326
bool normalize_by_gcd () {
305
327
for (unsigned l: m_f) {
306
328
if (!normalize_e_by_gcd (l)) {
307
- std::cout << " dioconflict\n " ;
308
329
m_conflict_index = l;
309
330
return false ;
310
331
}
@@ -530,7 +551,9 @@ namespace lp {
530
551
// tout << "bound_dep:\n";print_dep(tout, dep) << std::endl;);
531
552
}
532
553
public:
533
- lia_move check () {
554
+ lia_move check () {
555
+ if (++glb > 10 ) exit (0 );
556
+ std::cout << " check\n " ;
534
557
init ();
535
558
while (m_f.size ()) {
536
559
if (!normalize_by_gcd ()) {
@@ -586,38 +609,27 @@ namespace lp {
586
609
// }
587
610
// }
588
611
612
+
589
613
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;
594
618
mpq t;
595
619
for (const auto & p : m_e_matrix.m_rows [row_index]) {
596
620
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
603
622
ahk = t;
604
623
k_sign = p.coeff ().is_pos () ? 1 : -1 ;
605
624
k = p.var ();
606
625
first = false ;
607
- if (ahk.is_one ())
608
- break ;
609
-
626
+ // if (ahk.is_one()) // uncomment later
627
+ // break;
610
628
}
611
629
}
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);
621
633
}
622
634
623
635
term_o get_term_to_subst (const term_o& eh, unsigned k, int k_sign) {
@@ -666,9 +678,9 @@ namespace lp {
666
678
}
667
679
SASSERT (c.var () != piv_row_index);
668
680
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) ;
672
684
m_eprime[c.var ()].m_l = lra.mk_join (m_eprime[c.var ()].m_l , m_eprime[piv_row_index].m_l );
673
685
TRACE (" dioph_eq" , tout << " after pivoting c_row:" ; print_eprime_entry (c.var (), tout););
674
686
cell_to_process--;
@@ -689,14 +701,14 @@ namespace lp {
689
701
}
690
702
// k is the variable to substitute
691
703
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;
692
705
move_row_to_work_vector (e_index);
693
706
// step 7 from the paper
694
707
// xt is the fresh variable
695
708
unsigned xt = m_e_matrix.column_count ();
696
709
unsigned fresh_row = m_e_matrix.row_count ();
697
710
m_e_matrix.add_row (); // for the fresh variable definition
698
711
m_e_matrix.add_column (); // the fresh variable itself
699
- m_eprime.push_back ({fresh_row, nullptr , mpq (0 ), entry_status::S});
700
712
// Add a new row for the fresh variable definition
701
713
/* Let eh = sum(ai*xi) + c. For each i != k, let ai = qi*ahk + ri, and let c = c_q * ahk + c_r.
702
714
eh = ahk*(x_k + sum{qi*xi|i != k} + c_q) + sum {ri*xi|i!= k} + c_r.
@@ -707,7 +719,8 @@ namespace lp {
707
719
mpq q, r;
708
720
q = machine_div_rem (e.m_c , ahk, r);
709
721
e.m_c = r;
710
- m_eprime.back ().m_c = q;
722
+ m_eprime.push_back ({fresh_row, nullptr , q, entry_status::S});
723
+
711
724
unsigned h = e.m_row_index ;
712
725
m_e_matrix.add_new_element (h, xt, ahk);
713
726
m_e_matrix.add_new_element (fresh_row, xt, -mpq (1 ));
@@ -724,10 +737,13 @@ namespace lp {
724
737
}
725
738
726
739
// 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;
729
743
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);
731
747
eliminate_var_in_f (m_eprime.back (), k, 1 );
732
748
}
733
749
@@ -738,11 +754,11 @@ namespace lp {
738
754
739
755
std::ostream& print_eprime_entry (const eprime_entry& e, std::ostream& out, bool print_dep = true ) {
740
756
out << " {\n " ;
741
- print_term_o (get_term_from_e_matrix (e.m_row_index ), out << " \t row :" ) << " \n " ;
742
- out << " \t status:" << (int )e.m_entry_status ;
757
+ print_term_o (get_term_from_e_matrix (e.m_row_index ), out << " \t m_e :" ) << " , \n " ;
758
+ // out << "\tstatus:" << (int)e.m_entry_status;
743
759
if (print_dep)
744
- this ->print_dep (out<< " \n\t dep :" , e.m_l );
745
- out << " \n } " ;
760
+ this ->print_dep (out<< " \t m_l :" , e.m_l ) << " \n " ;
761
+ out << " } \n " ;
746
762
return out;
747
763
}
748
764
@@ -764,14 +780,19 @@ namespace lp {
764
780
auto eh_it = pick_eh ();
765
781
auto & eprime_entry = m_eprime[*eh_it];
766
782
TRACE (" dioph_eq" , print_eprime_entry (*eh_it, tout););
783
+ std::cout << " rewrite_eqs\n " ; print_eprime_entry (*eh_it, std::cout);
767
784
auto [ahk, k, k_sign] = find_minimal_abs_coeff (eprime_entry.m_row_index );
768
785
TRACE (" dioph_eq" , tout << " ahk:" << ahk << " , k:" << k << " , k_sign:" << k_sign << std::endl;);
769
786
if (ahk.is_one ()) {
770
787
TRACE (" dioph_eq" , tout << " push to S:\n " ; print_eprime_entry (*eh_it, tout););
771
788
move_entry_from_f_to_s (k, eh_it);
772
789
eliminate_var_in_f (eprime_entry, k , k_sign);
790
+ print_F (std::cout);
791
+ print_S (std::cout);
773
792
} 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);
775
796
}
776
797
}
777
798
public:
0 commit comments