@@ -39,8 +39,9 @@ struct create_cut {
39
39
#if SMALL_CUTS
40
40
mpq m_abs_max, m_big_number;
41
41
#endif
42
- int m_polarity;
43
- bool m_found_big;
42
+ int m_polarity;
43
+ bool m_found_big;
44
+ u_dependency* m_dep;
44
45
45
46
const impq & get_value (unsigned j) const { return lia.get_value (j); }
46
47
bool is_int (unsigned j) const { return lia.column_is_int (j) || (lia.is_fixed (j) &&
@@ -330,6 +331,10 @@ struct create_cut {
330
331
if (some_int_columns)
331
332
simplify_inequality ();
332
333
334
+ m_dep = nullptr ;
335
+ for (auto c : *m_ex)
336
+ m_dep = lia.lra .join_deps (lia.lra .dep_manager ().mk_leaf (c.ci ()), m_dep);
337
+
333
338
TRACE (" gomory_cut" , print_linear_combination_of_column_indices_only (m_t .coeffs_as_vector (), tout << " gomory cut: " ); tout << " >= " << m_k << std::endl;);
334
339
TRACE (" gomory_cut_detail" , dump_cut_and_constraints_as_smt_lemma (tout);
335
340
lia.lra .display (tout));
@@ -512,10 +517,10 @@ struct create_cut {
512
517
513
518
514
519
lia_move gomory::get_gomory_cuts (unsigned num_cuts) {
515
- struct cut_result {explanation ex ; lar_term t; mpq k; int polarity; lpvar j;};
520
+ struct cut_result {u_dependency *dep ; lar_term t; mpq k; int polarity; lpvar j;};
516
521
vector<cut_result> big_cuts;
517
- struct polar_pair {int polarity; lpvar j; u_dependency *dep;};
518
- vector< polar_pair> polar_vars;
522
+ struct polar_pair {int polarity; u_dependency *dep;};
523
+ std::unordered_map<lpvar, polar_pair> polar_vars;
519
524
unsigned_vector columns_for_cuts = gomory_select_int_infeasible_vars (num_cuts);
520
525
521
526
// define inline helper functions
@@ -524,15 +529,12 @@ struct create_cut {
524
529
return all_of (t, [&](auto ci) { return ci.coeff ().is_small (); });
525
530
};
526
531
auto add_cut = [&](cut_result const & cr) {
527
- u_dependency* dep = nullptr ;
528
- for (auto c : cr.ex )
529
- dep = lra.join_deps (lra.dep_manager ().mk_leaf (c.ci ()), dep);
532
+ u_dependency* dep = cr.dep ;
530
533
lp::lpvar term_index = lra.add_term (cr.t .coeffs_as_vector (), UINT_MAX);
531
534
term_index = lra.map_term_index_to_column_index (term_index);
532
535
lra.update_column_type_and_bound (term_index,
533
536
lp::lconstraint_kind::GE,
534
- lia.m_k , dep);
535
- return dep;
537
+ lia.m_k , dep);
536
538
};
537
539
auto _check_feasible = [&](void ) {
538
540
lra.find_feasible_solution ();
@@ -552,17 +554,16 @@ struct create_cut {
552
554
553
555
if (r != lia_move::cut)
554
556
continue ;
555
- cut_result cr = {*lia.m_ex , lia.m_t , lia.m_k , cc.m_polarity , j};
556
-
557
+ cut_result cr = {cc.m_dep , lia.m_t , lia.m_k , cc.m_polarity , j};
558
+ if (abs (cr.polarity ) == 1 ) // need to delay the update of the bounds for j in a polar case, because simplify_inequality relies on the old bounds
559
+ polar_vars[j] = {cr.polarity , cc.m_dep };
560
+
557
561
if (!is_small_cut (lia.m_t )) {
558
562
big_cuts.push_back (cr);
559
563
continue ;
560
564
}
561
565
has_small_cut = true ;
562
- auto dep = add_cut (cr);
563
- if (abs (cr.polarity ) == 1 ) // need to delay the update of the bounds for j in a polar case, because simplify_inequality relies on the old bounds
564
- polar_vars.push_back ({cr.polarity , j, dep}); // todo : polarity for big cuts
565
-
566
+ add_cut (cr);
566
567
if (lia.settings ().get_cancel_flag ())
567
568
return lia_move::undef;
568
569
}
@@ -581,12 +582,14 @@ struct create_cut {
581
582
return lia_move::conflict;
582
583
}
583
584
585
+ // this way we create bounds for the variables in polar cases even where the terms had big numbers
584
586
for (auto const & p : polar_vars) {
585
- if (p.polarity == 1 ) {
586
- lra.update_column_type_and_bound (p.j , lp::lconstraint_kind::LE, floor (lra.get_column_value (p.j ).x ), p.dep );
587
+ if (p.second . polarity == 1 ) {
588
+ lra.update_column_type_and_bound (p.first , lp::lconstraint_kind::LE, floor (lra.get_column_value (p.first ).x ), p. second .dep );
587
589
}
588
- else if (p.polarity == -1 ) {
589
- lra.update_column_type_and_bound (p.j , lp::lconstraint_kind::GE, ceil (lra.get_column_value (p.j ).x ), p.dep );
590
+ else {
591
+ SASSERT (p.second .polarity == -1 );
592
+ lra.update_column_type_and_bound (p.first , lp::lconstraint_kind::GE, ceil (lra.get_column_value (p.first ).x ), p.second .dep );
590
593
}
591
594
}
592
595
@@ -598,8 +601,6 @@ struct create_cut {
598
601
599
602
if (has_small_cut || big_cuts.size ())
600
603
return lia_move::continue_with_check;
601
-
602
-
603
604
604
605
lra.move_non_basic_columns_to_bounds ();
605
606
return lia_move::undef;
0 commit comments