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_pseudoboolean.c
26   	 * @ingroup DEFPLUGINS_CONS
27   	 * @brief  constraint handler for pseudo Boolean constraints
28   	 * @author Gerald Gamrath
29   	 * @author Stefan Heinz
30   	 * @author Michael Winkler
31   	 *
32   	 *
33   	 * The constraint handler deals with pseudo Boolean constraints. These are constraints of the form
34   	 * \f[
35   	 * \mbox{lhs} \leq \sum_{k=0}^m c_k \cdot x_k  +  \sum_{i=0}^n c_i \cdot \prod_{j \in I_i} x_j \leq \mbox{rhs}
36   	 * \f]
37   	 * where all x are binary and all c are integer
38   	 *
39   	 * @todo Add eventhandling.
40   	 */
41   	
42   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43   	
44   	#include "blockmemshell/memory.h"
45   	#include "scip/cons_and.h"
46   	#include "scip/cons_indicator.h"
47   	#include "scip/cons_knapsack.h"
48   	#include "scip/cons_linear.h"
49   	#include "scip/cons_logicor.h"
50   	#include "scip/cons_pseudoboolean.h"
51   	#include "scip/cons_setppc.h"
52   	#include "scip/cons_xor.h"
53   	#include "scip/debug.h"
54   	#include "scip/pub_cons.h"
55   	#include "scip/pub_message.h"
56   	#include "scip/pub_misc.h"
57   	#include "scip/pub_misc_sort.h"
58   	#include "scip/pub_var.h"
59   	#include "scip/scip_cons.h"
60   	#include "scip/scip_copy.h"
61   	#include "scip/scip_general.h"
62   	#include "scip/scip_mem.h"
63   	#include "scip/scip_message.h"
64   	#include "scip/scip_numerics.h"
65   	#include "scip/scip_param.h"
66   	#include "scip/scip_prob.h"
67   	#include "scip/scip_sol.h"
68   	#include "scip/scip_var.h"
69   	#include <string.h>
70   	
71   	#ifdef WITHEQKNAPSACK
72   	#include "scip/cons_eqknapsack.h"
73   	#endif
74   	
75   	/* constraint handler properties */
76   	#define CONSHDLR_NAME          "pseudoboolean"
77   	#define CONSHDLR_DESC          "constraint handler dealing with pseudo Boolean constraints"
78   	#define CONSHDLR_ENFOPRIORITY  -1000000 /**< priority of the constraint handler for constraint enforcing */
79   	#define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
80   	#define CONSHDLR_EAGERFREQ          100 /**< frequency for using all instead of only the useful constraints in separation,
81   	                                              *   propagation and enforcement, -1 for no eager evaluations, 0 for first only */
82   	#define CONSHDLR_MAXPREROUNDS        -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
83   	#define CONSHDLR_NEEDSCONS         TRUE /**< should the constraint handler be skipped, if no constraints are available? */
84   	
85   	#define CONSHDLR_PRESOLTIMING            SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
86   	
87   	#define DEFAULT_DECOMPOSENORMALPBCONS FALSE /**< decompose all normal pseudo boolean constraint into a "linear" constraint and "and" constraints */
88   	#define DEFAULT_DECOMPOSEINDICATORPBCONS TRUE /**< decompose all indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
89   	
90   	#define DEFAULT_SEPARATENONLINEAR  TRUE /**< if decomposed, should the nonlinear constraints be separated during LP processing */
91   	#define DEFAULT_PROPAGATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be propagated during node processing */
92   	#define DEFAULT_REMOVABLENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be removable */
93   	#define USEINDICATOR               TRUE
94   	#define NONLINCONSUPGD_PRIORITY   60000 /**< priority of upgrading nonlinear constraints */
95   	
96   	/* remove this line to compile the upgrade from nonlinear to pseudoboolean constraints */
97   	#undef NONLINCONSUPGD_PRIORITY  /*lint !e750*/
98   	
99   	/*
100  	 * Data structures
101  	 */
102  	#define HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS 500 /**< minimal size of hash table in and constraint tables */
103  	
104  	
105  	/* - create special linear(knapsack, setppc, logicor, (eqknapsack)) and and-constraints with check flags FALSE, to
106  	 *   get smaller amount of locks on the term variables, do all presolving ...?! in these constraint handlers
107  	 *
108  	 * - do the checking here, lock and-resultants in both directions and all and-variables according to their
109  	 *   coefficients and sides of the constraint,
110  	 *   @note this only works if the and-resultant has no objective cofficient, otherwise we need to lock variables also in both directions
111  	 *
112  	 * - need to keep and constraint pointer for special propagations like if two ands are due to their variables in
113  	 *   one clique, add this cliques of and-resultants
114  	 *
115  	 * - do special presolving like on instance :
116  	 * check/IP/PseudoBoolean/normalized-PB07/OPT-SMALLINT-NLC/submittedPB07/manquinho/bsg/normalized-bsg_1000_25_1.opb.gz
117  	 *
118  	 *  there exist constraint like:        1 x1 x2 + 1 x1 x3 + 1 x1 x4 + 1 x1 x5 <= 1 ;
119  	 *  which "equals" a linear constraint: 3 x1 + x2 + x3 + x4 + x5 <= 4 ;
120  	 *
121  	 *  in more general terms:                     1 x1 x2 x3 x4 + 1 x1 x2 x5 x6 x7 + 1 x1 x2 x8 x9 <= 1 ;
122  	 *  which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 5 ;
123  	 *
124  	 *  in an even more general terms:             5 x1 x2 x3 x4 + 1 x1 x2 x5 x6 x7 + 1 x1 x2 x8 x9 <= 6 ;
125  	 *            equals(should the knapsack do)   1 x1 x2 x3 x4 + 1 x1 x2 x5 x6 x7 + 1 x1 x2 x8 x9 <= 2 ;
126  	 *  which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 6 ;
127  	 *  (         without knapsack                 7 x1 + 7 x2 + 5 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 20 ; )
128  	 *
129  	 *  another special case :                     1 x1 x2 x3 + 1 x1 x2 x4 + 1 x5 x6 <= 1 ;
130  	 *  which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 + 1 x4 + 1 x5 x6 <= 5 ;
131  	 *  which "equals" a pseudoboolean constraint: 4 x1 + 4 x2 + 2 x3 + 2 x4 + 1 x5 + 1 x6 <= 10 ;
132  	 *
133  	 *  another special case :                     1 x1 x2 + 1 x1 x3 + 2 x4 x5 <= 3 ;
134  	 *  which "equals" a pseudoboolean constraint: 2 x1 + 1 x2 + 1 x3 + 2 x4 x5 <= 5 ;
135  	 *  which "equals" a pseudoboolean constraint: 2 x1 + 1 x2 + 1 x3 + 1 x4 + 1 x5 <= 5 ;
136  	 */
137  	/* @todo - in and-constraint better count nfixed zeros in both directions and maybe nfixedones for better propagation
138  	 *
139  	 *       - do better conflict analysis by choosing the earliest fixed variable which led to a conflict instead of maybe
140  	 *         best coefficient or create more conflicts by using all to zero fixed variables one by one
141  	 *
142  	 *       - how to make sure that we aggregate in a right way, when aggregating a resultant and a "normal" variable,
143  	 *         maybe add in SCIPaggregateVars a check for original variables, to prefer them if the variable type is the
144  	 *         same; probably it would be better too if we would aggregate two resultants that the one with less variables
145  	 *         inside the and-constraint will stay active
146  	 *
147  	 * @note since product resultants are artificial, we do not care for their solution value, but this can lead to fixation
148  	 *       of the resultant not representing the product, in 'optimization mode' we do not care, but this might make
149  	 *       solution debugging complicated
150  	 */
151  	
152  	/** and-constraint data object */
153  	struct ConsAndData
154  	{
155  	   SCIP_CONS*            cons;                /**< pointer to the and-constraint of this 'term' of variables */
156  	   SCIP_CONS*            origcons;            /**< pointer to the original and-constraint of this 'term' of variables
157  	                                               *   only after problem was transformed, NULL otherwise */
158  	   SCIP_VAR**            vars;                /**< all and-constraint variables */
159  	   int                   nvars;               /**< number of all and-constraint variables */
160  	   int                   svars;               /**< size for all and-constraint variables */
161  	   SCIP_VAR**            newvars;             /**< new variables in this presolving round */
162  	   int                   nnewvars;            /**< number of new variables in this presolving round */
163  	   int                   snewvars;            /**< size of new variables in this presolving round */
164  	   int                   noriguses;           /**< how often is this data in used by original constraints */
165  	   int                   nuses;               /**< how often is this data in used by transformed constraints */
166  	   unsigned int          istransformed:1;     /**< is transformed data active */
167  	   unsigned int          isoriginal:1;        /**< is original data active */
168  	};
169  	typedef struct ConsAndData CONSANDDATA;
170  	
171  	/** constraint data for pseudoboolean constraints */
172  	struct SCIP_ConsData
173  	{
174  	   SCIP_Real             lhs;                /**< left hand side of constraint */
175  	   SCIP_Real             rhs;                /**< right hand side of constraint */
176  	
177  	   SCIP_CONS*            lincons;            /**< linear constraint which represents this pseudoboolean constraint */
178  	   SCIP_LINEARCONSTYPE   linconstype;        /**< type of linear constraint which represents this pseudoboolean constraint */
179  	   int                   nlinvars;           /**< number of linear variables (without and-resultants) */
180  	
181  	   CONSANDDATA**         consanddatas;       /**< array of and-constraints-data-objects sorted after index of
182  	                                              *   and-resultant of corresponding and-constraint */
183  	   SCIP_Real*            andcoefs;           /**< array of coefficients for and-constraints of
184  	                                              *   and-constraints-data-objects
185  	                                              *   (changes during presolving, needs to be updated in every presolving
186  	                                              *   round) */
187  	   SCIP_Bool*            andnegs;            /**< array of negation status for and-constraints of
188  	                                              *   and-constraints-data-objects
189  	                                              *   (changes during presolving, needs to be updated in every presolving
190  	                                              *   round) */
191  	   int                   nconsanddatas;      /**< number of and-constraints-data-objects */
192  	   int                   sconsanddatas;      /**< size of and-constraints-data-objects array */
193  	
194  	   SCIP_VAR*             intvar;             /**< a artificial variable which was added only for the objective function,
195  	                                              *   if this variable is not NULL this constraint (without this integer
196  	                                              *   variable) describes the objective function */
197  	
198  	   SCIP_VAR*             indvar;             /**< indicator variable if it's a soft constraint, or NULL */
199  	   SCIP_Real             weight;             /**< weight of the soft constraint, if it is one */
200  	
201  	   unsigned int          issoftcons:1;       /**< is this a soft constraint */
202  	   unsigned int          changed:1;          /**< was constraint changed? */
203  	   unsigned int          propagated:1;       /**< is constraint already propagated? */
204  	   unsigned int          presolved:1;        /**< is constraint already presolved? */
205  	   unsigned int          cliquesadded:1;     /**< were the cliques of the constraint already extracted? */
206  	   unsigned int          upgradetried:1;     /**< was constraint upgrading already tried */
207  	};
208  	
209  	/** constraint handler data */
210  	struct SCIP_ConshdlrData
211  	{
212  	   CONSANDDATA**         allconsanddatas;    /**< array of all and-constraint data objects inside the whole problem,
213  	                                              *   created via this constraint handler */
214  	   int                   nallconsanddatas;   /**< number of all and-constraint data objects inside the whole problem,
215  	                                              *   created via this constraint handler */
216  	   int                   sallconsanddatas;   /**< size of all and-constraint data objects inside the whole problem,
217  	                                              *   created via this constraint handler */
218  	   SCIP_HASHTABLE*       hashtable;          /**< hash table for all and-constraint data objects */
219  	   int                   hashtablesize;      /**< size for hash table for all and-constraint data objects */
220  	
221  	   SCIP_HASHMAP*         hashmap;            /**< hash map for mapping all resultant to and-constraint */
222  	   int                   hashmapsize;        /**< size for hash map for mapping all resultant to and-constraint */
223  	
224  	   SCIP_Bool             decomposenormalpbcons;/**< decompose the pseudo boolean constraint into a "linear" constraint and "and" constraints */
225  	   SCIP_Bool             decomposeindicatorpbcons;/**< decompose the indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
226  	   SCIP_Bool             inithashmapandtable;/**< flag to store if the hashmap and -table is initialized */
227  	   int                   nlinconss;          /**< for counting number of created linear constraints */
228  	   int                   noriguses;          /**< how many consanddata objects are used by original constraints */
229  	};
230  	
231  	/*
232  	 * Local methods
233  	 */
234  	
235  	
236  	/** comparison method for sorting consanddatas according to the index of their corresponding resultant variables, if a
237  	 *  consanddata object is delete it is handled like it has an inactive resultant, so this will be put in front while
238  	 *  sorting
239  	 */
240  	static
241  	SCIP_DECL_SORTPTRCOMP(resvarCompWithInactive)
242  	{
243  	   CONSANDDATA* consanddata1;
244  	   CONSANDDATA* consanddata2;
245  	
246  	   consanddata1 = (CONSANDDATA*)elem1;
247  	   consanddata2 = (CONSANDDATA*)elem2;
248  	
249  	   /* check if and constraint data object is still valid */
250  	   if( !consanddata1->istransformed )
251  	   {
252  	      if( !consanddata2->istransformed )
253  	      {
254  	         return 0;
255  	      }
256  	      else
257  	         return -1;
258  	   }
259  	   else if( !consanddata2->istransformed )
260  	      return +1;
261  	
262  	   assert(consanddata1->cons != NULL);
263  	   assert(consanddata2->cons != NULL);
264  	
265  	   /* check if and constraint is still active */
266  	   if( SCIPconsIsDeleted(consanddata1->cons) )
267  	   {
268  	      if( SCIPconsIsDeleted(consanddata2->cons) )
269  	      {
270  	         return 0;
271  	      }
272  	      else
273  	         return -1;
274  	   }
275  	   else if( SCIPconsIsDeleted(consanddata2->cons) )
276  	      return +1;
277  	   else
278  	   {
279  	      SCIP_VAR* var1;
280  	      SCIP_VAR* var2;
281  	
282  	      /* hack with setting the first pointer to NULL */
283  	      var1 = SCIPgetResultantAnd(NULL, consanddata1->cons);
284  	      var2 = SCIPgetResultantAnd(NULL, consanddata2->cons);
285  	
286  	      assert(var1 != NULL);
287  	      assert(var2 != NULL);
288  	
289  	      if( SCIPvarGetIndex(var1) < SCIPvarGetIndex(var2) )
290  	         return -1;
291  	      else if( SCIPvarGetIndex(var1) > SCIPvarGetIndex(var2) )
292  	         return +1;
293  	      else
294  	      {
295  	         assert(var1 == var2);
296  	         return 0;
297  	      }
298  	   }
299  	}
300  	
301  	/** gets the key of the given element */
302  	static
303  	SCIP_DECL_HASHGETKEY(hashGetKeyAndConsDatas)
304  	{  /*lint --e{715}*/
305  	   /* the key is the element itself */
306  	   return elem;
307  	}
308  	
309  	/** returns TRUE iff both keys are equal; two non-linear terms are equal if they have the same variables */
310  	static
311  	SCIP_DECL_HASHKEYEQ(hashKeyEqAndConsDatas)
312  	{
313  	#ifndef NDEBUG
314  	   SCIP* scip;
315  	#endif
316  	   CONSANDDATA* cdata1;
317  	   CONSANDDATA* cdata2;
318  	   int v;
319  	
320  	   cdata1 = (CONSANDDATA*)key1;
321  	   cdata2 = (CONSANDDATA*)key2;
322  	
323  	#ifndef NDEBUG
324  	   scip = (SCIP*)userptr;
325  	#endif
326  	   assert(scip != NULL);
327  	   assert(cdata1 != NULL);
328  	   assert(cdata2 != NULL);
329  	   assert(cdata1->vars != NULL);
330  	   assert(cdata1->nvars > 1);
331  	   assert(cdata2->vars != NULL);
332  	   assert(cdata2->nvars > 1);
333  	
334  	#ifndef NDEBUG
335  	   /* check that cdata1 variables are sorted */
336  	   for( v = cdata1->nvars - 1; v > 0; --v )
337  	      assert(SCIPvarGetIndex(cdata1->vars[v]) >= SCIPvarGetIndex(cdata1->vars[v - 1]));
338  	   /* check that cdata2 variables are sorted */
339  	   for( v = cdata2->nvars - 1; v > 0; --v )
340  	      assert(SCIPvarGetIndex(cdata2->vars[v]) >= SCIPvarGetIndex(cdata2->vars[v - 1]));
341  	#endif
342  	
343  	   /* checks trivial case */
344  	   if( cdata1->nvars != cdata2->nvars )
345  	      return FALSE;
346  	
347  	   /* checks trivial case */
348  	   if( cdata1->cons != NULL && cdata2->cons != NULL && cdata1->cons != cdata2->cons )
349  	      return FALSE;
350  	
351  	   /* check each variable in both cdatas for equality */
352  	   for( v = cdata1->nvars - 1; v >= 0; --v )
353  	   {
354  	      assert(cdata1->vars[v] != NULL);
355  	      assert(cdata2->vars[v] != NULL);
356  	
357  	      /* tests if variables are equal */
358  	      if( cdata1->vars[v] != cdata2->vars[v] )
359  	      {
360  	         assert(SCIPvarCompare(cdata1->vars[v], cdata2->vars[v]) == 1 ||
361  	            SCIPvarCompare(cdata1->vars[v], cdata2->vars[v]) == -1);
362  	         return FALSE;
363  	      }
364  	      assert(SCIPvarCompare(cdata1->vars[v], cdata2->vars[v]) == 0);
365  	   }
366  	
367  	   return TRUE;
368  	}
369  	
370  	/** returns the hash value of the key */
371  	static
372  	SCIP_DECL_HASHKEYVAL(hashKeyValAndConsDatas)
373  	{  /*lint --e{715}*/
374  	   CONSANDDATA* cdata;
375  	   int minidx;
376  	   int mididx;
377  	   int maxidx;
378  	
379  	   cdata = (CONSANDDATA*)key;
380  	
381  	   assert(cdata != NULL);
382  	   assert(cdata->vars != NULL);
383  	   assert(cdata->nvars > 1);
384  	#ifndef NDEBUG
385  	   {
386  	      /* check that these variables are sorted */
387  	      int v;
388  	      for( v = cdata->nvars - 1; v > 0; --v )
389  	         assert(SCIPvarGetIndex(cdata->vars[v]) >= SCIPvarGetIndex(cdata->vars[v - 1]));
390  	   }
391  	#endif
392  	
393  	   minidx = SCIPvarGetIndex(cdata->vars[0]);
394  	   mididx = SCIPvarGetIndex(cdata->vars[cdata->nvars / 2]);
395  	   maxidx = SCIPvarGetIndex(cdata->vars[cdata->nvars - 1]);
396  	   assert(minidx >= 0 && minidx <= maxidx);
397  	
398  	   return SCIPhashFour(cdata->nvars, minidx, mididx, maxidx);
399  	}
400  	
401  	/** initializes the hashmap and -table used in this constraint handler data for artificial variables and specific
402  	 *  and-constraint data objects
403  	 */
404  	static
405  	SCIP_RETCODE inithashmapandtable(
406  	   SCIP*const            scip,               /**< SCIP data structure */
407  	   SCIP_CONSHDLRDATA**   conshdlrdata        /**< pointer to store the constraint handler data */
408  	   )
409  	{
410  	   if( ((*conshdlrdata)->inithashmapandtable) )
411  	   {
412  	      assert((*conshdlrdata)->hashtable != NULL);
413  	      assert((*conshdlrdata)->hashmap != NULL);
414  	
415  	      return SCIP_OKAY;
416  	   }
417  	
418  	   assert((*conshdlrdata)->hashtable == NULL);
419  	   assert((*conshdlrdata)->hashmap == NULL);
420  	
421  	   /* create a hash table for and-constraint data objects */
422  	   (*conshdlrdata)->hashtablesize = HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS;
423  	   SCIP_CALL( SCIPhashtableCreate(&((*conshdlrdata)->hashtable), SCIPblkmem(scip), (*conshdlrdata)->hashtablesize,
424  	         hashGetKeyAndConsDatas, hashKeyEqAndConsDatas, hashKeyValAndConsDatas, (void*) scip) );
425  	
426  	   /* create a hash table for and-resultant to and-constraint data objects */
427  	   (*conshdlrdata)->hashmapsize = HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS;
428  	   SCIP_CALL( SCIPhashmapCreate(&((*conshdlrdata)->hashmap), SCIPblkmem(scip), (*conshdlrdata)->hashmapsize) );
429  	
430  	   (*conshdlrdata)->inithashmapandtable = TRUE;
431  	
432  	   return SCIP_OKAY;
433  	}
434  	
435  	/** creates constraint handler data for pseudo boolean constraint handler */
436  	static
437  	SCIP_RETCODE conshdlrdataCreate(
438  	   SCIP*const            scip,               /**< SCIP data structure */
439  	   SCIP_CONSHDLRDATA**   conshdlrdata        /**< pointer to store the constraint handler data */
440  	   )
441  	{
442  	   assert(scip != NULL);
443  	   assert(conshdlrdata != NULL);
444  	
445  	   SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
446  	
447  	   (*conshdlrdata)->allconsanddatas = NULL;
448  	   (*conshdlrdata)->nallconsanddatas = 0;
449  	   (*conshdlrdata)->sallconsanddatas = 10;
450  	
451  	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas ) );
452  	
453  	   /* set hashmap and -table to NULL, mark them as uninitialized */
454  	   (*conshdlrdata)->inithashmapandtable = FALSE;
455  	   (*conshdlrdata)->hashtable = NULL;
456  	   (*conshdlrdata)->hashtablesize = 0;
457  	   (*conshdlrdata)->hashmap = NULL;
458  	   (*conshdlrdata)->hashmapsize = 0;
459  	
460  	   /* for constraint names count number of created constraints */
461  	   (*conshdlrdata)->nlinconss = 0;
462  	
463  	   /* initializes how many consanddata objects are used by original constraints */
464  	   (*conshdlrdata)->noriguses = 0;
465  	
466  	   return SCIP_OKAY;
467  	}
468  	
469  	
470  	/** frees constraint handler data for pseudo boolean constraint handler */
471  	static
472  	SCIP_RETCODE conshdlrdataFree(
473  	   SCIP*const            scip,               /**< SCIP data structure */
474  	   SCIP_CONSHDLRDATA**   conshdlrdata        /**< pointer to the constraint handler data */
475  	   )
476  	{
477  	   assert(scip != NULL);
478  	   assert(conshdlrdata != NULL);
479  	   assert(*conshdlrdata != NULL);
480  	   assert((*conshdlrdata)->nallconsanddatas == 0);
481  	
482  	   /* free hash table if necessary */
483  	   if( (*conshdlrdata)->inithashmapandtable )
484  	   {
485  	      SCIPhashmapFree(&((*conshdlrdata)->hashmap));
486  	      (*conshdlrdata)->hashmapsize = 0;
487  	      SCIPhashtableFree(&((*conshdlrdata)->hashtable));
488  	      (*conshdlrdata)->hashtablesize = 0;
489  	   }
490  	   else
491  	   {
492  	      assert((*conshdlrdata)->hashmap == NULL);
493  	      assert((*conshdlrdata)->hashtable == NULL);
494  	   }
495  	   (*conshdlrdata)->inithashmapandtable = FALSE;
496  	
497  	   /* clear array for all consanddata objects */
498  	   SCIPfreeBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas );
499  	
500  	   (*conshdlrdata)->allconsanddatas = NULL;
501  	   (*conshdlrdata)->nallconsanddatas = 0;
502  	   (*conshdlrdata)->sallconsanddatas = 0;
503  	
504  	   SCIPfreeBlockMemory(scip, conshdlrdata);
505  	
506  	   return SCIP_OKAY;
507  	}
508  	
509  	/** gets number of variables in linear constraint */
510  	static
511  	SCIP_RETCODE getLinearConsNVars(
512  	   SCIP*const            scip,               /**< SCIP data structure */
513  	   SCIP_CONS*const       cons,               /**< linear constraint */
514  	   SCIP_LINEARCONSTYPE const constype,       /**< linear constraint type */
515  	   int*const             nvars               /**< pointer to store number variables of linear constraint */
516  	   )
517  	{
518  	   assert(scip != NULL);
519  	   assert(cons != NULL);
520  	   assert(nvars != NULL);
521  	
522  	   /* determine for each special linear constranit all variables and coefficients */
523  	   switch( constype )
524  	   {
525  	   case SCIP_LINEARCONSTYPE_LINEAR:
526  	      *nvars = SCIPgetNVarsLinear(scip, cons);
527  	      break;
528  	   case SCIP_LINEARCONSTYPE_LOGICOR:
529  	      *nvars = SCIPgetNVarsLogicor(scip, cons);
530  	      break;
531  	   case SCIP_LINEARCONSTYPE_KNAPSACK:
532  	      *nvars = SCIPgetNVarsKnapsack(scip, cons);
533  	      break;
534  	   case SCIP_LINEARCONSTYPE_SETPPC:
535  	      *nvars = SCIPgetNVarsSetppc(scip, cons);
536  	      break;
537  	#ifdef WITHEQKNAPSACK
538  	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
539  	      *nvars = SCIPgetNVarsEQKnapsack(scip, cons);
540  	      break;
541  	#endif
542  	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
543  	   default:
544  	      SCIPerrorMessage("unknown linear constraint type\n");
545  	      return SCIP_INVALIDDATA;
546  	   }
547  	
548  	   return SCIP_OKAY;
549  	}
550  	
551  	
552  	/** gets sides of linear constraint */
553  	static
554  	SCIP_RETCODE getLinearConsSides(
555  	   SCIP*const            scip,               /**< SCIP data structure */
556  	   SCIP_CONS*const       cons,               /**< linear constraint */
557  	   SCIP_LINEARCONSTYPE const constype,       /**< linear constraint type */
558  	   SCIP_Real*const       lhs,                /**< pointer to store left hand side of linear constraint */
559  	   SCIP_Real*const       rhs                 /**< pointer to store right hand side of linear constraint */
560  	   )
561  	{
562  	   SCIP_SETPPCTYPE type;
563  	
564  	   switch( constype )
565  	   {
566  	   case SCIP_LINEARCONSTYPE_LINEAR:
567  	      *lhs = SCIPgetLhsLinear(scip, cons);
568  	      *rhs = SCIPgetRhsLinear(scip, cons);
569  	      break;
570  	   case SCIP_LINEARCONSTYPE_LOGICOR:
571  	      *lhs = 1.0;
572  	      *rhs = SCIPinfinity(scip);
573  	      break;
574  	   case SCIP_LINEARCONSTYPE_KNAPSACK:
575  	      *lhs = -SCIPinfinity(scip);
576  	      *rhs = SCIPgetCapacityKnapsack(scip, cons);
577  	      break;
578  	   case SCIP_LINEARCONSTYPE_SETPPC:
579  	      type = SCIPgetTypeSetppc(scip, cons);
580  	
581  	      switch( type )
582  	      {
583  	      case SCIP_SETPPCTYPE_PARTITIONING:
584  	         *lhs = 1.0;
585  	         *rhs = 1.0;
586  	         break;
587  	      case SCIP_SETPPCTYPE_PACKING:
588  	         *lhs = -SCIPinfinity(scip);
589  	         *rhs = 1.0;
590  	         break;
591  	      case SCIP_SETPPCTYPE_COVERING:
592  	         *lhs = 1.0;
593  	         *rhs = SCIPinfinity(scip);
594  	         break;
595  	      default:
596  	         SCIPerrorMessage("unknown setppc type\n");
597  	         return SCIP_INVALIDDATA;
598  	      }
599  	      break;
600  	#ifdef WITHEQKNAPSACK
601  	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
602  	      *lhs = SCIPgetCapacityEQKnapsack(scip, cons);
603  	      *rhs = *lhs;
604  	      break;
605  	#endif
606  	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
607  	   default:
608  	      SCIPerrorMessage("unknown linear constraint type\n");
609  	      return SCIP_INVALIDDATA;
610  	   }
611  	
612  	   return SCIP_OKAY;
613  	}
614  	
615  	/** gets variables and coefficients of linear constraint */
616  	static
617  	SCIP_RETCODE getLinearConsVarsData(
618  	   SCIP*const            scip,               /**< SCIP data structure */
619  	   SCIP_CONS*const       cons,               /**< linear constraint */
620  	   SCIP_LINEARCONSTYPE const constype,       /**< linear constraint type */
621  	   SCIP_VAR**const       vars,               /**< array to store sorted (after indices) variables of linear constraint */
622  	   SCIP_Real*const       coefs,              /**< array to store coefficient of linear constraint, or NULL */
623  	   int*const             nvars               /**< pointer to store number variables of linear constraint */
624  	   )
625  	{
626  	   SCIP_VAR** linvars;
627  	   int v;
628  	
629  	   assert(scip != NULL);
630  	   assert(cons != NULL);
631  	   assert(vars != NULL);
632  	   assert(nvars != NULL);
633  	
634  	   /* determine for each special linear constrait all variables and coefficients */
635  	   switch( constype )
636  	   {
637  	   case SCIP_LINEARCONSTYPE_LINEAR:
638  	   {
639  	      SCIP_Real* lincoefs;
640  	
641  	      *nvars = SCIPgetNVarsLinear(scip, cons);
642  	      linvars = SCIPgetVarsLinear(scip, cons);
643  	
644  	      if( coefs != NULL )
645  	      {
646  	         lincoefs = SCIPgetValsLinear(scip, cons);
647  	
648  	         for( v = 0; v < *nvars; ++v )
649  	         {
650  	            vars[v] = linvars[v];
651  	            coefs[v] = lincoefs[v];
652  	         }
653  	      }
654  	      else
655  	      {
656  	         for( v = 0; v < *nvars; ++v )
657  	            vars[v] = linvars[v];
658  	      }
659  	
660  	      break;
661  	   }
662  	   case SCIP_LINEARCONSTYPE_LOGICOR:
663  	      *nvars = SCIPgetNVarsLogicor(scip, cons);
664  	      linvars = SCIPgetVarsLogicor(scip, cons);
665  	      assert( linvars != NULL );
666  	
667  	      if( coefs != NULL )
668  	      {
669  	         for( v = 0; v < *nvars; ++v )
670  	         {
671  	            vars[v] = linvars[v];
672  	            coefs[v] = 1.0;
673  	         }
674  	      }
675  	      else
676  	      {
677  	         for( v = 0; v < *nvars; ++v )
678  	            vars[v] = linvars[v];
679  	      }
680  	
681  	      break;
682  	   case SCIP_LINEARCONSTYPE_KNAPSACK:
683  	   {
684  	      SCIP_Longint* weights;
685  	
686  	      *nvars = SCIPgetNVarsKnapsack(scip, cons);
687  	      linvars = SCIPgetVarsKnapsack(scip, cons);
688  	      assert( linvars != NULL );
689  	
690  	      if( coefs != NULL )
691  	      {
692  	         weights = SCIPgetWeightsKnapsack(scip, cons);
693  	
694  	         for( v = 0; v < *nvars; ++v )
695  	         {
696  	            vars[v] = linvars[v];
697  	            coefs[v] = (SCIP_Real) weights[v];
698  	         }
699  	      }
700  	      else
701  	      {
702  	         for( v = 0; v < *nvars; ++v )
703  	            vars[v] = linvars[v];
704  	      }
705  	
706  	      break;
707  	   }
708  	   case SCIP_LINEARCONSTYPE_SETPPC:
709  	      *nvars = SCIPgetNVarsSetppc(scip, cons);
710  	      linvars = SCIPgetVarsSetppc(scip, cons);
711  	      assert( linvars != NULL );
712  	
713  	      if( coefs != NULL )
714  	      {
715  		 for( v = 0; v < *nvars; ++v )
716  		 {
717  		    vars[v] = linvars[v];
718  		    coefs[v] = 1.0;
719  		 }
720  	      }
721  	      else
722  	      {
723  		 for( v = 0; v < *nvars; ++v )
724  		    vars[v] = linvars[v];
725  	      }
726  	
727  	      break;
728  	#ifdef WITHEQKNAPSACK
729  	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
730  	   {
731  	      SCIP_Longint* weights;
732  	
733  	      *nvars = SCIPgetNVarsEQKnapsack(scip, cons);
734  	      linvars = SCIPgetVarsEQKnapsack(scip, cons);
735  	      assert( linvars != NULL );
736  	
737  	      if( coefs != NULL )
738  	      {
739  		 weights = SCIPgetWeightsEQKnapsack(scip, cons);
740  	
741  		 for( v = 0; v < *nvars; ++v )
742  		 {
743  		    vars[v] = linvars[v];
744  		    coefs[v] = (SCIP_Real) weights[v];
745  		 }
746  	      }
747  	      else
748  	      {
749  		 for( v = 0; v < *nvars; ++v )
750  		    vars[v] = linvars[v];
751  	      }
752  	
753  	      break;
754  	   }
755  	#endif
756  	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
757  	   default:
758  	      SCIPerrorMessage("unknown linear constraint type\n");
759  	      return SCIP_INVALIDDATA;
760  	   }
761  	
762  	   /* sort variables after indices */
763  	   if( coefs != NULL )
764  	   {
765  	      SCIPsortPtrReal((void**)vars, coefs, SCIPvarComp, *nvars);
766  	   }
767  	   else
768  	   {
769  	      SCIPsortPtr((void**)vars, SCIPvarComp, *nvars);
770  	   }
771  	
772  	   return SCIP_OKAY;
773  	}
774  	
775  	/** calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
776  	 *  'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
777  	 *  afterwards
778  	 */
779  	static
780  	SCIP_RETCODE getLinVarsAndAndRess(
781  	   SCIP*const            scip,               /**< SCIP data structure */
782  	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
783  	   SCIP_VAR**const       vars,               /**< all variables of linear constraint */
784  	   SCIP_Real*const       coefs,              /**< all coefficients of linear constraint, or NULL */
785  	   int const             nvars,              /**< number of all variables of linear constraint */
786  	   SCIP_VAR**const       linvars,            /**< array to store not and-resultant variables of linear constraint, or NULL */
787  	   SCIP_Real*const       lincoefs,           /**< array to store coefficients of not and-resultant variables of linear
788  	                                              *   constraint, or NULL */
789  	   int*const             nlinvars,           /**< pointer to store number of not and-resultant variables, or NULL */
790  	   SCIP_VAR**const       andress,            /**< array to store and-resultant variables of linear constraint, or NULL */
791  	   SCIP_Real*const       andcoefs,           /**< array to store coefficients of and-resultant variables of linear
792  	                                              *   constraint, or NULL */
793  	   SCIP_Bool*const       andnegs,            /**< array to store negation status of and-resultant variables of linear
794  	                                              *   constraint, or NULL */
795  	   int*const             nandress            /**< pointer to store number of and-resultant variables, or NULL */
796  	   )
797  	{
798  	   SCIP_CONSHDLR* conshdlr;
799  	   SCIP_CONSHDLRDATA* conshdlrdata;
800  	   int v;
801  	
802  	   assert(scip != NULL);
803  	   assert(cons != NULL);
804  	   assert(vars != NULL);
805  	   assert((linvars != NULL) == (nlinvars != NULL));
806  	   assert((andress == NULL) || (nandress != NULL));
807  	   assert((andcoefs != NULL) == (andnegs != NULL));
808  	   assert((coefs != NULL) == ((lincoefs != NULL) || (andcoefs != NULL)));
809  	   assert(linvars != NULL || andress != NULL);
810  	
811  	   if( nlinvars != NULL )
812  	      *nlinvars = 0;
813  	   if( nandress != NULL )
814  	      *nandress = 0;
815  	
816  	   conshdlr = SCIPconsGetHdlr(cons);
817  	   assert(conshdlr != NULL);
818  	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
819  	   assert(conshdlrdata != NULL);
820  	   assert(conshdlrdata->hashmap != NULL);
821  	
822  	   /* @note it is necessary that the linear constraint is merged (not needed for negated variables) and sorted after
823  	    *       indices
824  	    */
825  	
826  	#ifndef NDEBUG
827  	   /* check that old variables are sorted */
828  	   for( v = nvars - 1; v > 0; --v )
829  	      assert(SCIPvarGetIndex(vars[v]) >= SCIPvarGetIndex(vars[v - 1]));
830  	#endif
831  	
832  	   /* split variables into original and artificial variables */
833  	   for( v = 0; v < nvars; ++v )
834  	   {
835  	      SCIP_Bool hashmapentryexists;
836  	      SCIP_VAR* hashmapvar;
837  	
838  	      assert(vars[v] != NULL);
839  	
840  	      hashmapentryexists = SCIPhashmapExists(conshdlrdata->hashmap, (void*)(vars[v]));
841  	
842  	      if( !hashmapentryexists && SCIPvarIsNegated(vars[v]) )
843  	      {
844  	         hashmapvar = SCIPvarGetNegationVar(vars[v]);
845  	         hashmapentryexists = SCIPhashmapExists(conshdlrdata->hashmap, (void*)(hashmapvar));
846  	      }
847  	      else
848  	         hashmapvar = vars[v];
849  	
850  	      /* if and resultant is not a resultant anymore (meaning the corresponding and-constraint was deleted/upgraded),
851  	       * correct the flag and count this variable as normal linear variable
852  	       */
853  	      if( hashmapentryexists )
854  	      {
855  		 if( !SCIPconsIsOriginal(cons) )
856  		 {
857  	            CONSANDDATA* consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)(hashmapvar));
858  	            assert(consanddata != NULL);
859  	
860  		    hashmapentryexists = (consanddata->istransformed);
861  	
862  		    if( hashmapentryexists )
863  		    {
864  		       assert(consanddata->cons != NULL);
865  		       hashmapentryexists = !SCIPconsIsDeleted(consanddata->cons);
866  		    }
867  		 }
868  	      }
869  	
870  	      if( !hashmapentryexists && linvars != NULL && nlinvars != NULL )
871  	      {
872  	         linvars[*nlinvars] = vars[v];
873  		 if( lincoefs != NULL )
874  		 {
875  		    assert(coefs != NULL);
876  		    lincoefs[*nlinvars] = coefs[v];
877  		 }
878  	         ++(*nlinvars);
879  	      }
880  	      else if( hashmapentryexists && nandress != NULL )
881  	      {
882  	         if( andress != NULL )
883  	         {
884  	            andress[*nandress] = hashmapvar;
885  	
886  	            if( andcoefs != NULL )
887  	            {
888  	               assert(andnegs != NULL);
889  	               assert(coefs != NULL);
890  	               andcoefs[*nandress] = coefs[v];
891  	               andnegs[*nandress] = (vars[v] != hashmapvar);
892  	            }
893  	         }
894  	         ++(*nandress);
895  	      }
896  	   }
897  	
898  	   /* @todo try to avoid sorting here */
899  	   if( andress != NULL && nandress != NULL )
900  	   {
901  	      /* sort and resultants by their variable index */
902  	      if( andcoefs != NULL )
903  	      {
904  	         assert(andnegs != NULL);
905  	         SCIPsortPtrRealBool((void**)andress, andcoefs, andnegs, SCIPvarComp, *nandress);
906  	      }
907  	      else
908  	      {
909  	         SCIPsortPtr((void**)andress, SCIPvarComp, *nandress);
910  	      }
911  	   }
912  	
913  	   return SCIP_OKAY;
914  	}
915  	
916  	
917  	#ifdef CHECK_CONSISTENCY
918  	/** check constraint consistency */
919  	static
920  	void checkConsConsistency(
921  	   SCIP*const            scip,               /**< SCIP data structure */
922  	   SCIP_CONS*const       cons                /**< pseudoboolean constraint */
923  	   )
924  	{
925  	   SCIP_CONSDATA* consdata;
926  	   SCIP_VAR** vars;
927  	   SCIP_Real* coefs;
928  	   int nvars;
929  	   SCIP_VAR** linvars;
930  	   SCIP_Real* lincoefs;
931  	   int nlinvars;
932  	   SCIP_VAR** andress;
933  	   SCIP_Real* andcoefs;
934  	   SCIP_Bool* andnegs;
935  	   int nandress;
936  	   SCIP_Bool* alreadyfound;
937  	   SCIP_VAR* res;
938  	   int c;
939  	   int v;
940  	   SCIP_Real newlhs;
941  	   SCIP_Real newrhs;
942  	
943  	   assert(scip != NULL);
944  	   assert(cons != NULL);
945  	
946  	   if( SCIPgetStage(scip) == SCIP_STAGE_FREETRANS )
947  	      return;
948  	
949  	   consdata = SCIPconsGetData(cons);
950  	   assert(consdata != NULL);
951  	
952  	   /* check standard pointers and sizes */
953  	   assert(consdata->lincons != NULL);
954  	   assert(!SCIPconsIsDeleted(consdata->lincons));
955  	   assert(consdata->linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
956  	   assert(consdata->consanddatas != NULL);
957  	   assert(consdata->nconsanddatas > 0);
958  	   assert(consdata->nconsanddatas <= consdata->sconsanddatas);
959  	
960  	   /* get sides of linear constraint */
961  	   SCIP_CALL_ABORT( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &newlhs, &newrhs) );
962  	   assert(!SCIPisInfinity(scip, newlhs));
963  	   assert(!SCIPisInfinity(scip, -newrhs));
964  	   assert(SCIPisLE(scip, newlhs, newrhs));
965  	   assert(SCIPisEQ(scip, newrhs, consdata->rhs) || SCIPisEQ(scip, newrhs, -consdata->lhs));
966  	   assert(SCIPisEQ(scip, newlhs, consdata->lhs) || SCIPisEQ(scip, newlhs, -consdata->rhs));
967  	
968  	   /* check number of linear variables */
969  	   SCIP_CALL_ABORT( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
970  	   assert(nvars == consdata->nlinvars + consdata->nconsanddatas);
971  	
972  	   /* get temporary memory */
973  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &vars, nvars) );
974  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &coefs, nvars) );
975  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &linvars, nvars) );
976  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &lincoefs, nvars) );
977  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &andress, nvars) );
978  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &andcoefs, nvars) );
979  	   SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &andnegs, nvars) );
980  	   SCIP_CALL_ABORT( SCIPallocClearBufferArray(scip, &alreadyfound, nvars) );
981  	
982  	   /* get variables and coefficients */
983  	   SCIP_CALL_ABORT( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
984  	   assert(nvars == 0 || (coefs != NULL));
985  	
986  	   /* calculate all not artificial linear variables and all artificial and-resultants */
987  	   SCIP_CALL_ABORT( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
988  	         andress, andcoefs, andnegs, &nandress) );
989  	   assert(nlinvars == consdata->nlinvars);
990  	   assert(nandress == consdata->nconsanddatas);
991  	
992  	   for( v = nandress - 1; v >= 0; --v )
993  	   {
994  	      SCIP_VAR* andresultant = andress[v];
995  	      int nfound = 0;
996  	
997  	      for( c = consdata->nconsanddatas - 1; c >= 0; --c )
998  	      {
999  	         assert(consdata->consanddatas[c] != NULL);
1000 	         if( consdata->consanddatas[c]->cons != NULL )
1001 	         {
1002 	            res = SCIPgetResultantAnd(scip, consdata->consanddatas[c]->cons);
1003 	            assert(res != NULL);
1004 	
1005 	            if( res == andresultant && consdata->andnegs[c] == andnegs[v] && consdata->andcoefs[c] == andcoefs[v] )
1006 	            {
1007 	               /* resultant should be either active or a negated variable of an active one */
1008 	               assert(SCIPvarIsActive(res) || (SCIPvarIsNegated(res) && SCIPvarIsActive(SCIPvarGetNegationVar(res))));
1009 	               assert(!alreadyfound[c]);
1010 	
1011 	               /* all and-resultants should be merged, so it is only allowed that each variable exists one time */
1012 	               alreadyfound[c] = TRUE;
1013 	               ++nfound;
1014 	               break;
1015 	            }
1016 	         }
1017 	      }
1018 	      assert(nfound == 1);
1019 	   }
1020 	
1021 	   for( c = consdata->nconsanddatas - 1; c >= 0; --c )
1022 	   {
1023 	      assert(alreadyfound[c]);
1024 	   }
1025 	
1026 	   /* free temporary memory */
1027 	   SCIPfreeBufferArray(scip, &alreadyfound);
1028 	   SCIPfreeBufferArray(scip, &andnegs);
1029 	   SCIPfreeBufferArray(scip, &andcoefs);
1030 	   SCIPfreeBufferArray(scip, &andress);
1031 	   SCIPfreeBufferArray(scip, &lincoefs);
1032 	   SCIPfreeBufferArray(scip, &linvars);
1033 	   SCIPfreeBufferArray(scip, &coefs);
1034 	   SCIPfreeBufferArray(scip, &vars);
1035 	}
1036 	#else
1037 	#define checkConsConsistency(scip, cons) /**/
1038 	#endif
1039 	
1040 	
1041 	/** transforming transformed consanddata object back to original space, if an corresponding original constraint exists,
1042 	 *  also clearing all transformed data, i.e. releasing transformed variables
1043 	 */
1044 	static
1045 	SCIP_RETCODE transformToOrig(
1046 	   SCIP*const            scip,               /**< SCIP data structure */
1047 	   CONSANDDATA*          consanddata,        /**< consanddata object */
1048 	   SCIP_CONSHDLRDATA*    conshdlrdata        /**< constraint handler data */
1049 	   )
1050 	{
1051 	   SCIP_VAR** tmpvars;
1052 	   SCIP_Bool origdata;
1053 	   int ntmpvars;
1054 	   int v;
1055 	
1056 	   assert(scip != NULL);
1057 	   assert(consanddata != NULL);
1058 	   assert(conshdlrdata != NULL);
1059 	
1060 	   origdata = TRUE;
1061 	
1062 	   tmpvars = consanddata->vars;
1063 	   ntmpvars = consanddata->nvars;
1064 	
1065 	   /* release all transformed variables */
1066 	   for( v = ntmpvars - 1; v >= 0; --v )
1067 	   {
1068 	      assert(tmpvars[v] != NULL);
1069 	      if( SCIPvarIsTransformed(tmpvars[v]) )
1070 	      {
1071 	         SCIP_CALL( SCIPreleaseVar(scip, &tmpvars[v]) );
1072 	         origdata = FALSE;
1073 	      }
1074 	   }
1075 	
1076 	   tmpvars = consanddata->newvars;
1077 	   ntmpvars = consanddata->nnewvars;
1078 	
1079 	   /* release all variables */
1080 	   for( v = ntmpvars - 1; v >= 0; --v )
1081 	   {
1082 	      assert(tmpvars[v] != NULL);
1083 	      if( SCIPvarIsTransformed(tmpvars[v]) )
1084 	      {
1085 	         SCIP_CALL( SCIPreleaseVar(scip, &tmpvars[v]) );
1086 	         origdata = FALSE;
1087 	      }
1088 	   }
1089 	
1090 	   /* reinstall original data */
1091 	   if( !origdata || consanddata->nvars == 0 )
1092 	   {
1093 	      SCIPfreeBlockMemoryArrayNull(scip, &(consanddata->vars), consanddata->svars);
1094 	      SCIPfreeBlockMemoryArrayNull(scip, &(consanddata->newvars), consanddata->snewvars);
1095 	
1096 	      consanddata->nuses = 0;
1097 	      consanddata->nvars = 0;
1098 	      consanddata->svars = 0;
1099 	      consanddata->nnewvars = 0;
1100 	      consanddata->snewvars = 0;
1101 	      consanddata->istransformed = FALSE;
1102 	
1103 	      if( consanddata->noriguses > 0 )
1104 	      {
1105 	         assert(consanddata->origcons != NULL);
1106 	         assert(consanddata->isoriginal);
1107 	
1108 	         assert(SCIPgetNVarsAnd(scip, consanddata->origcons) > 0);
1109 	         assert(SCIPgetVarsAnd(scip, consanddata->origcons) != NULL);
1110 	         consanddata->nvars = SCIPgetNVarsAnd(scip, consanddata->origcons);
1111 	         consanddata->svars = consanddata->nvars;
1112 	
1113 	         if( consanddata->nvars > 0 )
1114 	         {
1115 	            SCIP_VAR** andvars = SCIPgetVarsAnd(scip, consanddata->origcons);
1116 	
1117 	            SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(consanddata->vars), andvars, consanddata->nvars) );
1118 	
1119 	            /* sort variables */
1120 	            SCIPsortPtr((void**)(consanddata->vars), SCIPvarComp, consanddata->nvars);
1121 	         }
1122 	
1123 	         /* check that the hash map and tabkle are still having all information */
1124 	         if( conshdlrdata->inithashmapandtable )
1125 	         {
1126 	            assert(conshdlrdata->hashmap != NULL);
1127 	            assert(conshdlrdata->hashtable != NULL);
1128 	            assert(SCIPgetResultantAnd(scip, consanddata->origcons) != NULL);
1129 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
1130 	            assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1131 	            assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1132 	            assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1133 	         }
1134 	      }
1135 	      else
1136 	         assert(consanddata->origcons == NULL);
1137 	   }
1138 	   else
1139 	   {
1140 	      assert(consanddata->nuses == 0);
1141 	      assert(consanddata->nnewvars == 0);
1142 	      assert(consanddata->snewvars == 0);
1143 	      assert(consanddata->newvars == NULL);
1144 	
1145 	      consanddata->istransformed = FALSE;
1146 	
1147 	      if( consanddata->noriguses > 0 )
1148 	      {
1149 	         assert(consanddata->origcons != NULL);
1150 	         assert(consanddata->nvars > 0);
1151 	         assert(consanddata->svars > 0);
1152 	         assert(consanddata->vars != NULL);
1153 	         assert(consanddata->isoriginal);
1154 	
1155 	         /* check that the hash map and tabkle are still having all information */
1156 	         if( conshdlrdata->inithashmapandtable )
1157 	         {
1158 	            assert(conshdlrdata->hashmap != NULL);
1159 	            assert(conshdlrdata->hashtable != NULL);
1160 	            assert(SCIPgetResultantAnd(scip, consanddata->origcons) != NULL);
1161 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
1162 	            assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1163 	            assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1164 	            assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1165 	         }
1166 	      }
1167 	   }
1168 	
1169 	   return SCIP_OKAY;
1170 	}
1171 	
1172 	
1173 	
1174 	/** creates a pseudo boolean constraint data */
1175 	static
1176 	SCIP_RETCODE consdataCreate(
1177 	   SCIP*const            scip,               /**< SCIP data structure */
1178 	   SCIP_CONSHDLR*const   conshdlr,           /**< pseudoboolean constraint handler */
1179 	   SCIP_CONSDATA**       consdata,           /**< pointer to linear constraint data */
1180 	   SCIP_CONS*const       lincons,            /**< linear constraint with artificial and-resultants representing this pseudoboolean constraint */
1181 	   SCIP_LINEARCONSTYPE const linconstype,    /**< type of linear constraint */
1182 	   SCIP_CONS**const      andconss,           /**< array of and-constraints which occur in this pseudoboolean constraint */
1183 	   SCIP_Real*const       andcoefs,           /**< coefficients of and-constraints */
1184 	   SCIP_Bool*const       andnegs,            /**< negation status of and-constraints (or NULL, if no negated resultants) */
1185 	   int const             nandconss,          /**< number of and-constraints */
1186 	   SCIP_VAR*const        indvar,             /**< indicator variable if it's a soft constraint, or NULL */
1187 	   SCIP_Real const       weight,             /**< weight of the soft constraint, if it is one */
1188 	   SCIP_Bool const       issoftcons,         /**< is this a soft constraint */
1189 	   SCIP_VAR* const       intvar,             /**< a artificial variable which was added only for the objective function,
1190 	                                              *   if this variable is not NULL this constraint (without this integer
1191 	                                              *   variable) describes the objective function */
1192 	   SCIP_Real             lhs,                /**< left hand side of row */
1193 	   SCIP_Real             rhs,                /**< right hand side of row */
1194 	   SCIP_Bool             check,              /**< is the new constraint a check constraint? */
1195 	   SCIP_Bool             transforming        /**< are we called by CONSTRANS */
1196 	   )
1197 	{
1198 	   SCIP_Bool transformed;
1199 	   int nvars;
1200 	
1201 	   assert(scip != NULL);
1202 	   assert(conshdlr != NULL);
1203 	   assert(consdata != NULL);
1204 	   assert(lincons != NULL && linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
1205 	   assert(nandconss == 0 || (andconss != NULL && andcoefs != NULL));
1206 	   assert(!issoftcons || (!SCIPisZero(scip, weight) && indvar != NULL));
1207 	
1208 	   /* adjust right hand side */
1209 	   if( SCIPisInfinity(scip, rhs) )
1210 	      rhs = SCIPinfinity(scip);
1211 	   else if( SCIPisInfinity(scip, -rhs) )
1212 	      rhs = -SCIPinfinity(scip);
1213 	
1214 	   /* adjust left hand side */
1215 	   if( SCIPisInfinity(scip, -lhs) )
1216 	      lhs = -SCIPinfinity(scip);
1217 	   else if( SCIPisInfinity(scip, lhs) )
1218 	      lhs = SCIPinfinity(scip);
1219 	
1220 	   /* check left and right side */
1221 	   if( SCIPisGT(scip, lhs, rhs) )
1222 	   {
1223 	      SCIPerrorMessage("left hand side of pseudo boolean constraint greater than right hand side\n");
1224 	      SCIPerrorMessage(" -> lhs=%g, rhs=%g\n", lhs, rhs);
1225 	      return SCIP_INVALIDDATA;
1226 	   }
1227 	
1228 	   transformed = SCIPisTransformed(scip);
1229 	
1230 	   /* allocate memory for the constraint data */
1231 	   SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
1232 	
1233 	   /* initialize the weights for soft constraints */
1234 	   (*consdata)->issoftcons = issoftcons;
1235 	   if( issoftcons )
1236 	   {
1237 	      (*consdata)->weight = weight;
1238 	      if( transformed )
1239 	      {
1240 	         SCIP_CALL( SCIPgetTransformedVar(scip, indvar, &((*consdata)->indvar)) );
1241 	      }
1242 	      else
1243 	         (*consdata)->indvar = indvar;
1244 	   }
1245 	   else
1246 	      (*consdata)->indvar = NULL;
1247 	
1248 	   /* copy artificial integer variable if it exist */
1249 	   if( intvar != NULL )
1250 	   {
1251 	      if( transformed )
1252 	      {
1253 	         SCIP_CALL( SCIPgetTransformedVar(scip, intvar, &((*consdata)->intvar)) );
1254 	      }
1255 	      else
1256 	         (*consdata)->intvar = intvar;
1257 	   }
1258 	   else
1259 	      (*consdata)->intvar = NULL;
1260 	
1261 	   /* copy linear constraint */
1262 	   (*consdata)->lincons = lincons;
1263 	   (*consdata)->linconstype = linconstype;
1264 	
1265 	   /* get transformed linear constraint and capture it if necessary */
1266 	   if( transforming )
1267 	   {
1268 	      /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1269 	       * SCIPtransformCons()
1270 	       */
1271 	      SCIP_CALL( SCIPtransformCons(scip, (*consdata)->lincons, &((*consdata)->lincons)) );
1272 	      assert((*consdata)->lincons != NULL);
1273 	   }
1274 	
1275 	   if( transforming || transformed )
1276 	   {
1277 	      assert(SCIPconsIsTransformed((*consdata)->lincons));
1278 	
1279 	      /* we want to check all necessary transformed linear constraints */
1280 	      SCIP_CALL( SCIPsetConsChecked(scip, (*consdata)->lincons, check) );
1281 	   }
1282 	
1283 	   /* get number of non-linear terms in pseudoboolean constraint */
1284 	   SCIP_CALL( getLinearConsNVars(scip, (*consdata)->lincons, (*consdata)->linconstype, &nvars) );
1285 	   (*consdata)->nlinvars = nvars - nandconss;
1286 	
1287 	   /* copy and-constraints */
1288 	   if( nandconss > 0 )
1289 	   {
1290 	      SCIP_CONSHDLRDATA* conshdlrdata;
1291 	      SCIP_VAR** andress;
1292 	      int c;
1293 	
1294 	      SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*consdata)->consanddatas), nandconss) );
1295 	      SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &((*consdata)->andcoefs), andcoefs, nandconss) );
1296 	      if( andnegs != NULL )
1297 	      {
1298 	         SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &((*consdata)->andnegs), andnegs, nandconss) );
1299 	      }
1300 	      else
1301 	      {
1302 	         SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &((*consdata)->andnegs), nandconss) );
1303 	      }
1304 	      (*consdata)->nconsanddatas = nandconss;
1305 	      (*consdata)->sconsanddatas = nandconss;
1306 	
1307 	      /* allocate temporary memory */
1308 	      SCIP_CALL( SCIPallocBufferArray(scip, &andress, nandconss) );
1309 	
1310 	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
1311 	      assert(conshdlrdata != NULL);
1312 	      assert(conshdlrdata->hashmap != NULL);
1313 	
1314 	      /* get all and-resultants for sorting */
1315 	      for( c = nandconss - 1; c >= 0; --c )
1316 	      {
1317 	         assert(andconss[c] != NULL);
1318 	
1319 	         andress[c] = SCIPgetResultantAnd(scip, andconss[c]);
1320 	         assert(andress[c] != NULL);
1321 	
1322 	         (*consdata)->consanddatas[c] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[c]);
1323 	         assert((*consdata)->consanddatas[c] != NULL);
1324 	         assert((*consdata)->consanddatas[c]->origcons == andconss[c] || (*consdata)->consanddatas[c]->cons == andconss[c]);
1325 	
1326 	         if( transforming )
1327 	         {
1328 	            /* if we perform a new transformation, we need to capture the transformed constraint */
1329 	            if( (*consdata)->consanddatas[c]->origcons != NULL && (*consdata)->consanddatas[c]->cons == NULL )
1330 	            {
1331 	               SCIP_VAR** vars;
1332 	               int ncvars;
1333 	               int v;
1334 	
1335 	               /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1336 	                * SCIPtransformCons()
1337 	                */
1338 	               SCIP_CALL( SCIPtransformCons(scip, (*consdata)->consanddatas[c]->origcons, &((*consdata)->consanddatas[c]->cons)) );
1339 	               assert((*consdata)->consanddatas[c]->cons != NULL);
1340 	               assert((*consdata)->consanddatas[c]->newvars == NULL);
1341 	               assert((*consdata)->consanddatas[c]->isoriginal);
1342 	
1343 	               (*consdata)->consanddatas[c]->istransformed = TRUE;
1344 	
1345 	               vars = (*consdata)->consanddatas[c]->vars;
1346 	               ncvars = (*consdata)->consanddatas[c]->nvars;
1347 	               assert(vars != NULL || ncvars == 0);
1348 	
1349 	               /* get transformed variables */
1350 	               SCIP_CALL( SCIPgetTransformedVars(scip, ncvars, vars, vars) );
1351 	
1352 	               /* resort variables in transformed problem, because the order might change while tranforming */
1353 	               SCIPsortPtr((void**)vars, SCIPvarComp, ncvars);
1354 	
1355 	               /* capture all transformed variables */
1356 	               for( v = ncvars - 1; v >= 0; --v )
1357 	               {
1358 	                  SCIP_CALL( SCIPcaptureVar(scip, vars[v]) ); /*lint !e613*/
1359 	               }
1360 	            }
1361 	            else if( (*consdata)->consanddatas[c]->cons != NULL )
1362 	               assert((*consdata)->consanddatas[c]->istransformed);
1363 	
1364 	            ++((*consdata)->consanddatas[c]->nuses);
1365 	         }
1366 	         else if( transformed )
1367 	         {
1368 	            assert((*consdata)->consanddatas[c]->cons == andconss[c]);
1369 	            assert(SCIPconsIsTransformed(andconss[c]));
1370 	            assert((*consdata)->consanddatas[c]->istransformed);
1371 	         }
1372 	      }
1373 	
1374 	      /* sort and-constraints after indices of corresponding and-resultants */
1375 	      SCIPsortPtrPtrRealBool((void**)andress, (void**)((*consdata)->consanddatas), (*consdata)->andcoefs, (*consdata)->andnegs, SCIPvarComp, nandconss);
1376 	
1377 	      /* free temporary memory */
1378 	      SCIPfreeBufferArray(scip, &andress);
1379 	   }
1380 	   else
1381 	   {
1382 	      (*consdata)->consanddatas = NULL;
1383 	      (*consdata)->andcoefs = NULL;
1384 	      (*consdata)->andnegs = NULL;
1385 	      (*consdata)->nconsanddatas = 0;
1386 	      (*consdata)->sconsanddatas = 0;
1387 	   }
1388 	
1389 	   /* copy left and right hand side */
1390 	   (*consdata)->lhs = lhs;
1391 	   (*consdata)->rhs = rhs;
1392 	
1393 	   (*consdata)->changed = TRUE;
1394 	   (*consdata)->propagated = FALSE;
1395 	   (*consdata)->presolved = FALSE;
1396 	   (*consdata)->cliquesadded = FALSE;
1397 	   (*consdata)->upgradetried = TRUE;
1398 	
1399 	   /* count number of used consanddata objects in original problem */
1400 	   if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
1401 	   {
1402 	      SCIP_CONSHDLRDATA* conshdlrdata;
1403 	      conshdlrdata = SCIPconshdlrGetData(conshdlr);
1404 	      assert(conshdlrdata != NULL);
1405 	
1406 	      conshdlrdata->noriguses += (*consdata)->nconsanddatas;
1407 	   }
1408 	
1409 	   return SCIP_OKAY;
1410 	}
1411 	
1412 	/** free a pseudo boolean constraint data */
1413 	static
1414 	SCIP_RETCODE consdataFree(
1415 	   SCIP*const            scip,               /**< SCIP data structure */
1416 	   SCIP_CONSDATA**       consdata,           /**< pointer to linear constraint data */
1417 	   SCIP_Bool             isorig,             /**< are we freeing an original constraint? */
1418 	   SCIP_CONSHDLRDATA*    conshdlrdata        /**< constraint handler data */
1419 	   )
1420 	{
1421 	   CONSANDDATA** consanddatas;
1422 	   int nconsanddatas;
1423 	   int c;
1424 	
1425 	   assert(scip != NULL);
1426 	   assert(consdata != NULL);
1427 	   assert(*consdata != NULL);
1428 	   assert((*consdata)->nconsanddatas == 0 || (*consdata)->consanddatas != NULL);
1429 	   assert(conshdlrdata != NULL);
1430 	
1431 	   /* release linear constraint */
1432 	   if( (*consdata)->lincons != NULL )
1433 	   {
1434 	      SCIP_CALL( SCIPreleaseCons(scip, &((*consdata)->lincons)) );
1435 	   }
1436 	
1437 	   nconsanddatas = (*consdata)->nconsanddatas;
1438 	   consanddatas = (*consdata)->consanddatas;
1439 	
1440 	   /* count down uses and if necessary release constraints and delete data from hashtable and -map */
1441 	   for( c = nconsanddatas - 1; c >= 0; --c )
1442 	   {
1443 	      assert((consanddatas[c]->origcons == NULL) == (consanddatas[c]->noriguses == 0));
1444 	      assert((consanddatas[c]->cons == NULL) == (consanddatas[c]->nuses == 0));
1445 	      assert(consanddatas[c]->nuses >= 0);
1446 	      assert(consanddatas[c]->noriguses >= 0);
1447 	      assert(isorig ? consanddatas[c]->cons == NULL : TRUE);
1448 	
1449 	      /* are we deleteing a transformed constraint */
1450 	      if( !isorig && consanddatas[c]->cons != NULL )
1451 	      {
1452 	         assert(!SCIPconsIsOriginal(consanddatas[c]->cons));
1453 	
1454 	         --(consanddatas[c]->nuses);
1455 	
1456 	         /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1457 	         if( consanddatas[c]->nuses == 0 )
1458 	         {
1459 	            if( conshdlrdata->inithashmapandtable )
1460 	            {
1461 	               assert(conshdlrdata->hashmap != NULL);
1462 	               assert(conshdlrdata->hashtable != NULL);
1463 	
1464 	               /* remove consanddata from hashtable, if it existed only in transformed space */
1465 	               if( consanddatas[c]->origcons == NULL )
1466 	               {
1467 	                  assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddatas[c]));
1468 	                  SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddatas[c]) );
1469 	               }
1470 	               assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)));
1471 	               SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)) );
1472 	            }
1473 	
1474 	            SCIP_CALL( SCIPreleaseCons(scip, &(consanddatas[c]->cons)) );
1475 	
1476 	            /* if the consanddata object was only used in transformed space, delete the memory block */
1477 	            if( consanddatas[c]->origcons == NULL )
1478 	            {
1479 	               int d;
1480 	
1481 	               assert(conshdlrdata->nallconsanddatas > 0);
1482 	
1483 	               for( d = conshdlrdata->nallconsanddatas - 1; d >= 0; --d )
1484 	               {
1485 	                  if( conshdlrdata->allconsanddatas[d] == consanddatas[c] )
1486 	                  {
1487 	                     --conshdlrdata->nallconsanddatas;
1488 	
1489 	                     SCIPfreeBlockMemory(scip, &(conshdlrdata->allconsanddatas[d])); /*lint !e866*/
1490 	
1491 	                     conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1492 	                     break;
1493 	                  }
1494 	               }
1495 	               assert(d >= 0);
1496 	               continue;
1497 	            }
1498 	         }
1499 	      }
1500 	      /* are we deleteing an original constraint */
1501 	      else if( isorig && consanddatas[c]->origcons != NULL )
1502 	      {
1503 	         assert(SCIPconsIsOriginal(consanddatas[c]->origcons));
1504 	         assert(consanddatas[c]->nuses == 0);
1505 	         assert(consanddatas[c]->nnewvars == 0);
1506 	         assert(consanddatas[c]->snewvars == 0);
1507 	         assert(consanddatas[c]->newvars == NULL);
1508 	
1509 	         --(consanddatas[c]->noriguses);
1510 	
1511 	         /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1512 	         if( consanddatas[c]->noriguses == 0 )
1513 	         {
1514 	            int d;
1515 	
1516 	            if( conshdlrdata->inithashmapandtable )
1517 	            {
1518 	               assert(conshdlrdata->hashmap != NULL);
1519 	               assert(conshdlrdata->hashtable != NULL);
1520 	
1521 	               assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddatas[c]));
1522 	               SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddatas[c]) );
1523 	
1524 	               assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1525 	               SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)) );
1526 	            }
1527 	
1528 	            if( consanddatas[c]->vars != NULL )
1529 	            {
1530 	               assert(consanddatas[c]->nvars > 0);
1531 	               assert(consanddatas[c]->svars > 0);
1532 	               assert(consanddatas[c]->svars >= consanddatas[c]->nvars);
1533 	
1534 	               SCIPfreeBlockMemoryArrayNull(scip, &(consanddatas[c]->vars), consanddatas[c]->svars);
1535 	               consanddatas[c]->nvars = 0;
1536 	               consanddatas[c]->svars = 0;
1537 	            }
1538 	            else
1539 	            {
1540 	               assert(consanddatas[c]->nvars == 0);
1541 	               assert(consanddatas[c]->svars == 0);
1542 	            }
1543 	
1544 	            SCIP_CALL( SCIPreleaseCons(scip, &(consanddatas[c]->origcons)) );
1545 	            assert(consanddatas[c]->origcons == NULL);
1546 	
1547 	            /* delete consanddata object */
1548 	            assert(conshdlrdata->nallconsanddatas > 0);
1549 	            for( d = conshdlrdata->nallconsanddatas - 1; d >= 0; --d )
1550 	            {
1551 	               if( conshdlrdata->allconsanddatas[d] == consanddatas[c] )
1552 	               {
1553 	                  --conshdlrdata->nallconsanddatas;
1554 	
1555 	                  SCIPfreeBlockMemory(scip, &(conshdlrdata->allconsanddatas[d])); /*lint !e866*/
1556 	
1557 	                  conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1558 	                  break;
1559 	               }
1560 	            }
1561 	            assert(d >= 0);
1562 	
1563 	            continue;
1564 	         }
1565 	      }
1566 	      else
1567 	      {
1568 	         assert(!consanddatas[c]->istransformed);
1569 	         assert(consanddatas[c]->cons == NULL);
1570 	      }
1571 	
1572 	      /* clear and remove capture of transformed consanddata */
1573 	      if( consanddatas[c]->nuses == 0 && consanddatas[c]->istransformed )
1574 	      {
1575 	         SCIP_CALL( transformToOrig(scip, consanddatas[c], conshdlrdata) );
1576 	      }
1577 	#ifndef NDEBUG
1578 	      else if( consanddatas[c]->nuses == 0 )
1579 	      {
1580 	         SCIP_VAR** tmpvars;
1581 	         int ntmpvars;
1582 	         int v;
1583 	
1584 	         assert(consanddatas[c]->nnewvars == 0);
1585 	         assert(consanddatas[c]->snewvars == 0);
1586 	         assert(consanddatas[c]->newvars == NULL);
1587 	
1588 	         tmpvars = consanddatas[c]->vars;
1589 	         ntmpvars = consanddatas[c]->nvars;
1590 	
1591 	         /* release all variables */
1592 	         for( v = ntmpvars - 1; v >= 0; --v )
1593 	         {
1594 	            assert(tmpvars[v] != NULL);
1595 	            assert(SCIPvarIsOriginal(tmpvars[v]));
1596 	         }
1597 	      }
1598 	#endif
1599 	
1600 	      /* restore original data */
1601 	      if( !consanddatas[c]->istransformed && consanddatas[c]->noriguses > 0 )
1602 	      {
1603 	         assert(consanddatas[c]->origcons != NULL);
1604 	         assert(consanddatas[c]->nuses == 0);
1605 	         assert(consanddatas[c]->nnewvars == 0);
1606 	         assert(consanddatas[c]->snewvars == 0);
1607 	         assert(consanddatas[c]->newvars == NULL);
1608 	         assert(consanddatas[c]->nvars > 0);
1609 	         assert(consanddatas[c]->svars > 0);
1610 	         assert(consanddatas[c]->svars >= consanddatas[c]->nvars);
1611 	         assert(consanddatas[c]->vars != NULL);
1612 	         assert(consanddatas[c]->isoriginal);
1613 	
1614 	         assert(consanddatas[c]->nvars == SCIPgetNVarsAnd(scip, consanddatas[c]->origcons));
1615 	         assert(SCIPgetVarsAnd(scip, consanddatas[c]->origcons) != NULL);
1616 	
1617 	         /* check that the hash map and tabkle are still having all information */
1618 	         if( conshdlrdata->inithashmapandtable )
1619 	         {
1620 	            assert(conshdlrdata->hashmap != NULL);
1621 	            assert(conshdlrdata->hashtable != NULL);
1622 	            assert(SCIPgetResultantAnd(scip, consanddatas[c]->origcons) != NULL);
1623 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddatas[c]));
1624 	            assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddatas[c])));
1625 	            assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1626 	            assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons))));
1627 	         }
1628 	      }
1629 	   }
1630 	
1631 	   /* free array of and-constraints */
1632 	   SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->andnegs), (*consdata)->sconsanddatas);
1633 	   SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->andcoefs), (*consdata)->sconsanddatas);
1634 	   SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->consanddatas), (*consdata)->sconsanddatas);
1635 	
1636 	   SCIPfreeBlockMemory(scip, consdata);
1637 	
1638 	   return SCIP_OKAY;
1639 	}
1640 	
1641 	/** check the locks of an AND resultant and removes it from all global structures if the resultant is not locked anymore */
1642 	static
1643 	SCIP_RETCODE checkLocksAndRes(
1644 	   SCIP*const            scip,               /**< SCIP data structure */
1645 	   SCIP_VAR*             res                 /**< resultant of AND constraint */
1646 	   )
1647 	{
1648 	   assert(scip != NULL);
1649 	   assert(res != NULL);
1650 	
1651 	   /* the resultant has no locks left and might be dual fixed now, we need to delete all its cliques */
1652 	   if( SCIPvarIsActive(res) && SCIPvarGetNLocksDownType(res, SCIP_LOCKTYPE_MODEL) == 0
1653 	      && SCIPvarGetNLocksUpType(res, SCIP_LOCKTYPE_MODEL) == 0 && SCIPgetStage(scip) < SCIP_STAGE_FREETRANS )
1654 	   {
1655 	      SCIP_CALL( SCIPremoveVarFromGlobalStructures(scip, res) );
1656 	   }
1657 	
1658 	   return SCIP_OKAY;
1659 	}
1660 	
1661 	/** installs rounding locks for the given and-constraint associated with given coefficient */
1662 	static
1663 	SCIP_RETCODE lockRoundingAndCons(
1664 	   SCIP*const            scip,               /**< SCIP data structure */
1665 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
1666 	   CONSANDDATA*const     consanddata,        /**< CONSANDDATA object for which we want to add the locks */
1667 	   SCIP_Real const       coef,               /**< coefficient which led to old locks */
1668 	   SCIP_Real const       lhs,                /**< left hand side */
1669 	   SCIP_Real const       rhs                 /**< right hand side */
1670 	   )
1671 	{
1672 	   SCIP_VAR** vars;
1673 	   int nvars;
1674 	   SCIP_VAR* res;
1675 	   SCIP_Bool haslhs;
1676 	   SCIP_Bool hasrhs;
1677 	   int v;
1678 	
1679 	   assert(scip != NULL);
1680 	   assert(cons != NULL);
1681 	   assert(!SCIPconsIsLockedType(cons, SCIP_LOCKTYPE_CONFLICT));
1682 	   assert(consanddata != NULL);
1683 	   assert(!SCIPisInfinity(scip, coef) && !SCIPisInfinity(scip, -coef));
1684 	   assert(!SCIPisInfinity(scip, lhs));
1685 	   assert(!SCIPisInfinity(scip, -rhs));
1686 	   assert(SCIPisLE(scip, lhs, rhs));
1687 	
1688 	   /* choose correct variable array to add locks for, we only add locks for now valid variables */
1689 	   if( consanddata->nnewvars > 0 )
1690 	   {
1691 	      vars = consanddata->newvars;
1692 	      nvars = consanddata->nnewvars;
1693 	   }
1694 	   else
1695 	   {
1696 	      vars = consanddata->vars;
1697 	      nvars = consanddata->nvars;
1698 	   }
1699 	
1700 	   res = SCIPgetResultantAnd(scip, consanddata->cons);
1701 	   assert(nvars == 0 || (vars != NULL && res != NULL));
1702 	
1703 	   /* check which sites are infinity */
1704 	   haslhs = !SCIPisInfinity(scip, -lhs);
1705 	   hasrhs = !SCIPisInfinity(scip, rhs);
1706 	
1707 	   if( SCIPconsIsLocked(cons) )
1708 	   {
1709 	      /* locking variables */
1710 	      if( SCIPisPositive(scip, coef) )
1711 	      {
1712 	         for( v = nvars - 1; v >= 0; --v )
1713 	         {
1714 	            SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, haslhs, hasrhs) );
1715 	         }
1716 	      }
1717 	      else
1718 	      {
1719 	         for( v = nvars - 1; v >= 0; --v )
1720 	         {
1721 	            SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, hasrhs, haslhs) );
1722 	         }
1723 	      }
1724 	      SCIP_CALL( SCIPlockVarCons(scip, res, cons, TRUE, TRUE) );
1725 	   }
1726 	
1727 	   return SCIP_OKAY;
1728 	}
1729 	
1730 	/** removes rounding locks for the given and-constraint associated with given coefficient */
1731 	static
1732 	SCIP_RETCODE unlockRoundingAndCons(
1733 	   SCIP*const            scip,               /**< SCIP data structure */
1734 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
1735 	   CONSANDDATA*const     consanddata,        /**< CONSANDDATA object for which we want to delete the locks */
1736 	   SCIP_Real const       coef,               /**< coefficient which led to old locks */
1737 	   SCIP_Real const       lhs,                /**< left hand side which led to old locks */
1738 	   SCIP_Real const       rhs                 /**< right hand side which led to old locks */
1739 	   )
1740 	{
1741 	   SCIP_VAR** vars;
1742 	   int nvars;
1743 	   SCIP_VAR* res;
1744 	   SCIP_Bool haslhs;
1745 	   SCIP_Bool hasrhs;
1746 	   int v;
1747 	
1748 	   assert(scip != NULL);
1749 	   assert(cons != NULL);
1750 	   assert(!SCIPconsIsLockedType(cons, SCIP_LOCKTYPE_CONFLICT));
1751 	   assert(consanddata != NULL);
1752 	   assert(!SCIPisInfinity(scip, coef) && !SCIPisInfinity(scip, -coef));
1753 	   assert(!SCIPisInfinity(scip, lhs));
1754 	   assert(!SCIPisInfinity(scip, -rhs));
1755 	   assert(SCIPisLE(scip, lhs, rhs));
1756 	
1757 	   vars = consanddata->vars;
1758 	   nvars = consanddata->nvars;
1759 	
1760 	   if( consanddata->cons != NULL )
1761 	      res = SCIPgetResultantAnd(scip, consanddata->cons);
1762 	   else
1763 	      res = NULL;
1764 	   assert(nvars == 0 || vars != NULL);
1765 	
1766 	   /* check which sites are infinity */
1767 	   haslhs = !SCIPisInfinity(scip, -lhs);
1768 	   hasrhs = !SCIPisInfinity(scip, rhs);
1769 	
1770 	   if( SCIPconsIsLocked(cons) )
1771 	   {
1772 	      /* unlock variables */
1773 	      if( SCIPisPositive(scip, coef) )
1774 	      {
1775 	         for( v = nvars - 1; v >= 0; --v )
1776 	         {
1777 	            SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, haslhs, hasrhs) );
1778 	         }
1779 	      }
1780 	      else
1781 	      {
1782 	         for( v = nvars - 1; v >= 0; --v )
1783 	         {
1784 	            SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, hasrhs, haslhs) );
1785 	         }
1786 	      }
1787 	
1788 	      if( res != NULL )
1789 	      {
1790 	         SCIP_CALL( SCIPunlockVarCons(scip, res, cons, TRUE, TRUE) );
1791 	
1792 	         SCIP_CALL( checkLocksAndRes(scip, res) );
1793 	      }
1794 	   }
1795 	
1796 	   return SCIP_OKAY;
1797 	}
1798 	
1799 	/** prints pseudoboolean constraint in CIP format to file stream */
1800 	static
1801 	SCIP_RETCODE consdataPrint(
1802 	   SCIP*const            scip,               /**< SCIP data structure */
1803 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
1804 	   FILE*const            file                /**< output file (or NULL for standard output) */
1805 	   )
1806 	{
1807 	   SCIP_CONSHDLR* conshdlr;
1808 	   SCIP_CONSHDLRDATA* conshdlrdata;
1809 	   SCIP_CONSDATA* consdata;
1810 	
1811 	   SCIP_VAR** vars;
1812 	   SCIP_Real* coefs;
1813 	   int nvars;
1814 	   SCIP_Real lhs;
1815 	   SCIP_Real rhs;
1816 	
1817 	   SCIP_VAR** linvars;
1818 	   SCIP_Real* lincoefs;
1819 	   int nlinvars;
1820 	   int v;
1821 	
1822 	   SCIP_VAR** andress;
1823 	   SCIP_Real* andcoefs;
1824 	   SCIP_Bool* andnegs;
1825 	   int nandress;
1826 	
1827 	   SCIP_Bool printed;
1828 	
1829 	   assert(scip != NULL);
1830 	   assert(cons != NULL);
1831 	
1832 	#ifdef WITHEQKNAPSACK
1833 	   if( SCIPconsIsDeleted(cons) )
1834 	      return SCIP_OKAY;
1835 	#endif
1836 	
1837 	   consdata = SCIPconsGetData(cons);
1838 	   assert(consdata != NULL);
1839 	   assert(consdata->lincons != NULL);
1840 	   /* more than one and-constraint is needed, otherwise this pseudoboolean constraint should be upgraded to a linear constraint */
1841 	   assert(consdata->nconsanddatas >= 0);
1842 	
1843 	   /* gets number of variables in linear constraint */
1844 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
1845 	
1846 	   /* allocate temporary memory */
1847 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
1848 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
1849 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
1850 	   SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
1851 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nvars) );
1852 	   SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nvars) );
1853 	   SCIP_CALL( SCIPallocBufferArray(scip, &andnegs, nvars) );
1854 	
1855 	   /* get sides of linear constraint */
1856 	   SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &lhs, &rhs) );
1857 	   assert(!SCIPisInfinity(scip, lhs));
1858 	   assert(!SCIPisInfinity(scip, -rhs));
1859 	   assert(SCIPisLE(scip, lhs, rhs));
1860 	
1861 	   /* get variables and coefficient of linear constraint */
1862 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
1863 	   assert(nvars == 0 || (coefs != NULL));
1864 	
1865 	   /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
1866 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
1867 	    * afterwards
1868 	    */
1869 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
1870 	         andress, andcoefs, andnegs, &nandress) );
1871 	   assert(consdata->nconsanddatas == nandress);
1872 	
1873 	   /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
1874 	    * have to be equal to the number of variables in the linear constraint
1875 	    */
1876 	   assert(consdata->nlinvars + consdata->nconsanddatas == nvars);
1877 	
1878 	   /* print left hand side for ranged rows */
1879 	   if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
1880 	      SCIPinfoMessage(scip, file, "%.15g <= ", lhs);
1881 	
1882 	   printed = FALSE;
1883 	
1884 	   /* print coefficients and variables */
1885 	   if( nlinvars > 0)
1886 	   {
1887 	      printed= TRUE;
1888 	
1889 	      /* print linear part of constraint */
1890 	      SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, linvars, lincoefs, nlinvars, TRUE) );
1891 	   }
1892 	
1893 	   conshdlr = SCIPconsGetHdlr(cons);
1894 	   assert(conshdlr != NULL);
1895 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
1896 	   assert(conshdlrdata != NULL);
1897 	   assert(conshdlrdata->hashmap != NULL);
1898 	
1899 	   /* print all non-linear terms */
1900 	   for( v = nandress - 1; v >= 0; --v )
1901 	   {
1902 	      CONSANDDATA* consanddata;
1903 	      SCIP_CONS* andcons;
1904 	      SCIP_VAR** andvars;
1905 	      int nandvars;
1906 	
1907 	      if( !SCIPconsIsOriginal(cons) )
1908 	      {
1909 	         /* if the and resultant was fixed we print a constant */
1910 	         if( SCIPvarGetLbLocal(andress[v]) > 0.5 || SCIPvarGetUbLocal(andress[v]) < 0.5 )
1911 	         {
1912 	            if( SCIPvarGetLbGlobal(andress[v]) > 0.5 )
1913 	            {
1914 	               printed = TRUE;
1915 	               SCIPinfoMessage(scip, file, " %+.15g ", andcoefs[v] * SCIPvarGetLbGlobal(andress[v]));
1916 	            }
1917 	            continue;
1918 	         }
1919 	         else if( SCIPvarGetStatus(andress[v]) == SCIP_VARSTATUS_AGGREGATED )
1920 	         {
1921 	            SCIP_VAR* aggrvar;
1922 	            SCIP_Bool negated;
1923 	
1924 	            SCIP_CALL( SCIPgetBinvarRepresentative(scip, andress[v], &aggrvar, &negated) );
1925 	            assert(aggrvar != NULL);
1926 	            assert(SCIPvarGetType(aggrvar) == SCIP_VARTYPE_BINARY);
1927 	
1928 	            printed = TRUE;
1929 	            SCIPinfoMessage(scip, file, " %+.15g %s<%s>[B]", andcoefs[v], negated ? "~" : "", SCIPvarGetName(aggrvar));
1930 	
1931 	            continue;
1932 	         }
1933 	      }
1934 	
1935 	      consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[v]);
1936 	      assert(consanddata != NULL);
1937 	
1938 	      if( SCIPconsIsOriginal(cons) )
1939 	         andcons = consanddata->origcons;
1940 	      else
1941 	         andcons = consanddata->cons;
1942 	      assert(andcons != NULL);
1943 	
1944 	      andvars = SCIPgetVarsAnd(scip, andcons);
1945 	      nandvars = SCIPgetNVarsAnd(scip, andcons);
1946 	      assert(nandvars == 0 || andvars != NULL);
1947 	
1948 	      if( nandvars > 0 )
1949 	      {
1950 	         printed = TRUE;
1951 	         SCIPinfoMessage(scip, file, " %+.15g %s(", andcoefs[v], andnegs[v] ? "~" : "");
1952 	
1953 	         /* @todo: better write new method SCIPwriteProduct */
1954 	         /* print variable list */
1955 	         SCIP_CALL( SCIPwriteVarsList(scip, file, andvars, nandvars, TRUE, '*') );
1956 	
1957 	         SCIPinfoMessage(scip, file, ")");
1958 	      }
1959 	   }
1960 	
1961 	   if( !printed )
1962 	   {
1963 	      SCIPinfoMessage(scip, file, " 0 ");
1964 	   }
1965 	
1966 	   /* free temporary memory */
1967 	   SCIPfreeBufferArray(scip, &andnegs);
1968 	   SCIPfreeBufferArray(scip, &andcoefs);
1969 	   SCIPfreeBufferArray(scip, &andress);
1970 	   SCIPfreeBufferArray(scip, &lincoefs);
1971 	   SCIPfreeBufferArray(scip, &linvars);
1972 	   SCIPfreeBufferArray(scip, &coefs);
1973 	   SCIPfreeBufferArray(scip, &vars);
1974 	
1975 	   /* print right hand side */
1976 	   if( SCIPisEQ(scip, lhs, rhs) )
1977 	      SCIPinfoMessage(scip, file, "== %.15g", rhs);
1978 	   else if( !SCIPisInfinity(scip, rhs) )
1979 	      SCIPinfoMessage(scip, file, "<= %.15g", rhs);
1980 	   else if( !SCIPisInfinity(scip, -lhs) )
1981 	      SCIPinfoMessage(scip, file, ">= %.15g", lhs);
1982 	   else
1983 	      SCIPinfoMessage(scip, file, " [free]");
1984 	
1985 	   return SCIP_OKAY;
1986 	}
1987 	
1988 	/** creates and/or adds the resultant for a given term */
1989 	static
1990 	SCIP_RETCODE createAndAddAndCons(
1991 	   SCIP*const            scip,               /**< SCIP data structure */
1992 	   SCIP_CONSHDLR*const   conshdlr,           /**< pseudoboolean constraint handler */
1993 	   SCIP_VAR**const       vars,               /**< array of variables to get and-constraints for */
1994 	   int const             nvars,              /**< number of variables to get and-constraints for */
1995 	   SCIP_Bool const       initial,            /**< should the LP relaxation of constraint be in the initial LP?
1996 	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
1997 	   SCIP_Bool const       enforce,            /**< should the constraint be enforced during node processing?
1998 	                                              *   TRUE for model constraints, FALSE for additional, redundant
1999 	                                              *   constraints. */
2000 	   SCIP_Bool const       check,              /**< should the constraint be checked for feasibility?
2001 	                                              *   TRUE for model constraints, FALSE for additional, redundant
2002 	                                              *   constraints. */
2003 	   SCIP_Bool const       local,              /**< is constraint only valid locally?
2004 	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching
2005 	                                              *   constraints. */
2006 	   SCIP_Bool const       modifiable,         /**< is constraint modifiable (subject to column generation)?
2007 	                                              *   Usually set to FALSE. In column generation applications, set to TRUE
2008 	                                              *   if pricing adds coefficients to this constraint. */
2009 	   SCIP_Bool const       dynamic,            /**< is constraint subject to aging?
2010 	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
2011 	                                              *   are seperated as constraints. */
2012 	   SCIP_Bool const       stickingatnode,     /**< should the constraint always be kept at the node where it was added, even
2013 	                                              *   if it may be moved to a more global node?
2014 	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent
2015 	                                              *   node data. */
2016 	   SCIP_CONS**const      andcons             /**< pointer to store and-constraint */
2017 	   )
2018 	{
2019 	   CONSANDDATA* newdata;
2020 	   CONSANDDATA* tmpdata;
2021 	   SCIP_CONSHDLRDATA* conshdlrdata;
2022 	   char name[SCIP_MAXSTRLEN];
2023 	   SCIP_Bool separate;
2024 	   SCIP_Bool propagate;
2025 	   SCIP_Bool removable;
2026 	   SCIP_Bool transformed;
2027 	
2028 	   assert(scip != NULL);
2029 	   assert(conshdlr != NULL);
2030 	   assert(vars != NULL);
2031 	   assert(nvars > 0);
2032 	   assert(andcons != NULL);
2033 	
2034 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
2035 	   assert(conshdlrdata != NULL);
2036 	   assert(conshdlrdata->hashtable != NULL);
2037 	
2038 	   transformed = SCIPisTransformed(scip);
2039 	
2040 	   /* allocate memory for a possible new consanddata object */
2041 	   SCIP_CALL( SCIPallocBlockMemory(scip, &newdata) );
2042 	   SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(newdata->vars), vars, nvars) );
2043 	   newdata->nvars = nvars;
2044 	   newdata->svars = nvars;
2045 	   newdata->newvars = NULL;
2046 	   newdata->nnewvars = 0;
2047 	   newdata->snewvars = 0;
2048 	   newdata->noriguses = 0;
2049 	   newdata->nuses = 0;
2050 	   newdata->istransformed = transformed;
2051 	   newdata->isoriginal = !transformed;
2052 	   newdata->cons = NULL;
2053 	   newdata->origcons = NULL;
2054 	
2055 	   /* sort variables */
2056 	   SCIPsortPtr((void**)(newdata->vars), SCIPvarComp, nvars);
2057 	
2058 	   /* get constraint from current hash table with same variables as cons0 */
2059 	   tmpdata = (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)newdata));
2060 	
2061 	   /* if there is already the same and constraint created use this resultant */
2062 	   if( tmpdata != NULL )
2063 	   {
2064 	#ifndef NDEBUG
2065 	      SCIP_VAR* res;
2066 	#endif
2067 	      if( transformed )
2068 	      {
2069 	         assert(tmpdata->cons != NULL);
2070 	         *andcons = tmpdata->cons;
2071 	
2072 	         assert(tmpdata->nuses > 0);
2073 	         /* increase usage of data object */
2074 	         ++(tmpdata->nuses);
2075 	      }
2076 	      else
2077 	      {
2078 	         assert(tmpdata->origcons != NULL);
2079 	         *andcons = tmpdata->origcons;
2080 	
2081 	         assert(tmpdata->noriguses > 0);
2082 	         /* increase usage of data object */
2083 	         ++(tmpdata->noriguses);
2084 	      }
2085 	      assert(*andcons != NULL);
2086 	
2087 	#ifndef NDEBUG
2088 	      res = SCIPgetResultantAnd(scip, *andcons);
2089 	      assert(res != NULL);
2090 	
2091 	      /* check that we already have added this resultant to and-constraint entry */
2092 	      assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)res));
2093 	#endif
2094 	   }
2095 	   else
2096 	   {
2097 	      /* create new and-constraint */
2098 	      SCIP_CONS* newcons;
2099 	      SCIP_VAR* resultant;
2100 	
2101 	      /* create auxiliary variable */
2102 	      (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"%d", conshdlrdata->nallconsanddatas);
2103 	      SCIP_CALL( SCIPcreateVar(scip, &resultant, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
2104 	            TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
2105 	
2106 	#if 1 /* @todo: check whether we want to branch on artificial variables, the test results show that it is of advantage */
2107 	      /* change branching priority of artificial variable to -1 */
2108 	      SCIP_CALL( SCIPchgVarBranchPriority(scip, resultant, -1) );
2109 	#endif
2110 	
2111 	      /* add auxiliary variable to the problem */
2112 	      SCIP_CALL( SCIPaddVar(scip, resultant) );
2113 	
2114 	#if 0 /* does not work for since the value of artificial resultants must not be equal to the value computed by their
2115 	       * product, since these variables are irrelevant */
2116 	#ifdef WITH_DEBUG_SOLUTION
2117 	      if( SCIPdebugIsMainscip(scip) )
2118 	      {
2119 	         SCIP_Real val;
2120 	         SCIP_Real debugsolval;
2121 	         int v;
2122 	
2123 	         for( v = nvars - 1; v >= 0; --v )
2124 	         {
2125 	            SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
2126 	            assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
2127 	
2128 	            if( val < 0.5 )
2129 	               break;
2130 	         }
2131 	         val = ((val < 0.5) ? 0.0 : 1.0);
2132 	
2133 	         SCIP_CALL( SCIPdebugGetSolVal(scip, resultant, &debugsolval) );
2134 	         if( (SCIPvarIsOriginal(resultant) || SCIPvarIsTransformedOrigvar(resultant)) && !SCIPisFeasEQ(scip, debugsolval, val) )
2135 	         {
2136 	            SCIPerrorMessage("computed solution value %g for resultant <%s> violates debug solution value %g\n", val, SCIPvarGetName(resultant), debugsolval);
2137 	            SCIPABORT();
2138 	            return SCIP_ERROR; /*lint !e527*/
2139 	         }
2140 	         else if( !SCIPvarIsOriginal(resultant) && !SCIPvarIsTransformedOrigvar(resultant) )
2141 	         {
2142 	            SCIP_CALL( SCIPdebugAddSolVal(scip, resultant, val) );
2143 	         }
2144 	      }
2145 	#endif
2146 	#endif
2147 	
2148 	      SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/nlcseparate", &separate) );
2149 	      SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/nlcpropagate", &propagate) );
2150 	      SCIP_CALL( SCIPgetBoolParam(scip, "constraints/" CONSHDLR_NAME "/nlcremovable", &removable) );
2151 	
2152 	      /* we do not want to check the and constraints, so the check flag will be FALSE */
2153 	
2154 	      /* create and add "and" constraint for the multiplication of the binary variables */
2155 	      (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "andcons_%d", conshdlrdata->nallconsanddatas);
2156 	      SCIP_CALL( SCIPcreateConsAnd(scip, &newcons, name, resultant, newdata->nvars, newdata->vars,
2157 	            initial, separate, enforce, check && FALSE, propagate,
2158 	            local, modifiable, dynamic, removable, stickingatnode) ); /*lint !e506*/
2159 	      SCIP_CALL( SCIPaddCons(scip, newcons) );
2160 	      SCIPdebugPrintCons(scip, newcons, NULL);
2161 	
2162 	      /* force all deriving constraint from this and constraint to be checked and not removable */
2163 	      SCIP_CALL( SCIPchgAndConsCheckFlagWhenUpgr(scip, newcons, TRUE) );
2164 	      SCIP_CALL( SCIPchgAndConsRemovableFlagWhenUpgr(scip, newcons, TRUE) );
2165 	
2166 	      *andcons = newcons;
2167 	      assert(*andcons != NULL);
2168 	
2169 	      /* resize data for all and-constraints if necessary */
2170 	      if( conshdlrdata->nallconsanddatas == conshdlrdata->sallconsanddatas )
2171 	      {
2172 	         SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(conshdlrdata->allconsanddatas), &(conshdlrdata->sallconsanddatas), SCIPcalcMemGrowSize(scip, conshdlrdata->sallconsanddatas + 1)) );
2173 	      }
2174 	
2175 	      /* add new data object to global hash table */
2176 	      conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas] = newdata;
2177 	      ++(conshdlrdata->nallconsanddatas);
2178 	
2179 	      if( transformed )
2180 	      {
2181 	         int v;
2182 	
2183 	         newdata->cons = newcons;
2184 	         SCIP_CALL( SCIPcaptureCons(scip, newdata->cons) );
2185 	
2186 	         /* initialize usage of data object */
2187 	         newdata->nuses = 1;
2188 	
2189 	         /* capture all variables */
2190 	         for( v = newdata->nvars - 1; v >= 0; --v )
2191 	         {
2192 	            SCIP_CALL( SCIPcaptureVar(scip, newdata->vars[v]) ); /*lint !e613*/
2193 	         }
2194 	      }
2195 	      else
2196 	      {
2197 	         newdata->origcons = newcons;
2198 	         SCIP_CALL( SCIPcaptureCons(scip, newdata->origcons) );
2199 	
2200 	         /* initialize usage of data object */
2201 	         newdata->noriguses = 1;
2202 	      }
2203 	
2204 	      /* no such and-constraint in current hash table: insert the new object into hash table */
2205 	      SCIP_CALL( SCIPhashtableInsert(conshdlrdata->hashtable, (void*)newdata) );
2206 	
2207 	      /* insert new mapping */
2208 	      assert(!SCIPhashmapExists(conshdlrdata->hashmap, (void*)resultant));
2209 	      SCIP_CALL( SCIPhashmapInsert(conshdlrdata->hashmap, (void*)resultant, (void*)newdata) );
2210 	
2211 	      /* release and-resultant and -constraint */
2212 	      SCIP_CALL( SCIPreleaseVar(scip, &resultant) );
2213 	      SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
2214 	
2215 	      return SCIP_OKAY;
2216 	   }
2217 	
2218 	   /* free memory */
2219 	   SCIPfreeBlockMemoryArray(scip, &(newdata->vars), newdata->svars);
2220 	   SCIPfreeBlockMemory(scip, &newdata);
2221 	
2222 	   return SCIP_OKAY;
2223 	}
2224 	
2225 	/** adds a term to the given pseudoboolean constraint */
2226 	static
2227 	SCIP_RETCODE addCoefTerm(
2228 	   SCIP*const            scip,               /**< SCIP data structure */
2229 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
2230 	   SCIP_VAR**const       vars,               /**< variables of the nonlinear term */
2231 	   int const             nvars,              /**< number of variables of the nonlinear term */
2232 	   SCIP_Real const       val                 /**< coefficient of constraint entry */
2233 	   )
2234 	{
2235 	   SCIP_CONSHDLR* conshdlr;
2236 	   SCIP_CONSHDLRDATA* conshdlrdata;
2237 	   SCIP_CONS* andcons;
2238 	   SCIP_CONSDATA* consdata;
2239 	   SCIP_VAR* res;
2240 	
2241 	   assert(scip != NULL);
2242 	   assert(cons != NULL);
2243 	   assert(nvars == 0 || vars != NULL);
2244 	
2245 	   if( nvars == 0 || SCIPisZero(scip, val) )
2246 	      return SCIP_OKAY;
2247 	
2248 	   consdata = SCIPconsGetData(cons);
2249 	   assert(consdata != NULL);
2250 	
2251 	   conshdlr = SCIPconsGetHdlr(cons);
2252 	   assert(conshdlr != NULL);
2253 	
2254 	   conshdlrdata =  SCIPconshdlrGetData(conshdlr);
2255 	   assert(conshdlrdata != NULL);
2256 	
2257 	   /* create (and add) and-constraint */
2258 	   SCIP_CALL( createAndAddAndCons(scip, conshdlr, vars, nvars,
2259 	         SCIPconsIsInitial(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons), SCIPconsIsLocal(cons),
2260 	         SCIPconsIsModifiable(cons), SCIPconsIsDynamic(cons), SCIPconsIsStickingAtNode(cons),
2261 	         &andcons) );
2262 	   assert(andcons != NULL);
2263 	
2264 	   /* ensure memory size */
2265 	   if( consdata->nconsanddatas == consdata->sconsanddatas )
2266 	   {
2267 	      SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consdata->consanddatas), &(consdata->sconsanddatas), consdata->sconsanddatas + 1) );
2268 	   }
2269 	
2270 	   res = SCIPgetResultantAnd(scip, andcons);
2271 	   assert(res != NULL);
2272 	   assert(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res) != NULL);
2273 	
2274 	   consdata->consanddatas[consdata->nconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res);
2275 	   ++(consdata->nconsanddatas);
2276 	
2277 	   /* add auxiliary variables to linear constraint */
2278 	   switch( consdata->linconstype )
2279 	   {
2280 	   case SCIP_LINEARCONSTYPE_LINEAR:
2281 	      SCIP_CALL( SCIPaddCoefLinear(scip, consdata->lincons, res, val) );
2282 	      break;
2283 	   case SCIP_LINEARCONSTYPE_LOGICOR:
2284 	      if( !SCIPisEQ(scip, val, 1.0) )
2285 	         return SCIP_INVALIDDATA;
2286 	
2287 	      SCIP_CALL( SCIPaddCoefLogicor(scip, consdata->lincons, res) );
2288 	      break;
2289 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
2290 	      if( !SCIPisIntegral(scip, val) || !SCIPisPositive(scip, val) )
2291 	         return SCIP_INVALIDDATA;
2292 	
2293 	      SCIP_CALL( SCIPaddCoefKnapsack(scip, consdata->lincons, res, (SCIP_Longint) val) );
2294 	      break;
2295 	   case SCIP_LINEARCONSTYPE_SETPPC:
2296 	      if( !SCIPisEQ(scip, val, 1.0) )
2297 	         return SCIP_INVALIDDATA;
2298 	
2299 	      SCIP_CALL( SCIPaddCoefSetppc(scip, consdata->lincons, res) );
2300 	      break;
2301 	#ifdef WITHEQKNAPSACK
2302 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
2303 	      if( !SCIPisIntegral(scip, val) || !SCIPisPositive(scip, val) )
2304 	         return SCIP_INVALIDDATA;
2305 	
2306 	      SCIP_CALL( SCIPaddCoefEQKnapsack(scip, consdata->lincons, res, (SCIP_Longint) val) );
2307 	      break;
2308 	#endif
2309 	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
2310 	   default:
2311 	      SCIPerrorMessage("unknown linear constraint type\n");
2312 	      return SCIP_INVALIDDATA;
2313 	   }
2314 	
2315 	   /* install rounding locks for all new variable */
2316 	   SCIP_CALL( lockRoundingAndCons(scip, cons, consdata->consanddatas[consdata->nconsanddatas - 1], val, consdata->lhs, consdata->rhs) );
2317 	
2318 	   /* change flags */
2319 	   consdata->changed = TRUE;
2320 	   consdata->propagated = FALSE;
2321 	   consdata->presolved = FALSE;
2322 	   consdata->cliquesadded = FALSE;
2323 	   consdata->upgradetried = FALSE;
2324 	
2325 	   return SCIP_OKAY;
2326 	}
2327 	
2328 	/** changes left hand side of linear constraint */
2329 	static
2330 	SCIP_RETCODE chgLhsLinearCons(
2331 	   SCIP*const            scip,               /**< SCIP data structure */
2332 	   SCIP_CONS*const       cons,               /**< linear constraint */
2333 	   SCIP_LINEARCONSTYPE const constype,       /**< linear constraint type */
2334 	   SCIP_Real const       lhs                 /**< new left hand side of linear constraint */
2335 	   )
2336 	{
2337 	   switch( constype )
2338 	   {
2339 	   case SCIP_LINEARCONSTYPE_LINEAR:
2340 	      SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs) );
2341 	      break;
2342 	   case SCIP_LINEARCONSTYPE_LOGICOR:
2343 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
2344 	   case SCIP_LINEARCONSTYPE_SETPPC:
2345 	      SCIPerrorMessage("changing left hand side only allowed on standard lienar constraint \n");
2346 	      return SCIP_INVALIDDATA;
2347 	#ifdef WITHEQKNAPSACK
2348 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
2349 	#endif
2350 	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
2351 	   default:
2352 	      SCIPerrorMessage("unknown linear constraint type\n");
2353 	      return SCIP_INVALIDDATA;
2354 	   }
2355 	
2356 	   return SCIP_OKAY;
2357 	}
2358 	
2359 	/** changes right hand side of linear constraint */
2360 	static
2361 	SCIP_RETCODE chgRhsLinearCons(
2362 	   SCIP*const            scip,               /**< SCIP data structure */
2363 	   SCIP_CONS*const       cons,               /**< linear constraint */
2364 	   SCIP_LINEARCONSTYPE const constype,       /**< linear constraint type */
2365 	   SCIP_Real const       rhs                 /**< new right hand side of linear constraint */
2366 	   )
2367 	{
2368 	   switch( constype )
2369 	   {
2370 	   case SCIP_LINEARCONSTYPE_LINEAR:
2371 	      SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs) );
2372 	      break;
2373 	   case SCIP_LINEARCONSTYPE_LOGICOR:
2374 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
2375 	   case SCIP_LINEARCONSTYPE_SETPPC:
2376 	      SCIPerrorMessage("changing left hand side only allowed on standard lienar constraint \n");
2377 	      return SCIP_INVALIDDATA;
2378 	#ifdef WITHEQKNAPSACK
2379 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
2380 	#endif
2381 	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
2382 	   default:
2383 	      SCIPerrorMessage("unknown linear constraint type\n");
2384 	      return SCIP_INVALIDDATA;
2385 	   }
2386 	
2387 	   return SCIP_OKAY;
2388 	}
2389 	
2390 	/** sets left hand side of linear constraint */
2391 	static
2392 	SCIP_RETCODE chgLhs(
2393 	   SCIP*const            scip,               /**< SCIP data structure */
2394 	   SCIP_CONS*const       cons,               /**< linear constraint */
2395 	   SCIP_Real             lhs                 /**< new left hand side */
2396 	   )
2397 	{
2398 	   SCIP_CONSDATA* consdata;
2399 	   SCIP_VAR** vars;
2400 	   SCIP_Real* coefs;
2401 	   int nvars;
2402 	   SCIP_VAR** linvars;
2403 	   SCIP_Real* lincoefs;
2404 	   int nlinvars;
2405 	   SCIP_VAR** andress;
2406 	   SCIP_Real* andcoefs;
2407 	   SCIP_Bool* andnegs;
2408 	   int nandress;
2409 	   SCIP_Real oldlhs;
2410 	   SCIP_Real oldrhs;
2411 	
2412 	   assert(scip != NULL);
2413 	   assert(cons != NULL);
2414 	   assert(!SCIPconsIsLockedType(cons, SCIP_LOCKTYPE_CONFLICT));
2415 	   assert(!SCIPisInfinity(scip, lhs));
2416 	
2417 	   /* adjust value to not be smaller than -inf */
2418 	   if ( SCIPisInfinity(scip, -lhs) )
2419 	      lhs = -SCIPinfinity(scip);
2420 	
2421 	   consdata = SCIPconsGetData(cons);
2422 	   assert(consdata != NULL);
2423 	
2424 	   /* get sides of linear constraint */
2425 	   SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2426 	   assert(!SCIPisInfinity(scip, oldlhs));
2427 	   assert(!SCIPisInfinity(scip, -oldrhs));
2428 	   assert(SCIPisLE(scip, oldlhs, oldrhs));
2429 	
2430 	   /* check whether the side is not changed */
2431 	   if( SCIPisEQ(scip, oldlhs, lhs) )
2432 	      return SCIP_OKAY;
2433 	
2434 	   /* gets number of variables in linear constraint */
2435 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
2436 	
2437 	   /* allocate temporary memory */
2438 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
2439 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
2440 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
2441 	   SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
2442 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nvars) );
2443 	   SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nvars) );
2444 	   SCIP_CALL( SCIPallocBufferArray(scip, &andnegs, nvars) );
2445 	
2446 	   /* get variables and coefficient of linear constraint */
2447 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2448 	   assert(nvars == 0 || (coefs != NULL));
2449 	
2450 	   /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2451 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2452 	    * afterwards
2453 	    */
2454 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2455 	   assert(consdata->nconsanddatas == nandress);
2456 	
2457 	   /* if necessary, update the rounding locks of variables */
2458 	   if( SCIPconsIsLocked(cons) )
2459 	   {
2460 	      SCIP_VAR** andvars;
2461 	      int nandvars;
2462 	      SCIP_Real val;
2463 	      int v;
2464 	      int c;
2465 	
2466 	      assert(SCIPconsIsTransformed(cons));
2467 	
2468 	      if( SCIPisInfinity(scip, -oldlhs) && !SCIPisInfinity(scip, -lhs) )
2469 	      {
2470 	         /* non-linear part */
2471 	         for( c = consdata->nconsanddatas - 1; c >= 0; --c )
2472 	         {
2473 	            CONSANDDATA* consanddata;
2474 	            SCIP_CONS* andcons;
2475 	
2476 	            consanddata = consdata->consanddatas[c];
2477 	            assert(consanddata != NULL);
2478 	
2479 	            andcons = consanddata->cons;
2480 	            assert(andcons != NULL);
2481 	
2482 	            andvars = SCIPgetVarsAnd(scip, andcons);
2483 	            nandvars = SCIPgetNVarsAnd(scip, andcons);
2484 	            val = andnegs[c] ? -andcoefs[c] : andcoefs[c];
2485 	
2486 	            /* lock variables */
2487 	            if( SCIPisPositive(scip, val) )
2488 	            {
2489 	               for( v = nandvars - 1; v >= 0; --v )
2490 	               {
2491 	                  SCIP_CALL( SCIPlockVarCons(scip, andvars[v], cons, TRUE, FALSE) );
2492 	               }
2493 	            }
2494 	            else
2495 	            {
2496 	               for( v = nandvars - 1; v >= 0; --v )
2497 	               {
2498 	                  SCIP_CALL( SCIPlockVarCons(scip, andvars[v], cons, FALSE, TRUE) );
2499 	               }
2500 	            }
2501 	         }
2502 	      }
2503 	      else if( !SCIPisInfinity(scip, -oldlhs) && SCIPisInfinity(scip, -lhs) )
2504 	      {
2505 	         /* non-linear part */
2506 	         for( c = consdata->nconsanddatas - 1; c >= 0; --c )
2507 	         {
2508 	            CONSANDDATA* consanddata;
2509 	            SCIP_CONS* andcons;
2510 	
2511 	            consanddata = consdata->consanddatas[c];
2512 	            assert(consanddata != NULL);
2513 	
2514 	            andcons = consanddata->cons;
2515 	            assert(andcons != NULL);
2516 	
2517 	            andvars = SCIPgetVarsAnd(scip, andcons);
2518 	            nandvars = SCIPgetNVarsAnd(scip, andcons);
2519 	            val = andnegs[c] ? -andcoefs[c] : andcoefs[c];
2520 	
2521 	            /* lock variables */
2522 	            if( SCIPisPositive(scip, val) )
2523 	            {
2524 	               for( v = nandvars - 1; v >= 0; --v )
2525 	               {
2526 	                  SCIP_CALL( SCIPunlockVarCons(scip, andvars[v], cons, TRUE, FALSE) );
2527 	               }
2528 	            }
2529 	            else
2530 	            {
2531 	               for( v = nandvars - 1; v >= 0; --v )
2532 	               {
2533 	                  SCIP_CALL( SCIPunlockVarCons(scip, andvars[v], cons, FALSE, TRUE) );
2534 	               }
2535 	            }
2536 	         }
2537 	      }
2538 	   }
2539 	
2540 	   /* 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 */
2541 	   if( SCIPisLT(scip, oldlhs, lhs) )
2542 	   {
2543 	      consdata->propagated = FALSE;
2544 	   }
2545 	
2546 	   /* set new left hand side and update constraint data */
2547 	   SCIP_CALL( chgLhsLinearCons(scip, consdata->lincons, consdata->linconstype, lhs) );
2548 	   consdata->lhs = lhs;
2549 	   consdata->presolved = FALSE;
2550 	   consdata->changed = TRUE;
2551 	
2552 	   /* free temporary memory */
2553 	   SCIPfreeBufferArray(scip, &andnegs);
2554 	   SCIPfreeBufferArray(scip, &andcoefs);
2555 	   SCIPfreeBufferArray(scip, &andress);
2556 	   SCIPfreeBufferArray(scip, &lincoefs);
2557 	   SCIPfreeBufferArray(scip, &linvars);
2558 	   SCIPfreeBufferArray(scip, &coefs);
2559 	   SCIPfreeBufferArray(scip, &vars);
2560 	
2561 	   return SCIP_OKAY;
2562 	}
2563 	
2564 	/** sets right hand side of pseudoboolean constraint */
2565 	static
2566 	SCIP_RETCODE chgRhs(
2567 	   SCIP*const            scip,               /**< SCIP data structure */
2568 	   SCIP_CONS*const       cons,               /**< linear constraint */
2569 	   SCIP_Real             rhs                 /**< new right hand side */
2570 	   )
2571 	{
2572 	   SCIP_CONSDATA* consdata;
2573 	   SCIP_VAR** vars;
2574 	   SCIP_Real* coefs;
2575 	   int nvars;
2576 	   SCIP_VAR** linvars;
2577 	   SCIP_Real* lincoefs;
2578 	   int nlinvars;
2579 	   SCIP_VAR** andress;
2580 	   SCIP_Real* andcoefs;
2581 	   SCIP_Bool* andnegs;
2582 	   int nandress;
2583 	   SCIP_Real oldlhs;
2584 	   SCIP_Real oldrhs;
2585 	
2586 	   assert(scip != NULL);
2587 	   assert(cons != NULL);
2588 	   assert(!SCIPconsIsLockedType(cons, SCIP_LOCKTYPE_CONFLICT));
2589 	   assert(!SCIPisInfinity(scip, -rhs));
2590 	
2591 	   /* adjust value to not be larger than inf */
2592 	   if( SCIPisInfinity(scip, rhs) )
2593 	      rhs = SCIPinfinity(scip);
2594 	
2595 	   consdata = SCIPconsGetData(cons);
2596 	   assert(consdata != NULL);
2597 	
2598 	   /* get sides of linear constraint */
2599 	   SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2600 	   assert(!SCIPisInfinity(scip, oldlhs));
2601 	   assert(!SCIPisInfinity(scip, -oldrhs));
2602 	   assert(SCIPisLE(scip, oldlhs, oldrhs));
2603 	
2604 	   /* check whether the side is not changed */
2605 	   if( SCIPisEQ(scip, oldrhs, rhs) )
2606 	      return SCIP_OKAY;
2607 	
2608 	   /* gets number of variables in linear constraint */
2609 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
2610 	
2611 	   /* allocate temporary memory */
2612 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
2613 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
2614 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
2615 	   SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
2616 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nvars) );
2617 	   SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nvars) );
2618 	   SCIP_CALL( SCIPallocBufferArray(scip, &andnegs, nvars) );
2619 	
2620 	   /* get variables and coefficient of linear constraint */
2621 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2622 	   assert(nvars == 0 || (coefs != NULL));
2623 	
2624 	   /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2625 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2626 	    * afterwards
2627 	    */
2628 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2629 	   assert(consdata->nconsanddatas == nandress);
2630 	
2631 	   /* if necessary, update the rounding locks of variables */
2632 	   if( SCIPconsIsLocked(cons) )
2633 	   {
2634 	      SCIP_VAR** andvars;
2635 	      int nandvars;
2636 	      SCIP_Real val;
2637 	      int v;
2638 	      int c;
2639 	
2640 	      assert(SCIPconsIsTransformed(cons));
2641 	
2642 	      if( SCIPisInfinity(scip, oldrhs) && !SCIPisInfinity(scip, rhs) )
2643 	      {
2644 	         /* non-linear part */
2645 	         for( c = consdata->nconsanddatas - 1; c >= 0; --c )
2646 	         {
2647 	            CONSANDDATA* consanddata;
2648 	            SCIP_CONS* andcons;
2649 	
2650 	            consanddata = consdata->consanddatas[c];
2651 	            assert(consanddata != NULL);
2652 	
2653 	            andcons = consanddata->cons;
2654 	            assert(andcons != NULL);
2655 	
2656 	            andvars = SCIPgetVarsAnd(scip, andcons);
2657 	            nandvars = SCIPgetNVarsAnd(scip, andcons);
2658 	            val = andnegs[c] ? -andcoefs[c] : andcoefs[c];
2659 	
2660 	            /* lock variables */
2661 	            if( SCIPisPositive(scip, val) )
2662 	            {
2663 	               for( v = nandvars - 1; v >= 0; --v )
2664 	               {
2665 	                  SCIP_CALL( SCIPlockVarCons(scip, andvars[v], cons, FALSE, TRUE) );
2666 	               }
2667 	            }
2668 	            else
2669 	            {
2670 	               for( v = nandvars - 1; v >= 0; --v )
2671 	               {
2672 	                  SCIP_CALL( SCIPlockVarCons(scip, andvars[v], cons, TRUE, FALSE) );
2673 	               }
2674 	            }
2675 	         }
2676 	      }
2677 	      else if( !SCIPisInfinity(scip, oldrhs) && SCIPisInfinity(scip, rhs) )
2678 	      {
2679 	         /* non-linear part */
2680 	         for( c = consdata->nconsanddatas - 1; c >= 0; --c )
2681 	         {
2682 	            CONSANDDATA* consanddata;
2683 	            SCIP_CONS* andcons;
2684 	
2685 	            consanddata = consdata->consanddatas[c];
2686 	            assert(consanddata != NULL);
2687 	
2688 	            andcons = consanddata->cons;
2689 	            assert(andcons != NULL);
2690 	
2691 	            andvars = SCIPgetVarsAnd(scip, andcons);
2692 	            nandvars = SCIPgetNVarsAnd(scip, andcons);
2693 	            val = andnegs[c] ? -andcoefs[c] : andcoefs[c];
2694 	
2695 	            /* lock variables */
2696 	            if( SCIPisPositive(scip, val) )
2697 	            {
2698 	               for( v = nandvars - 1; v >= 0; --v )
2699 	               {
2700 	                  SCIP_CALL( SCIPunlockVarCons(scip, andvars[v], cons, FALSE, TRUE) );
2701 	               }
2702 	            }
2703 	            else
2704 	            {
2705 	               for( v = nandvars - 1; v >= 0; --v )
2706 	               {
2707 	                  SCIP_CALL( SCIPunlockVarCons(scip, andvars[v], cons, TRUE, FALSE) );
2708 	               }
2709 	            }
2710 	         }
2711 	      }
2712 	   }
2713 	
2714 	   /* 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 */
2715 	   if( SCIPisGT(scip, oldrhs, rhs) )
2716 	   {
2717 	      consdata->propagated = FALSE;
2718 	   }
2719 	
2720 	   /* set new right hand side and update constraint data */
2721 	   SCIP_CALL( chgRhsLinearCons(scip, consdata->lincons, consdata->linconstype, rhs) );
2722 	   consdata->rhs = rhs;
2723 	   consdata->presolved = FALSE;
2724 	   consdata->changed = TRUE;
2725 	
2726 	   /* free temporary memory */
2727 	   SCIPfreeBufferArray(scip, &andnegs);
2728 	   SCIPfreeBufferArray(scip, &andcoefs);
2729 	   SCIPfreeBufferArray(scip, &andress);
2730 	   SCIPfreeBufferArray(scip, &lincoefs);
2731 	   SCIPfreeBufferArray(scip, &linvars);
2732 	   SCIPfreeBufferArray(scip, &coefs);
2733 	   SCIPfreeBufferArray(scip, &vars);
2734 	
2735 	   return SCIP_OKAY;
2736 	}
2737 	
2738 	/** create and-constraints and get all and-resultants */
2739 	static
2740 	SCIP_RETCODE createAndAddAnds(
2741 	   SCIP*const            scip,               /**< SCIP data structure */
2742 	   SCIP_CONSHDLR*const   conshdlr,           /**< pseudoboolean constraint handler */
2743 	   SCIP_VAR**const*const terms,              /**< array of term variables to get and-constraints for */
2744 	   SCIP_Real*const       termcoefs,          /**< array of coefficients for and-constraints */
2745 	   int const             nterms,             /**< number of terms to get and-constraints for */
2746 	   int const*const       ntermvars,          /**< array of number of variable in each term */
2747 	   SCIP_Bool const       initial,            /**< should the LP relaxation of constraint be in the initial LP?
2748 	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2749 	   SCIP_Bool const       enforce,            /**< should the constraint be enforced during node processing?
2750 	                                              *   TRUE for model constraints, FALSE for additional, redundant
2751 	                                              *   constraints. */
2752 	   SCIP_Bool const       check,              /**< should the constraint be checked for feasibility?
2753 	                                              *   TRUE for model constraints, FALSE for additional, redundant
2754 	                                              *   constraints. */
2755 	   SCIP_Bool const       local,              /**< is constraint only valid locally?
2756 	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching
2757 	                                              *   constraints. */
2758 	   SCIP_Bool const       modifiable,         /**< is constraint modifiable (subject to column generation)?
2759 	                                              *   Usually set to FALSE. In column generation applications, set to TRUE
2760 	                                              *   if pricing adds coefficients to this constraint. */
2761 	   SCIP_Bool const       dynamic,            /**< is constraint subject to aging?
2762 	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
2763 	                                              *   are seperated as constraints. */
2764 	   SCIP_Bool const       stickingatnode,     /**< should the constraint always be kept at the node where it was added, even
2765 	                                              *   if it may be moved to a more global node?
2766 	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent
2767 	                                              *   node data. */
2768 	   SCIP_CONS**const      andconss,           /**< array to store all created and-constraints for given terms */
2769 	   SCIP_Real*const       andvals,            /**< array to store all coefficients of and-constraints */
2770 	   SCIP_Bool*const       andnegs,            /**< array to store negation status of and-constraints */
2771 	   int*const             nandconss           /**< number of created and constraints */
2772 	   )
2773 	{
2774 	   int t;
2775 	
2776 	   assert(scip != NULL);
2777 	   assert(conshdlr != NULL);
2778 	   assert(nterms == 0 || (terms != NULL && ntermvars != NULL));
2779 	   assert(andconss != NULL);
2780 	   assert(andvals != NULL);
2781 	   assert(nandconss != NULL);
2782 	
2783 	   (*nandconss) = 0;
2784 	
2785 	   if( nterms == 0 )
2786 	      return SCIP_OKAY;
2787 	
2788 	   /* loop over all terms and create/get all and constraints */
2789 	   for( t = 0; t < nterms; ++t )
2790 	   {
2791 	      if( !SCIPisZero(scip, termcoefs[t]) && ntermvars[t] > 0 )
2792 	      {
2793 	         SCIP_CALL( createAndAddAndCons(scip, conshdlr, terms[t], ntermvars[t],
2794 	               initial, enforce, check, local, modifiable, dynamic, stickingatnode,
2795 	               &(andconss[*nandconss])) );
2796 	         assert(andconss[*nandconss] != NULL);
2797 	         andvals[*nandconss] = termcoefs[t];
2798 	         andnegs[*nandconss] = FALSE;
2799 	         ++(*nandconss);
2800 	      }
2801 	   }
2802 	
2803 	   return SCIP_OKAY;
2804 	}
2805 	
2806 	/** created linear constraint of pseudo boolean constraint */
2807 	static
2808 	SCIP_RETCODE createAndAddLinearCons(
2809 	   SCIP*const            scip,               /**< SCIP data structure */
2810 	   SCIP_CONSHDLR*const   conshdlr,           /**< pseudoboolean constraint handler */
2811 	   SCIP_VAR**const       linvars,            /**< linear variables */
2812 	   int const             nlinvars,           /**< number of linear variables */
2813 	   SCIP_Real*const       linvals,            /**< linear coefficients */
2814 	   SCIP_VAR**const       andress,            /**< and-resultant variables */
2815 	   int const             nandress,           /**< number of and-resultant variables */
2816 	   SCIP_Real const*const andvals,            /**< and-resultant coefficients */
2817 	   SCIP_Bool*const       andnegs,            /**< and-resultant negation status */
2818 	   SCIP_Real*const       lhs,                /**< pointer to left hand side of linear constraint */
2819 	   SCIP_Real*const       rhs,                /**< pointer to right hand side of linear constraint */
2820 	   SCIP_Bool const       initial,            /**< should the LP relaxation of constraint be in the initial LP?
2821 	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2822 	   SCIP_Bool const       separate,           /**< should the constraint be separated during LP processing?
2823 	                                              *   Usually set to TRUE. */
2824 	   SCIP_Bool const       enforce,            /**< should the constraint be enforced during node processing?
2825 	                                              *   TRUE for model constraints, FALSE for additional, redundant
2826 	                                              *   constraints. */
2827 	   SCIP_Bool const       check,              /**< should the constraint be checked for feasibility?
2828 	                                              *   TRUE for model constraints, FALSE for additional, redundant
2829 	                                              *   constraints. */
2830 	   SCIP_Bool const       propagate,          /**< should the constraint be propagated during node processing?
2831 	                                              *   Usually set to TRUE. */
2832 	   SCIP_Bool const       local,              /**< is constraint only valid locally?
2833 	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching
2834 	                                              *   constraints. */
2835 	   SCIP_Bool const       modifiable,         /**< is constraint modifiable (subject to column generation)?
2836 	                                              *   Usually set to FALSE. In column generation applications, set to TRUE
2837 	                                              *   if pricing adds coefficients to this constraint. */
2838 	   SCIP_Bool const       dynamic,            /**< is constraint subject to aging?
2839 	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
2840 	                                              *   are seperated as constraints. */
2841 	   SCIP_Bool const       removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
2842 	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user
2843 	                                              *   cuts'. */
2844 	   SCIP_Bool const       stickingatnode,     /**< should the constraint always be kept at the node where it was added, even
2845 	                                              *   if it may be moved to a more global node?
2846 	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent
2847 	                                              *   node data. */
2848 	   SCIP_CONS**const      lincons,            /**< pointer to store created linear constraint */
2849 	   SCIP_LINEARCONSTYPE*const linconstype     /**< pointer to store the type of the linear constraint */
2850 	   )
2851 	{
2852 	   SCIP_CONSHDLRDATA* conshdlrdata;
2853 	   SCIP_CONSHDLR* upgrconshdlr;
2854 	   SCIP_CONS* cons;
2855 	   char name[SCIP_MAXSTRLEN];
2856 	   int v;
2857 	   SCIP_Bool created;
2858 	   SCIP_Bool integral;
2859 	   int nzero;
2860 	   int ncoeffspone;
2861 	   int ncoeffsnone;
2862 	   int ncoeffspint;
2863 	   int ncoeffsnint;
2864 	
2865 	   assert(scip != NULL);
2866 	   assert(conshdlr != NULL);
2867 	   assert(nlinvars == 0 || (linvars != NULL && linvals != NULL));
2868 	   assert(nandress == 0 || (andress != NULL && andvals != NULL));
2869 	   assert(lhs != NULL);
2870 	   assert(rhs != NULL);
2871 	   assert(lincons != NULL);
2872 	   assert(linconstype != NULL);
2873 	   assert(nlinvars > 0 || nandress > 0);
2874 	
2875 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
2876 	   assert(conshdlrdata != NULL);
2877 	
2878 	   (*linconstype) = SCIP_LINEARCONSTYPE_INVALIDCONS;
2879 	   (*lincons) = NULL;
2880 	   cons = NULL;
2881 	
2882 	   (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean_linear%d", conshdlrdata->nlinconss);
2883 	   ++(conshdlrdata->nlinconss);
2884 	
2885 	   created = FALSE;
2886 	
2887 	   if( !modifiable )
2888 	   {
2889 	      SCIP_Real val;
2890 	      int nvars;
2891 	
2892 	      /* calculate some statistics for upgrading on linear constraint */
2893 	      nzero = 0;
2894 	      ncoeffspone = 0;
2895 	      ncoeffsnone = 0;
2896 	      ncoeffspint = 0;
2897 	      ncoeffsnint = 0;
2898 	      integral = TRUE;
2899 	      nvars = nlinvars + nandress;
2900 	
2901 	      /* calculate information over linear part */
2902 	      for( v = nlinvars - 1; v >= 0; --v )
2903 	      {
2904 	         val = linvals[v];
2905 	
2906 	         if( SCIPisZero(scip, val) )
2907 	         {
2908 	            ++nzero;
2909 	            continue;
2910 	         }
2911 	         if( SCIPisEQ(scip, val, 1.0) )
2912 	            ++ncoeffspone;
2913 	         else if( SCIPisEQ(scip, val, -1.0) )
2914 	            ++ncoeffsnone;
2915 	         else if( SCIPisIntegral(scip, val) )
2916 	         {
2917 	            if( SCIPisPositive(scip, val) )
2918 	               ++ncoeffspint;
2919 	            else
2920 	               ++ncoeffsnint;
2921 	         }
2922 	         else
2923 	         {
2924 	            integral = FALSE;
2925 	            break;
2926 	         }
2927 	      }
2928 	
2929 	      if( integral )
2930 	      {
2931 	         /* calculate information over and-resultants */
2932 	         for( v = nandress - 1; v >= 0; --v )
2933 	         {
2934 	            val = andvals[v];
2935 	
2936 	            if( SCIPisZero(scip, val) )
2937 	            {
2938 	               ++nzero;
2939 	               continue;
2940 	            }
2941 	            if( SCIPisEQ(scip, val, 1.0) )
2942 	               ++ncoeffspone;
2943 	            else if( SCIPisEQ(scip, val, -1.0) )
2944 	               ++ncoeffsnone;
2945 	            else if( SCIPisIntegral(scip, val) )
2946 	            {
2947 	               if( SCIPisPositive(scip, val) )
2948 	                  ++ncoeffspint;
2949 	               else
2950 	                  ++ncoeffsnint;
2951 	            }
2952 	            else
2953 	            {
2954 	               integral = FALSE;
2955 	               break;
2956 	            }
2957 	         }
2958 	      }
2959 	
2960 	      SCIPdebugMsg(scip, "While creating the linear constraint of the pseudoboolean constraint we found %d zero coefficients that were removed\n", nzero);
2961 	
2962 	      /* try to upgrade to a special linear constraint */
2963 	      if( integral )
2964 	      {
2965 	         upgrconshdlr = SCIPfindConshdlr(scip, "logicor");
2966 	
2967 	         /* check, if linear constraint can be upgraded to logic or constraint
2968 	          * - logic or constraints consist only of binary variables with a
2969 	          *   coefficient of +1.0 or -1.0 (variables with -1.0 coefficients can be negated):
2970 	          *        lhs     <= x1 + ... + xp - y1 - ... - yn <= rhs
2971 	          * - negating all variables y = (1-Y) with negative coefficients gives:
2972 	          *        lhs + n <= x1 + ... + xp + Y1 + ... + Yn <= rhs + n
2973 	          * - negating all variables x = (1-X) with positive coefficients and multiplying with -1 gives:
2974 	          *        p - rhs <= X1 + ... + Xp + y1 + ... + yn <= p - lhs
2975 	          * - logic or constraints have left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
2976 	          *    -> without negations:  (lhs == 1 - n  and  rhs == +inf)  or  (lhs == -inf  and  rhs = p - 1)
2977 	          */
2978 	         if( upgrconshdlr != NULL && nvars > 2 && ncoeffspone + ncoeffsnone == nvars
2979 	            && ((SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) && SCIPisInfinity(scip, *rhs))
2980 	               || (SCIPisInfinity(scip, -*lhs) && SCIPisEQ(scip, *rhs, ncoeffspone - 1.0))) )
2981 	         {
2982 	            SCIP_VAR** transvars;
2983 	            int mult;
2984 	
2985 	            SCIPdebugMsg(scip, "linear constraint will be logic-or constraint\n");
2986 	
2987 	            /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
2988 	            mult = SCIPisInfinity(scip, *rhs) ? +1 : -1;
2989 	
2990 	            /* get temporary memory */
2991 	            SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
2992 	
2993 	            /* negate positive or negative variables */
2994 	            for( v = 0; v < nlinvars; ++v )
2995 	            {
2996 	               if( mult * linvals[v] > 0.0 )
2997 	                  transvars[v] = linvars[v];
2998 	               else
2999 	               {
3000 	                  SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3001 	               }
3002 	               assert(transvars[v] != NULL);
3003 	            }
3004 	
3005 	            /* negate positive or negative variables */
3006 	            for( v = 0; v < nandress; ++v )
3007 	            {
3008 	               if( mult * andvals[v] > 0.0 )
3009 	                  transvars[nlinvars + v] = andress[v];
3010 	               else
3011 	               {
3012 	                  SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3013 	                  andnegs[v] = TRUE;
3014 	               }
3015 	               assert(transvars[nlinvars + v] != NULL);
3016 	            }
3017 	
3018 	            assert(!modifiable);
3019 	            /* create the constraint */
3020 	            SCIP_CALL( SCIPcreateConsLogicor(scip, &cons, name, nvars, transvars,
3021 	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3022 	
3023 	            created = TRUE;
3024 	            (*linconstype) = SCIP_LINEARCONSTYPE_LOGICOR;
3025 	
3026 	            /* free temporary memory */
3027 	            SCIPfreeBufferArray(scip, &transvars);
3028 	
3029 		    *lhs = 1.0;
3030 		    *rhs = SCIPinfinity(scip);
3031 	         }
3032 	
3033 	         upgrconshdlr = SCIPfindConshdlr(scip, "setppc");
3034 	
3035 	         /* check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint
3036 	          * - all set partitioning / packing / covering constraints consist only of binary variables with a
3037 	          *   coefficient of +1.0 or -1.0 (variables with -1.0 coefficients can be negated):
3038 	          *        lhs     <= x1 + ... + xp - y1 - ... - yn <= rhs
3039 	          * - negating all variables y = (1-Y) with negative coefficients gives:
3040 	          *        lhs + n <= x1 + ... + xp + Y1 + ... + Yn <= rhs + n
3041 	          * - negating all variables x = (1-X) with positive coefficients and multiplying with -1 gives:
3042 	          *        p - rhs <= X1 + ... + Xp + y1 + ... + yn <= p - lhs
3043 	          * - a set partitioning constraint has left hand side of +1.0, and right hand side of +1.0 : x(S) == 1.0
3044 	          *    -> without negations:  lhs == rhs == 1 - n  or  lhs == rhs == p - 1
3045 	          * - a set packing constraint has left hand side of -infinity, and right hand side of +1.0 : x(S) <= 1.0
3046 	          *    -> without negations:  (lhs == -inf  and  rhs == 1 - n)  or  (lhs == p - 1  and  rhs = +inf)
3047 	          * - a set covering constraint has left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
3048 	          *    -> without negations:  (lhs == 1 - n  and  rhs == +inf)  or  (lhs == -inf  and  rhs = p - 1)
3049 	          */
3050 	         if( upgrconshdlr != NULL && !created && ncoeffspone + ncoeffsnone == nvars )
3051 	         {
3052 	            SCIP_VAR** transvars;
3053 	            int mult;
3054 	
3055 	            if( SCIPisEQ(scip, *lhs, *rhs) && (SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) || SCIPisEQ(scip, *lhs, ncoeffspone - 1.0)) )
3056 	            {
3057 	               SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a set partitioning constraint\n");
3058 	
3059 	               /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3060 	               mult = SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) ? +1 : -1;
3061 	
3062 	               /* get temporary memory */
3063 	               SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
3064 	
3065 	               /* negate positive or negative variables for linear variables */
3066 	               for( v = 0; v < nlinvars; ++v )
3067 	               {
3068 	                  if( mult * linvals[v] > 0.0 )
3069 	                     transvars[v] = linvars[v];
3070 	                  else
3071 	                  {
3072 	                     SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3073 	                  }
3074 	                  assert(transvars[v] != NULL);
3075 	               }
3076 	
3077 	               /* negate positive or negative variables for and-resultants */
3078 	               for( v = 0; v < nandress; ++v )
3079 	               {
3080 	                  if( mult * andvals[v] > 0.0 )
3081 	                     transvars[nlinvars + v] = andress[v];
3082 	                  else
3083 	                  {
3084 	                     SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3085 	                     andnegs[v] = TRUE;
3086 	                  }
3087 	                  assert(transvars[nlinvars + v] != NULL);
3088 	               }
3089 	
3090 	               /* create the constraint */
3091 	               assert(!modifiable);
3092 	               SCIP_CALL( SCIPcreateConsSetpart(scip, &cons, name, nvars, transvars,
3093 	                     initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3094 	
3095 	               created = TRUE;
3096 	               (*linconstype) = SCIP_LINEARCONSTYPE_SETPPC;
3097 	
3098 	               /* release temporary memory */
3099 	               SCIPfreeBufferArray(scip, &transvars);
3100 	
3101 		       *lhs = 1.0;
3102 		       *rhs = 1.0;
3103 	            }
3104 	            else if( (SCIPisInfinity(scip, -*lhs) && SCIPisEQ(scip, *rhs, 1.0 - ncoeffsnone))
3105 	               || (SCIPisEQ(scip, *lhs, ncoeffspone - 1.0) && SCIPisInfinity(scip, *rhs)) )
3106 	            {
3107 	               SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a set packing constraint\n");
3108 	
3109 	               /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3110 	               mult = SCIPisInfinity(scip, -*lhs) ? +1 : -1;
3111 	
3112 	               /* get temporary memory */
3113 	               SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
3114 	
3115 	               /* negate positive or negative variables for linear variables */
3116 	               for( v = 0; v < nlinvars; ++v )
3117 	               {
3118 	                  if( mult * linvals[v] > 0.0 )
3119 	                     transvars[v] = linvars[v];
3120 	                  else
3121 	                  {
3122 	                     SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3123 	                  }
3124 	                  assert(transvars[v] != NULL);
3125 	               }
3126 	
3127 	               /* negate positive or negative variables for and-resultants*/
3128 	               for( v = 0; v < nandress; ++v )
3129 	               {
3130 	                  if( mult * andvals[v] > 0.0 )
3131 	                     transvars[nlinvars + v] = andress[v];
3132 	                  else
3133 	                  {
3134 	                     SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3135 	                     andnegs[v] = TRUE;
3136 	                  }
3137 	                  assert(transvars[nlinvars + v] != NULL);
3138 	               }
3139 	
3140 	               /* create the constraint */
3141 	               assert(!modifiable);
3142 	               SCIP_CALL( SCIPcreateConsSetpack(scip, &cons, name, nvars, transvars,
3143 	                     initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3144 	
3145 	               created = TRUE;
3146 	               (*linconstype) = SCIP_LINEARCONSTYPE_SETPPC;
3147 	
3148 	               /* release temporary memory */
3149 	               SCIPfreeBufferArray(scip, &transvars);
3150 	
3151 		       *lhs = -SCIPinfinity(scip);
3152 		       *rhs = 1.0;
3153 	            }
3154 	            else if( (SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) && SCIPisInfinity(scip, *rhs))
3155 	               || (SCIPisInfinity(scip, -*lhs) && SCIPisEQ(scip, *rhs, ncoeffspone - 1.0)) )
3156 	            {
3157 	               if( nvars != 1 )
3158 	               {
3159 	                  if( nvars == 2 )
3160 	                  {
3161 	                     SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a set packing constraint.\n");
3162 	                  }
3163 	                  else
3164 	                  {
3165 	                     SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a logicor constraint.\n");
3166 	                  }
3167 	               }
3168 	               SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a set covering constraint\n");
3169 	
3170 	               /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3171 	               mult = SCIPisInfinity(scip, *rhs) ? +1 : -1;
3172 	
3173 	               /* get temporary memory */
3174 	               SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
3175 	
3176 	               /* negate positive or negative variables for linear variables */
3177 	               for( v = 0; v < nlinvars; ++v )
3178 	               {
3179 	                  if( mult * linvals[v] > 0.0 )
3180 	                     transvars[v] = linvars[v];
3181 	                  else
3182 	                  {
3183 	                     SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3184 	                  }
3185 	                  assert(transvars[v] != NULL);
3186 	               }
3187 	
3188 	               /* negate positive or negative variables for and-resultants*/
3189 	               for( v = 0; v < nandress; ++v )
3190 	               {
3191 	                  if( mult * andvals[v] > 0.0 )
3192 	                     transvars[nlinvars + v] = andress[v];
3193 	                  else
3194 	                  {
3195 	                     SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3196 	                     andnegs[v] = TRUE;
3197 	                  }
3198 	                  assert(transvars[nlinvars + v] != NULL);
3199 	               }
3200 	
3201 	               /* create the constraint */
3202 	               assert(!modifiable);
3203 	               SCIP_CALL( SCIPcreateConsSetcover(scip, &cons, name, nvars, transvars,
3204 	                     initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3205 	
3206 	               created = TRUE;
3207 	               (*linconstype) = SCIP_LINEARCONSTYPE_SETPPC;
3208 	
3209 	               /* release temporary memory */
3210 	               SCIPfreeBufferArray(scip, &transvars);
3211 	
3212 		       *lhs = 1.0;
3213 		       *rhs = SCIPinfinity(scip);
3214 	            }
3215 	         }
3216 	
3217 	         upgrconshdlr = SCIPfindConshdlr(scip, "knapsack");
3218 	
3219 	         /* check, if linear constraint can be upgraded to a knapsack constraint
3220 	          * - all variables must be binary
3221 	          * - all coefficients must be integral
3222 	          * - exactly one of the sides must be infinite
3223 	          */
3224 	         if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && (SCIPisInfinity(scip, -*lhs) != SCIPisInfinity(scip, *rhs)) )
3225 	         {
3226 	            SCIP_VAR** transvars;
3227 	            SCIP_Longint* weights;
3228 	            SCIP_Longint capacity;
3229 	            SCIP_Longint weight;
3230 	            int mult;
3231 	
3232 	            SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a knapsack constraint\n");
3233 	
3234 	            /* get temporary memory */
3235 	            SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
3236 	            SCIP_CALL( SCIPallocBufferArray(scip, &weights, nvars) );
3237 	
3238 	            /* if the right hand side is non-infinite, we have to negate all variables with negative coefficient;
3239 	             * otherwise, we have to negate all variables with positive coefficient and multiply the row with -1
3240 	             */
3241 	            if( SCIPisInfinity(scip, *rhs) )
3242 	            {
3243 	               mult = -1;
3244 	               capacity = (SCIP_Longint)SCIPfeasFloor(scip, -*lhs);
3245 	            }
3246 	            else
3247 	            {
3248 	               mult = +1;
3249 	               capacity = (SCIP_Longint)SCIPfeasFloor(scip, *rhs);
3250 	            }
3251 	
3252 	            /* negate positive or negative variables for linear variables */
3253 	            for( v = 0; v < nlinvars; ++v )
3254 	            {
3255 	               assert(SCIPisFeasIntegral(scip, linvals[v]));
3256 	               weight = mult * (SCIP_Longint)SCIPfeasFloor(scip, linvals[v]);
3257 	               if( weight > 0 )
3258 	               {
3259 	                  transvars[v] = linvars[v];
3260 	                  weights[v] = weight;
3261 	               }
3262 	               else
3263 	               {
3264 	                  SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3265 	                  weights[v] = -weight;
3266 	                  capacity -= weight;
3267 	               }
3268 	               assert(transvars[v] != NULL);
3269 	            }
3270 	            /* negate positive or negative variables for and-resultants */
3271 	            for( v = 0; v < nandress; ++v )
3272 	            {
3273 	               assert(SCIPisFeasIntegral(scip, andvals[v]));
3274 	               weight = mult * (SCIP_Longint)SCIPfeasFloor(scip, andvals[v]);
3275 	               if( weight > 0 )
3276 	               {
3277 	                  transvars[nlinvars + v] = andress[v];
3278 	                  weights[nlinvars + v] = weight;
3279 	               }
3280 	               else
3281 	               {
3282 	                  SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3283 	                  andnegs[v] = TRUE;
3284 	                  weights[nlinvars + v] = -weight;
3285 	                  capacity -= weight;
3286 	               }
3287 	               assert(transvars[nlinvars + v] != NULL);
3288 	            }
3289 	
3290 	            /* create the constraint */
3291 	            SCIP_CALL( SCIPcreateConsKnapsack(scip, &cons, name, nvars, transvars, weights, capacity,
3292 	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3293 	
3294 	            created = TRUE;
3295 	            (*linconstype) = SCIP_LINEARCONSTYPE_KNAPSACK;
3296 	
3297 	            /* free temporary memory */
3298 	            SCIPfreeBufferArray(scip, &weights);
3299 	            SCIPfreeBufferArray(scip, &transvars);
3300 	
3301 		    *lhs = -SCIPinfinity(scip);
3302 		    *rhs = capacity;
3303 	         }
3304 	#ifdef WITHEQKNAPSACK
3305 	
3306 	         upgrconshdlr = SCIPfindConshdlr(scip, "eqknapsack");
3307 	
3308 	         /* check, if linear constraint can be upgraded to a knapsack constraint
3309 	          * - all variables must be binary
3310 	          * - all coefficients must be integral
3311 	          * - both sides must be infinite
3312 	          */
3313 	         if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && SCIPisEQ(scip, *lhs, *rhs) )
3314 	         {
3315 	            SCIP_VAR** transvars;
3316 	            SCIP_Longint* weights;
3317 	            SCIP_Longint capacity;
3318 	            SCIP_Longint weight;
3319 	            int mult;
3320 	
3321 	            assert(!SCIPisInfinity(scip, *rhs));
3322 	
3323 	            SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a equality-knapsack constraint\n");
3324 	
3325 	            /* get temporary memory */
3326 	            SCIP_CALL( SCIPallocBufferArray(scip, &transvars, nvars) );
3327 	            SCIP_CALL( SCIPallocBufferArray(scip, &weights, nvars) );
3328 	
3329 	            if( SCIPisPositive(scip, *rhs) )
3330 	            {
3331 	               mult = +1;
3332 	               capacity = (SCIP_Longint)SCIPfeasFloor(scip, *rhs);
3333 	            }
3334 	            else
3335 	            {
3336 	               mult = -1;
3337 	               capacity = (SCIP_Longint)SCIPfeasFloor(scip, -*rhs);
3338 	            }
3339 	
3340 	            /* negate positive or negative variables for linear variables */
3341 	            for( v = 0; v < nlinvars; ++v )
3342 	            {
3343 	               assert(SCIPisFeasIntegral(scip, linvals[v]));
3344 	               weight = mult * (SCIP_Longint)SCIPfeasFloor(scip, linvals[v]);
3345 	               if( weight > 0 )
3346 	               {
3347 	                  transvars[v] = linvars[v];
3348 	                  weights[v] = weight;
3349 	               }
3350 	               else
3351 	               {
3352 	                  SCIP_CALL( SCIPgetNegatedVar(scip, linvars[v], &transvars[v]) );
3353 	                  weights[v] = -weight;
3354 	                  capacity -= weight;
3355 	               }
3356 	               assert(transvars[v] != NULL);
3357 	            }
3358 	            /* negate positive or negative variables for and-resultants */
3359 	            for( v = 0; v < nandress; ++v )
3360 	            {
3361 	               assert(SCIPisFeasIntegral(scip, andvals[v]));
3362 	               weight = mult * (SCIP_Longint)SCIPfeasFloor(scip, andvals[v]);
3363 	               if( weight > 0 )
3364 	               {
3365 	                  transvars[nlinvars + v] = andress[v];
3366 	                  weights[nlinvars + v] = weight;
3367 	               }
3368 	               else
3369 	               {
3370 	                  SCIP_CALL( SCIPgetNegatedVar(scip, andress[v], &transvars[nlinvars + v]) );
3371 	                  andnegs[v] = TRUE;
3372 	                  weights[nlinvars + v] = -weight;
3373 	                  capacity -= weight;
3374 	               }
3375 	               assert(transvars[nlinvars + v] != NULL);
3376 	            }
3377 	
3378 	            /* create the constraint */
3379 	            SCIP_CALL( SCIPcreateConsEqKnapsack(scip, &cons, name, nvars, transvars, weights, capacity,
3380 	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3381 	
3382 	            created = TRUE;
3383 	            (*linconstype) = SCIP_LINEARCONSTYPE_EQKNAPSACK;
3384 	
3385 	            /* free temporary memory */
3386 	            SCIPfreeBufferArray(scip, &weights);
3387 	            SCIPfreeBufferArray(scip, &transvars);
3388 	
3389 		    *lhs = capacity;
3390 		    *rhs = capacity;
3391 	         }
3392 	#endif
3393 	      }
3394 	   }
3395 	
3396 	   upgrconshdlr = SCIPfindConshdlr(scip, "linear");
3397 	   assert(created || upgrconshdlr != NULL);
3398 	
3399 	   if( !created )
3400 	   {
3401 	      SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, nlinvars, linvars, linvals, *lhs, *rhs,
3402 	            initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3403 	
3404 	      (*linconstype) = SCIP_LINEARCONSTYPE_LINEAR;
3405 	
3406 	      /* add all and-resultants */
3407 	      for( v = 0; v < nandress; ++v )
3408 	      {
3409 	         assert(andress[v] != NULL);
3410 	
3411 	         /* add auxiliary variables to linear constraint */
3412 	         SCIP_CALL( SCIPaddCoefLinear(scip, cons, andress[v], andvals[v]) );
3413 	      }
3414 	   }
3415 	
3416 	   assert(cons != NULL && *linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
3417 	
3418 	   SCIP_CALL( SCIPaddCons(scip, cons) );
3419 	   SCIPdebugPrintCons(scip, cons, NULL);
3420 	
3421 	   *lincons = cons;
3422 	   SCIP_CALL( SCIPcaptureCons(scip, *lincons) );
3423 	
3424 	   /* mark linear constraint not to be upgraded - otherwise we loose control over it */
3425 	   SCIPconsAddUpgradeLocks(cons, 1);
3426 	
3427 	   SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3428 	
3429 	   return SCIP_OKAY;
3430 	}
3431 	
3432 	/** checks one original pseudoboolean constraint for feasibility of given solution */
3433 	static
3434 	SCIP_RETCODE checkOrigPbCons(
3435 	   SCIP*const            scip,               /**< SCIP data structure */
3436 	   SCIP_CONS*const       cons,               /**< pseudo boolean constraint */
3437 	   SCIP_SOL*const        sol,                /**< solution to be checked, or NULL for current solution */
3438 	   SCIP_Bool*const       violated,           /**< pointer to store whether the constraint is violated */
3439 	   SCIP_Bool const       printreason         /**< should violation of constraint be printed */
3440 	   )
3441 	{
3442 	   SCIP_CONSDATA* consdata;
3443 	   SCIP_CONSHDLR* conshdlr;
3444 	   SCIP_CONSHDLRDATA* conshdlrdata;
3445 	
3446 	   SCIP_VAR** vars;
3447 	   SCIP_Real* coefs;
3448 	   int nvars;
3449 	   SCIP_Real lhs;
3450 	   SCIP_Real rhs;
3451 	
3452 	   SCIP_VAR** linvars;
3453 	   SCIP_Real* lincoefs;
3454 	   int nlinvars;
3455 	   int v;
3456 	
3457 	   SCIP_VAR** andress;
3458 	   SCIP_Real* andcoefs;
3459 	   int nandress;
3460 	
3461 	   SCIP_CONS* andcons;
3462 	   SCIP_Real andvalue;
3463 	   SCIP_Real activity;
3464 	   int c;
3465 	
3466 	   SCIP_Real lhsviol;
3467 	   SCIP_Real rhsviol;
3468 	   SCIP_Real absviol;
3469 	   SCIP_Real relviol;
3470 	
3471 	   assert(scip != NULL);
3472 	   assert(cons != NULL);
3473 	   assert(SCIPconsIsOriginal(cons));
3474 	   assert(violated != NULL);
3475 	
3476 	   *violated = FALSE;
3477 	
3478 	   SCIPdebugMsg(scip, "checking original pseudo boolean constraint <%s>\n", SCIPconsGetName(cons));
3479 	   SCIPdebugPrintCons(scip, cons, NULL);
3480 	
3481 	   consdata = SCIPconsGetData(cons);
3482 	   assert(consdata != NULL);
3483 	   assert(consdata->lincons != NULL);
3484 	   assert(consdata->linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
3485 	   assert(SCIPconsIsOriginal(consdata->lincons));
3486 	
3487 	   /* gets number of variables in linear constraint */
3488 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
3489 	
3490 	   /* allocate temporary memory */
3491 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
3492 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
3493 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
3494 	   SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
3495 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nvars) );
3496 	   SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nvars) );
3497 	
3498 	   /* get sides of linear constraint */
3499 	   SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &lhs, &rhs) );
3500 	   assert(!SCIPisInfinity(scip, lhs));
3501 	   assert(!SCIPisInfinity(scip, -rhs));
3502 	   assert(SCIPisLE(scip, lhs, rhs));
3503 	
3504 	   /* get variables and coefficient of linear constraint */
3505 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
3506 	   assert(nvars == 0 || (coefs != NULL));
3507 	
3508 	   /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
3509 	    * have to be equal to the number of variables in the linear constraint
3510 	    */
3511 	   assert(consdata->nlinvars + consdata->nconsanddatas == nvars);
3512 	
3513 	   nlinvars = 0;
3514 	
3515 	   conshdlr = SCIPconsGetHdlr(cons);
3516 	   assert(conshdlr != NULL);
3517 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
3518 	   assert(conshdlrdata != NULL);
3519 	   assert(conshdlrdata->hashmap != NULL);
3520 	
3521 	   nandress = 0;
3522 	
3523 	   activity = 0.0;
3524 	
3525 	   /* split variables into original and artificial variables and compute activity on normal linear variables (without
3526 	    * terms)
3527 	    */
3528 	   for( v = 0; v < nvars; ++v )
3529 	   {
3530 	      SCIP_VAR* hashmapvar;
3531 	      SCIP_Bool negated;
3532 	
3533 	      assert(vars[v] != NULL);
3534 	
3535 	      /* negated variables can also exist in the original problem, so we need to check */
3536 	      if( !SCIPhashmapExists(conshdlrdata->hashmap, (void*)(vars[v])) && SCIPvarIsNegated(vars[v]) )
3537 	      {
3538 	         hashmapvar = SCIPvarGetNegationVar(vars[v]);
3539 	         negated = TRUE;
3540 	      }
3541 	      else
3542 	      {
3543 	         hashmapvar = vars[v];
3544 	         negated = FALSE;
3545 	      }
3546 	      assert(hashmapvar != NULL);
3547 	
3548 	      if( !SCIPhashmapExists(conshdlrdata->hashmap, (void*)(hashmapvar)) )
3549 	      {
3550 	         assert(!SCIPhashmapExists(conshdlrdata->hashmap, (void*)(vars[v])));
3551 	
3552 	         activity += coefs[v] * SCIPgetSolVal(scip, sol, vars[v]);
3553 	
3554 	         linvars[nlinvars] = vars[v];
3555 	         lincoefs[nlinvars] = coefs[v];
3556 	         ++nlinvars;
3557 	      }
3558 	      else
3559 	      {
3560 	         /* negate coefficient in case of an original negated variable */
3561 	         andress[nandress] = hashmapvar;
3562 	         if( negated )
3563 	         {
3564 	            if( !SCIPisInfinity(scip, -lhs) )
3565 	               lhs -= coefs[v];
3566 	            if( !SCIPisInfinity(scip, rhs) )
3567 	               rhs -= coefs[v];
3568 	            andcoefs[nandress] = -coefs[v];
3569 	         }
3570 	         else
3571 	            andcoefs[nandress] = coefs[v];
3572 	         ++nandress;
3573 	      }
3574 	   }
3575 	   assert(nandress == consdata->nconsanddatas);
3576 	
3577 	   SCIPsortPtrReal((void**)andress, andcoefs, SCIPvarComp, nandress);
3578 	
3579 	   SCIPdebugMsg(scip, "nlinvars = %d, nandress = %d\n", nlinvars, nandress);
3580 	   SCIPdebugMsg(scip, "linear activity = %g\n", activity);
3581 	
3582 	   /* compute and add solution values on terms */
3583 	   for( c = consdata->nconsanddatas - 1; c >= 0; --c )
3584 	   {
3585 	      SCIP_VAR** andvars;
3586 	      int nandvars;
3587 	#ifndef NDEBUG
3588 	      SCIP_VAR* res;
3589 	#endif
3590 	      andcons = consdata->consanddatas[c]->origcons;
3591 	
3592 	      /* if after during or before presolving a solution will be transformed into original space and will be checked
3593 	       * there, but origcons was already removed and only the pointer to the transformed and-constraint is existing
3594 	       */
3595 	      if( andcons == NULL )
3596 	      {
3597 	         andcons = consdata->consanddatas[c]->cons;
3598 	      }
3599 	      assert(andcons != NULL);
3600 	
3601 	      andvars = SCIPgetVarsAnd(scip, andcons);
3602 	      nandvars = SCIPgetNVarsAnd(scip, andcons);
3603 	
3604 	#ifndef NDEBUG
3605 	      res = SCIPgetResultantAnd(scip, andcons);
3606 	      assert(nandvars == 0 || (andvars != NULL && res != NULL));
3607 	      assert(res == andress[c]);
3608 	#endif
3609 	
3610 	      andvalue = 1;
3611 	      /* check if the and-constraint is violated */
3612 	      for( v = nandvars - 1; v >= 0; --v )
3613 	      {
3614 	         andvalue *= SCIPgetSolVal(scip, sol, andvars[v]);
3615 	         if( SCIPisFeasZero(scip, andvalue) )
3616 	            break;
3617 	      }
3618 	      activity += andvalue * andcoefs[c];
3619 	   }
3620 	   SCIPdebugMsg(scip, "lhs = %g, overall activity = %g, rhs = %g\n", lhs, activity, rhs);
3621 	
3622 	   /* calculate absolute and relative violation */
3623 	   lhsviol = lhs - activity;
3624 	   rhsviol = activity - rhs;
3625 	
3626 	   if(lhsviol > rhsviol)
3627 	   {
3628 	      absviol = lhsviol;
3629 	      relviol = SCIPrelDiff(lhs, activity);
3630 	   }
3631 	   else
3632 	   {
3633 	      absviol = rhsviol;
3634 	      relviol = SCIPrelDiff(activity, rhs);
3635 	   }
3636 	
3637 	   /* update absolute and relative violation of the solution */
3638 	   if( sol != NULL )
3639 	      SCIPupdateSolConsViolation(scip, sol, absviol, relviol);
3640 	
3641 	   /* check left hand side for violation */
3642 	   if( SCIPisFeasLT(scip, activity, lhs) )
3643 	   {
3644 	      if( printreason )
3645 	      {
3646 	         SCIP_CALL( SCIPprintCons(scip, cons, NULL ) );
3647 		 SCIPinfoMessage(scip, NULL, ";\n");
3648 	         SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", lhs - activity);
3649 	
3650 	         /* print linear constraint in SCIP_DEBUG mode too */
3651 	         SCIPdebugPrintCons(scip, SCIPconsGetData(cons)->lincons, NULL);
3652 	      }
3653 	
3654 	      *violated = TRUE;
3655 	   }
3656 	
3657 	   /* check right hand side for violation */
3658 	   if( SCIPisFeasGT(scip, activity, rhs) )
3659 	   {
3660 	      if( printreason )
3661 	      {
3662 	         SCIP_CALL( SCIPprintCons(scip, cons, NULL ) );
3663 		 SCIPinfoMessage(scip, NULL, ";\n");
3664 	         SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - rhs);
3665 	      }
3666 	
3667 	      *violated = TRUE;
3668 	   }
3669 	
3670 	   /* free temporary memory */
3671 	   SCIPfreeBufferArray(scip, &andcoefs);
3672 	   SCIPfreeBufferArray(scip, &andress);
3673 	   SCIPfreeBufferArray(scip, &lincoefs);
3674 	   SCIPfreeBufferArray(scip, &linvars);
3675 	   SCIPfreeBufferArray(scip, &coefs);
3676 	   SCIPfreeBufferArray(scip, &vars);
3677 	
3678 	   return SCIP_OKAY;
3679 	}
3680 	
3681 	/** checks all and-constraints inside the pseudoboolean constraint handler for feasibility of given solution or current
3682 	 *  solution
3683 	 */
3684 	static
3685 	SCIP_RETCODE checkAndConss(
3686 	   SCIP*const            scip,               /**< SCIP data structure */
3687 	   SCIP_CONSHDLR*const   conshdlr,           /**< pseudo boolean constraint handler */
3688 	   SCIP_SOL*const        sol,                /**< solution to be checked, or NULL for current solution */
3689 	   SCIP_Bool*const       violated            /**< pointer to store whether the constraint is violated */
3690 	   )
3691 	{
3692 	   SCIP_CONSHDLRDATA* conshdlrdata;
3693 	   SCIP_CONS* andcons;
3694 	   SCIP_VAR** vars;
3695 	   SCIP_VAR* res;
3696 	   int nvars;
3697 	   int c;
3698 	   int v;
3699 	
3700 	   assert(scip != NULL);
3701 	   assert(conshdlr != NULL);
3702 	   assert(violated != NULL);
3703 	
3704 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
3705 	   assert(conshdlrdata != NULL);
3706 	
3707 	   *violated = FALSE;
3708 	
3709 	   for( c = conshdlrdata->nallconsanddatas - 1; c >= 0; --c )
3710 	   {
3711 	      SCIP_Real solval;
3712 	      SCIP_Real minsolval;
3713 	      SCIP_Real sumsolval;
3714 	      SCIP_Real viol;
3715 	
3716 	      if( !conshdlrdata->allconsanddatas[c]->istransformed )
3717 	         continue;
3718 	
3719 	      andcons = conshdlrdata->allconsanddatas[c]->cons;
3720 	
3721 	      /* need to check even locally deleted constraints */
3722 	      if( andcons == NULL ) /*|| !SCIPconsIsActive(andcons) )*/
3723 	         continue;
3724 	
3725 	      vars = SCIPgetVarsAnd(scip, andcons);
3726 	      nvars = SCIPgetNVarsAnd(scip, andcons);
3727 	      res = SCIPgetResultantAnd(scip, andcons);
3728 	      assert(nvars == 0 || (vars != NULL && res != NULL));
3729 	
3730 	      /* check if the and-constraint is violated */
3731 	      minsolval = 1.0;
3732 	      sumsolval = 0.0;
3733 	      for( v = nvars - 1; v >= 0; --v )
3734 	      {
3735 	         solval = SCIPgetSolVal(scip, sol, vars[v]);
3736 	
3737 	         if( solval < minsolval )
3738 	            minsolval = solval;
3739 	
3740 	         sumsolval += solval;
3741 	      }
3742 	
3743 	      /* the resultant must be at most as large as every operator
3744 	       * and at least as large as one minus the sum of negated operators
3745 	       */
3746 	      solval = SCIPgetSolVal(scip, sol, res);
3747 	      viol = MAX3(0.0, solval - minsolval, sumsolval - (nvars - 1.0 + solval));
3748 	
3749 	      if( SCIPisFeasPositive(scip, viol) )
3750 	      {
3751 	         /* only reset constraint age if we are in enforcement */
3752 	         if( sol == NULL )
3753 	         {
3754 	            SCIP_CALL( SCIPresetConsAge(scip, andcons) );
3755 	         }
3756 	
3757 	         *violated = TRUE;
3758 	         break;
3759 	      }
3760 	      else if( sol == NULL )
3761 	      {
3762 	         SCIP_CALL( SCIPincConsAge(scip, andcons) );
3763 	      }
3764 	   }
3765 	
3766 	   return SCIP_OKAY;
3767 	}
3768 	
3769 	/** creates by copying and captures a linear constraint */
3770 	static
3771 	SCIP_RETCODE copyConsPseudoboolean(
3772 	   SCIP*const            targetscip,         /**< target SCIP data structure */
3773 	   SCIP_CONS**           targetcons,         /**< pointer to store the created target constraint */
3774 	   SCIP*const            sourcescip,         /**< source SCIP data structure */
3775 	   SCIP_CONS*const       sourcecons,         /**< source constraint which will be copied */
3776 	   const char*           name,               /**< name of constraint */
3777 	   SCIP_HASHMAP*const    varmap,             /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
3778 	                                              *   variables of the target SCIP */
3779 	   SCIP_HASHMAP*const    consmap,            /**< a hashmap to store the mapping of source constraints to the corresponding
3780 	                                              *   target constraints */
3781 	   SCIP_Bool const       initial,            /**< should the LP relaxation of constraint be in the initial LP? */
3782 	   SCIP_Bool const       separate,           /**< should the constraint be separated during LP processing? */
3783 	   SCIP_Bool const       enforce,            /**< should the constraint be enforced during node processing? */
3784 	   SCIP_Bool const       check,              /**< should the constraint be checked for feasibility? */
3785 	   SCIP_Bool const       propagate,          /**< should the constraint be propagated during node processing? */
3786 	   SCIP_Bool const       local,              /**< is constraint only valid locally? */
3787 	   SCIP_Bool const       modifiable,         /**< is constraint modifiable (subject to column generation)? */
3788 	   SCIP_Bool const       dynamic,            /**< is constraint subject to aging? */
3789 	   SCIP_Bool const       removable,          /**< should the relaxation be removed from the LP due to aging or cleanup? */
3790 	   SCIP_Bool const       stickingatnode,     /**< should the constraint always be kept at the node where it was added, even
3791 	                                              *   if it may be moved to a more global node? */
3792 	   SCIP_Bool const       global,             /**< create a global or a local copy? */
3793 	   SCIP_Bool*const       valid               /**< pointer to store if the copying was valid */
3794 	   )
3795 	{
3796 	   SCIP_CONSDATA* sourceconsdata;
3797 	   SCIP_CONS* sourcelincons;
3798 	
3799 	   assert(targetscip != NULL);
3800 	   assert(targetcons != NULL);
3801 	   assert(sourcescip != NULL);
3802 	   assert(sourcecons != NULL);
3803 	   assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) == 0);
3804 	   assert(valid != NULL);
3805 	
3806 	   *valid = TRUE;
3807 	
3808 	   sourceconsdata = SCIPconsGetData(sourcecons);
3809 	   assert(sourceconsdata != NULL);
3810 	
3811 	   /* get linear constraint */
3812 	   sourcelincons = sourceconsdata->lincons;
3813 	   assert(sourcelincons != NULL);
3814 	
3815 	   /* get copied version of linear constraint */
3816 	   if( !SCIPconsIsDeleted(sourcelincons) )
3817 	   {
3818 	      SCIP_CONSHDLR* conshdlrlinear;
3819 	      SCIP_CONS* targetlincons;
3820 	      SCIP_CONS** targetandconss;
3821 	      SCIP_Real* targetandcoefs;
3822 	      int ntargetandconss;
3823 	      SCIP_LINEARCONSTYPE targetlinconstype;
3824 	
3825 	      targetlinconstype = sourceconsdata->linconstype;
3826 	
3827 	      switch( targetlinconstype )
3828 	      {
3829 	      case SCIP_LINEARCONSTYPE_LINEAR:
3830 	         conshdlrlinear = SCIPfindConshdlr(sourcescip, "linear");
3831 	         assert(conshdlrlinear != NULL);
3832 	         break;
3833 	      case SCIP_LINEARCONSTYPE_LOGICOR:
3834 	         conshdlrlinear = SCIPfindConshdlr(sourcescip, "logicor");
3835 	         assert(conshdlrlinear != NULL);
3836 	         break;
3837 	      case SCIP_LINEARCONSTYPE_KNAPSACK:
3838 	         conshdlrlinear = SCIPfindConshdlr(sourcescip, "knapsack");
3839 	         assert(conshdlrlinear != NULL);
3840 	         break;
3841 	      case SCIP_LINEARCONSTYPE_SETPPC:
3842 	         conshdlrlinear = SCIPfindConshdlr(sourcescip, "setppc");
3843 	         assert(conshdlrlinear != NULL);
3844 	         break;
3845 	#ifdef WITHEQKNAPSACK
3846 	      case SCIP_LINEARCONSTYPE_EQKNAPSACK:
3847 	         conshdlrlinear = SCIPfindConshdlr(sourcescip, "eqknapsack");
3848 	         assert(conshdlrlinear != NULL);
3849 	         break;
3850 	#endif
3851 	      case SCIP_LINEARCONSTYPE_INVALIDCONS:
3852 	      default:
3853 	         SCIPerrorMessage("unknown linear constraint type\n");
3854 	         return SCIP_INVALIDDATA;
3855 	      }
3856 	
3857 	      if( conshdlrlinear == NULL ) /*lint !e774*/
3858 	      {
3859 	         SCIPerrorMessage("linear constraint handler not found\n");
3860 	         return SCIP_INVALIDDATA;
3861 	      }
3862 	
3863 	      targetlincons = NULL;
3864 	
3865 	      /* copy linear constraint */
3866 	      SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, sourcelincons, &targetlincons, conshdlrlinear, varmap, consmap, SCIPconsGetName(sourcelincons),
3867 	            SCIPconsIsInitial(sourcelincons), SCIPconsIsSeparated(sourcelincons), SCIPconsIsEnforced(sourcelincons), SCIPconsIsChecked(sourcelincons),
3868 	            SCIPconsIsPropagated(sourcelincons), SCIPconsIsLocal(sourcelincons), SCIPconsIsModifiable(sourcelincons), SCIPconsIsDynamic(sourcelincons),
3869 	            SCIPconsIsRemovable(sourcelincons), SCIPconsIsStickingAtNode(sourcelincons), global, valid) );
3870 	
3871 	      if( *valid )
3872 	      {
3873 	         assert(targetlincons != NULL);
3874 	         assert(SCIPconsGetHdlr(targetlincons) != NULL);
3875 	         /* @note  due to copying special linear constraints, now leads only to simple linear constraints, we check that
3876 	          *        our target constraint handler is the same as our source constraint handler of the linear constraint,
3877 	          *        if not copying was not valid
3878 	          */
3879 	         if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(targetlincons)), "linear") == 0 )
3880 	            targetlinconstype = SCIP_LINEARCONSTYPE_LINEAR;
3881 	      }
3882 	
3883 	      targetandconss = NULL;
3884 	      targetandcoefs = NULL;
3885 	      ntargetandconss = 0;
3886 	
3887 	      if( *valid )
3888 	      {
3889 	         SCIP_CONSHDLR* conshdlrand;
3890 	         int c;
3891 	         int nsourceandconss;
3892 	         SCIP_HASHTABLE* linconsvarsmap;
3893 	         SCIP_VAR** targetlinvars;
3894 	         SCIP_Real* targetlincoefs;
3895 	         int ntargetlinvars;
3896 	
3897 	         conshdlrand = SCIPfindConshdlr(sourcescip, "and");
3898 	         assert(conshdlrand != NULL);
3899 	
3900 	         nsourceandconss = sourceconsdata->nconsanddatas;
3901 	
3902 	         /* allocate temporary memory */
3903 	         SCIP_CALL( SCIPallocBufferArray(sourcescip, &targetandconss, nsourceandconss) );
3904 	         SCIP_CALL( SCIPallocBufferArray(sourcescip, &targetandcoefs, nsourceandconss) );
3905 	
3906 	         /* get the number of vars in the copied linear constraint and allocate buffers
3907 	          * for the variables and the coefficients
3908 	          */
3909 	         SCIP_CALL( getLinearConsNVars(targetscip, targetlincons, targetlinconstype, &ntargetlinvars) );
3910 	         SCIP_CALL( SCIPallocBufferArray(sourcescip, &targetlinvars, ntargetlinvars) );
3911 	         SCIP_CALL( SCIPallocBufferArray(sourcescip, &targetlincoefs, ntargetlinvars) );
3912 	
3913 	         /* retrieve the variables of the copied linear constraint */
3914 	         SCIP_CALL( getLinearConsVarsData(targetscip, targetlincons, targetlinconstype,
3915 	                                          targetlinvars, targetlincoefs, &ntargetlinvars) );
3916 	
3917 	         /* now create a hashtable and insert the variables into it, so that it
3918 	          * can be checked in constant time if a variable was removed due to
3919 	          * compressed copying when looping over the and resultants
3920 	          */
3921 	         SCIP_CALL( SCIPhashtableCreate(&linconsvarsmap, SCIPblkmem(targetscip), ntargetlinvars, SCIPvarGetHashkey,
3922 	                                        SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
3923 	
3924 	         for( c = 0 ; c < ntargetlinvars; ++c )
3925 	         {
3926 	            SCIP_CALL( SCIPhashtableInsert(linconsvarsmap, targetlinvars[c]) );
3927 	         }
3928 	
3929 	         /* free the buffer arrays that were only required for building the hastable */
3930 	         SCIPfreeBufferArray(sourcescip, &targetlincoefs);
3931 	         SCIPfreeBufferArray(sourcescip, &targetlinvars);
3932 	
3933 	         for( c = 0 ; c < nsourceandconss; ++c )
3934 	         {
3935 	            CONSANDDATA* consanddata;
3936 	            SCIP_CONS* oldcons;
3937 	            SCIP_VAR* targetandresultant;
3938 	            SCIP_Bool validand;
3939 	
3940 	            consanddata = sourceconsdata->consanddatas[c];
3941 	            assert(consanddata != NULL);
3942 	
3943 	            oldcons = consanddata->cons;
3944 	            assert(oldcons != NULL);
3945 	
3946 	            targetandresultant = (SCIP_VAR*) SCIPhashmapGetImage(varmap, SCIPgetResultantAnd(sourcescip, oldcons));
3947 	            assert(targetandresultant != NULL);
3948 	
3949 	            /* if compressed copying is active, the resultant might not have been copied by the linear
3950 	             * constraint and we don't need to add it to the pseudo boolean constraint in this case
3951 	             */
3952 	            if( !SCIPhashtableExists(linconsvarsmap, targetandresultant) )
3953 	               continue;
3954 	
3955 	            validand = TRUE;
3956 	
3957 	            targetandconss[ntargetandconss] = NULL;
3958 	
3959 	            /* copy and-constraints */
3960 	            SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, oldcons, &targetandconss[ntargetandconss], conshdlrand, varmap, consmap, SCIPconsGetName(oldcons),
3961 	                  SCIPconsIsInitial(oldcons), SCIPconsIsSeparated(oldcons), SCIPconsIsEnforced(oldcons), SCIPconsIsChecked(oldcons),
3962 	                  SCIPconsIsPropagated(oldcons), SCIPconsIsLocal(oldcons), SCIPconsIsModifiable(oldcons), SCIPconsIsDynamic(oldcons),
3963 	                  SCIPconsIsRemovable(oldcons), SCIPconsIsStickingAtNode(oldcons), global, &validand) );
3964 	
3965 	            *valid &= validand;
3966 	
3967 	            if( validand )
3968 	            {
3969 	               targetandcoefs[ntargetandconss] = sourceconsdata->andcoefs[c];
3970 	               ++ntargetandconss;
3971 	            }
3972 	         }
3973 	
3974 	         SCIPhashtableFree(&linconsvarsmap);
3975 	         assert(ntargetandconss <= ntargetlinvars);
3976 	      }
3977 	
3978 	      /* no correct pseudoboolean constraint */
3979 	      if( ntargetandconss == 0 )
3980 	      {
3981 	         SCIPdebugMsg(sourcescip, "no and-constraints copied for pseudoboolean constraint <%s>\n", SCIPconsGetName(sourcecons));
3982 	         *valid = FALSE;
3983 	      }
3984 	
3985 	      if( *valid )
3986 	      {
3987 	         SCIP_Real targetrhs;
3988 	         SCIP_Real targetlhs;
3989 	
3990 	         SCIP_VAR* intvar;
3991 	         SCIP_VAR* indvar;
3992 	         const char* consname;
3993 	
3994 	         /* third the indicator and artificial integer variable part */
3995 	         assert(sourceconsdata->issoftcons == (sourceconsdata->indvar != NULL));
3996 	         indvar = sourceconsdata->indvar;
3997 	         intvar = sourceconsdata->intvar;
3998 	
3999 	         /* copy indicator variable */
4000 	         if( indvar != NULL )
4001 	         {
4002 	            assert(*valid);
4003 	            SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, indvar, &indvar, varmap, consmap, global, valid) );
4004 	            assert(!(*valid) || indvar != NULL);
4005 	         }
4006 	         /* copy artificial integer variable */
4007 	         if( intvar != NULL && *valid )
4008 	         {
4009 	            SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, intvar, &intvar, varmap, consmap, global, valid) );
4010 	            assert(!(*valid) || intvar != NULL);
4011 	         }
4012 	
4013 	         if( *valid )
4014 	         {
4015 	            if( name != NULL )
4016 	               consname = name;
4017 	            else
4018 	               consname = SCIPconsGetName(sourcecons);
4019 	
4020 	            /* get new left and right hand sides of copied linear constraint since
4021 	             * they might have changed if compressed copying is used
4022 	             */
4023 	            SCIP_CALL( getLinearConsSides(targetscip, targetlincons, targetlinconstype, &targetlhs, &targetrhs) );
4024 	
4025 	            /* create new pseudoboolean constraint */
4026 	            /* coverity[var_deref_op] */
4027 	            /* coverity[var_deref_model] */
4028 	            SCIP_CALL( SCIPcreateConsPseudobooleanWithConss(targetscip, targetcons, consname,
4029 	                  targetlincons, targetlinconstype, targetandconss, targetandcoefs, ntargetandconss,
4030 	                  indvar, sourceconsdata->weight, sourceconsdata->issoftcons, intvar, targetlhs, targetrhs,
4031 	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
4032 	         }
4033 	      }
4034 	
4035 	      if( !(*valid) && !SCIPisConsCompressionEnabled(sourcescip) )
4036 	      {
4037 	         SCIPverbMessage(sourcescip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy constraint <%s>\n", SCIPconsGetName(sourcecons));
4038 	      }
4039 	
4040 	      /* release copied linear constraint */
4041 	      if( targetlincons != NULL )
4042 	      {
4043 	         SCIP_CALL( SCIPreleaseCons(targetscip, &targetlincons) );
4044 	      }
4045 	
4046 	      /* release copied and constraint */
4047 	      if( targetandconss != NULL )
4048 	      {
4049 	         int c;
4050 	
4051 	         assert(ntargetandconss <= sourceconsdata->nconsanddatas);
4052 	
4053 	         for( c = 0 ; c < ntargetandconss; ++c )
4054 	         {
4055 	            if( targetandconss[c] != NULL )
4056 	            {
4057 	               SCIP_CALL( SCIPreleaseCons(targetscip, &targetandconss[c]) );
4058 	            }
4059 	         }
4060 	      }
4061 	
4062 	      /* free temporary memory */
4063 	      SCIPfreeBufferArrayNull(sourcescip, &targetandcoefs);
4064 	      SCIPfreeBufferArrayNull(sourcescip, &targetandconss);
4065 	   }
4066 	   else
4067 	      *valid = FALSE;
4068 	
4069 	   return SCIP_OKAY;
4070 	}
4071 	
4072 	/** compute all changes in consanddatas array */
4073 	static
4074 	SCIP_RETCODE computeConsAndDataChanges(
4075 	   SCIP*const            scip,               /**< SCIP data structure */
4076 	   SCIP_CONSHDLRDATA*const conshdlrdata      /**< pseudoboolean constraint handler data */
4077 	   )
4078 	{
4079 	   CONSANDDATA** allconsanddatas;
4080 	   CONSANDDATA* consanddata;
4081 	   int c;
4082 	
4083 	   assert(scip != NULL);
4084 	   assert(conshdlrdata != NULL);
4085 	
4086 	   allconsanddatas = conshdlrdata->allconsanddatas;
4087 	   assert(allconsanddatas != NULL);
4088 	   assert(conshdlrdata->nallconsanddatas > 0);
4089 	   assert(conshdlrdata->nallconsanddatas <= conshdlrdata->sallconsanddatas);
4090 	
4091 	   for( c = conshdlrdata->nallconsanddatas - 1; c >= 0; --c )
4092 	   {
4093 	      SCIP_CONS* cons;
4094 	      SCIP_VAR** vars;
4095 	      int nvars;
4096 	      SCIP_VAR** newvars;
4097 	      int nnewvars;
4098 	      int v;
4099 	
4100 	      consanddata = allconsanddatas[c];
4101 	
4102 	      if( !consanddata->istransformed )
4103 	         continue;
4104 	
4105 	      if( consanddata->nuses == 0 )
4106 	         continue;
4107 	
4108 	      vars = consanddata->vars;
4109 	      nvars = consanddata->nvars;
4110 	      assert(nvars == 0 || vars != NULL);
4111 	      assert(consanddata->nnewvars == 0 && ((consanddata->snewvars > 0) == (consanddata->newvars != NULL)));
4112 	
4113 	      if( nvars == 0 )
4114 	      {
4115 	#ifndef NDEBUG
4116 	         /* if an old consanddata-object has no variables left there should be no new variables */
4117 	         if( consanddata->cons != NULL )
4118 	            assert(SCIPgetNVarsAnd(scip, consanddata->cons) == 0);
4119 	#endif
4120 	         continue;
4121 	      }
4122 	
4123 	      cons = consanddata->cons;
4124 	      assert(cons != NULL);
4125 	
4126 	      if( SCIPconsIsDeleted(cons) )
4127 	         continue;
4128 	
4129 	      /* sort and-variables */
4130 	      if( !SCIPisAndConsSorted(scip, consanddata->cons) )
4131 	      {
4132 	         SCIP_CALL( SCIPsortAndCons(scip, consanddata->cons) );
4133 	         assert(SCIPisAndConsSorted(scip, consanddata->cons));
4134 	      }
4135 	
4136 	      /* get new and-variables */
4137 	      nnewvars = SCIPgetNVarsAnd(scip, consanddata->cons);
4138 	      newvars = SCIPgetVarsAnd(scip, consanddata->cons);
4139 	
4140 	      /* stop if the constraint has no variables or there was an error (coverity issue) */
4141 	      if( nnewvars <= 0 )
4142 	         continue;
4143 	
4144 	#ifndef NDEBUG
4145 	      /* check that old variables are sorted */
4146 	      for( v = nvars - 1; v > 0; --v )
4147 	         assert(SCIPvarGetIndex(vars[v]) >= SCIPvarGetIndex(vars[v - 1]));
4148 	      /* check that new variables are sorted */
4149 	      for( v = nnewvars - 1; v > 0; --v )
4150 	         assert(SCIPvarGetIndex(newvars[v]) >= SCIPvarGetIndex(newvars[v - 1]));
4151 	#endif
4152 	
4153 	      /* check for changings, if and-constraint did not change we do not need to copy all variables */
4154 	      if( nvars == nnewvars )
4155 	      {
4156 	         SCIP_Bool changed;
4157 	
4158 	         changed = FALSE;
4159 	
4160 	         /* check each variable */
4161 	         for( v = nvars - 1; v >= 0; --v )
4162 	         {
4163 	            if( vars[v] != newvars[v] )
4164 	            {
4165 	               changed = TRUE;
4166 	               break;
4167 	            }
4168 	         }
4169 	
4170 	         if( !changed )
4171 	            continue;
4172 	      }
4173 	
4174 	      /* resize newvars array if necessary */
4175 	      if( nnewvars > consanddata->snewvars )
4176 	      {
4177 	         SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consanddata->newvars), &(consanddata->snewvars), nnewvars) );
4178 	      }
4179 	
4180 	      /* copy all variables */
4181 	      BMScopyMemoryArray(consanddata->newvars, newvars, nnewvars);
4182 	      consanddata->nnewvars = nnewvars;
4183 	
4184 	      /* capture all variables */
4185 	      for( v = consanddata->nnewvars - 1; v >= 0; --v )
4186 	      {
4187 	         /* in original problem the variables was already deleted */
4188 	         assert(consanddata->newvars[v] != NULL);
4189 	         SCIP_CALL( SCIPcaptureVar(scip, consanddata->newvars[v]) );
4190 	      }
4191 	   }
4192 	
4193 	   return SCIP_OKAY;
4194 	}
4195 	
4196 	/** remove old locks */
4197 	static
4198 	SCIP_RETCODE removeOldLocks(
4199 	   SCIP*const            scip,               /**< SCIP data structure */
4200 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
4201 	   CONSANDDATA*const     consanddata,        /**< CONSANDDATA object for which we want to delete the locks and the
4202 	                                              *   capture of the corresponding and-constraint */
4203 	   SCIP_Real const       coef,               /**< coefficient which led to old locks */
4204 	   SCIP_Real const       lhs,                /**< left hand side which led to old locks */
4205 	   SCIP_Real const       rhs                 /**< right hand side which led to old locks */
4206 	   )
4207 	{
4208 	   assert(scip != NULL);
4209 	   assert(cons != NULL);
4210 	   assert(consanddata != NULL);
4211 	   assert(!SCIPisInfinity(scip, coef) && !SCIPisInfinity(scip, -coef));
4212 	   assert(!SCIPisInfinity(scip, lhs));
4213 	   assert(!SCIPisInfinity(scip, -rhs));
4214 	   assert(SCIPisLE(scip, lhs, rhs));
4215 	
4216 	   /* remove rounding locks */
4217 	   SCIP_CALL( unlockRoundingAndCons(scip, cons, consanddata, coef, lhs, rhs) );
4218 	
4219 	   assert(consanddata->cons != NULL);
4220 	
4221 	   return SCIP_OKAY;
4222 	}
4223 	
4224 	/** add new locks */
4225 	static
4226 	SCIP_RETCODE addNewLocks(
4227 	   SCIP*const            scip,               /**< SCIP data structure */
4228 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
4229 	   CONSANDDATA*const     consanddata,        /**< CONSANDDATA object for which we want to delete the locks and the
4230 	                                              *   capture of the corresponding and-constraint */
4231 	   SCIP_Real const       coef,               /**< coefficient which lead to new locks */
4232 	   SCIP_Real const       lhs,                /**< left hand side which lead to new locks */
4233 	   SCIP_Real const       rhs                 /**< right hand side which lead to new locks */
4234 	   )
4235 	{
4236 	   assert(scip != NULL);
4237 	   assert(cons != NULL);
4238 	   assert(consanddata != NULL);
4239 	   assert(!SCIPisInfinity(scip, coef) && !SCIPisInfinity(scip, -coef));
4240 	   assert(!SCIPisInfinity(scip, lhs));
4241 	   assert(!SCIPisInfinity(scip, -rhs));
4242 	   assert(SCIPisLE(scip, lhs, rhs));
4243 	
4244 	   /* add rounding locks due to old variables in consanddata object */
4245 	   SCIP_CALL( lockRoundingAndCons(scip, cons, consanddata, coef, lhs, rhs) );
4246 	
4247 	   assert(consanddata->cons != NULL);
4248 	
4249 	   return SCIP_OKAY;
4250 	}
4251 	
4252 	/** update all locks inside this constraint and all captures on all and-constraints */
4253 	static
4254 	SCIP_RETCODE correctLocksAndCaptures(
4255 	   SCIP*const            scip,               /**< SCIP data structure */
4256 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
4257 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
4258 	   SCIP_Real const       newlhs,             /**< new left hand side of pseudoboolean constraint */
4259 	   SCIP_Real const       newrhs,             /**< new right hand side of pseudoboolean constraint */
4260 	   SCIP_VAR**const       andress,            /**< current and-resultants in pseudoboolean constraint */
4261 	   SCIP_Real*const       andcoefs,           /**< current and-resultants-coeffcients in pseudoboolean constraint */
4262 	   SCIP_Bool*const       andnegs,            /**< current negation status of and-resultants in pseudoboolean constraint */
4263 	   int const             nandress            /**< number of current and-resultants in pseudoboolean constraint */
4264 	   )
4265 	{
4266 	   CONSANDDATA** newconsanddatas;
4267 	   int nnewconsanddatas;
4268 	   int snewconsanddatas;
4269 	   SCIP_Real* newandcoefs;
4270 	   SCIP_Real* oldandcoefs;
4271 	   SCIP_Bool* newandnegs;
4272 	   SCIP_Bool* oldandnegs;
4273 	   CONSANDDATA** consanddatas;
4274 	   int nconsanddatas;
4275 	   SCIP_CONSDATA* consdata;
4276 	   int oldnvars;
4277 	   int c;
4278 	   int c1;
4279 	
4280 	   assert(scip != NULL);
4281 	   assert(cons != NULL);
4282 	   assert(conshdlrdata != NULL);
4283 	   assert(conshdlrdata->hashmap != NULL);
4284 	   assert(nandress == 0 || (andress != NULL && andcoefs != NULL));
4285 	   assert(!SCIPisInfinity(scip, newlhs));
4286 	   assert(!SCIPisInfinity(scip, -newrhs));
4287 	   assert(SCIPisLE(scip, newlhs, newrhs));
4288 	
4289 	   consdata = SCIPconsGetData(cons);
4290 	   assert(consdata != NULL);
4291 	
4292 	   /* sort and-constraints after indices of corresponding and-resultants */
4293 	   SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4294 	
4295 	   consanddatas = consdata->consanddatas;
4296 	   oldandcoefs = consdata->andcoefs;
4297 	   oldandnegs = consdata->andnegs;
4298 	   nconsanddatas = consdata->nconsanddatas;
4299 	   assert(nconsanddatas == 0 || (consanddatas != NULL && oldandcoefs != NULL));
4300 	
4301 	#ifndef NDEBUG
4302 	   /* check that and-resultants are sorted, and coefficents are not zero */
4303 	   for( c = nandress - 1; c > 0; --c )
4304 	   {
4305 	      assert(!SCIPisZero(scip, andcoefs[c]));
4306 	      assert(SCIPvarGetIndex(andress[c]) > SCIPvarGetIndex(andress[c - 1]));
4307 	   }
4308 	   /* check that consanddata objects are sorted due to the index of the corresponding resultants, and coefficents are
4309 	    * not zero
4310 	    */
4311 	   for( c = nconsanddatas - 1; c > 0; --c )
4312 	   {
4313 	      SCIP_VAR* res1;
4314 	      SCIP_VAR* res2;
4315 	
4316 	      assert(consanddatas[c] != NULL);
4317 	
4318 	      if( !consanddatas[c]->istransformed )
4319 	         continue;
4320 	
4321 	      assert(!SCIPisZero(scip, oldandcoefs[c]));
4322 	      assert(consanddatas[c - 1] != NULL);
4323 	
4324 	      if( !consanddatas[c - 1]->istransformed )
4325 	         continue;
4326 	
4327 	      assert(!SCIPisZero(scip, oldandcoefs[c - 1]));
4328 	
4329 	      if( SCIPconsIsDeleted(consanddatas[c]->cons) || SCIPconsIsDeleted(consanddatas[c - 1]->cons) )
4330 	         continue;
4331 	
4332 	      assert(consanddatas[c]->cons != NULL);
4333 	      res1 = SCIPgetResultantAnd(scip, consanddatas[c]->cons);
4334 	      assert(res1 != NULL);
4335 	      assert(consanddatas[c - 1]->cons != NULL);
4336 	      res2 = SCIPgetResultantAnd(scip, consanddatas[c - 1]->cons);
4337 	      assert(res2 != NULL);
4338 	
4339 	      assert(SCIPvarGetIndex(res1) >= SCIPvarGetIndex(res2));
4340 	   }
4341 	#endif
4342 	
4343 	   snewconsanddatas = nconsanddatas + nandress;
4344 	
4345 	   /* allocate new block memory arrays */
4346 	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newconsanddatas, snewconsanddatas) );
4347 	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newandcoefs, snewconsanddatas) );
4348 	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newandnegs, snewconsanddatas) );
4349 	
4350 	   nnewconsanddatas = 0;
4351 	
4352 	   /* collect new consanddata objects and update locks and captures */
4353 	   for( c = 0, c1 = 0; c < nconsanddatas && c1 < nandress; )
4354 	   {
4355 	      SCIP_CONS* andcons;
4356 	      SCIP_VAR* res1;
4357 	      SCIP_VAR* res2;
4358 	
4359 	      assert(consanddatas[c] != NULL);
4360 	
4361 	      /* consanddata object could have been deleted in the last presolving round */
4362 	      if( !consanddatas[c]->istransformed )
4363 	      {
4364 	         ++c;
4365 	         consdata->changed = TRUE;
4366 	         consdata->upgradetried = FALSE;
4367 	         continue;
4368 	      }
4369 	
4370 	      andcons = consanddatas[c]->cons;
4371 	      assert(andcons != NULL);
4372 	
4373 	      if( andcons == NULL ) /*lint !e774*/
4374 	      {
4375 	         ++c;
4376 	         consdata->changed = TRUE;
4377 	         consdata->upgradetried = FALSE;
4378 	         continue;
4379 	      }
4380 	      else if( SCIPconsIsDeleted(andcons) )
4381 	      {
4382 	         /* remove rounding locks, because the and constraint was deleted  */
4383 	         SCIP_CALL( unlockRoundingAndCons(scip, cons, consanddatas[c],
4384 	               oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c], consdata->lhs, consdata->rhs) );
4385 	         ++c;
4386 	         consdata->changed = TRUE;
4387 	         consdata->upgradetried = FALSE;
4388 	         continue;
4389 	      }
4390 	      assert(andcons != NULL);
4391 	
4392 	      /* get and-resultants of consanddata object in constraint data */
4393 	      res1 = SCIPgetResultantAnd(scip, andcons);
4394 	      assert(res1 != NULL);
4395 	      assert(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res1) == consanddatas[c]);
4396 	
4397 	      /* get and-resultants in new corresponding linear constraint */
4398 	      res2 = andress[c1];
4399 	      assert(res2 != NULL);
4400 	      assert(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2) != NULL);
4401 	
4402 	      /* collect new consanddata objects in sorted order due to the variable index of corresponding and-resultants */
4403 	      if( SCIPvarGetIndex(res1) < SCIPvarGetIndex(res2) )
4404 	      {
4405 		 assert(consanddatas[c]->nuses > 0);
4406 		 --(consanddatas[c]->nuses);
4407 	
4408 	         /* remove old locks */
4409 	         SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4410 	               consdata->lhs, consdata->rhs) );
4411 	         ++c;
4412 	         consdata->changed = TRUE;
4413 	         consdata->upgradetried = FALSE;
4414 		 consdata->propagated = FALSE;
4415 		 consdata->presolved = FALSE;
4416 	      }
4417 	      else if( SCIPvarGetIndex(res1) > SCIPvarGetIndex(res2) )
4418 	      {
4419 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)res2));
4420 	         newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4421 	         newandcoefs[nnewconsanddatas] = andcoefs[c1];
4422 	         newandnegs[nnewconsanddatas] = andnegs[c1];
4423 		 ++(newconsanddatas[nnewconsanddatas]->nuses);
4424 	
4425 	         /* add new locks */
4426 	         SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4427 	               -newandcoefs[nnewconsanddatas] : newandcoefs[nnewconsanddatas], newlhs, newrhs) );
4428 	         ++c1;
4429 	         consdata->changed = TRUE;
4430 	         consdata->upgradetried = FALSE;
4431 	         consdata->cliquesadded = FALSE;
4432 		 consdata->propagated = FALSE;
4433 		 consdata->presolved = FALSE;
4434 	
4435 	         ++nnewconsanddatas;
4436 	      }
4437 	      else
4438 	      {
4439 	         SCIP_Bool coefsignchanged;
4440 	         SCIP_Bool lhschanged;
4441 	         SCIP_Bool rhschanged;
4442 	
4443 	         assert(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2) == consanddatas[c]);
4444 	
4445 	         /* copy old consanddata object and new coefficent */
4446 	         newconsanddatas[nnewconsanddatas] = consanddatas[c];
4447 	
4448 	         newandcoefs[nnewconsanddatas] = andcoefs[c1];
4449 	         newandnegs[nnewconsanddatas] = andnegs[c1];
4450 	
4451 	         if( ((oldandnegs[c] == andnegs[c1]) && !SCIPisEQ(scip, oldandcoefs[c], newandcoefs[c1]))
4452 	            || ((oldandnegs[c] != newandnegs[c1]) && !SCIPisEQ(scip, oldandcoefs[c], -newandcoefs[c1])) )
4453 	            consdata->upgradetried = FALSE;
4454 	
4455 	         coefsignchanged = (oldandnegs[c] == andnegs[c1]) &&
4456 	            ((oldandcoefs[c] < 0 && andcoefs[c1] > 0) || (oldandcoefs[c] > 0 && andcoefs[c1] < 0));
4457 	         coefsignchanged = coefsignchanged || ((oldandnegs[c] != andnegs[c1]) &&
4458 	            ((oldandcoefs[c] < 0 && andcoefs[c1] < 0) || (oldandcoefs[c] > 0 && andcoefs[c1] > 0)));
4459 	         lhschanged = (SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -newlhs)) || (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -newlhs))
4460 	            || (consdata->lhs < 0 && newlhs > 0) || (consdata->lhs > 0 && newlhs < 0);
4461 	         rhschanged = (SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, newrhs)) || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, newrhs))
4462 	            || (consdata->rhs < 0 && newrhs > 0) || (consdata->rhs > 0 && newrhs < 0);
4463 	
4464 	         /* update or renew locks */
4465 	         if( coefsignchanged || lhschanged || rhschanged || newconsanddatas[nnewconsanddatas]->nnewvars > 0)
4466 	         {
4467 	            /* renew locks */
4468 	            SCIP_CALL( removeOldLocks(scip, cons, newconsanddatas[nnewconsanddatas], oldandnegs[c] ?
4469 	                  -oldandcoefs[c] : oldandcoefs[c], consdata->lhs, consdata->rhs) );
4470 	            SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4471 	                  -newandcoefs[nnewconsanddatas] : newandcoefs[nnewconsanddatas], newlhs, newrhs) );
4472 	
4473 	            consdata->changed = TRUE;
4474 	            consdata->upgradetried = FALSE;
4475 	            consdata->cliquesadded = FALSE;
4476 	            consdata->propagated = FALSE;
4477 	            consdata->presolved = FALSE;
4478 	         }
4479 	
4480 	         ++c;
4481 	         ++c1;
4482 	         ++nnewconsanddatas;
4483 	      }
4484 	   }
4485 	
4486 	   /* add all remaining consanddatas and update locks and captures */
4487 	   if( c < nconsanddatas )
4488 	   {
4489 	      assert(c1 == nandress);
4490 	
4491 	      for( ; c < nconsanddatas; ++c )
4492 	      {
4493 	         SCIP_CONS* andcons;
4494 	#ifndef NDEBUG
4495 	         SCIP_VAR* res1;
4496 	
4497 	         assert(consanddatas[c] != NULL);
4498 	#endif
4499 	         andcons = consanddatas[c]->cons;
4500 	#ifndef NDEBUG
4501 	         if( andcons != NULL )
4502 	         {
4503 	            res1 = SCIPgetResultantAnd(scip, andcons);
4504 	            assert(res1 != NULL);
4505 	            assert(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res1) == consanddatas[c]);
4506 	         }
4507 	#endif
4508 	         if( andcons == NULL )
4509 	         {
4510 	            consdata->changed = TRUE;
4511 	            consdata->upgradetried = FALSE;
4512 	            continue;
4513 	         }
4514 	
4515 		 assert(consanddatas[c]->nuses > 0);
4516 		 --(consanddatas[c]->nuses);
4517 	
4518 	         /* remove old locks */
4519 	         SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4520 	               consdata->lhs, consdata->rhs) );
4521 	         consdata->changed = TRUE;
4522 	         consdata->upgradetried = FALSE;
4523 		 consdata->propagated = FALSE;
4524 		 consdata->presolved = FALSE;
4525 	      }
4526 	   }
4527 	   else if( c1 < nandress )
4528 	   {
4529 	      for( ; c1 < nandress; ++c1 )
4530 	      {
4531 	         SCIP_VAR* res2;
4532 	
4533 	         res2 = andress[c1];
4534 	         assert(res2 != NULL);
4535 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)res2));
4536 	         newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4537 	         newandcoefs[nnewconsanddatas] = andcoefs[c1];
4538 	         newandnegs[nnewconsanddatas] = andnegs[c1];
4539 		 ++(newconsanddatas[nnewconsanddatas]->nuses);
4540 	
4541 	         /* add new locks */
4542 	         SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4543 	               -newandcoefs[nnewconsanddatas] : newandcoefs[nnewconsanddatas], newlhs, newrhs) );
4544 	
4545 	         ++nnewconsanddatas;
4546 	         consdata->changed = TRUE;
4547 	         consdata->upgradetried = FALSE;
4548 		 consdata->cliquesadded = FALSE;
4549 		 consdata->propagated = FALSE;
4550 		 consdata->presolved = FALSE;
4551 	      }
4552 	   }
4553 	   assert(c == nconsanddatas && c1 == nandress);
4554 	
4555 	   /* delete old and-coefficients and consanddata objects */
4556 	   SCIPfreeBlockMemoryArray(scip, &(consdata->andcoefs), consdata->sconsanddatas);
4557 	   SCIPfreeBlockMemoryArray(scip, &(consdata->andnegs), consdata->sconsanddatas);
4558 	   SCIPfreeBlockMemoryArray(scip, &(consdata->consanddatas), consdata->sconsanddatas);
4559 	
4560 	   if( !SCIPisEQ(scip, consdata->lhs, newlhs) || !SCIPisEQ(scip, consdata->rhs, newrhs) )
4561 	   {
4562 	      consdata->upgradetried = FALSE;
4563 	      consdata->lhs = newlhs;
4564 	      consdata->rhs = newrhs;
4565 	   }
4566 	
4567 	   consdata->consanddatas = newconsanddatas;
4568 	   consdata->andcoefs = newandcoefs;
4569 	   consdata->andnegs = newandnegs;
4570 	   consdata->nconsanddatas = nnewconsanddatas;
4571 	   consdata->sconsanddatas = snewconsanddatas;
4572 	
4573 	   oldnvars = consdata->nlinvars;
4574 	   /* update number of linear variables without and-resultants */
4575 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &(consdata->nlinvars)) );
4576 	   consdata->nlinvars -= nnewconsanddatas;
4577 	
4578 	   if( oldnvars != consdata->nlinvars )
4579 	   {
4580 	      consdata->changed = TRUE;
4581 	      consdata->upgradetried = FALSE;
4582 	      consdata->cliquesadded = FALSE;
4583 	      consdata->propagated = FALSE;
4584 	      consdata->presolved = FALSE;
4585 	   }
4586 	
4587 	   /* we need to re-sort and-constraints after indices of corresponding and-resultants, since we might have replaced
4588 	    * negated variables
4589 	    */
4590 	   SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4591 	
4592 	#ifndef NDEBUG
4593 	   consanddatas = consdata->consanddatas;
4594 	   nconsanddatas = consdata->nconsanddatas;
4595 	   assert(nconsanddatas == 0 || consanddatas != NULL);
4596 	
4597 	   /* check that consanddata objects are sorted with respect to the index of the corresponding resultants */
4598 	   for( c = nconsanddatas - 1; c > 0; --c )
4599 	   {
4600 	      SCIP_VAR* res1;
4601 	      SCIP_VAR* res2;
4602 	
4603 	      assert(consanddatas[c] != NULL);
4604 	      assert(consanddatas[c]->cons != NULL);
4605 	      res1 = SCIPgetResultantAnd(scip, consanddatas[c]->cons);
4606 	      assert(res1 != NULL);
4607 	      assert(consanddatas[c - 1] != NULL);
4608 	      assert(consanddatas[c - 1]->cons != NULL);
4609 	      res2 = SCIPgetResultantAnd(scip, consanddatas[c - 1]->cons);
4610 	      assert(res2 != NULL);
4611 	
4612 	      assert(SCIPvarGetIndex(res1) > SCIPvarGetIndex(res2));
4613 	   }
4614 	#endif
4615 	
4616 	   return SCIP_OKAY;
4617 	}
4618 	
4619 	/** adds cliques of the pseudoboolean constraint to the global clique table */
4620 	static
4621 	SCIP_RETCODE addCliques(
4622 	   SCIP*const            scip,               /**< SCIP data structure */
4623 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
4624 	   SCIP_Bool*const       cutoff,             /**< pointer to store whether the node can be cut off */
4625 	   int*const             naggrvars,          /**< pointer to count the number of aggregated variables */
4626 	   int*const             nchgbds             /**< pointer to count the number of performed bound changes */
4627 	   )
4628 	{
4629 	   SCIP_CONSDATA* consdata;
4630 	   SCIP_VAR** vars;
4631 	   int nvars;
4632 	   SCIP_VAR** linvars;
4633 	   SCIP_VAR* andres;
4634 	   SCIP_VAR* andres2;
4635 	   int nlinvars;
4636 	   int nandress;
4637 	   int c;
4638 	   int v2;
4639 	   int v1;
4640 	   int nchgbdslocal;
4641 	
4642 	   assert(scip != NULL);
4643 	   assert(cons != NULL);
4644 	   assert(cutoff != NULL);
4645 	   assert(naggrvars != NULL);
4646 	   assert(nchgbds != NULL);
4647 	   assert(SCIPconsIsActive(cons));
4648 	
4649 	   *cutoff = FALSE;
4650 	
4651 	   consdata = SCIPconsGetData(cons);
4652 	   assert(consdata != NULL);
4653 	   /* if we have no and-constraints left, we should not be here and this constraint should be deleted (only the linaer should survive) */
4654 	   assert(consdata->nconsanddatas > 0);
4655 	
4656 	   /* check whether the cliques have already been added */
4657 	   if( consdata->cliquesadded )
4658 	      return SCIP_OKAY;
4659 	
4660 	   consdata->cliquesadded = TRUE;
4661 	
4662 	   checkConsConsistency(scip, cons);
4663 	
4664 	   /* check standard pointers and sizes */
4665 	   assert(consdata->lincons != NULL);
4666 	   assert(SCIPconsIsActive(consdata->lincons));
4667 	   assert(consdata->linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
4668 	   assert(consdata->consanddatas != NULL);
4669 	   assert(consdata->nconsanddatas > 0);
4670 	   assert(consdata->nconsanddatas <= consdata->sconsanddatas);
4671 	
4672 	   /* check number of linear variables */
4673 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
4674 	   assert(nvars == consdata->nlinvars + consdata->nconsanddatas);
4675 	
4676 	   /* get temporary memory */
4677 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
4678 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
4679 	
4680 	   /* get variables and coefficients */
4681 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, NULL, &nvars) );
4682 	
4683 	   /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
4684 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
4685 	    * afterwards
4686 	    * @todo should we take into accout the negation status of the cliques?
4687 	    */
4688 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, NULL, nvars, linvars, NULL, &nlinvars,
4689 	         NULL, NULL, NULL, &nandress) );
4690 	
4691 	   assert(nandress == consdata->nconsanddatas);
4692 	   assert(consdata->consanddatas != NULL);
4693 	
4694 	   /* find cliques from linear variable to and-resultant */
4695 	   for( c = nandress - 1; c >= 0; --c )
4696 	   {
4697 	      CONSANDDATA* consanddata;
4698 	      SCIP_VAR** andvars;
4699 	      int nandvars;
4700 	
4701 	      consanddata = consdata->consanddatas[c];
4702 	      assert(consanddata != NULL);
4703 	
4704 	      andres = SCIPgetResultantAnd(scip, consanddata->cons);
4705 	
4706 	      /* choose correct variable array */
4707 	      if( consanddata->nnewvars > 0 )
4708 	      {
4709 	         andvars = consanddata->newvars;
4710 	         nandvars = consanddata->nnewvars;
4711 	      }
4712 	      else
4713 	      {
4714 	         andvars = consanddata->vars;
4715 	         nandvars = consanddata->nvars;
4716 	      }
4717 	
4718 	      for( v1 = nandvars - 1; v1 >= 0; --v1 )
4719 	      {
4720 	         SCIP_VAR* var1;
4721 	         SCIP_Bool values[2];
4722 	
4723 	         var1 = andvars[v1];
4724 	         if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4725 	            continue;
4726 	
4727 	         /* get active counterpart to check for common cliques */
4728 	         if( SCIPvarGetStatus(var1) == SCIP_VARSTATUS_NEGATED )
4729 	         {
4730 	            var1 = SCIPvarGetNegationVar(var1);
4731 	            values[0] = FALSE;
4732 	         }
4733 	         else
4734 	            values[0] = TRUE;
4735 	
4736 	         for( v2 = nlinvars - 1; v2 >= 0; --v2 )
4737 	         {
4738 	            SCIP_VAR* var2;
4739 	
4740 	            var2 = linvars[v2];
4741 	            if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4742 	               continue;
4743 	
4744 	            /* get active counterpart to check for common cliques */
4745 	            if( SCIPvarGetStatus(var2) == SCIP_VARSTATUS_NEGATED )
4746 	            {
4747 	               var2 = SCIPvarGetNegationVar(var2);
4748 	               values[1] = FALSE;
4749 	            }
4750 	            else
4751 	               values[1] = TRUE;
4752 	
4753 	            /* if variable in and-constraint1 is the negated variable of a normal linear variable, than we can add a
4754 	             * clique between the and-resultant and the normal linear variable, negated variables are not save in
4755 	             * cliquetables
4756 	             *
4757 	             * set r_1 = var1 * z; (z is some product)
4758 	             * var1 == ~var2
4759 	             *
4760 	             * if:
4761 	             * var1 + ~var1 <= 1;          r_1
4762 	             *    0 +     1 <= 1             0   \
4763 	             *    1 +     0 <= 1   ==>  1 or 0    >   ==>    r_1 + var2 <= 1
4764 	             *    0 +     0 <= 1             0   /
4765 	             */
4766 	            if( values[0] != values[1] && var1 == var2 )
4767 	            {
4768 	               SCIP_CONS* newcons;
4769 	               SCIP_VAR* clqvars[2];
4770 	               char consname[SCIP_MAXSTRLEN];
4771 	
4772 	               clqvars[0] = andres;
4773 	               clqvars[1] = values[1] ? var2 : SCIPvarGetNegatedVar(var2);
4774 	               assert(clqvars[1] != NULL);
4775 	
4776 	               /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4777 	
4778 	               /* add clique */
4779 	               SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, 2, FALSE, cutoff, &nchgbdslocal) );
4780 	               if( *cutoff )
4781 	                  goto TERMINATE;
4782 	
4783 		       *nchgbds += nchgbdslocal;
4784 	
4785 	               (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4786 	               SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, consname, 2, clqvars,
4787 	                     SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
4788 	                     FALSE, SCIPconsIsPropagated(cons),
4789 	                     SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
4790 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
4791 	
4792 	               SCIP_CALL( SCIPaddCons(scip, newcons) );
4793 	               SCIPdebugMsg(scip, "added a clique/setppc constraint <%s> \n", SCIPconsGetName(newcons));
4794 	               SCIPdebugPrintCons(scip, newcons, NULL);
4795 	
4796 	               SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
4797 	            }
4798 	            /* if a variable in an and-constraint is in a clique with another normal linear variable, we can add the
4799 	             * clique between the linear variable and the and-resultant
4800 	             *
4801 	             * set r_1 = var1 * z; (z is some product)
4802 	             *
4803 	             * if:
4804 	             * var1 + var2 <= 1;          r_1
4805 	             *    0 +    1 <= 1             0   \
4806 	             *    1 +    0 <= 1   ==>  1 or 0    >   ==>    r_1 + var2 <= 1
4807 	             *    0 +    0 <= 1             0   /
4808 	             */
4809 	            if( (var1 != var2) && SCIPvarsHaveCommonClique(var1, values[0], var2, values[1], TRUE) )
4810 	            {
4811 	               SCIP_CONS* newcons;
4812 	               SCIP_VAR* clqvars[2];
4813 	               char consname[SCIP_MAXSTRLEN];
4814 	
4815 	               clqvars[0] = andres;
4816 	               clqvars[1] = values[1] ? var2 : SCIPvarGetNegatedVar(var2);
4817 	               assert(clqvars[1] != NULL);
4818 	
4819 	               /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4820 	
4821 	               /* add clique */
4822 	               SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, 2, FALSE, cutoff, &nchgbdslocal) );
4823 	               if( *cutoff )
4824 	                  goto TERMINATE;
4825 	
4826 		       *nchgbds += nchgbdslocal;
4827 	
4828 	               (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4829 	               SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, consname, 2, clqvars,
4830 	                     SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
4831 	                     FALSE, SCIPconsIsPropagated(cons),
4832 	                     SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
4833 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
4834 	
4835 	               SCIP_CALL( SCIPaddCons(scip, newcons) );
4836 	               SCIPdebugMsg(scip, "added a clique/setppc constraint <%s> \n", SCIPconsGetName(newcons));
4837 	               SCIPdebugPrintCons(scip, newcons, NULL);
4838 	
4839 	               SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
4840 	            }
4841 	         }
4842 	      }
4843 	   }
4844 	
4845 	   /* find cliques over variables which are in different and-constraints */
4846 	   for( c = nandress - 1; c > 0; --c )
4847 	   {
4848 	      CONSANDDATA* consanddata1;
4849 	      CONSANDDATA* consanddata2;
4850 	      SCIP_VAR** andvars1;
4851 	      int nandvars1;
4852 	      SCIP_VAR** andvars2;
4853 	      int nandvars2;
4854 	
4855 	      consanddata1 = consdata->consanddatas[c];
4856 	      assert(consanddata1 != NULL);
4857 	      consanddata2 = consdata->consanddatas[c - 1];
4858 	      assert(consanddata2 != NULL);
4859 	
4860 	      andres = SCIPgetResultantAnd(scip, consanddata1->cons);
4861 	      andres2 = SCIPgetResultantAnd(scip, consanddata2->cons);
4862 	
4863 	      /* choose correct variable array of consanddata object 1 */
4864 	      if( consanddata1->nnewvars > 0 )
4865 	      {
4866 	         andvars1 = consanddata1->newvars;
4867 	         nandvars1 = consanddata1->nnewvars;
4868 	      }
4869 	      else
4870 	      {
4871 	         andvars1 = consanddata1->vars;
4872 	         nandvars1 = consanddata1->nvars;
4873 	      }
4874 	
4875 	      /* choose correct variable array of consanddata object 2 */
4876 	      if( consanddata2->nnewvars > 0 )
4877 	      {
4878 	         andvars2 = consanddata2->newvars;
4879 	         nandvars2 = consanddata2->nnewvars;
4880 	      }
4881 	      else
4882 	      {
4883 	         andvars2 = consanddata2->vars;
4884 	         nandvars2 = consanddata2->nvars;
4885 	      }
4886 	
4887 	      /* compare both terms for finding new aggregated variables and new cliques */
4888 	      for( v1 = nandvars1 - 1; v1 >= 0; --v1 )
4889 	      {
4890 	         SCIP_VAR* var1;
4891 	         SCIP_Bool values[2];
4892 	
4893 	         var1 = andvars1[v1];
4894 	         if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4895 	            continue;
4896 	
4897 	         /* get active counterpart to check for common cliques */
4898 	         if( SCIPvarGetStatus(var1) == SCIP_VARSTATUS_NEGATED )
4899 	         {
4900 	            var1 = SCIPvarGetNegationVar(var1);
4901 	            values[0] = FALSE;
4902 	         }
4903 	         else
4904 	            values[0] = TRUE;
4905 	
4906 	         for( v2 = nandvars2 - 1; v2 >= 0; --v2 )
4907 	         {
4908 	            SCIP_VAR* var2;
4909 	
4910 	            var2 = andvars2[v2];
4911 	            if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4912 	               continue;
4913 	
4914 	            /* get active counterpart to check for common cliques */
4915 	            if( SCIPvarGetStatus(var2) == SCIP_VARSTATUS_NEGATED )
4916 	            {
4917 	               var2 = SCIPvarGetNegationVar(var2);
4918 	               values[1] = FALSE;
4919 	            }
4920 	            else
4921 	               values[1] = TRUE;
4922 	
4923 	            /* if a variable in and-constraint1 is the negated variable of a variable in and-constraint2, than we can
4924 	             * add a clique between both and-resultants, negated variables are not save in cliquetables
4925 	             *
4926 	             * set r_1 = var1 * z_1; (z_1 is some product)
4927 	             * set r_2 = var2 * z_2; (z_2 is some product)
4928 	             * var1 == ~var2
4929 	             *
4930 	             * if:
4931 	             * var1 + ~var1 <= 1;          r_1     r_2
4932 	             *    0 +     1 <= 1             0  1 or 0   \
4933 	             *    1 +     0 <= 1   ==>  1 or 0       0    >   ==>    r_1 + r_2 <= 1
4934 	             *    0 +     0 <= 1             0       0   /
4935 	             */
4936 	            if( values[0] != values[1] && var1 == var2 )
4937 	            {
4938 	               SCIP_CONS* newcons;
4939 	               SCIP_VAR* clqvars[2];
4940 	               char consname[SCIP_MAXSTRLEN];
4941 	
4942 	               clqvars[0] = andres;
4943 	               clqvars[1] = andres2;
4944 	
4945 	               /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4946 	
4947 	               /* add clique */
4948 	               SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, 2, FALSE, cutoff, &nchgbdslocal) );
4949 	               if( *cutoff )
4950 	                  goto TERMINATE;
4951 	
4952 		       *nchgbds += nchgbdslocal;
4953 	
4954 	               (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4955 	               SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, consname, 2, clqvars,
4956 	                     SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
4957 	                     FALSE, SCIPconsIsPropagated(cons),
4958 	                     SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
4959 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
4960 	
4961 	               SCIP_CALL( SCIPaddCons(scip, newcons) );
4962 	               SCIPdebugMsg(scip, "added a clique/setppc constraint <%s> \n", SCIPconsGetName(newcons));
4963 	               SCIPdebugPrintCons(scip, newcons, NULL);
4964 	
4965 	               SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
4966 	            }
4967 	            /* if a variable in an and-constraint is in a clique with a variable in another and-constraint, we can add
4968 	             * the clique between both and-resultant
4969 	             *
4970 	             * let r_1 = var1 * z_1; (z_1 is some product)
4971 	             * let r_2 = var2 * z_2; (z_2 is some product)
4972 	             *
4973 	             * if:
4974 	             * var1 + var2 <= 1;          r_1     r_2
4975 	             *    0 +    1 <= 1             0  1 or 0   \
4976 	             *    1 +    0 <= 1   ==>  1 or 0       0    >   ==>    r_1 + r_2 <= 1
4977 	             *    0 +    0 <= 1             0       0   /
4978 	             */
4979 	            else if( SCIPvarsHaveCommonClique(var1, values[0], var2, values[1], TRUE) && (var1 != var2) )
4980 	            {
4981 	               SCIP_CONS* newcons;
4982 	               SCIP_VAR* clqvars[2];
4983 	               char consname[SCIP_MAXSTRLEN];
4984 	
4985 	               clqvars[0] = andres;
4986 	               clqvars[1] = values[1] ? var2 : SCIPvarGetNegatedVar(var2);
4987 	               assert(clqvars[1] != NULL);
4988 	
4989 	               /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4990 	
4991 	               /* add clique */
4992 	               SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, 2, FALSE, cutoff, &nchgbdslocal) );
4993 	               if( *cutoff )
4994 	                  goto TERMINATE;
4995 	
4996 		       *nchgbds += nchgbdslocal;
4997 	
4998 	               (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4999 	               SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, consname, 2, clqvars,
5000 	                     SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
5001 	                     FALSE, SCIPconsIsPropagated(cons),
5002 	                     SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
5003 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
5004 	
5005 	               SCIP_CALL( SCIPaddCons(scip, newcons) );
5006 	               SCIPdebugMsg(scip, "added a clique/setppc constraint <%s> \n", SCIPconsGetName(newcons));
5007 	               SCIPdebugPrintCons(scip, newcons, NULL);
5008 	
5009 	               SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
5010 	            }
5011 	         }
5012 	      }
5013 	   }
5014 	
5015 	 TERMINATE:
5016 	   /* free temporary memory */
5017 	   SCIPfreeBufferArray(scip, &linvars);
5018 	   SCIPfreeBufferArray(scip, &vars);
5019 	
5020 	   return SCIP_OKAY;
5021 	}
5022 	
5023 	/** propagation method for pseudoboolean constraints */
5024 	static
5025 	SCIP_RETCODE propagateCons(
5026 	   SCIP*const            scip,               /**< SCIP data structure */
5027 	   SCIP_CONS*const       cons,               /**< knapsack constraint */
5028 	   SCIP_Bool*const       cutoff,             /**< pointer to store whether the node can be cut off */
5029 	   int*const             ndelconss           /**< pointer to count number of deleted constraints */
5030 	   )
5031 	{
5032 	   SCIP_CONSDATA* consdata;
5033 	
5034 	   assert(scip != NULL);
5035 	   assert(cons != NULL);
5036 	   assert(cutoff != NULL);
5037 	   assert(ndelconss != NULL);
5038 	
5039 	   *cutoff = FALSE;
5040 	
5041 	   consdata = SCIPconsGetData(cons);
5042 	   assert(consdata != NULL);
5043 	   assert(consdata->lincons != NULL);
5044 	
5045 	   /* if linear constraint is redundant, than pseudoboolean constraint is redundant too */
5046 	   if( SCIPconsIsDeleted(consdata->lincons) )
5047 	   {
5048 	      SCIP_CALL( SCIPdelConsLocal(scip, cons) );
5049 	      ++(*ndelconss);
5050 	   }
5051 	
5052 	   /* check if the constraint was already propagated */
5053 	   if( consdata->propagated )
5054 	      return SCIP_OKAY;
5055 	
5056 	   /* mark the constraint propagated */
5057 	   consdata->propagated = TRUE;
5058 	
5059 	   return SCIP_OKAY;
5060 	}
5061 	
5062 	/** update and-constraint flags due to pseudoboolean constraint flags */
5063 	static
5064 	SCIP_RETCODE updateAndConss(
5065 	   SCIP*const            scip,               /**< SCIP data structure */
5066 	   SCIP_CONS*const       cons                /**< pseudoboolean constraint */
5067 	   )
5068 	{
5069 	   CONSANDDATA** consanddatas;
5070 	   int nconsanddatas;
5071 	   SCIP_CONSDATA* consdata;
5072 	   int c;
5073 	
5074 	   assert(scip != NULL);
5075 	   assert(cons != NULL);
5076 	
5077 	   consdata = SCIPconsGetData(cons);
5078 	   assert(consdata != NULL);
5079 	
5080 	   consanddatas = consdata->consanddatas;
5081 	   nconsanddatas = consdata->nconsanddatas;
5082 	   assert(nconsanddatas == 0 || consanddatas != NULL);
5083 	
5084 	   if( !SCIPconsIsActive(cons) )
5085 	      return SCIP_OKAY;
5086 	
5087 	   /* release and-constraints and change check flag of and-constraint */
5088 	   for( c = nconsanddatas - 1; c >= 0; --c )
5089 	   {
5090 	      SCIP_CONS* andcons;
5091 	
5092 	      assert(consanddatas[c] != NULL);
5093 	
5094 	      if( !consanddatas[c]->istransformed )
5095 	         continue;
5096 	
5097 	      andcons = consanddatas[c]->cons;
5098 	      assert(andcons != NULL);
5099 	
5100 	      SCIP_CALL( SCIPsetConsChecked(scip, andcons, SCIPconsIsChecked(cons)) );
5101 	   }
5102 	
5103 	   return SCIP_OKAY;
5104 	}
5105 	
5106 	/** delete unused information in constraint handler data */
5107 	static
5108 	SCIP_RETCODE correctConshdlrdata(
5109 	   SCIP*const            scip,               /**< SCIP data structure */
5110 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
5111 	   int*const             ndelconss           /**< pointer to count number of deleted constraints */
5112 	   )
5113 	{
5114 	   CONSANDDATA** allconsanddatas;
5115 	   CONSANDDATA* consanddata;
5116 	   int c;
5117 	
5118 	   assert(scip != NULL);
5119 	   assert(conshdlrdata != NULL);
5120 	   assert(ndelconss != NULL);
5121 	
5122 	   allconsanddatas = conshdlrdata->allconsanddatas;
5123 	   assert(allconsanddatas != NULL);
5124 	   assert(conshdlrdata->nallconsanddatas > 0);
5125 	   assert(conshdlrdata->nallconsanddatas <= conshdlrdata->sallconsanddatas);
5126 	
5127 	   for( c = conshdlrdata->nallconsanddatas - 1; c >= 0; --c )
5128 	   {
5129 	      SCIP_VAR** tmpvars;
5130 	      int stmpvars;
5131 	      SCIP_CONS* cons;
5132 	      int v;
5133 	
5134 	      consanddata = allconsanddatas[c];
5135 	
5136 	      assert(consanddata->nvars == 0 || (consanddata->vars != NULL && consanddata->svars > 0));
5137 	      assert(consanddata->nnewvars == 0 || (consanddata->newvars != NULL && consanddata->snewvars > 0));
5138 	
5139 	      if( !consanddata->istransformed )
5140 	      {
5141 	         assert(consanddata->vars == NULL || consanddata->origcons != NULL);
5142 	         assert(consanddata->nvars == 0 || consanddata->origcons != NULL);
5143 	         assert(consanddata->svars == 0 || consanddata->origcons != NULL);
5144 	         assert(consanddata->newvars == NULL);
5145 	         assert(consanddata->nnewvars == 0);
5146 	         assert(consanddata->snewvars == 0);
5147 	
5148 	         continue;
5149 	      }
5150 	
5151 	      /* if no variables are left, delete variables arrays */
5152 	      if( consanddata->nvars == 0 )
5153 	      {
5154 	         SCIP_VAR* resvar = SCIPgetResultantAnd(scip, consanddata->cons);
5155 	
5156 	         /* if we have no old variables, than also no new variables */
5157 	         assert(consanddata->nnewvars == 0);
5158 	         assert(consanddata->nuses > 0);
5159 	         assert(resvar != NULL);
5160 	
5161 	         /* delete and-constraint */
5162 	         SCIP_CALL( SCIPdelCons(scip, consanddata->cons) );
5163 	         ++(*ndelconss);
5164 	
5165 	         SCIP_CALL( transformToOrig(scip, consanddata, conshdlrdata) );
5166 	
5167 	         /* release and-constraint */
5168 	         SCIP_CALL( SCIPreleaseCons(scip, &consanddata->cons) );
5169 	         consanddata->nuses = 0;
5170 	
5171 	         /* remove consanddata from hashtable, if it existed only in transformed space */
5172 	         if( consanddata->origcons == NULL )
5173 	         {
5174 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
5175 	            SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddata) );
5176 	         }
5177 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)resvar));
5178 	         SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)resvar) );
5179 	
5180 	         continue;
5181 	      }
5182 	
5183 	      /* the consanddata object is not used anymore, so extract the and constraint and delete other data */
5184 	      if( consanddata->nuses == 0 )
5185 	      {
5186 		 SCIP_Bool looseorcolumn;
5187 		 SCIP_VARSTATUS varstatus;
5188 	
5189 	         if( consanddata->cons == NULL )
5190 	         {
5191 	            assert(!consanddata->istransformed || consanddata->noriguses > 0);
5192 	            assert((consanddata->noriguses > 0) == (consanddata->origcons != NULL));
5193 	            assert(consanddata->vars == NULL || consanddata->origcons != NULL);
5194 	            assert(consanddata->nvars == 0 || consanddata->origcons != NULL);
5195 	            assert(consanddata->svars == 0 || consanddata->origcons != NULL);
5196 	            assert(consanddata->newvars == NULL);
5197 	            assert(consanddata->nnewvars == 0);
5198 	            assert(consanddata->snewvars == 0);
5199 	
5200 	            continue;
5201 	         }
5202 	
5203 	         SCIP_CALL( transformToOrig(scip, consanddata, conshdlrdata) );
5204 	
5205 		 varstatus = SCIPvarGetStatus(SCIPgetResultantAnd(scip, consanddata->cons));
5206 		 looseorcolumn = (varstatus == SCIP_VARSTATUS_LOOSE || varstatus == SCIP_VARSTATUS_COLUMN);
5207 	
5208 	#if 1
5209 		 /* @note  due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5210 		  *        delete the and-constraint if the resultant is of column or loose status
5211 		  *        and is not an active variable of another (multi-)aggregated/negated variable
5212 		  */
5213 		 if( looseorcolumn )
5214 		 {
5215 		    SCIP_Bool del = TRUE;
5216 	            int nfixedvars = SCIPgetNFixedVars(scip);
5217 	
5218 		    if( nfixedvars > 0 )
5219 		    {
5220 		       SCIP_VAR** fixedvars;
5221 		       SCIP_VAR** scipfixedvars;
5222 		       SCIP_VAR** activevars = NULL;
5223 		       SCIP_Real* activescalars = NULL;
5224 		       SCIP_Real activeconstant;
5225 		       int nactivevars;
5226 		       int requiredsize;
5227 		       int pos;
5228 		       int w;
5229 	
5230 		       scipfixedvars = SCIPgetFixedVars(scip);
5231 		       SCIP_CALL( SCIPduplicateBufferArray(scip, &fixedvars, scipfixedvars, nfixedvars) );
5232 	
5233 		       SCIPvarsGetProbvar(fixedvars, nfixedvars);
5234 	
5235 	               /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart,
5236 	                * for multi-aggregated variables, we need to check all active representatives
5237 	                * @todo move this outside of the consanddata loop
5238 		        */
5239 		       for( w = nfixedvars - 1; w >= 0; --w )
5240 		       {
5241 	                  if( SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_MULTAGGR )
5242 	                  {
5243 	                     if( activevars == NULL )
5244 	                     {
5245 	                        SCIP_CALL( SCIPallocBufferArray(scip, &activevars, SCIPgetNVars(scip)) );
5246 	                        SCIP_CALL( SCIPallocBufferArray(scip, &activescalars, SCIPgetNVars(scip)) );
5247 	                     }
5248 	                     assert(activevars != NULL);
5249 	                     assert(activescalars != NULL);
5250 	
5251 	                     activevars[0] = fixedvars[w];
5252 	                     activescalars[0] = 1.0;
5253 	                     activeconstant = 0.0;
5254 	                     nactivevars = 1;
5255 	
5256 	                     SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activescalars, &nactivevars, SCIPgetNVars(scip),
5257 	                           &activeconstant, &requiredsize, TRUE) );
5258 	                     assert(requiredsize <= SCIPgetNVars(scip));
5259 	
5260 	                     if( nactivevars == 0 )
5261 	                     {
5262 	                        --nfixedvars;
5263 	                        fixedvars[w] = fixedvars[nfixedvars];
5264 	                     }
5265 	                     else
5266 	                     {
5267 	                        fixedvars[w] = activevars[0];
5268 	
5269 	                        if( nactivevars > 1 )
5270 	                        {
5271 	                           int i;
5272 	
5273 	                           SCIP_CALL( SCIPreallocBufferArray(scip, &fixedvars, nfixedvars + nactivevars - 1) );
5274 	                           for( i = 1; i < nactivevars; ++i )
5275 	                           {
5276 	                              assert(SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_FIXED);
5277 	                              fixedvars[nfixedvars] = activevars[i];
5278 	                              ++nfixedvars;
5279 	                           }
5280 	                        }
5281 	                     }
5282 	                  }
5283 	
5284 			  assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5285 		       }
5286 	
5287 	               if( activevars != NULL )
5288 	               {
5289 	                  SCIPfreeBufferArray(scip, &activevars);
5290 	                  SCIPfreeBufferArray(scip, &activescalars);
5291 	               }
5292 	
5293 		       SCIPsortPtr((void**)fixedvars, SCIPvarComp, nfixedvars);
5294 	
5295 		       if( SCIPsortedvecFindPtr((void**)fixedvars, SCIPvarComp, SCIPgetResultantAnd(scip, consanddata->cons), nfixedvars, &pos) )
5296 			  del = FALSE;
5297 	
5298 		       SCIPfreeBufferArray(scip, &fixedvars);
5299 		    }
5300 	
5301 		    if( del )
5302 		    {
5303 		       SCIP_CALL( SCIPdelCons(scip, consanddata->cons) );
5304 		    }
5305 		 }
5306 	#endif
5307 	
5308 		 if( !SCIPconsIsDeleted(consanddata->cons) )
5309 		 {
5310 		    /* change flags */
5311 		    if( !looseorcolumn )
5312 		    {
5313 		       SCIP_CALL( SCIPsetConsInitial(scip, consanddata->cons, FALSE) );
5314 	#if 0
5315 		       SCIP_CALL( SCIPsetConsSeparated(scip, consanddata->cons, FALSE) );
5316 	#endif
5317 		    }
5318 		    SCIP_CALL( SCIPsetConsChecked(scip, consanddata->cons, TRUE) );
5319 		 }
5320 	
5321 	         /* remove consanddata from hashtable, if it existed only in transformed space */
5322 	         if( consanddata->origcons == NULL )
5323 	         {
5324 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
5325 	            SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddata) );
5326 	         }
5327 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5328 	         SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5329 	
5330 	         SCIP_CALL( SCIPreleaseCons(scip, &(consanddata->cons)) );
5331 	         ++(*ndelconss);
5332 	
5333 	         continue;
5334 	      }
5335 	
5336 	      cons = consanddata->cons;
5337 	      assert(cons != NULL);
5338 	
5339 	      /* if and-constraint is deleted, delete variables arrays */
5340 	      if( SCIPconsIsDeleted(cons) )
5341 	      {
5342 	         SCIP_VAR* resvar = SCIPgetResultantAnd(scip, consanddata->cons);
5343 	
5344 	         assert(consanddata->nuses > 0);
5345 	         assert(resvar != NULL);
5346 	
5347 	         SCIP_CALL( transformToOrig(scip, consanddata, conshdlrdata) );
5348 	
5349 	         /* release and-constraint */
5350 	         SCIP_CALL( SCIPreleaseCons(scip, &consanddata->cons) );
5351 	         consanddata->nuses = 0;
5352 	
5353 	         /* remove consanddata from hashtable, if it existed only in transformed space */
5354 	         if( consanddata->origcons == NULL )
5355 	         {
5356 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
5357 	            SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddata) );
5358 	         }
5359 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)resvar));
5360 	         SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)resvar) );
5361 	
5362 	         continue;
5363 	      }
5364 	
5365 	      /* if no new variables exist, we do not need to do anything here */
5366 	      if( consanddata->nnewvars == 0 )
5367 	         continue;
5368 	
5369 	      tmpvars = consanddata->vars;
5370 	      /* release all variables */
5371 	      for( v = consanddata->nvars - 1; v >= 0; --v )
5372 	      {
5373 	         /* in original problem the variables was already deleted */
5374 	         assert(tmpvars[v] != NULL);
5375 	         SCIP_CALL( SCIPreleaseVar(scip, &tmpvars[v]) );
5376 	      }
5377 	
5378 	      /* exchange newvars with old vars array */
5379 	      tmpvars = consanddata->vars;
5380 	      stmpvars = consanddata->svars;
5381 	      consanddata->vars = consanddata->newvars;
5382 	      consanddata->svars = consanddata->snewvars;
5383 	      consanddata->nvars = consanddata->nnewvars;
5384 	      consanddata->newvars = tmpvars;
5385 	      consanddata->snewvars = stmpvars;
5386 	      /* reset number of variables in newvars array */
5387 	      consanddata->nnewvars = 0;
5388 	   }
5389 	
5390 	   return SCIP_OKAY;
5391 	}
5392 	
5393 	/** update the uses counter of consandata objects which are used in pseudoboolean constraint, that were deleted and
5394 	 *  probably delete and-constraints
5395 	 */
5396 	static
5397 	SCIP_RETCODE updateConsanddataUses(
5398 	   SCIP*const            scip,               /**< SCIP data structure */
5399 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
5400 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
5401 	   int*const             ndelconss           /**< pointer to store number of deleted constraints */
5402 	   )
5403 	{
5404 	   CONSANDDATA** consanddatas;
5405 	   int nconsanddatas;
5406 	   SCIP_CONSDATA* consdata;
5407 	   int c;
5408 	
5409 	   assert(scip != NULL);
5410 	   assert(cons != NULL);
5411 	   assert(conshdlrdata != NULL);
5412 	   assert(ndelconss != NULL);
5413 	
5414 	   /* can only be called when constraint was deleted */
5415 	   assert(SCIPconsIsDeleted(cons));
5416 	
5417 	   consdata = SCIPconsGetData(cons);
5418 	   assert(consdata != NULL);
5419 	
5420 	   consanddatas = consdata->consanddatas;
5421 	   nconsanddatas = consdata->nconsanddatas;
5422 	   assert(nconsanddatas > 0 && consanddatas != NULL);
5423 	   assert(consdata->andcoefs != NULL);
5424 	
5425 	   /* remove old locks */
5426 	   for( c = nconsanddatas - 1; c >= 0; --c )
5427 	   {
5428 	      CONSANDDATA* consanddata;
5429 	
5430 	      consanddata = consanddatas[c];
5431 	      assert(consanddata != NULL);
5432 	
5433 	      if( !consanddata->istransformed )
5434 	         continue;
5435 	
5436 	      SCIP_CALL( removeOldLocks(scip, cons, consanddata, consdata->andcoefs[c], consdata->lhs, consdata->rhs) );
5437 	   }
5438 	
5439 	   /* correct consandata usage counters and data */
5440 	   for( c = nconsanddatas - 1; c >= 0; --c )
5441 	   {
5442 	      CONSANDDATA* consanddata;
5443 	
5444 	      consanddata = consanddatas[c];
5445 	      assert(consanddata != NULL);
5446 	      assert(consanddatas[c]->istransformed);
5447 	
5448 	      assert(consanddata->nuses > 0);
5449 	
5450 	      if( consanddata->nuses > 0 )
5451 	         --(consanddata->nuses);
5452 	
5453 	      /* if data object is not used anymore, delete it */
5454 	      if( consanddata->nuses == 0 )
5455 	      {
5456 	         SCIP_VAR* resvar;
5457 		 SCIP_VARSTATUS varstatus;
5458 		 SCIP_Bool looseorcolumn;
5459 	
5460 	         SCIP_CALL( transformToOrig(scip, consanddata, conshdlrdata) );
5461 	
5462 	         resvar = SCIPgetResultantAnd(scip, consanddata->cons);
5463 	         assert(resvar != NULL);
5464 	
5465 		 varstatus = SCIPvarGetStatus(resvar);
5466 		 looseorcolumn = (varstatus == SCIP_VARSTATUS_LOOSE || varstatus == SCIP_VARSTATUS_COLUMN);
5467 	
5468 	#if 1
5469 		 /* @note  due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5470 		  *        delete the and-constraint if the resultant is of column or loose status
5471 	          *        and is not an active variable of another (multi-)aggregated/negated variable
5472 		  */
5473 		 if( looseorcolumn )
5474 		 {
5475 		    SCIP_Bool delcons = TRUE;
5476 	#if 0
5477 		    const int nfixedvars = SCIPgetNFixedVars(scip);
5478 	
5479 		    if( nfixedvars > 0 )
5480 		    {
5481 		       SCIP_VAR** fixedvars;
5482 	               SCIP_Bool foundmultiaggrvar = FALSE; /* workaround for multi-aggregated variables */
5483 		       int pos;
5484 		       int w;
5485 	
5486 		       SCIP_CALL( SCIPduplicateBufferArray(scip, &fixedvars, SCIPgetFixedVars(scip), nfixedvars) );
5487 	
5488 		       SCIPvarsGetProbvar(fixedvars, nfixedvars);
5489 	
5490 		       /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart, but
5491 			* because we have only binary variables (in pseudobbolean contest) there should also be no
5492 			* multi-aggregated variable
5493 			*
5494 			* @todo for multi-aggregated variables check also all active representatives for this resultant
5495 		        */
5496 		       for( w = nfixedvars - 1; w >= 0; --w )
5497 		       {
5498 	                  if( SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_MULTAGGR )
5499 	                     foundmultiaggrvar = TRUE;
5500 	                  else
5501 	                     assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5502 		       }
5503 	
5504 		       SCIPsortPtr((void**)fixedvars, SCIPvarComp, nfixedvars);
5505 	
5506 	               if( foundmultiaggrvar )
5507 			  delcons = FALSE;
5508 		       else if( SCIPsortedvecFindPtr((void**)fixedvars, SCIPvarComp, resvar, nfixedvars, &pos) )
5509 			  delcons = FALSE;
5510 	
5511 		       SCIPfreeBufferArray(scip, &fixedvars);
5512 		    }
5513 	#endif
5514 	            /* we can only delete and constraints if the resultant is an artificial variable and also active, because
5515 	             * then the assigned value is not of interest and the artificial and constraint does not need to be
5516 	             * fulfilled
5517 	             *
5518 	             * if this variable is not such an artificial variable we need the IRRELEVANT vartype which should be the
5519 	             * correct way to fix this
5520 	             */
5521 		    if( delcons
5522 	#if 0
5523 	               && strlen(SCIPvarGetName(resvar)) > strlen(ARTIFICIALVARNAMEPREFIX) &&
5524 	               strncmp(SCIPvarGetName(resvar)+2, ARTIFICIALVARNAMEPREFIX, strlen(ARTIFICIALVARNAMEPREFIX)) == 0
5525 	#endif
5526 	               ) /*lint !e774*/
5527 		    {
5528 	               assert(!SCIPconsIsChecked(consanddata->cons));
5529 		       SCIP_CALL( SCIPdelCons(scip, consanddata->cons) );
5530 		    }
5531 		 }
5532 	#endif
5533 	
5534 	#if 0
5535 		 /* @note  due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5536 		  *        delete the and-constraint if the resultant is of column or loose status
5537 		  *        and is not an active variable of another (multi-)aggregated/negated variable
5538 		  */
5539 		 if( looseorcolumn )
5540 		 {
5541 		    SCIP_CALL( SCIPdelCons(scip, consanddata->cons) );
5542 		 }
5543 	#endif
5544 	
5545 		 if( !SCIPconsIsDeleted(consanddata->cons) )
5546 		 {
5547 		    /* change flags */
5548 		    if( !looseorcolumn )
5549 		    {
5550 		       SCIP_CALL( SCIPsetConsInitial(scip, consanddata->cons, FALSE) );
5551 	#if 0
5552 		       SCIP_CALL( SCIPsetConsSeparated(scip, consanddata->cons, FALSE) );
5553 	#endif
5554 		    }
5555 		    SCIP_CALL( SCIPsetConsChecked(scip, consanddata->cons, TRUE) );
5556 		 }
5557 	
5558 	         /* remove consanddata from hashtable, if it existed only in transformed space */
5559 	         if( consanddata->origcons == NULL )
5560 	         {
5561 	            assert(SCIPhashtableExists(conshdlrdata->hashtable, (void*)consanddata));
5562 	            SCIP_CALL( SCIPhashtableRemove(conshdlrdata->hashtable, (void*)consanddata) );
5563 	         }
5564 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5565 	         SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5566 	
5567 	         SCIP_CALL( SCIPreleaseCons(scip, &(consanddata->cons)) );
5568 	         ++(*ndelconss);
5569 	      }
5570 	   }
5571 	
5572 	   consdata->nconsanddatas = 0;
5573 	
5574 	   return SCIP_OKAY;
5575 	}
5576 	
5577 	
5578 	/* maximal number to enumerate solutions for one pseudoboolean constraint to check for an upgrade to an XOR constraint */
5579 	#define MAXNVARS 10 /* note that this cannot be bigger than 31 */
5580 	
5581 	/** calculate result for a given pseudoboolean constraint with given values, this is used to decide whether a
5582 	 *  pseudoboolean constraint can be upgrade to an XOR constraint
5583 	 */
5584 	static
5585 	SCIP_RETCODE checkSolution(
5586 	   SCIP*const            scip,               /**< SCIP data structure */
5587 	   SCIP_VAR**const       vars,               /**< all variables which occur */
5588 	   int const             nvars,              /**< number of all variables which appear in the pseudoboolean
5589 						      *   constraint
5590 						      */
5591 	   SCIP_Bool*const       values,             /**< values of all variables which appear in the pseudoboolean
5592 						      *   constraint
5593 						      */
5594 	   SCIP_VAR**const       linvars,            /**< linear variables */
5595 	   SCIP_Real*const       lincoefs,           /**< linear coefficients */
5596 	   int const             nlinvars,           /**< number of linear variables */
5597 	   SCIP_Real const       constant,           /**< offset to the linear part */
5598 	   SCIP_Real const       side,               /**< side of pseudoboolean constraint */
5599 	   CONSANDDATA**const    consanddatas,       /**< all consanddata objects in a constraint */
5600 	   SCIP_Real*const       consanddatacoefs,   /**< nonlinear coefficients */
5601 	   SCIP_Bool*const       consanddatanegs,    /**< negation status of and resultants in pseudo-boolean constraint */
5602 	   int const             nconsanddatas,      /**< number of all consanddata objects */
5603 	   int const             cnt,                /**< number of variables set to 1 */
5604 	   int*const             xortype             /**< pointer to save the possible xor type if a solution was valid and does
5605 						      *   not violate the old xortype
5606 						      */
5607 	   )
5608 	{
5609 	   CONSANDDATA* consanddata;
5610 	   SCIP_VAR** termvars;
5611 	   SCIP_VAR** repvars;
5612 	   int ntermvars;
5613 	   SCIP_Bool* negated;
5614 	   SCIP_Real value;
5615 	   int pos;
5616 	   int v;
5617 	   int c;
5618 	
5619 	   assert(scip != NULL);
5620 	   assert(vars != NULL);
5621 	   assert(nvars > 0);
5622 	   assert(values != NULL);
5623 	   assert(linvars != NULL || nlinvars == 0);
5624 	   assert(lincoefs != NULL || nlinvars == 0);
5625 	   assert(nvars >= nlinvars);
5626 	   assert(SCIPisEQ(scip, side, 1.0) || SCIPisZero(scip, side));
5627 	   assert(consanddatas != NULL);
5628 	   assert(consanddatacoefs != NULL);
5629 	   assert(nconsanddatas > 0);
5630 	   assert(*xortype >= -1 && *xortype <= 1);
5631 	
5632 	   /* order the variables after index, to compare them easier */
5633 	   SCIPsortPtr((void**)linvars, SCIPvarCompActiveAndNegated, nlinvars);
5634 	   SCIPsortPtr((void**)vars, SCIPvarCompActiveAndNegated, nvars);
5635 	
5636 	   value = constant;
5637 	   for( v = nlinvars - 1; v >= 0; --v )
5638 	   {
5639 	      if( SCIPsortedvecFindPtr((void**)vars, SCIPvarCompActiveAndNegated, linvars[v], nvars, &pos) ) /*lint !e613*/
5640 	      {
5641 		 if( values[pos] )
5642 		    value += lincoefs[v]; /*lint !e613*/
5643 	      }
5644 	      else
5645 	      {
5646 		 /* this cannot happen, all linear variables should be a part of 'vars' */
5647 	         SCIPABORT();
5648 	
5649 		 *xortype = -1;  /*lint !e527*/
5650 		 return SCIP_OKAY;
5651 	      }
5652 	   }
5653 	
5654 	   SCIP_CALL( SCIPallocBufferArray(scip, &repvars, MAXNVARS) );
5655 	   SCIP_CALL( SCIPallocBufferArray(scip, &negated, MAXNVARS) );
5656 	
5657 	   for( c = nconsanddatas - 1; c >= 0; --c )
5658 	   {
5659 	      SCIP_Bool val = TRUE;
5660 	
5661 	      consanddata = consanddatas[c];
5662 	      assert(consanddata != NULL);
5663 	      assert(consanddata->istransformed);
5664 	
5665 	      /* choose correct variable array to add locks for, we only add locks for now valid variables */
5666 	      if( consanddata->nnewvars > 0 )
5667 	      {
5668 		 termvars = consanddata->newvars;
5669 		 ntermvars = consanddata->nnewvars;
5670 	      }
5671 	      else
5672 	      {
5673 		 termvars = consanddata->vars;
5674 		 ntermvars = consanddata->nvars;
5675 	      }
5676 	      assert(ntermvars > 0 && termvars != NULL);
5677 	
5678 	      BMSclearMemoryArray(negated, MAXNVARS);
5679 	
5680 	      /* get linear active representation */
5681 	      SCIP_CALL( SCIPgetBinvarRepresentatives(scip, ntermvars, termvars, repvars, negated) );
5682 	      SCIPsortPtrBool((void**)repvars, negated, SCIPvarCompActiveAndNegated, ntermvars);
5683 	
5684 	      for( v = ntermvars - 1; v >= 0; --v )
5685 	      {
5686 		 SCIP_VAR* var;
5687 	
5688 		 assert(!negated[v] || (SCIPvarIsNegated(repvars[v]) && SCIPvarGetNegatedVar(repvars[v]) != NULL));
5689 	
5690 		 var = ( negated[v] ? SCIPvarGetNegationVar(repvars[v]) : repvars[v]);
5691 		 if( SCIPsortedvecFindPtr((void**)vars, SCIPvarCompActiveAndNegated, var, nvars, &pos) )
5692 		 {
5693 		    if( (negated[v] && values[pos]) || (!negated[v] && !values[pos]) )
5694 		    {
5695 		       val = FALSE;
5696 		       break;
5697 		    }
5698 		 }
5699 		 else
5700 		 {
5701 		    /* this cannot happen, all non-linear variables should be a part of 'vars' */
5702 		    SCIPABORT();
5703 	
5704 		    *xortype = -1; /*lint !e527*/
5705 		    goto TERMINATE;
5706 		 }
5707 	      }
5708 	
5709 	      if( val != consanddatanegs[c] )
5710 		 value += consanddatacoefs[c];
5711 	   }
5712 	
5713 	   if( SCIPisEQ(scip, value, side) )
5714 	   {
5715 	      /* first solution is checked, so determine the possible xor upgrade */
5716 	      if( *xortype == -1 )
5717 	      {
5718 		 if( cnt % 2 == 0 )
5719 		    *xortype = 0;
5720 		 else
5721 		    *xortype = 1;
5722 	      }
5723 	      /* check if this solution does not fit in all possible xor solutions */
5724 	      else if( *xortype == 1 && cnt % 2 == 0 )
5725 		 *xortype = -1;
5726 	      else if( *xortype == 0 && cnt % 2 == 1 )
5727 		 *xortype = -1;
5728 	   }
5729 	   else
5730 	   {
5731 	      /* first not-solution is checked, so determine the possible xor upgrade */
5732 	      if( *xortype == -1 )
5733 	      {
5734 		 if( cnt % 2 == 0 )
5735 		    *xortype = 1;
5736 		 else
5737 		    *xortype = 0;
5738 	      }
5739 	      /* check if this had to be a solution for an upgrade to an xor */
5740 	      else if( *xortype == 1 && cnt % 2 == 1 )
5741 		 *xortype = -1;
5742 	      else if( *xortype == 0 && cnt % 2 == 0 )
5743 		 *xortype = -1;
5744 	   }
5745 	
5746 	 TERMINATE:
5747 	   SCIPfreeBufferArray(scip, &negated);
5748 	   SCIPfreeBufferArray(scip, &repvars);
5749 	
5750 	   return SCIP_OKAY;
5751 	}
5752 	
5753 	/** try upgrading pseudoboolean linear constraint to an XOR constraint and/or remove possible and-constraints
5754 	 *
5755 	 *  @note An XOR(x_1,..,x_n) = 1 <=> XOR(x1,..,~x_j,..,x_n) = 0, for j in {1,..,n}, which is not yet checked while
5756 	 *  trying to upgrade
5757 	 */
5758 	static
5759 	SCIP_RETCODE tryUpgradingXor(
5760 	   SCIP*const            scip,               /**< SCIP data structure */
5761 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
5762 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
5763 	   int*const             ndelconss,          /**< pointer to store number of deleted constraints */
5764 	   int*const             naddconss,          /**< pointer to count number of added constraints */
5765 	   int*const             nfixedvars,         /**< pointer to store number of fixed variables */
5766 	   int*const             nchgcoefs,          /**< pointer to store number of changed coefficients constraints */
5767 	   int*const             nchgsides,          /**< pointer to store number of changed sides constraints */
5768 	   SCIP_Bool*const       cutoff              /**< pointer to store if a cutoff happened */
5769 	   )
5770 	{
5771 	   SCIP_CONSDATA* consdata;
5772 	   CONSANDDATA** consanddatas;
5773 	   int nconsanddatas;
5774 	   CONSANDDATA* consanddata;
5775 	   SCIP_VAR** allvars;
5776 	   SCIP_Real* allcoefs;
5777 	   int nallvars;
5778 	   SCIP_VAR** linvars;
5779 	   SCIP_Real* lincoefs;
5780 	   int nlinvars;
5781 	   SCIP_Real* andcoefs;
5782 	   SCIP_Bool* andnegs;
5783 	   int nandress;
5784 	   SCIP_VAR** vars;
5785 	   int nvars;
5786 	   SCIP_VAR** repvars;
5787 	   SCIP_Bool* negated;
5788 	   SCIP_VAR** activelinvars;
5789 	   SCIP_Bool* values;
5790 	   SCIP_CONS* lincons;
5791 	   SCIP_CONS* newcons;
5792 	   char newname[SCIP_MAXSTRLEN];
5793 	   SCIP_Real constant;
5794 	   int requiredsize;
5795 	   int firstnlinvars;
5796 	   int oldnlinvars;
5797 	   int xortype;
5798 	   int v;
5799 	   int v1;
5800 	   int c;
5801 	
5802 	   assert(scip != NULL);
5803 	   assert(cons != NULL);
5804 	   assert(conshdlrdata != NULL);
5805 	   assert(ndelconss != NULL);
5806 	   assert(nfixedvars != NULL);
5807 	   assert(nchgcoefs != NULL);
5808 	   assert(nchgsides != NULL);
5809 	   assert(cutoff != NULL);
5810 	   assert(SCIPconsIsActive(cons));
5811 	
5812 	   consdata = SCIPconsGetData(cons);
5813 	   assert(consdata != NULL);
5814 	
5815 	   consanddatas = consdata->consanddatas;
5816 	   andcoefs = consdata->andcoefs;
5817 	   andnegs = consdata->andnegs;
5818 	   nconsanddatas = consdata->nconsanddatas;
5819 	   assert(nconsanddatas > 0 && consanddatas != NULL);
5820 	
5821 	   assert(consdata->lincons != NULL);
5822 	   assert(consdata->linconstype == SCIP_LINEARCONSTYPE_LINEAR || consdata->linconstype == SCIP_LINEARCONSTYPE_SETPPC);
5823 	
5824 	   /* only equations can be updated */
5825 	   if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || (!SCIPisEQ(scip, consdata->lhs, 1.0) && !SCIPisZero(scip, consdata->lhs)) )
5826 	      return SCIP_OKAY;
5827 	
5828 	   assert(consanddatas[0] != NULL);
5829 	   assert(consanddatas[0]->cons != NULL);
5830 	
5831 	   lincons = consdata->lincons;
5832 	
5833 	   /* check number of linear variables */
5834 	   SCIP_CALL( getLinearConsNVars(scip, lincons, consdata->linconstype, &nallvars) );
5835 	   assert(nallvars - nconsanddatas == consdata->nlinvars);
5836 	   nlinvars = consdata->nlinvars;
5837 	
5838 	   if( nlinvars > MAXNVARS )
5839 	      return SCIP_OKAY;
5840 	
5841 	   checkConsConsistency(scip, cons);
5842 	
5843 	   /* allocate temporary memory */
5844 	   SCIP_CALL( SCIPallocBufferArray(scip, &allvars, nallvars) );
5845 	   SCIP_CALL( SCIPallocBufferArray(scip, &allcoefs, nallvars) );
5846 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, MAXNVARS) );
5847 	   SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, MAXNVARS) );
5848 	   SCIP_CALL( SCIPallocBufferArray(scip, &repvars, MAXNVARS) );
5849 	   SCIP_CALL( SCIPallocBufferArray(scip, &negated, MAXNVARS) );
5850 	
5851 	   /* get variables and coefficients */
5852 	   SCIP_CALL( getLinearConsVarsData(scip, lincons, consdata->linconstype, allvars, allcoefs, &nallvars) );
5853 	   assert(nallvars > 0);
5854 	
5855 	   /* calculate all not artificial linear variables */
5856 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, allvars, allcoefs, nallvars, linvars, lincoefs, &nlinvars,
5857 	         NULL, NULL, NULL, &nandress) );
5858 	   assert(nlinvars == consdata->nlinvars);
5859 	   assert(nandress == nallvars-nlinvars);
5860 	
5861 	   constant = 0;
5862 	
5863 	   /* get linear active representation */
5864 	   SCIP_CALL( SCIPgetProbvarLinearSum(scip, linvars, lincoefs, &nlinvars, MAXNVARS, &constant, &requiredsize, TRUE) );
5865 	   SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvars, linvars, nlinvars) );
5866 	
5867 	   if( requiredsize > MAXNVARS )
5868 	      goto TERMINATE;
5869 	
5870 	   firstnlinvars = nlinvars;
5871 	
5872 	   /* order the variables after index, to compare them easier */
5873 	   SCIPsortPtr((void**)linvars, SCIPvarCompActiveAndNegated, nlinvars);
5874 	
5875 	   for( c = nconsanddatas - 1; c >= 0; --c )
5876 	   {
5877 	      consanddata = consanddatas[c];
5878 	      assert(consanddata != NULL);
5879 	      assert(consanddata->istransformed);
5880 	
5881 	      /* choose correct variable array */
5882 	      if( consanddata->nnewvars > 0 )
5883 	      {
5884 	         vars = consanddata->newvars;
5885 	         nvars = consanddata->nnewvars;
5886 	      }
5887 	      else
5888 	      {
5889 	         vars = consanddata->vars;
5890 	         nvars = consanddata->nvars;
5891 	      }
5892 	      assert(nvars > 0 && vars != NULL);
5893 	
5894 	      if( nvars > MAXNVARS )
5895 	         goto TERMINATE;
5896 	
5897 	      BMSclearMemoryArray(negated, MAXNVARS);
5898 	
5899 	      /* get linear active representation */
5900 	      SCIP_CALL( SCIPgetBinvarRepresentatives(scip, nvars, vars, repvars, negated) );
5901 	      SCIPsortPtr((void**)repvars, SCIPvarCompActiveAndNegated, nvars);
5902 	
5903 	      oldnlinvars = nlinvars;
5904 	
5905 	      /* determine all different variables over the linear variables and all variables in all and constraints */
5906 	      for( v = nvars - 1, v1 = nlinvars - 1; v >= 0 && v1 >= 0; )
5907 	      {
5908 	         SCIP_VAR* var;
5909 	
5910 	         /* it appears that some fixed variables were not yet deleted */
5911 	         if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
5912 	            goto TERMINATE;
5913 	
5914 	         assert(SCIPvarIsActive(linvars[v1]));
5915 	         assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
5916 	
5917 	         if( SCIPvarIsActive(repvars[v]) )
5918 	            var = repvars[v];
5919 	         else
5920 	            var = SCIPvarGetNegationVar(repvars[v]);
5921 	
5922 	         /* implicit binary variables cannot be handled by xor */
5923 	         if( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT )
5924 	            goto TERMINATE;
5925 	
5926 	         if( SCIPvarGetIndex(var) > SCIPvarGetIndex(linvars[v1]) )
5927 	         {
5928 	            if( nlinvars + 1 < MAXNVARS )
5929 	            {
5930 	               linvars[nlinvars] = var;
5931 	               ++nlinvars;
5932 	            }
5933 	            else
5934 	               goto TERMINATE;
5935 	
5936 	            --v;
5937 	         }
5938 	         else if( SCIPvarGetIndex(var) < SCIPvarGetIndex(linvars[v1]) )
5939 	            --v1;
5940 	         else
5941 	         {
5942 	            --v;
5943 	            --v1;
5944 	         }
5945 	      }
5946 	
5947 	      /* add the rest of variables */
5948 	      if( v >= 0 )
5949 	      {
5950 	         SCIP_VAR* var;
5951 	
5952 	         for( ; v >= 0; --v )
5953 	         {
5954 	            /* it appears that some fixed variables were not yet deleted */
5955 	            if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
5956 	               goto TERMINATE;
5957 	
5958 	            assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
5959 	
5960 	            if( SCIPvarIsActive(repvars[v]) )
5961 	               var = repvars[v];
5962 	            else
5963 	               var = SCIPvarGetNegationVar(repvars[v]);
5964 	
5965 	            /* implicit binary variables cannot be handled by xor */
5966 	            if( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT )
5967 	               goto TERMINATE;
5968 	
5969 	            if( nlinvars + 1 < MAXNVARS )
5970 	            {
5971 	               linvars[nlinvars] = var;
5972 	               ++nlinvars;
5973 	            }
5974 	            else
5975 	               goto TERMINATE;
5976 	         }
5977 	      }
5978 	
5979 	      /* if some new variables were inserted we need to reorder the array */
5980 	      if( nlinvars > oldnlinvars )
5981 	      {
5982 	         /* order the variables after index, to compare them easier */
5983 	         SCIPsortPtr((void**)linvars, SCIPvarCompActiveAndNegated, nlinvars);
5984 	      }
5985 	   }
5986 	
5987 	   SCIP_CALL( SCIPallocBufferArray(scip, &values, nlinvars) );
5988 	   xortype = -1;
5989 	
5990 	   /* check values for variables which result in solutions which in the end lead to an XOR upgrade */
5991 	   for( v = (1 << nlinvars) - 1; v >= 0; --v ) /*lint !e701*/
5992 	   {
5993 	      int cnt = 0;
5994 	      for( v1 = nlinvars - 1; v1 >= 0; --v1 )
5995 	         if( v & (1 << v1) ) /*lint !e701*/
5996 	         {
5997 	            values[v1] = TRUE;
5998 	            ++cnt;
5999 	         }
6000 	         else
6001 	            values[v1] = FALSE;
6002 	
6003 	      /* at maximum nlinvars values could be set to TRUE */
6004 	      assert(cnt <= nlinvars);
6005 	
6006 	      SCIP_CALL( checkSolution(scip, linvars, nlinvars, values, activelinvars, lincoefs, firstnlinvars, constant,
6007 	            consdata->lhs, consanddatas, andcoefs, andnegs, nconsanddatas, cnt, &xortype) );
6008 	      if( xortype == -1 )
6009 	         break;
6010 	   }
6011 	
6012 	   SCIPfreeBufferArray(scip, &values);
6013 	
6014 	   assert(xortype >= -1 && xortype <= 1);
6015 	
6016 	   if( xortype >= 0 )
6017 	   {
6018 	      (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_upgraded", SCIPconsGetName(lincons));
6019 	
6020 	      SCIP_CALL( SCIPcreateConsXor(scip, &newcons, newname, (SCIP_Bool) xortype, nlinvars, linvars,
6021 	            SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
6022 	            SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons),
6023 	            SCIPconsIsDynamic(lincons), SCIPconsIsRemovable(lincons), SCIPconsIsStickingAtNode(lincons)) );
6024 	
6025 	      /* add and release new constraint */
6026 	      SCIP_CALL( SCIPaddCons(scip, newcons) );
6027 	
6028 	      SCIPdebugMsg(scip, "created upgraded XOR constraint:\n");
6029 	      SCIPdebugMsg(scip, "old -> ");
6030 	      SCIPdebugPrintCons(scip, lincons, NULL);
6031 	      SCIPdebugMsg(scip, "new -> ");
6032 	      SCIPdebugPrintCons(scip, newcons, NULL);
6033 	
6034 	      SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6035 	      ++(*naddconss);
6036 	
6037 	      /* delete old constraints */
6038 	      SCIP_CALL( SCIPdelCons(scip, lincons) );
6039 	      SCIP_CALL( SCIPdelCons(scip, cons) );
6040 	      (*ndelconss) += 2;
6041 	   }
6042 	
6043 	 TERMINATE:
6044 	   /* delete temporary memory */
6045 	   SCIPfreeBufferArray(scip, &activelinvars);
6046 	   SCIPfreeBufferArray(scip, &negated);
6047 	   SCIPfreeBufferArray(scip, &repvars);
6048 	   SCIPfreeBufferArray(scip, &lincoefs);
6049 	   SCIPfreeBufferArray(scip, &linvars);
6050 	   SCIPfreeBufferArray(scip, &allcoefs);
6051 	   SCIPfreeBufferArray(scip, &allvars);
6052 	
6053 	   return SCIP_OKAY;
6054 	}
6055 	
6056 	/** try upgrading pseudoboolean logicor constraint to a linear constraint and/or remove possible and-constraints */
6057 	static
6058 	SCIP_RETCODE tryUpgradingLogicor(
6059 	   SCIP*const            scip,               /**< SCIP data structure */
6060 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
6061 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
6062 	   int*const             ndelconss,          /**< pointer to store number of deleted constraints */
6063 	   int*const             naddconss,          /**< pointer to count number of added constraints */
6064 	   int*const             nfixedvars,         /**< pointer to store number of fixed variables */
6065 	   int*const             nchgcoefs,          /**< pointer to store number of changed coefficients constraints */
6066 	   int*const             nchgsides,          /**< pointer to store number of changed sides constraints */
6067 	   SCIP_Bool*const       cutoff              /**< pointer to store if a cutoff happened */
6068 	   )
6069 	{
6070 	   CONSANDDATA** consanddatas;
6071 	   int nconsanddatas;
6072 	   SCIP_CONSDATA* consdata;
6073 	   int c;
6074 	   int v;
6075 	   int v2;
6076 	   SCIP_VAR** eqvars;
6077 	   int neqvars;
6078 	   int nminvars;
6079 	   int nmaxvars;
6080 	
6081 	   assert(scip != NULL);
6082 	   assert(cons != NULL);
6083 	   assert(conshdlrdata != NULL);
6084 	   assert(ndelconss != NULL);
6085 	   assert(nfixedvars != NULL);
6086 	   assert(nchgcoefs != NULL);
6087 	   assert(nchgsides != NULL);
6088 	   assert(cutoff != NULL);
6089 	   assert(SCIPconsIsActive(cons));
6090 	
6091 	   consdata = SCIPconsGetData(cons);
6092 	   assert(consdata != NULL);
6093 	
6094 	   consanddatas = consdata->consanddatas;
6095 	   nconsanddatas = consdata->nconsanddatas;
6096 	   assert(nconsanddatas > 0 && consanddatas != NULL);
6097 	
6098 	   assert(consdata->lincons != NULL);
6099 	   assert(consdata->linconstype == SCIP_LINEARCONSTYPE_LOGICOR);
6100 	
6101 	   assert(consanddatas[0] != NULL);
6102 	   assert(consanddatas[0]->cons != NULL);
6103 	
6104 	   if( nconsanddatas == 1 )
6105 	   {
6106 	      CONSANDDATA* consanddata;
6107 	      SCIP_VAR** allvars;
6108 	      SCIP_Real* allcoefs;
6109 	      int nallvars;
6110 	      SCIP_VAR** linvars;
6111 	      SCIP_Real* lincoefs;
6112 	      int nlinvars;
6113 	      SCIP_VAR** vars;
6114 	      int nvars;
6115 	      SCIP_CONS* lincons;
6116 	      SCIP_CONS* newcons;
6117 	      char newname[SCIP_MAXSTRLEN];
6118 	      SCIP_Real lhs;
6119 	      SCIP_Real rhs;
6120 	
6121 	      /* if we have only one term left in the logicor constraint, the presolving should be done by the logicor
6122 	       * constraint handler
6123 	       */
6124 	      if( consdata->nlinvars == 0 )
6125 	      {
6126 	         return SCIP_OKAY;
6127 	      }
6128 	
6129 	      /* for every old logicor constraint: sum_i (x_i) + res >= 1 , with an and-constraint of res as the resultant,
6130 	       *     which looks like 'res = y_1 * ... * y_n' => sum_i (n * x_i) + sum_j=1^n y_j >= n
6131 	       *
6132 	       * i.e. x_1 +  x_2 +  x_3 + x_4 * x_5 * x_6 >= 1
6133 	       *  => 3x_1 + 3x_2 + 3x_3 + x_4 + x_5 + x_6 >= 3
6134 	       */
6135 	
6136 	      lincons = consdata->lincons;
6137 	
6138 	      consanddata = consanddatas[0];
6139 	      assert(consanddata != NULL);
6140 	      assert(consanddata->istransformed);
6141 	
6142 	      /* choose correct variable array to add locks for, we only add locks for now valid variables */
6143 	      if( consanddata->nnewvars > 0 )
6144 	      {
6145 	         vars = consanddata->newvars;
6146 	         nvars = consanddata->nnewvars;
6147 	      }
6148 	      else
6149 	      {
6150 	         vars = consanddata->vars;
6151 	         nvars = consanddata->nvars;
6152 	      }
6153 	      assert(nvars > 0 && vars != NULL);
6154 	
6155 	      lhs = nvars;
6156 	      rhs = SCIPinfinity(scip);
6157 	
6158 	      (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_upgraded", SCIPconsGetName(lincons));
6159 	
6160 	      SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, newname, 0, NULL, NULL, lhs, rhs,
6161 	            SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
6162 	            SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons),
6163 	            SCIPconsIsDynamic(lincons), SCIPconsIsRemovable(lincons), SCIPconsIsStickingAtNode(lincons)) );
6164 	
6165 	      /* check number of linear variables */
6166 	      SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nallvars) );
6167 	      assert(nallvars == consdata->nlinvars + 1);
6168 	
6169 	      nlinvars = consdata->nlinvars;
6170 	
6171 	      /* allocate temporary memory */
6172 	      SCIP_CALL( SCIPallocBufferArray(scip, &allvars, nallvars) );
6173 	      SCIP_CALL( SCIPallocBufferArray(scip, &allcoefs, nallvars) );
6174 	      SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinvars) );
6175 	      SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nlinvars) );
6176 	
6177 	      /* get variables and coefficients */
6178 	      SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, allvars, allcoefs, &nallvars) );
6179 	      assert(allcoefs != NULL);
6180 	
6181 	      /* calculate all not artificial linear variables */
6182 	      SCIP_CALL( getLinVarsAndAndRess(scip, cons, allvars, allcoefs, nallvars, linvars, lincoefs, &nlinvars,
6183 	            NULL, NULL, NULL, NULL) );
6184 	      assert(nlinvars == consdata->nlinvars);
6185 	
6186 	      /* add linear part to new constraint */
6187 	      for( v = 0; v < nlinvars; ++v )
6188 	      {
6189 	         SCIP_CALL( SCIPaddCoefLinear(scip, newcons, linvars[v], (SCIP_Real) nvars) );
6190 	      }
6191 	
6192 	      /* add non-linear part to new constraint */
6193 	      for( v = 0; v < nvars; ++v )
6194 	      {
6195 	         SCIP_CALL( SCIPaddCoefLinear(scip, newcons, vars[v], 1.0) );
6196 	      }
6197 	
6198 	      /* add and release new constraint */
6199 	      SCIP_CALL( SCIPaddCons(scip, newcons) );
6200 	
6201 	      SCIPdebugMsg(scip, "created upgraded linear constraint:\n");
6202 	      SCIPdebugMsg(scip, "old -> ");
6203 	      SCIPdebugPrintCons(scip, lincons, NULL);
6204 	      SCIPdebugMsg(scip, "new -> ");
6205 	      SCIPdebugPrintCons(scip, newcons, NULL);
6206 	
6207 	      SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6208 	      ++(*naddconss);
6209 	
6210 	      /* delete old constraints */
6211 	      SCIP_CALL( SCIPdelCons(scip, lincons) );
6212 	      SCIP_CALL( SCIPdelCons(scip, cons) );
6213 	      (*ndelconss) += 2;
6214 	
6215 	      /* delete temporary memory */
6216 	      SCIPfreeBufferArray(scip, &lincoefs);
6217 	      SCIPfreeBufferArray(scip, &linvars);
6218 	      SCIPfreeBufferArray(scip, &allcoefs);
6219 	      SCIPfreeBufferArray(scip, &allvars);
6220 	
6221 	      return SCIP_OKAY;
6222 	   }
6223 	
6224 	   /* initializing array for variables which can appear in all consanddata objects */
6225 	   c = nconsanddatas - 1;
6226 	   assert(consanddatas[c]->istransformed);
6227 	
6228 	   /* choose correct variable array */
6229 	   if( consanddatas[c]->nnewvars > 0 )
6230 	   {
6231 	      neqvars = consanddatas[c]->nnewvars;
6232 	      /* allocate temporary memory */
6233 	      SCIP_CALL( SCIPduplicateBufferArray(scip, &eqvars, consanddatas[c]->newvars, neqvars) );
6234 	   }
6235 	   else
6236 	   {
6237 	      neqvars = consanddatas[c]->nvars;
6238 	      /* allocate temporary memory */
6239 	      SCIP_CALL( SCIPduplicateBufferArray(scip, &eqvars, consanddatas[c]->vars, neqvars) );
6240 	   }
6241 	   nminvars = neqvars;
6242 	   nmaxvars = neqvars;
6243 	   assert(neqvars > 0 && eqvars != NULL);
6244 	
6245 	#ifndef NDEBUG
6246 	   /* check that variables are sorted */
6247 	   for( v = neqvars - 1; v > 0; --v )
6248 	      assert(SCIPvarGetIndex(eqvars[v]) > SCIPvarGetIndex(eqvars[v - 1]));
6249 	#endif
6250 	   /* computing all variables which appear in all consanddata objects */
6251 	   for( --c ; c >= 0; --c )
6252 	   {
6253 	      CONSANDDATA* consanddata;
6254 	      SCIP_VAR** vars;
6255 	      int nvars;
6256 	      int nneweqvars;
6257 	
6258 	      consanddata = consanddatas[c];
6259 	      assert(consanddata != NULL);
6260 	      assert(consanddatas[c]->istransformed);
6261 	
6262 	      /* choose correct variable array to add locks for, we only add locks for now valid variables */
6263 	      if( consanddata->nnewvars > 0 )
6264 	      {
6265 	         vars = consanddata->newvars;
6266 	         nvars = consanddata->nnewvars;
6267 	      }
6268 	      else
6269 	      {
6270 	         vars = consanddata->vars;
6271 	         nvars = consanddata->nvars;
6272 	      }
6273 	      assert(nvars > 0 && vars != NULL);
6274 	
6275 	#ifndef NDEBUG
6276 	      /* check that variables are sorted */
6277 	      for( v = nvars - 1; v > 0; --v )
6278 	         assert(SCIPvarGetIndex(vars[v]) > SCIPvarGetIndex(vars[v - 1]));
6279 	#endif
6280 	
6281 	      /* update minimal number of variables in and-constraint */
6282 	      if( nvars < nminvars )
6283 	         nminvars = nvars;
6284 	      /* update maximal number of variables in and-constraint */
6285 	      else if( nvars > nmaxvars )
6286 	         nmaxvars = nvars;
6287 	      assert(nminvars > 0);
6288 	      assert(nminvars <= nmaxvars);
6289 	
6290 	      nneweqvars = 0;
6291 	      for( v = 0, v2 = 0; v < neqvars && v2 < nvars; )
6292 	      {
6293 	         int index1;
6294 	         int index2;
6295 	
6296 	         assert(eqvars[v] != NULL);
6297 	         assert(vars[v2] != NULL);
6298 	         index1 = SCIPvarGetIndex(eqvars[v]);
6299 	         index2 = SCIPvarGetIndex(vars[v2]);
6300 	
6301 	         /* check which variables are still in all and-constraints */
6302 	         if( index1 < index2 )
6303 	            ++v;
6304 	         else if( index1 > index2 )
6305 	            ++v2;
6306 	         else
6307 	         {
6308 	            assert(index1 == index2);
6309 	            assert(nneweqvars <= v);
6310 	
6311 	            if( nneweqvars < v )
6312 	               eqvars[nneweqvars] = eqvars[v];
6313 	            ++nneweqvars;
6314 	            ++v;
6315 	            ++v2;
6316 	         }
6317 	      }
6318 	      neqvars = nneweqvars;
6319 	
6320 	      /* now we only want to handle the easy case where nminvars == neqvars + 1
6321 	       * @todo: implement for the othercase too
6322 	       */
6323 	      if( nminvars > neqvars + 1 )
6324 	         break;
6325 	
6326 	      /* if no variables overlap we have to stop */
6327 	      if( neqvars == 0 )
6328 	         break;
6329 	   }
6330 	
6331 	   /* if all and-constraints in pseudoboolean constraint have some equal variables we can extract them and create a new
6332 	    * linear constraint; iff the number of equal variables is equal to the number of variables - 1 in all consanddata
6333 	    * objects then the new constraint will not contain any products; if no normal linear variables exist we can fix all
6334 	    * equal variables to 1
6335 	    *
6336 	    * e.g. x1 * x2 + x1 * x3 + x1 * x4 >= 1
6337 	    * =>   x1 = 1 /\ x2 + x3 + x4 >= 1
6338 	    *
6339 	    * e.g. x1 * x2 * x3 + x1 * x2 * x4 + x5 >= 1
6340 	    * =>  2x1 + 2x2 + x3 + x4 + 5x5 >= 5
6341 	    *
6342 	    * e.g. x1 * x2 * x3 + x1 * x4 >= 1
6343 	    * =>   x1 = 1 /\ x2 * x3 + x4 >= 1 (constraint is created indirectly, caused by the fixing of x1)
6344 	    *
6345 	    * @todo: implement the next cases
6346 	    *
6347 	    * e.g. x1 * x2 * x3 + x1 * x4 + x5 >= 1
6348 	    * =>  2x1 + x2 * x3 + x4 + 3x5 >= 3 (x2 * x3 will be a new and-constraint)
6349 	    *
6350 	    * e.g. x1 * x2 + x1 * x2 * x3 + x4 >= 1
6351 	    * =>  x1 + x2 + 2x4 >= 2
6352 	    *
6353 	    * e.g. x1 * x2 + x1 * x3 + x2 * x3 + sum_i x_i >= 1
6354 	    * =>  x1 + x2 + x3 + 2 * sum_i x_i >= 2
6355 	    *
6356 	    */
6357 	
6358 	   /* Extract additional information ???
6359 	    *
6360 	    * e.g. x1 * x2 * x4 + x1 * x3 * x5 + x2 * x3 * x6 >= 1
6361 	    * =>  extract x1 + x2 + x3 >= 2
6362 	    */
6363 	
6364 	   /* if we have no normal linear variable in the logicor constraint, we can fix all equal variables */
6365 	   if( neqvars > 0 && consdata->nlinvars == 0 )
6366 	   {
6367 	      SCIP_Bool infeasible;
6368 	      SCIP_Bool fixed;
6369 	
6370 	      /* fix all equal variable in logicor constraints which have to be one to fulfill the constraint */
6371 	      for( v = 0; v < neqvars; ++v )
6372 	      {
6373 	         /* fix the variable which cannot be one */
6374 	         SCIP_CALL( SCIPfixVar(scip, eqvars[v], 1.0, &infeasible, &fixed) );
6375 	         if( infeasible )
6376 	         {
6377 	            SCIPdebugMsg(scip, " -> infeasible fixing\n");
6378 	            *cutoff = TRUE;
6379 	            goto TERMINATE;
6380 	         }
6381 	         if( fixed )
6382 	            ++(*nfixedvars);
6383 	      }
6384 	
6385 	      /* if a complete consanddata object have all variables in common with all other consanddata objects, than we can
6386 	       * delete this constraint after fixing all equal variables
6387 	       */
6388 	      if( nminvars == neqvars )
6389 	      {
6390 	         /* delete old constraints */
6391 	         SCIP_CALL( SCIPdelCons(scip, consdata->lincons) );
6392 	         SCIP_CALL( SCIPdelCons(scip, cons) );
6393 	         (*ndelconss) += 2;
6394 	
6395 	         goto TERMINATE;
6396 	      }
6397 	   }
6398 	
6399 	   /* now the following condition grant us that we can linearize the whole constraint */
6400 	   if( neqvars > 0 && nminvars == nmaxvars && nminvars == neqvars + 1 )
6401 	   {
6402 	      SCIP_CONS* lincons;
6403 	      SCIP_CONS* newcons;
6404 	      char newname[SCIP_MAXSTRLEN];
6405 	      SCIP_Real lhs;
6406 	      SCIP_Real rhs;
6407 	
6408 	      lhs = 1.0;
6409 	      rhs = SCIPinfinity(scip);
6410 	
6411 	      lincons = consdata->lincons;
6412 	
6413 	      (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_upgraded", SCIPconsGetName(lincons));
6414 	
6415 	      SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, newname, 0, NULL, NULL, lhs, rhs,
6416 	            SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
6417 	            SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons),
6418 	            SCIPconsIsDynamic(lincons), SCIPconsIsRemovable(lincons), SCIPconsIsStickingAtNode(lincons)) );
6419 	
6420 	      /* if createcons == TRUE add all variables which are not in the eqvars array to the new constraint with
6421 	       * coefficient 1.0
6422 	       */
6423 	      for( c = nconsanddatas - 1; c >= 0; --c )
6424 	      {
6425 	         CONSANDDATA* consanddata;
6426 	         SCIP_VAR** vars;
6427 	         int nvars;
6428 	
6429 	         consanddata = consanddatas[c];
6430 	         assert(consanddata != NULL);
6431 	         assert(consanddatas[c]->istransformed);
6432 	
6433 	         /* choose correct variable array to add locks for, we only add locks for now valid variables */
6434 	         if( consanddata->nnewvars > 0 )
6435 	         {
6436 	            vars = consanddata->newvars;
6437 	            nvars = consanddata->nnewvars;
6438 	         }
6439 	         else
6440 	         {
6441 	            vars = consanddata->vars;
6442 	            nvars = consanddata->nvars;
6443 	         }
6444 	         assert(nvars > 0 && vars != NULL);
6445 	
6446 	         for( v = 0, v2 = 0; v < neqvars && v2 < nvars; )
6447 	         {
6448 	            int index1;
6449 	            int index2;
6450 	
6451 	            assert(eqvars[v] != NULL);
6452 	            assert(vars[v2] != NULL);
6453 	            index1 = SCIPvarGetIndex(eqvars[v]);
6454 	            index2 = SCIPvarGetIndex(vars[v2]);
6455 	
6456 	            /* all variables in eqvars array must exist in all and-constraints */
6457 	            assert(index1 >= index2);
6458 	
6459 	            if( index1 > index2 )
6460 	            {
6461 	               SCIP_CALL( SCIPaddCoefLinear(scip, newcons, vars[v2], 1.0) );
6462 	               ++v2;
6463 	            }
6464 	            else
6465 	            {
6466 	               assert(index1 == index2);
6467 	               ++v;
6468 	               ++v2;
6469 	            }
6470 	         }
6471 	
6472 	         /* if we did not loop over all variables in the and-constraint, go on and fix variables */
6473 	         if( v2 < nvars )
6474 	         {
6475 	            assert(v == neqvars);
6476 	            for( ; v2 < nvars; ++v2)
6477 	            {
6478 	               SCIP_CALL( SCIPaddCoefLinear(scip, newcons, vars[v2], 1.0) );
6479 	            }
6480 	         }
6481 	         assert(v == neqvars && v2 == nvars);
6482 	      }
6483 	
6484 	      /* if we have normal linear variable in the logicor constraint, we did not fix all equal variables and we have to
6485 	       * add them with a coefficient of 'nconsanddatas'
6486 	       * we have to add also all normal linear variables with a coefficient of 'nconsanddatas * neqvars + 1'
6487 	       */
6488 	      if( consdata->nlinvars > 0 )
6489 	      {
6490 	         SCIP_VAR** vars;
6491 	         SCIP_Real* coefs;
6492 	         int nvars;
6493 	         SCIP_VAR** linvars;
6494 	         SCIP_Real* lincoefs;
6495 	         int nlinvars;
6496 	
6497 	         /* add all equal variables */
6498 	         for( v = 0; v < neqvars; ++v )
6499 	         {
6500 	            SCIP_CALL( SCIPaddCoefLinear(scip, newcons, eqvars[v], (SCIP_Real)nconsanddatas) );
6501 	         }
6502 	
6503 	         /* check number of linear variables */
6504 	         SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
6505 	         assert(nvars == consdata->nlinvars + consdata->nconsanddatas);
6506 	
6507 	         /* allocate temporary memory */
6508 	         SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
6509 	         SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
6510 	         SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
6511 	         SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
6512 	
6513 	         /* get variables and coefficients */
6514 	         SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
6515 	         assert(nvars == 0 || (coefs != NULL));
6516 	
6517 	#ifndef NDEBUG
6518 	         /* all coefficients have to be 1 */
6519 	         for( v = 0; v < nvars; ++v )
6520 	            assert(SCIPisEQ(scip, coefs[v], 1.0));
6521 	#endif
6522 	         /* calculate all not artificial linear variables */
6523 	         SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
6524 	               NULL, NULL, NULL, NULL) );
6525 	         assert(nlinvars == consdata->nlinvars);
6526 	
6527 	         /* add all old normal linear variables */
6528 	         for( v = 0; v < nlinvars; ++v )
6529 	         {
6530 	            SCIP_CALL( SCIPaddCoefLinear(scip, newcons, linvars[v], (SCIP_Real)(nconsanddatas * neqvars + 1)) ); /*lint !e732 !e790*/
6531 	         }
6532 	
6533 	         /* reset left hand side to correct value */
6534 	         SCIP_CALL( SCIPchgLhsLinear(scip, newcons, (SCIP_Real)(nconsanddatas * neqvars + 1)) ); /*lint !e732 !e790*/
6535 	
6536 	         /* free temporary memory */
6537 	         SCIPfreeBufferArray(scip, &lincoefs);
6538 	         SCIPfreeBufferArray(scip, &linvars);
6539 	         SCIPfreeBufferArray(scip, &coefs);
6540 	         SCIPfreeBufferArray(scip, &vars);
6541 	      }
6542 	
6543 	      /* add and release new constraint */
6544 	      SCIP_CALL( SCIPaddCons(scip, newcons) );
6545 	
6546 	      SCIPdebugMsg(scip, "created upgraded linear constraint:\n");
6547 	      SCIPdebugMsg(scip, "old -> ");
6548 	      SCIPdebugPrintCons(scip, lincons, NULL);
6549 	      SCIPdebugMsg(scip, "new -> ");
6550 	      SCIPdebugPrintCons(scip, newcons, NULL);
6551 	
6552 	      SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6553 	      ++(*naddconss);
6554 	
6555 	      /* delete old constraints */
6556 	      SCIP_CALL( SCIPdelCons(scip, lincons) );
6557 	      SCIP_CALL( SCIPdelCons(scip, cons) );
6558 	      (*ndelconss) += 2;
6559 	   }
6560 	
6561 	 TERMINATE:
6562 	   /* free temporary memory */
6563 	   SCIPfreeBufferArray(scip, &eqvars);
6564 	
6565 	   return SCIP_OKAY;
6566 	}
6567 	
6568 	/** try upgrading pseudoboolean setppc constraint to a linear constraint and/or remove possible and-constraints */
6569 	static
6570 	SCIP_RETCODE tryUpgradingSetppc(
6571 	   SCIP*const            scip,               /**< SCIP data structure */
6572 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
6573 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
6574 	   int*const             ndelconss,          /**< pointer to store number of deleted constraints */
6575 	   int*const             naddconss,          /**< pointer to count number of added constraints */
6576 	   int*const             nfixedvars,         /**< pointer to store number of fixed variables */
6577 	   int*const             nchgcoefs,          /**< pointer to store number of changed coefficients constraints */
6578 	   int*const             nchgsides,          /**< pointer to store number of changed sides constraints */
6579 	   SCIP_Bool*const       cutoff              /**< pointer to store if a cutoff happened */
6580 	   )
6581 	{
6582 	   CONSANDDATA** consanddatas;
6583 	   int nconsanddatas;
6584 	   SCIP_CONSDATA* consdata;
6585 	   SCIP_SETPPCTYPE type;
6586 	   int c;
6587 	   int v;
6588 	   int v2;
6589 	   SCIP_VAR** eqvars;
6590 	   int neqvars;
6591 	   int nminvars;
6592 	   int nmaxvars;
6593 	
6594 	   assert(scip != NULL);
6595 	   assert(cons != NULL);
6596 	   assert(conshdlrdata != NULL);
6597 	   assert(ndelconss != NULL);
6598 	   assert(nfixedvars != NULL);
6599 	   assert(nchgcoefs != NULL);
6600 	   assert(nchgsides != NULL);
6601 	   assert(cutoff != NULL);
6602 	   assert(SCIPconsIsActive(cons));
6603 	
6604 	   consdata = SCIPconsGetData(cons);
6605 	   assert(consdata != NULL);
6606 	
6607 	   consanddatas = consdata->consanddatas;
6608 	   nconsanddatas = consdata->nconsanddatas;
6609 	   assert(nconsanddatas > 0 && consanddatas != NULL);
6610 	
6611 	   assert(consdata->lincons != NULL);
6612 	   assert(consdata->linconstype == SCIP_LINEARCONSTYPE_SETPPC);
6613 	
6614 	   type = SCIPgetTypeSetppc(scip, consdata->lincons);
6615 	
6616 	   switch( type )
6617 	   {
6618 	   case SCIP_SETPPCTYPE_PARTITIONING:
6619 	   case SCIP_SETPPCTYPE_PACKING:
6620 	      break;
6621 	   case SCIP_SETPPCTYPE_COVERING:
6622 	      return SCIP_OKAY;
6623 	   default:
6624 	      SCIPerrorMessage("unknown setppc type\n");
6625 	      return SCIP_INVALIDDATA;
6626 	   }
6627 	
6628 	   assert(consanddatas[0] != NULL);
6629 	   assert(consanddatas[0]->cons != NULL);
6630 	
6631 	   if( nconsanddatas == 1 )
6632 	   {
6633 	      /* if we have only one term left in the setppc constraint, the presolving should be done by the setppc constraint handler */
6634 	      if( consdata->nlinvars == 0 )
6635 	      {
6636 	         return SCIP_OKAY;
6637 	      }
6638 	
6639 	      /* @todo: implement the following */
6640 	
6641 	      /* for each set packing constraint:
6642 	       *     sum_i (x_i) + res <= 1 , with and-constraint of res as the resultant like res = y_1 * ... * y_n
6643 	       *  => sum_i (n * x_i) + sum_j=1^n y_j <= n + n-1
6644 	       *
6645 	       * i.e. x_1 + x_2 + x_3 + x_4*x_5*x_6 <= 1
6646 	       *  => 3x_1 + 3x_2 + 3x_3 + x_4 + x_5 + x_6 <= 5
6647 	       */
6648 	
6649 	      /* for each set partitioning constraint:
6650 	       *     sum_i (x_i) + res = 1 , with the corresponding and-constraint of res like
6651 	       *                             res = y_1 * ... * y_n
6652 	       *
6653 	       *  => n <= sum_i (n * x_i) + sum_j=1^n y_j <= 2 * n - 1
6654 	       *
6655 	       * i.e. x_1 + x_2 + x_3 + x_4*x_5*x_6 = 1
6656 	       *  => 3 <= 3x_1 + 3x_2 + 3x_3 + x_4 + x_5 + x_6 <= 5
6657 	       *
6658 	       */
6659 	
6660 	      return SCIP_OKAY;
6661 	   }
6662 	
6663 	   if( consdata->nlinvars > 0 )
6664 	   {
6665 	      /* @todo: */
6666 	      return SCIP_OKAY;
6667 	   }
6668 	   assert(consdata->nlinvars == 0 && nconsanddatas > 1);
6669 	
6670 	   c = nconsanddatas - 1;
6671 	   assert(consanddatas[c]->istransformed);
6672 	
6673 	   /* initializing array for variables which can appear in all consanddata objects */
6674 	   if( consanddatas[c]->nnewvars > 0 )
6675 	   {
6676 	      neqvars = consanddatas[c]->nnewvars;
6677 	      /* allocate temporary memory */
6678 	      SCIP_CALL( SCIPduplicateBufferArray(scip, &eqvars, consanddatas[c]->newvars, neqvars) );
6679 	   }
6680 	   else
6681 	   {
6682 	      neqvars = consanddatas[c]->nvars;
6683 	      /* allocate temporary memory */
6684 	      SCIP_CALL( SCIPduplicateBufferArray(scip, &eqvars, consanddatas[c]->vars, neqvars) );
6685 	   }
6686 	   nminvars = neqvars;
6687 	   nmaxvars = neqvars;
6688 	   assert(neqvars > 0 && eqvars != NULL);
6689 	
6690 	#ifndef NDEBUG
6691 	   /* check that variables are sorted */
6692 	   for( v = neqvars - 1; v > 0; --v )
6693 	      assert(SCIPvarGetIndex(eqvars[v]) > SCIPvarGetIndex(eqvars[v - 1]));
6694 	#endif
6695 	
6696 	   for( --c ; c >= 0; --c )
6697 	   {
6698 	      CONSANDDATA* consanddata;
6699 	      SCIP_VAR** vars;
6700 	      int nvars;
6701 	      int nneweqvars;
6702 	
6703 	      consanddata = consanddatas[c];
6704 	      assert(consanddata != NULL);
6705 	      assert(consanddatas[c]->istransformed);
6706 	
6707 	      /* choose correct variable array to add locks for, we only add locks for now valid variables */
6708 	      if( consanddata->nnewvars > 0 )
6709 	      {
6710 	         vars = consanddata->newvars;
6711 	         nvars = consanddata->nnewvars;
6712 	      }
6713 	      else
6714 	      {
6715 	         vars = consanddata->vars;
6716 	         nvars = consanddata->nvars;
6717 	      }
6718 	      assert(nvars > 0 && vars != NULL);
6719 	
6720 	#ifndef NDEBUG
6721 	      /* check that variables are sorted */
6722 	      for( v = nvars - 1; v > 0; --v )
6723 	         assert(SCIPvarGetIndex(vars[v]) > SCIPvarGetIndex(vars[v - 1]));
6724 	#endif
6725 	
6726 	      /* update minimal number of variables in and-constraint */
6727 	      if( nvars < nminvars )
6728 	         nminvars = nvars;
6729 	      /* update maximal number of variables in and-constraint */
6730 	      else if( nvars > nmaxvars )
6731 	         nmaxvars = nvars;
6732 	      assert(nminvars > 0);
6733 	      assert(nminvars <= nmaxvars);
6734 	
6735 	      nneweqvars = 0;
6736 	      for( v = 0, v2 = 0; v < neqvars && v2 < nvars; )
6737 	      {
6738 	         int index1;
6739 	         int index2;
6740 	
6741 	         assert(eqvars[v] != NULL);
6742 	         assert(vars[v2] != NULL);
6743 	         index1 = SCIPvarGetIndex(eqvars[v]);
6744 	         index2 = SCIPvarGetIndex(vars[v2]);
6745 	
6746 	         /* check which variables are still in all and-constraints */
6747 	         if( index1 < index2 )
6748 	            ++v;
6749 	         else if( index1 > index2 )
6750 	            ++v2;
6751 	         else
6752 	         {
6753 	            assert(index1 == index2);
6754 	            assert(nneweqvars <= v);
6755 	
6756 	            if( nneweqvars < v )
6757 	               eqvars[nneweqvars] = eqvars[v];
6758 	            ++nneweqvars;
6759 	            ++v;
6760 	            ++v2;
6761 	         }
6762 	      }
6763 	      neqvars = nneweqvars;
6764 	
6765 	      /* now we only want to handle the easy case where nminvars == neqvars + 1
6766 	       * @todo: implement for the othercase too
6767 	       */
6768 	      if( nminvars > neqvars + 1 && type != SCIP_SETPPCTYPE_PARTITIONING)
6769 	         break;
6770 	
6771 	      if( neqvars == 0 )
6772 	         break;
6773 	   }
6774 	
6775 	   /* if all and-constraints in pseudoboolean constraint have the same length and some equal variables we can upgrade
6776 	    * the linear constraint and fix some variables in setpartitioning case
6777 	    *
6778 	    * e.g. x1 * x2 + x1 * x3 + x1 * x4 <= 1
6779 	    * =>  3x1 + x2 + x3 + x4 <= 4
6780 	    *
6781 	    * e.g. x1 * x2 * x3 + x1 * x2 * x4 <= 1
6782 	    * =>  2x1 + 2x2 + x3 + x4 <= 5
6783 	    *
6784 	    * e.g. x1 * x2 + x1 * x2 * x3 + x1 * x2 * x4 <= 1
6785 	    * =>  3x1 + 3x2 + x3 + x4 <= 6
6786 	    *
6787 	    * e.g. x1 * x2 + x1 * x3 == 1
6788 	    * =>   x1 = 1 /\ x2 + x3 == 1
6789 	    *
6790 	    * e.g. x1 * x2 * x3 + x1 * x4 == 1
6791 	    * =>   x1 = 1 /\ x2 * x3 + x4 == 1 (constraint is created indirectly, caused by the fixing of x1)
6792 	    *
6793 	    * e.g. x1 * x2 + x1 * x2 * x3 + x1 * x2 * x4 == 1
6794 	    * =>   x1 = 1, x2 = 1, x3 = 0, x4 = 0
6795 	    *
6796 	    * e.g. x1 * x2 + x1 * x2 * x3 + x1 * x2 * x4 * x5 == 1
6797 	    * =>   x1 = 1, x2 = 1, x3 = 0 /\ x4 * x5 == 0
6798 	    *
6799 	    * @todo: implement the next cases
6800 	    *
6801 	    * e.g. x1 * x2 * x3 + x1 * x2 * x4 + x5 <= 1
6802 	    * =>  2x1 + 2x2 + x3 + x4 + x5 <= 5
6803 	    *
6804 	    */
6805 	   if( neqvars > 0 && ((nminvars == nmaxvars && nminvars == neqvars + 1) || (nminvars == neqvars) || (type == SCIP_SETPPCTYPE_PARTITIONING)) )
6806 	   {
6807 	      SCIP_CONS* lincons;
6808 	      SCIP_CONS* newcons;
6809 	      char newname[SCIP_MAXSTRLEN];
6810 	      SCIP_Real lhs;
6811 	      SCIP_Real rhs;
6812 	      SCIP_Bool infeasible;
6813 	      SCIP_Bool fixed;
6814 	      SCIP_Bool createcons;
6815 	      SCIP_Bool deletecons;
6816 	
6817 	      newcons = NULL;
6818 	
6819 	      /* determine new sides of linear constraint */
6820 	      if( type == SCIP_SETPPCTYPE_PARTITIONING )
6821 	      {
6822 	         lhs = 1.0;
6823 	         rhs = 1.0;
6824 	      }
6825 	      else
6826 	      {
6827 	         assert(type == SCIP_SETPPCTYPE_PACKING);
6828 	         lhs = -SCIPinfinity(scip);
6829 	         rhs = 1.0;
6830 	      }
6831 	
6832 	      /* if one and-constraint was completely contained in all other and-constraints, we have to reduced the right hand
6833 	       * side by 1
6834 	       */
6835 	      if( neqvars == nminvars )
6836 	         rhs -= 1.0;
6837 	
6838 	      createcons = (SCIPisLE(scip, lhs, rhs) && ((nminvars == nmaxvars && nminvars == neqvars + 1) || (nminvars == neqvars)));
6839 	      assert(createcons || type == SCIP_SETPPCTYPE_PARTITIONING);
6840 	
6841 	      deletecons = (type == SCIP_SETPPCTYPE_PARTITIONING && nminvars == neqvars);
6842 	
6843 	      lincons = consdata->lincons;
6844 	
6845 	      if( createcons )
6846 	      {
6847 	         (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_upgraded", SCIPconsGetName(lincons));
6848 	
6849 	         SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, newname, 0, NULL, NULL, lhs, rhs,
6850 	               SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
6851 	               SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons),
6852 	               SCIPconsIsDynamic(lincons), SCIPconsIsRemovable(lincons), SCIPconsIsStickingAtNode(lincons)) );
6853 	      }
6854 	
6855 	      /* if createcons == TRUE add all variables which are not in the eqvars array to the new constraint with
6856 	       * coefficient 1.0
6857 	       *
6858 	       * otherwise (if createcons == FALSE) fix all variables to zero which are not in the eqvars array and if we have a
6859 	       * set partitioning constraint
6860 	       */
6861 	      for( c = nconsanddatas - 1; c >= 0; --c )
6862 	      {
6863 	         CONSANDDATA* consanddata;
6864 	         SCIP_VAR** vars;
6865 	         int nvars;
6866 	
6867 	         consanddata = consanddatas[c];
6868 	         assert(consanddata != NULL);
6869 	         assert(consanddatas[c]->istransformed);
6870 	
6871 	         /* choose correct variable array to add locks for, we only add locks for now valid variables */
6872 	         if( consanddata->nnewvars > 0 )
6873 	         {
6874 	            vars = consanddata->newvars;
6875 	            nvars = consanddata->nnewvars;
6876 	         }
6877 	         else
6878 	         {
6879 	            vars = consanddata->vars;
6880 	            nvars = consanddata->nvars;
6881 	         }
6882 	         assert(nvars > 0 && vars != NULL);
6883 	
6884 	         /* if the consanddata object has at least two more different variables then the equal variables we have to fix the resultant to zero */
6885 	         if( deletecons && neqvars + 1 < nvars )
6886 	         {
6887 	            assert(SCIPgetResultantAnd(scip, consanddata->cons) != NULL);
6888 	
6889 	            /* fix the resultant variable which have to be zero */
6890 	            SCIP_CALL( SCIPfixVar(scip, SCIPgetResultantAnd(scip, consanddata->cons), 0.0, &infeasible, &fixed) );
6891 	            if( infeasible )
6892 	            {
6893 	               SCIPdebugMsg(scip, " -> infeasible fixing\n");
6894 	               *cutoff = TRUE;
6895 	               goto TERMINATE;
6896 	            }
6897 	            if( fixed )
6898 	               ++(*nfixedvars);
6899 	
6900 	            continue;
6901 	         }
6902 	
6903 	         /* if the consanddata object has at exactly one more different variable then the equal variables we have to fix it to zero */
6904 	         for( v = 0, v2 = 0; v < neqvars && v2 < nvars; )
6905 	         {
6906 	            int index1;
6907 	            int index2;
6908 	
6909 	            assert(eqvars[v] != NULL);
6910 	            assert(vars[v2] != NULL);
6911 	            index1 = SCIPvarGetIndex(eqvars[v]);
6912 	            index2 = SCIPvarGetIndex(vars[v2]);
6913 	
6914 	            /* all variables in eqvars array must exist in all and-constraints */
6915 	            assert(index1 >= index2);
6916 	
6917 	            if( index1 > index2 )
6918 	            {
6919 	               if( createcons )
6920 	               {
6921 	                  assert(newcons != NULL);
6922 	                  SCIP_CALL( SCIPaddCoefLinear(scip, newcons, vars[v2], 1.0) );
6923 	               }
6924 	               else if( deletecons )
6925 	               {
6926 	                  /* fix the variable which cannot be one */
6927 	                  SCIP_CALL( SCIPfixVar(scip, vars[v2], 0.0, &infeasible, &fixed) );
6928 	                  if( infeasible )
6929 	                  {
6930 	                     SCIPdebugMsg(scip, " -> infeasible fixing\n");
6931 	                     *cutoff = TRUE;
6932 	                     goto TERMINATE;
6933 	                  }
6934 	                  if( fixed )
6935 	                     ++(*nfixedvars);
6936 	               }
6937 	               ++v2;
6938 	            }
6939 	            else
6940 	            {
6941 	               assert(index1 == index2);
6942 	
6943 	               ++v;
6944 	               ++v2;
6945 	            }
6946 	         }
6947 	
6948 	         /* if we did not loop over all variables in the and-constraint, go on and fix variables */
6949 	         if( v2 < nvars )
6950 	         {
6951 	            assert(v == neqvars);
6952 	            for( ; v2 < nvars; ++v2)
6953 	            {
6954 	               if( createcons )
6955 	               {
6956 	                  SCIP_CALL( SCIPaddCoefLinear(scip, newcons, vars[v2], 1.0) );
6957 	               }
6958 	               else if( deletecons )
6959 	               {
6960 	                  /* fix the variable which cannot be one */
6961 	                  SCIP_CALL( SCIPfixVar(scip, vars[v2], 0.0, &infeasible, &fixed) );
6962 	                  if( infeasible )
6963 	                  {
6964 	                     SCIPdebugMsg(scip, " -> infeasible fixing\n");
6965 	                     *cutoff = TRUE;
6966 	                     goto TERMINATE;
6967 	                  }
6968 	                  if( fixed )
6969 	                     ++(*nfixedvars);
6970 	               }
6971 	            }
6972 	         }
6973 	         assert(v == neqvars && v2 == nvars);
6974 	      }
6975 	
6976 	      /* fix all equal variable in set-partitioning constraints which have to be one, in set-packing constraint we have
6977 	       * to add these variable with a coeffcient as big as (nconsanddatas - 1)
6978 	       */
6979 	      for( v = 0; v < neqvars; ++v )
6980 	      {
6981 	         if( type == SCIP_SETPPCTYPE_PARTITIONING )
6982 	         {
6983 	            /* fix the variable which have to be one */
6984 	            SCIP_CALL( SCIPfixVar(scip, eqvars[v], 1.0, &infeasible, &fixed) );
6985 	            if( infeasible )
6986 	            {
6987 	               SCIPdebugMsg(scip, " -> infeasible fixing\n");
6988 	               *cutoff = TRUE;
6989 	               goto TERMINATE;
6990 	            }
6991 	            if( fixed )
6992 	               ++(*nfixedvars);
6993 	         }
6994 	         else
6995 	         {
6996 	            assert(type == SCIP_SETPPCTYPE_PACKING);
6997 	            SCIP_CALL( SCIPaddCoefLinear(scip, newcons, eqvars[v], (SCIP_Real)(nconsanddatas - 1)) );
6998 	         }
6999 	      }
7000 	
7001 	      /* correct right hand side for set packing constraint */
7002 	      if( type == SCIP_SETPPCTYPE_PACKING )
7003 	      {
7004 	         assert(createcons);
7005 	         assert(newcons != NULL);
7006 	
7007 	         SCIP_CALL( SCIPchgRhsLinear(scip, newcons, rhs + (SCIP_Real)((nconsanddatas - 1) * neqvars)) ); /*lint !e790*/
7008 	      }
7009 	
7010 	      /* add and release new constraint */
7011 	      if( createcons )
7012 	      {
7013 	         SCIP_CALL( SCIPaddCons(scip, newcons) );
7014 	
7015 	         SCIPdebugMsg(scip, "created upgraded linear constraint:\n");
7016 	         SCIPdebugMsg(scip, "old -> ");
7017 	         SCIPdebugPrintCons(scip, lincons, NULL);
7018 	         SCIPdebugMsg(scip, "new -> ");
7019 	         SCIPdebugPrintCons(scip, newcons, NULL);
7020 	
7021 	         SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
7022 	         ++(*naddconss);
7023 	
7024 	         assert(!deletecons);
7025 	         deletecons = TRUE;
7026 	      }
7027 	
7028 	      if( deletecons )
7029 	      {
7030 	         /* delete old constraints */
7031 	         SCIP_CALL( SCIPdelCons(scip, lincons) );
7032 	         SCIP_CALL( SCIPdelCons(scip, cons) );
7033 	         (*ndelconss) += 2;
7034 	      }
7035 	   }
7036 	
7037 	 TERMINATE:
7038 	   /* free temporary memory */
7039 	   SCIPfreeBufferArray(scip, &eqvars);
7040 	
7041 	   return SCIP_OKAY;
7042 	}
7043 	
7044 	/** try upgrading pseudoboolean constraint to a linear constraint and/or remove possible and-constraints */
7045 	static
7046 	SCIP_RETCODE tryUpgrading(
7047 	   SCIP*const            scip,               /**< SCIP data structure */
7048 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
7049 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
7050 	   int*const             ndelconss,          /**< pointer to store number of upgraded constraints */
7051 	   int*const             naddconss,          /**< pointer to count number of added constraints */
7052 	   int*const             nfixedvars,         /**< pointer to store number of fixed variables */
7053 	   int*const             nchgcoefs,          /**< pointer to store number of changed coefficients constraints */
7054 	   int*const             nchgsides,          /**< pointer to store number of changed sides constraints */
7055 	   SCIP_Bool*const       cutoff              /**< pointer to store if a cutoff happened */
7056 	   )
7057 	{
7058 	#ifndef NDEBUG
7059 	   CONSANDDATA** consanddatas;
7060 	#endif
7061 	   SCIP_CONSDATA* consdata;
7062 	   int nvars;
7063 	
7064 	   assert(scip != NULL);
7065 	   assert(cons != NULL);
7066 	   assert(conshdlrdata != NULL);
7067 	   assert(ndelconss != NULL);
7068 	   assert(nfixedvars != NULL);
7069 	   assert(nchgcoefs != NULL);
7070 	   assert(nchgsides != NULL);
7071 	   assert(cutoff != NULL);
7072 	   assert(SCIPconsIsActive(cons));
7073 	
7074 	   consdata = SCIPconsGetData(cons);
7075 	   assert(consdata != NULL);
7076 	   assert(consdata->lincons != NULL);
7077 	
7078 	#ifndef NDEBUG
7079 	   consanddatas = consdata->consanddatas;
7080 	   assert(consdata->nconsanddatas == 0 || consanddatas != NULL);
7081 	#endif
7082 	
7083 	   /* if no consanddata-objects in pseudoboolean constraint are left, create the corresponding linear constraint */
7084 	   if( consdata->nconsanddatas == 0 )
7085 	   {
7086 	      SCIPconsAddUpgradeLocks(consdata->lincons, -1);
7087 	      assert(SCIPconsGetNUpgradeLocks(consdata->lincons) == 0);
7088 	
7089 	      /* @TODO: maybe it is better to create everytime a standard linear constraint instead of letting the special
7090 	       *        linear constraint stay
7091 	       */
7092 	      SCIP_CALL( SCIPdelCons(scip, cons) );
7093 	      ++(*ndelconss);
7094 	
7095 	      return SCIP_OKAY;
7096 	   }
7097 	
7098 	   /* check number of linear variables */
7099 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
7100 	   assert(consdata->nlinvars + consdata->nconsanddatas == nvars);
7101 	
7102 	   switch( consdata->linconstype )
7103 	   {
7104 	   case SCIP_LINEARCONSTYPE_LINEAR:
7105 	      SCIP_CALL( tryUpgradingXor(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, cutoff) );
7106 	      break;
7107 	   case SCIP_LINEARCONSTYPE_LOGICOR:
7108 	      SCIP_CALL( tryUpgradingLogicor(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, cutoff) );
7109 	      break;
7110 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
7111 	      break;
7112 	   case SCIP_LINEARCONSTYPE_SETPPC:
7113 	      SCIP_CALL( tryUpgradingSetppc(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, cutoff) );
7114 	      if( !SCIPconsIsDeleted(cons) )
7115 	      {
7116 		 SCIP_CALL( tryUpgradingXor(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, cutoff) );
7117 	      }
7118 	      break;
7119 	#ifdef WITHEQKNAPSACK
7120 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
7121 	      SCIP_CALL( tryUpgradingXor(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, cutoff) );
7122 	#endif
7123 	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
7124 	   default:
7125 	      SCIPerrorMessage("unknown linear constraint type\n");
7126 	      return SCIP_INVALIDDATA;
7127 	   }
7128 	
7129 	   if( SCIPconsIsDeleted(cons) )
7130 	   {
7131 	      /* update the uses counter of consandata objects which are used in pseudoboolean constraint, which was deleted and
7132 	       * probably delete and-constraints
7133 	       */
7134 	      SCIP_CALL( updateConsanddataUses(scip, cons, conshdlrdata, ndelconss) );
7135 	   }
7136 	
7137 	   consdata->upgradetried = TRUE;
7138 	
7139 	   return SCIP_OKAY;
7140 	}
7141 	
7142 	/** check if we can aggregated some variables */
7143 	static
7144 	SCIP_RETCODE findAggregation(
7145 	   SCIP*const            scip,               /**< SCIP data structure */
7146 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
7147 	   SCIP_CONSHDLRDATA*const conshdlrdata,     /**< pseudoboolean constraint handler data */
7148 	   int*const             ndelconss,          /**< pointer to store number of upgraded constraints */
7149 	   int*const             naggrvars,          /**< pointer to store number of aggregated variables */
7150 	   SCIP_Bool*const       cutoff              /**< pointer to store if a cutoff happened */
7151 	   )
7152 	{
7153 	   CONSANDDATA** consanddatas;
7154 	   SCIP_CONSDATA* consdata;
7155 	   SCIP_VAR** allvars;
7156 	   int* varcount[2];
7157 	   SCIP_VAR** repvars;
7158 	   SCIP_Bool* negated;
7159 	   SCIP_VAR** vars;
7160 	   int nconsanddatas;
7161 	   int nvars;
7162 	   int zerocount;
7163 	   int onecount;
7164 	   int twocount;
7165 	   int othercount;
7166 	   int c;
7167 	   int v;
7168 	   int i;
7169 	
7170 	   assert(scip != NULL);
7171 	   assert(cons != NULL);
7172 	   assert(conshdlrdata != NULL);
7173 	   assert(ndelconss != NULL);
7174 	   assert(naggrvars != NULL);
7175 	   assert(cutoff != NULL);
7176 	   assert(SCIPconsIsActive(cons));
7177 	
7178 	   if( SCIPconsIsModifiable(cons) )
7179 	      return SCIP_OKAY;
7180 	
7181 	   consdata = SCIPconsGetData(cons);
7182 	   assert(consdata != NULL);
7183 	   assert(consdata->lincons != NULL);
7184 	
7185 	   consanddatas = consdata->consanddatas;
7186 	   nconsanddatas = consdata->nconsanddatas;
7187 	   assert(nconsanddatas == 0 || consanddatas != NULL);
7188 	
7189 	   /* we have only one special case for aggregations, a set-partinioning constraint */
7190 	   if( consdata->linconstype != SCIP_LINEARCONSTYPE_SETPPC || SCIPgetTypeSetppc(scip, consdata->lincons) != SCIP_SETPPCTYPE_PARTITIONING )
7191 	      return SCIP_OKAY;
7192 	
7193 	   assert(SCIPisEQ(scip, consdata->rhs, consdata->lhs));
7194 	   assert(SCIPisEQ(scip, consdata->rhs, 1.0));
7195 	
7196 	   if( nconsanddatas < 2 || nconsanddatas > 3 )
7197 	      return SCIP_OKAY;
7198 	
7199 	#ifndef NDEBUG
7200 	   /* check number of linear variables */
7201 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
7202 	   assert(consdata->nlinvars + nconsanddatas == nvars);
7203 	#endif
7204 	
7205 	   if( consdata->nlinvars != 1 )
7206 	      return SCIP_OKAY;
7207 	
7208 	   /* check valid number of variables */
7209 	   if( consanddatas[0]->nnewvars > 0 )
7210 	      nvars = consanddatas[0]->nnewvars;
7211 	   else
7212 	      nvars = consanddatas[0]->nvars;
7213 	
7214 	   if( consanddatas[1]->nnewvars > 0 )
7215 	   {
7216 	      if( nvars != consanddatas[1]->nnewvars )
7217 		 return SCIP_OKAY;
7218 	   }
7219 	   else if( nvars != consanddatas[1]->nvars )
7220 	      return SCIP_OKAY;
7221 	
7222 	   /* allocate temporary memory */
7223 	   SCIP_CALL( SCIPallocBufferArray(scip, &allvars, nvars) );
7224 	   SCIP_CALL( SCIPallocBufferArray(scip, &(varcount[0]), nvars) );
7225 	   BMSclearMemoryArray(varcount[0], nvars);
7226 	   SCIP_CALL( SCIPallocBufferArray(scip, &(varcount[1]), nvars) );
7227 	   BMSclearMemoryArray(varcount[1], nvars);
7228 	
7229 	   SCIP_CALL( SCIPallocBufferArray(scip, &repvars, nvars) );
7230 	   SCIP_CALL( SCIPallocBufferArray(scip, &negated, nvars) );
7231 	   BMSclearMemoryArray(negated, nvars);
7232 	
7233 	   /* get valid variables */
7234 	   if( consanddatas[nconsanddatas - 1]->nnewvars > 0 )
7235 	      vars = consanddatas[nconsanddatas - 1]->newvars;
7236 	   else
7237 	      vars = consanddatas[nconsanddatas - 1]->vars;
7238 	
7239 	   /* get linear active representation */
7240 	   SCIP_CALL( SCIPgetBinvarRepresentatives(scip, nvars, vars, repvars, negated) );
7241 	   SCIPsortPtrBool((void**)repvars, negated, SCIPvarCompActiveAndNegated, nvars);
7242 	
7243 	#ifndef NDEBUG
7244 	   /* and-constraints have to be merged in order to check for aggregation */
7245 	   for( v = 1; v < nvars; ++v )
7246 	   {
7247 	      SCIP_VAR* var1;
7248 	      SCIP_VAR* var2;
7249 	
7250 	      /* it appears that some fixed variables were not yet deleted */
7251 	      if( SCIPvarGetLbGlobal(repvars[v-1]) > 0.5 || SCIPvarGetUbGlobal(repvars[v-1]) < 0.5 )
7252 		 goto TERMINATE;
7253 	
7254 	      /* it appears that some fixed variables were not yet deleted */
7255 	      if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
7256 		 goto TERMINATE;
7257 	
7258 	      assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
7259 	      assert(SCIPvarIsActive(repvars[v-1]) || (SCIPvarIsNegated(repvars[v-1]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v-1]))));
7260 	      assert(SCIPvarIsActive(repvars[v]) != negated[v]);
7261 	      assert(SCIPvarIsActive(repvars[v-1]) != negated[v-1]);
7262 	
7263 	      var1 = (negated[v-1] ? SCIPvarGetNegationVar(repvars[v-1]) : repvars[v-1]);
7264 	      var2 = (negated[v] ? SCIPvarGetNegationVar(repvars[v]) : repvars[v]);
7265 	      assert(var1 != var2);
7266 	   }
7267 	#endif
7268 	
7269 	   /* initializing the statuses of all appearing variables */
7270 	   for( v = nvars - 1; v >= 0; --v )
7271 	   {
7272 	      /* it appears that some fixed variables were not yet deleted */
7273 	      if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
7274 		 goto TERMINATE;
7275 	
7276 	      assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
7277 	      assert(SCIPvarIsActive(repvars[v]) != negated[v]);
7278 	
7279 	      allvars[v] = negated[v] ? SCIPvarGetNegationVar(repvars[v]) : repvars[v];
7280 	
7281 	      ++(varcount[negated[v]][v]);
7282 	   }
7283 	
7284 	   for( c = nconsanddatas - 2; c >= 0; --c )
7285 	   {
7286 	      int pos = -1;
7287 	
7288 	      /* get valid variables */
7289 	      if( consanddatas[nconsanddatas - 1]->nnewvars > 0 )
7290 		 vars = consanddatas[c]->newvars;
7291 	      else
7292 		 vars = consanddatas[c]->vars;
7293 	
7294 	      /* need to reset the negated flags */
7295 	      BMSclearMemoryArray(negated, nvars);
7296 	
7297 	      /* get linear active representation */
7298 	      SCIP_CALL( SCIPgetBinvarRepresentatives(scip, nvars, vars, repvars, negated) );
7299 	      SCIPsortPtrBool((void**)repvars, negated, SCIPvarCompActiveAndNegated, nvars);
7300 	
7301 	#ifndef NDEBUG
7302 	      /* and-constraints have to be merged in order to check for aggregation */
7303 	      for( v = 1; v < nvars; ++v )
7304 	      {
7305 		 SCIP_VAR* var1;
7306 		 SCIP_VAR* var2;
7307 	
7308 		 /* it appears that some fixed variables were not yet deleted */
7309 		 if( SCIPvarGetLbGlobal(repvars[v-1]) > 0.5 || SCIPvarGetUbGlobal(repvars[v-1]) < 0.5 )
7310 		    goto TERMINATE;
7311 	
7312 		 /* it appears that some fixed variables were not yet deleted */
7313 		 if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
7314 		    goto TERMINATE;
7315 	
7316 		 assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
7317 		 assert(SCIPvarIsActive(repvars[v-1]) || (SCIPvarIsNegated(repvars[v-1]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v-1]))));
7318 		 assert(SCIPvarIsActive(repvars[v]) != negated[v]);
7319 		 assert(SCIPvarIsActive(repvars[v-1]) != negated[v-1]);
7320 	
7321 		 var1 = (negated[v-1] ? SCIPvarGetNegationVar(repvars[v-1]) : repvars[v-1]);
7322 		 var2 = (negated[v] ? SCIPvarGetNegationVar(repvars[v]) : repvars[v]);
7323 		 assert(var1 != var2);
7324 	      }
7325 	#endif
7326 	
7327 	      /* update the statuses of all appearing variables */
7328 	      for( v = nvars - 1; v >= 0; --v )
7329 	      {
7330 		 /* it appears that some fixed variables were not yet deleted */
7331 		 if( SCIPvarGetLbGlobal(repvars[v]) > 0.5 || SCIPvarGetUbGlobal(repvars[v]) < 0.5 )
7332 		    goto TERMINATE;
7333 	
7334 		 assert(SCIPvarIsActive(repvars[v]) || (SCIPvarIsNegated(repvars[v]) && SCIPvarIsActive(SCIPvarGetNegationVar(repvars[v]))));
7335 		 assert(SCIPvarIsActive(repvars[v]) != negated[v]);
7336 	
7337 		 /* we can only find an aggregation if all and constraints have the same variables */
7338 		 if( SCIPsortedvecFindPtr((void**)allvars, SCIPvarCompActiveAndNegated, repvars[v], nvars, &pos) )
7339 		 {
7340 		    assert(pos >= 0 && pos < nvars);
7341 	
7342 		    ++(varcount[negated[v]][pos]);
7343 		 }
7344 		 else
7345 		    goto TERMINATE;
7346 	      }
7347 	   }
7348 	
7349 	   zerocount = 0;
7350 	   onecount = 0;
7351 	   twocount = 0;
7352 	   othercount = 0;
7353 	
7354 	   /* count number of multiple appearances of a variable */
7355 	   for( i = 1; i >= 0; --i )
7356 	   {
7357 	      for( v = nvars - 1; v >= 0; --v )
7358 	      {
7359 		 assert(SCIPvarIsActive(allvars[v]));
7360 	
7361 		 if( varcount[i][v] == 0 )
7362 		    ++zerocount;
7363 		 else if( varcount[i][v] == 1 )
7364 		    ++onecount;
7365 		 else if( varcount[i][v] == 2 )
7366 		    ++twocount;
7367 		 else
7368 		    ++othercount;
7369 	      }
7370 	   }
7371 	
7372 	   /* exactly one variable in all and-constraints appears as active and as negated variable */
7373 	   if( othercount == 0 )
7374 	   {
7375 	      /* we have a constraint in the form of: x1 + x2 * x3 * ... * x_n + ~x2 * x3 * ... * x_n == 1
7376 	       * this leads to the aggregation x1 = 1 - x3 * ... * x_n
7377 	       */
7378 	      if( nconsanddatas == 2 && twocount == nvars - 1 && onecount == 2 && zerocount == 1 )
7379 	      {
7380 		 SCIP_VAR** consvars;
7381 		 SCIP_Real* conscoefs;
7382 		 int nconsvars;
7383 		 SCIP_VAR* linvar;
7384 		 SCIP_Real lincoef;
7385 		 int nlinvars;
7386 	
7387 		 /* allocate temporary memory */
7388 		 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, consdata->nlinvars + nconsanddatas) );
7389 		 SCIP_CALL( SCIPallocBufferArray(scip, &conscoefs, consdata->nlinvars + nconsanddatas) );
7390 	
7391 		 /* get variables and coefficients */
7392 		 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, consvars, conscoefs, &nconsvars) );
7393 		 assert(nconsvars == consdata->nlinvars + nconsanddatas);
7394 		 assert(conscoefs != NULL);
7395 	
7396 	#ifndef NDEBUG
7397 		 /* all coefficients have to be 1 */
7398 		 for( v = 0; v < nconsvars; ++v )
7399 		    assert(SCIPisEQ(scip, conscoefs[v], 1.0));
7400 	#endif
7401 		 linvar = NULL;
7402 	
7403 		 /* calculate all not artificial linear variables */
7404 		 SCIP_CALL( getLinVarsAndAndRess(scip, cons, consvars, conscoefs, nconsvars, &linvar, &lincoef, &nlinvars,
7405 	               NULL, NULL, NULL, NULL) );
7406 		 assert(nlinvars == 1);
7407 		 assert(linvar != NULL);
7408 	
7409 		 SCIPfreeBufferArray(scip, &conscoefs);
7410 		 SCIPfreeBufferArray(scip, &consvars);
7411 	
7412 		 /* if all and-constraints have exactly two variables */
7413 		 if( nvars == 2 )
7414 		 {
7415 		    SCIP_VAR* var;
7416 		    SCIP_Bool breaked;
7417 		    SCIP_Bool redundant;
7418 		    SCIP_Bool infeasible;
7419 		    SCIP_Bool aggregated;
7420 	
7421 		    var = NULL;
7422 		    breaked = FALSE;
7423 	
7424 		    /* find necessary variables, which only occur once */
7425 		    for( i = 1; i >= 0; --i )
7426 		    {
7427 		       for( v = nvars - 1; v >= 0; --v )
7428 		       {
7429 			  assert(i == 1 || SCIPvarGetNegatedVar(allvars[v]) != NULL);
7430 			  if( varcount[i][v] == 2 )
7431 			  {
7432 			     var = i ? SCIPvarGetNegatedVar(allvars[v]) : allvars[v];
7433 	
7434 			     breaked = TRUE;
7435 			     break;
7436 			  }
7437 		       }
7438 	
7439 		       if( breaked )
7440 			  break;
7441 		    }
7442 		    assert(var != NULL);
7443 	
7444 		    SCIPdebugMsg(scip, "aggregating variables <%s> == 1 - <%s> in pseudoboolean <%s>\n", SCIPvarGetName(linvar), SCIPvarGetName(var), SCIPconsGetName(cons));
7445 	
7446 		    SCIP_CALL( SCIPaggregateVars(scip, linvar, var, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
7447 	
7448 		    SCIPdebugPrintCons(scip, cons, NULL);
7449 		    SCIPdebugMsg(scip, "aggregation of variables: <%s> == 1 - <%s>, infeasible = %u, aggregated = %u\n", SCIPvarGetName(linvar), SCIPvarGetName(var), infeasible, aggregated);
7450 	
7451 		    if( infeasible )
7452 		       *cutoff = TRUE;
7453 		    else
7454 		    {
7455 		       if( aggregated )
7456 			  ++(*naggrvars);
7457 	
7458 		       /* delete old constraints */
7459 		       SCIP_CALL( SCIPdelCons(scip, consdata->lincons) );
7460 		       SCIP_CALL( SCIPdelCons(scip, cons) );
7461 		       (*ndelconss) += 2;
7462 		    }
7463 		 }
7464 	#if 0
7465 		 else
7466 		 {
7467 		    /* @todo */
7468 		    /* delete allvars[samepos] from all and-constraints which appear in this pseudoboolean constraint, and delete
7469 		     * all but one of the remaining and-constraint
7470 		     *
7471 		     * it is the same like aggregating linvar with the resultant of the product, which is the same in all and-
7472 		     * constraints without allvars[samepos]
7473 		     *
7474 		     * e.g. x1 + x2*x_3*...x_n + ~x2*x_3*...x_n = 1 => x1 = 1 - x_3*...x_n
7475 		     */
7476 		 }
7477 	#endif
7478 	      } /*lint !e438*/
7479 	      /* we have a constraint in the form of: x1 + x2 * x3 + ~x2 * x3 + ~x2 * ~x3 == 1
7480 	       * this leads to the aggregation x1 = x2 * ~x3
7481 	       *
7482 	       * @todo: implement more general step, that one combination of the variables in the and constraints is missing in
7483 	       *        the pseudoboolean constraint, which leads to the same result, that the only linear variable is the
7484 	       *        resultant of the missing and-constraint
7485 	       */
7486 	      else if( nvars == 2 && nconsanddatas == 3 && twocount == 2 && onecount == 2 && zerocount == 0)
7487 	      {
7488 		 SCIP_VAR** consvars;
7489 		 SCIP_Real* conscoefs;
7490 		 int nconsvars;
7491 		 SCIP_VAR* linvar;
7492 		 SCIP_Real lincoef;
7493 		 int nlinvars;
7494 		 SCIP_VAR* newandvars[2];
7495 		 SCIP_Bool breaked;
7496 		 SCIP_CONS* newcons;
7497 		 char name[SCIP_MAXSTRLEN];
7498 	
7499 		 /* allocate temporary memory */
7500 		 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, consdata->nlinvars + nconsanddatas) );
7501 		 SCIP_CALL( SCIPallocBufferArray(scip, &conscoefs, consdata->nlinvars + nconsanddatas) );
7502 	
7503 		 /* get variables and coefficients */
7504 		 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, consvars, conscoefs, &nconsvars) );
7505 		 assert(nconsvars == consdata->nlinvars + nconsanddatas);
7506 		 assert(conscoefs != NULL);
7507 	
7508 	#ifndef NDEBUG
7509 		 /* all coefficients have to be 1 */
7510 		 for( v = 0; v < nconsvars; ++v )
7511 		    assert(SCIPisEQ(scip, conscoefs[v], 1.0));
7512 	#endif
7513 		 linvar = NULL;
7514 	
7515 		 /* calculate all not artificial linear variables */
7516 		 SCIP_CALL( getLinVarsAndAndRess(scip, cons, consvars, conscoefs, nconsvars, &linvar, &lincoef, &nlinvars,
7517 	               NULL, NULL, NULL, NULL) );
7518 		 assert(nlinvars == 1);
7519 		 assert(linvar != NULL);
7520 	
7521 		 SCIPfreeBufferArray(scip, &conscoefs);
7522 		 SCIPfreeBufferArray(scip, &consvars);
7523 	
7524 		 newandvars[0] = NULL;
7525 		 newandvars[1] = NULL;
7526 		 breaked = FALSE;
7527 	
7528 		 /* find necessary variables, which only occur once */
7529 		 for( i = 1; i >= 0; --i )
7530 		 {
7531 		    for( v = nvars - 1; v >= 0; --v )
7532 		    {
7533 		       assert(i == 1 || SCIPvarGetNegatedVar(allvars[v]) != NULL);
7534 		       if( varcount[i][v] == 1 )
7535 		       {
7536 			  if( newandvars[0] == NULL )
7537 			     newandvars[0] = i ? SCIPvarGetNegatedVar(allvars[v]) : allvars[v];
7538 			  else
7539 			  {
7540 			     assert(newandvars[1] == NULL);
7541 			     newandvars[1] = i ? SCIPvarGetNegatedVar(allvars[v]) : allvars[v];
7542 	
7543 			     breaked = TRUE;
7544 			     break;
7545 			  }
7546 		       }
7547 		    }
7548 	
7549 		    if( breaked )
7550 		       break;
7551 		 }
7552 		 assert(newandvars[0] != NULL && newandvars[1] != NULL);
7553 	
7554 		 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "andcons_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(linvar));
7555 		 SCIP_CALL( SCIPcreateConsAnd(scip, &newcons, name, linvar, nvars, newandvars,
7556 		       TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
7557 		 SCIP_CALL( SCIPaddCons(scip, newcons) );
7558 		 SCIPdebugPrintCons(scip, newcons, NULL);
7559 		 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
7560 	
7561 		 /* delete old constraints */
7562 		 SCIP_CALL( SCIPdelCons(scip, consdata->lincons) );
7563 		 SCIP_CALL( SCIPdelCons(scip, cons) );
7564 		 (*ndelconss) += 2;
7565 	      } /*lint !e438*/
7566 	   }
7567 	
7568 	   if( SCIPconsIsDeleted(cons) )
7569 	   {
7570 	      /* update the uses counter of consandata objects which are used in pseudoboolean constraint, which was deleted and
7571 	       * probably delete and-constraints
7572 	       */
7573 	      SCIP_CALL( updateConsanddataUses(scip, cons, conshdlrdata, ndelconss) );
7574 	   }
7575 	
7576 	 TERMINATE:
7577 	   /* free temporary memory */
7578 	   SCIPfreeBufferArray(scip, &negated);
7579 	   SCIPfreeBufferArray(scip, &repvars);
7580 	   SCIPfreeBufferArray(scip, &(varcount[1]));
7581 	   SCIPfreeBufferArray(scip, &(varcount[0]));
7582 	   SCIPfreeBufferArray(scip, &allvars);
7583 	
7584 	   return SCIP_OKAY;
7585 	}
7586 	
7587 	
7588 	/*
7589 	 * Callback methods of constraint handler
7590 	 */
7591 	
7592 	#ifdef NONLINCONSUPGD_PRIORITY
7593 	#include "scip/cons_nonlinear.h"
7594 	/** tries to upgrade a nonlinear constraint into a pseudoboolean constraint */
7595 	static
7596 	SCIP_DECL_NONLINCONSUPGD(nonlinconsUpgdPseudoboolean)
7597 	{
7598 	   SCIP_EXPRGRAPH* exprgraph;
7599 	   SCIP_EXPRGRAPHNODE* node;
7600 	   SCIP_Real lhs;
7601 	   SCIP_Real rhs;
7602 	   SCIP_VAR* var;
7603 	   SCIP_VAR* objvar = NULL;
7604 	   SCIP_VAR** linvars = NULL;
7605 	   int nlinvars;
7606 	   SCIP_VAR*** terms;
7607 	   int nterms;
7608 	   int* ntermvars;
7609 	   SCIP_Real* termvals;
7610 	   int i;
7611 	   int j;
7612 	
7613 	   assert(nupgdconss != NULL);
7614 	   assert(upgdconss != NULL);
7615 	
7616 	   *nupgdconss = 0;
7617 	
7618 	   node = SCIPgetExprgraphNodeNonlinear(scip, cons);
7619 	
7620 	   /* no interest in linear constraints */
7621 	   if( node == NULL )
7622 	      return SCIP_OKAY;
7623 	
7624 	   switch( SCIPexprgraphGetNodeOperator(node) )
7625 	   {
7626 	   case SCIP_EXPR_VARIDX:
7627 	   case SCIP_EXPR_CONST:
7628 	   case SCIP_EXPR_PLUS:
7629 	   case SCIP_EXPR_MINUS:
7630 	   case SCIP_EXPR_SUM:
7631 	   case SCIP_EXPR_LINEAR:
7632 	      /* these should not appear as exprgraphnodes after constraint presolving */
7633 	      return SCIP_OKAY;
7634 	
7635 	   case SCIP_EXPR_MUL:
7636 	   case SCIP_EXPR_DIV:
7637 	   case SCIP_EXPR_SQUARE:
7638 	   case SCIP_EXPR_SQRT:
7639 	   case SCIP_EXPR_REALPOWER:
7640 	   case SCIP_EXPR_INTPOWER:
7641 	   case SCIP_EXPR_SIGNPOWER:
7642 	   case SCIP_EXPR_EXP:
7643 	   case SCIP_EXPR_LOG:
7644 	   case SCIP_EXPR_SIN:
7645 	   case SCIP_EXPR_COS:
7646 	   case SCIP_EXPR_TAN:
7647 	      /* case SCIP_EXPR_ERF: */
7648 	      /* case SCIP_EXPR_ERFI: */
7649 	   case SCIP_EXPR_MIN:
7650 	   case SCIP_EXPR_MAX:
7651 	   case SCIP_EXPR_ABS:
7652 	   case SCIP_EXPR_SIGN:
7653 	   case SCIP_EXPR_PRODUCT:
7654 	   case SCIP_EXPR_USER:
7655 	      /* these do not look like a proper pseudoboolean expression (assuming the expression graph simplifier did run) */
7656 	      return SCIP_OKAY;
7657 	
7658 	   case SCIP_EXPR_QUADRATIC:  /* let cons_quadratic still handle these for now */
7659 	      return SCIP_OKAY;
7660 	
7661 	   case SCIP_EXPR_POLYNOMIAL:
7662 	      /* these mean that we have something polynomial */
7663 	      break;
7664 	
7665 	   case SCIP_EXPR_PARAM:
7666 	   case SCIP_EXPR_LAST:
7667 	   default:
7668 	      SCIPwarningMessage(scip, "unexpected expression operator %d in nonlinear constraint <%s>\n", SCIPexprgraphGetNodeOperator(node), SCIPconsGetName(cons));
7669 	      return SCIP_OKAY;
7670 	   }
7671 	
7672 	   lhs = SCIPgetLhsNonlinear(scip, cons);
7673 	   rhs = SCIPgetRhsNonlinear(scip, cons);
7674 	
7675 	   /* we need all linear variables to be binary, except for one that was added to reformulate an objective function */
7676 	   for( i = 0; i < SCIPgetNLinearVarsNonlinear(scip, cons); ++i )
7677 	   {
7678 	      var = SCIPgetLinearVarsNonlinear(scip, cons)[i];
7679 	      assert(var != NULL);
7680 	
7681 	      if( SCIPvarIsBinary(var) )
7682 	         continue;
7683 	
7684 	#ifdef SCIP_DISABLED_CODE /* not working in cons_pseudoboolean yet, see cons_pseudoboolean.c:7925 */
7685 	      /* check whether the variable may have been added to represent the objective function */
7686 	      if( objvar == NULL && SCIPgetLinearCoefsNonlinear(scip, cons)[i] == -1.0 && /*TODO we could divide by the coefficient*/
7687 	          SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == (SCIPisInfinity(scip,  rhs) ? 0 : 1) &&  /*TODO correct?*/
7688 	          SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == (SCIPisInfinity(scip, -lhs) ? 0 : 1) &&  /*TODO correct?*/
7689 	          SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) && SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) &&
7690 	          SCIPvarGetObj(var) == 1.0 )  /*TODO we need this or just positive?*/
7691 	      {
7692 	         objvar = var;
7693 	         continue;
7694 	      }
7695 	#endif
7696 	
7697 	      SCIPdebugMsg(scip, "not pseudoboolean because linear variable <%s> is not binary or objective\n", SCIPvarGetName(var));
7698 	      return SCIP_OKAY;
7699 	   }
7700 	
7701 	   /* if simplified, then all children of root node should be variables, we need all of them to be binary */
7702 	   exprgraph = SCIPgetExprgraphNonlinear(scip, SCIPconsGetHdlr(cons));
7703 	   for( i = 0; i < SCIPexprgraphGetNodeNChildren(node); ++i )
7704 	   {
7705 	      SCIP_EXPRGRAPHNODE* child;
7706 	
7707 	      child = SCIPexprgraphGetNodeChildren(node)[i];
7708 	      assert(child != NULL);
7709 	      if( SCIPexprgraphGetNodeOperator(child) != SCIP_EXPR_VARIDX )
7710 	      {
7711 	         SCIPdebugMsg(scip, "not pseudoboolean because child %d is not a variable\n", i);
7712 	         return SCIP_OKAY;
7713 	      }
7714 	
7715 	      var = (SCIP_VAR*)SCIPexprgraphGetNodeVar(exprgraph, child);
7716 	      assert(var != NULL);
7717 	      if( !SCIPvarIsBinary(var) )
7718 	      {
7719 	         SCIPdebugMsg(scip, "not pseudoboolean because nonlinear var <%s> is not binary\n", SCIPvarGetName(var));
7720 	         return SCIP_OKAY;
7721 	      }
7722 	   }
7723 	
7724 	   /* setup a pseudoboolean constraint */
7725 	
7726 	   if( upgdconsssize < 1 )
7727 	   {
7728 	      /* request larger upgdconss array */
7729 	      *nupgdconss = -1;
7730 	      return SCIP_OKAY;
7731 	   }
7732 	
7733 	   SCIPdebugMsg(scip, "upgrading nonlinear constraint <%s> to pseudo-boolean\n", SCIPconsGetName(cons));
7734 	
7735 	   if( !SCIPisInfinity(scip, -lhs) )
7736 	      lhs -= SCIPexprgraphGetNodePolynomialConstant(node);
7737 	   if( !SCIPisInfinity(scip, -rhs) )
7738 	      rhs -= SCIPexprgraphGetNodePolynomialConstant(node);
7739 	
7740 	   /* setup linear part, if not identical */
7741 	   if( objvar != NULL )
7742 	   {
7743 	      SCIP_CALL( SCIPallocBufferArray(scip, &linvars, SCIPgetNLinearVarsNonlinear(scip, cons)-1) );
7744 	      nlinvars = 0;
7745 	      for( i = 0; i < SCIPgetNLinearVarsNonlinear(scip, cons); ++i )
7746 	      {
7747 	         var = SCIPgetLinearVarsNonlinear(scip, cons)[i];
7748 	         if( var != objvar )
7749 	            linvars[nlinvars++] = var;
7750 	      }
7751 	   }
7752 	   else
7753 	      nlinvars = SCIPgetNLinearVarsNonlinear(scip, cons);
7754 	
7755 	   /* setup nonlinear terms */
7756 	   nterms = SCIPexprgraphGetNodePolynomialNMonomials(node);
7757 	   SCIP_CALL( SCIPallocBufferArray(scip, &terms, nterms) );
7758 	   SCIP_CALL( SCIPallocBufferArray(scip, &ntermvars, nterms) );
7759 	   SCIP_CALL( SCIPallocBufferArray(scip, &termvals, nterms) );
7760 	
7761 	   for( i = 0; i < nterms; ++i )
7762 	   {
7763 	      SCIP_EXPRDATA_MONOMIAL* monomial;
7764 	
7765 	      monomial = SCIPexprgraphGetNodePolynomialMonomials(node)[i];
7766 	      assert(monomial != NULL);
7767 	
7768 	      ntermvars[i] = SCIPexprGetMonomialNFactors(monomial);
7769 	      SCIP_CALL( SCIPallocBufferArray(scip, &terms[i], ntermvars[i]) );
7770 	
7771 	      for( j = 0; j < SCIPexprGetMonomialNFactors(monomial); ++j )
7772 	      {
7773 	         terms[i][j] = (SCIP_VAR*)SCIPexprgraphGetNodeVar(exprgraph, SCIPexprgraphGetNodeChildren(node)[SCIPexprGetMonomialChildIndices(monomial)[j]]);
7774 	         assert(SCIPexprGetMonomialExponents(monomial)[j] > 0.0);
7775 	      }
7776 	
7777 	      termvals[i] = SCIPexprGetMonomialCoef(monomial);
7778 	   }
7779 	
7780 	   *nupgdconss = 1;
7781 	   SCIP_CALL( SCIPcreateConsPseudoboolean(scip, &upgdconss[0], SCIPconsGetName(cons),
7782 	         objvar != NULL ? linvars : SCIPgetLinearVarsNonlinear(scip, cons), nlinvars, SCIPgetLinearCoefsNonlinear(scip, cons),
7783 	         terms, nterms, ntermvars, termvals, NULL, 0.0, FALSE, objvar,
7784 	         lhs, rhs,
7785 	         SCIPconsIsInitial(cons), SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons),
7786 	         SCIPconsIsChecked(cons), SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons),
7787 	         SCIPconsIsModifiable(cons), SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
7788 	
7789 	   for( i = nterms-1; i >= 0; --i )
7790 	      SCIPfreeBufferArray(scip, &terms[i]);
7791 	
7792 	   SCIPfreeBufferArray(scip, &terms);
7793 	   SCIPfreeBufferArray(scip, &ntermvars);
7794 	   SCIPfreeBufferArray(scip, &termvals);
7795 	   SCIPfreeBufferArrayNull(scip, &linvars);
7796 	
7797 	   return SCIP_OKAY;
7798 	}
7799 	#endif
7800 	
7801 	/** copy method for constraint handler plugins (called when SCIP copies plugins) */
7802 	static
7803 	SCIP_DECL_CONSHDLRCOPY(conshdlrCopyPseudoboolean)
7804 	{  /*lint --e{715}*/
7805 	   assert(scip != NULL);
7806 	   assert(conshdlr != NULL);
7807 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
7808 	
7809 	   /* call inclusion method of constraint handler */
7810 	   SCIP_CALL( SCIPincludeConshdlrPseudoboolean(scip) );
7811 	
7812 	   *valid = TRUE;
7813 	
7814 	   return SCIP_OKAY;
7815 	}
7816 	
7817 	/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
7818 	static
7819 	SCIP_DECL_CONSFREE(consFreePseudoboolean)
7820 	{  /*lint --e{715}*/
7821 	   SCIP_CONSHDLRDATA* conshdlrdata;
7822 	
7823 	   assert(scip != NULL);
7824 	   assert(conshdlr != NULL);
7825 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
7826 	
7827 	   /* free constraint handler data */
7828 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
7829 	   assert(conshdlrdata != NULL);
7830 	
7831 	   SCIP_CALL( conshdlrdataFree(scip, &conshdlrdata) );
7832 	
7833 	   SCIPconshdlrSetData(conshdlr, NULL);
7834 	
7835 	   return SCIP_OKAY;
7836 	}
7837 	
7838 	
7839 	/** initialization method of constraint handler (called after problem was transformed) */
7840 	static
7841 	SCIP_DECL_CONSINIT(consInitPseudoboolean)
7842 	{  /*lint --e{715}*/
7843 	   SCIP_CONSHDLRDATA* conshdlrdata;
7844 	   int c;
7845 	
7846 	   assert(scip != NULL);
7847 	   assert(conshdlr != NULL);
7848 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
7849 	
7850 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
7851 	   assert(conshdlrdata != NULL);
7852 	
7853 	   /* check each constraint and get transformed constraints */
7854 	   for( c = conshdlrdata->nallconsanddatas - 1; c >= 0; --c )
7855 	   {
7856 	      SCIP_CONS* andcons;
7857 	      SCIP_VAR* resultant;
7858 	#ifndef NDEBUG
7859 	      SCIP_VAR** vars;
7860 	      int nvars;
7861 	      int v;
7862 	
7863 	      assert(conshdlrdata->allconsanddatas[c] != NULL);
7864 	      assert(conshdlrdata->allconsanddatas[c]->newvars == NULL);
7865 	
7866 	      vars = conshdlrdata->allconsanddatas[c]->vars;
7867 	      nvars = conshdlrdata->allconsanddatas[c]->nvars;
7868 	      assert(vars != NULL || nvars == 0);
7869 	
7870 	      /* check for correct variables data */
7871 	      for( v = nvars - 1; v > 0; --v )
7872 	      {
7873 	         assert(SCIPvarIsTransformed(vars[v])); /*lint !e613*/
7874 	         assert(SCIPvarGetIndex(vars[v]) >= SCIPvarGetIndex(vars[v-1])); /*lint !e613*/
7875 	      }
7876 	      assert(nvars == 0 || SCIPvarIsTransformed(vars[0])); /*lint !e613*/
7877 	#endif
7878 	
7879 	      andcons = conshdlrdata->allconsanddatas[c]->cons;
7880 	      assert(andcons != NULL);
7881 	
7882 	      assert(SCIPconsIsTransformed(andcons));
7883 	
7884 	      resultant = SCIPgetResultantAnd(scip, andcons);
7885 	      /* insert new mapping */
7886 	      assert(!SCIPhashmapExists(conshdlrdata->hashmap, (void*)resultant));
7887 	      SCIP_CALL( SCIPhashmapInsert(conshdlrdata->hashmap, (void*)resultant, (void*)(conshdlrdata->allconsanddatas[c])) );
7888 	
7889 	      SCIPdebugMsg(scip, "insert into hashmap <%s> (%p) -> <%s> (%p/%p)\n", SCIPvarGetName(resultant), (void*)resultant,
7890 	         SCIPconsGetName(conshdlrdata->allconsanddatas[c]->cons), (void*)(conshdlrdata->allconsanddatas[c]),
7891 	         (void*)(conshdlrdata->allconsanddatas[c]->cons));
7892 	   }
7893 	
7894 	   return SCIP_OKAY;
7895 	}
7896 	
7897 	/** presolving initialization method of constraint handler (called when presolving is about to begin) */
7898 	static
7899 	SCIP_DECL_CONSINITPRE(consInitprePseudoboolean)
7900 	{  /*lint --e{715}*/
7901 	   SCIP_CONSHDLRDATA* conshdlrdata;
7902 	   int c;
7903 	
7904 	   assert(scip != NULL);
7905 	   assert(conshdlr != NULL);
7906 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
7907 	
7908 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
7909 	   assert(conshdlrdata != NULL);
7910 	
7911 	   /* decompose all pseudo boolean constraints into a "linear" constraint and "and" constraints */
7912 	   if( conshdlrdata->decomposeindicatorpbcons || conshdlrdata->decomposenormalpbcons )
7913 	   {
7914 	      for( c = 0; c < nconss; ++c )
7915 	      {
7916 	         SCIP_CONS* cons;
7917 	         SCIP_CONSDATA* consdata;
7918 	         SCIP_VAR** vars;
7919 	         SCIP_Real* coefs;
7920 	         int nvars;
7921 	
7922 	         cons = conss[c];
7923 	         assert(cons != NULL);
7924 	
7925 		 /* only added constraints can be upgraded */
7926 		 if( !SCIPconsIsAdded(cons) )
7927 		    continue;
7928 	
7929 	         consdata = SCIPconsGetData(cons);
7930 	         assert(consdata != NULL);
7931 	
7932 	         /* gets number of variables in linear constraint */
7933 	         SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
7934 	
7935 	         /* allocate temporary memory */
7936 	         SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
7937 	         SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
7938 	
7939 	         /* get variables and coefficient of linear constraint */
7940 	         SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
7941 	         assert(nvars == 0 || (coefs != NULL));
7942 	
7943 	         if( consdata->issoftcons && conshdlrdata->decomposeindicatorpbcons )
7944 	         {
7945 	            SCIP_VAR* negindvar;
7946 	            char name[SCIP_MAXSTRLEN];
7947 	            SCIP_Real lhs;
7948 	            SCIP_Real rhs;
7949 	            SCIP_Bool initial;
7950 	            SCIP_Bool updateandconss;
7951 	            int v;
7952 	#if USEINDICATOR == FALSE
7953 	            SCIP_CONS* lincons;
7954 	            SCIP_Real maxact;
7955 	            SCIP_Real minact;
7956 	            SCIP_Real lb;
7957 	            SCIP_Real ub;
7958 	#else
7959 	            SCIP_CONS* indcons;
7960 	#endif
7961 	
7962 	            assert(consdata->weight != 0);
7963 	            assert(consdata->indvar != NULL);
7964 	
7965 	            /* if it is a soft constraint, there should be no integer variable */
7966 	            assert(consdata->intvar == NULL);
7967 	
7968 	            /* get negation of indicator variable */
7969 	            SCIP_CALL( SCIPgetNegatedVar(scip, consdata->indvar, &negindvar) );
7970 	            assert(negindvar != NULL);
7971 	
7972 	            /* get sides of linear constraint */
7973 	            SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &lhs, &rhs) );
7974 	            assert(!SCIPisInfinity(scip, lhs));
7975 	            assert(!SCIPisInfinity(scip, -rhs));
7976 	            assert(SCIPisLE(scip, lhs, rhs));
7977 	
7978 	            updateandconss = FALSE;
7979 	
7980 	#if USEINDICATOR == FALSE
7981 	            maxact = 0.0;
7982 	            minact = 0.0;
7983 	
7984 	            /* adding all linear coefficients up */
7985 	            for( v = nvars - 1; v >= 0; --v )
7986 	               if( coefs[v] > 0 )
7987 	                  maxact += coefs[v];
7988 	               else
7989 	                  minact += coefs[v];
7990 	
7991 	            if( SCIPisInfinity(scip, maxact) )
7992 	            {
7993 	               SCIPwarningMessage(scip, "maxactivity = %g exceed infinity value.\n", maxact);
7994 	            }
7995 	            if( SCIPisInfinity(scip, -minact) )
7996 	            {
7997 	               SCIPwarningMessage(scip, "minactivity = %g exceed -infinity value.\n", minact);
7998 	            }
7999 	
8000 	            /* @todo check whether it's better to set the initial flag to false */
8001 	            initial = SCIPconsIsInitial(cons); /* FALSE; */
8002 	
8003 	            /* first soft constraints for lhs */
8004 	            if( !SCIPisInfinity(scip, -lhs) )
8005 	            {
8006 	               /* first we are modelling the feasibility of the soft constraint by adding a slack variable */
8007 	               /* we ensure that if indvar == 1 => (a^T*x + ub*indvar >= lhs) */
8008 	               ub = lhs - minact;
8009 	
8010 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lhs_part1", SCIPconsGetName(cons));
8011 	
8012 	               SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars, vars, coefs, lhs, SCIPinfinity(scip),
8013 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8014 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
8015 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8016 	
8017 	               /* update and constraint flags */
8018 	               SCIP_CALL( updateAndConss(scip, cons) );
8019 	               updateandconss = TRUE;
8020 	
8021 	               /* add artificial indicator variable */
8022 	               SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->indvar, ub) );
8023 	
8024 	               SCIP_CALL( SCIPaddCons(scip, lincons) );
8025 	               SCIPdebugPrintCons(scip, lincons, NULL);
8026 	               SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
8027 	
8028 	               /* second we are modelling the implication that if the slack variable is on( negation is off), the constraint
8029 	                * is disabled, so only the cost arise if the slack variable is necessary */
8030 	               /* indvar == 1 => (a^T*x (+ ub * negindvar) <= lhs - 1) */
8031 	               ub = lhs - maxact - 1;
8032 	
8033 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lhs_part2", SCIPconsGetName(cons));
8034 	
8035 	               SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars, vars, coefs, -SCIPinfinity(scip), lhs - 1,
8036 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8037 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
8038 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8039 	
8040 	               /* add artificial indicator variable */
8041 	               SCIP_CALL( SCIPaddCoefLinear(scip, lincons, negindvar, ub) );
8042 	
8043 	               SCIP_CALL( SCIPaddCons(scip, lincons) );
8044 	               SCIPdebugPrintCons(scip, lincons, NULL);
8045 	               SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
8046 	            }
8047 	
8048 	            /* second soft constraints for rhs */
8049 	            if( !SCIPisInfinity(scip, rhs) )
8050 	            {
8051 	               /* first we are modelling the feasibility of the soft-constraint by adding a slack variable */
8052 	               /* indvar == 1 => (a^T*x + lb * indvar <= rhs) */
8053 	               lb = rhs - maxact;
8054 	
8055 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_rhs_part1", SCIPconsGetName(cons));
8056 	
8057 	               SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars, vars, coefs, -SCIPinfinity(scip), rhs,
8058 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8059 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
8060 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8061 	
8062 	               if( !updateandconss )
8063 	               {
8064 	                  /* update and constraint flags */
8065 	                  SCIP_CALL( updateAndConss(scip, cons) );
8066 	               }
8067 	
8068 	               /* add artificial indicator variable */
8069 	               SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->indvar, lb) );
8070 	
8071 	               SCIP_CALL( SCIPaddCons(scip, lincons) );
8072 	               SCIPdebugPrintCons(scip, lincons, NULL);
8073 	               SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
8074 	
8075 	               /* second we are modelling the implication that if the slack variable is on( negation is off), the constraint
8076 	                * is disabled, so only the cost arise if the slack variable is necessary */
8077 	               /* indvar == 1 => (a^T*x (+ lb * negindvar) >= rhs + 1) */
8078 	               lb = rhs - minact + 1;
8079 	
8080 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_rhs_part2", SCIPconsGetName(cons));
8081 	
8082 	               SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars, vars, coefs, rhs + 1, SCIPinfinity(scip),
8083 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8084 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons), SCIPconsIsModifiable(cons),
8085 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8086 	
8087 	               /* add artificial indicator variable */
8088 	               SCIP_CALL( SCIPaddCoefLinear(scip, lincons, negindvar, lb) );
8089 	
8090 	               SCIP_CALL( SCIPaddCons(scip, lincons) );
8091 	               SCIPdebugPrintCons(scip, lincons, NULL);
8092 	               SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
8093 	            }
8094 	#else /* with indicator */
8095 	            /* @todo check whether it's better to set the initial flag to false */
8096 	            initial = SCIPconsIsInitial(cons); /* FALSE; */
8097 	
8098 	            if( !SCIPisInfinity(scip, rhs) )
8099 	            {
8100 	               /* first we are modelling the implication that if the negation of the indicator variable is on, the constraint
8101 	                * is enabled */
8102 	               /* indvar == 0 => a^T*x <= rhs */
8103 	
8104 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_rhs_ind", SCIPconsGetName(cons));
8105 	
8106 	               SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, negindvar, nvars, vars, coefs, rhs,
8107 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8108 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons),
8109 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8110 	
8111 	               /* update and constraint flags */
8112 	               SCIP_CALL( updateAndConss(scip, cons) );
8113 	               updateandconss = TRUE;
8114 	
8115 	               SCIP_CALL( SCIPaddCons(scip, indcons) );
8116 	               SCIPdebugPrintCons(scip, indcons, NULL);
8117 	               SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
8118 	            }
8119 	
8120 	            if( !SCIPisInfinity(scip, -lhs) )
8121 	            {
8122 	               /* second we are modelling the implication that if the negation of the indicator variable is on, the constraint
8123 	                * is enabled */
8124 	               /* change the a^T*x >= lhs to -a^Tx<= -lhs, for indicator constraint */
8125 	
8126 	               for( v = nvars - 1; v >= 0; --v )
8127 	                  coefs[v] *= -1;
8128 	
8129 	               (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lhs_ind", SCIPconsGetName(cons));
8130 	
8131 	               SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, negindvar, nvars, vars, coefs, -lhs,
8132 	                     initial, SCIPconsIsSeparated(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons),
8133 	                     SCIPconsIsPropagated(cons), SCIPconsIsLocal(cons),
8134 	                     SCIPconsIsDynamic(cons), SCIPconsIsRemovable(cons), SCIPconsIsStickingAtNode(cons)) );
8135 	
8136 	               if( !updateandconss )
8137 	               {
8138 	                  /* update and constraint flags */
8139 	                  SCIP_CALL( updateAndConss(scip, cons) );
8140 	               }
8141 	
8142 	               SCIP_CALL( SCIPaddCons(scip, indcons) );
8143 	               SCIPdebugPrintCons(scip, indcons, NULL);
8144 	               SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
8145 	            }
8146 	#endif
8147 	            /* remove pseudo boolean and corresponding linear constraint, new linear constraints were created,
8148 	             * and-constraints still active
8149 	             */
8150 	            SCIP_CALL( SCIPdelCons(scip, consdata->lincons) );
8151 	            SCIP_CALL( SCIPdelCons(scip, cons) );
8152 	         }
8153 	         /* no soft constraint */
8154 	         else if( !consdata->issoftcons && conshdlrdata->decomposenormalpbcons )
8155 	         {
8156 	            /* todo: maybe better create a new linear constraint and let scip do the upgrade */
8157 	
8158 	            /* mark linear constraint not to be upgraded - otherwise we loose control over it */
8159 	            SCIPconsAddUpgradeLocks(consdata->lincons, 1);
8160 	
8161 	            /* update and constraint flags */
8162 	            SCIP_CALL( updateAndConss(scip, cons) );
8163 	
8164 	#if 0 /* not implemented correctly */
8165 	            if( consdata->intvar != NULL )
8166 	            {
8167 	               /* add auxiliary integer variables to linear constraint */
8168 	               SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->intvar, -1.0) );
8169 	            }
8170 	#endif
8171 	            /* remove pseudo boolean constraint, old linear constraint is still active, and-constraints too */
8172 	            SCIP_CALL( SCIPdelCons(scip, cons) );
8173 	         }
8174 	
8175 	         /* free temporary memory */
8176 	         SCIPfreeBufferArray(scip, &coefs);
8177 	         SCIPfreeBufferArray(scip, &vars);
8178 	      }
8179 	   }
8180 	
8181 	   return SCIP_OKAY;
8182 	}
8183 	
8184 	/** frees specific constraint data */
8185 	static
8186 	SCIP_DECL_CONSDELETE(consDeletePseudoboolean)
8187 	{  /*lint --e{715}*/
8188 	   SCIP_CONSHDLRDATA* conshdlrdata;
8189 	   SCIP_Bool isorig;
8190 	
8191 	   assert(scip != NULL);
8192 	   assert(conshdlr != NULL);
8193 	   assert(cons != NULL);
8194 	   assert(consdata != NULL);
8195 	   assert(*consdata != NULL);
8196 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8197 	
8198 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
8199 	   assert(conshdlrdata != NULL);
8200 	
8201 	   isorig = SCIPconsIsOriginal(cons);
8202 	
8203 	   /* count number of used consanddata objects in original problem */
8204 	   if( isorig )
8205 	   {
8206 	#ifndef NDEBUG
8207 	      int c;
8208 	      assert((*consdata)->lincons == NULL || SCIPconsIsOriginal((*consdata)->lincons));
8209 	
8210 	      for( c = (*consdata)->nconsanddatas - 1; c >= 0; --c )
8211 	      {
8212 	         assert((*consdata)->consanddatas[c]->nuses == 0);
8213 	         assert((*consdata)->consanddatas[c]->cons == NULL);
8214 	         assert((*consdata)->consanddatas[c]->noriguses == 0 || ((*consdata)->consanddatas[c]->origcons != NULL && SCIPconsIsOriginal((*consdata)->consanddatas[c]->origcons)));
8215 	      }
8216 	#endif
8217 	      conshdlrdata->noriguses -= (*consdata)->nconsanddatas;
8218 	   }
8219 	   assert(conshdlrdata->noriguses >= 0);
8220 	
8221 	   /* free pseudo boolean constraint */
8222 	   SCIP_CALL( consdataFree(scip, consdata, isorig, conshdlrdata) );
8223 	
8224 	   return SCIP_OKAY;
8225 	}
8226 	
8227 	/** transforms constraint data into data belonging to the transformed problem */
8228 	static
8229 	SCIP_DECL_CONSTRANS(consTransPseudoboolean)
8230 	{  /*lint --e{715}*/
8231 	   SCIP_CONSDATA* sourcedata;
8232 	   SCIP_CONSDATA* targetdata;
8233 	   SCIP_CONS** andconss;
8234 	   int c;
8235 	
8236 	   assert(scip != NULL);
8237 	   assert(conshdlr != NULL);
8238 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8239 	   assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
8240 	   assert(sourcecons != NULL);
8241 	   assert(targetcons != NULL);
8242 	
8243 	   sourcedata = SCIPconsGetData(sourcecons);
8244 	   assert(sourcedata != NULL);
8245 	
8246 	   assert(sourcedata->nconsanddatas == 0 || sourcedata->consanddatas != NULL);
8247 	
8248 	   /* allocate temporary memory */
8249 	   SCIP_CALL( SCIPallocBufferArray(scip, &andconss, sourcedata->nconsanddatas) );
8250 	
8251 	   /* copy and-constraints */
8252 	   for( c = sourcedata->nconsanddatas - 1; c >= 0; --c )
8253 	   {
8254 	      assert(sourcedata->consanddatas[c] != NULL);
8255 	      andconss[c] = sourcedata->consanddatas[c]->origcons;
8256 	      assert(andconss[c] != NULL);
8257 	      assert(SCIPconsIsOriginal(andconss[c]));
8258 	   }
8259 	
8260 	   /* create pseudoboolean constraint data for target constraint */
8261 	   SCIP_CALL( consdataCreate(scip, conshdlr, &targetdata, sourcedata->lincons, sourcedata->linconstype,
8262 	         andconss, sourcedata->andcoefs, sourcedata->andnegs, sourcedata->nconsanddatas, sourcedata->indvar, sourcedata->weight,
8263 	         sourcedata->issoftcons, sourcedata->intvar, sourcedata->lhs, sourcedata->rhs, SCIPconsIsChecked(sourcecons),
8264 	         TRUE) );
8265 	
8266 	   /* free temporary memory */
8267 	   SCIPfreeBufferArray(scip, &andconss);
8268 	
8269 	   /* create target constraint */
8270 	   SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
8271 	         SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
8272 	         SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
8273 	         SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
8274 	         SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
8275 	
8276 	   return SCIP_OKAY;
8277 	}
8278 	
8279 	/** constraint enforcing method of constraint handler for LP solutions */
8280 	static
8281 	SCIP_DECL_CONSENFOLP(consEnfolpPseudoboolean)
8282 	{  /*lint --e{715}*/
8283 	   SCIP_Bool violated;
8284 	
8285 	   assert(scip != NULL);
8286 	   assert(conshdlr != NULL);
8287 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8288 	   assert(result != NULL);
8289 	
8290 	   violated = FALSE;
8291 	
8292 	   /* check all and-constraints */
8293 	   SCIP_CALL( checkAndConss(scip, conshdlr, NULL, &violated) );
8294 	
8295 	   if( violated )
8296 	      *result = SCIP_INFEASIBLE;
8297 	   else
8298 	      *result = SCIP_FEASIBLE;
8299 	
8300 	   return SCIP_OKAY;
8301 	}
8302 	
8303 	
8304 	/** constraint enforcing method of constraint handler for relaxation solutions */
8305 	static
8306 	SCIP_DECL_CONSENFORELAX(consEnforelaxPseudoboolean)
8307 	{  /*lint --e{715}*/
8308 	   SCIP_Bool violated;
8309 	
8310 	   assert(scip != NULL);
8311 	   assert(conshdlr != NULL);
8312 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8313 	   assert(result != NULL);
8314 	
8315 	   violated = FALSE;
8316 	
8317 	   /* check all and-constraints */
8318 	   SCIP_CALL( checkAndConss(scip, conshdlr, sol, &violated) );
8319 	
8320 	   if( violated )
8321 	      *result = SCIP_INFEASIBLE;
8322 	   else
8323 	      *result = SCIP_FEASIBLE;
8324 	
8325 	   return SCIP_OKAY;
8326 	}
8327 	
8328 	
8329 	/** constraint enforcing method of constraint handler for pseudo solutions */
8330 	static
8331 	SCIP_DECL_CONSENFOPS(consEnfopsPseudoboolean)
8332 	{  /*lint --e{715}*/
8333 	   SCIP_Bool violated;
8334 	
8335 	   assert(scip != NULL);
8336 	   assert(conshdlr != NULL);
8337 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8338 	   assert(result != NULL);
8339 	
8340 	   violated = FALSE;
8341 	
8342 	   /* check all and-constraints */
8343 	   SCIP_CALL( checkAndConss(scip, conshdlr, NULL, &violated) );
8344 	
8345 	   if( violated )
8346 	      *result = SCIP_INFEASIBLE;
8347 	   else
8348 	      *result = SCIP_FEASIBLE;
8349 	
8350 	   return SCIP_OKAY;
8351 	}
8352 	
8353 	
8354 	/** feasibility check method of constraint handler for integral solutions */
8355 	static
8356 	SCIP_DECL_CONSCHECK(consCheckPseudoboolean)
8357 	{  /*lint --e{715}*/
8358 	   SCIP_Bool violated;
8359 	   int c;
8360 	
8361 	   assert(scip != NULL);
8362 	   assert(conshdlr != NULL);
8363 	   assert(sol != NULL);
8364 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8365 	   assert(result != NULL);
8366 	
8367 	   *result = SCIP_FEASIBLE;
8368 	
8369 	   if( nconss > 0 )
8370 	   {
8371 	      if( SCIPconsIsOriginal(conss[0]) )
8372 	      {
8373 	         SCIP_CONSDATA* consdata;
8374 	
8375 	         for( c = nconss - 1; c >= 0 && (*result == SCIP_FEASIBLE || completely); --c )
8376 	         {
8377 	            consdata = SCIPconsGetData(conss[c]);
8378 	            assert(consdata != NULL);
8379 	
8380 	            if( consdata->issoftcons )
8381 	            {
8382 	               assert(consdata->indvar != NULL);
8383 	
8384 	               if( SCIPisEQ(scip, SCIPgetSolVal(scip, sol, consdata->indvar), 1.0) )
8385 	                  continue;
8386 	            }
8387 	
8388 	            SCIP_CALL( checkOrigPbCons(scip, conss[c], sol, &violated, printreason) );
8389 	            if( violated )
8390 	               *result = SCIP_INFEASIBLE;
8391 	         }
8392 	      }
8393 	      else
8394 	      {
8395 	         /* check all and-constraints */
8396 	         SCIP_CALL( checkAndConss(scip, conshdlr, sol, &violated) );
8397 	         if( violated )
8398 	            *result = SCIP_INFEASIBLE;
8399 	      }
8400 	   }
8401 	
8402 	   return SCIP_OKAY;
8403 	}
8404 	
8405 	
8406 	/** presolving method of constraint handler */
8407 	static
8408 	SCIP_DECL_CONSPRESOL(consPresolPseudoboolean)
8409 	{  /*lint --e{715}*/
8410 	   SCIP_CONSHDLRDATA* conshdlrdata;
8411 	   SCIP_Bool cutoff;
8412 	   int firstchange;
8413 	   int firstupgradetry;
8414 	   int oldnfixedvars;
8415 	   int oldnaggrvars;
8416 	   int oldnchgbds;
8417 	   int oldndelconss;
8418 	   int oldnupgdconss;
8419 	   int oldnchgcoefs;
8420 	   int oldnchgsides;
8421 	   int c;
8422 	
8423 	   assert(scip != NULL);
8424 	   assert(conshdlr != NULL);
8425 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8426 	   assert(result != NULL);
8427 	
8428 	   /* remember old preprocessing counters */
8429 	   oldnfixedvars = *nfixedvars;
8430 	   oldnaggrvars = *naggrvars;
8431 	   oldnchgbds = *nchgbds;
8432 	   oldndelconss = *ndelconss;
8433 	   oldnupgdconss = *nupgdconss;
8434 	   oldnchgcoefs = *nchgcoefs;
8435 	   oldnchgsides = *nchgsides;
8436 	
8437 	   /* get constraint handler data */
8438 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
8439 	
8440 	   /* compute all changes in consanddata objects */
8441 	   SCIP_CALL( computeConsAndDataChanges(scip, conshdlrdata) );
8442 	
8443 	   firstchange = INT_MAX;
8444 	   firstupgradetry = INT_MAX;
8445 	   cutoff = FALSE;
8446 	
8447 	   for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
8448 	   {
8449 	      SCIP_CONS* cons;
8450 	      SCIP_CONSDATA* consdata;
8451 	      SCIP_VAR** vars;
8452 	      SCIP_Real* coefs;
8453 	      int nvars;
8454 	      SCIP_VAR** linvars;
8455 	      SCIP_Real* lincoefs;
8456 	      int nlinvars;
8457 	      SCIP_VAR** andress;
8458 	      SCIP_Real* andcoefs;
8459 	      SCIP_Bool* andnegs;
8460 	      int nandress;
8461 	      SCIP_Real newlhs;
8462 	      SCIP_Real newrhs;
8463 	
8464 	      cons = conss[c];
8465 	      assert(cons != NULL);
8466 	      assert(SCIPconsIsActive(cons));
8467 	
8468 	      consdata = SCIPconsGetData(cons);
8469 	      assert(consdata != NULL);
8470 	      assert(consdata->lincons != NULL);
8471 	
8472 	      /* if linear constraint is redundant, than pseudoboolean constraint is redundant too */
8473 	      if( SCIPconsIsDeleted(consdata->lincons) )
8474 	      {
8475 	         /* update and constraint flags */
8476 	         SCIP_CALL( updateAndConss(scip, cons) );
8477 	
8478 	         SCIP_CALL( SCIPdelCons(scip, cons) );
8479 	         ++(*ndelconss);
8480 	         continue;
8481 	      }
8482 	
8483 	      /* get sides of linear constraint */
8484 	      SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &newlhs, &newrhs) );
8485 	      assert(!SCIPisInfinity(scip, newlhs));
8486 	      assert(!SCIPisInfinity(scip, -newrhs));
8487 	      assert(SCIPisLE(scip, newlhs, newrhs));
8488 	
8489 	      /* gets number of variables in linear constraint */
8490 	      SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
8491 	
8492 	      /* allocate temporary memory */
8493 	      SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
8494 	      SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
8495 	      SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nvars) );
8496 	      SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nvars) );
8497 	      SCIP_CALL( SCIPallocBufferArray(scip, &andress, nvars) );
8498 	      SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nvars) );
8499 	      SCIP_CALL( SCIPallocBufferArray(scip, &andnegs, nvars) );
8500 	
8501 	      /* get variables and coefficient of linear constraint */
8502 	      SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
8503 	      assert(nvars == 0 || (coefs != NULL));
8504 	
8505 	      /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
8506 	       * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
8507 	       * afterwards
8508 	       */
8509 	      SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
8510 	            andress, andcoefs, andnegs, &nandress) );
8511 	
8512 	      /* update all locks inside this constraint and all captures on all and-constraints */
8513 	      SCIP_CALL( correctLocksAndCaptures(scip, cons, conshdlrdata, newlhs, newrhs, andress, andcoefs, andnegs, nandress) );
8514 	
8515 	      /* we can only presolve pseudoboolean constraints, that are not modifiable */
8516 	      if( SCIPconsIsModifiable(cons) )
8517 	         goto CONTTERMINATE;
8518 	
8519 	      SCIPdebugMsg(scip, "presolving pseudoboolean constraint <%s>\n", SCIPconsGetName(cons));
8520 	      SCIPdebugPrintCons(scip, cons, NULL);
8521 	
8522 	      /* remember the first changed constraint to begin the next aggregation round with */
8523 	      if( firstchange == INT_MAX && consdata->changed )
8524 	         firstchange = c;
8525 	
8526 	      if( consdata->changed && !SCIPisStopped(scip) )
8527 	      {
8528 		 /* check if we can aggregated some variables */
8529 		 SCIP_CALL( findAggregation(scip, cons, conshdlrdata, ndelconss, naggrvars, &cutoff) );
8530 	      }
8531 	
8532 	      /* if aggregation also deleted the constraint we can go to the next */
8533 	      if( !SCIPconsIsActive(cons) )
8534 	         goto CONTTERMINATE;
8535 	
8536 	      if( consdata->changed )
8537 	      {
8538 	         /* try upgrading pseudoboolean constraint to a linear constraint and/or remove possible and-constraints */
8539 	         SCIP_CALL( tryUpgrading(scip, cons, conshdlrdata, ndelconss, naddconss, nfixedvars, nchgcoefs, nchgsides, &cutoff) );
8540 	         if( cutoff )
8541 	            goto CONTTERMINATE;
8542 	      }
8543 	
8544 	      /* if upgrading deleted the pseudoboolean constraint we go on */
8545 	      if( !SCIPconsIsActive(cons) )
8546 	         goto CONTTERMINATE;
8547 	
8548 	      /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
8549 	      if( firstupgradetry == INT_MAX && !consdata->upgradetried )
8550 	         firstupgradetry = c;
8551 	
8552 	      while( !consdata->presolved && !SCIPisStopped(scip) )
8553 	      {
8554 	         /* mark constraint being presolved and propagated */
8555 	         consdata->presolved = TRUE;
8556 	
8557 	         /* add cliques to the clique table */
8558 	         SCIP_CALL( addCliques(scip, cons, &cutoff, naggrvars, nchgbds) );
8559 	         if( cutoff )
8560 	            break;
8561 	
8562 	         /* propagate constraint */
8563 	         SCIP_CALL( propagateCons(scip, cons, &cutoff, ndelconss) );
8564 	         if( cutoff )
8565 	            break;
8566 	      }
8567 	
8568 	   CONTTERMINATE:
8569 	
8570 	      /* reset changed flag */
8571 	      if( SCIPconsIsActive(cons) )
8572 	      {
8573 		 consdata->changed = FALSE;
8574 	      }
8575 	
8576 	      /* free temporary memory */
8577 	      SCIPfreeBufferArray(scip, &andnegs);
8578 	      SCIPfreeBufferArray(scip, &andcoefs);
8579 	      SCIPfreeBufferArray(scip, &andress);
8580 	      SCIPfreeBufferArray(scip, &lincoefs);
8581 	      SCIPfreeBufferArray(scip, &linvars);
8582 	      SCIPfreeBufferArray(scip, &coefs);
8583 	      SCIPfreeBufferArray(scip, &vars);
8584 	   }
8585 	
8586 	   /* delete unused information in constraint handler data */
8587 	   SCIP_CALL( correctConshdlrdata(scip, conshdlrdata, ndelconss) );
8588 	
8589 	   /* return the correct result code */
8590 	   if( cutoff )
8591 	      *result = SCIP_CUTOFF;
8592 	   else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
8593 	      || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
8594 	      *result = SCIP_SUCCESS;
8595 	   else
8596 	      *result = SCIP_DIDNOTFIND;
8597 	
8598 	   return SCIP_OKAY;
8599 	}
8600 	
8601 	/** variable rounding lock method of constraint handler */
8602 	static
8603 	SCIP_DECL_CONSLOCK(consLockPseudoboolean)
8604 	{  /*lint --e{715}*/
8605 	   SCIP_CONSDATA* consdata;
8606 	   SCIP_Real lhs;
8607 	   SCIP_Real rhs;
8608 	   SCIP_Bool haslhs;
8609 	   SCIP_Bool hasrhs;
8610 	   int v;
8611 	   int c;
8612 	
8613 	   assert(scip != NULL);
8614 	   assert(cons != NULL);
8615 	   assert(conshdlr != NULL);
8616 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8617 	   assert(locktype == SCIP_LOCKTYPE_MODEL);
8618 	
8619 	   consdata = SCIPconsGetData(cons);
8620 	   assert(consdata != NULL);
8621 	
8622 	   lhs = consdata->lhs;
8623 	   rhs = consdata->rhs;
8624 	   assert(!SCIPisInfinity(scip, lhs));
8625 	   assert(!SCIPisInfinity(scip, -rhs));
8626 	   assert(SCIPisLE(scip, lhs, rhs));
8627 	
8628 	   haslhs = !SCIPisInfinity(scip, -lhs);
8629 	   hasrhs = !SCIPisInfinity(scip, rhs);
8630 	
8631 	   SCIPdebugMsg(scip, "%socking constraint <%s> by [%d;%d].\n", (nlocksneg < 0) || (nlockspos < 0) ? "Unl" : "L", SCIPconsGetName(cons), nlocksneg, nlockspos);
8632 	
8633 	   /* update rounding locks of every single variable corresponding to the and-constraints */
8634 	   for( c = consdata->nconsanddatas - 1; c >= 0; --c )
8635 	   {
8636 	      SCIP_VAR* andres;
8637 	      SCIP_VAR** andvars;
8638 	      SCIP_Real val;
8639 	      int nandvars;
8640 	      SCIP_CONS* andcons;
8641 	      CONSANDDATA* consanddata;
8642 	
8643 	      consanddata = consdata->consanddatas[c];
8644 	      assert( consanddata != NULL );
8645 	
8646 	      if( !consanddata->istransformed )
8647 	         continue;
8648 	
8649 	      andcons = consanddata->cons;
8650 	
8651 	      if( andcons == NULL )
8652 	      {
8653 	         /* we should have no new variables */
8654 	         assert(consanddata->nnewvars == 0);
8655 	         assert(consanddata->nvars == 0);
8656 	
8657 	         SCIPfreeBlockMemoryArrayNull(scip, &(consanddata->vars), consanddata->svars);
8658 	         SCIPfreeBlockMemoryArrayNull(scip, &(consanddata->newvars), consanddata->snewvars);
8659 	
8660 	         consanddata->nvars = 0;
8661 	         consanddata->svars = 0;
8662 	         consanddata->nnewvars = 0;
8663 	         consanddata->snewvars = 0;
8664 	         consanddata->istransformed = FALSE;
8665 	
8666 	         continue;
8667 	      }
8668 	      assert(andcons != NULL);
8669 	      if( consanddata->nnewvars > 0 )
8670 	      {
8671 	         andvars = consanddata->newvars;
8672 	         nandvars = consanddata->nnewvars;
8673 	      }
8674 	      else
8675 	      {
8676 	         andvars = consanddata->vars;
8677 	         nandvars = consanddata->nvars;
8678 	      }
8679 	
8680 	      /* probably we need to store the resultant too, now it's not possible to remove the resultant from the and-constraint */
8681 	      andres = SCIPgetResultantAnd(scip, andcons);
8682 	      assert(nandvars == 0 || andvars != NULL);
8683 	      assert(andres != NULL);
8684 	      val = consdata->andnegs[c] ? -consdata->andcoefs[c] : consdata->andcoefs[c];
8685 	
8686 	      /* lock variables */
8687 	      if( SCIPisPositive(scip, val) )
8688 	      {
8689 	         if( haslhs )
8690 	         {
8691 	            for( v = nandvars - 1; v >= 0; --v )
8692 	            {
8693 	               SCIP_CALL( SCIPaddVarLocksType(scip, andvars[v], locktype, nlockspos, nlocksneg) );
8694 	            }
8695 	            SCIP_CALL( SCIPaddVarLocksType(scip, andres, locktype, nlocksneg + nlockspos, nlocksneg + nlockspos) );
8696 	
8697 	            SCIP_CALL( checkLocksAndRes(scip, andres) );
8698 	         }
8699 	         if( hasrhs )
8700 	         {
8701 	            for( v = nandvars - 1; v >= 0; --v )
8702 	            {
8703 	               SCIP_CALL( SCIPaddVarLocksType(scip, andvars[v], locktype, nlocksneg, nlockspos) );
8704 	            }
8705 	            /* don't double the locks on the and-resultant */
8706 	            if( !haslhs )
8707 	            {
8708 	               SCIP_CALL( SCIPaddVarLocksType(scip, andres, locktype, nlocksneg + nlockspos, nlocksneg + nlockspos) );
8709 	
8710 	               SCIP_CALL( checkLocksAndRes(scip, andres) );
8711 	            }
8712 	         }
8713 	      }
8714 	      else
8715 	      {
8716 	         if( haslhs )
8717 	         {
8718 	            for( v = nandvars - 1; v >= 0; --v )
8719 	            {
8720 	               SCIP_CALL( SCIPaddVarLocksType(scip, andvars[v], SCIP_LOCKTYPE_MODEL, nlocksneg, nlockspos) );
8721 	            }
8722 	            SCIP_CALL( SCIPaddVarLocksType(scip, andres, SCIP_LOCKTYPE_MODEL, nlocksneg + nlockspos, nlocksneg + nlockspos) );
8723 	
8724 	            SCIP_CALL( checkLocksAndRes(scip, andres) );
8725 	         }
8726 	         if( hasrhs )
8727 	         {
8728 	            for( v = nandvars - 1; v >= 0; --v )
8729 	            {
8730 	               SCIP_CALL( SCIPaddVarLocksType(scip, andvars[v], SCIP_LOCKTYPE_MODEL, nlockspos, nlocksneg) );
8731 	            }
8732 	            /* don't double the locks on the and-resultant */
8733 	            if( !haslhs )
8734 	            {
8735 	               SCIP_CALL( SCIPaddVarLocksType(scip, andres, SCIP_LOCKTYPE_MODEL, nlocksneg + nlockspos, nlocksneg + nlockspos) );
8736 	
8737 	               SCIP_CALL( checkLocksAndRes(scip, andres) );
8738 	            }
8739 	         }
8740 	      }
8741 	   }
8742 	
8743 	   return SCIP_OKAY;
8744 	}
8745 	
8746 	/** constraint display method of constraint handler */
8747 	static
8748 	SCIP_DECL_CONSPRINT(consPrintPseudoboolean)
8749 	{  /*lint --e{715}*/
8750 	   assert(scip != NULL);
8751 	   assert(conshdlr != NULL);
8752 	   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
8753 	   assert(cons != NULL);
8754 	
8755 	   SCIP_CALL( consdataPrint(scip, cons, file) );
8756 	
8757 	   return SCIP_OKAY;
8758 	}
8759 	
8760 	/** constraint copying method of constraint handler */
8761 	static
8762 	SCIP_DECL_CONSCOPY(consCopyPseudoboolean)
8763 	{  /*lint --e{715}*/
8764 	   const char* consname;
8765 	
8766 	   assert(scip != NULL);
8767 	   assert(sourcescip != NULL);
8768 	   assert(sourcecons != NULL);
8769 	
8770 	   if( name != NULL )
8771 	      consname = name;
8772 	   else
8773 	      consname = SCIPconsGetName(sourcecons);
8774 	
8775 	   SCIP_CALL( copyConsPseudoboolean(scip, cons, sourcescip, sourcecons, consname, varmap, consmap,
8776 	         initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global,
8777 	         valid) );
8778 	   assert(cons != NULL || *valid == FALSE);
8779 	
8780 	   return SCIP_OKAY;
8781 	}
8782 	
8783 	/** constraint method of constraint handler which returns the variables (if possible) */
8784 	static
8785 	SCIP_DECL_CONSGETVARS(consGetVarsPseudoboolean)
8786 	{  /*lint --e{715}*/
8787 	   SCIP_CONSHDLRDATA* conshdlrdata;
8788 	   SCIP_CONSDATA* consdata;
8789 	   CONSANDDATA* consanddata;
8790 	   SCIP_VAR** linconsvars;
8791 	   SCIP_VAR** linvars;
8792 	   SCIP_VAR** andress;
8793 	   int nlinconsvars;
8794 	   int nlinvars;
8795 	   int nandress;
8796 	   SCIP_Bool transformed;
8797 	   int nvars;
8798 	   int r;
8799 	
8800 	   assert(scip != NULL);
8801 	   assert(conshdlr != NULL);
8802 	   assert(cons != NULL);
8803 	   assert(vars != NULL);
8804 	   assert(success != NULL);
8805 	
8806 	   if( varssize < 0 )
8807 	      return SCIP_INVALIDDATA;
8808 	   assert(varssize >= 0);
8809 	
8810 	   *success = TRUE;
8811 	
8812 	   /* pseudoboolean constraint is already deleted */
8813 	   if( SCIPconsIsDeleted(cons) )
8814 	   {
8815 	      vars = NULL;
8816 	
8817 	      return SCIP_OKAY; /*lint !e438*/
8818 	   }
8819 	
8820 	   consdata = SCIPconsGetData(cons);
8821 	   assert(consdata != NULL);
8822 	   assert(consdata->lincons != NULL);
8823 	
8824 	   /* linear constraint of pseudoboolean is already deleted */
8825 	   if( SCIPconsIsDeleted(consdata->lincons) )
8826 	   {
8827 	      vars = NULL;
8828 	
8829 	      return SCIP_OKAY; /*lint !e438*/
8830 	   }
8831 	
8832 	   /* gets number of variables in linear constraint */
8833 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nlinconsvars) );
8834 	   assert(nlinconsvars >= 0);
8835 	
8836 	   /* no variables exist */
8837 	   if( nlinconsvars == 0 )
8838 	   {
8839 	      vars = NULL;
8840 	
8841 	      return SCIP_OKAY; /*lint !e438*/
8842 	   }
8843 	   /* not enough space in the variables array */
8844 	   else if( varssize < nlinconsvars )
8845 	   {
8846 	      (*success) = FALSE;
8847 	
8848 	      return SCIP_OKAY;
8849 	   }
8850 	
8851 	   /* allocate temporary memory */
8852 	   SCIP_CALL( SCIPallocBufferArray(scip, &linconsvars, nlinconsvars) );
8853 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinconsvars) );
8854 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nlinconsvars) );
8855 	
8856 	   /* get variables and coefficient of linear constraint */
8857 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, linconsvars, NULL, &nlinconsvars) );
8858 	
8859 	   /* calculate all non-artificial linear variables and all artificial and-resultants which will be ordered like the
8860 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
8861 	    * afterwards
8862 	    */
8863 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, linconsvars, NULL, nlinconsvars, linvars, NULL, &nlinvars,
8864 	         andress, NULL, NULL, &nandress) );
8865 	   assert(nlinconsvars == nlinvars + nandress);
8866 	
8867 	   nvars = nlinvars;
8868 	
8869 	   if( nlinvars > 0 )
8870 	   {
8871 	      assert(linvars != NULL);
8872 	      BMScopyMemoryArray(vars, linvars, nvars);
8873 	   }
8874 	
8875 	   if( nandress == 0 )
8876 	      goto TERMINATE;
8877 	
8878 	   assert(andress != NULL);
8879 	
8880 	   /* get constraint handler data */
8881 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
8882 	   assert(conshdlrdata != NULL);
8883 	   assert(conshdlrdata->hashmap != NULL);
8884 	
8885 	   transformed = SCIPconsIsTransformed(cons);
8886 	
8887 	   for( r = nandress - 1; r >= 0; --r )
8888 	   {
8889 	      SCIP_CONS* andcons;
8890 	
8891 	      assert(andress[r] != NULL);
8892 	
8893 	      consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[r]);
8894 	
8895 	      assert(consanddata != NULL);
8896 	      assert(consanddata->istransformed);
8897 	
8898 	      if( transformed )
8899 	         andcons = consanddata->cons;
8900 	      else
8901 	         andcons = consanddata->origcons;
8902 	
8903 	      assert(andcons != NULL);
8904 	
8905 	      /* not enough space for all variables */
8906 	      if( varssize <= nvars )
8907 	      {
8908 		 (*success) = FALSE;
8909 	
8910 		 goto TERMINATE;
8911 	      }
8912 	
8913 	      /* add the resultant */
8914 	      vars[nvars] = andress[r];
8915 	      ++nvars;
8916 	
8917 	      /* add all and-operands and the resultant */
8918 	      if( !SCIPconsIsDeleted(andcons) )
8919 	      {
8920 		 int noperands = SCIPgetNVarsAnd(scip, andcons);
8921 	
8922 		 assert(noperands >= 0);
8923 	
8924 		 /* not enough space for all variables */
8925 		 if( varssize < nvars + noperands )
8926 		 {
8927 		    (*success) = FALSE;
8928 	
8929 		    goto TERMINATE;
8930 		 }
8931 	
8932 		 /* copy operands */
8933 		 if( noperands > 0 )
8934 		 {
8935 		    assert(SCIPgetVarsAnd(scip, andcons) != NULL);
8936 		    BMScopyMemoryArray(&(vars[nvars]), SCIPgetVarsAnd(scip, andcons), noperands); /*lint !e866*/
8937 		    nvars += noperands;
8938 		 }
8939 	      }
8940 	   }
8941 	
8942 	 TERMINATE:
8943 	
8944 	   /* free temporary memory */
8945 	   SCIPfreeBufferArray(scip, &andress);
8946 	   SCIPfreeBufferArray(scip, &linvars);
8947 	   SCIPfreeBufferArray(scip, &linconsvars);
8948 	
8949 	   return SCIP_OKAY;
8950 	}
8951 	
8952 	/** constraint method of constraint handler which returns the number of variables (if possible) */
8953 	static
8954 	SCIP_DECL_CONSGETNVARS(consGetNVarsPseudoboolean)
8955 	{  /*lint --e{715}*/
8956 	   SCIP_CONSHDLRDATA* conshdlrdata;
8957 	   SCIP_CONSDATA* consdata;
8958 	   CONSANDDATA* consanddata;
8959 	   SCIP_VAR** linconsvars;
8960 	   SCIP_VAR** linvars;
8961 	   SCIP_VAR** andress;
8962 	   int nlinconsvars;
8963 	   int nlinvars;
8964 	   int nandress;
8965 	   SCIP_Bool transformed;
8966 	   int r;
8967 	
8968 	   assert(scip != NULL);
8969 	   assert(conshdlr != NULL);
8970 	   assert(cons != NULL);
8971 	   assert(nvars != NULL);
8972 	   assert(success != NULL);
8973 	
8974 	   (*success) = TRUE;
8975 	
8976 	   /* pseudoboolean constraint is already deleted */
8977 	   if( SCIPconsIsDeleted(cons) )
8978 	   {
8979 	      *nvars = 0;
8980 	
8981 	      return SCIP_OKAY;
8982 	   }
8983 	
8984 	   consdata = SCIPconsGetData(cons);
8985 	   assert(consdata != NULL);
8986 	   assert(consdata->lincons != NULL);
8987 	
8988 	   /* linear constraint of pseudoboolean is already deleted */
8989 	   if( SCIPconsIsDeleted(consdata->lincons) )
8990 	   {
8991 	      *nvars = 0;
8992 	
8993 	      return SCIP_OKAY;
8994 	   }
8995 	
8996 	   /* gets number of variables in linear constraint */
8997 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nlinconsvars) );
8998 	   assert(nlinconsvars >= 0);
8999 	
9000 	   /* no variables exist */
9001 	   if( nlinconsvars == 0 )
9002 	   {
9003 	      *nvars = 0;
9004 	
9005 	      return SCIP_OKAY;
9006 	   }
9007 	
9008 	   /* allocate temporary memory */
9009 	   SCIP_CALL( SCIPallocBufferArray(scip, &linconsvars, nlinconsvars) );
9010 	   SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinconsvars) );
9011 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nlinconsvars) );
9012 	
9013 	   /* get variables and coefficient of linear constraint */
9014 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, linconsvars, NULL, &nlinconsvars) );
9015 	
9016 	   /* calculate all non-artificial linear variables and all artificial and-resultants which will be ordered like the
9017 	    * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
9018 	    * afterwards
9019 	    */
9020 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, linconsvars, NULL, nlinconsvars, linvars, NULL, &nlinvars,
9021 	         andress, NULL, NULL, &nandress) );
9022 	   assert(nlinconsvars == nlinvars + nandress);
9023 	
9024 	   *nvars = nlinvars;
9025 	
9026 	   if( nandress == 0 )
9027 	      goto TERMINATE;
9028 	
9029 	   assert(andress != NULL);
9030 	
9031 	   /* get constraint handler data */
9032 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
9033 	   assert(conshdlrdata != NULL);
9034 	   assert(conshdlrdata->hashmap != NULL);
9035 	
9036 	   transformed = SCIPconsIsTransformed(cons);
9037 	
9038 	   for( r = nandress - 1; r >= 0; --r )
9039 	   {
9040 	      SCIP_CONS* andcons;
9041 	
9042 	      assert(andress[r] != NULL);
9043 	
9044 	      consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[r]);
9045 	
9046 	      assert(consanddata != NULL);
9047 	      assert(consanddata->istransformed);
9048 	
9049 	      if( transformed )
9050 	         andcons = consanddata->cons;
9051 	      else
9052 	         andcons = consanddata->origcons;
9053 	
9054 	      assert(andcons != NULL);
9055 	
9056 	      if( SCIPconsIsDeleted(andcons) )
9057 	      {
9058 		 /* only add one for the resultant */
9059 		 ++(*nvars);
9060 	      }
9061 	      else
9062 	      {
9063 		 /* add all and-operands and one for the resultant */
9064 		 *nvars += SCIPgetNVarsAnd(scip, andcons) + 1;
9065 	      }
9066 	   }
9067 	
9068 	 TERMINATE:
9069 	   /* free temporary memory */
9070 	   SCIPfreeBufferArray(scip, &andress);
9071 	   SCIPfreeBufferArray(scip, &linvars);
9072 	   SCIPfreeBufferArray(scip, &linconsvars);
9073 	
9074 	   return SCIP_OKAY;
9075 	}
9076 	
9077 	/*
9078 	 * constraint specific interface methods
9079 	 */
9080 	
9081 	/** creates the handler for pseudoboolean constraints and includes it in SCIP */
9082 	SCIP_RETCODE SCIPincludeConshdlrPseudoboolean(
9083 	   SCIP*                 scip                /**< SCIP data structure */
9084 	   )
9085 	{
9086 	   SCIP_CONSHDLR* conshdlr;
9087 	   SCIP_CONSHDLRDATA* conshdlrdata;
9088 	
9089 	   /* create pseudoboolean constraint handler data */
9090 	   SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata) );
9091 	
9092 	   /* include constraint handler */
9093 	   SCIP_CALL( SCIPincludeConshdlrBasic(scip, &conshdlr, CONSHDLR_NAME, CONSHDLR_DESC,
9094 	         CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY, CONSHDLR_EAGERFREQ, CONSHDLR_NEEDSCONS,
9095 	         consEnfolpPseudoboolean, consEnfopsPseudoboolean, consCheckPseudoboolean, consLockPseudoboolean,
9096 	         conshdlrdata) );
9097 	   assert(conshdlr != NULL);
9098 	
9099 	   /* set non-fundamental callbacks via specific setter functions */
9100 	   SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyPseudoboolean, consCopyPseudoboolean) );
9101 	   SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeletePseudoboolean) );
9102 	   SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreePseudoboolean) );
9103 	   SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsPseudoboolean) );
9104 	   SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsPseudoboolean) );
9105 	   SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitPseudoboolean) );
9106 	   SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitprePseudoboolean) );
9107 	   SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolPseudoboolean, CONSHDLR_MAXPREROUNDS,
9108 	         CONSHDLR_PRESOLTIMING) );
9109 	   SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintPseudoboolean) );
9110 	   SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransPseudoboolean) );
9111 	   SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxPseudoboolean) );
9112 	
9113 	   /* add pseudoboolean constraint handler parameters */
9114 	   SCIP_CALL( SCIPaddBoolParam(scip,
9115 	         "constraints/" CONSHDLR_NAME "/decomposenormal",
9116 	         "decompose all normal pseudo boolean constraint into a \"linear\" constraint and \"and\" constraints",
9117 	         &conshdlrdata->decomposenormalpbcons, TRUE, DEFAULT_DECOMPOSENORMALPBCONS, NULL, NULL) );
9118 	   SCIP_CALL( SCIPaddBoolParam(scip,
9119 	         "constraints/" CONSHDLR_NAME "/decomposeindicator",
9120 	         "decompose all indicator pseudo boolean constraint into a \"linear\" constraint and \"and\" constraints",
9121 	         &conshdlrdata->decomposeindicatorpbcons, TRUE, DEFAULT_DECOMPOSEINDICATORPBCONS, NULL, NULL) );
9122 	   SCIP_CALL( SCIPaddBoolParam(scip,
9123 	         "constraints/" CONSHDLR_NAME "/nlcseparate", "should the nonlinear constraints be separated during LP processing?",
9124 	         NULL, TRUE, DEFAULT_SEPARATENONLINEAR, NULL, NULL) );
9125 	   SCIP_CALL( SCIPaddBoolParam(scip,
9126 	         "constraints/" CONSHDLR_NAME "/nlcpropagate", "should the nonlinear constraints be propagated during node processing?",
9127 	         NULL, TRUE, DEFAULT_PROPAGATENONLINEAR, NULL, NULL) );
9128 	   SCIP_CALL( SCIPaddBoolParam(scip,
9129 	         "constraints/" CONSHDLR_NAME "/nlcremovable", "should the nonlinear constraints be removable?",
9130 	         NULL, TRUE, DEFAULT_REMOVABLENONLINEAR, NULL, NULL) );
9131 	
9132 	#ifdef NONLINCONSUPGD_PRIORITY
9133 	   /* include the quadratic constraint upgrade in the nonlinear constraint handler */
9134 	   SCIP_CALL( SCIPincludeNonlinconsUpgrade(scip, nonlinconsUpgdPseudoboolean, NULL, NONLINCONSUPGD_PRIORITY, TRUE, CONSHDLR_NAME) );
9135 	#endif
9136 	
9137 	   return SCIP_OKAY;
9138 	}
9139 	
9140 	/** creates and captures a pseudoboolean constraint, with given linear and and-constraints
9141 	 *
9142 	 *  @note intvar must currently be NULL
9143 	 */
9144 	SCIP_RETCODE SCIPcreateConsPseudobooleanWithConss(
9145 	   SCIP*                 scip,               /**< SCIP data structure */
9146 	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
9147 	   const char*           name,               /**< name of constraint */
9148 	   SCIP_CONS*            lincons,            /**< associated linear constraint */
9149 	   SCIP_LINEARCONSTYPE   linconstype,        /**< linear constraint type of associated linear constraint */
9150 	   SCIP_CONS**           andconss,           /**< associated and-constraints */
9151 	   SCIP_Real*            andcoefs,           /**< associated coefficients of and-constraints */
9152 	   int                   nandconss,          /**< number of associated and-constraints */
9153 	   SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
9154 	   SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
9155 	   SCIP_Bool             issoftcons,         /**< is this a soft constraint */
9156 	   SCIP_VAR*             intvar,             /**< an artificial variable which was added only for the objective function,
9157 	                                              *   if this variable is not NULL this constraint (without this integer
9158 	                                              *   variable) describes the objective function */
9159 	   SCIP_Real             lhs,                /**< left hand side of constraint */
9160 	   SCIP_Real             rhs,                /**< right hand side of constraint */
9161 	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
9162 	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
9163 	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
9164 	                                              *   Usually set to TRUE. */
9165 	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
9166 	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
9167 	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
9168 	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
9169 	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
9170 	                                              *   Usually set to TRUE. */
9171 	   SCIP_Bool             local,              /**< is constraint only valid locally?
9172 	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
9173 	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
9174 	                                              *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
9175 	                                              *   adds coefficients to this constraint. */
9176 	   SCIP_Bool             dynamic,            /**< is constraint subject to aging?
9177 	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
9178 	                                              *   are seperated as constraints. */
9179 	   SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
9180 	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
9181 	   SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
9182 	                                              *   if it may be moved to a more global node?
9183 	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
9184 	   )
9185 	{
9186 	   CONSANDDATA* newdata;
9187 	   CONSANDDATA* tmpdata;
9188 	   SCIP_CONSHDLR* conshdlr;
9189 	   SCIP_CONSHDLRDATA* conshdlrdata;
9190 	   SCIP_CONSDATA* consdata;
9191 	   SCIP_VAR** vars;
9192 	   SCIP_VAR* res;
9193 	   SCIP_Bool memisinvalid;
9194 	   SCIP_Bool transformed;
9195 	   int nvars;
9196 	   int c;
9197 	
9198 	   assert(scip != NULL);
9199 	   assert(cons != NULL);
9200 	   assert(lincons != NULL);
9201 	   assert(linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
9202 	   assert(andconss != NULL);
9203 	   assert(andcoefs != NULL);
9204 	   assert(nandconss >= 1);
9205 	   assert(issoftcons == (indvar != NULL));
9206 	
9207 	   if( intvar != NULL )
9208 	   {
9209 	      /* FIXME should work or really be removed */
9210 	      SCIPerrorMessage("intvar currently not supported by pseudo boolean constraint handler\n");
9211 	      return SCIP_INVALIDDATA;
9212 	   }
9213 	
9214 	   /* find the pseudoboolean constraint handler */
9215 	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
9216 	   if( conshdlr == NULL )
9217 	   {
9218 	      SCIPerrorMessage("pseudo boolean constraint handler not found\n");
9219 	      return SCIP_PLUGINNOTFOUND;
9220 	   }
9221 	
9222 	   /* get constraint handler data */
9223 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
9224 	   assert(conshdlrdata != NULL);
9225 	
9226 	   /* initial hashmap and -table */
9227 	   SCIP_CALL( inithashmapandtable(scip, &conshdlrdata) );
9228 	
9229 	   assert(conshdlrdata->hashmap != NULL);
9230 	   assert(conshdlrdata->hashtable != NULL);
9231 	   assert(conshdlrdata->allconsanddatas != NULL);
9232 	   assert(conshdlrdata->nallconsanddatas <= conshdlrdata->sallconsanddatas);
9233 	
9234 	   memisinvalid = TRUE;
9235 	   newdata = NULL;
9236 	
9237 	   transformed = SCIPconsIsTransformed(lincons);
9238 	
9239 	   /* create hash map and hash table entries */
9240 	   for( c = nandconss - 1; c >= 0; --c )
9241 	   {
9242 	      assert(andconss[c] != NULL);
9243 	      res = SCIPgetResultantAnd(scip, andconss[c]);
9244 	      vars = SCIPgetVarsAnd(scip, andconss[c]);
9245 	      nvars = SCIPgetNVarsAnd(scip, andconss[c]);
9246 	      assert(vars != NULL && nvars > 0);
9247 	      assert(res != NULL);
9248 	
9249 	      /* stop if the constraint has 0 variables or an error occurred (coverity issue) */
9250 	      if( nvars <= 0 )
9251 	         continue;
9252 	
9253 	      /* if allocated memory in this for loop was already used, allocate a new block, otherwise we only need to copy the variables */
9254 	      if( memisinvalid )
9255 	      {
9256 	         /* allocate memory for a possible new consanddata object */
9257 	         SCIP_CALL( SCIPallocBlockMemory(scip, &newdata) );
9258 	         SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(newdata->vars), vars, nvars) );
9259 	         newdata->svars = nvars;
9260 	         newdata->newvars = NULL;
9261 	         newdata->nnewvars = 0;
9262 	         newdata->snewvars = 0;
9263 	         newdata->istransformed = transformed;
9264 	         newdata->isoriginal = !transformed;
9265 	         newdata->noriguses = 0;
9266 	         newdata->nuses = 0;
9267 	         newdata->cons = NULL;
9268 	         newdata->origcons = NULL;
9269 	      }
9270 	      else
9271 	      {
9272 	         assert(newdata != NULL);
9273 	         /* resize variable array if necessary */
9274 	         if( newdata->svars < nvars )
9275 	         {
9276 	            SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(newdata->vars), &(newdata->svars), nvars) );
9277 	         }
9278 	
9279 	         /* copy variables in already allocated array */
9280 	         BMScopyMemoryArray(newdata->vars, vars, nvars);
9281 	      }
9282 	
9283 	      /* sort variables */
9284 	      SCIPsortPtr((void**)(newdata->vars), SCIPvarComp, nvars);
9285 	
9286 	      newdata->nvars = nvars;
9287 	      assert(newdata->vars != NULL && newdata->nvars > 0);
9288 	
9289 	      if( SCIPconsIsTransformed(andconss[c]) )
9290 	      {
9291 	         int v;
9292 	
9293 	         /* either all constraints are transformed or none */
9294 	         assert(transformed);
9295 	         newdata->cons = andconss[c];
9296 	
9297 	         /* capture all variables */
9298 	         for( v = newdata->nvars - 1; v >= 0; --v )
9299 	         {
9300 	            SCIP_CALL( SCIPcaptureVar(scip, newdata->vars[v]) ); /*lint !e613*/
9301 	         }
9302 	      }
9303 	      else
9304 	      {
9305 	         /* either all constraints are transformed or none */
9306 	         assert(!transformed);
9307 	         newdata->origcons = andconss[c];
9308 	      }
9309 	
9310 	      /* get constraint from current hash table with same variables as andconss[c] */
9311 	      tmpdata = (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)newdata));
9312 	      assert(tmpdata == NULL || tmpdata->cons != NULL || tmpdata->origcons != NULL);
9313 	
9314 	      if( tmpdata == NULL || (tmpdata->cons != andconss[c] && tmpdata->origcons != andconss[c]))
9315 	      {
9316 	         if( tmpdata != NULL && (tmpdata->cons != NULL || tmpdata->origcons != NULL) )
9317 	         {
9318 	            SCIPwarningMessage(scip, "Another and-constraint with the same variables but different and-resultant is added to the global and-constraint hashtable of pseudoboolean constraint handler.\n");
9319 	         }
9320 	
9321 	         /* resize data for all and-constraints if necessary */
9322 	         if( conshdlrdata->nallconsanddatas == conshdlrdata->sallconsanddatas )
9323 	         {
9324 	            SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(conshdlrdata->allconsanddatas), &(conshdlrdata->sallconsanddatas), SCIPcalcMemGrowSize(scip, conshdlrdata->sallconsanddatas + 1)) );
9325 	         }
9326 	
9327 	         conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas] = newdata;
9328 	         ++(conshdlrdata->nallconsanddatas);
9329 	
9330 	         /* no such and-constraint in current hash table: insert the new object into hash table */
9331 	         SCIP_CALL( SCIPhashtableInsert(conshdlrdata->hashtable, (void*)newdata) );
9332 	
9333 	         /* if newdata object was new we want to allocate new memory in next loop iteration */
9334 	         memisinvalid = TRUE;
9335 	         assert(!SCIPhashmapExists(conshdlrdata->hashmap, (void*)res));
9336 	
9337 	         /* capture and-constraint */
9338 	         if( transformed )
9339 	         {
9340 	            SCIP_CALL( SCIPcaptureCons(scip, newdata->cons) );
9341 	
9342 	            /* initialize usage of data object */
9343 	            newdata->nuses = 1;
9344 	         }
9345 	         else
9346 	         {
9347 	            SCIP_CALL( SCIPcaptureCons(scip, newdata->origcons) );
9348 	
9349 	            /* initialize usage of data object */
9350 	            newdata->noriguses = 1;
9351 	         }
9352 	
9353 	         /* insert new mapping */
9354 	         assert(!SCIPhashmapExists(conshdlrdata->hashmap, (void*)res));
9355 	         SCIP_CALL( SCIPhashmapInsert(conshdlrdata->hashmap, (void*)res, (void*)newdata) );
9356 	      }
9357 	      else
9358 	      {
9359 	         assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)res));
9360 	         memisinvalid = FALSE;
9361 	
9362 	         if( transformed )
9363 	         {
9364 	            assert(tmpdata->nuses > 0);
9365 	
9366 	            /* increase usage of data object */
9367 	            ++(tmpdata->nuses);
9368 	         }
9369 	         else
9370 	         {
9371 	            assert(tmpdata->noriguses > 0);
9372 	
9373 	            /* increase usage of data object */
9374 	            ++(tmpdata->noriguses);
9375 	         }
9376 	      }
9377 	   }
9378 	
9379 	   if( !memisinvalid )
9380 	   {
9381 	      assert(newdata != NULL);
9382 	
9383 	      /* free temporary memory */
9384 	      SCIPfreeBlockMemoryArray(scip, &(newdata->vars), newdata->svars);
9385 	      SCIPfreeBlockMemory(scip, &newdata);
9386 	   }
9387 	
9388 	   /* adjust right hand side */
9389 	   if( SCIPisInfinity(scip, rhs) )
9390 	      rhs = SCIPinfinity(scip);
9391 	   else if( SCIPisInfinity(scip, -rhs) )
9392 	      rhs = -SCIPinfinity(scip);
9393 	
9394 	   /* capture linear constraint */
9395 	   SCIP_CALL( SCIPcaptureCons(scip, lincons) );
9396 	
9397 	   /* todo: make the constraint upgrade flag global, now it works only for the common linear constraint */
9398 	   /* mark linear constraint not to be upgraded - otherwise we loose control over it */
9399 	   SCIPconsAddUpgradeLocks(lincons, 1);
9400 	
9401 	   /* create constraint data */
9402 	   /* checking for and-constraints will be FALSE, we check all information in this constraint handler */
9403 	   SCIP_CALL( consdataCreate(scip, conshdlr, &consdata, lincons, linconstype, andconss, andcoefs, NULL, nandconss,
9404 	         indvar, weight, issoftcons, intvar, lhs, rhs, check, FALSE) );
9405 	   assert(consdata != NULL);
9406 	
9407 	   /* create constraint */
9408 	   SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
9409 	         local, modifiable, dynamic, removable, stickingatnode) );
9410 	
9411 	   return SCIP_OKAY;
9412 	}
9413 	
9414 	/** creates and captures a pseudoboolean constraint
9415 	 *
9416 	 *  @note linear and nonlinear terms can be added using SCIPaddCoefPseudoboolean() and SCIPaddTermPseudoboolean(),
9417 	 *        respectively
9418 	 *
9419 	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
9420 	 *
9421 	 *  @note intvar must currently be NULL
9422 	 */
9423 	SCIP_RETCODE SCIPcreateConsPseudoboolean(
9424 	   SCIP*                 scip,               /**< SCIP data structure */
9425 	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
9426 	   const char*           name,               /**< name of constraint */
9427 	   SCIP_VAR**            linvars,            /**< variables of the linear part, or NULL */
9428 	   int                   nlinvars,           /**< number of variables of the linear part */
9429 	   SCIP_Real*            linvals,            /**< coefficients of linear part, or NULL */
9430 	   SCIP_VAR***           terms,              /**< nonlinear terms of variables, or NULL */
9431 	   int                   nterms,             /**< number of terms of variables of nonlinear term */
9432 	   int*                  ntermvars,          /**< number of variables in nonlinear terms, or NULL */
9433 	   SCIP_Real*            termvals,           /**< coefficients of nonlinear parts, or NULL */
9434 	   SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
9435 	   SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
9436 	   SCIP_Bool             issoftcons,         /**< is this a soft constraint */
9437 	   SCIP_VAR*             intvar,             /**< an artificial variable which was added only for the objective function,
9438 	                                              *   if this variable is not NULL this constraint (without this integer
9439 	                                              *   variable) describes the objective function */
9440 	   SCIP_Real             lhs,                /**< left hand side of constraint */
9441 	   SCIP_Real             rhs,                /**< right hand side of constraint */
9442 	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
9443 	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
9444 	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
9445 	                                              *   Usually set to TRUE. */
9446 	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
9447 	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
9448 	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
9449 	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
9450 	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
9451 	                                              *   Usually set to TRUE. */
9452 	   SCIP_Bool             local,              /**< is constraint only valid locally?
9453 	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
9454 	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
9455 	                                              *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
9456 	                                              *   adds coefficients to this constraint. */
9457 	   SCIP_Bool             dynamic,            /**< is constraint subject to aging?
9458 	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
9459 	                                              *   are separated as constraints. */
9460 	   SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
9461 	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
9462 	   SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
9463 	                                              *   if it may be moved to a more global node?
9464 	                                              *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
9465 	   )
9466 	{
9467 	   SCIP_CONSHDLRDATA* conshdlrdata;
9468 	   SCIP_CONSHDLR* conshdlr;
9469 	   SCIP_CONSDATA* consdata;
9470 	   SCIP_VAR** andress;
9471 	   SCIP_CONS** andconss;
9472 	   SCIP_Real* andcoefs;
9473 	   SCIP_Bool* andnegs;
9474 	   int nandconss;
9475 	   SCIP_CONS* lincons;
9476 	   SCIP_LINEARCONSTYPE linconstype;
9477 	   int c;
9478 	
9479 	   assert(scip != NULL);
9480 	   assert(cons != NULL);
9481 	   assert(nlinvars == 0 || (linvars != NULL && linvals != NULL));
9482 	   assert(nterms == 0 || (terms != NULL && termvals != NULL && ntermvars != NULL));
9483 	   assert(issoftcons == (indvar != NULL));
9484 	
9485 	   if( intvar != NULL )
9486 	   {
9487 	      /* FIXME should work or really be removed */
9488 	      SCIPerrorMessage("intvar currently not supported by pseudo boolean constraint handler\n");
9489 	      return SCIP_INVALIDDATA;
9490 	   }
9491 	
9492 	   /* find the pseudoboolean constraint handler */
9493 	   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
9494 	   if( conshdlr == NULL )
9495 	   {
9496 	      SCIPerrorMessage("pseudo boolean constraint handler not found\n");
9497 	      return SCIP_PLUGINNOTFOUND;
9498 	   }
9499 	
9500 	#if USEINDICATOR == TRUE
9501 	   if( issoftcons && modifiable )
9502 	   {
9503 	      SCIPerrorMessage("Indicator constraint handler can't work with modifiable constraints\n");
9504 	      return SCIP_INVALIDDATA;
9505 	   }
9506 	#endif
9507 	
9508 	   /* get constraint handler data */
9509 	   conshdlrdata = SCIPconshdlrGetData(conshdlr);
9510 	   assert(conshdlrdata != NULL);
9511 	
9512 	   /* initial hashmap and -table */
9513 	   SCIP_CALL( inithashmapandtable(scip, &conshdlrdata) );
9514 	
9515 	   /* get temporary memory */
9516 	   SCIP_CALL( SCIPallocBufferArray(scip, &andconss, nterms) );
9517 	   SCIP_CALL( SCIPallocBufferArray(scip, &andress, nterms) );
9518 	   SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, nterms) );
9519 	   SCIP_CALL( SCIPallocBufferArray(scip, &andnegs, nterms) );
9520 	
9521 	   nandconss = 0;
9522 	   /* create and-constraints */
9523 	   SCIP_CALL( createAndAddAnds(scip, conshdlr, terms, termvals, nterms, ntermvars,
9524 	         initial, enforce, check, local, modifiable, dynamic, stickingatnode,
9525 	         andconss, andcoefs, andnegs, &nandconss) );
9526 	   assert(nterms >= nandconss);
9527 	
9528 	   /* get all and-resultants for linear constraint */
9529 	   for( c = nandconss - 1; c >= 0; --c )
9530 	   {
9531 	      assert(andconss[c] != NULL);
9532 	      andress[c] = SCIPgetResultantAnd(scip, andconss[c]);
9533 	   }
9534 	
9535 	   linconstype = SCIP_LINEARCONSTYPE_INVALIDCONS;
9536 	
9537 	   /* adjust right hand side */
9538 	   if( SCIPisInfinity(scip, rhs) )
9539 	      rhs = SCIPinfinity(scip);
9540 	   else if( SCIPisInfinity(scip, -rhs) )
9541 	      rhs = -SCIPinfinity(scip);
9542 	
9543 	   /* create and add linear constraint */
9544 	   /* checking for original linear constraint will be FALSE, transformed linear constraints get the check flag like this
9545 	    * pseudoboolean constraint, in this constraint handler we only will check all and-constraints
9546 	    */
9547 	   SCIP_CALL( createAndAddLinearCons(scip, conshdlr, linvars, nlinvars, linvals, andress, nandconss, andcoefs, andnegs,
9548 	         &lhs, &rhs, initial, separate, enforce, FALSE/*check*/, propagate, local, modifiable, dynamic, removable,
9549 	         stickingatnode, &lincons, &linconstype) );
9550 	   assert(lincons != NULL);
9551 	   assert(linconstype > SCIP_LINEARCONSTYPE_INVALIDCONS);
9552 	
9553 	   /* create constraint data */
9554 	   /* checking for and-constraints will be FALSE, we check all information in this constraint handler */
9555 	   SCIP_CALL( consdataCreate(scip, conshdlr, &consdata, lincons, linconstype, andconss, andcoefs, andnegs, nandconss,
9556 	         indvar, weight, issoftcons, intvar, lhs, rhs, check, FALSE) );
9557 	   assert(consdata != NULL);
9558 	
9559 	   /* free temporary memory */
9560 	   SCIPfreeBufferArray(scip, &andnegs);
9561 	   SCIPfreeBufferArray(scip, &andcoefs);
9562 	   SCIPfreeBufferArray(scip, &andress);
9563 	   SCIPfreeBufferArray(scip, &andconss);
9564 	
9565 	   /* create constraint */
9566 	   SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
9567 	         local, modifiable, dynamic, removable, stickingatnode) );
9568 	
9569 	   return SCIP_OKAY;
9570 	}
9571 	
9572 	/** creates and captures a pseudoboolean constraint
9573 	 *  in its most basic variant, i. e., with all constraint flags set to their default values
9574 	 *
9575 	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
9576 	 *
9577 	 *  @note intvar must currently be NULL
9578 	 */
9579 	SCIP_RETCODE SCIPcreateConsBasicPseudoboolean(
9580 	   SCIP*                 scip,               /**< SCIP data structure */
9581 	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
9582 	   const char*           name,               /**< name of constraint */
9583 	   SCIP_VAR**            linvars,            /**< variables of the linear part, or NULL */
9584 	   int                   nlinvars,           /**< number of variables of the linear part */
9585 	   SCIP_Real*            linvals,            /**< coefficients of linear part, or NULL */
9586 	   SCIP_VAR***           terms,              /**< nonlinear terms of variables, or NULL */
9587 	   int                   nterms,             /**< number of terms of variables of nonlinear term */
9588 	   int*                  ntermvars,          /**< number of variables in nonlinear terms, or NULL */
9589 	   SCIP_Real*            termvals,           /**< coefficients of nonlinear parts, or NULL */
9590 	   SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
9591 	   SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
9592 	   SCIP_Bool             issoftcons,         /**< is this a soft constraint */
9593 	   SCIP_VAR*             intvar,             /**< a artificial variable which was added only for the objective function,
9594 	                                              *   if this variable is not NULL this constraint (without this integer
9595 	                                              *   variable) describes the objective function */
9596 	   SCIP_Real             lhs,                /**< left hand side of constraint */
9597 	   SCIP_Real             rhs                 /**< right hand side of constraint */
9598 	   )
9599 	{
9600 	   SCIP_CALL( SCIPcreateConsPseudoboolean(scip, cons, name, linvars, nlinvars, linvals,
9601 	         terms, nterms, ntermvars, termvals, indvar, weight, issoftcons, intvar, lhs, rhs,
9602 	         TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
9603 	
9604 	   return SCIP_OKAY;
9605 	}
9606 	
9607 	/** adds a variable to the pseudo boolean constraint (if it is not zero)
9608 	 *
9609 	 * @note  you can only add a coefficient if the special type of linear constraint won't changed
9610 	 *
9611 	 * @todo  if adding a coefficient would change the type of the special linear constraint, we need to erase it and
9612 	 *         create a new linear constraint
9613 	 */
9614 	SCIP_RETCODE SCIPaddCoefPseudoboolean(
9615 	   SCIP*const            scip,               /**< SCIP data structure */
9616 	   SCIP_CONS*const       cons,               /**< constraint data */
9617 	   SCIP_VAR*const        var,                /**< variable of constraint entry */
9618 	   SCIP_Real const       val                 /**< coefficient of constraint entry */
9619 	   )
9620 	{
9621 	   SCIP_CONSDATA* consdata;
9622 	
9623 	   assert(scip != NULL);
9624 	   assert(cons != NULL);
9625 	   assert(var != NULL);
9626 	
9627 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9628 	   {
9629 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9630 	      SCIPABORT();
9631 	      return SCIP_INVALIDDATA; /*lint !e527*/
9632 	   }
9633 	
9634 	   if( SCIPisZero(scip, val) )
9635 	      return SCIP_OKAY;
9636 	
9637 	   consdata = SCIPconsGetData(cons);
9638 	   assert(consdata != NULL);
9639 	
9640 	   switch( consdata->linconstype )
9641 	   {
9642 	   case SCIP_LINEARCONSTYPE_LINEAR:
9643 	      SCIP_CALL( SCIPaddCoefLinear(scip, consdata->lincons, var, val) );
9644 	      break;
9645 	   case SCIP_LINEARCONSTYPE_LOGICOR:
9646 	      if( !SCIPisEQ(scip, val, 1.0) )
9647 	         return SCIP_INVALIDDATA;
9648 	
9649 	      SCIP_CALL( SCIPaddCoefLogicor(scip, consdata->lincons, var) );
9650 	      break;
9651 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
9652 	      if( !SCIPisIntegral(scip, val) || !SCIPisPositive(scip, val) )
9653 	         return SCIP_INVALIDDATA;
9654 	
9655 	      SCIP_CALL( SCIPaddCoefKnapsack(scip, consdata->lincons, var, (SCIP_Longint) val) );
9656 	      break;
9657 	   case SCIP_LINEARCONSTYPE_SETPPC:
9658 	      if( !SCIPisEQ(scip, val, 1.0) )
9659 	         return SCIP_INVALIDDATA;
9660 	
9661 	      SCIP_CALL( SCIPaddCoefSetppc(scip, consdata->lincons, var) );
9662 	      break;
9663 	#ifdef WITHEQKNAPSACK
9664 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
9665 	      if( !SCIPisIntegral(scip, val) || !SCIPisPositive(scip, val) )
9666 	         return SCIP_INVALIDDATA;
9667 	
9668 	      SCIP_CALL( SCIPaddCoefEQKnapsack(scip, consdata->lincons, var, (SCIP_Longint) val) );
9669 	      break;
9670 	#endif
9671 	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
9672 	   default:
9673 	      SCIPerrorMessage("unknown linear constraint type\n");
9674 	      return SCIP_INVALIDDATA;
9675 	   }
9676 	
9677 	   consdata->propagated = FALSE;
9678 	   consdata->presolved = FALSE;
9679 	   consdata->cliquesadded = FALSE;
9680 	
9681 	   return SCIP_OKAY;
9682 	}
9683 	
9684 	/** adds nonlinear term to pseudo boolean constraint (if it is not zero)
9685 	 *
9686 	 * @note  you can only add a coefficient if the special type of linear constraint won't changed
9687 	 *
9688 	 * @todo if adding a coefficient would change the type of the special linear constraint, we need to erase it and
9689 	 *         create a new linear constraint
9690 	 */
9691 	SCIP_RETCODE SCIPaddTermPseudoboolean(
9692 	   SCIP*const            scip,               /**< SCIP data structure */
9693 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
9694 	   SCIP_VAR**const       vars,               /**< variables of the nonlinear term */
9695 	   int const             nvars,              /**< number of variables of the nonlinear term */
9696 	   SCIP_Real const       val                 /**< coefficient of constraint entry */
9697 	   )
9698 	{
9699 	   assert(scip != NULL);
9700 	   assert(cons != NULL);
9701 	   assert(nvars == 0 || vars != NULL);
9702 	
9703 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9704 	   {
9705 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9706 	      SCIPABORT();
9707 	      return SCIP_INVALIDDATA; /*lint !e527*/
9708 	   }
9709 	
9710 	   SCIP_CALL( addCoefTerm(scip, cons, vars, nvars, val) );
9711 	
9712 	   return SCIP_OKAY;
9713 	}
9714 	
9715 	/** gets indicator variable of pseudoboolean constraint, or NULL if there is no */
9716 	SCIP_VAR* SCIPgetIndVarPseudoboolean(
9717 	   SCIP*const            scip,               /**< SCIP data structure */
9718 	   SCIP_CONS*const       cons                /**< constraint data */
9719 	   )
9720 	{
9721 	   SCIP_CONSDATA* consdata;
9722 	
9723 	   assert(scip != NULL);
9724 	   assert(cons != NULL);
9725 	
9726 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9727 	   {
9728 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9729 	      SCIPABORT();
9730 	      return NULL; /*lint !e527*/
9731 	   }
9732 	
9733 	   consdata = SCIPconsGetData(cons);
9734 	   assert(consdata != NULL);
9735 	
9736 	   return consdata->indvar;
9737 	}
9738 	
9739 	/** gets linear constraint of pseudoboolean constraint */
9740 	SCIP_CONS* SCIPgetLinearConsPseudoboolean(
9741 	   SCIP*const            scip,               /**< SCIP data structure */
9742 	   SCIP_CONS*const       cons                /**< constraint data */
9743 	   )
9744 	{
9745 	   SCIP_CONSDATA* consdata;
9746 	
9747 	   assert(scip != NULL);
9748 	   assert(cons != NULL);
9749 	
9750 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9751 	   {
9752 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9753 	      SCIPABORT();
9754 	      return NULL; /*lint !e527*/
9755 	   }
9756 	
9757 	   consdata = SCIPconsGetData(cons);
9758 	   assert(consdata != NULL);
9759 	
9760 	   return consdata->lincons;
9761 	}
9762 	
9763 	/** gets type of linear constraint of pseudoboolean constraint */
9764 	SCIP_LINEARCONSTYPE SCIPgetLinearConsTypePseudoboolean(
9765 	   SCIP*const            scip,               /**< SCIP data structure */
9766 	   SCIP_CONS*const       cons                /**< constraint data */
9767 	   )
9768 	{
9769 	   SCIP_CONSDATA* consdata;
9770 	
9771 	   assert(scip != NULL);
9772 	   assert(cons != NULL);
9773 	
9774 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9775 	   {
9776 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9777 	      SCIPABORT();
9778 	      return SCIP_LINEARCONSTYPE_INVALIDCONS; /*lint !e527*/
9779 	   }
9780 	
9781 	   consdata = SCIPconsGetData(cons);
9782 	   assert(consdata != NULL);
9783 	
9784 	   return consdata->linconstype;
9785 	}
9786 	
9787 	/** gets number of linear variables without artificial terms variables of pseudoboolean constraint */
9788 	int SCIPgetNLinVarsWithoutAndPseudoboolean(
9789 	   SCIP*const            scip,               /**< SCIP data structure */
9790 	   SCIP_CONS*const       cons                /**< pseudoboolean constraint */
9791 	   )
9792 	{
9793 	   SCIP_CONSDATA* consdata;
9794 	
9795 	   assert(scip != NULL);
9796 	   assert(cons != NULL);
9797 	
9798 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9799 	   {
9800 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9801 	      SCIPABORT();
9802 	      return -1;  /*lint !e527*/
9803 	   }
9804 	
9805 	   checkConsConsistency(scip, cons);
9806 	
9807 	   consdata = SCIPconsGetData(cons);
9808 	   assert(consdata != NULL);
9809 	
9810 	   return consdata->nlinvars;
9811 	}
9812 	
9813 	/** gets linear constraint of pseudoboolean constraint */
9814 	SCIP_RETCODE SCIPgetLinDatasWithoutAndPseudoboolean(
9815 	   SCIP*const            scip,               /**< SCIP data structure */
9816 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
9817 	   SCIP_VAR**const       linvars,            /**< array to store and-constraints */
9818 	   SCIP_Real*const       lincoefs,           /**< array to store and-coefficients */
9819 	   int*const             nlinvars            /**< pointer to store the required array size for and-constraints, have to
9820 	                                              *   be initialized with size of given array */
9821 	   )
9822 	{
9823 	   SCIP_CONSDATA* consdata;
9824 	   SCIP_VAR** vars;
9825 	   SCIP_Real* coefs;
9826 	   int nvars;
9827 	
9828 	   assert(scip != NULL);
9829 	   assert(cons != NULL);
9830 	   assert(nlinvars != NULL);
9831 	   assert(*nlinvars == 0 || linvars != NULL);
9832 	   assert(*nlinvars == 0 || lincoefs != NULL);
9833 	
9834 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9835 	   {
9836 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9837 	      SCIPABORT();
9838 	      return SCIP_INVALIDDATA; /*lint !e527*/
9839 	   }
9840 	
9841 	   consdata = SCIPconsGetData(cons);
9842 	   assert(consdata != NULL);
9843 	
9844 	   checkConsConsistency(scip, cons);
9845 	
9846 	   if( *nlinvars < consdata->nlinvars )
9847 	   {
9848 	      *nlinvars = consdata->nlinvars;
9849 	      return SCIP_OKAY;
9850 	   }
9851 	
9852 	   /* gets number of variables in linear constraint */
9853 	   SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &nvars) );
9854 	
9855 	   /* allocate temporary memory */
9856 	   SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
9857 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
9858 	
9859 	   /* get variables and coefficient of linear constraint */
9860 	   SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
9861 	
9862 	   /* calculate all not artificial linear variables */
9863 	   SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, nlinvars, NULL, NULL, NULL, NULL) );
9864 	
9865 	   /* free temporary memory */
9866 	   SCIPfreeBufferArray(scip, &coefs);
9867 	   SCIPfreeBufferArray(scip, &vars);
9868 	
9869 	   return SCIP_OKAY;
9870 	}
9871 	
9872 	
9873 	/** gets and-constraints of pseudoboolean constraint */
9874 	SCIP_RETCODE SCIPgetAndDatasPseudoboolean(
9875 	   SCIP*const            scip,               /**< SCIP data structure */
9876 	   SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
9877 	   SCIP_CONS**const      andconss,           /**< array to store and-constraints */
9878 	   SCIP_Real*const       andcoefs,           /**< array to store and-coefficients */
9879 	   int*const             nandconss           /**< pointer to store the required array size for and-constraints, have to
9880 	                                              *   be initialized with size of given array */
9881 	   )
9882 	{
9883 	   SCIP_CONSDATA* consdata;
9884 	   SCIP_Bool isorig;
9885 	   int c;
9886 	
9887 	   assert(scip != NULL);
9888 	   assert(cons != NULL);
9889 	   assert(nandconss != NULL);
9890 	   assert(*nandconss == 0 || andconss != NULL);
9891 	   assert(*nandconss == 0 || andcoefs != NULL);
9892 	
9893 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9894 	   {
9895 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9896 	      SCIPABORT();
9897 	      return SCIP_INVALIDDATA; /*lint !e527*/
9898 	   }
9899 	
9900 	   consdata = SCIPconsGetData(cons);
9901 	   assert(consdata != NULL);
9902 	
9903 	   checkConsConsistency(scip, cons);
9904 	
9905 	   if( *nandconss < consdata->nconsanddatas )
9906 	   {
9907 	      *nandconss = consdata->nconsanddatas;
9908 	      return SCIP_OKAY;
9909 	   }
9910 	
9911 	   *nandconss = consdata->nconsanddatas;
9912 	   assert(*nandconss == 0 || consdata->consanddatas != NULL);
9913 	
9914 	   isorig = SCIPconsIsOriginal(cons);
9915 	
9916 	   for( c = *nandconss - 1; c >= 0; --c )
9917 	   {
9918 	      assert(consdata->consanddatas[c] != NULL);
9919 	      assert(consdata->consanddatas[c]->istransformed ? (consdata->consanddatas[c]->cons != NULL) : TRUE);
9920 	      assert(consdata->consanddatas[c]->isoriginal ? (consdata->consanddatas[c]->origcons != NULL) : TRUE);
9921 	      assert(consdata->consanddatas[c]->cons != NULL || consdata->consanddatas[c]->origcons != NULL);
9922 	      assert(isorig ? consdata->consanddatas[c]->origcons != NULL : consdata->consanddatas[c]->cons != NULL);
9923 	
9924 	      andconss[c] = (isorig ? consdata->consanddatas[c]->origcons : consdata->consanddatas[c]->cons);
9925 	      assert(andconss[c] != NULL);
9926 	
9927 	      andcoefs[c] = consdata->andcoefs[c];
9928 	   }
9929 	
9930 	   return SCIP_OKAY;
9931 	}
9932 	
9933 	/** gets number of and constraints of pseudoboolean constraint */
9934 	int SCIPgetNAndsPseudoboolean(
9935 	   SCIP*const            scip,               /**< SCIP data structure */
9936 	   SCIP_CONS*const       cons                /**< constraint data */
9937 	   )
9938 	{
9939 	   SCIP_CONSDATA* consdata;
9940 	
9941 	   assert(scip != NULL);
9942 	   assert(cons != NULL);
9943 	
9944 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9945 	   {
9946 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9947 	      SCIPABORT();
9948 	      return -1;  /*lint !e527*/
9949 	   }
9950 	
9951 	   checkConsConsistency(scip, cons);
9952 	
9953 	   consdata = SCIPconsGetData(cons);
9954 	   assert(consdata != NULL);
9955 	
9956 	   return consdata->nconsanddatas;
9957 	}
9958 	
9959 	/** changes left hand side of pseudoboolean constraint
9960 	 *
9961 	 * @note you can only change the left hand side if the special type of linear constraint won't changed
9962 	 *
9963 	 * @todo if changing the left hand side would change the type of the special linear constraint, we need to erase it
9964 	 *       and create a new linear constraint
9965 	 */
9966 	SCIP_RETCODE SCIPchgLhsPseudoboolean(
9967 	   SCIP*const            scip,               /**< SCIP data structure */
9968 	   SCIP_CONS*const       cons,               /**< constraint data */
9969 	   SCIP_Real const       lhs                 /**< new left hand side */
9970 	   )
9971 	{
9972 	   SCIP_CONSDATA* consdata;
9973 	
9974 	   assert(scip != NULL);
9975 	   assert(cons != NULL);
9976 	
9977 	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
9978 	   {
9979 	      SCIPerrorMessage("constraint is not pseudo boolean\n");
9980 	      return SCIP_INVALIDDATA;
9981 	   }
9982 	
9983 	   checkConsConsistency(scip, cons);
9984 	
9985 	   consdata = SCIPconsGetData(cons);
9986 	   assert(consdata != NULL);
9987 	
9988 	   switch( consdata->linconstype )
9989 	   {
9990 	   case SCIP_LINEARCONSTYPE_LINEAR:
9991 	      SCIP_CALL( chgLhs(scip, cons, lhs) );
9992 	      break;
9993 	   case SCIP_LINEARCONSTYPE_LOGICOR:
9994 	   case SCIP_LINEARCONSTYPE_KNAPSACK:
9995 	   case SCIP_LINEARCONSTYPE_SETPPC:
9996 	#ifdef WITHEQKNAPSACK
9997 	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
9998 	#endif
9999 	      SCIPerrorMessage("changing left hand side only allowed on standard linear constraint \n");
10000	      return SCIP_INVALIDDATA;
10001	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
10002	   default:
10003	      SCIPerrorMessage("unknown linear constraint type\n");
10004	      return SCIP_INVALIDDATA;
10005	   }
10006	
10007	   return SCIP_OKAY;
10008	}
10009	
10010	/** changes right hand side of pseudoboolean constraint
10011	 *
10012	 * @note you can only change the right hand side if the special type of linear constraint won't changed
10013	 *
10014	 * @todo if changing the right hand side would change the type of the special linear constraint, we need to erase it
10015	 *       and create a new linear constraint
10016	 */
10017	SCIP_RETCODE SCIPchgRhsPseudoboolean(
10018	   SCIP*const            scip,               /**< SCIP data structure */
10019	   SCIP_CONS*const       cons,               /**< constraint data */
10020	   SCIP_Real const       rhs                 /**< new right hand side */
10021	   )
10022	{
10023	   SCIP_CONSDATA* consdata;
10024	
10025	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
10026	   {
10027	      SCIPerrorMessage("constraint is not pseudo boolean\n");
10028	      return SCIP_INVALIDDATA;
10029	   }
10030	
10031	   checkConsConsistency(scip, cons);
10032	
10033	   consdata = SCIPconsGetData(cons);
10034	   assert(consdata != NULL);
10035	
10036	   switch( consdata->linconstype )
10037	   {
10038	   case SCIP_LINEARCONSTYPE_LINEAR:
10039	      SCIP_CALL( chgRhs(scip, cons, rhs) );
10040	      break;
10041	   case SCIP_LINEARCONSTYPE_LOGICOR:
10042	   case SCIP_LINEARCONSTYPE_KNAPSACK:
10043	   case SCIP_LINEARCONSTYPE_SETPPC:
10044	#ifdef WITHEQKNAPSACK
10045	   case SCIP_LINEARCONSTYPE_EQKNAPSACK:
10046	#endif
10047	      SCIPerrorMessage("changing right hand side only allowed on standard linear constraint \n");
10048	      return SCIP_INVALIDDATA;
10049	   case SCIP_LINEARCONSTYPE_INVALIDCONS:
10050	   default:
10051	      SCIPerrorMessage("unknown linear constraint type\n");
10052	      return SCIP_INVALIDDATA;
10053	   }
10054	
10055	   return SCIP_OKAY;
10056	}
10057	
10058	/** get left hand side of pseudoboolean constraint */
10059	SCIP_Real SCIPgetLhsPseudoboolean(
10060	   SCIP*const            scip,               /**< SCIP data structure */
10061	   SCIP_CONS*const       cons                /**< pseudoboolean constraint */
10062	   )
10063	{
10064	   SCIP_CONSDATA* consdata;
10065	
10066	   assert(scip != NULL);
10067	
10068	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
10069	   {
10070	      SCIPerrorMessage("constraint is not pseudo boolean\n");
10071	      SCIPABORT();
10072	      return SCIP_INVALID; /*lint !e527*/
10073	   }
10074	
10075	   checkConsConsistency(scip, cons);
10076	
10077	   consdata = SCIPconsGetData(cons);
10078	   assert(consdata != NULL);
10079	
10080	   return consdata->lhs;
10081	}
10082	
10083	/** get right hand side of pseudoboolean constraint */
10084	SCIP_Real SCIPgetRhsPseudoboolean(
10085	   SCIP*const            scip,               /**< SCIP data structure */
10086	   SCIP_CONS*const       cons                /**< pseudoboolean constraint */
10087	   )
10088	{
10089	   SCIP_CONSDATA* consdata;
10090	
10091	   assert(scip != NULL);
10092	
10093	   if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
10094	   {
10095	      SCIPerrorMessage("constraint is not pseudo boolean\n");
10096	      SCIPABORT();
10097	      return SCIP_INVALID; /*lint !e527*/
10098	   }
10099	
10100	   checkConsConsistency(scip, cons);
10101	
10102	   consdata = SCIPconsGetData(cons);
10103	   assert(consdata != NULL);
10104	
10105	   return consdata->rhs;
10106	}
10107