@@ -285,17 +285,29 @@ namespace lp {
285
285
struct undo_add_term : public trail {
286
286
imp& m_s;
287
287
const lar_term* m_t ;
288
- undo_add_term (imp& s, const lar_term *t): m_s(s), m_t (t) {
289
- TRACE (" dioph_eq" , m_s.print_lar_term_L (*t, tout); tout << " t->j()=" << t->j () << std::endl;);
288
+ unsigned m_l_column_count;
289
+ unsigned m_row_count;
290
+ unsigned m_e_column_count;
291
+ undo_add_term (imp& s, const lar_term *t):
292
+ m_s (s),
293
+ m_t (t),
294
+ m_l_column_count (m_s.m_l_matrix.column_count()),
295
+ m_row_count (m_s.m_l_matrix.row_count()),
296
+ m_e_column_count (m_s.m_e_matrix.column_count()) {
297
+ TRACE (" dioph_eq" , m_s.print_lar_term_L (*t, tout); tout << " t->j()=" << t->j () << std::endl;);
290
298
}
291
299
void undo () {
300
+ SASSERT (m_s.entries_are_ok ());
292
301
TRACE (" dioph_eq" , m_s.lra .print_term (*m_t , tout); tout << " , m_t->j() =" << m_t ->j () << std::endl;);
293
302
if (!contains (m_s.m_active_terms , m_t )) {
294
303
for (int i = m_s.m_added_terms .size () - 1 ; i >= 0 ; --i) {
295
304
if (m_s.m_added_terms [i] != m_t ) continue ;
296
305
// the address is the same
297
- if (i != m_s.m_added_terms .size () -1 ) m_s.m_added_terms [i] = m_s.m_added_terms .back ();
306
+ if (i != m_s.m_added_terms .size () -1 )
307
+ m_s.m_added_terms [i] = m_s.m_added_terms .back ();
298
308
m_s.m_added_terms .pop_back ();
309
+ SASSERT (m_s.m_l_matrix .row_count () == m_row_count && m_s.m_l_matrix .column_count () == m_l_column_count
310
+ && m_s.m_e_matrix .column_count () == m_e_column_count);
299
311
return ; // all is done since the term has not made it to entries, etc
300
312
}
301
313
}
@@ -307,18 +319,22 @@ namespace lp {
307
319
if (it->second .size () == 0 ) {
308
320
m_s.m_columns_to_terms .erase (it);
309
321
}
310
-
311
322
}
323
+ SASSERT (std::find (m_s.m_added_terms .begin (), m_s.m_added_terms .end (), m_t ) == m_s.m_added_terms .end ());
324
+ SASSERT (contains (m_s.m_active_terms , m_t ));
325
+ m_s.m_active_terms .erase (m_t );
326
+ std::cout << ++ lp_settings::ddd << std::endl;
312
327
TRACE (" dioph_eq" ,
313
328
tout << " the deleted term column in m_l_matrix" << std::endl;
314
329
for (auto p: m_s.m_l_matrix .column (m_t ->j ())) {
315
- tout << p.coeff ()<< " , row " << p.var () << std::endl;
330
+ tout << " p.coeff(): " << p.coeff ()<< " , row " << p.var () << std::endl;
316
331
}
317
- tout << " m_l_matrix has " << m_s.m_l_matrix .column_count () << std::endl;
318
- tout << " and" << m_s.m_l_matrix .row_count () << " rows" << std::endl;
332
+ tout << " m_l_matrix has " << m_s.m_l_matrix .column_count () << " columns" << std::endl;
333
+ tout << " and " << m_s.m_l_matrix .row_count () << " rows" << std::endl;
334
+ m_s.print_lar_term_L (*m_t , tout); tout << " ; m_t->j()=" << m_t ->j () << std::endl;
319
335
);
320
- NOT_IMPLEMENTED_YET ( );
321
- }
336
+ m_s. shrink_L_to_size (m_row_count, m_l_column_count, m_e_column_count, m_t );
337
+ }
322
338
};
323
339
324
340
@@ -335,6 +351,105 @@ namespace lp {
335
351
}
336
352
};
337
353
354
+
355
+ void remove_last_entry () {
356
+ unsigned ei = m_entries.size () - 1 ;
357
+
358
+ if (m_entries.back ().m_entry_status == entry_status::F) {
359
+ remove_entry_index (this ->m_f , ei);
360
+ } else {
361
+ remove_entry_index (this ->m_s , ei);
362
+ }
363
+ }
364
+ void shrink_L_to_size (unsigned row_count, unsigned l_column_count, unsigned e_column_count, const lar_term* t) {
365
+ while (row_count < m_l_matrix.row_count ()) {
366
+ shrink_L_one_size (t);
367
+ }
368
+ SASSERT (entries_are_ok ());
369
+ SASSERT (l_column_count == m_l_matrix.column_count () && e_column_count == m_e_matrix.column_count ());
370
+ }
371
+
372
+ void remove_last_row_column_in_matrix (static_matrix<mpq, mpq>& m) {
373
+ auto & last_row = m.m_rows .back ();
374
+ for (unsigned k = last_row.size (); k-- > 0 ;) {
375
+ m.remove_element (last_row, last_row[k]);
376
+ }
377
+ SASSERT (m.m_columns .back ().size () == 0 );
378
+ m.m_rows .pop_back ();
379
+ m.m_columns .pop_back ();
380
+ }
381
+
382
+ void shrink_L_one_size (const lar_term*t) {
383
+ unsigned j = m_l_matrix.column_count () - 1 ; // the last column
384
+ unsigned i = m_l_matrix.row_count () - 1 ; // the last row
385
+ auto last_col = m_l_matrix.column (j);
386
+ TRACE (" dioph_eq" , tout << " the last entry: i:" << i <<std::endl;
387
+ print_entry (i, tout);
388
+ tout << " t->j()=" << t->j () << " is mapped to " << lar_solver_to_local (t->j ()) << std::endl;
389
+ );
390
+ SASSERT (t->j () == j);
391
+
392
+ bool row_i_found = false ;
393
+ // prepare for pivoting
394
+
395
+ std_vector<unsigned > entries_to_change;
396
+
397
+ for (const auto p : last_col ) {
398
+ entries_to_change.push_back (p.var ()); ;
399
+ if (p.var () == i) {
400
+ row_i_found = true ;
401
+ }
402
+ }
403
+ SASSERT (row_i_found);
404
+
405
+ for (unsigned ei : entries_to_change)
406
+ move_entry_from_s_to_f (ei);
407
+
408
+ // find the coefficient before the term variable, k, in the last row of m_e_matrix
409
+ unsigned k = lar_solver_to_local (j);
410
+ auto &last_e_row = m_e_matrix.m_rows .back ();
411
+ mpq alpha;
412
+ for (const auto p: last_e_row) {
413
+ if (p.var () == k) {
414
+ alpha = p.coeff ();
415
+ break ;
416
+ }
417
+ }
418
+ this ->m_e_matrix .divide_row (i, alpha);
419
+ this ->m_l_matrix .divide_row (i, alpha);
420
+ this ->m_entries [i].m_c /= alpha;
421
+ SASSERT (entry_invariant (i));
422
+ eliminate_var_in_f (i, k, 1 );
423
+ TRACE (" dioph_eq" , tout << " last row before removal\n " ;
424
+ print_entry (m_entries.size () -1 , tout) << std::endl);
425
+ remove_last_row_column_in_matrix (m_l_matrix);
426
+ remove_last_row_column_in_matrix (m_e_matrix);
427
+ m_entries.pop_back ();
428
+ remove_entry_index (m_f, i);
429
+ remove_entry_index (m_s, i);
430
+ auto it = std::find_if (m_fresh_definitions.begin (), m_fresh_definitions.end (), [i](auto const & fe) {
431
+ return fe.m_origin == i;
432
+ });
433
+ if (it != m_fresh_definitions.end ())
434
+ m_fresh_definitions.erase (it);
435
+ for (unsigned k = 0 ; k < m_k2s.size () ; k++) {
436
+ if (m_k2s[k] == i) {
437
+ m_k2s[k] = -1 ;
438
+ }
439
+ }
440
+
441
+ m_var_register.shrink (m_e_matrix.column_count ());
442
+ }
443
+
444
+
445
+ void remove_entry_index (std::list<unsigned > & l, unsigned ei) {
446
+ auto it = std::find (l.begin (), l.end (), ei);
447
+ if (it != l.end ())
448
+ l.erase (it);
449
+ }
450
+
451
+
452
+
338
453
std::unordered_set<unsigned > m_changed_columns;
339
454
// m_column_to_terms[j] is the set of all k such lra.get_term(k) depends on j
340
455
std::unordered_map<unsigned , std::unordered_set<unsigned >> m_columns_to_terms;
@@ -377,8 +492,8 @@ namespace lp {
377
492
378
493
public:
379
494
imp (int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
380
- lra.register_add_term_delegate ( [this ](const lar_term*t){add_term_delegate (t);}) ;
381
- lra.register_update_column_bound_delegate ( [this ](unsigned j) {update_column_bound_delegate (j);}) ;
495
+ lra.m_add_term_callback = [this ](const lar_term*t){add_term_delegate (t);};
496
+ lra.m_update_column_bound_callback = [this ](unsigned j){update_column_bound_delegate (j);};
382
497
}
383
498
term_o get_term_from_entry (unsigned i) const {
384
499
term_o t;
@@ -428,6 +543,7 @@ namespace lp {
428
543
m_l_matrix.add_new_element (entry_index, t.j (), mpq (1 ));
429
544
// fill E-entry
430
545
m_e_matrix.add_row ();
546
+
431
547
SASSERT (m_e_matrix.row_count () == m_entries.size ());
432
548
433
549
for (const auto & p : t.ext_coeffs ()) {
@@ -552,6 +668,7 @@ namespace lp {
552
668
}
553
669
}
554
670
for (unsigned ei: entries_to_recalculate) {
671
+ SASSERT (std::find (m_f.begin (), m_f.end (), ei) == m_f.end ());
555
672
m_f.push_back (ei);
556
673
m_entries[ei].m_entry_status = entry_status::F;
557
674
}
@@ -560,7 +677,7 @@ namespace lp {
560
677
bool entries_are_ok () {
561
678
for (unsigned ei = 0 ; ei < m_entries.size (); ei++) {
562
679
if (entry_invariant (ei) == false ) {
563
- TRACE (" dioph_eq " , tout << " bad entry:" ; print_entry (ei, tout););
680
+ TRACE (" dioph_deb_eq " , tout << " bad entry:" ; print_entry (ei, tout););
564
681
return false ;
565
682
}
566
683
}
@@ -1446,10 +1563,10 @@ namespace lp {
1446
1563
std::ostream& print_e_row (unsigned i, std::ostream& out) {
1447
1564
return print_term_o (get_term_from_entry (i), out);
1448
1565
}
1449
- // j is the variable to eliminate, it appears in row e. m_e_matrix with
1450
- // a coefficient equal to +-1
1566
+ // j is the variable to eliminate, it appears in row ei of m_e_matrix with
1567
+ // a coefficient equal to j_sign which is +-1
1451
1568
void eliminate_var_in_f (unsigned ei, unsigned j, int j_sign) {
1452
- entry & e = m_entries[ei];
1569
+ const auto & e = m_entries[ei];
1453
1570
TRACE (" dioph_eq" , tout << " eliminate var:" << j << " by using:" ;
1454
1571
print_entry (ei, tout) << std::endl;);
1455
1572
auto & column = m_e_matrix.m_columns [j];
@@ -1515,7 +1632,7 @@ namespace lp {
1515
1632
term_to_lar_solver (remove_fresh_vars (get_term_from_entry (ei))) ==
1516
1633
fix_vars (open_ml (m_l_matrix.m_rows [ei]));
1517
1634
1518
- CTRACE ( " dioph_eq " , !ret,
1635
+ CTRACE ( " dioph_deb_eq " , !ret,
1519
1636
{
1520
1637
tout << " get_term_from_entry(" << ei << " ):" ;
1521
1638
print_term_o (get_term_from_entry (ei), tout) << std::endl;
@@ -1687,6 +1804,18 @@ namespace lp {
1687
1804
return out;
1688
1805
}
1689
1806
1807
+ void move_entry_from_s_to_f (unsigned ei) {
1808
+ if (m_entries[ei].m_entry_status == entry_status::F) return ;
1809
+ m_entries[ei].m_entry_status = entry_status::F;
1810
+ for (unsigned l = 0 ; l < m_k2s.size (); l++) {
1811
+ if (m_k2s[l] == ei) {
1812
+ m_k2s[l] = -1 ;
1813
+ }
1814
+ }
1815
+ m_s.remove (ei);
1816
+ m_f.push_back (ei);
1817
+ }
1818
+
1690
1819
// k is the index of the variable that is being substituted
1691
1820
void move_entry_from_f_to_s (unsigned k, unsigned h) {
1692
1821
SASSERT (m_entries[h].m_entry_status == entry_status::F);
0 commit comments