<pre style='margin:0'>
Renee Otten (reneeotten) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/25ac523b6de89fbc56342e7634a9b2f84be937dd">https://github.com/macports/macports-ports/commit/25ac523b6de89fbc56342e7634a9b2f84be937dd</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 25ac523b6de89fbc56342e7634a9b2f84be937dd
</span>Author: Kirill A. Korinsky <kirill@korins.ky>
AuthorDate: Wed Nov 30 23:51:31 2022 +0100

<span style='display:block; white-space:pre;color:#404040;'>    papilo: remove accidental dependency
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Papilo may pick from system scip, soplex and HIGHS to be used as fronted
</span><span style='display:block; white-space:pre;color:#404040;'>    which creates a depenency loop. Prevent that.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also make clear dependency with OneTBB, GMP and OpenBLAS.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also, enforce GMP instead libquadmath then the last one is available.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Thus, backport patch to support negative egcd.
</span>---
 math/papilo/Portfile                       |  25 +-
 math/papilo/files/patch-negative-egcd.diff | 397 +++++++++++++++++++++++++++++
 2 files changed, 421 insertions(+), 1 deletion(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/math/papilo/Portfile b/math/papilo/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index a65a0cfa84d..ab88a97f1b9 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/math/papilo/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/math/papilo/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -5,8 +5,11 @@ PortGroup               boost 1.0
</span> PortGroup               cmake 1.1
 PortGroup               github 1.0
 PortGroup               compiler_blacklist_versions 1.0
<span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup               compilers 1.0
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# NOTE: PaPILO can be used as a header-based library, please bump all dependent ports
</span> github.setup            scipopt papilo 2.1.1 v
<span style='display:block; white-space:pre;background:#e0ffe0;'>+revision                1
</span> categories              math
 license                 {LGPL-3 GPL-3}
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -19,8 +22,28 @@ checksums               rmd160  086c74c8ce81f8b10c7073ea3b0090a7d1e77e0f \
</span>                         sha256  f443e94de1ea61132526a68a681e8aa2e94488802085115284cf5dd000b31d25 \
                         size    1082818
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles              patch-negative-egcd.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compilers.setup         require_fortran
</span> compiler.cxx_standard   2014
 
 compiler.blacklist-append {clang < 1000}
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-depends_lib-append      port:onetbb
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+depends_lib-append      path:lib/libopenblas.dylib:OpenBLAS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        port:gmp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        port:onetbb
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# PAPILO might be frontend for SCIP and/or SOPLEX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# anyway, SCIP is also required PAPILO,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# to break the dependency loop and make build clean
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# disable SCIP, SOPLEX and HIGHS at PAPILO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# See: https://github.com/scipopt/papilo/issues/21
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args-append   -DSCIP=OFF \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        -DSOPLEX=OFF \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        -DHIGHS=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# PAPILO may be linked against libquadmath, prevent that by using GMP.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args-append   -DGMP=ON \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        -DQUADMATH=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test.run                yes
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/math/papilo/files/patch-negative-egcd.diff b/math/papilo/files/patch-negative-egcd.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..b33f6099332
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/math/papilo/files/patch-negative-egcd.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,397 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+https://github.com/scipopt/papilo/commit/53ec504638aaa72a6b6de71175e9db27e4d7b60b
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git CHANGELOG CHANGELOG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index c29d3041..145ef310 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- CHANGELOG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ CHANGELOG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -74,6 +74,7 @@ Fixed bugs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ - postsolving FixInfinityCol works also in primal case
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ - store data for FixInfinityCol correct if bounds are both infinity
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ - PaPILO shows some behavior on different OS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++- avoid abort because of calling extended_euclidean with negative coefficients
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Miscellaneous
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/papilo/presolvers/SimpleSubstitution.hpp src/papilo/presolvers/SimpleSubstitution.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index faf6a399..fbb2e8cd 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/papilo/presolvers/SimpleSubstitution.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/papilo/presolvers/SimpleSubstitution.hpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -243,15 +243,10 @@ SimpleSubstitution<REAL>::perform_simple_subsitution_step(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          auto res = boost::integer::extended_euclidean(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             static_cast<int64_t>( abs( vals[stay] ) ),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             static_cast<int64_t>( abs( vals[subst] ) ) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-         if( vals[stay] < 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            res.x *= -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-         if( vals[subst] < 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            res.y *= -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          if( !num.isIntegral( rhs / res.gcd ) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             return PresolveStatus::kInfeasible;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          // TODO: ensure isConstraintsFeasibleWithGivenBounds() works for negative sign
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-         else if( vals[stay] > 0 && vals[subst] > 0 &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            !isConstraintsFeasibleWithGivenBounds(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++         else if( !isConstraintsFeasibleWithGivenBounds(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                num, lower_bounds, upper_bounds, vals, rhs, subst, stay, res ) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             return PresolveStatus::kInfeasible;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -321,6 +316,16 @@ SimpleSubstitution<REAL>::perform_simple_subsitution_step(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reductions.aggregateFreeCol( inds[subst], i );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * check if the aggregated variable y of the equation a2x1 + a2x2 = b is within its bounds.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * 1. generate a solution for s a1 + t a2 = gcd(a1,a2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * 2. substitute variable x1 = -a2 y + s and x2 = a1 y + t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * 3. check bounds of y
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * see chapter 10.1.1 Constraint Integer Programming of Tobias Achterberg
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ template <typename REAL>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ SimpleSubstitution<REAL>::isConstraintsFeasibleWithGivenBounds(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -328,18 +333,24 @@ SimpleSubstitution<REAL>::isConstraintsFeasibleWithGivenBounds(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     const Vec<REAL>& upper_bounds, const REAL* vals, REAL rhs, int subst,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int stay, const boost::integer::euclidean_result_t<int64_t>& res ) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL initial_solution_for_x = res.x * rhs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL initial_solution_for_y = res.y * rhs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   int res_x = vals[stay] < 0 ? res.x * -1 : res.x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   int res_y = vals[subst] < 0 ? res.y * -1 : res.y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL initial_solution_for_x = res_x * rhs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL initial_solution_for_y = res_y * rhs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REAL factor = (int)(initial_solution_for_y * res.gcd / vals[stay]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL solution_for_x =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       initial_solution_for_x + factor / res.gcd * vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL solution_for_y =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       initial_solution_for_y - factor / res.gcd * vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL ub_sol_y = ( solution_for_y - lower_bounds[stay] ) / vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL lb_sol_y = ( solution_for_y - upper_bounds[stay] ) / vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL ub_sol_x = ( upper_bounds[subst] - solution_for_x ) / vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REAL lb_sol_x = ( lower_bounds[subst] - solution_for_x ) / vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL s = initial_solution_for_x + factor / res.gcd * vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL t = initial_solution_for_y - factor / res.gcd * vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL ub_sol_y = ( t - lower_bounds[subst] ) / vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL lb_sol_y = ( t - upper_bounds[subst] ) / vals[stay];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   if( vals[stay] < 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      std::swap( ub_sol_y, lb_sol_y );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL ub_sol_x = ( upper_bounds[stay] - s ) / vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REAL lb_sol_x = ( lower_bounds[stay] - s ) / vals[subst];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   if( vals[subst] < 0 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      std::swap( ub_sol_x, lb_sol_x );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return num.isFeasLE( num.epsCeil( lb_sol_y ), num.epsFloor( ub_sol_y ) ) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           num.isFeasLE( num.epsCeil( lb_sol_x ), num.epsFloor( ub_sol_x ) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git test/CMakeLists.txt test/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 9ed9064b..0211f195 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- test/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ test/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -176,13 +176,16 @@ set(unit_tests
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         "happy-path-simple-probing-only-binary-positive-coefficient"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         #Simple Substitution
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "happy-path-simple-substitution-for-2-int"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "happy-path-simple-substitution-for-2-continuous"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "happy-path-simple-substitution-for-continuous-and-integer"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "happy-path-simple-substitution-for-int-continuous-coeff"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "should_return_infeasible_if_gcd_of_coeff_is_in_rhs"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "should_return_feasible_if_gcd_of_coeff_is_in_rhs"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        "failed-path-simple-substitution-for-2-int"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-happy-path-for-2-int"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-happy-path-for-2-continuous"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-happy-path-for-continuous-and-integer"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-happy-path-for-int-continuous-coeff"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-should_return_infeasible_if_gcd_of_coeff_is_in_rhs"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-should_return_feasible_if_gcd_of_coeff_is_in_rhs"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-failed-path-for-2-int"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-2-negative-integer"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-feasible-gcd"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "simple-substitution-violated-gcd"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         #Simplify Inequality
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         "happy-path-simplify-inequalities-only-greatest-divisor"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git test/papilo/presolve/SimpleSubstitutionTest.cpp test/papilo/presolve/SimpleSubstitutionTest.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 81d37816..d4651f83 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- test/papilo/presolve/SimpleSubstitutionTest.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ test/papilo/presolve/SimpleSubstitutionTest.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -34,7 +34,9 @@ setupProblemWithSimpleSubstitution( uint8_t is_x_integer, uint8_t is_y_integer,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                     double a_y );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Problem<double>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-setupProblemWithInfeasibleBounds( double x, double y, double rhs );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++setupProblemWithInfeasibleBounds( double x, double y, double rhs, double coef1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double coef2, double lb1, double ub1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double lb2, double ub2 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Problem<double>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ setupProblemWithSimpleSubstitutionInfeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -42,7 +44,11 @@ setupProblemWithSimpleSubstitutionInfeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Problem<double>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ setupProblemWithSimpleSubstitutionFeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "happy-path-simple-substitution-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++PresolveStatus
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++check_gcd_result_with_expectation(double x, double y, double rhs, double coef1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                   double coef2, double lb1, double ub1, double lb2, double ub2 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-happy-path-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -91,7 +97,7 @@ TEST_CASE( "happy-path-simple-substitution-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REQUIRE( reductions.getReduction( 4 ).newval == 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "happy-path-simple-substitution-for-int-continuous-coeff",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-happy-path-for-int-continuous-coeff",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Message msg {};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -115,7 +121,7 @@ TEST_CASE( "happy-path-simple-substitution-for-int-continuous-coeff",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REQUIRE( presolveStatus == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "happy-path-simple-substitution-for-2-continuous", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-happy-path-for-2-continuous", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -154,7 +160,7 @@ TEST_CASE( "happy-path-simple-substitution-for-2-continuous", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REQUIRE( reductions.getReduction( 2 ).newval == 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "happy-path-simple-substitution-for-continuous-and-integer",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-happy-path-for-continuous-and-integer",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -194,7 +200,7 @@ TEST_CASE( "happy-path-simple-substitution-for-continuous-and-integer",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REQUIRE( reductions.getReduction( 2 ).newval == 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "failed-path-simple-substitution-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-simple-substitution-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -218,13 +224,58 @@ TEST_CASE( "failed-path-simple-substitution-for-2-int", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    REQUIRE( presolveStatus == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-2-negative-integer", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 2x - 2y = 4 with x,y in [0,3]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                1.0, 1.0, 4.0, 2.0, 2.0, 0.0, 3.0, 0.0, 3.0 ) == PresolveStatus::kReduced );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-feasible-gcd", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 3x + 8y = 37 with x in {0,7} y in {0,5} -> solution x = 7, y = 2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, 3.0, 8.0, 0.0, 7.0, 0.0, 5.0 ) == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // -3x -8y = 37 with x in {-7,0} y in {-5,0} -> solution x = -7, y = -2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, -3.0, -8.0, -7.0, 0.0, -5.0, 0.0 ) == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // -3x -8y = -37 with x in {0,7} y in {0,5} -> solution x = 7, y = 2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, -37.0, -3.0, -8.0, 0.0, 7.0, 0.0, 5.0 ) == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // -3x + 8y = 37 with x in {-7,0} y in {0,5} -> solution x = -7, y = 2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, -3.0, 8.0, -7.0, 0.0, 0.0, 5.0 ) == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 3x - 8y = 37 with x in {0,7} y in {-5,0} -> solution x = 7, y = -2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, 3.0, -8.0, 0.0, 7.0, -5.0, 0.0 ) == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "simple-substitution-violated-gcd", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // -3x - 8y = 37 with x,y in {-5,0}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, -3.0, 8.0, -5.0, 0.0, -5.0, 0.0 ) == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // -3x - 8y = -37 with x,y in {0,5}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, -37.0, -3.0, -8.0, 0.0, 5.0, 0.0, 5.0 ) == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ TEST_CASE( "example_10_1_in_constraint_integer_programming", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 3x + 8y = 37 with x,y in {0,5}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( check_gcd_result_with_expectation(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                8.0, 3.0, 37.0, 3.0, 8.0, 0.0, 5.0, 0.0, 5.0 ) == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "should_return_feasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Message msg {};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Timer t{ time };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Problem<double> problem = setupProblemWithInfeasibleBounds( 8.0, 3.0, 37.0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Problem<double> problem = setupProblemWithSimpleSubstitutionFeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Statistics statistics{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    PresolveOptions presolveOptions{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    presolveOptions.dualreds = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -238,17 +289,17 @@ TEST_CASE( "example_10_1_in_constraint_integer_programming", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    PresolveStatus presolveStatus =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        presolvingMethod.execute( problem, problemUpdate, num, reductions, t );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REQUIRE( presolveStatus == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( presolveStatus == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "should_return_feasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++TEST_CASE( "should_return_infeasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Message msg {};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Timer t{ time };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Problem<double> problem = setupProblemWithSimpleSubstitutionFeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Problem<double> problem = setupProblemWithSimpleSubstitutionInfeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Statistics statistics{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    PresolveOptions presolveOptions{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    presolveOptions.dualreds = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -263,16 +314,20 @@ TEST_CASE( "should_return_feasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    PresolveStatus presolveStatus =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        presolvingMethod.execute( problem, problemUpdate, num, reductions, t );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REQUIRE( presolveStatus == PresolveStatus::kUnchanged );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   REQUIRE( presolveStatus == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-TEST_CASE( "should_return_infeasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++PresolveStatus
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++check_gcd_result_with_expectation( double x, double y, double rhs, double coef1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double coef2, double lb1, double ub1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double lb2, double ub2 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Message msg {};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    double time = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Timer t{ time };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Problem<double> problem = setupProblemWithSimpleSubstitutionInfeasibleGcd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Problem<double> problem = setupProblemWithInfeasibleBounds(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       x, y, rhs, coef1, coef2, lb1, ub1, lb2, ub2 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Statistics statistics{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    PresolveOptions presolveOptions{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    presolveOptions.dualreds = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -284,30 +339,27 @@ TEST_CASE( "should_return_infeasible_if_gcd_of_coeff_is_in_rhs", "[presolve]" )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Reductions<double> reductions{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    problem.recomputeAllActivities();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   PresolveStatus presolveStatus =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        presolvingMethod.execute( problem, problemUpdate, num, reductions, t );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   REQUIRE( presolveStatus == PresolveStatus::kInfeasible );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Problem<double>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-setupProblemWithSimpleSubstitution( uint8_t is_x_integer, uint8_t is_y_integer,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                    double a_y )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++setupProblemWithInfeasibleBounds( double x, double y, double rhs, double coef1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double coef2, double lb1, double ub1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  double lb2, double ub2 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   // 2x + y = 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   // 0<= x,y y= 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> coefficients{ 3.0, 1.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> upperBounds{ 3.0, 3.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> lowerBounds{ 0.0, 0.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<uint8_t> isIntegral{ is_x_integer, is_y_integer };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> coefficients{ x, y };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> upperBounds{ ub1, ub2 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> lowerBounds{ lb1, lb2 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<uint8_t> isIntegral{ 1, 1 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> rhs{ 4.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> rhs_values{ rhs };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::string> rowNames{ "A1" };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::string> columnNames{ "c1", "c2" };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::tuple<int, int, double>> entries{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       std::tuple<int, int, double>{ 0, 0, 2.0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       std::tuple<int, int, double>{ 0, 1, a_y },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       std::tuple<int, int, double>{ 0, 0, coef1 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       std::tuple<int, int, double>{ 0, 1, coef2 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ProblemBuilder<double> pb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -319,49 +371,50 @@ setupProblemWithSimpleSubstitution( uint8_t is_x_integer, uint8_t is_y_integer,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setObjAll( coefficients );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setObjOffset( 0.0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColIntegralAll( isIntegral );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setRowRhsAll( rhs );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setRowRhsAll( rhs_values );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.addEntryAll( entries );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColNameAll( columnNames );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setProblemName( "matrix for testing simple probing" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setProblemName( "example 10.1 in Constraint Integer Programming" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Problem<double> problem = pb.build();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   problem.getConstraintMatrix().modifyLeftHandSide( 0,num, rhs[0] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   problem.getConstraintMatrix().modifyLeftHandSide( 0,num, rhs );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return problem;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Problem<double>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-setupProblemWithInfeasibleBounds( double x, double y, double rhs )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++setupProblemWithSimpleSubstitution( uint8_t is_x_integer, uint8_t is_y_integer,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                    double a_y )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   // 3x + 8y = 37
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   // 0<= x,y y= 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 2x + y = 4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   // 0<= x,y y= 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Num<double> num{};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> coefficients{ x, y };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> upperBounds{ 5.0, 5.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> coefficients{ 3.0, 1.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> upperBounds{ 3.0, 3.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<double> lowerBounds{ 0.0, 0.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<uint8_t> isIntegral{ 1, 1 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<uint8_t> isIntegral{ is_x_integer, is_y_integer };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   Vec<double> rhs_values{ rhs };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   Vec<double> rhs{ 4.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::string> rowNames{ "A1" };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::string> columnNames{ "c1", "c2" };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Vec<std::tuple<int, int, double>> entries{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       std::tuple<int, int, double>{ 0, 0, 3.0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       std::tuple<int, int, double>{ 0, 1, 8.0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       std::tuple<int, int, double>{ 0, 0, 2.0 },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       std::tuple<int, int, double>{ 0, 1, a_y },
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ProblemBuilder<double> pb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.reserve( entries.size(), rowNames.size(), columnNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setNumRows( rowNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setNumCols( columnNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.reserve( (int) entries.size(), (int) rowNames.size(), (int) columnNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setNumRows( (int) rowNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setNumCols( (int) columnNames.size() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColUbAll( upperBounds );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColLbAll( lowerBounds );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setObjAll( coefficients );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setObjOffset( 0.0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColIntegralAll( isIntegral );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setRowRhsAll( rhs_values );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setRowRhsAll( rhs );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.addEntryAll( entries );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    pb.setColNameAll( columnNames );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   pb.setProblemName( "example 10.1 in Constraint Integer Programming" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   pb.setProblemName( "matrix for testing simple probing" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Problem<double> problem = pb.build();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   problem.getConstraintMatrix().modifyLeftHandSide( 0,num, rhs );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   problem.getConstraintMatrix().modifyLeftHandSide( 0,num, rhs[0] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return problem;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span></pre><pre style='margin:0'>

</pre>