8
8
9
9
10
10
namespace lp {
11
+ struct column_update {
12
+ bool m_is_upper;
13
+ unsigned m_j;
14
+ impq m_bound;
15
+ column m_column;
16
+ };
17
+
18
+ struct imp {
19
+ lar_solver &lra;
20
+ vector<column_update> m_column_updates;
21
+
22
+ void set_r_upper_bound (unsigned j, const impq& b) {
23
+ lra.m_mpq_lar_core_solver .m_r_upper_bounds [j] = b;
24
+ }
25
+ void set_r_lower_bound (unsigned j, const impq& b) {
26
+ lra.m_mpq_lar_core_solver .m_r_lower_bounds [j] = b;
27
+ }
28
+
29
+ imp (lar_solver& s) : lra(s) {}
30
+
31
+ void set_column (unsigned j, const column& c) {
32
+ lra.m_columns [j] = c;
33
+ }
34
+
35
+ struct column_update_trail : public trail {
36
+ imp& m_imp;
37
+ column_update_trail (imp & i) : m_imp(i) {}
38
+ void undo () override {
39
+ auto & [is_upper, j, bound, column] = m_imp.m_column_updates .back ();
40
+ if (is_upper)
41
+ m_imp.set_r_upper_bound (j, bound);
42
+ else
43
+ m_imp.set_r_lower_bound (j, bound);
44
+ m_imp.set_column (j, column);
45
+ m_imp.m_column_updates .pop_back ();
46
+ }
47
+ };
48
+ };
11
49
50
+ imp* m_imp;
12
51
lp_settings& lar_solver::settings () { return m_settings; }
13
52
14
53
lp_settings const & lar_solver::settings () const { return m_settings; }
@@ -25,7 +64,8 @@ namespace lp {
25
64
lar_solver::lar_solver () :
26
65
m_mpq_lar_core_solver (m_settings, *this ),
27
66
m_var_register (),
28
- m_constraints (m_dependencies, *this ) {}
67
+ m_constraints (m_dependencies, *this ), m_imp(alloc(imp, *this )) {
68
+ }
29
69
30
70
// start or ends tracking the rows that were changed by solve()
31
71
void lar_solver::track_touched_rows (bool v) {
@@ -574,38 +614,25 @@ namespace lp {
574
614
A_r ().pop (k);
575
615
}
576
616
577
- struct lar_solver ::column_update_trail : public trail {
578
- lar_solver& s;
579
- column_update_trail (lar_solver& s) : s(s) {}
580
- void undo () override {
581
- auto & [is_upper, j, bound, column] = s.m_column_updates .back ();
582
- if (is_upper)
583
- s.m_mpq_lar_core_solver .m_r_upper_bounds [j] = bound;
584
- else
585
- s.m_mpq_lar_core_solver .m_r_lower_bounds [j] = bound;
586
- s.m_columns [j] = column;
587
- s.m_column_updates .pop_back ();
588
- }
589
- };
590
-
617
+
591
618
void lar_solver::set_upper_bound_witness (lpvar j, u_dependency* dep, impq const & high) {
592
619
bool has_upper = m_columns[j].upper_bound_witness () != nullptr ;
593
- m_column_updates.push_back ({true , j, get_upper_bound (j), m_columns[j]});
594
- m_trail.push (column_update_trail (*this ));
620
+ m_imp-> m_column_updates .push_back ({true , j, get_upper_bound (j), m_columns[j]});
621
+ m_trail.push (imp:: column_update_trail (*this -> m_imp ));
595
622
m_columns[j].set_upper_bound_witness (dep);
596
623
if (has_upper)
597
- m_columns[j].set_previous_upper (m_column_updates.size () - 1 );
624
+ m_columns[j].set_previous_upper (m_imp-> m_column_updates .size () - 1 );
598
625
m_mpq_lar_core_solver.m_r_upper_bounds [j] = high;
599
626
insert_to_columns_with_changed_bounds (j);
600
627
}
601
628
602
629
void lar_solver::set_lower_bound_witness (lpvar j, u_dependency* dep, impq const & low) {
603
630
bool has_lower = m_columns[j].lower_bound_witness () != nullptr ;
604
- m_column_updates.push_back ({false , j, get_lower_bound (j), m_columns[j]});
605
- m_trail.push (column_update_trail (*this ));
631
+ m_imp-> m_column_updates .push_back ({false , j, get_lower_bound (j), m_columns[j]});
632
+ m_trail.push (imp:: column_update_trail (*this -> m_imp ));
606
633
m_columns[j].set_lower_bound_witness (dep);
607
634
if (has_lower)
608
- m_columns[j].set_previous_lower (m_column_updates.size () - 1 );
635
+ m_columns[j].set_previous_lower (m_imp-> m_column_updates .size () - 1 );
609
636
m_mpq_lar_core_solver.m_r_lower_bounds [j] = low;
610
637
insert_to_columns_with_changed_bounds (j);
611
638
}
@@ -1196,26 +1223,34 @@ namespace lp {
1196
1223
1197
1224
#if 1
1198
1225
if (is_upper) {
1199
- if (ul.previous_upper () != UINT_MAX) {
1200
- auto const & [_is_upper, _j, _bound, _column] = m_column_updates[ul.previous_upper ()];
1226
+ unsigned current_update_index = ul.previous_upper ();
1227
+ while (current_update_index != UINT_MAX) {
1228
+ auto const & [_is_upper, _j, _bound, _column] = m_imp->m_column_updates [current_update_index];
1201
1229
auto new_slack = slack + coeff * (_bound - get_upper_bound (j));
1202
1230
if (sign == get_sign (new_slack)) {
1203
- // verbose_stream() << "can weaken j" << j << " " << coeff << " " << get_upper_bound(j) << " " << _bound << "\n";
1231
+ // verbose_stream() << "can weaken upper j" << j << " " << coeff << " " << get_upper_bound(j) << " " << _bound << "\n";
1204
1232
slack = new_slack;
1205
1233
bound_constr_i = _column.upper_bound_witness ();
1206
- }
1234
+ current_update_index = _column.previous_upper (); // Move to the next previous bound in the list
1235
+ } else
1236
+ break ; // Stop if weakening is not possible with this previous bound
1237
+
1207
1238
}
1208
- }
1239
+ }
1209
1240
else {
1210
- if (ul.previous_lower () != UINT_MAX) {
1211
- auto const & [_is_upper, _j, _bound, _column] = m_column_updates[ul.previous_lower ()];
1241
+ unsigned prev_l = ul.previous_lower ();
1242
+ while (prev_l != UINT_MAX) {
1243
+ auto const & [_is_upper, _j, _bound, _column] = m_imp->m_column_updates [prev_l];
1212
1244
auto new_slack = slack + coeff * (_bound - get_lower_bound (j));
1213
1245
if (sign == get_sign (new_slack)) {
1214
- // verbose_stream() << "can weaken j" << j << " " << coeff << " " << get_lower_bound(j) << " " << _bound << "\n";
1246
+ // verbose_stream() << "can weaken lower j" << j << " " << coeff << " " << get_lower_bound(j) << " " << _bound << "\n";
1215
1247
slack = new_slack;
1216
1248
bound_constr_i = _column.lower_bound_witness ();
1249
+ prev_l = _column.previous_lower ();
1217
1250
}
1218
- }
1251
+ else
1252
+ break ;
1253
+ }
1219
1254
}
1220
1255
#endif
1221
1256
0 commit comments