@@ -125,7 +125,7 @@ namespace lp {
125
125
m_c += t.c ();
126
126
return *this ;
127
127
}
128
- };
128
+ };
129
129
130
130
std::ostream& print_S (std::ostream& out) {
131
131
out << " S:\n " ;
@@ -204,7 +204,7 @@ namespace lp {
204
204
NO_S_NO_F
205
205
};
206
206
struct entry {
207
- lar_term m_l;
207
+ // lar_term m_l; the term is taken from matrix m_l_matrix of the index entry
208
208
mpq m_c; // the constant of the term, the term is taken from the row of
209
209
// m_e_matrix with the same index as the entry
210
210
entry_status m_entry_status;
@@ -214,6 +214,7 @@ namespace lp {
214
214
std_vector<entry> m_entries;
215
215
// the terms are stored in m_A and m_c
216
216
static_matrix<mpq, mpq> m_e_matrix; // the rows of the matrix are the terms,
217
+ static_matrix<mpq, mpq> m_l_matrix; // the rows of the matrix are the l_terms : providing the certificate to the entries
217
218
// without the constant part
218
219
int_solver& lia;
219
220
lar_solver& lra;
@@ -234,12 +235,12 @@ namespace lp {
234
235
// {coeff*lar.get_term(k)})
235
236
236
237
std_vector<unsigned > m_k2s;
237
- std_vector<unsigned > m_fresh_definitions; // seems only needed in the debug
238
- // version in remove_fresh_vars
238
+ std_vector<unsigned > m_fresh_definitions;
239
239
240
240
unsigned m_conflict_index = -1 ; // m_entries[m_conflict_index] gives the conflict
241
241
unsigned m_max_number_of_iterations = 100 ;
242
242
unsigned m_number_of_iterations;
243
+ std_vector<std::unordered_set<unsigned >> m_columns_to_entries; // m_columnn_to_terms[j] is the set of of all k such that m_entry[k].m_l depends on j
243
244
struct branch {
244
245
unsigned m_j = UINT_MAX;
245
246
mpq m_rs;
@@ -277,12 +278,57 @@ namespace lp {
277
278
}
278
279
};
279
280
281
+ struct undo_add_term : public trail {
282
+ imp& m_s;
283
+ lar_term m_t ;
284
+ undo_add_term (imp& s, const lar_term &t): m_s(s), m_t (t) {
285
+
286
+ }
287
+ void undo () {
288
+ NOT_IMPLEMENTED_YET ();
289
+ }
290
+ };
291
+
292
+
293
+ struct undo_add_column_bound : public trail {
294
+ imp& m_s;
295
+ unsigned m_j; // the column that has been added
296
+ undo_add_column_bound (imp& s, unsigned j) : m_s(s), m_j(j) {}
297
+
298
+ void undo () override {
299
+ NOT_IMPLEMENTED_YET ();
300
+ }
301
+ };
302
+
303
+ std_vector<const lar_term*> m_added_terms;
304
+
280
305
std_vector<variable_branch_stats> m_branch_stats;
281
306
std_vector<branch> m_branch_stack;
282
307
std_vector<constraint_index> m_explanation_of_branches;
308
+ void add_term_delegate (const lar_term* t) {
309
+ unsigned j = t->j ();
310
+ if (!lra.column_is_int (j) || !lra.column_has_term (j))
311
+ return ;
312
+ if (!all_vars_are_int (*t)) {
313
+ TRACE (" dioph_eq" , tout << " not all vars are integrall\n " ;);
314
+ return ;
315
+ }
316
+ m_added_terms.push_back (t);
317
+ auto undo = undo_add_term (*this , *t);
318
+ lra.trail ().push (undo);
319
+ }
320
+
321
+ void add_column_bound_delegate (unsigned j) {
322
+ if (!lra.column_is_int (j))
323
+ return ;
324
+ auto undo = undo_add_column_bound (*this , j);
325
+ lra.trail ().push (undo) ;
326
+ }
283
327
284
328
public:
285
- imp (int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {}
329
+ imp (int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
330
+ lra.register_add_term_delegate ([this ](const lar_term*t){add_term_delegate (t);});
331
+ }
286
332
term_o get_term_from_entry (unsigned i) const {
287
333
term_o t;
288
334
for (const auto & p : m_e_matrix.m_rows [i]) {
@@ -304,11 +350,16 @@ namespace lp {
304
350
// the term has form sum(a_i*x_i) - t.j() = 0,
305
351
void fill_entry (const lar_term& t) {
306
352
TRACE (" dioph_eq" , print_lar_term_L (t, tout) << std::endl;);
307
- entry te = {lar_term (t. j ()), mpq (0 ), entry_status::F};
353
+ entry te = { mpq (0 ), entry_status::F};
308
354
unsigned entry_index = (unsigned ) m_entries.size ();
309
355
m_f.push_back (entry_index);
310
356
m_entries.push_back (te);
311
357
entry& e = m_entries.back ();
358
+ SASSERT (m_l_matrix.row_count () == m_e_matrix.row_count ());
359
+ // fill m_l_matrix row
360
+ m_l_matrix.add_row ();
361
+ m_l_matrix.add_new_element (entry_index, t.j (), mpq (1 ));
362
+ // fill E-entry
312
363
m_e_matrix.add_row ();
313
364
SASSERT (m_e_matrix.row_count () == m_entries.size ());
314
365
@@ -356,6 +407,11 @@ namespace lp {
356
407
m_number_of_iterations = 0 ;
357
408
m_branch_stack.clear ();
358
409
m_lra_level = 0 ;
410
+ for (const lar_term* t: m_added_terms) {
411
+ fill_entry (*t);
412
+ }
413
+ m_added_terms.clear ();
414
+ /*
359
415
for (unsigned j = 0; j < lra.column_count(); j++) {
360
416
if (!lra.column_is_int(j) || !lra.column_has_term(j))
361
417
continue;
@@ -365,7 +421,7 @@ namespace lp {
365
421
continue;
366
422
}
367
423
fill_entry(t);
368
- }
424
+ }*/
369
425
}
370
426
371
427
template <typename K>
@@ -437,7 +493,11 @@ namespace lp {
437
493
p.coeff () /= g;
438
494
}
439
495
m_entries[ei].m_c = c_g;
440
- e.m_l *= (1 / g);
496
+ // e.m_l *= (1 / g);
497
+ for (auto & p : m_l_matrix.m_rows [ei]) {
498
+ p.coeff () /= g;
499
+ }
500
+
441
501
TRACE (" dioph_eq" , tout << " ep_m_e:" ;
442
502
print_entry (ei, tout) << std::endl;);
443
503
SASSERT (entry_invariant (ei));
@@ -511,13 +571,22 @@ namespace lp {
511
571
q.push (j);
512
572
}
513
573
m_c += coeff * e.m_c ;
514
- m_tmp_l += coeff * e.m_l ;
574
+
575
+ m_tmp_l += coeff * l_term_from_row (k); // improve later
515
576
TRACE (" dioph_eq" , tout << " after subs k:" << k << " \n " ;
516
577
print_term_o (create_term_from_ind_c (), tout) << std::endl;
517
578
tout << " m_tmp_l:{" ; print_lar_term_L (m_tmp_l, tout);
518
579
tout << " }, opened:" ; print_ml (m_tmp_l, tout) << std::endl;);
519
580
}
520
581
582
+ lar_term l_term_from_row (unsigned k) const {
583
+ lar_term ret;
584
+ for (const auto & p: m_l_matrix.m_rows [k])
585
+ ret.add_monomial (p.coeff (), p.var ());
586
+
587
+ return ret;
588
+ }
589
+
521
590
term_o create_term_from_l (const lar_term& l) {
522
591
term_o ret;
523
592
for (const auto & p : l) {
@@ -718,8 +787,8 @@ namespace lp {
718
787
// returns true only on a conflict.
719
788
// m_indexed_work_vector contains the coefficients of the term
720
789
// m_c contains the constant term
721
- // m_tmp_l is the linear combination of the equations that removs the
722
- // substituted variablse returns true iff the conflict is found
790
+ // m_tmp_l is the linear combination of the equations that removes the
791
+ // substituted variables, returns true iff the conflict is found
723
792
bool tighten_bounds_for_non_trivial_gcd (const mpq& g, unsigned j,
724
793
bool is_upper) {
725
794
mpq rs;
@@ -781,7 +850,7 @@ namespace lp {
781
850
return true ;
782
851
}
783
852
784
- u_dependency* explain_fixed_in_meta_term (const lar_term & t) {
853
+ template < typename T> u_dependency* explain_fixed_in_meta_term (const T & t) {
785
854
return explain_fixed (open_ml (t));
786
855
}
787
856
@@ -831,16 +900,6 @@ namespace lp {
831
900
return lia_move::undef;
832
901
}
833
902
834
- struct undo_fixed : public trail {
835
- lar_solver& m_lra;
836
- unsigned m_j; // the variable that became fixed
837
- undo_fixed (lar_solver& lra, unsigned j) : m_lra(lra), m_j(j) {}
838
-
839
- void undo () override {
840
- NOT_IMPLEMENTED_YET ();
841
- }
842
- };
843
-
844
903
void collect_evidence () {
845
904
lra.get_infeasibility_explanation (m_infeas_explanation);
846
905
for (const auto & p : m_infeas_explanation) {
@@ -894,7 +953,7 @@ namespace lp {
894
953
tout << " fixed j:" << j <<" , was substited by " ; print_entry (m_k2s[j], tout););
895
954
if (check_fixing (j) == lia_move::conflict) {
896
955
auto & ep = m_entries[m_k2s[j]];
897
- for (auto ci : lra.flatten (explain_fixed_in_meta_term (ep. m_l ))) {
956
+ for (auto ci : lra.flatten (explain_fixed_in_meta_term (m_l_matrix. m_rows [m_k2s[j]] ))) {
898
957
m_explanation_of_branches.push_back (ci);
899
958
}
900
959
return lia_move::conflict;
@@ -929,11 +988,11 @@ namespace lp {
929
988
}
930
989
TRACE (" dio_br" , lra.print_column_info (b.m_j , tout) <<" add bound" << std::endl;);
931
990
if (lra.column_is_fixed (b.m_j )) {
932
- unsigned local_mj ;
933
- if (! m_var_register.external_is_used (b.m_j , local_mj ))
991
+ unsigned local_bj ;
992
+ if (! m_var_register.external_is_used (b.m_j , local_bj ))
934
993
return lia_move::undef;
935
994
936
- if (fix_var (lar_solver_to_local (b. m_j ) ) == lia_move::conflict) {
995
+ if (fix_var (local_bj ) == lia_move::conflict) {
937
996
TRACE (" dio_br" , tout << " conflict in fix_var" << std::endl;) ;
938
997
return lia_move::conflict;
939
998
}
@@ -1197,14 +1256,15 @@ namespace lp {
1197
1256
print_entry (i, tout) << std::endl;);
1198
1257
m_entries[i].m_c -= j_sign * coeff * e.m_c ;
1199
1258
m_e_matrix.pivot_row_to_row_given_cell_with_sign (ei, c, j, j_sign);
1200
- m_entries[i].m_l -= j_sign * coeff * e.m_l ;
1259
+ // m_entries[i].m_l -= j_sign * coeff * e.m_l;
1260
+ m_l_matrix.add_rows ( -j_sign*coeff, ei, i);
1201
1261
TRACE (" dioph_eq" , tout << " after pivoting c_row:" ;
1202
1262
print_entry (i, tout););
1203
1263
CTRACE (
1204
1264
" dioph_eq" , !entry_invariant (i), tout << " invariant delta:" ; {
1205
1265
const auto & e = m_entries[i];
1206
1266
print_term_o (get_term_from_entry (ei) -
1207
- fix_vars (open_ml (e. m_l )),
1267
+ fix_vars (open_ml (m_l_matrix. m_rows [ei] )),
1208
1268
tout)
1209
1269
<< std::endl;
1210
1270
});
@@ -1226,19 +1286,20 @@ namespace lp {
1226
1286
const auto & e = m_entries[ei];
1227
1287
bool ret =
1228
1288
term_to_lar_solver (remove_fresh_vars (get_term_from_entry (ei))) ==
1229
- fix_vars (open_ml (e. m_l ));
1289
+ fix_vars (open_ml (m_l_matrix. m_rows [ei] ));
1230
1290
if (ret)
1231
1291
return true ;
1232
1292
TRACE (" dioph_eq" , tout << " get_term_from_entry(" << ei << " ):" ;
1233
1293
print_term_o (get_term_from_entry (ei), tout) << std::endl;
1234
1294
tout << " remove_fresh_vars:" ;
1235
1295
print_term_o (remove_fresh_vars (get_term_from_entry (ei)), tout)
1236
1296
<< std::endl;
1237
- tout << " e.m_l:" ; print_lar_term_L (e. m_l , tout) << std::endl;
1297
+ tout << " e.m_l:" ; print_lar_term_L (l_term_from_row (ei) , tout) << std::endl;
1238
1298
tout << " open_ml(e.m_l):" ;
1239
- print_term_o (open_ml (e. m_l ), tout) << std::endl;
1299
+ print_term_o (open_ml (l_term_from_row (ei) ), tout) << std::endl;
1240
1300
tout << " fix_vars(open_ml(e.m_l)):" ;
1241
- print_term_o (fix_vars (open_ml (e.m_l )), tout) << std::endl;);
1301
+ print_term_o (fix_vars (open_ml (l_term_from_row (ei))), tout) << std::endl;
1302
+ );
1242
1303
return false ;
1243
1304
}
1244
1305
@@ -1276,7 +1337,7 @@ namespace lp {
1276
1337
return print_term_o (opened_ml, out);
1277
1338
}
1278
1339
1279
- term_o open_ml (const lar_term & ml) const {
1340
+ template < typename T> term_o open_ml (const T & ml) const {
1280
1341
term_o r;
1281
1342
for (const auto & p : ml) {
1282
1343
r += p.coeff () * (lra.get_term (p.var ()) - lar_term (p.var ()));
@@ -1319,7 +1380,7 @@ namespace lp {
1319
1380
e.m_c = r;
1320
1381
m_e_matrix.add_new_element (h, xt, ahk);
1321
1382
1322
- m_entries.push_back ({lar_term (), q, entry_status::NO_S_NO_F});
1383
+ m_entries.push_back ({q, entry_status::NO_S_NO_F});
1323
1384
m_e_matrix.add_new_element (fresh_row, xt, -mpq (1 ));
1324
1385
m_e_matrix.add_new_element (fresh_row, k, mpq (1 ));
1325
1386
for (unsigned i : m_indexed_work_vector.m_index ) {
@@ -1359,9 +1420,9 @@ namespace lp {
1359
1420
// out << "\tstatus:" << (int)e.m_entry_status;
1360
1421
if (need_print_dep) {
1361
1422
out << " \t m_l:{" ;
1362
- print_lar_term_L (e. m_l , out) << " }, " ;
1363
- print_ml (e. m_l , out << " \n\t fixed expl of m_l:\n " ) << " \n " ;
1364
- print_dep (out, explain_fixed_in_meta_term (e. m_l )) << " ," ;
1423
+ print_lar_term_L (l_term_from_row (ei) , out) << " }, " ;
1424
+ print_ml (l_term_from_row (ei) , out << " \n\t fixed expl of m_l:\n " ) << " \n " ;
1425
+ print_dep (out, explain_fixed_in_meta_term (l_term_from_row (ei) )) << " ," ;
1365
1426
}
1366
1427
switch (e.m_entry_status ) {
1367
1428
case entry_status::F:
@@ -1436,7 +1497,7 @@ namespace lp {
1436
1497
TRACE (" dioph_eq" , tout << " conflict:" ;
1437
1498
print_entry (m_conflict_index, tout, true ) << std::endl;);
1438
1499
auto & ep = m_entries[m_conflict_index];
1439
- for (auto ci : lra.flatten (explain_fixed_in_meta_term (ep. m_l ))) {
1500
+ for (auto ci : lra.flatten (explain_fixed_in_meta_term (m_l_matrix. m_rows [m_conflict_index] ))) {
1440
1501
ex.push_back (ci);
1441
1502
}
1442
1503
TRACE (" dioph_eq" , lra.print_expl (tout, ex););
0 commit comments