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