Scippy

SCIP

Solving Constraint Integer Programs

cons.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2014 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons.c
17  * @brief methods for constraints and constraint handlers
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 #include <ctype.h>
27 
28 #include "scip/def.h"
29 #include "scip/set.h"
30 #include "scip/stat.h"
31 #include "scip/clock.h"
32 #include "scip/var.h"
33 #include "scip/prob.h"
34 #include "scip/tree.h"
35 #include "scip/sepastore.h"
36 #include "scip/cons.h"
37 #include "scip/branch.h"
38 #include "scip/pub_misc.h"
39 
40 #ifndef NDEBUG
41 #include "scip/struct_cons.h"
42 #endif
43 
44 
45 #define AGERESETAVG_INIT 1000.0 /**< initial value of the exponentially decaying weighted sum for ages */
46 #define AGERESETAVG_MIN 100.0 /**< minimal value to use for weighted sum of ages */
47 #define AGERESETAVG_DECAY 0.0005 /**< weight of a new addend in the exponentially decyaing sum */
48 #define AGERESETAVG_AGELIMIT 2.0 /**< in dynamic setting, a constraint is deleted if its age exceeds the
49  * average reset age by this factor */
50 #define AGERESETAVG_OBSOLETEAGE 1.8 /**< in dynamic setting, a constraint is marked obsolete if its age exceeds the
51  * average reset age by this factor */
52 
53 
54 /* #define CHECKCONSARRAYS */
55 
56 
57 /*
58  * dynamic memory arrays
59  */
60 
61 
62 /** resizes conss array to be able to store at least num constraints */
63 static
65  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
66  SCIP_SET* set, /**< global SCIP settings */
67  int num /**< minimal number of slots in array */
68  )
69 {
70  assert(conshdlr != NULL);
71  assert(set != NULL);
72 
73  if( num > conshdlr->consssize )
74  {
75  int newsize;
76 
77  newsize = SCIPsetCalcMemGrowSize(set, num);
78  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->conss, newsize) );
79  conshdlr->consssize = newsize;
80  }
81  assert(num <= conshdlr->consssize);
82 
83  return SCIP_OKAY;
84 }
85 
86 /** resizes initconss array to be able to store at least num constraints */
87 static
89  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
90  SCIP_SET* set, /**< global SCIP settings */
91  int num /**< minimal number of slots in array */
92  )
93 {
94  assert(conshdlr != NULL);
95  assert(set != NULL);
96 
97  if( num > conshdlr->initconsssize )
98  {
99  int newsize;
100 
101  newsize = SCIPsetCalcMemGrowSize(set, num);
102  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->initconss, newsize) );
103  conshdlr->initconsssize = newsize;
104  }
105  assert(num <= conshdlr->initconsssize);
106 
107  return SCIP_OKAY;
108 }
109 
110 /** resizes sepaconss array to be able to store at least num constraints */
111 static
113  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
114  SCIP_SET* set, /**< global SCIP settings */
115  int num /**< minimal number of slots in array */
116  )
117 {
118  assert(conshdlr != NULL);
119  assert(set != NULL);
120 
121  if( num > conshdlr->sepaconsssize )
122  {
123  int newsize;
124 
125  newsize = SCIPsetCalcMemGrowSize(set, num);
126  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->sepaconss, newsize) );
127  conshdlr->sepaconsssize = newsize;
128  }
129  assert(num <= conshdlr->sepaconsssize);
130 
131  return SCIP_OKAY;
132 }
133 
134 /** resizes enfoconss array to be able to store at least num constraints */
135 static
137  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
138  SCIP_SET* set, /**< global SCIP settings */
139  int num /**< minimal number of slots in array */
140  )
141 {
142  assert(conshdlr != NULL);
143  assert(set != NULL);
144 
145  if( num > conshdlr->enfoconsssize )
146  {
147  int newsize;
148 
149  newsize = SCIPsetCalcMemGrowSize(set, num);
150  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->enfoconss, newsize) );
151  conshdlr->enfoconsssize = newsize;
152  }
153  assert(num <= conshdlr->enfoconsssize);
154 
155  return SCIP_OKAY;
156 }
157 
158 /** resizes checkconss array to be able to store at least num constraints */
159 static
161  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
162  SCIP_SET* set, /**< global SCIP settings */
163  int num /**< minimal number of slots in array */
164  )
165 {
166  assert(conshdlr != NULL);
167  assert(set != NULL);
168 
169  if( num > conshdlr->checkconsssize )
170  {
171  int newsize;
172 
173  newsize = SCIPsetCalcMemGrowSize(set, num);
174  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->checkconss, newsize) );
175  conshdlr->checkconsssize = newsize;
176  }
177  assert(num <= conshdlr->checkconsssize);
178 
179  return SCIP_OKAY;
180 }
181 
182 /** resizes propconss array to be able to store at least num constraints */
183 static
185  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
186  SCIP_SET* set, /**< global SCIP settings */
187  int num /**< minimal number of slots in array */
188  )
189 {
190  assert(conshdlr != NULL);
191  assert(set != NULL);
192 
193  if( num > conshdlr->propconsssize )
194  {
195  int newsize;
196 
197  newsize = SCIPsetCalcMemGrowSize(set, num);
198  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->propconss, newsize) );
199  conshdlr->propconsssize = newsize;
200  }
201  assert(num <= conshdlr->propconsssize);
202 
203  return SCIP_OKAY;
204 }
205 
206 /** resizes updateconss array to be able to store at least num constraints */
207 static
209  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
210  SCIP_SET* set, /**< global SCIP settings */
211  int num /**< minimal number of slots in array */
212  )
213 {
214  assert(conshdlr != NULL);
215  assert(set != NULL);
216 
217  if( num > conshdlr->updateconsssize )
218  {
219  int newsize;
220 
221  newsize = SCIPsetCalcMemGrowSize(set, num);
222  SCIP_ALLOC( BMSreallocMemoryArray(&conshdlr->updateconss, newsize) );
223  conshdlr->updateconsssize = newsize;
224  }
225  assert(num <= conshdlr->updateconsssize);
226 
227  return SCIP_OKAY;
228 }
229 
230 
231 
232 
233 /*
234  * Constraint handler methods
235  */
236 
237 #define checkConssArrays(conshdlr) /**/
238 #ifndef NDEBUG
239 #ifdef CHECKCONSARRAYS
240 #undef checkConssArrays
241 /** sanity check for the constraint arrays of the constraint handler (only in debug mode) */
242 static
243 void checkConssArrays(
244  SCIP_CONSHDLR* conshdlr /**< constraint handler */
245  )
246 {
247  int c;
248 
249  assert(conshdlr != NULL);
250  assert(0 <= conshdlr->nactiveconss && conshdlr->nactiveconss <= conshdlr->nconss);
251 
252  for( c = 0; c < conshdlr->nconss; ++c )
253  {
254  assert(conshdlr->conss[c] != NULL);
255  assert(!conshdlr->conss[c]->original);
256  assert(conshdlr->conss[c]->active == (c < conshdlr->nactiveconss));
257  assert(conshdlr->conss[c]->consspos == c);
258  }
259 
260  for( c = 0; c < conshdlr->ninitconss; ++c )
261  {
262  assert(conshdlr->initconss[c] != NULL);
263  assert(!conshdlr->initconss[c]->original);
264  assert(c < conshdlr->ninitconsskept || conshdlr->initconss[c]->active);
265  assert(conshdlr->initconss[c]->initial);
266  }
267 
268  for( c = 0; c < conshdlr->nsepaconss; ++c )
269  {
270  assert(conshdlr->sepaconss[c] != NULL);
271  assert(!conshdlr->sepaconss[c]->original);
272  assert(conshdlr->sepaconss[c]->active);
273  assert(conshdlr->sepaconss[c]->separate);
274  assert(conshdlr->sepaconss[c]->sepaenabled);
275  assert(conshdlr->sepaconss[c]->obsolete == (c >= conshdlr->nusefulsepaconss));
276  }
277 
278  for( c = 0; c < conshdlr->nenfoconss; ++c )
279  {
280  assert(conshdlr->enfoconss[c] != NULL);
281  assert(!conshdlr->enfoconss[c]->original);
282  assert(conshdlr->enfoconss[c]->active);
283  assert(conshdlr->enfoconss[c]->enforce);
284  assert(conshdlr->enfoconss[c]->obsolete == (c >= conshdlr->nusefulenfoconss));
285  }
286 
287  for( c = 0; c < conshdlr->ncheckconss; ++c )
288  {
289  assert(conshdlr->checkconss[c] != NULL);
290  assert(!conshdlr->checkconss[c]->original);
291  assert(conshdlr->checkconss[c]->active);
292  assert(conshdlr->checkconss[c]->check);
293  assert(conshdlr->checkconss[c]->obsolete == (c >= conshdlr->nusefulcheckconss));
294  }
295 
296  for( c = 0; c < conshdlr->npropconss; ++c )
297  {
298  assert(conshdlr->propconss[c] != NULL);
299  assert(!conshdlr->propconss[c]->original);
300  assert(conshdlr->propconss[c]->active);
301  assert(conshdlr->propconss[c]->propagate);
302  assert(conshdlr->propconss[c]->propenabled);
303  assert(conshdlr->propconss[c]->markpropagate == (c < conshdlr->nmarkedpropconss));
304  assert(conshdlr->propconss[c]->markpropagate || (conshdlr->propconss[c]->obsolete == (c >= conshdlr->nusefulpropconss)));
305  }
306 }
307 #endif
308 #endif
309 
310 /** returns whether the constraint updates of the constraint handler are currently delayed */
311 static
313  SCIP_CONSHDLR* conshdlr /**< constraint handler */
314  )
315 {
316  return (conshdlr->delayupdatecount > 0);
317 }
318 
319 /** returns the exponentially decaying weighted age average for age resets */
320 static
322  SCIP_CONSHDLR* conshdlr /**< constraint handler */
323  )
324 {
325  assert(conshdlr != NULL);
326 
327  return MAX(conshdlr->ageresetavg, AGERESETAVG_MIN);
328 }
329 
330 /** updates the exponentially decaying weighted age average for age resets after a constraint age was reset */
331 static
333  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
334  SCIP_Real age /**< age of the constraint that is reset to zero */
335  )
336 {
337  assert(conshdlr != NULL);
338 
339  conshdlr->ageresetavg *= (1.0-AGERESETAVG_DECAY);
340  conshdlr->ageresetavg += AGERESETAVG_DECAY * age;
341 }
342 
343 /** returns whether the constraint's age exceeds the age limit */
344 static
346  SCIP_CONS* cons, /**< constraint to check */
347  SCIP_SET* set /**< global SCIP settings */
348  )
349 {
350  assert(cons != NULL);
351  assert(set != NULL);
352 
353  return (cons->dynamic
354  && ((set->cons_agelimit > 0 && cons->age > set->cons_agelimit)
355  || (set->cons_agelimit == 0 && cons->age > AGERESETAVG_AGELIMIT * conshdlrGetAgeresetavg(cons->conshdlr))));
356 }
357 
358 /** returns whether the constraint's age exceeds the obsolete age limit */
359 static
361  SCIP_CONS* cons, /**< constraint to check */
362  SCIP_SET* set /**< global SCIP settings */
363  )
364 {
365  assert(cons != NULL);
366  assert(set != NULL);
367 
368  return (cons->dynamic
369  && ((set->cons_obsoleteage > 0 && cons->age > set->cons_obsoleteage)
370  || (set->cons_obsoleteage == 0 && cons->age > AGERESETAVG_OBSOLETEAGE * conshdlrGetAgeresetavg(cons->conshdlr))));
371 }
372 
373 /** marks constraint to be obsolete; it will be moved to the last part of the constraint arrays, such that
374  * it is checked, enforced, separated, and propagated after the useful constraints
375  */
376 static
378  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
379  SCIP_CONS* cons /**< constraint to be marked obsolete */
380  )
381 {
382  SCIP_CONS* tmpcons;
383 
384  assert(conshdlr != NULL);
385  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
386  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
387  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
388  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
389  assert(cons != NULL);
390  assert(!cons->original);
391  assert(!cons->obsolete);
392  assert(!conshdlrAreUpdatesDelayed(conshdlr));
393 
394  cons->obsolete = TRUE;
395 
396  if( cons->active )
397  {
398  if( cons->check )
399  {
400  assert(0 <= cons->checkconsspos && cons->checkconsspos < conshdlr->nusefulcheckconss);
401 
402  /* switch the last useful (non-obsolete) check constraint with this constraint */
403  tmpcons = conshdlr->checkconss[conshdlr->nusefulcheckconss-1];
404  assert(tmpcons->checkconsspos == conshdlr->nusefulcheckconss-1);
405 
406  conshdlr->checkconss[conshdlr->nusefulcheckconss-1] = cons;
407  conshdlr->checkconss[cons->checkconsspos] = tmpcons;
408  tmpcons->checkconsspos = cons->checkconsspos;
409  cons->checkconsspos = conshdlr->nusefulcheckconss-1;
410 
411  conshdlr->nusefulcheckconss--;
412  }
413  }
414  if( cons->enabled )
415  {
416  if( cons->separate && cons->sepaenabled )
417  {
418  assert(0 <= cons->sepaconsspos && cons->sepaconsspos < conshdlr->nusefulsepaconss);
419 
420  if( cons->sepaconsspos < conshdlr->lastnusefulsepaconss )
421  conshdlr->lastnusefulsepaconss--;
422 
423  /* switch the last useful (non-obsolete) sepa constraint with this constraint */
424  tmpcons = conshdlr->sepaconss[conshdlr->nusefulsepaconss-1];
425  assert(tmpcons->sepaconsspos == conshdlr->nusefulsepaconss-1);
426 
427  conshdlr->sepaconss[conshdlr->nusefulsepaconss-1] = cons;
428  conshdlr->sepaconss[cons->sepaconsspos] = tmpcons;
429  tmpcons->sepaconsspos = cons->sepaconsspos;
430  cons->sepaconsspos = conshdlr->nusefulsepaconss-1;
431 
432  conshdlr->nusefulsepaconss--;
433  }
434  if( cons->enforce )
435  {
436  assert(0 <= cons->enfoconsspos && cons->enfoconsspos < conshdlr->nusefulenfoconss);
437 
438  if( cons->enfoconsspos < conshdlr->lastnusefulenfoconss )
439  conshdlr->lastnusefulenfoconss--;
440  else
441  {
442  /* the constraint that becomes obsolete is not yet enforced on the current solution:
443  * we have to make sure that it will be enforced the next time; this is not done, if the current
444  * solution was already enforced and only enforcement on the additional constraints is performed
445  * (because in this case, only the new useful constraints are enforced);
446  * thus, we have to reset the enforcement counters in order to enforce all constraints again, especially
447  * the now obsolete one;
448  * this case should occur almost never, because a constraint that was not enforced in the last enforcement
449  * is a newly added one, and it is very unlikely that this constraint will become obsolete before the next
450  * enforcement call;
451  * this reset is not performed for separation and propagation, because they are not vital for correctness
452  */
453  conshdlr->lastenfolplpcount = -1;
454  conshdlr->lastenfolpdomchgcount = -1;
455  conshdlr->lastenfopsdomchgcount = -1;
456  conshdlr->lastenfolpnode = -1;
457  conshdlr->lastenfopsnode = -1;
458  }
459 
460  /* switch the last useful (non-obsolete) enfo constraint with this constraint */
461  tmpcons = conshdlr->enfoconss[conshdlr->nusefulenfoconss-1];
462  assert(tmpcons->enfoconsspos == conshdlr->nusefulenfoconss-1);
463 
464  conshdlr->enfoconss[conshdlr->nusefulenfoconss-1] = cons;
465  conshdlr->enfoconss[cons->enfoconsspos] = tmpcons;
466  tmpcons->enfoconsspos = cons->enfoconsspos;
467  cons->enfoconsspos = conshdlr->nusefulenfoconss-1;
468 
469  conshdlr->nusefulenfoconss--;
470  }
471  /* in case the constraint is marked to be propagated, we do not move it in the propconss array since the first
472  * part of the array contains all marked constraints independently of their age
473  */
474  assert(!cons->markpropagate == (cons->propconsspos < conshdlr->nmarkedpropconss));
475  if( cons->propagate && cons->propenabled && !cons->markpropagate )
476  {
477  assert(0 <= cons->propconsspos && cons->propconsspos < conshdlr->nusefulpropconss);
478 
479  if( cons->propconsspos < conshdlr->lastnusefulpropconss )
480  conshdlr->lastnusefulpropconss--;
481 
482  /* switch the last useful (non-obsolete) prop constraint with this constraint */
483  tmpcons = conshdlr->propconss[conshdlr->nusefulpropconss-1];
484  assert(tmpcons->propconsspos == conshdlr->nusefulpropconss-1);
485 
486  conshdlr->propconss[conshdlr->nusefulpropconss-1] = cons;
487  conshdlr->propconss[cons->propconsspos] = tmpcons;
488  tmpcons->propconsspos = cons->propconsspos;
489  cons->propconsspos = conshdlr->nusefulpropconss-1;
490 
491  conshdlr->nusefulpropconss--;
492  }
493  }
494 
495  checkConssArrays(conshdlr);
496 
497  return SCIP_OKAY;
498 }
499 
500 /** marks obsolete constraint to be not obsolete anymore;
501  * it will be moved to the first part of the constraint arrays, such that it is checked, enforced, separated,
502  * and propagated before the obsolete constraints
503  */
504 static
506  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
507  SCIP_CONS* cons /**< constraint to be marked obsolete */
508  )
509 {
510  SCIP_CONS* tmpcons;
511 
512  assert(conshdlr != NULL);
513  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
514  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
515  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
516  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
517  assert(cons != NULL);
518  assert(!cons->original);
519  assert(cons->obsolete);
520  assert(!conshdlrAreUpdatesDelayed(conshdlr));
521 
522  cons->obsolete = FALSE;
523 
524  if( cons->active )
525  {
526  if( cons->check )
527  {
528  assert(conshdlr->nusefulcheckconss <= cons->checkconsspos && cons->checkconsspos < conshdlr->ncheckconss);
529 
530  /* switch the first obsolete check constraint with this constraint */
531  tmpcons = conshdlr->checkconss[conshdlr->nusefulcheckconss];
532  assert(tmpcons->checkconsspos == conshdlr->nusefulcheckconss);
533 
534  conshdlr->checkconss[conshdlr->nusefulcheckconss] = cons;
535  conshdlr->checkconss[cons->checkconsspos] = tmpcons;
536  tmpcons->checkconsspos = cons->checkconsspos;
537  cons->checkconsspos = conshdlr->nusefulcheckconss;
538 
539  conshdlr->nusefulcheckconss++;
540  }
541  }
542  if( cons->enabled )
543  {
544  if( cons->separate && cons->sepaenabled )
545  {
546  assert(conshdlr->nusefulsepaconss <= cons->sepaconsspos && cons->sepaconsspos < conshdlr->nsepaconss);
547 
548  /* switch the first obsolete sepa constraint with this constraint */
549  tmpcons = conshdlr->sepaconss[conshdlr->nusefulsepaconss];
550  assert(tmpcons->sepaconsspos == conshdlr->nusefulsepaconss);
551 
552  conshdlr->sepaconss[conshdlr->nusefulsepaconss] = cons;
553  conshdlr->sepaconss[cons->sepaconsspos] = tmpcons;
554  tmpcons->sepaconsspos = cons->sepaconsspos;
555  cons->sepaconsspos = conshdlr->nusefulsepaconss;
556 
557  conshdlr->nusefulsepaconss++;
558  }
559  if( cons->enforce )
560  {
561  assert(conshdlr->nusefulenfoconss <= cons->enfoconsspos && cons->enfoconsspos < conshdlr->nenfoconss);
562 
563  /* switch the first obsolete enfo constraint with this constraint */
564  tmpcons = conshdlr->enfoconss[conshdlr->nusefulenfoconss];
565  assert(tmpcons->enfoconsspos == conshdlr->nusefulenfoconss);
566 
567  conshdlr->enfoconss[conshdlr->nusefulenfoconss] = cons;
568  conshdlr->enfoconss[cons->enfoconsspos] = tmpcons;
569  tmpcons->enfoconsspos = cons->enfoconsspos;
570  cons->enfoconsspos = conshdlr->nusefulenfoconss;
571 
572  conshdlr->nusefulenfoconss++;
573  }
574  /* in case the constraint is marked to be propagated, we do not move it in the propconss array since the first
575  * part of the array contains all marked constraints independently of their age
576  */
577  assert(!cons->markpropagate == (cons->propconsspos < conshdlr->nmarkedpropconss));
578  if( cons->propagate && cons->propenabled && !cons->markpropagate)
579  {
580  assert(conshdlr->nusefulpropconss <= cons->propconsspos && cons->propconsspos < conshdlr->npropconss);
581 
582  /* switch the first obsolete prop constraint with this constraint */
583  tmpcons = conshdlr->propconss[conshdlr->nusefulpropconss];
584  assert(tmpcons->propconsspos == conshdlr->nusefulpropconss);
585 
586  conshdlr->propconss[conshdlr->nusefulpropconss] = cons;
587  conshdlr->propconss[cons->propconsspos] = tmpcons;
588  tmpcons->propconsspos = cons->propconsspos;
589  cons->propconsspos = conshdlr->nusefulpropconss;
590 
591  conshdlr->nusefulpropconss++;
592  }
593  }
594 
595  checkConssArrays(conshdlr);
596 
597  return SCIP_OKAY;
598 }
599 
600 /** marks constraint to be propagated in the next propagation round;
601  *
602  * @note the propagation array is divided into three parts in contrast to the other constraint arrays;
603  * the first part contains constraints which were marked to be propagated (independently of its age)
604  * the second part contains the useful (non-obsolete) constraints which are not marked to be propagated
605  * finally, the third part contains obsolete constraints which are not marked to be propagated
606  *
607  * @note if a constraint gets marked for propagation we put it into the first part regardless of its age
608  */
609 static
611  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
612  SCIP_CONS* cons /**< constraint to be marked obsolete */
613  )
614 {
615  SCIP_CONS* tmpcons;
616 
617  assert(conshdlr != NULL);
618  assert(conshdlr->nmarkedpropconss <= conshdlr->nusefulpropconss);
619  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
620  assert(cons != NULL);
621  assert(!cons->original);
622 
623  /* it may happen that the constraint is deleted while updates are delayed: in this case we just return */
624  if( !cons->enabled )
625  return;
626 
627  if( cons->markpropagate )
628  return;
629 
630  cons->markpropagate = TRUE;
631 
632  /* propagation of the constraint is globally or locally disabled, so we do not have to move the constraint in the
633  * propconss array
634  */
635  if( !cons->propagate || !cons->propenabled )
636  {
637  assert(cons->propconsspos == -1);
638  return;
639  }
640  assert(cons->propconsspos >= conshdlr->nmarkedpropconss);
641 
642  /* if the constraint is obsolete, we need to move it first to the non-obsolete part of the array */
643  if( cons->obsolete )
644  {
645  assert(conshdlr->nusefulpropconss <= cons->propconsspos && cons->propconsspos < conshdlr->npropconss);
646 
647  /* switch the first obsolete prop constraint with this constraint */
648  tmpcons = conshdlr->propconss[conshdlr->nusefulpropconss];
649  assert(tmpcons->propconsspos == conshdlr->nusefulpropconss);
650 
651  conshdlr->propconss[conshdlr->nusefulpropconss] = cons;
652  conshdlr->propconss[cons->propconsspos] = tmpcons;
653  tmpcons->propconsspos = cons->propconsspos;
654  cons->propconsspos = conshdlr->nusefulpropconss;
655 
656  conshdlr->nusefulpropconss++;
657  }
658  assert(conshdlr->nmarkedpropconss <= cons->propconsspos && cons->propconsspos < conshdlr->nusefulpropconss);
659 
660  /* switch the first useful prop constraint with this constraint */
661  tmpcons = conshdlr->propconss[conshdlr->nmarkedpropconss];
662  assert(tmpcons->propconsspos == conshdlr->nmarkedpropconss);
663 
664  conshdlr->propconss[conshdlr->nmarkedpropconss] = cons;
665  conshdlr->propconss[cons->propconsspos] = tmpcons;
666  tmpcons->propconsspos = cons->propconsspos;
667  cons->propconsspos = conshdlr->nmarkedpropconss;
668 
669  conshdlr->nmarkedpropconss++;
670 
671  checkConssArrays(conshdlr);
672 }
673 
674 /** unmarks constraint to be propagated in the next propagation round;
675  *
676  * @note the propagation array is divided into three parts in contrast to the other constraint arrays;
677  * the first part contains constraints which were marked to be propagated (independently of its age)
678  * the second part contains the useful (non-obsolete) constraints which are not marked to be propagated
679  * finally, the third part contains obsolete constraints which are not marked to be propagated
680  *
681  * @note if a constraint gets unmarked for propagation, it is put into the right part depending on its age
682  */
683 static
685  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
686  SCIP_CONS* cons /**< constraint to be marked obsolete */
687  )
688 {
689  SCIP_CONS* tmpcons;
690 
691  assert(conshdlr != NULL);
692  assert(conshdlr->nmarkedpropconss <= conshdlr->nusefulpropconss);
693  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
694  assert(cons != NULL);
695  assert(!cons->original);
696 
697  /* it may happen that the constraint is deleted while updates are delayed: in this case we just return */
698  if( !cons->enabled )
699  return;
700 
701  if( !cons->markpropagate )
702  return;
703 
704  cons->markpropagate = FALSE;
705 
706  /* propagation of the constraint is globally or locally disabled, so we do not have to move the constraint in the
707  * propconss array
708  */
709  if( !cons->propagate || !cons->propenabled )
710  {
711  assert(cons->propconsspos == -1);
712  return;
713  }
714  assert(cons->propconsspos >= 0);
715  assert(cons->propconsspos < conshdlr->nmarkedpropconss);
716 
717  /* first, move the constraint out of the first part to the second part of the constraint array */
718  if( cons->propconsspos < conshdlr->nmarkedpropconss - 1 )
719  {
720  conshdlr->nmarkedpropconss--;
721 
722  /* switch the last marked prop constraint with this constraint */
723  tmpcons = conshdlr->propconss[conshdlr->nmarkedpropconss];
724  assert(tmpcons->propconsspos == conshdlr->nmarkedpropconss);
725 
726  conshdlr->propconss[conshdlr->nmarkedpropconss] = cons;
727  conshdlr->propconss[cons->propconsspos] = tmpcons;
728  tmpcons->propconsspos = cons->propconsspos;
729  cons->propconsspos = conshdlr->nmarkedpropconss;
730  }
731  else if( cons->propconsspos == conshdlr->nmarkedpropconss - 1 )
732  conshdlr->nmarkedpropconss--;
733  assert(cons->propconsspos == conshdlr->nmarkedpropconss);
734 
735  /* if the constraint is obsolete, move it to the last part of the constraint array */
736  if( cons->obsolete )
737  {
738  conshdlr->nusefulpropconss--;
739 
740  /* switch the last useful prop constraint with this constraint */
741  tmpcons = conshdlr->propconss[conshdlr->nusefulpropconss];
742  assert(tmpcons->propconsspos == conshdlr->nusefulpropconss);
743 
744  conshdlr->propconss[conshdlr->nusefulpropconss] = cons;
745  conshdlr->propconss[cons->propconsspos] = tmpcons;
746  tmpcons->propconsspos = cons->propconsspos;
747  cons->propconsspos = conshdlr->nusefulpropconss;
748  }
749 
750  checkConssArrays(conshdlr);
751 }
752 
753 
754 /** adds constraint to the conss array of constraint handler */
755 static
757  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
758  SCIP_SET* set, /**< global SCIP settings */
759  SCIP_CONS* cons /**< constraint to add */
760  )
761 {
762  assert(conshdlr != NULL);
763  assert(cons != NULL);
764  assert(cons->conshdlr == conshdlr);
765  assert(!cons->original);
766  assert(!cons->active);
767  assert(cons->consspos == -1);
768  assert(set != NULL);
769  assert(cons->scip == set->scip);
770 
771  /* insert the constraint as inactive constraint into the transformed constraints array */
772  SCIP_CALL( conshdlrEnsureConssMem(conshdlr, set, conshdlr->nconss+1) );
773  conshdlr->conss[conshdlr->nconss] = cons;
774  cons->consspos = conshdlr->nconss;
775  conshdlr->nconss++;
776 
777  return SCIP_OKAY;
778 }
779 
780 /** deletes constraint from the conss array of constraint handler */
781 static
783  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
784  SCIP_CONS* cons /**< constraint to remove */
785  )
786 {
787  assert(conshdlr != NULL);
788  assert(cons != NULL);
789  assert(cons->conshdlr == conshdlr);
790  assert(!cons->original);
791  assert(!cons->active);
792  assert(conshdlr->nactiveconss <= cons->consspos && cons->consspos < conshdlr->nconss);
793 
794  conshdlr->conss[cons->consspos] = conshdlr->conss[conshdlr->nconss-1];
795  conshdlr->conss[cons->consspos]->consspos = cons->consspos;
796  conshdlr->nconss--;
797  cons->consspos = -1;
798 }
799 
800 /** adds constraint to the initconss array of constraint handler */
801 static
803  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
804  SCIP_SET* set, /**< global SCIP settings */
805  SCIP_STAT* stat, /**< dynamic problem statistics */
806  SCIP_CONS* cons /**< constraint to add */
807  )
808 {
809  int insertpos;
810 
811  assert(conshdlr != NULL);
812  assert(cons != NULL);
813  assert(cons->conshdlr == conshdlr);
814  assert(!cons->original);
815  assert(cons->active);
816  assert(cons->initial);
817  assert(cons->initconsspos == -1 || cons->initconsspos < conshdlr->ninitconsskept);
818 
819  SCIP_CALL( conshdlrEnsureInitconssMem(conshdlr, set, conshdlr->ninitconss+1) );
820 
821  insertpos = conshdlr->ninitconss;
822 
823  conshdlr->initconss[insertpos] = cons;
824  conshdlr->ninitconss++;
825  stat->ninitconssadded++;
826 
827  /* if the constraint is kept, we keep the stored position at the beginning of the array */
828  if( cons->initconsspos == -1 )
829  cons->initconsspos = insertpos;
830 
831  checkConssArrays(conshdlr);
832 
833  return SCIP_OKAY;
834 }
835 
836 /** deletes constraint from the initconss array of constraint handler */
837 static
839  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
840  SCIP_CONS* cons /**< constraint to remove */
841  )
842 {
843  int delpos;
844 
845  assert(conshdlr != NULL);
846  assert(cons != NULL);
847  assert(cons->conshdlr == conshdlr);
848  assert(!cons->original);
849  assert(0 <= cons->initconsspos && cons->initconsspos < conshdlr->ninitconss);
850 
851  delpos = cons->initconsspos;
852  if( delpos < conshdlr->ninitconsskept )
853  {
854  conshdlr->ninitconsskept--;
855  conshdlr->initconss[delpos] = conshdlr->initconss[conshdlr->ninitconsskept];
856  conshdlr->initconss[delpos]->initconsspos = delpos;
857  delpos = conshdlr->ninitconsskept;
858  }
859 
860  if( delpos < conshdlr->ninitconss-1 )
861  {
862  conshdlr->initconss[delpos] = conshdlr->initconss[conshdlr->ninitconss-1];
863  conshdlr->initconss[delpos]->initconsspos = delpos;
864  }
865  conshdlr->ninitconss--;
866  cons->initconsspos = -1;
867 
868  checkConssArrays(conshdlr);
869 }
870 
871 /** adds constraint to the sepaconss array of constraint handler */
872 static
874  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
875  SCIP_SET* set, /**< global SCIP settings */
876  SCIP_CONS* cons /**< constraint to add */
877  )
878 {
879  int insertpos;
880 
881  assert(conshdlr != NULL);
882  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
883  assert(cons != NULL);
884  assert(cons->conshdlr == conshdlr);
885  assert(!cons->original);
886  assert(cons->active);
887  assert(cons->separate);
888  assert(cons->sepaenabled);
889  assert(cons->sepaconsspos == -1);
890  assert(set != NULL);
891  assert(cons->scip == set->scip);
892  assert(!conshdlrAreUpdatesDelayed(conshdlr) || !conshdlr->duringsepa);
893 
894  SCIP_CALL( conshdlrEnsureSepaconssMem(conshdlr, set, conshdlr->nsepaconss+1) );
895  insertpos = conshdlr->nsepaconss;
896  if( !cons->obsolete )
897  {
898  if( conshdlr->nusefulsepaconss < conshdlr->nsepaconss )
899  {
900  conshdlr->sepaconss[conshdlr->nsepaconss] = conshdlr->sepaconss[conshdlr->nusefulsepaconss];
901  conshdlr->sepaconss[conshdlr->nsepaconss]->sepaconsspos = conshdlr->nsepaconss;
902  insertpos = conshdlr->nusefulsepaconss;
903  }
904  conshdlr->nusefulsepaconss++;
905  }
906  conshdlr->sepaconss[insertpos] = cons;
907  cons->sepaconsspos = insertpos;
908  conshdlr->nsepaconss++;
909 
910  checkConssArrays(conshdlr);
911 
912  return SCIP_OKAY;
913 }
914 
915 /** deletes constraint from the sepaconss array of constraint handler */
916 static
918  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
919  SCIP_CONS* cons /**< constraint to remove */
920  )
921 {
922  int delpos;
923 
924  assert(conshdlr != NULL);
925  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
926  assert(cons != NULL);
927  assert(cons->conshdlr == conshdlr);
928  assert(!cons->original);
929  assert(cons->separate);
930  assert(cons->sepaenabled);
931  assert(cons->sepaconsspos != -1);
932  assert(!conshdlrAreUpdatesDelayed(conshdlr) || !conshdlr->duringsepa);
933 
934  delpos = cons->sepaconsspos;
935  if( !cons->obsolete )
936  {
937  assert(0 <= delpos && delpos < conshdlr->nusefulsepaconss);
938 
939  if( delpos < conshdlr->lastnusefulsepaconss )
940  conshdlr->lastnusefulsepaconss--;
941 
942  conshdlr->sepaconss[delpos] = conshdlr->sepaconss[conshdlr->nusefulsepaconss-1];
943  conshdlr->sepaconss[delpos]->sepaconsspos = delpos;
944  delpos = conshdlr->nusefulsepaconss-1;
945  conshdlr->nusefulsepaconss--;
946  assert(conshdlr->nusefulsepaconss >= 0);
947  assert(conshdlr->lastnusefulsepaconss >= 0);
948  }
949  assert(conshdlr->nusefulsepaconss <= delpos && delpos < conshdlr->nsepaconss);
950  if( delpos < conshdlr->nsepaconss-1 )
951  {
952  conshdlr->sepaconss[delpos] = conshdlr->sepaconss[conshdlr->nsepaconss-1];
953  conshdlr->sepaconss[delpos]->sepaconsspos = delpos;
954  }
955  conshdlr->nsepaconss--;
956  cons->sepaconsspos = -1;
957 
958  checkConssArrays(conshdlr);
959 }
960 
961 /** adds constraint to the enfoconss array of constraint handler */
962 static
964  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
965  SCIP_SET* set, /**< global SCIP settings */
966  SCIP_CONS* cons /**< constraint to add */
967  )
968 {
969  int insertpos;
970 
971  assert(conshdlr != NULL);
972  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
973  assert(cons != NULL);
974  assert(cons->conshdlr == conshdlr);
975  assert(!cons->original);
976  assert(cons->active);
977  assert(cons->enforce);
978  assert(cons->enfoconsspos == -1);
979  assert(set != NULL);
980  assert(cons->scip == set->scip);
981 
982  SCIP_CALL( conshdlrEnsureEnfoconssMem(conshdlr, set, conshdlr->nenfoconss+1) );
983  insertpos = conshdlr->nenfoconss;
984  if( !cons->obsolete )
985  {
986  if( conshdlr->nusefulenfoconss < conshdlr->nenfoconss )
987  {
988  conshdlr->enfoconss[conshdlr->nenfoconss] = conshdlr->enfoconss[conshdlr->nusefulenfoconss];
989  conshdlr->enfoconss[conshdlr->nenfoconss]->enfoconsspos = conshdlr->nenfoconss;
990  insertpos = conshdlr->nusefulenfoconss;
991  }
992  conshdlr->nusefulenfoconss++;
993  }
994  else
995  {
996  /* we have to make sure that even this obsolete constraint is enforced in the next enforcement call;
997  * if the same LP or pseudo solution is enforced again, only the newly added useful constraints are
998  * enforced; thus, we have to reset the enforcement counters and force all constraints to be
999  * enforced again; this is not needed for separation and propagation, because they are not vital for correctness
1000  */
1001  conshdlr->lastenfolplpcount = -1;
1002  conshdlr->lastenfolpdomchgcount = -1;
1003  conshdlr->lastenfopsdomchgcount = -1;
1004  conshdlr->lastenfolpnode = -1;
1005  conshdlr->lastenfopsnode = -1;
1006  }
1007  conshdlr->enfoconss[insertpos] = cons;
1008  cons->enfoconsspos = insertpos;
1009  conshdlr->nenfoconss++;
1010 
1011  checkConssArrays(conshdlr);
1012 
1013  return SCIP_OKAY;
1014 }
1015 
1016 /** deletes constraint from the enfoconss array of constraint handler */
1017 static
1019  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1020  SCIP_CONS* cons /**< constraint to remove */
1021  )
1022 {
1023  int delpos;
1024 
1025  assert(conshdlr != NULL);
1026  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1027  assert(cons != NULL);
1028  assert(cons->conshdlr == conshdlr);
1029  assert(!cons->original);
1030  assert(cons->enforce);
1031  assert(cons->enfoconsspos != -1);
1032 
1033  delpos = cons->enfoconsspos;
1034  if( !cons->obsolete )
1035  {
1036  assert(0 <= delpos && delpos < conshdlr->nusefulenfoconss);
1037 
1038  if( delpos < conshdlr->lastnusefulenfoconss )
1039  conshdlr->lastnusefulenfoconss--;
1040 
1041  conshdlr->enfoconss[delpos] = conshdlr->enfoconss[conshdlr->nusefulenfoconss-1];
1042  conshdlr->enfoconss[delpos]->enfoconsspos = delpos;
1043  delpos = conshdlr->nusefulenfoconss-1;
1044  conshdlr->nusefulenfoconss--;
1045 
1046  /* if the constraint that moved to the free position was a newly added constraint and not enforced in the last
1047  * enforcement, we have to make sure it will be enforced in the next run;
1048  * this check is not performed for separation and propagation, because they are not vital for correctness
1049  */
1050  if( delpos >= conshdlr->lastnusefulenfoconss )
1051  conshdlr->lastnusefulenfoconss = cons->enfoconsspos;
1052 
1053  assert(conshdlr->nusefulenfoconss >= 0);
1054  assert(conshdlr->lastnusefulenfoconss >= 0);
1055  }
1056  assert(conshdlr->nusefulenfoconss <= delpos && delpos < conshdlr->nenfoconss);
1057  if( delpos < conshdlr->nenfoconss-1 )
1058  {
1059  conshdlr->enfoconss[delpos] = conshdlr->enfoconss[conshdlr->nenfoconss-1];
1060  conshdlr->enfoconss[delpos]->enfoconsspos = delpos;
1061  }
1062  conshdlr->nenfoconss--;
1063  cons->enfoconsspos = -1;
1064 
1065  checkConssArrays(conshdlr);
1066 }
1067 
1068 /** adds constraint to the checkconss array of constraint handler */
1069 static
1071  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1072  SCIP_SET* set, /**< global SCIP settings */
1073  SCIP_CONS* cons /**< constraint to add */
1074  )
1075 {
1076  int insertpos;
1077 
1078  assert(conshdlr != NULL);
1079  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1080  assert(cons != NULL);
1081  assert(cons->conshdlr == conshdlr);
1082  assert(!cons->original);
1083  assert(cons->active);
1084  assert(cons->check);
1085  assert(cons->checkconsspos == -1);
1086  assert(set != NULL);
1087  assert(cons->scip == set->scip);
1088 
1089  SCIP_CALL( conshdlrEnsureCheckconssMem(conshdlr, set, conshdlr->ncheckconss+1) );
1090  insertpos = conshdlr->ncheckconss;
1091  if( !cons->obsolete )
1092  {
1093  if( conshdlr->nusefulcheckconss < conshdlr->ncheckconss )
1094  {
1095  assert(conshdlr->checkconss[conshdlr->nusefulcheckconss] != NULL);
1096  conshdlr->checkconss[conshdlr->ncheckconss] = conshdlr->checkconss[conshdlr->nusefulcheckconss];
1097  conshdlr->checkconss[conshdlr->ncheckconss]->checkconsspos = conshdlr->ncheckconss;
1098  insertpos = conshdlr->nusefulcheckconss;
1099  }
1100  conshdlr->nusefulcheckconss++;
1101  }
1102  assert(0 <= insertpos && insertpos <= conshdlr->ncheckconss);
1103  conshdlr->checkconss[insertpos] = cons;
1104  cons->checkconsspos = insertpos;
1105  conshdlr->ncheckconss++;
1106 
1107  checkConssArrays(conshdlr);
1108 
1109  return SCIP_OKAY;
1110 }
1111 
1112 /** deletes constraint from the checkconss array of constraint handler */
1113 static
1115  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1116  SCIP_CONS* cons /**< constraint to add */
1117  )
1118 {
1119  int delpos;
1120 
1121  assert(conshdlr != NULL);
1122  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1123  assert(cons != NULL);
1124  assert(cons->conshdlr == conshdlr);
1125  assert(!cons->original);
1126  assert(cons->active);
1127  assert(cons->check);
1128  assert(cons->checkconsspos != -1);
1129 
1130  delpos = cons->checkconsspos;
1131  if( !cons->obsolete )
1132  {
1133  assert(0 <= delpos && delpos < conshdlr->nusefulcheckconss);
1134  conshdlr->checkconss[delpos] = conshdlr->checkconss[conshdlr->nusefulcheckconss-1];
1135  conshdlr->checkconss[delpos]->checkconsspos = delpos;
1136  delpos = conshdlr->nusefulcheckconss-1;
1137  conshdlr->nusefulcheckconss--;
1138  }
1139  assert(conshdlr->nusefulcheckconss <= delpos && delpos < conshdlr->ncheckconss);
1140  if( delpos < conshdlr->ncheckconss-1 )
1141  {
1142  conshdlr->checkconss[delpos] = conshdlr->checkconss[conshdlr->ncheckconss-1];
1143  conshdlr->checkconss[delpos]->checkconsspos = delpos;
1144  }
1145  conshdlr->ncheckconss--;
1146  cons->checkconsspos = -1;
1147 
1148  checkConssArrays(conshdlr);
1149 }
1150 
1151 /** adds constraint to the propconss array of constraint handler */
1152 static
1154  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1155  SCIP_SET* set, /**< global SCIP settings */
1156  SCIP_CONS* cons /**< constraint to add */
1157  )
1158 {
1159  int insertpos;
1160 
1161  assert(conshdlr != NULL);
1162  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1163  assert(cons != NULL);
1164  assert(cons->conshdlr == conshdlr);
1165  assert(!cons->original);
1166  assert(cons->active);
1167  assert(cons->enabled);
1168  assert(cons->propagate);
1169  assert(cons->propenabled);
1170  assert(cons->propconsspos == -1);
1171  assert(set != NULL);
1172  assert(cons->scip == set->scip);
1173  assert(!conshdlrAreUpdatesDelayed(conshdlr) || !conshdlr->duringprop);
1174 
1175  /* add constraint to the propagation array */
1176  SCIP_CALL( conshdlrEnsurePropconssMem(conshdlr, set, conshdlr->npropconss+1) );
1177  insertpos = conshdlr->npropconss;
1178  if( !cons->obsolete )
1179  {
1180  if( conshdlr->nusefulpropconss < conshdlr->npropconss )
1181  {
1182  conshdlr->propconss[conshdlr->npropconss] = conshdlr->propconss[conshdlr->nusefulpropconss];
1183  conshdlr->propconss[conshdlr->npropconss]->propconsspos = conshdlr->npropconss;
1184  insertpos = conshdlr->nusefulpropconss;
1185  }
1186  conshdlr->nusefulpropconss++;
1187  }
1188  conshdlr->propconss[insertpos] = cons;
1189  cons->propconsspos = insertpos;
1190  conshdlr->npropconss++;
1191 
1192  /* if the constraint is marked to be propagated, we have to move it to the first part of the array */
1193  if( cons->markpropagate )
1194  {
1195  /* temporarily unmark the constraint to be propagated, such that we can use the method below */
1196  cons->markpropagate = FALSE;
1197 
1198  conshdlrMarkConsPropagate(cons->conshdlr, cons);
1199  assert(cons->markpropagate);
1200  }
1201 
1202  checkConssArrays(conshdlr);
1203 
1204  return SCIP_OKAY;
1205 }
1206 
1207 /** deletes constraint from the propconss array of constraint handler */
1208 static
1210  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1211  SCIP_CONS* cons /**< constraint to remove */
1212  )
1213 {
1214  int delpos;
1215 
1216  assert(conshdlr != NULL);
1217  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1218  assert(cons != NULL);
1219  assert(cons->conshdlr == conshdlr);
1220  assert(!cons->original);
1221  assert(cons->propagate);
1222  assert(cons->propenabled);
1223  assert(cons->propconsspos != -1);
1224  assert(!conshdlrAreUpdatesDelayed(conshdlr) || !conshdlr->duringprop);
1225 
1226  /* unmark constraint to be propagated; this will move the constraint to the obsolete or non-obsolete part of the
1227  * array, depending on its age
1228  */
1229  if( cons->markpropagate )
1230  {
1232  assert(!cons->markpropagate);
1233  }
1234 
1235  /* delete constraint from the propagation array */
1236  delpos = cons->propconsspos;
1237  assert(delpos >= conshdlr->nmarkedpropconss);
1238  if( !cons->obsolete )
1239  {
1240  assert(0 <= delpos && delpos < conshdlr->nusefulpropconss);
1241 
1242  if( delpos < conshdlr->lastnusefulpropconss )
1243  conshdlr->lastnusefulpropconss--;
1244 
1245  conshdlr->propconss[delpos] = conshdlr->propconss[conshdlr->nusefulpropconss-1];
1246  conshdlr->propconss[delpos]->propconsspos = delpos;
1247  delpos = conshdlr->nusefulpropconss-1;
1248  conshdlr->nusefulpropconss--;
1249  assert(conshdlr->nusefulpropconss >= 0);
1250  assert(conshdlr->lastnusefulpropconss >= 0);
1251  }
1252  assert(conshdlr->nusefulpropconss <= delpos && delpos < conshdlr->npropconss);
1253 
1254  if( delpos < conshdlr->npropconss-1 )
1255  {
1256  conshdlr->propconss[delpos] = conshdlr->propconss[conshdlr->npropconss-1];
1257  conshdlr->propconss[delpos]->propconsspos = delpos;
1258  }
1259  conshdlr->npropconss--;
1260  cons->propconsspos = -1;
1261 
1262  checkConssArrays(conshdlr);
1263 }
1264 
1265 /** enables separation of constraint */
1266 static
1268  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1269  SCIP_SET* set, /**< global SCIP settings */
1270  SCIP_CONS* cons /**< constraint to add */
1271  )
1272 {
1273  assert(conshdlr != NULL);
1274  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1275  assert(cons != NULL);
1276  assert(cons->conshdlr == conshdlr);
1277  assert(!cons->sepaenabled);
1278  assert(cons->sepaconsspos == -1);
1279  assert(set != NULL);
1280  assert(cons->scip == set->scip);
1281 
1282  SCIPdebugMessage("enable separation of constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1283 
1284  /* enable separation of constraint */
1285  cons->sepaenabled = TRUE;
1286 
1287  /* add constraint to the separation array */
1288  if( cons->enabled && cons->separate )
1289  {
1290  SCIP_CALL( conshdlrAddSepacons(conshdlr, set, cons) );
1291  }
1292 
1293  return SCIP_OKAY;
1294 }
1295 
1296 /** disables separation of constraint */
1297 static
1299  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1300  SCIP_CONS* cons /**< constraint to remove */
1301  )
1302 {
1303  assert(conshdlr != NULL);
1304  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1305  assert(cons != NULL);
1306  assert(cons->conshdlr == conshdlr);
1307  assert(cons->sepaenabled);
1308  assert((cons->separate && cons->enabled) == (cons->sepaconsspos != -1));
1309 
1310  SCIPdebugMessage("disable separation of constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1311 
1312  /* delete constraint from the separation array */
1313  if( cons->separate && cons->enabled )
1314  {
1315  conshdlrDelSepacons(conshdlr, cons);
1316  }
1317  assert(cons->sepaconsspos == -1);
1318 
1319  /* disable separation of constraint */
1320  cons->sepaenabled = FALSE;
1321 
1322  return SCIP_OKAY;
1323 }
1324 
1325 /** enables propagation of constraint */
1326 static
1328  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1329  SCIP_SET* set, /**< global SCIP settings */
1330  SCIP_CONS* cons /**< constraint to add */
1331  )
1332 {
1333  assert(conshdlr != NULL);
1334  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1335  assert(cons != NULL);
1336  assert(cons->conshdlr == conshdlr);
1337  assert(!cons->propenabled);
1338  assert(cons->propconsspos == -1);
1339  assert(set != NULL);
1340  assert(cons->scip == set->scip);
1341 
1342  SCIPdebugMessage("enable propagation of constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1343 
1344  /* enable propagation of constraint */
1345  cons->propenabled = TRUE;
1346 
1347  /* add constraint to the propagation array */
1348  if( cons->enabled && cons->propagate )
1349  {
1350  SCIP_CALL( conshdlrAddPropcons(conshdlr, set, cons) );
1351  }
1352 
1353  return SCIP_OKAY;
1354 }
1355 
1356 /** disables propagation of constraint */
1357 static
1359  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1360  SCIP_CONS* cons /**< constraint to remove */
1361  )
1362 {
1363  assert(conshdlr != NULL);
1364  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1365  assert(cons != NULL);
1366  assert(cons->conshdlr == conshdlr);
1367  assert(cons->propenabled);
1368  assert((cons->propagate && cons->enabled) == (cons->propconsspos != -1));
1369 
1370  SCIPdebugMessage("disable propagation of constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1371 
1372  /* delete constraint from the propagation array */
1373  if( cons->propagate && cons->enabled )
1374  {
1375  conshdlrDelPropcons(conshdlr, cons);
1376  }
1377  assert(cons->propconsspos == -1);
1378 
1379  /* disable propagation of constraint */
1380  cons->propenabled = FALSE;
1381 
1382  return SCIP_OKAY;
1383 }
1384 
1385 /** enables separation, enforcement, and propagation of constraint */
1386 static
1388  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1389  SCIP_SET* set, /**< global SCIP settings */
1390  SCIP_STAT* stat, /**< dynamic problem statistics */
1391  SCIP_CONS* cons /**< constraint to add */
1392  )
1393 {
1394  assert(conshdlr != NULL);
1395  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1396  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1397  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1398  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1399  assert(set != NULL);
1400  assert(stat != NULL);
1401  assert(cons != NULL);
1402  assert(cons->scip == set->scip);
1403  assert(cons->conshdlr == conshdlr);
1404  assert(!cons->original);
1405  assert(cons->active);
1406  assert(!cons->enabled);
1407  assert(cons->sepaconsspos == -1);
1408  assert(cons->enfoconsspos == -1);
1409  assert(cons->propconsspos == -1);
1410 
1411  SCIPdebugMessage("enable constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1412 
1413  /* enable constraint */
1414  cons->enabled = TRUE;
1415  conshdlr->nenabledconss++;
1416  stat->nenabledconss++;
1417 
1418  /* add constraint to the separation array */
1419  if( cons->separate && cons->sepaenabled )
1420  {
1421  SCIP_CALL( conshdlrAddSepacons(conshdlr, set, cons) );
1422  }
1423 
1424  /* add constraint to the enforcement array */
1425  if( cons->enforce )
1426  {
1427  SCIP_CALL( conshdlrAddEnfocons(conshdlr, set, cons) );
1428  }
1429 
1430  /* add constraint to the propagation array */
1431  if( cons->propagate && cons->propenabled )
1432  {
1433  SCIP_CALL( conshdlrAddPropcons(conshdlr, set, cons) );
1434  }
1435 
1436  /* call constraint handler's enabling notification method */
1437  if( conshdlr->consenable != NULL )
1438  {
1439  SCIP_CALL( conshdlr->consenable(set->scip, conshdlr, cons) );
1440  }
1441 
1442  checkConssArrays(conshdlr);
1443 
1444  return SCIP_OKAY;
1445 }
1446 
1447 /** disables separation, enforcement, and propagation of constraint */
1448 static
1450  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1451  SCIP_SET* set, /**< global SCIP settings */
1452  SCIP_STAT* stat, /**< dynamic problem statistics */
1453  SCIP_CONS* cons /**< constraint to remove */
1454  )
1455 {
1456  assert(conshdlr != NULL);
1457  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1458  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1459  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1460  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1461  assert(set != NULL);
1462  assert(stat != NULL);
1463  assert(cons != NULL);
1464  assert(cons->scip == set->scip);
1465  assert(cons->conshdlr == conshdlr);
1466  assert(!cons->original);
1467  assert(cons->active);
1468  assert(cons->enabled);
1469  assert((cons->separate && cons->sepaenabled) == (cons->sepaconsspos != -1));
1470  assert(cons->enforce == (cons->enfoconsspos != -1));
1471  assert((cons->propagate && cons->propenabled) == (cons->propconsspos != -1));
1472 
1473  SCIPdebugMessage("disable constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1474 
1475  /* call constraint handler's disabling notification method */
1476  if( conshdlr->consdisable != NULL )
1477  {
1478  SCIP_CALL( conshdlr->consdisable(set->scip, conshdlr, cons) );
1479  }
1480 
1481  /* delete constraint from the separation array */
1482  if( cons->separate && cons->sepaenabled )
1483  {
1484  conshdlrDelSepacons(conshdlr, cons);
1485  }
1486 
1487  /* delete constraint from the enforcement array */
1488  if( cons->enforce )
1489  {
1490  conshdlrDelEnfocons(conshdlr, cons);
1491  }
1492 
1493  /* delete constraint from the propagation array */
1494  if( cons->propagate && cons->propenabled )
1495  {
1496  conshdlrDelPropcons(conshdlr, cons);
1497  }
1498 
1499  assert(cons->sepaconsspos == -1);
1500  assert(cons->enfoconsspos == -1);
1501  assert(cons->propconsspos == -1);
1502 
1503  /* disable constraint */
1504  cons->enabled = FALSE;
1505  conshdlr->nenabledconss--;
1506  stat->nenabledconss--;
1507 
1508  checkConssArrays(conshdlr);
1509 
1510  return SCIP_OKAY;
1511 }
1512 
1513 /** activates and adds constraint to constraint handler's constraint arrays */
1514 static
1516  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1517  SCIP_SET* set, /**< global SCIP settings */
1518  SCIP_STAT* stat, /**< dynamic problem statistics */
1519  SCIP_CONS* cons, /**< constraint to add */
1520  int depth, /**< depth in the tree where the activation takes place, or -1 for global problem */
1521  SCIP_Bool focusnode /**< does the constraint activation take place at the focus node? */
1522  )
1523 {
1524  assert(conshdlr != NULL);
1525  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1526  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1527  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1528  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1529  assert(set != NULL);
1530  assert(stat != NULL);
1531  assert(cons != NULL);
1532  assert(cons->scip == set->scip);
1533  assert(cons->conshdlr == conshdlr);
1534  assert(!cons->original);
1535  assert(!cons->active);
1536  assert(!cons->enabled);
1537  assert(conshdlr->nactiveconss <= cons->consspos && cons->consspos < conshdlr->nconss);
1538  assert(conshdlr->conss[cons->consspos] == cons);
1539  assert(cons->initconsspos < conshdlr->ninitconsskept);
1540  assert(cons->sepaconsspos == -1);
1541  assert(cons->enfoconsspos == -1);
1542  assert(cons->checkconsspos == -1);
1543  assert(cons->propconsspos == -1);
1544  assert(depth >= -1);
1545 
1546  SCIPdebugMessage("activate constraint <%s> in constraint handler <%s> (depth %d, focus=%u)\n",
1547  cons->name, conshdlr->name, depth, focusnode);
1548 
1549  /* activate constraint, switch positions with first inactive constraint */
1550  cons->active = TRUE;
1551  cons->activedepth = depth;
1552  conshdlr->conss[cons->consspos] = conshdlr->conss[conshdlr->nactiveconss];
1553  conshdlr->conss[cons->consspos]->consspos = cons->consspos;
1554  conshdlr->conss[conshdlr->nactiveconss] = cons;
1555  cons->consspos = conshdlr->nactiveconss;
1556  conshdlr->nactiveconss++;
1557  conshdlr->maxnactiveconss = MAX(conshdlr->maxnactiveconss, conshdlr->nactiveconss);
1558  stat->nactiveconss++;
1559 
1560  /* add constraint to the check array */
1561  if( cons->check )
1562  {
1563  SCIP_CALL( conshdlrAddCheckcons(conshdlr, set, cons) );
1564  }
1565 
1566  /* add constraint to the initconss array if the constraint is initial and added to the focus node */
1567  if( cons->initial )
1568  {
1569  SCIP_CALL( conshdlrAddInitcons(conshdlr, set, stat, cons) );
1570  }
1571 
1572  /* call constraint handler's activation notification method */
1573  if( conshdlr->consactive != NULL )
1574  {
1575  SCIP_CALL( conshdlr->consactive(set->scip, conshdlr, cons) );
1576  }
1577 
1578  /* enable separation, enforcement, and propagation of constraint */
1579  SCIP_CALL( conshdlrEnableCons(conshdlr, set, stat, cons) );
1580 
1581  assert(0 <= cons->consspos && cons->consspos < conshdlr->nactiveconss);
1582 
1583  checkConssArrays(conshdlr);
1584 
1585  return SCIP_OKAY;
1586 }
1587 
1588 /** deactivates and removes constraint from constraint handler's conss array */
1589 static
1591  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1592  SCIP_SET* set, /**< global SCIP settings */
1593  SCIP_STAT* stat, /**< dynamic problem statistics */
1594  SCIP_CONS* cons /**< constraint to remove */
1595  )
1596 {
1597  assert(conshdlr != NULL);
1598  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1599  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1600  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1601  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1602  assert(set != NULL);
1603  assert(stat != NULL);
1604  assert(cons != NULL);
1605  assert(cons->scip == set->scip);
1606  assert(cons->conshdlr == conshdlr);
1607  assert(!cons->original);
1608  assert(cons->active);
1609  assert(0 <= cons->consspos && cons->consspos < conshdlr->nactiveconss);
1610  assert(conshdlr->conss[cons->consspos] == cons);
1611  assert(cons->check == (cons->checkconsspos != -1));
1612 
1613  SCIPdebugMessage("deactivate constraint <%s> in constraint handler <%s>\n", cons->name, conshdlr->name);
1614 
1615  /* disable constraint */
1616  if( cons->enabled )
1617  {
1618  SCIP_CALL( conshdlrDisableCons(conshdlr, set, stat, cons) );
1619  }
1620  assert(!cons->enabled);
1621 
1622  /* call constraint handler's deactivation notification method */
1623  if( conshdlr->consdeactive != NULL )
1624  {
1625  SCIP_CALL( conshdlr->consdeactive(set->scip, conshdlr, cons) );
1626  }
1627 
1628  /* delete constraint from the initconss array */
1629  if( cons->initconsspos >= 0 )
1630  {
1631  conshdlrDelInitcons(conshdlr, cons);
1632  }
1633 
1634  /* delete constraint from the check array */
1635  if( cons->check )
1636  {
1637  conshdlrDelCheckcons(conshdlr, cons);
1638  }
1639 
1640  /* switch constraint with the last active constraint in the conss array */
1641  conshdlr->conss[cons->consspos] = conshdlr->conss[conshdlr->nactiveconss-1];
1642  conshdlr->conss[cons->consspos]->consspos = cons->consspos;
1643  conshdlr->conss[conshdlr->nactiveconss-1] = cons;
1644  cons->consspos = conshdlr->nactiveconss-1;
1645  conshdlr->nactiveconss--;
1646  cons->active = FALSE;
1647  cons->activedepth = -2;
1648  stat->nactiveconss--;
1649 
1650  assert(conshdlr->nactiveconss <= cons->consspos && cons->consspos < conshdlr->nconss);
1651  assert(cons->initconsspos == -1);
1652  assert(cons->sepaconsspos == -1);
1653  assert(cons->enfoconsspos == -1);
1654  assert(cons->checkconsspos == -1);
1655  assert(cons->propconsspos == -1);
1656 
1657  checkConssArrays(conshdlr);
1658 
1659  return SCIP_OKAY;
1660 }
1661 
1662 /** processes all delayed updates of constraints:
1663  * recently (de)activated constraints will be (de)activated;
1664  * recently en/disabled constraints will be en/disabled;
1665  * recent obsolete non-check constraints will be globally deleted;
1666  * recent obsolete check constraints will be moved to the last positions in the sepa-, enfo-, check-, and prop-arrays;
1667  * recent useful constraints will be moved to the first positions in the sepa-, enfo-, check-, and prop-arrays;
1668  * constraints which were recently marked to be propagated are moved to the first positions in the prop-array;
1669  * no longer used constraints will be freed and removed from the conss array
1670  */
1671 static
1673  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1674  BMS_BLKMEM* blkmem, /**< block memory */
1675  SCIP_SET* set, /**< global SCIP settings */
1676  SCIP_STAT* stat /**< dynamic problem statistics */
1677  )
1678 {
1679  SCIP_CONS* cons;
1680  int i;
1681 
1682  assert(conshdlr != NULL);
1683  assert(!conshdlrAreUpdatesDelayed(conshdlr));
1684  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
1685  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
1686  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
1687  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
1688 
1689  SCIPdebugMessage("processing %d constraints that have to be updated in constraint handler <%s>\n",
1690  conshdlr->nupdateconss, conshdlr->name);
1691 
1692  for( i = conshdlr->nupdateconss - 1; i >= 0; --i )
1693  {
1694  cons = conshdlr->updateconss[i];
1695  assert(cons != NULL);
1696  assert(cons->conshdlr == conshdlr);
1697  assert(cons->update);
1698  assert(cons->updateinsert || cons->updateactivate || cons->updatedeactivate
1699  || cons->updateenable || cons->updatedisable
1700  || cons->updatesepaenable || cons->updatesepadisable
1701  || cons->updatepropenable || cons->updatepropdisable
1702  || cons->updateobsolete || cons->updatefree
1703  || cons->updatemarkpropagate || cons->updateunmarkpropagate);
1704 
1705  SCIPdebugMessage(" -> constraint <%s>: insert=%u, activate=%u, deactivate=%u, enable=%u, disable=%u, sepaenable=%u, sepadisable=%u, propenable=%u, propdisable=%u, obsolete=%u, free=%u (consdata=%p)\n",
1706  cons->name, cons->updateinsert, cons->updateactivate, cons->updatedeactivate,
1707  cons->updateenable, cons->updatedisable,
1708  cons->updatesepaenable, cons->updatesepadisable,
1709  cons->updatepropenable, cons->updatepropdisable,
1710  cons->updateobsolete, cons->updatefree, (void*)cons->consdata);
1711 
1712  if( cons->updateinsert )
1713  {
1714  SCIP_CALL( conshdlrAddCons(conshdlr, set, cons) );
1715  cons->updateinsert = FALSE;
1716  }
1717 
1718  if( cons->updateactivate )
1719  {
1720  assert(!cons->active);
1721  assert(!cons->updatedeactivate);
1722  assert(!cons->updateenable);
1723  assert(!cons->updatedisable);
1724  assert(!cons->updateobsolete);
1725  assert(!cons->updatefree);
1726 
1727  /* the activation depth was already stored in SCIPconsActivate() */
1728  SCIP_CALL( conshdlrActivateCons(conshdlr, set, stat, cons, cons->activedepth, cons->updateactfocus) );
1729  assert(cons->active);
1730  cons->updateactivate = FALSE;
1731  }
1732  else if( cons->updatedeactivate )
1733  {
1734  assert(cons->active);
1735 
1736  SCIP_CALL( conshdlrDeactivateCons(conshdlr, set, stat, cons) );
1737  assert(!cons->active);
1738  cons->updatedeactivate = FALSE;
1739  cons->updateenable = FALSE;
1740  cons->updatedisable = FALSE;
1741  cons->obsolete = consExceedsObsoleteage(cons, set);
1742  cons->updateobsolete = FALSE;
1743  }
1744  else if( cons->updateenable )
1745  {
1746  assert(!cons->enabled);
1747  assert(!cons->updatedisable);
1748 
1749  SCIP_CALL( conshdlrEnableCons(conshdlr, set, stat, cons) );
1750  assert(cons->enabled);
1751  cons->updateenable = FALSE;
1752  }
1753  else if( cons->updatedisable )
1754  {
1755  assert(cons->enabled);
1756 
1757  SCIP_CALL( conshdlrDisableCons(conshdlr, set, stat, cons) );
1758  assert(!cons->enabled);
1759  cons->updatedisable = FALSE;
1760  }
1761 
1762  if( cons->updatesepaenable )
1763  {
1764  assert(!cons->updatesepadisable);
1765  if( !cons->sepaenabled )
1766  {
1767  SCIP_CALL( conshdlrEnableConsSeparation(conshdlr, set, cons) );
1768  assert(cons->sepaenabled);
1769  }
1770  cons->updatesepaenable = FALSE;
1771  }
1772  else if( cons->updatesepadisable )
1773  {
1774  if( cons->sepaenabled )
1775  {
1776  SCIP_CALL( conshdlrDisableConsSeparation(conshdlr, cons) );
1777  assert(!cons->sepaenabled);
1778  }
1779  cons->updatesepadisable = FALSE;
1780  }
1781 
1782  if( cons->updatepropenable )
1783  {
1784  assert(!cons->updatepropdisable);
1785  if( !cons->propenabled )
1786  {
1787  SCIP_CALL( conshdlrEnableConsPropagation(conshdlr, set, cons) );
1788  assert(cons->propenabled);
1789  }
1790  cons->updatepropenable = FALSE;
1791  }
1792  else if( cons->updatepropdisable )
1793  {
1794  if( cons->propenabled )
1795  {
1796  SCIP_CALL( conshdlrDisableConsPropagation(conshdlr, cons) );
1797  assert(!cons->propenabled);
1798  }
1799  cons->updatepropdisable = FALSE;
1800  }
1801 
1802  if( cons->updatefree )
1803  {
1804  /* nothing to do here: the constraint is freed, when it is released from the updateconss array */
1805  assert(cons->nuses == 1); /* it only exists in the updateconss array */
1806  cons->updatefree = FALSE;
1807  cons->updateobsolete = FALSE;
1808  }
1809  else
1810  {
1811  if( cons->updateobsolete )
1812  {
1813  if( !cons->obsolete && consExceedsObsoleteage(cons, set) )
1814  {
1815  /* the constraint's status must be switched to obsolete */
1816  SCIP_CALL( conshdlrMarkConsObsolete(conshdlr, cons) );
1817  }
1818  else if( cons->obsolete && !consExceedsObsoleteage(cons, set) )
1819  {
1820  /* the constraint's status must be switched to useful */
1821  SCIP_CALL( conshdlrMarkConsUseful(conshdlr, cons) );
1822  }
1823  cons->updateobsolete = FALSE;
1824  }
1825 
1826  if( cons->updatemarkpropagate )
1827  {
1828  /* the constraint must be marked to be propagated */
1829  conshdlrMarkConsPropagate(conshdlr, cons);
1830  cons->updatemarkpropagate = FALSE;
1831  }
1832  else if( cons->updateunmarkpropagate )
1833  {
1834  /* the constraint must be unmarked to be propagated */
1835  conshdlrUnmarkConsPropagate(conshdlr, cons);
1836  cons->updateunmarkpropagate = FALSE;
1837  }
1838  }
1839 
1840  assert(!cons->updateinsert);
1841  assert(!cons->updateactivate);
1842  assert(!cons->updatedeactivate);
1843  assert(!cons->updateenable);
1844  assert(!cons->updatedisable);
1845  assert(!cons->updatesepaenable);
1846  assert(!cons->updatesepadisable);
1847  assert(!cons->updatepropenable);
1848  assert(!cons->updatepropdisable);
1849  assert(!cons->updateobsolete);
1850  assert(!cons->updatemarkpropagate);
1851  assert(!cons->updateunmarkpropagate);
1852  assert(!cons->updatefree);
1853  cons->update = FALSE;
1854 
1855  /* release the constraint */
1856  SCIP_CALL( SCIPconsRelease(&conshdlr->updateconss[i], blkmem, set) );
1857  }
1858 
1859  conshdlr->nupdateconss = 0;
1860 
1861  return SCIP_OKAY;
1862 }
1863 
1864 /** marks constraint handler to delay all constraint updates until the next conshdlrProcessUpdates() call */
1865 static
1867  SCIP_CONSHDLR* conshdlr /**< constraint handler */
1868  )
1869 {
1870  assert(conshdlr != NULL);
1871 
1872  SCIPdebugMessage("constraint updates of constraint handler <%s> will be delayed (count:%d)\n",
1873  conshdlr->name, conshdlr->delayupdatecount+1);
1874 
1875  conshdlr->delayupdatecount++;
1876 }
1877 
1878 /** marks constraint handler to perform all constraint updates immediately;
1879  * all delayed constraint updates will be processed
1880  */
1881 static
1883  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1884  BMS_BLKMEM* blkmem, /**< block memory */
1885  SCIP_SET* set, /**< global SCIP settings */
1886  SCIP_STAT* stat /**< dynamic problem statistics */
1887  )
1888 {
1889  assert(conshdlr != NULL);
1890  assert(conshdlrAreUpdatesDelayed(conshdlr));
1891 
1892  SCIPdebugMessage("constraint updates of constraint handler <%s> will be processed immediately (count:%d)\n",
1893  conshdlr->name, conshdlr->delayupdatecount);
1894  conshdlr->delayupdatecount--;
1895 
1896  /* only run the update if all delays are taken away (reference counting) */
1897  if( !conshdlrAreUpdatesDelayed(conshdlr) )
1898  {
1899  SCIP_CALL( conshdlrProcessUpdates(conshdlr, blkmem, set, stat) );
1900  assert(conshdlr->nupdateconss == 0);
1901  }
1902 
1903  return SCIP_OKAY;
1904 }
1905 
1906 /** adds constraint to constraint handler's update constraint array and captures it */
1907 static
1909  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1910  SCIP_SET* set, /**< global SCIP settings */
1911  SCIP_CONS* cons /**< constraint to add */
1912  )
1913 {
1914  assert(conshdlr != NULL);
1915  assert(set != NULL);
1916  assert(cons != NULL);
1917  assert(cons->conshdlr == conshdlr);
1918 
1919  if( !cons->update )
1920  {
1921  SCIPdebugMessage("constraint <%s> of age %g has to be updated in constraint handler <%s> (consdata=%p)\n",
1922  cons->name, cons->age, conshdlr->name, (void*)cons->consdata);
1923 
1924  /* add constraint to the updateconss array */
1925  SCIP_CALL( conshdlrEnsureUpdateconssMem(conshdlr, set, conshdlr->nupdateconss+1) );
1926  conshdlr->updateconss[conshdlr->nupdateconss] = cons;
1927  conshdlr->nupdateconss++;
1928 
1929  /* capture constraint */
1930  SCIPconsCapture(cons);
1931 
1932  cons->update = TRUE;
1933  }
1934 
1935  return SCIP_OKAY;
1936 }
1937 
1938 /** compares two constraint handlers w. r. to their separation priority */
1939 SCIP_DECL_SORTPTRCOMP(SCIPconshdlrCompSepa)
1940 { /*lint --e{715}*/
1941  return ((SCIP_CONSHDLR*)elem2)->sepapriority - ((SCIP_CONSHDLR*)elem1)->sepapriority;
1942 }
1943 
1944 /** compares two constraint handlers w. r. to their enforcing priority */
1945 SCIP_DECL_SORTPTRCOMP(SCIPconshdlrCompEnfo)
1946 { /*lint --e{715}*/
1947  return ((SCIP_CONSHDLR*)elem2)->enfopriority - ((SCIP_CONSHDLR*)elem1)->enfopriority;
1948 }
1949 
1950 /** compares two constraint handlers w. r. to their feasibility check priority */
1951 SCIP_DECL_SORTPTRCOMP(SCIPconshdlrCompCheck)
1952 { /*lint --e{715}*/
1953  return ((SCIP_CONSHDLR*)elem2)->checkpriority - ((SCIP_CONSHDLR*)elem1)->checkpriority;
1954 }
1955 
1956 /** copies the given constraint handler to a new scip */
1958  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1959  SCIP_SET* set, /**< SCIP_SET of SCIP to copy to */
1960  SCIP_Bool* valid /**< was the copying process valid? */
1961  )
1962 {
1963  assert(conshdlr != NULL);
1964  assert(set != NULL);
1965  assert(valid != NULL);
1966  assert(set->scip != NULL);
1967 
1968  if( conshdlr->conshdlrcopy != NULL )
1969  {
1970  SCIPdebugMessage("including constraint handler %s in subscip %p\n", SCIPconshdlrGetName(conshdlr), (void*)set->scip);
1971  SCIP_CALL( conshdlr->conshdlrcopy(set->scip, conshdlr, valid) );
1972  }
1973 
1974  return SCIP_OKAY;
1975 }
1976 
1977 /** creates a constraint handler */
1979  SCIP_CONSHDLR** conshdlr, /**< pointer to constraint handler data structure */
1980  SCIP_SET* set, /**< global SCIP settings */
1981  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1982  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
1983  const char* name, /**< name of constraint handler */
1984  const char* desc, /**< description of constraint handler */
1985  int sepapriority, /**< priority of the constraint handler for separation */
1986  int enfopriority, /**< priority of the constraint handler for constraint enforcing */
1987  int checkpriority, /**< priority of the constraint handler for checking feasibility (and propagation) */
1988  int sepafreq, /**< frequency for separating cuts; zero means to separate only in the root node */
1989  int propfreq, /**< frequency for propagating domains; zero means only preprocessing propagation */
1990  int eagerfreq, /**< frequency for using all instead of only the useful constraints in separation,
1991  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
1992  int maxprerounds, /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
1993  SCIP_Bool delaysepa, /**< should separation method be delayed, if other separators found cuts? */
1994  SCIP_Bool delayprop, /**< should propagation method be delayed, if other propagators found reductions? */
1995  SCIP_Bool delaypresol, /**< should presolving method be delayed, if other presolvers found reductions? */
1996  SCIP_Bool needscons, /**< should the constraint handler be skipped, if no constraints are available? */
1997  SCIP_PROPTIMING timingmask, /**< positions in the node solving loop where propagation method of constraint handlers should be executed */
1998  SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), /**< copy method of constraint handler or NULL if you don't want to copy your plugin into sub-SCIPs */
1999  SCIP_DECL_CONSFREE ((*consfree)), /**< destructor of constraint handler */
2000  SCIP_DECL_CONSINIT ((*consinit)), /**< initialize constraint handler */
2001  SCIP_DECL_CONSEXIT ((*consexit)), /**< deinitialize constraint handler */
2002  SCIP_DECL_CONSINITPRE ((*consinitpre)), /**< presolving initialization method of constraint handler */
2003  SCIP_DECL_CONSEXITPRE ((*consexitpre)), /**< presolving deinitialization method of constraint handler */
2004  SCIP_DECL_CONSINITSOL ((*consinitsol)), /**< solving process initialization method of constraint handler */
2005  SCIP_DECL_CONSEXITSOL ((*consexitsol)), /**< solving process deinitialization method of constraint handler */
2006  SCIP_DECL_CONSDELETE ((*consdelete)), /**< free specific constraint data */
2007  SCIP_DECL_CONSTRANS ((*constrans)), /**< transform constraint data into data belonging to the transformed problem */
2008  SCIP_DECL_CONSINITLP ((*consinitlp)), /**< initialize LP with relaxations of "initial" constraints */
2009  SCIP_DECL_CONSSEPALP ((*conssepalp)), /**< separate cutting planes for LP solution */
2010  SCIP_DECL_CONSSEPASOL ((*conssepasol)), /**< separate cutting planes for arbitrary primal solution */
2011  SCIP_DECL_CONSENFOLP ((*consenfolp)), /**< enforcing constraints for LP solutions */
2012  SCIP_DECL_CONSENFOPS ((*consenfops)), /**< enforcing constraints for pseudo solutions */
2013  SCIP_DECL_CONSCHECK ((*conscheck)), /**< check feasibility of primal solution */
2014  SCIP_DECL_CONSPROP ((*consprop)), /**< propagate variable domains */
2015  SCIP_DECL_CONSPRESOL ((*conspresol)), /**< presolving method */
2016  SCIP_DECL_CONSRESPROP ((*consresprop)), /**< propagation conflict resolving method */
2017  SCIP_DECL_CONSLOCK ((*conslock)), /**< variable rounding lock method */
2018  SCIP_DECL_CONSACTIVE ((*consactive)), /**< activation notification method */
2019  SCIP_DECL_CONSDEACTIVE((*consdeactive)), /**< deactivation notification method */
2020  SCIP_DECL_CONSENABLE ((*consenable)), /**< enabling notification method */
2021  SCIP_DECL_CONSDISABLE ((*consdisable)), /**< disabling notification method */
2022  SCIP_DECL_CONSDELVARS ((*consdelvars)), /**< variable deletion method */
2023  SCIP_DECL_CONSPRINT ((*consprint)), /**< constraint display method */
2024  SCIP_DECL_CONSCOPY ((*conscopy)), /**< constraint copying method */
2025  SCIP_DECL_CONSPARSE ((*consparse)), /**< constraint parsing method */
2026  SCIP_DECL_CONSGETVARS ((*consgetvars)), /**< constraint get variables method */
2027  SCIP_DECL_CONSGETNVARS((*consgetnvars)), /**< constraint get number of variable method */
2028  SCIP_CONSHDLRDATA* conshdlrdata /**< constraint handler data */
2029  )
2030 {
2031  char paramname[SCIP_MAXSTRLEN];
2032  char paramdesc[SCIP_MAXSTRLEN];
2033 
2034  assert(conshdlr != NULL);
2035  assert(name != NULL);
2036  assert(desc != NULL);
2037  assert(conssepalp != NULL || conssepasol != NULL || sepafreq == -1);
2038  assert(consprop != NULL || propfreq == -1);
2039  assert(eagerfreq >= -1);
2040  assert(!needscons || ((conshdlrcopy == NULL) == (conscopy == NULL)));
2041 
2042  /* both callbacks have to exist or not exist */
2043  assert((consgetvars != NULL) == (consgetnvars != NULL));
2044 
2045  SCIP_ALLOC( BMSallocMemory(conshdlr) );
2046  SCIP_ALLOC( BMSduplicateMemoryArray(&(*conshdlr)->name, name, strlen(name)+1) );
2047  SCIP_ALLOC( BMSduplicateMemoryArray(&(*conshdlr)->desc, desc, strlen(desc)+1) );
2048  (*conshdlr)->sepapriority = sepapriority;
2049  (*conshdlr)->enfopriority = enfopriority;
2050  (*conshdlr)->checkpriority = checkpriority;
2051  (*conshdlr)->sepafreq = sepafreq;
2052  (*conshdlr)->propfreq = propfreq;
2053  (*conshdlr)->eagerfreq = eagerfreq;
2054  (*conshdlr)->maxprerounds = maxprerounds;
2055  (*conshdlr)->conshdlrcopy = conshdlrcopy;
2056  (*conshdlr)->consfree = consfree;
2057  (*conshdlr)->consinit = consinit;
2058  (*conshdlr)->consexit = consexit;
2059  (*conshdlr)->consinitpre = consinitpre;
2060  (*conshdlr)->consexitpre = consexitpre;
2061  (*conshdlr)->consinitsol = consinitsol;
2062  (*conshdlr)->consexitsol = consexitsol;
2063  (*conshdlr)->consdelete = consdelete;
2064  (*conshdlr)->constrans = constrans;
2065  (*conshdlr)->consinitlp = consinitlp;
2066  (*conshdlr)->conssepalp = conssepalp;
2067  (*conshdlr)->conssepasol = conssepasol;
2068  (*conshdlr)->consenfolp = consenfolp;
2069  (*conshdlr)->consenfops = consenfops;
2070  (*conshdlr)->conscheck = conscheck;
2071  (*conshdlr)->consprop = consprop;
2072  (*conshdlr)->conspresol = conspresol;
2073  (*conshdlr)->consresprop = consresprop;
2074  (*conshdlr)->conslock = conslock;
2075  (*conshdlr)->consactive = consactive;
2076  (*conshdlr)->consdeactive = consdeactive;
2077  (*conshdlr)->consenable = consenable;
2078  (*conshdlr)->consdisable = consdisable;
2079  (*conshdlr)->consprint = consprint;
2080  (*conshdlr)->consdelvars = consdelvars;
2081  (*conshdlr)->conscopy = conscopy;
2082  (*conshdlr)->consparse = consparse;
2083  (*conshdlr)->consgetvars = consgetvars;
2084  (*conshdlr)->consgetnvars = consgetnvars;
2085  (*conshdlr)->conshdlrdata = conshdlrdata;
2086  (*conshdlr)->conss = NULL;
2087  (*conshdlr)->consssize = 0;
2088  (*conshdlr)->nconss = 0;
2089  (*conshdlr)->nactiveconss = 0;
2090  (*conshdlr)->maxnactiveconss = 0;
2091  (*conshdlr)->startnactiveconss = 0;
2092  (*conshdlr)->initconss = NULL;
2093  (*conshdlr)->initconsssize = 0;
2094  (*conshdlr)->ninitconss = 0;
2095  (*conshdlr)->ninitconsskept = 0;
2096  (*conshdlr)->sepaconss = NULL;
2097  (*conshdlr)->sepaconsssize = 0;
2098  (*conshdlr)->nsepaconss = 0;
2099  (*conshdlr)->nusefulsepaconss = 0;
2100  (*conshdlr)->enfoconss = NULL;
2101  (*conshdlr)->enfoconsssize = 0;
2102  (*conshdlr)->nenfoconss = 0;
2103  (*conshdlr)->nusefulenfoconss = 0;
2104  (*conshdlr)->checkconss = NULL;
2105  (*conshdlr)->checkconsssize = 0;
2106  (*conshdlr)->ncheckconss = 0;
2107  (*conshdlr)->nusefulcheckconss = 0;
2108  (*conshdlr)->propconss = NULL;
2109  (*conshdlr)->propconsssize = 0;
2110  (*conshdlr)->npropconss = 0;
2111  (*conshdlr)->nusefulpropconss = 0;
2112  (*conshdlr)->nmarkedpropconss = 0;
2113  (*conshdlr)->updateconss = NULL;
2114  (*conshdlr)->updateconsssize = 0;
2115  (*conshdlr)->nupdateconss = 0;
2116  (*conshdlr)->nenabledconss = 0;
2117  (*conshdlr)->lastnusefulpropconss = 0;
2118  (*conshdlr)->lastnusefulsepaconss = 0;
2119  (*conshdlr)->lastnusefulenfoconss = 0;
2120 
2121  (*conshdlr)->storedpropconss = NULL;
2122  (*conshdlr)->storedpropconsssize = 0;
2123  (*conshdlr)->storednmarkedpropconss = 0;
2124  (*conshdlr)->storedpropdomchgcount = 0;
2125 
2126  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
2127  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->presoltime, SCIP_CLOCKTYPE_DEFAULT) );
2128  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->sepatime, SCIP_CLOCKTYPE_DEFAULT) );
2129  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->enfolptime, SCIP_CLOCKTYPE_DEFAULT) );
2130  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->enfopstime, SCIP_CLOCKTYPE_DEFAULT) );
2131  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->proptime, SCIP_CLOCKTYPE_DEFAULT) );
2132  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->sbproptime, SCIP_CLOCKTYPE_DEFAULT) );
2133  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->checktime, SCIP_CLOCKTYPE_DEFAULT) );
2134  SCIP_CALL( SCIPclockCreate(&(*conshdlr)->resproptime, SCIP_CLOCKTYPE_DEFAULT) );
2135 
2136  (*conshdlr)->nsepacalls = 0;
2137  (*conshdlr)->nenfolpcalls = 0;
2138  (*conshdlr)->nenfopscalls = 0;
2139  (*conshdlr)->npropcalls = 0;
2140  (*conshdlr)->ncheckcalls = 0;
2141  (*conshdlr)->nrespropcalls = 0;
2142  (*conshdlr)->ncutoffs = 0;
2143  (*conshdlr)->ncutsfound = 0;
2144  (*conshdlr)->ncutsapplied = 0;
2145  (*conshdlr)->nconssfound = 0;
2146  (*conshdlr)->ndomredsfound = 0;
2147  (*conshdlr)->nchildren = 0;
2148  (*conshdlr)->lastpropdomchgcount = -1;
2149  (*conshdlr)->lastsepalpcount = -1;
2150  (*conshdlr)->lastenfolplpcount = -1;
2151  (*conshdlr)->lastenfolpdomchgcount = -1;
2152  (*conshdlr)->lastenfopsdomchgcount = -1;
2153  (*conshdlr)->lastenfolpnode = -1;
2154  (*conshdlr)->lastenfopsnode = -1;
2155  (*conshdlr)->lastenfolpresult = SCIP_DIDNOTRUN;
2156  (*conshdlr)->lastenfopsresult = SCIP_DIDNOTRUN;
2157  (*conshdlr)->lastnfixedvars = 0;
2158  (*conshdlr)->lastnaggrvars = 0;
2159  (*conshdlr)->lastnchgvartypes = 0;
2160  (*conshdlr)->lastnchgbds = 0;
2161  (*conshdlr)->lastnaddholes = 0;
2162  (*conshdlr)->lastndelconss = 0;
2163  (*conshdlr)->lastnaddconss = 0;
2164  (*conshdlr)->lastnupgdconss = 0;
2165  (*conshdlr)->lastnchgcoefs = 0;
2166  (*conshdlr)->lastnchgsides = 0;
2167  (*conshdlr)->nfixedvars = 0;
2168  (*conshdlr)->naggrvars = 0;
2169  (*conshdlr)->nchgvartypes = 0;
2170  (*conshdlr)->nchgbds = 0;
2171  (*conshdlr)->naddholes = 0;
2172  (*conshdlr)->ndelconss = 0;
2173  (*conshdlr)->naddconss = 0;
2174  (*conshdlr)->nupgdconss = 0;
2175  (*conshdlr)->nchgcoefs = 0;
2176  (*conshdlr)->nchgsides = 0;
2177  (*conshdlr)->npresolcalls = 0;
2178  (*conshdlr)->delayupdatecount = 0;
2179  (*conshdlr)->ageresetavg = AGERESETAVG_INIT;
2180  (*conshdlr)->needscons = needscons;
2181  (*conshdlr)->sepalpwasdelayed = FALSE;
2182  (*conshdlr)->sepasolwasdelayed = FALSE;
2183  (*conshdlr)->propwasdelayed = FALSE;
2184  (*conshdlr)->presolwasdelayed = FALSE;
2185  (*conshdlr)->duringsepa = FALSE;
2186  (*conshdlr)->duringprop = FALSE;
2187  (*conshdlr)->initialized = FALSE;
2188 
2189  (*conshdlr)->pendingconss = NULL;
2190  SCIP_CALL( SCIPqueueCreate( &((*conshdlr)->pendingconss), 100, 1.5 ) );
2191 
2192  /* add parameters */
2193  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/sepafreq", name);
2194  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
2195  "frequency for separating cuts (-1: never, 0: only in root node)",
2196  &(*conshdlr)->sepafreq, FALSE, sepafreq, -1, INT_MAX, NULL, NULL) );
2197 
2198  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/propfreq", name);
2199  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
2200  "frequency for propagating domains (-1: never, 0: only in root node)",
2201  &(*conshdlr)->propfreq, FALSE, propfreq, -1, INT_MAX, NULL, NULL) );
2202 
2203  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/timingmask", name);
2204  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing when constraint propagation should be called (%u:BEFORELP, %u:DURINGLPLOOP, %u:AFTERLPLOOP, %u:ALWAYS)", SCIP_PROPTIMING_BEFORELP, SCIP_PROPTIMING_DURINGLPLOOP, SCIP_PROPTIMING_AFTERLPLOOP, SCIP_PROPTIMING_ALWAYS);
2205  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
2206  (int*)(&(*conshdlr)->timingmask), TRUE, timingmask, (int) SCIP_PROPTIMING_BEFORELP, (int) SCIP_PROPTIMING_ALWAYS, NULL, NULL) ); /*lint !e713*/
2207 
2208  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/eagerfreq", name);
2209  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
2210  "frequency for using all instead of only the useful constraints in separation, propagation and enforcement (-1: never, 0: only in first evaluation)",
2211  &(*conshdlr)->eagerfreq, TRUE, eagerfreq, -1, INT_MAX, NULL, NULL) );
2212 
2213  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/maxprerounds", name);
2214  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
2215  "maximal number of presolving rounds the constraint handler participates in (-1: no limit)",
2216  &(*conshdlr)->maxprerounds, TRUE, maxprerounds, -1, INT_MAX, NULL, NULL) );
2217 
2218  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/delaysepa", name);
2219  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
2220  "should separation method be delayed, if other separators found cuts?",
2221  &(*conshdlr)->delaysepa, TRUE, delaysepa, NULL, NULL) ); /*lint !e740*/
2222 
2223  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/delayprop", name);
2224  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
2225  "should propagation method be delayed, if other propagators found reductions?",
2226  &(*conshdlr)->delayprop, TRUE, delayprop, NULL, NULL) ); /*lint !e740*/
2227 
2228  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/%s/delaypresol", name);
2229  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
2230  "should presolving method be delayed, if other presolvers found reductions?",
2231  &(*conshdlr)->delaypresol, TRUE, delaypresol, NULL, NULL) ); /*lint !e740*/
2232 
2233  return SCIP_OKAY;
2234 }
2235 
2236 /** calls destructor and frees memory of constraint handler */
2238  SCIP_CONSHDLR** conshdlr, /**< pointer to constraint handler data structure */
2239  SCIP_SET* set /**< global SCIP settings */
2240  )
2241 {
2242  assert(conshdlr != NULL);
2243  assert(*conshdlr != NULL);
2244  assert(!(*conshdlr)->initialized);
2245  assert((*conshdlr)->nconss == 0);
2246  assert(set != NULL);
2247 
2248  SCIPqueueFree( &((*conshdlr)->pendingconss) );
2249 
2250  /* call destructor of constraint handler */
2251  if( (*conshdlr)->consfree != NULL )
2252  {
2253  SCIP_CALL( (*conshdlr)->consfree(set->scip, *conshdlr) );
2254  }
2255 
2256  SCIPclockFree(&(*conshdlr)->resproptime);
2257  SCIPclockFree(&(*conshdlr)->checktime);
2258  SCIPclockFree(&(*conshdlr)->sbproptime);
2259  SCIPclockFree(&(*conshdlr)->proptime);
2260  SCIPclockFree(&(*conshdlr)->enfopstime);
2261  SCIPclockFree(&(*conshdlr)->enfolptime);
2262  SCIPclockFree(&(*conshdlr)->sepatime);
2263  SCIPclockFree(&(*conshdlr)->presoltime);
2264  SCIPclockFree(&(*conshdlr)->setuptime);
2265 
2266  BMSfreeMemoryArray(&(*conshdlr)->name);
2267  BMSfreeMemoryArray(&(*conshdlr)->desc);
2268  BMSfreeMemoryArrayNull(&(*conshdlr)->conss);
2269  BMSfreeMemoryArrayNull(&(*conshdlr)->initconss);
2270  BMSfreeMemoryArrayNull(&(*conshdlr)->sepaconss);
2271  BMSfreeMemoryArrayNull(&(*conshdlr)->enfoconss);
2272  BMSfreeMemoryArrayNull(&(*conshdlr)->checkconss);
2273  BMSfreeMemoryArrayNull(&(*conshdlr)->propconss);
2274  BMSfreeMemoryArrayNull(&(*conshdlr)->updateconss);
2275  BMSfreeMemoryArrayNull(&(*conshdlr)->storedpropconss);
2276  BMSfreeMemory(conshdlr);
2277 
2278  return SCIP_OKAY;
2279 }
2280 
2281 /** calls initialization method of constraint handler */
2283  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2284  BMS_BLKMEM* blkmem, /**< block memory */
2285  SCIP_SET* set, /**< global SCIP settings */
2286  SCIP_STAT* stat /**< dynamic problem statistics */
2287  )
2288 {
2289  assert(conshdlr != NULL);
2290  assert(set != NULL);
2291 
2292  if( conshdlr->initialized )
2293  {
2294  SCIPerrorMessage("constraint handler <%s> already initialized\n", conshdlr->name);
2295  return SCIP_INVALIDCALL;
2296  }
2297 
2298  if( set->misc_resetstat )
2299  {
2300  SCIPclockReset(conshdlr->setuptime);
2301  SCIPclockReset(conshdlr->presoltime);
2302  SCIPclockReset(conshdlr->sepatime);
2303  SCIPclockReset(conshdlr->enfolptime);
2304  SCIPclockReset(conshdlr->enfopstime);
2305  SCIPclockReset(conshdlr->proptime);
2306  SCIPclockReset(conshdlr->sbproptime);
2307  SCIPclockReset(conshdlr->checktime);
2308  SCIPclockReset(conshdlr->resproptime);
2309 
2310  conshdlr->nsepacalls = 0;
2311  conshdlr->nenfolpcalls = 0;
2312  conshdlr->nenfopscalls = 0;
2313  conshdlr->npropcalls = 0;
2314  conshdlr->ncheckcalls = 0;
2315  conshdlr->nrespropcalls = 0;
2316  conshdlr->ncutoffs = 0;
2317  conshdlr->ncutsfound = 0;
2318  conshdlr->ncutsapplied = 0;
2319  conshdlr->nconssfound = 0;
2320  conshdlr->ndomredsfound = 0;
2321  conshdlr->nchildren = 0;
2322  conshdlr->lastpropdomchgcount = -1;
2323  conshdlr->lastenfolpdomchgcount = -1;
2324  conshdlr->lastenfopsdomchgcount = -1;
2325  conshdlr->lastenfolpnode = -1;
2326  conshdlr->lastenfopsnode = -1;
2327  conshdlr->lastenfolpresult = SCIP_DIDNOTRUN;
2328  conshdlr->lastenfopsresult = SCIP_DIDNOTRUN;
2329  conshdlr->maxnactiveconss = conshdlr->nactiveconss;
2330  conshdlr->startnactiveconss = 0;
2331  conshdlr->lastsepalpcount = -1;
2332  conshdlr->lastenfolplpcount = -1;
2333  conshdlr->lastnusefulpropconss = 0;
2334  conshdlr->lastnusefulsepaconss = 0;
2335  conshdlr->lastnusefulenfoconss = 0;
2336  conshdlr->lastnfixedvars = 0;
2337  conshdlr->lastnaggrvars = 0;
2338  conshdlr->lastnchgvartypes = 0;
2339  conshdlr->lastnchgbds = 0;
2340  conshdlr->lastnaddholes = 0;
2341  conshdlr->lastndelconss = 0;
2342  conshdlr->lastnaddconss = 0;
2343  conshdlr->lastnupgdconss = 0;
2344  conshdlr->lastnchgcoefs = 0;
2345  conshdlr->lastnchgsides = 0;
2346  conshdlr->nfixedvars = 0;
2347  conshdlr->naggrvars = 0;
2348  conshdlr->nchgvartypes = 0;
2349  conshdlr->nchgbds = 0;
2350  conshdlr->naddholes = 0;
2351  conshdlr->ndelconss = 0;
2352  conshdlr->naddconss = 0;
2353  conshdlr->nupgdconss = 0;
2354  conshdlr->nchgcoefs = 0;
2355  conshdlr->nchgsides = 0;
2356  conshdlr->npresolcalls = 0;
2357  conshdlr->ageresetavg = AGERESETAVG_INIT;
2358  conshdlr->sepalpwasdelayed = FALSE;
2359  conshdlr->sepasolwasdelayed = FALSE;
2360  conshdlr->propwasdelayed = FALSE;
2361  conshdlr->presolwasdelayed = FALSE;
2362  }
2363 
2364  /* call initialization method of constraint handler */
2365  if( conshdlr->consinit != NULL )
2366  {
2367  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2368  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2369  * external method; to avoid this, these changes will be buffered and processed after the method call
2370  */
2371  conshdlrDelayUpdates(conshdlr);
2372 
2373  /* start timing */
2374  SCIPclockStart(conshdlr->setuptime, set);
2375 
2376  /* call external method */
2377  SCIP_CALL( conshdlr->consinit(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
2378 
2379  /* stop timing */
2380  SCIPclockStop(conshdlr->setuptime, set);
2381 
2382  /* perform the cached constraint updates */
2383  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2384  }
2385  conshdlr->initialized = TRUE;
2386  assert(!conshdlrAreUpdatesDelayed(conshdlr));
2387 
2388  return SCIP_OKAY;
2389 }
2390 
2391 /** calls exit method of constraint handler */
2393  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2394  BMS_BLKMEM* blkmem, /**< block memory */
2395  SCIP_SET* set, /**< global SCIP settings */
2396  SCIP_STAT* stat /**< dynamic problem statistics */
2397  )
2398 {
2399  assert(conshdlr != NULL);
2400  assert(set != NULL);
2401 
2402  if( !conshdlr->initialized )
2403  {
2404  SCIPerrorMessage("constraint handler <%s> not initialized\n", conshdlr->name);
2405  return SCIP_INVALIDCALL;
2406  }
2407 
2408  while( !SCIPqueueIsEmpty(conshdlr->pendingconss) )
2409  {
2410  SCIP_CALL( SCIPconshdlrPopProp(conshdlr, blkmem, set) );
2411  }
2412 
2413  /* call deinitialization method of constraint handler */
2414  if( conshdlr->consexit != NULL )
2415  {
2416  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2417  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2418  * external method; to avoid this, these changes will be buffered and processed after the method call
2419  */
2420  conshdlrDelayUpdates(conshdlr);
2421 
2422  /* start timing */
2423  SCIPclockStart(conshdlr->setuptime, set);
2424 
2425  /* call external method */
2426  SCIP_CALL( conshdlr->consexit(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
2427 
2428  /* stop timing */
2429  SCIPclockStop(conshdlr->setuptime, set);
2430 
2431  /* perform the cached constraint updates */
2432  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2433  }
2434  conshdlr->initialized = FALSE;
2435 
2436  return SCIP_OKAY;
2437 }
2438 
2439 /** informs constraint handler that the presolving process is being started */
2441  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2442  BMS_BLKMEM* blkmem, /**< block memory */
2443  SCIP_SET* set, /**< global SCIP settings */
2444  SCIP_STAT* stat /**< dynamic problem statistics */
2445  )
2446 {
2447  assert(conshdlr != NULL);
2448  assert(set != NULL);
2449 
2450  /* reset conshdlr last presolved data in case of a restart */
2451  conshdlr->lastpropdomchgcount = -1;
2452  conshdlr->lastenfolpdomchgcount = -1;
2453  conshdlr->lastenfopsdomchgcount = -1;
2454  conshdlr->lastenfolpnode = -1;
2455  conshdlr->lastenfopsnode = -1;
2456  conshdlr->lastenfolpresult = SCIP_DIDNOTRUN;
2457  conshdlr->lastenfopsresult = SCIP_DIDNOTRUN;
2458  conshdlr->maxnactiveconss = conshdlr->nactiveconss;
2459  conshdlr->startnactiveconss = 0;
2460  conshdlr->lastsepalpcount = -1;
2461  conshdlr->lastenfolplpcount = -1;
2462  conshdlr->lastnusefulpropconss = 0;
2463  conshdlr->lastnusefulsepaconss = 0;
2464  conshdlr->lastnusefulenfoconss = 0;
2465  conshdlr->lastnfixedvars = 0;
2466  conshdlr->lastnaggrvars = 0;
2467  conshdlr->lastnchgvartypes = 0;
2468  conshdlr->lastnchgbds = 0;
2469  conshdlr->lastnaddholes = 0;
2470  conshdlr->lastndelconss = 0;
2471  conshdlr->lastnaddconss = 0;
2472  conshdlr->lastnupgdconss = 0;
2473  conshdlr->lastnchgcoefs = 0;
2474  conshdlr->lastnchgsides = 0;
2475  conshdlr->propwasdelayed = FALSE;
2476  conshdlr->presolwasdelayed = FALSE;
2477 
2478  /* call presolving initialization method of constraint handler */
2479  if( conshdlr->consinitpre != NULL )
2480  {
2481  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2482  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2483  * external method; to avoid this, these changes will be buffered and processed after the method call
2484  */
2485  conshdlrDelayUpdates(conshdlr);
2486 
2487  /* start timing */
2488  SCIPclockStart(conshdlr->setuptime, set);
2489 
2490  /* call external method */
2491  SCIP_CALL( conshdlr->consinitpre(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
2492 
2493  /* stop timing */
2494  SCIPclockStop(conshdlr->setuptime, set);
2495 
2496  /* perform the cached constraint updates */
2497  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2498  }
2499 
2500  /* after a restart the LP is empty but the initial constraints are not included in the initialconss array anymore;
2501  * we have to put them back into this array in order to obtain the correct initial root relaxation
2502  */
2503  if( stat->nruns >= 2 )
2504  {
2505  int c;
2506 
2507  for( c = 0; c < conshdlr->nconss; ++c )
2508  {
2509 
2510  /**@todo should only active constraints be added to the initconss array? at least cons->active is asserted in
2511  * conshdlrAddInitcons(conshdlr, set, conshdlr->conss[c])
2512  */
2513  if( conshdlr->conss[c]->addarraypos >= 0 && !conshdlr->conss[c]->deleted &&
2514  conshdlr->conss[c]->initial && conshdlr->conss[c]->initconsspos == -1 )
2515  {
2516  SCIP_CALL( conshdlrAddInitcons(conshdlr, set, stat, conshdlr->conss[c]) );
2517  }
2518  }
2519  }
2520 
2521 #if 0
2522  /* check if all initial constraints are included in the initconss array */
2523  {
2524  int c;
2525 
2526  for( c = 0; c < conshdlr->nconss; ++c )
2527  {
2528  assert(conshdlr->conss[c]->deleted || conshdlr->conss[c]->initial == (conshdlr->conss[c]->initconsspos >= 0));
2529  assert(conshdlr->conss[c]->deleted || !conshdlr->conss[c]->initial
2530  || conshdlr->initconss[conshdlr->conss[c]->initconsspos] == conshdlr->conss[c]);
2531  }
2532  }
2533 #endif
2534 
2535  return SCIP_OKAY;
2536 }
2537 
2538 /** informs constraint handler that the presolving is finished */
2540  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2541  BMS_BLKMEM* blkmem, /**< block memory */
2542  SCIP_SET* set, /**< global SCIP settings */
2543  SCIP_STAT* stat /**< dynamic problem statistics */
2544  )
2545 {
2546  assert(conshdlr != NULL);
2547  assert(set != NULL);
2548 
2549  /* empty the queue: the solving process will use a new one in any case */
2550  while( !SCIPqueueIsEmpty(conshdlr->pendingconss) )
2551  {
2552  SCIP_CALL( SCIPconshdlrPopProp(conshdlr, blkmem, set) );
2553  }
2554 
2555  /* call presolving deinitialization method of constraint handler */
2556  if( conshdlr->consexitpre != NULL )
2557  {
2558  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2559  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2560  * external method; to avoid this, these changes will be buffered and processed after the method call
2561  */
2562  conshdlrDelayUpdates(conshdlr);
2563 
2564  /* start timing */
2565  SCIPclockStart(conshdlr->setuptime, set);
2566 
2567  /* call external method */
2568  SCIP_CALL( conshdlr->consexitpre(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
2569 
2570  /* stop timing */
2571  SCIPclockStop(conshdlr->setuptime, set);
2572 
2573  /* perform the cached constraint updates */
2574  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2575  }
2576 
2577  /* update statistics */
2578  conshdlr->maxnactiveconss = conshdlr->nactiveconss;
2579  conshdlr->startnactiveconss = conshdlr->nactiveconss;
2580 
2581  return SCIP_OKAY;
2582 }
2583 
2584 /** informs constraint handler that the branch and bound process is being started */
2586  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2587  BMS_BLKMEM* blkmem, /**< block memory */
2588  SCIP_SET* set, /**< global SCIP settings */
2589  SCIP_STAT* stat /**< dynamic problem statistics */
2590  )
2591 {
2592  assert(conshdlr != NULL);
2593  assert(set != NULL);
2594  assert(stat != NULL);
2595 
2596  conshdlr->sepalpwasdelayed = FALSE;
2597  conshdlr->sepasolwasdelayed = FALSE;
2598 
2599  /* call solving process initialization method of constraint handler */
2600  if( conshdlr->consinitsol != NULL )
2601  {
2602  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2603  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2604  * external method; to avoid this, these changes will be buffered and processed after the method call
2605  */
2606  conshdlrDelayUpdates(conshdlr);
2607 
2608  /* start timing */
2609  SCIPclockStart(conshdlr->setuptime, set);
2610 
2611  /* call external method */
2612  SCIP_CALL( conshdlr->consinitsol(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
2613 
2614  /* stop timing */
2615  SCIPclockStop(conshdlr->setuptime, set);
2616 
2617  /* perform the cached constraint updates */
2618  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2619  }
2620 
2621  return SCIP_OKAY;
2622 }
2623 
2624 /** informs constraint handler that the branch and bound process data is being freed */
2626  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2627  BMS_BLKMEM* blkmem, /**< block memory */
2628  SCIP_SET* set, /**< global SCIP settings */
2629  SCIP_STAT* stat, /**< dynamic problem statistics */
2630  SCIP_Bool restart /**< was this exit solve call triggered by a restart? */
2631  )
2632 {
2633  assert(conshdlr != NULL);
2634  assert(set != NULL);
2635 
2636  /* call solving process deinitialization method of constraint handler */
2637  if( conshdlr->consexitsol != NULL )
2638  {
2639  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2640  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2641  * external method; to avoid this, these changes will be buffered and processed after the method call
2642  */
2643  conshdlrDelayUpdates(conshdlr);
2644 
2645  /* start timing */
2646  SCIPclockStart(conshdlr->setuptime, set);
2647 
2648  /* call external method */
2649  SCIP_CALL( conshdlr->consexitsol(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss, restart) );
2650 
2651  /* stop timing */
2652  SCIPclockStop(conshdlr->setuptime, set);
2653 
2654  /* perform the cached constraint updates */
2655  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2656  }
2657 
2658  return SCIP_OKAY;
2659 }
2660 
2661 /** calls LP initialization method of constraint handler to separate all initial active constraints */
2663  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2664  BMS_BLKMEM* blkmem, /**< block memory */
2665  SCIP_SET* set, /**< global SCIP settings */
2666  SCIP_STAT* stat, /**< dynamic problem statistics */
2667  SCIP_TREE* tree, /**< branch and bound tree */
2668  SCIP_Bool initkeptconss /**< Also initialize constraints which are valid at a more global node,
2669  * but were not activated there? Should be FALSE for repeated calls at
2670  * one node or if the current focusnode is a child of the former one */
2671  )
2672 {
2673  assert(conshdlr != NULL);
2674 #ifdef MORE_DEBUG
2675  assert(stat->nnodes > 1 || conshdlr->ninitconsskept == 0 || SCIPtreeProbing(tree));
2676 #endif
2677 
2678  if( conshdlr->consinitlp != NULL )
2679  {
2680  int currentdepth;
2681  int oldninitconss;
2682  int c;
2683 
2684  SCIPdebugMessage("initializing LP with %d initial constraints of handler <%s> (ninitconss=%d, kept=%d, initkept=%u)\n",
2685  initkeptconss ? conshdlr->ninitconss : conshdlr->ninitconss - conshdlr->ninitconsskept, conshdlr->name,
2686  conshdlr->ninitconss, conshdlr->ninitconsskept, initkeptconss);
2687 
2688  /* no constraints to initialize (or only kept constraints which do not need to be initialized this time) -> return */
2689  if( conshdlr->ninitconss == 0 || (!initkeptconss && conshdlr->ninitconss == conshdlr->ninitconsskept) )
2690  return SCIP_OKAY;
2691 
2692  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2693  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2694  * external method; to avoid this, these changes will be buffered and processed after the method call
2695  */
2696  conshdlrDelayUpdates(conshdlr);
2697 
2698  oldninitconss = conshdlr->ninitconss;
2699 
2700  /* start timing */
2701  SCIPclockStart(conshdlr->sepatime, set);
2702 
2703  if( initkeptconss )
2704  {
2705  /* add all kept initial constraints which are currently active to the second part of the initconss array */
2706  /* @todo keep track of where a constraint was already initialized (e.g., in the conssetchg)? */
2707  for( c = 0; c < conshdlr->ninitconsskept; ++c )
2708  {
2709  assert(conshdlr->initconss[c]->initconsspos == c);
2710 
2711  if( SCIPconsIsActive(conshdlr->initconss[c]) )
2712  {
2713  SCIP_CALL( conshdlrAddInitcons(conshdlr, set, stat, conshdlr->initconss[c]) );
2714  }
2715  }
2716  }
2717 
2718  /* call external method */
2719  SCIP_CALL( conshdlr->consinitlp(set->scip, conshdlr, &conshdlr->initconss[conshdlr->ninitconsskept],
2720  conshdlr->ninitconss - conshdlr->ninitconsskept) );
2721 
2722  /* stop timing */
2723  SCIPclockStop(conshdlr->sepatime, set);
2724 
2725  /* perform the cached constraint updates */
2726  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2727 
2728  currentdepth = SCIPtreeGetCurrentDepth(tree);
2729  assert(currentdepth >= 0);
2730 
2731  /* clear the initconss array */
2732  for( c = conshdlr->ninitconsskept; c < oldninitconss; ++c )
2733  {
2734  assert(SCIPconsGetActiveDepth(conshdlr->initconss[c]) >= -1);
2735  assert(SCIPconsGetActiveDepth(conshdlr->initconss[c]) <= currentdepth);
2736 
2737  /* if the constraint was not initialized at its valid node, we keep it */
2738  if( currentdepth > 0 ? SCIPconsGetActiveDepth(conshdlr->initconss[c]) != currentdepth :
2739  SCIPconsGetActiveDepth(conshdlr->initconss[c]) > 0 )
2740  {
2741  conshdlr->initconss[conshdlr->ninitconsskept] = conshdlr->initconss[c];
2742  conshdlr->initconss[conshdlr->ninitconsskept]->initconsspos = conshdlr->ninitconsskept;
2743  ++(conshdlr->ninitconsskept);
2744  }
2745  else
2746  conshdlr->initconss[c]->initconsspos = -1;
2747  }
2748 #ifndef NDEBUG
2749  for( ; c < conshdlr->ninitconss; ++c )
2750  assert(conshdlr->initconss[c]->initconsspos < conshdlr->ninitconsskept);
2751 #endif
2752  conshdlr->ninitconss = conshdlr->ninitconsskept;
2753 
2754  if( conshdlr->ninitconss == 0 )
2755  {
2756  BMSfreeMemoryArrayNull(&conshdlr->initconss);
2757  conshdlr->initconsssize = 0;
2758  }
2759  }
2760 
2761  return SCIP_OKAY;
2762 }
2763 
2764 /** calls separator method of constraint handler to separate LP solution */
2766  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2767  BMS_BLKMEM* blkmem, /**< block memory */
2768  SCIP_SET* set, /**< global SCIP settings */
2769  SCIP_STAT* stat, /**< dynamic problem statistics */
2770  SCIP_SEPASTORE* sepastore, /**< separation storage */
2771  int depth, /**< depth of current node */
2772  SCIP_Bool execdelayed, /**< execute separation method even if it is marked to be delayed */
2773  SCIP_RESULT* result /**< pointer to store the result of the callback method */
2774  )
2775 {
2776  assert(conshdlr != NULL);
2777  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
2778  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
2779  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
2780  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
2781  assert(stat != NULL);
2782  assert(conshdlr->lastsepalpcount != stat->lpcount
2783  || (0 <= conshdlr->lastnusefulsepaconss && conshdlr->lastnusefulsepaconss <= conshdlr->nusefulsepaconss));
2784  assert(set != NULL);
2785  assert(result != NULL);
2786 
2787  *result = SCIP_DIDNOTRUN;
2788 
2789  if( conshdlr->conssepalp != NULL
2790  && ((depth == 0 && conshdlr->sepafreq == 0)
2791  || (conshdlr->sepafreq > 0 && depth % conshdlr->sepafreq == 0)
2792  || conshdlr->sepalpwasdelayed) )
2793  {
2794  /* check, if separation method should be delayed */
2795  if( !conshdlr->delaysepa || execdelayed )
2796  {
2797  int nconss;
2798  int nusefulconss;
2799  int firstcons;
2800 
2801  /* check, if this LP solution was already separated */
2802  if( conshdlr->lastsepalpcount == stat->lpcount )
2803  {
2804  /* all constraints that were not yet separated on the new LP solution must be useful constraints, which means,
2805  * that the new constraints are the last constraints of the useful ones
2806  */
2807  nconss = conshdlr->nusefulsepaconss - conshdlr->lastnusefulsepaconss;
2808  nusefulconss = nconss;
2809  firstcons = conshdlr->lastnusefulsepaconss;
2810  }
2811  else
2812  {
2813  /* on a new LP solution, we want to separate all constraints */
2814  nconss = conshdlr->nsepaconss;
2815  nusefulconss = conshdlr->nusefulsepaconss;
2816  firstcons = 0;
2817  }
2818  assert(firstcons >= 0);
2819  assert(firstcons + nconss <= conshdlr->nsepaconss);
2820  assert(nusefulconss <= nconss);
2821 
2822  /* constraint handlers without constraints should only be called once */
2823  if( nconss > 0 || (!conshdlr->needscons && conshdlr->lastsepalpcount != stat->lpcount) )
2824  {
2825  SCIP_CONS** conss;
2826  SCIP_Longint oldndomchgs;
2827  SCIP_Longint oldnprobdomchgs;
2828  SCIP_Longint lastsepalpcount;
2829  int oldncuts;
2830  int oldnactiveconss;
2831  int lastnusefulsepaconss;
2832 
2833  SCIPdebugMessage("separating constraints %d to %d of %d constraints of handler <%s> (%s LP solution)\n",
2834  firstcons, firstcons + nconss - 1, conshdlr->nsepaconss, conshdlr->name,
2835  conshdlr->lastsepalpcount == stat->lpcount ? "old" : "new");
2836 
2837  /* remember the number of processed constraints on the current LP solution */
2838  lastsepalpcount = stat->lpcount;
2839  lastnusefulsepaconss = conshdlr->nusefulsepaconss;
2840 
2841  /* get the array of the constraints to be processed */
2842  conss = &(conshdlr->sepaconss[firstcons]);
2843 
2844  oldndomchgs = stat->nboundchgs + stat->nholechgs;
2845  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
2846  oldncuts = SCIPsepastoreGetNCuts(sepastore);
2847  oldnactiveconss = stat->nactiveconss;
2848 
2849  /* check, if we want to use eager evaluation */
2850  if( (conshdlr->eagerfreq == 0 && conshdlr->nsepacalls == 0)
2851  || (conshdlr->eagerfreq > 0 && conshdlr->nsepacalls % conshdlr->eagerfreq == 0) )
2852  nusefulconss = nconss;
2853 
2854  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2855  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2856  * external method; to avoid this, these changes will be buffered and processed after the method call
2857  */
2858  conshdlrDelayUpdates(conshdlr);
2859  conshdlr->duringsepa = TRUE;
2860 
2861  /* start timing */
2862  SCIPclockStart(conshdlr->sepatime, set);
2863 
2864  /* call external method */
2865  SCIP_CALL( conshdlr->conssepalp(set->scip, conshdlr, conss, nconss, nusefulconss, result) );
2866  SCIPdebugMessage(" -> separating LP returned result <%d>\n", *result);
2867 
2868  /* stop timing */
2869  SCIPclockStop(conshdlr->sepatime, set);
2870 
2871  /* perform the cached constraint updates */
2872  conshdlr->duringsepa = FALSE;
2873  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
2874 
2875  /* update statistics */
2876  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
2877  {
2878  conshdlr->lastsepalpcount = lastsepalpcount;
2879  conshdlr->lastnusefulsepaconss = MIN(lastnusefulsepaconss, conshdlr->nusefulsepaconss);
2880  conshdlr->nsepacalls++;
2881  }
2882  if( *result == SCIP_CUTOFF )
2883  conshdlr->ncutoffs++;
2884  conshdlr->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
2885  conshdlr->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
2886 
2887  /* update domain reductions; therefore remove the domain
2888  * reduction counts which were generated in probing mode */
2889  conshdlr->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
2890  conshdlr->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
2891 
2892  /* evaluate result */
2893  if( *result != SCIP_CUTOFF
2894  && *result != SCIP_CONSADDED
2895  && *result != SCIP_REDUCEDDOM
2896  && *result != SCIP_SEPARATED
2897  && *result != SCIP_NEWROUND
2898  && *result != SCIP_DIDNOTFIND
2899  && *result != SCIP_DIDNOTRUN
2900  && *result != SCIP_DELAYED )
2901  {
2902  SCIPerrorMessage("LP separation method of constraint handler <%s> returned invalid result <%d>\n",
2903  conshdlr->name, *result);
2904  return SCIP_INVALIDRESULT;
2905  }
2906  }
2907  }
2908  else
2909  {
2910  SCIPdebugMessage("LP separation method of constraint handler <%s> was delayed\n", conshdlr->name);
2911  *result = SCIP_DELAYED;
2912  }
2913 
2914  /* remember whether separation method was delayed */
2915  conshdlr->sepalpwasdelayed = (*result == SCIP_DELAYED);
2916  }
2917 
2918  return SCIP_OKAY;
2919 }
2920 
2921 /** calls separator method of constraint handler to separate given primal solution */
2923  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2924  BMS_BLKMEM* blkmem, /**< block memory */
2925  SCIP_SET* set, /**< global SCIP settings */
2926  SCIP_STAT* stat, /**< dynamic problem statistics */
2927  SCIP_SEPASTORE* sepastore, /**< separation storage */
2928  SCIP_SOL* sol, /**< primal solution that should be separated */
2929  int depth, /**< depth of current node */
2930  SCIP_Bool execdelayed, /**< execute separation method even if it is marked to be delayed */
2931  SCIP_RESULT* result /**< pointer to store the result of the callback method */
2932  )
2933 {
2934  assert(conshdlr != NULL);
2935  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
2936  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
2937  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
2938  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
2939  assert(set != NULL);
2940  assert(stat != NULL);
2941  assert(result != NULL);
2942 
2943  *result = SCIP_DIDNOTRUN;
2944 
2945  if( conshdlr->conssepasol != NULL
2946  && ((depth == 0 && conshdlr->sepafreq == 0)
2947  || (conshdlr->sepafreq > 0 && depth % conshdlr->sepafreq == 0)
2948  || conshdlr->sepasolwasdelayed) )
2949  {
2950  /* check, if separation method should be delayed */
2951  if( !conshdlr->delaysepa || execdelayed )
2952  {
2953  int nconss;
2954  int nusefulconss;
2955 
2956  /* always separate all constraints */
2957  nconss = conshdlr->nsepaconss;
2958  nusefulconss = conshdlr->nusefulsepaconss;
2959  assert(nusefulconss <= nconss);
2960 
2961  if( nconss > 0 || !conshdlr->needscons )
2962  {
2963  SCIP_CONS** conss;
2964  SCIP_Longint oldndomchgs;
2965  SCIP_Longint oldnprobdomchgs;
2966  int oldncuts;
2967  int oldnactiveconss;
2968 
2969  SCIPdebugMessage("separating %d constraints of handler <%s> (primal solution %p)\n",
2970  nconss, conshdlr->name, (void*)sol);
2971 
2972  /* get the array of the constraints to be processed */
2973  conss = conshdlr->sepaconss;
2974 
2975  oldndomchgs = stat->nboundchgs + stat->nholechgs;
2976  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
2977  oldncuts = SCIPsepastoreGetNCuts(sepastore);
2978  oldnactiveconss = stat->nactiveconss;
2979 
2980  /* check, if we want to use eager evaluation */
2981  if( (conshdlr->eagerfreq == 0 && conshdlr->nsepacalls == 0)
2982  || (conshdlr->eagerfreq > 0 && conshdlr->nsepacalls % conshdlr->eagerfreq == 0) )
2983  nusefulconss = nconss;
2984 
2985  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
2986  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
2987  * external method; to avoid this, these changes will be buffered and processed after the method call
2988  */
2989  conshdlrDelayUpdates(conshdlr);
2990  conshdlr->duringsepa = TRUE;
2991 
2992  /* start timing */
2993  SCIPclockStart(conshdlr->sepatime, set);
2994 
2995  /* call external method */
2996  SCIP_CALL( conshdlr->conssepasol(set->scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
2997  SCIPdebugMessage(" -> separating sol returned result <%d>\n", *result);
2998 
2999  /* stop timing */
3000  SCIPclockStop(conshdlr->sepatime, set);
3001 
3002  /* perform the cached constraint updates */
3003  conshdlr->duringsepa = FALSE;
3004  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3005 
3006  /* update statistics */
3007  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
3008  conshdlr->nsepacalls++;
3009  if( *result == SCIP_CUTOFF )
3010  conshdlr->ncutoffs++;
3011  conshdlr->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
3012  conshdlr->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
3013 
3014  /* update domain reductions; therefore remove the domain
3015  * reduction counts which were generated in probing mode */
3016  conshdlr->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
3017  conshdlr->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
3018 
3019  /* evaluate result */
3020  if( *result != SCIP_CUTOFF
3021  && *result != SCIP_CONSADDED
3022  && *result != SCIP_REDUCEDDOM
3023  && *result != SCIP_SEPARATED
3024  && *result != SCIP_NEWROUND
3025  && *result != SCIP_DIDNOTFIND
3026  && *result != SCIP_DIDNOTRUN
3027  && *result != SCIP_DELAYED )
3028  {
3029  SCIPerrorMessage("SOL separation method of constraint handler <%s> returned invalid result <%d>\n",
3030  conshdlr->name, *result);
3031  return SCIP_INVALIDRESULT;
3032  }
3033  }
3034  }
3035  else
3036  {
3037  SCIPdebugMessage("SOL separation method of constraint handler <%s> was delayed\n", conshdlr->name);
3038  *result = SCIP_DELAYED;
3039  }
3040 
3041  /* remember whether separation method was delayed */
3042  conshdlr->sepasolwasdelayed = (*result == SCIP_DELAYED);
3043  }
3044 
3045  return SCIP_OKAY;
3046 }
3047 
3048 /** calls enforcing method of constraint handler for LP solution for all constraints added after last
3049  * conshdlrResetEnfo() call
3050  */
3052  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3053  BMS_BLKMEM* blkmem, /**< block memory */
3054  SCIP_SET* set, /**< global SCIP settings */
3055  SCIP_STAT* stat, /**< dynamic problem statistics */
3056  SCIP_TREE* tree, /**< branch and bound tree */
3057  SCIP_SEPASTORE* sepastore, /**< separation storage */
3058  SCIP_Bool solinfeasible, /**< was the solution already found out to be infeasible? */
3059  SCIP_RESULT* result /**< pointer to store the result of the callback method */
3060  )
3061 {
3062  assert(conshdlr != NULL);
3063  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
3064  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
3065  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
3066  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
3067  assert(stat != NULL);
3068  assert(conshdlr->lastenfolplpcount != stat->lpcount
3069  || conshdlr->lastenfolpdomchgcount != stat->domchgcount
3070  || conshdlr->lastenfolpnode != stat->nnodes
3071  || (0 <= conshdlr->lastnusefulenfoconss && conshdlr->lastnusefulenfoconss <= conshdlr->nusefulenfoconss));
3072  assert(set != NULL);
3073  assert(tree != NULL);
3074  assert(tree->nchildren == 0);
3075  assert(result != NULL);
3076 
3077  *result = SCIP_FEASIBLE;
3078 
3079  if( conshdlr->consenfolp != NULL )
3080  {
3081  int nconss;
3082  int nusefulconss;
3083  int firstcons;
3084  SCIP_Bool lpchanged;
3085  SCIP_Bool lastinfeasible;
3086 
3087  /* check, if this LP solution was already enforced at this node */
3088  if( conshdlr->lastenfolplpcount == stat->lpcount
3089  && conshdlr->lastenfolpdomchgcount == stat->domchgcount
3090  && conshdlr->lastenfolpnode == stat->nnodes
3091  && conshdlr->lastenfolpresult != SCIP_CONSADDED )
3092  {
3093  assert(conshdlr->lastenfolpresult == SCIP_FEASIBLE || conshdlr->lastenfolpresult == SCIP_INFEASIBLE
3094  || conshdlr->lastenfolpresult == SCIP_SEPARATED );
3095 
3096  /* if we already enforced the same pseudo solution at this node, we will only enforce new constraints in the
3097  * following; however, the result of the last call for the old constraint is still valid and we have to ensure
3098  * that an infeasibility in the last call is not lost because we only enforce new constraints
3099  */
3100  if( conshdlr->lastenfolpresult == SCIP_FEASIBLE )
3101  lastinfeasible = FALSE;
3102  else
3103  {
3104  assert(conshdlr->lastenfolpresult == SCIP_INFEASIBLE || conshdlr->lastenfolpresult == SCIP_SEPARATED);
3105  *result = SCIP_INFEASIBLE;
3106  lastinfeasible = TRUE;
3107  }
3108 
3109  /* all constraints that were not yet enforced on the new LP solution must be useful constraints, which means,
3110  * that the new constraints are the last constraints of the useful ones
3111  */
3112  nconss = conshdlr->nusefulenfoconss - conshdlr->lastnusefulenfoconss;
3113  nusefulconss = nconss;
3114  firstcons = conshdlr->lastnusefulenfoconss;
3115  lpchanged = FALSE;
3116  }
3117  else
3118  {
3119  /* on a new LP solution or a new node, we want to enforce all constraints */
3120  nconss = conshdlr->nenfoconss;
3121  nusefulconss = conshdlr->nusefulenfoconss;
3122  firstcons = 0;
3123  lpchanged = TRUE;
3124  lastinfeasible = FALSE;
3125  }
3126  assert(firstcons >= 0);
3127  assert(firstcons + nconss <= conshdlr->nenfoconss);
3128  assert(nusefulconss <= nconss);
3129 
3130  /* constraint handlers without constraints should only be called once */
3131  if( nconss > 0 || (!conshdlr->needscons && lpchanged) )
3132  {
3133  SCIP_CONS** conss;
3134  SCIP_Longint oldndomchgs;
3135  SCIP_Longint oldnprobdomchgs;
3136  int oldncuts;
3137  int oldnactiveconss;
3138 
3139  SCIPdebugMessage("enforcing constraints %d to %d of %d constraints of handler <%s> (%s LP solution)\n",
3140  firstcons, firstcons + nconss - 1, conshdlr->nenfoconss, conshdlr->name, lpchanged ? "new" : "old");
3141 
3142  /* remember the number of processed constraints on the current LP solution */
3143  conshdlr->lastenfolplpcount = stat->lpcount;
3144  conshdlr->lastenfolpdomchgcount = stat->domchgcount;
3145  conshdlr->lastenfolpnode = stat->nnodes;
3146  conshdlr->lastnusefulenfoconss = conshdlr->nusefulenfoconss;
3147 
3148  /* get the array of the constraints to be processed */
3149  conss = &(conshdlr->enfoconss[firstcons]);
3150 
3151  oldncuts = SCIPsepastoreGetNCuts(sepastore);
3152  oldnactiveconss = stat->nactiveconss;
3153  oldndomchgs = stat->nboundchgs + stat->nholechgs;
3154  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
3155 
3156  /* check, if we want to use eager evaluation */
3157  if( (conshdlr->eagerfreq == 0 && conshdlr->nenfolpcalls == 0)
3158  || (conshdlr->eagerfreq > 0 && conshdlr->nenfolpcalls % conshdlr->eagerfreq == 0) )
3159  nusefulconss = nconss;
3160 
3161  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3162  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3163  * external method; to avoid this, these changes will be buffered and processed after the method call
3164  */
3165  conshdlrDelayUpdates(conshdlr);
3166 
3167  /* start timing */
3168  SCIPclockStart(conshdlr->enfolptime, set);
3169 
3170  /* call external method */
3171  SCIP_CALL( conshdlr->consenfolp(set->scip, conshdlr, conss, nconss, nusefulconss, solinfeasible, result) );
3172  SCIPdebugMessage(" -> enforcing returned result <%d>\n", *result);
3173 
3174  /* stop timing */
3175  SCIPclockStop(conshdlr->enfolptime, set);
3176 
3177  /* perform the cached constraint updates */
3178  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3179 
3180  /* remember the result of the enforcement call */
3181  conshdlr->lastenfolpresult = *result;
3182 
3183  /* update statistics */
3184  if( *result != SCIP_DIDNOTRUN )
3185  conshdlr->nenfolpcalls++;
3186  if( *result == SCIP_CUTOFF )
3187  conshdlr->ncutoffs++;
3188  conshdlr->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
3189  conshdlr->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
3190  if( *result != SCIP_BRANCHED )
3191  {
3192  assert(tree->nchildren == 0);
3193 
3194  /* update domain reductions; therefore remove the domain
3195  * reduction counts which were generated in probing mode */
3196  conshdlr->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
3197  conshdlr->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
3198  }
3199  else
3200  conshdlr->nchildren += tree->nchildren;
3201 
3202  /* evaluate result */
3203  if( *result != SCIP_CUTOFF
3204  && *result != SCIP_CONSADDED
3205  && *result != SCIP_REDUCEDDOM
3206  && *result != SCIP_SEPARATED
3207  && *result != SCIP_BRANCHED
3208  && *result != SCIP_INFEASIBLE
3209  && *result != SCIP_FEASIBLE )
3210  {
3211  SCIPerrorMessage("enforcing method of constraint handler <%s> for LP solutions returned invalid result <%d>\n",
3212  conshdlr->name, *result);
3213  return SCIP_INVALIDRESULT;
3214  }
3215 
3216  /* if the same LP solution was already enforced at this node, we only enforced new constraints this time;
3217  * if the enfolp call returns feasible now, the solution is only feasible w.r.t. the new constraints, if the
3218  * last call detected infeasibility for the old constraints, we have to change the result to infeasible
3219  */
3220  if( lastinfeasible && *result == SCIP_FEASIBLE )
3221  *result = SCIP_INFEASIBLE;
3222  }
3223  }
3224 
3225  return SCIP_OKAY;
3226 }
3227 
3228 /** calls enforcing method of constraint handler for pseudo solution for all constraints added after last
3229  * conshdlrResetEnfo() call
3230  */
3232  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3233  BMS_BLKMEM* blkmem, /**< block memory */
3234  SCIP_SET* set, /**< global SCIP settings */
3235  SCIP_STAT* stat, /**< dynamic problem statistics */
3236  SCIP_TREE* tree, /**< branch and bound tree */
3237  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
3238  SCIP_Bool solinfeasible, /**< was the solution already found out to be infeasible? */
3239  SCIP_Bool objinfeasible, /**< is the solution infeasible anyway due to violating lower objective bound? */
3240  SCIP_Bool forced, /**< should enforcement of pseudo solution be forced? */
3241  SCIP_RESULT* result /**< pointer to store the result of the callback method */
3242  )
3243 {
3244  assert(conshdlr != NULL);
3245  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
3246  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
3247  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
3248  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
3249  assert(stat != NULL);
3250  assert(conshdlr->lastenfopsdomchgcount != stat->domchgcount
3251  || conshdlr->lastenfopsnode != stat->nnodes
3252  || (0 <= conshdlr->lastnusefulenfoconss && conshdlr->lastnusefulenfoconss <= conshdlr->nusefulenfoconss));
3253  assert(set != NULL);
3254  assert(tree != NULL);
3255  assert(tree->nchildren == 0);
3256  assert(result != NULL);
3257 
3258  /* no enforcing of pseudo solution */
3259  if( set->cons_disableenfops && SCIPbranchcandGetNPseudoCands(branchcand) > 0 )
3260  {
3261  *result = SCIP_INFEASIBLE;
3262  return SCIP_OKAY;
3263  }
3264 
3265  *result = SCIP_FEASIBLE;
3266  if( conshdlr->consenfops != NULL )
3267  {
3268  int nconss;
3269  int nusefulconss;
3270  int firstcons;
3271  SCIP_Bool pschanged;
3272  SCIP_Bool lastinfeasible;
3273 
3274  /* check, if this pseudo solution was already enforced at this node */
3275  if( !forced && conshdlr->lastenfopsdomchgcount == stat->domchgcount
3276  && conshdlr->lastenfopsnode == stat->nnodes
3277  && conshdlr->lastenfopsresult != SCIP_CONSADDED
3278  && conshdlr->lastenfopsresult != SCIP_SOLVELP
3279  )
3280  {
3281  assert(conshdlr->lastenfopsresult != SCIP_CUTOFF);
3282  assert(conshdlr->lastenfopsresult != SCIP_BRANCHED);
3283  assert(conshdlr->lastenfopsresult != SCIP_REDUCEDDOM);
3284  assert(conshdlr->lastenfopsresult != SCIP_DIDNOTRUN || objinfeasible);
3285 
3286  /* if we already enforced the same pseudo solution at this node, we will only enforce new constraints in the
3287  * following; however, the result of the last call for the old constraint is still valid and we have to ensure
3288  * that an infeasibility in the last call is not lost because we only enforce new constraints
3289  */
3290  if( conshdlr->lastenfopsresult == SCIP_INFEASIBLE )
3291  {
3292  *result = SCIP_INFEASIBLE;
3293  lastinfeasible = TRUE;
3294  }
3295  else
3296  lastinfeasible = FALSE;
3297 
3298  /* all constraints that were not yet enforced on the new LP solution must be useful constraints, which means,
3299  * that the new constraints are the last constraints of the useful ones
3300  */
3301  nconss = conshdlr->nusefulenfoconss - conshdlr->lastnusefulenfoconss;
3302  nusefulconss = nconss;
3303  firstcons = conshdlr->lastnusefulenfoconss;
3304  pschanged = FALSE;
3305  }
3306  else
3307  {
3308  /* on a new pseudo solution or a new node, we want to enforce all constraints */
3309  nconss = conshdlr->nenfoconss;
3310  nusefulconss = conshdlr->nusefulenfoconss;
3311  firstcons = 0;
3312  pschanged = TRUE;
3313  lastinfeasible = FALSE;
3314  }
3315  assert(firstcons >= 0);
3316  assert(firstcons + nconss <= conshdlr->nenfoconss);
3317  assert(nusefulconss <= nconss);
3318 
3319  /* constraint handlers without constraints should only be called once */
3320  if( nconss > 0 || (!conshdlr->needscons && pschanged) )
3321  {
3322  SCIP_CONS** conss;
3323  SCIP_Longint oldndomchgs;
3324  SCIP_Longint oldnprobdomchgs;
3325 
3326  SCIPdebugMessage("enforcing constraints %d to %d of %d constraints of handler <%s> (%s pseudo solution, objinfeasible=%u)\n",
3327  firstcons, firstcons + nconss - 1, conshdlr->nenfoconss, conshdlr->name, pschanged ? "new" : "old", objinfeasible);
3328 
3329  /* remember the number of processed constraints on the current pseudo solution */
3330  conshdlr->lastenfopsdomchgcount = stat->domchgcount;
3331  conshdlr->lastenfopsnode = stat->nnodes;
3332  conshdlr->lastnusefulenfoconss = conshdlr->nusefulenfoconss;
3333 
3334  /* get the array of the constraints to be processed */
3335  conss = &(conshdlr->enfoconss[firstcons]);
3336 
3337  oldndomchgs = stat->nboundchgs + stat->nholechgs;
3338  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
3339 
3340  /* check, if we want to use eager evaluation */
3341  if( (conshdlr->eagerfreq == 0 && conshdlr->nenfopscalls == 0)
3342  || (conshdlr->eagerfreq > 0 && conshdlr->nenfopscalls % conshdlr->eagerfreq == 0) )
3343  nusefulconss = nconss;
3344 
3345  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3346  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3347  * external method; to avoid this, these changes will be buffered and processed after the method call
3348  */
3349  conshdlrDelayUpdates(conshdlr);
3350 
3351  /* start timing */
3352  SCIPclockStart(conshdlr->enfopstime, set);
3353 
3354  /* call external method */
3355  SCIP_CALL( conshdlr->consenfops(set->scip, conshdlr, conss, nconss, nusefulconss, solinfeasible, objinfeasible, result) );
3356  SCIPdebugMessage(" -> enforcing returned result <%d>\n", *result);
3357 
3358  /* stop timing */
3359  SCIPclockStop(conshdlr->enfopstime, set);
3360 
3361  /* perform the cached constraint updates */
3362  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3363 
3364  /* update statistics */
3365  if( *result != SCIP_DIDNOTRUN )
3366  conshdlr->nenfopscalls++;
3367  else if( !objinfeasible )
3368  {
3369  SCIPerrorMessage("enforcing method of constraint handler <%s> for pseudo solutions was skipped, even though the solution was not objective-infeasible\n",
3370  conshdlr->name);
3371  conshdlr->lastenfopsresult = *result;
3372 
3373  return SCIP_INVALIDRESULT;
3374  }
3375  /* A constraint handler might return SCIP_DIDNOTRUN and not check any constraints in case objinfeasible was
3376  * TRUE; we change the result pointer to SCIP_INFEASIBLE in this case.
3377  */
3378  else
3379  *result = SCIP_INFEASIBLE;
3380 
3381  if( *result == SCIP_CUTOFF )
3382  conshdlr->ncutoffs++;
3383 
3384  if( *result != SCIP_BRANCHED )
3385  {
3386  assert(tree->nchildren == 0);
3387 
3388  /* update domain reductions; therefore remove the domain
3389  * reduction counts which were generated in probing mode */
3390  conshdlr->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
3391  conshdlr->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
3392  }
3393  else
3394  conshdlr->nchildren += tree->nchildren;
3395 
3396  /* remember the result of the enforcement call */
3397  conshdlr->lastenfopsresult = *result;
3398 
3399  /* evaluate result */
3400  if( *result != SCIP_CUTOFF
3401  && *result != SCIP_CONSADDED
3402  && *result != SCIP_REDUCEDDOM
3403  && *result != SCIP_BRANCHED
3404  && *result != SCIP_SOLVELP
3405  && *result != SCIP_INFEASIBLE
3406  && *result != SCIP_FEASIBLE
3407  && *result != SCIP_DIDNOTRUN )
3408  {
3409  SCIPerrorMessage("enforcing method of constraint handler <%s> for pseudo solutions returned invalid result <%d>\n",
3410  conshdlr->name, *result);
3411  return SCIP_INVALIDRESULT;
3412  }
3413 
3414  /* if the same pseudo solution was already enforced at this node, we only enforced new constraints this time;
3415  * if the enfops call returns feasible now, the solution is only feasible w.r.t. the new constraints, if the
3416  * last call detected infeasibility for the old constraints, we have to change the result to infeasible
3417  */
3418  if( lastinfeasible && *result == SCIP_FEASIBLE )
3419  *result = SCIP_INFEASIBLE;
3420  }
3421  }
3422 
3423  return SCIP_OKAY;
3424 }
3425 
3426 /** calls feasibility check method of constraint handler */
3428  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3429  BMS_BLKMEM* blkmem, /**< block memory */
3430  SCIP_SET* set, /**< global SCIP settings */
3431  SCIP_STAT* stat, /**< dynamic problem statistics */
3432  SCIP_SOL* sol, /**< primal CIP solution */
3433  SCIP_Bool checkintegrality, /**< has integrality to be checked? */
3434  SCIP_Bool checklprows, /**< have current LP rows to be checked? */
3435  SCIP_Bool printreason, /**< should the reason for the violation be printed? */
3436  SCIP_RESULT* result /**< pointer to store the result of the callback method */
3437  )
3438 {
3439  assert(conshdlr != NULL);
3440  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
3441  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
3442  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
3443  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
3444  assert(set != NULL);
3445  assert(result != NULL);
3446 
3447  *result = SCIP_FEASIBLE;
3448 
3449  if( conshdlr->conscheck != NULL && (!conshdlr->needscons || conshdlr->ncheckconss > 0) )
3450  {
3451  SCIPdebugMessage("checking %d constraints of handler <%s>\n", conshdlr->ncheckconss, conshdlr->name);
3452 
3453  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3454  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3455  * external method; to avoid this, these changes will be buffered and processed after the method call
3456  */
3457  conshdlrDelayUpdates(conshdlr);
3458 
3459  /* start timing */
3460  SCIPclockStart(conshdlr->checktime, set);
3461 
3462  /* call external method */
3463  SCIP_CALL( conshdlr->conscheck(set->scip, conshdlr, conshdlr->checkconss, conshdlr->ncheckconss,
3464  sol, checkintegrality, checklprows, printreason, result) );
3465  SCIPdebugMessage(" -> checking returned result <%d>\n", *result);
3466 
3467  /* stop timing */
3468  SCIPclockStop(conshdlr->checktime, set);
3469 
3470  /* update statistics */
3471  conshdlr->ncheckcalls++;
3472 
3473 
3474 
3475  /* perform the cached constraint updates */
3476  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3477 
3478  /* evaluate result */
3479  if( *result != SCIP_INFEASIBLE
3480  && *result != SCIP_FEASIBLE )
3481  {
3482  SCIPerrorMessage("feasibility check of constraint handler <%s> returned invalid result <%d>\n",
3483  conshdlr->name, *result);
3484  return SCIP_INVALIDRESULT;
3485  }
3486  }
3487 
3488  return SCIP_OKAY;
3489 }
3490 
3491 /** calls propagation method of constraint handler */
3493  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3494  BMS_BLKMEM* blkmem, /**< block memory */
3495  SCIP_SET* set, /**< global SCIP settings */
3496  SCIP_STAT* stat, /**< dynamic problem statistics */
3497  int depth, /**< depth of current node */
3498  SCIP_Bool fullpropagation, /**< should all constraints be propagated (or only new ones)? */
3499  SCIP_Bool execdelayed, /**< execute propagation method even if it is marked to be delayed */
3500  SCIP_Bool instrongbranching, /**< are we currently doing strong branching? */
3501  SCIP_PROPTIMING proptiming, /**< current point in the node solving process */
3502  SCIP_RESULT* result /**< pointer to store the result of the callback method */
3503  )
3504 {
3505  assert(conshdlr != NULL);
3506  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
3507  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
3508  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
3509  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
3510  assert(stat != NULL);
3511  assert(conshdlr->lastpropdomchgcount != stat->domchgcount
3512  || (0 <= conshdlr->lastnusefulpropconss && conshdlr->lastnusefulpropconss <= conshdlr->nusefulpropconss));
3513  assert(set != NULL);
3514  assert(depth >= 0);
3515  assert(result != NULL);
3516 
3517  *result = SCIP_DIDNOTRUN;
3518 
3519  if( conshdlr->consprop != NULL
3520  && (!conshdlr->needscons || conshdlr->npropconss > 0)
3521  && ((depth == 0 && conshdlr->propfreq == 0)
3522  || (conshdlr->propfreq > 0 && depth % conshdlr->propfreq == 0)
3523  || conshdlr->propwasdelayed) )
3524  {
3525  /* check, if propagation method should be delayed */
3526  if( !conshdlr->delayprop || execdelayed )
3527  {
3528  int nconss;
3529  int nusefulconss;
3530  int nmarkedpropconss;
3531  int firstcons;
3532 
3533  nmarkedpropconss = conshdlr->nmarkedpropconss;
3534 
3535  /* check, if the current domains were already propagated */
3536  if( !fullpropagation && conshdlr->lastpropdomchgcount == stat->domchgcount )
3537  {
3538  /* all constraints that were not yet propagated on the new domains must be useful constraints, which means,
3539  * that the new constraints are the last constraints of the useful ones
3540  */
3541  nconss = conshdlr->nusefulpropconss - conshdlr->lastnusefulpropconss;
3542  nusefulconss = nconss;
3543  firstcons = conshdlr->lastnusefulpropconss;
3544  }
3545  else
3546  {
3547  /* on new domains, we want to propagate all constraints */
3548  nconss = conshdlr->npropconss;
3549  nusefulconss = conshdlr->nusefulpropconss;
3550  firstcons = 0;
3551  }
3552  assert(firstcons >= 0);
3553  assert(firstcons + nconss <= conshdlr->npropconss);
3554  assert(nusefulconss <= nconss);
3555 
3556  /* constraint handlers without constraints should only be called once */
3557  if( nconss > 0 || fullpropagation
3558  || (!conshdlr->needscons && conshdlr->lastpropdomchgcount != stat->domchgcount) )
3559  {
3560  SCIP_CONS** conss;
3561  SCIP_Longint oldndomchgs;
3562  SCIP_Longint oldnprobdomchgs;
3563  SCIP_Longint lastpropdomchgcount;
3564  int lastnusefulpropconss;
3565 
3566  SCIPdebugMessage("propagating constraints %d to %d of %d constraints of handler <%s> (%s pseudo solution, %d useful)\n",
3567  firstcons, firstcons + nconss - 1, conshdlr->npropconss, conshdlr->name,
3568  !fullpropagation && conshdlr->lastpropdomchgcount == stat->domchgcount ? "old" : "new", nusefulconss);
3569 
3570  /* remember the number of processed constraints on the current domains */
3571  lastpropdomchgcount = stat->domchgcount;
3572  lastnusefulpropconss = conshdlr->nusefulpropconss;
3573 
3574  /* get the array of the constraints to be processed */
3575  conss = &(conshdlr->propconss[firstcons]);
3576 
3577  oldndomchgs = stat->nboundchgs + stat->nholechgs;
3578  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
3579 
3580  /* check, if we want to use eager evaluation */
3581  if( (conshdlr->eagerfreq == 0 && conshdlr->npropcalls == 0)
3582  || (conshdlr->eagerfreq > 0 && conshdlr->npropcalls % conshdlr->eagerfreq == 0) )
3583  nusefulconss = nconss;
3584 
3585  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3586  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3587  * external method; to avoid this, these changes will be buffered and processed after the method call
3588  */
3589  conshdlrDelayUpdates(conshdlr);
3590  conshdlr->duringprop = TRUE;
3591 
3592  /* start timing */
3593  if( instrongbranching )
3594  SCIPclockStart(conshdlr->sbproptime, set);
3595  else
3596  SCIPclockStart(conshdlr->proptime, set);
3597 
3598  /* call external method */
3599  SCIP_CALL( conshdlr->consprop(set->scip, conshdlr, conss, nconss, nusefulconss, nmarkedpropconss, proptiming, result) );
3600  SCIPdebugMessage(" -> propagation returned result <%d>\n", *result);
3601 
3602  /* stop timing */
3603  if( instrongbranching )
3604  SCIPclockStop(conshdlr->sbproptime, set);
3605  else
3606  SCIPclockStop(conshdlr->proptime, set);
3607 
3608  /* perform the cached constraint updates */
3609  conshdlr->duringprop = FALSE;
3610  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3611 
3612  /* update statistics */
3613  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
3614  {
3615  conshdlr->lastpropdomchgcount = lastpropdomchgcount;
3616  conshdlr->lastnusefulpropconss = MIN(conshdlr->nusefulpropconss, lastnusefulpropconss);
3617  conshdlr->npropcalls++;
3618  }
3619  else
3620  {
3621  assert(lastpropdomchgcount == stat->domchgcount);
3622  assert(lastnusefulpropconss == conshdlr->nusefulpropconss);
3623  }
3624  if( *result == SCIP_CUTOFF )
3625  conshdlr->ncutoffs++;
3626 
3627  /* update domain reductions; therefore remove the domain
3628  * reduction counts which were generated in probing mode */
3629  conshdlr->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
3630  conshdlr->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
3631 
3632  /* check result code of callback method */
3633  if( *result != SCIP_CUTOFF
3634  && *result != SCIP_REDUCEDDOM
3635  && *result != SCIP_DIDNOTFIND
3636  && *result != SCIP_DIDNOTRUN
3637  && *result != SCIP_DELAYED )
3638  {
3639  SCIPerrorMessage("propagation method of constraint handler <%s> returned invalid result <%d>\n",
3640  conshdlr->name, *result);
3641  return SCIP_INVALIDRESULT;
3642  }
3643  }
3644  }
3645  else
3646  {
3647  SCIPdebugMessage("propagation method of constraint handler <%s> was delayed\n", conshdlr->name);
3648  *result = SCIP_DELAYED;
3649  }
3650 
3651  /* remember whether propagation method was delayed */
3652  conshdlr->propwasdelayed = (*result == SCIP_DELAYED);
3653  }
3654 
3655  return SCIP_OKAY;
3656 }
3657 
3658 /** calls presolving method of constraint handler */
3660  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3661  BMS_BLKMEM* blkmem, /**< block memory */
3662  SCIP_SET* set, /**< global SCIP settings */
3663  SCIP_STAT* stat, /**< dynamic problem statistics */
3664  SCIP_Bool execdelayed, /**< execute presolving method even if it is marked to be delayed */
3665  int nrounds, /**< number of presolving rounds already done */
3666  int* nfixedvars, /**< pointer to total number of variables fixed of all presolvers */
3667  int* naggrvars, /**< pointer to total number of variables aggregated of all presolvers */
3668  int* nchgvartypes, /**< pointer to total number of variable type changes of all presolvers */
3669  int* nchgbds, /**< pointer to total number of variable bounds tightened of all presolvers */
3670  int* naddholes, /**< pointer to total number of domain holes added of all presolvers */
3671  int* ndelconss, /**< pointer to total number of deleted constraints of all presolvers */
3672  int* naddconss, /**< pointer to total number of added constraints of all presolvers */
3673  int* nupgdconss, /**< pointer to total number of upgraded constraints of all presolvers */
3674  int* nchgcoefs, /**< pointer to total number of changed coefficients of all presolvers */
3675  int* nchgsides, /**< pointer to total number of changed left/right hand sides of all presolvers */
3676  SCIP_RESULT* result /**< pointer to store the result of the callback method */
3677  )
3678 {
3679  assert(conshdlr != NULL);
3680  assert(conshdlr->nusefulsepaconss <= conshdlr->nsepaconss);
3681  assert(conshdlr->nusefulenfoconss <= conshdlr->nenfoconss);
3682  assert(conshdlr->nusefulcheckconss <= conshdlr->ncheckconss);
3683  assert(conshdlr->nusefulpropconss <= conshdlr->npropconss);
3684  assert(set != NULL);
3685  assert(nfixedvars != NULL);
3686  assert(naggrvars != NULL);
3687  assert(nchgvartypes != NULL);
3688  assert(nchgbds != NULL);
3689  assert(naddholes != NULL);
3690  assert(ndelconss != NULL);
3691  assert(naddconss != NULL);
3692  assert(nupgdconss != NULL);
3693  assert(nchgcoefs != NULL);
3694  assert(nchgsides != NULL);
3695  assert(result != NULL);
3696 
3697  *result = SCIP_DIDNOTRUN;
3698 
3699  if( conshdlr->conspresol != NULL
3700  && (!conshdlr->needscons || conshdlr->nactiveconss > 0)
3701  && (conshdlr->maxprerounds == -1 || nrounds < conshdlr->maxprerounds || conshdlr->presolwasdelayed) )
3702  {
3703  SCIPdebugMessage("presolving %d constraints of handler <%s>\n", conshdlr->nactiveconss, conshdlr->name);
3704 
3705  /* check, if presolving method should be delayed */
3706  if( !conshdlr->delaypresol || execdelayed )
3707  {
3708  int nnewfixedvars;
3709  int nnewaggrvars;
3710  int nnewchgvartypes;
3711  int nnewchgbds;
3712  int nnewholes;
3713  int nnewdelconss;
3714  int nnewaddconss;
3715  int nnewupgdconss;
3716  int nnewchgcoefs;
3717  int nnewchgsides;
3718 
3719  /* calculate the number of changes since last call */
3720  nnewfixedvars = *nfixedvars - conshdlr->lastnfixedvars;
3721  nnewaggrvars = *naggrvars - conshdlr->lastnaggrvars;
3722  nnewchgvartypes = *nchgvartypes - conshdlr->lastnchgvartypes;
3723  nnewchgbds = *nchgbds - conshdlr->lastnchgbds;
3724  nnewholes = *naddholes - conshdlr->lastnaddholes;
3725  nnewdelconss = *ndelconss - conshdlr->lastndelconss;
3726  nnewaddconss = *naddconss - conshdlr->lastnaddconss;
3727  nnewupgdconss = *nupgdconss - conshdlr->lastnupgdconss;
3728  nnewchgcoefs = *nchgcoefs - conshdlr->lastnchgcoefs;
3729  nnewchgsides = *nchgsides - conshdlr->lastnchgsides;
3730 
3731  /* remember the old number of changes */
3732  conshdlr->lastnfixedvars = *nfixedvars;
3733  conshdlr->lastnaggrvars = *naggrvars;
3734  conshdlr->lastnchgvartypes = *nchgvartypes;
3735  conshdlr->lastnchgbds = *nchgbds;
3736  conshdlr->lastnaddholes = *naddholes;
3737  conshdlr->lastndelconss = *ndelconss;
3738  conshdlr->lastnaddconss = *naddconss;
3739  conshdlr->lastnupgdconss = *nupgdconss;
3740  conshdlr->lastnchgcoefs = *nchgcoefs;
3741  conshdlr->lastnchgsides = *nchgsides;
3742 
3743  /* because during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3744  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3745  * external method; to avoid this, these changes will be buffered and processed after the method call
3746  */
3747  conshdlrDelayUpdates(conshdlr);
3748 
3749  /* start timing */
3750  SCIPclockStart(conshdlr->presoltime, set);
3751 
3752  /* call external method */
3753  SCIP_CALL( conshdlr->conspresol(set->scip, conshdlr, conshdlr->conss, conshdlr->nactiveconss, nrounds,
3754  nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewholes,
3755  nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides,
3756  nfixedvars, naggrvars, nchgvartypes, nchgbds, naddholes,
3757  ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides, result) );
3758 
3759  /* stop timing */
3760  SCIPclockStop(conshdlr->presoltime, set);
3761 
3762  /* perform the cached constraint updates */
3763  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3764 
3765  /* count the new changes */
3766  conshdlr->nfixedvars += *nfixedvars - conshdlr->lastnfixedvars;
3767  conshdlr->naggrvars += *naggrvars - conshdlr->lastnaggrvars;
3768  conshdlr->nchgvartypes += *nchgvartypes - conshdlr->lastnchgvartypes;
3769  conshdlr->nchgbds += *nchgbds - conshdlr->lastnchgbds;
3770  conshdlr->naddholes += *naddholes - conshdlr->lastnaddholes;
3771  conshdlr->ndelconss += *ndelconss - conshdlr->lastndelconss;
3772  conshdlr->naddconss += *naddconss - conshdlr->lastnaddconss;
3773  conshdlr->nupgdconss += *nupgdconss - conshdlr->lastnupgdconss;
3774  conshdlr->nchgcoefs += *nchgcoefs - conshdlr->lastnchgcoefs;
3775  conshdlr->nchgsides += *nchgsides - conshdlr->lastnchgsides;
3776 
3777  /* check result code of callback method */
3778  if( *result != SCIP_CUTOFF
3779  && *result != SCIP_UNBOUNDED
3780  && *result != SCIP_SUCCESS
3781  && *result != SCIP_DIDNOTFIND
3782  && *result != SCIP_DIDNOTRUN
3783  && *result != SCIP_DELAYED )
3784  {
3785  SCIPerrorMessage("presolving method of constraint handler <%s> returned invalid result <%d>\n",
3786  conshdlr->name, *result);
3787  return SCIP_INVALIDRESULT;
3788  }
3789 
3790  /* increase the number of calls, if the presolving method tried to find reductions */
3791  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
3792  ++(conshdlr->npresolcalls);
3793  }
3794  else
3795  {
3796  SCIPdebugMessage("presolving method of constraint handler <%s> was delayed\n", conshdlr->name);
3797  *result = SCIP_DELAYED;
3798  }
3799 
3800  SCIPdebugMessage("after presolving %d constraints left of handler <%s>\n", conshdlr->nactiveconss, conshdlr->name);
3801 
3802  /* remember whether presolving method was delayed */
3803  conshdlr->presolwasdelayed = (*result == SCIP_DELAYED);
3804  }
3805 
3806  return SCIP_OKAY;
3807 }
3808 
3809 /** calls variable deletion method of constraint handler */
3811  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3812  BMS_BLKMEM* blkmem, /**< block memory */
3813  SCIP_SET* set, /**< global SCIP settings */
3814  SCIP_STAT* stat /**< dynamic problem statistics */
3815  )
3816 {
3817  assert(conshdlr != NULL);
3818  assert(set != NULL);
3819 
3820  if( conshdlr->consdelvars != NULL )
3821  {
3822  SCIPdebugMessage("deleting variables in constraints of handler <%s>\n", conshdlr->name);
3823 
3824  /* during constraint processing, constraints of this handler may be deleted, activated, deactivated,
3825  * enabled, disabled, marked obsolete or useful, which would change the conss array given to the
3826  * external method; to avoid this, these changes will be buffered and processed after the method call
3827  */
3828  conshdlrDelayUpdates(conshdlr);
3829 
3830  /* call external method */
3831  SCIP_CALL( conshdlr->consdelvars(set->scip, conshdlr, conshdlr->conss, conshdlr->nconss) );
3832 
3833  /* perform the cached constraint updates */
3834  SCIP_CALL( conshdlrForceUpdates(conshdlr, blkmem, set, stat) );
3835  }
3836 
3837  return SCIP_OKAY;
3838 }
3839 
3840 /** locks rounding of variables involved in the given constraint constraint handler that doesn't need constraints */
3842  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3843  SCIP_SET* set /**< global SCIP settings */
3844  )
3845 {
3846  assert(conshdlr != NULL);
3847  assert(conshdlr->conslock != NULL);
3848  assert(!conshdlr->needscons);
3849 
3850  SCIP_CALL( conshdlr->conslock(set->scip, conshdlr, NULL, +1, 0) );
3851 
3852  return SCIP_OKAY;
3853 }
3854 
3855 /** unlocks rounding of variables involved in the given constraint constraint handler that doesn't need constraints */
3857  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3858  SCIP_SET* set /**< global SCIP settings */
3859  )
3860 {
3861  assert(conshdlr != NULL);
3862  assert(conshdlr->conslock != NULL);
3863  assert(!conshdlr->needscons);
3864 
3865  SCIP_CALL( conshdlr->conslock(set->scip, conshdlr, NULL, -1, 0) );
3866 
3867  return SCIP_OKAY;
3868 }
3869 
3870 /** gets name of constraint handler */
3872  SCIP_CONSHDLR* conshdlr /**< constraint handler */
3873  )
3874 {
3875  assert(conshdlr != NULL);
3876 
3877  return conshdlr->name;
3878 }
3879 
3880 /** gets description of constraint handler */
3882  SCIP_CONSHDLR* conshdlr /**< constraint handler */
3883  )
3884 {
3885  assert(conshdlr != NULL);
3886 
3887  return conshdlr->desc;
3888 }
3889 
3890 /** gets user data of constraint handler */
3892  SCIP_CONSHDLR* conshdlr /**< constraint handler */
3893  )
3894 {
3895  assert(conshdlr != NULL);
3896 
3897  return conshdlr->conshdlrdata;
3898 }
3899 
3900 /** sets user data of constraint handler; user has to free old data in advance! */
3902  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3903  SCIP_CONSHDLRDATA* conshdlrdata /**< new constraint handler user data */
3904  )
3905 {
3906  assert(conshdlr != NULL);
3907 
3908  conshdlr->conshdlrdata = conshdlrdata;
3909 }
3910 
3911 /** sets all separation related callbacks of the constraint handler */
3913  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3914  SCIP_DECL_CONSSEPALP ((*conssepalp)), /**< separate cutting planes for LP solution */
3915  SCIP_DECL_CONSSEPASOL ((*conssepasol)), /**< separate cutting planes for arbitrary primal solution */
3916  int sepafreq, /**< frequency for separating cuts; zero means to separate only in the root node */
3917  int sepapriority, /**< priority of the constraint handler for separation */
3918  SCIP_Bool delaysepa /**< should separation method be delayed, if other separators found cuts? */
3919  )
3920 {
3921  assert(conshdlr != NULL);
3922 
3923  assert(conssepalp != NULL || conssepasol != NULL || sepafreq == -1);
3924 
3925  conshdlr->conssepalp = conssepalp;
3926  conshdlr->conssepasol = conssepasol;
3927  conshdlr->sepafreq = sepafreq;
3928  conshdlr->sepapriority = sepapriority;
3929  conshdlr->delaysepa = delaysepa;
3930 }
3931 
3932 /** sets both the propagation callback and the propagation frequency of the constraint handler */
3934  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3935  SCIP_DECL_CONSPROP ((*consprop)), /**< propagate variable domains */
3936  int propfreq, /**< frequency for propagating domains; zero means only preprocessing propagation */
3937  SCIP_Bool delayprop, /**< should propagation method be delayed, if other propagators found reductions? */
3938  SCIP_PROPTIMING timingmask /**< positions in the node solving loop where propagators should be executed */
3939  )
3940 {
3941  assert(conshdlr != NULL);
3942 
3943  assert(consprop != NULL || propfreq == -1);
3944 
3945  conshdlr->consprop = consprop;
3946  conshdlr->propfreq = propfreq;
3947  conshdlr->delayprop = delayprop;
3948  conshdlr->timingmask = timingmask;
3949 }
3950 
3951 /** sets copy method of both the constraint handler and each associated constraint */
3953  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3954  SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), /**< copy method of constraint handler or NULL if you don't want to copy your plugin into sub-SCIPs */
3955  SCIP_DECL_CONSCOPY ((*conscopy)) /**< constraint copying method */
3956  )
3957 {
3958  assert(conshdlr != NULL);
3959 
3960  assert(!conshdlr->needscons || (conshdlrcopy == NULL) == (conscopy == NULL));
3961 
3962  conshdlr->conshdlrcopy = conshdlrcopy;
3963  conshdlr->conscopy = conscopy;
3964 }
3965 
3966 /** sets destructor method of constraint handler */
3968  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3969  SCIP_DECL_CONSFREE ((*consfree)) /**< destructor of constraint handler */
3970  )
3971 {
3972  assert(conshdlr != NULL);
3973 
3974  conshdlr->consfree = consfree;
3975 }
3976 
3977 /** sets initialization method of constraint handler */
3979  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3980  SCIP_DECL_CONSINIT ((*consinit)) /**< initialize constraint handler */
3981  )
3982 {
3983  assert(conshdlr != NULL);
3984 
3985  conshdlr->consinit = consinit;
3986 }
3987 
3988 /** sets deinitialization method of constraint handler */
3990  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3991  SCIP_DECL_CONSEXIT ((*consexit)) /**< deinitialize constraint handler */
3992  )
3993 {
3994  assert(conshdlr != NULL);
3995 
3996  conshdlr->consexit = consexit;
3997 }
3998 
3999 /** sets solving process initialization method of constraint handler */
4001  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4002  SCIP_DECL_CONSINITSOL((*consinitsol)) /**< solving process initialization method of constraint handler */
4003  )
4004 {
4005  assert(conshdlr != NULL);
4006 
4007  conshdlr->consinitsol = consinitsol;
4008 }
4009 
4010 /** sets solving process deinitialization method of constraint handler */
4012  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4013  SCIP_DECL_CONSEXITSOL ((*consexitsol)) /**< solving process deinitialization method of constraint handler */
4014  )
4015 {
4016  assert(conshdlr != NULL);
4017 
4018  conshdlr->consexitsol = consexitsol;
4019 }
4020 
4021 /** sets preprocessing initialization method of constraint handler */
4023  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4024  SCIP_DECL_CONSINITPRE((*consinitpre)) /**< preprocessing initialization method of constraint handler */
4025  )
4026 {
4027  assert(conshdlr != NULL);
4028 
4029  conshdlr->consinitpre = consinitpre;
4030 }
4031 
4032 /** sets preprocessing deinitialization method of constraint handler */
4034  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4035  SCIP_DECL_CONSEXITPRE((*consexitpre)) /**< preprocessing deinitialization method of constraint handler */
4036  )
4037 {
4038  assert(conshdlr != NULL);
4039 
4040  conshdlr->consexitpre = consexitpre;
4041 }
4042 
4043 /** sets presolving method of constraint handler */
4045  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4046  SCIP_DECL_CONSPRESOL ((*conspresol)), /**< presolving method of constraint handler */
4047  int maxprerounds, /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
4048  SCIP_Bool delaypresol /**< should presolving method be delayed, if other presolvers found reductions? */
4049  )
4050 {
4051  assert(conshdlr != NULL);
4052 
4053  conshdlr->conspresol = conspresol;
4054  conshdlr->maxprerounds = maxprerounds;
4055  conshdlr->delaypresol = delaypresol;
4056 }
4057 
4058 /** sets method of constraint handler to free specific constraint data */
4060  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4061  SCIP_DECL_CONSDELETE ((*consdelete)) /**< free specific constraint data */
4062  )
4063 {
4064  assert(conshdlr != NULL);
4065 
4066  conshdlr->consdelete = consdelete;
4067 }
4068 
4069 /** sets method of constraint handler to transform constraint data into data belonging to the transformed problem */
4071  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4072  SCIP_DECL_CONSTRANS ((*constrans)) /**< transform constraint data into data belonging to the transformed problem */
4073  )
4074 {
4075  assert(conshdlr != NULL);
4076 
4077  conshdlr->constrans = constrans;
4078 }
4079 
4080 /** sets method of constraint handler to initialize LP with relaxations of "initial" constraints */
4082  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4083  SCIP_DECL_CONSINITLP ((*consinitlp)) /**< initialize LP with relaxations of "initial" constraints */
4084  )
4085 {
4086  assert(conshdlr != NULL);
4087 
4088  conshdlr->consinitlp = consinitlp;
4089 }
4090 
4091 /** sets propagation conflict resolving method of constraint handler */
4093  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4094  SCIP_DECL_CONSRESPROP ((*consresprop)) /**< propagation conflict resolving method */
4095  )
4096 {
4097  assert(conshdlr != NULL);
4098 
4099  conshdlr->consresprop = consresprop;
4100 }
4101 
4102 /** sets activation notification method of constraint handler */
4104  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4105  SCIP_DECL_CONSACTIVE ((*consactive)) /**< activation notification method */
4106  )
4107 {
4108  assert(conshdlr != NULL);
4109 
4110  conshdlr->consactive = consactive;
4111 }
4112 
4113 /** sets deactivation notification method of constraint handler */
4115  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4116  SCIP_DECL_CONSDEACTIVE((*consdeactive)) /**< deactivation notification method */
4117  )
4118 {
4119  assert(conshdlr != NULL);
4120 
4121  conshdlr->consdeactive = consdeactive;
4122 }
4123 
4124 /** sets enabling notification method of constraint handler */
4126  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4127  SCIP_DECL_CONSENABLE ((*consenable)) /**< enabling notification method */
4128  )
4129 {
4130  assert(conshdlr != NULL);
4131 
4132  conshdlr->consenable = consenable;
4133 }
4134 
4135 /** sets disabling notification method of constraint handler */
4137  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4138  SCIP_DECL_CONSDISABLE ((*consdisable)) /**< disabling notification method */
4139  )
4140 {
4141  assert(conshdlr != NULL);
4142 
4143  conshdlr->consdisable = consdisable;
4144 }
4145 
4146 /** sets variable deletion method of constraint handler */
4148  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4149  SCIP_DECL_CONSDELVARS ((*consdelvars)) /**< variable deletion method */
4150  )
4151 {
4152  assert(conshdlr != NULL);
4153 
4154  conshdlr->consdelvars = consdelvars;
4155 }
4156 
4157 /** sets constraint display method of constraint handler */
4159  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4160  SCIP_DECL_CONSPRINT ((*consprint)) /**< constraint display method */
4161  )
4162 {
4163  assert(conshdlr != NULL);
4164 
4165  conshdlr->consprint = consprint;
4166 }
4167 
4168 /** sets constraint parsing method of constraint handler */
4170  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4171  SCIP_DECL_CONSPARSE ((*consparse)) /**< constraint parsing method */
4172  )
4173 {
4174  assert(conshdlr != NULL);
4175 
4176  conshdlr->consparse = consparse;
4177 }
4178 
4179 /** sets constraint variable getter method of constraint handler */
4181  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4182  SCIP_DECL_CONSGETVARS ((*consgetvars)) /**< constraint variable getter method */
4183  )
4184 {
4185  assert(conshdlr != NULL);
4186 
4187  conshdlr->consgetvars = consgetvars;
4188 }
4189 
4190 /** sets constraint variable number getter method of constraint handler */
4192  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4193  SCIP_DECL_CONSGETNVARS((*consgetnvars)) /**< constraint variable number getter method */
4194  )
4195 {
4196  assert(conshdlr != NULL);
4197 
4198  conshdlr->consgetnvars = consgetnvars;
4199 }
4200 
4201 /** gets array with constraints of constraint handler; the first SCIPconshdlrGetNActiveConss() entries are the active
4202  * constraints, the last SCIPconshdlrGetNConss() - SCIPconshdlrGetNActiveConss() constraints are deactivated
4203  *
4204  * @note A constraint is active if it is global and was not removed or it was added locally (in that case the local
4205  * flag is TRUE) and the current node belongs to the corresponding sub tree.
4206  */
4208  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4209  )
4210 {
4211  assert(conshdlr != NULL);
4212 
4213  return conshdlr->conss;
4214 }
4215 
4216 /** gets array with enforced constraints of constraint handler; this is local information */
4218  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4219  )
4220 {
4221  assert(conshdlr != NULL);
4222 
4223  return conshdlr->enfoconss;
4224 }
4225 
4226 /** gets array with checked constraints of constraint handler; this is local information */
4228  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4229  )
4230 {
4231  assert(conshdlr != NULL);
4232 
4233  return conshdlr->checkconss;
4234 }
4235 
4236 /** gets total number of existing transformed constraints of constraint handler */
4238  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4239  )
4240 {
4241  assert(conshdlr != NULL);
4242 
4243  return conshdlr->nconss;
4244 }
4245 
4246 /** gets number of enforced constraints of constraint handler; this is local information */
4248  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4249  )
4250 {
4251  assert(conshdlr != NULL);
4252 
4253  return conshdlr->nenfoconss;
4254 }
4255 
4256 /** gets number of checked constraints of constraint handler; this is local information */
4258  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4259  )
4260 {
4261  assert(conshdlr != NULL);
4262 
4263  return conshdlr->ncheckconss;
4264 }
4265 
4266 /** gets number of active constraints of constraint handler
4267  *
4268  * @note A constraint is active if it is global and was not removed or it was added locally (in that case the local
4269  * flag is TRUE) and the current node belongs to the corresponding sub tree.
4270  */
4272  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4273  )
4274 {
4275  assert(conshdlr != NULL);
4276 
4277  return conshdlr->nactiveconss;
4278 }
4279 
4280 /** gets number of enabled constraints of constraint handler */
4282  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4283  )
4284 {
4285  assert(conshdlr != NULL);
4286 
4287  return conshdlr->nenabledconss;
4288 }
4289 
4290 /** gets time in seconds used for setting up this constraint handler for new stages */
4292  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4293  )
4294 {
4295  assert(conshdlr != NULL);
4296 
4297  return SCIPclockGetTime(conshdlr->setuptime);
4298 }
4299 
4300 /** gets time in seconds used for presolving in this constraint handler */
4302  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4303  )
4304 {
4305  assert(conshdlr != NULL);
4306 
4307  return SCIPclockGetTime(conshdlr->presoltime);
4308 }
4309 
4310 /** gets time in seconds used for separation in this constraint handler */
4312  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4313  )
4314 {
4315  assert(conshdlr != NULL);
4316 
4317  return SCIPclockGetTime(conshdlr->sepatime);
4318 }
4319 
4320 /** gets time in seconds used for LP enforcement in this constraint handler */
4322  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4323  )
4324 {
4325  assert(conshdlr != NULL);
4326 
4327  return SCIPclockGetTime(conshdlr->enfolptime);
4328 }
4329 
4330 /** gets time in seconds used for pseudo enforcement in this constraint handler */
4332  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4333  )
4334 {
4335  assert(conshdlr != NULL);
4336 
4337  return SCIPclockGetTime(conshdlr->enfopstime);
4338 }
4339 
4340 /** gets time in seconds used for propagation in this constraint handler */
4342  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4343  )
4344 {
4345  assert(conshdlr != NULL);
4346 
4347  return SCIPclockGetTime(conshdlr->proptime);
4348 }
4349 
4350 /** gets time in seconds used for propagation in this constraint handler during strong branching */
4352  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4353  )
4354 {
4355  assert(conshdlr != NULL);
4356 
4357  return SCIPclockGetTime(conshdlr->sbproptime);
4358 }
4359 
4360 /** gets time in seconds used for feasibility checking in this constraint handler */
4362  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4363  )
4364 {
4365  assert(conshdlr != NULL);
4366 
4367  return SCIPclockGetTime(conshdlr->checktime);
4368 }
4369 
4370 /** gets time in seconds used for resolving propagation in this constraint handler */
4372  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4373  )
4374 {
4375  assert(conshdlr != NULL);
4376 
4377  return SCIPclockGetTime(conshdlr->resproptime);
4378 }
4379 
4380 /** gets number of calls to the constraint handler's separation method */
4382  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4383  )
4384 {
4385  assert(conshdlr != NULL);
4386 
4387  return conshdlr->nsepacalls;
4388 }
4389 
4390 /** gets number of calls to the constraint handler's LP enforcing method */
4392  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4393  )
4394 {
4395  assert(conshdlr != NULL);
4396 
4397  return conshdlr->nenfolpcalls;
4398 }
4399 
4400 /** gets number of calls to the constraint handler's pseudo enforcing method */
4402  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4403  )
4404 {
4405  assert(conshdlr != NULL);
4406 
4407  return conshdlr->nenfopscalls;
4408 }
4409 
4410 /** gets number of calls to the constraint handler's propagation method */
4412  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4413  )
4414 {
4415  assert(conshdlr != NULL);
4416 
4417  return conshdlr->npropcalls;
4418 }
4419 
4420 /** gets number of calls to the constraint handler's checking method */
4422  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4423  )
4424 {
4425  assert(conshdlr != NULL);
4426 
4427  return conshdlr->ncheckcalls;
4428 }
4429 
4430 /** gets number of calls to the constraint handler's resolve propagation method */
4432  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4433  )
4434 {
4435  assert(conshdlr != NULL);
4436 
4437  return conshdlr->nrespropcalls;
4438 }
4439 
4440 /** gets total number of times, this constraint handler detected a cutoff */
4442  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4443  )
4444 {
4445  assert(conshdlr != NULL);
4446 
4447  return conshdlr->ncutoffs;
4448 }
4449 
4450 /** gets total number of cuts found by this constraint handler */
4452  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4453  )
4454 {
4455  assert(conshdlr != NULL);
4456 
4457  return conshdlr->ncutsfound;
4458 }
4459 
4460 /** gets total number of cuts found by this constraint handler applied to lp */
4462  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4463  )
4464 {
4465  assert(conshdlr != NULL);
4466 
4467  return conshdlr->ncutsapplied;
4468 }
4469 
4470 /** increase count of applied cuts */
4472  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4473  )
4474 {
4475  assert(conshdlr != NULL);
4476 
4477  ++conshdlr->ncutsapplied;
4478 }
4479 
4480 /** increase count of found cuts */
4482  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4483  )
4484 {
4485  assert(conshdlr != NULL);
4486 
4487  ++conshdlr->ncutsfound;
4488 }
4489 
4490 /** gets total number of additional constraints added by this constraint handler */
4492  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4493  )
4494 {
4495  assert(conshdlr != NULL);
4496 
4497  return conshdlr->nconssfound;
4498 }
4499 
4500 /** gets total number of domain reductions found by this constraint handler */
4502  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4503  )
4504 {
4505  assert(conshdlr != NULL);
4506 
4507  return conshdlr->ndomredsfound;
4508 }
4509 
4510 /** gets number of children created by this constraint handler */
4512  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4513  )
4514 {
4515  assert(conshdlr != NULL);
4516 
4517  return conshdlr->nchildren;
4518 }
4519 
4520 /** gets maximum number of active constraints of constraint handler existing at the same time */
4522  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4523  )
4524 {
4525  assert(conshdlr != NULL);
4526 
4527  return conshdlr->maxnactiveconss;
4528 }
4529 
4530 /** gets initial number of active constraints of constraint handler */
4532  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4533  )
4534 {
4535  assert(conshdlr != NULL);
4536 
4537  return conshdlr->startnactiveconss;
4538 }
4539 
4540 /** gets number of variables fixed in presolving method of constraint handler */
4542  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4543  )
4544 {
4545  assert(conshdlr != NULL);
4546 
4547  return conshdlr->nfixedvars;
4548 }
4549 
4550 /** gets number of variables aggregated in presolving method of constraint handler */
4552  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4553  )
4554 {
4555  assert(conshdlr != NULL);
4556 
4557  return conshdlr->naggrvars;
4558 }
4559 
4560 /** gets number of variable types changed in presolving method of constraint handler */
4562  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4563  )
4564 {
4565  assert(conshdlr != NULL);
4566 
4567  return conshdlr->nchgvartypes;
4568 }
4569 
4570 /** gets number of bounds changed in presolving method of constraint handler */
4572  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4573  )
4574 {
4575  assert(conshdlr != NULL);
4576 
4577  return conshdlr->nchgbds;
4578 }
4579 
4580 /** gets number of holes added to domains of variables in presolving method of constraint handler */
4582  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4583  )
4584 {
4585  assert(conshdlr != NULL);
4586 
4587  return conshdlr->naddholes;
4588 }
4589 
4590 /** gets number of constraints deleted in presolving method of constraint handler */
4592  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4593  )
4594 {
4595  assert(conshdlr != NULL);
4596 
4597  return conshdlr->ndelconss;
4598 }
4599 
4600 /** gets number of constraints added in presolving method of constraint handler */
4602  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4603  )
4604 {
4605  assert(conshdlr != NULL);
4606 
4607  return conshdlr->naddconss;
4608 }
4609 
4610 /** gets number of constraints upgraded in presolving method of constraint handler */
4612  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4613  )
4614 {
4615  assert(conshdlr != NULL);
4616 
4617  return conshdlr->nupgdconss;
4618 }
4619 
4620 /** gets number of coefficients changed in presolving method of constraint handler */
4622  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4623  )
4624 {
4625  assert(conshdlr != NULL);
4626 
4627  return conshdlr->nchgcoefs;
4628 }
4629 
4630 /** gets number of constraint sides changed in presolving method of constraint handler */
4632  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4633  )
4634 {
4635  assert(conshdlr != NULL);
4636 
4637  return conshdlr->nchgsides;
4638 }
4639 
4640 /** gets number of times the presolving method of the constraint handler was called and tried to find reductions */
4642  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4643  )
4644 {
4645  assert(conshdlr != NULL);
4646 
4647  return conshdlr->npresolcalls;
4648 }
4649 
4650 /** gets separation priority of constraint handler */
4652  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4653  )
4654 {
4655  assert(conshdlr != NULL);
4656 
4657  return conshdlr->sepapriority;
4658 }
4659 
4660 /** gets enforcing priority of constraint handler */
4662  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4663  )
4664 {
4665  assert(conshdlr != NULL);
4666 
4667  return conshdlr->enfopriority;
4668 }
4669 
4670 /** gets checking priority of constraint handler */
4672  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4673  )
4674 {
4675  assert(conshdlr != NULL);
4676 
4677  return conshdlr->checkpriority;
4678 }
4679 
4680 /** gets separation frequency of constraint handler */
4682  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4683  )
4684 {
4685  assert(conshdlr != NULL);
4686 
4687  return conshdlr->sepafreq;
4688 }
4689 
4690 /** gets propagation frequency of constraint handler */
4692  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4693  )
4694 {
4695  assert(conshdlr != NULL);
4696 
4697  return conshdlr->propfreq;
4698 }
4699 
4700 /** gets frequency of constraint handler for eager evaluations in separation, propagation and enforcement */
4702  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4703  )
4704 {
4705  assert(conshdlr != NULL);
4706 
4707  return conshdlr->eagerfreq;
4708 }
4709 
4710 /** needs constraint handler a constraint to be called? */
4712  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4713  )
4714 {
4715  assert(conshdlr != NULL);
4716 
4717  return conshdlr->needscons;
4718 }
4719 
4720 /** does the constraint handler perform presolving? */
4722  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4723  )
4724 {
4725  assert(conshdlr != NULL);
4726 
4727  return (conshdlr->conspresol != NULL);
4728 }
4729 
4730 /** should separation method be delayed, if other separators found cuts? */
4732  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4733  )
4734 {
4735  assert(conshdlr != NULL);
4736 
4737  return conshdlr->delaysepa;
4738 }
4739 
4740 /** should propagation method be delayed, if other propagators found reductions? */
4742  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4743  )
4744 {
4745  assert(conshdlr != NULL);
4746 
4747  return conshdlr->delayprop;
4748 }
4749 
4750 /** should presolving method be delayed, if other presolvers found reductions? */
4752  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4753  )
4754 {
4755  assert(conshdlr != NULL);
4756 
4757  return conshdlr->delaypresol;
4758 }
4759 
4760 /** was LP separation method delayed at the last call? */
4762  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4763  )
4764 {
4765  assert(conshdlr != NULL);
4766 
4767  return conshdlr->sepalpwasdelayed;
4768 }
4769 
4770 /** was primal solution separation method delayed at the last call? */
4772  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4773  )
4774 {
4775  assert(conshdlr != NULL);
4776 
4777  return conshdlr->sepasolwasdelayed;
4778 }
4779 
4780 /** was propagation method delayed at the last call? */
4782  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4783  )
4784 {
4785  assert(conshdlr != NULL);
4786 
4787  return conshdlr->propwasdelayed;
4788 }
4789 
4790 /** was presolving method delayed at the last call? */
4792  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4793  )
4794 {
4795  assert(conshdlr != NULL);
4796 
4797  return conshdlr->presolwasdelayed;
4798 }
4799 
4800 /** is constraint handler initialized? */
4802  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4803  )
4804 {
4805  assert(conshdlr != NULL);
4806 
4807  return conshdlr->initialized;
4808 }
4809 
4810 /** does the constraint handler have a copy function? */
4812  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4813  )
4814 {
4815  assert(conshdlr != NULL);
4816 
4817  return (conshdlr->conshdlrcopy != NULL);
4818 }
4819 
4820 /** returns the timing mask of the propagation method of the constraint handler */
4822  SCIP_CONSHDLR* conshdlr /**< constraint handler */
4823  )
4824 {
4825  assert(conshdlr != NULL);
4826 
4827  return conshdlr->timingmask;
4828 }
4829 
4830 
4831 
4832 /*
4833  * Constraint set change methods
4834  */
4835 
4836 /** creates empty constraint set change data */
4837 static
4839  SCIP_CONSSETCHG** conssetchg, /**< pointer to constraint set change data */
4840  BMS_BLKMEM* blkmem /**< block memory */
4841  )
4842 {
4843  assert(conssetchg != NULL);
4844  assert(blkmem != NULL);
4845 
4846  SCIP_ALLOC( BMSallocBlockMemory(blkmem, conssetchg) );
4847  (*conssetchg)->addedconss = NULL;
4848  (*conssetchg)->disabledconss = NULL;
4849  (*conssetchg)->addedconsssize = 0;
4850  (*conssetchg)->naddedconss = 0;
4851  (*conssetchg)->disabledconsssize = 0;
4852  (*conssetchg)->ndisabledconss = 0;
4853 
4854  return SCIP_OKAY;
4855 }
4856 
4857 /** releases all constraints of the constraint set change data */
4858 static
4860  SCIP_CONSSETCHG* conssetchg, /**< constraint set change data */
4861  BMS_BLKMEM* blkmem, /**< block memory */
4862  SCIP_SET* set /**< global SCIP settings */
4863  )
4864 {
4865  int i;
4866 
4867  assert(conssetchg != NULL);
4868 
4869  /* release constraints */
4870  for( i = 0; i < conssetchg->naddedconss; ++i )
4871  {
4872  if( conssetchg->addedconss[i] != NULL )
4873  {
4874  SCIP_CALL( SCIPconsRelease(&conssetchg->addedconss[i], blkmem, set) );
4875  }
4876  }
4877  for( i = 0; i < conssetchg->ndisabledconss; ++i )
4878  {
4879  if( conssetchg->disabledconss[i] != NULL )
4880  {
4881  SCIP_CALL( SCIPconsRelease(&conssetchg->disabledconss[i], blkmem, set) );
4882  }
4883  }
4884 
4885  return SCIP_OKAY;
4886 }
4887 
4888 /** frees constraint set change data and releases all included constraints */
4890  SCIP_CONSSETCHG** conssetchg, /**< pointer to constraint set change */
4891  BMS_BLKMEM* blkmem, /**< block memory */
4892  SCIP_SET* set /**< global SCIP settings */
4893  )
4894 {
4895  assert(conssetchg != NULL);
4896  assert(blkmem != NULL);
4897 
4898  if( *conssetchg != NULL )
4899  {
4900  /* release constraints */
4901  SCIP_CALL( conssetchgRelease(*conssetchg, blkmem, set) );
4902 
4903  /* free memory */
4904  BMSfreeBlockMemoryArrayNull(blkmem, &(*conssetchg)->addedconss, (*conssetchg)->addedconsssize);
4905  BMSfreeBlockMemoryArrayNull(blkmem, &(*conssetchg)->disabledconss, (*conssetchg)->disabledconsssize);
4906  BMSfreeBlockMemory(blkmem, conssetchg);
4907  }
4908 
4909  return SCIP_OKAY;
4910 }
4911 
4912 /** ensures, that addedconss array can store at least num entries */
4913 static
4915  SCIP_CONSSETCHG* conssetchg, /**< constraint set change data structure */
4916  BMS_BLKMEM* blkmem, /**< block memory */
4917  SCIP_SET* set, /**< global SCIP settings */
4918  int num /**< minimum number of entries to store */
4919  )
4920 {
4921  assert(conssetchg != NULL);
4922 
4923  if( num > conssetchg->addedconsssize )
4924  {
4925  int newsize;
4926 
4927  newsize = SCIPsetCalcMemGrowSize(set, num);
4928  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conssetchg->addedconss, conssetchg->addedconsssize, newsize) );
4929  conssetchg->addedconsssize = newsize;
4930  }
4931  assert(num <= conssetchg->addedconsssize);
4932 
4933  return SCIP_OKAY;
4934 }
4935 
4936 /** ensures, that disabledconss array can store at least num entries */
4937 static
4939  SCIP_CONSSETCHG* conssetchg, /**< constraint set change data structure */
4940  BMS_BLKMEM* blkmem, /**< block memory */
4941  SCIP_SET* set, /**< global SCIP settings */
4942  int num /**< minimum number of entries to store */
4943  )
4944 {
4945  assert(conssetchg != NULL);
4946 
4947  if( num > conssetchg->disabledconsssize )
4948  {
4949  int newsize;
4950 
4951  newsize = SCIPsetCalcMemGrowSize(set, num);
4952  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &conssetchg->disabledconss, conssetchg->disabledconsssize, newsize) );
4953  conssetchg->disabledconsssize = newsize;
4954  }
4955  assert(num <= conssetchg->disabledconsssize);
4956 
4957  return SCIP_OKAY;
4958 }
4959 
4960 /** adds constraint addition to constraint set changes, and captures constraint; activates constraint if the
4961  * constraint set change data is currently active
4962  */
4964  SCIP_CONSSETCHG** conssetchg, /**< pointer to constraint set change data structure */
4965  BMS_BLKMEM* blkmem, /**< block memory */
4966  SCIP_SET* set, /**< global SCIP settings */
4967  SCIP_STAT* stat, /**< dynamic problem statistics */
4968  SCIP_CONS* cons, /**< added constraint */
4969  int depth, /**< depth of constraint set change's node */
4970  SCIP_Bool focusnode, /**< does the constraint set change belong to the focus node? */
4971  SCIP_Bool active /**< is the constraint set change currently active? */
4972  )
4973 {
4974  assert(conssetchg != NULL);
4975  assert(cons != NULL);
4976 
4977  /* if constraint set change doesn't exist, create it */
4978  if( *conssetchg == NULL )
4979  {
4980  SCIP_CALL( conssetchgCreate(conssetchg, blkmem) );
4981  }
4982 
4983  /* add constraint to the addedconss array */
4984  SCIP_CALL( conssetchgEnsureAddedconssSize(*conssetchg, blkmem, set, (*conssetchg)->naddedconss+1) );
4985  (*conssetchg)->addedconss[(*conssetchg)->naddedconss] = cons;
4986  (*conssetchg)->naddedconss++;
4987 
4988  /* undelete constraint, if it was globally deleted in the past */
4989  cons->deleted = FALSE;
4990 
4991  /* capture constraint */
4992  SCIPconsCapture(cons);
4993 
4994  /* activate constraint, if node is active */
4995  if( active && !SCIPconsIsActive(cons) )
4996  {
4997  SCIP_CALL( SCIPconsActivate(cons, set, stat, depth, focusnode) );
4998  assert(SCIPconsIsActive(cons));
4999 
5000  /* remember, that this constraint set change data was responsible for the constraint's addition */
5001  cons->addconssetchg = *conssetchg;
5002  cons->addarraypos = (*conssetchg)->naddedconss-1;
5003  }
5004 
5005  return SCIP_OKAY;
5006 }
5007 
5008 /** adds constraint disabling to constraint set changes, and captures constraint */
5010  SCIP_CONSSETCHG** conssetchg, /**< pointer to constraint set change data structure */
5011  BMS_BLKMEM* blkmem, /**< block memory */
5012  SCIP_SET* set, /**< global SCIP settings */
5013  SCIP_CONS* cons /**< disabled constraint */
5014  )
5015 {
5016  assert(conssetchg != NULL);
5017  assert(cons != NULL);
5018 
5019  /* if constraint set change doesn't exist, create it */
5020  if( *conssetchg == NULL )
5021  {
5022  SCIP_CALL( conssetchgCreate(conssetchg, blkmem) );
5023  }
5024 
5025  /* add constraint to the disabledconss array */
5026  SCIP_CALL( conssetchgEnsureDisabledconssSize(*conssetchg, blkmem, set, (*conssetchg)->ndisabledconss+1) );
5027  (*conssetchg)->disabledconss[(*conssetchg)->ndisabledconss] = cons;
5028  (*conssetchg)->ndisabledconss++;
5029 
5030  /* capture constraint */
5031  SCIPconsCapture(cons);
5032 
5033  return SCIP_OKAY;
5034 }
5035 
5036 /** deactivates, deletes, and releases constraint from the addedconss array of the constraint set change data */
5037 static
5039  SCIP_CONSSETCHG* conssetchg, /**< constraint set change to delete constraint from */
5040  BMS_BLKMEM* blkmem, /**< block memory */
5041  SCIP_SET* set, /**< global SCIP settings */
5042  int arraypos /**< position of constraint in disabledconss array */
5043  )
5044 {
5045  SCIP_CONS* cons;
5046 
5047  assert(conssetchg != NULL);
5048  assert(conssetchg->addedconss != NULL);
5049  assert(0 <= arraypos && arraypos < conssetchg->naddedconss);
5050 
5051  cons = conssetchg->addedconss[arraypos];
5052  assert(cons != NULL);
5053 
5054  SCIPdebugMessage("delete added constraint <%s> at position %d from constraint set change data\n", cons->name, arraypos);
5055 
5056  /* remove the link to the constraint set change data */
5057  if( cons->addconssetchg == conssetchg )
5058  {
5059  cons->addconssetchg = NULL;
5060  cons->addarraypos = -1;
5061  }
5062 
5063  /* release constraint */
5064  SCIP_CALL( SCIPconsRelease(&conssetchg->addedconss[arraypos], blkmem, set) );
5065 
5066  /* we want to keep the order of the constraint additions: move all subsequent constraints one slot to the front */
5067  for( ; arraypos < conssetchg->naddedconss-1; ++arraypos )
5068  {
5069  conssetchg->addedconss[arraypos] = conssetchg->addedconss[arraypos+1];
5070  assert(conssetchg->addedconss[arraypos] != NULL);
5071  if( conssetchg->addedconss[arraypos]->addconssetchg == conssetchg )
5072  {
5073  assert(conssetchg->addedconss[arraypos]->addarraypos == arraypos+1);
5074  conssetchg->addedconss[arraypos]->addarraypos = arraypos;
5075  }
5076  }
5077  conssetchg->naddedconss--;
5078 
5079  return SCIP_OKAY;
5080 }
5081 
5082 /** deletes and releases deactivated constraint from the disabledconss array of the constraint set change data */
5083 static
5085  SCIP_CONSSETCHG* conssetchg, /**< constraint set change to apply */
5086  BMS_BLKMEM* blkmem, /**< block memory */
5087  SCIP_SET* set, /**< global SCIP settings */
5088  int arraypos /**< position of constraint in disabledconss array */
5089  )
5090 {
5091  assert(conssetchg != NULL);
5092  assert(0 <= arraypos && arraypos < conssetchg->ndisabledconss);
5093  assert(conssetchg->disabledconss[arraypos] != NULL);
5094 
5095  SCIPdebugMessage("delete disabled constraint <%s> at position %d from constraint set change data\n",
5096  conssetchg->disabledconss[arraypos]->name, arraypos);
5097 
5098  /* release constraint */
5099  SCIP_CALL( SCIPconsRelease(&conssetchg->disabledconss[arraypos], blkmem, set) );
5100 
5101  /* we want to keep the order of the constraint disablings: move all subsequent constraints one slot to the front */
5102  for( ; arraypos < conssetchg->ndisabledconss-1; ++arraypos )
5103  {
5104  conssetchg->disabledconss[arraypos] = conssetchg->disabledconss[arraypos+1];
5105  assert(conssetchg->disabledconss[arraypos] != NULL);
5106  }
5107  conssetchg->ndisabledconss--;
5108 
5109  return SCIP_OKAY;
5110 }
5111 
5112 /** applies constraint set change */
5114  SCIP_CONSSETCHG* conssetchg, /**< constraint set change to apply */
5115  BMS_BLKMEM* blkmem, /**< block memory */
5116  SCIP_SET* set, /**< global SCIP settings */
5117  SCIP_STAT* stat, /**< dynamic problem statistics */
5118  int depth, /**< depth of constraint set change's node */
5119  SCIP_Bool focusnode /**< does the constraint set change belong to the focus node? */
5120  )
5121 {
5122  SCIP_CONS* cons;
5123  int i;
5124 
5125  if( conssetchg == NULL )
5126  return SCIP_OKAY;
5127 
5128  SCIPdebugMessage("applying constraint set changes at %p: %d constraint additions, %d constraint disablings\n",
5129  (void*)conssetchg, conssetchg->naddedconss, conssetchg->ndisabledconss);
5130 
5131  /* apply constraint additions */
5132  i = 0;
5133  while( i < conssetchg->naddedconss )
5134  {
5135  cons = conssetchg->addedconss[i];
5136  assert(cons != NULL);
5137  assert(!cons->update);
5138 
5139  /* if constraint is already active, or if constraint is globally deleted, it can be removed from addedconss array */
5140  if( cons->active || cons->deleted )
5141  {
5142  /* delete constraint from addedcons array, the empty slot is now used by the next constraint,
5143  * and naddedconss was decreased, so do not increase i
5144  */
5145  SCIP_CALL( conssetchgDelAddedCons(conssetchg, blkmem, set, i) );
5146  }
5147  else
5148  {
5149  assert(cons->addconssetchg == NULL);
5150  assert(cons->addarraypos == -1);
5151 
5152  /* activate constraint */
5153  SCIP_CALL( SCIPconsActivate(cons, set, stat, depth, focusnode) );
5154  assert(cons->active);
5155  assert(!cons->update);
5156 
5157  /* remember, that this constraint set change data was responsible for the constraint's addition */
5158  cons->addconssetchg = conssetchg;
5159  cons->addarraypos = i;
5160 
5161  ++i; /* handle the next constraint */
5162  }
5163  }
5164 
5165  /* apply constraint disablings */
5166  i = 0;
5167  while( i < conssetchg->ndisabledconss )
5168  {
5169  cons = conssetchg->disabledconss[i];
5170  assert(cons != NULL);
5171  assert(!cons->update);
5172 
5173  /* if the constraint is disabled, we can permanently remove it from the disabledconss array */
5174  if( !cons->enabled )
5175  {
5176  SCIPdebugMessage("constraint <%s> of handler <%s> was deactivated -> remove it from disabledconss array\n",
5177  cons->name, cons->conshdlr->name);
5178 
5179  /* release and remove constraint from the disabledconss array, the empty slot is now used by the next constraint
5180  * and ndisabledconss was decreased, so do not increase i
5181  */
5182  SCIP_CALL( conssetchgDelDisabledCons(conssetchg, blkmem, set, i) );
5183  }
5184  else
5185  {
5186  assert(cons->addarraypos >= 0);
5187  assert(!cons->deleted); /* deleted constraints must not be enabled! */
5188  SCIP_CALL( SCIPconsDisable(conssetchg->disabledconss[i], set, stat) );
5189  assert(!cons->update);
5190  assert(!cons->enabled);
5191 
5192  ++i; /* handle the next constraint */
5193  }
5194  }
5195 
5196  return SCIP_OKAY;
5197 }
5198 
5199 /** undoes constraint set change */
5201  SCIP_CONSSETCHG* conssetchg, /**< constraint set change to undo */
5202  BMS_BLKMEM* blkmem, /**< block memory */
5203  SCIP_SET* set, /**< global SCIP settings */
5204  SCIP_STAT* stat /**< dynamic problem statistics */
5205  )
5206 {
5207  SCIP_CONS* cons;
5208  int i;
5209 
5210  if( conssetchg == NULL )
5211  return SCIP_OKAY;
5212 
5213  SCIPdebugMessage("undoing constraint set changes at %p: %d constraint additions, %d constraint disablings\n",
5214  (void*)conssetchg, conssetchg->naddedconss, conssetchg->ndisabledconss);
5215 
5216  /* undo constraint disablings */
5217  for( i = conssetchg->ndisabledconss-1; i >= 0; --i )
5218  {
5219  cons = conssetchg->disabledconss[i];
5220  assert(cons != NULL);
5221  assert(!cons->update);
5222 
5223  /* If the constraint is inactive, we can permanently remove it from the disabledconss array. It was deactivated
5224  * in the subtree of the current node but not reactivated on the switching way back to the current node, which
5225  * means, the deactivation was more global (i.e. valid on a higher level node) than the current node and the
5226  * disabling at the current node doesn't have any effect anymore.
5227  * If the constraint is already enabled, we need not to do anything. This may happen on a path A -> B,
5228  * if the constraint is disabled at node B, and while processing the subtree of B, it is also disabled at
5229  * the more global node A. Then on the switching path back to A, the constraint is enabled at node B (which is
5230  * actually wrong, since it now should be disabled in the whole subtree of A, but we cannot know this), and
5231  * again enabled at node A (where enabling is ignored). If afterwards, a subnode of B is processed, the
5232  * switching disables the constraint in node A, and the disabling is then removed from node B.
5233  */
5234  if( !cons->active )
5235  {
5236  SCIPdebugMessage("constraint <%s> of handler <%s> was deactivated -> remove it from disabledconss array\n",
5237  cons->name, cons->conshdlr->name);
5238 
5239  /* release and remove constraint from the disabledconss array */
5240  SCIP_CALL( conssetchgDelDisabledCons(conssetchg, blkmem, set, i) );
5241  }
5242  else if( !cons->enabled )
5243  {
5244  assert(cons->addarraypos >= 0);
5245  assert(!cons->deleted); /* deleted constraints must not be active! */
5246  SCIP_CALL( SCIPconsEnable(cons, set, stat) );
5247  }
5248  assert(!cons->update);
5249  assert(!cons->active || cons->enabled);
5250  }
5251 
5252  /* undo constraint additions */
5253  for( i = conssetchg->naddedconss-1; i >= 0; --i )
5254  {
5255  cons = conssetchg->addedconss[i];
5256  assert(cons != NULL);
5257  assert(!cons->update);
5258 
5259  /* If the constraint is already deactivated, we need not to do anything. This may happen on a path A -> B,
5260  * if the constraint is added at node B, and while processing the subtree of B, it is also added at
5261  * the more global node A. Then on the switching path back to A, the node is deactivated at node B (which is
5262  * actually wrong, since it now should be active in the whole subtree of A, but we cannot know this), and
5263  * again deactivated at node A (where deactivation is ignored). If afterwards, a subnode of B is processed, the
5264  * switching activates the constraint in node A, and the activation is then removed from node B.
5265  */
5266  if( cons->active )
5267  {
5268  assert(cons->addconssetchg == conssetchg);
5269  assert(cons->addarraypos == i);
5270 
5271  /* deactivate constraint */
5272  SCIP_CALL( SCIPconsDeactivate(cons, set, stat) );
5273 
5274  /* unlink the constraint and the constraint set change */
5275  cons->addconssetchg = NULL;
5276  cons->addarraypos = -1;
5277  }
5278  assert(!cons->active);
5279  assert(!cons->update);
5280  }
5281 
5282  return SCIP_OKAY;
5283 }
5284 
5285 /** applies constraint set change to the global problem and deletes the constraint set change data */
5287  SCIP_CONSSETCHG** conssetchg, /**< pointer to constraint set change data */
5288  BMS_BLKMEM* blkmem, /**< block memory */
5289  SCIP_SET* set, /**< global SCIP settings */
5290  SCIP_STAT* stat, /**< dynamic problem statistics */
5291  SCIP_PROB* prob /**< problem data */
5292  )
5293 {
5294  SCIP_CONS* cons;
5295  int i;
5296 
5297  assert(conssetchg != NULL);
5298 
5299  /* nothing to do on empty constraint set change data */
5300  if( *conssetchg == NULL )
5301  return SCIP_OKAY;
5302 
5303  SCIPdebugMessage("moving constraint set changes at %p to global problem: %d constraint additions, %d constraint disablings\n",
5304  (void*)*conssetchg, (*conssetchg)->naddedconss, (*conssetchg)->ndisabledconss);
5305 
5306  /* apply constraint additions to the global problem (loop backwards, because then conssetchgDelAddedCons() is
5307  * more efficient)
5308  */
5309  for( i = (*conssetchg)->naddedconss-1; i >= 0; --i )
5310  {
5311  cons = (*conssetchg)->addedconss[i];
5312  assert(cons != NULL);
5313  assert(!cons->update);
5314 
5315  /* only move constraints that are not sticking at the current node */
5316  if( !SCIPconsIsStickingAtNode(cons) )
5317  {
5318  /* because we first have to delete the constraint, we have to capture it in order to not loose it */
5319  SCIPconsCapture(cons);
5320 
5321  /* delete constraint addition from constraint set change data */
5322  SCIP_CALL( conssetchgDelAddedCons(*conssetchg, blkmem, set, i) );
5323 
5324  /* don't move deleted constraints to the global problem */
5325  if( !cons->deleted )
5326  {
5327  SCIP_CALL( SCIPprobAddCons(prob, set, stat, cons) );
5328  }
5329 
5330  /* release constraint */
5331  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5332  }
5333  }
5334 
5335  /* apply constraint disablings to the global problem (loop backwards, because then conssetchgDelDisabledCons() is
5336  * more efficient)
5337  */
5338  for( i = (*conssetchg)->ndisabledconss-1; i >= 0; --i )
5339  {
5340  cons = (*conssetchg)->disabledconss[i];
5341  assert(cons != NULL);
5342  assert(!cons->update);
5343 
5344  /* only delete constraints that are not sticking at the current node */
5345  if( !SCIPconsIsStickingAtNode(cons) )
5346  {
5347  /* globally delete constraint */
5348  if( !cons->deleted )
5349  {
5350  SCIP_CALL( SCIPconsDelete(cons, blkmem, set, stat, prob) );
5351  }
5352 
5353  /* release and remove constraint from the disabledconss array */
5354  SCIP_CALL( conssetchgDelDisabledCons(*conssetchg, blkmem, set, i) );
5355  }
5356  }
5357 
5358  if( (*conssetchg)->naddedconss == 0 && (*conssetchg)->ndisabledconss == 0 )
5359  {
5360  /* free empty constraint set change data */
5361  SCIP_CALL( SCIPconssetchgFree(conssetchg, blkmem, set) );
5362  }
5363 
5364  return SCIP_OKAY;
5365 }
5366 
5367 
5368 
5369 
5370 /*
5371  * Constraint methods
5372  */
5373 
5374 /** creates and captures a constraint, and inserts it into the conss array of its constraint handler
5375  *
5376  * @warning If a constraint is marked to be checked for feasibility but not to be enforced, a LP or pseudo solution
5377  * may be declared feasible even if it violates this particular constraint.
5378  * This constellation should only be used, if no LP or pseudo solution can violate the constraint -- e.g. if a
5379  * local constraint is redundant due to the variable's local bounds.
5380  */
5382  SCIP_CONS** cons, /**< pointer to constraint */
5383  BMS_BLKMEM* blkmem, /**< block memory */
5384  SCIP_SET* set, /**< global SCIP settings */
5385  const char* name, /**< name of constraint */
5386  SCIP_CONSHDLR* conshdlr, /**< constraint handler for this constraint */
5387  SCIP_CONSDATA* consdata, /**< data for this specific constraint */
5388  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
5389  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
5390  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
5391  * Usually set to TRUE. */
5392  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
5393  * TRUE for model constraints, FALSE for additional, redundant constraints. */
5394  SCIP_Bool check, /**< should the constraint be checked for feasibility?
5395  * TRUE for model constraints, FALSE for additional, redundant constraints. */
5396  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
5397  * Usually set to TRUE. */
5398  SCIP_Bool local, /**< is constraint only valid locally?
5399  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
5400  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
5401  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
5402  * adds coefficients to this constraint. */
5403  SCIP_Bool dynamic, /**< is constraint subject to aging?
5404  * Usually set to FALSE. Set to TRUE for own cuts which
5405  * are separated as constraints. */
5406  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
5407  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
5408  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
5409  * if it may be moved to a more global node?
5410  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
5411  SCIP_Bool original, /**< is constraint belonging to the original problem? */
5412  SCIP_Bool deleteconsdata /**< has the constraint data to be deleted if constraint is freed? */
5413  )
5414 {
5415  assert(cons != NULL);
5416  assert(blkmem != NULL);
5417  assert(set != NULL);
5418  assert(name != NULL);
5419  assert(conshdlr != NULL);
5420  assert(!original || deleteconsdata);
5421 
5422  /* constraints of constraint handlers that don't need constraints cannot be created */
5423  if( !conshdlr->needscons )
5424  {
5425  SCIPerrorMessage("cannot create constraint <%s> of type [%s] - constraint handler does not need constraints\n",
5426  name, conshdlr->name);
5427  return SCIP_INVALIDCALL;
5428  }
5429 
5430  /* create constraint data */
5431  SCIP_ALLOC( BMSallocBlockMemory(blkmem, cons) );
5432  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*cons)->name, name, strlen(name)+1) );
5433 #ifndef NDEBUG
5434  (*cons)->scip = set->scip;
5435 #endif
5436  (*cons)->conshdlr = conshdlr;
5437  (*cons)->consdata = consdata;
5438  (*cons)->transorigcons = NULL;
5439  (*cons)->addconssetchg = NULL;
5440  (*cons)->addarraypos = -1;
5441  (*cons)->consspos = -1;
5442  (*cons)->initconsspos = -1;
5443  (*cons)->sepaconsspos = -1;
5444  (*cons)->enfoconsspos = -1;
5445  (*cons)->checkconsspos = -1;
5446  (*cons)->propconsspos = -1;
5447  (*cons)->activedepth = -2;
5448  (*cons)->validdepth = (local ? -1 : 0);
5449  (*cons)->age = 0.0;
5450  (*cons)->nlockspos = 0;
5451  (*cons)->nlocksneg = 0;
5452  (*cons)->markedprop = FALSE;
5453  (*cons)->nuses = 0;
5454  (*cons)->nupgradelocks = 0;
5455  (*cons)->initial = initial;
5456  (*cons)->separate = separate;
5457  (*cons)->enforce = enforce;
5458  (*cons)->check = check;
5459  (*cons)->propagate = propagate;
5460  (*cons)->sepaenabled = separate;
5461  (*cons)->propenabled = propagate;
5462  (*cons)->local = local;
5463  (*cons)->modifiable = modifiable;
5464  (*cons)->dynamic = dynamic;
5465  (*cons)->removable = removable;
5466  (*cons)->stickingatnode = stickingatnode;
5467  (*cons)->original = original;
5468  (*cons)->deleteconsdata = deleteconsdata;
5469  (*cons)->active = FALSE;
5470  (*cons)->enabled = FALSE;
5471  (*cons)->obsolete = FALSE;
5472  (*cons)->markpropagate = FALSE;
5473  (*cons)->deleted = FALSE;
5474  (*cons)->update = FALSE;
5475  (*cons)->updateinsert = FALSE;
5476  (*cons)->updateactivate = FALSE;
5477  (*cons)->updatedeactivate = FALSE;
5478  (*cons)->updateenable = FALSE;
5479  (*cons)->updatedisable = FALSE;
5480  (*cons)->updatesepaenable = FALSE;
5481  (*cons)->updatesepadisable = FALSE;
5482  (*cons)->updatepropenable = FALSE;
5483  (*cons)->updatepropdisable = FALSE;
5484  (*cons)->updateobsolete = FALSE;
5485  (*cons)->updatemarkpropagate = FALSE;
5486  (*cons)->updateunmarkpropagate = FALSE;
5487  (*cons)->updatefree = FALSE;
5488  (*cons)->updateactfocus = FALSE;
5489 
5490  /* capture constraint */
5491  SCIPconsCapture(*cons);
5492 
5493  /* insert the constraint as inactive constraint into the transformed constraints array */
5494  if( !original )
5495  {
5496  /* check, if inserting constraint should be delayed */
5497  if( conshdlrAreUpdatesDelayed(conshdlr) )
5498  {
5499  SCIPdebugMessage(" -> delaying insertion of constraint <%s>\n", (*cons)->name);
5500  (*cons)->updateinsert = TRUE;
5501  SCIP_CALL( conshdlrAddUpdateCons((*cons)->conshdlr, set, *cons) );
5502  assert((*cons)->update);
5503  assert((*cons)->nuses == 2);
5504  }
5505  else
5506  {
5507  SCIP_CALL( conshdlrAddCons(conshdlr, set, *cons) );
5508  }
5509  }
5510 
5511  checkConssArrays(conshdlr);
5512 
5513  return SCIP_OKAY;
5514 }
5515 
5516 /** copies source constraint of source SCIP into the target constraint for the target SCIP, using the variable map for
5517  * mapping the variables of the source SCIP to the variables of the target SCIP; if the copying process was successful
5518  * a constraint is created and captured;
5519  *
5520  * @warning If a constraint is marked to be checked for feasibility but not to be enforced, a LP or pseudo solution
5521  * may be declared feasible even if it violates this particular constraint.
5522  * This constellation should only be used, if no LP or pseudo solution can violate the constraint -- e.g. if a
5523  * local constraint is redundant due to the variable's local bounds.
5524  */
5526  SCIP_CONS** cons, /**< pointer to store the created target constraint */
5527  SCIP_SET* set, /**< global SCIP settings of the target SCIP */
5528  const char* name, /**< name of constraint, or NULL if the name of the source constraint should be used */
5529  SCIP* sourcescip, /**< source SCIP data structure */
5530  SCIP_CONSHDLR* sourceconshdlr, /**< source constraint handler for this constraint */
5531  SCIP_CONS* sourcecons, /**< source constraint of the source SCIP */
5532  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
5533  * variables of the target SCIP */
5534  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
5535  * target constraints, must not be NULL! */
5536  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
5537  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
5538  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
5539  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
5540  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
5541  SCIP_Bool local, /**< is constraint only valid locally? */
5542  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
5543  SCIP_Bool dynamic, /**< is constraint subject to aging? */
5544  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
5545  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
5546  * if it may be moved to a more global node? */
5547  SCIP_Bool global, /**< create a global or a local copy? */
5548  SCIP_Bool* success /**< pointer to store whether the copying was successful or not */
5549  )
5550 {
5551  assert(cons != NULL);
5552  assert(set != NULL);
5553  assert(sourcescip != NULL);
5554  assert(sourceconshdlr != NULL);
5555  assert(sourcecons != NULL);
5556  assert(varmap != NULL);
5557  assert(consmap != NULL);
5558  assert(success != NULL);
5559 
5560  /* if constraint handler does not support copying, success will return false. Constraints handlers have to actively set this to true. */
5561  (*success) = FALSE;
5562 
5563  if( sourceconshdlr->conscopy != NULL )
5564  {
5565  SCIP_CALL( sourceconshdlr->conscopy(set->scip, cons, name, sourcescip, sourceconshdlr, sourcecons, varmap, consmap,
5566  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, success) );
5567  }
5568 #if 0
5569  else
5570  {
5571  SCIPwarningMessage(scip, "constraint handler <%s> doesn't support copying constraints\n", sourceconshdlr->name);
5572  }
5573 #endif
5574  return SCIP_OKAY;
5575 }
5576 
5577 
5578 /** parses constraint information (in cip format) out of a string; if the parsing process was successful a constraint is
5579  * created, captured, and inserted into the conss array of its constraint handler.
5580  *
5581  * @warning If a constraint is marked to be checked for feasibility but not to be enforced, an LP or pseudo solution
5582  * may be declared feasible even if it violates this particular constraint.
5583  * This constellation should only be used, if no LP or pseudo solution can violate the constraint -- e.g. if a
5584  * local constraint is redundant due to the variable's local bounds.
5585  */
5587  SCIP_CONS** cons, /**< pointer to constraint */
5588  SCIP_SET* set, /**< global SCIP settings */
5589  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler of target SCIP */
5590  const char* str, /**< string to parse for constraint */
5591  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
5592  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
5593  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
5594  * Usually set to TRUE. */
5595  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
5596  * TRUE for model constraints, FALSE for additional, redundant constraints. */
5597  SCIP_Bool check, /**< should the constraint be checked for feasibility?
5598  * TRUE for model constraints, FALSE for additional, redundant constraints. */
5599  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
5600  * Usually set to TRUE. */
5601  SCIP_Bool local, /**< is constraint only valid locally?
5602  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
5603  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
5604  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
5605  * adds coefficients to this constraint. */
5606  SCIP_Bool dynamic, /**< is constraint subject to aging?
5607  * Usually set to FALSE. Set to TRUE for own cuts which
5608  * are separated as constraints. */
5609  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
5610  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
5611  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
5612  * if it may be moved to a more global node?
5613  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
5614  SCIP_Bool* success /**< pointer store if the paring process was successful */
5615  )
5616 {
5617  SCIP_CONSHDLR* conshdlr;
5618  char conshdlrname[SCIP_MAXSTRLEN];
5619  char consname[SCIP_MAXSTRLEN];
5620  char* endptr;
5621 
5622  assert(cons != NULL);
5623  assert(set != NULL);
5624 
5625  (*success) = FALSE;
5626 
5627  /* scan constraint handler name */
5628  assert(str != NULL);
5629  SCIPstrCopySection(str, '[', ']', conshdlrname, SCIP_MAXSTRLEN, &endptr);
5630  if ( endptr == NULL || endptr == str )
5631  {
5632  SCIPmessagePrintWarning(messagehdlr, "Syntax error: Could not find constraint handler name.\n");
5633  return SCIP_OKAY;
5634  }
5635  assert(endptr != NULL);
5636  SCIPdebugMessage("constraint handler name <%s>\n", conshdlrname);
5637 
5638  /* scan constraint name */
5639  SCIPstrCopySection(endptr, '<', '>', consname, SCIP_MAXSTRLEN, &endptr);
5640  if ( endptr == NULL || endptr == str )
5641  {
5642  SCIPmessagePrintWarning(messagehdlr, "Syntax error: Could not find constraint name.\n");
5643  return SCIP_OKAY;
5644  }
5645  assert(endptr != NULL);
5646  SCIPdebugMessage("constraint name <%s>\n", consname);
5647 
5648  str = endptr;
5649 
5650  /* skip white space */
5651  while ( isspace((unsigned char)* str) )
5652  ++str;
5653 
5654  /* check for colon */
5655  if( *str != ':' )
5656  {
5657  SCIPmessagePrintWarning(messagehdlr, "Syntax error: Could not find colon ':' after constraint name.\n");
5658  return SCIP_OKAY;
5659  }
5660 
5661  /* skip colon */
5662  ++str;
5663 
5664  /* skip white space */
5665  while ( isspace((unsigned char)* str) )
5666  ++str;
5667 
5668  /* check if a constraint handler with parsed name exists */
5669  conshdlr = SCIPsetFindConshdlr(set, conshdlrname);
5670 
5671  if( conshdlr == NULL )
5672  {
5673  SCIPmessagePrintWarning(messagehdlr, "constraint handler <%s> doesn't exist in SCIP data structure\n", conshdlrname);
5674  }
5675  else
5676  {
5677  assert( conshdlr != NULL );
5678  if ( conshdlr->consparse == NULL )
5679  {
5680  SCIPmessagePrintWarning(messagehdlr, "constraint handler <%s> does not support parsing constraints\n", conshdlrname);
5681  }
5682  else
5683  {
5684  SCIP_CALL( conshdlr->consparse(set->scip, conshdlr, cons, consname, str,
5685  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );
5686  }
5687  }
5688 
5689  return SCIP_OKAY;
5690 }
5691 
5692 /** change name of given constraint */
5694  SCIP_CONS* cons, /**< problem constraint */
5695  BMS_BLKMEM* blkmem, /**< block memory buffer */
5696  const char* name /**< new name of constraint */
5697  )
5698 {
5699  assert(cons != NULL);
5700  assert(cons->name != NULL);
5701 
5702  /* free old constraint name */
5703  BMSfreeBlockMemoryArray(blkmem, &cons->name, strlen(cons->name)+1);
5704 
5705  /* copy new constraint name */
5706  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &cons->name, name, strlen(name)+1) );
5707 
5708  return SCIP_OKAY;
5709 }
5710 
5711 
5712 /** frees a constraint and removes it from the conss array of its constraint handler */
5714  SCIP_CONS** cons, /**< constraint to free */
5715  BMS_BLKMEM* blkmem, /**< block memory buffer */
5716  SCIP_SET* set /**< global SCIP settings */
5717  )
5718 {
5719  assert(cons != NULL);
5720  assert(*cons != NULL);
5721  assert((*cons)->conshdlr != NULL);
5722  assert((*cons)->nuses == 0);
5723  assert(!(*cons)->active);
5724  assert(!(*cons)->update);
5725  assert(!(*cons)->original || (*cons)->transorigcons == NULL);
5726  assert(blkmem != NULL);
5727  assert(set != NULL);
5728  assert((*cons)->scip == set->scip);
5729 
5730  SCIPdebugMessage("freeing constraint <%s> at conss pos %d of handler <%s>\n",
5731  (*cons)->name, (*cons)->consspos, (*cons)->conshdlr->name);
5732 
5733  /* free constraint data */
5734  if( (*cons)->conshdlr->consdelete != NULL && (*cons)->consdata != NULL && (*cons)->deleteconsdata )
5735  {
5736  SCIP_CALL( (*cons)->conshdlr->consdelete(set->scip, (*cons)->conshdlr, *cons, &(*cons)->consdata) );
5737  }
5738  else if( !(*cons)->deleteconsdata )
5739  (*cons)->consdata = NULL;
5740  assert((*cons)->consdata == NULL);
5741 
5742  /* unlink transformed and original constraint */
5743  if( (*cons)->transorigcons != NULL )
5744  {
5745  assert(!(*cons)->original);
5746  assert((*cons)->transorigcons->original);
5747  assert((*cons)->transorigcons->transorigcons == *cons);
5748 
5749  (*cons)->transorigcons->transorigcons = NULL;
5750  }
5751 
5752  /* remove constraint from the transformed constraints array */
5753  if( !(*cons)->original )
5754  {
5755  conshdlrDelCons((*cons)->conshdlr, *cons);
5756  checkConssArrays((*cons)->conshdlr);
5757  }
5758  assert((*cons)->consspos == -1);
5759 
5760  /* free constraint */
5761  BMSfreeBlockMemoryArray(blkmem, &(*cons)->name, strlen((*cons)->name)+1);
5762  BMSfreeBlockMemory(blkmem, cons);
5763 
5764  return SCIP_OKAY;
5765 }
5766 
5767 /** increases usage counter of constraint */
5769  SCIP_CONS* cons /**< constraint */
5770  )
5771 {
5772  assert(cons != NULL);
5773  assert(cons->nuses >= 0);
5774 
5775  SCIPdebugMessage("capture constraint <%s> with nuses=%d, cons pointer %p\n", cons->name, cons->nuses, (void*)cons);
5776  cons->nuses++;
5777 }
5778 
5779 /** decreases usage counter of constraint, and frees memory if necessary */
5781  SCIP_CONS** cons, /**< pointer to constraint */
5782  BMS_BLKMEM* blkmem, /**< block memory */
5783  SCIP_SET* set /**< global SCIP settings */
5784  )
5785 {
5786  assert(blkmem != NULL);
5787  assert(cons != NULL);
5788  assert(*cons != NULL);
5789  assert((*cons)->conshdlr != NULL);
5790  assert((*cons)->nuses >= 1);
5791  assert(set != NULL);
5792  assert((*cons)->scip == set->scip);
5793 
5794  SCIPdebugMessage("release constraint <%s> with nuses=%d, cons pointer %p\n", (*cons)->name, (*cons)->nuses, (void*)(*cons));
5795  (*cons)->nuses--;
5796  if( (*cons)->nuses == 0 )
5797  {
5798  assert(!(*cons)->active || (*cons)->updatedeactivate);
5799 
5800  /* check, if freeing constraint should be delayed */
5801  if( conshdlrAreUpdatesDelayed((*cons)->conshdlr) )
5802  {
5803  SCIPdebugMessage(" -> delaying freeing constraint <%s>\n", (*cons)->name);
5804  (*cons)->updatefree = TRUE;
5805  SCIP_CALL( conshdlrAddUpdateCons((*cons)->conshdlr, set, *cons) );
5806  assert((*cons)->update);
5807  assert((*cons)->nuses == 1);
5808  }
5809  else
5810  {
5811  SCIP_CALL( SCIPconsFree(cons, blkmem, set) );
5812  }
5813  }
5814  *cons = NULL;
5815 
5816  return SCIP_OKAY;
5817 }
5818 
5819 /** outputs constraint information to file stream */
5821  SCIP_CONS* cons, /**< constraint to print */
5822  SCIP_SET* set, /**< global SCIP settings */
5823  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5824  FILE* file /**< output file (or NULL for standard output) */
5825  )
5826 {
5827  SCIP_CONSHDLR* conshdlr;
5828 
5829  assert(cons != NULL);
5830  assert(set != NULL);
5831  assert(cons->scip == set->scip);
5832 
5833  conshdlr = cons->conshdlr;
5834  assert(conshdlr != NULL);
5835 
5836  SCIPmessageFPrintInfo(messagehdlr, file, " [%s] <%s>: ", conshdlr->name, cons->name);
5837 
5838  if( conshdlr->consprint != NULL )
5839  {
5840  SCIP_CALL( conshdlr->consprint(set->scip, conshdlr, cons, file) );
5841  }
5842  else
5843  SCIPmessageFPrintInfo(messagehdlr, file, "constraint handler <%s> doesn't support printing constraint;\n", conshdlr->name);
5844 
5845  return SCIP_OKAY;
5846 }
5847 
5848 /** method to collect the variables of a constraint
5849  *
5850  * If the number of variables is greater than the available slots in the variable array, nothing happens except that
5851  * the success point is set to FALSE. With the method SCIPconsGetNVars() it is possible to get the number of variables
5852  * a constraint has in its scope.
5853  *
5854  * @note The success pointer indicates if all variables were copied into the vars arrray.
5855  *
5856  * @note It might be that a constraint handler does not support this functionality, in that case the success pointer is
5857  * set to FALSE.
5858  */
5860  SCIP_CONS* cons, /**< constraint to print */
5861  SCIP_SET* set, /**< global SCIP settings */
5862  SCIP_VAR** vars, /**< array to store the involved variable of the constraint */
5863  int varssize, /**< available slots in vars array which is needed to check if the array is large enough */
5864  SCIP_Bool* success /**< pointer to store whether the variables are successfully copied */
5865  )
5866 {
5867  SCIP_CONSHDLR* conshdlr;
5868 
5869  assert(cons != NULL);
5870  assert(set != NULL);
5871  assert(cons->scip == set->scip);
5872 
5873  conshdlr = cons->conshdlr;
5874  assert(conshdlr != NULL);
5875 
5876  if( conshdlr->consgetvars != NULL )
5877  {
5878  SCIP_CALL( conshdlr->consgetvars(set->scip, conshdlr, cons, vars, varssize, success) );
5879  }
5880  else
5881  {
5882  (*success) = FALSE;
5883  }
5884 
5885  return SCIP_OKAY;
5886 }
5887 
5888 /** methed to collect the number of variables of a constraint
5889  *
5890  * @note The success pointer indicates if the contraint handler was able to return the number of variables
5891  *
5892  * @note It might be that a constraint handler does not support this functionality, in that case the success pointer is
5893  * set to FALSE
5894  */
5896  SCIP_CONS* cons, /**< constraint to print */
5897  SCIP_SET* set, /**< global SCIP settings */
5898  int* nvars, /**< pointer to store the number of variables */
5899  SCIP_Bool* success /**< pointer to store whether the constraint successfully returned the number of variables */
5900  )
5901 {
5902  SCIP_CONSHDLR* conshdlr;
5903 
5904  assert(cons != NULL);
5905  assert(set != NULL);
5906  assert(cons->scip == set->scip);
5907 
5908  conshdlr = cons->conshdlr;
5909  assert(conshdlr != NULL);
5910 
5911  if( conshdlr->consgetnvars != NULL )
5912  {
5913  SCIP_CALL( conshdlr->consgetnvars(set->scip, conshdlr, cons, nvars, success) );
5914  }
5915  else
5916  {
5917  (*nvars) = 0;
5918  (*success) = FALSE;
5919  }
5920 
5921  return SCIP_OKAY;
5922 }
5923 
5924 /** globally removes constraint from all subproblems; removes constraint from the constraint set change data of the
5925  * node, where it was created, or from the problem, if it was a problem constraint
5926  */
5928  SCIP_CONS* cons, /**< constraint to delete */
5929  BMS_BLKMEM* blkmem, /**< block memory */
5930  SCIP_SET* set, /**< global SCIP settings */
5931  SCIP_STAT* stat, /**< dynamic problem statistics */
5932  SCIP_PROB* prob /**< problem data */
5933  )
5934 {
5935  assert(cons != NULL);
5936  assert(cons->conshdlr != NULL);
5937  assert(!cons->active || cons->updatedeactivate || cons->addarraypos >= 0);
5938  assert(set != NULL);
5939  assert(cons->scip == set->scip);
5940 
5941  SCIPdebugMessage("globally deleting constraint <%s> (delay updates: %d)\n",
5942  cons->name, cons->conshdlr->delayupdatecount);
5943 
5944  /* deactivate constraint, if it is currently active */
5945  if( cons->active && !cons->updatedeactivate )
5946  {
5947  SCIP_CALL( SCIPconsDeactivate(cons, set, stat) );
5948  }
5949  else
5950  cons->updateactivate = FALSE;
5951 
5952  assert(!cons->active || cons->updatedeactivate);
5953  assert(!cons->enabled || cons->updatedeactivate);
5954 
5955  /* mark constraint deleted */
5956  cons->deleted = TRUE;
5957 
5958  /* remove formerly active constraint from the conssetchg's addedconss / prob's conss array */
5959  if( cons->addarraypos >= 0 )
5960  {
5961  if( cons->addconssetchg == NULL )
5962  {
5963  /* remove problem constraint from the problem */
5964  SCIP_CALL( SCIPprobDelCons(prob, blkmem, set, stat, cons) );
5965  }
5966  else
5967  {
5968  assert(cons->addconssetchg->addedconss != NULL);
5969  assert(0 <= cons->addarraypos && cons->addarraypos < cons->addconssetchg->naddedconss);
5970  assert(cons->addconssetchg->addedconss[cons->addarraypos] == cons);
5971 
5972  /* remove constraint from the constraint set change addedconss array */
5973  SCIP_CALL( conssetchgDelAddedCons(cons->addconssetchg, blkmem, set, cons->addarraypos) );
5974  }
5975  }
5976 
5977  return SCIP_OKAY;
5978 }
5979 
5980 /** gets and captures transformed constraint of a given original constraint; if the constraint is not yet transformed,
5981  * a new transformed constraint for this constraint is created
5982  */
5984  SCIP_CONS* origcons, /**< original constraint */
5985  BMS_BLKMEM* blkmem, /**< block memory buffer */
5986  SCIP_SET* set, /**< global SCIP settings */
5987  SCIP_CONS** transcons /**< pointer to store the transformed constraint */
5988  )
5989 {
5990  assert(origcons != NULL);
5991  assert(set != NULL);
5992  assert(origcons->scip == set->scip);
5993  assert(origcons->conshdlr != NULL);
5994  assert(origcons->original);
5995  assert(transcons != NULL);
5996 
5997  /* check, if the constraint is already transformed */
5998  if( origcons->transorigcons != NULL )
5999  {
6000  *transcons = origcons->transorigcons;
6001  SCIPconsCapture(*transcons);
6002  }
6003  else
6004  {
6005  /* create transformed constraint */
6006  if( origcons->conshdlr->constrans != NULL )
6007  {
6008  /* use constraint handler's own method to transform constraint */
6009  SCIP_CALL( origcons->conshdlr->constrans(set->scip, origcons->conshdlr, origcons, transcons) );
6010  }
6011  else
6012  {
6013  /* create new constraint with a pointer copy of the constraint data */
6014  SCIP_CALL( SCIPconsCreate(transcons, blkmem, set, origcons->name, origcons->conshdlr, origcons->consdata, origcons->initial,
6015  origcons->separate, origcons->enforce, origcons->check, origcons->propagate,
6016  origcons->local, origcons->modifiable, origcons->dynamic, origcons->removable, origcons->stickingatnode,
6017  FALSE, FALSE) );
6018  }
6019 
6020  /* link original and transformed constraint */
6021  origcons->transorigcons = *transcons;
6022  (*transcons)->transorigcons = origcons;
6023 
6024  /* copy the number of upgradelocks */
6025  (*transcons)->nupgradelocks = origcons->nupgradelocks; /*lint !e732*/
6026  }
6027  assert(*transcons != NULL);
6028 
6029  return SCIP_OKAY;
6030 }
6031 
6032 /** sets the initial flag of the given constraint */
6034  SCIP_CONS* cons, /**< constraint */
6035  SCIP_SET* set, /**< global SCIP settings */
6036  SCIP_STAT* stat, /**< dynamic problem statistics */
6037  SCIP_Bool initial /**< new value */
6038  )
6039 {
6040  assert(cons != NULL);
6041  assert(set != NULL);
6042  assert(cons->scip == set->scip);
6043 
6044  if( cons->initial != initial )
6045  {
6046  cons->initial = initial;
6047  if( !cons->original )
6048  {
6049  if( cons->initial )
6050  {
6051  SCIP_CALL( conshdlrAddInitcons(SCIPconsGetHdlr(cons), set, stat, cons) );
6052  }
6053  else
6054  {
6055  if( cons->initconsspos >= 0 )
6056  {
6057  conshdlrDelInitcons(SCIPconsGetHdlr(cons), cons);
6058  }
6059  }
6060  }
6061  }
6062 
6063  return SCIP_OKAY;
6064 }
6065 
6066 /** sets the separate flag of the given constraint */
6068  SCIP_CONS* cons, /**< constraint */
6069  SCIP_SET* set, /**< global SCIP settings */
6070  SCIP_Bool separate /**< new value */
6071  )
6072 {
6073  assert(cons != NULL);
6074  assert(set != NULL);
6075  assert(cons->scip == set->scip);
6076 
6077  if( cons->separate != separate )
6078  {
6079  if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM )
6080  {
6081  cons->separate = separate;
6082  }
6083  else if( cons->enabled && cons->sepaenabled )
6084  {
6085  if( separate )
6086  {
6087  cons->separate = separate;
6088  SCIP_CALL( conshdlrAddSepacons(cons->conshdlr, set, cons) );
6089  }
6090  else
6091  {
6092  conshdlrDelSepacons(cons->conshdlr, cons);
6093  cons->separate = separate;
6094  }
6095  }
6096  }
6097 
6098  return SCIP_OKAY;
6099 }
6100 
6101 /** sets the enforce flag of the given constraint */
6103  SCIP_CONS* cons, /**< constraint */
6104  SCIP_SET* set, /**< global SCIP settings */
6105  SCIP_Bool enforce /**< new value */
6106  )
6107 {
6108  assert(cons != NULL);
6109  assert(set != NULL);
6110  assert(cons->scip == set->scip);
6111 
6112  if( cons->enforce != enforce )
6113  {
6114  if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM )
6115  {
6116  cons->enforce = enforce;
6117  }
6118  else if( cons->enabled )
6119  {
6120  if( enforce )
6121  {
6122  cons->enforce = enforce;
6123  SCIP_CALL( conshdlrAddEnfocons(cons->conshdlr, set, cons) );
6124  }
6125  else
6126  {
6127  conshdlrDelEnfocons(cons->conshdlr, cons);
6128  cons->enforce = enforce;
6129  }
6130  }
6131  }
6132 
6133  return SCIP_OKAY;
6134 }
6135 
6136 /** sets the check flag of the given constraint */
6138  SCIP_CONS* cons, /**< constraint */
6139  SCIP_SET* set, /**< global SCIP settings */
6140  SCIP_Bool check /**< new value */
6141  )
6142 {
6143  assert(cons != NULL);
6144  assert(set != NULL);
6145  assert(cons->scip == set->scip);
6146 
6147  if( cons->check != check )
6148  {
6149  cons->check = check;
6150 
6151  if( !cons->original )
6152  {
6153  /* if constraint is a problem constraint, update variable roundings locks */
6154  if( cons->addconssetchg == NULL && cons->addarraypos >= 0 )
6155  {
6156  if( cons->check )
6157  {
6158  SCIP_CALL( SCIPconsAddLocks(cons, set, +1, 0) );
6159  }
6160  else
6161  {
6162  SCIP_CALL( SCIPconsAddLocks(cons, set, -1, 0) );
6163  }
6164  }
6165 
6166  /* if constraint is active, update the checkconss array of the constraint handler */
6167  if( cons->active )
6168  {
6169  if( cons->check )
6170  {
6171  SCIP_CALL( conshdlrAddCheckcons(cons->conshdlr, set, cons) );
6172  }
6173  else
6174  {
6175  conshdlrDelCheckcons(cons->conshdlr, cons);
6176  }
6177  }
6178  }
6179  }
6180 
6181  return SCIP_OKAY;
6182 }
6183 
6184 /** sets the propagate flag of the given constraint */
6186  SCIP_CONS* cons, /**< constraint */
6187  SCIP_SET* set, /**< global SCIP settings */
6188  SCIP_Bool propagate /**< new value */
6189  )
6190 {
6191  assert(cons != NULL);
6192  assert(set != NULL);
6193  assert(cons->scip == set->scip);
6194 
6195  if( cons->propagate != propagate )
6196  {
6197  if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM )
6198  {
6199  cons->propagate = propagate;
6200  }
6201  else if( cons->enabled && cons->propenabled )
6202  {
6203  if( propagate )
6204  {
6205  cons->propagate = propagate;
6206  SCIP_CALL( conshdlrAddPropcons(cons->conshdlr, set, cons) );
6207  }
6208  else
6209  {
6210  conshdlrDelPropcons(cons->conshdlr, cons);
6211  cons->propagate = propagate;
6212  }
6213  }
6214  }
6215 
6216  return SCIP_OKAY;
6217 }
6218 
6219 /** sets the local flag of the given constraint */
6221  SCIP_CONS* cons, /**< constraint */
6222  SCIP_Bool local /**< new value */
6223  )
6224 {
6225  assert(cons != NULL);
6226 
6227  cons->local = local;
6228  if( !local )
6229  cons->validdepth = 0;
6230 }
6231 
6232 /** sets the modifiable flag of the given constraint */
6234  SCIP_CONS* cons, /**< constraint */
6235  SCIP_Bool modifiable /**< new value */
6236  )
6237 {
6238  assert(cons != NULL);
6239 
6240  cons->modifiable = modifiable;
6241 }
6242 
6243 /** sets the dynamic flag of the given constraint */
6245  SCIP_CONS* cons, /**< constraint */
6246  SCIP_Bool dynamic /**< new value */
6247  )
6248 {
6249  assert(cons != NULL);
6250 
6251  cons->dynamic = dynamic;
6252 }
6253 
6254 /** sets the removable flag of the given constraint */
6256  SCIP_CONS* cons, /**< constraint */
6257  SCIP_Bool removable /**< new value */
6258  )
6259 {
6260  assert(cons != NULL);
6261 
6262  cons->removable = removable;
6263 }
6264 
6265 /** sets the stickingatnode flag of the given constraint */
6267  SCIP_CONS* cons, /**< constraint */
6268  SCIP_Bool stickingatnode /**< new value */
6269  )
6270 {
6271  assert(cons != NULL);
6272 
6273  cons->stickingatnode = stickingatnode;
6274 }
6275 
6276 /** gives the constraint a new name; ATTENTION: to old pointer is over written that might
6277  * result in a memory leakage */
6279  SCIP_CONS* cons, /**< constraint */
6280  const char* name /**< new name of constraint */
6281  )
6282 {
6283  assert( cons != NULL );
6284  assert( name != NULL );
6285 
6286  cons->name = (char*)name;
6287 }
6288 
6289 /** gets associated transformed constraint of an original constraint, or NULL if no associated transformed constraint
6290  * exists
6291  */
6293  SCIP_CONS* cons /**< constraint */
6294  )
6295 {
6296  assert(cons->original);
6297 
6298  return cons->transorigcons;
6299 }
6300 
6301 /** activates constraint or marks constraint to be activated in next update */
6303  SCIP_CONS* cons, /**< constraint */
6304  SCIP_SET* set, /**< global SCIP settings */
6305  SCIP_STAT* stat, /**< dynamic problem statistics */
6306  int depth, /**< depth in the tree where the constraint activation takes place, or -1 for global problem */
6307  SCIP_Bool focusnode /**< does the constraint activation take place at the focus node? */
6308  )
6309 {
6310  assert(cons != NULL);
6311  assert(!cons->original);
6312  assert(!cons->active);
6313  assert(!cons->updateactivate);
6314  assert(!cons->updatedeactivate);
6315  assert(!cons->updateenable);
6316  assert(!cons->updatedisable);
6317  assert(!cons->updateobsolete);
6318  assert(!cons->updatefree);
6319  assert(cons->activedepth == -2);
6320  assert(cons->conshdlr != NULL);
6321  assert(set != NULL);
6322  assert(cons->scip == set->scip);
6323 
6324  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6325  {
6326  SCIPdebugMessage("delayed activation of constraint <%s> in constraint handler <%s> (depth %d)\n",
6327  cons->name, cons->conshdlr->name, depth);
6328  cons->updateactivate = TRUE;
6329  cons->activedepth = depth;
6330  cons->updateactfocus = focusnode;
6331  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6332  assert(cons->update);
6333  }
6334  else
6335  {
6336  SCIP_CALL( conshdlrActivateCons(cons->conshdlr, set, stat, cons, depth, focusnode) );
6337  assert(cons->active);
6338  }
6339 
6340  return SCIP_OKAY;
6341 }
6342 
6343 /** deactivates constraint or marks constraint to be deactivated in next update */
6345  SCIP_CONS* cons, /**< constraint */
6346  SCIP_SET* set, /**< global SCIP settings */
6347  SCIP_STAT* stat /**< dynamic problem statistics */
6348  )
6349 {
6350  assert(cons != NULL);
6351  assert(!cons->original);
6352  assert(cons->active);
6353  assert(!cons->updateactivate);
6354  assert(!cons->updatedeactivate);
6355  assert(cons->activedepth >= -1);
6356  assert(cons->conshdlr != NULL);
6357  assert(set != NULL);
6358  assert(cons->scip == set->scip);
6359 
6360  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6361  {
6362  SCIPdebugMessage("delayed deactivation of constraint <%s> in constraint handler <%s>\n",
6363  cons->name, cons->conshdlr->name);
6364  cons->updatedeactivate = TRUE;
6365  cons->activedepth = -2;
6366  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6367  assert(cons->update);
6368  }
6369  else
6370  {
6371  SCIP_CALL( conshdlrDeactivateCons(cons->conshdlr, set, stat, cons) );
6372  assert(!cons->active);
6373  }
6374 
6375  return SCIP_OKAY;
6376 }
6377 
6378 /** enables constraint's separation, enforcing, and propagation capabilities or marks them to be enabled in next update */
6380  SCIP_CONS* cons, /**< constraint */
6381  SCIP_SET* set, /**< global SCIP settings */
6382  SCIP_STAT* stat /**< dynamic problem statistics */
6383  )
6384 {
6385  assert(cons != NULL);
6386  assert(!cons->original);
6387  assert(cons->conshdlr != NULL);
6388  assert(set != NULL);
6389  assert(cons->scip == set->scip);
6390 
6391  if( !cons->active || cons->updatedeactivate || cons->updateenable || (cons->enabled && !cons->updatedisable) )
6392  return SCIP_OKAY;
6393 
6394  assert(!cons->updateactivate);
6395 
6396  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6397  {
6398  cons->updateenable = TRUE;
6399  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6400  assert(cons->update);
6401  }
6402  else
6403  {
6404  SCIP_CALL( conshdlrEnableCons(cons->conshdlr, set, stat, cons) );
6405  assert(cons->enabled);
6406  }
6407 
6408  return SCIP_OKAY;
6409 }
6410 
6411 /** disables constraint's separation, enforcing, and propagation capabilities or marks them to be disabled in next update */
6413  SCIP_CONS* cons, /**< constraint */
6414  SCIP_SET* set, /**< global SCIP settings */
6415  SCIP_STAT* stat /**< dynamic problem statistics */
6416  )
6417 {
6418  assert(cons != NULL);
6419  assert(!cons->original);
6420  assert(cons->conshdlr != NULL);
6421  assert(set != NULL);
6422  assert(cons->scip == set->scip);
6423 
6424  if( cons->updatedisable || (!cons->enabled && !cons->updateenable) )
6425  return SCIP_OKAY;
6426 
6427  assert(cons->active);
6428  assert(!cons->updateactivate);
6429 
6430  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6431  {
6432  cons->updatedisable = TRUE;
6433  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6434  assert(cons->update);
6435  }
6436  else
6437  {
6438  SCIP_CALL( conshdlrDisableCons(cons->conshdlr, set, stat, cons) );
6439  assert(!cons->enabled);
6440  }
6441 
6442  return SCIP_OKAY;
6443 }
6444 
6445 /** enables constraint's separation capabilities or marks them to be enabled in next update */
6447  SCIP_CONS* cons, /**< constraint */
6448  SCIP_SET* set /**< global SCIP settings */
6449  )
6450 {
6451  assert(cons != NULL);
6452  assert(cons->conshdlr != NULL);
6453  assert(set != NULL);
6454  assert(cons->scip == set->scip);
6455 
6456  if( cons->updatesepaenable || (cons->sepaenabled && !cons->updatesepadisable) )
6457  return SCIP_OKAY;
6458 
6459  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6460  {
6461  cons->updatesepadisable = FALSE;
6462  cons->updatesepaenable = TRUE;
6463  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6464  assert(cons->update);
6465  }
6466  else
6467  {
6468  SCIP_CALL( conshdlrEnableConsSeparation(cons->conshdlr, set, cons) );
6469  assert(cons->sepaenabled);
6470  }
6471 
6472  return SCIP_OKAY;
6473 }
6474 
6475 /** disables constraint's separation capabilities or marks them to be disabled in next update */
6477  SCIP_CONS* cons, /**< constraint */
6478  SCIP_SET* set /**< global SCIP settings */
6479  )
6480 {
6481  assert(cons != NULL);
6482  assert(cons->conshdlr != NULL);
6483 
6484  if( cons->updatesepadisable || (!cons->sepaenabled && !cons->updatesepaenable) )
6485  return SCIP_OKAY;
6486 
6487  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6488  {
6489  cons->updatesepaenable = FALSE;
6490  cons->updatesepadisable = TRUE;
6491  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6492  assert(cons->update);
6493  }
6494  else
6495  {
6497  assert(!cons->sepaenabled);
6498  }
6499 
6500  return SCIP_OKAY;
6501 }
6502 
6503 /** enables constraint's propagation capabilities or marks them to be enabled in next update */
6505  SCIP_CONS* cons, /**< constraint */
6506  SCIP_SET* set /**< global SCIP settings */
6507  )
6508 {
6509  assert(cons != NULL);
6510  assert(cons->conshdlr != NULL);
6511  assert(set != NULL);
6512  assert(cons->scip == set->scip);
6513 
6514  if( cons->updatepropenable || (cons->propenabled && !cons->updatepropdisable) )
6515  return SCIP_OKAY;
6516 
6517  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6518  {
6519  cons->updatepropdisable = FALSE;
6520  cons->updatepropenable = TRUE;
6521  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6522  assert(cons->update);
6523  }
6524  else
6525  {
6526  SCIP_CALL( conshdlrEnableConsPropagation(cons->conshdlr, set, cons) );
6527  assert(cons->propenabled);
6528  }
6529 
6530  return SCIP_OKAY;
6531 }
6532 
6533 /** disables constraint's propagation capabilities or marks them to be disabled in next update */
6535  SCIP_CONS* cons, /**< constraint */
6536  SCIP_SET* set /**< global SCIP settings */
6537  )
6538 {
6539  assert(cons != NULL);
6540  assert(cons->conshdlr != NULL);
6541  assert(set != NULL);
6542  assert(cons->scip == set->scip);
6543 
6544  if( cons->updatepropdisable || (!cons->propenabled && !cons->updatepropenable) )
6545  return SCIP_OKAY;
6546 
6547  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6548  {
6549  cons->updatepropenable = FALSE;
6550  cons->updatepropdisable = TRUE;
6551  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6552  assert(cons->update);
6553  }
6554  else
6555  {
6557  assert(!cons->propenabled);
6558  }
6559 
6560  return SCIP_OKAY;
6561 }
6562 
6563 /** marks the constraint to be propagated (update might be delayed) */
6565  SCIP_CONS* cons, /**< constraint */
6566  SCIP_SET* set /**< global SCIP settings */
6567  )
6568 {
6569  assert(cons != NULL);
6570  assert(cons->conshdlr != NULL);
6571  assert(set != NULL);
6572  assert(cons->scip == set->scip);
6573 
6574  if( cons->updatemarkpropagate || (cons->markpropagate && !cons->updateunmarkpropagate) )
6575  return SCIP_OKAY;
6576 
6577  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6578  {
6579  cons->updateunmarkpropagate = FALSE;
6580  cons->updatemarkpropagate = TRUE;
6581  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6582  assert(cons->update);
6583  }
6584  else
6585  {
6586  conshdlrMarkConsPropagate(cons->conshdlr, cons);
6587  assert(cons->markpropagate || !cons->enabled);
6588  }
6589 
6590  return SCIP_OKAY;
6591 }
6592 
6593 /** unmarks the constraint to be propagated (update might be delayed) */
6595  SCIP_CONS* cons, /**< constraint */
6596  SCIP_SET* set /**< global SCIP settings */
6597  )
6598 {
6599  assert(cons != NULL);
6600  assert(cons->conshdlr != NULL);
6601  assert(set != NULL);
6602  assert(cons->scip == set->scip);
6603 
6604  if( cons->updateunmarkpropagate || (!cons->markpropagate && !cons->updatemarkpropagate) )
6605  return SCIP_OKAY;
6606 
6607  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6608  {
6609  cons->updatemarkpropagate = FALSE;
6610  cons->updateunmarkpropagate = TRUE;
6611  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6612  assert(cons->update);
6613  }
6614  else
6615  {
6617  assert(!cons->markpropagate || !cons->enabled);
6618  }
6619 
6620  return SCIP_OKAY;
6621 
6622 }
6623 
6624 /** adds given value to age of constraint, but age can never become negative;
6625  * should be called
6626  * - in constraint separation, if no cut was found for this constraint,
6627  * - in constraint enforcing, if constraint was feasible, and
6628  * - in constraint propagation, if no domain reduction was deduced;
6629  * if it's age exceeds the constraint age limit, makes constraint obsolete or marks constraint to be made obsolete
6630  * in next update
6631  */
6633  SCIP_CONS* cons, /**< constraint */
6634  BMS_BLKMEM* blkmem, /**< block memory */
6635  SCIP_SET* set, /**< global SCIP settings */
6636  SCIP_STAT* stat, /**< dynamic problem statistics */
6637  SCIP_PROB* prob, /**< problem data */
6638  SCIP_Real deltaage /**< value to add to the constraint's age */
6639  )
6640 {
6641  assert(cons != NULL);
6642  assert(cons->conshdlr != NULL);
6643  assert(!cons->updateactivate);
6644  assert(set != NULL);
6645  assert(cons->scip == set->scip);
6646 
6647  /* no aging in presolving */
6648  if( set->stage == SCIP_STAGE_PRESOLVING )
6649  return SCIP_OKAY;
6650 
6651  SCIPdebugMessage("adding %g to age (%g) of constraint <%s> of handler <%s>\n",
6652  deltaage, cons->age, cons->name, cons->conshdlr->name);
6653 
6654  cons->age += deltaage;
6655  cons->age = MAX(cons->age, 0.0);
6656 
6657  if( !cons->original )
6658  {
6659  if( !cons->check && consExceedsAgelimit(cons, set) )
6660  {
6661  SCIP_CALL( SCIPconsDelete(cons, blkmem, set, stat, prob) );
6662  }
6663  else if( !cons->obsolete && consExceedsObsoleteage(cons, set) )
6664  {
6665  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6666  {
6667  cons->updateobsolete = TRUE;
6668  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6669  assert(cons->update);
6670  }
6671  else
6672  {
6674  assert(cons->obsolete);
6675  }
6676  }
6677  }
6678 
6679  return SCIP_OKAY;
6680 }
6681 
6682 /** increases age of constraint by 1.0;
6683  * should be called
6684  * - in constraint separation, if no cut was found for this constraint,
6685  * - in constraint enforcing, if constraint was feasible, and
6686  * - in constraint propagation, if no domain reduction was deduced;
6687  * if it's age exceeds the constraint age limit, makes constraint obsolete or marks constraint to be made obsolete
6688  * in next update
6689  */
6691  SCIP_CONS* cons, /**< constraint */
6692  BMS_BLKMEM* blkmem, /**< block memory */
6693  SCIP_SET* set, /**< global SCIP settings */
6694  SCIP_STAT* stat, /**< dynamic problem statistics */
6695  SCIP_PROB* prob /**< problem data */
6696  )
6697 {
6698  SCIP_CALL( SCIPconsAddAge(cons, blkmem, set, stat, prob, 1.0) );
6699 
6700  return SCIP_OKAY;
6701 }
6702 
6703 /** resets age of constraint to zero;
6704  * should be called
6705  * - in constraint separation, if a cut was found for this constraint,
6706  * - in constraint enforcing, if the constraint was violated, and
6707  * - in constraint propagation, if a domain reduction was deduced;
6708  * if it was obsolete, makes constraint useful again or marks constraint to be made useful again in next update
6709  */
6711  SCIP_CONS* cons, /**< constraint */
6712  SCIP_SET* set /**< global SCIP settings */
6713  )
6714 {
6715  assert(cons != NULL);
6716  assert(cons->conshdlr != NULL);
6717  assert(!cons->updateactivate);
6718  assert(set != NULL);
6719  assert(cons->scip == set->scip);
6720 
6721  SCIPdebugMessage("resetting age %g of constraint <%s> of handler <%s>\n", cons->age, cons->name, cons->conshdlr->name);
6722 
6723  conshdlrUpdateAgeresetavg(cons->conshdlr, cons->age);
6724  cons->age = 0.0;
6725 
6726  if( cons->obsolete )
6727  {
6728  assert(!cons->original);
6729  if( conshdlrAreUpdatesDelayed(cons->conshdlr) )
6730  {
6731  cons->updateobsolete = TRUE;
6732  SCIP_CALL( conshdlrAddUpdateCons(cons->conshdlr, set, cons) );
6733  assert(cons->update);
6734  }
6735  else
6736  {
6737  SCIP_CALL( conshdlrMarkConsUseful(cons->conshdlr, cons) );
6738  assert(!cons->obsolete);
6739  }
6740  }
6741 
6742  return SCIP_OKAY;
6743 }
6744 
6745 /** adds an active constraint to the propagation queue(if not already marked for propagation) of corresponding
6746  * constraint handler and marks the constraint to be propagated in the next propagation round
6747  *
6748  * @note if constraint is added to the queue it will be captured
6749  */
6751  SCIP_CONS* cons /**< constraint */
6752  )
6753 {
6754  assert(cons != NULL);
6755  assert(cons->conshdlr != NULL);
6756 
6757  if( !SCIPconsIsActive(cons) )
6758  return SCIP_OKAY;
6759 
6760  if( !cons->markedprop )
6761  {
6762  SCIP_CALL( SCIPqueueInsert(cons->conshdlr->pendingconss, (void*)cons) );
6763  SCIPconsCapture(cons);
6764  cons->markedprop = TRUE;
6765  }
6766  assert(cons->markedprop);
6767 
6768  return SCIP_OKAY;
6769 }
6770 
6771 /** returns first constraint from propagation queue(if not empty) of given constraint handler */
6773  SCIP_CONSHDLR* conshdlr /**< constraint handler */
6774  )
6775 {
6776  if( SCIPqueueIsEmpty(conshdlr->pendingconss) )
6777  return NULL;
6778 
6779  return (SCIP_CONS*)SCIPqueueFirst(conshdlr->pendingconss);
6780 }
6781 
6782 /** removes constraint from propagation queue(if not empty) of given constraint handler and unmarks constraint to be
6783  * propagated in the next propagation round
6784  *
6785  * @note if constraint is removed from the queue it will be released
6786  */
6788  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
6789  BMS_BLKMEM* blkmem, /**< block memory */
6790  SCIP_SET* set /**< global SCIP settings */
6791  )
6792 {
6793  SCIP_CONS* cons;
6794 
6795  if( SCIPqueueIsEmpty(conshdlr->pendingconss) )
6796  return SCIP_OKAY;
6797 
6798  cons = (SCIP_CONS*)SCIPqueueRemove(conshdlr->pendingconss);
6799  assert(cons != NULL);
6800 
6801  cons->markedprop = FALSE;
6802  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
6803 
6804  return SCIP_OKAY;
6805 }
6806 
6807 /** resolves the given conflicting bound, that was deduced by the given constraint, by putting all "reason" bounds
6808  * leading to the deduction into the conflict queue with calls to SCIPaddConflictLb(), SCIPaddConflictUb(), SCIPaddConflictBd(),
6809  * SCIPaddConflictRelaxedLb(), SCIPaddConflictRelaxedUb(), SCIPaddConflictRelaxedBd(), or SCIPaddConflictBinvar();
6810  *
6811  * @note it is sufficient to explain the relaxed bound change
6812  */
6814  SCIP_CONS* cons, /**< constraint that deduced the assignment */
6815  SCIP_SET* set, /**< global SCIP settings */
6816  SCIP_VAR* infervar, /**< variable whose bound was deduced by the constraint */
6817  int inferinfo, /**< user inference information attached to the bound change */
6818  SCIP_BOUNDTYPE inferboundtype, /**< bound that was deduced (lower or upper bound) */
6819  SCIP_BDCHGIDX* bdchgidx, /**< bound change index, representing the point of time where change took place */
6820  SCIP_Real relaxedbd, /**< the relaxed bound */
6821  SCIP_RESULT* result /**< pointer to store the result of the callback method */
6822  )
6823 {
6824  SCIP_CONSHDLR* conshdlr;
6825 
6826  assert(cons != NULL);
6827  assert((inferboundtype == SCIP_BOUNDTYPE_LOWER
6828  && SCIPvarGetLbAtIndex(infervar, bdchgidx, TRUE) > SCIPvarGetLbGlobal(infervar))
6829  || (inferboundtype == SCIP_BOUNDTYPE_UPPER
6830  && SCIPvarGetUbAtIndex(infervar, bdchgidx, TRUE) < SCIPvarGetUbGlobal(infervar)));
6831  assert(result != NULL);
6832  assert(set != NULL);
6833  assert(cons->scip == set->scip);
6834 
6835  *result = SCIP_DIDNOTRUN;
6836 
6837  conshdlr = cons->conshdlr;
6838  assert(conshdlr != NULL);
6839 
6840  if( conshdlr->consresprop != NULL )
6841  {
6842  /* start timing */
6843  SCIPclockStart(conshdlr->resproptime, set);
6844 
6845  SCIP_CALL( conshdlr->consresprop(set->scip, conshdlr, cons, infervar, inferinfo, inferboundtype, bdchgidx,
6846  relaxedbd, result) );
6847 
6848  /* stop timing */
6849  SCIPclockStop(conshdlr->resproptime, set);
6850 
6851  /* update statistics */
6852  conshdlr->nrespropcalls++;
6853 
6854  /* check result code */
6855  if( *result != SCIP_SUCCESS && *result != SCIP_DIDNOTFIND )
6856  {
6857  SCIPerrorMessage("propagation conflict resolving method of constraint handler <%s> returned invalid result <%d>\n",
6858  conshdlr->name, *result);
6859  return SCIP_INVALIDRESULT;
6860  }
6861  }
6862  else
6863  {
6864  SCIPerrorMessage("propagation conflict resolving method of constraint handler <%s> is not implemented\n",
6865  conshdlr->name);
6866  return SCIP_PLUGINNOTFOUND;
6867  }
6868 
6869  return SCIP_OKAY;
6870 }
6871 
6872 /** adds given values to lock status of the constraint and updates the rounding locks of the involved variables */
6874  SCIP_CONS* cons, /**< constraint */
6875  SCIP_SET* set, /**< global SCIP settings */
6876  int nlockspos, /**< increase in number of rounding locks for constraint */
6877  int nlocksneg /**< increase in number of rounding locks for constraint's negation */
6878  )
6879 {
6880  int oldnlockspos;
6881  int oldnlocksneg;
6882  int updlockpos;
6883  int updlockneg;
6884 
6885  assert(cons != NULL);
6886  assert(cons->conshdlr != NULL);
6887  assert(cons->conshdlr->conslock != NULL);
6888  assert(cons->nlockspos >= 0);
6889  assert(cons->nlocksneg >= 0);
6890  assert(-2 <= nlockspos && nlockspos <= 2);
6891  assert(-2 <= nlocksneg && nlocksneg <= 2);
6892  assert(set != NULL);
6893  assert(cons->scip == set->scip);
6894 
6895  /* update the rounding locks */
6896  oldnlockspos = cons->nlockspos;
6897  oldnlocksneg = cons->nlocksneg;
6898  cons->nlockspos += nlockspos;
6899  cons->nlocksneg += nlocksneg;
6900  assert(cons->nlockspos >= 0);
6901  assert(cons->nlocksneg >= 0);
6902 
6903  /* check, if the constraint switched from unlocked to locked, or from locked to unlocked */
6904  updlockpos = (int)(cons->nlockspos > 0) - (int)(oldnlockspos > 0);
6905  updlockneg = (int)(cons->nlocksneg > 0) - (int)(oldnlocksneg > 0);
6906 
6907  /* lock the variables, if the constraint switched from unlocked to locked or from locked to unlocked */
6908  if( updlockpos != 0 || updlockneg != 0 )
6909  {
6910  SCIP_CALL( cons->conshdlr->conslock(set->scip, cons->conshdlr, cons, updlockpos, updlockneg) );
6911  }
6912 
6913  return SCIP_OKAY;
6914 }
6915 
6916 /** checks single constraint for feasibility of the given solution */
6918  SCIP_CONS* cons, /**< constraint to check */
6919  SCIP_SET* set, /**< global SCIP settings */
6920  SCIP_SOL* sol, /**< primal CIP solution */
6921  SCIP_Bool checkintegrality, /**< has integrality to be checked? */
6922  SCIP_Bool checklprows, /**< have current LP rows to be checked? */
6923  SCIP_Bool printreason, /**< should the reason for the violation be printed? */
6924  SCIP_RESULT* result /**< pointer to store the result of the callback method */
6925  )
6926 {
6927  SCIP_CONSHDLR* conshdlr;
6928 
6929  assert(cons != NULL);
6930  assert(set != NULL);
6931  assert(cons->scip == set->scip);
6932  assert(result != NULL);
6933 
6934  conshdlr = cons->conshdlr;
6935  assert(conshdlr != NULL);
6936 
6937  /* call external method */
6938  assert(conshdlr->conscheck != NULL);
6939 
6940  SCIP_CALL( conshdlr->conscheck(set->scip, conshdlr, &cons, 1, sol, checkintegrality, checklprows, printreason, result) );
6941  SCIPdebugMessage(" -> checking returned result <%d>\n", *result);
6942 
6943  if( *result != SCIP_INFEASIBLE && *result != SCIP_FEASIBLE )
6944  {
6945  SCIPerrorMessage("feasibility check of constraint handler <%s> on constraint <%s> returned invalid result <%d>\n",
6946  conshdlr->name, cons->name, *result);
6947  return SCIP_INVALIDRESULT;
6948  }
6949 
6950  return SCIP_OKAY;
6951 }
6952 
6953 /** enforces single constraint for a given pseudo solution */
6955  SCIP_CONS* cons, /**< constraint to enforce */
6956  SCIP_SET* set, /**< global SCIP settings */
6957  SCIP_Bool solinfeasible, /**< was the solution already declared infeasible by a constraint handler? */
6958  SCIP_Bool objinfeasible, /**< is the solution infeasible anyway due to violating lower objective bound? */
6959  SCIP_RESULT* result /**< pointer to store the result of the callback method */
6960  )
6961 {
6962  SCIP_CONSHDLR* conshdlr;
6963 
6964  assert(cons != NULL);
6965  assert(set != NULL);
6966  assert(cons->scip == set->scip);
6967  assert(result != NULL);
6968 
6969  conshdlr = cons->conshdlr;
6970  assert(conshdlr != NULL);
6971 
6972  /* call external method */
6973  assert(conshdlr->consenfops != NULL);
6974 
6975  SCIP_CALL( conshdlr->consenfops(set->scip, conshdlr, &cons, 1, 1, solinfeasible, objinfeasible, result) );
6976  SCIPdebugMessage(" -> enfops returned result <%d>\n", *result);
6977 
6978  if( *result != SCIP_CUTOFF
6979  && *result != SCIP_CONSADDED
6980  && *result != SCIP_REDUCEDDOM
6981  && *result != SCIP_BRANCHED
6982  && *result != SCIP_SOLVELP
6983  && *result != SCIP_INFEASIBLE
6984  && *result != SCIP_FEASIBLE
6985  && *result != SCIP_DIDNOTRUN )
6986  {
6987  SCIPerrorMessage("enforcing method of constraint handler <%s> for pseudo solutions returned invalid result <%d>\n",
6988  conshdlr->name, *result);
6989  return SCIP_INVALIDRESULT;
6990  }
6991 
6992  /* do not update statistics */
6993 
6994  return SCIP_OKAY;
6995 }
6996 
6997 /** enforces single constraint for a given LP solution */
6999  SCIP_CONS* cons, /**< constraint to enforce */
7000  SCIP_SET* set, /**< global SCIP settings */
7001  SCIP_Bool solinfeasible, /**< was the solution already declared infeasible by a constraint handler? */
7002  SCIP_RESULT* result /**< pointer to store the result of the callback method */
7003  )
7004 {
7005  SCIP_CONSHDLR* conshdlr;
7006 
7007  assert(cons != NULL);
7008  assert(set != NULL);
7009  assert(cons->scip == set->scip);
7010  assert(result != NULL);
7011 
7012  conshdlr = cons->conshdlr;
7013  assert(conshdlr != NULL);
7014 
7015  /* call external method */
7016  assert(conshdlr->consenfolp != NULL);
7017 
7018  SCIP_CALL( conshdlr->consenfolp(set->scip, conshdlr, &cons, 1, 1, solinfeasible, result) );
7019  SCIPdebugMessage(" -> enfolp returned result <%d>\n", *result);
7020 
7021  if( *result != SCIP_CUTOFF
7022  && *result != SCIP_CONSADDED
7023  && *result != SCIP_REDUCEDDOM
7024  && *result != SCIP_BRANCHED
7025  && *result != SCIP_SEPARATED
7026  && *result != SCIP_INFEASIBLE
7027  && *result != SCIP_FEASIBLE)
7028  {
7029  SCIPerrorMessage("enforcing method of constraint handler <%s> for LP returned invalid result <%d>\n",
7030  conshdlr->name, *result);
7031  return SCIP_INVALIDRESULT;
7032  }
7033 
7034  /* do not update statistics */
7035 
7036  return SCIP_OKAY;
7037 }
7038 
7039 
7040 /** calls LP initialization method for single constraint */
7042  SCIP_CONS* cons, /**< constraint to initialize */
7043  SCIP_SET* set /**< global SCIP settings */
7044  )
7045 {
7046  SCIP_CONSHDLR* conshdlr;
7047 
7048  assert(cons != NULL);
7049  assert(set != NULL);
7050  assert(cons->scip == set->scip);
7051 
7052  conshdlr = cons->conshdlr;
7053  assert(conshdlr != NULL);
7054 
7055  /* call external method */
7056  if( conshdlr->consinitlp != NULL )
7057  {
7058  SCIP_CALL( conshdlr->consinitlp(set->scip, conshdlr, &cons, 1) );
7059  }
7060 
7061  return SCIP_OKAY;
7062 }
7063 
7064 /** calls separation method of single constraint for LP solution */
7066  SCIP_CONS* cons, /**< constraint to separate */
7067  SCIP_SET* set, /**< global SCIP settings */
7068  SCIP_RESULT* result /**< pointer to store the result of the separation call */
7069  )
7070 {
7071  SCIP_CONSHDLR* conshdlr;
7072 
7073  assert(cons != NULL);
7074  assert(set != NULL);
7075  assert(cons->scip == set->scip);
7076  assert(result != NULL);
7077 
7078  conshdlr = cons->conshdlr;
7079  assert(conshdlr != NULL);
7080 
7081  /* call external method */
7082  if( conshdlr->conssepalp != NULL )
7083  {
7084  SCIP_CALL( conshdlr->conssepalp(set->scip, conshdlr, &cons, 1, 1, result) );
7085  SCIPdebugMessage(" -> sepalp returned result <%d>\n", *result);
7086 
7087  if( *result != SCIP_CUTOFF
7088  && *result != SCIP_CONSADDED
7089  && *result != SCIP_REDUCEDDOM
7090  && *result != SCIP_SEPARATED
7091  && *result != SCIP_NEWROUND
7092  && *result != SCIP_DIDNOTFIND
7093  && *result != SCIP_DIDNOTRUN
7094  && *result != SCIP_DELAYED )
7095  {
7096  SCIPerrorMessage("separation method of constraint handler <%s> returned invalid result <%d>\n", conshdlr->name,
7097  *result);
7098  return SCIP_INVALIDRESULT;
7099  }
7100  }
7101 
7102  return SCIP_OKAY;
7103 }
7104 
7105 /** calls separation method of single constraint for given primal solution */
7107  SCIP_CONS* cons, /**< constraint to separate */
7108  SCIP_SET* set, /**< global SCIP settings */
7109  SCIP_SOL* sol, /**< primal solution that should be separated */
7110  SCIP_RESULT* result /**< pointer to store the result of the separation call */
7111  )
7112 {
7113  SCIP_CONSHDLR* conshdlr;
7114 
7115  assert(cons != NULL);
7116  assert(set != NULL);
7117  assert(cons->scip == set->scip);
7118  assert(sol != NULL);
7119  assert(result != NULL);
7120 
7121  conshdlr = cons->conshdlr;
7122  assert(conshdlr != NULL);
7123 
7124  /* call external method */
7125  if( conshdlr->conssepasol != NULL )
7126  {
7127  SCIP_CALL( conshdlr->conssepasol(set->scip, conshdlr, &cons, 1, 1, sol, result) );
7128  SCIPdebugMessage(" -> sepasol returned result <%d>\n", *result);
7129 
7130  if( *result != SCIP_CUTOFF
7131  && *result != SCIP_CONSADDED
7132  && *result != SCIP_REDUCEDDOM
7133  && *result != SCIP_SEPARATED
7134  && *result != SCIP_NEWROUND
7135  && *result != SCIP_DIDNOTFIND
7136  && *result != SCIP_DIDNOTRUN
7137  && *result != SCIP_DELAYED )
7138  {
7139  SCIPerrorMessage("separation method of constraint handler for arbitrary primal solution <%s> returned invalid result <%d>\n",
7140  conshdlr->name, *result);
7141  return SCIP_INVALIDRESULT;
7142  }
7143  }
7144 
7145  return SCIP_OKAY;
7146 }
7147 
7148 /** calls domain propagation method of single constraint */
7150  SCIP_CONS* cons, /**< constraint to propagate */
7151  SCIP_SET* set, /**< global SCIP settings */
7152  SCIP_PROPTIMING proptiming, /**< current point in the node solving loop */
7153  SCIP_RESULT* result /**< pointer to store the result of the callback method */
7154  )
7155 {
7156  SCIP_CONSHDLR* conshdlr;
7157 
7158  assert(cons != NULL);
7159  assert(set != NULL);
7160  assert(cons->scip == set->scip);
7161  assert(result != NULL);
7162 
7163  conshdlr = cons->conshdlr;
7164  assert(conshdlr != NULL);
7165 
7166  /* call external method */
7167  if( conshdlr->consprop != NULL )
7168  {
7169  SCIP_CALL( conshdlr->consprop(set->scip, conshdlr, &cons, 1, 1, 1, proptiming, result) );
7170  SCIPdebugMessage(" -> prop returned result <%d>\n", *result);
7171 
7172  if( *result != SCIP_CUTOFF
7173  && *result != SCIP_CONSADDED
7174  && *result != SCIP_REDUCEDDOM
7175  && *result != SCIP_DIDNOTFIND
7176  && *result != SCIP_DIDNOTRUN
7177  && *result != SCIP_DELAYED )
7178  {
7179  SCIPerrorMessage("propagation method of constraint handler <%s> returned invalid result <%d>\n",
7180  conshdlr->name, *result);
7181  return SCIP_INVALIDRESULT;
7182  }
7183  }
7184 
7185  return SCIP_OKAY;
7186 }
7187 
7188 /** resolves propagation conflict of single constraint */
7190  SCIP_CONS* cons, /**< constraint to resolve conflict for */
7191  SCIP_SET* set, /**< global SCIP settings */
7192  SCIP_VAR* infervar, /**< the conflict variable whose bound change has to be resolved */
7193  int inferinfo, /**< the user information passed to the corresponding SCIPinferVarLbCons() or SCIPinferVarUbCons() call */
7194  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
7195  SCIP_BDCHGIDX* bdchgidx, /**< the index of the bound change, representing the point of time where the change took place */
7196  SCIP_Real relaxedbd, /**< the relaxed bound which is sufficient to be explained */
7197  SCIP_RESULT* result /**< pointer to store the result of the callback method */
7198  )
7199 {
7200  SCIP_CONSHDLR* conshdlr;
7201 
7202  assert(cons != NULL);
7203  assert(set != NULL);
7204  assert(cons->scip == set->scip);
7205  assert(result != NULL);
7206  assert(infervar != NULL);
7207  assert(bdchgidx != NULL);
7208 
7209  conshdlr = cons->conshdlr;
7210  assert(conshdlr != NULL);
7211 
7212  /* call external method */
7213  if( conshdlr->consresprop != NULL )
7214  {
7215  SCIP_CALL( conshdlr->consresprop(set->scip, conshdlr, cons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
7216  SCIPdebugMessage(" -> resprop returned result <%d>\n", *result);
7217 
7218  if( *result != SCIP_SUCCESS
7219  && *result != SCIP_DIDNOTFIND )
7220  {
7221  SCIPerrorMessage("propagation conflict resolving method of constraint handler <%s> returned invalid result <%d>\n",
7222  conshdlr->name, *result);
7223  return SCIP_INVALIDRESULT;
7224  }
7225  }
7226 
7227  return SCIP_OKAY;
7228 }
7229 
7230 /** presolves single constraint */
7232  SCIP_CONS* cons, /**< constraint to presolve */
7233  SCIP_SET* set, /**< global SCIP settings */
7234  int nrounds, /**< number of presolving rounds already done */
7235  int nnewfixedvars, /**< number of variables fixed since the last call to the presolving method */
7236  int nnewaggrvars, /**< number of variables aggregated since the last call to the presolving method */
7237  int nnewchgvartypes, /**< number of variable type changes since the last call to the presolving method */
7238  int nnewchgbds, /**< number of variable bounds tightened since the last call to the presolving method */
7239  int nnewholes, /**< number of domain holes added since the last call to the presolving method */
7240  int nnewdelconss, /**< number of deleted constraints since the last call to the presolving method */
7241  int nnewaddconss, /**< number of added constraints since the last call to the presolving method */
7242  int nnewupgdconss, /**< number of upgraded constraints since the last call to the presolving method */
7243  int nnewchgcoefs, /**< number of changed coefficients since the last call to the presolving method */
7244  int nnewchgsides, /**< number of changed left or right hand sides since the last call to the presolving method */
7245  int* nfixedvars, /**< pointer to count total number of variables fixed of all presolvers */
7246  int* naggrvars, /**< pointer to count total number of variables aggregated of all presolvers */
7247  int* nchgvartypes, /**< pointer to count total number of variable type changes of all presolvers */
7248  int* nchgbds, /**< pointer to count total number of variable bounds tightened of all presolvers */
7249  int* naddholes, /**< pointer to count total number of domain holes added of all presolvers */
7250  int* ndelconss, /**< pointer to count total number of deleted constraints of all presolvers */
7251  int* naddconss, /**< pointer to count total number of added constraints of all presolvers */
7252  int* nupgdconss, /**< pointer to count total number of upgraded constraints of all presolvers */
7253  int* nchgcoefs, /**< pointer to count total number of changed coefficients of all presolvers */
7254  int* nchgsides, /**< pointer to count total number of changed left/right hand sides of all presolvers */
7255  SCIP_RESULT* result /**< pointer to store the result of the callback method */
7256  )
7257 {
7258  SCIP_CONSHDLR* conshdlr;
7259 
7260  assert(cons != NULL);
7261  assert(set != NULL);
7262  assert(cons->scip == set->scip);
7263  assert(nfixedvars != NULL);
7264  assert(naggrvars != NULL);
7265  assert(nchgvartypes != NULL);
7266  assert(nchgbds != NULL);
7267  assert(naddholes != NULL);
7268  assert(ndelconss != NULL);
7269  assert(naddconss != NULL);
7270  assert(nupgdconss != NULL);
7271  assert(nchgcoefs != NULL);
7272  assert(nchgsides != NULL);
7273  assert(result != NULL);
7274 
7275  conshdlr = cons->conshdlr;
7276  assert(conshdlr != NULL);
7277 
7278  /* call external method */
7279  if( conshdlr->conspresol != NULL )
7280  {
7281  SCIP_CALL( conshdlr->conspresol(set->scip, conshdlr, &cons, 1, nrounds, nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds,
7282  nnewholes, nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, nfixedvars, naggrvars, nchgvartypes,
7283  nchgbds, naddholes, ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides, result) );
7284  SCIPdebugMessage(" -> presol returned result <%d>\n", *result);
7285 
7286  if( *result != SCIP_UNBOUNDED
7287  && *result != SCIP_CUTOFF
7288  && *result != SCIP_SUCCESS
7289  && *result != SCIP_DIDNOTFIND
7290  && *result != SCIP_DIDNOTRUN
7291  && *result != SCIP_DELAYED )
7292  {
7293  SCIPerrorMessage("presolving method of constraint handler <%s> returned invalid result <%d>\n",
7294  conshdlr->name, *result);
7295  return SCIP_INVALIDRESULT;
7296  }
7297  }
7298 
7299  return SCIP_OKAY;
7300 }
7301 
7302 /** calls constraint activation notification method of single constraint */
7304  SCIP_CONS* cons, /**< constraint to notify */
7305  SCIP_SET* set /**< global SCIP settings */
7306  )
7307 {
7308  SCIP_CONSHDLR* conshdlr;
7309 
7310  assert(cons != NULL);
7311  assert(set != NULL);
7312  assert(cons->scip == set->scip);
7313 
7314  conshdlr = cons->conshdlr;
7315  assert(conshdlr != NULL);
7316 
7317  /* call external method */
7318  if( conshdlr->consactive != NULL )
7319  {
7320  SCIP_CALL( conshdlr->consactive(set->scip, conshdlr, cons) );
7321  }
7322 
7323  return SCIP_OKAY;
7324 }
7325 
7326 /** calls constraint deactivation notification method of single constraint */
7328  SCIP_CONS* cons, /**< constraint to notify */
7329  SCIP_SET* set /**< global SCIP settings */
7330  )
7331 {
7332  SCIP_CONSHDLR* conshdlr;
7333 
7334  assert(cons != NULL);
7335  assert(set != NULL);
7336  assert(cons->scip == set->scip);
7337 
7338  conshdlr = cons->conshdlr;
7339  assert(conshdlr != NULL);
7340 
7341  /* call external method */
7342  if( conshdlr->consdeactive != NULL )
7343  {
7344  SCIP_CALL( conshdlr->consdeactive(set->scip, conshdlr, cons) );
7345  }
7346 
7347  return SCIP_OKAY;
7348 }
7349 
7350 
7351 
7352 /*
7353  * Hash functions
7354  */
7355 
7356 /** gets the key (i.e. the name) of the given constraint */
7357 SCIP_DECL_HASHGETKEY(SCIPhashGetKeyCons)
7358 { /*lint --e{715}*/
7359  SCIP_CONS* cons = (SCIP_CONS*)elem;
7360 
7361  assert(cons != NULL);
7362  return cons->name;
7363 }
7364 
7365 
7366 /*
7367  * method for arrays of contraint handlers
7368  */
7369 
7370 /** ensures size of storage for propagable constraints with a minimum size of num */
7371 static
7373  SCIP_SET* set, /**< global SCIP settings */
7374  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
7375  int num /**< minimum number of entries to store */
7376  )
7377 {
7378  assert(set != NULL);
7379  assert(conshdlr != NULL);
7380 
7381  if( num > conshdlr->storedpropconsssize )
7382  {
7383  int newsize;
7384 
7385  newsize = SCIPsetCalcMemGrowSize(set, num);
7386  SCIP_ALLOC( BMSreallocMemoryArray(&(conshdlr->storedpropconss), newsize) );
7387 
7388  conshdlr->storedpropconsssize = newsize;
7389  }
7390  assert(num <= conshdlr->storedpropconsssize);
7391 
7392  return SCIP_OKAY;
7393 }
7394 
7395 /** stores all constraints marked for propagation away when probing is started */
7397  SCIP_SET* set, /**< global SCIP settings */
7398  SCIP_CONSHDLR** conshdlrs, /**< all constraint handlers */
7399  int nconshdlrs /**< number of contraint handlers */
7400  )
7401 {
7402  SCIP_CONSHDLR* conshdlr;
7403  int c;
7404 
7405  assert(set != NULL);
7406  assert(conshdlrs != NULL || nconshdlrs == 0);
7407 
7408  for( c = nconshdlrs - 1; c >= 0; --c )
7409  {
7410  conshdlr = conshdlrs[c]; /*lint !e613*/
7411  assert(conshdlr != NULL);
7412  assert(conshdlr->storednmarkedpropconss == 0);
7413 
7414  if( conshdlr->nmarkedpropconss > 0 )
7415  {
7416  int v;
7417 
7418  SCIP_CALL( ensurePropagationStorage(set, conshdlr, conshdlr->nmarkedpropconss) );
7419  BMScopyMemoryArray(conshdlr->storedpropconss, conshdlr->propconss, conshdlr->nmarkedpropconss);
7420 
7421  conshdlr->storednmarkedpropconss = conshdlr->nmarkedpropconss;
7422  conshdlr->storedpropdomchgcount = conshdlr->lastpropdomchgcount;
7423 
7424  for( v = conshdlr->storednmarkedpropconss - 1; v >= 0; --v )
7425  {
7426  SCIPconsCapture(conshdlr->storedpropconss[v]);
7427  SCIP_CALL( SCIPconsUnmarkPropagate(conshdlr->storedpropconss[v], set) );
7428  }
7429  assert(conshdlr->nmarkedpropconss == 0);
7430  }
7431  }
7432 
7433  return SCIP_OKAY;
7434 }
7435 
7436 /** reset all constraints marked for propagation when probing was finished */
7438  SCIP_SET* set, /**< global SCIP settings */
7439  BMS_BLKMEM* blkmem, /**< block memory */
7440  SCIP_CONSHDLR** conshdlrs, /**< all constraint handlers */
7441  int nconshdlrs /**< number of contraint handlers */
7442  )
7443 {
7444  SCIP_CONSHDLR* conshdlr;
7445  int c;
7446 
7447  assert(set != NULL);
7448  assert(blkmem != NULL);
7449  assert(conshdlrs != NULL || nconshdlrs == 0);
7450 
7451  for( c = nconshdlrs - 1; c >= 0; --c )
7452  {
7453  conshdlr = conshdlrs[c]; /*lint !e613*/
7454  assert(conshdlr != NULL);
7455 
7456  if( conshdlr->storednmarkedpropconss > 0 )
7457  {
7458 #ifndef NDEBUG
7459  int ndisabled = 0;
7460 #endif
7461  int v;
7462 
7463  /* mark all previously marked constraint, which were marked before probing */
7464  for( v = conshdlr->storednmarkedpropconss - 1; v >= 0; --v )
7465  {
7466  SCIP_CONS* cons = conshdlr->storedpropconss[v];
7467  assert(cons != NULL);
7468 
7469  if( cons->enabled && cons->propagate && cons->propenabled )
7470  {
7471  SCIP_CALL( SCIPconsMarkPropagate(cons, set) );
7472  }
7473 #ifndef NDEBUG
7474  else
7475  ++ndisabled;
7476 #endif
7477  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
7478  }
7479  assert(conshdlr->storednmarkedpropconss - ndisabled <= conshdlr->npropconss);
7480  assert(conshdlr->nmarkedpropconss + ndisabled >= conshdlr->storednmarkedpropconss || (conshdlrAreUpdatesDelayed(conshdlr) && conshdlr->nupdateconss + ndisabled >= conshdlr->storednmarkedpropconss));
7481 
7482  conshdlr->lastpropdomchgcount = conshdlr->storedpropdomchgcount;
7483  conshdlr->storednmarkedpropconss = 0;
7484  }
7485  }
7486 
7487  return SCIP_OKAY;
7488 }
7489 
7490 /*
7491  * simple functions implemented as defines
7492  */
7493 
7494 /* In debug mode, the following methods are implemented as function calls to ensure
7495  * type validity.
7496  * In optimized mode, the methods are implemented as defines to improve performance.
7497  * However, we want to have them in the library anyways, so we have to undef the defines.
7498  */
7499 
7500 #undef SCIPconsGetName
7501 #undef SCIPconsGetPos
7502 #undef SCIPconsGetHdlr
7503 #undef SCIPconsGetData
7504 #undef SCIPconsGetNUses
7505 #undef SCIPconsGetActiveDepth
7506 #undef SCIPconsGetValidDepth
7507 #undef SCIPconsIsActive
7508 #undef SCIPconsIsEnabled
7509 #undef SCIPconsIsSeparationEnabled
7510 #undef SCIPconsIsPropagationEnabled
7511 #undef SCIPconsIsDeleted
7512 #undef SCIPconsIsObsolete
7513 #undef SCIPconsGetAge
7514 #undef SCIPconsIsInitial
7515 #undef SCIPconsIsSeparated
7516 #undef SCIPconsIsEnforced
7517 #undef SCIPconsIsChecked
7518 #undef SCIPconsIsMarkedPropagate
7519 #undef SCIPconsIsPropagated
7520 #undef SCIPconsIsGlobal
7521 #undef SCIPconsIsLocal
7522 #undef SCIPconsIsModifiable
7523 #undef SCIPconsIsDynamic
7524 #undef SCIPconsIsRemovable
7525 #undef SCIPconsIsStickingAtNode
7526 #undef SCIPconsIsInProb
7527 #undef SCIPconsIsOriginal
7528 #undef SCIPconsIsTransformed
7529 #undef SCIPconsIsLockedPos
7530 #undef SCIPconsIsLockedNeg
7531 #undef SCIPconsIsLocked
7532 #undef SCIPconsGetNLocksPos
7533 #undef SCIPconsGetNLocksNeg
7534 #undef SCIPconsIsAdded
7535 #undef SCIPconsGetNUpgradeLocks
7536 
7537 /** returns the name of the constraint
7538  *
7539  * @note to change the name of a constraint, use SCIPchgConsName() from scip.h
7540  */
7541 const char* SCIPconsGetName(
7542  SCIP_CONS* cons /**< constraint */
7543  )
7544 {
7545  assert(cons != NULL);
7546 
7547  return cons->name;
7548 }
7549 
7550 /** returns the position of constraint in the corresponding handler's conss array */
7552  SCIP_CONS* cons /**< constraint */
7553  )
7554 {
7555  assert(cons != NULL);
7556 
7557  return cons->consspos;
7558 }
7559 
7560 /** returns the constraint handler of the constraint */
7562  SCIP_CONS* cons /**< constraint */
7563  )
7564 {
7565  assert(cons != NULL);
7566 
7567  return cons->conshdlr;
7568 }
7569 
7570 /** returns the constraint data field of the constraint */
7572  SCIP_CONS* cons /**< constraint */
7573  )
7574 {
7575  assert(cons != NULL);
7576 
7577  return cons->consdata;
7578 }
7579 
7580 /** gets number of times, the constraint is currently captured */
7582  SCIP_CONS* cons /**< constraint */
7583  )
7584 {
7585  assert(cons != NULL);
7586 
7587  return cons->nuses;
7588 }
7589 
7590 /** for an active constraint, returns the depth in the tree at which the constraint was activated */
7592  SCIP_CONS* cons /**< constraint */
7593  )
7594 {
7595  assert(cons != NULL);
7596  assert(SCIPconsIsActive(cons));
7597 
7598  return cons->activedepth;
7599 }
7600 
7601 /** returns TRUE iff constraint is active in the current node */
7603  SCIP_CONS* cons /**< constraint */
7604  )
7605 {
7606  assert(cons != NULL);
7607 
7608  return cons->updateactivate || (cons->active && !cons->updatedeactivate);
7609 }
7610 
7611 /** returns the depth in the tree at which the constraint is valid; returns INT_MAX, if the constraint is local
7612  * and currently not active
7613  */
7615  SCIP_CONS* cons /**< constraint */
7616  )
7617 {
7618  assert(cons != NULL);
7619  assert(cons->validdepth == 0 || cons->local);
7620 
7621  return (!cons->local ? 0
7622  : !SCIPconsIsActive(cons) ? INT_MAX
7623  : cons->validdepth == -1 ? SCIPconsGetActiveDepth(cons)
7624  : cons->validdepth);
7625 }
7626 
7627 /** returns TRUE iff constraint is enabled in the current node */
7629  SCIP_CONS* cons /**< constraint */
7630  )
7631 {
7632  assert(cons != NULL);
7633 
7634  return cons->updateenable || (cons->enabled && !cons->updatedisable);
7635 }
7636 
7637 /** returns TRUE iff constraint's separation is enabled in the current node */
7639  SCIP_CONS* cons /**< constraint */
7640  )
7641 {
7642  assert(cons != NULL);
7643 
7644  return SCIPconsIsEnabled(cons)
7645  && (cons->updatesepaenable || (cons->sepaenabled && !cons->updatesepadisable));
7646 }
7647 
7648 /** returns TRUE iff constraint's propagation is enabled in the current node */
7650  SCIP_CONS* cons /**< constraint */
7651  )
7652 {
7653  assert(cons != NULL);
7654 
7655  return SCIPconsIsEnabled(cons)
7656  && (cons->updatepropenable || (cons->propenabled && !cons->updatepropdisable));
7657 }
7658 
7659 /** returns TRUE iff constraint is deleted or marked to be deleted */
7661  SCIP_CONS* cons /**< constraint */
7662  )
7663 {
7664  assert(cons != NULL);
7665 
7666  return cons->deleted;
7667 }
7668 
7669 /** returns TRUE iff constraint is marked obsolete */
7671  SCIP_CONS* cons /**< constraint */
7672  )
7673 {
7674  assert(cons != NULL);
7675 
7676  return cons->updateobsolete || cons->obsolete;
7677 }
7678 
7679 /** gets age of constraint */
7681  SCIP_CONS* cons /**< constraint */
7682  )
7683 {
7684  assert(cons != NULL);
7685 
7686  return cons->age;
7687 }
7688 
7689 /** returns TRUE iff the LP relaxation of constraint should be in the initial LP */
7691  SCIP_CONS* cons /**< constraint */
7692  )
7693 {
7694  assert(cons != NULL);
7695 
7696  return cons->initial;
7697 }
7698 
7699 /** returns TRUE iff constraint should be separated during LP processing */
7701  SCIP_CONS* cons /**< constraint */
7702  )
7703 {
7704  assert(cons != NULL);
7705 
7706  return cons->separate;
7707 }
7708 
7709 /** returns TRUE iff constraint should be enforced during node processing */
7711  SCIP_CONS* cons /**< constraint */
7712  )
7713 {
7714  assert(cons != NULL);
7715 
7716  return cons->enforce;
7717 }
7718 
7719 /** returns TRUE iff constraint should be checked for feasibility */
7721  SCIP_CONS* cons /**< constraint */
7722  )
7723 {
7724  assert(cons != NULL);
7725 
7726  return cons->check;
7727 }
7728 
7729 /** returns whether the constraint is marked for propagation */
7731  SCIP_CONS* cons /**< constraint */
7732  )
7733 {
7734  assert(cons != NULL);
7735 
7736  return cons->markpropagate;
7737 }
7738 
7739 /** returns TRUE iff constraint should be propagated during node processing */
7741  SCIP_CONS* cons /**< constraint */
7742  )
7743 {
7744  assert(cons != NULL);
7745 
7746  return cons->propagate;
7747 }
7748 
7749 /** returns TRUE iff constraint is globally valid */
7751  SCIP_CONS* cons /**< constraint */
7752  )
7753 {
7754  assert(cons != NULL);
7755 
7756  return !cons->local;
7757 }
7758 
7759 /** returns TRUE iff constraint is only locally valid or not added to any (sub)problem */
7761  SCIP_CONS* cons /**< constraint */
7762  )
7763 {
7764  assert(cons != NULL);
7765 
7766  return cons->local;
7767 }
7768 
7769 /** returns TRUE iff constraint is modifiable (subject to column generation) */
7771  SCIP_CONS* cons /**< constraint */
7772  )
7773 {
7774  assert(cons != NULL);
7775 
7776  return cons->modifiable;
7777 }
7778 
7779 /** returns TRUE iff constraint is subject to aging */
7781  SCIP_CONS* cons /**< constraint */
7782  )
7783 {
7784  assert(cons != NULL);
7785 
7786  return cons->dynamic;
7787 }
7788 
7789 /** returns TRUE iff constraint's relaxation should be removed from the LP due to aging or cleanup */
7791  SCIP_CONS* cons /**< constraint */
7792  )
7793 {
7794  assert(cons != NULL);
7795 
7796  return cons->removable;
7797 }
7798 
7799 /** returns TRUE iff constraint's relaxation should be removed from the LP due to aging or cleanup */
7801  SCIP_CONS* cons /**< constraint */
7802  )
7803 {
7804  assert(cons != NULL);
7805 
7806  return cons->stickingatnode;
7807 }
7808 
7809 /** returns TRUE iff constraint belongs to the global problem */
7811  SCIP_CONS* cons /**< constraint */
7812  )
7813 {
7814  assert(cons != NULL);
7815 
7816  return (cons->addconssetchg == NULL && cons->addarraypos >= 0);
7817 }
7818 
7819 /** returns TRUE iff constraint is belonging to original space */
7821  SCIP_CONS* cons /**< constraint */
7822  )
7823 {
7824  assert(cons != NULL);
7825 
7826  return cons->original;
7827 }
7828 
7829 /** returns TRUE iff constraint is belonging to transformed space */
7831  SCIP_CONS* cons /**< constraint */
7832  )
7833 {
7834  assert(cons != NULL);
7835 
7836  return !cons->original;
7837 }
7838 
7839 /** returns TRUE iff roundings for variables in constraint are locked */
7841  SCIP_CONS* cons /**< constraint */
7842  )
7843 {
7844  assert(cons != NULL);
7845 
7846  return (cons->nlockspos > 0);
7847 }
7848 
7849 /** returns TRUE iff roundings for variables in constraint's negation are locked */
7851  SCIP_CONS* cons /**< constraint */
7852  )
7853 {
7854  assert(cons != NULL);
7855 
7856  return (cons->nlocksneg > 0);
7857 }
7858 
7859 /** returns TRUE iff roundings for variables in constraint or in constraint's negation are locked */
7861  SCIP_CONS* cons /**< constraint */
7862  )
7863 {
7864  assert(cons != NULL);
7865 
7866  return (cons->nlockspos > 0 || cons->nlocksneg > 0);
7867 }
7868 
7869 /** get number of times the roundings for variables in constraint are locked */
7871  SCIP_CONS* cons /**< constraint */
7872  )
7873 {
7874  assert(cons != NULL);
7875 
7876  return cons->nlockspos;
7877 }
7878 
7879 /** get number of times the roundings for variables in constraint's negation are locked */
7881  SCIP_CONS* cons /**< constraint */
7882  )
7883 {
7884  assert(cons != NULL);
7885 
7886  return cons->nlocksneg;
7887 }
7888 
7889 /** returns if the constraint was already added to a SCIP instance */
7891  SCIP_CONS* cons /**< constraint */
7892  )
7893 {
7894  assert(cons != NULL);
7895 
7896  return (cons->addarraypos >= 0);
7897 }
7898 
7899 /** adds locks to (dis-)allow upgrading of constraint */
7901  SCIP_CONS* cons, /**< constraint to add locks */
7902  int nlocks /**< number of locks to add */
7903  )
7904 {
7905  assert(cons != NULL);
7906 
7907  assert(cons->nupgradelocks < (1 << 29) - nlocks); /*lint !e574*/
7908  cons->nupgradelocks += (unsigned int) nlocks;
7909 }
7910 
7911 /** gets number of locks against upgrading the constraint, 0 means this constraint can be upgraded */
7913  SCIP_CONS* cons /**< constraint */
7914  )
7915 {
7916  assert(cons != NULL);
7917 
7918  return cons->nupgradelocks;
7919 }
7920