Scippy

SCIP

Solving Constraint Integer Programs

cons_or.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 2002-2022 Zuse Institute Berlin */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file cons_or.c
26  * @ingroup DEFPLUGINS_CONS
27  * @brief Constraint handler for "or" constraints, \f$r = x_1 \vee x_2 \vee \dots \vee x_n\f$
28  * @author Tobias Achterberg
29  * @author Stefan Heinz
30  * @author Michael Winkler
31  *
32  * This constraint handler deals with "or" constraint. These are constraint of the form:
33  *
34  * \f[
35  * r = x_1 \vee x_2 \vee \dots \vee x_n
36  * \f]
37  *
38  * where \f$x_i\f$ is a binary variable for all \f$i\f$. Hence, \f$r\f$ is also of binary type. The variable \f$r\f$ is
39  * called resultant and the \f$x\f$'s operators.
40  */
41 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 
44 #include "blockmemshell/memory.h"
45 #include "scip/cons_and.h"
46 #include "scip/cons_or.h"
47 #include "scip/pub_cons.h"
48 #include "scip/pub_event.h"
49 #include "scip/pub_lp.h"
50 #include "scip/pub_message.h"
51 #include "scip/pub_misc.h"
52 #include "scip/pub_var.h"
53 #include "scip/scip_conflict.h"
54 #include "scip/scip_cons.h"
55 #include "scip/scip_copy.h"
56 #include "scip/scip_cut.h"
57 #include "scip/scip_event.h"
58 #include "scip/scip_general.h"
59 #include "scip/scip_lp.h"
60 #include "scip/scip_mem.h"
61 #include "scip/scip_message.h"
62 #include "scip/scip_numerics.h"
63 #include "scip/scip_prob.h"
64 #include "scip/scip_probing.h"
65 #include "scip/scip_sol.h"
66 #include "scip/scip_tree.h"
67 #include "scip/scip_var.h"
68 #include <string.h>
69 
70 
71 /* constraint handler properties */
72 #define CONSHDLR_NAME "or"
73 #define CONSHDLR_DESC "constraint handler for or constraints: r = or(x1, ..., xn)"
74 #define CONSHDLR_SEPAPRIORITY +850000 /**< priority of the constraint handler for separation */
75 #define CONSHDLR_ENFOPRIORITY -850000 /**< priority of the constraint handler for constraint enforcing */
76 #define CONSHDLR_CHECKPRIORITY -850000 /**< priority of the constraint handler for checking feasibility */
77 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
78 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
79 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
80  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
81 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
82 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
83 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
84 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
85 
86 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
87 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
88 
89 #define EVENTHDLR_NAME "or"
90 #define EVENTHDLR_DESC "event handler for or constraints"
91 
92 
93 /*
94  * Data structures
95  */
96 
97 /** constraint data for or constraints */
98 struct SCIP_ConsData
99 {
100  SCIP_VAR** vars; /**< variables in the or operation */
101  SCIP_VAR* resvar; /**< resultant variable */
102  SCIP_ROW** rows; /**< rows for linear relaxation of or constraint */
103  int nvars; /**< number of variables in or operation */
104  int varssize; /**< size of vars array */
105  int rowssize; /**< size of rows array */
106  int watchedvar1; /**< position of first watched operator variable */
107  int watchedvar2; /**< position of second watched operator variable */
108  int filterpos1; /**< event filter position of first watched operator variable */
109  int filterpos2; /**< event filter position of second watched operator variable */
110  unsigned int propagated:1; /**< is constraint already preprocessed/propagated? */
111  unsigned int nofixedone:1; /**< is none of the operator variables fixed to TRUE? */
112  unsigned int impladded:1; /**< were the implications of the constraint already added? */
113  unsigned int opimpladded:1; /**< was the implication for 2 operands with fixed resultant added? */
114 };
115 
116 /** constraint handler data */
117 struct SCIP_ConshdlrData
118 {
119  SCIP_EVENTHDLR* eventhdlr; /**< event handler for events on watched variables */
120 };
121 
122 
123 /*
124  * Propagation rules
125  */
126 
127 enum Proprule
128 {
129  PROPRULE_1 = 0, /**< v_i = TRUE => r = TRUE */
130  PROPRULE_2 = 1, /**< r = FALSE => v_i = FALSE for all i */
131  PROPRULE_3 = 2, /**< v_i = FALSE for all i => r = FALSE */
132  PROPRULE_4 = 3, /**< r = TRUE, v_i = FALSE for all i except j => v_j = TRUE */
133  PROPRULE_INVALID = 4 /**< propagation was applied without a specific propagation rule */
134 };
135 typedef enum Proprule PROPRULE;
137 
138 /*
139  * Local methods
140  */
141 
142 /** installs rounding locks for the given variable in the given or constraint */
143 static
145  SCIP* scip, /**< SCIP data structure */
146  SCIP_CONS* cons, /**< or constraint */
147  SCIP_VAR* var /**< variable of constraint entry */
148  )
149 {
151 
152  /* rounding in both directions may violate the constraint */
153  SCIP_CALL( SCIPlockVarCons(scip, var, cons, TRUE, TRUE) );
154 
155  return SCIP_OKAY;
156 }
157 
158 /** removes rounding locks for the given variable in the given or constraint */
159 static
161  SCIP* scip, /**< SCIP data structure */
162  SCIP_CONS* cons, /**< or constraint */
163  SCIP_VAR* var /**< variable of constraint entry */
164  )
165 {
167 
168  /* rounding in both directions may violate the constraint */
169  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
170 
171  return SCIP_OKAY;
172 }
173 
174 /** creates constraint handler data */
175 static
177  SCIP* scip, /**< SCIP data structure */
178  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
179  SCIP_EVENTHDLR* eventhdlr /**< event handler */
180  )
181 {
182  assert(scip != NULL);
183  assert(conshdlrdata != NULL);
184  assert(eventhdlr != NULL);
185 
186  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
187 
188  /* set event handler for catching events on watched variables */
189  (*conshdlrdata)->eventhdlr = eventhdlr;
190 
191  return SCIP_OKAY;
192 }
193 
194 /** frees constraint handler data */
195 static
196 void conshdlrdataFree(
197  SCIP* scip, /**< SCIP data structure */
198  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
199  )
200 {
201  assert(conshdlrdata != NULL);
202  assert(*conshdlrdata != NULL);
203 
204  SCIPfreeBlockMemory(scip, conshdlrdata);
205 }
206 
207 /** gets number of LP rows needed for the LP relaxation of the constraint */
208 static
209 int consdataGetNRows(
210  SCIP_CONSDATA* consdata /**< constraint data */
211  )
212 {
213  assert(consdata != NULL);
214 
215  return consdata->nvars + 1;
216 }
217 
218 /** catches events for the watched variable at given position */
219 static
221  SCIP* scip, /**< SCIP data structure */
222  SCIP_CONSDATA* consdata, /**< or constraint data */
223  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
224  int pos, /**< array position of variable to catch bound change events for */
225  int* filterpos /**< pointer to store position of event filter entry */
226  )
227 {
228  assert(consdata != NULL);
229  assert(consdata->vars != NULL);
230  assert(eventhdlr != NULL);
231  assert(0 <= pos && pos < consdata->nvars);
232  assert(filterpos != NULL);
233 
234  /* catch tightening events for upper bound and relaxed events for lower bounds on watched variable */
236  eventhdlr, (SCIP_EVENTDATA*)consdata, filterpos) );
237 
238  return SCIP_OKAY;
239 }
240 
241 
242 /** drops events for the watched variable at given position */
243 static
245  SCIP* scip, /**< SCIP data structure */
246  SCIP_CONSDATA* consdata, /**< or constraint data */
247  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
248  int pos, /**< array position of watched variable to drop bound change events for */
249  int filterpos /**< position of event filter entry */
250  )
251 {
252  assert(consdata != NULL);
253  assert(consdata->vars != NULL);
254  assert(eventhdlr != NULL);
255  assert(0 <= pos && pos < consdata->nvars);
256  assert(filterpos >= 0);
257 
258  /* drop tightening events for upper bound and relaxed events for lower bounds on watched variable */
260  eventhdlr, (SCIP_EVENTDATA*)consdata, filterpos) );
261 
262  return SCIP_OKAY;
263 }
264 
265 /** catches needed events on all variables of constraint, except the special ones for watched variables */
266 static
268  SCIP* scip, /**< SCIP data structure */
269  SCIP_CONSDATA* consdata, /**< or constraint data */
270  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
271  )
272 {
273  int i;
274 
275  assert(consdata != NULL);
276 
277  /* catch bound change events for both bounds on resultant variable */
278  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->resvar, SCIP_EVENTTYPE_BOUNDCHANGED,
279  eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
280 
281  /* catch tightening events for lower bound and relaxed events for upper bounds on operator variables */
282  for( i = 0; i < consdata->nvars; ++i )
283  {
285  eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
286  }
287 
288  return SCIP_OKAY;
289 }
290 
291 /** drops events on all variables of constraint, except the special ones for watched variables */
292 static
294  SCIP* scip, /**< SCIP data structure */
295  SCIP_CONSDATA* consdata, /**< or constraint data */
296  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
297  )
298 {
299  int i;
300 
301  assert(consdata != NULL);
302 
303  /* drop bound change events for both bounds on resultant variable */
304  SCIP_CALL( SCIPdropVarEvent(scip, consdata->resvar, SCIP_EVENTTYPE_BOUNDCHANGED,
305  eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
306 
307  /* drop tightening events for lower bound and relaxed events for upper bounds on operator variables */
308  for( i = 0; i < consdata->nvars; ++i )
309  {
311  eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
312  }
313 
314  return SCIP_OKAY;
315 }
316 
317 /** stores the given variable numbers as watched variables, and updates the event processing */
318 static
320  SCIP* scip, /**< SCIP data structure */
321  SCIP_CONSDATA* consdata, /**< or constraint data */
322  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
323  int watchedvar1, /**< new first watched variable */
324  int watchedvar2 /**< new second watched variable */
325  )
326 {
327  assert(consdata != NULL);
328  assert(watchedvar1 == -1 || watchedvar1 != watchedvar2);
329  assert(watchedvar1 != -1 || watchedvar2 == -1);
330  assert(watchedvar1 == -1 || (0 <= watchedvar1 && watchedvar1 < consdata->nvars));
331  assert(watchedvar2 == -1 || (0 <= watchedvar2 && watchedvar2 < consdata->nvars));
332 
333  /* if one watched variable is equal to the old other watched variable, just switch positions */
334  if( watchedvar1 == consdata->watchedvar2 || watchedvar2 == consdata->watchedvar1 )
335  {
336  int tmp;
337 
338  tmp = consdata->watchedvar1;
339  consdata->watchedvar1 = consdata->watchedvar2;
340  consdata->watchedvar2 = tmp;
341  tmp = consdata->filterpos1;
342  consdata->filterpos1 = consdata->filterpos2;
343  consdata->filterpos2 = tmp;
344  }
345  assert(watchedvar1 == -1 || watchedvar1 != consdata->watchedvar2);
346  assert(watchedvar2 == -1 || watchedvar2 != consdata->watchedvar1);
347 
348  /* drop events on old watched variables */
349  if( consdata->watchedvar1 != -1 && consdata->watchedvar1 != watchedvar1 )
350  {
351  assert(consdata->filterpos1 != -1);
352  SCIP_CALL( consdataDropWatchedEvents(scip, consdata, eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
353  }
354  if( consdata->watchedvar2 != -1 && consdata->watchedvar2 != watchedvar2 )
355  {
356  assert(consdata->filterpos2 != -1);
357  SCIP_CALL( consdataDropWatchedEvents(scip, consdata, eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
358  }
359 
360  /* catch events on new watched variables */
361  if( watchedvar1 != -1 && watchedvar1 != consdata->watchedvar1 )
362  {
363  SCIP_CALL( consdataCatchWatchedEvents(scip, consdata, eventhdlr, watchedvar1, &consdata->filterpos1) );
364  }
365  if( watchedvar2 != -1 && watchedvar2 != consdata->watchedvar2 )
366  {
367  SCIP_CALL( consdataCatchWatchedEvents(scip, consdata, eventhdlr, watchedvar2, &consdata->filterpos2) );
368  }
369 
370  /* set the new watched variables */
371  consdata->watchedvar1 = watchedvar1;
372  consdata->watchedvar2 = watchedvar2;
373 
374  return SCIP_OKAY;
375 }
376 
377 /** ensures, that the vars array can store at least num entries */
378 static
380  SCIP* scip, /**< SCIP data structure */
381  SCIP_CONSDATA* consdata, /**< linear constraint data */
382  int num /**< minimum number of entries to store */
383  )
384 {
385  assert(consdata != NULL);
386  assert(consdata->nvars <= consdata->varssize);
387 
388  if( num > consdata->varssize )
389  {
390  int newsize;
391 
392  newsize = SCIPcalcMemGrowSize(scip, num);
393  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
394  consdata->varssize = newsize;
395  }
396  assert(num <= consdata->varssize);
397 
398  return SCIP_OKAY;
399 }
400 
401 /** creates constraint data for or constraint */
402 static
404  SCIP* scip, /**< SCIP data structure */
405  SCIP_CONSDATA** consdata, /**< pointer to store the constraint data */
406  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
407  int nvars, /**< number of variables in the or operation */
408  SCIP_VAR** vars, /**< variables in or operation */
409  SCIP_VAR* resvar /**< resultant variable */
410  )
411 {
412  assert(consdata != NULL);
413  assert(nvars == 0 || vars != NULL);
414  assert(resvar != NULL);
415 
416  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
417  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
418  (*consdata)->resvar = resvar;
419  (*consdata)->rows = NULL;
420  (*consdata)->nvars = nvars;
421  (*consdata)->varssize = nvars;
422  (*consdata)->rowssize = 0;
423  (*consdata)->watchedvar1 = -1;
424  (*consdata)->watchedvar2 = -1;
425  (*consdata)->filterpos1 = -1;
426  (*consdata)->filterpos2 = -1;
427  (*consdata)->propagated = FALSE;
428  (*consdata)->nofixedone = FALSE;
429  (*consdata)->impladded = FALSE;
430  (*consdata)->opimpladded = FALSE;
431 
432  /* get transformed variables, if we are in the transformed problem */
433  if( SCIPisTransformed(scip) )
434  {
435  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
436  SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->resvar, &(*consdata)->resvar) );
437 
438  /* catch needed events on variables */
439  SCIP_CALL( consdataCatchEvents(scip, *consdata, eventhdlr) );
440  }
441 
442  return SCIP_OKAY;
443 }
444 
445 /** releases LP rows of constraint data and frees rows array */
446 static
448  SCIP* scip, /**< SCIP data structure */
449  SCIP_CONSDATA* consdata /**< constraint data */
450  )
451 {
452  int r;
453 
454  assert(consdata != NULL);
455 
456  if( consdata->rows != NULL )
457  {
458  int nrows;
459 
460  nrows = consdataGetNRows(consdata);
461 
462  for( r = 0; r < nrows; ++r )
463  {
464  SCIP_CALL( SCIPreleaseRow(scip, &consdata->rows[r]) );
465  }
466  SCIPfreeBlockMemoryArray(scip, &consdata->rows, consdata->rowssize);
467  }
468 
469  return SCIP_OKAY;
470 }
471 
472 /** frees constraint data for or constraint */
473 static
475  SCIP* scip, /**< SCIP data structure */
476  SCIP_CONSDATA** consdata, /**< pointer to the constraint data */
477  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
478  )
479 {
480  assert(consdata != NULL);
481  assert(*consdata != NULL);
482 
483  if( SCIPisTransformed(scip) )
484  {
485  /* drop events for watched variables */
486  SCIP_CALL( consdataSwitchWatchedvars(scip, *consdata, eventhdlr, -1, -1) );
487 
488  /* drop all other events on variables */
489  SCIP_CALL( consdataDropEvents(scip, *consdata, eventhdlr) );
490  }
491  else
492  {
493  assert((*consdata)->watchedvar1 == -1);
494  assert((*consdata)->watchedvar2 == -1);
495  }
496 
497  /* release and free the rows */
498  SCIP_CALL( consdataFreeRows(scip, *consdata) );
499 
500  SCIPfreeBlockMemoryArray(scip, &(*consdata)->vars, (*consdata)->varssize);
501  SCIPfreeBlockMemory(scip, consdata);
502 
503  return SCIP_OKAY;
504 }
505 
506 /** prints or constraint to file stream */
507 static
509  SCIP* scip, /**< SCIP data structure */
510  SCIP_CONSDATA* consdata, /**< or constraint data */
511  FILE* file /**< output file (or NULL for standard output) */
512  )
513 {
514  assert(consdata != NULL);
515 
516  /* print resultant */
517  SCIP_CALL( SCIPwriteVarName(scip, file, consdata->resvar, TRUE) );
518 
519  /* start the variable list */
520  SCIPinfoMessage(scip, file, " == or(");
521 
522  /* print variable list */
523  SCIP_CALL( SCIPwriteVarsList(scip, file, consdata->vars, consdata->nvars, TRUE, ',') );
524 
525  /* close the variable list */
526  SCIPinfoMessage(scip, file, ")");
527 
528  return SCIP_OKAY;
529 }
530 
531 /** adds coefficient in or constraint */
532 static
534  SCIP* scip, /**< SCIP data structure */
535  SCIP_CONS* cons, /**< linear constraint */
536  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
537  SCIP_VAR* var /**< variable to add to the constraint */
538  )
539 {
540  SCIP_CONSDATA* consdata;
541  SCIP_Bool transformed;
542 
543  assert(var != NULL);
544 
545  consdata = SCIPconsGetData(cons);
546  assert(consdata != NULL);
547  assert(consdata->rows == NULL);
548 
549  /* are we in the transformed problem? */
550  transformed = SCIPconsIsTransformed(cons);
551 
552  /* always use transformed variables in transformed constraints */
553  if( transformed )
554  {
555  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
556  }
557  assert(var != NULL);
558  assert(transformed == SCIPvarIsTransformed(var));
559 
560  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
561  consdata->vars[consdata->nvars] = var;
562  consdata->nvars++;
563 
564  /* if we are in transformed problem, catch the variable's events */
565  if( transformed )
566  {
567  /* catch bound change events of variable */
569  eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
570  }
571 
572  /* install the rounding locks for the new variable */
573  SCIP_CALL( lockRounding(scip, cons, var) );
574 
575  /**@todo update LP rows */
576  if( consdata->rows != NULL )
577  {
578  SCIPerrorMessage("cannot add coefficients to or constraint after LP relaxation was created\n");
579  return SCIP_INVALIDCALL;
580  }
581 
582  return SCIP_OKAY;
583 }
584 
585 /** deletes coefficient at given position from or constraint data */
586 static
588  SCIP* scip, /**< SCIP data structure */
589  SCIP_CONS* cons, /**< or constraint */
590  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
591  int pos /**< position of coefficient to delete */
592  )
593 {
594  SCIP_CONSDATA* consdata;
595 
596  assert(eventhdlr != NULL);
597 
598  consdata = SCIPconsGetData(cons);
599  assert(consdata != NULL);
600  assert(0 <= pos && pos < consdata->nvars);
601  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(consdata->vars[pos]));
602 
603  /* remove the rounding locks of the variable */
604  SCIP_CALL( unlockRounding(scip, cons, consdata->vars[pos]) );
605 
606  if( SCIPconsIsTransformed(cons) )
607  {
608  /* drop bound change events of variable */
610  eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
611  }
612 
613  if( SCIPconsIsTransformed(cons) )
614  {
615  /* if the position is watched, stop watching the position */
616  if( consdata->watchedvar1 == pos )
617  {
618  SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, consdata->watchedvar2, -1) );
619  }
620  if( consdata->watchedvar2 == pos )
621  {
622  SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, consdata->watchedvar1, -1) );
623  }
624  }
625  assert(pos != consdata->watchedvar1);
626  assert(pos != consdata->watchedvar2);
627 
628  /* move the last variable to the free slot */
629  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
630  consdata->nvars--;
631 
632  /* if the last variable (that moved) was watched, update the watched position */
633  if( consdata->watchedvar1 == consdata->nvars )
634  consdata->watchedvar1 = pos;
635  if( consdata->watchedvar2 == consdata->nvars )
636  consdata->watchedvar2 = pos;
637 
638  consdata->propagated = FALSE;
639 
640  return SCIP_OKAY;
641 }
642 
643 /** deletes all zero-fixed variables */
644 static
646  SCIP* scip, /**< SCIP data structure */
647  SCIP_CONS* cons, /**< or constraint */
648  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
649  )
650 {
651  SCIP_CONSDATA* consdata;
652  SCIP_VAR* var;
653  int v;
654 
655  consdata = SCIPconsGetData(cons);
656  assert(consdata != NULL);
657  assert(consdata->nvars == 0 || consdata->vars != NULL);
658 
659  v = 0;
660  while( v < consdata->nvars )
661  {
662  var = consdata->vars[v];
663  assert(SCIPvarIsBinary(var));
664 
665  if( SCIPvarGetUbGlobal(var) < 0.5 )
666  {
667  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), 0.0));
668  SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
669  }
670  else
671  {
672  SCIP_VAR* repvar;
673  SCIP_Bool negated;
674 
675  /* get binary representative of variable */
676  SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &repvar, &negated) );
677 
678  /* check, if the variable should be replaced with the representative */
679  if( repvar != var )
680  {
681  /* delete old (aggregated) variable */
682  SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
683 
684  /* add representative instead */
685  SCIP_CALL( addCoef(scip, cons, eventhdlr, repvar) );
686  }
687  else
688  ++v;
689  }
690  }
691 
692  SCIPdebugMsg(scip, "after fixings: ");
693  SCIPdebug( SCIP_CALL(consdataPrint(scip, consdata, NULL)) );
694  SCIPdebugMsgPrint(scip, "\n");
695 
696  return SCIP_OKAY;
697 }
698 
699 /** creates LP rows corresponding to or constraint:
700  * - for each operator variable vi: resvar - vi >= 0
701  * - one additional row: resvar - v1 - ... - vn <= 0
702  */
703 static
705  SCIP* scip, /**< SCIP data structure */
706  SCIP_CONS* cons /**< constraint to check */
707  )
708 {
709  SCIP_CONSDATA* consdata;
710  char rowname[SCIP_MAXSTRLEN];
711  int nvars;
712  int i;
713 
714  consdata = SCIPconsGetData(cons);
715  assert(consdata != NULL);
716  assert(consdata->rows == NULL);
717 
718  nvars = consdata->nvars;
719 
720  /* get memory for rows */
721  consdata->rowssize = consdataGetNRows(consdata);
722  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->rows, consdata->rowssize) );
723  assert(consdata->rowssize == nvars+1);
724 
725  /* create operator rows */
726  for( i = 0; i < nvars; ++i )
727  {
728  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s_%d", SCIPconsGetName(cons), i);
729  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->rows[i], cons, rowname, 0.0, SCIPinfinity(scip),
731  SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[i], consdata->resvar, 1.0) );
732  SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[i], consdata->vars[i], -1.0) );
733  }
734 
735  /* create additional row */
736  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s_add", SCIPconsGetName(cons));
737  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->rows[nvars], cons, rowname, -SCIPinfinity(scip), 0.0,
739  SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[nvars], consdata->resvar, 1.0) );
740  SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->rows[nvars], nvars, consdata->vars, -1.0) );
741 
742  return SCIP_OKAY;
743 }
744 
745 /** adds linear relaxation of or constraint to the LP */
746 static
748  SCIP* scip, /**< SCIP data structure */
749  SCIP_CONS* cons, /**< constraint to check */
750  SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected */
751  )
752 {
753  SCIP_CONSDATA* consdata;
754  int r;
755  int nrows;
756 
757  consdata = SCIPconsGetData(cons);
758  assert(consdata != NULL);
759 
760  if( consdata->rows == NULL )
761  {
762  SCIP_CALL( createRelaxation(scip, cons) );
763  }
764  assert( consdata->rows != NULL );
765 
766  nrows = consdataGetNRows(consdata);
767 
768  for( r = 0; r < nrows && !(*infeasible); ++r )
769  {
770  if( !SCIProwIsInLP(consdata->rows[r]) )
771  {
772  SCIP_CALL( SCIPaddRow(scip, consdata->rows[r], FALSE, infeasible) );
773  }
774  }
775 
776  return SCIP_OKAY;
777 }
778 
779 /** checks or constraint for feasibility of given solution: returns TRUE iff constraint is feasible */
780 static
782  SCIP* scip, /**< SCIP data structure */
783  SCIP_CONS* cons, /**< constraint to check */
784  SCIP_SOL* sol, /**< solution to check, NULL for current solution */
785  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
786  SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
787  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
788  )
789 {
790  SCIP_CONSDATA* consdata;
791  SCIP_Bool mustcheck;
792  int r;
793 
794  assert(violated != NULL);
795 
796  consdata = SCIPconsGetData(cons);
797  assert(consdata != NULL);
798 
799  *violated = FALSE;
800 
801  /* check, if we can skip this feasibility check, because all rows are in the LP and doesn't have to be checked */
802  mustcheck = checklprows;
803  mustcheck = mustcheck || (consdata->rows == NULL);
804  if( !mustcheck )
805  {
806  int nrows;
807 
808  assert(consdata->rows != NULL);
809 
810  nrows = consdataGetNRows(consdata);
811 
812  for( r = 0; r < nrows; ++r )
813  {
814  mustcheck = !SCIProwIsInLP(consdata->rows[r]);
815  if( mustcheck )
816  break;
817  }
818  }
819 
820  /* check feasibility of constraint if necessary */
821  if( mustcheck )
822  {
823  SCIP_Real solval;
824  int i;
825 
826  /* increase age of constraint; age is reset to zero, if a violation was found only in case we are in
827  * enforcement
828  */
829  if( sol == NULL )
830  {
831  SCIP_CALL( SCIPincConsAge(scip, cons) );
832  }
833 
834  /* check, if all operator variables are FALSE */
835  for( i = 0; i < consdata->nvars; ++i )
836  {
837  solval = SCIPgetSolVal(scip, sol, consdata->vars[i]);
838  assert(SCIPisFeasIntegral(scip, solval));
839  if( solval > 0.5 )
840  break;
841  }
842 
843  /* if all operator variables are FALSE, the resultant has to be FALSE, otherwise, the resultant has to be TRUE */
844  solval = SCIPgetSolVal(scip, sol, consdata->resvar);
845  assert(SCIPisFeasIntegral(scip, solval));
846 
847  if( (i == consdata->nvars) != (solval < 0.5) )
848  {
849  *violated = TRUE;
850 
851  /* only reset constraint age if we are in enforcement */
852  if( sol == NULL )
853  {
854  SCIP_CALL( SCIPresetConsAge(scip, cons) );
855  }
856  /* update constraint violation in solution */
857  else
858  SCIPupdateSolConsViolation(scip, sol, 1.0, 1.0);
859 
860  if( printreason )
861  {
862  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
863  SCIPinfoMessage(scip, NULL, ";\nviolation:\n");
864  if( i == consdata->nvars )
865  {
866  SCIPinfoMessage(scip, NULL, " all operands are FALSE and resultant <%s> = TRUE\n",
867  SCIPvarGetName(consdata->resvar));
868  }
869  else
870  {
871  SCIPinfoMessage(scip, NULL, " operand <%s> = TRUE and resultant <%s> = FALSE\n",
872  SCIPvarGetName(consdata->vars[i-1]), SCIPvarGetName(consdata->resvar));
873  }
874  }
875  }
876  }
877 
878  return SCIP_OKAY;
879 }
880 
881 /** separates current LP solution */
882 static
884  SCIP* scip, /**< SCIP data structure */
885  SCIP_CONS* cons, /**< constraint to check */
886  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
887  SCIP_Bool* separated /**< pointer to store whether a cut was found */
888  )
889 {
890  SCIP_CONSDATA* consdata;
891  SCIP_Real feasibility;
892  int r;
893  int nrows;
894 
895  assert(separated != NULL);
896 
897  consdata = SCIPconsGetData(cons);
898  assert(consdata != NULL);
899 
900  *separated = FALSE;
901 
902  /* create all necessary rows for the linear relaxation */
903  if( consdata->rows == NULL )
904  {
905  SCIP_CALL( createRelaxation(scip, cons) );
906  }
907  assert(consdata->rows != NULL);
908 
909  nrows = consdataGetNRows(consdata);
910 
911  /* test all rows for feasibility and add infeasible rows */
912  for( r = 0; r < nrows; ++r )
913  {
914  if( !SCIProwIsInLP(consdata->rows[r]) )
915  {
916  feasibility = SCIPgetRowSolFeasibility(scip, consdata->rows[r], sol);
917  if( SCIPisFeasNegative(scip, feasibility) )
918  {
919  SCIP_Bool infeasible;
920 
921  SCIP_CALL( SCIPaddRow(scip, consdata->rows[r], FALSE, &infeasible) );
922  assert( ! infeasible );
923  *separated = TRUE;
924  }
925  }
926  }
927 
928  return SCIP_OKAY;
929 }
930 
931 /** analyzes conflicting FALSE assignment to resultant of given constraint, and adds conflict constraint to problem */
932 static
934  SCIP* scip, /**< SCIP data structure */
935  SCIP_CONS* cons, /**< or constraint that detected the conflict */
936  int truepos /**< position of operand that is fixed to TRUE */
937  )
938 {
939  SCIP_CONSDATA* consdata;
940 
941  /* conflict analysis can only be applied in solving stage and if it is applicable */
943  return SCIP_OKAY;
944 
945  consdata = SCIPconsGetData(cons);
946  assert(consdata != NULL);
947  assert(SCIPvarGetUbLocal(consdata->resvar) < 0.5);
948  assert(0 <= truepos && truepos < consdata->nvars);
949  assert(SCIPvarGetLbLocal(consdata->vars[truepos]) > 0.5);
950 
951  /* initialize conflict analysis, and add resultant and single operand variable to conflict candidate queue */
953 
954  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
955  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[truepos]) );
956 
957  /* analyze the conflict */
958  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
959 
960  return SCIP_OKAY;
961 }
962 
963 /** analyzes conflicting TRUE assignment to resultant of given constraint, and adds conflict constraint to problem */
964 static
966  SCIP* scip, /**< SCIP data structure */
967  SCIP_CONS* cons /**< or constraint that detected the conflict */
968  )
969 {
970  SCIP_CONSDATA* consdata;
971  int v;
972 
973  assert(!SCIPconsIsModifiable(cons));
974 
975  /* conflict analysis can only be applied in solving stage and if it is applicable */
977  return SCIP_OKAY;
978 
979  consdata = SCIPconsGetData(cons);
980  assert(consdata != NULL);
981  assert(SCIPvarGetLbLocal(consdata->resvar) > 0.5);
982 
983  /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
985 
986  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
987  for( v = 0; v < consdata->nvars; ++v )
988  {
989  assert(SCIPvarGetUbLocal(consdata->vars[v]) < 0.5);
990  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
991  }
992 
993  /* analyze the conflict */
994  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
995 
996  return SCIP_OKAY;
997 }
998 
999 /** propagates constraint with the following rules:
1000  * (1) v_i = TRUE => r = TRUE
1001  * (2) r = FALSE => v_i = FALSE for all i
1002  * (3) v_i = FALSE for all i => r = FALSE
1003  * (4) r = TRUE, v_i = FALSE for all i except j => v_j = TRUE
1004  */
1005 static
1007  SCIP* scip, /**< SCIP data structure */
1008  SCIP_CONS* cons, /**< or constraint to be processed */
1009  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1010  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1011  int* nfixedvars /**< pointer to add up the number of found domain reductions */
1012  )
1013 {
1014  SCIP_CONSDATA* consdata;
1015  SCIP_VAR* resvar;
1016  SCIP_VAR** vars;
1017  int nvars;
1018  int watchedvar1;
1019  int watchedvar2;
1020  int i;
1021  SCIP_Bool infeasible;
1022  SCIP_Bool tightened;
1023 
1024  assert(cutoff != NULL);
1025  assert(nfixedvars != NULL);
1026 
1027  consdata = SCIPconsGetData(cons);
1028  assert(consdata != NULL);
1029 
1030  resvar = consdata->resvar;
1031  vars = consdata->vars;
1032  nvars = consdata->nvars;
1033 
1034  /* don't process the constraint, if none of the operator variables was fixed to TRUE, and if the watched variables
1035  * and the resultant weren't fixed to any value since last propagation call
1036  */
1037  if( consdata->propagated )
1038  {
1039  assert(consdata->nofixedone);
1040  assert(SCIPisFeasEQ(scip, SCIPvarGetUbLocal(resvar), 1.0));
1041  return SCIP_OKAY;
1042  }
1043 
1044  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
1045  if( !SCIPinRepropagation(scip) )
1046  {
1047  SCIP_CALL( SCIPincConsAge(scip, cons) );
1048  }
1049 
1050  /* if one of the operator variables was fixed to TRUE, the resultant can be fixed to TRUE (rule (1)) */
1051  if( !consdata->nofixedone )
1052  {
1053  for( i = 0; i < nvars && SCIPvarGetLbLocal(vars[i]) < 0.5; ++i ) /* search fixed operator */
1054  {}
1055  if( i < nvars )
1056  {
1057  SCIPdebugMsg(scip, "constraint <%s>: operator var <%s> fixed to 1.0 -> fix resultant <%s> to 1.0\n",
1058  SCIPconsGetName(cons), SCIPvarGetName(vars[i]), SCIPvarGetName(resvar));
1059  SCIP_CALL( SCIPinferBinvarCons(scip, resvar, TRUE, cons, (int)PROPRULE_1, &infeasible, &tightened) );
1060  if( infeasible )
1061  {
1062  /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1063  SCIP_CALL( analyzeConflictZero(scip, cons, i) );
1064  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1065  *cutoff = TRUE;
1066  }
1067  else
1068  {
1069  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1070  if( tightened )
1071  {
1072  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1073  (*nfixedvars)++;
1074  }
1075  }
1076 
1077  return SCIP_OKAY;
1078  }
1079  else
1080  consdata->nofixedone = TRUE;
1081  }
1082  assert(consdata->nofixedone);
1083 
1084  /* if resultant is fixed to FALSE, all operator variables can be fixed to FALSE (rule (2)) */
1085  if( SCIPvarGetUbLocal(resvar) < 0.5 )
1086  {
1087  for( i = 0; i < nvars && !(*cutoff); ++i )
1088  {
1089  SCIPdebugMsg(scip, "constraint <%s>: resultant var <%s> fixed to 0.0 -> fix operator var <%s> to 0.0\n",
1090  SCIPconsGetName(cons), SCIPvarGetName(resvar), SCIPvarGetName(vars[i]));
1091  SCIP_CALL( SCIPinferBinvarCons(scip, vars[i], FALSE, cons, (int)PROPRULE_2, &infeasible, &tightened) );
1092  if( infeasible )
1093  {
1094  /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1095  SCIP_CALL( analyzeConflictZero(scip, cons, i) );
1096  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1097  *cutoff = TRUE;
1098  }
1099  else if( tightened )
1100  {
1101  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1102  (*nfixedvars)++;
1103  }
1104  }
1105 
1106  if( !(*cutoff) )
1107  {
1108  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1109  }
1110 
1111  return SCIP_OKAY;
1112  }
1113 
1114  /* rules (3) and (4) can only be applied, if we know all operator variables */
1115  if( SCIPconsIsModifiable(cons) )
1116  return SCIP_OKAY;
1117 
1118  /* rules (3) and (4) cannot be applied, if we have at least two unfixed variables left;
1119  * that means, we only have to watch (i.e. capture events) of two variables, and switch to other variables
1120  * if these ones get fixed
1121  */
1122  watchedvar1 = consdata->watchedvar1;
1123  watchedvar2 = consdata->watchedvar2;
1124 
1125  /* check, if watched variables are still unfixed */
1126  if( watchedvar1 != -1 )
1127  {
1128  assert(SCIPvarGetLbLocal(vars[watchedvar1]) < 0.5); /* otherwise, rule (1) could be applied */
1129  if( SCIPvarGetUbLocal(vars[watchedvar1]) < 0.5 )
1130  watchedvar1 = -1;
1131  }
1132  if( watchedvar2 != -1 )
1133  {
1134  assert(SCIPvarGetLbLocal(vars[watchedvar2]) < 0.5); /* otherwise, rule (1) could be applied */
1135  if( SCIPvarGetUbLocal(vars[watchedvar2]) < 0.5 )
1136  watchedvar2 = -1;
1137  }
1138 
1139  /* if only one watched variable is still unfixed, make it the first one */
1140  if( watchedvar1 == -1 )
1141  {
1142  watchedvar1 = watchedvar2;
1143  watchedvar2 = -1;
1144  }
1145  assert(watchedvar1 != -1 || watchedvar2 == -1);
1146 
1147  /* if the watched variables are invalid (fixed), find new ones if existing */
1148  if( watchedvar2 == -1 )
1149  {
1150  for( i = 0; i < nvars; ++i )
1151  {
1152  assert(SCIPvarGetLbLocal(vars[i]) < 0.5); /* otherwise, rule (1) could be applied */
1153  if( SCIPvarGetUbLocal(vars[i]) > 0.5 )
1154  {
1155  if( watchedvar1 == -1 )
1156  {
1157  assert(watchedvar2 == -1);
1158  watchedvar1 = i;
1159  }
1160  else if( watchedvar1 != i )
1161  {
1162  watchedvar2 = i;
1163  break;
1164  }
1165  }
1166  }
1167  }
1168  assert(watchedvar1 != -1 || watchedvar2 == -1);
1169 
1170  /* if all variables are fixed to FALSE, the resultant can also be fixed to FALSE (rule (3)) */
1171  if( watchedvar1 == -1 )
1172  {
1173  assert(watchedvar2 == -1);
1174 
1175  SCIPdebugMsg(scip, "constraint <%s>: all operator vars fixed to 0.0 -> fix resultant <%s> to 0.0\n",
1176  SCIPconsGetName(cons), SCIPvarGetName(resvar));
1177  SCIP_CALL( SCIPinferBinvarCons(scip, resvar, FALSE, cons, (int)PROPRULE_3, &infeasible, &tightened) );
1178  if( infeasible )
1179  {
1180  /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1181  SCIP_CALL( analyzeConflictOne(scip, cons) );
1182  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1183  *cutoff = TRUE;
1184  }
1185  else
1186  {
1187  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1188  if( tightened )
1189  {
1190  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1191  (*nfixedvars)++;
1192  }
1193  }
1194 
1195  return SCIP_OKAY;
1196  }
1197 
1198  /* if resultant is fixed to TRUE, and only one operator variable is not fixed to FALSE, this operator variable
1199  * can be fixed to TRUE (rule (4))
1200  */
1201  if( SCIPvarGetLbLocal(resvar) > 0.5 && watchedvar2 == -1 )
1202  {
1203  assert(watchedvar1 != -1);
1204 
1205  SCIPdebugMsg(scip, "constraint <%s>: resultant <%s> fixed to 1.0, only one unfixed operand -> fix operand <%s> to 1.0\n",
1206  SCIPconsGetName(cons), SCIPvarGetName(resvar), SCIPvarGetName(vars[watchedvar1]));
1207  SCIP_CALL( SCIPinferBinvarCons(scip, vars[watchedvar1], TRUE, cons, (int)PROPRULE_4, &infeasible, &tightened) );
1208  if( infeasible )
1209  {
1210  /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1211  SCIP_CALL( analyzeConflictOne(scip, cons) );
1212  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1213  *cutoff = TRUE;
1214  }
1215  else
1216  {
1217  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1218  if( tightened )
1219  {
1220  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1221  (*nfixedvars)++;
1222  }
1223  }
1224 
1225  return SCIP_OKAY;
1226  }
1227 
1228  /* switch to the new watched variables */
1229  SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, watchedvar1, watchedvar2) );
1230 
1231  /* mark the constraint propagated */
1232  consdata->propagated = TRUE;
1233 
1234  return SCIP_OKAY;
1235 }
1236 
1237 /** resolves a conflict on the given variable by supplying the variables needed for applying the corresponding
1238  * propagation rule (see propagateCons()):
1239  * (1) v_i = TRUE => r = TRUE
1240  * (2) r = FALSE => v_i = FALSE for all i
1241  * (3) v_i = FALSE for all i => r = FALSE
1242  * (4) r = TRUE, v_i = FALSE for all i except j => v_j = TRUE
1243  */
1244 static
1246  SCIP* scip, /**< SCIP data structure */
1247  SCIP_CONS* cons, /**< constraint that inferred the bound change */
1248  SCIP_VAR* infervar, /**< variable that was deduced */
1249  PROPRULE proprule, /**< propagation rule that deduced the value */
1250  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1251  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
1252  )
1253 {
1254  SCIP_CONSDATA* consdata;
1255  SCIP_VAR** vars;
1256  int nvars;
1257  int i;
1258 
1259  assert(result != NULL);
1260 
1261  consdata = SCIPconsGetData(cons);
1262  assert(consdata != NULL);
1263  vars = consdata->vars;
1264  nvars = consdata->nvars;
1265 
1266  switch( proprule )
1267  {
1268  case PROPRULE_1:
1269  /* the resultant was infered to TRUE, because one operand variable was TRUE */
1270  assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
1271  assert(infervar == consdata->resvar);
1272  for( i = 0; i < nvars; ++i )
1273  {
1274  if( SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) > 0.5 )
1275  {
1276  SCIP_CALL( SCIPaddConflictBinvar(scip, vars[i]) );
1277  break;
1278  }
1279  }
1280  assert(i < nvars);
1281  *result = SCIP_SUCCESS;
1282  break;
1283 
1284  case PROPRULE_2:
1285  /* the operand variable was infered to FALSE, because the resultant was FALSE */
1286  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
1287  assert(SCIPgetVarUbAtIndex(scip, consdata->resvar, bdchgidx, FALSE) < 0.5);
1288  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
1289  *result = SCIP_SUCCESS;
1290  break;
1291 
1292  case PROPRULE_3:
1293  /* the resultant was infered to FALSE, because all operand variables were FALSE */
1294  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
1295  assert(infervar == consdata->resvar);
1296  for( i = 0; i < nvars; ++i )
1297  {
1298  assert(SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) < 0.5);
1299  SCIP_CALL( SCIPaddConflictBinvar(scip, vars[i]) );
1300  }
1301  *result = SCIP_SUCCESS;
1302  break;
1303 
1304  case PROPRULE_4:
1305  /* the operand variable was infered to TRUE, because the resultant was TRUE and all other operands were FALSE */
1306  assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
1307  assert(SCIPgetVarLbAtIndex(scip, consdata->resvar, bdchgidx, FALSE) > 0.5);
1308  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
1309  for( i = 0; i < nvars; ++i )
1310  {
1311  if( vars[i] != infervar )
1312  {
1313  assert(SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) < 0.5);
1314  SCIP_CALL( SCIPaddConflictBinvar(scip, vars[i]) );
1315  }
1316  }
1317  *result = SCIP_SUCCESS;
1318  break;
1319 
1320  case PROPRULE_INVALID:
1321  default:
1322  SCIPerrorMessage("invalid inference information %d in or constraint <%s>\n", proprule, SCIPconsGetName(cons));
1323  return SCIP_INVALIDDATA;
1324  }
1325 
1326  return SCIP_OKAY;
1327 }
1328 
1329 /** upgrades unmodifiable or constraint into an and constraint on negated variables */
1330 static
1332  SCIP* scip, /**< SCIP data structure */
1333  SCIP_CONS* cons, /**< constraint that inferred the bound change */
1334  int* nupgdconss /**< pointer to count the number of constraint upgrades */
1335  )
1336 {
1337  SCIP_CONSDATA* consdata;
1338  SCIP_VAR** negvars;
1339  SCIP_VAR* negresvar;
1340  SCIP_CONS* andcons;
1341  int i;
1342 
1343  assert(nupgdconss != NULL);
1344 
1345  /* we cannot upgrade a modifiable constraint, since we don't know what additional variables to expect */
1346  if( SCIPconsIsModifiable(cons) )
1347  return SCIP_OKAY;
1348 
1349  SCIPdebugMsg(scip, "upgrading or constraint <%s> into equivalent and constraint on negated variables\n",
1350  SCIPconsGetName(cons));
1351 
1352  consdata = SCIPconsGetData(cons);
1353  assert(consdata != NULL);
1354 
1355  /* get the negated versions of the variables */
1356  SCIP_CALL( SCIPallocBufferArray(scip, &negvars, consdata->nvars) );
1357  for( i = 0; i < consdata->nvars; ++i )
1358  {
1359  SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[i], &negvars[i]) );
1360  }
1361  SCIP_CALL( SCIPgetNegatedVar(scip, consdata->resvar, &negresvar) );
1362 
1363  /* create and add the and constraint */
1364  SCIP_CALL( SCIPcreateConsAnd(scip, &andcons, SCIPconsGetName(cons), negresvar, consdata->nvars, negvars,
1368  SCIP_CALL( SCIPaddCons(scip, andcons) );
1369  SCIP_CALL( SCIPreleaseCons(scip, &andcons) );
1370 
1371  /* delete the or constraint */
1372  SCIP_CALL( SCIPdelCons(scip, cons) );
1373 
1374  /* free temporary memory */
1375  SCIPfreeBufferArray(scip, &negvars);
1376 
1377  (*nupgdconss)++;
1378 
1379  return SCIP_OKAY;
1380 }
1381 
1382 
1383 /*
1384  * Callback methods of constraint handler
1385  */
1386 
1387 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
1388 static
1389 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOr)
1390 { /*lint --e{715}*/
1391  assert(scip != NULL);
1392  assert(conshdlr != NULL);
1393  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1394 
1395  /* call inclusion method of constraint handler */
1397 
1398  *valid = TRUE;
1399 
1400  return SCIP_OKAY;
1401 }
1402 
1403 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
1404 static
1405 SCIP_DECL_CONSFREE(consFreeOr)
1406 { /*lint --e{715}*/
1407  SCIP_CONSHDLRDATA* conshdlrdata;
1408 
1409  /* free constraint handler data */
1410  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1411  assert(conshdlrdata != NULL);
1412 
1413  conshdlrdataFree(scip, &conshdlrdata);
1414 
1415  SCIPconshdlrSetData(conshdlr, NULL);
1416 
1417  return SCIP_OKAY;
1418 }
1419 
1420 
1421 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
1422 static
1423 SCIP_DECL_CONSEXITSOL(consExitsolOr)
1424 { /*lint --e{715}*/
1425  SCIP_CONSDATA* consdata;
1426  int c;
1427 
1428  /* release and free the rows of all constraints */
1429  for( c = 0; c < nconss; ++c )
1430  {
1431  consdata = SCIPconsGetData(conss[c]);
1432  SCIP_CALL( consdataFreeRows(scip, consdata) );
1433  }
1434 
1435  return SCIP_OKAY;
1436 }
1437 
1438 
1439 /** frees specific constraint data */
1440 static
1441 SCIP_DECL_CONSDELETE(consDeleteOr)
1442 { /*lint --e{715}*/
1443  SCIP_CONSHDLRDATA* conshdlrdata;
1444 
1445  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1446  assert(conshdlrdata != NULL);
1447 
1448  SCIP_CALL( consdataFree(scip, consdata, conshdlrdata->eventhdlr) );
1449 
1450  return SCIP_OKAY;
1451 }
1452 
1453 
1454 /** transforms constraint data into data belonging to the transformed problem */
1455 static
1456 SCIP_DECL_CONSTRANS(consTransOr)
1457 { /*lint --e{715}*/
1458  SCIP_CONSHDLRDATA* conshdlrdata;
1459  SCIP_CONSDATA* sourcedata;
1460  SCIP_CONSDATA* targetdata;
1461 
1462  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1463  assert(conshdlrdata != NULL);
1464 
1465  sourcedata = SCIPconsGetData(sourcecons);
1466  assert(sourcedata != NULL);
1467 
1468  /* create target constraint data */
1469  SCIP_CALL( consdataCreate(scip, &targetdata, conshdlrdata->eventhdlr,
1470  sourcedata->nvars, sourcedata->vars, sourcedata->resvar) );
1471 
1472  /* create target constraint */
1473  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
1474  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
1475  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
1476  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
1477  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
1478 
1479  return SCIP_OKAY;
1480 }
1481 
1482 
1483 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
1484 static
1485 SCIP_DECL_CONSINITLP(consInitlpOr)
1486 { /*lint --e{715}*/
1487  int i;
1488 
1489  *infeasible = FALSE;
1490 
1491  for( i = 0; i < nconss && !(*infeasible); i++ )
1492  {
1493  assert(SCIPconsIsInitial(conss[i]));
1494  SCIP_CALL( addRelaxation(scip, conss[i], infeasible) );
1495  }
1496 
1497  return SCIP_OKAY;
1498 }
1499 
1500 
1501 /** separation method of constraint handler for LP solutions */
1502 static
1503 SCIP_DECL_CONSSEPALP(consSepalpOr)
1504 { /*lint --e{715}*/
1505  SCIP_Bool separated;
1506  int c;
1507 
1508  *result = SCIP_DIDNOTFIND;
1509 
1510  /* separate all useful constraints */
1511  for( c = 0; c < nusefulconss; ++c )
1512  {
1513  SCIP_CALL( separateCons(scip, conss[c], NULL, &separated) );
1514  if( separated )
1515  *result = SCIP_SEPARATED;
1516  }
1517 
1518  /* combine constraints to get more cuts */
1519  /**@todo combine constraints to get further cuts */
1520 
1521  return SCIP_OKAY;
1522 }
1523 
1524 
1525 /** separation method of constraint handler for arbitrary primal solutions */
1526 static
1527 SCIP_DECL_CONSSEPASOL(consSepasolOr)
1528 { /*lint --e{715}*/
1529  SCIP_Bool separated;
1530  int c;
1531 
1532  *result = SCIP_DIDNOTFIND;
1533 
1534  /* separate all useful constraints */
1535  for( c = 0; c < nusefulconss; ++c )
1536  {
1537  SCIP_CALL( separateCons(scip, conss[c], sol, &separated) );
1538  if( separated )
1539  *result = SCIP_SEPARATED;
1540  }
1541 
1542  /* combine constraints to get more cuts */
1543  /**@todo combine constraints to get further cuts */
1544 
1545  return SCIP_OKAY;
1546 }
1547 
1548 
1549 /** constraint enforcing method of constraint handler for LP solutions */
1550 static
1551 SCIP_DECL_CONSENFOLP(consEnfolpOr)
1552 { /*lint --e{715}*/
1553  SCIP_Bool violated;
1554  int i;
1555 
1556  /* method is called only for integral solutions, because the enforcing priority is negative */
1557  for( i = 0; i < nconss; i++ )
1558  {
1559  SCIP_CALL( checkCons(scip, conss[i], NULL, FALSE, FALSE, &violated) );
1560  if( violated )
1561  {
1562  SCIP_Bool separated;
1563 
1564  SCIP_CALL( separateCons(scip, conss[i], NULL, &separated) );
1565  assert(separated); /* because the solution is integral, the separation always finds a cut */
1566  *result = SCIP_SEPARATED;
1567  return SCIP_OKAY;
1568  }
1569  }
1570  *result = SCIP_FEASIBLE;
1571 
1572  return SCIP_OKAY;
1573 }
1574 
1575 
1576 /** constraint enforcing method of constraint handler for relaxation solutions */
1577 static
1578 SCIP_DECL_CONSENFORELAX(consEnforelaxOr)
1579 { /*lint --e{715}*/
1580  SCIP_Bool violated;
1581  int i;
1582 
1583  /* method is called only for integral solutions, because the enforcing priority is negative */
1584  for( i = 0; i < nconss; i++ )
1585  {
1586  SCIP_CALL( checkCons(scip, conss[i], sol, FALSE, FALSE, &violated) );
1587  if( violated )
1588  {
1589  SCIP_Bool separated;
1590 
1591  SCIP_CALL( separateCons(scip, conss[i], sol, &separated) );
1592  assert(separated); /* because the solution is integral, the separation always finds a cut */
1593  *result = SCIP_SEPARATED;
1594  return SCIP_OKAY;
1595  }
1596  }
1597  *result = SCIP_FEASIBLE;
1598 
1599  return SCIP_OKAY;
1600 }
1601 
1602 
1603 /** constraint enforcing method of constraint handler for pseudo solutions */
1604 static
1605 SCIP_DECL_CONSENFOPS(consEnfopsOr)
1606 { /*lint --e{715}*/
1607  SCIP_Bool violated;
1608  int i;
1609 
1610  /* method is called only for integral solutions, because the enforcing priority is negative */
1611  for( i = 0; i < nconss; i++ )
1612  {
1613  SCIP_CALL( checkCons(scip, conss[i], NULL, TRUE, FALSE, &violated) );
1614  if( violated )
1615  {
1616  *result = SCIP_INFEASIBLE;
1617  return SCIP_OKAY;
1618  }
1619  }
1620  *result = SCIP_FEASIBLE;
1621 
1622  return SCIP_OKAY;
1623 }
1624 
1625 
1626 /** feasibility check method of constraint handler for integral solutions */
1627 static
1628 SCIP_DECL_CONSCHECK(consCheckOr)
1629 { /*lint --e{715}*/
1630  int i;
1631 
1632  *result = SCIP_FEASIBLE;
1633 
1634  /* method is called only for integral solutions, because the enforcing priority is negative */
1635  for( i = 0; i < nconss && (*result == SCIP_FEASIBLE || completely); i++ )
1636  {
1637  SCIP_Bool violated = FALSE;
1638 
1639  SCIP_CALL( checkCons(scip, conss[i], sol, checklprows, printreason, &violated) );
1640 
1641  if( violated )
1642  *result = SCIP_INFEASIBLE;
1643  }
1644 
1645  return SCIP_OKAY;
1646 }
1647 
1648 
1649 /** domain propagation method of constraint handler */
1650 static
1651 SCIP_DECL_CONSPROP(consPropOr)
1652 { /*lint --e{715}*/
1653  SCIP_CONSHDLRDATA* conshdlrdata;
1654  SCIP_Bool cutoff;
1655  int nfixedvars;
1656  int c;
1657 
1658  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1659  assert(conshdlrdata != NULL);
1660 
1661  cutoff = FALSE;
1662  nfixedvars = 0;
1663 
1664  /* propagate all useful constraints */
1665  for( c = 0; c < nusefulconss && !cutoff; ++c )
1666  {
1667  SCIP_CALL( propagateCons(scip, conss[c], conshdlrdata->eventhdlr, &cutoff, &nfixedvars) );
1668  }
1669 
1670  /* return the correct result */
1671  if( cutoff )
1672  *result = SCIP_CUTOFF;
1673  else if( nfixedvars > 0 )
1674  *result = SCIP_REDUCEDDOM;
1675  else
1676  *result = SCIP_DIDNOTFIND;
1677 
1678  return SCIP_OKAY;
1679 }
1680 
1681 
1682 /** presolving method of constraint handler */
1683 static
1684 SCIP_DECL_CONSPRESOL(consPresolOr)
1685 { /*lint --e{715}*/
1686  SCIP_CONSHDLRDATA* conshdlrdata;
1687  SCIP_CONS* cons;
1688  SCIP_CONSDATA* consdata;
1689  SCIP_Bool cutoff;
1690  SCIP_Bool redundant;
1691  SCIP_Bool aggregated;
1692  int oldnfixedvars;
1693  int oldnaggrvars;
1694  int oldnupgdconss;
1695  int c;
1696 
1697  assert(result != NULL);
1698 
1699  *result = SCIP_DIDNOTFIND;
1700  oldnfixedvars = *nfixedvars;
1701  oldnaggrvars = *naggrvars;
1702  oldnupgdconss = *nupgdconss;
1703 
1704  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1705  assert(conshdlrdata != NULL);
1706 
1707  /* process constraints */
1708  cutoff = FALSE;
1709  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
1710  {
1711  cons = conss[c];
1712  assert(cons != NULL);
1713  consdata = SCIPconsGetData(cons);
1714  assert(consdata != NULL);
1715 
1716  /* force presolving the constraint in the initial round */
1717  if( nrounds == 0 )
1718  consdata->propagated = FALSE;
1719 
1720  /* propagate constraint */
1721  SCIP_CALL( propagateCons(scip, cons, conshdlrdata->eventhdlr, &cutoff, nfixedvars) );
1722 
1723  /* remove all variables that are fixed to one */
1724  SCIP_CALL( applyFixings(scip, cons, conshdlrdata->eventhdlr) );
1725 
1726  /* transform or constraints into and constraints on the negated variables in order to improve
1727  * the pairwise constraint presolving possibilities
1728  */
1729  SCIP_CALL( upgradeCons(scip, cons, nupgdconss) );
1730 
1731  if( !cutoff && !SCIPconsIsDeleted(cons) && !SCIPconsIsModifiable(cons) )
1732  {
1733  assert(consdata->nvars >= 1); /* otherwise, propagateCons() has deleted the constraint */
1734 
1735  /* if only one variable is left, the resultant has to be equal to this single variable */
1736  if( consdata->nvars == 1 )
1737  {
1738  SCIPdebugMsg(scip, "or constraint <%s> has only one variable not fixed to 0.0\n", SCIPconsGetName(cons));
1739 
1740  assert(consdata->vars != NULL);
1741  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->vars[0]), 0.0));
1742  assert(SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(consdata->vars[0]), 1.0));
1743 
1744  /* aggregate variables: resultant - operand == 0 */
1745  SCIP_CALL( SCIPaggregateVars(scip, consdata->resvar, consdata->vars[0], 1.0, -1.0, 0.0,
1746  &cutoff, &redundant, &aggregated) );
1747  assert(redundant || SCIPdoNotAggr(scip));
1748 
1749  if( aggregated )
1750  {
1751  assert(redundant);
1752  (*naggrvars)++;
1753  }
1754 
1755  if( redundant )
1756  {
1757  /* delete constraint */
1758  SCIP_CALL( SCIPdelCons(scip, cons) );
1759  (*ndelconss)++;
1760  }
1761  }
1762  else if( !consdata->impladded )
1763  {
1764  int i;
1765 
1766  /* add implications: resultant == 0 -> all operands == 0 */
1767  for( i = 0; i < consdata->nvars && !cutoff; ++i )
1768  {
1769  int nimplbdchgs;
1770 
1771  SCIP_CALL( SCIPaddVarImplication(scip, consdata->resvar, FALSE, consdata->vars[i],
1772  SCIP_BOUNDTYPE_UPPER, 0.0, &cutoff, &nimplbdchgs) );
1773  *nchgbds += nimplbdchgs;
1774  }
1775  consdata->impladded = TRUE;
1776  }
1777 
1778  /* if in r = x or y, the resultant is fixed to one, add implication x = 0 -> y = 1 */
1779  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 2 && !consdata->opimpladded
1780  && SCIPvarGetLbGlobal(consdata->resvar) > 0.5 )
1781  {
1782  int nimplbdchgs;
1783 
1784  SCIP_CALL( SCIPaddVarImplication(scip, consdata->vars[0], FALSE, consdata->vars[1],
1785  SCIP_BOUNDTYPE_LOWER, 1.0, &cutoff, &nimplbdchgs) );
1786  (*nchgbds) += nimplbdchgs;
1787  consdata->opimpladded = TRUE;
1788  }
1789  }
1790  }
1791 
1792  /* return the correct result code */
1793  if( cutoff )
1794  *result = SCIP_CUTOFF;
1795  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nupgdconss > oldnupgdconss )
1796  *result = SCIP_SUCCESS;
1797 
1798  return SCIP_OKAY;
1799 }
1800 
1801 
1802 /** propagation conflict resolving method of constraint handler */
1803 static
1804 SCIP_DECL_CONSRESPROP(consRespropOr)
1805 { /*lint --e{715}*/
1806  SCIP_CALL( resolvePropagation(scip, cons, infervar, (PROPRULE)inferinfo, bdchgidx, result) );
1807 
1808  return SCIP_OKAY;
1809 }
1810 
1811 
1812 /** variable rounding lock method of constraint handler */
1813 static
1814 SCIP_DECL_CONSLOCK(consLockOr)
1815 { /*lint --e{715}*/
1816  SCIP_CONSDATA* consdata;
1817  int i;
1818 
1819  assert(locktype == SCIP_LOCKTYPE_MODEL);
1820 
1821  consdata = SCIPconsGetData(cons);
1822  assert(consdata != NULL);
1823 
1824  /* lock resultant variable */
1825  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->resvar, locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
1826 
1827  /* lock all operand variables */
1828  for( i = 0; i < consdata->nvars; ++i )
1829  {
1830  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
1831  }
1832 
1833  return SCIP_OKAY;
1834 }
1835 
1836 
1837 /** constraint display method of constraint handler */
1838 static
1839 SCIP_DECL_CONSPRINT(consPrintOr)
1840 { /*lint --e{715}*/
1841  assert( scip != NULL );
1842  assert( conshdlr != NULL );
1843  assert( cons != NULL );
1844 
1845  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
1846 
1847  return SCIP_OKAY;
1848 }
1849 
1850 /** constraint copying method of constraint handler */
1851 static
1852 SCIP_DECL_CONSCOPY(consCopyOr)
1853 { /*lint --e{715}*/
1854  SCIP_VAR** sourcevars;
1855  SCIP_VAR** vars;
1856  SCIP_VAR* sourceresvar;
1857  SCIP_VAR* resvar;
1858  int nvars;
1859  int v;
1860 
1861  assert(valid != NULL);
1862  (*valid) = TRUE;
1863  resvar = NULL;
1864 
1865  /* get variables that need to be copied */
1866  sourceresvar = SCIPgetResultantOr(sourcescip, sourcecons);
1867  sourcevars = SCIPgetVarsOr(sourcescip, sourcecons);
1868  nvars = SCIPgetNVarsOr(sourcescip, sourcecons);
1869 
1870  if( nvars == -1 )
1871  return SCIP_INVALIDCALL;
1872 
1873  /* allocate buffer array */
1874  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
1875 
1876  /* map operand variables to active variables of the target SCIP */
1877  for( v = 0; v < nvars && *valid; ++v )
1878  {
1879  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[v], &vars[v], varmap, consmap, global, valid) );
1880  assert(!(*valid) || vars[v] != NULL);
1881  }
1882 
1883  /* map resultant to active variable of the target SCIP */
1884  if( *valid )
1885  {
1886  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourceresvar, &resvar, varmap, consmap, global, valid) );
1887  assert(!(*valid) || resvar != NULL);
1888 
1889  if( *valid )
1890  {
1891  assert(resvar != NULL);
1892  SCIP_CALL( SCIPcreateConsOr(scip, cons, SCIPconsGetName(sourcecons), resvar, nvars, vars,
1893  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
1894  }
1895  }
1896 
1897  /* free buffer array */
1898  SCIPfreeBufferArray(scip, &vars);
1899 
1900  return SCIP_OKAY;
1901 }
1902 
1903 /** constraint parsing method of constraint handler */
1904 static
1905 SCIP_DECL_CONSPARSE(consParseOr)
1906 { /*lint --e{715}*/
1907  SCIP_VAR** vars;
1908  SCIP_VAR* resvar;
1909  char* strcopy;
1910  char* token;
1911  char* saveptr;
1912  char* endptr;
1913  int requiredsize;
1914  int varssize;
1915  int nvars;
1916 
1917  SCIPdebugMsg(scip, "parse <%s> as or constraint\n", str);
1918 
1919  /* copy string for truncating it */
1920  SCIP_CALL( SCIPduplicateBufferArray(scip, &strcopy, str, (int)(strlen(str)+1)));
1921 
1922  /* cutoff "or" form the constraint string */
1923  token = SCIPstrtok(strcopy, "=", &saveptr );
1924 
1925  /* parse variable name */
1926  SCIP_CALL( SCIPparseVarName(scip, token, &resvar, &endptr) );
1927 
1928  if( resvar == NULL )
1929  {
1930  SCIPdebugMsg(scip, "resultant variable %s does not exist \n", token);
1931  *success = FALSE;
1932  }
1933  else
1934  {
1935  /* cutoff "or" form the constraint string */
1936  (void) SCIPstrtok(NULL, "(", &saveptr );
1937 
1938  /* cutoff ")" form the constraint string */
1939  token = SCIPstrtok(NULL, ")", &saveptr );
1940 
1941  varssize = 100;
1942  nvars = 0;
1943 
1944  /* allocate buffer array for variables */
1945  SCIP_CALL( SCIPallocBufferArray(scip, &vars, varssize) );
1946 
1947  /* parse string */
1948  SCIP_CALL( SCIPparseVarsList(scip, token, vars, &nvars, varssize, &requiredsize, &endptr, ',', success) );
1949 
1950  if( *success )
1951  {
1952  /* check if the size of the variable array was great enough */
1953  if( varssize < requiredsize )
1954  {
1955  /* reallocate memory */
1956  varssize = requiredsize;
1957  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, varssize) );
1958 
1959  /* parse string again with the correct size of the variable array */
1960  SCIP_CALL( SCIPparseVarsList(scip, token, vars, &nvars, varssize, &requiredsize, &endptr, ',', success) );
1961  }
1962 
1963  assert(*success);
1964  assert(varssize >= requiredsize);
1965 
1966  /* create and constraint */
1967  SCIP_CALL( SCIPcreateConsOr(scip, cons, name, resvar, nvars, vars,
1968  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
1969  }
1970 
1971  /* free variable buffer */
1972  SCIPfreeBufferArray(scip, &vars);
1973  }
1974 
1975  /* free string buffer */
1976  SCIPfreeBufferArray(scip, &strcopy);
1977 
1978  return SCIP_OKAY;
1979 }
1980 
1981 /** constraint method of constraint handler which returns the variables (if possible) */
1982 static
1983 SCIP_DECL_CONSGETVARS(consGetVarsOr)
1984 { /*lint --e{715}*/
1985  SCIP_CONSDATA* consdata;
1986 
1987  consdata = SCIPconsGetData(cons);
1988  assert(consdata != NULL);
1989 
1990  if( varssize < consdata->nvars + 1 )
1991  (*success) = FALSE;
1992  else
1993  {
1994  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
1995  vars[consdata->nvars] = consdata->resvar;
1996  (*success) = TRUE;
1997  }
1998 
1999  return SCIP_OKAY;
2000 }
2001 
2002 /** constraint method of constraint handler which returns the number of variable (if possible) */
2003 static
2004 SCIP_DECL_CONSGETNVARS(consGetNVarsOr)
2005 { /*lint --e{715}*/
2006  SCIP_CONSDATA* consdata;
2007 
2008  assert(cons != NULL);
2009 
2010  consdata = SCIPconsGetData(cons);
2011  assert(consdata != NULL);
2012 
2013  (*nvars) = consdata->nvars + 1;
2014  (*success) = TRUE;
2015 
2016  return SCIP_OKAY;
2017 }
2018 
2019 
2020 /*
2021  * Callback methods of event handler
2022  */
2023 
2024 static
2025 SCIP_DECL_EVENTEXEC(eventExecOr)
2026 { /*lint --e{715}*/
2027  SCIP_CONSDATA* consdata;
2028 
2029  assert(eventhdlr != NULL);
2030  assert(eventdata != NULL);
2031  assert(event != NULL);
2032 
2033  consdata = (SCIP_CONSDATA*)eventdata;
2034  assert(consdata != NULL);
2035 
2036  /* check, if the variable was fixed to one */
2038  consdata->nofixedone = FALSE;
2039 
2040  consdata->propagated = FALSE;
2041 
2042  return SCIP_OKAY;
2043 }
2044 
2045 
2046 /*
2047  * constraint specific interface methods
2048  */
2049 
2050 /** creates the handler for or constraints and includes it in SCIP */
2052  SCIP* scip /**< SCIP data structure */
2053  )
2054 {
2055  SCIP_CONSHDLRDATA* conshdlrdata;
2056  SCIP_CONSHDLR* conshdlr;
2057  SCIP_EVENTHDLR* eventhdlr;
2058 
2059  /* create event handler for events on variables */
2061  eventExecOr, NULL) );
2062 
2063  /* create constraint handler data */
2064  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
2065 
2066  /* include constraint handler */
2069  consEnfolpOr, consEnfopsOr, consCheckOr, consLockOr,
2070  conshdlrdata) );
2071  assert(conshdlr != NULL);
2072 
2073  /* set non-fundamental callbacks via specific setter functions */
2074  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyOr, consCopyOr) );
2075  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteOr) );
2076  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolOr) );
2077  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeOr) );
2078  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsOr) );
2079  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsOr) );
2080  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpOr) );
2081  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseOr) );
2083  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintOr) );
2084  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropOr, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
2086  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropOr) );
2087  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpOr, consSepasolOr, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY,
2088  CONSHDLR_DELAYSEPA) );
2089  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransOr) );
2090  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxOr) );
2091 
2092  return SCIP_OKAY;
2093 }
2094 
2095 /** creates and captures an or constraint
2096  *
2097  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2098  */
2100  SCIP* scip, /**< SCIP data structure */
2101  SCIP_CONS** cons, /**< pointer to hold the created constraint */
2102  const char* name, /**< name of constraint */
2103  SCIP_VAR* resvar, /**< resultant variable of the operation */
2104  int nvars, /**< number of operator variables in the constraint */
2105  SCIP_VAR** vars, /**< array with operator variables of constraint */
2106  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
2107  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2108  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
2109  * Usually set to TRUE. */
2110  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
2111  * TRUE for model constraints, FALSE for additional, redundant constraints. */
2112  SCIP_Bool check, /**< should the constraint be checked for feasibility?
2113  * TRUE for model constraints, FALSE for additional, redundant constraints. */
2114  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
2115  * Usually set to TRUE. */
2116  SCIP_Bool local, /**< is constraint only valid locally?
2117  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
2118  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
2119  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
2120  * adds coefficients to this constraint. */
2121  SCIP_Bool dynamic, /**< is constraint subject to aging?
2122  * Usually set to FALSE. Set to TRUE for own cuts which
2123  * are separated as constraints. */
2124  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2125  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
2126  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2127  * if it may be moved to a more global node?
2128  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2129  )
2130 {
2131  SCIP_CONSHDLR* conshdlr;
2132  SCIP_CONSHDLRDATA* conshdlrdata;
2133  SCIP_CONSDATA* consdata;
2134 
2135  /* find the or constraint handler */
2136  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2137  if( conshdlr == NULL )
2138  {
2139  SCIPerrorMessage("or constraint handler not found\n");
2140  return SCIP_PLUGINNOTFOUND;
2141  }
2142 
2143  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2144  assert(conshdlrdata != NULL);
2145 
2146  /* create constraint data */
2147  SCIP_CALL( consdataCreate(scip, &consdata, conshdlrdata->eventhdlr, nvars, vars, resvar) );
2148 
2149  /* create constraint */
2150  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2151  local, modifiable, dynamic, removable, stickingatnode) );
2152 
2153  return SCIP_OKAY;
2154 }
2155 
2156 /** creates and captures an or constraint
2157  * in its most basic variant, i. e., with all constraint flags set to their default values
2158  *
2159  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2160  */
2162  SCIP* scip, /**< SCIP data structure */
2163  SCIP_CONS** cons, /**< pointer to hold the created constraint */
2164  const char* name, /**< name of constraint */
2165  SCIP_VAR* resvar, /**< resultant variable of the operation */
2166  int nvars, /**< number of operator variables in the constraint */
2167  SCIP_VAR** vars /**< array with operator variables of constraint */
2168  )
2169 {
2170  SCIP_CALL( SCIPcreateConsOr(scip, cons, name, resvar, nvars, vars, TRUE, TRUE, TRUE, TRUE, TRUE,
2171  FALSE, FALSE, FALSE, FALSE, FALSE) );
2172 
2173  return SCIP_OKAY;
2174 }
2175 
2176 /** gets number of variables in or constraint */
2177 int SCIPgetNVarsOr(
2178  SCIP* scip, /**< SCIP data structure */
2179  SCIP_CONS* cons /**< constraint data */
2180  )
2181 {
2182  SCIP_CONSDATA* consdata;
2183 
2184  assert(scip != NULL);
2185 
2186  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
2187  {
2188  SCIPerrorMessage("constraint is not an or constraint\n");
2189  SCIPABORT();
2190  return -1; /*lint !e527*/
2191  }
2192 
2193  consdata = SCIPconsGetData(cons);
2194  assert(consdata != NULL);
2195 
2196  return consdata->nvars;
2197 }
2198 
2199 /** gets array of variables in or constraint */
2201  SCIP* scip, /**< SCIP data structure */
2202  SCIP_CONS* cons /**< constraint data */
2203  )
2204 {
2205  SCIP_CONSDATA* consdata;
2206 
2207  assert(scip != NULL);
2208 
2209  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
2210  {
2211  SCIPerrorMessage("constraint is not an or constraint\n");
2212  SCIPABORT();
2213  return NULL; /*lint !e527*/
2214  }
2215 
2216  consdata = SCIPconsGetData(cons);
2217  assert(consdata != NULL);
2218 
2219  return consdata->vars;
2220 }
2221 
2222 /** gets the resultant variable in or constraint */
2224  SCIP* scip, /**< SCIP data structure */
2225  SCIP_CONS* cons /**< constraint data */
2226  )
2227 {
2228  SCIP_CONSDATA* consdata;
2229 
2230  assert(scip != NULL);
2231 
2232  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
2233  {
2234  SCIPerrorMessage("constraint is not a or constraint\n");
2235  SCIPABORT();
2236  return NULL; /*lint !e527*/
2237  }
2238 
2239  consdata = SCIPconsGetData(cons);
2240  assert(consdata != NULL);
2241 
2242  return consdata->resvar;
2243 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
#define CONSHDLR_DELAYSEPA
Definition: cons_or.c:83
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
SCIP_RETCODE SCIPaddVarsToRowSameCoef(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real val)
Definition: scip_lp.c:1767
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4214
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1730
SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip_lp.c:1422
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:572
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip_tree.c:146
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_or.c:588
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool *violated)
Definition: cons_or.c:782
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2134
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:365
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_or.c:748
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8353
static SCIP_RETCODE consdataCatchWatchedEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int *filterpos)
Definition: cons_or.c:221
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:595
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1603
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_or.c:509
static SCIP_DECL_CONSLOCK(consLockOr)
Definition: cons_or.c:1815
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1998
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition: cons_or.c:161
static SCIP_DECL_CONSINITLP(consInitlpOr)
Definition: cons_or.c:1486
public methods for memory management
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:354
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:886
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17919
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:825
#define SCIP_MAXSTRLEN
Definition: def.h:302
public methods for conflict handler plugins and conflict analysis
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:317
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1758
#define EVENTHDLR_NAME
Definition: cons_or.c:90
#define CONSHDLR_EAGERFREQ
Definition: cons_or.c:79
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2851
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1695
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17975
SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip_event.c:104
static SCIP_RETCODE upgradeCons(SCIP *scip, SCIP_CONS *cons, int *nupgdconss)
Definition: cons_or.c:1332
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1445
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:533
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17440
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
#define FALSE
Definition: def.h:96
static SCIP_RETCODE consdataDropWatchedEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int filterpos)
Definition: cons_or.c:245
static SCIP_RETCODE consdataSwitchWatchedvars(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int watchedvar1, int watchedvar2)
Definition: cons_or.c:320
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip_cons.c:175
SCIP_RETCODE SCIPcreateConsBasicOr(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars)
Definition: cons_or.c:2162
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10764
static SCIP_DECL_CONSCHECK(consCheckOr)
Definition: cons_or.c:1629
#define TRUE
Definition: def.h:95
#define SCIPdebug(x)
Definition: pub_message.h:93
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_or.c:177
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8373
static SCIP_RETCODE resolvePropagation(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, PROPRULE proprule, SCIP_BDCHGIDX *bdchgidx, SCIP_RESULT *result)
Definition: cons_or.c:1246
static SCIP_DECL_CONSPROP(consPropOr)
Definition: cons_or.c:1652
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8403
static SCIP_DECL_CONSSEPALP(consSepalpOr)
Definition: cons_or.c:1504
public methods for problem variables
static SCIP_DECL_CONSPARSE(consParseOr)
Definition: cons_or.c:1906
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
Definition: scip_cons.c:229
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
enum Proprule PROPRULE
Definition: cons_or.c:136
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:575
public methods for SCIP variables
static SCIP_DECL_CONSENFOPS(consEnfopsOr)
Definition: cons_or.c:1606
#define CONSHDLR_ENFOPRIORITY
Definition: cons_or.c:75
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8363
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:125
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:618
#define SCIPdebugMsgPrint
Definition: scip_message.h:79
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1486
SCIP_RETCODE SCIPcreateConsOr(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_or.c:2100
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:802
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8155
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip_cons.c:943
public methods for numerical tolerances
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17515
#define CONSHDLR_MAXPREROUNDS
Definition: cons_or.c:82
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4265
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:78
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
public methods for the branch-and-bound tree
static SCIP_RETCODE createRelaxation(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:705
Constraint handler for "or" constraints, .
#define CONSHDLR_SEPAPRIORITY
Definition: cons_or.c:74
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17929
static SCIP_DECL_CONSCOPY(consCopyOr)
Definition: cons_or.c:1853
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_EVENTHDLR *eventhdlr, int nvars, SCIP_VAR **vars, SCIP_VAR *resvar)
Definition: cons_or.c:404
public methods for managing constraints
SCIP_RETCODE SCIPparseVarsList(SCIP *scip, const char *str, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize, char **endptr, char delimiter, SCIP_Bool *success)
Definition: scip_var.c:610
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:341
static SCIP_RETCODE consdataCatchEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_or.c:268
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_and.c:5028
#define CONSHDLR_NAME
Definition: cons_or.c:72
#define SCIPerrorMessage
Definition: pub_message.h:64
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4184
#define CONSHDLR_DELAYPROP
Definition: cons_or.c:84
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2778
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3482
public methods for event handler plugins and event handlers
SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6786
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4443
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8094
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8313
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:173
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17260
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:366
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4204
#define NULL
Definition: lpi_spx1.cpp:164
static SCIP_DECL_CONSPRESOL(consPresolOr)
Definition: cons_or.c:1685
static SCIP_DECL_CONSPRINT(consPrintOr)
Definition: cons_or.c:1840
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:80
#define CONSHDLR_CHECKPRIORITY
Definition: cons_or.c:76
public methods for problem copies
#define SCIP_CALL(x)
Definition: def.h:393
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:77
enum Proprule PROPRULE
Definition: cons_and.c:178
static SCIP_DECL_CONSFREE(consFreeOr)
Definition: cons_or.c:1406
static SCIP_DECL_CONSGETVARS(consGetVarsOr)
Definition: cons_or.c:1984
SCIP_VAR ** SCIPgetVarsOr(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:2201
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8333
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOr)
Definition: cons_or.c:1390
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:250
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:641
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:65
#define CONSHDLR_PRESOLTIMING
Definition: cons_or.c:88
public methods for constraint handler plugins and constraints
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
public data structures and miscellaneous methods
static int consdataGetNRows(SCIP_CONSDATA *consdata)
Definition: cons_or.c:210
#define SCIP_Bool
Definition: def.h:93
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1030
int SCIPgetNVarsOr(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:2178
#define EVENTHDLR_DESC
Definition: cons_or.c:91
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2482
static SCIP_DECL_CONSENFORELAX(consEnforelaxOr)
Definition: cons_or.c:1579
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8114
static SCIP_RETCODE consdataDropEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_or.c:294
static SCIP_DECL_CONSSEPASOL(consSepasolOr)
Definition: cons_or.c:1528
public methods for LP management
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8223
public methods for cuts and aggregation rows
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8293
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8263
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:400
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *separated)
Definition: cons_or.c:884
static SCIP_DECL_CONSDELETE(consDeleteOr)
Definition: cons_or.c:1442
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:136
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4357
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:779
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:79
static SCIP_DECL_EVENTEXEC(eventExecOr)
Definition: cons_or.c:2026
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
public methods for the LP relaxation, rows and columns
SCIP_Real * r
Definition: circlepacking.c:59
static SCIP_RETCODE consdataFreeRows(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_or.c:448
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8487
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_or.c:475
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_or.c:1007
#define CONSHDLR_DESC
Definition: cons_or.c:73
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1562
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition: scip_var.c:292
public methods for managing events
general public methods
public methods for solutions
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition: scip_copy.c:711
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8124
SCIP_VAR * SCIPgetResultantOr(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:2224
static SCIP_DECL_CONSRESPROP(consRespropOr)
Definition: cons_or.c:1805
public methods for the probing mode
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1119
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition: cons_or.c:145
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:534
public methods for message output
static SCIP_DECL_CONSEXITSOL(consExitsolOr)
Definition: cons_or.c:1424
void SCIPupdateSolConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip_sol.c:273
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_VAR *var)
Definition: cons_or.c:534
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:8407
#define SCIP_Real
Definition: def.h:186
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8343
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:703
static SCIP_DECL_CONSTRANS(consTransOr)
Definition: cons_or.c:1457
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:848
public methods for message handling
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8283
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8571
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_or.c:197
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8273
Proprule
Definition: cons_and.c:170
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2161
#define CONSHDLR_NEEDSCONS
Definition: cons_or.c:85
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_or.c:380
#define CONSHDLR_PROP_TIMING
Definition: cons_or.c:87
static SCIP_RETCODE analyzeConflictZero(SCIP *scip, SCIP_CONS *cons, int truepos)
Definition: cons_or.c:934
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:64
SCIP_RETCODE SCIPincludeConshdlrOr(SCIP *scip)
Definition: cons_or.c:2052
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17985
static SCIP_RETCODE analyzeConflictOne(SCIP *scip, SCIP_CONS *cons)
Definition: cons_or.c:966
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17402
#define CONSHDLR_PROPFREQ
Definition: cons_or.c:78
static SCIP_DECL_CONSENFOLP(consEnfolpOr)
Definition: cons_or.c:1552
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_or.c:646
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:462
#define SCIPABORT()
Definition: def.h:365
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
public methods for global and local (sub)problems
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10722
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1361
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5729
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1533
static SCIP_DECL_CONSGETNVARS(consGetNVarsOr)
Definition: cons_or.c:2005
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:275
#define CONSHDLR_SEPAFREQ
Definition: cons_or.c:77
memory allocation routines