1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   cons_linear.c
26   	 * @ingroup DEFPLUGINS_CONS
27   	 * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
28   	 * @author Tobias Achterberg
29   	 * @author Timo Berthold
30   	 * @author Marc Pfetsch
31   	 * @author Kati Wolter
32   	 * @author Michael Winkler
33   	 * @author Gerald Gamrath
34   	 * @author Domenico Salvagnin
35   	 *
36   	 *  Linear constraints are separated with a high priority, because they are easy
37   	 *  to separate. Instead of using the global cut pool, the same effect can be
38   	 *  implemented by adding linear constraints to the root node, such that they are
39   	 *  separated each time, the linear constraints are separated. A constraint
40   	 *  handler, which generates linear constraints in this way should have a lower
41   	 *  separation priority than the linear constraint handler, and it should have a
42   	 *  separation frequency that is a multiple of the frequency of the linear
43   	 *  constraint handler. In this way, it can be avoided to separate the same cut
44   	 *  twice, because if a separation run of the handler is always preceded by a
45   	 *  separation of the linear constraints, the priorily added constraints are
46   	 *  always satisfied.
47   	 *
48   	 *  Linear constraints are enforced and checked with a very low priority. Checking
49   	 *  of (many) linear constraints is much more involved than checking the solution
50   	 *  values for integrality. Because we are separating the linear constraints quite
51   	 *  often, it is only necessary to enforce them for integral solutions. A constraint
52   	 *  handler which generates pool cuts in its enforcing method should have an
53   	 *  enforcing priority smaller than that of the linear constraint handler to avoid
54   	 *  regenerating constraints which already exist.
55   	 */
56   	
57   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
58   	
59   	#include "blockmemshell/memory.h"
60   	#include "scip/cons_nonlinear.h"
61   	#include "scip/cons_knapsack.h"
62   	#include "scip/cons_linear.h"
63   	#include "scip/debug.h"
64   	#include "scip/pub_conflict.h"
65   	#include "scip/pub_cons.h"
66   	#include "scip/pub_event.h"
67   	#include "scip/pub_expr.h"
68   	#include "scip/pub_lp.h"
69   	#include "scip/pub_message.h"
70   	#include "scip/pub_misc.h"
71   	#include "scip/pub_misc_sort.h"
72   	#include "scip/pub_var.h"
73   	#include "scip/scip_branch.h"
74   	#include "scip/scip_conflict.h"
75   	#include "scip/scip_cons.h"
76   	#include "scip/scip_copy.h"
77   	#include "scip/scip_cut.h"
78   	#include "scip/scip_event.h"
79   	#include "scip/scip_general.h"
80   	#include "scip/scip_lp.h"
81   	#include "scip/scip_mem.h"
82   	#include "scip/scip_message.h"
83   	#include "scip/scip_numerics.h"
84   	#include "scip/scip_param.h"
85   	#include "scip/scip_prob.h"
86   	#include "scip/scip_probing.h"
87   	#include "scip/scip_sol.h"
88   	#include "scip/scip_solvingstats.h"
89   	#include "scip/scip_tree.h"
90   	#include "scip/scip_var.h"
91   	#include "scip/symmetry_graph.h"
92   	#include "symmetry/struct_symmetry.h"
93   	#include "scip/dbldblarith.h"
94   	
95   	
96   	#define CONSHDLR_NAME          "linear"
97   	#define CONSHDLR_DESC          "linear constraints of the form  lhs <= a^T x <= rhs"
98   	#define CONSHDLR_SEPAPRIORITY   +100000 /**< priority of the constraint handler for separation */
99   	#define CONSHDLR_ENFOPRIORITY  -1000000 /**< priority of the constraint handler for constraint enforcing */
100  	#define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
101  	#define CONSHDLR_SEPAFREQ             0 /**< frequency for separating cuts; zero means to separate only in the root node */
102  	#define CONSHDLR_PROPFREQ             1 /**< frequency for propagating domains; zero means only preprocessing propagation */
103  	#define CONSHDLR_EAGERFREQ          100 /**< frequency for using all instead of only the useful constraints in separation,
104  	                                         *   propagation and enforcement, -1 for no eager evaluations, 0 for first only */
105  	#define CONSHDLR_MAXPREROUNDS        -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
106  	#define CONSHDLR_DELAYSEPA        FALSE /**< should separation method be delayed, if other separators found cuts? */
107  	#define CONSHDLR_DELAYPROP        FALSE /**< should propagation method be delayed, if other propagators found reductions? */
108  	#define CONSHDLR_NEEDSCONS         TRUE /**< should the constraint handler be skipped, if no constraints are available? */
109  	
110  	#define CONSHDLR_PRESOLTIMING    (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
111  	#define CONSHDLR_PROP_TIMING     SCIP_PROPTIMING_BEFORELP
112  	
113  	#define EVENTHDLR_NAME         "linear"
114  	#define EVENTHDLR_DESC         "bound change event handler for linear constraints"
115  	
116  	#define CONFLICTHDLR_NAME      "linear"
117  	#define CONFLICTHDLR_DESC      "conflict handler creating linear constraints"
118  	#define CONFLICTHDLR_PRIORITY  -1000000
119  	
120  	#define DEFAULT_TIGHTENBOUNDSFREQ       1 /**< multiplier on propagation frequency, how often the bounds are tightened */
121  	#define DEFAULT_MAXROUNDS               5 /**< maximal number of separation rounds per node (-1: unlimited) */
122  	#define DEFAULT_MAXROUNDSROOT          -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
123  	#define DEFAULT_MAXSEPACUTS            50 /**< maximal number of cuts separated per separation round */
124  	#define DEFAULT_MAXSEPACUTSROOT       200 /**< maximal number of cuts separated per separation round in root node */
125  	#define DEFAULT_PRESOLPAIRWISE       TRUE /**< should pairwise constraint comparison be performed in presolving? */
126  	#define DEFAULT_PRESOLUSEHASHING     TRUE /**< should hash table be used for detecting redundant constraints in advance */
127  	#define DEFAULT_NMINCOMPARISONS    200000 /**< number for minimal pairwise presolving comparisons */
128  	#define DEFAULT_MINGAINPERNMINCOMP  1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
129  	                                           *   comparison round */
130  	#define DEFAULT_SORTVARS             TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
131  	                                           *  propagation? */
132  	#define DEFAULT_CHECKRELMAXABS      FALSE /**< should the violation for a constraint with side 0.0 be checked relative
133  	                                           *   to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
134  	#define DEFAULT_MAXAGGRNORMSCALE      0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
135  	                                           *   (0.0: disable constraint aggregation) */
136  	#define DEFAULT_MAXEASYACTIVITYDELTA  1e6 /**< maximum activity delta to run easy propagation on linear constraint
137  	                                           *   (faster, but numerically less stable) */
138  	#define DEFAULT_MAXCARDBOUNDDIST      0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
139  	                                           *   to best node's dual bound for separating knapsack cardinality cuts */
140  	#define DEFAULT_SEPARATEALL         FALSE /**< should all constraints be subject to cardinality cut generation instead of only
141  	                                           *   the ones with non-zero dual value? */
142  	#define DEFAULT_AGGREGATEVARIABLES   TRUE /**< should presolving search for redundant variables in equations */
143  	#define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
144  	#define DEFAULT_DUALPRESOLVING       TRUE /**< should dual presolving steps be performed? */
145  	#define DEFAULT_SINGLETONSTUFFING    TRUE /**< should stuffing of singleton continuous variables be performed? */
146  	#define DEFAULT_SINGLEVARSTUFFING   FALSE /**< should single variable stuffing be performed, which tries to fulfill
147  	                                           *   constraints using the cheapest variable? */
148  	#define DEFAULT_DETECTCUTOFFBOUND    TRUE /**< should presolving try to detect constraints parallel to the objective
149  	                                           *   function defining an upper bound and prevent these constraints from
150  	                                           *   entering the LP */
151  	#define DEFAULT_DETECTLOWERBOUND     TRUE /**< should presolving try to detect constraints parallel to the objective
152  	                                           *   function defining a lower bound and prevent these constraints from
153  	                                           *   entering the LP */
154  	#define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
155  	                                            *   objective function */
156  	#define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
157  	#define DEFAULT_RANGEDROWARTCONS     TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
158  	#define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
159  	#define DEFAULT_RANGEDROWFREQ           1 /**< frequency for applying ranged row propagation */
160  	
161  	#define DEFAULT_MULTAGGRREMOVE      FALSE /**< should multi-aggregations only be performed if the constraint can be
162  	                                           *   removed afterwards? */
163  	#define DEFAULT_MAXMULTAGGRQUOT     1e+03 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
164  	#define DEFAULT_MAXDUALMULTAGGRQUOT 1e+20 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
165  	#define DEFAULT_EXTRACTCLIQUES       TRUE /**< should cliques be extracted? */
166  	
167  	#define MAXDNOM                   10000LL /**< maximal denominator for simple rational fixed values */
168  	#define MAXSCALEDCOEF                   0 /**< maximal coefficient value after scaling */
169  	#define MAXSCALEDCOEFINTEGER            0 /**< maximal coefficient value after scaling if all variables are of integral
170  	                                           *   type
171  	                                           */
172  	#define MAXACTVAL                   1e+09 /**< maximal absolute value of full and partial activities such that
173  	                                           *   redundancy-based simplifications are allowed to be applied
174  	                                           */
175  	
176  	#define MAXVALRECOMP                1e+06 /**< maximal abolsute value we trust without recomputing the activity */
177  	#define MINVALRECOMP                1e-05 /**< minimal abolsute value we trust without recomputing the activity */
178  	
179  	
180  	#define NONLINCONSUPGD_PRIORITY   1000000 /**< priority of the constraint handler for upgrading of expressions constraints */
181  	
182  	/* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
183  	 *       maybe in fullDualPresolve(), see convertLongEquality()
184  	 */
185  	
186  	
187  	/** constraint data for linear constraints */
188  	struct SCIP_ConsData
189  	{
190  	   SCIP_Real             lhs;                /**< left hand side of row (for ranged rows) */
191  	   SCIP_Real             rhs;                /**< right hand side of row */
192  	   SCIP_Real             maxabsval;          /**< maximum absolute value of all coefficients */
193  	   SCIP_Real             minabsval;          /**< minimal absolute value of all coefficients */
194  	   QUAD_MEMBER(SCIP_Real minactivity);       /**< minimal value w.r.t. the variable's local bounds for the constraint's
195  	                                              *   activity, ignoring the coefficients contributing with infinite value */
196  	   QUAD_MEMBER(SCIP_Real maxactivity);       /**< maximal value w.r.t. the variable's local bounds for the constraint's
197  	                                              *   activity, ignoring the coefficients contributing with infinite value */
198  	   SCIP_Real             lastminactivity;    /**< last minimal activity which was computed by complete summation
199  	                                              *   over all contributing values */
200  	   SCIP_Real             lastmaxactivity;    /**< last maximal activity which was computed by complete summation
201  	                                              *   over all contributing values */
202  	   QUAD_MEMBER(SCIP_Real glbminactivity);    /**< minimal value w.r.t. the variable's global bounds for the constraint's
203  	                                              *   activity, ignoring the coefficients contributing with infinite value */
204  	   QUAD_MEMBER(SCIP_Real glbmaxactivity);    /**< maximal value w.r.t. the variable's global bounds for the constraint's
205  	                                              *   activity, ignoring the coefficients contributing with infinite value */
206  	   SCIP_Real             lastglbminactivity; /**< last global minimal activity which was computed by complete summation
207  	                                              *   over all contributing values */
208  	   SCIP_Real             lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
209  	                                              *   over all contributing values */
210  	   SCIP_Real             maxactdelta;        /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
211  	   SCIP_VAR*             maxactdeltavar;     /**< variable with maximal activity contribution, or NULL if invalid */
212  	   uint64_t              possignature;       /**< bit signature of coefficients that may take a positive value */
213  	   uint64_t              negsignature;       /**< bit signature of coefficients that may take a negative value */
214  	   SCIP_ROW*             row;                /**< LP row, if constraint is already stored in LP row format */
215  	   SCIP_NLROW*           nlrow;              /**< NLP row, if constraint has been added to NLP relaxation */
216  	   SCIP_VAR**            vars;               /**< variables of constraint entries */
217  	   SCIP_Real*            vals;               /**< coefficients of constraint entries */
218  	   SCIP_EVENTDATA**      eventdata;          /**< event data for bound change events of the variables */
219  	   int                   minactivityneginf;  /**< number of coefficients contributing with neg. infinite value to minactivity */
220  	   int                   minactivityposinf;  /**< number of coefficients contributing with pos. infinite value to minactivity */
221  	   int                   maxactivityneginf;  /**< number of coefficients contributing with neg. infinite value to maxactivity */
222  	   int                   maxactivityposinf;  /**< number of coefficients contributing with pos. infinite value to maxactivity */
223  	   int                   minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
224  	   int                   minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
225  	   int                   maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
226  	   int                   maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
227  	   int                   glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
228  	   int                   glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
229  	   int                   glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
230  	   int                   glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
231  	   int                   glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
232  	   int                   glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
233  	   int                   glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
234  	   int                   glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
235  	   int                   varssize;           /**< size of the vars- and vals-arrays */
236  	   int                   nvars;              /**< number of nonzeros in constraint */
237  	   int                   nbinvars;           /**< the number of binary variables in the constraint, only valid after
238  	                                              *   sorting in stage >= SCIP_STAGE_INITSOLVE
239  	                                              */
240  	   unsigned int          boundstightened:2;  /**< is constraint already propagated with bound tightening? */
241  	   unsigned int          rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
242  	                                                 *   (0: no, 1: yes, 2: with potentially adding artificial constraint */
243  	   unsigned int          validmaxabsval:1;   /**< is the maximum absolute value valid? */
244  	   unsigned int          validminabsval:1;   /**< is the minimum absolute value valid? */
245  	   unsigned int          validactivities:1;  /**< are the activity bounds (local and global) valid? */
246  	   unsigned int          validminact:1;      /**< is the local minactivity valid? */
247  	   unsigned int          validmaxact:1;      /**< is the local maxactivity valid? */
248  	   unsigned int          validglbminact:1;   /**< is the global minactivity valid? */
249  	   unsigned int          validglbmaxact:1;   /**< is the global maxactivity valid? */
250  	   unsigned int          presolved:1;        /**< is constraint already presolved? */
251  	   unsigned int          removedfixings:1;   /**< are all fixed variables removed from the constraint? */
252  	   unsigned int          validsignature:1;   /**< is the bit signature valid? */
253  	   unsigned int          changed:1;          /**< was constraint changed since last aggregation round in preprocessing? */
254  	   unsigned int          normalized:1;       /**< is the constraint in normalized form? */
255  	   unsigned int          upgradetried:1;     /**< was the constraint already tried to be upgraded? */
256  	   unsigned int          upgraded:1;         /**< is the constraint upgraded and will it be removed after preprocessing? */
257  	   unsigned int          indexsorted:1;      /**< are the constraint's variables sorted by type and index? */
258  	   unsigned int          merged:1;           /**< are the constraint's equal variables already merged? */
259  	   unsigned int          cliquesadded:1;     /**< were the cliques of the constraint already extracted? */
260  	   unsigned int          implsadded:1;       /**< were the implications of the constraint already extracted? */
261  	   unsigned int          coefsorted:1;       /**< are variables sorted by type and their absolute activity delta? */
262  	   unsigned int          varsdeleted:1;      /**< were variables deleted after last cleanup? */
263  	   unsigned int          hascontvar:1;       /**< does the constraint contain at least one continuous variable? */
264  	   unsigned int          hasnonbinvar:1;     /**< does the constraint contain at least one non-binary variable? */
265  	   unsigned int          hasnonbinvalid:1;   /**< is the information stored in hasnonbinvar and hascontvar valid? */
266  	   unsigned int          checkabsolute:1;    /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
267  	};
268  	
269  	/** event data for bound change event */
270  	struct SCIP_EventData
271  	{
272  	   SCIP_CONS*            cons;               /**< linear constraint to process the bound change for */
273  	   int                   varpos;             /**< position of variable in vars array */
274  	   int                   filterpos;          /**< position of event in variable's event filter */
275  	};
276  	
277  	/** constraint handler data */
278  	struct SCIP_ConshdlrData
279  	{
280  	   SCIP_EVENTHDLR*       eventhdlr;          /**< event handler for bound change events */
281  	   SCIP_LINCONSUPGRADE** linconsupgrades;    /**< linear constraint upgrade methods for specializing linear constraints */
282  	   SCIP_Real             maxaggrnormscale;   /**< maximal allowed relative gain in maximum norm for constraint aggregation
283  	                                              *   (0.0: disable constraint aggregation) */
284  	   SCIP_Real             maxcardbounddist;   /**< maximal relative distance from current node's dual bound to primal bound compared
285  	                                              *   to best node's dual bound for separating knapsack cardinality cuts */
286  	   SCIP_Real             mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
287  	   SCIP_Real             maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
288  	                                               *   (faster, but numerically less stable) */
289  	   int                   linconsupgradessize;/**< size of linconsupgrade array */
290  	   int                   nlinconsupgrades;   /**< number of linear constraint upgrade methods */
291  	   int                   tightenboundsfreq;  /**< multiplier on propagation frequency, how often the bounds are tightened */
292  	   int                   maxrounds;          /**< maximal number of separation rounds per node (-1: unlimited) */
293  	   int                   maxroundsroot;      /**< maximal number of separation rounds in the root node (-1: unlimited) */
294  	   int                   maxsepacuts;        /**< maximal number of cuts separated per separation round */
295  	   int                   maxsepacutsroot;    /**< maximal number of cuts separated per separation round in root node */
296  	   int                   nmincomparisons;    /**< number for minimal pairwise presolving comparisons */
297  	   int                   naddconss;          /**< number of added constraints */
298  	   SCIP_Bool             presolpairwise;     /**< should pairwise constraint comparison be performed in presolving? */
299  	   SCIP_Bool             presolusehashing;   /**< should hash table be used for detecting redundant constraints in advance */
300  	   SCIP_Bool             separateall;        /**< should all constraints be subject to cardinality cut generation instead of only
301  	                                              *   the ones with non-zero dual value? */
302  	   SCIP_Bool             aggregatevariables; /**< should presolving search for redundant variables in equations */
303  	   SCIP_Bool             simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
304  	   SCIP_Bool             dualpresolving;     /**< should dual presolving steps be performed? */
305  	   SCIP_Bool             singletonstuffing;  /**< should stuffing of singleton continuous variables be performed? */
306  	   SCIP_Bool             singlevarstuffing;  /**< should single variable stuffing be performed, which tries to fulfill
307  	                                              *   constraints using the cheapest variable? */
308  	   SCIP_Bool             sortvars;           /**< should binary variables be sorted for faster propagation? */
309  	   SCIP_Bool             checkrelmaxabs;     /**< should the violation for a constraint with side 0.0 be checked relative
310  	                                              *   to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
311  	   SCIP_Bool             detectcutoffbound;  /**< should presolving try to detect constraints parallel to the objective
312  	                                              *   function defining an upper bound and prevent these constraints from
313  	                                              *   entering the LP */
314  	   SCIP_Bool             detectlowerbound;   /**< should presolving try to detect constraints parallel to the objective
315  	                                              *   function defining a lower bound and prevent these constraints from
316  	                                              *   entering the LP */
317  	   SCIP_Bool             detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
318  	                                                 *   the objective function */
319  	   SCIP_Bool             rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
320  	                                               *   infeasibility, and extract sub-constraints from ranged rows and
321  	                                               *   equations */
322  	   SCIP_Bool             rangedrowartcons;   /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
323  	   int                   rangedrowmaxdepth;  /**< maximum depth to apply ranged row propagation */
324  	   int                   rangedrowfreq;      /**< frequency for applying ranged row propagation */
325  	   SCIP_Bool             multaggrremove;     /**< should multi-aggregations only be performed if the constraint can be
326  	                                              *   removed afterwards? */
327  	   SCIP_Real             maxmultaggrquot;    /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
328  	   SCIP_Real             maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
329  	   SCIP_Bool             extractcliques;     /**< should cliques be extracted? */
330  	};
331  	
332  	/** linear constraint update method */
333  	struct SCIP_LinConsUpgrade
334  	{
335  	   SCIP_DECL_LINCONSUPGD((*linconsupgd));    /**< method to call for upgrading linear constraint */
336  	   int                   priority;           /**< priority of upgrading method */
337  	   SCIP_Bool             active;             /**< is upgrading enabled */
338  	};
339  	
340  	
341  	/*
342  	 * Propagation rules
343  	 */
344  	
345  	enum Proprule
346  	{
347  	   PROPRULE_1_RHS        = 1,                /**< activity residuals of all other variables tighten bounds of single
348  	                                              *   variable due to the right hand side of the inequality */
349  	   PROPRULE_1_LHS        = 2,                /**< activity residuals of all other variables tighten bounds of single
350  	                                              *   variable due to the left hand side of the inequality */
351  	   PROPRULE_1_RANGEDROW  = 3,                /**< fixed variables and gcd of all left variables tighten bounds of a
352  						      *   single variable in this reanged row */
353  	   PROPRULE_INVALID      = 0                 /**< propagation was applied without a specific propagation rule */
354  	};
355  	typedef enum Proprule PROPRULE;
356  	
357  	/** inference information */
358  	struct InferInfo
359  	{
360  	   union
361  	   {
362  	      struct
363  	      {
364  	         unsigned int    proprule:8;         /**< propagation rule that was applied */
365  	         unsigned int    pos:24;             /**< variable position, the propagation rule was applied at */
366  	      } asbits;
367  	      int                asint;              /**< inference information as a single int value */
368  	   } val;
369  	};
370  	typedef struct InferInfo INFERINFO;
371  	
372  	/** converts an integer into an inference information */
373  	static
374  	INFERINFO intToInferInfo(
375  	   int                   i                   /**< integer to convert */
376  	   )
377  	{
378  	   INFERINFO inferinfo;
379  	
380  	   inferinfo.val.asint = i;
381  	
382  	   return inferinfo;
383  	}
384  	
385  	/** converts an inference information into an int */
386  	static
387  	int inferInfoToInt(
388  	   INFERINFO             inferinfo           /**< inference information to convert */
389  	   )
390  	{
391  	   return inferinfo.val.asint;
392  	}
393  	
394  	/** returns the propagation rule stored in the inference information */
395  	static
396  	int inferInfoGetProprule(
397  	   INFERINFO             inferinfo           /**< inference information to convert */
398  	   )
399  	{
400  	   return (int) inferinfo.val.asbits.proprule;
401  	}
402  	
403  	/** returns the position stored in the inference information */
404  	static
405  	int inferInfoGetPos(
406  	   INFERINFO             inferinfo           /**< inference information to convert */
407  	   )
408  	{
409  	   return (int) inferinfo.val.asbits.pos;
410  	}
411  	
412  	/** constructs an inference information out of a propagation rule and a position number */
413  	static
414  	INFERINFO getInferInfo(
415  	   PROPRULE              proprule,           /**< propagation rule that deduced the value */
416  	   int                   pos                 /**< variable position, the propagation rule was applied at */
417  	   )
418  	{
419  	   INFERINFO inferinfo;
420  	
421  	   assert(pos >= 0);
422  	   /* in the inferinfo struct only 24 bits for 'pos' are reserved */
423  	   assert(pos < (1<<24));
424  	
425  	   inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
426  	   inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
427  	
428  	   return inferinfo;
429  	}
430  	
431  	/** constructs an inference information out of a propagation rule and a position number, returns info as int */
432  	static
433  	int getInferInt(
434  	   PROPRULE              proprule,           /**< propagation rule that deduced the value */
435  	   int                   pos                 /**< variable position, the propagation rule was applied at */
436  	   )
437  	{
438  	   return inferInfoToInt(getInferInfo(proprule, pos));
439  	}
440  	
441  	
442  	/*
443  	 * memory growing methods for dynamically allocated arrays
444  	 */
445  	
446  	/** ensures, that linconsupgrades array can store at least num entries */
447  	static
448  	SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(
449  	   SCIP*                 scip,               /**< SCIP data structure */
450  	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< linear constraint handler data */
451  	   int                   num                 /**< minimum number of entries to store */
452  	   )
453  	{
454  	   assert(scip != NULL);
455  	   assert(conshdlrdata != NULL);
456  	   assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
457  	
458  	   if( num > conshdlrdata->linconsupgradessize )
459  	   {
460  	      int newsize;
461  	
462  	      newsize = SCIPcalcMemGrowSize(scip, num);
463  	      SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
464  	      conshdlrdata->linconsupgradessize = newsize;
465  	   }
466  	   assert(num <= conshdlrdata->linconsupgradessize);
467  	
468  	   return SCIP_OKAY;
469  	}
470  	
471  	/** ensures, that vars and vals arrays can store at least num entries */
472  	static
473  	SCIP_RETCODE consdataEnsureVarsSize(
474  	   SCIP*                 scip,               /**< SCIP data structure */
475  	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
476  	   int                   num                 /**< minimum number of entries to store */
477  	   )
478  	{
479  	   assert(scip != NULL);
480  	   assert(consdata != NULL);
481  	   assert(consdata->nvars <= consdata->varssize);
482  	
483  	   if( num > consdata->varssize )
484  	   {
485  	      int newsize;
486  	
487  	      newsize = SCIPcalcMemGrowSize(scip, num);
488  	      SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
489  	      SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
490  	      if( consdata->eventdata != NULL )
491  	      {
492  	         SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
493  	      }
494  	      consdata->varssize = newsize;
495  	   }
496  	   assert(num <= consdata->varssize);
497  	
498  	   return SCIP_OKAY;
499  	}
500  	
501  	
502  	/*
503  	 * local methods for managing linear constraint update methods
504  	 */
505  	
506  	/** creates a linear constraint upgrade data object */
507  	static
508  	SCIP_RETCODE linconsupgradeCreate(
509  	   SCIP*                 scip,               /**< SCIP data structure */
510  	   SCIP_LINCONSUPGRADE** linconsupgrade,     /**< pointer to store the linear constraint upgrade */
511  	   SCIP_DECL_LINCONSUPGD((*linconsupgd)),    /**< method to call for upgrading linear constraint */
512  	   int                   priority            /**< priority of upgrading method */
513  	   )
514  	{
515  	   assert(scip != NULL);
516  	   assert(linconsupgrade != NULL);
517  	   assert(linconsupgd != NULL);
518  	
519  	   SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
520  	   (*linconsupgrade)->linconsupgd = linconsupgd;
521  	   (*linconsupgrade)->priority = priority;
522  	   (*linconsupgrade)->active = TRUE;
523  	
524  	   return SCIP_OKAY;
525  	}
526  	
527  	/** frees a linear constraint upgrade data object */
528  	static
529  	void linconsupgradeFree(
530  	   SCIP*                 scip,               /**< SCIP data structure */
531  	   SCIP_LINCONSUPGRADE** linconsupgrade      /**< pointer to the linear constraint upgrade */
532  	   )
533  	{
534  	   assert(scip != NULL);
535  	   assert(linconsupgrade != NULL);
536  	   assert(*linconsupgrade != NULL);
537  	
538  	   SCIPfreeBlockMemory(scip, linconsupgrade);
539  	}
540  	
541  	/** creates constraint handler data for linear constraint handler */
542  	static
543  	SCIP_RETCODE conshdlrdataCreate(
544  	   SCIP*                 scip,               /**< SCIP data structure */
545  	   SCIP_CONSHDLRDATA**   conshdlrdata,       /**< pointer to store the constraint handler data */
546  	   SCIP_EVENTHDLR*       eventhdlr           /**< event handler */
547  	   )
548  	{
549  	   assert(scip != NULL);
550  	   assert(conshdlrdata != NULL);
551  	   assert(eventhdlr != NULL);
552  	
553  	   SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
554  	   (*conshdlrdata)->linconsupgrades = NULL;
555  	   (*conshdlrdata)->linconsupgradessize = 0;
556  	   (*conshdlrdata)->nlinconsupgrades = 0;
557  	   (*conshdlrdata)->naddconss = 0;
558  	
559  	   /* set event handler for updating linear constraint activity bounds */
560  	   (*conshdlrdata)->eventhdlr = eventhdlr;
561  	
562  	   return SCIP_OKAY;
563  	}
564  	
565  	/** frees constraint handler data for linear constraint handler */
566  	static
567  	void conshdlrdataFree(
568  	   SCIP*                 scip,               /**< SCIP data structure */
569  	   SCIP_CONSHDLRDATA**   conshdlrdata        /**< pointer to the constraint handler data */
570  	   )
571  	{
572  	   int i;
573  	
574  	   assert(scip != NULL);
575  	   assert(conshdlrdata != NULL);
576  	   assert(*conshdlrdata != NULL);
577  	
578  	   for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
579  	   {
580  	      linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
581  	   }
582  	   SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
583  	
584  	   SCIPfreeBlockMemory(scip, conshdlrdata);
585  	}
586  	
587  	/** creates a linear constraint upgrade data object */
588  	static
589  	SCIP_Bool conshdlrdataHasUpgrade(
590  	   SCIP*                 scip,               /**< SCIP data structure */
591  	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< constraint handler data */
592  	   SCIP_DECL_LINCONSUPGD((*linconsupgd)),    /**< method to call for upgrading linear constraint */
593  	   const char*           conshdlrname        /**< name of the constraint handler */
594  	   )
595  	{
596  	   int i;
597  	
598  	   assert(scip != NULL);
599  	   assert(conshdlrdata != NULL);
600  	   assert(linconsupgd != NULL);
601  	   assert(conshdlrname != NULL);
602  	
603  	   for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
604  	   {
605  	      if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
606  	      {
607  	#ifdef SCIP_DEBUG
608  	         SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
609  	#endif
610  	         return TRUE;
611  	      }
612  	   }
613  	
614  	   return FALSE;
615  	}
616  	
617  	/** adds a linear constraint update method to the constraint handler's data */
618  	static
619  	SCIP_RETCODE conshdlrdataIncludeUpgrade(
620  	   SCIP*                 scip,               /**< SCIP data structure */
621  	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< constraint handler data */
622  	   SCIP_LINCONSUPGRADE*  linconsupgrade      /**< linear constraint upgrade method */
623  	   )
624  	{
625  	   int i;
626  	
627  	   assert(scip != NULL);
628  	   assert(conshdlrdata != NULL);
629  	   assert(linconsupgrade != NULL);
630  	
631  	   SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
632  	
633  	   for( i = conshdlrdata->nlinconsupgrades;
634  	        i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
635  	   {
636  	      conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
637  	   }
638  	   assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
639  	   conshdlrdata->linconsupgrades[i] = linconsupgrade;
640  	   conshdlrdata->nlinconsupgrades++;
641  	
642  	   return SCIP_OKAY;
643  	}
644  	
645  	/*
646  	 * local methods
647  	 */
648  	
649  	/** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
650  	static
651  	SCIP_RETCODE lockRounding(
652  	   SCIP*                 scip,               /**< SCIP data structure */
653  	   SCIP_CONS*            cons,               /**< linear constraint */
654  	   SCIP_VAR*             var,                /**< variable of constraint entry */
655  	   SCIP_Real             val                 /**< coefficient of constraint entry */
656  	   )
657  	{
658  	   SCIP_CONSDATA* consdata;
659  	
660  	   assert(scip != NULL);
661  	   assert(cons != NULL);
662  	   assert(var != NULL);
663  	
664  	   consdata = SCIPconsGetData(cons);
665  	   assert(consdata != NULL);
666  	   assert(!SCIPisZero(scip, val));
667  	
668  	   if( SCIPisPositive(scip, val) )
669  	   {
670  	      SCIP_CALL( SCIPlockVarCons(scip, var, cons,
671  	         !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
672  	   }
673  	   else
674  	   {
675  	      SCIP_CALL( SCIPlockVarCons(scip, var, cons,
676  	         !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
677  	   }
678  	
679  	   return SCIP_OKAY;
680  	}
681  	
682  	/** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
683  	static
684  	SCIP_RETCODE unlockRounding(
685  	   SCIP*                 scip,               /**< SCIP data structure */
686  	   SCIP_CONS*            cons,               /**< linear constraint */
687  	   SCIP_VAR*             var,                /**< variable of constraint entry */
688  	   SCIP_Real             val                 /**< coefficient of constraint entry */
689  	   )
690  	{
691  	   SCIP_CONSDATA* consdata;
692  	
693  	   assert(scip != NULL);
694  	   assert(cons != NULL);
695  	   assert(var != NULL);
696  	
697  	   consdata = SCIPconsGetData(cons);
698  	   assert(consdata != NULL);
699  	   assert(!SCIPisZero(scip, val));
700  	
701  	   if( SCIPisPositive(scip, val) )
702  	   {
703  	      SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, -consdata->lhs),
704  	         !SCIPisInfinity(scip, consdata->rhs)) );
705  	   }
706  	   else
707  	   {
708  	      SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, consdata->rhs),
709  	         !SCIPisInfinity(scip, -consdata->lhs)) );
710  	   }
711  	
712  	   return SCIP_OKAY;
713  	}
714  	
715  	/** creates event data for variable at given position, and catches events */
716  	/**! [SnippetDebugAssertions] */
717  	static
718  	SCIP_RETCODE consCatchEvent(
719  	   SCIP*                 scip,               /**< SCIP data structure */
720  	   SCIP_CONS*            cons,               /**< linear constraint */
721  	   SCIP_EVENTHDLR*       eventhdlr,          /**< event handler to call for the event processing */
722  	   int                   pos                 /**< array position of variable to catch bound change events for */
723  	   )
724  	{
725  	   SCIP_CONSDATA* consdata;
726  	   assert(scip != NULL);
727  	   assert(cons != NULL);
728  	   assert(eventhdlr != NULL);
729  	
730  	   consdata = SCIPconsGetData(cons);
731  	   assert(consdata != NULL);
732  	
733  	   assert(0 <= pos && pos < consdata->nvars);
734  	   assert(consdata->vars != NULL);
735  	   assert(consdata->vars[pos] != NULL);
736  	   assert(SCIPvarIsTransformed(consdata->vars[pos]));
737  	   assert(consdata->eventdata != NULL);
738  	   assert(consdata->eventdata[pos] == NULL);
739  	
740  	   SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
741  	   consdata->eventdata[pos]->cons = cons;
742  	   consdata->eventdata[pos]->varpos = pos;
743  	
744  	   SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
745  	         SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_VARFIXED | SCIP_EVENTTYPE_VARUNLOCKED
746  	         | SCIP_EVENTTYPE_GBDCHANGED | SCIP_EVENTTYPE_VARDELETED | SCIP_EVENTTYPE_TYPECHANGED,
747  	         eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
748  	
749  	   consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
750  	
751  	   return SCIP_OKAY;
752  	}
753  	/**! [SnippetDebugAssertions] */
754  	
755  	/** deletes event data for variable at given position, and drops events */
756  	static
757  	SCIP_RETCODE consDropEvent(
758  	   SCIP*                 scip,               /**< SCIP data structure */
759  	   SCIP_CONS*            cons,               /**< linear constraint */
760  	   SCIP_EVENTHDLR*       eventhdlr,          /**< event handler to call for the event processing */
761  	   int                   pos                 /**< array position of variable to catch bound change events for */
762  	   )
763  	{
764  	   SCIP_CONSDATA* consdata;
765  	   assert(scip != NULL);
766  	   assert(cons != NULL);
767  	   assert(eventhdlr != NULL);
768  	
769  	   consdata = SCIPconsGetData(cons);
770  	   assert(consdata != NULL);
771  	
772  	   assert(0 <= pos && pos < consdata->nvars);
773  	   assert(consdata->vars[pos] != NULL);
774  	   assert(consdata->eventdata != NULL);
775  	   assert(consdata->eventdata[pos] != NULL);
776  	   assert(consdata->eventdata[pos]->cons == cons);
777  	   assert(consdata->eventdata[pos]->varpos == pos);
778  	
779  	   SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
780  	         SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_VARFIXED | SCIP_EVENTTYPE_VARUNLOCKED
781  	         | SCIP_EVENTTYPE_GBDCHANGED | SCIP_EVENTTYPE_VARDELETED | SCIP_EVENTTYPE_TYPECHANGED,
782  	         eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
783  	
784  	   SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
785  	
786  	   return SCIP_OKAY;
787  	}
788  	
789  	/** catches bound change events for all variables in transformed linear constraint */
790  	static
791  	SCIP_RETCODE consCatchAllEvents(
792  	   SCIP*                 scip,               /**< SCIP data structure */
793  	   SCIP_CONS*            cons,               /**< linear constraint */
794  	   SCIP_EVENTHDLR*       eventhdlr           /**< event handler to call for the event processing */
795  	   )
796  	{
797  	   SCIP_CONSDATA* consdata;
798  	   int i;
799  	
800  	   assert(scip != NULL);
801  	   assert(cons != NULL);
802  	
803  	   consdata = SCIPconsGetData(cons);
804  	   assert(consdata != NULL);
805  	   assert(consdata->eventdata == NULL);
806  	
807  	   /* allocate eventdata array */
808  	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
809  	   assert(consdata->eventdata != NULL);
810  	   BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
811  	
812  	   /* catch event for every single variable */
813  	   for( i = 0; i < consdata->nvars; ++i )
814  	   {
815  	      SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
816  	   }
817  	
818  	   return SCIP_OKAY;
819  	}
820  	
821  	/** drops bound change events for all variables in transformed linear constraint */
822  	static
823  	SCIP_RETCODE consDropAllEvents(
824  	   SCIP*                 scip,               /**< SCIP data structure */
825  	   SCIP_CONS*            cons,               /**< linear constraint */
826  	   SCIP_EVENTHDLR*       eventhdlr           /**< event handler to call for the event processing */
827  	   )
828  	{
829  	   SCIP_CONSDATA* consdata;
830  	   int i;
831  	
832  	   assert(scip != NULL);
833  	   assert(cons != NULL);
834  	
835  	   consdata = SCIPconsGetData(cons);
836  	   assert(consdata != NULL);
837  	   assert(consdata->eventdata != NULL);
838  	
839  	   /* drop event of every single variable */
840  	   for( i = consdata->nvars - 1; i >= 0; --i )
841  	   {
842  	      SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
843  	   }
844  	
845  	   /* free eventdata array */
846  	   SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
847  	   assert(consdata->eventdata == NULL);
848  	
849  	   return SCIP_OKAY;
850  	}
851  	
852  	/** creates a linear constraint data */
853  	static
854  	SCIP_RETCODE consdataCreate(
855  	   SCIP*                 scip,               /**< SCIP data structure */
856  	   SCIP_CONSDATA**       consdata,           /**< pointer to linear constraint data */
857  	   int                   nvars,              /**< number of nonzeros in the constraint */
858  	   SCIP_VAR**            vars,               /**< array with variables of constraint entries */
859  	   SCIP_Real*            vals,               /**< array with coefficients of constraint entries */
860  	   SCIP_Real             lhs,                /**< left hand side of row */
861  	   SCIP_Real             rhs                 /**< right hand side of row */
862  	   )
863  	{
864  	   int v;
865  	   SCIP_Real constant;
866  	
867  	   assert(scip != NULL);
868  	   assert(consdata != NULL);
869  	   assert(nvars == 0 || vars != NULL);
870  	   assert(nvars == 0 || vals != NULL);
871  	
872  	   if( SCIPisInfinity(scip, rhs) )
873  	      rhs = SCIPinfinity(scip);
874  	   else if( SCIPisInfinity(scip, -rhs) )
875  	      rhs = -SCIPinfinity(scip);
876  	
877  	   if( SCIPisInfinity(scip, -lhs) )
878  	      lhs = -SCIPinfinity(scip);
879  	   else if( SCIPisInfinity(scip, lhs) )
880  	      lhs = SCIPinfinity(scip);
881  	
882  	   if( SCIPisGT(scip, lhs, rhs) )
883  	   {
884  	      SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
885  	      SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
886  	   }
887  	
888  	   SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
889  	
890  	   (*consdata)->varssize = 0;
891  	   (*consdata)->nvars = nvars;
892  	   (*consdata)->hascontvar = FALSE;
893  	   (*consdata)->hasnonbinvar = FALSE;
894  	   (*consdata)->hasnonbinvalid = TRUE;
895  	   (*consdata)->vars = NULL;
896  	   (*consdata)->vals = NULL;
897  	
898  	   constant = 0.0;
899  	   if( nvars > 0 )
900  	   {
901  	      int k;
902  	
903  	      SCIP_VAR** varsbuffer;
904  	      SCIP_Real* valsbuffer;
905  	
906  	      /* copy variables into temporary buffer */
907  	      SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
908  	      SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
909  	      k = 0;
910  	
911  	      /* loop over variables and sort out fixed ones */
912  	      for( v = 0; v < nvars; ++v )
913  	      {
914  	         SCIP_VAR* var;
915  	         SCIP_Real val;
916  	
917  	         var = vars[v];
918  	         val = vals[v];
919  	
920  	         assert(var != NULL);
921  	         if( !SCIPisZero(scip, val) )
922  	         {
923  	            /* treat fixed variable as a constant if problem compression is enabled */
924  	            if( SCIPisConsCompressionEnabled(scip) && SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
925  	            {
926  	               constant += SCIPvarGetLbGlobal(var) * val;
927  	            }
928  	            else
929  	            {
930  	               varsbuffer[k] = var;
931  	               valsbuffer[k] = val;
932  	               k++;
933  	
934  	               /* update hascontvar and hasnonbinvar flags */
935  	               if( !(*consdata)->hascontvar )
936  	               {
937  	                  SCIP_VARTYPE vartype = SCIPvarGetType(var);
938  	
939  	                  if( vartype != SCIP_VARTYPE_BINARY )
940  	                  {
941  	                     (*consdata)->hasnonbinvar = TRUE;
942  	
943  	                     if( vartype == SCIP_VARTYPE_CONTINUOUS )
944  	                        (*consdata)->hascontvar = TRUE;
945  	                  }
946  	               }
947  	            }
948  	         }
949  	      }
950  	      (*consdata)->nvars = k;
951  	
952  	      if( k > 0 )
953  	      {
954  	         /* copy the possibly reduced buffer arrays into block */
955  	         SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
956  	         SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
957  	         (*consdata)->varssize = k;
958  	      }
959  	      /* free temporary buffer */
960  	      SCIPfreeBufferArray(scip, &valsbuffer);
961  	      SCIPfreeBufferArray(scip, &varsbuffer);
962  	   }
963  	
964  	   (*consdata)->eventdata = NULL;
965  	
966  	   /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
967  	   if( !SCIPisZero(scip, constant) )
968  	   {
969  	      if( !SCIPisInfinity(scip, REALABS(lhs)) )
970  	         lhs -= constant;
971  	
972  	      if( !SCIPisInfinity(scip, REALABS(rhs)) )
973  	         rhs -= constant;
974  	   }
975  	
976  	   (*consdata)->row = NULL;
977  	   (*consdata)->nlrow = NULL;
978  	   (*consdata)->lhs = lhs;
979  	   (*consdata)->rhs = rhs;
980  	   (*consdata)->maxabsval = SCIP_INVALID;
981  	   (*consdata)->minabsval = SCIP_INVALID;
982  	   QUAD_ASSIGN((*consdata)->minactivity, SCIP_INVALID);
983  	   QUAD_ASSIGN((*consdata)->maxactivity, SCIP_INVALID);
984  	   (*consdata)->lastminactivity = SCIP_INVALID;
985  	   (*consdata)->lastmaxactivity = SCIP_INVALID;
986  	   (*consdata)->maxactdelta = SCIP_INVALID;
987  	   (*consdata)->maxactdeltavar = NULL;
988  	   (*consdata)->minactivityneginf = -1;
989  	   (*consdata)->minactivityposinf = -1;
990  	   (*consdata)->maxactivityneginf = -1;
991  	   (*consdata)->maxactivityposinf = -1;
992  	   (*consdata)->minactivityneghuge = -1;
993  	   (*consdata)->minactivityposhuge = -1;
994  	   (*consdata)->maxactivityneghuge = -1;
995  	   (*consdata)->maxactivityposhuge = -1;
996  	   QUAD_ASSIGN((*consdata)->glbminactivity, SCIP_INVALID);
997  	   QUAD_ASSIGN((*consdata)->glbmaxactivity, SCIP_INVALID);
998  	   (*consdata)->lastglbminactivity = SCIP_INVALID;
999  	   (*consdata)->lastglbmaxactivity = SCIP_INVALID;
1000 	   (*consdata)->glbminactivityneginf = -1;
1001 	   (*consdata)->glbminactivityposinf = -1;
1002 	   (*consdata)->glbmaxactivityneginf = -1;
1003 	   (*consdata)->glbmaxactivityposinf = -1;
1004 	   (*consdata)->glbminactivityneghuge = -1;
1005 	   (*consdata)->glbminactivityposhuge = -1;
1006 	   (*consdata)->glbmaxactivityneghuge = -1;
1007 	   (*consdata)->glbmaxactivityposhuge = -1;
1008 	   (*consdata)->possignature = 0;
1009 	   (*consdata)->negsignature = 0;
1010 	   (*consdata)->validmaxabsval = FALSE;
1011 	   (*consdata)->validminabsval = FALSE;
1012 	   (*consdata)->validactivities = FALSE;
1013 	   (*consdata)->validminact = FALSE;
1014 	   (*consdata)->validmaxact = FALSE;
1015 	   (*consdata)->validglbminact = FALSE;
1016 	   (*consdata)->validglbmaxact = FALSE;
1017 	   (*consdata)->boundstightened = 0;
1018 	   (*consdata)->presolved = FALSE;
1019 	   (*consdata)->removedfixings = FALSE;
1020 	   (*consdata)->validsignature = FALSE;
1021 	   (*consdata)->changed = TRUE;
1022 	   (*consdata)->normalized = FALSE;
1023 	   (*consdata)->upgradetried = FALSE;
1024 	   (*consdata)->upgraded = FALSE;
1025 	   (*consdata)->indexsorted = (nvars <= 1);
1026 	   (*consdata)->merged = (nvars <= 1);
1027 	   (*consdata)->cliquesadded = FALSE;
1028 	   (*consdata)->implsadded = FALSE;
1029 	   (*consdata)->coefsorted = FALSE;
1030 	   (*consdata)->nbinvars = -1;
1031 	   (*consdata)->varsdeleted = FALSE;
1032 	   (*consdata)->rangedrowpropagated = 0;
1033 	   (*consdata)->checkabsolute = FALSE;
1034 	
1035 	   if( SCIPisTransformed(scip) )
1036 	   {
1037 	      /* get transformed variables */
1038 	      SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1039 	   }
1040 	
1041 	   /* capture variables */
1042 	   for( v = 0; v < (*consdata)->nvars; v++ )
1043 	   {
1044 	      /* likely implies a deleted variable */
1045 	      if( (*consdata)->vars[v] == NULL )
1046 	      {
1047 	         SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1048 	         SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1049 	         SCIPfreeBlockMemory(scip, consdata);
1050 	         return SCIP_INVALIDDATA;
1051 	      }
1052 	
1053 	      assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1054 	      SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1055 	   }
1056 	
1057 	   return SCIP_OKAY;
1058 	}
1059 	
1060 	/** frees a linear constraint data */
1061 	static
1062 	SCIP_RETCODE consdataFree(
1063 	   SCIP*                 scip,               /**< SCIP data structure */
1064 	   SCIP_CONSDATA**       consdata            /**< pointer to linear constraint data */
1065 	   )
1066 	{
1067 	   int v;
1068 	
1069 	   assert(scip != NULL);
1070 	   assert(consdata != NULL);
1071 	   assert(*consdata != NULL);
1072 	   assert((*consdata)->varssize >= 0);
1073 	
1074 	   /* release the row */
1075 	   if( (*consdata)->row != NULL )
1076 	   {
1077 	      SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1078 	   }
1079 	
1080 	   /* release the nlrow */
1081 	   if( (*consdata)->nlrow != NULL )
1082 	   {
1083 	      SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
1084 	   }
1085 	
1086 	   /* release variables */
1087 	   for( v = 0; v < (*consdata)->nvars; v++ )
1088 	   {
1089 	      assert((*consdata)->vars[v] != NULL);
1090 	      assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1091 	      SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1092 	   }
1093 	
1094 	   SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1095 	   SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1096 	   SCIPfreeBlockMemory(scip, consdata);
1097 	
1098 	   return SCIP_OKAY;
1099 	}
1100 	
1101 	/** prints linear constraint in CIP format to file stream */
1102 	static
1103 	SCIP_RETCODE consdataPrint(
1104 	   SCIP*                 scip,               /**< SCIP data structure */
1105 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
1106 	   FILE*                 file                /**< output file (or NULL for standard output) */
1107 	   )
1108 	{
1109 	   assert(scip != NULL);
1110 	   assert(consdata != NULL);
1111 	
1112 	   /* print left hand side for ranged rows */
1113 	   if( !SCIPisInfinity(scip, -consdata->lhs)
1114 	      && !SCIPisInfinity(scip, consdata->rhs)
1115 	      && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1116 	      SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1117 	
1118 	   /* print coefficients and variables */
1119 	   if( consdata->nvars == 0 )
1120 	      SCIPinfoMessage(scip, file, "0");
1121 	   else
1122 	   {
1123 	      /* post linear sum of the linear constraint */
1124 	      SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1125 	   }
1126 	
1127 	   /* print right hand side */
1128 	   if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1129 	      SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1130 	   else if( !SCIPisInfinity(scip, consdata->rhs) )
1131 	      SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1132 	   else if( !SCIPisInfinity(scip, -consdata->lhs) )
1133 	      SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1134 	   else
1135 	      SCIPinfoMessage(scip, file, " [free]");
1136 	
1137 	   return SCIP_OKAY;
1138 	}
1139 	
1140 	/** prints linear constraint and contained solution values of variables to file stream */
1141 	static
1142 	SCIP_RETCODE consPrintConsSol(
1143 	   SCIP*                 scip,               /**< SCIP data structure */
1144 	   SCIP_CONS*            cons,               /**< linear constraint */
1145 	   SCIP_SOL*             sol,                /**< solution to print */
1146 	   FILE*                 file                /**< output file (or NULL for standard output) */
1147 	   )
1148 	{
1149 	   SCIP_CONSDATA* consdata;
1150 	
1151 	   assert(scip != NULL);
1152 	   assert(cons != NULL);
1153 	
1154 	   consdata = SCIPconsGetData(cons);
1155 	   assert(consdata != NULL);
1156 	
1157 	   SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "  [%s] <%s>: ", SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), SCIPconsGetName(cons));
1158 	
1159 	   /* print left hand side for ranged rows */
1160 	   if( !SCIPisInfinity(scip, -consdata->lhs)
1161 	      && !SCIPisInfinity(scip, consdata->rhs)
1162 	      && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1163 	      SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1164 	
1165 	   /* print coefficients and variables */
1166 	   if( consdata->nvars == 0 )
1167 	      SCIPinfoMessage(scip, file, "0");
1168 	   else
1169 	   {
1170 	      int v;
1171 	
1172 	      /* post linear sum of the linear constraint */
1173 	      for( v = 0; v < consdata->nvars; ++v )
1174 	      {
1175 	         if( consdata->vals != NULL )
1176 	         {
1177 	            if( consdata->vals[v] == 1.0 )
1178 	            {
1179 	               if( v > 0 )
1180 	                  SCIPinfoMessage(scip, file, " +");
1181 	            }
1182 	            else if( consdata->vals[v] == -1.0 )
1183 	               SCIPinfoMessage(scip, file, " -");
1184 	            else
1185 	               SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
1186 	         }
1187 	         else if( consdata->nvars > 0 )
1188 	            SCIPinfoMessage(scip, file, " +");
1189 	
1190 	         /* print variable name */
1191 	         SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
1192 	
1193 	         SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
1194 	      }
1195 	   }
1196 	
1197 	   /* print right hand side */
1198 	   if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1199 	      SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1200 	   else if( !SCIPisInfinity(scip, consdata->rhs) )
1201 	      SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1202 	   else if( !SCIPisInfinity(scip, -consdata->lhs) )
1203 	      SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1204 	   else
1205 	      SCIPinfoMessage(scip, file, " [free]");
1206 	
1207 	   SCIPinfoMessage(scip, file, ";\n");
1208 	
1209 	   return SCIP_OKAY;
1210 	}
1211 	
1212 	/** invalidates activity bounds, such that they are recalculated in next get */
1213 	static
1214 	void consdataInvalidateActivities(
1215 	   SCIP_CONSDATA*        consdata            /**< linear constraint */
1216 	   )
1217 	{
1218 	   assert(consdata != NULL);
1219 	
1220 	   consdata->validactivities = FALSE;
1221 	   consdata->validminact = FALSE;
1222 	   consdata->validmaxact = FALSE;
1223 	   consdata->validglbminact = FALSE;
1224 	   consdata->validglbmaxact = FALSE;
1225 	   consdata->validmaxabsval = FALSE;
1226 	   consdata->validminabsval = FALSE;
1227 	   consdata->hasnonbinvalid = FALSE;
1228 	   QUAD_ASSIGN(consdata->minactivity, SCIP_INVALID);
1229 	   QUAD_ASSIGN(consdata->maxactivity, SCIP_INVALID);
1230 	   consdata->lastminactivity = SCIP_INVALID;
1231 	   consdata->lastmaxactivity = SCIP_INVALID;
1232 	   consdata->maxabsval = SCIP_INVALID;
1233 	   consdata->minabsval = SCIP_INVALID;
1234 	   consdata->maxactdelta = SCIP_INVALID;
1235 	   consdata->maxactdeltavar = NULL;
1236 	   consdata->minactivityneginf = -1;
1237 	   consdata->minactivityposinf = -1;
1238 	   consdata->maxactivityneginf = -1;
1239 	   consdata->maxactivityposinf = -1;
1240 	   consdata->minactivityneghuge = -1;
1241 	   consdata->minactivityposhuge = -1;
1242 	   consdata->maxactivityneghuge = -1;
1243 	   consdata->maxactivityposhuge = -1;
1244 	   QUAD_ASSIGN(consdata->glbminactivity, SCIP_INVALID);
1245 	   QUAD_ASSIGN(consdata->glbmaxactivity, SCIP_INVALID);
1246 	   consdata->lastglbminactivity = SCIP_INVALID;
1247 	   consdata->lastglbmaxactivity = SCIP_INVALID;
1248 	   consdata->glbminactivityneginf = -1;
1249 	   consdata->glbminactivityposinf = -1;
1250 	   consdata->glbmaxactivityneginf = -1;
1251 	   consdata->glbmaxactivityposinf = -1;
1252 	   consdata->glbminactivityneghuge = -1;
1253 	   consdata->glbminactivityposhuge = -1;
1254 	   consdata->glbmaxactivityneghuge = -1;
1255 	   consdata->glbmaxactivityposhuge = -1;
1256 	}
1257 	
1258 	/** compute the pseudo activity of a constraint */
1259 	static
1260 	SCIP_Real consdataComputePseudoActivity(
1261 	   SCIP*                 scip,               /**< SCIP data structure */
1262 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1263 	   )
1264 	{
1265 	   int i;
1266 	   int pseudoactivityposinf;
1267 	   int pseudoactivityneginf;
1268 	   SCIP_Real pseudoactivity;
1269 	   SCIP_Real bound;
1270 	   SCIP_Real val;
1271 	
1272 	   pseudoactivity = 0;
1273 	   pseudoactivityposinf = 0;
1274 	   pseudoactivityneginf = 0;
1275 	
1276 	   for( i = consdata->nvars - 1; i >= 0; --i )
1277 	   {
1278 	      val = consdata->vals[i];
1279 	      bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1280 	      if( SCIPisInfinity(scip, bound) )
1281 	      {
1282 	         if( val > 0.0 )
1283 	            pseudoactivityposinf++;
1284 	         else
1285 	            pseudoactivityneginf++;
1286 	      }
1287 	      else
1288 	      {
1289 	         if( SCIPisInfinity(scip, -bound) )
1290 	         {
1291 	            if( val > 0.0 )
1292 	               pseudoactivityneginf++;
1293 	            else
1294 	               pseudoactivityposinf++;
1295 	         }
1296 	         else
1297 	            pseudoactivity += val * bound;
1298 	      }
1299 	   }
1300 	
1301 	   if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1302 	      return SCIP_INVALID;
1303 	   else if( pseudoactivityneginf > 0 )
1304 	      return -SCIPinfinity(scip);
1305 	   else if( pseudoactivityposinf > 0 )
1306 	      return SCIPinfinity(scip);
1307 	
1308 	   return pseudoactivity;
1309 	}
1310 	
1311 	/** recompute the minactivity of a constraint */
1312 	static
1313 	void consdataRecomputeMinactivity(
1314 	   SCIP*                 scip,               /**< SCIP data structure */
1315 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1316 	   )
1317 	{
1318 	   int i;
1319 	   SCIP_Real bound;
1320 	
1321 	   QUAD_ASSIGN(consdata->minactivity, 0.0);
1322 	
1323 	   for( i = consdata->nvars - 1; i >= 0; --i )
1324 	   {
1325 	      bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1326 	      if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1327 	         && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1328 	         SCIPquadprecSumQD(consdata->minactivity, consdata->minactivity, consdata->vals[i] * bound);
1329 	   }
1330 	
1331 	   /* the activity was just computed from scratch and is valid now */
1332 	   consdata->validminact = TRUE;
1333 	
1334 	   /* the activity was just computed from scratch, mark it to be reliable */
1335 	   consdata->lastminactivity = QUAD_TO_DBL(consdata->minactivity);
1336 	}
1337 	
1338 	/** recompute the maxactivity of a constraint */
1339 	static
1340 	void consdataRecomputeMaxactivity(
1341 	   SCIP*                 scip,               /**< SCIP data structure */
1342 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1343 	   )
1344 	{
1345 	   int i;
1346 	   SCIP_Real bound;
1347 	
1348 	   QUAD_ASSIGN(consdata->maxactivity, 0.0);
1349 	
1350 	   for( i = consdata->nvars - 1; i >= 0; --i )
1351 	   {
1352 	      bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1353 	      if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1354 	         && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1355 	         SCIPquadprecSumQD(consdata->maxactivity, consdata->maxactivity, consdata->vals[i] * bound);
1356 	   }
1357 	
1358 	   /* the activity was just computed from scratch and is valid now */
1359 	   consdata->validmaxact = TRUE;
1360 	
1361 	   /* the activity was just computed from scratch, mark it to be reliable */
1362 	   consdata->lastmaxactivity = QUAD_TO_DBL(consdata->maxactivity);
1363 	}
1364 	
1365 	/** recompute the global minactivity of a constraint */
1366 	static
1367 	void consdataRecomputeGlbMinactivity(
1368 	   SCIP*                 scip,               /**< SCIP data structure */
1369 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1370 	   )
1371 	{
1372 	   int i;
1373 	   SCIP_Real bound;
1374 	
1375 	   QUAD_ASSIGN(consdata->glbminactivity, 0.0);
1376 	
1377 	   for( i = consdata->nvars - 1; i >= 0; --i )
1378 	   {
1379 	      bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1380 	      if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1381 	         && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1382 	         SCIPquadprecSumQD(consdata->glbminactivity, consdata->glbminactivity, consdata->vals[i] * bound);
1383 	   }
1384 	
1385 	   /* the activity was just computed from scratch and is valid now */
1386 	   consdata->validglbminact = TRUE;
1387 	
1388 	   /* the activity was just computed from scratch, mark it to be reliable */
1389 	   consdata->lastglbminactivity = QUAD_TO_DBL(consdata->glbminactivity);
1390 	}
1391 	
1392 	/** recompute the global maxactivity of a constraint */
1393 	static
1394 	void consdataRecomputeGlbMaxactivity(
1395 	   SCIP*                 scip,               /**< SCIP data structure */
1396 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1397 	   )
1398 	{
1399 	   int i;
1400 	   SCIP_Real bound;
1401 	
1402 	   QUAD_ASSIGN(consdata->glbmaxactivity, 0.0);
1403 	
1404 	   for( i = consdata->nvars - 1; i >= 0; --i )
1405 	   {
1406 	      bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1407 	      if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1408 	         && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1409 	         SCIPquadprecSumQD(consdata->glbmaxactivity, consdata->glbmaxactivity, consdata->vals[i] * bound);
1410 	   }
1411 	
1412 	   /* the activity was just computed from scratch and is valid now */
1413 	   consdata->validglbmaxact = TRUE;
1414 	
1415 	   /* the activity was just computed from scratch, mark it to be reliable */
1416 	   consdata->lastglbmaxactivity = QUAD_TO_DBL(consdata->glbmaxactivity);
1417 	}
1418 	
1419 	/** calculates maximum absolute value of coefficients */
1420 	static
1421 	void consdataCalcMaxAbsval(
1422 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1423 	   )
1424 	{
1425 	   SCIP_Real absval;
1426 	   int i;
1427 	
1428 	   assert(consdata != NULL);
1429 	   assert(!consdata->validmaxabsval);
1430 	   assert(consdata->maxabsval >= SCIP_INVALID);
1431 	
1432 	   consdata->validmaxabsval = TRUE;
1433 	   consdata->maxabsval = 0.0;
1434 	   for( i = 0; i < consdata->nvars; ++i )
1435 	   {
1436 	      absval = consdata->vals[i];
1437 	      absval = REALABS(absval);
1438 	      if( absval > consdata->maxabsval )
1439 	         consdata->maxabsval = absval;
1440 	   }
1441 	}
1442 	
1443 	/** calculates minimum absolute value of coefficients */
1444 	static
1445 	void consdataCalcMinAbsval(
1446 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1447 	   )
1448 	{
1449 	   SCIP_Real absval;
1450 	   int i;
1451 	
1452 	   assert(consdata != NULL);
1453 	   assert(!consdata->validminabsval);
1454 	   assert(consdata->minabsval >= SCIP_INVALID);
1455 	
1456 	   consdata->validminabsval = TRUE;
1457 	
1458 	   if( consdata->nvars > 0 )
1459 	      consdata->minabsval = REALABS(consdata->vals[0]);
1460 	   else
1461 	      consdata->minabsval = 0.0;
1462 	
1463 	   for( i = 1; i < consdata->nvars; ++i )
1464 	   {
1465 	      absval = consdata->vals[i];
1466 	      absval = REALABS(absval);
1467 	      if( absval < consdata->minabsval )
1468 	         consdata->minabsval = absval;
1469 	   }
1470 	}
1471 	
1472 	/** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1473 	static
1474 	void consdataCheckNonbinvar(
1475 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1476 	   )
1477 	{
1478 	   int v;
1479 	
1480 	   assert(!consdata->hasnonbinvalid);
1481 	   consdata->hasnonbinvar = FALSE;
1482 	   consdata->hascontvar = FALSE;
1483 	
1484 	   for( v = consdata->nvars - 1; v >= 0; --v )
1485 	   {
1486 	      SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1487 	
1488 	      if( vartype != SCIP_VARTYPE_BINARY )
1489 	      {
1490 	         consdata->hasnonbinvar = TRUE;
1491 	
1492 	         if( vartype == SCIP_VARTYPE_CONTINUOUS )
1493 	         {
1494 	            consdata->hascontvar = TRUE;
1495 	            break;
1496 	         }
1497 	      }
1498 	   }
1499 	   assert(consdata->hascontvar || v < 0);
1500 	
1501 	   consdata->hasnonbinvalid = TRUE;
1502 	}
1503 	
1504 	
1505 	#ifdef CHECKMAXACTDELTA
1506 	/** checks that the stored maximal activity delta (if not invalid) is correct */
1507 	static
1508 	void checkMaxActivityDelta(
1509 	   SCIP*                 scip,               /**< SCIP data structure */
1510 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1511 	   )
1512 	{
1513 	   if( consdata->maxactdelta != SCIP_INVALID )
1514 	   {
1515 	      SCIP_Real maxactdelta = 0.0;
1516 	      SCIP_Real domain;
1517 	      SCIP_Real delta;
1518 	      SCIP_Real lb;
1519 	      SCIP_Real ub;
1520 	      int v;
1521 	
1522 	      for( v = consdata->nvars - 1; v >= 0; --v )
1523 	      {
1524 	         lb = SCIPvarGetLbLocal(consdata->vars[v]);
1525 	         ub = SCIPvarGetUbLocal(consdata->vars[v]);
1526 	
1527 	         if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1528 	         {
1529 	            maxactdelta = SCIPinfinity(scip);
1530 	            break;
1531 	         }
1532 	
1533 	         domain = ub - lb;
1534 	         delta = REALABS(consdata->vals[v]) * domain;
1535 	
1536 	         if( delta > maxactdelta )
1537 	         {
1538 	            maxactdelta = delta;
1539 	         }
1540 	      }
1541 	      assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1542 	   }
1543 	}
1544 	#else
1545 	#define checkMaxActivityDelta(scip, consdata) /**/
1546 	#endif
1547 	
1548 	/** recompute maximal activity contribution for a single variable */
1549 	static
1550 	void consdataRecomputeMaxActivityDelta(
1551 	   SCIP*                 scip,               /**< SCIP data structure */
1552 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
1553 	   )
1554 	{
1555 	   SCIP_Real delta;
1556 	   int v;
1557 	
1558 	   consdata->maxactdelta = 0.0;
1559 	
1560 	   if( !consdata->hasnonbinvalid )
1561 	      consdataCheckNonbinvar(consdata);
1562 	
1563 	   /* easy case, the problem consists only of binary variables */
1564 	   if( !consdata->hasnonbinvar )
1565 	   {
1566 	      for( v = consdata->nvars - 1; v >= 0; --v )
1567 	      {
1568 	         if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1569 	         {
1570 	            delta = REALABS(consdata->vals[v]);
1571 	
1572 	            if( delta > consdata->maxactdelta )
1573 	            {
1574 	               consdata->maxactdelta = delta;
1575 	               consdata->maxactdeltavar = consdata->vars[v];
1576 	            }
1577 	         }
1578 	      }
1579 	      return;
1580 	   }
1581 	
1582 	   for( v = consdata->nvars - 1; v >= 0; --v )
1583 	   {
1584 	      SCIP_Real domain;
1585 	      SCIP_Real lb;
1586 	      SCIP_Real ub;
1587 	
1588 	      lb = SCIPvarGetLbLocal(consdata->vars[v]);
1589 	      ub = SCIPvarGetUbLocal(consdata->vars[v]);
1590 	
1591 	      if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1592 	      {
1593 	         consdata->maxactdelta = SCIPinfinity(scip);
1594 	         consdata->maxactdeltavar = consdata->vars[v];
1595 	         break;
1596 	      }
1597 	
1598 	      domain = ub - lb;
1599 	      delta = REALABS(consdata->vals[v]) * domain;
1600 	
1601 	      if( delta > consdata->maxactdelta )
1602 	      {
1603 	         consdata->maxactdelta = delta;
1604 	         consdata->maxactdeltavar = consdata->vars[v];
1605 	      }
1606 	   }
1607 	}
1608 	
1609 	
1610 	/** updates activities for a change in a bound */
1611 	static
1612 	void consdataUpdateActivities(
1613 	   SCIP*                 scip,               /**< SCIP data structure */
1614 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
1615 	   SCIP_VAR*             var,                /**< variable that has been changed; can be NULL for global bound changes */
1616 	   SCIP_Real             oldbound,           /**< old bound of variable */
1617 	   SCIP_Real             newbound,           /**< new bound of variable */
1618 	   SCIP_Real             val,                /**< coefficient of constraint entry */
1619 	   SCIP_BOUNDTYPE        boundtype,          /**< type of the bound change */
1620 	   SCIP_Bool             global,             /**< is it a global or a local bound change? */
1621 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
1622 	   )
1623 	{
1624 	   QUAD_MEMBER(SCIP_Real* activity);
1625 	   QUAD_MEMBER(SCIP_Real delta);
1626 	   SCIP_Real* lastactivity;
1627 	   int* activityposinf;
1628 	   int* activityneginf;
1629 	   int* activityposhuge;
1630 	   int* activityneghuge;
1631 	   SCIP_Real oldcontribution;
1632 	   SCIP_Real newcontribution;
1633 	   SCIP_Bool validact;
1634 	   SCIP_Bool finitenewbound;
1635 	   SCIP_Bool hugevalnewcont;
1636 	
1637 	   assert(scip != NULL);
1638 	   assert(consdata != NULL);
1639 	   assert(global || (var != NULL));
1640 	   assert(consdata->validactivities);
1641 	   assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
1642 	   assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
1643 	   assert(consdata->lastminactivity < SCIP_INVALID);
1644 	   assert(consdata->lastmaxactivity < SCIP_INVALID);
1645 	   assert(consdata->minactivityneginf >= 0);
1646 	   assert(consdata->minactivityposinf >= 0);
1647 	   assert(consdata->maxactivityneginf >= 0);
1648 	   assert(consdata->maxactivityposinf >= 0);
1649 	   assert(consdata->minactivityneghuge >= 0);
1650 	   assert(consdata->minactivityposhuge >= 0);
1651 	   assert(consdata->maxactivityneghuge >= 0);
1652 	   assert(consdata->maxactivityposhuge >= 0);
1653 	   assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
1654 	   assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
1655 	   assert(consdata->lastglbminactivity < SCIP_INVALID);
1656 	   assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1657 	   assert(consdata->glbminactivityneginf >= 0);
1658 	   assert(consdata->glbminactivityposinf >= 0);
1659 	   assert(consdata->glbmaxactivityneginf >= 0);
1660 	   assert(consdata->glbmaxactivityposinf >= 0);
1661 	   assert(consdata->glbminactivityneghuge >= 0);
1662 	   assert(consdata->glbminactivityposhuge >= 0);
1663 	   assert(consdata->glbmaxactivityneghuge >= 0);
1664 	   assert(consdata->glbmaxactivityposhuge >= 0);
1665 	
1666 	   QUAD_ASSIGN(delta, 0.0);
1667 	
1668 	   /* we are updating global activities */
1669 	   if( global )
1670 	   {
1671 	      /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1672 	       * lower bound + pos. coef: update minactivity
1673 	       * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1674 	       * upper bound + pos. coef: update maxactivity
1675 	       * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1676 	       */
1677 	      if( boundtype == SCIP_BOUNDTYPE_LOWER )
1678 	      {
1679 	         if( val > 0.0 )
1680 	         {
1681 	            QUAD_ASSIGN_Q(activity, &consdata->glbminactivity);
1682 	            lastactivity = &(consdata->lastglbminactivity);
1683 	            activityposinf = &(consdata->glbminactivityposinf);
1684 	            activityneginf = &(consdata->glbminactivityneginf);
1685 	            activityposhuge = &(consdata->glbminactivityposhuge);
1686 	            activityneghuge = &(consdata->glbminactivityneghuge);
1687 	            validact = consdata->validglbminact;
1688 	         }
1689 	         else
1690 	         {
1691 	            QUAD_ASSIGN_Q(activity, &consdata->glbmaxactivity);
1692 	            lastactivity = &(consdata->lastglbmaxactivity);
1693 	            activityposinf = &(consdata->glbmaxactivityneginf);
1694 	            activityneginf = &(consdata->glbmaxactivityposinf);
1695 	            activityposhuge = &(consdata->glbmaxactivityposhuge);
1696 	            activityneghuge = &(consdata->glbmaxactivityneghuge);
1697 	            validact = consdata->validglbmaxact;
1698 	         }
1699 	      }
1700 	      else
1701 	      {
1702 	         if( val > 0.0 )
1703 	         {
1704 	            QUAD_ASSIGN_Q(activity, &consdata->glbmaxactivity);
1705 	            lastactivity = &(consdata->lastglbmaxactivity);
1706 	            activityposinf = &(consdata->glbmaxactivityposinf);
1707 	            activityneginf = &(consdata->glbmaxactivityneginf);
1708 	            activityposhuge = &(consdata->glbmaxactivityposhuge);
1709 	            activityneghuge = &(consdata->glbmaxactivityneghuge);
1710 	            validact = consdata->validglbmaxact;
1711 	         }
1712 	         else
1713 	         {
1714 	            QUAD_ASSIGN_Q(activity, &consdata->glbminactivity);
1715 	            lastactivity = &(consdata->lastglbminactivity);
1716 	            activityposinf = &(consdata->glbminactivityneginf);
1717 	            activityneginf = &(consdata->glbminactivityposinf);
1718 	            activityposhuge = &(consdata->glbminactivityposhuge);
1719 	            activityneghuge = &(consdata->glbminactivityneghuge);
1720 	            validact = consdata->validglbminact;
1721 	         }
1722 	      }
1723 	   }
1724 	   /* we are updating local activities */
1725 	   else
1726 	   {
1727 	      /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1728 	       * lower bound + pos. coef: update minactivity
1729 	       * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1730 	       * upper bound + pos. coef: update maxactivity
1731 	       * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1732 	       */
1733 	      if( boundtype == SCIP_BOUNDTYPE_LOWER )
1734 	      {
1735 	         if( val > 0.0 )
1736 	         {
1737 	            QUAD_ASSIGN_Q(activity, &consdata->minactivity);
1738 	            lastactivity = &(consdata->lastminactivity);
1739 	            activityposinf = &(consdata->minactivityposinf);
1740 	            activityneginf = &(consdata->minactivityneginf);
1741 	            activityposhuge = &(consdata->minactivityposhuge);
1742 	            activityneghuge = &(consdata->minactivityneghuge);
1743 	            validact = consdata->validminact;
1744 	         }
1745 	         else
1746 	         {
1747 	            QUAD_ASSIGN_Q(activity, &consdata->maxactivity);
1748 	            lastactivity = &(consdata->lastmaxactivity);
1749 	            activityposinf = &(consdata->maxactivityneginf);
1750 	            activityneginf = &(consdata->maxactivityposinf);
1751 	            activityposhuge = &(consdata->maxactivityposhuge);
1752 	            activityneghuge = &(consdata->maxactivityneghuge);
1753 	            validact = consdata->validmaxact;
1754 	         }
1755 	      }
1756 	      else
1757 	      {
1758 	         if( val > 0.0 )
1759 	         {
1760 	            QUAD_ASSIGN_Q(activity, &consdata->maxactivity);
1761 	            lastactivity = &(consdata->lastmaxactivity);
1762 	            activityposinf = &(consdata->maxactivityposinf);
1763 	            activityneginf = &(consdata->maxactivityneginf);
1764 	            activityposhuge = &(consdata->maxactivityposhuge);
1765 	            activityneghuge = &(consdata->maxactivityneghuge);
1766 	            validact = consdata->validmaxact;
1767 	         }
1768 	         else
1769 	         {
1770 	            QUAD_ASSIGN_Q(activity, &consdata->minactivity);
1771 	            lastactivity = &(consdata->lastminactivity);
1772 	            activityposinf = &(consdata->minactivityneginf);
1773 	            activityneginf = &(consdata->minactivityposinf);
1774 	            activityposhuge = &(consdata->minactivityposhuge);
1775 	            activityneghuge = &(consdata->minactivityneghuge);
1776 	            validact = consdata->validminact;
1777 	         }
1778 	      }
1779 	   }
1780 	
1781 	   oldcontribution = val * oldbound;
1782 	   newcontribution = val * newbound;
1783 	   hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1784 	   finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1785 	
1786 	   if( SCIPisInfinity(scip, REALABS(oldbound)) )
1787 	   {
1788 	      /* old bound was +infinity */
1789 	      if( oldbound > 0.0 )
1790 	      {
1791 	         assert((*activityposinf) >= 1);
1792 	
1793 	         /* we only have to do something if the new bound is not again +infinity */
1794 	         if( finitenewbound || newbound < 0.0 )
1795 	         {
1796 	            /* decrease the counter for positive infinite contributions */
1797 	            (*activityposinf)--;
1798 	
1799 	            /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1800 	            if( !finitenewbound && newbound < 0.0 )
1801 	               (*activityneginf)++;
1802 	            else if( hugevalnewcont )
1803 	            {
1804 	               /* if the contribution of this variable is too large, increase the counter for huge values */
1805 	               if( newcontribution > 0.0 )
1806 	                  (*activityposhuge)++;
1807 	               else
1808 	                  (*activityneghuge)++;
1809 	            }
1810 	            /* "normal case": just add the contribution to the activity */
1811 	            else
1812 	               QUAD_ASSIGN(delta, newcontribution);
1813 	         }
1814 	      }
1815 	      /* old bound was -infinity */
1816 	      else
1817 	      {
1818 	         assert(oldbound < 0.0);
1819 	         assert((*activityneginf) >= 1);
1820 	
1821 	         /* we only have to do something ig the new bound is not again -infinity */
1822 	         if( finitenewbound || newbound > 0.0 )
1823 	         {
1824 	            /* decrease the counter for negative infinite contributions */
1825 	            (*activityneginf)--;
1826 	
1827 	            /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1828 	            if( !finitenewbound && newbound > 0.0 )
1829 	               (*activityposinf)++;
1830 	            else if( hugevalnewcont )
1831 	            {
1832 	               /* if the contribution of this variable is too large, increase the counter for huge values */
1833 	               if( newcontribution > 0.0 )
1834 	                  (*activityposhuge)++;
1835 	               else
1836 	                  (*activityneghuge)++;
1837 	            }
1838 	            /* "normal case": just add the contribution to the activity */
1839 	            else
1840 	               QUAD_ASSIGN(delta, newcontribution);
1841 	         }
1842 	      }
1843 	   }
1844 	   else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1845 	   {
1846 	      /* old contribution was too large and positive */
1847 	      if( oldcontribution > 0.0 )
1848 	      {
1849 	         assert((*activityposhuge) >= 1);
1850 	
1851 	         /* decrease the counter for huge positive contributions; it might be increased again later,
1852 	          * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1853 	          */
1854 	         (*activityposhuge)--;
1855 	
1856 	         if( !finitenewbound )
1857 	         {
1858 	            /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1859 	            if( newbound > 0.0 )
1860 	               (*activityposinf)++;
1861 	            /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1862 	            else
1863 	               (*activityneginf)++;
1864 	         }
1865 	         else if( hugevalnewcont )
1866 	         {
1867 	            /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1868 	            if( newcontribution > 0.0 )
1869 	               (*activityposhuge)++;
1870 	            /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1871 	            else
1872 	               (*activityneghuge)++;
1873 	         }
1874 	         /* "normal case": just add the contribution to the activity */
1875 	         else
1876 	            QUAD_ASSIGN(delta, newcontribution);
1877 	      }
1878 	      /* old contribution was too large and negative */
1879 	      else
1880 	      {
1881 	         assert(oldcontribution < 0.0);
1882 	         assert((*activityneghuge) >= 1);
1883 	
1884 	         /* decrease the counter for huge negative contributions; it might be increased again later,
1885 	          * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1886 	          */
1887 	         (*activityneghuge)--;
1888 	
1889 	         if( !finitenewbound )
1890 	         {
1891 	            /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1892 	            if( newbound > 0.0 )
1893 	               (*activityposinf)++;
1894 	            /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1895 	            else
1896 	               (*activityneginf)++;
1897 	         }
1898 	         else if( hugevalnewcont )
1899 	         {
1900 	            /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1901 	            if( newcontribution > 0.0 )
1902 	               (*activityposhuge)++;
1903 	            /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1904 	            else
1905 	               (*activityneghuge)++;
1906 	         }
1907 	         /* "normal case": just add the contribution to the activity */
1908 	         else
1909 	            QUAD_ASSIGN(delta, newcontribution);
1910 	      }
1911 	   }
1912 	   /* old bound was finite and not too large */
1913 	   else
1914 	   {
1915 	      if( !finitenewbound )
1916 	      {
1917 	         /* if the new bound is +infinity, the old contribution has to be subtracted
1918 	          * and the counter for positive infinite contributions has to be increased
1919 	          */
1920 	         if( newbound > 0.0 )
1921 	         {
1922 	            (*activityposinf)++;
1923 	            QUAD_ASSIGN(delta, -oldcontribution);
1924 	         }
1925 	         /* if the new bound is -infinity, the old contribution has to be subtracted
1926 	          * and the counter for negative infinite contributions has to be increased
1927 	          */
1928 	         else
1929 	         {
1930 	            assert(newbound < 0.0 );
1931 	
1932 	            (*activityneginf)++;
1933 	            QUAD_ASSIGN(delta, -oldcontribution);
1934 	         }
1935 	      }
1936 	      /* if the contribution of this variable is too large, increase the counter for huge values */
1937 	      else if( hugevalnewcont )
1938 	      {
1939 	         if( newcontribution > 0.0 )
1940 	         {
1941 	            (*activityposhuge)++;
1942 	            QUAD_ASSIGN(delta, -oldcontribution);
1943 	         }
1944 	         else
1945 	         {
1946 	            (*activityneghuge)++;
1947 	            QUAD_ASSIGN(delta, -oldcontribution);
1948 	         }
1949 	      }
1950 	      /* "normal case": just update the activity */
1951 	      else
1952 	      {
1953 	         QUAD_ASSIGN(delta, newcontribution);
1954 	         SCIPquadprecSumQD(delta, delta, -oldcontribution);
1955 	      }
1956 	   }
1957 	
1958 	   /* update the activity, if the current value is valid and there was a change in the finite part */
1959 	   if( validact && (QUAD_TO_DBL(delta) != 0.0) )
1960 	   {
1961 	      SCIP_Real curractivity;
1962 	
1963 	      /* if the absolute value of the activity is increased, this is regarded as reliable,
1964 	       * otherwise, we check whether we can still trust the updated value
1965 	       */
1966 	      SCIPquadprecSumQD(*activity, *activity, QUAD_TO_DBL(delta));
1967 	
1968 	      curractivity = QUAD_TO_DBL(*activity);
1969 	      assert(!SCIPisInfinity(scip, -curractivity) && !SCIPisInfinity(scip, curractivity));
1970 	
1971 	      if( REALABS((*lastactivity)) < REALABS(curractivity) )
1972 	      {
1973 	         (*lastactivity) = curractivity;
1974 	      }
1975 	      else
1976 	      {
1977 	         if( checkreliability && SCIPisUpdateUnreliable(scip, curractivity, (*lastactivity)) )
1978 	         {
1979 	            SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1980 	               (global ? "global " : ""), curractivity);
1981 	
1982 	            /* mark the activity that was just changed and is not reliable anymore to be invalid */
1983 	            if( global )
1984 	            {
1985 	               if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1986 	                  consdata->validglbminact = FALSE;
1987 	               else
1988 	                  consdata->validglbmaxact = FALSE;
1989 	            }
1990 	            else
1991 	            {
1992 	               if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1993 	                  consdata->validminact = FALSE;
1994 	               else
1995 	                  consdata->validmaxact = FALSE;
1996 	            }
1997 	         }
1998 	      }
1999 	   }
2000 	}
2001 	
2002 	/** updates minimum and maximum activity for a change in lower bound */
2003 	static
2004 	void consdataUpdateActivitiesLb(
2005 	   SCIP*                 scip,               /**< SCIP data structure */
2006 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2007 	   SCIP_VAR*             var,                /**< variable that has been changed */
2008 	   SCIP_Real             oldlb,              /**< old lower bound of variable */
2009 	   SCIP_Real             newlb,              /**< new lower bound of variable */
2010 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2011 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2012 	   )
2013 	{
2014 	   assert(scip != NULL);
2015 	   assert(consdata != NULL);
2016 	   assert(var != NULL);
2017 	
2018 	   if( consdata->validactivities )
2019 	   {
2020 	      consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
2021 	
2022 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->minactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->minactivity)));
2023 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->maxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->maxactivity)));
2024 	   }
2025 	}
2026 	
2027 	/** updates minimum and maximum activity for a change in upper bound */
2028 	static
2029 	void consdataUpdateActivitiesUb(
2030 	   SCIP*                 scip,               /**< SCIP data structure */
2031 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2032 	   SCIP_VAR*             var,                /**< variable that has been changed */
2033 	   SCIP_Real             oldub,              /**< old upper bound of variable */
2034 	   SCIP_Real             newub,              /**< new upper bound of variable */
2035 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2036 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2037 	   )
2038 	{
2039 	   assert(scip != NULL);
2040 	   assert(consdata != NULL);
2041 	   assert(var != NULL);
2042 	
2043 	   if( consdata->validactivities )
2044 	   {
2045 	      consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
2046 	
2047 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->minactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->minactivity)));
2048 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->maxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->maxactivity)));
2049 	   }
2050 	}
2051 	
2052 	/** updates minimum and maximum global activity for a change in the global lower bound */
2053 	static
2054 	void consdataUpdateActivitiesGlbLb(
2055 	   SCIP*                 scip,               /**< SCIP data structure */
2056 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2057 	   SCIP_Real             oldlb,              /**< old lower bound of variable */
2058 	   SCIP_Real             newlb,              /**< new lower bound of variable */
2059 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2060 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2061 	   )
2062 	{
2063 	   assert(scip != NULL);
2064 	   assert(consdata != NULL);
2065 	
2066 	   if( consdata->validactivities )
2067 	   {
2068 	      consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
2069 	
2070 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbminactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbminactivity)));
2071 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbmaxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbmaxactivity)));
2072 	   }
2073 	}
2074 	
2075 	/** updates minimum and maximum global activity for a change in global upper bound */
2076 	static
2077 	void consdataUpdateActivitiesGlbUb(
2078 	   SCIP*                 scip,               /**< SCIP data structure */
2079 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2080 	   SCIP_Real             oldub,              /**< old upper bound of variable */
2081 	   SCIP_Real             newub,              /**< new upper bound of variable */
2082 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2083 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2084 	   )
2085 	{
2086 	   assert(scip != NULL);
2087 	   assert(consdata != NULL);
2088 	
2089 	   if( consdata->validactivities )
2090 	   {
2091 	      consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
2092 	
2093 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbminactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbminactivity)));
2094 	      assert(!SCIPisInfinity(scip, -QUAD_TO_DBL(consdata->glbmaxactivity)) && !SCIPisInfinity(scip, QUAD_TO_DBL(consdata->glbmaxactivity)));
2095 	   }
2096 	}
2097 	
2098 	/** updates minimum and maximum activity and maximum absolute value for coefficient addition */
2099 	static
2100 	void consdataUpdateAddCoef(
2101 	   SCIP*                 scip,               /**< SCIP data structure */
2102 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2103 	   SCIP_VAR*             var,                /**< variable of constraint entry */
2104 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2105 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2106 	   )
2107 	{
2108 	   assert(scip != NULL);
2109 	   assert(consdata != NULL);
2110 	   assert(var != NULL);
2111 	
2112 	   /* update maximum absolute value */
2113 	   if( consdata->validmaxabsval )
2114 	   {
2115 	      SCIP_Real absval;
2116 	
2117 	      assert(consdata->maxabsval < SCIP_INVALID);
2118 	
2119 	      absval = REALABS(val);
2120 	      consdata->maxabsval = MAX(consdata->maxabsval, absval);
2121 	   }
2122 	
2123 	   if( consdata->validminabsval )
2124 	   {
2125 	      SCIP_Real absval;
2126 	
2127 	      assert(consdata->minabsval < SCIP_INVALID);
2128 	
2129 	      absval = REALABS(val);
2130 	      consdata->minabsval = MIN(consdata->minabsval, absval);
2131 	   }
2132 	
2133 	   /* update minimal and maximal activity */
2134 	   if( consdata->validactivities )
2135 	   {
2136 	      assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
2137 	      assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
2138 	      assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
2139 	      assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
2140 	
2141 	      consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2142 	      consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2143 	      consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2144 	      consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2145 	   }
2146 	}
2147 	
2148 	/** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2149 	static
2150 	void consdataUpdateDelCoef(
2151 	   SCIP*                 scip,               /**< SCIP data structure */
2152 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2153 	   SCIP_VAR*             var,                /**< variable of constraint entry */
2154 	   SCIP_Real             val,                /**< coefficient of constraint entry */
2155 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2156 	   )
2157 	{
2158 	   assert(scip != NULL);
2159 	   assert(consdata != NULL);
2160 	   assert(var != NULL);
2161 	
2162 	   /* invalidate maximum absolute value, if this coefficient was the maximum */
2163 	   if( consdata->validmaxabsval )
2164 	   {
2165 	      SCIP_Real absval;
2166 	
2167 	      absval = REALABS(val);
2168 	
2169 	      if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2170 	      {
2171 	         consdata->validmaxabsval = FALSE;
2172 	         consdata->maxabsval = SCIP_INVALID;
2173 	      }
2174 	   }
2175 	
2176 	   /* invalidate minimum absolute value, if this coefficient was the minimum */
2177 	   if( consdata->validminabsval )
2178 	   {
2179 	      SCIP_Real absval;
2180 	
2181 	      absval = REALABS(val);
2182 	
2183 	      if( SCIPisEQ(scip, absval, consdata->minabsval) )
2184 	      {
2185 	         consdata->validminabsval = FALSE;
2186 	         consdata->minabsval = SCIP_INVALID;
2187 	      }
2188 	   }
2189 	
2190 	   /* update minimal and maximal activity */
2191 	   if( consdata->validactivities )
2192 	   {
2193 	      assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
2194 	      assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
2195 	      assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
2196 	      assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
2197 	
2198 	      consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2199 	      consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2200 	      consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2201 	      consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2202 	   }
2203 	}
2204 	
2205 	/** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2206 	static
2207 	void consdataUpdateChgCoef(
2208 	   SCIP*                 scip,               /**< SCIP data structure */
2209 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
2210 	   SCIP_VAR*             var,                /**< variable of constraint entry */
2211 	   SCIP_Real             oldval,             /**< old coefficient of constraint entry */
2212 	   SCIP_Real             newval,             /**< new coefficient of constraint entry */
2213 	   SCIP_Bool             checkreliability    /**< should the reliability of the recalculated activity be checked? */
2214 	   )
2215 	{
2216 	   assert(scip != NULL);
2217 	   assert(consdata != NULL);
2218 	   assert(var != NULL);
2219 	
2220 	   /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2221 	   assert(!SCIPisZero(scip, oldval));
2222 	
2223 	   /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2224 	   assert(!SCIPisZero(scip, newval));
2225 	
2226 	   /* update maximum absolute value */
2227 	   if( consdata->validmaxabsval )
2228 	   {
2229 	      SCIP_Real absval;
2230 	
2231 	      absval = REALABS(newval);
2232 	
2233 	      if( SCIPisGE(scip, absval, consdata->maxabsval) )
2234 	      {
2235 	         consdata->maxabsval = absval;
2236 	      }
2237 	      else
2238 	      {
2239 	         absval = REALABS(oldval);
2240 	
2241 	         /* invalidate maximum absolute value */
2242 	         if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2243 	         {
2244 	            consdata->validmaxabsval = FALSE;
2245 	            consdata->maxabsval = SCIP_INVALID;
2246 	         }
2247 	      }
2248 	   }
2249 	
2250 	   /* update minimum absolute value */
2251 	   if( consdata->validminabsval )
2252 	   {
2253 	      SCIP_Real absval;
2254 	
2255 	      absval = REALABS(newval);
2256 	
2257 	      if( SCIPisLE(scip, absval, consdata->minabsval) )
2258 	      {
2259 	         consdata->minabsval = absval;
2260 	      }
2261 	      else
2262 	      {
2263 	         absval = REALABS(oldval);
2264 	
2265 	         /* invalidate minimum absolute value */
2266 	         if( SCIPisEQ(scip, absval, consdata->minabsval) )
2267 	         {
2268 	            consdata->validminabsval = FALSE;
2269 	            consdata->minabsval = SCIP_INVALID;
2270 	         }
2271 	      }
2272 	   }
2273 	
2274 	   /* update maximum activity delta */
2275 	   if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2276 	   {
2277 	      SCIP_Real domain;
2278 	      SCIP_Real delta;
2279 	
2280 	      assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2281 	      assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2282 	
2283 	      domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2284 	      delta = REALABS(newval) * domain;
2285 	
2286 	      if( delta > consdata->maxactdelta )
2287 	      {
2288 	         consdata->maxactdelta = delta;
2289 	         consdata->maxactdeltavar = var;
2290 	      }
2291 	      else
2292 	      {
2293 	         /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2294 	         if( consdata->maxactdeltavar == var )
2295 	            consdata->maxactdelta = SCIP_INVALID;
2296 	      }
2297 	   }
2298 	
2299 	   /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2300 	   consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2301 	   consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2302 	}
2303 	
2304 	/** returns the maximum absolute value of all coefficients in the constraint */
2305 	static
2306 	SCIP_Real consdataGetMaxAbsval(
2307 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
2308 	   )
2309 	{
2310 	   assert(consdata != NULL);
2311 	
2312 	   if( !consdata->validmaxabsval )
2313 	      consdataCalcMaxAbsval(consdata);
2314 	   assert(consdata->validmaxabsval);
2315 	   assert(consdata->maxabsval < SCIP_INVALID);
2316 	
2317 	   return consdata->maxabsval;
2318 	}
2319 	
2320 	/** returns the minimum absolute value of all coefficients in the constraint */
2321 	static
2322 	SCIP_Real consdataGetMinAbsval(
2323 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
2324 	   )
2325 	{
2326 	   assert(consdata != NULL);
2327 	
2328 	   if( !consdata->validminabsval )
2329 	      consdataCalcMinAbsval(consdata);
2330 	   assert(consdata->validminabsval);
2331 	   assert(consdata->minabsval < SCIP_INVALID);
2332 	
2333 	   return consdata->minabsval;
2334 	}
2335 	
2336 	/** calculates minimum and maximum local and global activity for constraint from scratch;
2337 	 *  additionally recalculates maximum absolute value of coefficients
2338 	 */
2339 	static
2340 	void consdataCalcActivities(
2341 	   SCIP*                 scip,               /**< SCIP data structure */
2342 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
2343 	   )
2344 	{
2345 	   int i;
2346 	
2347 	   assert(scip != NULL);
2348 	   assert(consdata != NULL);
2349 	   assert(!consdata->validactivities);
2350 	   assert(QUAD_TO_DBL(consdata->minactivity) >= SCIP_INVALID || consdata->validminact);
2351 	   assert(QUAD_TO_DBL(consdata->maxactivity) >= SCIP_INVALID || consdata->validmaxact);
2352 	   assert(QUAD_TO_DBL(consdata->glbminactivity) >= SCIP_INVALID || consdata->validglbminact);
2353 	   assert(QUAD_TO_DBL(consdata->glbmaxactivity) >= SCIP_INVALID || consdata->validglbmaxact);
2354 	
2355 	   consdata->validmaxabsval = TRUE;
2356 	   consdata->validminabsval = TRUE;
2357 	   consdata->validactivities = TRUE;
2358 	   consdata->validminact = TRUE;
2359 	   consdata->validmaxact = TRUE;
2360 	   consdata->validglbminact = TRUE;
2361 	   consdata->validglbmaxact = TRUE;
2362 	   consdata->maxabsval = 0.0;
2363 	   consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2364 	   QUAD_ASSIGN(consdata->minactivity, 0.0);
2365 	   QUAD_ASSIGN(consdata->maxactivity, 0.0);
2366 	   consdata->lastminactivity = 0.0;
2367 	   consdata->lastmaxactivity = 0.0;
2368 	   consdata->minactivityneginf = 0;
2369 	   consdata->minactivityposinf = 0;
2370 	   consdata->maxactivityneginf = 0;
2371 	   consdata->maxactivityposinf = 0;
2372 	   consdata->minactivityneghuge = 0;
2373 	   consdata->minactivityposhuge = 0;
2374 	   consdata->maxactivityneghuge = 0;
2375 	   consdata->maxactivityposhuge = 0;
2376 	   QUAD_ASSIGN(consdata->glbminactivity, 0.0);
2377 	   QUAD_ASSIGN(consdata->glbmaxactivity, 0.0);
2378 	   consdata->lastglbminactivity = 0.0;
2379 	   consdata->lastglbmaxactivity = 0.0;
2380 	   consdata->glbminactivityneginf = 0;
2381 	   consdata->glbminactivityposinf = 0;
2382 	   consdata->glbmaxactivityneginf = 0;
2383 	   consdata->glbmaxactivityposinf = 0;
2384 	   consdata->glbminactivityneghuge = 0;
2385 	   consdata->glbminactivityposhuge = 0;
2386 	   consdata->glbmaxactivityneghuge = 0;
2387 	   consdata->glbmaxactivityposhuge = 0;
2388 	
2389 	   for( i = 0; i < consdata->nvars; ++i )
2390 	      consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2391 	
2392 	   consdata->lastminactivity = QUAD_TO_DBL(consdata->minactivity);
2393 	   consdata->lastmaxactivity = QUAD_TO_DBL(consdata->maxactivity);
2394 	   consdata->lastglbminactivity = QUAD_TO_DBL(consdata->glbminactivity);
2395 	   consdata->lastglbmaxactivity = QUAD_TO_DBL(consdata->glbmaxactivity);
2396 	}
2397 	
2398 	/** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2399 	 *  and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2400 	 */
2401 	static
2402 	void getMinActivity(
2403 	   SCIP*                 scip,               /**< SCIP data structure */
2404 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2405 	   int                   posinf,             /**< number of coefficients contributing pos. infinite value */
2406 	   int                   neginf,             /**< number of coefficients contributing neg. infinite value */
2407 	   int                   poshuge,            /**< number of coefficients contributing huge pos. value */
2408 	   int                   neghuge,            /**< number of coefficients contributing huge neg. value */
2409 	   SCIP_Real             delta,              /**< value to subtract from stored minactivity
2410 	                                              *   (contribution of the variable set to zero when getting residual activity) */
2411 	   SCIP_Bool             global,             /**< should the global or local minimal activity be returned? */
2412 	   SCIP_Bool             goodrelax,          /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2413 	   SCIP_Real*            minactivity,        /**< pointer to store the minimal activity */
2414 	   SCIP_Bool*            isrelax,            /**< pointer to store whether the activity is a relaxation,
2415 	                                              *   i.e. is <= the exact minactivity (in case of huge contributing values) */
2416 	   SCIP_Bool*            issettoinfinity     /**< pointer to store whether minactivity was set to infinity or calculated */
2417 	   )
2418 	{
2419 	   assert(scip != NULL);
2420 	   assert(consdata != NULL);
2421 	   assert(posinf >= 0);
2422 	   assert(neginf >= 0);
2423 	   assert(poshuge >= 0);
2424 	   assert(neghuge >= 0);
2425 	   assert(minactivity != NULL);
2426 	   assert(isrelax != NULL);
2427 	   assert(issettoinfinity != NULL);
2428 	
2429 	   /* if we have pos. infinite contributions, the minactivity is +infty */
2430 	   if( posinf > 0 )
2431 	   {
2432 	      *minactivity = SCIPinfinity(scip);
2433 	      *issettoinfinity = TRUE;
2434 	      *isrelax = FALSE;
2435 	   }
2436 	   /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2437 	   else if( neginf > 0 )
2438 	   {
2439 	      *minactivity = -SCIPinfinity(scip);
2440 	      *issettoinfinity = TRUE;
2441 	      *isrelax = FALSE;
2442 	   }
2443 	   /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2444 	   else if( neghuge > 0 )
2445 	   {
2446 	      *minactivity = -SCIPinfinity(scip);
2447 	      *issettoinfinity = TRUE;
2448 	      *isrelax = TRUE;
2449 	   }
2450 	   /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2451 	   else if( !goodrelax && poshuge > 0 )
2452 	   {
2453 	      *minactivity = -SCIPinfinity(scip);
2454 	      *issettoinfinity = TRUE;
2455 	      *isrelax = TRUE;
2456 	   }
2457 	   else
2458 	   {
2459 	      SCIP_Real tmpactivity;
2460 	
2461 	      /* recompute minactivity if it is not valid */
2462 	      if( global )
2463 	      {
2464 	         if( !consdata->validglbminact )
2465 	            consdataRecomputeGlbMinactivity(scip, consdata);
2466 	         assert(consdata->validglbminact);
2467 	
2468 	         tmpactivity = QUAD_TO_DBL(consdata->glbminactivity);
2469 	      }
2470 	      else
2471 	      {
2472 	         if( !consdata->validminact )
2473 	            consdataRecomputeMinactivity(scip, consdata);
2474 	         assert(consdata->validminact);
2475 	
2476 	         tmpactivity = QUAD_TO_DBL(consdata->minactivity);
2477 	      }
2478 	
2479 	      /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2480 	       * a feasible relaxation of the minactivity is the number of positive huge contributions
2481 	       * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2482 	       */
2483 	      if( poshuge > 0 )
2484 	      {
2485 	         *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2486 	         *issettoinfinity = FALSE;
2487 	         *isrelax = TRUE;
2488 	      }
2489 	      /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2490 	      else
2491 	      {
2492 	         *minactivity = tmpactivity - delta;
2493 	         *issettoinfinity = FALSE;
2494 	         *isrelax = FALSE;
2495 	      }
2496 	   }
2497 	}
2498 	
2499 	/** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2500 	 *  and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2501 	 */
2502 	static
2503 	void getMaxActivity(
2504 	   SCIP*                 scip,               /**< SCIP data structure */
2505 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2506 	   int                   posinf,             /**< number of coefficients contributing pos. infinite value */
2507 	   int                   neginf,             /**< number of coefficients contributing neg. infinite value */
2508 	   int                   poshuge,            /**< number of coefficients contributing huge pos. value */
2509 	   int                   neghuge,            /**< number of coefficients contributing huge neg. value */
2510 	   SCIP_Real             delta,              /**< value to subtract from stored maxactivity
2511 	                                              *   (contribution of the variable set to zero when getting residual activity) */
2512 	   SCIP_Bool             global,             /**< should the global or local maximal activity be returned? */
2513 	   SCIP_Bool             goodrelax,          /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2514 	   SCIP_Real*            maxactivity,        /**< pointer to store the maximal activity */
2515 	   SCIP_Bool*            isrelax,            /**< pointer to store whether the activity is a relaxation,
2516 	                                              *   i.e. is >= the exact maxactivity (in case of huge contributing values) */
2517 	   SCIP_Bool*            issettoinfinity     /**< pointer to store whether maxactivity was set to infinity or calculated */
2518 	   )
2519 	{
2520 	   assert(scip != NULL);
2521 	   assert(consdata != NULL);
2522 	   assert(posinf >= 0);
2523 	   assert(neginf >= 0);
2524 	   assert(poshuge >= 0);
2525 	   assert(neghuge >= 0);
2526 	   assert(maxactivity != NULL);
2527 	   assert(isrelax != NULL);
2528 	   assert(issettoinfinity != NULL);
2529 	
2530 	   /* if we have neg. infinite contributions, the maxactivity is -infty */
2531 	   if( neginf > 0 )
2532 	   {
2533 	      *maxactivity = -SCIPinfinity(scip);
2534 	      *issettoinfinity = TRUE;
2535 	      *isrelax = FALSE;
2536 	   }
2537 	   /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2538 	   else if( posinf > 0 )
2539 	   {
2540 	      *maxactivity = SCIPinfinity(scip);
2541 	      *issettoinfinity = TRUE;
2542 	      *isrelax = FALSE;
2543 	   }
2544 	   /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2545 	   else if( poshuge > 0 )
2546 	   {
2547 	      *maxactivity = SCIPinfinity(scip);
2548 	      *issettoinfinity = TRUE;
2549 	      *isrelax = TRUE;
2550 	   }
2551 	   /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2552 	   else if( !goodrelax && neghuge > 0 )
2553 	   {
2554 	      *maxactivity = SCIPinfinity(scip);
2555 	      *issettoinfinity = TRUE;
2556 	      *isrelax = TRUE;
2557 	   }
2558 	   else
2559 	   {
2560 	      SCIP_Real tmpactivity;
2561 	
2562 	      /* recompute maxactivity if it is not valid */
2563 	      if( global )
2564 	      {
2565 	         if( !consdata->validglbmaxact )
2566 	            consdataRecomputeGlbMaxactivity(scip, consdata);
2567 	         assert(consdata->validglbmaxact);
2568 	
2569 	         tmpactivity = QUAD_TO_DBL(consdata->glbmaxactivity);
2570 	      }
2571 	      else
2572 	      {
2573 	         if( !consdata->validmaxact )
2574 	            consdataRecomputeMaxactivity(scip, consdata);
2575 	         assert(consdata->validmaxact);
2576 	
2577 	         tmpactivity = QUAD_TO_DBL(consdata->maxactivity);
2578 	      }
2579 	
2580 	      /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2581 	       * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2582 	       * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2583 	       */
2584 	      if( neghuge > 0 )
2585 	      {
2586 	         *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2587 	         *issettoinfinity = FALSE;
2588 	         *isrelax = TRUE;
2589 	      }
2590 	      /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2591 	      else
2592 	      {
2593 	         *maxactivity = tmpactivity - delta;
2594 	         *issettoinfinity = FALSE;
2595 	         *isrelax = FALSE;
2596 	      }
2597 	   }
2598 	}
2599 	
2600 	/** gets activity bounds for constraint */
2601 	static
2602 	void consdataGetActivityBounds(
2603 	   SCIP*                 scip,               /**< SCIP data structure */
2604 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2605 	   SCIP_Bool             goodrelax,          /**< if we have huge contributions, do we need a good relaxation or are
2606 	                                              *   relaxed activities ignored, anyway? */
2607 	   SCIP_Real*            minactivity,        /**< pointer to store the minimal activity */
2608 	   SCIP_Real*            maxactivity,        /**< pointer to store the maximal activity */
2609 	   SCIP_Bool*            minisrelax,         /**< pointer to store whether the returned minactivity is just a relaxation,
2610 	                                              *   i.e. <= the exact minactivity (in case of huge contributions),
2611 	                                              *   or equal to the exact minimal activity */
2612 	   SCIP_Bool*            maxisrelax,         /**< pointer to store whether the returned maxactivity is just a relaxation,
2613 	                                              *   i.e. >= the exact maxactivity (in case of huge contributions),
2614 	                                              *   or equal to the exact maximal activity */
2615 	   SCIP_Bool*            isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2616 	   SCIP_Bool*            ismaxsettoinfinity  /**< pointer to store whether maxactivity was set to infinity or calculated */
2617 	
2618 	   )
2619 	{
2620 	   assert(scip != NULL);
2621 	   assert(consdata != NULL);
2622 	   assert(minactivity != NULL);
2623 	   assert(maxactivity != NULL);
2624 	   assert(isminsettoinfinity != NULL);
2625 	   assert(ismaxsettoinfinity != NULL);
2626 	
2627 	   if( !consdata->validactivities )
2628 	   {
2629 	      consdataCalcActivities(scip, consdata);
2630 	      assert(consdata->validminact);
2631 	      assert(consdata->validmaxact);
2632 	   }
2633 	   assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
2634 	   assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
2635 	   assert(consdata->minactivityneginf >= 0);
2636 	   assert(consdata->minactivityposinf >= 0);
2637 	   assert(consdata->maxactivityneginf >= 0);
2638 	   assert(consdata->maxactivityposinf >= 0);
2639 	
2640 	   getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2641 	      consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2642 	      minactivity, minisrelax, isminsettoinfinity);
2643 	
2644 	   getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2645 	      consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2646 	      maxactivity, maxisrelax, ismaxsettoinfinity);
2647 	}
2648 	
2649 	/** calculates activity bounds for constraint after setting variable to zero */
2650 	static
2651 	void consdataGetReliableResidualActivity(
2652 	   SCIP*                 scip,               /**< SCIP data structure */
2653 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2654 	   SCIP_VAR*             cancelvar,          /**< variable to calculate activity residual for */
2655 	   SCIP_Real*            resactivity,        /**< pointer to store the residual activity */
2656 	   SCIP_Bool             isminresact,        /**< should minimal or maximal residual activity be calculated? */
2657 	   SCIP_Bool             useglobalbounds     /**< should global or local bounds be used? */
2658 	   )
2659 	{
2660 	   SCIP_VAR* var;
2661 	   SCIP_Real val;
2662 	   SCIP_Real lb;
2663 	   SCIP_Real ub;
2664 	   int v;
2665 	
2666 	   assert(scip != NULL);
2667 	   assert(consdata != NULL);
2668 	   assert(cancelvar != NULL);
2669 	   assert(resactivity != NULL);
2670 	
2671 	   *resactivity = 0.0;
2672 	
2673 	   for( v = 0; v < consdata->nvars; ++v )
2674 	   {
2675 	      var = consdata->vars[v];
2676 	      assert(var != NULL);
2677 	      if( var == cancelvar )
2678 	         continue;
2679 	
2680 	      val = consdata->vals[v];
2681 	
2682 	      if( useglobalbounds )
2683 	      {
2684 	         lb = SCIPvarGetLbGlobal(var);
2685 	         ub = SCIPvarGetUbGlobal(var);
2686 	      }
2687 	      else
2688 	      {
2689 	         lb = SCIPvarGetLbLocal(var);
2690 	         ub = SCIPvarGetUbLocal(var);
2691 	      }
2692 	
2693 	      assert(!SCIPisZero(scip, val));
2694 	      assert(SCIPisLE(scip, lb, ub));
2695 	
2696 	      if( val > 0.0 )
2697 	      {
2698 	         if( isminresact )
2699 	         {
2700 	            assert(!SCIPisInfinity(scip, -lb));
2701 	            assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2702 	            *resactivity += val*lb;
2703 	         }
2704 	         else
2705 	         {
2706 	            assert(!SCIPisInfinity(scip, ub));
2707 	            assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2708 	            *resactivity += val*ub;
2709 	         }
2710 	      }
2711 	      else
2712 	      {
2713 	         if( isminresact)
2714 	         {
2715 	            assert(!SCIPisInfinity(scip, ub));
2716 	            assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2717 	            *resactivity += val*ub;
2718 	         }
2719 	         else
2720 	         {
2721 	            assert(!SCIPisInfinity(scip, -lb));
2722 	            assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2723 	            *resactivity += val*lb;
2724 	         }
2725 	      }
2726 	   }
2727 	   assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2728 	}
2729 	
2730 	/** gets activity bounds for constraint after setting variable to zero */
2731 	static
2732 	void consdataGetActivityResiduals(
2733 	   SCIP*                 scip,               /**< SCIP data structure */
2734 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2735 	   SCIP_VAR*             var,                /**< variable to calculate activity residual for */
2736 	   SCIP_Real             val,                /**< coefficient value of variable in linear constraint */
2737 	   SCIP_Bool             goodrelax,          /**< if we have huge contributions, do we need a good relaxation or are
2738 	                                              *   relaxed acticities ignored, anyway? */
2739 	   SCIP_Real*            minresactivity,     /**< pointer to store the minimal residual activity */
2740 	   SCIP_Real*            maxresactivity,     /**< pointer to store the maximal residual activity */
2741 	   SCIP_Bool*            minisrelax,         /**< pointer to store whether the returned residual minactivity is just a
2742 	                                              *   relaxation, i.e. <= the exact residual minactivity (in case of huge
2743 	                                              *   contributions), or equal to the exact residual minactivity */
2744 	   SCIP_Bool*            maxisrelax,         /**< pointer to store whether the returned residual maxactivity is just a
2745 	                                              *   relaxation, i.e. <= the exact residual maxactivity (in case of huge
2746 	                                              *   contributions), or equal to the exact residual minactivity */
2747 	   SCIP_Bool*            isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2748 	   SCIP_Bool*            ismaxsettoinfinity  /**< pointer to store whether maxresactivity was set to infinity or calculated */
2749 	   )
2750 	{
2751 	   SCIP_Real minactbound;
2752 	   SCIP_Real maxactbound;
2753 	   SCIP_Real absval;
2754 	
2755 	   assert(scip != NULL);
2756 	   assert(consdata != NULL);
2757 	   assert(var != NULL);
2758 	   assert(minresactivity != NULL);
2759 	   assert(maxresactivity != NULL);
2760 	   assert(minisrelax != NULL);
2761 	   assert(maxisrelax != NULL);
2762 	   assert(isminsettoinfinity != NULL);
2763 	   assert(ismaxsettoinfinity != NULL);
2764 	
2765 	   /* get activity bounds of linear constraint */
2766 	   if( !consdata->validactivities )
2767 	   {
2768 	      consdataCalcActivities(scip, consdata);
2769 	      assert(consdata->validminact);
2770 	      assert(consdata->validmaxact);
2771 	   }
2772 	   assert(QUAD_TO_DBL(consdata->minactivity) < SCIP_INVALID);
2773 	   assert(QUAD_TO_DBL(consdata->maxactivity) < SCIP_INVALID);
2774 	   assert(consdata->minactivityneginf >= 0);
2775 	   assert(consdata->minactivityposinf >= 0);
2776 	   assert(consdata->maxactivityneginf >= 0);
2777 	   assert(consdata->maxactivityposinf >= 0);
2778 	   assert(consdata->minactivityneghuge >= 0);
2779 	   assert(consdata->minactivityposhuge >= 0);
2780 	   assert(consdata->maxactivityneghuge >= 0);
2781 	   assert(consdata->maxactivityposhuge >= 0);
2782 	
2783 	   if( val > 0.0 )
2784 	   {
2785 	      minactbound = SCIPvarGetLbLocal(var);
2786 	      maxactbound = SCIPvarGetUbLocal(var);
2787 	      absval = val;
2788 	   }
2789 	   else
2790 	   {
2791 	      minactbound = -SCIPvarGetUbLocal(var);
2792 	      maxactbound = -SCIPvarGetLbLocal(var);
2793 	      absval = -val;
2794 	   }
2795 	
2796 	   /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2797 	    * and contribution of variable set to zero that has to be subtracted from finite part of activity
2798 	    */
2799 	   if( SCIPisInfinity(scip, minactbound) )
2800 	   {
2801 	      assert(consdata->minactivityposinf >= 1);
2802 	
2803 	      getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2804 	         consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2805 	         minresactivity, minisrelax, isminsettoinfinity);
2806 	   }
2807 	   else if( SCIPisInfinity(scip, -minactbound) )
2808 	   {
2809 	      assert(consdata->minactivityneginf >= 1);
2810 	
2811 	      getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2812 	         consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2813 	         minresactivity, minisrelax, isminsettoinfinity);
2814 	   }
2815 	   else if( SCIPisHugeValue(scip, minactbound * absval) )
2816 	   {
2817 	      assert(consdata->minactivityposhuge >= 1);
2818 	
2819 	      getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2820 	         consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2821 	         minresactivity, minisrelax, isminsettoinfinity);
2822 	   }
2823 	   else if( SCIPisHugeValue(scip, -minactbound * absval) )
2824 	   {
2825 	      assert(consdata->minactivityneghuge >= 1);
2826 	
2827 	      getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2828 	         consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2829 	         minresactivity, minisrelax, isminsettoinfinity);
2830 	   }
2831 	   else
2832 	   {
2833 	      getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2834 	         consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2835 	         minresactivity, minisrelax, isminsettoinfinity);
2836 	   }
2837 	
2838 	   /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2839 	    * and contribution of variable set to zero that has to be subtracted from finite part of activity
2840 	    */
2841 	   if( SCIPisInfinity(scip, -maxactbound) )
2842 	   {
2843 	      assert(consdata->maxactivityneginf >= 1);
2844 	
2845 	      getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2846 	         consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2847 	         maxresactivity, maxisrelax, ismaxsettoinfinity);
2848 	   }
2849 	   else if( SCIPisInfinity(scip, maxactbound) )
2850 	   {
2851 	      assert(consdata->maxactivityposinf >= 1);
2852 	
2853 	      getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2854 	         consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2855 	         maxresactivity, maxisrelax, ismaxsettoinfinity);
2856 	   }
2857 	   else if( SCIPisHugeValue(scip, absval * maxactbound) )
2858 	   {
2859 	      assert(consdata->maxactivityposhuge >= 1);
2860 	
2861 	      getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2862 	         consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2863 	         maxresactivity, maxisrelax, ismaxsettoinfinity);
2864 	   }
2865 	   else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2866 	   {
2867 	      assert(consdata->maxactivityneghuge >= 1);
2868 	
2869 	      getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2870 	         consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2871 	         maxresactivity, maxisrelax, ismaxsettoinfinity);
2872 	   }
2873 	   else
2874 	   {
2875 	      getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2876 	         consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2877 	         maxresactivity, maxisrelax, ismaxsettoinfinity);
2878 	   }
2879 	}
2880 	
2881 	/** gets global activity bounds for constraint */
2882 	static
2883 	void consdataGetGlbActivityBounds(
2884 	   SCIP*                 scip,               /**< SCIP data structure */
2885 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2886 	   SCIP_Bool             goodrelax,          /**< if we have huge contributions, do we need a good relaxation or are
2887 	                                              *   relaxed acticities ignored, anyway? */
2888 	   SCIP_Real*            glbminactivity,     /**< pointer to store the minimal activity, or NULL, if not needed */
2889 	   SCIP_Real*            glbmaxactivity,     /**< pointer to store the maximal activity, or NULL, if not needed */
2890 	   SCIP_Bool*            minisrelax,         /**< pointer to store whether the returned minactivity is just a relaxation,
2891 	                                              *   i.e. <= the exact minactivity (in case of huge contributions),
2892 	                                              *   or equal to the exact minimal activity */
2893 	   SCIP_Bool*            maxisrelax,         /**< pointer to store whether the returned maxactivity is just a relaxation,
2894 	                                              *   i.e. >= the exact maxactivity (in case of huge contributions),
2895 	                                              *   or equal to the exact maximal activity */
2896 	   SCIP_Bool*            isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2897 	   SCIP_Bool*            ismaxsettoinfinity  /**< pointer to store whether maxresactivity was set to infinity or calculated */
2898 	   )
2899 	{
2900 	   assert(scip != NULL);
2901 	   assert(consdata != NULL);
2902 	   assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2903 	      || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2904 	
2905 	   if( !consdata->validactivities )
2906 	   {
2907 	      consdataCalcActivities(scip, consdata);
2908 	      assert(consdata->validglbminact);
2909 	      assert(consdata->validglbmaxact);
2910 	   }
2911 	   assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
2912 	   assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
2913 	   assert(consdata->glbminactivityneginf >= 0);
2914 	   assert(consdata->glbminactivityposinf >= 0);
2915 	   assert(consdata->glbmaxactivityneginf >= 0);
2916 	   assert(consdata->glbmaxactivityposinf >= 0);
2917 	   assert(consdata->glbminactivityneghuge >= 0);
2918 	   assert(consdata->glbminactivityposhuge >= 0);
2919 	   assert(consdata->glbmaxactivityneghuge >= 0);
2920 	   assert(consdata->glbmaxactivityposhuge >= 0);
2921 	
2922 	   if( glbminactivity != NULL )
2923 	   {
2924 	      assert(isminsettoinfinity != NULL);
2925 	      assert(minisrelax != NULL);
2926 	
2927 	      getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2928 	         consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2929 	         glbminactivity, minisrelax, isminsettoinfinity);
2930 	   }
2931 	
2932 	   if( glbmaxactivity != NULL )
2933 	   {
2934 	      assert(ismaxsettoinfinity != NULL);
2935 	      assert(maxisrelax != NULL);
2936 	
2937 	      getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2938 	         consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2939 	         glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2940 	   }
2941 	}
2942 	
2943 	/** gets global activity bounds for constraint after setting variable to zero */
2944 	static
2945 	void consdataGetGlbActivityResiduals(
2946 	   SCIP*                 scip,               /**< SCIP data structure */
2947 	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
2948 	   SCIP_VAR*             var,                /**< variable to calculate activity residual for */
2949 	   SCIP_Real             val,                /**< coefficient value of variable in linear constraint */
2950 	   SCIP_Bool             goodrelax,          /**< if we have huge contributions, do we need a good relaxation or are
2951 	                                              *   relaxed acticities ignored, anyway? */
2952 	   SCIP_Real*            minresactivity,     /**< pointer to store the minimal residual activity, or NULL, if not needed */
2953 	   SCIP_Real*            maxresactivity,     /**< pointer to store the maximal residual activity, or NULL, if not needed */
2954 	   SCIP_Bool*            minisrelax,         /**< pointer to store whether the returned residual minactivity is just a
2955 	                                              *   relaxation, i.e. <= the exact residual minactivity (in case of huge
2956 	                                              *   contributions), or equal to the exact residual minactivity */
2957 	   SCIP_Bool*            maxisrelax,         /**< pointer to store whether the returned residual maxactivity is just a
2958 	                                              *   relaxation, i.e. <= the exact residual maxactivity (in case of huge
2959 	                                              *   contributions), or equal to the exact residual minactivity */
2960 	   SCIP_Bool*            isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2961 	   SCIP_Bool*            ismaxsettoinfinity  /**< pointer to store whether maxresactivity was set to infinity or calculated */
2962 	   )
2963 	{
2964 	   SCIP_Real minactbound;
2965 	   SCIP_Real maxactbound;
2966 	   SCIP_Real absval;
2967 	
2968 	   assert(scip != NULL);
2969 	   assert(consdata != NULL);
2970 	   assert(var != NULL);
2971 	   assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2972 	      || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2973 	
2974 	   /* get activity bounds of linear constraint */
2975 	   if( !consdata->validactivities )
2976 	      consdataCalcActivities(scip, consdata);
2977 	
2978 	   assert(QUAD_TO_DBL(consdata->glbminactivity) < SCIP_INVALID);
2979 	   assert(QUAD_TO_DBL(consdata->glbmaxactivity) < SCIP_INVALID);
2980 	   assert(consdata->glbminactivityneginf >= 0);
2981 	   assert(consdata->glbminactivityposinf >= 0);
2982 	   assert(consdata->glbmaxactivityneginf >= 0);
2983 	   assert(consdata->glbmaxactivityposinf >= 0);
2984 	
2985 	   if( val > 0.0 )
2986 	   {
2987 	      minactbound = SCIPvarGetLbGlobal(var);
2988 	      maxactbound = SCIPvarGetUbGlobal(var);
2989 	      absval = val;
2990 	   }
2991 	   else
2992 	   {
2993 	      minactbound = -SCIPvarGetUbGlobal(var);
2994 	      maxactbound = -SCIPvarGetLbGlobal(var);
2995 	      absval = -val;
2996 	   }
2997 	
2998 	   if( minresactivity != NULL )
2999 	   {
3000 	      assert(isminsettoinfinity != NULL);
3001 	      assert(minisrelax != NULL);
3002 	
3003 	      /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
3004 	       * and contribution of variable set to zero that has to be subtracted from finite part of activity
3005 	       */
3006 	      if( SCIPisInfinity(scip, minactbound) )
3007 	      {
3008 	         assert(consdata->glbminactivityposinf >= 1);
3009 	
3010 	         getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
3011 	            consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3012 	            minresactivity, minisrelax, isminsettoinfinity);
3013 	      }
3014 	      else if( SCIPisInfinity(scip, -minactbound) )
3015 	      {
3016 	         assert(consdata->glbminactivityneginf >= 1);
3017 	
3018 	         getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
3019 	            consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3020 	            minresactivity, minisrelax, isminsettoinfinity);
3021 	      }
3022 	      else if( SCIPisHugeValue(scip, minactbound * absval) )
3023 	      {
3024 	         assert(consdata->glbminactivityposhuge >= 1);
3025 	
3026 	         getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3027 	            consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3028 	            minresactivity, minisrelax, isminsettoinfinity);
3029 	      }
3030 	      else if( SCIPisHugeValue(scip, -minactbound * absval) )
3031 	      {
3032 	         assert(consdata->glbminactivityneghuge >= 1);
3033 	
3034 	         getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3035 	            consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
3036 	            minresactivity, minisrelax, isminsettoinfinity);
3037 	      }
3038 	      else
3039 	      {
3040 	         getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3041 	            consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
3042 	            goodrelax, minresactivity, minisrelax, isminsettoinfinity);
3043 	      }
3044 	   }
3045 	
3046 	   if( maxresactivity != NULL )
3047 	   {
3048 	      assert(ismaxsettoinfinity != NULL);
3049 	      assert(maxisrelax != NULL);
3050 	
3051 	      /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
3052 	       * and contribution of variable set to zero that has to be subtracted from finite part of activity
3053 	       */
3054 	      if( SCIPisInfinity(scip, -maxactbound) )
3055 	      {
3056 	         assert(consdata->glbmaxactivityneginf >= 1);
3057 	
3058 	         getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
3059 	            consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3060 	            maxresactivity, maxisrelax, ismaxsettoinfinity);
3061 	      }
3062 	      else if( SCIPisInfinity(scip, maxactbound) )
3063 	      {
3064 	         assert(consdata->glbmaxactivityposinf >= 1);
3065 	
3066 	         getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
3067 	            consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3068 	            maxresactivity, maxisrelax, ismaxsettoinfinity);
3069 	      }
3070 	      else if( SCIPisHugeValue(scip, absval * maxactbound) )
3071 	      {
3072 	         assert(consdata->glbmaxactivityposhuge >= 1);
3073 	
3074 	         getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3075 	            consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3076 	            maxresactivity, maxisrelax, ismaxsettoinfinity);
3077 	      }
3078 	      else if( SCIPisHugeValue(scip, -absval * maxactbound) )
3079 	      {
3080 	         assert(consdata->glbmaxactivityneghuge >= 1);
3081 	
3082 	         getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3083 	            consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
3084 	            maxresactivity, maxisrelax, ismaxsettoinfinity);
3085 	      }
3086 	      else
3087 	      {
3088 	         getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3089 	            consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
3090 	            goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
3091 	      }
3092 	   }
3093 	}
3094 	
3095 	/** calculates the activity of the linear constraint for given solution */
3096 	static
3097 	SCIP_Real consdataGetActivity(
3098 	   SCIP*                 scip,               /**< SCIP data structure */
3099 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
3100 	   SCIP_SOL*             sol                 /**< solution to get activity for, NULL to current solution */
3101 	   )
3102 	{
3103 	   SCIP_Real activity;
3104 	
3105 	   assert(scip != NULL);
3106 	   assert(consdata != NULL);
3107 	
3108 	   if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
3109 	      activity = consdataComputePseudoActivity(scip, consdata);
3110 	   else
3111 	   {
3112 	      SCIP_Real solval;
3113 	      int nposinf;
3114 	      int nneginf;
3115 	      SCIP_Bool negsign;
3116 	      int v;
3117 	
3118 	      activity = 0.0;
3119 	      nposinf = 0;
3120 	      nneginf = 0;
3121 	
3122 	      for( v = 0; v < consdata->nvars; ++v )
3123 	      {
3124 	         solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3125 	
3126 	         if( consdata->vals[v] < 0 )
3127 	            negsign = TRUE;
3128 	         else
3129 	            negsign = FALSE;
3130 	
3131 	         if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3132 	            ++nposinf;
3133 	         else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3134 	            ++nneginf;
3135 	         else
3136 	            activity += consdata->vals[v] * solval;
3137 	      }
3138 	      assert(nneginf >= 0 && nposinf >= 0);
3139 	
3140 	      SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3141 	
3142 	      /* check for amount of infinity values and correct the activity */
3143 	      if( nposinf > 0 && nneginf > 0 )
3144 	         activity = (consdata->rhs + consdata->lhs) / 2;
3145 	      else if( nposinf > 0 )
3146 	         activity = SCIPinfinity(scip);
3147 	      else if( nneginf > 0 )
3148 	         activity = -SCIPinfinity(scip);
3149 	
3150 	      SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3151 	   }
3152 	
3153 	   if( activity == SCIP_INVALID ) /*lint !e777*/
3154 	      return activity;
3155 	   else if( activity < 0 )
3156 	      activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3157 	   else
3158 	      activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3159 	
3160 	   return activity;
3161 	}
3162 	
3163 	/** calculates the feasibility of the linear constraint for given solution */
3164 	static
3165 	SCIP_Real consdataGetFeasibility(
3166 	   SCIP*                 scip,               /**< SCIP data structure */
3167 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
3168 	   SCIP_SOL*             sol                 /**< solution to get feasibility for, NULL to current solution */
3169 	   )
3170 	{
3171 	   SCIP_Real activity;
3172 	
3173 	   assert(scip != NULL);
3174 	   assert(consdata != NULL);
3175 	
3176 	   activity = consdataGetActivity(scip, consdata, sol);
3177 	
3178 	   if( activity == SCIP_INVALID ) /*lint !e777*/
3179 	      return -SCIPinfinity(scip);
3180 	
3181 	   return MIN(consdata->rhs - activity, activity - consdata->lhs);
3182 	}
3183 	
3184 	/** updates bit signatures after adding a single coefficient */
3185 	static
3186 	void consdataUpdateSignatures(
3187 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
3188 	   int                   pos                 /**< position of coefficient to update signatures for */
3189 	   )
3190 	{
3191 	   uint64_t varsignature;
3192 	   SCIP_Real lb;
3193 	   SCIP_Real ub;
3194 	   SCIP_Real val;
3195 	
3196 	   assert(consdata != NULL);
3197 	   assert(consdata->validsignature);
3198 	
3199 	   varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3200 	   lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3201 	   ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3202 	   val = consdata->vals[pos];
3203 	   if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3204 	      consdata->possignature |= varsignature;
3205 	   if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3206 	      consdata->negsignature |= varsignature;
3207 	}
3208 	
3209 	/** calculates the bit signatures of the given constraint data */
3210 	static
3211 	void consdataCalcSignatures(
3212 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
3213 	   )
3214 	{
3215 	   assert(consdata != NULL);
3216 	
3217 	   if( !consdata->validsignature )
3218 	   {
3219 	      int i;
3220 	
3221 	      consdata->validsignature = TRUE;
3222 	      consdata->possignature = 0;
3223 	      consdata->negsignature = 0;
3224 	      for( i = 0; i < consdata->nvars; ++i )
3225 	         consdataUpdateSignatures(consdata, i);
3226 	   }
3227 	}
3228 	
3229 	/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3230 	static
3231 	SCIP_DECL_SORTINDCOMP(consdataCompVar)
3232 	{  /*lint --e{715}*/
3233 	   SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3234 	   SCIP_VAR* var1;
3235 	   SCIP_VAR* var2;
3236 	
3237 	   assert(consdata != NULL);
3238 	   assert(0 <= ind1 && ind1 < consdata->nvars);
3239 	   assert(0 <= ind2 && ind2 < consdata->nvars);
3240 	
3241 	   var1 = consdata->vars[ind1];
3242 	   var2 = consdata->vars[ind2];
3243 	
3244 	   /* exactly one variable is binary */
3245 	   if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3246 	   {
3247 	      return (SCIPvarIsBinary(var1) ? -1 : +1);
3248 	   }
3249 	   /* both variables are binary */
3250 	   else if( SCIPvarIsBinary(var1) )
3251 	   {
3252 	      return SCIPvarCompare(var1, var2);
3253 	   }
3254 	   else
3255 	   {
3256 	      SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3257 	      SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3258 	
3259 	      if( vartype1 < vartype2 )
3260 	         return -1;
3261 	      else if( vartype1 > vartype2 )
3262 	         return +1;
3263 	      else
3264 	         return SCIPvarCompare(var1, var2);
3265 	   }
3266 	}
3267 	
3268 	/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3269 	static
3270 	SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3271 	{  /*lint --e{715}*/
3272 	   SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3273 	   SCIP_VAR* var1;
3274 	   SCIP_VAR* var2;
3275 	
3276 	   assert(consdata != NULL);
3277 	   assert(0 <= ind1 && ind1 < consdata->nvars);
3278 	   assert(0 <= ind2 && ind2 < consdata->nvars);
3279 	
3280 	   var1 = consdata->vars[ind1];
3281 	   var2 = consdata->vars[ind2];
3282 	
3283 	   /* exactly one variable is binary */
3284 	   if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3285 	   {
3286 	      return (SCIPvarIsBinary(var1) ? -1 : +1);
3287 	   }
3288 	   /* both variables are binary */
3289 	   else if( SCIPvarIsBinary(var1) )
3290 	   {
3291 	      SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
3292 	      SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
3293 	
3294 	      if( EPSGT(abscoef1, abscoef2, 1e-9) )
3295 	         return -1;
3296 	      else if( EPSGT(abscoef2, abscoef1, 1e-9) )
3297 	         return +1;
3298 	      else
3299 	         return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3300 	   }
3301 	   else
3302 	   {
3303 	      SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3304 	      SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3305 	
3306 	      if( vartype1 < vartype2 )
3307 	      {
3308 	         return -1;
3309 	      }
3310 	      else if( vartype1 > vartype2 )
3311 	      {
3312 	         return +1;
3313 	      }
3314 	      else
3315 	      {
3316 	         /* both variables are continuous */
3317 	         if( !SCIPvarIsIntegral(var1) )
3318 	         {
3319 	            assert(!SCIPvarIsIntegral(var2));
3320 	            return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3321 	         }
3322 	         else
3323 	         {
3324 	            SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
3325 	            SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
3326 	
3327 	            if( EPSGT(abscont1, abscont2, 1e-9) )
3328 	               return -1;
3329 	            else if( EPSGT(abscont2, abscont1, 1e-9) )
3330 	               return +1;
3331 	            else
3332 	               return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3333 	         }
3334 	      }
3335 	   }
3336 	}
3337 	
3338 	/** permutes the constraint's variables according to a given permutation. */
3339 	static
3340 	void permSortConsdata(
3341 	   SCIP_CONSDATA*        consdata,           /**< the constraint data */
3342 	   int*                  perm,               /**< the target permutation */
3343 	   int                   nvars               /**< the number of variables */
3344 	   )
3345 	{  /*lint --e{715}*/
3346 	   SCIP_VAR* varv;
3347 	   SCIP_EVENTDATA* eventdatav;
3348 	   SCIP_Real valv;
3349 	   int v;
3350 	   int i;
3351 	   int nexti;
3352 	
3353 	   assert(perm != NULL);
3354 	   assert(consdata != NULL);
3355 	
3356 	   /* permute the variables in the linear constraint according to the target permutation */
3357 	   eventdatav = NULL;
3358 	   for( v = 0; v < nvars; ++v )
3359 	   {
3360 	      if( perm[v] != v )
3361 	      {
3362 	         varv = consdata->vars[v];
3363 	         valv = consdata->vals[v];
3364 	         if( consdata->eventdata != NULL )
3365 	            eventdatav = consdata->eventdata[v];
3366 	         i = v;
3367 	         do
3368 	         {
3369 	            assert(0 <= perm[i] && perm[i] < nvars);
3370 	            assert(perm[i] != i);
3371 	            consdata->vars[i] = consdata->vars[perm[i]];
3372 	            consdata->vals[i] = consdata->vals[perm[i]];
3373 	            if( consdata->eventdata != NULL )
3374 	            {
3375 	               consdata->eventdata[i] = consdata->eventdata[perm[i]];
3376 	               consdata->eventdata[i]->varpos = i;
3377 	            }
3378 	            nexti = perm[i];
3379 	            perm[i] = i;
3380 	            i = nexti;
3381 	         }
3382 	         while( perm[i] != v );
3383 	         consdata->vars[i] = varv;
3384 	         consdata->vals[i] = valv;
3385 	         if( consdata->eventdata != NULL )
3386 	         {
3387 	            consdata->eventdata[i] = eventdatav;
3388 	            consdata->eventdata[i]->varpos = i;
3389 	         }
3390 	         perm[i] = i;
3391 	      }
3392 	   }
3393 	#ifdef SCIP_DEBUG
3394 	   /* check sorting */
3395 	   for( v = 0; v < nvars; ++v )
3396 	   {
3397 	      assert(perm[v] == v);
3398 	      assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3399 	   }
3400 	#endif
3401 	}
3402 	
3403 	/** sorts linear constraint's variables depending on the stage of the solving process:
3404 	 * - during PRESOLVING
3405 	 *       sorts variables by binaries, integers, implicit integers, and continuous variables,
3406 	 *       and the variables of the same type by non-decreasing variable index
3407 	 *
3408 	 * - during SOLVING
3409 	 *       sorts variables of the remaining problem by binaries, integers, implicit integers, and continuous variables,
3410 	 *       and binary and integer variables by their global max activity delta (within each group),
3411 	 *       ties within a group are broken by problem index of the variable.
3412 	 *
3413 	 *       This fastens the propagation time of the constraint handler.
3414 	 */
3415 	static
3416 	SCIP_RETCODE consdataSort(
3417 	   SCIP*                 scip,               /**< SCIP data structure */
3418 	   SCIP_CONSDATA*        consdata            /**< linear constraint data */
3419 	   )
3420 	{
3421 	   assert(scip != NULL);
3422 	   assert(consdata != NULL);
3423 	
3424 	   /* check if there are variables for sorting */
3425 	   if( consdata->nvars <= 1 )
3426 	   {
3427 	      consdata->indexsorted = TRUE;
3428 	      consdata->coefsorted = TRUE;
3429 	      consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3430 	   }
3431 	   else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3432 	      || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3433 	   {
3434 	      int* perm;
3435 	      int v;
3436 	
3437 	      /* get temporary memory to store the sorted permutation */
3438 	      SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3439 	
3440 	      /* call sorting method  */
3441 	      if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3442 	         SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3443 	      else
3444 	         SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3445 	
3446 	      permSortConsdata(consdata, perm, consdata->nvars);
3447 	
3448 	      /* free temporary memory */
3449 	      SCIPfreeBufferArray(scip, &perm);
3450 	
3451 	      if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE )
3452 	      {
3453 	         consdata->indexsorted = FALSE;
3454 	         consdata->coefsorted = TRUE;
3455 	
3456 	         /* count binary variables in the sorted vars array */
3457 	         consdata->nbinvars = 0;
3458 	         for( v = 0; v < consdata->nvars; ++v )
3459 	         {
3460 	            if( SCIPvarIsBinary(consdata->vars[v]) )
3461 	               ++consdata->nbinvars;
3462 	            else
3463 	               break;
3464 	         }
3465 	      }
3466 	      else
3467 	      {
3468 	         consdata->indexsorted = TRUE;
3469 	         consdata->coefsorted = FALSE;
3470 	      }
3471 	   }
3472 	
3473 	   return SCIP_OKAY;
3474 	}
3475 	
3476 	
3477 	/*
3478 	 * local linear constraint handler methods
3479 	 */
3480 	
3481 	/** sets left hand side of linear constraint */
3482 	static
3483 	SCIP_RETCODE chgLhs(
3484 	   SCIP*                 scip,               /**< SCIP data structure */
3485 	   SCIP_CONS*            cons,               /**< linear constraint */
3486 	   SCIP_Real             lhs                 /**< new left hand side */
3487 	   )
3488 	{
3489 	   SCIP_CONSDATA* consdata;
3490 	   SCIP_Bool locked;
3491 	   int i;
3492 	
3493 	   assert(scip != NULL);
3494 	   assert(cons != NULL);
3495 	   assert(!SCIPisInfinity(scip, lhs));
3496 	
3497 	   /* adjust value to not be smaller than -inf */
3498 	   if ( SCIPisInfinity(scip, -lhs) )
3499 	      lhs = -SCIPinfinity(scip);
3500 	
3501 	   consdata = SCIPconsGetData(cons);
3502 	   assert(consdata != NULL);
3503 	   assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3504 	   assert(!SCIPisInfinity(scip, consdata->lhs));
3505 	
3506 	   /* check whether the side is not changed */
3507 	   if( SCIPisEQ(scip, consdata->lhs, lhs) )
3508 	      return SCIP_OKAY;
3509 	
3510 	   /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3511 	   if( SCIPisEQ(scip, lhs, consdata->rhs) )
3512 	   {
3513 	      consdata->rhs = lhs;
3514 	      assert(consdata->row == NULL);
3515 	   }
3516 	
3517 	   locked = FALSE;
3518 	   for( i = 0; i < NLOCKTYPES && !locked; i++ )
3519 	      locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3520 	
3521 	   /* if necessary, update the rounding locks of variables */
3522 	   if( locked )
3523 	   {
3524 	      if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3525 	      {
3526 	         SCIP_VAR** vars;
3527 	         SCIP_Real* vals;
3528 	         int v;
3529 	
3530 	         /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3531 	         vars = consdata->vars;
3532 	         vals = consdata->vals;
3533 	
3534 	         for( v = 0; v < consdata->nvars; ++v )
3535 	         {
3536 	            assert(vars[v] != NULL);
3537 	            assert(!SCIPisZero(scip, vals[v]));
3538 	
3539 	            if( SCIPisPositive(scip, vals[v]) )
3540 	            {
3541 	               SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3542 	            }
3543 	            else
3544 	            {
3545 	               SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3546 	            }
3547 	         }
3548 	      }
3549 	      else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3550 	      {
3551 	         SCIP_VAR** vars;
3552 	         SCIP_Real* vals;
3553 	         int v;
3554 	
3555 	         /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3556 	         vars = consdata->vars;
3557 	         vals = consdata->vals;
3558 	
3559 	         for( v = 0; v < consdata->nvars; ++v )
3560 	         {
3561 	            assert(vars[v] != NULL);
3562 	            assert(!SCIPisZero(scip, vals[v]));
3563 	
3564 	            if( SCIPisPositive(scip, vals[v]) )
3565 	            {
3566 	               SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3567 	            }
3568 	            else
3569 	            {
3570 	               SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3571 	            }
3572 	         }
3573 	      }
3574 	   }
3575 	
3576 	   /* check whether the left hand side is increased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
3577 	   if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3578 	   {
3579 	      consdata->boundstightened = 0;
3580 	      consdata->presolved = FALSE;
3581 	      consdata->cliquesadded = FALSE;
3582 	      consdata->implsadded = FALSE;
3583 	
3584 	      /* mark the constraint for propagation */
3585 	      if( SCIPconsIsTransformed(cons) )
3586 	      {
3587 	         SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3588 	      }
3589 	   }
3590 	
3591 	   /* set new left hand side and update constraint data */
3592 	   consdata->lhs = lhs;
3593 	   consdata->changed = TRUE;
3594 	   consdata->normalized = FALSE;
3595 	   consdata->upgradetried = FALSE;
3596 	   consdata->rangedrowpropagated = 0;
3597 	
3598 	   /* update the lhs of the LP row */
3599 	   if( consdata->row != NULL )
3600 	   {
3601 	      SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3602 	   }
3603 	
3604 	   return SCIP_OKAY;
3605 	}
3606 	
3607 	/** sets right hand side of linear constraint */
3608 	static
3609 	SCIP_RETCODE chgRhs(
3610 	   SCIP*                 scip,               /**< SCIP data structure */
3611 	   SCIP_CONS*            cons,               /**< linear constraint */
3612 	   SCIP_Real             rhs                 /**< new right hand side */
3613 	   )
3614 	{
3615 	   SCIP_CONSDATA* consdata;
3616 	   SCIP_Bool locked;
3617 	   int i;
3618 	
3619 	   assert(scip != NULL);
3620 	   assert(cons != NULL);
3621 	   assert(!SCIPisInfinity(scip, -rhs));
3622 	
3623 	   /* adjust value to not be larger than inf */
3624 	   if ( SCIPisInfinity(scip, rhs) )
3625 	      rhs = SCIPinfinity(scip);
3626 	
3627 	   consdata = SCIPconsGetData(cons);
3628 	   assert(consdata != NULL);
3629 	   assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3630 	   assert(!SCIPisInfinity(scip, -consdata->rhs));
3631 	
3632 	   /* check whether the side is not changed */
3633 	   if( SCIPisEQ(scip, consdata->rhs, rhs) )
3634 	      return SCIP_OKAY;
3635 	
3636 	   /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3637 	   if( SCIPisEQ(scip, rhs, consdata->lhs) )
3638 	   {
3639 	      consdata->lhs = rhs;
3640 	      assert(consdata->row == NULL);
3641 	   }
3642 	
3643 	   locked = FALSE;
3644 	   for( i = 0; i < NLOCKTYPES && !locked; i++ )
3645 	      locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3646 	
3647 	   /* if necessary, update the rounding locks of variables */
3648 	   if( locked )
3649 	   {
3650 	      assert(SCIPconsIsTransformed(cons));
3651 	
3652 	      if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3653 	      {
3654 	         SCIP_VAR** vars;
3655 	         SCIP_Real* vals;
3656 	         int v;
3657 	
3658 	         /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3659 	         vars = consdata->vars;
3660 	         vals = consdata->vals;
3661 	
3662 	         for( v = 0; v < consdata->nvars; ++v )
3663 	         {
3664 	            assert(vars[v] != NULL);
3665 	            assert(!SCIPisZero(scip, vals[v]));
3666 	
3667 	            if( SCIPisPositive(scip, vals[v]) )
3668 	            {
3669 	               SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3670 	            }
3671 	            else
3672 	            {
3673 	               SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3674 	            }
3675 	         }
3676 	      }
3677 	      else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3678 	      {
3679 	         SCIP_VAR** vars;
3680 	         SCIP_Real* vals;
3681 	         int v;
3682 	
3683 	         /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3684 	         vars = consdata->vars;
3685 	         vals = consdata->vals;
3686 	
3687 	         for( v = 0; v < consdata->nvars; ++v )
3688 	         {
3689 	            assert(vars[v] != NULL);
3690 	            assert(!SCIPisZero(scip, vals[v]));
3691 	
3692 	            if( SCIPisPositive(scip, vals[v]) )
3693 	            {
3694 	               SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3695 	            }
3696 	            else
3697 	            {
3698 	               SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3699 	            }
3700 	         }
3701 	      }
3702 	   }
3703 	
3704 	   /* check whether the right hand side is decreased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
3705 	   if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3706 	   {
3707 	      consdata->boundstightened = 0;
3708 	      consdata->presolved = FALSE;
3709 	      consdata->cliquesadded = FALSE;
3710 	      consdata->implsadded = FALSE;
3711 	
3712 	      /* mark the constraint for propagation */
3713 	      if( SCIPconsIsTransformed(cons) )
3714 	      {
3715 	         SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3716 	      }
3717 	   }
3718 	
3719 	   /* set new right hand side and update constraint data */
3720 	   consdata->rhs = rhs;
3721 	   consdata->changed = TRUE;
3722 	   consdata->normalized = FALSE;
3723 	   consdata->upgradetried = FALSE;
3724 	   consdata->rangedrowpropagated = 0;
3725 	
3726 	   /* update the rhs of the LP row */
3727 	   if( consdata->row != NULL )
3728 	   {
3729 	      SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3730 	   }
3731 	
3732 	   return SCIP_OKAY;
3733 	}
3734 	
3735 	/** adds coefficient in linear constraint */
3736 	static
3737 	SCIP_RETCODE addCoef(
3738 	   SCIP*                 scip,               /**< SCIP data structure */
3739 	   SCIP_CONS*            cons,               /**< linear constraint */
3740 	   SCIP_VAR*             var,                /**< variable of constraint entry */
3741 	   SCIP_Real             val                 /**< coefficient of constraint entry */
3742 	   )
3743 	{
3744 	   SCIP_CONSDATA* consdata;
3745 	   SCIP_Bool transformed;
3746 	
3747 	   assert(scip != NULL);
3748 	   assert(cons != NULL);
3749 	   assert(var != NULL);
3750 	
3751 	   /* relaxation-only variables must not be used in checked or enforced constraints */
3752 	   assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
3753 	
3754 	   /* ignore coefficient if it is nearly zero */
3755 	   if( SCIPisZero(scip, val) )
3756 	      return SCIP_OKAY;
3757 	
3758 	   consdata = SCIPconsGetData(cons);
3759 	   assert(consdata != NULL);
3760 	
3761 	   /* are we in the transformed problem? */
3762 	   transformed = SCIPconsIsTransformed(cons);
3763 	
3764 	   /* always use transformed variables in transformed constraints */
3765 	   if( transformed )
3766 	   {
3767 	      SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3768 	   }
3769 	   assert(var != NULL);
3770 	   assert(transformed == SCIPvarIsTransformed(var));
3771 	
3772 	   SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3773 	   consdata->vars[consdata->nvars] = var;
3774 	   consdata->vals[consdata->nvars] = val;
3775 	   consdata->nvars++;
3776 	
3777 	   /* capture variable */
3778 	   SCIP_CALL( SCIPcaptureVar(scip, var) );
3779 	
3780 	   /* if we are in transformed problem, the variable needs an additional event data */
3781 	   if( transformed )
3782 	   {
3783 	      if( consdata->eventdata != NULL )
3784 	      {
3785 	         SCIP_CONSHDLR* conshdlr;
3786 	         SCIP_CONSHDLRDATA* conshdlrdata;
3787 	
3788 	         /* check for event handler */
3789 	         conshdlr = SCIPconsGetHdlr(cons);
3790 	         conshdlrdata = SCIPconshdlrGetData(conshdlr);
3791 	         assert(conshdlrdata != NULL);
3792 	         assert(conshdlrdata->eventhdlr != NULL);
3793 	
3794 	         /* initialize eventdata array */
3795 	         consdata->eventdata[consdata->nvars-1] = NULL;
3796 	
3797 	         /* catch bound change events of variable */
3798 	         SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3799 	      }
3800 	
3801 	      /* update minimum and maximum activities */
3802 	      consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3803 	
3804 	      /* update maximum activity delta */
3805 	      if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3806 	      {
3807 	         SCIP_Real lb;
3808 	         SCIP_Real ub;
3809 	
3810 	         lb = SCIPvarGetLbLocal(var);
3811 	         ub = SCIPvarGetUbLocal(var);
3812 	
3813 	         if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3814 	         {
3815 	            consdata->maxactdelta = SCIPinfinity(scip);
3816 	            consdata->maxactdeltavar = var;
3817 	         }
3818 	         else
3819 	         {
3820 	            SCIP_Real domain = ub - lb;
3821 	            SCIP_Real delta = REALABS(val) * domain;
3822 	
3823 	            if( delta > consdata->maxactdelta )
3824 	            {
3825 	               consdata->maxactdelta = delta;
3826 	               consdata->maxactdeltavar = var;
3827 	            }
3828 	         }
3829 	      }
3830 	   }
3831 	
3832 	   /* install rounding locks for new variable */
3833 	   SCIP_CALL( lockRounding(scip, cons, var, val) );
3834 	
3835 	   /* mark the constraint for propagation */
3836 	   if( transformed )
3837 	   {
3838 	      SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3839 	   }
3840 	
3841 	   consdata->boundstightened = 0;
3842 	   consdata->presolved = FALSE;
3843 	   consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3844 	
3845 	   if( consdata->validsignature )
3846 	      consdataUpdateSignatures(consdata, consdata->nvars-1);
3847 	
3848 	   consdata->changed = TRUE;
3849 	   consdata->normalized = FALSE;
3850 	   consdata->upgradetried = FALSE;
3851 	   consdata->cliquesadded = FALSE;
3852 	   consdata->implsadded = FALSE;
3853 	   consdata->rangedrowpropagated = 0;
3854 	
3855 	   if( consdata->nvars == 1 )
3856 	   {
3857 	      consdata->indexsorted = TRUE;
3858 	      consdata->coefsorted = TRUE;
3859 	      consdata->merged = TRUE;
3860 	   }
3861 	   else
3862 	   {
3863 	      consdata->merged = FALSE;
3864 	
3865 	      if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3866 	      {
3867 	         consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3868 	         consdata->coefsorted = FALSE;
3869 	      }
3870 	      else
3871 	      {
3872 	         consdata->indexsorted = FALSE;
3873 	         consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3874 	      }
3875 	   }
3876 	
3877 	   /* update hascontvar and hasnonbinvar flags */
3878 	   if( consdata->hasnonbinvalid && !consdata->hascontvar )
3879 	   {
3880 	      SCIP_VARTYPE vartype = SCIPvarGetType(var);
3881 	
3882 	      if( vartype != SCIP_VARTYPE_BINARY )
3883 	      {
3884 	         consdata->hasnonbinvar = TRUE;
3885 	
3886 	         if( vartype == SCIP_VARTYPE_CONTINUOUS )
3887 	            consdata->hascontvar = TRUE;
3888 	      }
3889 	   }
3890 	
3891 	   /* add the new coefficient to the LP row */
3892 	   if( consdata->row != NULL )
3893 	   {
3894 	      SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3895 	   }
3896 	
3897 	   return SCIP_OKAY;
3898 	}
3899 	
3900 	/** deletes coefficient at given position from linear constraint data */
3901 	static
3902 	SCIP_RETCODE delCoefPos(
3903 	   SCIP*                 scip,               /**< SCIP data structure */
3904 	   SCIP_CONS*            cons,               /**< linear constraint */
3905 	   int                   pos                 /**< position of coefficient to delete */
3906 	   )
3907 	{
3908 	   SCIP_CONSDATA* consdata;
3909 	   SCIP_VAR* var;
3910 	   SCIP_Real val;
3911 	
3912 	   assert(scip != NULL);
3913 	   assert(cons != NULL);
3914 	
3915 	   consdata = SCIPconsGetData(cons);
3916 	   assert(consdata != NULL);
3917 	   assert(0 <= pos && pos < consdata->nvars);
3918 	
3919 	   var = consdata->vars[pos];
3920 	   val = consdata->vals[pos];
3921 	   assert(var != NULL);
3922 	
3923 	   /* remove rounding locks for deleted variable */
3924 	   SCIP_CALL( unlockRounding(scip, cons, var, val) );
3925 	
3926 	   /* if we are in transformed problem, delete the event data of the variable */
3927 	   if( SCIPconsIsTransformed(cons) )
3928 	   {
3929 	      SCIP_CONSHDLR* conshdlr;
3930 	      SCIP_CONSHDLRDATA* conshdlrdata;
3931 	
3932 	      /* check for event handler */
3933 	      conshdlr = SCIPconsGetHdlr(cons);
3934 	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
3935 	      assert(conshdlrdata != NULL);
3936 	      assert(conshdlrdata->eventhdlr != NULL);
3937 	
3938 	      /* drop bound change events of variable */
3939 	      if( consdata->eventdata != NULL )
3940 	      {
3941 	         SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3942 	         assert(consdata->eventdata[pos] == NULL);
3943 	      }
3944 	   }
3945 	
3946 	   /* move the last variable to the free slot */
3947 	   if( pos != consdata->nvars - 1 )
3948 	   {
3949 	      consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3950 	      consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3951 	
3952 	      if( consdata->eventdata != NULL )
3953 	      {
3954 	         consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3955 	         assert(consdata->eventdata[pos] != NULL);
3956 	         consdata->eventdata[pos]->varpos = pos;
3957 	      }
3958 	
3959 	      consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3960 	      consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3961 	   }
3962 	   consdata->nvars--;
3963 	
3964 	   /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3965 	    * of the remaining variable, or give exactly 0.0)
3966 	    */
3967 	   if( consdata->nvars <= 1 )
3968 	      consdataInvalidateActivities(consdata);
3969 	   else
3970 	   {
3971 	      if( SCIPconsIsTransformed(cons) )
3972 	      {
3973 	         /* if we are in transformed problem, update minimum and maximum activities */
3974 	         consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3975 	
3976 	         /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3977 	          * delta needs to be recalculated on the next real propagation
3978 	          */
3979 	         if( consdata->maxactdeltavar == var )
3980 	         {
3981 	            consdata->maxactdelta = SCIP_INVALID;
3982 	            consdata->maxactdeltavar = NULL;
3983 	         }
3984 	      }
3985 	   }
3986 	
3987 	   /* mark the constraint for propagation */
3988 	   if( SCIPconsIsTransformed(cons) )
3989 	   {
3990 	      SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3991 	   }
3992 	
3993 	   consdata->boundstightened = 0;
3994 	   consdata->presolved = FALSE;
3995 	   consdata->validsignature = FALSE;
3996 	   consdata->changed = TRUE;
3997 	   consdata->normalized = FALSE;
3998 	   consdata->upgradetried = FALSE;
3999 	   consdata->cliquesadded = FALSE;
4000 	   consdata->implsadded = FALSE;
4001 	   consdata->rangedrowpropagated = 0;
4002 	
4003 	   /* check if hasnonbinvar flag might be incorrect now */
4004 	   if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
4005 	   {
4006 	      consdata->hasnonbinvalid = FALSE;
4007 	   }
4008 	
4009 	   /* delete coefficient from the LP row */
4010 	   if( consdata->row != NULL )
4011 	   {
4012 	      SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
4013 	   }
4014 	
4015 	   /* release variable */
4016 	   SCIP_CALL( SCIPreleaseVar(scip, &var) );
4017 	
4018 	   return SCIP_OKAY;
4019 	}
4020 	
4021 	/** changes coefficient value at given position of linear constraint data */
4022 	static
4023 	SCIP_RETCODE chgCoefPos(
4024 	   SCIP*                 scip,               /**< SCIP data structure */
4025 	   SCIP_CONS*            cons,               /**< linear constraint */
4026 	   int                   pos,                /**< position of coefficient to delete */
4027 	   SCIP_Real             newval              /**< new value of coefficient */
4028 	   )
4029 	{
4030 	   SCIP_CONSDATA* consdata;
4031 	   SCIP_VAR* var;
4032 	   SCIP_Real val;
4033 	   SCIP_Bool locked;
4034 	   int i;
4035 	
4036 	   assert(scip != NULL);
4037 	   assert(cons != NULL);
4038 	   assert(!SCIPisZero(scip, newval));
4039 	
4040 	   consdata = SCIPconsGetData(cons);
4041 	   assert(consdata != NULL);
4042 	   assert(0 <= pos && pos < consdata->nvars);
4043 	   assert(!SCIPisZero(scip, newval));
4044 	
4045 	   var = consdata->vars[pos];
4046 	   val = consdata->vals[pos];
4047 	   assert(var != NULL);
4048 	   assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
4049 	
4050 	   locked = FALSE;
4051 	   for( i = 0; i < NLOCKTYPES && !locked; i++ )
4052 	      locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
4053 	
4054 	   /* if necessary, update the rounding locks of the variable */
4055 	   if( locked && newval * val < 0.0 )
4056 	   {
4057 	      assert(SCIPconsIsTransformed(cons));
4058 	
4059 	      /* remove rounding locks for variable with old coefficient */
4060 	      SCIP_CALL( unlockRounding(scip, cons, var, val) );
4061 	
4062 	      /* install rounding locks for variable with new coefficient */
4063 	      SCIP_CALL( lockRounding(scip, cons, var, newval) );
4064 	   }
4065 	
4066 	   /* change the value */
4067 	   consdata->vals[pos] = newval;
4068 	
4069 	   if( consdata->coefsorted )
4070 	   {
4071 	      if( pos > 0 )
4072 	         consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
4073 	      if( consdata->coefsorted && pos < consdata->nvars - 1 )
4074 	         consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
4075 	   }
4076 	
4077 	   /* update minimum and maximum activities */
4078 	   if( SCIPconsIsTransformed(cons) )
4079 	      consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
4080 	
4081 	   /* mark the constraint for propagation */
4082 	   if( SCIPconsIsTransformed(cons) )
4083 	   {
4084 	      SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
4085 	   }
4086 	
4087 	   consdata->boundstightened = 0;
4088 	   consdata->presolved = FALSE;
4089 	   consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
4090 	   consdata->changed = TRUE;
4091 	   consdata->normalized = FALSE;
4092 	   consdata->upgradetried = FALSE;
4093 	   consdata->cliquesadded = FALSE;
4094 	   consdata->implsadded = FALSE;
4095 	   consdata->rangedrowpropagated = 0;
4096 	
4097 	   return SCIP_OKAY;
4098 	}
4099 	
4100 	/** scales a linear constraint with a constant scalar */
4101 	static
4102 	SCIP_RETCODE scaleCons(
4103 	   SCIP*                 scip,               /**< SCIP data structure */
4104 	   SCIP_CONS*            cons,               /**< linear constraint to scale */
4105 	   SCIP_Real             scalar              /**< value to scale constraint with */
4106 	   )
4107 	{
4108 	   SCIP_CONSDATA* consdata;
4109 	   SCIP_Real newval;
4110 	   SCIP_Real absscalar;
4111 	   int i;
4112 	
4113 	   assert(scip != NULL);
4114 	   assert(cons != NULL);
4115 	
4116 	   consdata = SCIPconsGetData(cons);
4117 	   assert(consdata != NULL);
4118 	   assert(consdata->row == NULL);
4119 	   assert(!SCIPisEQ(scip, scalar, 1.0));
4120 	
4121 	   if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
4122 	      || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
4123 	   {
4124 	      SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
4125 	         SCIPconsGetName(cons), scalar);
4126 	
4127 	      return SCIP_OKAY;
4128 	   }
4129 	
4130 	   /* scale the coefficients */
4131 	   for( i = consdata->nvars - 1; i >= 0; --i )
4132 	   {
4133 	      newval = scalar * consdata->vals[i];
4134 	
4135 	      /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4136 	       * flooring down our new value
4137 	       */
4138 	      if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
4139 	         newval = SCIPfeasFloor(scip, newval + 0.5);
4140 	
4141 	      if( SCIPisZero(scip, newval) )
4142 	      {
4143 	         SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
4144 	            consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
4145 	         SCIP_CALL( delCoefPos(scip, cons, i) );
4146 	      }
4147 	      else
4148 	         consdata->vals[i] = newval;
4149 	   }
4150 	
4151 	   /* scale the sides */
4152 	   if( scalar < 0.0 )
4153 	   {
4154 	      SCIP_Real lhs;
4155 	
4156 	      lhs = consdata->lhs;
4157 	      consdata->lhs = -consdata->rhs;
4158 	      consdata->rhs = -lhs;
4159 	   }
4160 	   absscalar = REALABS(scalar);
4161 	   if( !SCIPisInfinity(scip, -consdata->lhs) )
4162 	   {
4163 	      newval = absscalar * consdata->lhs;
4164 	
4165 	      /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4166 	       * flooring down our new value
4167 	       */
4168 	      if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
4169 	         consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
4170 	      else
4171 	         consdata->lhs = newval;
4172 	   }
4173 	   if( !SCIPisInfinity(scip, consdata->rhs) )
4174 	   {
4175 	      newval = absscalar * consdata->rhs;
4176 	
4177 	      /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4178 	       * our new value
4179 	       */
4180 	      if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4181 	         consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4182 	      else
4183 	         consdata->rhs = newval;
4184 	   }
4185 	
4186 	   consdataInvalidateActivities(consdata);
4187 	   consdata->cliquesadded = FALSE;
4188 	   consdata->implsadded = FALSE;
4189 	
4190 	   return SCIP_OKAY;
4191 	}
4192 	
4193 	/** perform deletion of variables in all constraints of the constraint handler */
4194 	static
4195 	SCIP_RETCODE performVarDeletions(
4196 	   SCIP*                 scip,               /**< SCIP data structure */
4197 	   SCIP_CONSHDLR*        conshdlr,           /**< constraint handler */
4198 	   SCIP_CONS**           conss,              /**< array of constraints */
4199 	   int                   nconss              /**< number of constraints */
4200 	   )
4201 	{
4202 	   SCIP_CONSDATA* consdata;
4203 	   int i;
4204 	   int v;
4205 	
4206 	   assert(scip != NULL);
4207 	   assert(conshdlr != NULL);
4208 	   assert(conss != NULL);
4209 	   assert(nconss >= 0);
4210 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4211 	
4212 	   /* iterate over all constraints */
4213 	   for( i = 0; i < nconss; i++ )
4214 	   {
4215 	      consdata = SCIPconsGetData(conss[i]);
4216 	
4217 	      /* constraint is marked, that some of its variables were deleted */
4218 	      if( consdata->varsdeleted )
4219 	      {
4220 	         /* iterate over all variables of the constraint and delete them from the constraint */
4221 	         for( v = consdata->nvars - 1; v >= 0; --v )
4222 	         {
4223 	            if( SCIPvarIsDeleted(consdata->vars[v]) )
4224 	            {
4225 	               SCIP_CALL( delCoefPos(scip, conss[i], v) );
4226 	            }
4227 	         }
4228 	         consdata->varsdeleted = FALSE;
4229 	      }
4230 	   }
4231 	
4232 	   return SCIP_OKAY;
4233 	}
4234 	
4235 	
4236 	/** normalizes a linear constraint with the following rules:
4237 	 *  - if all coefficients have them same absolute value, change them to (-)1.0
4238 	 *  - multiplication with +1 or -1:
4239 	 *      Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4240 	 *      if the current rule doesn't determine the sign):
4241 	 *        1. the right hand side must not be negative
4242 	 *        2. the right hand side must not be infinite
4243 	 *        3. the absolute value of the right hand side must be greater than that of the left hand side
4244 	 *        4. the number of positive coefficients must not be smaller than the number of negative coefficients
4245 	 *        5. multiply with +1
4246 	 *  - rationals to integrals
4247 	 *      Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4248 	 *      by the smallest common multiple of all denominators to get integral coefficients.
4249 	 *      Forbid large denominators due to numerical stability.
4250 	 *  - division by greatest common divisor
4251 	 *      If all coefficients are integral, divide them by the greatest common divisor.
4252 	 */
4253 	static
4254 	SCIP_RETCODE normalizeCons(
4255 	   SCIP*                 scip,               /**< SCIP data structure */
4256 	   SCIP_CONS*            cons,               /**< linear constraint to normalize */
4257 	   SCIP_Bool*            infeasible          /**< pointer to store whether infeasibility was detected */
4258 	   )
4259 	{
4260 	   SCIP_CONSDATA* consdata;
4261 	   SCIP_Real* vals;
4262 	   SCIP_Longint scm;
4263 	   SCIP_Longint nominator;
4264 	   SCIP_Longint denominator;
4265 	   SCIP_Longint gcd;
4266 	   SCIP_Longint maxmult;
4267 	   SCIP_Real epsilon;
4268 	   SCIP_Real feastol;
4269 	   SCIP_Real maxabsval;
4270 	   SCIP_Real minabsval;
4271 	   SCIP_Bool success;
4272 	   SCIP_Bool onlyintegral;
4273 	   int nvars;
4274 	   int mult;
4275 	   int nposcoeffs;
4276 	   int nnegcoeffs;
4277 	   int i;
4278 	   int v;
4279 	
4280 	   assert(scip != NULL);
4281 	   assert(cons != NULL);
4282 	   assert(infeasible != NULL);
4283 	
4284 	   *infeasible = FALSE;
4285 	
4286 	   /* we must not change a modifiable constraint in any way */
4287 	   if( SCIPconsIsModifiable(cons) )
4288 	      return SCIP_OKAY;
4289 	
4290 	   /* get constraint data */
4291 	   consdata = SCIPconsGetData(cons);
4292 	   assert(consdata != NULL);
4293 	
4294 	   /* check, if the constraint is already normalized */
4295 	   if( consdata->normalized )
4296 	      return SCIP_OKAY;
4297 	
4298 	   /* get coefficient arrays */
4299 	   vals = consdata->vals;
4300 	   nvars = consdata->nvars;
4301 	   assert(nvars == 0 || vals != NULL);
4302 	
4303 	   if( nvars == 0 )
4304 	   {
4305 	      consdata->normalized = TRUE;
4306 	      return SCIP_OKAY;
4307 	   }
4308 	
4309 	   assert(vals != NULL);
4310 	
4311 	   /* get maximal and minimal absolute coefficient */
4312 	   maxabsval = consdataGetMaxAbsval(consdata);
4313 	   minabsval = consdataGetMinAbsval(consdata);
4314 	
4315 	   /* return if scaling by maxval will eliminate coefficients */
4316 	   if( SCIPisZero(scip, minabsval/maxabsval) )
4317 	      return SCIP_OKAY;
4318 	
4319 	   /* check if all coefficients are in absolute value equal, and not 1.0 */
4320 	   if( !SCIPisEQ(scip, maxabsval, 1.0) )
4321 	   {
4322 	      SCIP_Bool abscoefsequ;
4323 	
4324 	      abscoefsequ = TRUE;
4325 	
4326 	      for( v = nvars - 1; v >= 0; --v )
4327 	      {
4328 	         if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4329 	         {
4330 	            abscoefsequ = FALSE;
4331 	            break;
4332 	         }
4333 	      }
4334 	
4335 	      /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4336 	      if( abscoefsequ )
4337 	      {
4338 	         SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
4339 	         SCIPdebugPrintCons(scip, cons, NULL);
4340 	         SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4341 	
4342 	         if( consdata->validmaxabsval )
4343 	         {
4344 	            if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4345 	               consdata->maxabsval = 1.0;
4346 	            if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4347 	               consdata->minabsval = 1.0;
4348 	
4349 	            maxabsval = 1.0;
4350 	         }
4351 	         else
4352 	         {
4353 	            /* get maximal absolute coefficient */
4354 	            maxabsval = consdataGetMaxAbsval(consdata);
4355 	         }
4356 	
4357 	         /* get new consdata information, because scaleCons() might have deleted variables */
4358 	         vals = consdata->vals;
4359 	         nvars = consdata->nvars;
4360 	
4361 	         assert(nvars == 0 || vals != NULL);
4362 	      }
4363 	   }
4364 	
4365 	   /* nvars might have changed */
4366 	   if( nvars == 0 )
4367 	   {
4368 	      consdata->normalized = TRUE;
4369 	      return SCIP_OKAY;
4370 	   }
4371 	
4372 	   assert(vals != NULL);
4373 	
4374 	   /* calculate the maximal multiplier for common divisor calculation:
4375 	    *   |p/q - val| < epsilon  and  q < feastol/epsilon  =>  |p - q*val| < feastol
4376 	    * which means, a value of feastol/epsilon should be used as maximal multiplier;
4377 	    * additionally, we don't want to scale the constraint if this would lead to too
4378 	    * large coefficients
4379 	    */
4380 	   epsilon = SCIPepsilon(scip) * 0.9;  /* slightly decrease epsilon to be safe in rational conversion below */
4381 	   feastol = SCIPfeastol(scip);
4382 	   maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4383 	
4384 	   if( !consdata->hasnonbinvalid )
4385 	      consdataCheckNonbinvar(consdata);
4386 	
4387 	   /* if all variables are of integral type we will allow a greater multiplier */
4388 	   if( !consdata->hascontvar )
4389 	      maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
4390 	   else
4391 	      maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
4392 	
4393 	   /*
4394 	    * multiplication with +1 or -1
4395 	    */
4396 	   mult = 0;
4397 	
4398 	   /* 1. the right hand side must not be negative */
4399 	   if( SCIPisPositive(scip, consdata->lhs) )
4400 	      mult = +1;
4401 	   else if( SCIPisNegative(scip, consdata->rhs) )
4402 	      mult = -1;
4403 	
4404 	   if( mult == 0 )
4405 	   {
4406 	      /* 2. the right hand side must not be infinite */
4407 	      if( SCIPisInfinity(scip, -consdata->lhs) )
4408 	         mult = +1;
4409 	      else if( SCIPisInfinity(scip, consdata->rhs) )
4410 	         mult = -1;
4411 	   }
4412 	
4413 	   if( mult == 0 )
4414 	   {
4415 	      /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4416 	      if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4417 	         mult = +1;
4418 	      else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4419 	         mult = -1;
4420 	   }
4421 	
4422 	   if( mult == 0 )
4423 	   {
4424 	      /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4425 	      nposcoeffs = 0;
4426 	      nnegcoeffs = 0;
4427 	      for( i = 0; i < nvars; ++i )
4428 	      {
4429 	         if( vals[i] > 0.0 )
4430 	            nposcoeffs++;
4431 	         else
4432 	            nnegcoeffs++;
4433 	      }
4434 	      if( nposcoeffs > nnegcoeffs )
4435 	         mult = +1;
4436 	      else if( nposcoeffs < nnegcoeffs )
4437 	         mult = -1;
4438 	   }
4439 	
4440 	   if( mult == 0 )
4441 	   {
4442 	      /* 5. multiply with +1 */
4443 	      mult = +1;
4444 	   }
4445 	
4446 	   assert(mult == +1 || mult == -1);
4447 	   if( mult == -1 )
4448 	   {
4449 	      /* scale the constraint with -1 */
4450 	      SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4451 	      SCIPdebugPrintCons(scip, cons, NULL);
4452 	      SCIP_CALL( scaleCons(scip, cons, -1.0) );
4453 	
4454 	      /* scalecons() can delete variables, but scaling with -1 should not do that */
4455 	      assert(nvars == consdata->nvars);
4456 	   }
4457 	
4458 	   /*
4459 	    * rationals to integrals
4460 	    *
4461 	    * @todo try scaling only on behalf of non-continuous variables
4462 	    */
4463 	   success = TRUE;
4464 	   scm = 1;
4465 	   for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4466 	   {
4467 	      if( !SCIPisIntegral(scip, vals[i]) )
4468 	      {
4469 	         /* epsilon has been slightly decreased above - to be on the safe side */
4470 	         success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4471 	         if( success )
4472 	            scm = SCIPcalcSmaComMul(scm, denominator);
4473 	      }
4474 	   }
4475 	   assert(scm >= 1);
4476 	
4477 	   /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4478 	    * their greatest common divisor
4479 	    */
4480 	   onlyintegral = TRUE;
4481 	   if( scm == 1 )
4482 	   {
4483 	      for( i = nvars - 1; i >= 0; --i )
4484 	      {
4485 	         if( !SCIPisIntegral(scip, vals[i]) )
4486 	         {
4487 	            onlyintegral = FALSE;
4488 	            break;
4489 	         }
4490 	      }
4491 	   }
4492 	
4493 	   success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4494 	   if( success && scm != 1 )
4495 	   {
4496 	      /* scale the constraint with the smallest common multiple of all denominators */
4497 	      SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4498 	      SCIPdebugPrintCons(scip, cons, NULL);
4499 	      SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4500 	
4501 	      if( consdata->validmaxabsval )
4502 	      {
4503 	         consdata->maxabsval *= REALABS((SCIP_Real)scm);
4504 	         if( !SCIPisIntegral(scip, consdata->maxabsval) )
4505 	         {
4506 	            consdata->validmaxabsval = FALSE;
4507 	            consdata->maxabsval = SCIP_INVALID;
4508 	            consdataCalcMaxAbsval(consdata);
4509 	         }
4510 	      }
4511 	
4512 	      if( consdata->validminabsval )
4513 	      {
4514 	         consdata->minabsval *= REALABS((SCIP_Real)scm);
4515 	         if( !SCIPisIntegral(scip, consdata->minabsval) )
4516 	         {
4517 	            consdata->validminabsval = FALSE;
4518 	            consdata->minabsval = SCIP_INVALID;
4519 	            consdataCalcMinAbsval(consdata);
4520 	         }
4521 	      }
4522 	
4523 	      /* get new consdata information, because scalecons() might have deleted variables */
4524 	      vals = consdata->vals;
4525 	      nvars = consdata->nvars;
4526 	      assert(nvars == 0 || vals != NULL);
4527 	   }
4528 	
4529 	   /*
4530 	    * division by greatest common divisor
4531 	    */
4532 	   if( success && nvars >= 1 )
4533 	   {
4534 	      /* all coefficients are integral: divide them by their greatest common divisor */
4535 	      assert(SCIPisIntegral(scip, vals[0]));
4536 	
4537 	      gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4538 	      for( i = 1; i < nvars && gcd > 1; ++i )
4539 	      {
4540 	         assert(SCIPisIntegral(scip, vals[i]));
4541 	         gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4542 	      }
4543 	
4544 	      if( gcd > 1 )
4545 	      {
4546 	         /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
4547 	         if( !consdata->hascontvar && onlyintegral )
4548 	         {
4549 	            if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
4550 	            {
4551 	               *infeasible = TRUE;
4552 	
4553 	               SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
4554 	               SCIPdebugPrintCons(scip, cons, NULL);
4555 	
4556 	               return SCIP_OKAY;
4557 	            }
4558 	         }
4559 	
4560 	         /* divide the constraint by the greatest common divisor of the coefficients */
4561 	         SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4562 	         SCIPdebugPrintCons(scip, cons, NULL);
4563 	         SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4564 	
4565 	         if( consdata->validmaxabsval )
4566 	         {
4567 	            consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4568 	         }
4569 	         if( consdata->validminabsval )
4570 	         {
4571 	            consdata->minabsval /= REALABS((SCIP_Real)gcd);
4572 	         }
4573 	      }
4574 	   }
4575 	
4576 	   /* mark constraint to be normalized */
4577 	   consdata->normalized = TRUE;
4578 	
4579 	   SCIPdebugMsg(scip, "normalized constraint:\n");
4580 	   SCIPdebugPrintCons(scip, cons, NULL);
4581 	
4582 	   return SCIP_OKAY;
4583 	}
4584 	
4585 	/** replaces multiple occurrences of a variable by a single coefficient */
4586 	static
4587 	SCIP_RETCODE mergeMultiples(
4588 	   SCIP*                 scip,               /**< SCIP data structure */
4589 	   SCIP_CONS*            cons                /**< linear constraint */
4590 	   )
4591 	{
4592 	   SCIP_CONSDATA* consdata;
4593 	   SCIP_VAR* var;
4594 	   SCIP_Real valsum;
4595 	   int v;
4596 	
4597 	   assert(scip != NULL);
4598 	   assert(cons != NULL);
4599 	
4600 	   consdata = SCIPconsGetData(cons);
4601 	   assert(consdata != NULL);
4602 	
4603 	   if( consdata->merged )
4604 	      return SCIP_OKAY;
4605 	
4606 	   /* sort the constraint */
4607 	   SCIP_CALL( consdataSort(scip, consdata) );
4608 	
4609 	   /* go backwards through the constraint looking for multiple occurrences of the same variable;
4610 	    * backward direction is necessary, since delCoefPos() modifies the given position and
4611 	    * the subsequent ones
4612 	    */
4613 	   v = consdata->nvars-1;
4614 	   while( v >= 1 )
4615 	   {
4616 	      var = consdata->vars[v];
4617 	      if( consdata->vars[v-1] == var )
4618 	      {
4619 	         valsum = consdata->vals[v];
4620 	         do
4621 	         {
4622 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4623 	            --v;
4624 	            valsum += consdata->vals[v];
4625 	         }
4626 	         while( v >= 1 && consdata->vars[v-1] == var );
4627 	
4628 	         /* modify the last existing occurrence of the variable */
4629 	         assert(consdata->vars[v] == var);
4630 	         if( SCIPisZero(scip, valsum) )
4631 	         {
4632 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4633 	
4634 	            /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4635 	             * delta needs to be recalculated on the next real propagation
4636 	             */
4637 	            if( consdata->maxactdeltavar == var )
4638 	            {
4639 	               consdata->maxactdelta = SCIP_INVALID;
4640 	               consdata->maxactdeltavar = NULL;
4641 	            }
4642 	         }
4643 	         else
4644 	         {
4645 	            SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4646 	         }
4647 	      }
4648 	      --v;
4649 	   }
4650 	
4651 	   consdata->merged = TRUE;
4652 	
4653 	   return SCIP_OKAY;
4654 	}
4655 	
4656 	/** replaces all fixed and aggregated variables by their non-fixed counterparts */
4657 	static
4658 	SCIP_RETCODE applyFixings(
4659 	   SCIP*                 scip,               /**< SCIP data structure */
4660 	   SCIP_CONS*            cons,               /**< linear constraint */
4661 	   SCIP_Bool*            infeasible          /**< pointer to store if infeasibility is detected; or NULL if this
4662 	                                              *   information is not needed; in this case, we apply all fixings
4663 	                                              *   instead of stopping after the first infeasible one */
4664 	   )
4665 	{
4666 	   SCIP_CONSDATA* consdata;
4667 	   SCIP_VAR* var;
4668 	   SCIP_VAR** aggrvars;
4669 	   SCIP_Real val;
4670 	   SCIP_Real* aggrscalars;
4671 	   SCIP_Real fixedval;
4672 	   SCIP_Real aggrconst;
4673 	   int v;
4674 	   int naggrvars;
4675 	   int i;
4676 	
4677 	   assert(scip != NULL);
4678 	   assert(cons != NULL);
4679 	
4680 	   if( infeasible != NULL )
4681 	      *infeasible = FALSE;
4682 	
4683 	   consdata = SCIPconsGetData(cons);
4684 	   assert(consdata != NULL);
4685 	
4686 	   if( consdata->eventdata == NULL )
4687 	   {
4688 	      SCIP_CONSHDLR* conshdlr;
4689 	      SCIP_CONSHDLRDATA* conshdlrdata;
4690 	
4691 	      conshdlr = SCIPconsGetHdlr(cons);
4692 	      assert(conshdlr != NULL);
4693 	
4694 	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
4695 	      assert(conshdlrdata != NULL);
4696 	
4697 	      /* catch bound change events of variables */
4698 	      SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
4699 	      assert(consdata->eventdata != NULL);
4700 	   }
4701 	
4702 	   if( !consdata->removedfixings )
4703 	   {
4704 	      SCIP_Real lhssubtrahend;
4705 	      SCIP_Real rhssubtrahend;
4706 	
4707 	      /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
4708 	       * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
4709 	       */
4710 	      assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
4711 	
4712 	      lhssubtrahend = 0.0;
4713 	      rhssubtrahend = 0.0;
4714 	
4715 	      SCIPdebugMsg(scip, "applying fixings:\n");
4716 	      SCIPdebugPrintCons(scip, cons, NULL);
4717 	
4718 	      v = 0;
4719 	      while( v < consdata->nvars )
4720 	      {
4721 	         var = consdata->vars[v];
4722 	         val = consdata->vals[v];
4723 	         assert(SCIPvarIsTransformed(var));
4724 	
4725 	         switch( SCIPvarGetStatus(var) )
4726 	         {
4727 	         case SCIP_VARSTATUS_ORIGINAL:
4728 	            SCIPerrorMessage("original variable in transformed linear constraint\n");
4729 	            return SCIP_INVALIDDATA;
4730 	
4731 	         case SCIP_VARSTATUS_LOOSE:
4732 	         case SCIP_VARSTATUS_COLUMN:
4733 	            ++v;
4734 	            break;
4735 	
4736 	         case SCIP_VARSTATUS_FIXED:
4737 	            assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4738 	            fixedval = SCIPvarGetLbGlobal(var);
4739 	            if( !SCIPisInfinity(scip, -consdata->lhs) )
4740 	            {
4741 	               if( SCIPisInfinity(scip, ABS(fixedval)) )
4742 	               {
4743 	                  if( val * fixedval > 0.0 )
4744 	                  {
4745 	                     SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4746 	                  }
4747 	                  else
4748 	                  {
4749 	                     if( infeasible != NULL )
4750 	                     {
4751 	                        /* if lhs gets infinity it means that the problem is infeasible */
4752 	                        *infeasible = TRUE;
4753 	                        return SCIP_OKAY;
4754 	                     }
4755 	                     else
4756 	                     {
4757 	                        SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4758 	                     }
4759 	                  }
4760 	               }
4761 	               else
4762 	                  lhssubtrahend += val * fixedval;
4763 	            }
4764 	            if( !SCIPisInfinity(scip, consdata->rhs) )
4765 	            {
4766 	               if( SCIPisInfinity(scip, ABS(fixedval)) )
4767 	               {
4768 	                  if( val * fixedval > 0.0 )
4769 	                  {
4770 	                     if( infeasible != NULL )
4771 	                     {
4772 	                        /* if rhs gets -infinity it means that the problem is infeasible */
4773 	                        *infeasible = TRUE;
4774 	                        return SCIP_OKAY;
4775 	                     }
4776 	                     else
4777 	                     {
4778 	                        SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4779 	                     }
4780 	                  }
4781 	                  else
4782 	                  {
4783 	                     SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4784 	                  }
4785 	               }
4786 	               else
4787 	                  rhssubtrahend += val * fixedval;
4788 	            }
4789 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4790 	            break;
4791 	
4792 	         case SCIP_VARSTATUS_AGGREGATED:
4793 		 {
4794 		    SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4795 		    SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4796 		    SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4797 	
4798 		    assert(activevar != NULL);
4799 		    SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4800 		    assert(activevar != NULL);
4801 	
4802 		    if( !SCIPisZero(scip, activescalar) )
4803 		    {
4804 		       SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4805 		    }
4806 	
4807 		    if( !SCIPisZero(scip, activeconstant) )
4808 		    {
4809 		       if( !SCIPisInfinity(scip, -consdata->lhs) )
4810 			  lhssubtrahend += activeconstant;
4811 		       if( !SCIPisInfinity(scip, consdata->rhs) )
4812 			  rhssubtrahend += activeconstant;
4813 		    }
4814 	
4815 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4816 	            break;
4817 		 }
4818 	         case SCIP_VARSTATUS_MULTAGGR:
4819 	            SCIP_CALL( SCIPflattenVarAggregationGraph(scip, var) );
4820 	            naggrvars = SCIPvarGetMultaggrNVars(var);
4821 	            aggrvars = SCIPvarGetMultaggrVars(var);
4822 	            aggrscalars = SCIPvarGetMultaggrScalars(var);
4823 	            for( i = 0; i < naggrvars; ++i )
4824 	            {
4825 	               SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4826 	            }
4827 	            aggrconst = SCIPvarGetMultaggrConstant(var);
4828 	
4829 	            if( !SCIPisInfinity(scip, -consdata->lhs) )
4830 	               lhssubtrahend += val * aggrconst;
4831 	            if( !SCIPisInfinity(scip, consdata->rhs) )
4832 	               rhssubtrahend += val * aggrconst;
4833 	
4834 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4835 	            break;
4836 	
4837 	         case SCIP_VARSTATUS_NEGATED:
4838 	            SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4839 	            aggrconst = SCIPvarGetNegationConstant(var);
4840 	
4841 	            if( !SCIPisInfinity(scip, -consdata->lhs) )
4842 	               lhssubtrahend += val * aggrconst;
4843 	            if( !SCIPisInfinity(scip, consdata->rhs) )
4844 	               rhssubtrahend += val * aggrconst;
4845 	
4846 	            SCIP_CALL( delCoefPos(scip, cons, v) );
4847 	            break;
4848 	
4849 	         default:
4850 	            SCIPerrorMessage("unknown variable status\n");
4851 	            SCIPABORT();
4852 	            return SCIP_INVALIDDATA;  /*lint !e527*/
4853 	         }
4854 	      }
4855 	
4856 	      if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4857 	      {
4858 	         /* for large numbers that are relatively equal, substraction can lead to cancellation,
4859 	          * causing wrong fixings of other variables --> better use a real zero here;
4860 	          * for small numbers, polishing the difference might lead to wrong results -->
4861 	          * better use the exact difference in this case
4862 	          */
4863 	         if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4864 	         {
4865 	            SCIP_CALL( chgLhs(scip, cons, 0.0) );
4866 	         }
4867 	         else
4868 	         {
4869 	            SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4870 	         }
4871 	      }
4872 	      if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4873 	      {
4874 	         /* for large numbers that are relatively equal, substraction can lead to cancellation,
4875 	          * causing wrong fixings of other variables --> better use a real zero here;
4876 	          * for small numbers, polishing the difference might lead to wrong results -->
4877 	          * better use the exact difference in this case
4878 	          */
4879 	         if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4880 	         {
4881 	            SCIP_CALL( chgRhs(scip, cons, 0.0) );
4882 	         }
4883 	         else
4884 	         {
4885 	            SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4886 	         }
4887 	      }
4888 	      consdata->removedfixings = TRUE;
4889 	
4890 	      SCIPdebugMsg(scip, "after fixings:\n");
4891 	      SCIPdebugPrintCons(scip, cons, NULL);
4892 	
4893 	      /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4894 	       * to clean up the constraint
4895 	       */
4896 	      SCIP_CALL( mergeMultiples(scip, cons) );
4897 	
4898 	      SCIPdebugMsg(scip, "after merging:\n");
4899 	      SCIPdebugPrintCons(scip, cons, NULL);
4900 	   }
4901 	   assert(consdata->removedfixings);
4902 	
4903 	#ifndef NDEBUG
4904 	   /* check, if all fixings are applied */
4905 	   for( v = 0; v < consdata->nvars; ++v )
4906 	      assert(SCIPvarIsActive(consdata->vars[v]));
4907 	#endif
4908 	
4909 	   return SCIP_OKAY;
4910 	}
4911 	
4912 	/** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4913 	 *  candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4914 	 *  inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4915 	 *  conflict detecting constraint by using NULL as inferred variable
4916 	 */
4917 	static
4918 	SCIP_RETCODE addConflictBounds(
4919 	   SCIP*                 scip,               /**< SCIP data structure */
4920 	   SCIP_CONS*            cons,               /**< constraint that inferred the bound change */
4921 	   SCIP_VAR*             infervar,           /**< variable that was deduced, or NULL */
4922 	   SCIP_BDCHGIDX*        bdchgidx,           /**< bound change index (time stamp of bound change), or NULL for current time */
4923 	   int                   inferpos,           /**< position of the inferred variable in the vars array */
4924 	   SCIP_Bool             reasonisrhs         /**< is the right hand side responsible for the bound change? */
4925 	   )
4926 	{
4927 	   SCIP_CONSDATA* consdata;
4928 	   SCIP_VAR** vars;
4929 	   SCIP_Real* vals;
4930 	   int nvars;
4931 	   int i;
4932 	
4933 	   assert(scip != NULL);
4934 	   assert(cons != NULL);
4935 	
4936 	   consdata = SCIPconsGetData(cons);
4937 	
4938 	   assert(consdata != NULL);
4939 	
4940 	   vars = consdata->vars;
4941 	   vals = consdata->vals;
4942 	   nvars = consdata->nvars;
4943 	
4944 	   assert(vars != NULL || nvars == 0);
4945 	   assert(vals != NULL || nvars == 0);
4946 	
4947 	   assert(-1 <= inferpos && inferpos < nvars);
4948 	   assert((infervar == NULL) == (inferpos == -1));
4949 	   assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4950 	
4951 	   /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4952 	    * residual value, depending on whether the left or right hand side is responsible for the bound change:
4953 	    *  - if the right hand side is the reason, the minimal residual activity is responsible
4954 	    *  - if the left hand side is the reason, the maximal residual activity is responsible
4955 	    */
4956 	
4957 	   /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4958 	   if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4959 	   {
4960 	      SCIP_Real minresactivity;
4961 	      SCIP_Real maxresactivity;
4962 	      SCIP_Bool minisrelax;
4963 	      SCIP_Bool maxisrelax;
4964 	      SCIP_Bool isminsettoinfinity;
4965 	      SCIP_Bool ismaxsettoinfinity;
4966 	
4967 	      minresactivity = -SCIPinfinity(scip);
4968 	      maxresactivity = SCIPinfinity(scip);
4969 	
4970 	      /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4971 	      if( infervar != NULL )
4972 	      {
4973 	         assert(vals != NULL); /* for flexelint */
4974 	         if( reasonisrhs )
4975 	            consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4976 	               &minisrelax, NULL, &isminsettoinfinity, NULL);
4977 	         else
4978 	            consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4979 	               NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4980 	      }
4981 	      else
4982 	      {
4983 	         if( reasonisrhs )
4984 	            consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4985 	               &minisrelax, NULL, &isminsettoinfinity, NULL);
4986 	         else
4987 	            consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4988 	               NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4989 	      }
4990 	
4991 	      /* we can only do something clever, if the residual activity is finite and not relaxed */
4992 	      if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4993 	      {
4994 	         SCIP_Real rescap;
4995 	         SCIP_Bool resactisinf;
4996 	
4997 	         resactisinf = FALSE;
4998 	
4999 	         /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
5000 	          * than its inferred bound
5001 	          */
5002 	         if( infervar != NULL )
5003 	         {
5004 	            assert(vals != NULL); /* for flexelint */
5005 	
5006 	            if( reasonisrhs )
5007 	            {
5008 	               if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
5009 	               {
5010 	                  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
5011 	                  if( SCIPisInfinity(scip, -minresactivity) )
5012 	                     resactisinf = TRUE;
5013 	               }
5014 	               rescap = consdata->rhs - minresactivity;
5015 	            }
5016 	            else
5017 	            {
5018 	               if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
5019 	               {
5020 	                  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
5021 	                  if( SCIPisInfinity(scip, maxresactivity) )
5022 	                     resactisinf = TRUE;
5023 	               }
5024 	               rescap = consdata->lhs - maxresactivity;
5025 	            }
5026 	
5027 	            if( reasonisrhs == (vals[inferpos] > 0.0) )
5028 	               rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
5029 	            else
5030 	               rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
5031 	         }
5032 	         else
5033 	            rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
5034 	
5035 	         if( !resactisinf )
5036 	         {
5037 	            /* now add bounds as reasons until the residual capacity is exceeded */
5038 	            for( i = 0; i < nvars; ++i )
5039 	            {
5040 	               assert( vars != NULL && vals != NULL ); /* for lint */
5041 	
5042 	               /* zero coefficients and the inferred variable can be ignored */
5043 	               if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5044 	                  continue;
5045 	
5046 	               /* check if the residual capacity is exceeded */
5047 	               if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
5048 	                  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
5049 	                  break;
5050 	
5051 	               /* update the residual capacity due to the local bound of this variable */
5052 	               if( reasonisrhs == (vals[i] > 0.0) )
5053 	               {
5054 	                  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
5055 	                  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5056 	                  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
5057 	               }
5058 	               else
5059 	               {
5060 	                  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
5061 	                  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5062 	                  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
5063 	               }
5064 	            }
5065 	            return SCIP_OKAY;
5066 	         }
5067 	      }
5068 	   }
5069 	
5070 	   /* for a bound change on a continuous variable, all locally changed bounds are responsible */
5071 	   for( i = 0; i < nvars; ++i )
5072 	   {
5073 	      assert(vars != NULL); /* for flexelint */
5074 	      assert(vals != NULL); /* for flexelint */
5075 	
5076 	      /* zero coefficients and the inferred variable can be ignored */
5077 	      if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5078 	         continue;
5079 	
5080 	      if( reasonisrhs == (vals[i] > 0.0) )
5081 	      {
5082 	         /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
5083 	         SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5084 	      }
5085 	      else
5086 	      {
5087 	         /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
5088 	         SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5089 	      }
5090 	   }
5091 	
5092 	   return SCIP_OKAY;
5093 	}
5094 	
5095 	/** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
5096 	 *  variables to the conflict analysis' candidate store; the conflict analysis can be initialized
5097 	 *  with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
5098 	 */
5099 	static
5100 	SCIP_RETCODE addConflictFixedVars(
5101 	   SCIP*                 scip,               /**< SCIP data structure */
5102 	   SCIP_CONS*            cons,               /**< constraint that inferred the bound change */
5103 	   SCIP_VAR*             infervar,           /**< variable that was deduced, or NULL */
5104 	   SCIP_BDCHGIDX*        bdchgidx,           /**< bound change index (time stamp of bound change), or NULL for current time */
5105 	   int                   inferpos            /**< position of the inferred variable in the vars array, or -1 */
5106 	   )
5107 	{
5108 	   SCIP_CONSDATA* consdata;
5109 	   SCIP_VAR** vars;
5110 	   int nvars;
5111 	   int v;
5112 	
5113 	   assert(scip != NULL);
5114 	   assert(cons != NULL);
5115 	
5116 	   consdata = SCIPconsGetData(cons);
5117 	   assert(consdata != NULL);
5118 	   vars = consdata->vars;
5119 	   nvars = consdata->nvars;
5120 	   assert(vars != NULL || nvars == 0);
5121 	   assert(-1 <= inferpos && inferpos < nvars);
5122 	   assert((infervar == NULL) == (inferpos == -1));
5123 	   assert(inferpos == -1 || vars != NULL);
5124 	   assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
5125 	
5126 	   /* collect all fixed variables */
5127 	   for( v = nvars - 1; v >= 0; --v )
5128 	   {
5129 	      assert(vars != NULL); /* for flexelint */
5130 	
5131 	      /* need to add old bounds before propagation of inferrence variable */
5132 	      if( vars[v] == infervar )
5133 	      {
5134 		 assert(vars[v] != NULL);
5135 	
5136 		 if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
5137 		 {
5138 		    /* @todo get boundchange index before this last boundchange and correct the index */
5139 		    SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5140 		 }
5141 	
5142 		 if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
5143 		 {
5144 		    /* @todo get boundchange index before this last boundchange and correct the index */
5145 		    SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5146 		 }
5147 	
5148 		 continue;
5149 	      }
5150 	
5151 	      /* check for fixed variables */
5152 	      if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
5153 	      {
5154 		 /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
5155 	         SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5156 	         SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5157 	      }
5158 	   }
5159 	
5160 	   return SCIP_OKAY;
5161 	}
5162 	
5163 	/** add reasoning variables to conflict candidate queue which led to the conflict */
5164 	static
5165 	SCIP_RETCODE addConflictReasonVars(
5166 	   SCIP*                 scip,               /**< SCIP data structure */
5167 	   SCIP_VAR**            vars,               /**< variables reasoning the infeasibility */
5168 	   int                   nvars,              /**< number of variables reasoning the infeasibility */
5169 	   SCIP_VAR*             var,                /**< variable which was tried to fix/tighten, or NULL */
5170 	   SCIP_Real             bound               /**< bound of variable which was tried to apply, or SCIP_INVALID */
5171 	   )
5172 	{
5173 	   int v;
5174 	
5175 	   assert(scip != NULL);
5176 	
5177 	   /* collect all variables for which the local bounds differ from their global bounds */
5178 	   for( v = nvars - 1; v >= 0; --v )
5179 	   {
5180 	      assert(vars != NULL);
5181 	
5182 	      /* check for local bound changes variables */
5183 	      if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5184 	      {
5185 		 /* add conflict bound */
5186 	         SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5187 	      }
5188 	
5189 	      if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5190 	      {
5191 	         SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5192 	      }
5193 	   }
5194 	
5195 	   if( var != NULL )
5196 	   {
5197 	      if( bound < SCIPvarGetLbLocal(var) )
5198 	      {
5199 	         SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5200 	      }
5201 	
5202 	      if( bound > SCIPvarGetUbLocal(var) )
5203 	      {
5204 	         SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5205 	      }
5206 	   }
5207 	
5208 	   return SCIP_OKAY;
5209 	}
5210 	
5211 	/** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5212 	 *  propagation rule (see propagateCons()):
5213 	 *   (1) activity residuals of all other variables tighten bounds of single variable
5214 	 */
5215 	static
5216 	SCIP_RETCODE resolvePropagation(
5217 	   SCIP*                 scip,               /**< SCIP data structure */
5218 	   SCIP_CONS*            cons,               /**< constraint that inferred the bound change */
5219 	   SCIP_VAR*             infervar,           /**< variable that was deduced */
5220 	   INFERINFO             inferinfo,          /**< inference information */
5221 	   SCIP_BOUNDTYPE        boundtype,          /**< the type of the changed bound (lower or upper bound) */
5222 	   SCIP_BDCHGIDX*        bdchgidx,           /**< bound change index (time stamp of bound change), or NULL for current time */
5223 	   SCIP_RESULT*          result              /**< pointer to store the result of the propagation conflict resolving call */
5224 	   )
5225 	{
5226 	   SCIP_CONSDATA* consdata;
5227 	   SCIP_VAR** vars;
5228 	#ifndef NDEBUG
5229 	   SCIP_Real* vals;
5230 	#endif
5231 	   int nvars;
5232 	   int inferpos;
5233 	
5234 	   assert(scip != NULL);
5235 	   assert(cons != NULL);
5236 	   assert(result != NULL);
5237 	
5238 	   consdata = SCIPconsGetData(cons);
5239 	   assert(consdata != NULL);
5240 	   vars = consdata->vars;
5241 	   nvars = consdata->nvars;
5242 	#ifndef NDEBUG
5243 	   vals = consdata->vals;
5244 	   assert(vars != NULL);
5245 	   assert(vals != NULL);
5246 	#endif
5247 	
5248 	   /* get the position of the inferred variable in the vars array */
5249 	   inferpos = inferInfoGetPos(inferinfo);
5250 	   if( inferpos >= nvars || vars[inferpos] != infervar )
5251 	   {
5252 	      /* find inference variable in constraint */
5253 	      /**@todo use a binary search here; the variables can be sorted by variable index */
5254 	      for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5255 	      {}
5256 	   }
5257 	   assert(inferpos < nvars);
5258 	   assert(vars[inferpos] == infervar);
5259 	   assert(!SCIPisZero(scip, vals[inferpos]));
5260 	
5261 	   switch( inferInfoGetProprule(inferinfo) )
5262 	   {
5263 	   case PROPRULE_1_RHS:
5264 	      /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5265 	       * constraint (only taking the other variables into account) didn't leave enough space for a larger
5266 	       * domain in order to not exceed the right hand side of the inequality
5267 	       */
5268 	      assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5269 	      SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5270 	      *result = SCIP_SUCCESS;
5271 	      break;
5272 	
5273 	   case PROPRULE_1_LHS:
5274 	      /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5275 	       * constraint (only taking the other variables into account) didn't leave enough space for a larger
5276 	       * domain in order to not fall below the left hand side of the inequality
5277 	       */
5278 	      assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5279 	      SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5280 	      *result = SCIP_SUCCESS;
5281 	      break;
5282 	
5283 	   case PROPRULE_1_RANGEDROW:
5284 	      /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5285 	       * the given inference variable to their bounds in this given ranged row
5286 	       */
5287 	
5288 	      /* check that we really have a ranged row here */
5289 	      assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5290 	      SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5291 	      *result = SCIP_SUCCESS;
5292 	      break;
5293 	
5294 	   case PROPRULE_INVALID:
5295 	   default:
5296 	      SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5297 	         inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5298 	         boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5299 	      SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5300 	      SCIPinfoMessage(scip, NULL, ";\n");
5301 	      return SCIP_INVALIDDATA;
5302 	   }
5303 	
5304 	   return SCIP_OKAY;
5305 	}
5306 	
5307 	/** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5308 	static
5309 	SCIP_RETCODE analyzeConflict(
5310 	   SCIP*                 scip,               /**< SCIP data structure */
5311 	   SCIP_CONS*            cons,               /**< conflict detecting constraint */
5312 	   SCIP_Bool             reasonisrhs         /**< is the right hand side responsible for the conflict? */
5313 	   )
5314 	{
5315 	   /* conflict analysis can only be applied in solving stage and if it is turned on */
5316 	   if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
5317 	      return SCIP_OKAY;
5318 	
5319 	   /* initialize conflict analysis */
5320 	   SCIP_CALL( SCIPinitConflictAnalysis(scip, SCIP_CONFTYPE_PROPAGATION, FALSE) );
5321 	
5322 	   /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5323 	   SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5324 	
5325 	   /* analyze the conflict */
5326 	   SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5327 	
5328 	   return SCIP_OKAY;
5329 	}
5330 	
5331 	/** check if there is any hope of tightening some bounds */
5332 	static
5333 	SCIP_Bool canTightenBounds(
5334 	   SCIP_CONS*            cons                /**< linear constraint */
5335 	   )
5336 	{
5337 	   SCIP_CONSDATA* consdata;
5338 	   int infcountmin;
5339 	   int infcountmax;
5340 	
5341 	   consdata = SCIPconsGetData(cons);
5342 	   assert(consdata != NULL);
5343 	
5344 	   infcountmin = consdata->minactivityneginf
5345 	      + consdata->minactivityposinf
5346 	      + consdata->minactivityneghuge
5347 	      + consdata->minactivityposhuge;
5348 	   infcountmax = consdata->maxactivityneginf
5349 	      + consdata->maxactivityposinf
5350 	      + consdata->maxactivityneghuge
5351 	      + consdata->maxactivityposhuge;
5352 	
5353 	   if( infcountmin > 1 && infcountmax > 1 )
5354 	      return FALSE;
5355 	
5356 	   return TRUE;
5357 	}
5358 	
5359 	/** tighten upper bound */
5360 	static
5361 	SCIP_RETCODE tightenVarUb(
5362 	   SCIP*                 scip,               /**< SCIP data structure */
5363 	   SCIP_CONS*            cons,               /**< linear constraint */
5364 	   int                   pos,                /**< variable position */
5365 	   PROPRULE              proprule,           /**< propagation rule that deduced the value */
5366 	   SCIP_Real             newub,              /**< new upper bound */
5367 	   SCIP_Real             oldub,              /**< old upper bound */
5368 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
5369 	   int*                  nchgbds,            /**< pointer to count the total number of tightened bounds */
5370 	   SCIP_Bool             force               /**< should a possible bound change be forced even if below bound strengthening tolerance */
5371 	   )
5372 	{
5373 	   SCIP_CONSDATA* consdata;
5374 	   SCIP_VAR* var;
5375 	   SCIP_Real lb;
5376 	   SCIP_Bool infeasible;
5377 	   SCIP_Bool tightened;
5378 	
5379 	   assert(cons != NULL);
5380 	   assert(!SCIPisInfinity(scip, newub));
5381 	
5382 	   consdata = SCIPconsGetData(cons);
5383 	   assert(consdata != NULL);
5384 	   var = consdata->vars[pos];
5385 	   assert(var != NULL);
5386 	
5387 	   lb = SCIPvarGetLbLocal(var);
5388 	   newub = SCIPadjustedVarUb(scip, var, newub);
5389 	
5390 	   if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5391 	   {
5392 	      SCIP_VARTYPE vartype;
5393 	
5394 	      SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5395 	         SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos],
5396 	         QUAD_TO_DBL(consdata->minactivity), QUAD_TO_DBL(consdata->maxactivity), consdata->lhs, consdata->rhs, newub);
5397 	
5398 	      vartype = SCIPvarGetType(var);
5399 	
5400 	      /* tighten upper bound */
5401 	      SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5402 	
5403 	      if( infeasible )
5404 	      {
5405 	         SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5406 	            SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5407 	
5408 	         /* analyze conflict */
5409 	         SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5410 	
5411 	         *cutoff = TRUE;
5412 	      }
5413 	      else if( tightened )
5414 	      {
5415 	         assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5416 	         SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5417 	            SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5418 	
5419 	         (*nchgbds)++;
5420 	
5421 	         /* if variable type was changed we might be able to upgrade the constraint */
5422 	         if( vartype != SCIPvarGetType(var) )
5423 	            consdata->upgradetried = FALSE;
5424 	      }
5425 	   }
5426 	   return SCIP_OKAY;
5427 	}
5428 	
5429 	/** tighten lower bound */
5430 	static
5431 	SCIP_RETCODE tightenVarLb(
5432 	   SCIP*                 scip,               /**< SCIP data structure */
5433 	   SCIP_CONS*            cons,               /**< linear constraint */
5434 	   int                   pos,                /**< variable position */
5435 	   PROPRULE              proprule,           /**< propagation rule that deduced the value */
5436 	   SCIP_Real             newlb,              /**< new lower bound */
5437 	   SCIP_Real             oldlb,              /**< old lower bound */
5438 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
5439 	   int*                  nchgbds,            /**< pointer to count the total number of tightened bounds */
5440 	   SCIP_Bool             force               /**< should a possible bound change be forced even if below bound strengthening tolerance */
5441 	   )
5442 	{
5443 	   SCIP_CONSDATA* consdata;
5444 	   SCIP_VAR* var;
5445 	   SCIP_Real ub;
5446 	   SCIP_Bool infeasible;
5447 	   SCIP_Bool tightened;
5448 	
5449 	   assert(cons != NULL);
5450 	   assert(!SCIPisInfinity(scip, newlb));
5451 	
5452 	   consdata = SCIPconsGetData(cons);
5453 	   assert(consdata != NULL);
5454 	   var = consdata->vars[pos];
5455 	   assert(var != NULL);
5456 	
5457 	   ub = SCIPvarGetUbLocal(var);
5458 	   newlb = SCIPadjustedVarLb(scip, var, newlb);
5459 	
5460 	   if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5461 	   {
5462 	      SCIP_VARTYPE vartype;
5463 	
5464 	      SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5465 	         SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos],
5466 	         QUAD_TO_DBL(consdata->minactivity), QUAD_TO_DBL(consdata->maxactivity), consdata->lhs, consdata->rhs, newlb);
5467 	
5468 	      vartype = SCIPvarGetType(var);
5469 	
5470 	      /* tighten lower bound */
5471 	      SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5472 	
5473 	      if( infeasible )
5474 	      {
5475 	         SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5476 	            SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5477 	
5478 	         /* analyze conflict */
5479 	         SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5480 	
5481 	         *cutoff = TRUE;
5482 	      }
5483 	      else if( tightened )
5484 	      {
5485 	         assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5486 	         SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5487 	            SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5488 	
5489 	         (*nchgbds)++;
5490 	
5491 	         /* if variable type was changed we might be able to upgrade the constraint */
5492 	         if( vartype != SCIPvarGetType(var) )
5493 	            consdata->upgradetried = FALSE;
5494 	      }
5495 	   }
5496 	   return SCIP_OKAY;
5497 	}
5498 	
5499 	/** tightens bounds of a single variable due to activity bounds (easy case) */
5500 	static
5501 	SCIP_RETCODE tightenVarBoundsEasy(
5502 	   SCIP*                 scip,               /**< SCIP data structure */
5503 	   SCIP_CONS*            cons,               /**< linear constraint */
5504 	   int                   pos,                /**< position of the variable in the vars array */
5505 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
5506 	   int*                  nchgbds,            /**< pointer to count the total number of tightened bounds */
5507 	   SCIP_Bool             force               /**< should a possible bound change be forced even if below bound strengthening tolerance */
5508 	   )
5509 	{
5510 	   SCIP_CONSDATA* consdata;
5511 	   SCIP_VAR* var;
5512 	   SCIP_Real val;
5513 	   SCIP_Real lb;
5514 	   SCIP_Real ub;
5515 	   SCIP_Real lhs;
5516 	   SCIP_Real rhs;
5517 	
5518 	   assert(scip != NULL);
5519 	   assert(cons != NULL);
5520 	   assert(cutoff != NULL);
5521 	   assert(nchgbds != NULL);
5522 	
5523 	   /* we cannot tighten variables' bounds, if the constraint may be not complete */
5524 	   if( SCIPconsIsModifiable(cons) )
5525 	      return SCIP_OKAY;
5526 	
5527 	   consdata = SCIPconsGetData(cons);
5528 	   assert(consdata != NULL);
5529 	   assert(0 <= pos && pos < consdata->nvars);
5530 	
5531 	   *cutoff = FALSE;
5532 	
5533 	   var = consdata->vars[pos];
5534 	   assert(var != NULL);
5535 	
5536 	   /* we cannot tighten bounds of multi-aggregated variables */
5537 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
5538 	      return SCIP_OKAY;
5539 	
5540 	   val = consdata->vals[pos];
5541 	   lhs = consdata->lhs;
5542 	   rhs = consdata->rhs;
5543 	   assert(!SCIPisZero(scip, val));
5544 	   assert(!SCIPisInfinity(scip, lhs));
5545 	   assert(!SCIPisInfinity(scip, -rhs));
5546 	
5547 	   lb = SCIPvarGetLbLocal(var);
5548 	   ub = SCIPvarGetUbLocal(var);
5549 	   assert(SCIPisLE(scip, lb, ub));
5550 	
5551 	   /* recompute activities if needed */
5552 	   if( !consdata->validactivities )
5553 	      consdataCalcActivities(scip, consdata);
5554 	   assert(consdata->validactivities);
5555 	   if( !consdata->validminact )
5556 	      consdataRecomputeMinactivity(scip, consdata);
5557 	   assert(consdata->validminact);
5558 	
5559 	   if( val > 0.0 )
5560 	   {
5561 	      /* check, if we can tighten the variable's upper bound */
5562 	      if( !SCIPisInfinity(scip, rhs) )
5563 	      {
5564 	         SCIP_Real slack;
5565 	         SCIP_Real alpha;
5566 	
5567 	         /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5568 	         assert(consdata->validminact);
5569 	
5570 	         /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5571 	         if( SCIPisFeasLT(scip, rhs, QUAD_TO_DBL(consdata->minactivity)) )
5572 	         {
5573 	            SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, minactivity=%.15g > rhs=%.15g\n",
5574 	               SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->minactivity), rhs);
5575 	
5576 	            *cutoff = TRUE;
5577 	            return SCIP_OKAY;
5578 	         }
5579 	
5580 	         slack = rhs - QUAD_TO_DBL(consdata->minactivity);
5581 	
5582 	         /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5583 	          * it to zero
5584 	          */
5585 	         if( !SCIPisPositive(scip, slack) )
5586 	            slack = 0.0;
5587 	
5588 	         alpha = val * (ub - lb);
5589 	         assert(!SCIPisNegative(scip, alpha));
5590 	
5591 	         if( SCIPisSumGT(scip, alpha, slack)  || (force && SCIPisGT(scip, alpha, slack)) )
5592 	         {
5593 	            SCIP_Real newub;
5594 	
5595 	            /* compute new upper bound */
5596 	            newub = lb + (slack / val);
5597 	
5598 	            SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5599 	
5600 	            if( *cutoff )
5601 	            {
5602 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5603 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5604 	
5605 	               return SCIP_OKAY;
5606 	            }
5607 	
5608 	            /* collect the new upper bound which is needed for the lower bound computation */
5609 	            ub = SCIPvarGetUbLocal(var);
5610 	         }
5611 	      }
5612 	
5613 	      /* check, if we can tighten the variable's lower bound */
5614 	      if( !SCIPisInfinity(scip, -lhs) )
5615 	      {
5616 	         SCIP_Real slack;
5617 	         SCIP_Real alpha;
5618 	
5619 	         /* make sure the max activity is reliable */
5620 	         if( !consdata->validmaxact )
5621 	         {
5622 	            consdataRecomputeMaxactivity(scip, consdata);
5623 	         }
5624 	         assert(consdata->validmaxact);
5625 	
5626 	         /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5627 	         if( SCIPisFeasLT(scip, QUAD_TO_DBL(consdata->maxactivity), lhs) )
5628 	         {
5629 	            SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, maxactivity=%.15g < lhs=%.15g\n",
5630 	               SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->maxactivity), lhs);
5631 	
5632 	            *cutoff = TRUE;
5633 	            return SCIP_OKAY;
5634 	         }
5635 	
5636 	         slack = QUAD_TO_DBL(consdata->maxactivity) - lhs;
5637 	
5638 	         /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5639 	          * it to zero
5640 	          */
5641 	         if( !SCIPisPositive(scip, slack) )
5642 	            slack = 0.0;
5643 	
5644 	         alpha = val * (ub - lb);
5645 	         assert(!SCIPisNegative(scip, alpha));
5646 	
5647 	         if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5648 	         {
5649 	            SCIP_Real newlb;
5650 	
5651 	            /* compute new lower bound */
5652 	            newlb = ub - (slack / val);
5653 	
5654 	            SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5655 	
5656 	            if( *cutoff )
5657 	            {
5658 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5659 	                  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5660 	
5661 	               return SCIP_OKAY;
5662 	            }
5663 	         }
5664 	      }
5665 	   }
5666 	   else
5667 	   {
5668 	      /* check, if we can tighten the variable's lower bound */
5669 	      if( !SCIPisInfinity(scip, rhs) )
5670 	      {
5671 	         SCIP_Real slack;
5672 	         SCIP_Real alpha;
5673 	
5674 	         /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5675 	         assert(consdata->validminact);
5676 	
5677 	         /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5678 	         if( SCIPisFeasLT(scip, rhs, QUAD_TO_DBL(consdata->minactivity)) )
5679 	         {
5680 	            SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, minactivity=%.15g > rhs=%.15g\n",
5681 	               SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->minactivity), rhs);
5682 	
5683 	            *cutoff = TRUE;
5684 	            return SCIP_OKAY;
5685 	         }
5686 	
5687 	         slack = rhs - QUAD_TO_DBL(consdata->minactivity);
5688 	
5689 	         /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5690 	          * it to zero
5691 	          */
5692 	         if( !SCIPisPositive(scip, slack) )
5693 	            slack = 0.0;
5694 	
5695 	         alpha = val * (lb - ub);
5696 	         assert(!SCIPisNegative(scip, alpha));
5697 	
5698 	         if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5699 	         {
5700 	            SCIP_Real newlb;
5701 	
5702 	            /* compute new lower bound */
5703 	            newlb = ub + slack / val;
5704 	
5705 	            SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5706 	
5707 	            if( *cutoff )
5708 	            {
5709 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5710 	                  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5711 	
5712 	               return SCIP_OKAY;
5713 	            }
5714 	            /* collect the new lower bound which is needed for the upper bound computation */
5715 	            lb = SCIPvarGetLbLocal(var);
5716 	         }
5717 	      }
5718 	
5719 	      /* check, if we can tighten the variable's upper bound */
5720 	      if( !SCIPisInfinity(scip, -lhs) )
5721 	      {
5722 	         SCIP_Real slack;
5723 	         SCIP_Real alpha;
5724 	
5725 	         /* make sure the max activity is reliable */
5726 	         if( !consdata->validmaxact )
5727 	         {
5728 	            consdataRecomputeMaxactivity(scip, consdata);
5729 	         }
5730 	         assert(consdata->validmaxact);
5731 	
5732 	         /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5733 	         if( SCIPisFeasLT(scip, QUAD_TO_DBL(consdata->maxactivity), lhs) )
5734 	         {
5735 	            SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, maxactivity=%.15g < lhs=%.15g\n",
5736 	               SCIPconsGetName(cons), SCIPvarGetName(var), QUAD_TO_DBL(consdata->maxactivity), lhs);
5737 	
5738 	            *cutoff = TRUE;
5739 	            return SCIP_OKAY;
5740 	         }
5741 	
5742 	         slack = QUAD_TO_DBL(consdata->maxactivity) - lhs;
5743 	
5744 	         /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5745 	          * it to zero
5746 	          */
5747 	         if( !SCIPisPositive(scip, slack) )
5748 	            slack = 0.0;
5749 	
5750 	         alpha = val * (lb - ub);
5751 	         assert(!SCIPisNegative(scip, alpha));
5752 	
5753 	         if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5754 	         {
5755 	            SCIP_Real newub;
5756 	
5757 	            /* compute new upper bound */
5758 	            newub = lb - (slack / val);
5759 	
5760 	            SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5761 	
5762 	            if( *cutoff )
5763 	            {
5764 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
5765 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5766 	
5767 	               return SCIP_OKAY;
5768 	            }
5769 	         }
5770 	      }
5771 	   }
5772 	
5773 	   return SCIP_OKAY;
5774 	}
5775 	
5776 	/** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5777 	static
5778 	SCIP_RETCODE analyzeConflictRangedRow(
5779 	   SCIP*                 scip,               /**< SCIP data structure */
5780 	   SCIP_CONS*            cons,               /**< conflict detecting constraint */
5781 	   SCIP_VAR**            vars,               /**< variables reasoning the infeasibility */
5782 	   int                   nvars,              /**< number of variables reasoning the infeasibility */
5783 	   SCIP_VAR*             var,                /**< variable which was tried to fix/tighten, or NULL */
5784 	   SCIP_Real             bound               /**< bound of variable which was tried to apply, or SCIP_INVALID */
5785 	   )
5786 	{
5787 	#ifndef NDEBUG
5788 	   SCIP_CONSDATA* consdata;
5789 	
5790 	   assert(scip != NULL);
5791 	   assert(cons != NULL);
5792 	
5793 	   consdata = SCIPconsGetData(cons);
5794 	   assert(consdata != NULL);
5795 	   assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5796 	#endif
5797 	
5798 	   /* conflict analysis can only be applied in solving stage and if it is turned on */
5799 	   if( (SCIPgetStage(scip) != SCIP_STAGE_SOLVING && !SCIPinProbing(scip)) || !SCIPisConflictAnalysisApplicable(scip) )
5800 	      return SCIP_OKAY;
5801 	
5802 	   /* initialize conflict analysis */
5803 	   SCIP_CALL( SCIPinitConflictAnalysis(scip, SCIP_CONFTYPE_PROPAGATION, FALSE) );
5804 	
5805 	   /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5806 	   SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5807 	
5808 	   /* add reasoning variables to conflict candidate queue which led to the conflict */
5809 	   SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5810 	
5811 	   /* analyze the conflict */
5812 	   SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5813 	
5814 	   return SCIP_OKAY;
5815 	}
5816 	
5817 	/** propagate ranged rows
5818 	 *
5819 	 *  Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5820 	 *  solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5821 	 *  variables better.
5822 	 *
5823 	 *  Example:
5824 	 *  c1: 12 x1 + 9  x2 - x3 = 0  with x1, x2 free and 1 <= x3 <= 2
5825 	 *
5826 	 *  x3 needs to be a multiple of 3, so the instance is infeasible.
5827 	 *
5828 	 *  Example:
5829 	 *  c1: 12 x1 + 9  x2 - x3 = 1  with x1, x2 free and 1 <= x3 <= 2
5830 	 *
5831 	 *  The only possible value for x3 is 2, so the variable will be fixed.
5832 	 *
5833 	 *  @todo add holes if possible
5834 	 */
5835 	static
5836 	SCIP_RETCODE rangedRowPropagation(
5837 	   SCIP*                 scip,               /**< SCIP data structure */
5838 	   SCIP_CONS*            cons,               /**< linear constraint */
5839 	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
5840 	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
5841 	   int*                  nchgbds,            /**< pointer to count the number of bound changes */
5842 	   int*                  naddconss           /**< pointer to count number of added constraints */
5843 	   )
5844 	{
5845 	   SCIP_CONSHDLRDATA* conshdlrdata;
5846 	   SCIP_CONSHDLR* conshdlr;
5847 	   SCIP_CONSDATA* consdata;
5848 	   SCIP_VAR** infcheckvars;
5849 	   SCIP_Real* infcheckvals;
5850 	   SCIP_Real minactinfvars;
5851 	   SCIP_Real maxactinfvars;
5852 	   SCIP_Real lb;
5853 	   SCIP_Real ub;
5854 	   SCIP_Real feastol;
5855 	   SCIP_Real fixedact;
5856 	   SCIP_Real lhs;
5857 	   SCIP_Real rhs;
5858 	   SCIP_Real absminbincoef;
5859 	   SCIP_Longint gcd;
5860 	   SCIP_Longint gcdtmp;
5861 	   SCIP_Bool minactinfvarsinvalid;
5862 	   SCIP_Bool maxactinfvarsinvalid;
5863 	   SCIP_Bool possiblegcd;
5864 	   SCIP_Bool gcdisone;
5865 	   SCIP_Bool addartconss;
5866 	   int ninfcheckvars;
5867 	   int nunfixedvars;
5868 	   int nfixedconsvars;
5869 	   int ncontvars;
5870 	   int pos;
5871 	   int v;
5872 	
5873 	   assert(scip != NULL);
5874 	   assert(cons != NULL);
5875 	   assert(cutoff != NULL);
5876 	   assert(nfixedvars != NULL);
5877 	   assert(nchgbds != NULL);
5878 	   assert(naddconss != NULL);
5879 	
5880 	   /* modifiable constraint can be changed so we do not have all necessary information */
5881 	   if( SCIPconsIsModifiable(cons) )
5882 	      return SCIP_OKAY;
5883 	
5884 	   consdata = SCIPconsGetData(cons);
5885 	   assert(consdata != NULL);
5886 	
5887 	   /* we already did full ranged row propagation */
5888 	   if( consdata->rangedrowpropagated == 2 )
5889 	      return SCIP_OKAY;
5890 	
5891 	   /* at least three variables are needed */
5892 	   if( consdata->nvars < 3 )
5893 	      return SCIP_OKAY;
5894 	
5895 	   /* do nothing on normal inequalities */
5896 	   if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5897 	      return SCIP_OKAY;
5898 	
5899 	   /* get constraint handler data */
5900 	   conshdlr = SCIPconsGetHdlr(cons);
5901 	   assert(conshdlr != NULL);
5902 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
5903 	   assert(conshdlrdata != NULL);
5904 	
5905 	   addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5906 	
5907 	   /* we may add artificial constraints */
5908 	   if( addartconss )
5909 	      consdata->rangedrowpropagated = 2;
5910 	   /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5911 	    * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5912 	    * artificial constraints
5913 	    */
5914 	   else
5915 	   {
5916 	      if( consdata->rangedrowpropagated > 0 )
5917 	         return SCIP_OKAY;
5918 	
5919 	      consdata->rangedrowpropagated = 1;
5920 	   }
5921 	   fixedact = 0;
5922 	   nfixedconsvars = 0;
5923 	   /* calculate fixed activity and number of fixed variables */
5924 	   for( v = consdata->nvars - 1; v >= 0; --v )
5925 	   {
5926 	      /* all zero coefficients should be eliminated */
5927 	      assert(!SCIPisZero(scip, consdata->vals[v]));
5928 	
5929 	      if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5930 	      {
5931 	         fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5932 		 ++nfixedconsvars;
5933 	      }
5934 	   }
5935 	
5936 	   /* do not work with huge fixed activities */
5937 	   if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5938 	      return SCIP_OKAY;
5939 	
5940 	   /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5941 	   assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5942 	   lhs = consdata->lhs - fixedact;
5943 	   rhs = consdata->rhs - fixedact;
5944 	   nunfixedvars = consdata->nvars - nfixedconsvars;
5945 	
5946 	   /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5947 	   SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5948 	   SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5949 	
5950 	   absminbincoef = SCIP_REAL_MAX;
5951 	   ncontvars = 0;
5952 	   gcdisone = TRUE;
5953 	   possiblegcd = TRUE;
5954 	
5955 	   /* we now partition all unfixed variables in two groups:
5956 	    *
5957 	    * the first one contains all integral variable with integral
5958 	    * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5959 	    * given
5960 	    *
5961 	    * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5962 	    * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5963 	    */
5964 	
5965 	   /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5966 	    * variables
5967 	    */
5968 	   ninfcheckvars = 0;
5969 	   v = -1;
5970 	   pos = -1;
5971 	   do
5972 	   {
5973 	      ++v;
5974 	
5975 	      /* partition the variables, do not change the order of collection, because it might be used later on */
5976 	      while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5977 	            !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5978 	      {
5979 	         if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5980 	         {
5981 	            if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5982 	            {
5983 	               ++ncontvars;
5984 	            }
5985 	            else if( SCIPvarIsBinary(consdata->vars[v]) )
5986 	            {
5987 	               SCIP_Real absval;
5988 	
5989 	               absval = REALABS(consdata->vals[v]);
5990 	
5991 	               if( absminbincoef > absval )
5992 	                  absminbincoef = absval;
5993 	            }
5994 	
5995 	            gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5996 	            possiblegcd = FALSE;
5997 	            infcheckvars[ninfcheckvars] = consdata->vars[v];
5998 	            infcheckvals[ninfcheckvars] = consdata->vals[v];
5999 	            ++ninfcheckvars;
6000 	
6001 		    if( pos == -1 )
6002 		       pos = v;
6003 	         }
6004 	         ++v;
6005 	      }
6006 	   }
6007 	   while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
6008 	
6009 	   /* if the first group of variables is empty, we stop */
6010 	   /* @todo try to propagate/split up a constraint of the form:
6011 	    *       x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
6012 	    *       with k \in Z, c \in (d,d + 1], d \in Z, (a_1*y_1 + ... + a_n*y_n) \in (c-1 + d,d + 1]
6013 	    */
6014 	   if( v == consdata->nvars )
6015 	      goto TERMINATE;
6016 	
6017 	   /* we need at least two non-continuous variables */
6018 	   if( ncontvars + 2 > nunfixedvars )
6019 	      goto TERMINATE;
6020 	
6021 	   assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
6022 	   assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
6023 	
6024 	   feastol = SCIPfeastol(scip);
6025 	
6026 	   gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
6027 	   assert(gcd >= 2);
6028 	
6029 	   /* go on to partition the variables, do not change the order of collection, because it might be used later on;
6030 	    * calculate gcd over the first part of variables */
6031 	   for( ; v < consdata->nvars; ++v )
6032 	   {
6033 	      if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6034 	         continue;
6035 	
6036 	      if( SCIPvarIsBinary(consdata->vars[v]) )
6037 	      {
6038 	         SCIP_Real absval;
6039 	
6040 	         absval = REALABS(consdata->vals[v]);
6041 	
6042 	         if( absminbincoef > absval )
6043 	            absminbincoef = absval;
6044 	      }
6045 	
6046 	      if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
6047 	         SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
6048 	      {
6049 	         if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
6050 	            ++ncontvars;
6051 	
6052 	         gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
6053 	         possiblegcd = FALSE;
6054 	         infcheckvars[ninfcheckvars] = consdata->vars[v];
6055 	         infcheckvals[ninfcheckvars] = consdata->vals[v];
6056 	
6057 	         ++ninfcheckvars;
6058 	
6059 		 if( pos == -1 )
6060 		    pos = v;
6061 	      }
6062 	      else
6063 	      {
6064 	         assert(REALABS(consdata->vals[v]) > 1.5);
6065 	
6066 	         gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
6067 	         assert(gcdtmp >= 1);
6068 	
6069 	         if( gcdtmp == 1 )
6070 	         {
6071 	            infcheckvars[ninfcheckvars] = consdata->vars[v];
6072 	            infcheckvals[ninfcheckvars] = consdata->vals[v];
6073 	
6074 	            ++ninfcheckvars;
6075 	
6076 		    if( pos == -1 )
6077 		       pos = v;
6078 	         }
6079 	         else
6080 	            gcd = gcdtmp;
6081 	      }
6082 	   }
6083 	   assert(gcd >= 2);
6084 	
6085 	   /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
6086 	    * normalizeCons() */
6087 	   if( ninfcheckvars == 0 )
6088 	      goto TERMINATE;
6089 	
6090 	   assert(pos >= 0);
6091 	
6092 	   minactinfvarsinvalid = FALSE;
6093 	   maxactinfvarsinvalid = FALSE;
6094 	   maxactinfvars = 0.0;
6095 	   minactinfvars = 0.0;
6096 	
6097 	   /* calculate activities over all infcheckvars */
6098 	   for( v = ninfcheckvars - 1; v >= 0; --v )
6099 	   {
6100 	      lb = SCIPvarGetLbLocal(infcheckvars[v]);
6101 	      ub = SCIPvarGetUbLocal(infcheckvars[v]);
6102 	
6103 	      if( SCIPisInfinity(scip, -lb) )
6104 	      {
6105 	         if( infcheckvals[v] < 0.0 )
6106 	            maxactinfvarsinvalid = TRUE;
6107 	         else
6108 	            minactinfvarsinvalid = TRUE;
6109 	      }
6110 	      else
6111 	      {
6112 	         if( infcheckvals[v] < 0.0 )
6113 	            maxactinfvars += infcheckvals[v] * lb;
6114 	         else
6115 	            minactinfvars += infcheckvals[v] * lb;
6116 	      }
6117 	
6118 	      if( SCIPisInfinity(scip, ub) )
6119 	      {
6120 	         if( infcheckvals[v] > 0.0 )
6121 	            maxactinfvarsinvalid = TRUE;
6122 	         else
6123 	            minactinfvarsinvalid = TRUE;
6124 	      }
6125 	      else
6126 	      {
6127 	         if( infcheckvals[v] > 0.0 )
6128 	            maxactinfvars += infcheckvals[v] * ub;
6129 	         else
6130 	            minactinfvars += infcheckvals[v] * ub;
6131 	      }
6132 	
6133 	      /* better abort on to big values */
6134 	      if( SCIPisHugeValue(scip, -minactinfvars) )
6135 		 minactinfvarsinvalid = TRUE;
6136 	      if( SCIPisHugeValue(scip, maxactinfvars) )
6137 		 maxactinfvarsinvalid = TRUE;
6138 	
6139 	      if( minactinfvarsinvalid || maxactinfvarsinvalid )
6140 	         goto TERMINATE;
6141 	   }
6142 	   assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
6143 	
6144 	   SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
6145 	      minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
6146 	
6147 	   /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
6148 	   /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
6149 	    *       activities */
6150 	   /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
6151 	    *       !!!note!!!
6152 	    *       that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
6153 	    *       are not at their global bound
6154 	    */
6155 	
6156 	   /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
6157 	    * infeasibility */
6158 	   if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
6159 	      SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
6160 	   {
6161 	      SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
6162 	      SCIPdebugPrintCons(scip, cons, NULL);
6163 	
6164 	      /* start conflict analysis */
6165 	      /* @todo improve conflict analysis by adding relaxed bounds */
6166 	      SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6167 	
6168 	      *cutoff = TRUE;
6169 	   }
6170 	   else if( ncontvars == 0 )
6171 	   {
6172 	      SCIP_Longint gcdinfvars = -1;
6173 	
6174 	      /* check for gcd over all infcheckvars */
6175 	      if( possiblegcd )
6176 	      {
6177 	         v = ninfcheckvars - 1;
6178 	         gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
6179 	         assert(gcdinfvars >= 2);
6180 	
6181 	         for( ; v >= 0 && gcdinfvars >= 2; --v )
6182 	         {
6183 	            gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
6184 	         }
6185 	      }
6186 	      else if( gcdisone )
6187 	         gcdinfvars = 1;
6188 	
6189 	      SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
6190 	
6191 	      /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
6192 	      if( gcdinfvars >= 1 )
6193 	      {
6194 	         SCIP_Real value;
6195 	         SCIP_Real value2;
6196 	         SCIP_Real minvalue = SCIP_INVALID;
6197 	         SCIP_Real maxvalue = SCIP_INVALID;
6198 	         int nsols = 0;
6199 	
6200 	         value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
6201 	
6202 	         /* check how many possible solutions exist */
6203 	         while( SCIPisLE(scip, value, maxactinfvars) )
6204 	         {
6205 		    value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
6206 	
6207 	             /* value2 might violate lhs due to numerics, in this case take the next divisible number */
6208 	             if( !SCIPisGE(scip, value2, lhs) )
6209 	             {
6210 	                value2 += gcd;
6211 	             }
6212 	
6213 		    if( SCIPisLE(scip, value2, rhs) )
6214 		    {
6215 		       ++nsols;
6216 	
6217 		       /* early termination if we found more than two solutions */
6218 		       if( nsols == 3 )
6219 			  break;
6220 	
6221 		       if( minvalue == SCIP_INVALID ) /*lint !e777*/
6222 			  minvalue = value;
6223 	
6224 		       maxvalue = value;
6225 		    }
6226 	            value += gcdinfvars;
6227 	         }
6228 	         assert(nsols < 2 || minvalue <= maxvalue);
6229 	
6230 	         /* determine last possible solution for better bounding */
6231 	         if( nsols == 3 )
6232 	         {
6233 	#ifndef NDEBUG
6234 	            SCIP_Real secondsolval = maxvalue;
6235 	#endif
6236 	            value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
6237 	
6238 	            /* check how many possible solutions exist */
6239 	            while( SCIPisGE(scip, value, minactinfvars) )
6240 	            {
6241 	               value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
6242 	
6243 	               /* value2 might violate rhs due to numerics, in this case take the next divisible number */
6244 	               if( !SCIPisLE(scip, value2, rhs) )
6245 	               {
6246 	                  value2 -= gcd;
6247 	               }
6248 	
6249 	               if( SCIPisGE(scip, value2, lhs) )
6250 	               {
6251 	                  maxvalue = value;
6252 	                  assert(maxvalue > minvalue);
6253 	                  break;
6254 	               }
6255 	               value -= gcdinfvars;
6256 	            }
6257 	            assert(maxvalue > secondsolval);
6258 	         }
6259 	
6260 	         SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
6261 	            nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
6262 	
6263 	         /* no possible solution found */
6264 	         if( nsols == 0 )
6265 	         {
6266 		    SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
6267 	               gcdinfvars, gcd, lhs, rhs);
6268 	            SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
6269 	            SCIPdebugPrintCons(scip, cons, NULL);
6270 	
6271 		    /* start conflict analysis */
6272 	            /* @todo improve conflict analysis by adding relaxed bounds */
6273 		    SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6274 	
6275 	            *cutoff = TRUE;
6276 	         }
6277 	         /* if only one solution exist we can extract a new constraint or fix variables */
6278 	         else if( nsols == 1 )
6279 	         {
6280 		    assert(minvalue == maxvalue); /*lint !e777*/
6281 	
6282 		    /* we can fix the only variable in our second set of variables */
6283 	            if( ninfcheckvars == 1 )
6284 	            {
6285 	               SCIP_Bool fixed;
6286 	
6287 		       assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6288 	
6289 	               SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6290 	                  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
6291 	                  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
6292 	
6293 	               /* fix variable to only possible value */
6294 	               SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
6295 	                     getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
6296 	
6297 		       if( *cutoff )
6298 		       {
6299 			  /* start conflict analysis */
6300 	                  /* @todo improve conflict analysis by adding relaxed bounds */
6301 			  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6302 		       }
6303 	
6304 	               if( fixed )
6305 	                  ++(*nfixedvars);
6306 	            }
6307 	            else
6308 	            {
6309 	               /* check for exactly one unfixed variable which is not part of the infcheckvars */
6310 	               if( ninfcheckvars == nunfixedvars - 1 )
6311 	               {
6312 	                  SCIP_Real bound;
6313 	                  SCIP_Bool foundvar = FALSE;
6314 	                  SCIP_Bool fixed;
6315 			  int w = 0;
6316 	
6317 	                  assert(ninfcheckvars > 0);
6318 	
6319 	                  /* find variable which is not an infcheckvar and fix it */
6320 	                  for( v = 0; v < consdata->nvars - 1; ++v )
6321 			  {
6322 	                     if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6323 			     {
6324 				if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6325 				{
6326 	#ifndef NDEBUG
6327 	                           int v2 = v + 1;
6328 	                           int w2 = w;
6329 	
6330 	                           assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6331 	
6332 	                           for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6333 	                           {
6334 	                              if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6335 	                                 continue;
6336 	
6337 	                              assert(consdata->vars[v2] == infcheckvars[w2]);
6338 	                              ++w2;
6339 	                           }
6340 	                           assert(w2 == ninfcheckvars);
6341 	#endif
6342 				   assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6343 	
6344 				   foundvar = TRUE;
6345 	
6346 				   if( consdata->vals[v] < 0 )
6347 				   {
6348 				      bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6349 				   }
6350 				   else
6351 				   {
6352 				      bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6353 				   }
6354 	
6355 				   SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6356 	                              SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6357 	                              SCIPvarGetUbLocal(consdata->vars[v]), bound);
6358 	
6359 				   /* fix variable to only possible value */
6360 				   SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6361 	                                 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6362 	
6363 				   if( *cutoff )
6364 				   {
6365 				      /* start conflict analysis */
6366 	                              /* @todo improve conflict analysis by adding relaxed bounds */
6367 				      SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6368 	                                    consdata->vars[v], bound) );
6369 				   }
6370 	
6371 				   if( fixed )
6372 				      ++(*nfixedvars);
6373 	
6374 				   break;
6375 				}
6376 	
6377 				++w;
6378 			     }
6379 			  }
6380 	
6381 	                  /* maybe last variable was the not infcheckvar */
6382 	                  if( !foundvar )
6383 	                  {
6384 	                     assert(v == consdata->nvars - 1);
6385 			     assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6386 	
6387 			     if( consdata->vals[v] < 0 )
6388 			     {
6389 				bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6390 			     }
6391 			     else
6392 			     {
6393 				bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6394 			     }
6395 	
6396 	                     SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6397 	                        SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6398 	                        SCIPvarGetUbLocal(consdata->vars[v]), bound);
6399 	
6400 	                     /* fix variable to only possible value */
6401 			     SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6402 	                           getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6403 	
6404 			     if( *cutoff )
6405 			     {
6406 				/* start conflict analysis */
6407 	                        /* @todo improve conflict analysis by adding relaxed bounds */
6408 	                        SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6409 	                              consdata->vars[v], bound) );
6410 			     }
6411 	
6412 	                     if( fixed )
6413 	                        ++(*nfixedvars);
6414 	                  }
6415 	               }
6416 	               else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6417 	               {
6418 	                  /* aggregation possible if we have two variables, but this will be done later on */
6419 	                  SCIP_CONS* newcons;
6420 	                  char name[SCIP_MAXSTRLEN];
6421 	
6422 	                  /* create, add, and release new artificial constraint */
6423 	                  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6424 	                  ++conshdlrdata->naddconss;
6425 	
6426 			  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6427 	
6428 	                  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6429 	                        maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6430 	                  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6431 	
6432 	                  SCIPdebugPrintCons(scip, newcons, NULL);
6433 	
6434 	                  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6435 	
6436 	                  ++(*naddconss);
6437 	               }
6438 	            }
6439 	         }
6440 	         /* at least two solutions */
6441 	         else
6442 	         {
6443 	            /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6444 	
6445 		    /* only one variable in the second set, so we can bound this variables */
6446 	            if( ninfcheckvars == 1 )
6447 	            {
6448 	               SCIP_Bool tightened;
6449 	               SCIP_Real newlb;
6450 	               SCIP_Real newub;
6451 	
6452 		       assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6453 	
6454 	               if( infcheckvals[0] < 0 )
6455 	               {
6456 	                  newlb = maxvalue/infcheckvals[0];
6457 	                  newub = minvalue/infcheckvals[0];
6458 	               }
6459 	               else
6460 	               {
6461 	                  newlb = minvalue/infcheckvals[0];
6462 	                  newub = maxvalue/infcheckvals[0];
6463 	               }
6464 	               assert(newlb < newub);
6465 	
6466 		       if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6467 		       {
6468 			  /* update lower bound of variable */
6469 			  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6470 	                     SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6471 	
6472 			  /* tighten variable lower bound to minimal possible value */
6473 			  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6474 	                        getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6475 	
6476 			  if( *cutoff )
6477 			  {
6478 			     /* start conflict analysis */
6479 	                     /* @todo improve conflict analysis by adding relaxed bounds */
6480 			     SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6481 			  }
6482 	
6483 			  if( tightened )
6484 			     ++(*nchgbds);
6485 		       }
6486 	
6487 		       if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6488 		       {
6489 			  /* update upper bound of variable */
6490 			  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6491 	                     SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6492 	
6493 			  /* tighten variable upper bound to maximal possible value */
6494 			  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6495 	                        getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6496 	
6497 			  if( *cutoff )
6498 			  {
6499 			     /* start conflict analysis */
6500 	                     /* @todo improve conflict analysis by adding relaxed bounds */
6501 			     SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6502 			  }
6503 	
6504 			  if( tightened )
6505 			     ++(*nchgbds);
6506 		       }
6507 	            }
6508 	            /* check if we have only one not infcheckvars, if so we can tighten this variable */
6509 	            else if( ninfcheckvars == nunfixedvars - 1 )
6510 	            {
6511 	               SCIP_Bool foundvar = FALSE;
6512 	               SCIP_Bool tightened;
6513 	               SCIP_Real newlb;
6514 	               SCIP_Real newub;
6515 		       int w = 0;
6516 	
6517 	               assert(ninfcheckvars > 0);
6518 	               assert(minvalue < maxvalue);
6519 	
6520 	               /* find variable which is not an infcheckvar and fix it */
6521 	               for( v = 0; v < consdata->nvars - 1; ++v )
6522 		       {
6523 	                  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6524 			  {
6525 			     if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6526 			     {
6527 	#ifndef NDEBUG
6528 	                        int v2 = v + 1;
6529 	                        int w2 = w;
6530 	
6531 	                        assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6532 	
6533 	                        for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6534 	                        {
6535 	                           if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6536 	                              continue;
6537 	
6538 	                           assert(consdata->vars[v2] == infcheckvars[w2]);
6539 	                           ++w2;
6540 	                        }
6541 	                        assert(w2 == ninfcheckvars);
6542 	#endif
6543 	
6544 				assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6545 				foundvar = TRUE;
6546 	
6547 				if( consdata->vals[v] < 0 )
6548 				{
6549 				   newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6550 				   newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6551 				}
6552 				else
6553 				{
6554 				   newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6555 				   newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6556 				}
6557 				assert(SCIPisLE(scip, newlb, newub));
6558 	
6559 				if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6560 				{
6561 				   /* update lower bound of variable */
6562 				   SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6563 	                              SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6564 	
6565 				   /* tighten variable lower bound to minimal possible value */
6566 				   SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6567 	                                 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6568 	
6569 				   if( *cutoff )
6570 				   {
6571 				      /* start conflict analysis */
6572 	                              /* @todo improve conflict analysis by adding relaxed bounds */
6573 				      SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6574 	                                    consdata->vars[v], newlb) );
6575 				   }
6576 	
6577 				   if( tightened )
6578 				      ++(*nchgbds);
6579 				}
6580 	
6581 				if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6582 				{
6583 				   /* update upper bound of variable */
6584 				   SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6585 	                              SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6586 	
6587 				   /* tighten variable upper bound to maximal possible value */
6588 				   SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6589 	                                 getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6590 	
6591 				   if( *cutoff )
6592 				   {
6593 				      /* start conflict analysis */
6594 	                              /* @todo improve conflict analysis by adding relaxed bounds */
6595 				      SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6596 	                                    consdata->vars[v], newub) );
6597 				   }
6598 	
6599 				   if( tightened )
6600 				      ++(*nchgbds);
6601 				}
6602 	
6603 				break;
6604 			     }
6605 	
6606 			     ++w;
6607 			  }
6608 		       }
6609 	
6610 	               /* maybe last variable was the not infcheckvar */
6611 	               if( !foundvar )
6612 	               {
6613 	                  assert(v == consdata->nvars - 1);
6614 			  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6615 	
6616 			  if( consdata->vals[v] < 0 )
6617 			  {
6618 			     newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6619 			     newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6620 			  }
6621 			  else
6622 			  {
6623 			     newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6624 			     newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6625 			  }
6626 	                  assert(SCIPisLE(scip, newlb, newub));
6627 	
6628 			  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6629 			  {
6630 			     /* update lower bound of variable */
6631 			     SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6632 	                        SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6633 	
6634 	                     /* tighten variable lower bound to minimal possible value */
6635 			     SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6636 	                           getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6637 	
6638 			     if( *cutoff )
6639 			     {
6640 				/* start conflict analysis */
6641 	                        /* @todo improve conflict analysis by adding relaxed bounds */
6642 	                        SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6643 			     }
6644 	
6645 			     if( tightened )
6646 				++(*nchgbds);
6647 			  }
6648 	
6649 			  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6650 			  {
6651 			     /* update upper bound of variable */
6652 			     SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6653 	                        SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6654 	
6655 			     /* tighten variable upper bound to maximal possible value */
6656 			     SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6657 	                           getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6658 	
6659 			     if( *cutoff )
6660 			     {
6661 				/* start conflict analysis */
6662 	                        /* @todo improve conflict analysis by adding relaxed bounds */
6663 	                        SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6664 			     }
6665 	
6666 			     if( tightened )
6667 				++(*nchgbds);
6668 			  }
6669 	               }
6670 	            }
6671 	            /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6672 	             * region for our infcheckvars, if possible
6673 	             */
6674 	            else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6675 	            {
6676 	               SCIP_CONS* newcons;
6677 	               char name[SCIP_MAXSTRLEN];
6678 	               SCIP_Real newlhs;
6679 	               SCIP_Real newrhs;
6680 	
6681 	               assert(maxvalue > minvalue);
6682 	
6683 	               if( SCIPisGT(scip, minvalue, minactinfvars) )
6684 	                  newlhs = minvalue;
6685 	               else
6686 	                  newlhs = -SCIPinfinity(scip);
6687 	
6688 	               if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6689 	                  newrhs = maxvalue;
6690 	               else
6691 	                  newrhs = SCIPinfinity(scip);
6692 	
6693 		       if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6694 		       {
6695 			  /* create, add, and release new artificial constraint */
6696 			  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6697 			  ++conshdlrdata->naddconss;
6698 	
6699 			  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6700 	
6701 			  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6702 				TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6703 			  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6704 	
6705 			  SCIPdebugPrintCons(scip, newcons, NULL);
6706 			  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6707 	
6708 			  ++(*naddconss);
6709 		       }
6710 	               /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6711 	                *       should be maxvalue */
6712 	            }
6713 	         }
6714 	      }
6715 	   }
6716 	   else if( addartconss && ncontvars < ninfcheckvars )
6717 	   {
6718 	      SCIP_Real maxact = 0.0;
6719 	      SCIP_Real minact = 0.0;
6720 	      int w = 0;
6721 	
6722 	      /* compute activities of non-infcheckvars */
6723 	      for( v = 0; v < consdata->nvars; ++v )
6724 	      {
6725 	         if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6726 	         {
6727 	            ++w;
6728 	            continue;
6729 	         }
6730 	
6731 	         if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6732 	         {
6733 	            if( SCIPvarIsBinary(consdata->vars[v]) )
6734 	            {
6735 	               if( consdata->vals[v] > 0.0 )
6736 	                  maxact += consdata->vals[v];
6737 	               else
6738 	                  minact += consdata->vals[v];
6739 	            }
6740 	            else
6741 	            {
6742 	               SCIP_Real tmpval;
6743 	
6744 	               assert(SCIPvarIsIntegral(consdata->vars[v]));
6745 	
6746 	               if( consdata->vals[v] > 0.0 )
6747 	               {
6748 	                  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6749 	
6750 	                  if( SCIPisHugeValue(scip, -tmpval) )
6751 	                     break;
6752 	
6753 	                  minact += tmpval;
6754 	
6755 	                  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6756 	
6757 	                  if( SCIPisHugeValue(scip, tmpval) )
6758 	                     break;
6759 	
6760 	                  maxact += tmpval;
6761 	               }
6762 	               else
6763 	               {
6764 	                  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6765 	
6766 	                  if( SCIPisHugeValue(scip, -tmpval) )
6767 	                     break;
6768 	
6769 	                  minact += tmpval;
6770 	
6771 	                  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6772 	
6773 	                  if( SCIPisHugeValue(scip, tmpval) )
6774 	                     break;
6775 	
6776 	                  maxact += tmpval;
6777 	               }
6778 	            }
6779 	         }
6780 	      }
6781 	      if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6782 	      {
6783 	         SCIP_CONS* newcons;
6784 	         char name[SCIP_MAXSTRLEN];
6785 	         SCIP_Real newlhs;
6786 	         SCIP_Real newrhs;
6787 	
6788 	         assert(maxact > minact);
6789 	         assert(w == ninfcheckvars);
6790 	
6791 	         newlhs = lhs - maxact;
6792 	         newrhs = rhs - minact;
6793 	         assert(newlhs < newrhs);
6794 	
6795 	         /* create, add, and release new artificial constraint */
6796 	         (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6797 	         ++conshdlrdata->naddconss;
6798 	
6799 	         SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6800 	
6801 	         SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6802 	               TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6803 	         SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6804 	
6805 	         SCIPdebugPrintCons(scip, newcons, NULL);
6806 	         SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6807 	
6808 	         ++(*naddconss);
6809 	      }
6810 	   }
6811 	
6812 	 TERMINATE:
6813 	   SCIPfreeBufferArray(scip, &infcheckvals);
6814 	   SCIPfreeBufferArray(scip, &infcheckvars);
6815 	
6816 	   return SCIP_OKAY;
6817 	}
6818 	
6819 	/** tightens bounds of a single variable due to activity bounds */
6820 	static
6821 	SCIP_RETCODE tightenVarBounds(
6822 	   SCIP*                 scip,               /**< SCIP data structure */
6823 	   SCIP_CONS*            cons,               /**< linear constraint */
6824 	   int                   pos,                /**< position of the variable in the vars array */
6825 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
6826 	   int*                  nchgbds,            /**< pointer to count the total number of tightened bounds */
6827 	   SCIP_Bool             force               /**< should a possible bound change be forced even if below bound strengthening tolerance */
6828 	   )
6829 	{
6830 	   SCIP_CONSDATA* consdata;
6831 	   SCIP_VAR* var;
6832 	   SCIP_Real val;
6833 	   SCIP_Real lb;
6834 	   SCIP_Real ub;
6835 	   SCIP_Real minresactivity;
6836 	   SCIP_Real maxresactivity;
6837 	   SCIP_Real lhs;
6838 	   SCIP_Real rhs;
6839 	   SCIP_Bool infeasible;
6840 	   SCIP_Bool tightened;
6841 	   SCIP_Bool minisrelax;
6842 	   SCIP_Bool maxisrelax;
6843 	   SCIP_Bool isminsettoinfinity;
6844 	   SCIP_Bool ismaxsettoinfinity;
6845 	
6846 	   assert(scip != NULL);
6847 	   assert(cons != NULL);
6848 	   assert(cutoff != NULL);
6849 	   assert(nchgbds != NULL);
6850 	
6851 	   /* we cannot tighten variables' bounds, if the constraint may be not complete */
6852 	   if( SCIPconsIsModifiable(cons) )
6853 	      return SCIP_OKAY;
6854 	
6855 	   consdata = SCIPconsGetData(cons);
6856 	   assert(consdata != NULL);
6857 	   assert(0 <= pos && pos < consdata->nvars);
6858 	
6859 	   *cutoff = FALSE;
6860 	
6861 	   var = consdata->vars[pos];
6862 	
6863 	   /* we cannot tighten bounds of multi-aggregated variables */
6864 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
6865 	      return SCIP_OKAY;
6866 	
6867 	   val = consdata->vals[pos];
6868 	   lhs = consdata->lhs;
6869 	   rhs = consdata->rhs;
6870 	   consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6871 	      &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6872 	   assert(var != NULL);
6873 	   assert(!SCIPisZero(scip, val));
6874 	   assert(!SCIPisInfinity(scip, lhs));
6875 	   assert(!SCIPisInfinity(scip, -rhs));
6876 	
6877 	   lb = SCIPvarGetLbLocal(var);
6878 	   ub = SCIPvarGetUbLocal(var);
6879 	   assert(SCIPisLE(scip, lb, ub));
6880 	
6881 	   if( val > 0.0 )
6882 	   {
6883 	      /* check, if we can tighten the variable's bounds */
6884 	      if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6885 	      {
6886 	         SCIP_Real newub;
6887 	
6888 	         newub = (rhs - minresactivity)/val;
6889 	
6890 	         if( !SCIPisInfinity(scip, newub) &&
6891 	            ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6892 	         {
6893 	            SCIP_Bool activityunreliable;
6894 	            activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6895 	
6896 	            /* check minresactivities for reliability */
6897 	            if( activityunreliable )
6898 	            {
6899 	               consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6900 	               newub = (rhs - minresactivity)/val;
6901 	               activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6902 	                  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6903 	                     && (!force || !SCIPisLT(scip, newub, ub)));
6904 	            }
6905 	
6906 	            if( !activityunreliable )
6907 	            {
6908 	               /* tighten upper bound */
6909 	               SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6910 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6911 	               SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6912 	                     &infeasible, &tightened) );
6913 	               if( infeasible )
6914 	               {
6915 	                  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
6916 	                     SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6917 	
6918 	                  /* analyze conflict */
6919 	                  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6920 	
6921 	                  *cutoff = TRUE;
6922 	                  return SCIP_OKAY;
6923 	               }
6924 	               if( tightened )
6925 	               {
6926 	                  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6927 	                  assert(SCIPisFeasLE(scip, ub, newub));
6928 	                  (*nchgbds)++;
6929 	
6930 	                  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6931 	                     SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6932 	               }
6933 	            }
6934 	         }
6935 	      }
6936 	
6937 	      if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6938 	      {
6939 	         SCIP_Real newlb;
6940 	
6941 	         newlb = (lhs - maxresactivity)/val;
6942 	         if( !SCIPisInfinity(scip, -newlb) &&
6943 	            ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6944 	         {
6945 	            /* check maxresactivities for reliability */
6946 	            if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6947 	            {
6948 	               consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6949 	               newlb = (lhs - maxresactivity)/val;
6950 	
6951 	               if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6952 	                     && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6953 	                     && (!force || !SCIPisGT(scip, newlb, lb))) )
6954 	                  return SCIP_OKAY;
6955 	            }
6956 	
6957 	            /* tighten lower bound */
6958 	            SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6959 	               SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6960 	            SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6961 	                  &infeasible, &tightened) );
6962 	            if( infeasible )
6963 	            {
6964 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
6965 	                  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6966 	
6967 	               /* analyze conflict */
6968 	               SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6969 	
6970 	               *cutoff = TRUE;
6971 	               return SCIP_OKAY;
6972 	            }
6973 	            if( tightened )
6974 	            {
6975 	               lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6976 	               assert(SCIPisFeasGE(scip, lb, newlb));
6977 	               (*nchgbds)++;
6978 	               SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6979 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6980 	            }
6981 	         }
6982 	      }
6983 	   }
6984 	   else
6985 	   {
6986 	      /* check, if we can tighten the variable's bounds */
6987 	      if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6988 	      {
6989 	         SCIP_Real newlb;
6990 	
6991 	         newlb = (rhs - minresactivity)/val;
6992 	         if( !SCIPisInfinity(scip, -newlb) &&
6993 	            ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6994 	         {
6995 	            SCIP_Bool activityunreliable;
6996 	            activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6997 	            /* check minresactivities for reliability */
6998 	            if( activityunreliable )
6999 	            {
7000 	               consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
7001 	               newlb = (rhs - minresactivity)/val;
7002 	
7003 	               activityunreliable = SCIPisInfinity(scip, -minresactivity)
7004 	                  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
7005 	                     && (!force || !SCIPisGT(scip, newlb, lb)));
7006 	            }
7007 	
7008 	            if( !activityunreliable )
7009 	            {
7010 	               /* tighten lower bound */
7011 	               SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
7012 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
7013 	               SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
7014 	                     &infeasible, &tightened) );
7015 	               if( infeasible )
7016 	               {
7017 	                  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
7018 	                     SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
7019 	
7020 	                  /* analyze conflict */
7021 	                  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7022 	
7023 	                  *cutoff = TRUE;
7024 	                  return SCIP_OKAY;
7025 	               }
7026 	               if( tightened )
7027 	               {
7028 	                  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7029 	                  assert(SCIPisFeasGE(scip, lb, newlb));
7030 	                  (*nchgbds)++;
7031 	                  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7032 	                     SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7033 	               }
7034 	            }
7035 	         }
7036 	      }
7037 	
7038 	      if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
7039 	      {
7040 	         SCIP_Real newub;
7041 	
7042 	         newub = (lhs - maxresactivity)/val;
7043 	         if(  !SCIPisInfinity(scip, newub) &&
7044 	            ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
7045 	         {
7046 	            /* check maxresactivities for reliability */
7047 	            if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
7048 	            {
7049 	               consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
7050 	               newub = (lhs - maxresactivity)/val;
7051 	
7052 	               if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
7053 	                     && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
7054 	                     && (!force || !SCIPisLT(scip, newub, ub))) )
7055 	                  return SCIP_OKAY;
7056 	            }
7057 	
7058 	            /* tighten upper bound */
7059 	            SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
7060 	               SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
7061 	            SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
7062 	                  &infeasible, &tightened) );
7063 	            if( infeasible )
7064 	            {
7065 	               SCIPdebugMsg(scip, "linear constraint <%s>: cutoff  <%s>, new bds=[%.15g,%.15g]\n",
7066 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
7067 	
7068 	               /* analyze conflict */
7069 	               SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7070 	
7071 	               *cutoff = TRUE;
7072 	               return SCIP_OKAY;
7073 	            }
7074 	            if( tightened )
7075 	            {
7076 	               ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7077 	               assert(SCIPisFeasLE(scip, ub, newub));
7078 	               (*nchgbds)++;
7079 	               SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7080 	                  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7081 	            }
7082 	         }
7083 	      }
7084 	   }
7085 	
7086 	   return SCIP_OKAY;
7087 	}
7088 	
7089 	#define MAXTIGHTENROUNDS 10
7090 	
7091 	/** tightens bounds of variables in constraint due to activity bounds */
7092 	static
7093 	SCIP_RETCODE tightenBounds(
7094 	   SCIP*                 scip,               /**< SCIP data structure */
7095 	   SCIP_CONS*            cons,               /**< linear constraint */
7096 	   SCIP_Real             maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7097 	   SCIP_Bool             sortvars,           /**< should variables be used in sorted order? */
7098 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
7099 	   int*                  nchgbds             /**< pointer to count the total number of tightened bounds */
7100 	   )
7101 	{
7102 	   SCIP_CONSDATA* consdata;
7103 	   unsigned int tightenmode;
7104 	   int nvars;
7105 	   int nrounds;
7106 	   int lastchange;
7107 	   int oldnchgbds;
7108 	#ifndef SCIP_DEBUG
7109 	   int oldnchgbdstotal;
7110 	#endif
7111 	   int v;
7112 	   SCIP_Bool force;
7113 	   SCIP_Bool easycase;
7114 	
7115 	   assert(scip != NULL);
7116 	   assert(cons != NULL);
7117 	   assert(nchgbds != NULL);
7118 	   assert(cutoff != NULL);
7119 	
7120 	   *cutoff = FALSE;
7121 	
7122 	   /* we cannot tighten variables' bounds, if the constraint may be not complete */
7123 	   if( SCIPconsIsModifiable(cons) )
7124 	      return SCIP_OKAY;
7125 	
7126 	   /* if a constraint was created after presolve, then it may hold fixed variables
7127 	    * if there are even multi-aggregated variables, then we cannot do bound tightening on these
7128 	    * thus, ensure here again that variable fixings have been applied
7129 	    */
7130 	   SCIP_CALL( applyFixings(scip, cons, cutoff) );
7131 	   if( *cutoff )
7132 	      return SCIP_OKAY;
7133 	
7134 	   /* check if constraint has any chances of tightening bounds */
7135 	   if( !canTightenBounds(cons) )
7136 	      return SCIP_OKAY;
7137 	
7138 	   consdata = SCIPconsGetData(cons);
7139 	   assert(consdata != NULL);
7140 	
7141 	   nvars = consdata->nvars;
7142 	   force = (nvars == 1) && !SCIPconsIsModifiable(cons);
7143 	
7144 	   /* we are at the root node or during presolving */
7145 	   if( SCIPgetDepth(scip) < 1 )
7146 	      tightenmode = 2;
7147 	   else
7148 	      tightenmode = 1;
7149 	
7150 	   /* stop if we already tightened the constraint and the tightening is not forced */
7151 	   if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
7152 	      return SCIP_OKAY;
7153 	
7154 	   /* ensure that the variables are properly sorted */
7155 	   if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7156 	   {
7157 	      SCIP_CALL( consdataSort(scip, consdata) );
7158 	      assert(consdata->coefsorted);
7159 	   }
7160 	
7161 	   /* update maximal activity delta if necessary */
7162 	   if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
7163 	      consdataRecomputeMaxActivityDelta(scip, consdata);
7164 	
7165 	   assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
7166 	   assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
7167 	   checkMaxActivityDelta(scip, consdata);
7168 	
7169 	   /* this may happen if all variables are fixed */
7170 	   if( SCIPisFeasZero(scip, consdata->maxactdelta) )
7171 	      return SCIP_OKAY;
7172 	
7173 	   if( !SCIPisInfinity(scip, consdata->maxactdelta) )
7174 	   {
7175 	      SCIP_Real slack;
7176 	      SCIP_Real surplus;
7177 	      SCIP_Real minactivity;
7178 	      SCIP_Real maxactivity;
7179 	      SCIP_Bool minisrelax;
7180 	      SCIP_Bool maxisrelax;
7181 	      SCIP_Bool isminsettoinfinity;
7182 	      SCIP_Bool ismaxsettoinfinity;
7183 	
7184 	      /* use maximal activity delta to skip propagation (cannot deduce anything) */
7185 	      consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
7186 	         &isminsettoinfinity, &ismaxsettoinfinity);
7187 	      assert(!SCIPisInfinity(scip, minactivity));
7188 	      assert(!SCIPisInfinity(scip, -maxactivity));
7189 	
7190 	      slack = (SCIPisInfinity(scip, consdata->rhs) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
7191 	      surplus = (SCIPisInfinity(scip, -consdata->lhs) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
7192 	
7193 	      /* check if the constraint will propagate */
7194 	      if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
7195 	         return SCIP_OKAY;
7196 	   }
7197 	
7198 	   /* check if we can use fast implementation for easy and numerically well behaved cases */
7199 	   easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
7200 	
7201 	   /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
7202 	   lastchange = -1;
7203 	   oldnchgbds = 0;
7204 	
7205 	#ifndef SCIP_DEBUG
7206 	   oldnchgbdstotal = *nchgbds;
7207 	#endif
7208 	
7209 	   for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
7210 	   {
7211 	      /* ensure that the variables are properly sorted
7212 	       *
7213 	       * note: it might happen that integer variables become binary during bound tightening at the root node
7214 	       */
7215 	      if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7216 	      {
7217 	         SCIP_CALL( consdataSort(scip, consdata) );
7218 	         assert(consdata->coefsorted);
7219 	      }
7220 	
7221 	      /* mark the constraint to have the variables' bounds tightened */
7222 	      consdata->boundstightened = (unsigned int)tightenmode;
7223 	
7224 	      /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
7225 	       * sorting enables skipping variables
7226 	       */
7227 	      v = 0;
7228 	      while( v < nvars && v != lastchange && !(*cutoff) )
7229 	      {
7230 	         oldnchgbds = *nchgbds;
7231 	
7232 	         if( easycase )
7233 	         {
7234 	            SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
7235 	         }
7236 	         else
7237 	         {
7238 	            SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
7239 	         }
7240 	
7241 	         /* if there was no progress, skip the rest of the binary variables */
7242 	         if( *nchgbds > oldnchgbds )
7243 	         {
7244 	            lastchange = v;
7245 	            ++v;
7246 	         }
7247 	         else if( consdata->coefsorted && v < consdata->nbinvars - 1
7248 	            && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
7249 	            v = consdata->nbinvars;
7250 	         else
7251 	            ++v;
7252 	      }
7253 	
7254 	#ifndef SCIP_DEBUG
7255 	      SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
7256 	         *nchgbds - oldnchgbdstotal, nrounds);
7257 	      oldnchgbdstotal += oldnchgbds;
7258 	#endif
7259 	   }
7260 	
7261 	#ifndef NDEBUG
7262 	   if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
7263 	      assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
7264 	#endif
7265 	
7266 	   return SCIP_OKAY;
7267 	}
7268 	
7269 	/** checks linear constraint for feasibility of given solution or current solution */
7270 	static
7271 	SCIP_RETCODE checkCons(
7272 	   SCIP*                 scip,               /**< SCIP data structure */
7273 	   SCIP_CONS*            cons,               /**< linear constraint */
7274 	   SCIP_SOL*             sol,                /**< solution to be checked, or NULL for current solution */
7275 	   SCIP_Bool             checklprows,        /**< Do constraints represented by rows in the current LP have to be checked? */
7276 	   SCIP_Bool             checkrelmaxabs,     /**< Should the violation for a constraint with side 0.0 be checked relative
7277 	                                              *   to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
7278 	   SCIP_Bool*            violated            /**< pointer to store whether the constraint is violated */
7279 	   )
7280 	{
7281 	   SCIP_CONSDATA* consdata;
7282 	   SCIP_Real activity;
7283 	   SCIP_Real absviol;
7284 	   SCIP_Real relviol;
7285 	   SCIP_Real lhsviol;
7286 	   SCIP_Real rhsviol;
7287 	
7288 	   assert(scip != NULL);
7289 	   assert(cons != NULL);
7290 	   assert(violated != NULL);
7291 	
7292 	   SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
7293 	   SCIPdebugPrintCons(scip, cons, NULL);
7294 	
7295 	   consdata = SCIPconsGetData(cons);
7296 	   assert(consdata != NULL);
7297 	
7298 	   *violated = FALSE;
7299 	
7300 	   if( consdata->row != NULL )
7301 	   {
7302 	      if( !checklprows && SCIProwIsInLP(consdata->row) )
7303 	         return SCIP_OKAY;
7304 	      else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
7305 	         activity = consdataComputePseudoActivity(scip, consdata);
7306 	      else
7307 	         activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
7308 	   }
7309 	   else
7310 	      activity = consdataGetActivity(scip, consdata, sol);
7311 	
7312 	   SCIPdebugMsg(scip, "  consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
7313 	      activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
7314 	      consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
7315 	      consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
7316 	
7317 	   /* calculate absolute and relative bound violations */
7318 	   lhsviol = consdata->lhs - activity;
7319 	   rhsviol = activity - consdata->rhs;
7320 	
7321 	   absviol = 0.0;
7322 	   relviol = 0.0;
7323 	   if( (lhsviol > 0) && (lhsviol > rhsviol) )
7324 	   {
7325 	      absviol = lhsviol;
7326 	      relviol = SCIPrelDiff(consdata->lhs, activity);
7327 	   }
7328 	   else if( rhsviol > 0 )
7329 	   {
7330 	      absviol = rhsviol;
7331 	      relviol = SCIPrelDiff(activity, consdata->rhs);
7332 	   }
7333 	
7334 	   /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
7335 	    * return infeasible for safety
7336 	    */
7337 	   if( activity == SCIP_INVALID ) /*lint !e777*/
7338 	   {
7339 	      assert(sol == NULL);
7340 	      *violated = TRUE;
7341 	
7342 	      /* set violation of invalid pseudo solutions */
7343 	      absviol = SCIP_INVALID;
7344 	      relviol = SCIP_INVALID;
7345 	
7346 	      /* reset constraint age since we are in enforcement */
7347 	      SCIP_CALL( SCIPresetConsAge(scip, cons) );
7348 	   }
7349 	   /* check with relative tolerances (the default) */
7350 	   else if( !consdata->checkabsolute && (SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs)) )
7351 	   {
7352 	      /* the "normal" check: one of the two sides is violated */
7353 	      if( !checkrelmaxabs )
7354 	      {
7355 	         *violated = TRUE;
7356 	
7357 	         /* only reset constraint age if we are in enforcement */
7358 	         if( sol == NULL )
7359 	         {
7360 	            SCIP_CALL( SCIPresetConsAge(scip, cons) );
7361 	         }
7362 	      }
7363 	      /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7364 	       * small compared to the absolute values occurring in the activity
7365 	       */
7366 	      else
7367 	      {
7368 	         SCIP_Real maxabs;
7369 	         SCIP_Real coef;
7370 	         SCIP_Real absval;
7371 	         SCIP_Real solval;
7372 	         int v;
7373 	
7374 	         maxabs = 1.0;
7375 	
7376 	         /* compute maximum absolute value */
7377 	         for( v = 0; v < consdata->nvars; ++v )
7378 	         {
7379 	            if( consdata->vals != NULL )
7380 	            {
7381 	               coef = consdata->vals[v];
7382 	            }
7383 	            else
7384 	               coef = 1.0;
7385 	
7386 	            solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7387 	            absval = REALABS( coef * solval );
7388 	            maxabs = MAX( maxabs, absval );
7389 	         }
7390 	
7391 	         /* regard left hand side, first */
7392 	         if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7393 	         {
7394 	            /* check whether violation is random noise */
7395 	            if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7396 	            {
7397 	               SCIPdebugMsg(scip, "  lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7398 	                  consdata->lhs - activity, maxabs);
7399 	               SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7400 	
7401 	               /* only increase constraint age if we are in enforcement */
7402 	               if( sol == NULL )
7403 	               {
7404 	                  SCIP_CALL( SCIPincConsAge(scip, cons) );
7405 	               }
7406 	            }
7407 	            /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7408 	            else if( SCIPisZero(scip, consdata->lhs) )
7409 	            {
7410 	               if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7411 	               {
7412 	                  SCIPdebugMsg(scip, "  lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7413 	                     consdata->lhs - activity, maxabs);
7414 	                  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7415 	
7416 	                  /* only increase constraint age if we are in enforcement */
7417 	                  if( sol == NULL )
7418 	                  {
7419 	                     SCIP_CALL( SCIPincConsAge(scip, cons) );
7420 	                  }
7421 	               }
7422 	               else
7423 	               {
7424 	                  *violated = TRUE;
7425 	
7426 	                  /* only reset constraint age if we are in enforcement */
7427 	                  if( sol == NULL )
7428 	                  {
7429 	                     SCIP_CALL( SCIPresetConsAge(scip, cons) );
7430 	                  }
7431 	               }
7432 	            }
7433 	            else
7434 	            {
7435 	               *violated = TRUE;
7436 	
7437 	               /* only reset constraint age if we are in enforcement */
7438 	               if( sol == NULL )
7439 	               {
7440 	                  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7441 	               }
7442 	            }
7443 	         }
7444 	
7445 	         /* now regard right hand side */
7446 	         if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7447 	         {
7448 	            /* check whether violation is random noise */
7449 	            if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7450 	            {
7451 	               SCIPdebugMsg(scip, "  rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7452 	                  activity - consdata->rhs, maxabs);
7453 	               SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7454 	
7455 	               /* only increase constraint age if we are in enforcement */
7456 	               if( sol == NULL )
7457 	               {
7458 	                  SCIP_CALL( SCIPincConsAge(scip, cons) );
7459 	               }
7460 	            }
7461 	            /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7462 	            else if( SCIPisZero(scip, consdata->rhs) )
7463 	            {
7464 	               if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7465 	               {
7466 	                  SCIPdebugMsg(scip, "  rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7467 	                     activity - consdata->rhs, maxabs);
7468 	                  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7469 	
7470 	                  /* only increase constraint age if we are in enforcement */
7471 	                  if( sol == NULL )
7472 	                  {
7473 	                     SCIP_CALL( SCIPincConsAge(scip, cons) );
7474 	                  }
7475 	               }
7476 	               else
7477 	               {
7478 	                  *violated = TRUE;
7479 	
7480 	                  /* only reset constraint age if we are in enforcement */
7481 	                  if( sol == NULL )
7482 	                  {
7483 	                     SCIP_CALL( SCIPresetConsAge(scip, cons) );
7484 	                  }
7485 	               }
7486 	            }
7487 	            else
7488 	            {
7489 	               *violated = TRUE;
7490 	
7491 	               /* only reset constraint age if we are in enforcement */
7492 	               if( sol == NULL )
7493 	               {
7494 	                  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7495 	               }
7496 	            }
7497 	         }
7498 	      }
7499 	   }
7500 	   /* check with absolute tolerances */
7501 	   else if( consdata->checkabsolute &&
7502 	      ((!SCIPisInfinity(scip, -consdata->lhs) && SCIPisGT(scip, consdata->lhs-activity, SCIPfeastol(scip))) ||
7503 	       (!SCIPisInfinity(scip,  consdata->rhs) && SCIPisGT(scip, activity-consdata->rhs, SCIPfeastol(scip)))) )
7504 	   {
7505 	      *violated = TRUE;
7506 	
7507 	      /* only reset constraint age if we are in enforcement */
7508 	      if( sol == NULL )
7509 	      {
7510 	         SCIP_CALL( SCIPresetConsAge(scip, cons) );
7511 	      }
7512 	   }
7513 	   else
7514 	   {
7515 	      /* only increase constraint age if we are in enforcement */
7516 	      if( sol == NULL )
7517 	      {
7518 	         SCIP_CALL( SCIPincConsAge(scip, cons) );
7519 	      }
7520 	   }
7521 	
7522 	   /* update absolute and relative violation of the solution */
7523 	   if( sol != NULL )
7524 	      SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
7525 	
7526 	   return SCIP_OKAY;
7527 	}
7528 	
7529 	/** creates an LP row in a linear constraint data */
7530 	static
7531 	SCIP_RETCODE createRow(
7532 	   SCIP*                 scip,               /**< SCIP data structure */
7533 	   SCIP_CONS*            cons                /**< linear constraint */
7534 	   )
7535 	{
7536 	   SCIP_CONSDATA* consdata;
7537 	
7538 	   assert(scip != NULL);
7539 	   assert(cons != NULL);
7540 	
7541 	   consdata = SCIPconsGetData(cons);
7542 	   assert(consdata != NULL);
7543 	   assert(consdata->row == NULL);
7544 	
7545 	   SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7546 	         SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons), SCIPconsIsRemovable(cons)) );
7547 	
7548 	   SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7549 	
7550 	   return SCIP_OKAY;
7551 	}
7552 	
7553 	/** adds linear constraint as cut to the LP */
7554 	static
7555 	SCIP_RETCODE addRelaxation(
7556 	   SCIP*                 scip,               /**< SCIP data structure */
7557 	   SCIP_CONS*            cons,               /**< linear constraint */
7558 	   SCIP_Bool*            cutoff              /**< pointer to store whether a cutoff was found */
7559 	   )
7560 	{
7561 	   SCIP_CONSDATA* consdata;
7562 	
7563 	   assert(scip != NULL);
7564 	   assert(cons != NULL);
7565 	
7566 	   consdata = SCIPconsGetData(cons);
7567 	   assert(consdata != NULL);
7568 	
7569 	   if( consdata->row == NULL )
7570 	   {
7571 	      if( !SCIPconsIsModifiable(cons) )
7572 	      {
7573 	         /* replace all fixed variables by active counterparts, as we have no chance to do this anymore after the row has been added to the LP
7574 	          * removing this here will make test cons/linear/fixedvar.c fail (as of 2018-12-03)
7575 	          */
7576 	         SCIP_CALL( applyFixings(scip, cons, cutoff) );
7577 	         if( *cutoff )
7578 	            return SCIP_OKAY;
7579 	      }
7580 	
7581 	      /* convert consdata object into LP row */
7582 	      SCIP_CALL( createRow(scip, cons) );
7583 	   }
7584 	   assert(consdata->row != NULL);
7585 	
7586 	   if( consdata->nvars == 0 )
7587 	   {
7588 	      SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
7589 	   }
7590 	
7591 	   /* insert LP row as cut */
7592 	   if( !SCIProwIsInLP(consdata->row) )
7593 	   {
7594 	      SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7595 	      SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7596 	      /* if presolving is turned off, the row might be trivial */
7597 	      if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7598 	      {
7599 	         SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
7600 	      }
7601 	#ifndef NDEBUG
7602 	      else
7603 	      {
7604 	         int pr;
7605 	         int cr;
7606 	         SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7607 	         SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7608 	         assert( pr == 0 || cr == 0 );
7609 	      }
7610 	#endif
7611 	   }
7612 	
7613 	   return SCIP_OKAY;
7614 	}
7615 	
7616 	/** adds linear constraint as row to the NLP, if not added yet */
7617 	static
7618 	SCIP_RETCODE addNlrow(
7619 	   SCIP*                 scip,               /**< SCIP data structure */
7620 	   SCIP_CONS*            cons                /**< linear constraint */
7621 	   )
7622 	{
7623 	   SCIP_CONSDATA* consdata;
7624 	
7625 	   assert(SCIPisNLPConstructed(scip));
7626 	
7627 	   /* skip deactivated, redundant, or local linear constraints (the NLP does not allow for local rows at the moment) */
7628 	   if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
7629 	      return SCIP_OKAY;
7630 	
7631 	   consdata = SCIPconsGetData(cons);
7632 	   assert(consdata != NULL);
7633 	
7634 	   if( consdata->nlrow == NULL )
7635 	   {
7636 	      assert(consdata->lhs <= consdata->rhs);
7637 	
7638 	      SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
7639 	         0.0, consdata->nvars, consdata->vars, consdata->vals, NULL, consdata->lhs, consdata->rhs, SCIP_EXPRCURV_LINEAR) );
7640 	
7641 	      assert(consdata->nlrow != NULL);
7642 	   }
7643 	
7644 	   if( !SCIPnlrowIsInNLP(consdata->nlrow) )
7645 	   {
7646 	      SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
7647 	   }
7648 	
7649 	   return SCIP_OKAY;
7650 	}
7651 	
7652 	/** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7653 	static
7654 	SCIP_RETCODE separateCons(
7655 	   SCIP*                 scip,               /**< SCIP data structure */
7656 	   SCIP_CONS*            cons,               /**< linear constraint */
7657 	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< constraint handler data */
7658 	   SCIP_SOL*             sol,                /**< primal CIP solution, NULL for current LP solution */
7659 	   SCIP_Bool             separatecards,      /**< should knapsack cardinality cuts be generated? */
7660 	   SCIP_Bool             separateall,        /**< should all constraints be subject to cardinality cut generation instead of only
7661 	                                              *   the ones with non-zero dual value? */
7662 	   int*                  ncuts,              /**< pointer to add up the number of found cuts */
7663 	   SCIP_Bool*            cutoff              /**< pointer to store whether a cutoff was found */
7664 	   )
7665 	{
7666 	   SCIP_CONSDATA* consdata;
7667 	   SCIP_Bool violated;
7668 	   int oldncuts;
7669 	
7670 	   assert(scip != NULL);
7671 	   assert(conshdlrdata != NULL);
7672 	   assert(cons != NULL);
7673 	   assert(cutoff != NULL);
7674 	
7675 	   consdata = SCIPconsGetData(cons);
7676 	   assert(ncuts != NULL);
7677 	   assert(consdata != NULL);
7678 	
7679 	   oldncuts = *ncuts;
7680 	   *cutoff = FALSE;
7681 	
7682 	   SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7683 	
7684 	   if( violated )
7685 	   {
7686 	      /* insert LP row as cut */
7687 	      SCIP_CALL( addRelaxation(scip, cons, cutoff) );
7688 	      (*ncuts)++;
7689 	   }
7690 	   else if( !SCIPconsIsModifiable(cons) && separatecards )
7691 	   {
7692 	      /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7693 	      if( !separateall && sol == NULL )
7694 	      {
7695 	         /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7696 	         if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7697 	         {
7698 	            SCIP_Real dualsol;
7699 	
7700 	            dualsol = SCIProwGetDualsol(consdata->row);
7701 	            if( SCIPisFeasNegative(scip, dualsol) )
7702 	            {
7703 	               if( !SCIPisInfinity(scip, consdata->rhs) )
7704 	               {
7705 	                  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7706 	                        consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7707 	               }
7708 	            }
7709 	            else if( SCIPisFeasPositive(scip, dualsol) )
7710 	            {
7711 	               if( !SCIPisInfinity(scip, -consdata->lhs) )
7712 	               {
7713 	                  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7714 	                        consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7715 	               }
7716 	            }
7717 	         }
7718 	      }
7719 	      else
7720 	      {
7721 	         if( !SCIPisInfinity(scip, consdata->rhs) )
7722 	         {
7723 	            SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7724 	                  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7725 	         }
7726 	         if( !SCIPisInfinity(scip, -consdata->lhs) )
7727 	         {
7728 	            SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7729 	                  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7730 	         }
7731 	      }
7732 	   }
7733 	
7734 	   if( *ncuts > oldncuts )
7735 	   {
7736 	      SCIP_CALL( SCIPresetConsAge(scip, cons) );
7737 	   }
7738 	
7739 	   return SCIP_OKAY;
7740 	}
7741 	
7742 	/** propagation method for linear constraints */
7743 	static
7744 	SCIP_RETCODE propagateCons(
7745 	   SCIP*                 scip,               /**< SCIP data structure */
7746 	   SCIP_CONS*            cons,               /**< linear constraint */
7747 	   SCIP_Bool             tightenbounds,      /**< should the variable's bounds be tightened? */
7748 	   SCIP_Bool             rangedrowpropagation,/**< should ranged row propagation be performed? */
7749 	   SCIP_Real             maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7750 	   SCIP_Bool             sortvars,           /**< should variable sorting for faster propagation be used? */
7751 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the node can be cut off */
7752 	   int*                  nchgbds             /**< pointer to count the total number of tightened bounds */
7753 	   )
7754 	{
7755 	   SCIP_CONSDATA* consdata;
7756 	   SCIP_Real minactivity;
7757 	   SCIP_Real maxactivity;
7758 	   SCIP_Bool minactisrelax;
7759 	   SCIP_Bool maxactisrelax;
7760 	   SCIP_Bool isminsettoinfinity;
7761 	   SCIP_Bool ismaxsettoinfinity;
7762 	
7763 	   assert(scip != NULL);
7764 	   assert(cons != NULL);
7765 	   assert(cutoff != NULL);
7766 	   assert(nchgbds != NULL);
7767 	
7768 	   /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7769 	
7770 	   consdata = SCIPconsGetData(cons);
7771 	   assert(consdata != NULL);
7772 	
7773 	   if( consdata->eventdata == NULL )
7774 	   {
7775 	      SCIP_CONSHDLR* conshdlr;
7776 	      SCIP_CONSHDLRDATA* conshdlrdata;
7777 	
7778 	      conshdlr = SCIPconsGetHdlr(cons);
7779 	      assert(conshdlr != NULL);
7780 	
7781 	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
7782 	      assert(conshdlrdata != NULL);
7783 	
7784 	      /* catch bound change events of variables */
7785 	      SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
7786 	      assert(consdata->eventdata != NULL);
7787 	   }
7788 	
7789 	   *cutoff = FALSE;
7790 	
7791 	   /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7792 	   if( !SCIPconsIsModifiable(cons) )
7793 	   {
7794 	      /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7795 	      if( !SCIPinRepropagation(scip) )
7796 	      {
7797 	         SCIP_CALL( SCIPincConsAge(scip, cons) );
7798 	      }
7799 	
7800 	      /* tighten the variable's bounds */
7801 	      if( tightenbounds )
7802 	      {
7803 	         int oldnchgbds;
7804 	
7805 	         oldnchgbds = *nchgbds;
7806 	
7807 	         SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7808 	
7809 	         if( *nchgbds > oldnchgbds )
7810 	         {
7811 	            SCIP_CALL( SCIPresetConsAge(scip, cons) );
7812 	         }
7813 	      }
7814 	
7815 	      /* propagate ranged rows */
7816 	      if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7817 	      {
7818 	         int nfixedvars;
7819 	         int naddconss;
7820 	         SCIPdebug( int oldnchgbds = *nchgbds; )
7821 	
7822 	         nfixedvars = 0;
7823 	         naddconss = 0;
7824 	
7825 	         SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7826 	
7827 	         if( *cutoff )
7828 	         {
7829 	            SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7830 	         }
7831 	         else
7832 	         {
7833 	            SCIPdebug( SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars); )
7834 	         }
7835 	
7836 	         if( nfixedvars > 0 )
7837 	            *nchgbds += 2*nfixedvars;
7838 	      } /*lint !e438*/
7839 	
7840 	      /* check constraint for infeasibility and redundancy */
7841 	      if( !(*cutoff) )
7842 	      {
7843 	         consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
7844 	            &isminsettoinfinity, &ismaxsettoinfinity);
7845 	
7846 	         if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7847 	         {
7848 	            SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7849 	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7850 	
7851 	            /* analyze conflict */
7852 	            SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7853 	
7854 	            SCIP_CALL( SCIPresetConsAge(scip, cons) );
7855 	            *cutoff = TRUE;
7856 	         }
7857 	         else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7858 	         {
7859 	            SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7860 	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7861 	
7862 	            /* analyze conflict */
7863 	            SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7864 	
7865 	            SCIP_CALL( SCIPresetConsAge(scip, cons) );
7866 	            *cutoff = TRUE;
7867 	         }
7868 	         else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7869 	         {
7870 	            SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7871 	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7872 	
7873 	            /* remove the constraint locally unless it has become empty, in which case it is removed globally */
7874 	            if( consdata->nvars > 0 )
7875 	               SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7876 	            else
7877 	               SCIP_CALL( SCIPdelCons(scip, cons) );
7878 	         }
7879 	      }
7880 	   }
7881 	
7882 	   return SCIP_OKAY;
7883 	}
7884 	
7885 	
7886 	/*
7887 	 * Presolving methods
7888 	 */
7889 	
7890 	/** converts all variables with fixed domain into FIXED variables */
7891 	static
7892 	SCIP_RETCODE fixVariables(
7893 	   SCIP*                 scip,               /**< SCIP data structure */
7894 	   SCIP_CONS*            cons,               /**< linear constraint */
7895 	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
7896 	   int*                  nfixedvars          /**< pointer to count the total number of fixed variables */
7897 	   )
7898 	{
7899 	   SCIP_CONSDATA* consdata;
7900 	   SCIP_VAR* var;
7901 	   SCIP_VARSTATUS varstatus;
7902 	   SCIP_Real lb;
7903 	   SCIP_Real ub;
7904 	   SCIP_Bool fixed;
7905 	   SCIP_Bool infeasible;
7906 	   int v;
7907 	
7908 	   assert(scip != NULL);
7909 	   assert(cons != NULL);
7910 	   assert(cutoff != NULL);
7911 	   assert(nfixedvars != NULL);
7912 	
7913 	   consdata = SCIPconsGetData(cons);
7914 	   assert(consdata != NULL);
7915 	
7916 	   for( v = 0; v < consdata->nvars; ++v )
7917 	   {
7918 	      assert(consdata->vars != NULL);
7919 	      var = consdata->vars[v];
7920 	      varstatus = SCIPvarGetStatus(var);
7921 	
7922 	      if( varstatus != SCIP_VARSTATUS_FIXED )
7923 	      {
7924 	         lb = SCIPvarGetLbGlobal(var);
7925 	         ub = SCIPvarGetUbGlobal(var);
7926 	         if( SCIPisEQ(scip, lb, ub) )
7927 	         {
7928 	            SCIP_Real fixval;
7929 	
7930 	            fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7931 	            SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7932 	               SCIPvarGetName(var), lb, ub, fixval);
7933 	            SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7934 	            if( infeasible )
7935 	            {
7936 	               SCIPdebugMsg(scip, " -> infeasible fixing\n");
7937 	               *cutoff = TRUE;
7938 	               return SCIP_OKAY;
7939 	            }
7940 	            if( fixed )
7941 	               (*nfixedvars)++;
7942 	         }
7943 	      }
7944 	   }
7945 	
7946 	   SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7947 	
7948 	   if( infeasible )
7949 	   {
7950 	      SCIPdebugMsg(scip, " -> infeasible fixing\n");
7951 	      *cutoff = TRUE;
7952 	      return SCIP_OKAY;
7953 	   }
7954 	
7955 	   assert(consdata->removedfixings);
7956 	
7957 	   return SCIP_OKAY;
7958 	}
7959 	
7960 	#define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7961 	
7962 	/** extracts cliques of the constraint and adds them to SCIP
7963 	 *
7964 	 *  The following clique extraction mechanism are implemeneted
7965 	 *
7966 	 *  1. collect binary variables and sort them in non increasing order, then
7967 	 *
7968 	 *     a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7969 	 *        then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7970 	 *        condition
7971 	 *
7972 	 *            minactivity + vals[i] + vals[i+1] > rhs
7973 	 *
7974 	 *        and also add the binary to binary implication also for non-successive variables for which the same argument
7975 	 *        holds
7976 	 *
7977 	 *            minactivity + vals[i] + vals[j] > rhs
7978 	 *
7979 	 *        e.g. 5.3 x1 + 3.6 x2 + 3.3 x3 + 2.1 x4 <= 5.5 (all x are binary) would lead to the clique (x1, x2, x3) and the
7980 	 *             binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7981 	 *
7982 	 *     b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7983 	 *        then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7984 	 *        condition
7985 	 *
7986 	 *            maxactivity + vals[i] + vals[i-1] < lhs
7987 	 *
7988 	 *        and also add the binary to binary implication also for non-successive variables for which the same argument
7989 	 *        holds
7990 	 *
7991 	 *            maxactivity + vals[i] + vals[j] < lhs
7992 	 *
7993 	 *        e.g. you could multiply the above example by -1
7994 	 *
7995 	 *     c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7996 	 *        clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7997 	 *        condition
7998 	 *
7999 	 *            minactivity - vals[i] - vals[i-1] > rhs
8000 	 *
8001 	 *        and also add the binary to binary implication also for non-successive variables for which the
8002 	 *        same argument holds
8003 	 *
8004 	 *            minactivity - vals[i] - vals[j] > rhs
8005 	 *
8006 	 *        e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
8007 	 *             implication x1 = 0 => x3 = 1
8008 	 *
8009 	 *     d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
8010 	 *        clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
8011 	 *        condition
8012 	 *
8013 	 *            maxactivity - vals[i] - vals[i+1] < lhs
8014 	 *
8015 	 *        and also add the binary to binary implication also for non-successive variables for which the same argument
8016 	 *        holds
8017 	 *
8018 	 *            maxactivity - vals[i] - vals[j] < lhs
8019 	 *
8020 	 *        e.g. you could multiply the above example by -1
8021 	 *
8022 	 *  2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
8023 	 *     as clique, (this part is done at the end of the method)
8024 	 *
8025 	 */
8026 	static
8027 	SCIP_RETCODE extractCliques(
8028 	   SCIP*                 scip,               /**< SCIP data structure */
8029 	   SCIP_CONS*            cons,               /**< linear constraint */
8030 	   SCIP_Real             maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
8031 	   SCIP_Bool             sortvars,           /**< should variables be used in sorted order? */
8032 	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
8033 	   int*                  nchgbds,            /**< pointer to count the total number of tightened bounds */
8034 	   SCIP_Bool*            cutoff              /**< pointer to store TRUE, if a cutoff was found */
8035 	   )
8036 	{
8037 	   SCIP_VAR** vars;
8038 	   SCIP_Real* vals;
8039 	   SCIP_CONSDATA* consdata;
8040 	   SCIP_Bool lhsclique;
8041 	   SCIP_Bool rhsclique;
8042 	   SCIP_Bool finitelhs;
8043 	   SCIP_Bool finiterhs;
8044 	   SCIP_Bool finiteminact;
8045 	   SCIP_Bool finitemaxact;
8046 	   SCIP_Bool finitenegminact;
8047 	   SCIP_Bool finitenegmaxact;
8048 	   SCIP_Bool finiteposminact;
8049 	   SCIP_Bool finiteposmaxact;
8050 	   SCIP_Bool infeasible;
8051 	   SCIP_Bool stopped;
8052 	   int cliquenonzerosadded;
8053 	   int v;
8054 	   int i;
8055 	   int nposcoefs;
8056 	   int nnegcoefs;
8057 	   int nvars;
8058 	
8059 	   assert(scip != NULL);
8060 	   assert(cons != NULL);
8061 	   assert(nfixedvars != NULL);
8062 	   assert(nchgbds != NULL);
8063 	   assert(cutoff != NULL);
8064 	   assert(!SCIPconsIsDeleted(cons));
8065 	
8066 	   consdata = SCIPconsGetData(cons);
8067 	   assert(consdata != NULL);
8068 	
8069 	   if( consdata->nvars < 2 )
8070 	      return SCIP_OKAY;
8071 	
8072 	   /* add implications if possible
8073 	    *
8074 	    * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
8075 	    * maximal absolute contribution and also only if this variable would force all other variables to their bound
8076 	    * corresponding to the global minimal activity of the constraint
8077 	    */
8078 	   if( !consdata->implsadded )
8079 	   {
8080 	      /* sort variables by variable type */
8081 	      SCIP_CALL( consdataSort(scip, consdata) );
8082 	
8083 	      /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
8084 	       *       up front, might change sorting correspondingly
8085 	       */
8086 	      /* fast abort if no binaries seem to exist
8087 	       * "seem to", because there are rare situations in which variables may actually not be sorted by type, even though consdataSort has been called
8088 	       * this situation can occur if, e.g., the type of consdata->vars[1] has been changed to binary, but the corresponding variable event has
8089 	       * not been executed yet, because it is the eventExecLinear() which marks the variables array as unsorted (set consdata->indexsorted to FALSE),
8090 	       * which is the requirement for consdataSort() to actually resort the variables
8091 	       * we assume that in this situation the below code may be executed in a future presolve round, after the variable events have been executed
8092 	       */
8093 	      if( !SCIPvarIsBinary(consdata->vars[0]) )
8094 	         return SCIP_OKAY;
8095 	
8096 	      nvars = consdata->nvars;
8097 	      vars = consdata->vars;
8098 	      vals = consdata->vals;
8099 	
8100 	      /* recompute activities if needed */
8101 	      if( !consdata->validactivities )
8102 	         consdataCalcActivities(scip, consdata);
8103 	      assert(consdata->validactivities);
8104 	
8105 	      finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8106 	      finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8107 	      finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8108 	      finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8109 	      finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8110 	      finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8111 	      finiteminact = (finitenegminact && finiteposminact);
8112 	      finitemaxact = (finitenegmaxact && finiteposmaxact);
8113 	
8114 	      if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8115 	      {
8116 	         SCIP_Real maxabscontrib = -1.0;
8117 	         SCIP_Bool posval = FALSE;
8118 	         SCIP_Bool allbinary = TRUE;
8119 	         int oldnchgbds = *nchgbds;
8120 	         int nbdchgs = 0;
8121 	         int nimpls = 0;
8122 	         int position = -1;
8123 	
8124 	         /* we need a valid minimal/maximal activity to add cliques */
8125 	         if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8126 	         {
8127 	            consdataRecomputeGlbMinactivity(scip, consdata);
8128 	            assert(consdata->validglbminact);
8129 	         }
8130 	
8131 	         if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8132 	         {
8133 	            consdataRecomputeGlbMaxactivity(scip, consdata);
8134 	            assert(consdata->validglbmaxact);
8135 	         }
8136 	         assert(consdata->validglbminact || consdata->validglbmaxact);
8137 	
8138 	         /* @todo extend this to local/constraint probing */
8139 	
8140 	         /* determine maximal contribution to the activity */
8141 	         for( v = nvars - 1; v >= 0; --v )
8142 	         {
8143 	            if( SCIPvarIsBinary(vars[v]) )
8144 	            {
8145 	               if( vals[v] > 0 )
8146 	               {
8147 	                  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
8148 	
8149 	                  if( value > maxabscontrib )
8150 	                  {
8151 	                     maxabscontrib = value;
8152 	                     position = v;
8153 	                     posval = TRUE;
8154 	                  }
8155 	               }
8156 	               else
8157 	               {
8158 	                  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
8159 	
8160 	                  value = REALABS(value);
8161 	
8162 	                  if( value > maxabscontrib )
8163 	                  {
8164 	                     maxabscontrib = value;
8165 	                     position = v;
8166 	                     posval = FALSE;
8167 	                  }
8168 	               }
8169 	            }
8170 	            else
8171 	               allbinary = FALSE;
8172 	         }
8173 	         assert(0 <= position && position < nvars);
8174 	
8175 	         if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
8176 	         {
8177 	            /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
8178 	             * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8179 	             * implications
8180 	             */
8181 	            if( finiterhs && finiteminact && SCIPisEQ(scip, QUAD_TO_DBL(consdata->glbminactivity), consdata->rhs - maxabscontrib) )
8182 	            {
8183 	               for( v = nvars - 1; v >= 0; --v )
8184 	               {
8185 	                  /* binary to binary implications will be collected when extrating cliques */
8186 	                  if( !SCIPvarIsBinary(vars[v]) )
8187 	                  {
8188 	                     if( v != position )
8189 	                     {
8190 	                        if( vals[v] > 0 )
8191 	                        {
8192 	                           /* add implications */
8193 	                           SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8194 	                           ++nimpls;
8195 	                           *nchgbds += nbdchgs;
8196 	                        }
8197 	                        else
8198 	                        {
8199 	                           /* add implications */
8200 	                           SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8201 	                           ++nimpls;
8202 	                           *nchgbds += nbdchgs;
8203 	                        }
8204 	
8205 	                        if( infeasible )
8206 	                        {
8207 	                           *cutoff = TRUE;
8208 	                           break;
8209 	                        }
8210 	                     }
8211 	                  }
8212 	                  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8213 	                  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8214 	                     break;
8215 	               }
8216 	            }
8217 	
8218 	            /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
8219 	             * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8220 	             * implications
8221 	             */
8222 	            if( finitelhs && finitemaxact && SCIPisEQ(scip, QUAD_TO_DBL(consdata->glbmaxactivity), consdata->lhs - maxabscontrib) )
8223 	            {
8224 	               for( v = nvars - 1; v >= 0; --v )
8225 	               {
8226 	                  /* binary to binary implications will be collected when extrating cliques */
8227 	                  if( !SCIPvarIsBinary(vars[v]) )
8228 	                  {
8229 	                     if( v != position )
8230 	                     {
8231 	                        if( vals[v] > 0 )
8232 	                        {
8233 	                           /* add implications */
8234 	                           SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8235 	                           ++nimpls;
8236 	                           *nchgbds += nbdchgs;
8237 	                        }
8238 	                        else
8239 	                        {
8240 	                           /* add implications */
8241 	                           SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8242 	                           ++nimpls;
8243 	                           *nchgbds += nbdchgs;
8244 	                        }
8245 	
8246 	                        if( infeasible )
8247 	                        {
8248 	                           *cutoff = TRUE;
8249 	                           break;
8250 	                        }
8251 	                     }
8252 	                  }
8253 	                  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8254 	                  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8255 	                     break;
8256 	               }
8257 	            }
8258 	
8259 	            /* did we find some implications */
8260 	            if( nimpls > 0 )
8261 	            {
8262 	               SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
8263 	
8264 	               if( *cutoff )
8265 	                  return SCIP_OKAY;
8266 	
8267 	               /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8268 	               if( *nchgbds - oldnchgbds > 0 )
8269 	               {
8270 	                  /* check for fixed variables */
8271 	                  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8272 	                  if( *cutoff )
8273 	                     return SCIP_OKAY;
8274 	
8275 	                  /* tighten variable's bounds */
8276 	                  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8277 	                  if( *cutoff )
8278 	                     return SCIP_OKAY;
8279 	
8280 	                  /* check for fixed variables */
8281 	                  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8282 	                  if( *cutoff )
8283 	                     return SCIP_OKAY;
8284 	               }
8285 	            }
8286 	         }
8287 	      }
8288 	
8289 	      consdata->implsadded = TRUE;
8290 	   }
8291 	
8292 	   /* check if we already added the cliques of this constraint */
8293 	   if( consdata->cliquesadded )
8294 	      return SCIP_OKAY;
8295 	
8296 	   consdata->cliquesadded = TRUE;
8297 	   cliquenonzerosadded = 0;
8298 	   stopped = FALSE;
8299 	
8300 	   /* sort variables by variable type */
8301 	   SCIP_CALL( consdataSort(scip, consdata) );
8302 	
8303 	   nvars = consdata->nvars;
8304 	   vars = consdata->vars;
8305 	   vals = consdata->vals;
8306 	
8307 	   /**@todo extract more cliques, implications and variable bounds from linear constraints */
8308 	
8309 	   /* recompute activities if needed */
8310 	   if( !consdata->validactivities )
8311 	      consdataCalcActivities(scip, consdata);
8312 	   assert(consdata->validactivities);
8313 	
8314 	   finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8315 	   finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8316 	   finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8317 	   finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8318 	   finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8319 	   finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8320 	   finiteminact = (finitenegminact && finiteposminact);
8321 	   finitemaxact = (finitenegmaxact && finiteposmaxact);
8322 	
8323 	   /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
8324 	    *    information
8325 	    */
8326 	   if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8327 	   {
8328 	      SCIP_VAR** binvars;
8329 	      SCIP_Real* binvarvals;
8330 	      int nposbinvars = 0;
8331 	      int nnegbinvars = 0;
8332 	      int allonebinary = 0;
8333 	
8334 	      SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
8335 	      SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
8336 	
8337 	      /* collect binary variables */
8338 	      for( i = 0; i < nvars; ++i )
8339 	      {
8340 	         if( SCIPvarIsBinary(vars[i]) )
8341 	         {
8342 	            assert(!SCIPisZero(scip, vals[i]));
8343 	
8344 	            if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8345 	               ++allonebinary;
8346 	
8347 	            binvars[nposbinvars + nnegbinvars] = vars[i];
8348 	            binvarvals[nposbinvars + nnegbinvars] = vals[i];
8349 	
8350 	            if( SCIPisPositive(scip, vals[i]) )
8351 	               ++nposbinvars;
8352 	            else
8353 	               ++nnegbinvars;
8354 	
8355 	            assert(nposbinvars + nnegbinvars <= nvars);
8356 	         }
8357 	         /* stop searching for binary variables, because the constraint data is sorted */
8358 	         else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8359 	            break;
8360 	      }
8361 	      assert(nposbinvars + nnegbinvars <= nvars);
8362 	
8363 	      /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
8364 	       * cliques
8365 	       */
8366 	      if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
8367 	      {
8368 	         SCIP_Real threshold;
8369 	         int oldnchgbds = *nchgbds;
8370 	         int nbdchgs;
8371 	         int jstart;
8372 	         int j;
8373 	
8374 	         /* we need a valid minimal/maximal activity to add cliques */
8375 	         if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8376 	         {
8377 	            consdataRecomputeGlbMinactivity(scip, consdata);
8378 	            assert(consdata->validglbminact);
8379 	         }
8380 	
8381 	         if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8382 	         {
8383 	            consdataRecomputeGlbMaxactivity(scip, consdata);
8384 	            assert(consdata->validglbmaxact);
8385 	         }
8386 	         assert(consdata->validglbminact || consdata->validglbmaxact);
8387 	
8388 	         /* sort coefficients non-increasing to be faster in the clique search */
8389 	         SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
8390 	
8391 	         /* case a) */
8392 	         if( finiterhs && finitenegminact && nposbinvars >= 2 )
8393 	         {
8394 	            /* compute value that needs to be exceeded */
8395 	            threshold = consdata->rhs - QUAD_TO_DBL(consdata->glbminactivity);
8396 	
8397 	            j = 1;
8398 	#ifdef SCIP_DISABLED_CODE /* assertion should only hold when constraints were fully propagated and boundstightened */
8399 	            /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8400 	            assert(SCIPisFeasLE(scip, binvarvals[0], threshold));
8401 	#endif
8402 	            /* check if at least two variables are in a clique */
8403 	            if( SCIPisFeasGT(scip, binvarvals[0] + binvarvals[j], threshold) )
8404 	            {
8405 	               ++j;
8406 	               /* check for extending the clique */
8407 	               while( j < nposbinvars )
8408 	               {
8409 	                  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
8410 	                     break;
8411 	                  ++j;
8412 	               }
8413 	               assert(j >= 2);
8414 	
8415 	               /* add clique with at least two variables */
8416 	               SCIP_CALL( SCIPaddClique(scip, binvars, NULL, j, FALSE, &infeasible, &nbdchgs) );
8417 	
8418 	               if( infeasible )
8419 	                  *cutoff = TRUE;
8420 	
8421 	               *nchgbds += nbdchgs;
8422 	
8423 	               cliquenonzerosadded += j;
8424 	               if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8425 	                  stopped = TRUE;
8426 	
8427 	               /* exchange the last variable in the clique if possible and add all new ones */
8428 	               if( !stopped && !(*cutoff) && j < nposbinvars )
8429 	               {
8430 	                  SCIP_VAR** clqvars;
8431 	                  int lastfit = j - 2;
8432 	                  assert(lastfit >= 0);
8433 	
8434 	                  /* copy all 'main'-clique variables */
8435 	                  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8436 	
8437 	                  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8438 	                  while( lastfit >= 0 && j < nposbinvars )
8439 	                  {
8440 	                     /* check if two variables are in a clique */
8441 	                     if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8442 	                     {
8443 	                        clqvars[lastfit + 1] = binvars[j];
8444 	
8445 	                        /* add clique with at least two variables */
8446 	                        SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8447 	
8448 	                        if( infeasible )
8449 	                        {
8450 	                           *cutoff = TRUE;
8451 	                           break;
8452 	                        }
8453 	
8454 	                        *nchgbds += nbdchgs;
8455 	
8456 	                        cliquenonzerosadded += (lastfit + 2);
8457 	                        if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8458 	                        {
8459 	                           stopped = TRUE;
8460 	                           break;
8461 	                        }
8462 	
8463 	                        ++j;
8464 	                     }
8465 	                     else
8466 	                        --lastfit;
8467 	                  }
8468 	
8469 	                  SCIPfreeBufferArray(scip, &clqvars);
8470 	               }
8471 	            }
8472 	         }
8473 	
8474 	         /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8475 	         if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8476 	         {
8477 	            /* check for fixed variables */
8478 	            SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8479 	
8480 	            if( !*cutoff )
8481 	            {
8482 	               /* tighten variable's bounds */
8483 	               SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8484 	
8485 	               if( !*cutoff )
8486 	               {
8487 	                  /* check for fixed variables */
8488 	                  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8489 	
8490 	                  if( !*cutoff )
8491 	                  {
8492 	                     /* sort variables by variable type */
8493 	                     SCIP_CALL( consdataSort(scip, consdata) );
8494 	
8495 	                     /* recompute activities if needed */
8496 	                     if( !consdata->validactivities )
8497 	                        consdataCalcActivities(scip, consdata);
8498 	                     assert(consdata->validactivities);
8499 	
8500 	                     nvars = consdata->nvars;
8501 	                     vars = consdata->vars;
8502 	                     vals = consdata->vals;
8503 	                     nposbinvars = 0;
8504 	                     nnegbinvars = 0;
8505 	                     allonebinary = 0;
8506 	
8507 	                     /* update binary variables */
8508 	                     for( i = 0; i < nvars; ++i )
8509 	                     {
8510 	                        if( SCIPvarIsBinary(vars[i]) )
8511 	                        {
8512 	                           assert(!SCIPisZero(scip, vals[i]));
8513 	
8514 	                           if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8515 	                              ++allonebinary;
8516 	
8517 	                           binvars[nposbinvars + nnegbinvars] = vars[i];
8518 	                           binvarvals[nposbinvars + nnegbinvars] = vals[i];
8519 	
8520 	                           if( SCIPisPositive(scip, vals[i]) )
8521 	                              ++nposbinvars;
8522 	                           else
8523 	                              ++nnegbinvars;
8524 	
8525 	                           assert(nposbinvars + nnegbinvars <= nvars);
8526 	                        }
8527 	                        /* stop searching for binary variables, because the constraint data is sorted */
8528 	                        else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8529 	                           break;
8530 	                     }
8531 	                     assert(nposbinvars + nnegbinvars <= nvars);
8532 	                  }
8533 	               }
8534 	            }
8535 	
8536 	            oldnchgbds = *nchgbds;
8537 	         }
8538 	
8539 	         /* case b) */
8540 	         if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8541 	         {
8542 	            /* compute value that needs to be deceeded */
8543 	            threshold = consdata->lhs - QUAD_TO_DBL(consdata->glbmaxactivity);
8544 	
8545 	            i = nposbinvars + nnegbinvars - 1;
8546 	            j = i - 1;
8547 	#if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8548 	            /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8549 	            assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8550 	#endif
8551 	            /* check if two variables are in a clique */
8552 	            if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8553 	            {
8554 	               --j;
8555 	               /* check for extending the clique */
8556 	               while( j >= nposbinvars )
8557 	               {
8558 	                  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8559 	                     break;
8560 	                  --j;
8561 	               }
8562 	               jstart = j;
8563 	
8564 	               assert(i - j >= 2);
8565 	               /* add clique with at least two variables */
8566 	               SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8567 	
8568 	               if( infeasible )
8569 	                  *cutoff = TRUE;
8570 	
8571 	               *nchgbds += nbdchgs;
8572 	
8573 	               cliquenonzerosadded += (i - j);
8574 	               if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8575 	                  stopped = TRUE;
8576 	
8577 	               /* exchange the last variable in the clique if possible and add all new ones */
8578 	               if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8579 	               {
8580 	                  SCIP_VAR** clqvars;
8581 	                  int lastfit = jstart + 1;
8582 	                  assert(lastfit < i);
8583 	
8584 	                  /* copy all 'main'-clique variables */
8585 	                  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8586 	                  ++lastfit;
8587 	
8588 	                  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8589 	                  while( lastfit <= i && j >= nposbinvars )
8590 	                  {
8591 	                     /* check if two variables are in a clique */
8592 	                     if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8593 	                     {
8594 	                        assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8595 	                        clqvars[lastfit - jstart - 2] = binvars[j];
8596 	
8597 	                        assert(i - lastfit + 2 >= 2);
8598 	                        /* add clique with at least two variables */
8599 	                        SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8600 	
8601 	                        if( infeasible )
8602 	                        {
8603 	                           *cutoff = TRUE;
8604 	                           break;
8605 	                        }
8606 	
8607 	                        *nchgbds += nbdchgs;
8608 	
8609 	                        cliquenonzerosadded += (i - lastfit + 2);
8610 	                        if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8611 	                        {
8612 	                           stopped = TRUE;
8613 	                           break;
8614 	                        }
8615 	
8616 	                        --j;
8617 	                     }
8618 	                     else
8619 	                        ++lastfit;
8620 	                  }
8621 	
8622 	                  SCIPfreeBufferArray(scip, &clqvars);
8623 	               }
8624 	            }
8625 	         }
8626 	
8627 	         /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8628 	         if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8629 	         {
8630 	            /* check for fixed variables */
8631 	            SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8632 	
8633 	            if( !*cutoff )
8634 	            {
8635 	               /* tighten variable's bounds */
8636 	               SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8637 	
8638 	               if( !*cutoff )
8639 	               {
8640 	                  /* check for fixed variables */
8641 	                  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8642 	
8643 	                  if( !*cutoff )
8644 	                  {
8645 	                     /* sort variables by variable type */
8646 	                     SCIP_CALL( consdataSort(scip, consdata) );
8647 	
8648 	                     /* recompute activities if needed */
8649 	                     if( !consdata->validactivities )
8650 	                        consdataCalcActivities(scip, consdata);
8651 	                     assert(consdata->validactivities);
8652 	
8653 	                     nvars = consdata->nvars;
8654 	                     vars = consdata->vars;
8655 	                     vals = consdata->vals;
8656 	                     nposbinvars = 0;
8657 	                     nnegbinvars = 0;
8658 	                     allonebinary = 0;
8659 	
8660 	                     /* update binary variables */
8661 	                     for( i = 0; i < nvars; ++i )
8662 	                     {
8663 	                        if( SCIPvarIsBinary(vars[i]) )
8664 	                        {
8665 	                           assert(!SCIPisZero(scip, vals[i]));
8666 	
8667 	                           if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8668 	                              ++allonebinary;
8669 	
8670 	                           binvars[nposbinvars + nnegbinvars] = vars[i];
8671 	                           binvarvals[nposbinvars + nnegbinvars] = vals[i];
8672 	
8673 	                           if( SCIPisPositive(scip, vals[i]) )
8674 	                              ++nposbinvars;
8675 	                           else
8676 	                              ++nnegbinvars;
8677 	
8678 	                           assert(nposbinvars + nnegbinvars <= nvars);
8679 	                        }
8680 	                        /* stop searching for binary variables, because the constraint data is sorted */
8681 	                        else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8682 	                           break;
8683 	                     }
8684 	                     assert(nposbinvars + nnegbinvars <= nvars);
8685 	                  }
8686 	               }
8687 	            }
8688 	
8689 	            oldnchgbds = *nchgbds;
8690 	         }
8691 	
8692 	         /* case c) */
8693 	         if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8694 	         {
8695 	            SCIP_Bool* values;
8696 	
8697 	            /* initialize clique values array for adding a negated clique */
8698 	            SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8699 	            BMSclearMemoryArray(values, nnegbinvars);
8700 	
8701 	            /* compute value that needs to be exceeded */
8702 	            threshold = consdata->rhs - QUAD_TO_DBL(consdata->glbminactivity);
8703 	
8704 	            i = nposbinvars + nnegbinvars - 1;
8705 	            j = i - 1;
8706 	
8707 	#if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8708 	            /* check if the variable should not have already been fixed to one */
8709 	            assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8710 	#endif
8711 	
8712 	            if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8713 	            {
8714 	               --j;
8715 	               /* check for extending the clique */
8716 	               while( j >= nposbinvars )
8717 	               {
8718 	                  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8719 	                     break;
8720 	                  --j;
8721 	               }
8722 	               jstart = j;
8723 	
8724 	               assert(i - j >= 2);
8725 	               /* add negated clique with at least two variables */
8726 	               SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8727 	
8728 	               if( infeasible )
8729 	                  *cutoff = TRUE;
8730 	
8731 	               *nchgbds += nbdchgs;
8732 	
8733 	               cliquenonzerosadded += (i - j);
8734 	               if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8735 	                  stopped = TRUE;
8736 	
8737 	               /* exchange the last variable in the clique if possible and add all new ones */
8738 	               if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8739 	               {
8740 	                  SCIP_VAR** clqvars;
8741 	                  int lastfit = j + 1;
8742 	                  assert(lastfit < i);
8743 	
8744 	                  /* copy all 'main'-clique variables */
8745 	                  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8746 	                  ++lastfit;
8747 	
8748 	                  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8749 	                  while( lastfit <= i && j >= nposbinvars )
8750 	                  {
8751 	                     /* check if two variables are in a negated clique */
8752 	                     if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8753 	                     {
8754 	                        assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8755 	                        clqvars[lastfit - jstart - 2] = binvars[j];
8756 	
8757 	                        assert(i - lastfit + 2 >= 2);
8758 	                        /* add clique with at least two variables */
8759 	                        SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8760 	
8761 	                        if( infeasible )
8762 	                        {
8763 	                           *cutoff = TRUE;
8764 	                           break;
8765 	                        }
8766 	
8767 	                        *nchgbds += nbdchgs;
8768 	
8769 	                        cliquenonzerosadded += (i - lastfit + 2);
8770 	                        if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8771 	                        {
8772 	                           stopped = TRUE;
8773 	                           break;
8774 	                        }
8775 	
8776 	                        --j;
8777 	                     }
8778 	                     else
8779 	                        ++lastfit;
8780 	                  }
8781 	
8782 	                  SCIPfreeBufferArray(scip, &clqvars);
8783 	               }
8784 	            }
8785 	
8786 	            SCIPfreeBufferArray(scip, &values);
8787 	         }
8788 	
8789 	         /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8790 	         if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8791 	         {
8792 	            /* check for fixed variables */
8793 	            SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8794 	
8795 	            if( !*cutoff )
8796 	            {
8797 	               /* tighten variable's bounds */
8798 	               SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8799 	
8800 	               if( !*cutoff )
8801 	               {
8802 	                  /* check for fixed variables */
8803 	                  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8804 	
8805 	                  if( !*cutoff )
8806 	                  {
8807 	                     /* sort variables by variable type */
8808 	                     SCIP_CALL( consdataSort(scip, consdata) );
8809 	
8810 	                     /* recompute activities if needed */
8811 	                     if( !consdata->validactivities )
8812 	                        consdataCalcActivities(scip, consdata);
8813 	                     assert(consdata->validactivities);
8814 	
8815 	                     nvars = consdata->nvars;
8816 	                     vars = consdata->vars;
8817 	                     vals = consdata->vals;
8818 	                     nposbinvars = 0;
8819 	                     nnegbinvars = 0;
8820 	                     allonebinary = 0;
8821 	
8822 	                     /* update binary variables */
8823 	                     for( i = 0; i < nvars; ++i )
8824 	                     {
8825 	                        if( SCIPvarIsBinary(vars[i]) )
8826 	                        {
8827 	                           assert(!SCIPisZero(scip, vals[i]));
8828 	
8829 	                           if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8830 	                              ++allonebinary;
8831 	
8832 	                           binvars[nposbinvars + nnegbinvars] = vars[i];
8833 	                           binvarvals[nposbinvars + nnegbinvars] = vals[i];
8834 	
8835 	                           if( SCIPisPositive(scip, vals[i]) )
8836 	                              ++nposbinvars;
8837 	                           else
8838 	                              ++nnegbinvars;
8839 	
8840 	                           assert(nposbinvars + nnegbinvars <= nvars);
8841 	                        }
8842 	                        /* stop searching for binary variables, because the constraint data is sorted */
8843 	                        else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8844 	                           break;
8845 	                     }
8846 	                     assert(nposbinvars + nnegbinvars <= nvars);
8847 	                  }
8848 	               }
8849 	            }
8850 	         }
8851 	
8852 	         /* case d) */
8853 	         if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8854 	         {
8855 	            SCIP_Bool* values;
8856 	
8857 	            /* initialize clique values array for adding a negated clique */
8858 	            SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8859 	            BMSclearMemoryArray(values, nposbinvars);
8860 	
8861 	            /* compute value that needs to be exceeded */
8862 	            threshold = consdata->lhs - QUAD_TO_DBL(consdata->glbmaxactivity);
8863 	
8864 	            j = 1;
8865 	
8866 	#if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8867 	            /* check if the variable should not have already been fixed to one */
8868 	            assert(!SCIPisFeasLT(scip, -binvarvals[0], threshold));
8869 	#endif
8870 	
8871 	            if( SCIPisFeasLT(scip, -binvarvals[0] - binvarvals[j], threshold) )
8872 	            {
8873 	               ++j;
8874 	               /* check for extending the clique */
8875 	               while( j < nposbinvars )
8876 	               {
8877 	                  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8878 	                     break;
8879 	                  ++j;
8880 	               }
8881 	               assert(j >= 2);
8882 	
8883 	               /* add negated clique with at least two variables */
8884 	               SCIP_CALL( SCIPaddClique(scip, binvars, values, j, FALSE, &infeasible, &nbdchgs) );
8885 	
8886 	               if( infeasible )
8887 	                  *cutoff = TRUE;
8888 	
8889 	               *nchgbds += nbdchgs;
8890 	
8891 	               cliquenonzerosadded += j;
8892 	               if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8893 	                  stopped = TRUE;
8894 	
8895 	               /* exchange the last variable in the clique if possible and add all new ones */
8896 	               if( !stopped && !(*cutoff) && j < nposbinvars )
8897 	               {
8898 	                  SCIP_VAR** clqvars;
8899 	                  int lastfit = j - 2;
8900 	                  assert(lastfit >= 0);
8901 	
8902 	                  /* copy all 'main'-clique variables */
8903 	                  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8904 	
8905 	                  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8906 	                  while( lastfit >= 0 && j < nposbinvars )
8907 	                  {
8908 	                     /* check if two variables are in a negated clique */
8909 	                     if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8910 	                     {
8911 	                        clqvars[lastfit + 1] = binvars[j];
8912 	
8913 	                        /* add clique with at least two variables */
8914 	                        SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8915 	
8916 	                        if( infeasible )
8917 	                        {
8918 	                           *cutoff = TRUE;
8919 	                           break;
8920 	                        }
8921 	
8922 	                        *nchgbds += nbdchgs;
8923 	
8924 	                        cliquenonzerosadded += lastfit + 2;
8925 	                        if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8926 	                           break;
8927 	
8928 	                        ++j;
8929 	                     }
8930 	                     else
8931 	                        --lastfit;
8932 	                  }
8933 	
8934 	                  SCIPfreeBufferArray(scip, &clqvars);
8935 	               }
8936 	            }
8937 	
8938 	            SCIPfreeBufferArray(scip, &values);
8939 	         }
8940 	      }
8941 	
8942 	      SCIPfreeBufferArray(scip, &binvarvals);
8943 	      SCIPfreeBufferArray(scip, &binvars);
8944 	
8945 	      if( *cutoff )
8946 	         return SCIP_OKAY;
8947 	   }
8948 	
8949 	   /* 2. we only check if the constraint is a set packing / partitioning constraint */
8950 	
8951 	   /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8952 	    * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8953 	    */
8954 	   nposcoefs = 0;
8955 	   nnegcoefs = 0;
8956 	   for( i = 0; i < nvars; ++i )
8957 	   {
8958 	      if( !SCIPvarIsBinary(vars[i]) )
8959 	         return SCIP_OKAY;
8960 	      else if( SCIPisEQ(scip, vals[i], +1.0) )
8961 	         nposcoefs++;
8962 	      else if( SCIPisEQ(scip, vals[i], -1.0) )
8963 	         nnegcoefs++;
8964 	      else
8965 	         return SCIP_OKAY;
8966 	   }
8967 	
8968 	   lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8969 	   rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8970 	
8971 	   if( lhsclique || rhsclique )
8972 	   {
8973 	      SCIP_Bool* values;
8974 	      int nbdchgs;
8975 	
8976 	      SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8977 	         SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8978 	      SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8979 	
8980 	      for( i = 0; i < nvars; ++i )
8981 	         values[i] = (rhsclique == (vals[i] > 0.0));
8982 	
8983 	      SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8984 	
8985 	      if( infeasible )
8986 	         *cutoff = TRUE;
8987 	
8988 	      *nchgbds += nbdchgs;
8989 	      SCIPfreeBufferArray(scip, &values);
8990 	   }
8991 	
8992 	   return SCIP_OKAY;
8993 	}
8994 	
8995 	/** tightens left and right hand side of constraint due to integrality */
8996 	static
8997 	SCIP_RETCODE tightenSides(
8998 	   SCIP*                 scip,               /**< SCIP data structure */
8999 	   SCIP_CONS*            cons,               /**< linear constraint */
9000 	   int*                  nchgsides,          /**< pointer to count number of side changes */
9001 	   SCIP_Bool*            infeasible          /**< pointer to store whether infeasibility was detected */
9002 	   )
9003 	{
9004 	   SCIP_CONSDATA* consdata;
9005 	   SCIP_Real newlhs;
9006 	   SCIP_Real newrhs;
9007 	   SCIP_Bool chglhs;
9008 	   SCIP_Bool chgrhs;
9009 	   SCIP_Bool integral;
9010 	   int i;
9011 	
9012 	   assert(scip != NULL);
9013 	   assert(cons != NULL);
9014 	   assert(nchgsides != NULL);
9015 	   assert(infeasible != NULL);
9016 	
9017 	   consdata = SCIPconsGetData(cons);
9018 	   assert(consdata != NULL);
9019 	
9020 	   *infeasible = FALSE;
9021 	
9022 	   chglhs = FALSE;
9023 	   chgrhs = FALSE;
9024 	   newlhs = -SCIPinfinity(scip);
9025 	   newrhs = SCIPinfinity(scip);
9026 	
9027 	   if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
9028 	   {
9029 	      integral = TRUE;
9030 	      for( i = 0; i < consdata->nvars && integral; ++i )
9031 	      {
9032 	         integral = SCIPisIntegral(scip, consdata->vals[i])
9033 	            && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
9034 	      }
9035 	      if( integral )
9036 	      {
9037 	         if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
9038 	         {
9039 	            newlhs = SCIPfeasCeil(scip, consdata->lhs);
9040 	            chglhs = TRUE;
9041 	         }
9042 	         if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
9043 	         {
9044 	            newrhs = SCIPfeasFloor(scip, consdata->rhs);
9045 	            chgrhs = TRUE;
9046 	         }
9047 	
9048 	         /* check whether rounding would lead to an unsatisfiable constraint */
9049 	         if( SCIPisGT(scip, newlhs, newrhs) )
9050 	         {
9051 	            SCIPdebugMsg(scip, "rounding sides=[%.15g,%.15g] of linear constraint <%s> with integral coefficients and variables only "
9052 	                  "is infeasible\n", consdata->lhs, consdata->rhs, SCIPconsGetName(cons));
9053 	
9054 	            *infeasible = TRUE;
9055 	            return SCIP_OKAY;
9056 	         }
9057 	
9058 	         SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
9059 	            SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9060 	
9061 	         if( chglhs )
9062 	         {
9063 	            assert(!SCIPisInfinity(scip, -newlhs));
9064 	
9065 	            SCIP_CALL( chgLhs(scip, cons, newlhs) );
9066 	            if( !consdata->upgraded )
9067 	               (*nchgsides)++;
9068 	         }
9069 	         if( chgrhs )
9070 	         {
9071 	            assert(!SCIPisInfinity(scip, newrhs));
9072 	
9073 	            SCIP_CALL( chgRhs(scip, cons, newrhs) );
9074 	            if( !consdata->upgraded )
9075 	               (*nchgsides)++;
9076 	         }
9077 	         SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
9078 	            SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9079 	      }
9080 	   }
9081 	
9082 	   return SCIP_OKAY;
9083 	}
9084 	
9085 	/** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
9086 	 *  given an inequality  lhs <= a*x + ai*xi <= rhs, with a non-continuous variable  li <= xi <= ui
9087 	 *  let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
9088 	 *  (i) ai >= 0:
9089 	 *      if  minact + ai >= lhs  and  maxact - ai <= rhs: (**)
9090 	 *       - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
9091 	 *       - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9092 	 *         xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9093 	 *       - change coefficients:
9094 	 *           ai'  := max(lhs - minact, maxact - rhs)
9095 	 *           lhs' := lhs - (ai - ai')*li
9096 	 *           rhs' := rhs - (ai - ai')*ui
9097 	 * (ii) ai < 0:
9098 	 *      if  minact - ai >= lhs  and  maxact + ai <= rhs: (***)
9099 	 *       - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
9100 	 *       - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9101 	 *         xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9102 	 *       - change coefficients:
9103 	 *           ai'  := min(rhs - maxact, minact - lhs)
9104 	 *           lhs' := lhs - (ai - ai')*ui
9105 	 *           rhs' := rhs - (ai - ai')*li
9106 	 *
9107 	 *  We further try to remove redundant variable from the constraint;
9108 	 *  Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
9109 	 *  A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
9110 	 *  variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
9111 	 *  the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
9112 	 *  E.g., for binary variables and an inequality x_1 +x_2 +10y_1 +10y_2 >= 5, setting either of the y_i to one
9113 	 *  suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
9114 	 *
9115 	 *  @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
9116 	 *        cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
9117 	 */
9118 	static
9119 	SCIP_RETCODE consdataTightenCoefs(
9120 	   SCIP*                 scip,               /**< SCIP data structure */
9121 	   SCIP_CONS*            cons,               /**< linear constraint */
9122 	   int*                  nchgcoefs,          /**< pointer to count total number of changed coefficients */
9123 	   int*                  nchgsides           /**< pointer to count number of side changes */
9124 	   )
9125 	{
9126 	   SCIP_CONSDATA* consdata;
9127 	   SCIP_VAR* var;
9128 	   SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
9129 	                           * activity, ignoring the coefficients contributing with infinite value */
9130 	   SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
9131 	                           * activity, ignoring the coefficients contributing with infinite value */
9132 	   SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
9133 	   SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
9134 	   SCIP_Bool isminsettoinfinity;
9135 	   SCIP_Bool ismaxsettoinfinity;
9136 	   SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
9137 	   SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
9138 	   SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
9139 	   SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
9140 	   SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
9141 	   SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
9142 	   SCIP_Real val;
9143 	   SCIP_Real newval;
9144 	   SCIP_Real newlhs;
9145 	   SCIP_Real newrhs;
9146 	   SCIP_Real lb;
9147 	   SCIP_Real ub;
9148 	   int i;
9149 	
9150 	   assert(scip != NULL);
9151 	   assert(cons != NULL);
9152 	   assert(nchgcoefs != NULL);
9153 	   assert(nchgsides != NULL);
9154 	
9155 	   consdata = SCIPconsGetData(cons);
9156 	   assert(consdata != NULL);
9157 	
9158 	   /* @todo Is this still needed with automatic recomputation of activities? */
9159 	   /* if the maximal coefficient is too large, recompute the activities */
9160 	   if( (consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP)
9161 	      || (consdata->validminabsval && consdata->minabsval < MINVALRECOMP) )
9162 	   {
9163 	      consdataRecomputeMinactivity(scip, consdata);
9164 	      consdataRecomputeMaxactivity(scip, consdata);
9165 	   }
9166 	
9167 	   /* get the minimal and maximal activity of the constraint */
9168 	   consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9169 	      &isminsettoinfinity, &ismaxsettoinfinity);
9170 	
9171 	   minleftactivity = 0.0;
9172 	   maxleftactivity = 0.0;
9173 	
9174 	   /* try to tighten each coefficient */
9175 	   i = 0;
9176 	   while( i < consdata->nvars )
9177 	   {
9178 	      var = consdata->vars[i];
9179 	
9180 	      /* get coefficient and variable's bounds */
9181 	      lb = SCIPvarGetLbLocal(var);
9182 	      ub = SCIPvarGetUbLocal(var);
9183 	      val = consdata->vals[i];
9184 	      assert(!SCIPisZero(scip, val));
9185 	
9186 	      /* check sign of coefficient */
9187 	      if( val >= 0.0 )
9188 	      {
9189 	         /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9190 	         if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS &&
9191 	            SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
9192 	         {
9193 	            /* change coefficients:
9194 	             *   ai'  := max(lhs - minact, maxact - rhs)
9195 	             *   lhs' := lhs - (ai - ai')*li
9196 	             *   rhs' := rhs - (ai - ai')*ui
9197 	             */
9198 	
9199 	            lval = consdata->lhs - minactivity;
9200 	            rval = maxactivity - consdata->rhs;
9201 	
9202 	            /* Try to avoid cancellation, if there are only two variables */
9203 	            if( consdata->nvars == 2 )
9204 	            {
9205 	               SCIP_Real otherval;
9206 	               otherval = consdata->vals[1-i];
9207 	
9208 	               if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9209 	               {
9210 	                  lval = consdata->lhs - val*lb;
9211 	                  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9212 	               }
9213 	
9214 	               if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9215 	               {
9216 	                  rval = val*ub - consdata->rhs;
9217 	                  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9218 	               }
9219 	            }
9220 	
9221 	            newval = MAX(lval, rval);
9222 	            assert(SCIPisSumRelLE(scip, newval, val));
9223 	
9224 	            /* Try to avoid cancellation in computation of lhs/rhs */
9225 	            newlhs = consdata->lhs - val * lb;
9226 	            newlhs += newval * lb;
9227 	            newrhs = consdata->rhs - val * ub;
9228 	            newrhs += newval * ub;
9229 	
9230 	            if( !SCIPisSumRelEQ(scip, newval, val) )
9231 	            {
9232 	               SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9233 	                  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9234 	                  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9235 	
9236 	               /* update the coefficient and the activity bounds */
9237 	               if( SCIPisZero(scip, newval) )
9238 	               {
9239 	                  SCIP_CALL( delCoefPos(scip, cons, i) );
9240 	                  i--;
9241 	               }
9242 	               else
9243 	               {
9244 	                  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9245 	               }
9246 	               (*nchgcoefs)++;
9247 	
9248 	               /* get the new minimal and maximal activity of the constraint */
9249 	               consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9250 	                  &isminsettoinfinity, &ismaxsettoinfinity);
9251 	
9252 	               if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9253 	               {
9254 	                  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9255 	
9256 	                  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9257 	                  (*nchgsides)++;
9258 	                  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9259 	               }
9260 	
9261 	               if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9262 	               {
9263 	                  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9264 	
9265 	                  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9266 	                  (*nchgsides)++;
9267 	                  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9268 	               }
9269 	            }
9270 	         }
9271 	         else
9272 	         {
9273 	            if( !SCIPisInfinity(scip, -minleftactivity) )
9274 	            {
9275 	               assert(!SCIPisInfinity(scip, val));
9276 	               assert(!SCIPisInfinity(scip, lb));
9277 	               if( SCIPisInfinity(scip, -lb) )
9278 	                  minleftactivity = -SCIPinfinity(scip);
9279 	               else
9280 	                  minleftactivity += val * lb;
9281 	            }
9282 	
9283 	            if( !SCIPisInfinity(scip, maxleftactivity) )
9284 	            {
9285 	               assert(!SCIPisInfinity(scip, val));
9286 	               assert(!SCIPisInfinity(scip, -ub));
9287 	               if( SCIPisInfinity(scip,ub) )
9288 	                  maxleftactivity = SCIPinfinity(scip);
9289 	               else
9290 	                  maxleftactivity += val * ub;
9291 	            }
9292 	         }
9293 	      }
9294 	      else
9295 	      {
9296 	         /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9297 	         if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS &&
9298 	            SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
9299 	         {
9300 	            /* change coefficients:
9301 	             *   ai'  := min(rhs - maxact, minact - lhs)
9302 	             *   lhs' := lhs - (ai - ai')*ui
9303 	             *   rhs' := rhs - (ai - ai')*li
9304 	             */
9305 	
9306 	            lval = minactivity - consdata->lhs;
9307 	            rval = consdata->rhs - maxactivity;
9308 	
9309 	            /* Try to avoid cancellation, if there are only two variables */
9310 	            if( consdata->nvars == 2 )
9311 	            {
9312 	               SCIP_Real otherval;
9313 	               otherval = consdata->vals[1-i];
9314 	
9315 	               if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9316 	               {
9317 	                  lval = val*ub - consdata->lhs;
9318 	                  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9319 	               }
9320 	
9321 	               if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9322 	               {
9323 	                  rval = consdata->rhs - val*lb;
9324 	                  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9325 	               }
9326 	            }
9327 	
9328 	            newval = MIN(lval, rval);
9329 	            assert(SCIPisSumRelGE(scip, newval, val));
9330 	
9331 	            /* Try to avoid cancellation in computation of lhs/rhs */
9332 	            newlhs = consdata->lhs - val * ub;
9333 	            newlhs += newval * ub;
9334 	            newrhs = consdata->rhs - val * lb;
9335 	            newrhs += newval * lb;
9336 	
9337 	            if( !SCIPisSumRelEQ(scip, newval, val) )
9338 	            {
9339 	               SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9340 	                  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9341 	                  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9342 	
9343 	               /* update the coefficient and the activity bounds */
9344 	               if( SCIPisZero(scip, newval) )
9345 	               {
9346 	                  SCIP_CALL( delCoefPos(scip, cons, i) );
9347 	                  i--;
9348 	               }
9349 	               else
9350 	               {
9351 	                  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9352 	               }
9353 	               (*nchgcoefs)++;
9354 	
9355 	               /* get the new minimal and maximal activity of the constraint */
9356 	               consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9357 	                  &isminsettoinfinity, &ismaxsettoinfinity);
9358 	
9359 	               if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9360 	               {
9361 	                  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9362 	
9363 	                  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9364 	                  (*nchgsides)++;
9365 	                  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9366 	               }
9367 	
9368 	               if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9369 	               {
9370 	                  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9371 	
9372 	                  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9373 	                  (*nchgsides)++;
9374 	                  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9375 	               }
9376 	            }
9377 	         }
9378 	         else
9379 	         {
9380 	            if( !SCIPisInfinity(scip, -minleftactivity) )
9381 	            {
9382 	               assert(!SCIPisInfinity(scip, -val));
9383 	               assert(!SCIPisInfinity(scip, -ub));
9384 	               if( SCIPisInfinity(scip, ub) )
9385 	                  minleftactivity = -SCIPinfinity(scip);
9386 	               else
9387 	                  minleftactivity += val * ub;
9388 	            }
9389 	
9390 	            if( !SCIPisInfinity(scip, maxleftactivity) )
9391 	            {
9392 	               assert(!SCIPisInfinity(scip, -val));
9393 	               assert(!SCIPisInfinity(scip, lb));
9394 	               if( SCIPisInfinity(scip, -lb) )
9395 	                  maxleftactivity = SCIPinfinity(scip);
9396 	               else
9397 	                  maxleftactivity += val * lb;
9398 	            }
9399 	         }
9400 	      }
9401 	      ++i;
9402 	   }
9403 	
9404 	   SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
9405 	      minleftactivity, consdata->rhs);
9406 	   SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
9407 	      maxleftactivity, consdata->lhs);
9408 	
9409 	   /* minleft == \infty  ==>  minactivity == \infty */
9410 	   assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
9411 	   assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
9412 	
9413 	   /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
9414 	    * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
9415 	    * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
9416 	    * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
9417 	    */
9418 	   assert(!SCIPisInfinity(scip, minactivity));
9419 	   if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
9420 	      return SCIP_OKAY;
9421 	
9422 	   /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
9423 	    * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
9424 	    * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
9425 	    * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
9426 	    */
9427 	   assert(!SCIPisInfinity(scip, -maxactivity));
9428 	   if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
9429 	      return SCIP_OKAY;
9430 	
9431 	   /* correct lhs and rhs by min/max activity of surely non-redundant variables
9432 	    * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
9433 	    */
9434 	   aggrlhs = consdata->lhs - minactivity + minleftactivity;
9435 	   aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
9436 	
9437 	   /* check if the constraint contains variables which are redundant. The reasoning is the following:
9438 	    * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
9439 	    * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
9440 	    * they can be removed from the constraint.
9441 	    * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
9442 	    */
9443 	   if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
9444 	      && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
9445 	   {
9446 	      SCIP_Real minleftactivitypart;
9447 	      SCIP_Real maxleftactivitypart;
9448 	
9449 	      assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
9450 	
9451 	      /* try to remove redundant variables from constraint */
9452 	      i = 0;
9453 	      while( i < consdata->nvars )
9454 	      {
9455 	         var = consdata->vars[i];
9456 	         minleftactivitypart = 0.0;
9457 	         maxleftactivitypart = 0.0;
9458 	         lb = SCIPvarGetLbLocal(var);
9459 	         ub = SCIPvarGetUbLocal(var);
9460 	
9461 	         /* get coefficient and variable's bounds */
9462 	         val = consdata->vals[i];
9463 	         assert(!SCIPisZero(scip, val));
9464 	
9465 	         /* check sign of coefficient */
9466 	         if( val >= 0.0 )
9467 	         {
9468 	            /* negation of condition above in case of positive val */
9469 	            if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
9470 	               SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
9471 	            {
9472 	               SCIPdebugMsg(scip, "minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
9473 	               SCIPdebugMsg(scip, "maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
9474 	               SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9475 	                  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9476 	
9477 	               minleftactivitypart = val * lb;
9478 	               maxleftactivitypart = val * ub;
9479 	
9480 	               SCIP_CALL( delCoefPos(scip, cons, i) );
9481 	               i--;
9482 	
9483 	               /* get the new minimal and maximal activity of the constraint */
9484 	               consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9485 	                  &isminsettoinfinity, &ismaxsettoinfinity);
9486 	
9487 	               /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9488 	                * huge contributions
9489 	                */
9490 	               assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9491 	               assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9492 	            }
9493 	         }
9494 	         else
9495 	         {
9496 	            /* negation of condition above in case of negative val */
9497 	            if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
9498 	               SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9499 	            {
9500 	               SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9501 	                  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9502 	
9503 	               minleftactivitypart = val * ub;
9504 	               maxleftactivitypart = val * lb;
9505 	
9506 	               SCIP_CALL( delCoefPos(scip, cons, i) );
9507 	               i--;
9508 	
9509 	               /* get the new minimal and maximal activity of the constraint */
9510 	               consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9511 	                  &isminsettoinfinity, &ismaxsettoinfinity);
9512 	
9513 	               /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9514 	                * huge contributions
9515 	                */
9516 	               assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9517 	               assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9518 	            }
9519 	         }
9520 	
9521 	         /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9522 	          * redundant variables could get deleted,
9523 	          * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9524 	          * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9525 	          * we would also delete y2 and as a result we would have gotten infeasibility */
9526 	         /* adjust lhs and right hand side */
9527 	         newlhs = consdata->lhs - minleftactivitypart;
9528 	         newrhs = consdata->rhs - maxleftactivitypart;
9529 	
9530 	         if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9531 	         {
9532 	            SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9533 	            SCIP_CALL( chgLhs(scip, cons, newlhs) );
9534 	            ++(*nchgsides);
9535 	            assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9536 	         }
9537 	         if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9538 	         {
9539 	            SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9540 	            SCIP_CALL( chgRhs(scip, cons, newrhs) );
9541 	            ++(*nchgsides);
9542 	            assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9543 	         }
9544 	         ++i;
9545 	      }
9546 	   }
9547 	
9548 	   return SCIP_OKAY;
9549 	}
9550 	
9551 	/** processes equality with only one variable by fixing the variable and deleting the constraint */
9552 	static
9553 	SCIP_RETCODE convertUnaryEquality(
9554 	   SCIP*                 scip,               /**< SCIP data structure */
9555 	   SCIP_CONS*            cons,               /**< linear constraint */
9556 	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
9557 	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
9558 	   int*                  ndelconss           /**< pointer to count number of deleted constraints */
9559 	   )
9560 	{
9561 	   SCIP_CONSDATA* consdata;
9562 	   SCIP_VAR* var;
9563 	   SCIP_Real val;
9564 	   SCIP_Real fixval;
9565 	   SCIP_Bool infeasible;
9566 	   SCIP_Bool fixed;
9567 	
9568 	   assert(scip != NULL);
9569 	   assert(cons != NULL);
9570 	   assert(cutoff != NULL);
9571 	   assert(nfixedvars != NULL);
9572 	   assert(ndelconss != NULL);
9573 	
9574 	   consdata = SCIPconsGetData(cons);
9575 	   assert(consdata != NULL);
9576 	   assert(consdata->nvars == 1);
9577 	   assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9578 	
9579 	   /* calculate the value to fix the variable to */
9580 	   var = consdata->vars[0];
9581 	   val = consdata->vals[0];
9582 	   assert(!SCIPisZero(scip, val));
9583 	   fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9584 	      consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9585 	   SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
9586 	      SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9587 	
9588 	   /* fix variable */
9589 	   SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9590 	   if( infeasible )
9591 	   {
9592 	      SCIPdebugMsg(scip, " -> infeasible fixing\n");
9593 	      *cutoff = TRUE;
9594 	      return SCIP_OKAY;
9595 	   }
9596 	   if( fixed )
9597 	      (*nfixedvars)++;
9598 	
9599 	   /* disable constraint */
9600 	   SCIP_CALL( SCIPdelCons(scip, cons) );
9601 	   if( !consdata->upgraded )
9602 	      (*ndelconss)++;
9603 	
9604 	   return SCIP_OKAY;
9605 	}
9606 	
9607 	/** processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9608 	static
9609 	SCIP_RETCODE convertBinaryEquality(
9610 	   SCIP*                 scip,               /**< SCIP data structure */
9611 	   SCIP_CONS*            cons,               /**< linear constraint */
9612 	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
9613 	   int*                  naggrvars,          /**< pointer to count number of aggregated variables */
9614 	   int*                  ndelconss           /**< pointer to count number of deleted constraints */
9615 	   )
9616 	{
9617 	   SCIP_CONSDATA* consdata;
9618 	   SCIP_Bool infeasible;
9619 	   SCIP_Bool redundant;
9620 	   SCIP_Bool aggregated;
9621 	
9622 	   assert(scip != NULL);
9623 	   assert(cons != NULL);
9624 	   assert(cutoff != NULL);
9625 	   assert(naggrvars != NULL);
9626 	   assert(ndelconss != NULL);
9627 	
9628 	   consdata = SCIPconsGetData(cons);
9629 	   assert(consdata != NULL);
9630 	   assert(consdata->nvars == 2);
9631 	   assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9632 	
9633 	   SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9634 	      SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9635 	      consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9636 	
9637 	   /* aggregate the equality */
9638 	   SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9639 	         consdata->rhs, &infeasible, &redundant, &aggregated) );
9640 	
9641 	   /* check for infeasibility of aggregation */
9642 	   if( infeasible )
9643 	   {
9644 	      SCIPdebugMsg(scip, " -> infeasible aggregation\n");
9645 	      *cutoff = TRUE;
9646 	      return SCIP_OKAY;
9647 	   }
9648 	
9649 	   /* count the aggregation */
9650 	   if( aggregated )
9651 	      (*naggrvars)++;
9652 	
9653 	   /* delete the constraint, if it is redundant */
9654 	   if( redundant )
9655 	   {
9656 	      SCIP_CALL( SCIPdelCons(scip, cons) );
9657 	
9658 	      if( !consdata->upgraded )
9659 	         (*ndelconss)++;
9660 	   }
9661 	
9662 	   return SCIP_OKAY;
9663 	}
9664 	
9665 	/** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9666 	static
9667 	void getNewSidesAfterAggregation(
9668 	   SCIP*                 scip,               /**< SCIP data structure */
9669 	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
9670 	   SCIP_VAR*             slackvar,           /**< variable to be aggregated out */
9671 	   SCIP_Real             slackcoef,          /**< coefficient of variable in constraint */
9672 	   SCIP_Real*            newlhs,             /**< pointer to store new lhs of constraint */
9673 	   SCIP_Real*            newrhs              /**< pointer to store new rhs of constraint */
9674 	   )
9675 	{
9676 	   SCIP_Real slackvarlb;
9677 	   SCIP_Real slackvarub;
9678 	
9679 	   assert(scip != NULL);
9680 	   assert(consdata != NULL);
9681 	   assert(newlhs != NULL);
9682 	   assert(newrhs != NULL);
9683 	   assert(!SCIPisInfinity(scip, -consdata->lhs));
9684 	   assert(!SCIPisInfinity(scip, consdata->rhs));
9685 	
9686 	   slackvarlb = SCIPvarGetLbGlobal(slackvar);
9687 	   slackvarub = SCIPvarGetUbGlobal(slackvar);
9688 	   if( slackcoef > 0.0 )
9689 	   {
9690 	      if( SCIPisInfinity(scip, -slackvarlb) )
9691 	         *newrhs = SCIPinfinity(scip);
9692 	      else
9693 	         *newrhs = consdata->rhs - slackcoef * slackvarlb;
9694 	      if( SCIPisInfinity(scip, slackvarub) )
9695 	         *newlhs = -SCIPinfinity(scip);
9696 	      else
9697 	         *newlhs = consdata->lhs - slackcoef * slackvarub;
9698 	   }
9699 	   else
9700 	   {
9701 	      if( SCIPisInfinity(scip, -slackvarlb) )
9702 	         *newlhs = -SCIPinfinity(scip);
9703 	      else
9704 	         *newlhs = consdata->rhs - slackcoef * slackvarlb;
9705 	      if( SCIPisInfinity(scip, slackvarub) )
9706 	         *newrhs = SCIPinfinity(scip);
9707 	      else
9708 	         *newrhs = consdata->lhs - slackcoef * slackvarub;
9709 	   }
9710 	   assert(SCIPisLE(scip, *newlhs, *newrhs));
9711 	}
9712 	
9713 	/** processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9714 	 *  into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9715 	 *  is implicitly integral by this constraint
9716 	 *
9717 	 *  @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9718 	 *       can help.
9719 	 */
9720 	static
9721 	SCIP_RETCODE convertLongEquality(
9722 	   SCIP*                 scip,               /**< SCIP data structure */
9723 	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< linear constraint handler data */
9724 	   SCIP_CONS*            cons,               /**< linear constraint */
9725 	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
9726 	   int*                  naggrvars,          /**< pointer to count number of aggregated variables */
9727 	   int*                  ndelconss           /**< pointer to count number of deleted constraints */
9728 	   )
9729 	{
9730 	   SCIP_CONSDATA* consdata;
9731 	   SCIP_VAR** vars;
9732 	   SCIP_Real* vals;
9733 	   SCIP_VARTYPE bestslacktype;
9734 	   SCIP_VARTYPE slacktype;
9735 	   SCIP_Real lhs;
9736 	   SCIP_Real rhs;
9737 	   SCIP_Real bestslackdomrng;
9738 	   SCIP_Real minabsval;
9739 	   SCIP_Real maxabsval;
9740 	   SCIP_Bool bestremovescons;
9741 	   SCIP_Bool coefszeroone;
9742 	   SCIP_Bool coefsintegral;
9743 	   SCIP_Bool varsintegral;
9744 	   SCIP_Bool infeasible;
9745 	   SCIP_Bool samevar;
9746 	   int supinf;                               /* counter for infinite contributions to the supremum of a possible
9747 	                                              * multi-aggregation
9748 	                                              */
9749 	   int infinf;                               /* counter for infinite contributions to the infimum of a possible
9750 	                                              * multi-aggregation
9751 	                                              */
9752 	   int maxnlocksstay;
9753 	   int maxnlocksremove;
9754 	   int bestslackpos;
9755 	   int bestnlocks;
9756 	   int ncontvars;
9757 	   int contvarpos;
9758 	   int nintvars;
9759 	   int nimplvars;
9760 	   int intvarpos;
9761 	   int v;
9762 	
9763 	   assert(scip != NULL);
9764 	   assert(cons != NULL);
9765 	   assert(cutoff != NULL);
9766 	   assert(naggrvars != NULL);
9767 	
9768 	   consdata = SCIPconsGetData(cons);
9769 	   assert(consdata != NULL);
9770 	   assert(consdata->nvars > 2);
9771 	   assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9772 	
9773 	   SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9774 	
9775 	   /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9776 	    * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9777 	    *   maxnlocksstay:   maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9778 	    *   maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9779 	    */
9780 	   lhs = consdata->lhs;
9781 	   rhs = consdata->rhs;
9782 	   maxnlocksstay = 0;
9783 	   if( consdata->nvars == 3 )
9784 	   {
9785 	      /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9786 	       * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9787 	       */
9788 	      maxnlocksremove = 3;
9789 	   }
9790 	   else if( consdata->nvars == 4 )
9791 	   {
9792 	      /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9793 	       * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9794 	       */
9795 	      maxnlocksremove = 2;
9796 	   }
9797 	   else
9798 	   {
9799 	      /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9800 	      maxnlocksremove = 1;
9801 	   }
9802 	
9803 	   /* the locks on this constraint can be ignored */
9804 	   if( SCIPconsIsChecked(cons) )
9805 	   {
9806 	      if( !SCIPisInfinity(scip, -lhs) )
9807 	      {
9808 	         maxnlocksstay++;
9809 	         maxnlocksremove++;
9810 	      }
9811 	      if( !SCIPisInfinity(scip, rhs) )
9812 	      {
9813 	         maxnlocksstay++;
9814 	         maxnlocksremove++;
9815 	      }
9816 	   }
9817 	
9818 	   /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9819 	   vars = consdata->vars;
9820 	   vals = consdata->vals;
9821 	   bestslackpos = -1;
9822 	   bestslacktype = SCIP_VARTYPE_BINARY;
9823 	   bestnlocks = INT_MAX;
9824 	   bestremovescons = FALSE;
9825 	   bestslackdomrng = 0.0;
9826 	   coefszeroone = TRUE;
9827 	   coefsintegral = TRUE;
9828 	   varsintegral = TRUE;
9829 	   ncontvars = 0;
9830 	   contvarpos = -1;
9831 	   nintvars = 0;
9832 	   nimplvars = 0;
9833 	   intvarpos = -1;
9834 	   minabsval = SCIPinfinity(scip);
9835 	   maxabsval = -1.0;
9836 	   for( v = 0; v < consdata->nvars; ++v )
9837 	   {
9838 	      SCIP_VAR* var;
9839 	      SCIP_Real val;
9840 	      SCIP_Real absval;
9841 	      SCIP_Real varlb;
9842 	      SCIP_Real varub;
9843 	      SCIP_Bool iscont;
9844 	      int nlocks;
9845 	
9846 	      assert(vars != NULL);
9847 	      assert(vals != NULL);
9848 	
9849 	      var = vars[v];
9850 	      assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= 1); /* because variable is locked in this equality */
9851 	      assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= 1);
9852 	      varlb = SCIPvarGetLbGlobal(var);
9853 	      varub = SCIPvarGetUbGlobal(var);
9854 	
9855 	      val = vals[v];
9856 	      absval = REALABS(val);
9857 	      assert(SCIPisPositive(scip, absval));
9858 	
9859 	      /* calculate minimal and maximal absolute value */
9860 	      if( absval < minabsval )
9861 	         minabsval = absval;
9862 	      if( absval > maxabsval )
9863 	         maxabsval = absval;
9864 	
9865 	      /* do not try to multi aggregate, when numerical bad */
9866 	      if( maxabsval / minabsval > conshdlrdata->maxmultaggrquot )
9867 	         return SCIP_OKAY;
9868 	
9869 	      slacktype = SCIPvarGetType(var);
9870 	      coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9871 	      coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9872 	      varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9873 	      iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9874 	
9875 	      /* update candidates for continuous -> implint and integer -> implint conversion */
9876 	      if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9877 	      {
9878 	         ncontvars++;
9879 	         contvarpos = v;
9880 	      }
9881 	      else if( slacktype == SCIP_VARTYPE_IMPLINT )
9882 	      {
9883 	         ++nimplvars;
9884 	      }
9885 	      else if( slacktype == SCIP_VARTYPE_INTEGER )
9886 	      {
9887 	         nintvars++;
9888 	         intvarpos = v;
9889 	      }
9890 	
9891 	      /* check, if variable is already fixed or aggregated */
9892 	      if( !SCIPvarIsActive(var) )
9893 	         continue;
9894 	
9895 	      /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9896 	      nlocks = SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) + SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
9897 	
9898 	      if( nlocks > maxnlocksremove )
9899 	         continue;
9900 	
9901 	      /* check, if variable can be used as a slack variable */
9902 	      if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9903 	         !SCIPdoNotMultaggrVar(scip, var) )
9904 	      {
9905 	         SCIP_Bool better;
9906 	         SCIP_Bool equal;
9907 	         SCIP_Real slackdomrng;
9908 	
9909 	         if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9910 	            slackdomrng = SCIPinfinity(scip);
9911 	         /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9912 	         else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9913 	            return SCIP_OKAY;
9914 	         else
9915 	         {
9916 	            slackdomrng = (varub - varlb)*absval;
9917 	            assert(!SCIPisInfinity(scip, slackdomrng));
9918 	         }
9919 	         equal = FALSE;
9920 	         better = (slacktype > bestslacktype) || (bestslackpos == -1);
9921 	         if( !better && slacktype == bestslacktype )
9922 	         {
9923 	            better = (nlocks < bestnlocks);
9924 	            if( nlocks == bestnlocks && !bestremovescons )
9925 	            {
9926 	               better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9927 	               equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9928 	            }
9929 	         }
9930 	
9931 	         if( better || equal )
9932 	         {
9933 	            SCIP_Real minresactivity;
9934 	            SCIP_Real maxresactivity;
9935 	            SCIP_Real newlhs;
9936 	            SCIP_Real newrhs;
9937 	            SCIP_Bool removescons;
9938 	            SCIP_Bool minisrelax;
9939 	            SCIP_Bool maxisrelax;
9940 	            SCIP_Bool isminsettoinfinity;
9941 	            SCIP_Bool ismaxsettoinfinity;
9942 	
9943 	            /* check if the constraint becomes redundant after multi-aggregation */
9944 	            consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9945 	               &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9946 	
9947 	            /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9948 	             * activity
9949 	             */
9950 	            if( minisrelax || maxisrelax )
9951 	               continue;
9952 	
9953 	            getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9954 	            removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9955 	
9956 	            /* check resactivities for reliability */
9957 	            if( removescons )
9958 	            {
9959 	               if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9960 	                  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9961 	
9962 	               if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9963 	                  && SCIPisFeasLE(scip, newlhs, minresactivity))
9964 	                  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9965 	
9966 	               removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9967 	            }
9968 	
9969 	            /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9970 	            if( conshdlrdata->multaggrremove && !removescons )
9971 	               continue;
9972 	
9973 	            /* prefer variables that make the constraints redundant */
9974 	            if( bestremovescons && !removescons )
9975 	               continue;
9976 	
9977 	            /* if the constraint does not become redundant, only accept the variable if it does not appear in
9978 	             * other constraints
9979 	             */
9980 	            if( !removescons && nlocks > maxnlocksstay )
9981 	               continue;
9982 	
9983 	            better = better || (!bestremovescons && removescons);
9984 	            if( better )
9985 	            {
9986 	               bestslackpos = v;
9987 	               bestslacktype = slacktype;
9988 	               bestnlocks = nlocks;
9989 	               bestslackdomrng = slackdomrng;
9990 	               bestremovescons = removescons;
9991 	            }
9992 	         }
9993 	      }
9994 	   }
9995 	
9996 	   /* if all coefficients and variables are integral, the right hand side must also be integral */
9997 	   if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9998 	   {
9999 	      SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
10000	      SCIPdebugPrintCons(scip, cons, NULL);
10001	      *cutoff = TRUE;
10002	      return SCIP_OKAY;
10003	   }
10004	
10005	   supinf = 0;
10006	   infinf = 0;
10007	   samevar = FALSE;
10008	
10009	   /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
10010	   for( v = 0; v < consdata->nvars; ++v )
10011	   {
10012	      if( v != bestslackpos )
10013	      {
10014	         if( SCIPisPositive(scip, consdata->vals[v]) )
10015	         {
10016	            if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10017	            {
10018	               ++supinf;
10019	               if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10020	               {
10021	                  ++infinf;
10022	                  samevar = TRUE;
10023	               }
10024	            }
10025	            else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10026	               ++infinf;
10027	         }
10028	         else if( SCIPisNegative(scip, consdata->vals[v]) )
10029	         {
10030	            if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10031	            {
10032	               ++supinf;
10033	               if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10034	               {
10035	                  ++infinf;
10036	                  samevar = TRUE;
10037	               }
10038	            }
10039	            else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10040	               ++infinf;
10041	         }
10042	      }
10043	   }
10044	   assert(!samevar || (supinf > 0 && infinf > 0));
10045	
10046	   /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10047	    * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10048	   if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
10049	   {
10050	      SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
10051	      return SCIP_OKAY;
10052	   }
10053	
10054	   /* if the slack variable is of integer type, and the constraint itself may take fractional values,
10055	    * we cannot aggregate the variable, because the integrality condition would get lost
10056	    * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
10057	    * loose the integrality condition for this variable.
10058	    */
10059	   if( bestslackpos >= 0
10060	      && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
10061	         || (coefsintegral && varsintegral && nimplvars == 0)) )
10062	   {
10063	      SCIP_VAR* slackvar;
10064	      SCIP_Real* scalars;
10065	      SCIP_Real slackcoef;
10066	      SCIP_Real aggrconst;
10067	      SCIP_Real newlhs;
10068	      SCIP_Real newrhs;
10069	      SCIP_Bool aggregated;
10070	
10071	      /* we found a slack variable that only occurs in at most one other constraint:
10072	       *   a_1*x_1 + ... + a_k*x_k + a'*s == rhs  ->  s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
10073	       */
10074	      assert(bestslackpos < consdata->nvars);
10075	
10076	      /* do not multi aggregate binary variables */
10077	      if( SCIPvarIsBinary(vars[bestslackpos]) )
10078	         return SCIP_OKAY;
10079	
10080	      /* convert equality into inequality by deleting the slack variable:
10081	       *  x + a*s == b, l <= s <= u   ->  b - a*u <= x <= b - a*l
10082	       */
10083	      slackvar = vars[bestslackpos];
10084	      slackcoef = vals[bestslackpos];
10085	      assert(!SCIPisZero(scip, slackcoef));
10086	      aggrconst = consdata->rhs/slackcoef;
10087	
10088	      getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
10089	      assert(SCIPisLE(scip, newlhs, newrhs));
10090	      SCIP_CALL( chgLhs(scip, cons, newlhs) );
10091	      SCIP_CALL( chgRhs(scip, cons, newrhs) );
10092	      SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
10093	
10094	      /* allocate temporary memory */
10095	      SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
10096	
10097	      /* set up the multi-aggregation */
10098	      SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
10099	      for( v = 0; v < consdata->nvars; ++v )
10100	      {
10101	         scalars[v] = -consdata->vals[v]/slackcoef;
10102	         SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
10103	      }
10104	      SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
10105	         aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
10106	         bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
10107	
10108	      /* perform the multi-aggregation */
10109	      SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
10110	            &infeasible, &aggregated) );
10111	      assert(aggregated);
10112	
10113	      /* free temporary memory */
10114	      SCIPfreeBufferArray(scip, &scalars);
10115	
10116	      /* check for infeasible aggregation */
10117	      if( infeasible )
10118	      {
10119	         SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10120	         *cutoff = TRUE;
10121	         return SCIP_OKAY;
10122	      }
10123	
10124	      (*naggrvars)++;
10125	
10126	      /* delete the constraint if it became redundant */
10127	      if( bestremovescons )
10128	      {
10129	         SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
10130	         SCIP_CALL( SCIPdelCons(scip, cons) );
10131	
10132	         if( !consdata->upgraded )
10133	            (*ndelconss)++;
10134	      }
10135	   }
10136	   else if( ncontvars == 1 )
10137	   {
10138	      SCIP_VAR* var;
10139	
10140	      assert(0 <= contvarpos && contvarpos < consdata->nvars);
10141	      var = vars[contvarpos];
10142	      assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
10143	
10144	      if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
10145	      {
10146	         /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
10147	         if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
10148	         {
10149	            /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10150	            SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
10151	               SCIPconsGetName(cons), SCIPvarGetName(var));
10152	            SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10153	            if( infeasible )
10154	            {
10155	               SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10156	               *cutoff = TRUE;
10157	
10158	               return SCIP_OKAY;
10159	            }
10160	         }
10161	         /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
10162	         /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
10163	         else if( !SCIPdoNotAggr(scip) )
10164	         {
10165	            SCIP_VAR* newvar;
10166	            SCIP_Real absval;
10167	            char newvarname[SCIP_MAXSTRLEN];
10168	            SCIP_Bool redundant;
10169	            SCIP_Bool aggregated;
10170	
10171	            absval = REALABS(vals[contvarpos]);
10172	
10173	            (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
10174	
10175	            /* create new implicit variable for aggregation */
10176	            SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
10177	                  SCIP_VARTYPE_IMPLINT, SCIPvarIsInitial(var), SCIPvarIsRemovable(var), NULL, NULL, NULL, NULL, NULL) );
10178	
10179	            /* add new variable to problem */
10180	            SCIP_CALL( SCIPaddVar(scip, newvar) );
10181	
10182	#ifdef WITH_DEBUG_SOLUTION
10183	            if( SCIPdebugIsMainscip(scip) )
10184	            {
10185	               SCIP_Real varval;
10186	               SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
10187	               SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
10188	            }
10189	#endif
10190	
10191	            /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10192	            SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
10193	               SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
10194	
10195	            /* aggregate continuous and implicit variable */
10196	            SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
10197	
10198	            if( infeasible )
10199	            {
10200	               SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
10201	                  SCIPvarGetName(var), SCIPvarGetName(newvar));
10202	               *cutoff = TRUE;
10203	
10204	               /* release implicit variable */
10205	               SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10206	
10207	               return SCIP_OKAY;
10208	            }
10209	
10210	            /* release implicit variable */
10211	            SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10212	
10213	            if( aggregated )
10214	               (*naggrvars)++;
10215	            else
10216	               return SCIP_OKAY;
10217	         }
10218	
10219	         /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
10220	          * again
10221	          */
10222	         consdata->boundstightened = 0;
10223	         consdata->rangedrowpropagated = 0;
10224	         consdata->presolved = FALSE;
10225	      }
10226	   }
10227	   else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
10228	   {
10229	      SCIP_VAR* var;
10230	
10231	      /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
10232	       *  -> we don't convert integers into implints if the row is a 0/1-row
10233	       */
10234	      assert(varsintegral);
10235	      assert(0 <= intvarpos && intvarpos < consdata->nvars);
10236	      var = vars[intvarpos];
10237	      assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
10238	
10239	      if( coefsintegral
10240	         && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
10241	         && SCIPisFeasIntegral(scip, consdata->rhs) )
10242	      {
10243	         /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
10244	         SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
10245	            SCIPconsGetName(cons), SCIPvarGetName(var));
10246	         SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10247	         if( infeasible )
10248	         {
10249	            SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10250	            *cutoff = TRUE;
10251	
10252	            return SCIP_OKAY;
10253	         }
10254	      }
10255	   }
10256	
10257	   return SCIP_OKAY;
10258	}
10259	
10260	/** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
10261	static
10262	SCIP_Bool checkEqualObjective(
10263	   SCIP*                 scip,               /**< SCIP data structure */
10264	   SCIP_CONSDATA*        consdata,           /**< linear constraint data */
10265	   SCIP_Real*            scale,              /**< pointer to store the scaling factor between the constraint and the
10266						      *   objective function */
10267	   SCIP_Real*            offset              /**< pointer to store the offset of the objective function resulting by
10268						      *   this constraint */
10269	   )
10270	{
10271	   SCIP_VAR** vars;
10272	   SCIP_VAR* var;
10273	   SCIP_Real objval;
10274	   SCIP_Bool negated;
10275	   int nvars;
10276	   int v;
10277	
10278	   vars = consdata->vars;
10279	   nvars = consdata->nvars;
10280	
10281	   assert(vars != NULL);
10282	
10283	   for( v = 0; v < nvars; ++v )
10284	   {
10285	      negated = FALSE;
10286	      var = vars[v];
10287	      assert(var != NULL);
10288	
10289	      if( SCIPvarIsNegated(var) )
10290	      {
10291	         negated = TRUE;
10292	         var = SCIPvarGetNegatedVar(var);
10293	         assert(var != NULL);
10294	      }
10295	
10296	      objval = SCIPvarGetObj(var);
10297	
10298	      /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
10299	       * function
10300	       */
10301	      if( SCIPisZero(scip, objval) )
10302	         return FALSE;
10303	      else
10304	      {
10305	         SCIP_Real val;
10306	
10307	         val = consdata->vals[v];
10308	
10309	         if( negated )
10310	         {
10311	            if( v == 0 )
10312	            {
10313	               /* the first variable defines the scale */
10314	               (*scale) = val / -objval;
10315	
10316	               (*offset) += val;
10317	            }
10318	            else if( SCIPisEQ(scip, -objval * (*scale), val) )
10319	               (*offset) += val;
10320	            else
10321	               return FALSE;
10322	         }
10323	         else if( v == 0 )
10324	         {
10325	            /* the first variable defines the scale */
10326	            (*scale) = val / objval;
10327	         }
10328	         else if( !SCIPisEQ(scip, objval * (*scale), val) )
10329	            return FALSE;
10330	      }
10331	   }
10332	
10333	   return TRUE;
10334	}
10335	
10336	/** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
10337	 *  objective coefficients and add an objective offset
10338	 */
10339	static
10340	SCIP_RETCODE checkPartialObjective(
10341	   SCIP*                 scip,               /**< SCIP data structure */
10342	   SCIP_CONS*            cons,               /**< linear equation constraint */
10343	   SCIP_CONSHDLRDATA*    conshdlrdata        /**< linear constraint handler data */
10344	   )
10345	{
10346	   SCIP_CONSDATA* consdata;
10347	   SCIP_Real offset;
10348	   SCIP_Real scale;
10349	   SCIP_Bool applicable;
10350	   int nobjvars;
10351	   int nvars;
10352	   int v;
10353	
10354	   assert(scip != NULL);
10355	   assert(cons != NULL);
10356	   assert(conshdlrdata != NULL);
10357	
10358	   consdata = SCIPconsGetData(cons);
10359	   assert(consdata != NULL);
10360	   assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
10361	
10362	   nvars = consdata->nvars;
10363	   nobjvars = SCIPgetNObjVars(scip);
10364	
10365	   /* check if the linear equality constraints does not have more variables than the objective function */
10366	   if( nvars > nobjvars || nvars == 0 )
10367	      return SCIP_OKAY;
10368	
10369	   /* check for allowance of algorithm */
10370	   if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
10371	      (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
10372	      return SCIP_OKAY;
10373	
10374	   offset = consdata->rhs;
10375	   scale = 1.0;
10376	
10377	   /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10378	   applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10379	
10380	   if( applicable )
10381	   {
10382	      SCIP_VAR** vars;
10383	
10384	      vars = consdata->vars;
10385	      assert(vars != NULL);
10386	
10387	      offset /= scale;
10388	
10389	      SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
10390	         SCIPconsGetName(cons), consdata->rhs, offset);
10391	
10392	      /* make equality a model constraint to ensure optimality in this direction */
10393	      SCIP_CALL( SCIPsetConsChecked(scip, cons, TRUE) );
10394	      SCIP_CALL( SCIPsetConsEnforced(scip, cons, TRUE) );
10395	
10396	      /* set all objective coefficient to zero */
10397	      for( v = 0; v < nvars; ++v )
10398	      {
10399	         SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
10400	      }
10401	
10402	      /* add an objective offset */
10403	      SCIP_CALL( SCIPaddObjoffset(scip, offset) );
10404	   }
10405	
10406	   return SCIP_OKAY;
10407	}
10408	
10409	/** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
10410	static
10411	SCIP_RETCODE updateCutoffbound(
10412	   SCIP*                 scip,               /**< SCIP data structure */
10413	   SCIP_CONS*            cons,               /**< constraint */
10414	   SCIP_Real             primalbound         /**< feasible primal bound */
10415	   )
10416	{
10417	   SCIP_Real cutoffbound;
10418	
10419	   /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
10420	    * accepted
10421	    */
10422	   cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
10423	
10424	   if( cutoffbound < SCIPgetCutoffbound(scip) )
10425	   {
10426	      SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
10427	
10428	      SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
10429	   }
10430	   else
10431	   {
10432	      SCIP_CONSDATA* consdata;
10433	
10434	      consdata = SCIPconsGetData(cons);
10435	      assert(consdata != NULL);
10436	
10437	      /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
10438	       * resulted from one side
10439	       */
10440	      if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
10441	      {
10442	         /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
10443	          * propagation
10444	          */
10445	         SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
10446	         SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
10447	      }
10448	   }
10449	
10450	   return SCIP_OKAY;
10451	}
10452	
10453	/** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
10454	 *  constraint enters the LP by setting the initial and separated flag to FALSE
10455	 */
10456	static
10457	SCIP_RETCODE checkParallelObjective(
10458	   SCIP*                 scip,               /**< SCIP data structure */
10459	   SCIP_CONS*            cons,               /**< linear constraint */
10460	   SCIP_CONSHDLRDATA*    conshdlrdata        /**< linear constraint handler data */
10461	   )
10462	{
10463	   SCIP_CONSDATA* consdata;
10464	   SCIP_Real offset;
10465	   SCIP_Real scale;
10466	   SCIP_Bool applicable;
10467	   int nobjvars;
10468	   int nvars;
10469	
10470	   assert(scip != NULL);
10471	   assert(cons != NULL);
10472	   assert(conshdlrdata != NULL);
10473	
10474	   consdata = SCIPconsGetData(cons);
10475	   assert(consdata != NULL);
10476	
10477	   /* ignore equalities since these are covered by the method checkPartialObjective() */
10478	   if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10479	      return SCIP_OKAY;
10480	
10481	   nvars = consdata->nvars;
10482	   nobjvars = SCIPgetNObjVars(scip);
10483	
10484	   /* check if the linear inequality constraints has the same number of variables as the objective function and if the
10485	    * initial and/or separated flag is set to FALSE
10486	    */
10487	   if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
10488	      return SCIP_OKAY;
10489	
10490	   offset = 0.0;
10491	   scale = 1.0;
10492	
10493	   /* There are no variables in the objective function and in the constraint. Thus, the constraint is redundant or proves
10494	    * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
10495	    */
10496	   if( nobjvars == 0 )
10497	      return SCIP_OKAY;
10498	
10499	   /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10500	   applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10501	
10502	   if( applicable )
10503	   {
10504	      SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10505	      SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10506	
10507	      assert(scale != 0.0);
10508	
10509	      if( scale > 0.0 )
10510	      {
10511	         if( conshdlrdata->detectcutoffbound && rhsfinite )
10512	         {
10513	            SCIP_Real primalbound;
10514	
10515	            primalbound = (consdata->rhs - offset) / scale;
10516	
10517	            SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10518	               SCIPconsGetName(cons), primalbound);
10519	
10520	            SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10521	         }
10522	
10523	         if( conshdlrdata->detectlowerbound && lhsfinite )
10524	         {
10525	            SCIP_Real lowerbound;
10526	
10527	            lowerbound = (consdata->lhs - offset) / scale;
10528	
10529	            SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10530	               SCIPconsGetName(cons), lowerbound);
10531	
10532	            SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10533	         }
10534	
10535	         if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10536	            (conshdlrdata->detectlowerbound && !rhsfinite) )
10537	         {
10538	            /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10539	            SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10540	            SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10541	         }
10542	      }
10543	      else
10544	      {
10545	         if( conshdlrdata->detectlowerbound && rhsfinite )
10546	         {
10547	            SCIP_Real lowerbound;
10548	
10549	            lowerbound = (consdata->rhs - offset) / scale;
10550	
10551	            SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10552	               SCIPconsGetName(cons), lowerbound);
10553	
10554	            SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10555	         }
10556	
10557	         if( conshdlrdata->detectcutoffbound && lhsfinite )
10558	         {
10559	            SCIP_Real primalbound;
10560	
10561	            primalbound = (consdata->lhs - offset) / scale;
10562	
10563	            SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10564	               SCIPconsGetName(cons), primalbound);
10565	
10566	            SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10567	         }
10568	
10569	         if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10570	            (conshdlrdata->detectlowerbound && !lhsfinite) )
10571	         {
10572	            /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10573	            SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10574	            SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10575	         }
10576	      }
10577	   }
10578	
10579	   return SCIP_OKAY;
10580	}
10581	
10582	/** converts special equalities */
10583	static
10584	SCIP_RETCODE convertEquality(
10585	   SCIP*                 scip,               /**< SCIP data structure */
10586	   SCIP_CONS*            cons,               /**< linear constraint */
10587	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< linear constraint handler data */
10588	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
10589	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
10590	   int*                  naggrvars,          /**< pointer to count number of aggregated variables */
10591	   int*                  ndelconss           /**< pointer to count number of deleted constraints */
10592	   )
10593	{
10594	   SCIP_CONSDATA* consdata;
10595	
10596	   assert(scip != NULL);
10597	   assert(cons != NULL);
10598	   assert(conshdlrdata != NULL);
10599	   assert(cutoff != NULL);
10600	   assert(nfixedvars != NULL);
10601	   assert(naggrvars != NULL);
10602	   assert(ndelconss != NULL);
10603	
10604	   consdata = SCIPconsGetData(cons);
10605	   assert(consdata != NULL);
10606	   assert(consdata->removedfixings);
10607	
10608	   /* do nothing on inequalities */
10609	   if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10610	      return SCIP_OKAY;
10611	
10612	   /* depending on the number of variables, call a special conversion method */
10613	   if( consdata->nvars == 1 )
10614	   {
10615	      /* fix variable */
10616	      SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10617	   }
10618	   else if( consdata->nvars == 2 )
10619	   {
10620	      /* aggregate one of the variables */
10621	      SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10622	   }
10623	   else
10624	   {
10625	      /* check if the equality is part of the objective function */
10626	      SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10627	
10628	      /* try to multi-aggregate one of the variables */
10629	      SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10630	   }
10631	
10632	   return SCIP_OKAY;
10633	}
10634	
10635	/** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10636	 *  integral
10637	 */
10638	static
10639	SCIP_Bool consdataIsResidualIntegral(
10640	   SCIP*                 scip,               /**< SCIP data structure */
10641	   SCIP_CONSDATA*        consdata,           /**< linear constraint */
10642	   int                   pos,                /**< position of variable to be left out */
10643	   SCIP_Real             val                 /**< value to divide the coefficients by */
10644	   )
10645	{
10646	   int v;
10647	
10648	   assert(scip != NULL);
10649	   assert(consdata != NULL);
10650	   assert(0 <= pos && pos < consdata->nvars);
10651	
10652	   for( v = 0; v < consdata->nvars; ++v )
10653	   {
10654	      if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10655	         return FALSE;
10656	   }
10657	
10658	   return TRUE;
10659	}
10660	
10661	/** check if \f$lhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$,
10662	 *  check if \f$rhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$
10663	 */
10664	static
10665	void calculateMinvalAndMaxval(
10666	   SCIP*                 scip,               /**< SCIP data structure */
10667	   SCIP_Real             side,               /**< lhs or rhs */
10668	   SCIP_Real             val,                /**< coefficient */
10669	   SCIP_Real             minresactivity,     /**< minimal residual activity */
10670	   SCIP_Real             maxresactivity,     /**< maximal residual activity */
10671	   SCIP_Real*            minval,             /**< pointer to store calculated minval */
10672	   SCIP_Real*            maxval              /**< pointer to store calculated maxval */
10673	   )
10674	{
10675	   assert(scip != NULL);
10676	   assert(minval != NULL);
10677	   assert(maxval != NULL);
10678	
10679	   if( val > 0.0 )
10680	   {
10681	      if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10682	         *minval = -maxresactivity;
10683	      else
10684	         *minval = (side - maxresactivity)/val;
10685	
10686	      if( SCIPisInfinity(scip, ABS(minresactivity)) )
10687	         *maxval = -minresactivity;
10688	      else
10689	         *maxval = (side - minresactivity)/val;
10690	   }
10691	   else
10692	   {
10693	      if( SCIPisInfinity(scip, ABS(minresactivity)) )
10694	         *minval = minresactivity;
10695	      else
10696	         *minval = (side - minresactivity)/val;
10697	
10698	      if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10699	         *maxval = maxresactivity;
10700	      else
10701	         *maxval = (side - maxresactivity)/val;
10702	   }
10703	}
10704	
10705	
10706	/** applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10707	 *  linear inequality
10708	 */
10709	static
10710	SCIP_RETCODE dualPresolve(
10711	   SCIP*                 scip,               /**< SCIP data structure */
10712	   SCIP_CONSHDLRDATA*    conshdlrdata,       /**< linear constraint handler data */
10713	   SCIP_CONS*            cons,               /**< linear constraint */
10714	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
10715	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
10716	   int*                  naggrvars,          /**< pointer to count number of aggregated variables */
10717	   int*                  ndelconss           /**< pointer to count number of deleted constraints */
10718	   )
10719	{
10720	   SCIP_CONSDATA* consdata;
10721	   SCIP_Bool lhsexists;
10722	   SCIP_Bool rhsexists;
10723	   SCIP_Bool bestisint;
10724	   SCIP_Bool bestislhs;
10725	   SCIP_Real minabsval;
10726	   SCIP_Real maxabsval;
10727	   int bestpos;
10728	   int i;
10729	   int maxotherlocks;
10730	
10731	   assert(scip != NULL);
10732	   assert(cons != NULL);
10733	   assert(cutoff != NULL);
10734	   assert(nfixedvars != NULL);
10735	   assert(naggrvars != NULL);
10736	   assert(ndelconss != NULL);
10737	
10738	   /* only process checked constraints (for which the locks are increased);
10739	    * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10740	    * dualfix presolver
10741	    */
10742	   if( !SCIPconsIsChecked(cons) )
10743	      return SCIP_OKAY;
10744	
10745	   consdata = SCIPconsGetData(cons);
10746	   assert(consdata != NULL);
10747	
10748	   lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10749	   rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10750	
10751	   /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10752	    * can use it safely for aggregation and break the search loop
10753	    */
10754	   bestpos = -1;
10755	   bestisint = TRUE;
10756	   bestislhs = FALSE;
10757	
10758	   /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10759	    * everything else would produce fill-in. Exceptions:
10760	    * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10761	    *   produced.
10762	    * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10763	    *   six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10764	    *   six nonzeros (two variables per substitution).
10765	    * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10766	    *   six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10767	    *   six nonzeros (three variables per substitution). God exists!
10768	    */
10769	   if( consdata->nvars <= 2 )
10770	      maxotherlocks = INT_MAX;
10771	   else if( consdata->nvars == 3 )
10772	      maxotherlocks = 3;
10773	   else if( consdata->nvars == 4 )
10774	      maxotherlocks = 2;
10775	   else
10776	      maxotherlocks = 1;
10777	
10778	   /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10779	   if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
10780	      maxotherlocks++;
10781	
10782	   minabsval = SCIPinfinity(scip);
10783	   maxabsval = -1.0;
10784	   for( i = 0; i < consdata->nvars && bestisint; ++i )
10785	   {
10786	      SCIP_VAR* var;
10787	      SCIP_Bool isint;
10788	      SCIP_Real val;
10789	      SCIP_Real absval;
10790	      SCIP_Real obj;
10791	      SCIP_Real lb;
10792	      SCIP_Real ub;
10793	      SCIP_Bool agglhs;
10794	      SCIP_Bool aggrhs;
10795	
10796	      val = consdata->vals[i];
10797	      absval = REALABS(val);
10798	
10799	      /* calculate minimal and maximal absolute value */
10800	      if( absval < minabsval )
10801	         minabsval = absval;
10802	      if( absval > maxabsval )
10803	         maxabsval = absval;
10804	
10805	      /* do not try to multi aggregate, when numerical bad */
10806	      if( maxabsval / minabsval > conshdlrdata->maxdualmultaggrquot )
10807	         return SCIP_OKAY;
10808	
10809	      var = consdata->vars[i];
10810	      isint = (SCIPvarGetType(var) == SCIP_VARTYPE_BINARY || SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
10811	
10812	      /* if we already found a candidate, skip integers */
10813	      if( bestpos >= 0 && isint )
10814	         continue;
10815	
10816	      /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10817	       * active, fixed, or single-aggregated with another binary variable
10818	       */
10819	      if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10820	         continue;
10821	
10822	      if ( SCIPdoNotMultaggrVar(scip, var) )
10823	         continue;
10824	
10825	      val = consdata->vals[i];
10826	      obj = SCIPvarGetObj(var);
10827	      lb = SCIPvarGetLbGlobal(var);
10828	      ub = SCIPvarGetUbGlobal(var);
10829	
10830	      /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10831	       *
10832	       * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10833	       *  - constraint is the only one that forbids fixing the variable to its lower bound
10834	       *  - fix x_i to the smallest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10835	       *
10836	       * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10837	       *  - constraint is the only one that forbids fixing the variable to its upper bound
10838	       *  - fix x_i to the largest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10839	       *
10840	       * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10841	       *  - constraint is the only one that forbids fixing the variable to its upper bound
10842	       *  - fix x_i to the largest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10843	       *
10844	       * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10845	       *  - constraint is the only one that forbids fixing the variable to its lower bound
10846	       *  - fix x_i to the smallest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10847	       *
10848	       * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10849	       *      of all x_j
10850	       * furthermore: we only want to apply this, if no fill-in will be produced
10851	       */
10852	      agglhs = lhsexists
10853	         && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10854	               && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10855	            || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10856	               && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10857	      aggrhs = rhsexists
10858	         && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10859	               && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10860	            || (val < 0.0 && !SCIPisNegative(scip, obj)  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10861	               && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10862	      if( agglhs || aggrhs )
10863	      {
10864	         SCIP_Real minresactivity;
10865	         SCIP_Real maxresactivity;
10866	         SCIP_Real minval;
10867	         SCIP_Real maxval;
10868	         SCIP_Bool minisrelax;
10869	         SCIP_Bool maxisrelax;
10870	         SCIP_Bool isminsettoinfinity;
10871	         SCIP_Bool ismaxsettoinfinity;
10872	
10873	         /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10874	         consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10875	            &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10876	         assert(SCIPisLE(scip, minresactivity, maxresactivity));
10877	
10878	         /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10879	          * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10880	          * This is needed, because we do not want to rely on relaxed finite resactivities.
10881	          */
10882	         assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10883	
10884	         if( agglhs )
10885	         {
10886	            /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10887	            calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10888	
10889	            assert(SCIPisLE(scip, minval, maxval));
10890	            if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10891	               (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10892	            {
10893	               SCIP_Real oldmaxresactivity;
10894	               SCIP_Real oldminresactivity;
10895	               SCIP_Bool recalculated;
10896	
10897	               recalculated = FALSE;
10898	               oldmaxresactivity = maxresactivity;
10899	               oldminresactivity = minresactivity;
10900	
10901	               /* check minresactivity for reliability */
10902	               if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10903	               {
10904	                  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10905	                  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10906	                  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10907	               }
10908	
10909	               /* check maxresactivity for reliability */
10910	               if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10911	               {
10912	                  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10913	                  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10914	                  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10915	               }
10916	
10917	               /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10918	               if( recalculated )
10919	               {
10920	                  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10921	
10922	                  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10923	                  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10924	
10925	                  assert(SCIPisLE(scip, minval, maxval));
10926	               }
10927	
10928	               if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10929	               {
10930	                  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10931	                   * in the multi-aggregation
10932	                   */
10933	                  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10934	                  {
10935	                     bestpos = i;
10936	                     bestisint = isint;
10937	                     bestislhs = TRUE;
10938	                     continue; /* no need to also look at the right hand side */
10939	                  }
10940	               }
10941	            }
10942	         }
10943	
10944	         if( aggrhs )
10945	         {
10946	            /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10947	            calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10948	
10949	            assert(SCIPisLE(scip,minval,maxval));
10950	            if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10951	               (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10952	            {
10953	               SCIP_Real oldmaxresactivity;
10954	               SCIP_Real oldminresactivity;
10955	               SCIP_Bool recalculated;
10956	
10957	               recalculated = FALSE;
10958	               oldmaxresactivity = maxresactivity;
10959	               oldminresactivity = minresactivity;
10960	
10961	               /* check minresactivity for reliability */
10962	               if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10963	               {
10964	                  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10965	                  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10966	               }
10967	
10968	               /* check maxresactivity for reliability */
10969	               if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10970	               {
10971	                  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10972	                  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10973	               }
10974	
10975	               /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10976	               if( recalculated )
10977	               {
10978	                  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10979	                  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10980	                  assert(SCIPisLE(scip,minval,maxval));
10981	               }
10982	
10983	               if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10984	               {
10985	                  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10986	                   * in the multi-aggregation
10987	                   */
10988	                  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10989	                  {
10990	                     bestpos = i;
10991	                     bestisint = isint;
10992	                     bestislhs = FALSE;
10993	                  }
10994	               }
10995	            }
10996	         }
10997	      }
10998	   }
10999	
11000	   if( bestpos >= 0 )
11001	   {
11002	      SCIP_VAR** aggrvars;
11003	      SCIP_Real* aggrcoefs;
11004	      SCIP_Real aggrconst;
11005	      SCIP_VAR* bestvar;
11006	      SCIP_Real bestval;
11007	      SCIP_Real epsilon;
11008	      int naggrs;
11009	      int j;
11010	      SCIP_Bool infeasible;
11011	      SCIP_Bool aggregated;
11012	      SCIP_Bool samevar;
11013	      int supinf;                            /* counter for infinite contributions to the supremum of a possible
11014	                                              * multi-aggregation
11015	                                              */
11016	      int infinf;                            /* counter for infinite contributions to the infimum of a possible
11017	                                              * multi-aggregation
11018	                                              */
11019	
11020	      assert(!bestislhs || lhsexists);
11021	      assert(bestislhs || rhsexists);
11022	
11023	      bestvar = consdata->vars[bestpos];
11024	      bestval = consdata->vals[bestpos];
11025	      assert(bestisint ==
11026	         (SCIPvarGetType(bestvar) == SCIP_VARTYPE_BINARY || SCIPvarGetType(bestvar) == SCIP_VARTYPE_INTEGER));
11027	
11028	      /* allocate temporary memory */
11029	      SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
11030	      SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
11031	
11032	      /* set up the multi-aggregation */
11033	      SCIPdebugPrintCons(scip, cons, NULL);
11034	      SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
11035	      naggrs = 0;
11036	      supinf = 0;
11037	      infinf = 0;
11038	      samevar = FALSE;
11039	      epsilon = SCIPepsilon(scip);
11040	
11041	      for( j = 0; j < consdata->nvars; ++j )
11042	      {
11043	         if( j != bestpos )
11044	         {
11045	            SCIP_Real absaggrcoef;
11046	
11047	            aggrvars[naggrs] = consdata->vars[j];
11048	            aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
11049	            SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
11050	
11051	            absaggrcoef = REALABS(aggrcoefs[naggrs]);
11052	
11053	            /* do not try to multi aggregate, when numerical bad */
11054	            if( absaggrcoef < epsilon )
11055	            {
11056	               SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
11057	
11058	               /* free temporary memory */
11059	               SCIPfreeBufferArray(scip, &aggrcoefs);
11060	               SCIPfreeBufferArray(scip, &aggrvars);
11061	
11062	               return SCIP_OKAY;
11063	            }
11064	
11065	            if( bestisint )
11066	            {
11067	               /* coefficient must be integral: round it to exact integral value */
11068	               assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
11069	               aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
11070	            }
11071	
11072	            if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
11073	            {
11074	               if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11075	               {
11076	                  ++supinf;
11077	                  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11078	                  {
11079	                     ++infinf;
11080	                     samevar = TRUE;
11081	                  }
11082	               }
11083	               else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11084	                  ++infinf;
11085	            }
11086	            else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
11087	            {
11088	               if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11089	               {
11090	                  ++supinf;
11091	                  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11092	                  {
11093	                     ++infinf;
11094	                     samevar = TRUE;
11095	                  }
11096	               }
11097	               else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11098	                  ++infinf;
11099	            }
11100	
11101	            naggrs++;
11102	         }
11103	      }
11104	      assert(!samevar || (supinf > 0 && infinf > 0));
11105	
11106	      aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
11107	      SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
11108	         SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
11109	      assert(naggrs == consdata->nvars-1);
11110	
11111	      /* right hand side must be integral: round it to exact integral value */
11112	      if( bestisint )
11113	      {
11114	         assert(SCIPisIntegral(scip, aggrconst));
11115	         aggrconst = SCIPfloor(scip, aggrconst+0.5);
11116	      }
11117	
11118	      aggregated = FALSE;
11119	      infeasible = FALSE;
11120	
11121	      /* perform the multi-aggregation */
11122	      if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
11123	      {
11124	         /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
11125	          * also convertLongEquality() early termination due to coefficients
11126	          */
11127	         SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
11128	
11129	         /* if the multi-aggregate bestvar is integer, we need to convert implicit integers to integers because
11130	          *  the implicitness might rely on the constraint and the integrality of bestvar
11131	          */
11132	         if( !infeasible && aggregated && SCIPvarGetType(bestvar) == SCIP_VARTYPE_INTEGER )
11133	         {
11134	            SCIP_Bool infeasiblevartypechg;
11135	
11136	            for( j = 0; j < naggrs; ++j)
11137	            {
11138	               /* If the multi-aggregation was not infeasible, then setting implicit integers to integers should not
11139	                *  lead to infeasibility
11140	                */
11141	               if( SCIPvarGetType(aggrvars[j]) == SCIP_VARTYPE_IMPLINT )
11142	               {
11143	                  SCIP_CALL( SCIPchgVarType(scip, aggrvars[j], SCIP_VARTYPE_INTEGER, &infeasiblevartypechg) );
11144	                  assert(!infeasiblevartypechg);
11145	               }
11146	            }
11147	         }
11148	      }
11149	      else
11150	      {
11151	         /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
11152	          * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
11153	         SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
11154	      }
11155	      /* free temporary memory */
11156	      SCIPfreeBufferArray(scip, &aggrcoefs);
11157	      SCIPfreeBufferArray(scip, &aggrvars);
11158	
11159	      /* check for infeasible aggregation */
11160	      if( infeasible )
11161	      {
11162	         SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
11163	         *cutoff = TRUE;
11164	         return SCIP_OKAY;
11165	      }
11166	
11167	      /* delete the constraint, if the aggregation was successful */
11168	      if( aggregated )
11169	      {
11170	         SCIP_CALL( SCIPdelCons(scip, cons) );
11171	
11172	         if( !consdata->upgraded )
11173	            (*ndelconss)++;
11174	         (*naggrvars)++;
11175	      }
11176	      else
11177	      {
11178	         SCIPdebugMsg(scip, "aggregation non successful!\n");
11179	      }
11180	   }
11181	
11182	   return SCIP_OKAY;
11183	}
11184	
11185	#define BINWEIGHT  1
11186	#define INTWEIGHT  4
11187	#define CONTWEIGHT 8
11188	
11189	/** gets weight for variable in a "weighted number of variables" sum */
11190	static
11191	int getVarWeight(
11192	   SCIP_VAR*             var                 /**< variable to get weight for */
11193	   )
11194	{
11195	   switch( SCIPvarGetType(var) )
11196	   {
11197	   case SCIP_VARTYPE_BINARY:
11198	      return BINWEIGHT;
11199	   case SCIP_VARTYPE_INTEGER:
11200	   case SCIP_VARTYPE_IMPLINT:
11201	      return INTWEIGHT;
11202	   case SCIP_VARTYPE_CONTINUOUS:
11203	      return CONTWEIGHT;
11204	   default:
11205	      SCIPerrorMessage("invalid variable type\n");
11206	      SCIPABORT();
11207	      return 0; /*lint !e527*/
11208	   }
11209	}
11210	
11211	/** tries to aggregate variables in equations a^Tx = lhs
11212	 *  in case there are at most two binary variables with an odd coefficient and all other
11213	 *  variables are not continuous and have an even coefficient then:
11214	 *  - exactly one odd binary variables
11215	 *    this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
11216	 *     - lhs is odd ->  y = 1
11217	 *     - lhs is even -> y = 0
11218	 *  - exactly two odd binary variables
11219	 *    aggregate the two binary variables with odd coefficient
11220	 *     - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11221	 *     - lhs is even -> both have to take the same value -> var1 - var2 = 0
11222	 */
11223	static
11224	SCIP_RETCODE aggregateVariables(
11225	   SCIP*                 scip,               /**< SCIP data structure */
11226	   SCIP_CONS*            cons,               /**< linear constraint */
11227	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
11228	   int*                  nfixedvars,         /**< pointer to count number of fixed variables */
11229	   int*                  naggrvars           /**< pointer to count number of aggregated variables */
11230	   )
11231	{  /*lint --e{715}*/
11232	   SCIP_CONSDATA* consdata;
11233	   SCIP_Bool success;
11234	
11235	   assert( scip != NULL );
11236	   assert( cons != NULL );
11237	
11238	   consdata = SCIPconsGetData(cons);
11239	   assert( consdata != NULL );
11240	
11241	   /* check if the linear constraint is an equation with integral right hand side */
11242	   if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
11243	      return SCIP_OKAY;
11244	
11245	   /* try to fix and aggregated variables until nothing is possible anymore */
11246	   do
11247	   {
11248	      int v;
11249	      int nvars;
11250	      SCIP_VAR** vars;
11251	      SCIP_Real* vals;
11252	      SCIP_Real lhs;
11253	      SCIP_Bool lhsodd;
11254	
11255	      SCIP_Bool infeasible;
11256	      SCIP_Bool fixed;
11257	      SCIP_Bool aggregated;
11258	      SCIP_Bool redundant;
11259	
11260	      SCIP_VAR* var1;
11261	      SCIP_VAR* var2;
11262	      int noddvars;
11263	
11264	      success = FALSE;
11265	
11266	      lhs = consdata->lhs;
11267	      vars = consdata->vars;
11268	      vals = consdata->vals;
11269	      nvars = consdata->nvars;
11270	
11271	      assert( !SCIPisInfinity(scip, ABS(lhs)) );
11272	
11273	      var1 = NULL;
11274	      var2 = NULL;
11275	      noddvars = 0;
11276	
11277	      /* search for binary variables with an odd coefficient */
11278	      for( v = 0; v < nvars && noddvars < 3; ++v )
11279	      {
11280	         SCIP_Longint val;
11281	
11282	         /* all coefficients and variables have to be integral */
11283	         if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11284	            return SCIP_OKAY;
11285	
11286	         val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
11287	         if( val % 2 != 0 )
11288	         {
11289	            /* the odd values have to belong to binary variables */
11290	            if( !SCIPvarIsBinary(vars[v]) )
11291	               return SCIP_OKAY;
11292	
11293	            if( noddvars == 0 )
11294	               var1 = vars[v];
11295	            else
11296	               var2 = vars[v];
11297	
11298	            noddvars++;
11299	         }
11300	      }
11301	
11302	      /* check lhs is odd or even */
11303	      lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
11304	
11305	      if( noddvars == 1 )
11306	      {
11307	         assert( var1 != NULL );
11308	
11309	         SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
11310	            SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
11311	
11312	         SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
11313	
11314	         /* check for infeasibility of fixing */
11315	         if( infeasible )
11316	         {
11317	            SCIPdebugMsg(scip, " -> infeasible fixing\n");
11318	            *cutoff = TRUE;
11319	            return SCIP_OKAY;
11320	         }
11321	
11322	         if( fixed )
11323	         {
11324	            SCIPdebugMsg(scip, " -> feasible fixing\n");
11325	            (*nfixedvars)++;
11326	            success = TRUE;
11327	         }
11328	      }
11329	      else if( noddvars == 2 )
11330	      {
11331	         assert( var1 != NULL );
11332	         assert( var2 != NULL );
11333	
11334	         /* aggregate the two variables with odd coefficient
11335	          * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11336	          * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11337	          */
11338	         SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
11339	            SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
11340	
11341	         SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
11342	               lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
11343	
11344	         /* check for infeasibility of aggregation */
11345	         if( infeasible )
11346	         {
11347	            SCIPdebugMsg(scip, " -> infeasible aggregation\n");
11348	            *cutoff = TRUE;
11349	            return SCIP_OKAY;
11350	         }
11351	
11352	         /* count the aggregation */
11353	         if( aggregated )
11354	         {
11355	            SCIPdebugMsg(scip, " -> feasible aggregation\n");
11356	            (*naggrvars)++;
11357	            success = TRUE;
11358	         }
11359	      }
11360	
11361	      if( success )
11362	      {
11363	         /* apply fixings and aggregation to successfully rerun this presolving step */
11364	         SCIP_CALL( applyFixings(scip, cons, &infeasible) );
11365	
11366	         if( infeasible )
11367	         {
11368	            SCIPdebugMsg(scip, " -> infeasible fixing\n");
11369	            *cutoff = TRUE;
11370	            return SCIP_OKAY;
11371	         }
11372	
11373	         /* normalize constraint */
11374	         SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
11375	
11376	         if( infeasible )
11377	         {
11378	            SCIPdebugMsg(scip, " -> infeasible normalization\n");
11379	            *cutoff = TRUE;
11380	            return SCIP_OKAY;
11381	         }
11382	      }
11383	   }
11384	   while( success );
11385	
11386	   return SCIP_OKAY;
11387	}
11388	
11389	
11390	
11391	/** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
11392	 *  the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
11393	 *  coefficients
11394	 */
11395	static
11396	SCIP_DECL_SORTINDCOMP(consdataCompSim)
11397	{  /*lint --e{715}*/
11398	   SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
11399	   SCIP_VARTYPE vartype1;
11400	   SCIP_VARTYPE vartype2;
11401	   SCIP_Real value;
11402	
11403	   assert(consdata != NULL);
11404	   assert(0 <= ind1 && ind1 < consdata->nvars);
11405	   assert(0 <= ind2 && ind2 < consdata->nvars);
11406	
11407	   vartype1 = SCIPvarGetType(consdata->vars[ind1]);
11408	   vartype2 = SCIPvarGetType(consdata->vars[ind2]);
11409	
11410	   if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
11411	   {
11412	      /* continuous varibles will be sorted to the back */
11413	      if( vartype2 != vartype1 )
11414	         return +1;
11415	      /* both variables are continuous */
11416	      else
11417	         return 0;
11418	   }
11419	   /* continuous variables will be sorted to the back */
11420	   else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
11421	      return -1;
11422	
11423	   value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
11424	
11425	   /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
11426	   return (value > 0 ? +1 : (value < 0 ? -1 : 0));
11427	}
11428	
11429	/** tries to simplify coefficients in ranged row of the form lhs <= a^Tx <= rhs
11430	 *
11431	 *  1. lhs <= a^Tx <= rhs, x binary, lhs > 0, forall a_i >= lhs, a_i <= rhs, and forall pairs a_i + a_j > rhs,
11432	 *     then we can change this constraint to 1^Tx = 1
11433	 */
11434	static
11435	SCIP_RETCODE rangedRowSimplify(
11436	   SCIP*                 scip,               /**< SCIP data structure */
11437	   SCIP_CONS*            cons,               /**< linear constraint */
11438	   int*                  nchgcoefs,          /**< pointer to store the amount of changed coefficients */
11439	   int*                  nchgsides           /**< pointer to store the amount of changed sides */
11440	   )
11441	{
11442	   SCIP_CONSDATA* consdata;
11443	   SCIP_VAR** vars;
11444	   SCIP_Real* vals;
11445	   SCIP_Real minval;
11446	   SCIP_Real secondminval;
11447	   SCIP_Real maxval;
11448	   SCIP_Real lhs;
11449	   SCIP_Real rhs;
11450	   int nvars;
11451	   int v;
11452	
11453	   /* we must not change a modifiable constraint in any way */
11454	   if( SCIPconsIsModifiable(cons) )
11455	      return SCIP_OKAY;
11456	
11457	   if( SCIPconsIsDeleted(cons) )
11458	      return SCIP_OKAY;
11459	
11460	   consdata = SCIPconsGetData(cons);
11461	   assert(consdata != NULL);
11462	
11463	   nvars = consdata->nvars;
11464	
11465	   /* do not check empty or bound-constraints */
11466	   if( nvars < 2 )
11467	      return SCIP_OKAY;
11468	
11469	   lhs = consdata->lhs;
11470	   rhs = consdata->rhs;
11471	   assert(!SCIPisInfinity(scip, -lhs));
11472	   assert(!SCIPisInfinity(scip, rhs));
11473	   assert(!SCIPisNegative(scip, rhs));
11474	
11475	   /* sides must be positive and different to detect set partition */
11476	   if( !SCIPisPositive(scip, lhs) || !SCIPisLT(scip, lhs, rhs) )
11477	      return SCIP_OKAY;
11478	
11479	   vals = consdata->vals;
11480	   vars = consdata->vars;
11481	   assert(vars != NULL);
11482	   assert(vals != NULL);
11483	
11484	   minval = SCIP_INVALID;
11485	   secondminval = SCIP_INVALID;
11486	   maxval = -SCIP_INVALID;
11487	
11488	   for( v = nvars - 1; v >= 0; --v )
11489	   {
11490	      if( SCIPvarIsBinary(vars[v]) )
11491	      {
11492	         if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
11493	         {
11494	            secondminval = minval;
11495	            minval = vals[v];
11496	         }
11497	         else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
11498	            secondminval = vals[v];
11499	
11500	         if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
11501	            maxval = vals[v];
11502	      }
11503	      else
11504	         break;
11505	   }
11506	
11507	   /* check if all variables are binary, we can choose one, and need to choose at most one */
11508	   if( v == -1 && SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs)
11509	      && SCIPisGT(scip, minval + secondminval, rhs) )
11510	   {
11511	      /* change all coefficients to 1.0 */
11512	      for( v = nvars - 1; v >= 0; --v )
11513	      {
11514	         SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
11515	      }
11516	      (*nchgcoefs) += nvars;
11517	
11518	      /* replace old right and left hand side with 1.0 */
11519	      SCIP_CALL( chgRhs(scip, cons, 1.0) );
11520	      SCIP_CALL( chgLhs(scip, cons, 1.0) );
11521	      (*nchgsides) += 2;
11522	   }
11523	
11524	   return SCIP_OKAY;
11525	}
11526	
11527	/** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
11528	 *
11529	 *  for both-sided constraints only @see rangedRowSimplify() will be called
11530	 *
11531	 *  for one-sided constraints there are several different coefficient reduction steps which will be applied
11532	 *
11533	 *  1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
11534	 *
11535	 *     e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
11536	 *
11537	 *  2. We try to remove redundant fractional parts in a constraint
11538	 *
11539	 *     e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3  => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
11540	 *
11541	 *  3. We are using the greatest common divisor for further reductions
11542	 *
11543	 *     e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15  => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
11544	 *          integral
11545	 */
11546	static
11547	SCIP_RETCODE simplifyInequalities(
11548	   SCIP*                 scip,               /**< SCIP data structure */
11549	   SCIP_CONS*            cons,               /**< linear constraint */
11550	   int*                  nchgcoefs,          /**< pointer to store the amount of changed coefficients */
11551	   int*                  nchgsides,          /**< pointer to store the amount of changed sides */
11552	   SCIP_Bool*            infeasible          /**< pointer to store whether infeasibility was detected */
11553	   )
11554	{
11555	   SCIP_CONSDATA* consdata;
11556	   SCIP_VAR** vars;
11557	   SCIP_Real* vals;
11558	   int* perm;
11559	   SCIP_Real minactsub;
11560	   SCIP_Real maxactsub;
11561	   SCIP_Real siderest;
11562	   SCIP_Real feastol;
11563	   SCIP_Real newcoef;
11564	   SCIP_Real absval;
11565	   SCIP_Real minact;
11566	   SCIP_Real maxact;
11567	   SCIP_Real side;
11568	   SCIP_Real lhs;
11569	   SCIP_Real rhs;
11570	   SCIP_Real lb;
11571	   SCIP_Real ub;
11572	   SCIP_Longint restcoef;
11573	   SCIP_Longint oldgcd;
11574	   SCIP_Longint rest;
11575	   SCIP_Longint gcd;
11576	   SCIP_Bool isminsettoinfinity;
11577	   SCIP_Bool ismaxsettoinfinity;
11578	   SCIP_Bool isminrelax;
11579	   SCIP_Bool ismaxrelax;
11580	   SCIP_Bool allcoefintegral;
11581	   SCIP_Bool onlybin;
11582	   SCIP_Bool hasrhs;
11583	   SCIP_Bool haslhs;
11584	   int oldnchgcoefs;
11585	   int oldnchgsides;
11586	   int foundbin;
11587	   int candpos;
11588	   int candpos2;
11589	   int offsetv;
11590	   int nvars;
11591	   int v;
11592	   int w;
11593	
11594	   assert(scip != NULL);
11595	   assert(cons != NULL);
11596	   assert(nchgcoefs != NULL);
11597	   assert(nchgsides != NULL);
11598	
11599	   *infeasible = FALSE;
11600	
11601	   /* we must not change a modifiable constraint in any way */
11602	   if( SCIPconsIsModifiable(cons) )
11603	      return SCIP_OKAY;
11604	
11605	   if( SCIPconsIsDeleted(cons) )
11606	      return SCIP_OKAY;
11607	
11608	   consdata = SCIPconsGetData(cons);
11609	   assert(consdata != NULL);
11610	
11611	   nvars = consdata->nvars;
11612	
11613	   /* do not check empty or bound-constraints */
11614	   if( nvars <= 2 )
11615	      return SCIP_OKAY;
11616	
11617	   /* update maximal activity delta if necessary */
11618	   if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11619	      consdataRecomputeMaxActivityDelta(scip, consdata);
11620	
11621	   assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11622	   assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11623	   checkMaxActivityDelta(scip, consdata);
11624	
11625	   /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11626	    *       accordingly
11627	    */
11628	   /* can only work with valid non-infinity activities per variable */
11629	   if( SCIPisInfinity(scip, consdata->maxactdelta) )
11630	      return SCIP_OKAY;
11631	
11632	   /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11633	    *        but the eventsystem seems to be full
11634	    */
11635	   consdata->normalized = FALSE;
11636	
11637	   /* normalize constraint */
11638	   SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11639	   assert(nvars == consdata->nvars);
11640	
11641	   if( *infeasible )
11642	      return SCIP_OKAY;
11643	
11644	   if( !consdata->normalized )
11645	      return SCIP_OKAY;
11646	
11647	   lhs = consdata->lhs;
11648	   rhs = consdata->rhs;
11649	   assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11650	   assert(!SCIPisNegative(scip, rhs));
11651	
11652	   if( !SCIPisInfinity(scip, -lhs) )
11653	      haslhs = TRUE;
11654	   else
11655	      haslhs = FALSE;
11656	
11657	   if( !SCIPisInfinity(scip, rhs) )
11658	      hasrhs = TRUE;
11659	   else
11660	      hasrhs = FALSE;
11661	
11662	   SCIPdebug( oldnchgcoefs = *nchgcoefs; )
11663	   SCIPdebug( oldnchgsides = *nchgsides; )
11664	
11665	   /* @todo extend both-sided simplification */
11666	   if( haslhs && hasrhs )
11667	   {
11668	      SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11669	
11670	      return SCIP_OKAY;
11671	   }
11672	   assert(haslhs != hasrhs);
11673	
11674	   /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11675	   assert(!hasrhs || !SCIPisNegative(scip, rhs));
11676	   assert(!haslhs || !SCIPisNegative(scip, lhs));
11677	
11678	   /* get temporary memory to store the sorted permutation */
11679	   SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11680	
11681	   /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11682	    * value of their coefficients
11683	    */
11684	   SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11685	
11686	   /* perform sorting after permutation array */
11687	   permSortConsdata(consdata, perm, nvars);
11688	   consdata->indexsorted = FALSE;
11689	   consdata->coefsorted = FALSE;
11690	
11691	   vars = consdata->vars;
11692	   vals = consdata->vals;
11693	   assert(vars != NULL);
11694	   assert(vals != NULL);
11695	   assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11696	
11697	   /* free temporary memory */
11698	   SCIPfreeBufferArray(scip, &perm);
11699	
11700	   /* only check constraints with at least two non continuous variables */
11701	   if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11702	      return SCIP_OKAY;
11703	
11704	   /* do not process constraints when all coefficients are 1.0 */
11705	   if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11706	      return SCIP_OKAY;
11707	
11708	   feastol = SCIPfeastol(scip);
11709	
11710	   SCIPdebugMsg(scip, "starting simplification of coefficients\n");
11711	   SCIPdebugPrintCons(scip, cons, NULL);
11712	
11713	   /* get global activities */
11714	   consdataGetGlbActivityBounds(scip, consdata, FALSE, &minact, &maxact,
11715	      &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11716	
11717	   /* cannot work with infinite activities */
11718	   if( isminsettoinfinity || ismaxsettoinfinity )
11719	      return SCIP_OKAY;
11720	
11721	   assert(!isminrelax);
11722	   assert(!ismaxrelax);
11723	   assert(maxact > minact);
11724	   assert(!SCIPisInfinity(scip, -minact));
11725	   assert(!SCIPisInfinity(scip, maxact));
11726	
11727	   v = 0;
11728	   offsetv = -1;
11729	   side = haslhs ? lhs : rhs;
11730	   minactsub = minact;
11731	   maxactsub = maxact;
11732	
11733	   /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11734	    * do not need to look at the large coefficients
11735	    *
11736	    * e.g.  all x are binary, z are positive integer
11737	    *       c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5   (x5 is redundant and does not change (in-)feasibility of this constraint)
11738	    *       c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4   (gcd (without the coefficient of x5) after the large coefficients is 3
11739	    *       c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11740	    *
11741	    *       can be changed to
11742	    *
11743	    *       c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6        (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11744	    *       c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6  (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11745	    *       c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11746	    */
11747	
11748	   /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11749	    * hand side, we cannot apply the extra reduction step and need to reset v
11750	    *
11751	    * e.g. 7x1 + 7x2 - 4x3 - 4x4 >= 7 => xi = 1 for all i is not a solution, but if we would do a change on the
11752	    *      coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11753	    *      for all i is a solution
11754	    *
11755	    * also redundancy of variables would not be correctly determined in such a case
11756	    */
11757	   if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11758	   {
11759	      v = 1;
11760	
11761	      while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11762	      {
11763	         /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11764	          * extra step, which might have worked
11765	          */
11766	         if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11767	         {
11768	            v = 0;
11769	            break;
11770	         }
11771	
11772	         ++v;
11773	      }
11774	
11775	      /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11776	      /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11777	      if( v == nvars )
11778	         return SCIP_OKAY;
11779	
11780	      /* cannot work with continuous variables which have a big coefficient */
11781	      if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11782	         return SCIP_OKAY;
11783	
11784	      /* big negative coefficient, do not try to use the extra coefficient reduction step */
11785	      if( SCIPisEQ(scip, side, -vals[v]) )
11786	         v = 0;
11787	
11788	      /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11789	       * reduction
11790	       */
11791	      if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11792	         v = 0;
11793	
11794	      if( v > 0 )
11795	      {
11796	         assert(v < nvars);
11797	
11798	         offsetv = v - 1;
11799	
11800	         for( w = 0; w < v; ++w )
11801	         {
11802	            lb = SCIPvarGetLbGlobal(vars[w]);
11803	            ub = SCIPvarGetUbGlobal(vars[w]);
11804	
11805	            assert(vals[w] > 0);
11806	
11807	            /* update residual activities */
11808	            maxactsub -= ub * vals[w];
11809	            minactsub -= lb * vals[w];
11810	            assert(maxactsub > minactsub);
11811	         }
11812	      }
11813	   }
11814	
11815	   /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11816	    *
11817	    * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11818	    *
11819	    *        15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11820	    * to
11821	    *        15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11822	    */
11823	   if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11824	   {
11825	      SCIP_Bool redundant = FALSE;
11826	      SCIP_Bool numericsok;
11827	      SCIP_Bool rredundant;
11828	      SCIP_Bool lredundant;
11829	
11830	      gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11831	      assert(gcd >= 1);
11832	
11833	      if( v == 0 )
11834	      {
11835	         lb = SCIPvarGetLbGlobal(vars[0]);
11836	         ub = SCIPvarGetUbGlobal(vars[0]);
11837	
11838	         /* update residual activities */
11839	         if( vals[0] > 0 )
11840	         {
11841	            maxactsub -= ub * vals[0];
11842	            minactsub -= lb * vals[0];
11843	         }
11844	         else
11845	         {
11846	            maxactsub -= lb * vals[0];
11847	            minactsub -= ub * vals[0];
11848	         }
11849	         assert(maxactsub > minactsub);
11850	         ++v;
11851	      }
11852	
11853	      siderest = -SCIP_INVALID;
11854	      allcoefintegral = TRUE;
11855	
11856	      /* check if some variables always fit into the given constraint */
11857	      for( ; v < nvars - 1; ++v )
11858	      {
11859	         if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11860	            break;
11861	
11862	         if( !SCIPisIntegral(scip, vals[v]) )
11863	         {
11864	            allcoefintegral = FALSE;
11865	            break;
11866	         }
11867	
11868	         /* calculate greatest common divisor for all general and binary variables */
11869	         gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11870	
11871	         if( gcd == 1 )
11872	            break;
11873	
11874	         lb = SCIPvarGetLbGlobal(vars[v]);
11875	         ub = SCIPvarGetUbGlobal(vars[v]);
11876	
11877	         assert(!SCIPisInfinity(scip, -lb));
11878	         assert(!SCIPisInfinity(scip, ub));
11879	
11880	         /* update residual activities */
11881	         if( vals[v] > 0 )
11882	         {
11883	            maxactsub -= ub * vals[v];
11884	            minactsub -= lb * vals[v];
11885	         }
11886	         else
11887	         {
11888	            maxactsub -= lb * vals[v];
11889	            minactsub -= ub * vals[v];
11890	         }
11891	         assert(SCIPisGE(scip, maxactsub, minactsub));
11892	
11893	         if( hasrhs )
11894	         {
11895	            /* determine the remainder of the right hand side and the gcd */
11896	            siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11897	         }
11898	         else
11899	         {
11900	            /* determine the remainder of the left hand side and the gcd */
11901	            siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11902	            if( SCIPisZero(scip, siderest) )
11903	               siderest = gcd;
11904	         }
11905	
11906	         rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
11907	         lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11908	
11909	         /* early termination if the activities deceed the gcd */
11910	         if( offsetv == -1 && (rredundant || lredundant) )
11911	         {
11912	            redundant = TRUE;
11913	            break;
11914	         }
11915	      }
11916	      assert(v < nvars || (offsetv >= 0 && gcd > 1));
11917	
11918	      if( !redundant )
11919	      {
11920	         if( hasrhs )
11921	         {
11922	            /* determine the remainder of the right hand side and the gcd */
11923	            siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11924	         }
11925	         else
11926	         {
11927	            /* determine the remainder of the left hand side and the gcd */
11928	            siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11929	            if( SCIPisZero(scip, siderest) )
11930	               siderest = gcd;
11931	         }
11932	      }
11933	      else
11934	         ++v;
11935	
11936	      SCIPdebugMsg(scip, "stopped at pos %d (of %d), subactivities [%g, %g], redundant = %u, hasrhs = %u, siderest = %g, gcd = %" SCIP_LONGINT_FORMAT ", offset position for 'side' coefficients = %d\n",
11937	            v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11938	
11939	      /* to avoid inconsistencies due to numerics, check that the full and partial activities have
11940	       * reasonable absolute values */
11941	      numericsok = REALABS(maxact) < MAXACTVAL && REALABS(maxactsub) < MAXACTVAL && REALABS(minact) < MAXACTVAL &&
11942	            REALABS(minactsub) < MAXACTVAL;
11943	
11944	      rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
11945	      lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11946	
11947	      /* check if we can remove redundant variables */
11948	      if( v < nvars && numericsok && (redundant || (offsetv == -1 && (rredundant || lredundant))) )
11949	      {
11950	         SCIP_Real oldcoef;
11951	
11952	         /* double check the redundancy */
11953	#ifndef NDEBUG
11954	         SCIP_Real tmpminactsub = 0.0;
11955	         SCIP_Real tmpmaxactsub = 0.0;
11956	
11957	         /* recompute residual activities */
11958	         for( w = v; w < nvars; ++w )
11959	         {
11960	            lb = SCIPvarGetLbGlobal(vars[w]);
11961	            ub = SCIPvarGetUbGlobal(vars[w]);
11962	
11963	            assert(!SCIPisInfinity(scip, -lb));
11964	            assert(!SCIPisInfinity(scip, ub));
11965	
11966	            /* update residual activities */
11967	            if( vals[w] > 0 )
11968	            {
11969	               tmpmaxactsub += ub * vals[w];
11970	               tmpminactsub += lb * vals[w];
11971	            }
11972	            else
11973	            {
11974	               tmpmaxactsub += lb * vals[w];
11975	               tmpminactsub += ub * vals[w];
11976	            }
11977	            assert(tmpmaxactsub >= tmpminactsub);
11978	         }
11979	
11980	         if( hasrhs )
11981	         {
11982	            assert(offsetv == -1);
11983	
11984	            /* determine the remainder of the right hand side and the gcd */
11985	            siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11986	         }
11987	         else
11988	         {
11989	            /* determine the remainder of the left hand side and the gcd */
11990	            siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11991	            if( SCIPisZero(scip, siderest) )
11992	               siderest = gcd;
11993	         }
11994	
11995	         /* is the redundancy really fulfilled */
11996	         assert((hasrhs && SCIPisFeasLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) ||
11997	               (haslhs && tmpmaxactsub < siderest && SCIPisFeasGE(scip, tmpminactsub, siderest - gcd)));
11998	#endif
11999	
12000	         SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
12001	            nvars - v, SCIPconsGetName(cons));
12002	
12003	         /* remove redundant variables */
12004	         for( w = nvars - 1; w >= v; --w )
12005	         {
12006	            SCIP_CALL( delCoefPos(scip, cons, w) );
12007	         }
12008	         (*nchgcoefs) += (nvars - v);
12009	
12010	         assert(w >= 0);
12011	
12012	         oldcoef = vals[w];
12013	
12014	         /* normalize constraint */
12015	         SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12016	         assert(vars == consdata->vars);
12017	         assert(vals == consdata->vals);
12018	         assert(w < consdata->nvars);
12019	
12020	         if( *infeasible )
12021	            return SCIP_OKAY;
12022	
12023	         /* compute new greatest common divisor due to normalization */
12024	         gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
12025	         assert(gcd >= 1);
12026	
12027	         /* update side */
12028	         if( hasrhs )
12029	         {
12030	            /* replace old with new right hand side */
12031	            SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
12032	            rhs = consdata->rhs;
12033	         }
12034	         else
12035	         {
12036	            if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
12037	            {
12038	               SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
12039	               lhs = consdata->lhs;
12040	            }
12041	            else
12042	               assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
12043	         }
12044	         ++(*nchgsides);
12045	
12046	         assert(!hasrhs || !SCIPisNegative(scip, rhs));
12047	         assert(!haslhs || !SCIPisNegative(scip, lhs));
12048	
12049	         /* get new constraint data */
12050	         nvars = consdata->nvars;
12051	         assert(nvars > 0);
12052	
12053	         allcoefintegral = TRUE;
12054	
12055	#ifndef NDEBUG
12056	         /* check integrality */
12057	         for( w = offsetv + 1; w < nvars; ++w )
12058	         {
12059	            assert(SCIPisIntegral(scip, vals[w]));
12060	         }
12061	#endif
12062	         SCIPdebugPrintCons(scip, cons, NULL);
12063	      }
12064	
12065	      /* try to find a better gcd, when having large coefficients */
12066	      if( offsetv >= 0 && gcd == 1 )
12067	      {
12068	         /* calculate greatest common divisor for all general variables */
12069	         gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
12070	
12071	         if( gcd > 1 )
12072	         {
12073	            gcd = -1;
12074	            candpos = -1;
12075	
12076	            for( v = nvars - 1; v > offsetv; --v )
12077	            {
12078	               assert(!SCIPisZero(scip, vals[v]));
12079	               if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
12080	                  break;
12081	
12082	               if( !SCIPisIntegral(scip, vals[v]) )
12083	               {
12084	                  allcoefintegral = FALSE;
12085	                  break;
12086	               }
12087	
12088	               oldgcd = gcd;
12089	
12090	               if( gcd == -1 )
12091	               {
12092	                  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12093	                  assert(gcd >= 1);
12094	               }
12095	               else
12096	               {
12097	                  /* calculate greatest common divisor for all general and binary variables */
12098	                  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12099	               }
12100	
12101	               /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12102	                * can stop searching
12103	                */
12104	               if( gcd == 1 )
12105	               {
12106	                  if( !SCIPvarIsBinary(vars[v]) )
12107	                     break;
12108	
12109	                  /* found candidate */
12110	                  if( candpos == -1 )
12111	                  {
12112	                     gcd = oldgcd;
12113	                     candpos = v;
12114	                  }
12115	                  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12116	                  else
12117	                     break;
12118	               }
12119	            }
12120	            assert(v > offsetv || candpos > offsetv);
12121	         }
12122	         else
12123	            candpos = -1;
12124	      }
12125	      else
12126	         candpos = nvars - 1;
12127	
12128	      /* check last coefficient for integrality */
12129	      if( gcd > 1 && allcoefintegral && !redundant )
12130	      {
12131	         if( !SCIPisIntegral(scip, vals[nvars - 1]) )
12132	            allcoefintegral = FALSE;
12133	      }
12134	
12135	      /* check for further necessary coefficient adjustments */
12136	      if( offsetv >= 0 && gcd > 1 && allcoefintegral )
12137	      {
12138	         assert(offsetv + 1 < nvars);
12139	         assert(0 <= candpos && candpos < nvars);
12140	
12141	         if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
12142	         {
12143	            SCIP_Bool notchangable = FALSE;
12144	
12145	#ifndef NDEBUG
12146	            /* check integrality */
12147	            for( w = offsetv + 1; w < nvars; ++w )
12148	            {
12149	               assert(SCIPisIntegral(scip, vals[w]));
12150	            }
12151	#endif
12152	
12153	            if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
12154	               SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
12155	            {
12156	               /* determine the remainder of the side and the gcd */
12157	               if( hasrhs )
12158	                  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12159	               else
12160	                  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12161	               assert(rest >= 0);
12162	               assert(rest < gcd);
12163	
12164	               /* determine the remainder of the coefficient candidate and the gcd */
12165	               restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12166	               assert(restcoef >= 1);
12167	               assert(restcoef < gcd);
12168	
12169	               if( hasrhs )
12170	               {
12171	                  /* calculate new coefficient */
12172	                  if( restcoef > rest )
12173	                     newcoef = vals[candpos] - restcoef + gcd;
12174	                  else
12175	                     newcoef = vals[candpos] - restcoef;
12176	               }
12177	               else
12178	               {
12179	                  /* calculate new coefficient */
12180	                  if( rest == 0 || restcoef < rest )
12181	                     newcoef = vals[candpos] - restcoef;
12182	                  else
12183	                     newcoef = vals[candpos] - restcoef + gcd;
12184	               }
12185	
12186	               /* done */
12187	
12188	               /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
12189	                * another with the big coefficient was set to 1
12190	                */
12191	               if( hasrhs && SCIPisZero(scip, newcoef) )
12192	               {
12193	                  notchangable = TRUE;
12194	               }
12195	               else if( SCIPisZero(scip, newcoef) )
12196	               {
12197	                  /* delete old redundant coefficient */
12198	                  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12199	                  ++(*nchgcoefs);
12200	               }
12201	               else
12202	               {
12203	                  /* replace old with new coefficient */
12204	                  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12205	                  ++(*nchgcoefs);
12206	               }
12207	            }
12208	            else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
12209	            {
12210	               gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
12211	            }
12212	
12213	            /* correct side and big coefficients */
12214	            if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
12215	               ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
12216	            {
12217	               if( haslhs )
12218	               {
12219	                  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
12220	
12221	                  SCIP_CALL( chgLhs(scip, cons, newcoef) );
12222	                  ++(*nchgsides);
12223	               }
12224	               else
12225	               {
12226	                  assert(hasrhs);
12227	                  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
12228	
12229	                  SCIP_CALL( chgRhs(scip, cons, newcoef) );
12230	                  ++(*nchgsides);
12231	               }
12232	
12233	               /* correct coefficients up front */
12234	               for( w = offsetv; w >= 0; --w )
12235	               {
12236	                  assert(vals[w] > 0);
12237	
12238	                  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
12239	               }
12240	               (*nchgcoefs) += (offsetv + 1);
12241	            }
12242	
12243	            if( !notchangable )
12244	            {
12245	               /* normalize constraint */
12246	               SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12247	               assert(vars == consdata->vars);
12248	               assert(vals == consdata->vals);
12249	
12250	               if( *infeasible )
12251	                  return SCIP_OKAY;
12252	
12253	               /* get new constraint data */
12254	               nvars = consdata->nvars;
12255	               assert(nvars >= 2);
12256	
12257	               SCIPdebugPrintCons(scip, cons, NULL);
12258	
12259	               lhs = consdata->lhs;
12260	               rhs = consdata->rhs;
12261	               assert(!hasrhs || !SCIPisNegative(scip, rhs));
12262	               assert(!haslhs || !SCIPisNegative(scip, lhs));
12263	            }
12264	         }
12265	      }
12266	   }
12267	
12268	   /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
12269	   /* no continuous variables are left over */
12270	   if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
12271	      return SCIP_OKAY;
12272	
12273	   onlybin = TRUE;
12274	   allcoefintegral = TRUE;
12275	   /* check if all variables are of binary type */
12276	   for( v = nvars - 1; v >= 0; --v )
12277	   {
12278	      if( !SCIPvarIsBinary(vars[v]) )
12279	         onlybin = FALSE;
12280	      if( !SCIPisIntegral(scip, vals[v]) )
12281	         allcoefintegral = FALSE;
12282	   }
12283	
12284	   /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
12285	    * hand side or bigger than the left hand side respectively, so we can make all of them integral
12286	    *
12287	    * @todo there are some steps missing ....
12288	    */
12289	   if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
12290	   {
12291	      SCIP_Real val;
12292	      SCIP_Real newval;
12293	      SCIP_Real frac = 0.0;
12294	      SCIP_Bool found = FALSE;
12295	
12296	      if( hasrhs )
12297	      {
12298	         if( allcoefintegral )
12299	         {
12300	            /* replace old with new right hand side */
12301	            SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12302	            ++(*nchgsides);
12303	         }
12304	         else
12305	         {
12306	            siderest = rhs - SCIPfloor(scip, rhs);
12307	
12308	            /* try to round down all non-integral coefficients */
12309	            for( v = nvars - 1; v >= 0; --v )
12310	            {
12311	               val = vals[v];
12312	
12313	               /* add up all possible fractional parts */
12314	               if( !SCIPisIntegral(scip, val) )
12315	               {
12316	                  lb = SCIPvarGetLbGlobal(vars[v]);
12317	                  ub = SCIPvarGetUbGlobal(vars[v]);
12318	
12319	                  /* at least one bound need to be at zero */
12320	                  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12321	                     return SCIP_OKAY;
12322	
12323	                  /* swap bounds for 'standard' form */
12324	                  if( !SCIPisFeasZero(scip, lb) )
12325	                  {
12326	                     ub = lb;
12327	                     val *= -1;
12328	                  }
12329	
12330	                  found = TRUE;
12331	
12332	                  frac += (val - SCIPfloor(scip, val)) * ub;
12333	
12334	                  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
12335	                   *
12336	                   * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
12337	                   *      x3, x4 set to 1 would be infeasible but feasible after flooring
12338	                   */
12339	                  if( SCIPisGT(scip, frac, siderest) )
12340	                     return SCIP_OKAY;
12341	               }
12342	            }
12343	            assert(v == -1);
12344	
12345	            SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
12346	
12347	            /* round rhs and coefficients to integral values */
12348	            if( found )
12349	            {
12350	               for( v = nvars - 1; v >= 0; --v )
12351	               {
12352	                  val = vals[v];
12353	
12354	                  /* add the whole fractional part */
12355	                  if( !SCIPisIntegral(scip, val) )
12356	                  {
12357	                     lb = SCIPvarGetLbGlobal(vars[v]);
12358	
12359	                     if( SCIPisFeasZero(scip, lb) )
12360	                        newval = SCIPfloor(scip, val);
12361	                     else
12362	                        newval = SCIPceil(scip, val);
12363	
12364	                     if( SCIPisZero(scip, newval) )
12365	                     {
12366	                        /* delete old redundant coefficient */
12367	                        SCIP_CALL( delCoefPos(scip, cons, v) );
12368	                        ++(*nchgcoefs);
12369	                     }
12370	                     else
12371	                     {
12372	                        /* replace old with new coefficient */
12373	                        SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12374	                        ++(*nchgcoefs);
12375	                     }
12376	                  }
12377	               }
12378	            }
12379	
12380	            /* replace old with new right hand side */
12381	            SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12382	            ++(*nchgsides);
12383	         }
12384	      }
12385	      else
12386	      {
12387	         if( allcoefintegral )
12388	         {
12389	            /* replace old with new left hand side */
12390	            SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
12391	            ++(*nchgsides);
12392	         }
12393	         else
12394	         {
12395	            /* cannot floor left hand side to zero */
12396	            if( SCIPisLT(scip, lhs, 1.0) )
12397	               return SCIP_OKAY;
12398	
12399	            siderest = lhs - SCIPfloor(scip, lhs);
12400	
12401	            /* try to round down all non-integral coefficients */
12402	            for( v = nvars - 1; v >= 0; --v )
12403	            {
12404	               val = vals[v];
12405	
12406	               /* add up all possible fractional parts */
12407	               if( !SCIPisIntegral(scip, val) )
12408	               {
12409	                  lb = SCIPvarGetLbGlobal(vars[v]);
12410	                  ub = SCIPvarGetUbGlobal(vars[v]);
12411	
12412	                  /* at least one bound need to be at zero */
12413	                  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12414	                     return SCIP_OKAY;
12415	
12416	                  /* swap bounds for 'standard' form */
12417	                  if( !SCIPisFeasZero(scip, lb) )
12418	                  {
12419	                     ub = lb;
12420	                     val *= -1;
12421	                  }
12422	
12423	                  /* cannot floor to zero */
12424	                  if( SCIPisLT(scip, val, 1.0) )
12425	                     return SCIP_OKAY;
12426	
12427	                  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
12428	                  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
12429	                     return SCIP_OKAY;
12430	
12431	                  found = TRUE;
12432	
12433	                  frac += (val - SCIPfloor(scip, val)) * ub;
12434	
12435	                  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
12436	                   * fractional parts of the variables, we cannot tighten the coefficients
12437	                   *
12438	                   * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
12439	                   *      x2-x4 set to 1 would be feasible but not after flooring
12440	                   */
12441	                  if( SCIPisGE(scip, frac, 1 + siderest) )
12442	                     return SCIP_OKAY;
12443	               }
12444	               /* all coefficients need to be integral, otherwise we might do an invalid reduction */
12445	               else
12446	                  return SCIP_OKAY;
12447	            }
12448	            assert(v == -1);
12449	
12450	            SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
12451	
12452	            /* round lhs and coefficients to integral values */
12453	            if( found )
12454	            {
12455	               for( v = nvars - 1; v >= 0; --v )
12456	               {
12457	                  val = vals[v];
12458	
12459	                  /* add the whole fractional part */
12460	                  if( !SCIPisIntegral(scip, val) )
12461	                  {
12462	                     lb = SCIPvarGetLbGlobal(vars[v]);
12463	
12464	                     if( SCIPisFeasZero(scip, lb) )
12465	                        newval = SCIPfloor(scip, val);
12466	                     else
12467	                        newval = SCIPceil(scip, val);
12468	
12469	                     if( SCIPisZero(scip, newval) )
12470	                     {
12471	                        /* delete old redundant coefficient */
12472	                        SCIP_CALL( delCoefPos(scip, cons, v) );
12473	                        ++(*nchgcoefs);
12474	                     }
12475	                     else
12476	                     {
12477	                        /* replace old with new coefficient */
12478	                        SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12479	                        ++(*nchgcoefs);
12480	                     }
12481	                  }
12482	               }
12483	            }
12484	
12485	            /* replace old with new left hand side */
12486	            SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
12487	            ++(*nchgsides);
12488	         }
12489	      }
12490	
12491	      /* normalize constraint */
12492	      SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12493	      assert(vars == consdata->vars);
12494	      assert(vals == consdata->vals);
12495	
12496	      if( *infeasible )
12497	         return SCIP_OKAY;
12498	
12499	      rhs = consdata->rhs;
12500	      lhs = consdata->lhs;
12501	
12502	      assert(!hasrhs || !SCIPisNegative(scip, rhs));
12503	      assert(!haslhs || !SCIPisNegative(scip, lhs));
12504	
12505	      SCIPdebugPrintCons(scip, cons, NULL);
12506	
12507	      nvars = consdata->nvars;
12508	      if( nvars < 2 )
12509	         return SCIP_OKAY;
12510	
12511	      allcoefintegral = TRUE;
12512	#ifndef NDEBUG
12513	      /* debug check if all coefficients are really integral */
12514	      for( v = nvars - 1; v >= 0; --v )
12515	         assert(SCIPisIntegral(scip, vals[v]));
12516	#endif
12517	   }
12518	
12519	   /* @todo following can also work on non integral coefficients, need more investigation */
12520	   /* only check constraints with integral coefficients on all integral variables */
12521	   if( !allcoefintegral )
12522	      return SCIP_OKAY;
12523	
12524	   /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
12525	   if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
12526	      return SCIP_OKAY;
12527	
12528	   /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
12529	   if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
12530	      return SCIP_OKAY;
12531	
12532	   /* stop if the last coeffcients is one in absolute value and the variable is not binary */
12533	   if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
12534	      return SCIP_OKAY;
12535	
12536	   assert(nvars >= 2);
12537	
12538	   /* start gcd procedure for all variables */
12539	   do
12540	   {
12541	      SCIPdebug( oldnchgcoefs = *nchgcoefs; )
12542	      SCIPdebug( oldnchgsides = *nchgsides; )
12543	
12544	      /* stop if we have two coeffcients which are one in absolute value */
12545	      if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
12546	         return SCIP_OKAY;
12547	
12548	      gcd = -1;
12549	
12550	      /* calculate greatest common divisor over all integer variables; note that the onlybin flag needs to be recomputed
12551	       * because coefficients of non-binary variables might have changed to zero */
12552	      if( !onlybin )
12553	      {
12554	         foundbin = -1;
12555	         onlybin = TRUE;
12556	
12557	         for( v = nvars - 1; v >= 0; --v )
12558	         {
12559	            assert(!SCIPisZero(scip, vals[v]));
12560	            assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
12561	
12562	            if( SCIPvarIsBinary(vars[v]) )
12563	            {
12564	               if( foundbin == -1 )
12565	                  foundbin = v;
12566	               continue;
12567	            }
12568	            else
12569	               onlybin = FALSE;
12570	
12571	            absval = REALABS(vals[v]);
12572	            /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12573	             * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12574	             */
12575	            assert(SCIPisFeasIntegral(scip, absval));
12576	
12577	            if( gcd == -1 )
12578	            {
12579	               gcd = (SCIP_Longint)(absval + feastol);
12580	               assert(gcd >= 1);
12581	            }
12582	            else
12583	            {
12584	               /* calculate greatest common divisor for all general variables */
12585	               gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
12586	            }
12587	            if( gcd == 1 )
12588	               break;
12589	         }
12590	      }
12591	      else
12592	         foundbin = nvars - 1;
12593	
12594	      /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
12595	      if( gcd == 1 || foundbin == -1)
12596	         return SCIP_OKAY;
12597	
12598	      assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
12599	
12600	      candpos = -1;
12601	      candpos2 = -1;
12602	
12603	      /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
12604	       * change the coefficient
12605	       */
12606	      for( v = foundbin; v >= 0; --v )
12607	      {
12608	         if( onlybin || SCIPvarIsBinary(vars[v]) )
12609	         {
12610	            absval = REALABS(vals[v]);
12611	            /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12612	             * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12613	             */
12614	            assert(SCIPisFeasIntegral(scip, absval));
12615	
12616	            oldgcd = gcd;
12617	
12618	            if( gcd == -1 )
12619	            {
12620	               gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12621	               assert(gcd >= 1);
12622	            }
12623	            else
12624	            {
12625	               /* calculate greatest common divisor for all general and binary variables */
12626	               gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12627	            }
12628	
12629	            /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12630	             * can terminate
12631	             */
12632	            if( gcd == 1 )
12633	            {
12634	               /* found candidate */
12635	               if( candpos == -1 )
12636	               {
12637	                  gcd = oldgcd;
12638	                  candpos = v;
12639	
12640	                  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12641	                   * the coefficient change
12642	                   */
12643	                  if( onlybin && v == foundbin - 1 )
12644	                     candpos2 = foundbin;
12645	               }
12646	               /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12647	               else
12648	               {
12649	                  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12650	                  {
12651	                     assert(candpos2 == nvars - 1);
12652	
12653	                     /* take new candidates */
12654	                     candpos = candpos2;
12655	
12656	                     /* recalculate gcd from scratch */
12657	                     gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12658	                     assert(gcd >= 1);
12659	
12660	                     /* calculate greatest common divisor for all general and binary variables */
12661	                     gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12662	                     if( gcd == 1 )
12663	                        return SCIP_OKAY;
12664	                  }
12665	                  else
12666	                     /* cannot determine a possible coefficient for reduction */
12667	                     return SCIP_OKAY;
12668	               }
12669	            }
12670	         }
12671	      }
12672	      assert(gcd >= 2);
12673	
12674	      /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12675	       * further
12676	       */
12677	      assert(candpos >= 0 && candpos < nvars);
12678	
12679	      /* all variables and all coefficients are integral, so the side should be too */
12680	      assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12681	
12682	      /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12683	       * @see normalizeCons()
12684	       */
12685	      assert(!hasrhs || !SCIPisNegative(scip, rhs));
12686	      assert(!haslhs || !SCIPisNegative(scip, lhs));
12687	
12688	      /* determine the remainder of the side and the gcd */
12689	      if( hasrhs )
12690	         rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12691	      else
12692	         rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12693	      assert(rest >= 0);
12694	      assert(rest < gcd);
12695	
12696	      /* determine the remainder of the coefficient candidate and the gcd */
12697	      if( vals[candpos] < 0 )
12698	      {
12699	         restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12700	         assert(restcoef <= -1);
12701	         restcoef += gcd;
12702	      }
12703	      else
12704	         restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12705	      assert(restcoef >= 1);
12706	      assert(restcoef < gcd);
12707	
12708	      if( hasrhs )
12709	      {
12710	         if( rest > 0 )
12711	         {
12712	            /* replace old with new right hand side */
12713	            SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12714	            ++(*nchgsides);
12715	         }
12716	
12717	         /* calculate new coefficient */
12718	         if( restcoef > rest )
12719	            newcoef = vals[candpos] - restcoef + gcd;
12720	         else
12721	            newcoef = vals[candpos] - restcoef;
12722	      }
12723	      else
12724	      {
12725	         if( rest > 0 )
12726	         {
12727	            /* replace old with new left hand side */
12728	            SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12729	            ++(*nchgsides);
12730	         }
12731	
12732	         /* calculate new coefficient */
12733	         if( rest == 0 || restcoef < rest )
12734	            newcoef = vals[candpos] - restcoef;
12735	         else
12736	            newcoef = vals[candpos] - restcoef + gcd;
12737	      }
12738	      assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12739	
12740	      SCIPdebugMsg(scip, "gcd = %" SCIP_LONGINT_FORMAT ", rest = %" SCIP_LONGINT_FORMAT ", restcoef = %" SCIP_LONGINT_FORMAT "; changing coef of variable <%s> to %g and %s by %" SCIP_LONGINT_FORMAT "\n", gcd, rest, restcoef, SCIPvarGetName(vars[candpos]), newcoef, hasrhs ? "reduced rhs" : "increased lhs", hasrhs ? rest : (rest > 0 ? gcd - rest : 0));
12741	
12742	      if( SCIPisZero(scip, newcoef) )
12743	      {
12744	         /* delete redundant coefficient */
12745	         SCIP_CALL( delCoefPos(scip, cons, candpos) );
12746	      }
12747	      else
12748	      {
12749	         /* replace old with new coefficient */
12750	         SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12751	      }
12752	      ++(*nchgcoefs);
12753	
12754	      /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12755	      SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12756	      assert(vars == consdata->vars);
12757	      assert(vals == consdata->vals);
12758	
12759	      if( *infeasible )
12760	         return SCIP_OKAY;
12761	
12762	      SCIPdebugPrintCons(scip, cons, NULL);
12763	
12764	      rhs = consdata->rhs;
12765	      lhs = consdata->lhs;
12766	      assert(!hasrhs || !SCIPisNegative(scip, rhs));
12767	      assert(!haslhs || !SCIPisNegative(scip, lhs));
12768	
12769	      nvars = consdata->nvars;
12770	
12771	      SCIPdebugMsg(scip, "we did %d coefficient changes and %d side changes on constraint %s when applying one round of the gcd algorithm\n", *nchgcoefs - oldnchgcoefs, *nchgsides - oldnchgsides, SCIPconsGetName(cons));
12772	   }
12773	   while( nvars >= 2 );
12774	
12775	   return SCIP_OKAY;
12776	}
12777	
12778	
12779	/** tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12780	 *   cons0 := a * cons0 + b * cons1,
12781	 *  where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12782	 *  for numerical stability, we will only accept integral a and b;
12783	 *  the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12784	 *  each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12785	 */
12786	static
12787	SCIP_RETCODE aggregateConstraints(
12788	   SCIP*                 scip,               /**< SCIP data structure */
12789	   SCIP_CONS*            cons0,              /**< (in)equality to modify */
12790	   SCIP_CONS*            cons1,              /**< equality to use for aggregation of cons0 */
12791	   int*                  commonidx0,         /**< array with indices of variables in cons0, that appear also in cons1 */
12792	   int*                  commonidx1,         /**< array with indices of variables in cons1, that appear also in cons0 */
12793	   int*                  diffidx0minus1,     /**< array with indices of variables in cons0, that don't appear in cons1 */
12794	   int*                  diffidx1minus0,     /**< array with indices of variables in cons1, that don't appear in cons0 */
12795	   int                   nvarscommon,        /**< number of variables, that appear in both constraints */
12796	   int                   commonidxweight,    /**< variable weight sum of common variables */
12797	   int                   diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12798	   int                   diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12799	   SCIP_Real             maxaggrnormscale,   /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12800	   int*                  nchgcoefs,          /**< pointer to count the number of changed coefficients */
12801	   SCIP_Bool*            aggregated,         /**< pointer to store whether an aggregation was made */
12802	   SCIP_Bool*            infeasible          /**< pointer to store whether infeasibility was detected */
12803	   )
12804	{
12805	   SCIP_CONSDATA* consdata0;
12806	   SCIP_CONSDATA* consdata1;
12807	   SCIP_Real a;
12808	   SCIP_Real b;
12809	   SCIP_Real aggrcoef;
12810	   SCIP_Real scalarsum;
12811	   SCIP_Real bestscalarsum;
12812	   SCIP_Bool betterscalarsum;
12813	   SCIP_Bool commonvarlindependent;  /* indicates whether coefficient vector of common variables in linearly dependent */
12814	   int varweight;
12815	   int nvars;
12816	   int bestvarweight;
12817	   int bestnvars;
12818	   int bestv;
12819	   int v;
12820	   int i;
12821	
12822	   assert(scip != NULL);
12823	   assert(cons0 != NULL);
12824	   assert(cons1 != NULL);
12825	   assert(commonidx0 != NULL);
12826	   assert(commonidx1 != NULL);
12827	   assert(diffidx0minus1 != NULL);
12828	   assert(diffidx1minus0 != NULL);
12829	   assert(nvarscommon >= 1);
12830	   assert(commonidxweight >= nvarscommon);
12831	   assert(nchgcoefs != NULL);
12832	   assert(aggregated != NULL);
12833	
12834	   assert(SCIPconsIsActive(cons0));
12835	   assert(SCIPconsIsActive(cons1));
12836	
12837	   *infeasible = FALSE;
12838	
12839	   SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12840	
12841	   /* cons0 is an (in)equality */
12842	   consdata0 = SCIPconsGetData(cons0);
12843	   assert(consdata0 != NULL);
12844	   assert(consdata0->nvars >= 1);
12845	   assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12846	   assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12847	
12848	   /* cons1 is an equality */
12849	   consdata1 = SCIPconsGetData(cons1);
12850	   assert(consdata1 != NULL);
12851	   assert(consdata1->nvars >= 1);
12852	   assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12853	   assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12854	
12855	   *aggregated = FALSE;
12856	
12857	   /* search for the best common variable such that
12858	    *   val1[var] * consdata0 - val0[var] * consdata1
12859	    * has least weighted number of variables
12860	    */
12861	   bestvarweight = commonidxweight + diffidx0minus1weight;
12862	   bestnvars = consdata0->nvars;
12863	   bestv = -1;
12864	   bestscalarsum = 0.0;
12865	   commonvarlindependent = TRUE;
12866	   for( v = 0; v < nvarscommon; ++v )
12867	   {
12868	      assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12869	      a = consdata1->vals[commonidx1[v]];
12870	      b = -consdata0->vals[commonidx0[v]];
12871	
12872	      /* only try aggregation, if coefficients are integral (numerical stability) */
12873	      if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12874	      {
12875	         /* count the number of variables in the potential new constraint  a * consdata0 + b * consdata1 */
12876	         varweight = diffidx0minus1weight + diffidx1minus0weight;
12877	         nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12878	         scalarsum = REALABS(a) + REALABS(b);
12879	         betterscalarsum = (scalarsum < bestscalarsum);
12880	         for( i = 0; i < nvarscommon
12881	                 && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12882	         {
12883	            aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12884	            if( !SCIPisZero(scip, aggrcoef) )
12885	            {
12886	               varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12887	               nvars++;
12888	            }
12889	         }
12890	         if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12891	         {
12892	            bestv = v;
12893	            bestvarweight = varweight;
12894	            bestnvars = nvars;
12895	            bestscalarsum = scalarsum;
12896	         }
12897	      }
12898	
12899	      /* update commonvarlindependent flag, if still TRUE:
12900	       * v's common coefficient in cons1 / v's common coefficient in cons0 should be constant, i.e., equal 0's common coefficient in cons1 / 0's common coefficient in cons0
12901	       */
12902	      if( commonvarlindependent && v > 0 )
12903	         commonvarlindependent = SCIPisEQ(scip,
12904	            consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12905	            consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12906	   }
12907	
12908	   /* if better aggregation was found, create new constraint and delete old one */
12909	   if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12910	   {
12911	      SCIP_CONS* newcons;
12912	      SCIP_CONSDATA* newconsdata;
12913	      SCIP_VAR** newvars;
12914	      SCIP_Real* newvals;
12915	      SCIP_Real newlhs;
12916	      SCIP_Real newrhs;
12917	      int newnvars;
12918	
12919	      if( bestv != -1 )
12920	      {
12921	         /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12922	         if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12923	         {
12924	            a = consdata1->vals[commonidx1[bestv]];
12925	            b = -consdata0->vals[commonidx0[bestv]];
12926	         }
12927	         else
12928	         {
12929	            a = -consdata1->vals[commonidx1[bestv]];
12930	            b = consdata0->vals[commonidx0[bestv]];
12931	         }
12932	         assert(SCIPisIntegral(scip, a));
12933	         assert(SCIPisPositive(scip, a));
12934	         assert(SCIPisIntegral(scip, b));
12935	         assert(!SCIPisZero(scip, b));
12936	      }
12937	      else
12938	      {
12939	         assert(commonvarlindependent);
12940	         if( consdata1->vals[commonidx1[0]] > 0.0 )
12941	         {
12942	            a =  consdata1->vals[commonidx1[0]];
12943	            b = -consdata0->vals[commonidx0[0]];
12944	         }
12945	         else
12946	         {
12947	            a = -consdata1->vals[commonidx1[0]];
12948	            b =  consdata0->vals[commonidx0[0]];
12949	         }
12950	         assert(SCIPisPositive(scip, a));
12951	         assert(!SCIPisZero(scip, b));
12952	
12953	         /* if a/b is integral, then we can easily choose integer multipliers */
12954	         if( SCIPisIntegral(scip, a/b) )
12955	         {
12956	            if( a/b > 0 )
12957	            {
12958	               a /= b;
12959	               b = 1.0;
12960	            }
12961	            else
12962	            {
12963	               a /= -b;
12964	               b = -1.0;
12965	            }
12966	         }
12967	
12968	         /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12969	         SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
12970	         bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12971	      }
12972	
12973	      SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s>  ->  nvars: %d -> %d, weight: %d -> %d\n",
12974	         SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12975	         consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12976	      SCIPdebugPrintCons(scip, cons0, NULL);
12977	      SCIPdebugPrintCons(scip, cons1, NULL);
12978	
12979	      /* get temporary memory for creating the new linear constraint */
12980	      SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12981	      SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12982	
12983	      /* calculate the common coefficients, if we have not recognized linear dependency */
12984	      newnvars = 0;
12985	      if( !commonvarlindependent )
12986	      {
12987	         for( i = 0; i < nvarscommon; ++i )
12988	         {
12989	            assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12990	            assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12991	
12992	            aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12993	            if( !SCIPisZero(scip, aggrcoef) )
12994	            {
12995	               assert(newnvars < bestnvars);
12996	               newvars[newnvars] = consdata0->vars[commonidx0[i]];
12997	               newvals[newnvars] = aggrcoef;
12998	               newnvars++;
12999	            }
13000	         }
13001	      }
13002	      else
13003	      {
13004	         /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
13005	#ifndef NDEBUG
13006	         for( i = 0; i < nvarscommon; ++i )
13007	         {
13008	            assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
13009	            assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
13010	
13011	            aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
13012	            assert(SCIPisZero(scip, aggrcoef));
13013	         }
13014	#endif
13015	      }
13016	
13017	      /* calculate the coefficients appearing in cons0 but not in cons1 */
13018	      for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
13019	      {
13020	         assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
13021	
13022	         aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
13023	         assert(!SCIPisZero(scip, aggrcoef));
13024	         assert(newnvars < bestnvars);
13025	         newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
13026	         newvals[newnvars] = aggrcoef;
13027	         newnvars++;
13028	      }
13029	
13030	      /* calculate the coefficients appearing in cons1 but not in cons0 */
13031	      for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
13032	      {
13033	         assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
13034	
13035	         aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
13036	         assert(!SCIPisZero(scip, aggrcoef));
13037	         assert(newnvars < bestnvars);
13038	         newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
13039	         newvals[newnvars] = aggrcoef;
13040	         newnvars++;
13041	      }
13042	      assert(newnvars == bestnvars);
13043	
13044	      /* calculate the new left and right hand side of the (in)equality */
13045	      assert(!SCIPisInfinity(scip, -consdata1->lhs));
13046	      assert(!SCIPisInfinity(scip, consdata1->rhs));
13047	      if( SCIPisInfinity(scip, -consdata0->lhs) )
13048	         newlhs = -SCIPinfinity(scip);
13049	      else
13050	         newlhs = a * consdata0->lhs + b * consdata1->lhs;
13051	      if( SCIPisInfinity(scip, consdata0->rhs) )
13052	         newrhs = SCIPinfinity(scip);
13053	      else
13054	         newrhs = a * consdata0->rhs + b * consdata1->rhs;
13055	
13056	      /* create the new linear constraint */
13057	      SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
13058	            SCIPconsIsInitial(cons0), SCIPconsIsSeparated(cons0), SCIPconsIsEnforced(cons0),
13059	            SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
13060	            SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
13061	            SCIPconsIsDynamic(cons0), SCIPconsIsRemovable(cons0), SCIPconsIsStickingAtNode(cons0)) );
13062	
13063	      newconsdata = SCIPconsGetData(newcons);
13064	      assert(newconsdata != NULL);
13065	
13066	      /* copy the upgraded flag from the old cons0 to the new constraint */
13067	      newconsdata->upgraded = consdata0->upgraded;
13068	
13069	      /* normalize the new constraint */
13070	      SCIP_CALL( normalizeCons(scip, newcons, infeasible) );
13071	
13072	      if( *infeasible )
13073	         goto TERMINATE;
13074	
13075	      /* check, if we really want to use the new constraint instead of the old one:
13076	       * use the new one, if the maximum norm doesn't grow too much
13077	       */
13078	      if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
13079	      {
13080	         SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
13081	         SCIPdebugPrintCons(scip, newcons, NULL);
13082	
13083	         /* update the statistics: we changed all coefficients */
13084	         if( !consdata0->upgraded )
13085	            (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
13086	         *aggregated = TRUE;
13087	
13088	         /* delete the old constraint, and add the new linear constraint to the problem */
13089	         SCIP_CALL( SCIPdelCons(scip, cons0) );
13090	         SCIP_CALL( SCIPaddCons(scip, newcons) );
13091	      }
13092	
13093	     TERMINATE:
13094	      /* release the new constraint */
13095	      SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
13096	
13097	      /* free temporary memory */
13098	      SCIPfreeBufferArray(scip, &newvals);
13099	      SCIPfreeBufferArray(scip, &newvars);
13100	   }
13101	
13102	   return SCIP_OKAY;
13103	}
13104	
13105	/** gets the key of the given element */
13106	static
13107	SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
13108	{  /*lint --e{715}*/
13109	   /* the key is the element itself */
13110	   return elem;
13111	}
13112	
13113	/** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
13114	 *  coefficients are either equal or negated
13115	 */
13116	static
13117	SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
13118	{
13119	   SCIP* scip;
13120	   SCIP_CONSDATA* consdata1;
13121	   SCIP_CONSDATA* consdata2;
13122	   SCIP_Real cons1scale;
13123	   SCIP_Real cons2scale;
13124	   int i;
13125	
13126	   assert(key1 != NULL);
13127	   assert(key2 != NULL);
13128	   consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
13129	   consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
13130	   assert(consdata1->indexsorted);
13131	   assert(consdata2->indexsorted);
13132	
13133	   scip = (SCIP*)userptr;
13134	   assert(scip != NULL);
13135	
13136	   /* if it is the same constraint we dont need to check anything */
13137	   if( key1 == key2 )
13138	      return TRUE;
13139	
13140	   /* checks trivial case */
13141	   if( consdata1->nvars != consdata2->nvars )
13142	      return FALSE;
13143	
13144	   /* tests if variables are equal */
13145	   for( i = 0; i < consdata1->nvars; ++i )
13146	   {
13147	      if( consdata1->vars[i] != consdata2->vars[i] )
13148	      {
13149	         assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
13150	            SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
13151	         return FALSE;
13152	      }
13153	      assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
13154	   }
13155	
13156	   /* compute scale before comparing coefficients of constraints */
13157	   cons1scale = COPYSIGN(1.0/consdata1->maxabsval, consdata1->vals[0]);
13158	   cons2scale = COPYSIGN(1.0/consdata2->maxabsval, consdata2->vals[0]);
13159	
13160	   /* tests if coefficients are equal with the computed scale */
13161	   for( i = 0; i < consdata1->nvars; ++i )
13162	   {
13163	      SCIP_Real val1;
13164	      SCIP_Real val2;
13165	
13166	      val1 = consdata1->vals[i] * cons1scale;
13167	      val2 = consdata2->vals[i] * cons2scale;
13168	
13169	      if( !SCIPisEQ(scip, val1, val2) )
13170	         return FALSE;
13171	   }
13172	
13173	   return TRUE;
13174	}
13175	
13176	/** returns the hash value of the key */
13177	static
13178	SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
13179	{
13180	   SCIP_CONSDATA* consdata;
13181	   int minidx;
13182	   int mididx;
13183	   int maxidx;
13184	   SCIP_Real scale;
13185	#ifndef NDEBUG
13186	   SCIP* scip;
13187	
13188	   scip = (SCIP*)userptr;
13189	   assert(scip != NULL);
13190	#endif
13191	
13192	   assert(key != NULL);
13193	   consdata = SCIPconsGetData((SCIP_CONS*)key);
13194	   assert(consdata != NULL);
13195	   assert(consdata->nvars > 0);
13196	
13197	   assert(consdata->indexsorted);
13198	
13199	   minidx = SCIPvarGetIndex(consdata->vars[0]);
13200	   mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
13201	   maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
13202	   scale = COPYSIGN(1.0/consdata->maxabsval, consdata->vals[0]);
13203	
13204	   /* using only the variable indices as hash, since the values are compared by epsilon */
13205	   return SCIPhashSeven(consdata->nvars, minidx, SCIPrealHashCode(consdata->vals[0] * scale),
13206	                        mididx, SCIPrealHashCode(consdata->vals[consdata->nvars / 2] * scale),
13207	                        maxidx, SCIPrealHashCode(consdata->vals[consdata->nvars - 1] * scale));
13208	}
13209	
13210	/** returns the key for deciding which of two parallel constraints should be kept (smaller key should be kept);
13211	 *  prefers non-upgraded constraints and as second criterion the constraint with the smallest position
13212	 */
13213	static
13214	unsigned int getParallelConsKey(
13215	   SCIP_CONS*            cons                /**< linear constraint */
13216	   )
13217	{
13218	   SCIP_CONSDATA* consdata;
13219	
13220	   assert(cons != NULL);
13221	
13222	   consdata = SCIPconsGetData(cons);
13223	   assert(consdata != NULL);
13224	
13225	   return (((unsigned int)consdata->upgraded)<<31) + (unsigned int)SCIPconsGetPos(cons); /*lint !e571*/
13226	}
13227	
13228	/** updates the hashtable such that out of all constraints in the hashtable that are detected
13229	 *  to be parallel to *querycons, only one is kept in the hashtable and stored into *querycons,
13230	 *  and all others are removed from the hashtable and stored in the given array
13231	 */
13232	static
13233	SCIP_RETCODE retrieveParallelConstraints(
13234	   SCIP_HASHTABLE*       hashtable,          /**< hashtable containing linear constraints */
13235	   SCIP_CONS**           querycons,          /**< pointer to linear constraint used to look for duplicates in the hash table;
13236	                                              *   upon return will contain the constraint that should be kept */
13237	   SCIP_CONS**           parallelconss,      /**< array to return constraints that are parallel to the given;
13238	                                              *   these constraints where removed from the hashtable */
13239	   int*                  nparallelconss      /**< pointer to return number of parallel constraints */
13240	   )
13241	{
13242	   SCIP_CONS* parallelcons;
13243	   unsigned int querykey;
13244	
13245	   *nparallelconss = 0;
13246	   querykey = getParallelConsKey(*querycons);
13247	
13248	   while( (parallelcons = (SCIP_CONS*)SCIPhashtableRetrieve(hashtable, (void*)(*querycons))) != NULL )
13249	   {
13250	      unsigned int conskey = getParallelConsKey(parallelcons);
13251	
13252	      if( conskey < querykey )
13253	      {
13254	         parallelconss[(*nparallelconss)++] = *querycons;
13255	         *querycons = parallelcons;
13256	         querykey = conskey;
13257	      }
13258	      else
13259	      {
13260	         parallelconss[(*nparallelconss)++] = parallelcons;
13261	      }
13262	
13263	      /* if the constraint that just came out of the hash table is the one that is kept,
13264	       * we do not need to look into the hashtable again, since the invariant is that
13265	       * in the hashtable only pair-wise non-parallel constraints are contained.
13266	       * For the original querycons, however, multiple constraints that compare equal (=parallel)
13267	       * could be contained due to non-transitivity of the equality comparison.
13268	       * Also we can return immediately, since parallelcons is already contained in the
13269	       * hashtable and we do not need to remove and reinsert it.
13270	       */
13271	      if( *querycons == parallelcons )
13272	         return SCIP_OKAY;
13273	
13274	      /* remove parallelcons from the hashtable, since it will be replaced by querycons */
13275	      SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) parallelcons) );
13276	   }
13277	
13278	   /* in debug mode we make sure, that the hashtable cannot contain a constraint that
13279	    * comnpares equal to querycons at this point
13280	    */
13281	#ifndef NDEBUG
13282	   SCIP_CALL_ABORT( SCIPhashtableSafeInsert(hashtable, *querycons) );
13283	#else
13284	   SCIP_CALL( SCIPhashtableInsert(hashtable, *querycons) );
13285	#endif
13286	
13287	   return SCIP_OKAY;
13288	}
13289	
13290	/** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
13291	 *  accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
13292	 */
13293	static
13294	SCIP_RETCODE detectRedundantConstraints(
13295	   SCIP*                 scip,               /**< SCIP data structure */
13296	   BMS_BLKMEM*           blkmem,             /**< block memory */
13297	   SCIP_CONS**           conss,              /**< constraint set */
13298	   int                   nconss,             /**< number of constraints in constraint set */
13299	   int*                  firstchange,        /**< pointer to store first changed constraint */
13300	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
13301	   int*                  ndelconss,          /**< pointer to count number of deleted constraints */
13302	   int*                  nchgsides           /**< pointer to count number of changed left/right hand sides */
13303	   )
13304	{
13305	   SCIP_HASHTABLE* hashtable;
13306	   SCIP_CONS** parallelconss;
13307	   int nparallelconss;
13308	   int hashtablesize;
13309	   int c;
13310	
13311	   assert(scip != NULL);
13312	   assert(blkmem != NULL);
13313	   assert(conss != NULL);
13314	   assert(firstchange != NULL);
13315	   assert(cutoff != NULL);
13316	   assert(ndelconss != NULL);
13317	   assert(nchgsides != NULL);
13318	
13319	   /* create a hash table for the constraint set */
13320	   hashtablesize = nconss;
13321	   SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
13322	         hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
13323	
13324	   SCIP_CALL( SCIPallocBufferArray(scip, &parallelconss, nconss) );
13325	
13326	   /* check all constraints in the given set for redundancy */
13327	   for( c = 0; c < nconss; ++c )
13328	   {
13329	      SCIP_CONS* cons0;
13330	      SCIP_CONSDATA* consdata0;
13331	
13332	      cons0 = conss[c];
13333	
13334	      if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
13335	         continue;
13336	
13337	      /* do not check for parallel constraints if they should not be upgraded */
13338	      if ( SCIPconsGetNUpgradeLocks(cons0) > 0 )
13339	         continue;
13340	
13341	      /* check for interuption */
13342	      if( c % 1000 == 0 && SCIPisStopped(scip) )
13343	         break;
13344	
13345	      /* sorts the constraint */
13346	      consdata0 = SCIPconsGetData(cons0);
13347	      assert(consdata0 != NULL);
13348	      SCIP_CALL( consdataSort(scip, consdata0) );
13349	      assert(consdata0->indexsorted);
13350	
13351	      /* get constraints from current hash table with same variables as cons0 and with coefficients equal
13352	       * to the ones of cons0 when both are scaled such that maxabsval is 1.0 and the coefficient of the
13353	       * first variable is positive
13354	       * Also inserts cons0 into the hashtable.
13355	       */
13356	      SCIP_CALL( retrieveParallelConstraints(hashtable, &cons0, parallelconss, &nparallelconss) );
13357	
13358	      if( nparallelconss != 0 )
13359	      {
13360	         SCIP_Real lhs;
13361	         SCIP_Real rhs;
13362	
13363	         int i;
13364	
13365	         /* cons0 may have been changed in retrieveParallelConstraints() */
13366	         consdata0 = SCIPconsGetData(cons0);
13367	
13368	         lhs = consdata0->lhs;
13369	         rhs = consdata0->rhs;
13370	
13371	         for( i = 0; i < nparallelconss; ++i )
13372	         {
13373	            SCIP_CONS* consdel;
13374	            SCIP_CONSDATA* consdatadel;
13375	            SCIP_Real scale;
13376	
13377	            consdel = parallelconss[i];
13378	            consdatadel = SCIPconsGetData(consdel);
13379	
13380	            /* do not delete constraint if it should not be upgraded */
13381	            if ( SCIPconsGetNUpgradeLocks(consdel) > 0 )
13382	               continue;
13383	
13384	            assert(SCIPconsIsActive(consdel));
13385	            assert(!SCIPconsIsModifiable(consdel));
13386	
13387	            /* constraint found: create a new constraint with same coefficients and best left and right hand side;
13388	             * delete old constraints afterwards
13389	             */
13390	            assert(consdatadel != NULL);
13391	            assert(consdata0->nvars >= 1 && consdata0->nvars == consdatadel->nvars);
13392	
13393	            assert(consdatadel->indexsorted);
13394	            assert(consdata0->vars[0] == consdatadel->vars[0]);
13395	
13396	            scale = consdata0->vals[0] / consdatadel->vals[0];
13397	            assert(scale != 0.0);
13398	
13399	            /* in debug mode, check that all coefficients are equal with respect to epsilon
13400	             * if the constraints are in equilibrium scale
13401	             */
13402	#ifndef NDEBUG
13403	            {
13404	               int k;
13405	               SCIP_Real scale0 = 1.0 / consdata0->maxabsval;
13406	               SCIP_Real scaledel = COPYSIGN(1.0 / consdatadel->maxabsval, scale);
13407	
13408	               for( k = 0; k < consdata0->nvars; ++k )
13409	               {
13410	                  assert(SCIPisEQ(scip, scale0 * consdata0->vals[k], scaledel * consdatadel->vals[k]));
13411	               }
13412	            }
13413	#endif
13414	
13415	            if( scale > 0.0 )
13416	            {
13417	               /* the coefficients of both constraints are parallel with a positive scale */
13418	               SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
13419	                            SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13420	               SCIPdebugPrintCons(scip, cons0, NULL);
13421	               SCIPdebugPrintCons(scip, consdel, NULL);
13422	
13423	               if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13424	                  lhs = MAX(scale * consdatadel->lhs, lhs);
13425	
13426	               if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13427	                  rhs = MIN(scale * consdatadel->rhs, rhs);
13428	            }
13429	            else
13430	            {
13431	               /* the coefficients of both rows are negations */
13432	               SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
13433	                            SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13434	               SCIPdebugPrintCons(scip, cons0, NULL);
13435	               SCIPdebugPrintCons(scip, consdel, NULL);
13436	
13437	               if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13438	                  lhs = MAX(scale * consdatadel->rhs, lhs);
13439	
13440	               if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13441	                  rhs = MIN(scale * consdatadel->lhs, rhs);
13442	            }
13443	
13444	            /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13445	            SCIP_CALL( SCIPupdateConsFlags(scip, cons0, consdel) );
13446	
13447	            /* delete consdel */
13448	            assert( ! consdata0->upgraded || consdatadel->upgraded );
13449	            SCIP_CALL( SCIPdelCons(scip, consdel) );
13450	            if( !consdatadel->upgraded )
13451	               (*ndelconss)++;
13452	         }
13453	
13454	         if( SCIPisFeasLT(scip, rhs, lhs) )
13455	         {
13456	            SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13457	            *cutoff = TRUE;
13458	            break;
13459	         }
13460	
13461	         /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
13462	         if( lhs > rhs )
13463	         {
13464	            rhs = (lhs + rhs)/2;
13465	            lhs = rhs;
13466	         }
13467	
13468	         /* update lhs and rhs of cons0 */
13469	         SCIP_CALL( chgLhs(scip, cons0, lhs) );
13470	         SCIP_CALL( chgRhs(scip, cons0, rhs) );
13471	
13472	         /* update the first changed constraint to begin the next aggregation round with */
13473	         if( consdata0->changed && SCIPconsGetPos(cons0) < *firstchange )
13474	            *firstchange = SCIPconsGetPos(cons0);
13475	
13476	         assert(SCIPconsIsActive(cons0));
13477	      }
13478	   }
13479	#ifdef  SCIP_MORE_DEBUG
13480	   SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
13481	   SCIPhashtablePrintStatistics(hashtable, SCIPgetMessagehdlr(scip));
13482	#endif
13483	
13484	   SCIPfreeBufferArray(scip, &parallelconss);
13485	
13486	   /* free hash table */
13487	   SCIPhashtableFree(&hashtable);
13488	
13489	   return SCIP_OKAY;
13490	}
13491	
13492	/** compares constraint with all prior constraints for possible redundancy or aggregation,
13493	 *  and removes or changes constraint accordingly
13494	 */
13495	static
13496	SCIP_RETCODE preprocessConstraintPairs(
13497	   SCIP*                 scip,               /**< SCIP data structure */
13498	   SCIP_CONS**           conss,              /**< constraint set */
13499	   int                   firstchange,        /**< first constraint that changed since last pair preprocessing round */
13500	   int                   chkind,             /**< index of constraint to check against all prior indices upto startind */
13501	   SCIP_Real             maxaggrnormscale,   /**< maximal allowed relative gain in maximum norm for constraint aggregation */
13502	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
13503	   int*                  ndelconss,          /**< pointer to count number of deleted constraints */
13504	   int*                  nchgsides,          /**< pointer to count number of changed left/right hand sides */
13505	   int*                  nchgcoefs           /**< pointer to count number of changed coefficients */
13506	   )
13507	{
13508	   SCIP_CONS* cons0;
13509	   SCIP_CONSDATA* consdata0;
13510	   int* commonidx0;
13511	   int* commonidx1;
13512	   int* diffidx0minus1;
13513	   int* diffidx1minus0;
13514	   uint64_t possignature0;
13515	   uint64_t negsignature0;
13516	   SCIP_Bool cons0changed;
13517	   SCIP_Bool cons0isequality;
13518	   int diffidx1minus0size;
13519	   int c;
13520	   SCIP_Real cons0lhs;
13521	   SCIP_Real cons0rhs;
13522	   SCIP_Bool cons0upgraded;
13523	
13524	   assert(scip != NULL);
13525	   assert(conss != NULL);
13526	   assert(firstchange <= chkind);
13527	   assert(cutoff != NULL);
13528	   assert(ndelconss != NULL);
13529	   assert(nchgsides != NULL);
13530	   assert(nchgcoefs != NULL);
13531	
13532	   /* get the constraint to be checked against all prior constraints */
13533	   cons0 = conss[chkind];
13534	   assert(cons0 != NULL);
13535	   assert(SCIPconsIsActive(cons0));
13536	   assert(!SCIPconsIsModifiable(cons0));
13537	
13538	   consdata0 = SCIPconsGetData(cons0);
13539	   assert(consdata0 != NULL);
13540	   assert(consdata0->nvars >= 1);
13541	   cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
13542	
13543	   /* sort the constraint */
13544	   SCIP_CALL( consdataSort(scip, consdata0) );
13545	
13546	   /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
13547	   consdataCalcSignatures(consdata0);
13548	   possignature0 = consdata0->possignature;
13549	   negsignature0 = consdata0->negsignature;
13550	
13551	   /* get temporary memory for indices of common variables */
13552	   SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
13553	   SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
13554	   SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
13555	   SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
13556	   diffidx1minus0size = consdata0->nvars;
13557	
13558	   cons0lhs = consdata0->lhs;
13559	   cons0rhs = consdata0->rhs;
13560	   cons0upgraded = consdata0->upgraded;
13561	
13562	   /* check constraint against all prior constraints */
13563	   cons0changed = consdata0->changed;
13564	   consdata0->changed = FALSE;
13565	   for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
13566	   {
13567	      SCIP_CONS* cons1;
13568	      SCIP_CONSDATA* consdata1;
13569	      uint64_t possignature1;
13570	      uint64_t negsignature1;
13571	      SCIP_Bool cons0dominateslhs;
13572	      SCIP_Bool cons1dominateslhs;
13573	      SCIP_Bool cons0dominatesrhs;
13574	      SCIP_Bool cons1dominatesrhs;
13575	      SCIP_Bool cons1isequality;
13576	      SCIP_Bool coefsequal;
13577	      SCIP_Bool coefsnegated;
13578	      SCIP_Bool tryaggregation;
13579	      int nvarscommon;
13580	      int nvars0minus1;
13581	      int nvars1minus0;
13582	      int commonidxweight;
13583	      int diffidx0minus1weight;
13584	      int diffidx1minus0weight;
13585	      int v0;
13586	      int v1;
13587	
13588	      assert(cons0lhs == consdata0->lhs);  /*lint !e777*/
13589	      assert(cons0rhs == consdata0->rhs);  /*lint !e777*/
13590	      assert(cons0upgraded == consdata0->upgraded);
13591	
13592	      cons1 = conss[c];
13593	
13594	      /* cons1 has become inactive during presolving of constraint pairs */
13595	      if( cons1 == NULL )
13596	         continue;
13597	
13598	      assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
13599	      assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
13600	
13601	      consdata1 = SCIPconsGetData(cons1);
13602	      assert(consdata1 != NULL);
13603	
13604	      /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
13605	         SCIPconsGetName(cons0), cons0changed, cons0upgraded,
13606	         SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
13607	
13608	      /* if both constraints didn't change since last pair processing, we can ignore the pair */
13609	      if( !cons0changed && !consdata1->changed )
13610	         continue;
13611	
13612	      /* if both constraints are already upgraded, skip the pair;
13613	       * because changes on these constraints cannot be applied to the instance anymore */
13614	      if( cons0upgraded && consdata1->upgraded )
13615	         continue;
13616	
13617	      assert(consdata1->nvars >= 1);
13618	
13619	      /* sort the constraint */
13620	      SCIP_CALL( consdataSort(scip, consdata1) );
13621	
13622	      /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
13623	      consdataCalcSignatures(consdata1);
13624	      possignature1 = consdata1->possignature;
13625	      negsignature1 = consdata1->negsignature;
13626	
13627	      /* the signatures give a quick test to check for domination and equality of coefficients */
13628	      coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
13629	      coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
13630	      cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
13631	         && ((possignature0 | possignature1) == possignature1)  /* possignature0 <= possignature1 (as bit vector) */
13632	         && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13633	      cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
13634	         && ((possignature0 | possignature1) == possignature0)  /* possignature0 >= possignature1 (as bit vector) */
13635	         && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13636	      cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
13637	         && ((possignature0 | possignature1) == possignature0)  /* possignature0 >= possignature1 (as bit vector) */
13638	         && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13639	      cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
13640	         && ((possignature0 | possignature1) == possignature1)  /* possignature0 <= possignature1 (as bit vector) */
13641	         && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13642	      cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
13643	      tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
13644	      if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
13645	         && !coefsequal && !coefsnegated && !tryaggregation )
13646	         continue;
13647	
13648	      /* make sure, we have enough memory for the index set of V_1 \ V_0 */
13649	      if( tryaggregation && consdata1->nvars > diffidx1minus0size )
13650	      {
13651	         SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
13652	         diffidx1minus0size = consdata1->nvars;
13653	      }
13654	
13655	      /* check consdata0 against consdata1:
13656	       * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
13657	       *   consdata0 dominates consdata1 w.r.t. left hand side
13658	       * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
13659	       *   consdata0 dominates consdata1 w.r.t. right hand side
13660	       * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
13661	       *   ranged row (or equality)
13662	       * - if at least one constraint is an equality, count the weighted number of common variables W_c
13663	       *   and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
13664	       *   where the weight of each variable depends on its type, such that aggregations in order to remove the
13665	       *   number of continuous and integer variables are preferred:
13666	       *   - if W_c > W_1, try to aggregate  consdata0 := a * consdata0 + b * consdata1  in order to decrease the
13667	       *     variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
13668	       *     the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13669	       *     to be positive to not switch the sense of the (in)equality cons0
13670	       *   - if W_c > W_0, try to aggregate  consdata1 := a * consdata1 + b * consdata0  in order to decrease the
13671	       *     variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
13672	       *     the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13673	       *     to be positive to not switch the sense of the (in)equality cons1
13674	       */
13675	
13676	      /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
13677	      nvarscommon = 0;
13678	      commonidxweight = 0;
13679	      nvars0minus1 = 0;
13680	      diffidx0minus1weight = 0;
13681	      nvars1minus0 = 0;
13682	      diffidx1minus0weight = 0;
13683	      v0 = 0;
13684	      v1 = 0;
13685	      while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
13686	         && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
13687	            || coefsequal || coefsnegated || tryaggregation) )
13688	      {
13689	         SCIP_VAR* var;
13690	         SCIP_Real val0;
13691	         SCIP_Real val1;
13692	         int varcmp;
13693	
13694	         /* test, if variable appears in only one or in both constraints */
13695	         if( v0 < consdata0->nvars && v1 < consdata1->nvars )
13696	            varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
13697	         else if( v0 < consdata0->nvars )
13698	            varcmp = -1;
13699	         else
13700	            varcmp = +1;
13701	
13702	         switch( varcmp )
13703	         {
13704	         case -1:
13705	            /* variable doesn't appear in consdata1 */
13706	            var = consdata0->vars[v0];
13707	            val0 = consdata0->vals[v0];
13708	            val1 = 0.0;
13709	            if( tryaggregation )
13710	            {
13711	               diffidx0minus1[nvars0minus1] = v0;
13712	               nvars0minus1++;
13713	               diffidx0minus1weight += getVarWeight(var);
13714	            }
13715	            v0++;
13716	            coefsequal = FALSE;
13717	            coefsnegated = FALSE;
13718	            break;
13719	
13720	         case +1:
13721	            /* variable doesn't appear in consdata0 */
13722	            var = consdata1->vars[v1];
13723	            val0 = 0.0;
13724	            val1 = consdata1->vals[v1];
13725	            if( tryaggregation )
13726	            {
13727	               diffidx1minus0[nvars1minus0] = v1;
13728	               nvars1minus0++;
13729	               diffidx1minus0weight += getVarWeight(var);
13730	            }
13731	            v1++;
13732	            coefsequal = FALSE;
13733	            coefsnegated = FALSE;
13734	            break;
13735	
13736	         case 0:
13737	            /* variable appears in both constraints */
13738	            assert(consdata0->vars[v0] == consdata1->vars[v1]);
13739	            var = consdata0->vars[v0];
13740	            val0 = consdata0->vals[v0];
13741	            val1 = consdata1->vals[v1];
13742	            if( tryaggregation )
13743	            {
13744	               commonidx0[nvarscommon] = v0;
13745	               commonidx1[nvarscommon] = v1;
13746	               nvarscommon++;
13747	               commonidxweight += getVarWeight(var);
13748	            }
13749	            v0++;
13750	            v1++;
13751	            coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13752	            coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13753	            break;
13754	
13755	         default:
13756	            SCIPerrorMessage("invalid comparison result\n");
13757	            SCIPABORT();
13758	            var = NULL;
13759	            val0 = 0.0;
13760	            val1 = 0.0;
13761	         }
13762	         assert(var != NULL);
13763	
13764	         /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13765	         if( SCIPisGT(scip, val0, val1) )
13766	         {
13767	            if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13768	            {
13769	               cons0dominatesrhs = FALSE;
13770	               cons1dominateslhs = FALSE;
13771	            }
13772	            if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13773	            {
13774	               cons0dominateslhs = FALSE;
13775	               cons1dominatesrhs = FALSE;
13776	            }
13777	         }
13778	         else if( SCIPisLT(scip, val0, val1) )
13779	         {
13780	            if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13781	            {
13782	               cons0dominateslhs = FALSE;
13783	               cons1dominatesrhs = FALSE;
13784	            }
13785	            if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13786	            {
13787	               cons0dominatesrhs = FALSE;
13788	               cons1dominateslhs = FALSE;
13789	            }
13790	         }
13791	      }
13792	
13793	      /* check for disaggregated ranged rows */
13794	      if( coefsequal || coefsnegated )
13795	      {
13796	         SCIP_CONS* consstay;
13797	         SCIP_CONS* consdel;
13798	#ifndef NDEBUG
13799	         SCIP_CONSDATA* consdatastay;
13800	#endif
13801	         SCIP_CONSDATA* consdatadel;
13802	         SCIP_Real lhs;
13803	         SCIP_Real rhs;
13804	         int consinddel;
13805	
13806	         /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13807	          * best left and right hand sides; delete the old constraints afterwards
13808	          */
13809	         SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13810	            SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13811	         SCIPdebugPrintCons(scip, cons0, NULL);
13812	         SCIPdebugPrintCons(scip, cons1, NULL);
13813	
13814	         if( coefsequal )
13815	         {
13816	            /* the coefficients of both rows are equal */
13817	            lhs = MAX(consdata0->lhs, consdata1->lhs);
13818	            rhs = MIN(consdata0->rhs, consdata1->rhs);
13819	         }
13820	         else
13821	         {
13822	            /* the coefficients of both rows are negations */
13823	            lhs = MAX(consdata0->lhs, -consdata1->rhs);
13824	            rhs = MIN(consdata0->rhs, -consdata1->lhs);
13825	         }
13826	         if( SCIPisFeasLT(scip, rhs, lhs) )
13827	         {
13828	            SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13829	            *cutoff = TRUE;
13830	            break;
13831	         }
13832	
13833	         /* check which constraint has to stay;
13834	          * changes applied to an upgraded constraint will not be considered in the instance */
13835	         if( consdata0->upgraded )
13836	         {
13837	            assert(!consdata1->upgraded);
13838	            consstay = cons1;
13839	#ifndef NDEBUG
13840	            consdatastay = consdata1;
13841	#endif
13842	
13843	            consdel = cons0;
13844	            consdatadel = consdata0;
13845	            consinddel = chkind;
13846	         }
13847	         else
13848	         {
13849	            consstay = cons0;
13850	#ifndef NDEBUG
13851	            consdatastay = consdata0;
13852	#endif
13853	
13854	            consdel = cons1;
13855	            consdatadel = consdata1;
13856	            consinddel = c;
13857	         }
13858	
13859	         /* update the sides of consstay */
13860	         SCIP_CALL( chgLhs(scip, consstay, lhs) );
13861	         SCIP_CALL( chgRhs(scip, consstay, rhs) );
13862	         if( !consdata0->upgraded )
13863	         {
13864	            assert(consstay == cons0);
13865	            cons0lhs = consdata0->lhs;
13866	            cons0rhs = consdata0->rhs;
13867	         }
13868	
13869	         /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13870	         SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13871	
13872	         assert( !consdatastay->upgraded );
13873	         /* delete consdel */
13874	         SCIP_CALL( SCIPdelCons(scip, consdel) );
13875	         conss[consinddel] = NULL;
13876	         if( !consdatadel->upgraded )
13877	            (*ndelconss)++;
13878	         continue;
13879	      }
13880	
13881	      /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13882	       * redundant
13883	       */
13884	      if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13885	      {
13886	         /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13887	         SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13888	            SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13889	         SCIPdebugPrintCons(scip, cons0, NULL);
13890	         SCIPdebugPrintCons(scip, cons1, NULL);
13891	
13892	         /* check for infeasibility */
13893	         if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13894	         {
13895	            SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13896	            *cutoff = TRUE;
13897	            break;
13898	         }
13899	
13900	         /* remove redundant left hand side */
13901	         if( !SCIPisInfinity(scip, -consdata0->lhs) )
13902	         {
13903	            SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13904	            cons0lhs = consdata0->lhs;
13905	            cons0isequality = FALSE;
13906	            if( !consdata0->upgraded )
13907	            {
13908	               /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13909	               SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13910	
13911	               (*nchgsides)++;
13912	            }
13913	         }
13914	      }
13915	      else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13916	      {
13917	         /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13918	         SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13919	            SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13920	         SCIPdebugPrintCons(scip, cons1, NULL);
13921	         SCIPdebugPrintCons(scip, cons0, NULL);
13922	
13923	         /* check for infeasibility */
13924	         if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13925	         {
13926	            SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13927	            *cutoff = TRUE;
13928	            break;
13929	         }
13930	
13931	         /* remove redundant left hand side */
13932	         if( !SCIPisInfinity(scip, -consdata1->lhs) )
13933	         {
13934	            SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13935	            cons1isequality = FALSE;
13936	            if( !consdata1->upgraded )
13937	            {
13938	               /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13939	               SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13940	
13941	               (*nchgsides)++;
13942	            }
13943	         }
13944	      }
13945	      if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13946	      {
13947	         /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13948	         SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13949	            SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13950	         SCIPdebugPrintCons(scip, cons0, NULL);
13951	         SCIPdebugPrintCons(scip, cons1, NULL);
13952	
13953	         /* check for infeasibility */
13954	         if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13955	         {
13956	            SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13957	            *cutoff = TRUE;
13958	            break;
13959	         }
13960	
13961	         /* remove redundant right hand side */
13962	         if( !SCIPisInfinity(scip, consdata0->rhs) )
13963	         {
13964	            SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13965	            cons0rhs = consdata0->rhs;
13966	            cons0isequality = FALSE;
13967	            if( !consdata0->upgraded )
13968	            {
13969	               /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13970	               SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13971	
13972	               (*nchgsides)++;
13973	            }
13974	         }
13975	      }
13976	      else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13977	      {
13978	         /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13979	         SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13980	            SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13981	         SCIPdebugPrintCons(scip, cons1, NULL);
13982	         SCIPdebugPrintCons(scip, cons0, NULL);
13983	
13984	         /* check for infeasibility */
13985	         if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13986	         {
13987	            SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13988	            *cutoff = TRUE;
13989	            break;
13990	         }
13991	
13992	         /* remove redundant right hand side */
13993	         if( !SCIPisInfinity(scip, consdata1->rhs) )
13994	         {
13995	            SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13996	            cons1isequality = FALSE;
13997	            if( !consdata1->upgraded )
13998	            {
13999	               /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
14000	               SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
14001	
14002	               (*nchgsides)++;
14003	            }
14004	         }
14005	      }
14006	
14007	      /* check for now redundant constraints */
14008	      if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
14009	      {
14010	         /* consdata0 became redundant */
14011	         SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
14012	         SCIP_CALL( SCIPdelCons(scip, cons0) );
14013	         conss[chkind] = NULL;
14014	         if( !consdata0->upgraded )
14015	         {
14016	            /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
14017	            SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
14018	
14019	            (*ndelconss)++;
14020	         }
14021	         continue;
14022	      }
14023	      if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
14024	      {
14025	         /* consdata1 became redundant */
14026	         SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
14027	         SCIP_CALL( SCIPdelCons(scip, cons1) );
14028	         conss[c] = NULL;
14029	         if( !consdata1->upgraded )
14030	         {
14031	            /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
14032	            SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
14033	
14034	            (*ndelconss)++;
14035	         }
14036	         continue;
14037	      }
14038	
14039	      /* check, if we want to aggregate an (in)equality with an equality:
14040	       *   consdata0 := a * consdata0 + b * consdata1  or  consdata1 := a * consdata1 + b * consdata0
14041	       */
14042	      if( tryaggregation )
14043	      {
14044	         SCIP_Bool aggregated;
14045	
14046	         assert(consdata0->nvars == nvarscommon + nvars0minus1);
14047	         assert(consdata1->nvars == nvarscommon + nvars1minus0);
14048	
14049	         aggregated = FALSE;
14050	         if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
14051	         {
14052	            /* W_c > W_1: try to aggregate  consdata0 := a * consdata0 + b * consdata1 */
14053	            SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
14054	                  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
14055	                  nchgcoefs, &aggregated, cutoff) );
14056	
14057	            if( *cutoff )
14058	               break;
14059	
14060	            /* update array of active constraints */
14061	            if( aggregated )
14062	            {
14063	               assert(!SCIPconsIsActive(cons0));
14064	               assert(SCIPconsIsActive(cons1));
14065	               conss[chkind] = NULL;
14066	            }
14067	         }
14068	         if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
14069	         {
14070	            /* W_c > W_0: try to aggregate  consdata1 := a * consdata1 + b * consdata0 */
14071	            SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
14072	                  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
14073	                  nchgcoefs, &aggregated, cutoff) );
14074	
14075	            if( *cutoff )
14076	               break;
14077	
14078	            /* update array of active constraints */
14079	            if( aggregated )
14080	            {
14081	               assert(!SCIPconsIsActive(cons1));
14082	               assert(SCIPconsIsActive(cons0));
14083	               conss[c] = NULL;
14084	            }
14085	         }
14086	      }
14087	   }
14088	
14089	   /* free temporary memory */
14090	   SCIPfreeBufferArray(scip, &diffidx1minus0);
14091	   SCIPfreeBufferArray(scip, &diffidx0minus1);
14092	   SCIPfreeBufferArray(scip, &commonidx1);
14093	   SCIPfreeBufferArray(scip, &commonidx0);
14094	
14095	   return SCIP_OKAY;
14096	}
14097	
14098	/** do stuffing presolving on a single constraint */
14099	static
14100	SCIP_RETCODE presolStuffing(
14101	   SCIP*                 scip,               /**< SCIP data structure */
14102	   SCIP_CONS*            cons,               /**< linear constraint */
14103	   SCIP_Bool             singletonstuffing,  /**< should stuffing of singleton continuous variables be performed? */
14104	   SCIP_Bool             singlevarstuffing,  /**< should single variable stuffing be performed, which tries to fulfill
14105	                                              *   constraints using the cheapest variable? */
14106	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
14107	   int*                  nfixedvars,         /**< pointer to count the total number of fixed variables */
14108	   int*                  nchgbds             /**< pointer to count the total number of tightened bounds */
14109	   )
14110	{
14111	   SCIP_CONSDATA* consdata;
14112	   SCIP_Real* ratios;
14113	   int* varpos;
14114	   SCIP_Bool* swapped;
14115	   SCIP_VAR** vars;
14116	   SCIP_Real* vals;
14117	   SCIP_VAR* var;
14118	   SCIP_Real lb;
14119	   SCIP_Real ub;
14120	   SCIP_Real minactivity;
14121	   SCIP_Real maxactivity;
14122	   SCIP_Real maxcondactivity;
14123	   SCIP_Real mincondactivity;
14124	   SCIP_Real rhs;
14125	   SCIP_Real val;
14126	   SCIP_Real obj;
14127	   SCIP_Real factor;
14128	   SCIP_Bool minactisrelax;
14129	   SCIP_Bool maxactisrelax;
14130	   SCIP_Bool isminsettoinfinity;
14131	   SCIP_Bool ismaxsettoinfinity;
14132	   SCIP_Bool tryfixing;
14133	   int nsingletons;
14134	   int idx;
14135	   int v;
14136	   int nvars;
14137	
14138	   assert(scip != NULL);
14139	   assert(cons != NULL);
14140	   assert(nfixedvars != NULL);
14141	
14142	   consdata = SCIPconsGetData(cons);
14143	
14144	   /* we only want to run for inequalities */
14145	   if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
14146	      return SCIP_OKAY;
14147	
14148	   if( singlevarstuffing )
14149	   {
14150	      consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
14151	         &isminsettoinfinity, &ismaxsettoinfinity);
14152	   }
14153	   else
14154	   {
14155	      minactivity = SCIP_INVALID;
14156	      maxactivity = SCIP_INVALID;
14157	      isminsettoinfinity = FALSE;
14158	      ismaxsettoinfinity = FALSE;
14159	   }
14160	
14161	   /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
14162	    * the new maxactivity is minus the old minactivity then
14163	    */
14164	   if( SCIPisInfinity(scip, consdata->rhs) )
14165	   {
14166	      rhs = -consdata->lhs;
14167	      factor = -1.0;
14168	      maxactivity = -minactivity;
14169	      ismaxsettoinfinity = isminsettoinfinity;
14170	   }
14171	   else
14172	   {
14173	      assert(SCIPisInfinity(scip, -consdata->lhs));
14174	      rhs = consdata->rhs;
14175	      factor = 1.0;
14176	   }
14177	
14178	   nvars = consdata->nvars;
14179	   vars = consdata->vars;
14180	   vals = consdata->vals;
14181	
14182	   /* check for continuous singletons */
14183	   if( singletonstuffing )
14184	   {
14185	      for( v = 0; v < nvars; ++v )
14186	      {
14187	         var = vars[v];
14188	
14189	         if( (SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) + SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL)) == 1
14190	            && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
14191	            break;
14192	      }
14193	   }
14194	   else
14195	      /* we don't want to go into the next block */
14196	      v = nvars;
14197	
14198	   /* a singleton was found -> perform singleton variable stuffing */
14199	   if( v < nvars )
14200	   {
14201	      assert(singletonstuffing);
14202	
14203	      SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
14204	      SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
14205	      SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
14206	
14207	      tryfixing = TRUE;
14208	      nsingletons = 0;
14209	      mincondactivity = 0.0;
14210	      maxcondactivity = 0.0;
14211	
14212	      for( v = 0; v < nvars; ++v )
14213	      {
14214	         var = vars[v];
14215	         lb = SCIPvarGetLbGlobal(var);
14216	         ub = SCIPvarGetUbGlobal(var);
14217	         obj = SCIPvarGetObj(var);
14218	         val = factor * vals[v];
14219	
14220	         assert(!SCIPisZero(scip, val));
14221	
14222	         /* the variable is a singleton and continuous */
14223	         if( (SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) + SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL)) == 1
14224	            && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
14225	         {
14226	            if( SCIPisNegative(scip, obj) && val > 0 )
14227	            {
14228	               /* case 1: obj < 0 and coef > 0 */
14229	               if( SCIPisInfinity(scip, -lb) )
14230	               {
14231	                  tryfixing = FALSE;
14232	                  break;
14233	               }
14234	
14235	               maxcondactivity += val * lb;
14236	               mincondactivity += val * lb;
14237	               swapped[v] = FALSE;
14238	               ratios[nsingletons] = obj / val;
14239	               varpos[nsingletons] = v;
14240	               nsingletons++;
14241	            }
14242	            else if( SCIPisPositive(scip, obj) && val < 0 )
14243	            {
14244	               /* case 2: obj > 0 and coef < 0 */
14245	               if( SCIPisInfinity(scip, ub) )
14246	               {
14247	                  tryfixing = FALSE;
14248	                  break;
14249	               }
14250	               /* multiply column by (-1) to become case 1.
14251	                * now bounds are swapped: ub := -lb, lb := -ub
14252	                */
14253	
14254	               maxcondactivity += val * ub;
14255	               mincondactivity += val * ub;
14256	               swapped[v] = TRUE;
14257	               ratios[nsingletons] = obj / val;
14258	               varpos[nsingletons] = v;
14259	               nsingletons++;
14260	            }
14261	            else if( val > 0 )
14262	            {
14263	               /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
14264	                *  we only consider the lower bound for the constants
14265	                */
14266	               assert(!SCIPisNegative(scip, obj));
14267	
14268	               if( SCIPisInfinity(scip, -lb) )
14269	               {
14270	                  /* maybe unbounded */
14271	                  tryfixing = FALSE;
14272	                  break;
14273	               }
14274	
14275	               maxcondactivity += val * lb;
14276	               mincondactivity += val * lb;
14277	            }
14278	            else
14279	            {
14280	               /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
14281	                * we only consider the upper bound for the constants
14282	                */
14283	               assert(!SCIPisPositive(scip, obj));
14284	               assert(val < 0);
14285	
14286	               if( SCIPisInfinity(scip, ub) )
14287	               {
14288	                  /* maybe unbounded */
14289	                  tryfixing = FALSE;
14290	                  break;
14291	               }
14292	
14293	               maxcondactivity += val * ub;
14294	               mincondactivity += val * ub;
14295	            }
14296	         }
14297	         else
14298	         {
14299	            /* consider contribution of discrete variables, non-singleton
14300	             * continuous variables and variables with more than one lock
14301	             */
14302	            if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14303	            {
14304	               tryfixing = FALSE;
14305	               break;
14306	            }
14307	
14308	            if( val > 0 )
14309	            {
14310	               maxcondactivity += val * ub;
14311	               mincondactivity += val * lb;
14312	            }
14313	            else
14314	            {
14315	               maxcondactivity += val * lb;
14316	               mincondactivity += val * ub;
14317	            }
14318	         }
14319	      }
14320	      if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
14321	      {
14322	         SCIP_Real delta;
14323	         SCIP_Bool tightened;
14324	#ifdef SCIP_DEBUG
14325	         int oldnfixedvars = *nfixedvars;
14326	         int oldnchgbds = *nchgbds;
14327	#endif
14328	
14329	         SCIPsortRealInt(ratios, varpos, nsingletons);
14330	
14331	         /* verify which singleton continuous variables can be fixed */
14332	         for( v = 0; v < nsingletons; ++v )
14333	         {
14334	            idx = varpos[v];
14335	            var = vars[idx];
14336	            val = factor * vals[idx];
14337	            lb = SCIPvarGetLbGlobal(var);
14338	            ub = SCIPvarGetUbGlobal(var);
14339	
14340	            assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
14341	            assert((val < 0) == swapped[idx]);
14342	            val = REALABS(val);
14343	
14344	            /* stop fixing if variable bounds are not finite */
14345	            if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14346	               break;
14347	
14348	            assert((SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL)
14349	               + SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL)) == 1);
14350	            assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14351	
14352	            /* calculate the change in the row activities if this variable changes
14353	             * its value from its worst to its best bound
14354	             */
14355	            if( swapped[idx] )
14356	               delta = -(lb - ub) * val;
14357	            else
14358	               delta =  (ub - lb) * val;
14359	
14360	            assert(!SCIPisNegative(scip, delta));
14361	
14362	            if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
14363	            {
14364	               if( swapped[idx] )
14365	               {
14366	                  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14367	                  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14368	               }
14369	               else
14370	               {
14371	                  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14372	                  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14373	               }
14374	
14375	               if( *cutoff )
14376	                  break;
14377	               if( tightened )
14378	               {
14379	                  (*nfixedvars)++;
14380	               }
14381	            }
14382	            /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
14383	             *        since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
14384	             *        anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
14385	             *        troubles in case of large bounds.
14386	             */
14387	            else if( SCIPisLE(scip, rhs, mincondactivity) )
14388	            {
14389	               if( swapped[idx] )
14390	               {
14391	                  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14392	                  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14393	               }
14394	               else
14395	               {
14396	                  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14397	                  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14398	               }
14399	
14400	               if( *cutoff )
14401	                  break;
14402	               if( tightened )
14403	               {
14404	                  (*nfixedvars)++;
14405	               }
14406	            }
14407	
14408	            maxcondactivity += delta;
14409	            mincondactivity += delta;
14410	         }
14411	
14412	#ifdef SCIP_DEBUG
14413	         if( *nfixedvars - oldnfixedvars > 0 || *nchgbds - oldnchgbds > 0 )
14414	         {
14415	            SCIPdebugMsg(scip, "### stuffing fixed %d variables and changed %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
14416	         }
14417	#endif
14418	      }
14419	
14420	      SCIPfreeBufferArray(scip, &swapped);
14421	      SCIPfreeBufferArray(scip, &ratios);
14422	      SCIPfreeBufferArray(scip, &varpos);
14423	   }
14424	
14425	   /* perform single-variable stuffing:
14426	    * for a linear inequality
14427	    *  a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
14428	    * with a_i > 0 and objective coefficients c_i < 0,
14429	    * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
14430	    * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
14431	    * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
14432	    * is redundant.
14433	    * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
14434	    * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
14435	    * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
14436	    * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
14437	    * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
14438	    * upper bound.
14439	    * Note that the others variables may have downlocks from other constraints, which we do not need to care
14440	    * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
14441	    * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
14442	    * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
14443	    * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
14444	    * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
14445	    * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
14446	    * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
14447	    * filling the remaining gap in the constraint with the next-best variable. For this, we check that
14448	    * c_k * ceil((maxactivity - rhs)/val) is still better than
14449	    * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
14450	    * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
14451	    * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
14452	    * sign of coefficients in constraint and objective prevent the use of this method.
14453	    */
14454	   if( singlevarstuffing && !ismaxsettoinfinity )
14455	   {
14456	      SCIP_Real bestratio = -SCIPinfinity(scip);
14457	      SCIP_Real secondbestratio = -SCIPinfinity(scip);
14458	      SCIP_Real ratio;
14459	      int bestindex = -1;
14460	      int bestuplocks = 0;
14461	      int bestdownlocks = 1;
14462	      int downlocks;
14463	      int uplocks;
14464	      SCIPdebug( int oldnfixedvars = *nfixedvars; )
14465	      SCIPdebug( int oldnchgbds = *nchgbds; )
14466	
14467	      /* loop over all variables to identify the best and second-best ratio */
14468	      for( v = 0; v < nvars; ++v )
14469	      {
14470	         var = vars[v];
14471	         obj = SCIPvarGetObj(var);
14472	         val = factor * vals[v];
14473	
14474	         assert(!SCIPisZero(scip, val));
14475	
14476	         ratio = obj / val;
14477	
14478	         /* if both objective and constraint push the variable to the same direction, we can do nothing here */
14479	         if( !SCIPisNegative(scip, ratio) )
14480	         {
14481	            bestindex = -1;
14482	            break;
14483	         }
14484	
14485	         if( val > 0 )
14486	         {
14487	            downlocks = SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
14488	            uplocks = SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
14489	         }
14490	         else
14491	         {
14492	            downlocks = SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
14493	            uplocks = SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
14494	         }
14495	
14496	         /* better ratio, update best candidate
14497	          * @todo use some tolerance
14498	          * @todo check size of domain and updated ratio for integer variables already?
14499	          */
14500	         if( ratio > bestratio || ((ratio == bestratio) && downlocks == 0 && (bestdownlocks > 0 /*lint !e777*/
14501	                  || (SCIPvarGetType(vars[bestindex]) != SCIP_VARTYPE_CONTINUOUS
14502	                     && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS))) )
14503	         {
14504	            /* best index becomes second-best*/
14505	            if( bestindex != -1 )
14506	            {
14507	               /* second-best index must not have more than 1 uplock */
14508	               if( bestuplocks > 1 )
14509	               {
14510	                  bestindex = -1;
14511	                  break;
14512	               }
14513	               else
14514	               {
14515	                  secondbestratio = bestratio;
14516	               }
14517	            }
14518	            bestdownlocks = downlocks;
14519	            bestuplocks = uplocks;
14520	            bestratio = ratio;
14521	            bestindex = v;
14522	
14523	            /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
14524	             * if it is not the best, it has too many uplocks -> not applicable
14525	             */
14526	            if( bestdownlocks > 0 && bestuplocks > 1 )
14527	            {
14528	               bestindex = -1;
14529	               break;
14530	            }
14531	         }
14532	         else
14533	         {
14534	            /* non-best index must not have more than 1 uplock */
14535	            if( uplocks > 1 )
14536	            {
14537	               bestindex = -1;
14538	               break;
14539	            }
14540	            /* update second-best ratio */
14541	            if( ratio > secondbestratio )
14542	            {
14543	               secondbestratio = ratio;
14544	            }
14545	         }
14546	      }
14547	
14548	      /* check if we can apply single variable stuffing */
14549	      if( bestindex != -1 && bestdownlocks == 0 )
14550	      {
14551	         SCIP_Bool tightened = FALSE;
14552	         SCIP_Real bounddelta;
14553	
14554	         var = vars[bestindex];
14555	         obj = SCIPvarGetObj(var);
14556	         val = factor * vals[bestindex];
14557	         lb = SCIPvarGetLbGlobal(var);
14558	         ub = SCIPvarGetUbGlobal(var);
14559	         tryfixing = TRUE;
14560	
14561	         if( val < 0 )
14562	         {
14563	            assert(!SCIPisNegative(scip, obj));
14564	
14565	            /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14566	            if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/-val) )
14567	            {
14568	               SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
14569	               SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
14570	               assert(SCIPisPositive(scip, activitydelta));
14571	
14572	               tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
14573	
14574	               bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
14575	               assert(SCIPisPositive(scip, bounddelta));
14576	            }
14577	            else
14578	               bounddelta = (maxactivity - rhs)/-val;
14579	
14580	            tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14581	
14582	            if( tryfixing )
14583	            {
14584	               assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0);
14585	
14586	               if( SCIPisEQ(scip, lb + bounddelta, ub) )
14587	               {
14588	                  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
14589	                  SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
14590	               }
14591	               else
14592	               {
14593	                  SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
14594	                  SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
14595	               }
14596	            }
14597	         }
14598	         else
14599	         {
14600	            assert(!SCIPisPositive(scip, obj));
14601	
14602	            /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14603	            if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS  && !SCIPisIntegral(scip, (maxactivity - rhs)/val))
14604	            {
14605	               SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
14606	               SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
14607	               assert(SCIPisPositive(scip, activitydelta));
14608	
14609	               tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
14610	
14611	               bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
14612	               assert(SCIPisPositive(scip, bounddelta));
14613	            }
14614	            else
14615	               bounddelta = (maxactivity - rhs)/val;
14616	
14617	            tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14618	
14619	            if( tryfixing )
14620	            {
14621	               assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 0);
14622	
14623	               if( SCIPisEQ(scip, ub - bounddelta, lb) )
14624	               {
14625	                  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
14626	                  SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
14627	               }
14628	               else
14629	               {
14630	                  SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
14631	                  SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
14632	               }
14633	            }
14634	         }
14635	
14636	         if( *cutoff )
14637	            return SCIP_OKAY;
14638	         if( tightened )
14639	         {
14640	            if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
14641	               ++(*nfixedvars);
14642	            else
14643	               ++(*nchgbds);
14644	
14645	            SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
14646	            for( v = 0; v < nvars; ++v )
14647	            {
14648	               SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]),
14649	                  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]),
14650	                  SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL),
14651	                  SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL),
14652	                  SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS ? "C" : "I");
14653	            }
14654	            SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
14655	
14656	            for( v = 0; v < nvars; ++v )
14657	            {
14658	               if( v == bestindex )
14659	                  continue;
14660	
14661	               if( factor * vals[v] < 0 )
14662	               {
14663	                  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14664	                  SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n",
14665	                     SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
14666	                  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
14667	               }
14668	               else
14669	               {
14670	                  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14671	                  SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n",
14672	                     SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
14673	                  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
14674	               }
14675	
14676	               if( *cutoff )
14677	                  return SCIP_OKAY;
14678	               if( tightened )
14679	                  ++(*nfixedvars);
14680	            }
14681	            SCIPdebug( SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds); )
14682	         }
14683	      }
14684	   }
14685	
14686	   return SCIP_OKAY;
14687	}
14688	
14689	/** applies full dual presolving on variables that only appear in linear constraints */
14690	static
14691	SCIP_RETCODE fullDualPresolve(
14692	   SCIP*                 scip,               /**< SCIP data structure */
14693	   SCIP_CONS**           conss,              /**< constraint set */
14694	   int                   nconss,             /**< number of constraints */
14695	   SCIP_Bool*            cutoff,             /**< pointer to store TRUE, if a cutoff was found */
14696	   int*                  nchgbds             /**< pointer to count the number of bound changes */
14697	   )
14698	{
14699	   SCIP_Real* redlb;
14700	   SCIP_Real* redub;
14701	   int* nlocksdown;
14702	   int* nlocksup;
14703	   SCIP_Bool* isimplint;
14704	   SCIP_VAR** origvars;
14705	   SCIP_VAR** vars;
14706	   SCIP_VAR** conscontvars;
14707	   int nvars;
14708	   int nbinvars;
14709	   int nintvars;
14710	   int ncontvars;
14711	   int v;
14712	   int c;
14713	
14714	   /* we calculate redundancy bounds with the following meaning:
14715	    *   redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
14716	    *   redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
14717	    * then:
14718	    *   c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
14719	    *   c_v <= 0 : x_v >= redub[v] is feasible due to optimality
14720	    */
14721	
14722	   /* Additionally, we detect continuous variables that are implicitly integral.
14723	    * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
14724	    * and all constraints (including the bounds as trivial constraints) in which:
14725	    *   c_j > 0: the variable is down-locked,
14726	    *   c_j < 0: the variable is up-locked,
14727	    *   c_j = 0: the variable appears
14728	    * have, apart from j, only integer variables with integral coefficients and integral sides.
14729	    * This is because then, the value of the variable is either determined by one of its bounds or
14730	    * by one of these constraints, and in all cases, the value of the variable is integral.
14731	    */
14732	
14733	   assert(scip != NULL);
14734	   assert(nconss == 0 || conss != NULL);
14735	   assert(nchgbds != NULL);
14736	   assert(!SCIPinProbing(scip));
14737	
14738	   /* get active variables */
14739	   nvars = SCIPgetNVars(scip);
14740	   origvars = SCIPgetVars(scip);
14741	
14742	   /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
14743	   nbinvars = SCIPgetNBinVars(scip);
14744	   if( nbinvars == nvars )
14745	      return SCIP_OKAY;
14746	
14747	   /* get number of continuous variables */
14748	   ncontvars = SCIPgetNContVars(scip);
14749	   nintvars = nvars - ncontvars;
14750	
14751	   /* copy the variable array since this array might change during the curse of this algorithm */
14752	   nvars = nvars - nbinvars;
14753	   SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
14754	
14755	   /* allocate temporary memory */
14756	   SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
14757	   SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
14758	   SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
14759	   SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
14760	   SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
14761	   SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
14762	
14763	   /* initialize redundancy bounds */
14764	   for( v = 0; v < nvars; ++v )
14765	   {
14766	      assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14767	      redlb[v] = SCIPvarGetLbGlobal(vars[v]);
14768	      redub[v] = SCIPvarGetUbGlobal(vars[v]);
14769	   }
14770	   BMSclearMemoryArray(nlocksdown, nvars);
14771	   BMSclearMemoryArray(nlocksup, nvars);
14772	
14773	   /* Initialize isimplint array: variable may be implicit integer if rounded to their best bound they are integral.
14774	    * We better not use SCIPisFeasIntegral() in these checks.
14775	    */
14776	   for( v = 0; v < ncontvars; v++ )
14777	   {
14778	      SCIP_VAR* var;
14779	      SCIP_Real obj;
14780	      SCIP_Real lb;
14781	      SCIP_Real ub;
14782	
14783	      var = vars[v + nintvars - nbinvars];
14784	      lb = SCIPvarGetLbGlobal(var);
14785	      ub = SCIPvarGetUbGlobal(var);
14786	
14787	      obj = SCIPvarGetObj(var);
14788	      if( SCIPisZero(scip, obj) )
14789	         isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14790	      else
14791	      {
14792	         if( SCIPisPositive(scip, obj) )
14793	            isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
14794	         else
14795	         {
14796	            assert(SCIPisNegative(scip, obj));
14797	            isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14798	         }
14799	      }
14800	   }
14801	
14802	   /* scan all constraints */
14803	   for( c = 0; c < nconss; ++c )
14804	   {
14805	      /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
14806	       * part of checked disjunctions)
14807	       */
14808	      if( SCIPconsIsLocked(conss[c]) )
14809	      {
14810	         SCIP_CONSDATA* consdata;
14811	         SCIP_Bool lhsexists;
14812	         SCIP_Bool rhsexists;
14813	         SCIP_Bool hasimpliedpotential;
14814	         SCIP_Bool integralcoefs;
14815	         int nlockspos;
14816	         int contvarpos;
14817	         int nconscontvars;
14818	         int i;
14819	
14820	         consdata = SCIPconsGetData(conss[c]);
14821	         assert(consdata != NULL);
14822	
14823	         /* get number of times the constraint was locked */
14824	         nlockspos = SCIPconsGetNLocksPos(conss[c]);
14825	
14826	         /* we do not want to include constraints with locked negation (this would be too weird) */
14827	         if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
14828	         {
14829	            /* mark all continuous variables as not being implicit integral */
14830	            for( i = 0; i < consdata->nvars; ++i )
14831	            {
14832	               SCIP_VAR* var;
14833	
14834	               var = consdata->vars[i];
14835	               if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
14836	               {
14837	                  int contv;
14838	                  contv = SCIPvarGetProbindex(var) - nintvars;
14839	                  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
14840	                  isimplint[contv] = FALSE;
14841	               }
14842	            }
14843	            continue;
14844	         }
14845	
14846	         /* check for existing sides */
14847	         lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
14848	         rhsexists = !SCIPisInfinity(scip, consdata->rhs);
14849	
14850	         /* count locks and update redundancy bounds */
14851	         contvarpos = -1;
14852	         nconscontvars = 0;
14853	         hasimpliedpotential = FALSE;
14854	         integralcoefs = !SCIPconsIsModifiable(conss[c]);
14855	
14856	         for( i = 0; i < consdata->nvars; ++i )
14857	         {
14858	            SCIP_VAR* var;
14859	            SCIP_Real val;
14860	            SCIP_Real minresactivity;
14861	            SCIP_Real maxresactivity;
14862	            SCIP_Real newredlb;
14863	            SCIP_Real newredub;
14864	            SCIP_Bool minisrelax;
14865	            SCIP_Bool maxisrelax;
14866	            SCIP_Bool isminsettoinfinity;
14867	            SCIP_Bool ismaxsettoinfinity;
14868	            int arrayindex;
14869	
14870	            var = consdata->vars[i];
14871	            val = consdata->vals[i];
14872	
14873	            /* check if still all integer variables have integral coefficients */
14874	            if( SCIPvarIsIntegral(var) )
14875	               integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
14876	
14877	            /* we do not need to process binary variables */
14878	            if( SCIPvarIsBinary(var) )
14879	               continue;
14880	
14881	            if( SCIPconsIsModifiable(conss[c]) )
14882	            {
14883	               minresactivity = -SCIPinfinity(scip);
14884	               maxresactivity =  SCIPinfinity(scip);
14885	               isminsettoinfinity = TRUE;
14886	               ismaxsettoinfinity = TRUE;
14887	            }
14888	            else
14889	            {
14890	               /* calculate residual activity bounds if variable would be fixed to zero */
14891	               consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
14892	                  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
14893	
14894	               /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
14895	                * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
14896	                * This is needed, because we do not want to rely on relaxed finite resactivities.
14897	                */
14898	               assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
14899	
14900	               /* check minresactivity for reliability */
14901	               if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
14902	                  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
14903	
14904	               /* check maxresactivity for reliability */
14905	               if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
14906	                  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
14907	            }
14908	
14909	            arrayindex = SCIPvarGetProbindex(var) - nbinvars;
14910	
14911	            assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
14912	
14913	            newredlb = redlb[arrayindex];
14914	            newredub = redub[arrayindex];
14915	            if( val > 0.0 )
14916	            {
14917	               if( lhsexists )
14918	               {
14919	                  /* lhs <= d*x + a*y, d > 0  ->  redundant in y if  x >= (lhs - min{a*y})/d */
14920	                  nlocksdown[arrayindex] += nlockspos;
14921	                  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14922	               }
14923	               if( rhsexists )
14924	               {
14925	                  /* d*x + a*y <= rhs, d > 0  ->  redundant in y if  x <= (rhs - max{a*y})/d */
14926	                  nlocksup[arrayindex] += nlockspos;
14927	                  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14928	               }
14929	            }
14930	            else
14931	            {
14932	               if( lhsexists )
14933	               {
14934	                  /* lhs <= d*x + a*y, d < 0  ->  redundant in y if  x <= (lhs - min{a*y})/d */
14935	                  nlocksup[arrayindex] += nlockspos;
14936	                  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14937	               }
14938	               if( rhsexists )
14939	               {
14940	                  /* d*x + a*y <= rhs, d < 0  ->  redundant in y if  x >= (rhs - max{a*y})/d */
14941	                  nlocksdown[arrayindex] += nlockspos;
14942	                  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14943	               }
14944	            }
14945	
14946	            /* if the variable is integer, we have to round the value to the next integral value */
14947	            if( SCIPvarIsIntegral(var) )
14948	            {
14949	               if( !SCIPisInfinity(scip, newredlb) )
14950	                  newredlb = SCIPceil(scip, newredlb);
14951	               if( !SCIPisInfinity(scip, -newredub) )
14952	                  newredub = SCIPfloor(scip, newredub);
14953	            }
14954	
14955	            /* update redundancy bounds */
14956	            redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
14957	            redub[arrayindex] = MIN(redub[arrayindex], newredub);
14958	
14959	            /* collect the continuous variables of the constraint */
14960	            if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
14961	            {
14962	               int contv;
14963	
14964	               assert(nconscontvars < ncontvars);
14965	               contvarpos = i;
14966	               conscontvars[nconscontvars] = var;
14967	               nconscontvars++;
14968	
14969	               contv = SCIPvarGetProbindex(var) - nintvars;
14970	               assert(0 <= contv && contv < ncontvars);
14971	               hasimpliedpotential = hasimpliedpotential || isimplint[contv];
14972	            }
14973	         }
14974	
14975	         /* update implicit integer status of continuous variables */
14976	         if( hasimpliedpotential )
14977	         {
14978	            if( nconscontvars > 1 || !integralcoefs )
14979	            {
14980	               /* there is more than one continuous variable or the integer variables have fractional coefficients:
14981	                * none of the continuous variables is implicit integer
14982	                */
14983	               for( i = 0; i < nconscontvars; i++ )
14984	               {
14985	                  int contv;
14986	                  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
14987	                  assert(0 <= contv && contv < ncontvars);
14988	                  isimplint[contv] = FALSE;
14989	               }
14990	            }
14991	            else
14992	            {
14993	               SCIP_VAR* var;
14994	               SCIP_Real val;
14995	               SCIP_Real absval;
14996	               int contv;
14997	
14998	               /* there is exactly one continuous variable and the integer variables have integral coefficients:
14999	                * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
15000	                * side(s) of the constraint is integral
15001	                */
15002	               assert(nconscontvars == 1);
15003	               assert(0 <= contvarpos && contvarpos < consdata->nvars);
15004	               var = consdata->vars[contvarpos];
15005	               val = consdata->vals[contvarpos];
15006	               contv = SCIPvarGetProbindex(var) - nintvars;
15007	               assert(0 <= contv && contv < ncontvars);
15008	               assert(isimplint[contv]);
15009	
15010	               absval = REALABS(val);
15011	               if( !SCIPisEQ(scip, absval, 1.0) )
15012	                  isimplint[contv] =  FALSE;
15013	               else
15014	               {
15015	                  SCIP_Real obj;
15016	
15017	                  obj = SCIPvarGetObj(var);
15018	                  if( obj * val >= 0.0 && lhsexists )
15019	                  {
15020	                     /* the variable may be blocked by the constraint's left hand side */
15021	                     isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
15022	                  }
15023	                  if( obj * val <= 0.0 && rhsexists )
15024	                  {
15025	                     /* the variable may be blocked by the constraint's left hand side */
15026	                     isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
15027	                  }
15028	               }
15029	            }
15030	         }
15031	      }
15032	   }
15033	
15034	   /* check if any bounds can be tightened due to optimality */
15035	   for( v = 0; v < nvars; ++v )
15036	   {
15037	      SCIP_VAR* var;
15038	      SCIP_Real obj;
15039	      SCIP_Bool infeasible;
15040	      SCIP_Bool tightened;
15041	
15042	      assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
15043	      assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
15044	      assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
15045	
15046	      var = vars[v];
15047	      obj = SCIPvarGetObj(var);
15048	      if( !SCIPisPositive(scip, -obj) )
15049	      {
15050	         /* making the variable as small as possible does not increase the objective:
15051	          * check if all down locks of the variables are due to linear constraints;
15052	          * if variable is cost neutral and only upper bounded non-positively or negative largest bound to make
15053	          * constraints redundant is huge, we better do nothing for numerical reasons
15054	          */
15055	         if( ( SCIPisPositive(scip, obj) || SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) || !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
15056	            && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15057	            && !SCIPisHugeValue(scip, -redlb[v])
15058	            && redlb[v] < SCIPvarGetUbGlobal(var) )
15059	         {
15060	            SCIP_Real ub;
15061	
15062	            /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
15063	             *  -> tighten upper bound to x_v <= redlb[v]
15064	             */
15065	            SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
15066	               SCIPvarGetName(var), SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var),
15067	               redlb[v]);
15068	            SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
15069	            assert(!infeasible);
15070	
15071	            ub = SCIPvarGetUbGlobal(var);
15072	            redub[v] = MIN(redub[v], ub);
15073	            if( tightened )
15074	               (*nchgbds)++;
15075	         }
15076	      }
15077	      if( !SCIPisPositive(scip, obj) )
15078	      {
15079	         /* making the variable as large as possible does not increase the objective:
15080	          * check if all up locks of the variables are due to linear constraints;
15081	          * if variable is cost neutral and only lower bounded non-negatively or positive smallest bound to make
15082	          * constraints redundant is huge, we better do nothing for numerical reasons
15083	          */
15084	         if( ( SCIPisPositive(scip, -obj) || SCIPisPositive(scip, -SCIPvarGetLbGlobal(var)) || !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
15085	            && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v]
15086	            && !SCIPisHugeValue(scip, redub[v])
15087	            && redub[v] > SCIPvarGetLbGlobal(var) )
15088	         {
15089	            SCIP_Real lb;
15090	
15091	            /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
15092	             *  -> tighten lower bound to x_v >= redub[v]
15093	             */
15094	            SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
15095	               SCIPvarGetName(var), SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var),
15096	               redub[v]);
15097	            SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
15098	            assert(!infeasible);
15099	
15100	            lb = SCIPvarGetLbGlobal(var);
15101	            redlb[v] = MAX(redlb[v], lb);
15102	            if( tightened )
15103	               (*nchgbds)++;
15104	         }
15105	      }
15106	   }
15107	
15108	   /* upgrade continuous variables to implicit integers */
15109	   for( v = nintvars - nbinvars; v < nvars; ++v )
15110	   {
15111	      SCIP_VAR* var;
15112	      SCIP_Bool infeasible;
15113	
15114	      var = vars[v];
15115	      assert(var != NULL);
15116	
15117	      assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
15118	      assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
15119	      assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
15120	      assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
15121	
15122	      /* we can only conclude implicit integrality if the variable appears in no other constraint */
15123	      if( isimplint[v - nintvars + nbinvars]
15124	         && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15125	         && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v] )
15126	      {
15127	         /* since we locally copied the variable array we can change the variable type immediately */
15128	         SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
15129	
15130	         if( infeasible )
15131	         {
15132	            SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
15133	            *cutoff = TRUE;
15134	
15135	            break;
15136	         }
15137	
15138	         SCIPdebugMsg(scip, "dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
15139	            SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var));
15140	      }
15141	   }
15142	
15143	   /* free temporary memory */
15144	   SCIPfreeBufferArray(scip, &conscontvars);
15145	   SCIPfreeBufferArray(scip, &isimplint);
15146	   SCIPfreeBufferArray(scip, &nlocksup);
15147	   SCIPfreeBufferArray(scip, &nlocksdown);
15148	   SCIPfreeBufferArray(scip, &redub);
15149	   SCIPfreeBufferArray(scip, &redlb);
15150	
15151	   SCIPfreeBufferArray(scip, &vars);
15152	
15153	   return SCIP_OKAY;
15154	}
15155	
15156	/** helper function to enforce constraints */
15157	static
15158	SCIP_RETCODE enforceConstraint(
15159	   SCIP*                 scip,               /**< SCIP data structure */
15160	   SCIP_CONSHDLR*        conshdlr,           /**< constraint handler */
15161	   SCIP_CONS**           conss,              /**< constraints to process */
15162	   int                   nconss,             /**< number of constraints */
15163	   int                   nusefulconss,       /**< number of useful (non-obsolete) constraints to process */
15164	   SCIP_SOL*             sol,                /**< solution to enforce (NULL for the LP solution) */
15165	   SCIP_RESULT*          result              /**< pointer to store the result of the enforcing call */
15166	   )
15167	{
15168	   SCIP_CONSHDLRDATA* conshdlrdata;
15169	   SCIP_Bool checkrelmaxabs;
15170	   SCIP_Bool violated;
15171	   SCIP_Bool cutoff = FALSE;
15172	   int c;
15173	
15174	   assert(scip != NULL);
15175	   assert(conshdlr != NULL);
15176	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15177	   assert(result != NULL);
15178	
15179	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
15180	   assert(conshdlrdata != NULL);
15181	
15182	   checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15183	
15184	   SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
15185	
15186	   /* check for violated constraints
15187	    * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
15188	    */
15189	   *result = SCIP_FEASIBLE;
15190	
15191	   /* check all useful linear constraints for feasibility */
15192	   for( c = 0; c < nusefulconss; ++c )
15193	   {
15194	      SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15195	
15196	      if( violated )
15197	      {
15198	         /* insert LP row as cut */
15199	         SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15200	         if ( cutoff )
15201	            *result = SCIP_CUTOFF;
15202	         else
15203	            *result = SCIP_SEPARATED;
15204	      }
15205	   }
15206	
15207	   /* check all obsolete linear constraints for feasibility */
15208	   for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
15209	   {
15210	      SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15211	
15212	      if( violated )
15213	      {
15214	         /* insert LP row as cut */
15215	         SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15216	         if ( cutoff )
15217	            *result = SCIP_CUTOFF;
15218	         else
15219	            *result = SCIP_SEPARATED;
15220	      }
15221	   }
15222	
15223	   SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
15224	
15225	   return SCIP_OKAY;
15226	}
15227	
15228	/** adds symmetry information of constraint to a symmetry detection graph */
15229	static
15230	SCIP_RETCODE addSymmetryInformation(
15231	   SCIP*                 scip,               /**< SCIP pointer */
15232	   SYM_SYMTYPE           symtype,            /**< type of symmetries that need to be added */
15233	   SCIP_CONS*            cons,               /**< constraint */
15234	   SYM_GRAPH*            graph,              /**< symmetry detection graph */
15235	   SCIP_Bool*            success             /**< pointer to store whether symmetry information could be added */
15236	   )
15237	{
15238	   SCIP_CONSDATA* consdata;
15239	   SCIP_VAR** vars;
15240	   SCIP_Real* vals;
15241	   SCIP_Real constant = 0.0;
15242	   SCIP_Real lhs;
15243	   SCIP_Real rhs;
15244	   int nlocvars;
15245	   int nvars;
15246	   int i;
15247	
15248	   assert(scip != NULL);
15249	   assert(cons != NULL);
15250	   assert(graph != NULL);
15251	   assert(success != NULL);
15252	
15253	   consdata = SCIPconsGetData(cons);
15254	   assert(consdata != NULL);
15255	
15256	   /* get active variables of the constraint */
15257	   nvars = SCIPgetNVars(scip);
15258	   nlocvars = consdata->nvars;
15259	
15260	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
15261	   SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
15262	
15263	   for( i = 0; i < nlocvars; ++i )
15264	   {
15265	      vars[i] = consdata->vars[i];
15266	      vals[i] = consdata->vals[i];
15267	   }
15268	
15269	   SCIP_CALL( SCIPgetActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
15270	   lhs = consdata->lhs - constant;
15271	   rhs = consdata->rhs - constant;
15272	
15273	   /* if rhs is infinite, normalize rhs to be finite to make sure that different encodings
15274	    * of the same constraint are rated as equal
15275	    */
15276	   if ( SCIPisInfinity(scip, rhs) )
15277	   {
15278	      SCIP_Real tmp;
15279	      assert(!SCIPisInfinity(scip, -lhs));
15280	
15281	      for( i = 0; i < nlocvars; ++i )
15282	         vals[i] *= -1;
15283	      tmp = rhs;
15284	      rhs = -lhs;
15285	      lhs = -tmp;
15286	   }
15287	
15288	   SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
15289	         cons, lhs, rhs, success) );
15290	
15291	   SCIPfreeBufferArray(scip, &vals);
15292	   SCIPfreeBufferArray(scip, &vars);
15293	
15294	   return SCIP_OKAY;
15295	}
15296	
15297	/*
15298	 * Callback methods of constraint handler
15299	 */
15300	
15301	/** copy method for constraint handler plugins (called when SCIP copies plugins) */
15302	static
15303	SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
15304	{  /*lint --e{715}*/
15305	   assert(scip != NULL);
15306	   assert(conshdlr != NULL);
15307	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15308	
15309	   /* call inclusion method of constraint handler */
15310	   SCIP_CALL( SCIPincludeConshdlrLinear(scip) );
15311	
15312	   *valid = TRUE;
15313	
15314	   return SCIP_OKAY;
15315	}
15316	
15317	/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
15318	static
15319	SCIP_DECL_CONSFREE(consFreeLinear)
15320	{  /*lint --e{715}*/
15321	   SCIP_CONSHDLRDATA* conshdlrdata;
15322	
15323	   assert(scip != NULL);
15324	   assert(conshdlr != NULL);
15325	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15326	
15327	   /* free constraint handler data */
15328	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
15329	   assert(conshdlrdata != NULL);
15330	
15331	   conshdlrdataFree(scip, &conshdlrdata);
15332	
15333	   SCIPconshdlrSetData(conshdlr, NULL);
15334	
15335	   return SCIP_OKAY;
15336	}
15337	
15338	
15339	/** initialization method of constraint handler (called after problem was transformed) */
15340	static
15341	SCIP_DECL_CONSINIT(consInitLinear)
15342	{
15343	   SCIP_CONSHDLRDATA* conshdlrdata;
15344	   int c;
15345	
15346	   assert(scip != NULL);
15347	
15348	   /* check for event handler */
15349	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
15350	   assert(conshdlrdata != NULL);
15351	   assert(conshdlrdata->eventhdlr != NULL);
15352	   assert(nconss == 0 || conss != NULL);
15353	
15354	   conshdlrdata->naddconss = 0;
15355	
15356	   /* catch events for the constraints */
15357	   for( c = 0; c < nconss; ++c )
15358	   {
15359	      /* catch all events */
15360	      SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15361	   }
15362	
15363	   return SCIP_OKAY;
15364	}
15365	
15366	
15367	/** deinitialization method of constraint handler (called before transformed problem is freed) */
15368	static
15369	SCIP_DECL_CONSEXIT(consExitLinear)
15370	{
15371	   SCIP_CONSHDLRDATA* conshdlrdata;
15372	   int c;
15373	
15374	   assert(scip != NULL);
15375	
15376	   /* check for event handler */
15377	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
15378	   assert(conshdlrdata != NULL);
15379	   assert(conshdlrdata->eventhdlr != NULL);
15380	
15381	   /* drop events for the constraints */
15382	   for( c = nconss - 1; c >= 0; --c )
15383	   {
15384	      SCIP_CONSDATA* consdata;
15385	
15386	      consdata = SCIPconsGetData(conss[c]);
15387	      assert(consdata != NULL);
15388	
15389	      if( consdata->eventdata != NULL )
15390	      {
15391	         /* drop all events */
15392	         SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15393	         assert(consdata->eventdata == NULL);
15394	      }
15395	   }
15396	
15397	   return SCIP_OKAY;
15398	}
15399	
15400	/** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15401	static
15402	SCIP_Bool isRangedRow(
15403	   SCIP*                 scip,               /**< SCIP data structure */
15404	   SCIP_Real             lhs,                /**< left hand side */
15405	   SCIP_Real             rhs                 /**< right hand side */
15406	   )
15407	{
15408	   assert(scip != NULL);
15409	
15410	   return !(SCIPisEQ(scip, lhs, rhs) || SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
15411	}
15412	
15413	/** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15414	static
15415	SCIP_Bool isFiniteNonnegativeIntegral(
15416	   SCIP*                 scip,               /**< SCIP data structure */
15417	   SCIP_Real             x                   /**< value */
15418	   )
15419	{
15420	   assert(scip != NULL);
15421	
15422	   return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
15423	}
15424	
15425	/** performs linear constraint type classification as used for MIPLIB
15426	 *
15427	 *  iterates through all linear constraints and stores relevant statistics in the linear constraint statistics \p linconsstats.
15428	 *
15429	 *  @note only constraints are iterated that belong to the linear constraint handler. If the problem has been presolved already,
15430	 *  constraints that were upgraded to more special types such as, e.g., varbound constraints, will not be shown correctly anymore.
15431	 *  Similarly, if specialized constraints were created through the API, these are currently not present.
15432	 */
15433	SCIP_RETCODE SCIPclassifyConstraintTypesLinear(
15434	   SCIP*                 scip,               /**< SCIP data structure */
15435	   SCIP_LINCONSSTATS*    linconsstats        /**< linear constraint type classification */
15436	   )
15437	{
15438	   int c;
15439	   SCIP_CONSHDLR* conshdlr;
15440	   SCIP_CONS** conss;
15441	   int nconss;
15442	
15443	   assert(scip != NULL);
15444	   assert(linconsstats != NULL);
15445	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
15446	   assert(conshdlr != NULL);
15447	
15448	   if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
15449	   {
15450	      conss = SCIPgetConss(scip);
15451	      nconss = SCIPgetNConss(scip);
15452	   }
15453	   else
15454	   {
15455	      conss = SCIPconshdlrGetConss(conshdlr);
15456	      nconss = SCIPconshdlrGetNConss(conshdlr);
15457	   }
15458	
15459	   /* reset linear constraint type classification */
15460	   SCIPlinConsStatsReset(linconsstats);
15461	
15462	   /* loop through all constraints */
15463	   for( c = 0; c < nconss; c++ )
15464	   {
15465	      SCIP_CONS* cons;
15466	      SCIP_CONSDATA* consdata;
15467	      SCIP_Real lhs;
15468	      SCIP_Real rhs;
15469	      int i;
15470	
15471	      /* get constraint */
15472	      cons = conss[c];
15473	      assert(cons != NULL);
15474	
15475	      /* skip constraints that are not handled by the constraint handler */
15476	      if( SCIPconsGetHdlr(cons) != conshdlr )
15477	         continue;
15478	
15479	      /* get constraint data */
15480	      consdata = SCIPconsGetData(cons);
15481	      assert(consdata != NULL);
15482	      rhs = consdata->rhs;
15483	      lhs = consdata->lhs;
15484	
15485	      /* merge multiples and delete variables with zero coefficient */
15486	      SCIP_CALL( mergeMultiples(scip, cons) );
15487	      for( i = 0; i < consdata->nvars; i++ )
15488	      {
15489	         assert(!SCIPisZero(scip, consdata->vals[i]));
15490	      }
15491	
15492	      /* is constraint of type SCIP_CONSTYPE_EMPTY? */
15493	      if( consdata->nvars == 0 )
15494	      {
15495	         SCIPdebugMsg(scip, "classified as EMPTY: ");
15496	         SCIPdebugPrintCons(scip, cons, NULL);
15497	         SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_EMPTY, 1);
15498	
15499	         continue;
15500	      }
15501	
15502	      /* is constraint of type SCIP_CONSTYPE_FREE? */
15503	      if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
15504	      {
15505	         SCIPdebugMsg(scip, "classified as FREE: ");
15506	         SCIPdebugPrintCons(scip, cons, NULL);
15507	         SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_FREE, 1);
15508	
15509	         continue;
15510	      }
15511	
15512	      /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
15513	      if( consdata->nvars == 1 )
15514	      {
15515	         SCIPdebugMsg(scip, "classified as SINGLETON: ");
15516	         SCIPdebugPrintCons(scip, cons, NULL);
15517	         SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SINGLETON, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15518	
15519	         continue;
15520	      }
15521	
15522	      /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
15523	      if( consdata->nvars == 2 && SCIPisEQ(scip, lhs, rhs) )
15524	      {
15525	         SCIPdebugMsg(scip, "classified as AGGREGATION: ");
15526	         SCIPdebugPrintCons(scip, cons, NULL);
15527	         SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_AGGREGATION, 1);
15528	
15529	         continue;
15530	      }
15531	
15532	      /* is constraint of type SCIP_CONSTYPE_{VARBOUND,PRECEDENCE}? */
15533	      if( consdata->nvars == 2 )
15534	      {
15535	         SCIP_LINCONSTYPE constype;
15536	
15537	         /* precedence constraints have the same coefficient, but with opposite sign for the same variable type */
15538	         if( SCIPisEQ(scip, consdata->vals[0], -consdata->vals[1])
15539	               && SCIPvarGetType(consdata->vars[0]) == SCIPvarGetType(consdata->vars[1]))
15540	         {
15541	            constype = SCIP_LINCONSTYPE_PRECEDENCE;
15542	            SCIPdebugMsg(scip, "classified as PRECEDENCE: ");
15543	         }
15544	         else
15545	         {
15546	            constype = SCIP_LINCONSTYPE_VARBOUND;
15547	            SCIPdebugMsg(scip, "classified as VARBOUND: ");
15548	         }
15549	         SCIPdebugPrintCons(scip, cons, NULL);
15550	
15551	         SCIPlinConsStatsIncTypeCount(linconsstats, constype, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15552	
15553	         continue;
15554	      }
15555	
15556	      /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
15557	      {
15558	         SCIP_Real scale;
15559	         SCIP_Real b;
15560	         SCIP_Bool unmatched;
15561	         int nnegbinvars;
15562	
15563	         unmatched = FALSE;
15564	         nnegbinvars = 0;
15565	
15566	         scale = REALABS(consdata->vals[0]);
15567	
15568	         /* scan through variables and detect if all variables are binary and have a coefficient +/-1 */
15569	         for( i = 0; i < consdata->nvars && !unmatched; i++ )
15570	         {
15571	            unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15572	            unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15573	            unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15574	            unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
15575	
15576	            if( consdata->vals[i] < 0.0 )
15577	               nnegbinvars++;
15578	         }
15579	
15580	         if( !unmatched )
15581	         {
15582	            if( SCIPisEQ(scip, lhs, rhs) )
15583	            {
15584	               b = rhs/scale + nnegbinvars;
15585	               if( SCIPisEQ(scip, 1.0, b) )
15586	               {
15587	                  SCIPdebugMsg(scip, "classified as SETPARTITION: ");
15588	                  SCIPdebugPrintCons(scip, cons, NULL);
15589	                  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SETPARTITION, 1);
15590	
15591	                  continue;
15592	               }
15593	               else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15594	               {
15595	                  SCIPdebugMsg(scip, "classified as CARDINALITY: ");
15596	                  SCIPdebugPrintCons(scip, cons, NULL);
15597	                  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_CARDINALITY, 1);
15598	
15599	                  continue;
15600	               }
15601	            }
15602	
15603	            /* compute right hand side divided by scale */
15604	            if( !SCIPisInfinity(scip, rhs) )
15605	               b = rhs/scale + nnegbinvars;
15606	            else
15607	               b = SCIPinfinity(scip);
15608	
15609	            if( SCIPisEQ(scip, 1.0, b) )
15610	            {
15611	               SCIPdebugMsg(scip, "classified as SETPACKING: ");
15612	               SCIPdebugPrintCons(scip, cons, NULL);
15613	               SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SETPACKING, 1);
15614	
15615	               /* relax right hand side to prevent further classifications */
15616	               rhs = SCIPinfinity(scip);
15617	            }
15618	            else if( !SCIPisInfinity(scip, b) && SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15619	            {
15620	               SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
15621	               SCIPdebugPrintCons(scip, cons, NULL);
15622	
15623	               SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_INVKNAPSACK, 1);;
15624	
15625	               /* relax right hand side to prevent further classifications */
15626	               rhs = SCIPinfinity(scip);
15627	            }
15628	
15629	            if( !SCIPisInfinity(scip, lhs) )
15630	               b = lhs/scale + nnegbinvars;
15631	            else
15632	               b = SCIPinfinity(scip);
15633	
15634	            if( SCIPisEQ(scip, 1.0, b) )
15635	            {
15636	               SCIPdebugMsg(scip, "classified as SETCOVERING: ");
15637	               SCIPdebugPrintCons(scip, cons, NULL);
15638	               SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SETCOVERING, 1);
15639	
15640	               /* relax left hand side to prevent further classifications */
15641	               lhs = -SCIPinfinity(scip);
15642	            }
15643	
15644	            /* if both sides are infinite at this point, no further classification is necessary for this constraint */
15645	            if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
15646	               continue;
15647	         }
15648	      }
15649	
15650	      /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
15651	      /* @todo If coefficients or rhs are not integral, we currently do not check
15652	       * if the constraint could be scaled (finitely), such that they are.
15653	       */
15654	      {
15655	         SCIP_Real b;
15656	         SCIP_Bool unmatched;
15657	
15658	         b = rhs;
15659	         unmatched = FALSE;
15660	         for( i = 0; i < consdata->nvars && !unmatched; i++ )
15661	         {
15662	            unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15663	            unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15664	            unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15665	            unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15666	
15667	            if( SCIPisNegative(scip, consdata->vals[i]) )
15668	               b -= consdata->vals[i];
15669	         }
15670	         unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15671	
15672	         if( !unmatched )
15673	         {
15674	            if( SCIPisEQ(scip, lhs, rhs) )
15675	            {
15676	               SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
15677	               SCIPdebugPrintCons(scip, cons, NULL);
15678	
15679	               SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_EQKNAPSACK, 1);
15680	
15681	               continue;
15682	            }
15683	            else
15684	            {
15685	               SCIP_Bool matched;
15686	
15687	               matched = FALSE;
15688	               for( i = 0; i < consdata->nvars && !matched; i++ )
15689	               {
15690	                  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
15691	               }
15692	
15693	               SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
15694	               SCIPdebugPrintCons(scip, cons, NULL);
15695	               SCIPlinConsStatsIncTypeCount(linconsstats, matched ? SCIP_LINCONSTYPE_BINPACKING : SCIP_LINCONSTYPE_KNAPSACK, 1);
15696	            }
15697	
15698	            /* check if finite left hand side allows for a second classification, relax already used right hand side */
15699	            if( SCIPisInfinity(scip, -lhs) )
15700	               continue;
15701	            else
15702	               rhs = SCIPinfinity(scip);
15703	         }
15704	      }
15705	
15706	      /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
15707	      {
15708	         SCIP_Real b;
15709	         SCIP_Bool unmatched;
15710	
15711	         unmatched = FALSE;
15712	
15713	         b = rhs;
15714	         unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15715	
15716	         for( i = 0; i < consdata->nvars && !unmatched; i++ )
15717	         {
15718	            unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15719	            unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
15720	            unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15721	            unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
15722	         }
15723	
15724	         if( !unmatched )
15725	         {
15726	            SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
15727	            SCIPdebugPrintCons(scip, cons, NULL);
15728	            SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_INTKNAPSACK, 1);
15729	
15730	            /* check if finite left hand side allows for a second classification, relax already used right hand side */
15731	            if( SCIPisInfinity(scip, -lhs) )
15732	               continue;
15733	            else
15734	               rhs = SCIPinfinity(scip);
15735	         }
15736	      }
15737	
15738	      /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
15739	      {
15740	         SCIP_Bool unmatched;
15741	
15742	         unmatched = FALSE;
15743	         for( i = 0; i < consdata->nvars && !unmatched; i++ )
15744	         {
15745	            if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
15746	               && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
15747	                  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
15748	               unmatched = TRUE;
15749	         }
15750	
15751	         if( !unmatched )
15752	         {
15753	            SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, lhs, rhs) ? 2 : 1);
15754	            SCIPdebugPrintCons(scip, cons, NULL);
15755	            SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_MIXEDBINARY, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15756	
15757	            continue;
15758	         }
15759	      }
15760	
15761	      /* no special structure detected */
15762	      SCIPdebugMsg(scip, "classified as GENERAL: ");
15763	      SCIPdebugPrintCons(scip, cons, NULL);
15764	      SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_GENERAL, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15765	   }
15766	
15767	   return SCIP_OKAY;
15768	}
15769	
15770	
15771	/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
15772	static
15773	SCIP_DECL_CONSEXITPRE(consExitpreLinear)
15774	{  /*lint --e{715}*/
15775	   int c;
15776	#ifdef SCIP_STATISTIC
15777	   SCIP_CONSHDLRDATA* conshdlrdata;
15778	   int ngoodconss;
15779	   int nallconss;
15780	#endif
15781	
15782	   /* delete all linear constraints that were upgraded to a more specific constraint type;
15783	    * make sure, only active variables remain in the remaining constraints
15784	    */
15785	   assert(scip != NULL);
15786	
15787	#ifdef SCIP_STATISTIC
15788	   /* count number of well behaved linear constraints */
15789	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
15790	   assert(conshdlrdata != NULL);
15791	
15792	   ngoodconss = 0;
15793	   nallconss = 0;
15794	
15795	   for( c = 0; c < nconss; ++c )
15796	   {
15797	      SCIP_CONSDATA* consdata;
15798	
15799	      if( SCIPconsIsDeleted(conss[c]) )
15800	         continue;
15801	
15802	      consdata = SCIPconsGetData(conss[c]);
15803	      assert(consdata != NULL);
15804	
15805	      if( consdata->upgraded )
15806	         continue;
15807	
15808	      nallconss++;
15809	
15810	      consdataRecomputeMaxActivityDelta(scip, consdata);
15811	
15812	      if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
15813	         ngoodconss++;
15814	   }
15815	   if( nallconss )
15816	   {
15817	      SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
15818	   }
15819	#endif
15820	
15821	   for( c = 0; c < nconss; ++c )
15822	   {
15823	      SCIP_CONSDATA* consdata;
15824	
15825	      if( SCIPconsIsDeleted(conss[c]) )
15826	         continue;
15827	
15828	      consdata = SCIPconsGetData(conss[c]);
15829	      assert(consdata != NULL);
15830	
15831	      if( consdata->upgraded )
15832	      {
15833	         /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
15834	          * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
15835	          */
15836	         SCIP_CALL( SCIPdelCons(scip, conss[c]) );
15837	      }
15838	      else
15839	      {
15840	         /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
15841	         SCIP_CALL( applyFixings(scip, conss[c], NULL) );
15842	      }
15843	   }
15844	
15845	   return SCIP_OKAY;
15846	}
15847	
15848	/** solving process initialization method of constraint handler */
15849	static
15850	SCIP_DECL_CONSINITSOL(consInitsolLinear)
15851	{  /*lint --e{715}*/
15852	   /* add nlrow representation to NLP, if NLP had been constructed */
15853	   if( SCIPisNLPConstructed(scip) )
15854	   {
15855	      int c;
15856	      for( c = 0; c < nconss; ++c )
15857	      {
15858	         SCIP_CALL( addNlrow(scip, conss[c]) );
15859	      }
15860	   }
15861	
15862	   return SCIP_OKAY;
15863	}
15864	
15865	/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
15866	static
15867	SCIP_DECL_CONSEXITSOL(consExitsolLinear)
15868	{  /*lint --e{715}*/
15869	   int c;
15870	
15871	   assert(scip != NULL);
15872	
15873	   /* release the rows and nlrows of all constraints */
15874	   for( c = 0; c < nconss; ++c )
15875	   {
15876	      SCIP_CONSDATA* consdata;
15877	
15878	      consdata = SCIPconsGetData(conss[c]);
15879	      assert(consdata != NULL);
15880	
15881	      if( consdata->row != NULL )
15882	      {
15883	         SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
15884	      }
15885	
15886	      if( consdata->nlrow != NULL )
15887	      {
15888	         SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
15889	      }
15890	   }
15891	
15892	   /* if this is a restart, convert cutpool rows into linear constraints */
15893	   if( restart )
15894	   {
15895	      int ncutsadded;
15896	
15897	      ncutsadded = 0;
15898	
15899	      /* create out of all active cuts in cutpool linear constraints */
15900	      SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
15901	
15902	      if( ncutsadded > 0 )
15903	      {
15904	         SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
15905	            "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
15906	         /* an extra blank line should be printed separately since the buffer message handler only handles up to one
15907	          * line correctly
15908	          */
15909	         SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "\n");
15910	      }
15911	   }
15912	
15913	   return SCIP_OKAY;
15914	}
15915	
15916	
15917	/** constraint activation notification method of constraint handler */
15918	static
15919	SCIP_DECL_CONSACTIVE(consActiveLinear)
15920	{  /*lint --e{715}*/
15921	   assert(cons != NULL);
15922	
15923	   if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && SCIPisNLPConstructed(scip) )
15924	   {
15925	      SCIP_CALL( addNlrow(scip, cons) );
15926	   }
15927	
15928	   return SCIP_OKAY;
15929	}
15930	
15931	/** constraint deactivation notification method of constraint handler */
15932	static
15933	SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
15934	{  /*lint --e{715}*/
15935	   SCIP_CONSDATA* consdata;
15936	
15937	   assert(scip != NULL);
15938	   assert(conshdlr != NULL);
15939	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15940	   assert(cons != NULL );
15941	
15942	   /* get constraint data */
15943	   consdata = SCIPconsGetData(cons);
15944	   assert(consdata != NULL);
15945	
15946	   if( SCIPconsIsDeleted(cons) )
15947	   {
15948	      SCIP_CONSHDLRDATA* conshdlrdata;
15949	
15950	      /* check for event handler */
15951	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
15952	      assert(conshdlrdata != NULL);
15953	      assert(conshdlrdata->eventhdlr != NULL);
15954	
15955	      /* free event data */
15956	      if( consdata->eventdata != NULL )
15957	      {
15958	         /* drop bound change events of variables */
15959	         SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15960	      }
15961	      assert(consdata->eventdata == NULL);
15962	   }
15963	
15964	   /* remove row from NLP, if still in solving
15965	    * if we are in exitsolve, the whole NLP will be freed anyway
15966	    */
15967	   if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
15968	   {
15969	      SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
15970	   }
15971	
15972	   return SCIP_OKAY;
15973	}
15974	
15975	
15976	/** frees specific constraint data */
15977	static
15978	SCIP_DECL_CONSDELETE(consDeleteLinear)
15979	{  /*lint --e{715}*/
15980	   assert(scip != NULL);
15981	   assert(conshdlr != NULL);
15982	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15983	
15984	   if( (*consdata)->eventdata != NULL )
15985	   {
15986	      SCIP_CONSHDLRDATA* conshdlrdata;
15987	
15988	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
15989	      assert(conshdlrdata != NULL);
15990	
15991	      /* drop all events */
15992	      SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15993	      assert((*consdata)->eventdata == NULL);
15994	   }
15995	
15996	   /* free linear constraint */
15997	   SCIP_CALL( consdataFree(scip, consdata) );
15998	
15999	   return SCIP_OKAY;
16000	}
16001	
16002	
16003	/** transforms constraint data into data belonging to the transformed problem */
16004	static
16005	SCIP_DECL_CONSTRANS(consTransLinear)
16006	{  /*lint --e{715}*/
16007	   SCIP_CONSDATA* sourcedata;
16008	   SCIP_CONSDATA* targetdata;
16009	
16010	   /*debugMsg(scip, "Trans method of linear constraints\n");*/
16011	
16012	   assert(scip != NULL);
16013	   assert(conshdlr != NULL);
16014	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16015	   assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
16016	   assert(sourcecons != NULL);
16017	   assert(targetcons != NULL);
16018	
16019	   sourcedata = SCIPconsGetData(sourcecons);
16020	   assert(sourcedata != NULL);
16021	   assert(sourcedata->row == NULL);  /* in original problem, there cannot be LP rows */
16022	
16023	   /* create linear constraint data for target constraint */
16024	   SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
16025	
16026	#ifndef NDEBUG
16027	   /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
16028	   if( SCIPconsIsEnforced(sourcecons) || SCIPconsIsChecked(sourcecons) )
16029	   {
16030	      int n;
16031	      for(n = targetdata->nvars - 1; n >= 0; --n )
16032	         assert(!SCIPvarIsRelaxationOnly(targetdata->vars[n]));
16033	   }
16034	#endif
16035	
16036	   /* create target constraint */
16037	   SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
16038	         SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
16039	         SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
16040	         SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
16041	         SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
16042	
16043	   return SCIP_OKAY;
16044	}
16045	
16046	
16047	/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
16048	static
16049	SCIP_DECL_CONSINITLP(consInitlpLinear)
16050	{  /*lint --e{715}*/
16051	   int c;
16052	
16053	   assert(scip != NULL);
16054	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16055	
16056	   *infeasible = FALSE;
16057	
16058	   for( c = 0; c < nconss && !(*infeasible); ++c )
16059	   {
16060	      assert(SCIPconsIsInitial(conss[c]));
16061	      SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
16062	   }
16063	
16064	   return SCIP_OKAY;
16065	}
16066	
16067	
16068	/** separation method of constraint handler for LP solutions */
16069	static
16070	SCIP_DECL_CONSSEPALP(consSepalpLinear)
16071	{  /*lint --e{715}*/
16072	   SCIP_CONSHDLRDATA* conshdlrdata;
16073	   SCIP_Real loclowerbound;
16074	   SCIP_Real glblowerbound;
16075	   SCIP_Real cutoffbound;
16076	   SCIP_Real maxbound;
16077	   SCIP_Bool separatecards;
16078	   SCIP_Bool cutoff;
16079	   int c;
16080	   int depth;
16081	   int nrounds;
16082	   int maxsepacuts;
16083	   int ncuts;
16084	
16085	   assert(scip != NULL);
16086	   assert(conshdlr != NULL);
16087	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16088	   assert(result != NULL);
16089	
16090	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16091	   assert(conshdlrdata != NULL);
16092	   depth = SCIPgetDepth(scip);
16093	   nrounds = SCIPgetNSepaRounds(scip);
16094	
16095	   /*debugMsg(scip, "Sepa method of linear constraints\n");*/
16096	
16097	   *result = SCIP_DIDNOTRUN;
16098	
16099	   /* only call the separator a given number of times at each node */
16100	   if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
16101	      || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
16102	      return SCIP_OKAY;
16103	
16104	   /* get the maximal number of cuts allowed in a separation round */
16105	   maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
16106	
16107	   /* check if we want to produce knapsack cardinality cuts at this node */
16108	   loclowerbound = SCIPgetLocalLowerbound(scip);
16109	   glblowerbound = SCIPgetLowerbound(scip);
16110	   cutoffbound = SCIPgetCutoffbound(scip);
16111	   maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
16112	   separatecards = SCIPisLE(scip, loclowerbound, maxbound);
16113	   separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
16114	
16115	   *result = SCIP_DIDNOTFIND;
16116	   ncuts = 0;
16117	   cutoff = FALSE;
16118	
16119	   /* check all useful linear constraints for feasibility */
16120	   for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16121	   {
16122	      /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16123	      SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
16124	   }
16125	
16126	   /* adjust return value */
16127	   if( cutoff )
16128	      *result = SCIP_CUTOFF;
16129	   else if( ncuts > 0 )
16130	      *result = SCIP_SEPARATED;
16131	
16132	   /* combine linear constraints to get more cuts */
16133	   /**@todo further cuts of linear constraints */
16134	
16135	   return SCIP_OKAY;
16136	}
16137	
16138	
16139	/** separation method of constraint handler for arbitrary primal solutions */
16140	static
16141	SCIP_DECL_CONSSEPASOL(consSepasolLinear)
16142	{  /*lint --e{715}*/
16143	   SCIP_CONSHDLRDATA* conshdlrdata;
16144	   int c;
16145	   int depth;
16146	   int nrounds;
16147	   int maxsepacuts;
16148	   int ncuts;
16149	   SCIP_Bool cutoff;
16150	
16151	   assert(scip != NULL);
16152	   assert(conshdlr != NULL);
16153	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16154	   assert(result != NULL);
16155	
16156	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16157	   assert(conshdlrdata != NULL);
16158	   depth = SCIPgetDepth(scip);
16159	   nrounds = SCIPgetNSepaRounds(scip);
16160	
16161	   /*debugMsg(scip, "Sepa method of linear constraints\n");*/
16162	
16163	   *result = SCIP_DIDNOTRUN;
16164	
16165	   /* only call the separator a given number of times at each node */
16166	   if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
16167	      || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
16168	      return SCIP_OKAY;
16169	
16170	   /* get the maximal number of cuts allowed in a separation round */
16171	   maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
16172	
16173	   *result = SCIP_DIDNOTFIND;
16174	   ncuts = 0;
16175	   cutoff = FALSE;
16176	
16177	   /* check all useful linear constraints for feasibility */
16178	   for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16179	   {
16180	      /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16181	      SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
16182	   }
16183	
16184	   /* adjust return value */
16185	   if( cutoff )
16186	      *result = SCIP_CUTOFF;
16187	   else if( ncuts > 0 )
16188	      *result = SCIP_SEPARATED;
16189	
16190	   /* combine linear constraints to get more cuts */
16191	   /**@todo further cuts of linear constraints */
16192	
16193	   return SCIP_OKAY;
16194	}
16195	
16196	
16197	/** constraint enforcing method of constraint handler for LP solutions */
16198	static
16199	SCIP_DECL_CONSENFOLP(consEnfolpLinear)
16200	{  /*lint --e{715}*/
16201	   SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
16202	
16203	   return SCIP_OKAY;
16204	}
16205	
16206	/** constraint enforcing method of constraint handler for relaxation solutions */
16207	static
16208	SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
16209	{  /*lint --e{715}*/
16210	   SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
16211	
16212	   return SCIP_OKAY;
16213	}
16214	
16215	/** constraint enforcing method of constraint handler for pseudo solutions */
16216	static
16217	SCIP_DECL_CONSENFOPS(consEnfopsLinear)
16218	{  /*lint --e{715}*/
16219	   SCIP_CONSHDLRDATA* conshdlrdata;
16220	   SCIP_Bool checkrelmaxabs;
16221	   SCIP_Bool violated;
16222	   int c;
16223	
16224	   assert(scip != NULL);
16225	   assert(conshdlr != NULL);
16226	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16227	   assert(result != NULL);
16228	
16229	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16230	   assert(conshdlrdata != NULL);
16231	
16232	   checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16233	
16234	   SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
16235	
16236	   /* if the solution is infeasible anyway due to objective value, skip the enforcement */
16237	   if( objinfeasible )
16238	   {
16239	      SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
16240	
16241	      *result = SCIP_DIDNOTRUN;
16242	      return SCIP_OKAY;
16243	   }
16244	
16245	   /* check all linear constraints for feasibility */
16246	   violated = FALSE;
16247	   for( c = 0; c < nconss && !violated; ++c )
16248	   {
16249	      SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
16250	   }
16251	
16252	   if( violated )
16253	      *result = SCIP_INFEASIBLE;
16254	   else
16255	      *result = SCIP_FEASIBLE;
16256	
16257	   SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
16258	
16259	   return SCIP_OKAY;
16260	}
16261	
16262	
16263	/** feasibility check method of constraint handler for integral solutions */
16264	static
16265	SCIP_DECL_CONSCHECK(consCheckLinear)
16266	{  /*lint --e{715}*/
16267	   SCIP_CONSHDLRDATA* conshdlrdata;
16268	   SCIP_Bool checkrelmaxabs;
16269	   int c;
16270	
16271	   assert(scip != NULL);
16272	   assert(conshdlr != NULL);
16273	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16274	   assert(result != NULL);
16275	
16276	   *result = SCIP_FEASIBLE;
16277	
16278	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16279	   assert(conshdlrdata != NULL);
16280	
16281	   checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16282	
16283	   /*debugMsg(scip, "Check method of linear constraints\n");*/
16284	
16285	   /* check all linear constraints for feasibility */
16286	   for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
16287	   {
16288	      SCIP_Bool violated = FALSE;
16289	      SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
16290	
16291	      if( violated )
16292	      {
16293	         *result = SCIP_INFEASIBLE;
16294	
16295	         if( printreason )
16296	         {
16297	            SCIP_CONSDATA* consdata;
16298	            SCIP_Real activity;
16299	
16300	            consdata = SCIPconsGetData(conss[c]);
16301	            assert( consdata != NULL);
16302	
16303	            activity = consdataGetActivity(scip, consdata, sol);
16304	
16305	            SCIP_CALL( consPrintConsSol(scip, conss[c], sol, NULL ) );
16306	            SCIPinfoMessage(scip, NULL, ";\n");
16307	
16308	            if( activity == SCIP_INVALID ) /*lint !e777*/
16309	               SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
16310	            else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
16311	               SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
16312	            else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
16313	               SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
16314	         }
16315	      }
16316	   }
16317	
16318	   return SCIP_OKAY;
16319	}
16320	
16321	
16322	/** domain propagation method of constraint handler */
16323	static
16324	SCIP_DECL_CONSPROP(consPropLinear)
16325	{  /*lint --e{715}*/
16326	   SCIP_CONSHDLRDATA* conshdlrdata;
16327	   SCIP_Bool rangedrowpropagation = FALSE;
16328	   SCIP_Bool tightenbounds;
16329	   SCIP_Bool cutoff;
16330	
16331	   int nchgbds;
16332	   int i;
16333	
16334	   assert(scip != NULL);
16335	   assert(conshdlr != NULL);
16336	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16337	   assert(result != NULL);
16338	
16339	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16340	   assert(conshdlrdata != NULL);
16341	
16342	   /*debugMsg(scip, "Prop method of linear constraints\n");*/
16343	
16344	   /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
16345	   if( SCIPinProbing(scip) )
16346	      tightenbounds = TRUE;
16347	   else
16348	   {
16349	      int depth;
16350	      int propfreq;
16351	      int tightenboundsfreq;
16352	      int rangedrowfreq;
16353	
16354	      depth = SCIPgetDepth(scip);
16355	      propfreq = SCIPconshdlrGetPropFreq(conshdlr);
16356	      tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
16357	      tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
16358	         && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
16359	
16360	      /* check if we want to do ranged row propagation */
16361	      rangedrowpropagation = conshdlrdata->rangedrowpropagation;
16362	      rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
16363	      rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
16364	      rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
16365	      rangedrowpropagation = rangedrowpropagation && (conshdlrdata->rangedrowfreq >= 0)
16366	         && ((rangedrowfreq == 0 && depth == 0) || (rangedrowfreq >= 1 && (depth % rangedrowfreq == 0)));
16367	   }
16368	
16369	   cutoff = FALSE;
16370	   nchgbds = 0;
16371	
16372	   /* process constraints marked for propagation */
16373	   for( i = 0; i < nmarkedconss && !cutoff; i++ )
16374	   {
16375	      SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
16376	      SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
16377	            conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
16378	   }
16379	
16380	   /* adjust result code */
16381	   if( cutoff )
16382	      *result = SCIP_CUTOFF;
16383	   else if( nchgbds > 0 )
16384	      *result = SCIP_REDUCEDDOM;
16385	   else
16386	      *result = SCIP_DIDNOTFIND;
16387	
16388	   return SCIP_OKAY;
16389	}
16390	
16391	
16392	#define MAXCONSPRESOLROUNDS 10
16393	/** presolving method of constraint handler */
16394	static
16395	SCIP_DECL_CONSPRESOL(consPresolLinear)
16396	{  /*lint --e{715}*/
16397	   SCIP_CONSHDLRDATA* conshdlrdata;
16398	   SCIP_CONS* cons;
16399	   SCIP_CONSDATA* consdata;
16400	   SCIP_Real minactivity;
16401	   SCIP_Real maxactivity;
16402	   SCIP_Bool minactisrelax;
16403	   SCIP_Bool maxactisrelax;
16404	   SCIP_Bool isminsettoinfinity;
16405	   SCIP_Bool ismaxsettoinfinity;
16406	   SCIP_Bool cutoff;
16407	   int oldnfixedvars;
16408	   int oldnaggrvars;
16409	   int oldnchgbds;
16410	   int oldndelconss;
16411	   int oldnupgdconss;
16412	   int oldnchgcoefs;
16413	   int oldnchgsides;
16414	   int firstchange;
16415	   int firstupgradetry;
16416	   int c;
16417	
16418	   assert(scip != NULL);
16419	   assert(conshdlr != NULL);
16420	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16421	   assert(result != NULL);
16422	
16423	   /*debugMsg(scip, "Presol method of linear constraints\n");*/
16424	
16425	   /* remember old preprocessing counters */
16426	   cutoff = FALSE;
16427	   oldnfixedvars = *nfixedvars;
16428	   oldnaggrvars = *naggrvars;
16429	   oldnchgbds = *nchgbds;
16430	   oldndelconss = *ndelconss;
16431	   oldnupgdconss = *nupgdconss;
16432	   oldnchgcoefs = *nchgcoefs;
16433	   oldnchgsides = *nchgsides;
16434	
16435	   /* get constraint handler data */
16436	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
16437	   assert(conshdlrdata != NULL);
16438	
16439	   /* process single constraints */
16440	   firstchange = INT_MAX;
16441	   firstupgradetry = INT_MAX;
16442	   for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
16443	   {
16444	      int npresolrounds;
16445	      SCIP_Bool infeasible;
16446	
16447	      infeasible = FALSE;
16448	
16449	      cons = conss[c];
16450	      assert(SCIPconsIsActive(cons));
16451	      consdata = SCIPconsGetData(cons);
16452	      assert(consdata != NULL);
16453	
16454	      /* ensure that rhs >= lhs is satisfied without numerical tolerance */
16455	      if( SCIPisEQ(scip, consdata->rhs, consdata->lhs) )
16456	      {
16457	         consdata->lhs = consdata->rhs;
16458	         assert(consdata->row == NULL);
16459	      }
16460	
16461	      if( consdata->eventdata == NULL )
16462	      {
16463	         /* catch bound change events of variables */
16464	         SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
16465	         assert(consdata->eventdata != NULL);
16466	      }
16467	
16468	      /* constraint should not be already presolved in the initial round */
16469	      assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
16470	      assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
16471	      assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
16472	      assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
16473	
16474	      /* incorporate fixings and aggregations in constraint */
16475	      SCIP_CALL( applyFixings(scip, cons, &infeasible) );
16476	
16477	      if( infeasible )
16478	      {
16479	         SCIPdebugMsg(scip, " -> infeasible fixing\n");
16480	         cutoff = TRUE;
16481	         break;
16482	      }
16483	
16484	      assert(consdata->removedfixings);
16485	
16486	      /* we can only presolve linear constraints, that are not modifiable */
16487	      if( SCIPconsIsModifiable(cons) )
16488	         continue;
16489	
16490	      /* remember the first changed constraint to begin the next aggregation round with */
16491	      if( firstchange == INT_MAX && consdata->changed )
16492	         firstchange = c;
16493	
16494	      /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16495	      if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16496	         firstupgradetry = c;
16497	
16498	      /* check, if constraint is already preprocessed */
16499	      if( consdata->presolved )
16500	         continue;
16501	
16502	      assert(SCIPconsIsActive(cons));
16503	
16504	      SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
16505	      SCIPdebugPrintCons(scip, cons, NULL);
16506	
16507	      /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
16508	       * to avoid nearly infinite cycling due to very small bound changes)
16509	       */
16510	      npresolrounds = 0;
16511	      while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
16512	      {
16513	         assert(!cutoff);
16514	         npresolrounds++;
16515	
16516	         /* mark constraint being presolved and propagated */
16517	         consdata->presolved = TRUE;
16518	         SCIP_CALL( SCIPunmarkConsPropagate(scip, cons) );
16519	
16520	         /* normalize constraint */
16521	         SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
16522	
16523	         if( infeasible )
16524	         {
16525	            SCIPdebugMsg(scip, " -> infeasible normalization\n");
16526	            cutoff = TRUE;
16527	            break;
16528	         }
16529	
16530	         /* tighten left and right hand side due to integrality */
16531	         SCIP_CALL( tightenSides(scip, cons, nchgsides, &infeasible) );
16532	
16533	         if( infeasible )
16534	         {
16535	            SCIPdebugMsg(scip, " -> infeasibility detected during tightening sides\n");
16536	            cutoff = TRUE;
16537	            break;
16538	         }
16539	
16540	         /* check bounds */
16541	         if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16542	         {
16543	            SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16544	               SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16545	            cutoff = TRUE;
16546	            break;
16547	         }
16548	
16549	         /* tighten variable's bounds */
16550	         SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
16551	         if( cutoff )
16552	            break;
16553	
16554	         /* check for fixed variables */
16555	         SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
16556	         if( cutoff )
16557	            break;
16558	
16559	         /* check constraint for infeasibility and redundancy */
16560	         consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
16561	            &isminsettoinfinity, &ismaxsettoinfinity);
16562	         if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
16563	         {
16564	            SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16565	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16566	            cutoff = TRUE;
16567	            break;
16568	         }
16569	         else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
16570	         {
16571	            SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16572	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16573	            SCIP_CALL( SCIPdelCons(scip, cons) );
16574	            assert(!SCIPconsIsActive(cons));
16575	
16576	            if( !consdata->upgraded )
16577	               (*ndelconss)++;
16578	            break;
16579	         }
16580	         else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisGE(scip, minactivity, consdata->lhs) )
16581	         {
16582	            SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16583	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16584	            SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
16585	            if( !consdata->upgraded )
16586	               (*nchgsides)++;
16587	         }
16588	         else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
16589	         {
16590	            SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16591	               SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16592	            SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
16593	            if( !consdata->upgraded )
16594	               (*nchgsides)++;
16595	         }
16596	
16597	         /* handle empty constraint */
16598	         if( consdata->nvars == 0 )
16599	         {
16600	            if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16601	            {
16602	               SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16603	                  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16604	               cutoff = TRUE;
16605	            }
16606	            else
16607	            {
16608	               SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16609	                  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16610	               SCIP_CALL( SCIPdelCons(scip, cons) );
16611	               assert(!SCIPconsIsActive(cons));
16612	
16613	               if( !consdata->upgraded )
16614	                  (*ndelconss)++;
16615	            }
16616	            break;
16617	         }
16618	
16619	         /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
16620	         SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
16621	
16622	         /* try to simplify inequalities */
16623	         if( conshdlrdata->simplifyinequalities )
16624	         {
16625	            SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides, &cutoff) );
16626	
16627	            if( cutoff )
16628	               break;
16629	         }
16630	
16631	         /* aggregation variable in equations */
16632	         if( conshdlrdata->aggregatevariables )
16633	         {
16634	            SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars) );
16635	            if( cutoff )
16636	               break;
16637	         }
16638	      }
16639	
16640	      if( !cutoff && !SCIPisStopped(scip) )
16641	      {
16642	         /* perform ranged row propagation */
16643	         if( conshdlrdata->rangedrowpropagation )
16644	         {
16645	            int lastnfixedvars;
16646	
16647	            lastnfixedvars = *nfixedvars;
16648	
16649	            SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
16650	            if( !cutoff )
16651	            {
16652	               if( lastnfixedvars < *nfixedvars )
16653	               {
16654	                  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
16655	               }
16656	            }
16657	         }
16658	
16659	         /* extract cliques from constraint */
16660	         if( conshdlrdata->extractcliques && !cutoff && SCIPconsIsActive(cons) )
16661	         {
16662	            SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
16663	                  nfixedvars, nchgbds, &cutoff) );
16664	
16665	            /* check if the constraint got redundant or infeasible */
16666	            if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
16667	            {
16668	               if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16669	               {
16670	                  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16671	                        SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16672	                  cutoff = TRUE;
16673	               }
16674	               else
16675	               {
16676	                  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16677	                        SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16678	                  SCIP_CALL( SCIPdelCons(scip, cons) );
16679	                  assert(!SCIPconsIsActive(cons));
16680	
16681	                  if( !consdata->upgraded )
16682	                     (*ndelconss)++;
16683	               }
16684	            }
16685	         }
16686	
16687	         /* convert special equalities */
16688	         if( !cutoff && SCIPconsIsActive(cons) )
16689	         {
16690	            SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
16691	         }
16692	
16693	         /* apply dual presolving for variables that appear in only one constraint */
16694	         if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
16695	         {
16696	            SCIP_CALL( dualPresolve(scip, conshdlrdata, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
16697	         }
16698	
16699	         /* check if an inequality is parallel to the objective function */
16700	         if( !cutoff && SCIPconsIsActive(cons) )
16701	         {
16702	            SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
16703	         }
16704	
16705	         /* remember the first changed constraint to begin the next aggregation round with */
16706	         if( firstchange == INT_MAX && consdata->changed )
16707	            firstchange = c;
16708	
16709	         /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16710	         if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16711	            firstupgradetry = c;
16712	      }
16713	
16714	      /* singleton column stuffing */
16715	      if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
16716	         (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowStrongDualReds(scip) )
16717	      {
16718	         SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
16719	               conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
16720	
16721	         /* handle empty constraint */
16722	         if( consdata->nvars == 0 )
16723	         {
16724	            if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16725	            {
16726	               SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16727	                  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16728	               cutoff = TRUE;
16729	            }
16730	            else
16731	            {
16732	               SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16733	                  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16734	               SCIP_CALL( SCIPdelCons(scip, cons) );
16735	               assert(!SCIPconsIsActive(cons));
16736	
16737	               if( !consdata->upgraded )
16738	                  (*ndelconss)++;
16739	            }
16740	            break;
16741	         }
16742	      }
16743	   }
16744	
16745	   /* process pairs of constraints: check them for redundancy and try to aggregate them;
16746	    * only apply this expensive procedure in exhaustive presolving timing
16747	    */
16748	   if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
16749	   {
16750	      assert(firstchange >= 0);
16751	
16752	      if( firstchange < nconss && conshdlrdata->presolusehashing )
16753	      {
16754	         /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
16755	         SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
16756	               ndelconss, nchgsides) );
16757	      }
16758	
16759	      if( firstchange < nconss && conshdlrdata->presolpairwise )
16760	      {
16761	         SCIP_CONS** usefulconss;
16762	         int nusefulconss;
16763	         int firstchangenew;
16764	         SCIP_Longint npaircomparisons;
16765	
16766	         npaircomparisons = 0;
16767	         oldndelconss = *ndelconss;
16768	         oldnchgsides = *nchgsides;
16769	         oldnchgcoefs = *nchgcoefs;
16770	
16771	         /* allocate temporary memory */
16772	         SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
16773	
16774	         nusefulconss = 0;
16775	         firstchangenew = -1;
16776	         for( c = 0; c < nconss; ++c )
16777	         {
16778	            /* update firstchange */
16779	            if( c == firstchange )
16780	               firstchangenew = nusefulconss;
16781	
16782	            /* ignore inactive and modifiable constraints */
16783	            if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
16784	               continue;
16785	
16786	            usefulconss[nusefulconss] = conss[c];
16787	            ++nusefulconss;
16788	         }
16789	         firstchange = firstchangenew;
16790	         assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
16791	
16792	         for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
16793	         {
16794	            /* constraint has become inactive or modifiable during pairwise presolving */
16795	            if( usefulconss[c] == NULL )
16796	               continue;
16797	
16798	            npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
16799	
16800	            assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
16801	            SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
16802	                  &cutoff, ndelconss, nchgsides, nchgcoefs) );
16803	
16804	            if( npaircomparisons > conshdlrdata->nmincomparisons )
16805	            {
16806	               assert(npaircomparisons > 0);
16807	               if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
16808	                  break;
16809	               oldndelconss = *ndelconss;
16810	               oldnchgsides = *nchgsides;
16811	               oldnchgcoefs = *nchgcoefs;
16812	               npaircomparisons = 0;
16813	            }
16814	         }
16815	         /* free temporary memory */
16816	         SCIPfreeBufferArray(scip, &usefulconss);
16817	      }
16818	   }
16819	
16820	   /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
16821	    * in linear constraints and we therefore have full information about it
16822	    */
16823	   if( !cutoff && firstupgradetry < nconss
16824	      && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
16825	      && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
16826	      )
16827	   {
16828	      if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) && !SCIPisStopped(scip) )
16829	      {
16830	         SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
16831	      }
16832	   }
16833	
16834	   /* try to upgrade constraints into a more specific constraint type;
16835	    * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
16836	    * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
16837	    */
16838	   if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
16839	   {
16840	      for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
16841	      {
16842	         cons = conss[c];
16843	
16844	         /* don't upgrade modifiable constraints */
16845	         if( SCIPconsIsModifiable(cons) )
16846	            continue;
16847	
16848	         consdata = SCIPconsGetData(cons);
16849	         assert(consdata != NULL);
16850	
16851	         /* only upgrade completely presolved constraints, that changed since the last upgrading call */
16852	         if( consdata->upgradetried )
16853	            continue;
16854	         /* @todo force that upgrade will be performed later? */
16855	         if( !consdata->presolved )
16856	            continue;
16857	
16858	         consdata->upgradetried = TRUE;
16859	         if( SCIPconsIsActive(cons) )
16860	         {
16861	            SCIP_CONS* upgdcons;
16862	
16863	            SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16864	            if( upgdcons != NULL )
16865	            {
16866	               /* add the upgraded constraint to the problem */
16867	               SCIP_CALL( SCIPaddCons(scip, upgdcons) );
16868	               SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
16869	               (*nupgdconss)++;
16870	
16871	               /* mark the linear constraint being upgraded and to be removed after presolving;
16872	                * don't delete it directly, because it may help to preprocess other linear constraints
16873	                */
16874	               assert(!consdata->upgraded);
16875	               consdata->upgraded = TRUE;
16876	
16877	               /* delete upgraded inequalities immediately;
16878	                * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
16879	                */
16880	               if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
16881	                  || !conshdlrdata->presolpairwise
16882	                  || (conshdlrdata->maxaggrnormscale == 0.0) )
16883	               {
16884	                  SCIP_CALL( SCIPdelCons(scip, cons) );
16885	               }
16886	            }
16887	         }
16888	      }
16889	   }
16890	
16891	   /* return the correct result code */
16892	   if( cutoff )
16893	      *result = SCIP_CUTOFF;
16894	   else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
16895	      || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
16896	      *result = SCIP_SUCCESS;
16897	   else
16898	      *result = SCIP_DIDNOTFIND;
16899	
16900	   return SCIP_OKAY;
16901	}
16902	
16903	
16904	/** propagation conflict resolving method of constraint handler */
16905	static
16906	SCIP_DECL_CONSRESPROP(consRespropLinear)
16907	{  /*lint --e{715}*/
16908	   assert(scip != NULL);
16909	   assert(cons != NULL);
16910	   assert(result != NULL);
16911	
16912	   SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
16913	
16914	   return SCIP_OKAY;
16915	}
16916	
16917	
16918	/** variable rounding lock method of constraint handler */
16919	static
16920	SCIP_DECL_CONSLOCK(consLockLinear)
16921	{  /*lint --e{715}*/
16922	   SCIP_CONSDATA* consdata;
16923	   SCIP_Bool haslhs;
16924	   SCIP_Bool hasrhs;
16925	   int i;
16926	
16927	   assert(scip != NULL);
16928	   assert(cons != NULL);
16929	   consdata = SCIPconsGetData(cons);
16930	   assert(consdata != NULL);
16931	
16932	   haslhs = !SCIPisInfinity(scip, -consdata->lhs);
16933	   hasrhs = !SCIPisInfinity(scip, consdata->rhs);
16934	
16935	   /* update rounding locks of every single variable */
16936	   for( i = 0; i < consdata->nvars; ++i )
16937	   {
16938	      if( SCIPisPositive(scip, consdata->vals[i]) )
16939	      {
16940	         if( haslhs )
16941	         {
16942	            SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16943	         }
16944	         if( hasrhs )
16945	         {
16946	            SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16947	         }
16948	      }
16949	      else
16950	      {
16951	         if( haslhs )
16952	         {
16953	            SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16954	         }
16955	         if( hasrhs )
16956	         {
16957	            SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16958	         }
16959	      }
16960	   }
16961	
16962	   return SCIP_OKAY;
16963	}
16964	
16965	
16966	/** variable deletion method of constraint handler */
16967	static
16968	SCIP_DECL_CONSDELVARS(consDelvarsLinear)
16969	{
16970	   assert(scip != NULL);
16971	   assert(conshdlr != NULL);
16972	   assert(conss != NULL || nconss == 0);
16973	
16974	   if( nconss > 0 )
16975	   {
16976	      SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
16977	   }
16978	
16979	   return SCIP_OKAY;
16980	}
16981	
16982	/** constraint display method of constraint handler */
16983	static
16984	SCIP_DECL_CONSPRINT(consPrintLinear)
16985	{  /*lint --e{715}*/
16986	   assert(scip != NULL);
16987	   assert(conshdlr != NULL);
16988	   assert(cons != NULL);
16989	
16990	   SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
16991	
16992	   return SCIP_OKAY;
16993	}
16994	
16995	/** constraint copying method of constraint handler */
16996	static
16997	SCIP_DECL_CONSCOPY(consCopyLinear)
16998	{  /*lint --e{715}*/
16999	   SCIP_VAR** sourcevars;
17000	   SCIP_Real* sourcecoefs;
17001	   const char* consname;
17002	   int nvars;
17003	
17004	   assert(scip != NULL);
17005	   assert(sourcescip != NULL);
17006	   assert(sourcecons != NULL);
17007	
17008	   /* get variables and coefficients of the source constraint */
17009	   sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
17010	   sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
17011	   nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
17012	
17013	   if( name != NULL )
17014	      consname = name;
17015	   else
17016	      consname = SCIPconsGetName(sourcecons);
17017	
17018	   SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
17019	         SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
17020	         initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
17021	   assert(cons != NULL || *valid == FALSE);
17022	
17023	   /* @todo should also the checkabsolute flag of the constraint be copied? */
17024	
17025	   return SCIP_OKAY;
17026	}
17027	
17028	/** find operators '<=', '==', '>=', [free] in input string and return those places
17029	 *
17030	 *  There should only be one operator, except for ranged rows for which exactly two operators '<=' must be present.
17031	 */
17032	static
17033	void findOperators(
17034	   const char*           str,                /**< null terminated input string */
17035	   char**                firstoperator,      /**< pointer to store the string starting at the first operator */
17036	   char**                secondoperator,     /**< pointer to store the string starting at the second operator */
17037	   SCIP_Bool*            success             /**< pointer to store if the line contains a valid operator order */
17038	   )
17039	{
17040	   char* curr;
17041	
17042	   assert(str != NULL);
17043	   assert(firstoperator != NULL);
17044	   assert(secondoperator != NULL);
17045	
17046	   *firstoperator = NULL;
17047	   *secondoperator = NULL;
17048	
17049	   curr = (char*)str;
17050	   *success = TRUE;
17051	
17052	   /* loop over the input string to find all operators */
17053	   while( *curr && *success )
17054	   {
17055	      SCIP_Bool found = FALSE;
17056	      int increment = 1;
17057	
17058	      /* try if we found a possible operator */
17059	      switch( *curr )
17060	      {
17061	      case '<':
17062	      case '=':
17063	      case '>':
17064	
17065	         /* check if the two characters curr[0,1] form an operator together */
17066	         if( curr[1] == '=' )
17067	         {
17068	            found = TRUE;
17069	
17070	            /* update increment to continue after this operator */
17071	            increment = 2;
17072	         }
17073	         break;
17074	      case '[':
17075	         if( strncmp(curr, "[free]", 6) == 0 )
17076	         {
17077	            found = TRUE;
17078	
17079	            /* update increment to continue after this operator */
17080	            increment = 6;
17081	         }
17082	         break;
17083	      default:
17084	         break;
17085	      }
17086	
17087	      /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
17088	      if( found )
17089	      {
17090	         if( *firstoperator == NULL )
17091	         {
17092	            *firstoperator = curr;
17093	         }
17094	         else
17095	         {
17096	            if( *secondoperator != NULL )
17097	            {
17098	               SCIPerrorMessage("Found more than two operators in line %s\n", str);
17099	               *success = FALSE;
17100	            }
17101	            else if( strncmp(*firstoperator, "<=", 2) != 0 )
17102	            {
17103	               SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
17104	               *success = FALSE;
17105	            }
17106	            else if( strncmp(curr, "<=", 2) != 0 )
17107	            {
17108	               SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
17109	               *success = FALSE;
17110	            }
17111	
17112	            *secondoperator = curr;
17113	         }
17114	      }
17115	
17116	      curr += increment;
17117	   }
17118	
17119	   /* check if we did find at least one operator */
17120	   if( *success )
17121	   {
17122	      if( *firstoperator == NULL )
17123	      {
17124	         SCIPerrorMessage("Could not find any operator in line %s\n", str);
17125	         *success = FALSE;
17126	      }
17127	   }
17128	}
17129	
17130	/** constraint parsing method of constraint handler */
17131	static
17132	SCIP_DECL_CONSPARSE(consParseLinear)
17133	{  /*lint --e{715}*/
17134	   SCIP_VAR** vars;
17135	   SCIP_Real* coefs;
17136	   int        nvars;
17137	   int        coefssize;
17138	   int        requsize;
17139	   SCIP_Real  lhs;
17140	   SCIP_Real  rhs;
17141	   char*      endptr;
17142	   char*      firstop;
17143	   char*      secondop;
17144	   SCIP_Bool  operatorsuccess;
17145	   char*      lhsstrptr;
17146	   char*      rhsstrptr;
17147	   char*      varstrptr;
17148	
17149	   assert(scip != NULL);
17150	   assert(success != NULL);
17151	   assert(str != NULL);
17152	   assert(name != NULL);
17153	   assert(cons != NULL);
17154	
17155	   /* set left and right hand side to their default values */
17156	   lhs = -SCIPinfinity(scip);
17157	   rhs =  SCIPinfinity(scip);
17158	
17159	   (*success) = FALSE;
17160	
17161	   /* return of string empty */
17162	   if( !*str )
17163	      return SCIP_OKAY;
17164	
17165	   /* ignore whitespace */
17166	   SCIP_CALL( SCIPskipSpace((char**)&str) );
17167	
17168	   /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
17169	    * and the special word [free]
17170	    */
17171	   findOperators(str, &firstop, &secondop, &operatorsuccess);
17172	
17173	   /* if the grammar is not valid for parsing a linear constraint, return */
17174	   if( ! operatorsuccess )
17175	      return SCIP_OKAY;
17176	
17177	   varstrptr = (char *)str;
17178	   lhsstrptr = rhsstrptr = NULL;
17179	   assert(firstop != NULL);
17180	
17181	   /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
17182	   switch( *firstop )
17183	   {
17184	      case '<':
17185	         assert(firstop[1] == '=');
17186	         /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
17187	         if( secondop != NULL )
17188	         {
17189	            assert(secondop[0] == '<' && secondop[1] == '=');
17190	            lhsstrptr = (char *)str;
17191	            varstrptr = firstop + 2;
17192	            rhsstrptr = secondop + 2;
17193	         }
17194	         else
17195	         {
17196	            /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
17197	            lhsstrptr = NULL;
17198	            varstrptr = (char *)str;
17199	            rhsstrptr = firstop + 2;
17200	         }
17201	         break;
17202	      case '>':
17203	         assert(firstop[1] == '=');
17204	         assert(secondop == NULL);
17205	         /* we have a_1 x_1 + ... + a_n x_n >= lhs */
17206	         lhsstrptr = firstop + 2;
17207	         break;
17208	      case '=':
17209	         assert(firstop[1] == '=');
17210	         assert(secondop == NULL);
17211	         /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
17212	         rhsstrptr = firstop + 2;
17213	         lhsstrptr = firstop + 2;
17214	         break;
17215	      case '[':
17216	         assert(strncmp(firstop, "[free]", 6) == 0);
17217	         assert(secondop == NULL);
17218	         /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
17219	         break;
17220	      default:
17221	         /* it should not be possible that a different character appears in that position */
17222	         SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
17223	         return SCIP_READERROR;
17224	   }
17225	
17226	   /* parse left hand side, if necessary */
17227	   if( lhsstrptr != NULL )
17228	   {
17229	      if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
17230	      {
17231	         SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
17232	         return SCIP_OKAY;
17233	      }
17234	
17235	      /* in case of an equation, assign the left also to the right hand side */
17236	      if( rhsstrptr == lhsstrptr )
17237	         rhs = lhs;
17238	   }
17239	
17240	   /* parse right hand side, if different from left hand side */
17241	   if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
17242	   {
17243	      if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
17244	      {
17245	         SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
17246	         return SCIP_OKAY;
17247	      }
17248	   }
17249	
17250	   /* initialize buffers for storing the variables and coefficients */
17251	   coefssize = 100;
17252	   SCIP_CALL( SCIPallocBufferArray(scip, &vars,  coefssize) );
17253	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
17254	
17255	   assert(varstrptr != NULL);
17256	
17257	   /* parse linear sum to get variables and coefficients */
17258	   SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17259	
17260	   if( *success && requsize > coefssize )
17261	   {
17262	      /* realloc buffers and try again */
17263	      coefssize = requsize;
17264	      SCIP_CALL( SCIPreallocBufferArray(scip, &vars,  coefssize) );
17265	      SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
17266	
17267	      SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17268	      assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
17269	   }
17270	
17271	   if( !*success )
17272	   {
17273	      SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
17274	   }
17275	   else
17276	   {
17277	      SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
17278	            initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17279	   }
17280	
17281	   SCIPfreeBufferArray(scip, &coefs);
17282	   SCIPfreeBufferArray(scip, &vars);
17283	
17284	   return SCIP_OKAY;
17285	}
17286	
17287	
17288	/** constraint method of constraint handler which returns the variables (if possible) */
17289	static
17290	SCIP_DECL_CONSGETVARS(consGetVarsLinear)
17291	{  /*lint --e{715}*/
17292	   SCIP_CONSDATA* consdata;
17293	
17294	   consdata = SCIPconsGetData(cons);
17295	   assert(consdata != NULL);
17296	
17297	   if( varssize < consdata->nvars )
17298	      (*success) = FALSE;
17299	   else
17300	   {
17301	      assert(vars != NULL);
17302	
17303	      BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
17304	      (*success) = TRUE;
17305	   }
17306	
17307	   return SCIP_OKAY;
17308	}
17309	
17310	/**! [Callback for the number of variables]*/
17311	/** constraint method of constraint handler which returns the number of variables (if possible) */
17312	static
17313	SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
17314	{  /*lint --e{715}*/
17315	   SCIP_CONSDATA* consdata;
17316	
17317	   consdata = SCIPconsGetData(cons);
17318	   assert(consdata != NULL);
17319	
17320	   (*nvars) = consdata->nvars;
17321	   (*success) = TRUE;
17322	
17323	   return SCIP_OKAY;
17324	}
17325	/**! [Callback for the number of variables]*/
17326	
17327	/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
17328	static
17329	SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinear)
17330	{  /*lint --e{715}*/
17331	   SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
17332	
17333	   return SCIP_OKAY;
17334	}
17335	
17336	/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
17337	static
17338	SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinear)
17339	{  /*lint --e{715}*/
17340	   SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
17341	
17342	   return SCIP_OKAY;
17343	}
17344	
17345	/*
17346	 * Callback methods of event handler
17347	 */
17348	
17349	/** execution method of event handler */
17350	static
17351	SCIP_DECL_EVENTEXEC(eventExecLinear)
17352	{  /*lint --e{715}*/
17353	   SCIP_CONS* cons;
17354	   SCIP_CONSDATA* consdata;
17355	   SCIP_VAR* var;
17356	   SCIP_EVENTTYPE eventtype;
17357	
17358	   assert(scip != NULL);
17359	   assert(eventhdlr != NULL);
17360	   assert(eventdata != NULL);
17361	   assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
17362	   assert(event != NULL);
17363	
17364	   cons = eventdata->cons;
17365	   assert(cons != NULL);
17366	   consdata = SCIPconsGetData(cons);
17367	   assert(consdata != NULL);
17368	
17369	   /* we can skip events droped for deleted constraints */
17370	   if( SCIPconsIsDeleted(cons) )
17371	      return SCIP_OKAY;
17372	
17373	   eventtype = SCIPeventGetType(event);
17374	   var = SCIPeventGetVar(event);
17375	
17376	   if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
17377	   {
17378	      SCIP_Real oldbound;
17379	      SCIP_Real newbound;
17380	      SCIP_Real val;
17381	      int varpos;
17382	
17383	      varpos = eventdata->varpos;
17384	      assert(0 <= varpos && varpos < consdata->nvars);
17385	      oldbound = SCIPeventGetOldbound(event);
17386	      newbound = SCIPeventGetNewbound(event);
17387	      assert(var != NULL);
17388	      assert(consdata->vars[varpos] == var);
17389	      val = consdata->vals[varpos];
17390	
17391	      /* we only need to update the activities if the constraint is active,
17392	       * otherwise we mark them to be invalid
17393	       */
17394	      if( SCIPconsIsActive(cons) )
17395	      {
17396	         /* update the activity values */
17397	         if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
17398	            consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
17399	         else
17400	         {
17401	            assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
17402	            consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
17403	         }
17404	      }
17405	      else
17406	         consdataInvalidateActivities(consdata);
17407	
17408	      consdata->presolved = FALSE;
17409	      consdata->rangedrowpropagated = 0;
17410	
17411	      /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
17412	      if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
17413	      {
17414	         SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
17415	
17416	         /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17417	         if( consdata->maxactdeltavar == var )
17418	         {
17419	            consdata->maxactdelta = SCIP_INVALID;
17420	            consdata->maxactdeltavar = NULL;
17421	         }
17422	
17423	         /* check whether bound tightening might now be successful */
17424	         if( consdata->boundstightened > 0)
17425	         {
17426	            switch( eventtype )
17427	            {
17428	            case SCIP_EVENTTYPE_LBTIGHTENED:
17429	               if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
17430	                  consdata->boundstightened = 0;
17431	               break;
17432	            case SCIP_EVENTTYPE_UBTIGHTENED:
17433	               if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
17434	                  consdata->boundstightened = 0;
17435	               break;
17436	            default:
17437	               SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
17438	               return SCIP_INVALIDDATA;
17439	            }
17440	         }
17441	      }
17442	      /* update maximal activity delta if a bound was relaxed */
17443	      else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
17444	      {
17445	         SCIP_Real lb;
17446	         SCIP_Real ub;
17447	         SCIP_Real domain;
17448	         SCIP_Real delta;
17449	
17450	         assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
17451	
17452	         lb = SCIPvarGetLbLocal(var);
17453	         ub = SCIPvarGetUbLocal(var);
17454	
17455	         domain = ub - lb;
17456	         delta = REALABS(val) * domain;
17457	
17458	         if( delta > consdata->maxactdelta )
17459	         {
17460	            consdata->maxactdelta = delta;
17461	            consdata->maxactdeltavar = var;
17462	         }
17463	      }
17464	   }
17465	   else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
17466	   {
17467	      /* we want to remove the fixed variable */
17468	      consdata->presolved = FALSE;
17469	      consdata->removedfixings = FALSE;
17470	      consdata->rangedrowpropagated = 0;
17471	
17472	      /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17473	      if( consdata->maxactdeltavar == var )
17474	      {
17475	         consdata->maxactdelta = SCIP_INVALID;
17476	         consdata->maxactdeltavar = NULL;
17477	      }
17478	   }
17479	   else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
17480	   {
17481	      /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
17482	      assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17483	      assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17484	      consdata->presolved = FALSE;
17485	   }
17486	   else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
17487	   {
17488	      SCIP_Real oldbound;
17489	      SCIP_Real newbound;
17490	      SCIP_Real val;
17491	      int varpos;
17492	
17493	      varpos = eventdata->varpos;
17494	      assert(0 <= varpos && varpos < consdata->nvars);
17495	      oldbound = SCIPeventGetOldbound(event);
17496	      newbound = SCIPeventGetNewbound(event);
17497	      assert(var != NULL);
17498	      assert(consdata->vars[varpos] == var);
17499	      val = consdata->vals[varpos];
17500	
17501	      consdata->rangedrowpropagated = 0;
17502	
17503	      /* update the activity values */
17504	      if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
17505	         consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
17506	      else
17507	      {
17508	         assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
17509	         consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
17510	      }
17511	
17512	      /* if the variable is binary but not fixed it had to become binary due to this global change */
17513	      if( SCIPvarIsBinary(var) && SCIPisGT(scip, SCIPvarGetUbGlobal(var), SCIPvarGetLbGlobal(var)) )
17514	      {
17515	         if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
17516	            consdata->indexsorted = FALSE;
17517	         else
17518	            consdata->coefsorted = FALSE;
17519	      }
17520	   }
17521	   else if( (eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0 )
17522	   {
17523	      assert(SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED);
17524	
17525	      /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
17526	      consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
17527	
17528	      /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
17529	      consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
17530	   }
17531	   else
17532	   {
17533	      assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
17534	      consdata->varsdeleted = TRUE;
17535	   }
17536	
17537	   return SCIP_OKAY;
17538	}
17539	
17540	
17541	/*
17542	 * Callback methods of conflict handler
17543	 */
17544	
17545	/** conflict processing method of conflict handler (called when conflict was found) */
17546	static
17547	SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
17548	{  /*lint --e{715}*/
17549	   SCIP_VAR** vars;
17550	   SCIP_Real* vals;
17551	   SCIP_Real lhs;
17552	   int i;
17553	
17554	   assert(scip != NULL);
17555	   assert(conflicthdlr != NULL);
17556	   assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
17557	   assert(bdchginfos != NULL || nbdchginfos == 0);
17558	   assert(result != NULL);
17559	
17560	   /* don't process already resolved conflicts */
17561	   if( resolved )
17562	   {
17563	      *result = SCIP_DIDNOTRUN;
17564	      return SCIP_OKAY;
17565	   }
17566	
17567	   *result = SCIP_DIDNOTFIND;
17568	
17569	   /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
17570	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
17571	   SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
17572	   lhs = 1.0;
17573	   for( i = 0; i < nbdchginfos; ++i )
17574	   {
17575	      assert(bdchginfos != NULL);
17576	
17577	      vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
17578	
17579	      /* we can only treat binary variables */
17580	      /**@todo extend linear conflict constraints to some non-binary cases */
17581	      if( !SCIPvarIsBinary(vars[i]) )
17582	         break;
17583	
17584	      /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
17585	      if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
17586	         vals[i] = 1.0;
17587	      else
17588	      {
17589	         vals[i] = -1.0;
17590	         lhs -= 1.0;
17591	      }
17592	   }
17593	
17594	   if( i == nbdchginfos )
17595	   {
17596	      SCIP_CONS* cons;
17597	      SCIP_CONS* upgdcons;
17598	      char consname[SCIP_MAXSTRLEN];
17599	
17600	      /* create a constraint out of the conflict set */
17601	      (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%" SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
17602	      SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
17603	            FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
17604	
17605	      /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
17606	      SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
17607	      if( upgdcons != NULL )
17608	      {
17609	         SCIP_CALL( SCIPreleaseCons(scip, &cons) );
17610	         cons = upgdcons;
17611	      }
17612	
17613	      /* add conflict to SCIP */
17614	      SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
17615	
17616	      *result = SCIP_CONSADDED;
17617	   }
17618	
17619	   /* free temporary memory */
17620	   SCIPfreeBufferArray(scip, &vals);
17621	   SCIPfreeBufferArray(scip, &vars);
17622	
17623	   return SCIP_OKAY;
17624	}
17625	
17626	
17627	/*
17628	 * Nonlinear constraint upgrading
17629	 */
17630	
17631	/** tries to upgrade a nonlinear constraint into a linear constraint */
17632	static
17633	SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
17634	{
17635	   SCIP_CONSDATA* consdata;
17636	   SCIP_EXPR* expr;
17637	   SCIP_Real lhs;
17638	   SCIP_Real rhs;
17639	   int i;
17640	
17641	   assert(nupgdconss != NULL);
17642	   assert(upgdconss != NULL);
17643	   assert(upgdconsssize > 0);
17644	
17645	   expr = SCIPgetExprNonlinear(cons);
17646	   assert(expr != NULL);
17647	
17648	   /* not a linear constraint if the expression is not a sum
17649	    * (unless the expression is a variable or a constant or a constant*variable, but these are simplified away in cons_nonlinear)
17650	    */
17651	   if( !SCIPisExprSum(scip, expr) )
17652	      return SCIP_OKAY;
17653	
17654	   /* if at least one child is not a variable, then not a linear constraint */
17655	   for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17656	      if( !SCIPisExprVar(scip, SCIPexprGetChildren(expr)[i]) )
17657	         return SCIP_OKAY;
17658	
17659	   /* consider constant part of the sum expression */
17660	   lhs = SCIPisInfinity(scip, -SCIPgetLhsNonlinear(cons)) ? -SCIPinfinity(scip) : (SCIPgetLhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17661	   rhs = SCIPisInfinity(scip,  SCIPgetRhsNonlinear(cons)) ?  SCIPinfinity(scip) : (SCIPgetRhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17662	
17663	   SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
17664	         0, NULL, NULL, lhs, rhs,
17665	         SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
17666	         SCIPconsIsChecked(cons), SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons),
17667	         SCIPconsIsModifiable(cons), SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons),
17668	         SCIPconsIsStickingAtNode(cons)) );
17669	   assert(upgdconss[0] != NULL);
17670	
17671	   consdata = SCIPconsGetData(upgdconss[0]);
17672	
17673	   /* add linear terms */
17674	   SCIP_CALL( consdataEnsureVarsSize(scip, consdata, SCIPexprGetNChildren(expr)) );
17675	   for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17676	   {
17677	      SCIP_CALL( addCoef(scip, upgdconss[0], SCIPgetVarExprVar(SCIPexprGetChildren(expr)[i]), SCIPgetCoefsExprSum(expr)[i]) );
17678	   }
17679	
17680	   /* check violation of this linear constraint with absolute tolerances, to be consistent with the original nonlinear constraint */
17681	   consdata->checkabsolute = TRUE;
17682	
17683	   *nupgdconss = 1;
17684	
17685	   SCIPdebugMsg(scip, "created linear constraint:\n");
17686	   SCIPdebugPrintCons(scip, upgdconss[0], NULL);
17687	
17688	   return SCIP_OKAY;
17689	} /*lint !e715*/
17690	
17691	/*
17692	 * constraint specific interface methods
17693	 */
17694	
17695	/** creates the handler for linear constraints and includes it in SCIP */
17696	SCIP_RETCODE SCIPincludeConshdlrLinear(
17697	   SCIP*                 scip                /**< SCIP data structure */
17698	   )
17699	{
17700	   SCIP_CONSHDLRDATA* conshdlrdata;
17701	   SCIP_CONSHDLR* conshdlr;
17702	   SCIP_EVENTHDLR* eventhdlr;
17703	   SCIP_CONFLICTHDLR* conflicthdlr;
17704	
17705	   assert(scip != NULL);
17706	
17707	   /* create event handler for bound change events */
17708	   SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC,
17709	         eventExecLinear, NULL) );
17710	
17711	   /* create conflict handler for linear constraints */
17712	   SCIP_CALL( SCIPincludeConflicthdlrBasic(scip, &conflicthdlr, CONFLICTHDLR_NAME, CONFLICTHDLR_DESC, CONFLICTHDLR_PRIORITY,
17713	         conflictExecLinear, NULL) );
17714	
17715	   /* create constraint handler data */
17716	   SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
17717	
17718	   /* include constraint handler */
17719	   SCIP_CALL( SCIPincludeConshdlrBasic(scip, &conshdlr, CONSHDLR_NAME, CONSHDLR_DESC,
17720	         CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY, CONSHDLR_EAGERFREQ, CONSHDLR_NEEDSCONS,
17721	         consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
17722	         conshdlrdata) );
17723	
17724	   assert(conshdlr != NULL);
17725	
17726	   /* set non-fundamental callbacks via specific setter functions */
17727	   SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
17728	   SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinear) );
17729	   SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinear) );
17730	   SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
17731	   SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
17732	   SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
17733	   SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
17734	   SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinear) );
17735	   SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
17736	   SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
17737	   SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
17738	   SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
17739	   SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
17740	   SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
17741	   SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
17742	   SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
17743	   SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
17744	   SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
17745	         CONSHDLR_PROP_TIMING) );
17746	   SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
17747	   SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
17748	         CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
17749	   SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
17750	   SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
17751	   SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphLinear) );
17752	   SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphLinear) );
17753	
17754	   if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
17755	   {
17756	      /* include the linear constraint upgrade in the nonlinear constraint handler */
17757	      SCIP_CALL( SCIPincludeConsUpgradeNonlinear(scip, upgradeConsNonlinear, NONLINCONSUPGD_PRIORITY, TRUE, CONSHDLR_NAME) );
17758	   }
17759	
17760	   /* add linear constraint handler parameters */
17761	   SCIP_CALL( SCIPaddIntParam(scip,
17762	         "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
17763	         "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
17764	         &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17765	   SCIP_CALL( SCIPaddIntParam(scip,
17766	         "constraints/" CONSHDLR_NAME "/maxrounds",
17767	         "maximal number of separation rounds per node (-1: unlimited)",
17768	         &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
17769	   SCIP_CALL( SCIPaddIntParam(scip,
17770	         "constraints/" CONSHDLR_NAME "/maxroundsroot",
17771	         "maximal number of separation rounds per node in the root node (-1: unlimited)",
17772	         &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
17773	   SCIP_CALL( SCIPaddIntParam(scip,
17774	         "constraints/" CONSHDLR_NAME "/maxsepacuts",
17775	         "maximal number of cuts separated per separation round",
17776	         &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
17777	   SCIP_CALL( SCIPaddIntParam(scip,
17778	         "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
17779	         "maximal number of cuts separated per separation round in the root node",
17780	         &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
17781	   SCIP_CALL( SCIPaddBoolParam(scip,
17782	         "constraints/" CONSHDLR_NAME "/presolpairwise",
17783	         "should pairwise constraint comparison be performed in presolving?",
17784	         &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
17785	   SCIP_CALL( SCIPaddBoolParam(scip,
17786	         "constraints/" CONSHDLR_NAME "/presolusehashing",
17787	         "should hash table be used for detecting redundant constraints in advance",
17788	         &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
17789	   SCIP_CALL( SCIPaddIntParam(scip,
17790	         "constraints/" CONSHDLR_NAME "/nmincomparisons",
17791	         "number for minimal pairwise presolve comparisons",
17792	         &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
17793	   SCIP_CALL( SCIPaddRealParam(scip,
17794	         "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
17795	         "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
17796	         &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
17797	   SCIP_CALL( SCIPaddRealParam(scip,
17798	         "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
17799	         "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
17800	         &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17801	   SCIP_CALL( SCIPaddRealParam(scip,
17802	         "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
17803	         "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
17804	         &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17805	   SCIP_CALL( SCIPaddRealParam(scip,
17806	         "constraints/" CONSHDLR_NAME "/maxcardbounddist",
17807	         "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
17808	         &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
17809	   SCIP_CALL( SCIPaddBoolParam(scip,
17810	         "constraints/" CONSHDLR_NAME "/separateall",
17811	         "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
17812	         &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
17813	   SCIP_CALL( SCIPaddBoolParam(scip,
17814	         "constraints/" CONSHDLR_NAME "/aggregatevariables",
17815	         "should presolving search for aggregations in equations",
17816	         &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
17817	   SCIP_CALL( SCIPaddBoolParam(scip,
17818	         "constraints/" CONSHDLR_NAME "/simplifyinequalities",
17819	         "should presolving try to simplify inequalities",
17820	         &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
17821	   SCIP_CALL( SCIPaddBoolParam(scip,
17822	         "constraints/" CONSHDLR_NAME "/dualpresolving",
17823	         "should dual presolving steps be performed?",
17824	         &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
17825	   SCIP_CALL( SCIPaddBoolParam(scip,
17826	         "constraints/" CONSHDLR_NAME "/singletonstuffing",
17827	         "should stuffing of singleton continuous variables be performed?",
17828	         &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
17829	   SCIP_CALL( SCIPaddBoolParam(scip,
17830	         "constraints/" CONSHDLR_NAME "/singlevarstuffing",
17831	         "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
17832	         &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
17833	   SCIP_CALL( SCIPaddBoolParam(scip,
17834	         "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
17835	         &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
17836	   SCIP_CALL( SCIPaddBoolParam(scip,
17837	         "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
17838	         "should the violation for a constraint with side 0.0 be checked relative to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)?",
17839	         &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
17840	   SCIP_CALL( SCIPaddBoolParam(scip,
17841	         "constraints/" CONSHDLR_NAME "/detectcutoffbound",
17842	         "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
17843	         &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
17844	   SCIP_CALL( SCIPaddBoolParam(scip,
17845	         "constraints/" CONSHDLR_NAME "/detectlowerbound",
17846	         "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
17847	         &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
17848	   SCIP_CALL( SCIPaddBoolParam(scip,
17849	         "constraints/" CONSHDLR_NAME "/detectpartialobjective",
17850	         "should presolving try to detect subsets of constraints parallel to the objective function?",
17851	         &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
17852	   SCIP_CALL( SCIPaddBoolParam(scip,
17853	         "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
17854	         "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
17855	         &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
17856	   SCIP_CALL( SCIPaddBoolParam(scip,
17857	         "constraints/" CONSHDLR_NAME "/rangedrowartcons",
17858	         "should presolving and propagation extract sub-constraints from ranged rows and equations?",
17859	         &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
17860	   SCIP_CALL( SCIPaddIntParam(scip,
17861	         "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
17862	         "maximum depth to apply ranged row propagation",
17863	         &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
17864	   SCIP_CALL( SCIPaddIntParam(scip,
17865	         "constraints/" CONSHDLR_NAME "/rangedrowfreq",
17866	         "frequency for applying ranged row propagation",
17867	         &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17868	   SCIP_CALL( SCIPaddBoolParam(scip,
17869	         "constraints/" CONSHDLR_NAME "/multaggrremove",
17870	         "should multi-aggregations only be performed if the constraint can be removed afterwards?",
17871	         &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
17872	   SCIP_CALL( SCIPaddRealParam(scip,
17873	         "constraints/" CONSHDLR_NAME "/maxmultaggrquot",
17874	         "maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation",
17875	         &conshdlrdata->maxmultaggrquot, TRUE, DEFAULT_MAXMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17876	   SCIP_CALL( SCIPaddRealParam(scip,
17877	         "constraints/" CONSHDLR_NAME "/maxdualmultaggrquot",
17878	         "maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation",
17879	         &conshdlrdata->maxdualmultaggrquot, TRUE, DEFAULT_MAXDUALMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17880	   SCIP_CALL( SCIPaddBoolParam(scip,
17881	         "constraints/" CONSHDLR_NAME "/extractcliques",
17882	         "should Cliques be extracted?",
17883	         &conshdlrdata->extractcliques, TRUE, DEFAULT_EXTRACTCLIQUES, NULL, NULL) );
17884	
17885	   return SCIP_OKAY;
17886	}
17887	
17888	/** includes a linear constraint update method into the linear constraint handler */
17889	SCIP_RETCODE SCIPincludeLinconsUpgrade(
17890	   SCIP*                 scip,               /**< SCIP data structure */
17891	   SCIP_DECL_LINCONSUPGD((*linconsupgd)),    /**< method to call for upgrading linear constraint */
17892	   int                   priority,           /**< priority of upgrading method */
17893	   const char*           conshdlrname        /**< name of the constraint handler */
17894	   )
17895	{
17896	   SCIP_CONSHDLR* conshdlr;
17897	   SCIP_CONSHDLRDATA* conshdlrdata;
17898	   SCIP_LINCONSUPGRADE* linconsupgrade;
17899	   char paramname[SCIP_MAXSTRLEN];
17900	   char paramdesc[SCIP_MAXSTRLEN];
17901	
17902	   assert(scip != NULL);
17903	   assert(linconsupgd != NULL);
17904	   assert(conshdlrname != NULL );
17905	
17906	   /* find the linear constraint handler */
17907	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17908	   if( conshdlr == NULL )
17909	   {
17910	      SCIPerrorMessage("linear constraint handler not found\n");
17911	      return SCIP_PLUGINNOTFOUND;
17912	   }
17913	
17914	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
17915	   assert(conshdlrdata != NULL);
17916	
17917	   /* check if linear constraint update method already exists in constraint handler data */
17918	   if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
17919	   {
17920	      /* create a linear constraint upgrade data object */
17921	      SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
17922	
17923	      /* insert linear constraint update method into constraint handler data */
17924	      SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
17925	
17926	      /* adds parameter to turn on and off the upgrading step */
17927	      (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
17928	      (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
17929	      SCIP_CALL( SCIPaddBoolParam(scip,
17930	            paramname, paramdesc,
17931	            &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
17932	   }
17933	
17934	   return SCIP_OKAY;
17935	}
17936	
17937	/** creates and captures a linear constraint
17938	 *
17939	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17940	 */
17941	SCIP_RETCODE SCIPcreateConsLinear(
17942	   SCIP*                 scip,               /**< SCIP data structure */
17943	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
17944	   const char*           name,               /**< name of constraint */
17945	   int                   nvars,              /**< number of nonzeros in the constraint */
17946	   SCIP_VAR**            vars,               /**< array with variables of constraint entries */
17947	   SCIP_Real*            vals,               /**< array with coefficients of constraint entries */
17948	   SCIP_Real             lhs,                /**< left hand side of constraint */
17949	   SCIP_Real             rhs,                /**< right hand side of constraint */
17950	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
17951	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
17952	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
17953	                                              *   Usually set to TRUE. */
17954	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
17955	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
17956	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
17957	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
17958	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
17959	                                              *   Usually set to TRUE. */
17960	   SCIP_Bool             local,              /**< is constraint only valid locally?
17961	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
17962	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
17963	                                              *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
17964	                                              *   adds coefficients to this constraint. */
17965	   SCIP_Bool             dynamic,            /**< is constraint subject to aging?
17966	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
17967	                                              *   are separated as constraints. */
17968	   SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
17969	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
17970	   SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
17971	                                              *   if it may be moved to a more global node?
17972	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
17973	   )
17974	{
17975	   SCIP_CONSHDLR* conshdlr;
17976	   SCIP_CONSDATA* consdata;
17977	   int j;
17978	
17979	   assert(scip != NULL);
17980	   assert(cons != NULL);
17981	
17982	   /* find the linear constraint handler */
17983	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17984	   if( conshdlr == NULL )
17985	   {
17986	      SCIPerrorMessage("linear constraint handler not found\n");
17987	      return SCIP_PLUGINNOTFOUND;
17988	   }
17989	
17990	   for( j = 0; j < nvars; ++j )
17991	   {
17992	      if( SCIPisInfinity(scip, REALABS(vals[j])) )
17993	      {
17994	         SCIPerrorMessage("coefficient of variable <%s> is infinite.\n", SCIPvarGetName(vars[j]));
17995	         SCIPABORT();
17996	         return SCIP_INVALIDDATA;
17997	      }
17998	   }
17999	
18000	   /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
18001	    * constraint after presolving we have to ensure that it holds active variables
18002	    */
18003	   if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
18004	   {
18005	      SCIP_VAR** consvars;
18006	      SCIP_Real* consvals;
18007	      SCIP_Real constant = 0.0;
18008	      int nconsvars;
18009	      int requiredsize;
18010	
18011	      nconsvars = nvars;
18012	      SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
18013	      SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
18014	
18015	      /* get active variables for new constraint */
18016	      SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
18017	
18018	      /* if space was not enough we need to resize the buffers */
18019	      if( requiredsize > nconsvars )
18020	      {
18021	         SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
18022	         SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
18023	
18024	         SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
18025	         assert(requiredsize <= nconsvars);
18026	      }
18027	
18028	      /* adjust sides and check that we do not subtract infinity values */
18029	      if( SCIPisInfinity(scip, REALABS(constant)) )
18030	      {
18031	         if( constant < 0.0 )
18032	         {
18033	            if( SCIPisInfinity(scip, lhs) )
18034	            {
18035	               SCIPfreeBufferArray(scip, &consvals);
18036	               SCIPfreeBufferArray(scip, &consvars);
18037	
18038	               SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
18039	
18040	               SCIPABORT();
18041	               return SCIP_INVALIDDATA; /*lint !e527*/
18042	            }
18043	            if( SCIPisInfinity(scip, rhs) )
18044	            {
18045	               SCIPfreeBufferArray(scip, &consvals);
18046	               SCIPfreeBufferArray(scip, &consvars);
18047	
18048	               SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
18049	
18050	               SCIPABORT();
18051	               return SCIP_INVALIDDATA; /*lint !e527*/
18052	            }
18053	
18054	            lhs = -SCIPinfinity(scip);
18055	            rhs = -SCIPinfinity(scip);
18056	         }
18057	         else
18058	         {
18059	            if( SCIPisInfinity(scip, -lhs) )
18060	            {
18061	               SCIPfreeBufferArray(scip, &consvals);
18062	               SCIPfreeBufferArray(scip, &consvars);
18063	
18064	               SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
18065	
18066	               SCIPABORT();
18067	               return SCIP_INVALIDDATA; /*lint !e527*/
18068	            }
18069	            if( SCIPisInfinity(scip, -rhs) )
18070	            {
18071	               SCIPfreeBufferArray(scip, &consvals);
18072	               SCIPfreeBufferArray(scip, &consvars);
18073	
18074	               SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
18075	
18076	               SCIPABORT();
18077	               return SCIP_INVALIDDATA; /*lint !e527*/
18078	            }
18079	
18080	            lhs = SCIPinfinity(scip);
18081	            rhs = SCIPinfinity(scip);
18082	         }
18083	      }
18084	      else
18085	      {
18086	         if( !SCIPisInfinity(scip, REALABS(lhs)) )
18087	            lhs -= constant;
18088	         if( !SCIPisInfinity(scip, REALABS(rhs)) )
18089	            rhs -= constant;
18090	
18091	         if( SCIPisInfinity(scip, -lhs) )
18092	            lhs = -SCIPinfinity(scip);
18093	         else if( SCIPisInfinity(scip, lhs) )
18094	            lhs = SCIPinfinity(scip);
18095	
18096	         if( SCIPisInfinity(scip, rhs) )
18097	            rhs = SCIPinfinity(scip);
18098	         else if( SCIPisInfinity(scip, -rhs) )
18099	            rhs = -SCIPinfinity(scip);
18100	      }
18101	
18102	      /* create constraint data */
18103	      SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
18104	      assert(consdata != NULL);
18105	
18106	      SCIPfreeBufferArray(scip, &consvals);
18107	      SCIPfreeBufferArray(scip, &consvars);
18108	   }
18109	   else
18110	   {
18111	      /* create constraint data */
18112	      SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
18113	      assert(consdata != NULL);
18114	   }
18115	
18116	#ifndef NDEBUG
18117	   /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
18118	   if( check || enforce )
18119	   {
18120	      int n;
18121	      for(n = consdata->nvars - 1; n >= 0; --n )
18122	         assert(!SCIPvarIsRelaxationOnly(consdata->vars[n]));
18123	   }
18124	#endif
18125	
18126	   /* create constraint */
18127	   SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
18128	         local, modifiable, dynamic, removable, stickingatnode) );
18129	
18130	   return SCIP_OKAY;
18131	}
18132	
18133	/** creates and captures a linear constraint
18134	 *  in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
18135	 *  method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
18136	 *
18137	 *  @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
18138	 *
18139	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
18140	 */
18141	SCIP_RETCODE SCIPcreateConsBasicLinear(
18142	   SCIP*                 scip,               /**< SCIP data structure */
18143	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
18144	   const char*           name,               /**< name of constraint */
18145	   int                   nvars,              /**< number of nonzeros in the constraint */
18146	   SCIP_VAR**            vars,               /**< array with variables of constraint entries */
18147	   SCIP_Real*            vals,               /**< array with coefficients of constraint entries */
18148	   SCIP_Real             lhs,                /**< left hand side of constraint */
18149	   SCIP_Real             rhs                 /**< right hand side of constraint */
18150	   )
18151	{
18152	   assert(scip != NULL);
18153	
18154	   SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
18155	         TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
18156	
18157	   return SCIP_OKAY;
18158	}
18159	
18160	/** creates by copying and captures a linear constraint */
18161	SCIP_RETCODE SCIPcopyConsLinear(
18162	   SCIP*                 scip,               /**< target SCIP data structure */
18163	   SCIP_CONS**           cons,               /**< pointer to store the created target constraint */
18164	   SCIP*                 sourcescip,         /**< source SCIP data structure */
18165	   const char*           name,               /**< name of constraint */
18166	   int                   nvars,              /**< number of variables in source variable array */
18167	   SCIP_VAR**            sourcevars,         /**< source variables of the linear constraints */
18168	   SCIP_Real*            sourcecoefs,        /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
18169	   SCIP_Real             lhs,                /**< left hand side of the linear constraint */
18170	   SCIP_Real             rhs,                /**< right hand side of the linear constraint */
18171	   SCIP_HASHMAP*         varmap,             /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
18172	                                              *   variables of the target SCIP */
18173	   SCIP_HASHMAP*         consmap,            /**< a hashmap to store the mapping of source constraints to the corresponding
18174	                                              *   target constraints */
18175	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP? */
18176	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing? */
18177	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing? */
18178	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility? */
18179	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing? */
18180	   SCIP_Bool             local,              /**< is constraint only valid locally? */
18181	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)? */
18182	   SCIP_Bool             dynamic,            /**< is constraint subject to aging? */
18183	   SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup? */
18184	   SCIP_Bool             stickingatnode,     /**< should the constraint always be kept at the node where it was added, even
18185	                                              *   if it may be moved to a more global node? */
18186	   SCIP_Bool             global,             /**< create a global or a local copy? */
18187	   SCIP_Bool*            valid               /**< pointer to store if the copying was valid */
18188	   )
18189	{
18190	   SCIP_VAR** vars;
18191	   SCIP_Real* coefs;
18192	
18193	   SCIP_Real constant;
18194	   int requiredsize;
18195	   int v;
18196	   SCIP_Bool success;
18197	
18198	   if( SCIPisGT(scip, lhs, rhs) )
18199	   {
18200	      *valid = FALSE;
18201	      return SCIP_OKAY;
18202	   }
18203	
18204	   (*valid) = TRUE;
18205	
18206	   if( nvars == 0 )
18207	   {
18208	      SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
18209	            initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18210	      return SCIP_OKAY;
18211	   }
18212	
18213	   /* duplicate variable array */
18214	   SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
18215	
18216	   /* duplicate coefficient array */
18217	   if( sourcecoefs != NULL )
18218	   {
18219	      SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
18220	   }
18221	   else
18222	   {
18223	      SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
18224	      for( v = 0; v < nvars; ++v )
18225	         coefs[v] = 1.0;
18226	   }
18227	
18228	   constant = 0.0;
18229	
18230	   /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
18231	    * the target SCIP
18232	    */
18233	   if( !SCIPvarIsOriginal(vars[0]) )
18234	   {
18235	      SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
18236	
18237	      if( requiredsize > nvars )
18238	      {
18239	         SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
18240	         SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
18241	
18242	         SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
18243	         assert(requiredsize <= nvars);
18244	      }
18245	   }
18246	   else
18247	   {
18248	      for( v = 0; v < nvars; ++v )
18249	      {
18250	         assert(SCIPvarIsOriginal(vars[v]));
18251	         SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
18252	         assert(vars[v] != NULL);
18253	      }
18254	   }
18255	
18256	   success = TRUE;
18257	   /* map variables of the source constraint to variables of the target SCIP */
18258	   for( v = 0; v < nvars && success; ++v )
18259	   {
18260	      SCIP_VAR* var;
18261	      var = vars[v];
18262	
18263	      /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
18264	      assert(!SCIPvarIsRelaxationOnly(var) || (!check && !enforce));
18265	
18266	      SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
18267	      assert(!(success) || vars[v] != NULL);
18268	   }
18269	
18270	   /* only create the target constraint, if all variables could be copied */
18271	   if( success )
18272	   {
18273	      if( !SCIPisInfinity(scip, -lhs) )
18274	         lhs -= constant;
18275	
18276	      if( !SCIPisInfinity(scip, rhs) )
18277	         rhs -= constant;
18278	
18279	      SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
18280	            initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18281	   }
18282	   else
18283	      *valid = FALSE;
18284	
18285	   /* free buffer array */
18286	   SCIPfreeBufferArray(scip, &coefs);
18287	   SCIPfreeBufferArray(scip, &vars);
18288	
18289	   return SCIP_OKAY;
18290	}
18291	
18292	/** adds coefficient to linear constraint (if it is not zero) */
18293	SCIP_RETCODE SCIPaddCoefLinear(
18294	   SCIP*                 scip,               /**< SCIP data structure */
18295	   SCIP_CONS*            cons,               /**< constraint data */
18296	   SCIP_VAR*             var,                /**< variable of constraint entry */
18297	   SCIP_Real             val                 /**< coefficient of constraint entry */
18298	   )
18299	{
18300	   assert(scip != NULL);
18301	   assert(cons != NULL);
18302	   assert(var != NULL);
18303	
18304	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18305	   {
18306	      SCIPerrorMessage("constraint is not linear\n");
18307	      return SCIP_INVALIDDATA;
18308	   }
18309	
18310	   /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
18311	    * constraint after presolving we have to ensure that it holds active variables
18312	    */
18313	   if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
18314	   {
18315	      SCIP_CONSDATA* consdata;
18316	      SCIP_VAR** consvars;
18317	      SCIP_Real* consvals;
18318	      SCIP_Real constant = 0.0;
18319	      SCIP_Real rhs;
18320	      SCIP_Real lhs;
18321	      int nconsvars;
18322	      int requiredsize;
18323	      int v;
18324	
18325	      nconsvars = 1;
18326	      SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
18327	      SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
18328	      consvars[0] = var;
18329	      consvals[0] = val;
18330	
18331	      /* get active variables for new constraint */
18332	      SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
18333	
18334	      /* if space was not enough we need to resize the buffers */
18335	      if( requiredsize > nconsvars )
18336	      {
18337	         SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
18338	         SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
18339	
18340	         SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
18341	         assert(requiredsize <= nconsvars);
18342	      }
18343	
18344	      consdata = SCIPconsGetData(cons);
18345	      assert(consdata != NULL);
18346	
18347	      lhs = consdata->lhs;
18348	      rhs = consdata->rhs;
18349	
18350	      /* adjust sides and check that we do not subtract infinity values */
18351	      /* constant is infinite */
18352	      if( SCIPisInfinity(scip, REALABS(constant)) )
18353	      {
18354		 if( constant < 0.0 )
18355		 {
18356		    if( SCIPisInfinity(scip, lhs) )
18357		    {
18358		       SCIPfreeBufferArray(scip, &consvals);
18359		       SCIPfreeBufferArray(scip, &consvars);
18360	
18361		       SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18362	
18363		       SCIPABORT();
18364		       return SCIP_INVALIDDATA; /*lint !e527*/
18365		    }
18366		    if( SCIPisInfinity(scip, rhs) )
18367		    {
18368		       SCIPfreeBufferArray(scip, &consvals);
18369		       SCIPfreeBufferArray(scip, &consvars);
18370	
18371		       SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18372	
18373		       SCIPABORT();
18374		       return SCIP_INVALIDDATA; /*lint !e527*/
18375		    }
18376	
18377		    lhs = -SCIPinfinity(scip);
18378		    rhs = -SCIPinfinity(scip);
18379		 }
18380		 else
18381		 {
18382		    if( SCIPisInfinity(scip, -lhs) )
18383		    {
18384		       SCIPfreeBufferArray(scip, &consvals);
18385		       SCIPfreeBufferArray(scip, &consvars);
18386	
18387		       SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18388	
18389		       SCIPABORT();
18390		       return SCIP_INVALIDDATA; /*lint !e527*/
18391		    }
18392		    if( SCIPisInfinity(scip, -rhs) )
18393		    {
18394		       SCIPfreeBufferArray(scip, &consvals);
18395		       SCIPfreeBufferArray(scip, &consvars);
18396	
18397		       SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18398	
18399		       SCIPABORT();
18400		       return SCIP_INVALIDDATA; /*lint !e527*/
18401		    }
18402	
18403		    lhs = SCIPinfinity(scip);
18404		    rhs = SCIPinfinity(scip);
18405		 }
18406	      }
18407	      /* constant is not infinite */
18408	      else
18409	      {
18410		 if( !SCIPisInfinity(scip, REALABS(lhs)) )
18411		    lhs -= constant;
18412		 if( !SCIPisInfinity(scip, REALABS(rhs)) )
18413		    rhs -= constant;
18414	
18415		 if( SCIPisInfinity(scip, -lhs) )
18416		    lhs = -SCIPinfinity(scip);
18417		 else if( SCIPisInfinity(scip, lhs) )
18418		    lhs = SCIPinfinity(scip);
18419	
18420		 if( SCIPisInfinity(scip, rhs) )
18421		    rhs = SCIPinfinity(scip);
18422		 else if( SCIPisInfinity(scip, -rhs) )
18423		    rhs = -SCIPinfinity(scip);
18424	      }
18425	
18426	      /* add all active variables to constraint */
18427	      for( v = nconsvars - 1; v >= 0; --v )
18428	      {
18429		 SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
18430	      }
18431	
18432	      /* update left and right hand sides */
18433	      SCIP_CALL( chgLhs(scip, cons, lhs));
18434	      SCIP_CALL( chgRhs(scip, cons, rhs));
18435	
18436	      SCIPfreeBufferArray(scip, &consvals);
18437	      SCIPfreeBufferArray(scip, &consvars);
18438	   }
18439	   else
18440	   {
18441	      SCIP_CALL( addCoef(scip, cons, var, val) );
18442	   }
18443	
18444	   return SCIP_OKAY;
18445	}
18446	
18447	/** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
18448	 *  not yet contained in the constraint
18449	 *
18450	 *  @note This method may only be called during problem creation stage for an original constraint and variable.
18451	 *
18452	 *  @note This method requires linear time to search for occurences of the variable in the constraint data.
18453	 */
18454	SCIP_RETCODE SCIPchgCoefLinear(
18455	   SCIP*                 scip,               /**< SCIP data structure */
18456	   SCIP_CONS*            cons,               /**< constraint data */
18457	   SCIP_VAR*             var,                /**< variable of constraint entry */
18458	   SCIP_Real             val                 /**< new coefficient of constraint entry */
18459	   )
18460	{
18461	   SCIP_CONSDATA* consdata;
18462	   SCIP_VAR** vars;
18463	   SCIP_Bool found;
18464	   int i;
18465	
18466	   assert(scip != NULL);
18467	   assert(cons != NULL);
18468	   assert(var != NULL);
18469	
18470	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18471	   {
18472	      SCIPerrorMessage("constraint is not linear\n");
18473	      return SCIP_INVALIDDATA;
18474	   }
18475	
18476	   if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
18477	   {
18478	      SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
18479	      return SCIP_INVALIDDATA;
18480	   }
18481	
18482	   consdata = SCIPconsGetData(cons);
18483	   assert(consdata != NULL);
18484	
18485	   vars = consdata->vars;
18486	   found = FALSE;
18487	   i = 0;
18488	   while( i < consdata->nvars )
18489	   {
18490	      if( vars[i] == var )
18491	      {
18492	         if( found || SCIPisZero(scip, val) )
18493	         {
18494	            SCIP_CALL( delCoefPos(scip, cons, i) );
18495	
18496	            /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
18497	            i--;
18498	         }
18499	         else
18500	         {
18501	            SCIP_CALL( chgCoefPos(scip, cons, i, val) );
18502	         }
18503	         found = TRUE;
18504	      }
18505	      i++;
18506	   }
18507	
18508	   if( !found && !SCIPisZero(scip, val) )
18509	   {
18510	      SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
18511	   }
18512	
18513	   return SCIP_OKAY;
18514	}
18515	
18516	/** deletes variable from linear constraint
18517	 *
18518	 *  @note This method may only be called during problem creation stage for an original constraint and variable.
18519	 *
18520	 *  @note This method requires linear time to search for occurences of the variable in the constraint data.
18521	 */
18522	SCIP_RETCODE SCIPdelCoefLinear(
18523	   SCIP*                 scip,               /**< SCIP data structure */
18524	   SCIP_CONS*            cons,               /**< constraint data */
18525	   SCIP_VAR*             var                 /**< variable of constraint entry */
18526	   )
18527	{
18528	   assert(scip != NULL);
18529	   assert(cons != NULL);
18530	   assert(var != NULL);
18531	
18532	   SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
18533	
18534	   return SCIP_OKAY;
18535	}
18536	
18537	/** gets left hand side of linear constraint */
18538	SCIP_Real SCIPgetLhsLinear(
18539	   SCIP*                 scip,               /**< SCIP data structure */
18540	   SCIP_CONS*            cons                /**< constraint data */
18541	   )
18542	{
18543	   SCIP_CONSDATA* consdata;
18544	
18545	   assert(scip != NULL);
18546	   assert(cons != NULL);
18547	
18548	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18549	   {
18550	      SCIPerrorMessage("constraint is not linear\n");
18551	      SCIPABORT();
18552	      return SCIP_INVALID;  /*lint !e527*/
18553	   }
18554	
18555	   consdata = SCIPconsGetData(cons);
18556	   assert(consdata != NULL);
18557	
18558	   return consdata->lhs;
18559	}
18560	
18561	/** gets right hand side of linear constraint */
18562	SCIP_Real SCIPgetRhsLinear(
18563	   SCIP*                 scip,               /**< SCIP data structure */
18564	   SCIP_CONS*            cons                /**< constraint data */
18565	   )
18566	{
18567	   SCIP_CONSDATA* consdata;
18568	
18569	   assert(scip != NULL);
18570	   assert(cons != NULL);
18571	
18572	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18573	   {
18574	      SCIPerrorMessage("constraint is not linear\n");
18575	      SCIPABORT();
18576	      return SCIP_INVALID;  /*lint !e527*/
18577	   }
18578	
18579	   consdata = SCIPconsGetData(cons);
18580	   assert(consdata != NULL);
18581	
18582	   return consdata->rhs;
18583	}
18584	
18585	/** changes left hand side of linear constraint */
18586	SCIP_RETCODE SCIPchgLhsLinear(
18587	   SCIP*                 scip,               /**< SCIP data structure */
18588	   SCIP_CONS*            cons,               /**< constraint data */
18589	   SCIP_Real             lhs                 /**< new left hand side */
18590	   )
18591	{
18592	   assert(scip != NULL);
18593	   assert(cons != NULL);
18594	
18595	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18596	   {
18597	      SCIPerrorMessage("constraint is not linear\n");
18598	      return SCIP_INVALIDDATA;
18599	   }
18600	
18601	   SCIP_CALL( chgLhs(scip, cons, lhs) );
18602	
18603	   return SCIP_OKAY;
18604	}
18605	
18606	/** changes right hand side of linear constraint */
18607	SCIP_RETCODE SCIPchgRhsLinear(
18608	   SCIP*                 scip,               /**< SCIP data structure */
18609	   SCIP_CONS*            cons,               /**< constraint data */
18610	   SCIP_Real             rhs                 /**< new right hand side */
18611	   )
18612	{
18613	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18614	   {
18615	      SCIPerrorMessage("constraint is not linear\n");
18616	      return SCIP_INVALIDDATA;
18617	   }
18618	
18619	   SCIP_CALL( chgRhs(scip, cons, rhs) );
18620	
18621	   return SCIP_OKAY;
18622	}
18623	
18624	/** gets the number of variables in the linear constraint */
18625	int SCIPgetNVarsLinear(
18626	   SCIP*                 scip,               /**< SCIP data structure */
18627	   SCIP_CONS*            cons                /**< constraint data */
18628	   )
18629	{
18630	   SCIP_CONSDATA* consdata;
18631	
18632	   assert(scip != NULL);
18633	   assert(cons != NULL);
18634	
18635	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18636	   {
18637	      SCIPerrorMessage("constraint is not linear\n");
18638	      SCIPABORT();
18639	      return -1;  /*lint !e527*/
18640	   }
18641	
18642	   consdata = SCIPconsGetData(cons);
18643	   assert(consdata != NULL);
18644	
18645	   return consdata->nvars;
18646	}
18647	
18648	/** gets the array of variables in the linear constraint; the user must not modify this array! */
18649	SCIP_VAR** SCIPgetVarsLinear(
18650	   SCIP*                 scip,               /**< SCIP data structure */
18651	   SCIP_CONS*            cons                /**< constraint data */
18652	   )
18653	{
18654	   SCIP_CONSDATA* consdata;
18655	
18656	   assert(scip != NULL);
18657	   assert(cons != NULL);
18658	
18659	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18660	   {
18661	      SCIPerrorMessage("constraint is not linear\n");
18662	      SCIPABORT();
18663	      return NULL;  /*lint !e527*/
18664	   }
18665	
18666	   consdata = SCIPconsGetData(cons);
18667	   assert(consdata != NULL);
18668	
18669	   return consdata->vars;
18670	}
18671	
18672	/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
18673	SCIP_Real* SCIPgetValsLinear(
18674	   SCIP*                 scip,               /**< SCIP data structure */
18675	   SCIP_CONS*            cons                /**< constraint data */
18676	   )
18677	{
18678	   SCIP_CONSDATA* consdata;
18679	
18680	   assert(scip != NULL);
18681	   assert(cons != NULL);
18682	
18683	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18684	   {
18685	      SCIPerrorMessage("constraint is not linear\n");
18686	      SCIPABORT();
18687	      return NULL;  /*lint !e527*/
18688	   }
18689	
18690	   consdata = SCIPconsGetData(cons);
18691	   assert(consdata != NULL);
18692	
18693	   return consdata->vals;
18694	}
18695	
18696	/** gets the activity of the linear constraint in the given solution
18697	 *
18698	 *  @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
18699	 *        comprises positive and negative infinity contributions
18700	 */
18701	SCIP_Real SCIPgetActivityLinear(
18702	   SCIP*                 scip,               /**< SCIP data structure */
18703	   SCIP_CONS*            cons,               /**< constraint data */
18704	   SCIP_SOL*             sol                 /**< solution, or NULL to use current node's solution */
18705	   )
18706	{
18707	   SCIP_CONSDATA* consdata;
18708	
18709	   assert(scip != NULL);
18710	   assert(cons != NULL);
18711	
18712	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18713	   {
18714	      SCIPerrorMessage("constraint is not linear\n");
18715	      SCIPABORT();
18716	      return SCIP_INVALID;  /*lint !e527*/
18717	   }
18718	
18719	   consdata = SCIPconsGetData(cons);
18720	   assert(consdata != NULL);
18721	
18722	   if( consdata->row != NULL )
18723	      return SCIPgetRowSolActivity(scip, consdata->row, sol);
18724	   else
18725	      return consdataGetActivity(scip, consdata, sol);
18726	}
18727	
18728	/** gets the feasibility of the linear constraint in the given solution */
18729	SCIP_Real SCIPgetFeasibilityLinear(
18730	   SCIP*                 scip,               /**< SCIP data structure */
18731	   SCIP_CONS*            cons,               /**< constraint data */
18732	   SCIP_SOL*             sol                 /**< solution, or NULL to use current node's solution */
18733	   )
18734	{
18735	   SCIP_CONSDATA* consdata;
18736	
18737	   assert(scip != NULL);
18738	   assert(cons != NULL);
18739	
18740	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18741	   {
18742	      SCIPerrorMessage("constraint is not linear\n");
18743	      SCIPABORT();
18744	      return SCIP_INVALID;  /*lint !e527*/
18745	   }
18746	
18747	   consdata = SCIPconsGetData(cons);
18748	   assert(consdata != NULL);
18749	
18750	   if( consdata->row != NULL )
18751	      return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
18752	   else
18753	      return consdataGetFeasibility(scip, consdata, sol);
18754	}
18755	
18756	/** gets the dual solution of the linear constraint in the current LP */
18757	SCIP_Real SCIPgetDualsolLinear(
18758	   SCIP*                 scip,               /**< SCIP data structure */
18759	   SCIP_CONS*            cons                /**< constraint data */
18760	   )
18761	{
18762	   SCIP_CONSDATA* consdata;
18763	
18764	   assert(scip != NULL);
18765	   assert(cons != NULL);
18766	   assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18767	
18768	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18769	   {
18770	      SCIPerrorMessage("constraint is not linear\n");
18771	      SCIPABORT();
18772	      return SCIP_INVALID;  /*lint !e527*/
18773	   }
18774	
18775	   consdata = SCIPconsGetData(cons);
18776	   assert(consdata != NULL);
18777	
18778	   if( consdata->row != NULL )
18779	      return SCIProwGetDualsol(consdata->row);
18780	   else
18781	      return 0.0;
18782	}
18783	
18784	/** gets the dual Farkas value of the linear constraint in the current infeasible LP */
18785	SCIP_Real SCIPgetDualfarkasLinear(
18786	   SCIP*                 scip,               /**< SCIP data structure */
18787	   SCIP_CONS*            cons                /**< constraint data */
18788	   )
18789	{
18790	   SCIP_CONSDATA* consdata;
18791	
18792	   assert(scip != NULL);
18793	   assert(cons != NULL);
18794	   assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18795	
18796	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18797	   {
18798	      SCIPerrorMessage("constraint is not linear\n");
18799	      SCIPABORT();
18800	      return SCIP_INVALID;  /*lint !e527*/
18801	   }
18802	
18803	   consdata = SCIPconsGetData(cons);
18804	   assert(consdata != NULL);
18805	
18806	   if( consdata->row != NULL )
18807	      return SCIProwGetDualfarkas(consdata->row);
18808	   else
18809	      return 0.0;
18810	}
18811	
18812	/** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
18813	 *  the user must not modify the row!
18814	 */
18815	SCIP_ROW* SCIPgetRowLinear(
18816	   SCIP*                 scip,               /**< SCIP data structure */
18817	   SCIP_CONS*            cons                /**< constraint data */
18818	   )
18819	{
18820	   SCIP_CONSDATA* consdata;
18821	
18822	   assert(scip != NULL);
18823	   assert(cons != NULL);
18824	
18825	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18826	   {
18827	      SCIPerrorMessage("constraint is not linear\n");
18828	      SCIPABORT();
18829	      return NULL;  /*lint !e527*/
18830	   }
18831	
18832	   consdata = SCIPconsGetData(cons);
18833	   assert(consdata != NULL);
18834	
18835	   return consdata->row;
18836	}
18837	
18838	/** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
18839	SCIP_RETCODE SCIPupgradeConsLinear(
18840	   SCIP*                 scip,               /**< SCIP data structure */
18841	   SCIP_CONS*            cons,               /**< source constraint to try to convert */
18842	   SCIP_CONS**           upgdcons            /**< pointer to store upgraded constraint, or NULL if not successful */
18843	   )
18844	{
18845	   SCIP_CONSHDLR* conshdlr;
18846	   SCIP_CONSHDLRDATA* conshdlrdata;
18847	   SCIP_CONSDATA* consdata;
18848	   SCIP_VAR* var;
18849	   SCIP_Real val;
18850	   SCIP_Real lb;
18851	   SCIP_Real ub;
18852	   SCIP_Real poscoeffsum;
18853	   SCIP_Real negcoeffsum;
18854	   SCIP_Bool infeasible;
18855	   SCIP_Bool integral;
18856	   int nchgsides = 0;
18857	   int nposbin;
18858	   int nnegbin;
18859	   int nposint;
18860	   int nnegint;
18861	   int nposimpl;
18862	   int nnegimpl;
18863	   int nposimplbin;
18864	   int nnegimplbin;
18865	   int nposcont;
18866	   int nnegcont;
18867	   int ncoeffspone;
18868	   int ncoeffsnone;
18869	   int ncoeffspint;
18870	   int ncoeffsnint;
18871	   int ncoeffspfrac;
18872	   int ncoeffsnfrac;
18873	   int i;
18874	
18875	   assert(scip != NULL);
18876	   assert(cons != NULL);
18877	   assert(upgdcons != NULL);
18878	
18879	   *upgdcons = NULL;
18880	
18881	   /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
18882	   if( SCIPconsIsModifiable(cons) )
18883	      return SCIP_OKAY;
18884	
18885	   /* check for upgradability */
18886	   if( SCIPconsGetNUpgradeLocks(cons) > 0 )
18887	      return SCIP_OKAY;
18888	
18889	   /* get the constraint handler and check, if it's really a linear constraint */
18890	   conshdlr = SCIPconsGetHdlr(cons);
18891	   if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
18892	   {
18893	      SCIPerrorMessage("constraint is not linear\n");
18894	      return SCIP_INVALIDDATA;
18895	   }
18896	
18897	   /* get constraint handler data and constraint data */
18898	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
18899	   assert(conshdlrdata != NULL);
18900	   consdata = SCIPconsGetData(cons);
18901	   assert(consdata != NULL);
18902	
18903	   /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
18904	   if( consdata->upgraded )
18905	      return SCIP_OKAY;
18906	
18907	   /* check, if the constraint is already stored as LP row */
18908	   if( consdata->row != NULL )
18909	   {
18910	      if( SCIProwIsInLP(consdata->row) )
18911	      {
18912	         SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
18913	         return SCIP_INVALIDDATA;
18914	      }
18915	      else
18916	      {
18917	         SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
18918	      }
18919	   }
18920	
18921	   /* normalize constraint */
18922	   SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
18923	
18924	   /* normalizeCons() can only detect infeasibility when scaling with the gcd. in that case, the scaling was
18925	    * skipped and we hope that the infeasibility gets detected later again.
18926	    *
18927	    * TODO: do we want to try to upgrade the constraint anyway?
18928	    *
18929	    * TODO: this needs to be fixed on master by changing the API and passing a pointer to whether the constraint is
18930	    *       proven to be infeasible.
18931	    */
18932	   if( infeasible )   /*lint !e774*/
18933	      return SCIP_OKAY;
18934	
18935	   /* tighten sides */
18936	   SCIP_CALL( tightenSides(scip, cons, &nchgsides, &infeasible) );
18937	
18938	   if( infeasible )   /*lint !e774*/
18939	      return SCIP_OKAY;
18940	
18941	   /*
18942	    * calculate some statistics on linear constraint
18943	    */
18944	
18945	   nposbin = 0;
18946	   nnegbin = 0;
18947	   nposint = 0;
18948	   nnegint = 0;
18949	   nposimpl = 0;
18950	   nnegimpl = 0;
18951	   nposimplbin = 0;
18952	   nnegimplbin = 0;
18953	   nposcont = 0;
18954	   nnegcont = 0;
18955	   ncoeffspone = 0;
18956	   ncoeffsnone = 0;
18957	   ncoeffspint = 0;
18958	   ncoeffsnint = 0;
18959	   ncoeffspfrac = 0;
18960	   ncoeffsnfrac = 0;
18961	   integral = TRUE;
18962	   poscoeffsum = 0.0;
18963	   negcoeffsum = 0.0;
18964	
18965	   for( i = 0; i < consdata->nvars; ++i )
18966	   {
18967	      var = consdata->vars[i];
18968	      val = consdata->vals[i];
18969	      lb = SCIPvarGetLbLocal(var);
18970	      ub = SCIPvarGetUbLocal(var);
18971	      assert(!SCIPisZero(scip, val));
18972	
18973	      switch( SCIPvarGetType(var) )
18974	      {
18975	      case SCIP_VARTYPE_BINARY:
18976	         if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18977	            integral = integral && SCIPisIntegral(scip, val);
18978	         if( val >= 0.0 )
18979	            nposbin++;
18980	         else
18981	            nnegbin++;
18982	         break;
18983	      case SCIP_VARTYPE_INTEGER:
18984	         if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18985	            integral = integral && SCIPisIntegral(scip, val);
18986	         if( val >= 0.0 )
18987	            nposint++;
18988	         else
18989	            nnegint++;
18990	         break;
18991	      case SCIP_VARTYPE_IMPLINT:
18992	         if( SCIPvarIsBinary(var) )
18993	         {
18994	            if( val >= 0.0 )
18995	               nposimplbin++;
18996	            else
18997	               nnegimplbin++;
18998	         }
18999	         if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
19000	            integral = integral && SCIPisIntegral(scip, val);
19001	         if( val >= 0.0 )
19002	            nposimpl++;
19003	         else
19004	            nnegimpl++;
19005	         break;
19006	      case SCIP_VARTYPE_CONTINUOUS:
19007	         integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
19008	         if( val >= 0.0 )
19009	            nposcont++;
19010	         else
19011	            nnegcont++;
19012	         break;
19013	      default:
19014	         SCIPerrorMessage("unknown variable type\n");
19015	         return SCIP_INVALIDDATA;
19016	      }
19017	      if( SCIPisEQ(scip, val, 1.0) )
19018	         ncoeffspone++;
19019	      else if( SCIPisEQ(scip, val, -1.0) )
19020	         ncoeffsnone++;
19021	      else if( SCIPisIntegral(scip, val) )
19022	      {
19023	         if( SCIPisPositive(scip, val) )
19024	            ncoeffspint++;
19025	         else
19026	            ncoeffsnint++;
19027	      }
19028	      else
19029	      {
19030	         if( SCIPisPositive(scip, val) )
19031	            ncoeffspfrac++;
19032	         else
19033	            ncoeffsnfrac++;
19034	      }
19035	      if( SCIPisPositive(scip, val) )
19036	         poscoeffsum += val;
19037	      else
19038	         negcoeffsum += val;
19039	   }
19040	
19041	   /*
19042	    * call the upgrading methods
19043	    */
19044	
19045	   SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
19046	      SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
19047	   SCIPdebugMsg(scip, " +bin=%d -bin=%d +int=%d -int=%d +impl=%d -impl=%d +cont=%d -cont=%d +1=%d -1=%d +I=%d -I=%d +F=%d -F=%d possum=%.15g negsum=%.15g integral=%u\n",
19048	      nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
19049	      ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
19050	      poscoeffsum, negcoeffsum, integral);
19051	
19052	   /* try all upgrading methods in priority order in case the upgrading step is enable  */
19053	   for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
19054	   {
19055	      if( conshdlrdata->linconsupgrades[i]->active )
19056	      {
19057	         SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
19058	               consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
19059	               nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
19060	               ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
19061	               poscoeffsum, negcoeffsum, integral,
19062	               upgdcons) );
19063	      }
19064	   }
19065	
19066	#ifdef SCIP_DEBUG
19067	   if( *upgdcons != NULL )
19068	   {
19069	      SCIPdebugPrintCons(scip, cons, NULL);
19070	      SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
19071	      SCIPdebugPrintCons(scip, *upgdcons, NULL);
19072	   }
19073	#endif
19074	
19075	   return SCIP_OKAY; /*lint !e438*/
19076	}
19077	
19078	/** cleans up (multi-)aggregations and fixings from linear constraints */
19079	SCIP_RETCODE SCIPcleanupConssLinear(
19080	   SCIP*                 scip,               /**< SCIP data structure */
19081	   SCIP_Bool             onlychecked,        /**< should only checked constraints be cleaned up? */
19082	   SCIP_Bool*            infeasible          /**< pointer to return whether the problem was detected to be infeasible */
19083	   )
19084	{
19085	   SCIP_CONSHDLR* conshdlr;
19086	   SCIP_CONS** conss;
19087	   int nconss;
19088	   int i;
19089	
19090	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
19091	   if( conshdlr == NULL )
19092	      return SCIP_OKAY;
19093	
19094	   assert(infeasible != NULL);
19095	   *infeasible = FALSE;
19096	
19097	   nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
19098	   conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
19099	
19100	   for( i = 0; i < nconss; ++i )
19101	   {
19102	      SCIP_CALL( applyFixings(scip, conss[i], infeasible) );
19103	
19104	      if( *infeasible )
19105	         break;
19106	   }
19107	
19108	   return SCIP_OKAY;
19109	}
19110