SCIP

    Solving Constraint Integer Programs

    cons_superindicator.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file cons_superindicator.c
    26 * @ingroup DEFPLUGINS_CONS
    27 * @brief constraint handler for indicator constraints over arbitrary constraint types
    28 * @author Ambros Gleixner
    29 * @author Frederic Pythoud
    30 */
    31
    32/**@todo allow more types for slack constraint */
    33/**@todo implement more upgrades, e.g., for nonlinear, quadratic, logicor slack constraints; upgrades could also help to
    34 * handle difficult slack constraints such as pseudoboolean or indicator
    35 */
    36/**@todo unify enfolp and enfops, sepalp and sepaps callbacks */
    37/**@todo enforce by branching on binary variable if slack constraint only returns SCIP_INFEASIBLE */
    38/**@todo consider enforcing by adding slack constraint (or copy of it) locally if binary variable is fixed to 1
    39 * (some constraint handler cannot enforce constraints that are not active)
    40 */
    41
    42/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    43
    45#include "scip/cons_indicator.h"
    46#include "scip/cons_linear.h"
    48#include "scip/dialog_default.h"
    49#include "scip/pub_cons.h"
    50#include "scip/pub_dialog.h"
    51#include "scip/pub_heur.h"
    52#include "scip/pub_message.h"
    53#include "scip/pub_misc.h"
    54#include "scip/pub_sol.h"
    55#include "scip/pub_var.h"
    56#include "scip/scip_conflict.h"
    57#include "scip/scip_cons.h"
    58#include "scip/scip_copy.h"
    59#include "scip/scip_dialog.h"
    60#include "scip/scip_general.h"
    61#include "scip/scip_mem.h"
    62#include "scip/scip_message.h"
    63#include "scip/scip_numerics.h"
    64#include "scip/scip_param.h"
    65#include "scip/scip_prob.h"
    66#include "scip/scip_sol.h"
    67#include "scip/scip_var.h"
    68#include "scip/symmetry_graph.h"
    69
    70
    71/* constraint handler properties */
    72#define CONSHDLR_NAME "superindicator"
    73#define CONSHDLR_DESC "constraint handler for indicator constraints over arbitrary constraint types"
    74#define CONSHDLR_SEPAPRIORITY 0 /**< priority of the constraint handler for separation */
    75#define CONSHDLR_ENFOPRIORITY -5000000 /**< priority of the constraint handler for constraint enforcing */
    76#define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
    77#define CONSHDLR_SEPAFREQ -1 /**< 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
    82 * participates in (-1: no limit) */
    83#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
    84#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    85#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
    86
    87#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
    88#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
    89
    90#define DEFAULT_CHECKSLACKTYPE TRUE /**< should type of slack constraint be checked when creating superindicator constraint? */
    91#define DEFAULT_UPGDPRIOINDICATOR 1 /**< priority for upgrading to an indicator constraint (-1: never) */
    92#define DEFAULT_UPGDPRIOLINEAR 2 /**< priority for upgrading to a linear constraint (-1: never) */
    93#define DEFAULT_MAXUPGDCOEFLINEAR 1e4 /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
    94 * (relative to smallest coefficient) */
    95
    96
    97/*
    98 * Data structures
    99 */
    100
    101/** constraint data for superindicator constraints */
    102struct SCIP_ConsData
    103{
    104 SCIP_CONS* slackcons; /**< constraint corresponding to the handled constraint */
    105 SCIP_VAR* binvar; /**< binary variable for indicator constraint */
    106};
    107
    108/** constraint handler data */
    109struct SCIP_ConshdlrData
    110{
    111 SCIP_Bool checkslacktype; /**< should type of slack constraint be checked when creating superindicator constraint? */
    112 SCIP_Real maxupgdcoeflinear; /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
    113 * (relative to smallest coefficient) */
    114 int upgdprioindicator; /**< priority for upgrading to an indicator constraint (-1: never) */
    115 int upgdpriolinear; /**< priority for upgrading to a linear constraint (-1: never) */
    116 int nrejects; /**< number of rejected calls to create method */
    117};
    118
    119/*
    120 * Local methods
    121 */
    122
    123/** creates superindicator constraint data */
    124static
    126 SCIP* scip, /**< SCIP data structure */
    127 SCIP_CONSDATA** consdata, /**< pointer to constraint data */
    128 SCIP_VAR* binvar, /**< binary variable */
    129 SCIP_CONS* slackcons /**< slack constraint */
    130 )
    131{
    132 assert(scip != NULL);
    133
    134 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
    135
    136 (*consdata)->binvar = binvar;
    137 (*consdata)->slackcons = slackcons;
    138
    140 {
    141 SCIPdebugMsg(scip, "creating the transformed data\n");
    142
    143 /* do not capture the slack constraint when scip is in transformed mode; this automatically happens in
    144 * SCIPtransformCons() if necessary
    145 */
    146 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->slackcons, &(*consdata)->slackcons) );
    147
    148 /* get transformed binary variable */
    149 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->binvar, &(*consdata)->binvar) );
    150 }
    151 else
    152 {
    153 /* we need to capture the constraint to avoid that SCIP deletes them since they are not (yet) added to the problem */
    154 SCIP_CALL( SCIPcaptureCons(scip, slackcons) );
    155 }
    156
    157 assert((*consdata)->slackcons != NULL);
    158
    159 return SCIP_OKAY;
    160}
    161
    162/** checks the feasibility of a superindicator constraint */
    163static
    165 SCIP* scip, /**< SCIP data structure */
    166 SCIP_CONSDATA* consdata, /**< pointer to superindicator constraint data */
    167 SCIP_SOL* sol, /**< pointer to the solution to be checked */
    168 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
    169 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
    170 SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
    171 SCIP_RESULT* result /**< pointer to store the result of the test */
    172 )
    173{
    174 SCIP_Real binval;
    175
    176 /* not to be called if infeasibility is already detected */
    177 assert(*result == SCIP_FEASIBLE || *result == SCIP_DIDNOTRUN);
    178
    179 binval = SCIPgetSolVal(scip, sol, consdata->binvar);
    180
    181 /* check integrality of binary variable */
    182 if( checkintegrality && !SCIPisIntegral(scip, binval) )
    183 {
    184 if( printreason )
    185 {
    186 SCIPinfoMessage(scip, NULL, "violation: binvar takes fractional value %.15g\n", binval);
    187 }
    188
    189 *result = SCIP_INFEASIBLE;
    190 }
    191 /* if binvar is one, call SCIPcheckCons() for the slack constraint */
    192 else if( binval > 0.5 )
    193 {
    194 assert(SCIPisFeasEQ(scip, binval, 1.0));
    195
    196 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, checklprows, printreason, result) );
    197
    198 if( printreason && *result != SCIP_FEASIBLE )
    199 {
    200 SCIPinfoMessage(scip, NULL, "violation: SCIPcheckCons() for slack constraint <%s> returns infeasible while binvar <%s> == 1\n",
    201 SCIPconsGetName(consdata->slackcons), SCIPvarGetName(consdata->binvar));
    202 }
    203
    204#ifdef SCIP_DEBUG
    205 {
    206 /* checking in debug mode that different flags don't give us different results */
    207 SCIP_RESULT testresultnotintegrality;
    208 SCIP_RESULT testresultnotlprows;
    209
    210 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, TRUE, TRUE, &testresultnotintegrality) );
    211 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, TRUE, checklprows, TRUE, &testresultnotlprows) );
    212
    213 assert(*result == testresultnotintegrality);
    214 assert(*result == testresultnotlprows);
    215 }
    216#endif
    217
    218 SCIPdebugMsg(scip, "binvar <%s> == 1, sol=%p --> SCIPcheckCons() on constraint <%s> --> %s\n",
    219 SCIPvarGetName(consdata->binvar), (void*)sol, SCIPconsGetName(consdata->slackcons),
    220 *result == SCIP_FEASIBLE ? "satisfied" : "violated");
    221 }
    222 /* if binval is zero, the superindicator constraint is feasible */
    223 else
    224 {
    225 *result = SCIP_FEASIBLE;
    226 }
    227
    228 return SCIP_OKAY;
    229}
    230
    231/** computes the minactivity, maxactivity, and minimal absolute value of nonzero coefficients of a linear constraint
    232 * with respect to its global bounds
    233 */
    234static
    236 SCIP* scip, /**< SCIP data structure */
    237 SCIP_CONS* cons, /**< pointer to linear constraint */
    238 SCIP_Real* minactivity, /**< pointer to return the minimal activity */
    239 SCIP_Real* maxactivity, /**< pointer to return the maximal activity */
    240 SCIP_Real* minabscoef /**< pointer to return the minimal absolute value of the coefficients */
    241 )
    242{
    243 SCIP_VAR** vars;
    244 SCIP_Real* vals;
    245 SCIP_Bool ismininfinity;
    246 SCIP_Bool ismaxinfinity;
    247 int nvars;
    248 int i;
    249
    250 assert(scip != NULL);
    251 assert(cons != NULL);
    252 assert(minactivity != NULL);
    253 assert(maxactivity != NULL);
    254 assert(minabscoef != NULL);
    255
    256 /* get nonzero elements */
    257 vars = SCIPgetVarsLinear(scip, cons);
    258 vals = SCIPgetValsLinear(scip, cons);
    259 nvars = SCIPgetNVarsLinear(scip, cons);
    260
    261 /* initialize values */
    262 *minactivity = 0.0;
    263 *maxactivity = 0.0;
    264 *minabscoef = SCIPinfinity(scip);
    265 ismininfinity = FALSE;
    266 ismaxinfinity = FALSE;
    267
    268 /* we loop over all the coefficients of the constraint and we cannot end if the minactivity is infinite as we
    269 * still need to compute the minimum absolute coefficient value
    270 */
    271 for( i = nvars-1; i >= 0; i-- )
    272 {
    273 SCIP_Real val;
    274 SCIP_Real lb;
    275 SCIP_Real ub;
    276
    277 val = vals[i];
    278 lb = SCIPvarGetLbGlobal(vars[i]);
    279 ub = SCIPvarGetUbGlobal(vars[i]);
    280
    281 /* update flags for infinite bounds */
    282 ismininfinity = ismininfinity || (val > 0.0 && (SCIPisInfinity(scip, lb) || SCIPisInfinity(scip, -lb)))
    283 || (val < 0.0 && (SCIPisInfinity(scip, ub) || SCIPisInfinity(scip, -ub)));
    284
    285 ismaxinfinity = ismaxinfinity || (val > 0.0 && (SCIPisInfinity(scip, ub) || SCIPisInfinity(scip, -ub)))
    286 || (val < 0.0 && (SCIPisInfinity(scip, lb) || SCIPisInfinity(scip, -lb)));
    287
    288 /* update activities if not infinite */
    289 if( !ismininfinity )
    290 *minactivity += (val > 0.0) ? val * lb : val * ub;
    291
    292 if( !ismaxinfinity )
    293 *maxactivity += (val > 0.0) ? val * ub : val * lb;
    294
    295 /* update minimal absolute coefficient value */
    296 if( val > 0.0 && val < *minabscoef )
    297 *minabscoef = val;
    298 else if( val < 0.0 && -val < *minabscoef )
    299 *minabscoef = -vals[i];
    300 }
    301
    302 if( ismininfinity )
    303 *minactivity = -SCIPinfinity(scip);
    304
    305 if( ismaxinfinity )
    306 *maxactivity = SCIPinfinity(scip);
    307}
    308
    309/** tries to upgrade superindicator constraint to an indicator constraint */
    310static
    312 SCIP* scip, /**< SCIP data structure */
    313 SCIP_CONS* cons, /**< superindicator constraint to be upgraded */
    314 SCIP_Bool* success, /**< pointer to store if the upgrading was successful */
    315 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
    316 )
    317{
    318 SCIP_CONSHDLR* conshdlr;
    319 SCIP_CONSDATA* consdata;
    320 SCIP_CONS* indcons;
    321
    322 SCIP_Real lhs;
    323 SCIP_Real rhs;
    324 char name[SCIP_MAXSTRLEN];
    325 int i;
    326
    327#ifdef SCIP_DEBUG
    328 int nnewconss;
    329#endif
    330
    331 assert(scip != NULL);
    332 assert(cons != NULL);
    333 assert(success != NULL);
    334 assert(deleted != NULL);
    335
    336 *success = FALSE;
    337 *deleted = FALSE;
    338
    339 SCIPdebug( nnewconss = 0 );
    340
    341 /* get data of superindicator constraint */
    342 consdata = SCIPconsGetData(cons);
    343 assert(consdata != NULL);
    344
    345 /* upgrade only for linear slack constraint */
    346 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(consdata->slackcons)), "linear") != 0 )
    347 return SCIP_OKAY;
    348
    349 /* upgrade only if indicator constraint handler found */
    350 conshdlr = SCIPfindConshdlr(scip, "indicator");
    351 if( conshdlr == NULL )
    352 return SCIP_OKAY;
    353
    354 /* if linear slack constraint is free we can delete the superindicator constraint */
    355 lhs = SCIPgetLhsLinear(scip, consdata->slackcons);
    356 rhs = SCIPgetRhsLinear(scip, consdata->slackcons);
    357 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    358 {
    359 SCIP_CALL( SCIPdelCons(scip, cons) );
    360 *deleted = TRUE;
    361
    362 SCIPdebugMsg(scip, "constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
    363
    364 return SCIP_OKAY;
    365 }
    366
    367 /* upgrade rhs inequality */
    368 if( !SCIPisInfinity(scip, rhs) )
    369 {
    370 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_indrhs", SCIPconsGetName(cons));
    371
    372 SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, consdata->binvar, SCIPgetNVarsLinear(scip, consdata->slackcons),
    373 SCIPgetVarsLinear(scip, consdata->slackcons), SCIPgetValsLinear(scip, consdata->slackcons), rhs,
    377
    378 SCIP_CALL( SCIPaddCons(scip, indcons) );
    379 SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
    380
    381 SCIPdebug( nnewconss++ );
    382 }
    383
    384 /* upgrade lhs inequality */
    385 if( !SCIPisInfinity(scip, -lhs) )
    386 {
    387 SCIP_Real* negvals;
    388 SCIP_Real* vals;
    389 int nvars;
    390
    391 vals = SCIPgetValsLinear(scip, consdata->slackcons);
    392 nvars = SCIPgetNVarsLinear(scip, consdata->slackcons);
    393
    394 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_indlhs", SCIPconsGetName(cons));
    395
    396 /* create array of negated coefficient values */
    397 SCIP_CALL( SCIPallocBufferArray(scip, &negvals, nvars) );
    398 for( i = nvars-1; i >= 0; i-- )
    399 negvals[i] = -vals[i];
    400
    401 SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, consdata->binvar, nvars,
    402 SCIPgetVarsLinear(scip, consdata->slackcons), negvals, -lhs,
    406
    407 SCIP_CALL( SCIPaddCons(scip, indcons) );
    408 SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
    409
    410 SCIPfreeBufferArray(scip, &negvals);
    411
    412 SCIPdebug( nnewconss++ );
    413 }
    414
    415 SCIPdebug( SCIPdebugMsg(scip, "constraint <%s> upgraded to %d indicator constraint%s\n",
    416 SCIPconsGetName(cons), nnewconss, nnewconss == 1 ? "" : "s") );
    417
    418 /* delete the superindicator constraint */
    419 SCIP_CALL( SCIPdelCons(scip, cons) );
    420 *success = TRUE;
    421
    422 return SCIP_OKAY;
    423}
    424
    425/** upgrades a superindicator constraint to a linear constraint if possible */
    426static
    428 SCIP* scip, /**< SCIP data structure */
    429 SCIP_CONS* cons, /**< superindicator constraint to be upgraded */
    430 SCIP_Bool* success, /**< pointer to store if the upgrading was successful */
    431 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
    432 )
    433{
    434 SCIP_CONSHDLR* conshdlr;
    435 SCIP_CONSDATA* consdata;
    436 SCIP_CONS* slackcons;
    437 SCIP_VAR** slackvars;
    438 SCIP_VAR** newvars;
    439 SCIP_Real* slackvals;
    440 SCIP_Real* newvals;
    441
    442 SCIP_Real maxcoef;
    443 SCIP_Real minabscoef;
    444 SCIP_Real minact;
    445 SCIP_Real maxact;
    446 SCIP_Real lhs;
    447 SCIP_Real rhs;
    448
    449 int nvars;
    450 int i;
    451
    452#ifdef SCIP_DEBUG
    453 int nnewconss;
    454#endif
    455
    456 assert(scip != NULL);
    457 assert(cons != NULL);
    458 assert(success != NULL);
    459 assert(deleted != NULL);
    460
    461 *success = FALSE;
    462 *deleted = FALSE;
    463
    464 SCIPdebug( nnewconss = 0 );
    465
    466 /* get data of superindicator constraint */
    467 consdata = SCIPconsGetData(cons);
    468 assert(consdata != NULL);
    469
    470 slackcons = consdata->slackcons;
    471 assert(slackcons != NULL);
    472
    473 /* upgrade only for linear slack constraint */
    474 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 )
    475 return SCIP_OKAY;
    476
    477 /**@todo store in conshdlrdata */
    478
    479 /* upgrade only if linear constraint handler found */
    480 conshdlr = SCIPfindConshdlr(scip, "linear");
    481 if( conshdlr == NULL )
    482 return SCIP_OKAY;
    483
    484 /* if linear slack constraint is free we can delete the superindicator constraint */
    485 rhs = SCIPgetRhsLinear(scip, slackcons);
    486 lhs = SCIPgetLhsLinear(scip, slackcons);
    487
    488 if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
    489 {
    490 SCIP_CALL( SCIPdelCons(scip, cons) );
    491 *deleted = TRUE;
    492
    493 SCIPdebugMsg(scip, "constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
    494
    495 return SCIP_OKAY;
    496 }
    497
    498 /* if linear slack constraint is redundant due to bounded activities we can delete the superindicator constraint */
    499 extractLinearValues(scip, slackcons, &minact, &maxact, &minabscoef);
    500 assert(!SCIPisInfinity(scip, minact));
    501 assert(!SCIPisInfinity(scip, -maxact));
    502
    503 if( (SCIPisInfinity(scip, -lhs) || SCIPisLE(scip, lhs, minact)) && (SCIPisInfinity(scip, rhs) || SCIPisGE(scip, rhs, maxact)) )
    504 {
    505 SCIP_CALL( SCIPdelCons(scip, cons) );
    506 *deleted = TRUE;
    507
    508 SCIPdebugMsg(scip, "constraint <%s> deleted because of redundant slack constraint\n", SCIPconsGetName(cons));
    509
    510 return SCIP_OKAY;
    511 }
    512
    513 /* if the big-M coefficient is too large compared to the coefficients of the slack constraint, we do not upgrade to
    514 * avoid numerical problems
    515 */
    516 maxcoef = minabscoef * SCIPconshdlrGetData(SCIPconsGetHdlr(cons))->maxupgdcoeflinear;
    517
    518 if( (!SCIPisInfinity(scip, rhs) && (SCIPisInfinity(scip, maxact) || SCIPisInfinity(scip, maxact - rhs) ||
    519 maxact - rhs > maxcoef)) ||
    520 (!SCIPisInfinity(scip, -lhs) && (SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, lhs - minact) ||
    521 lhs - minact > maxcoef)) )
    522 {
    523 SCIPdebugMsg(scip, "constraint <%s> not upgraded to a linear constraint due to large big-M coefficient\n",
    524 SCIPconsGetName(cons));
    525 return SCIP_OKAY;
    526 }
    527
    528 /* allocating memory for new constraint */
    529 nvars = SCIPgetNVarsLinear(scip, slackcons);
    530 SCIP_CALL( SCIPallocBufferArray(scip, &newvars, nvars+1) );
    531 SCIP_CALL( SCIPallocBufferArray(scip, &newvals, nvars+1) );
    532
    533 /* copy the vars and the vals array */
    534 slackvars = SCIPgetVarsLinear(scip, slackcons);
    535 slackvals = SCIPgetValsLinear(scip, slackcons);
    536
    537 assert(slackvars != NULL);
    538 assert(slackvals != NULL);
    539
    540 for( i = nvars-1; i >= 0; i-- )
    541 {
    542 newvars[i] = slackvars[i];
    543 newvals[i] = slackvals[i];
    544 }
    545
    546 /* add binary variable */
    547 newvars[nvars] = consdata->binvar;
    548 assert(newvars[nvars] != NULL);
    549
    550 assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
    551
    552 /* create the upgraded constraint for rhs inequality */
    553 if( !SCIPisInfinity(scip, rhs) )
    554 {
    555 SCIP_CONS* newcons;
    556 char name[SCIP_MAXSTRLEN];
    557
    558 assert(!SCIPisInfinity(scip, -maxact) );
    559 assert(!SCIPisInfinity(scip, maxact));
    560
    561 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_linrhs", SCIPconsGetName(cons));
    562
    563 /* compute big-M */
    564 newvals[nvars] = maxact - rhs;
    565 assert(!SCIPisInfinity(scip, newvals[nvars]));
    566 assert(!SCIPisInfinity(scip, -newvals[nvars]));
    567
    568 /* rhs inequality is redundant if maxact is less equal rhs */
    569 if( SCIPisPositive(scip, newvals[nvars]) )
    570 {
    571 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, -SCIPinfinity(scip), maxact,
    575
    576 SCIP_CALL( SCIPaddCons(scip, newcons) );
    577 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    578
    579 SCIPdebug( nnewconss++ );
    580 }
    581 }
    582
    583 /* create the upgraded constraint for rhs inequality */
    584 if( !SCIPisInfinity(scip, -lhs) )
    585 {
    586 SCIP_CONS* newcons;
    587 char name[SCIP_MAXSTRLEN];
    588
    589 assert(!SCIPisInfinity(scip, minact));
    590 assert(!SCIPisInfinity(scip, -minact));
    591
    592 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_linlhs", SCIPconsGetName(cons));
    593
    594 /* compute big-M */
    595 newvals[nvars] = minact - lhs;
    596 assert(!SCIPisInfinity(scip, newvals[nvars]));
    597 assert(!SCIPisInfinity(scip, -newvals[nvars]));
    598
    599 /* lhs inequality is redundant if minact is greater equal lhs */
    600 if( SCIPisNegative(scip, newvals[nvars]) )
    601 {
    602 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, minact, SCIPinfinity(scip),
    606
    607 SCIP_CALL( SCIPaddCons(scip, newcons) );
    608 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    609
    610 SCIPdebug( nnewconss++ );
    611 }
    612 }
    613
    614 /* free memory */
    615 SCIPfreeBufferArray(scip, &newvals);
    616 SCIPfreeBufferArray(scip, &newvars);
    617
    618 SCIPdebug( SCIPdebugMsg(scip, "constraint <%s> upgraded to %d indicator constraint%s\n",
    619 SCIPconsGetName(cons), nnewconss, nnewconss == 1 ? "" : "s") );
    620
    621 /* delete the superindicator constraint */
    622 SCIP_CALL( SCIPdelCons(scip, cons) );
    623 *success = TRUE;
    624
    625 return SCIP_OKAY;
    626}
    627
    628/** tries to upgrade a superindicator constraint in order of the upgrade priority parameters */
    629static
    631 SCIP* scip, /**< SCIP data structure */
    632 SCIP_CONS* cons, /**< superindicator constraint to be updated */
    633 SCIP_Bool* success, /**< pointer to store if the constraint was upgraded */
    634 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
    635 )
    636{
    637 SCIP_CONSHDLRDATA* conshdlrdata;
    638
    639 assert(scip != NULL);
    640 assert(cons != NULL);
    641 assert(success != NULL);
    642 assert(deleted != NULL);
    643
    644 *success = FALSE;
    645 *deleted = FALSE;
    646
    647 conshdlrdata = SCIPconshdlrGetData(SCIPconsGetHdlr(cons));
    648
    649 /* indicator upgrade before linear upgrade */
    650 if( conshdlrdata->upgdprioindicator > conshdlrdata->upgdpriolinear )
    651 {
    652 assert(conshdlrdata->upgdprioindicator >= 0);
    653
    654 SCIP_CALL( upgradeIndicatorSuperindicator(scip, cons, success, deleted) );
    655
    656 if( !*deleted && !*success && conshdlrdata->upgdpriolinear >= 0 )
    657 {
    658 SCIP_CALL( upgradeLinearSuperindicator(scip, cons, success, deleted) );
    659 }
    660 }
    661 /* linear upgrade before indicator upgrade */
    662 else if( conshdlrdata->upgdpriolinear >= 0 )
    663 {
    664 SCIP_CALL( upgradeLinearSuperindicator(scip, cons, success, deleted) );
    665
    666 if( !*deleted && !*success && conshdlrdata->upgdprioindicator >= 0 )
    667 {
    668 SCIP_CALL( upgradeIndicatorSuperindicator(scip, cons, success, deleted) );
    669 }
    670 }
    671
    672 return SCIP_OKAY;
    673}
    674
    675/** helper function to enforce constraints */ /*lint -e{715}*/
    676static
    678 SCIP* scip, /**< SCIP data structure */
    679 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
    680 SCIP_CONS** conss, /**< constraints to process */
    681 int nconss, /**< number of constraints */
    682 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
    683 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
    684 SCIP_Bool solinfeasible, /**< was the solution already declared infeasible by a constraint handler? */
    685 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
    686 )
    687{ /*lint --e{715}*/
    688 SCIP_Bool cont;
    689 int i;
    690
    691 assert(scip != NULL);
    692 assert(conshdlr != NULL);
    693 assert(result != NULL);
    694
    695 /* if the solution is infeasible anyway, skip the enforcement */
    696 if( solinfeasible )
    697 {
    698 *result = SCIP_FEASIBLE;
    699 return SCIP_OKAY;
    700 }
    701
    702 SCIPdebugMsg(scip, "executing enforcement callback for %s solution\n", sol == NULL ? "LP" : "relaxation");
    703
    704 cont = TRUE;
    705 *result = SCIP_FEASIBLE;
    706
    707#ifdef SCIP_OUTPUT
    709#endif
    710
    711 /* check all constraints */
    712 for( i = nconss-1; i >= 0 && cont; i-- )
    713 {
    714 SCIP_CONSDATA* consdata;
    715 SCIP_RESULT locresult;
    716
    717 consdata = SCIPconsGetData(conss[i]);
    718 assert(consdata != NULL);
    719
    720 locresult = SCIP_FEASIBLE;
    721
    722 /* enforce only if binvar is fixed to one */
    723 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    724 {
    725 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    726
    727 if( sol == NULL )
    728 {
    729 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenfolpCons() on constraint <%s>\n",
    730 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    731
    732 SCIP_CALL( SCIPenfolpCons(scip, consdata->slackcons, solinfeasible, &locresult) );
    733 }
    734 else
    735 {
    736 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenforelaxCons() on constraint <%s>\n",
    737 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    738
    739 SCIP_CALL( SCIPenforelaxCons(scip, consdata->slackcons, sol, solinfeasible, &locresult) );
    740 }
    741
    742 SCIPdebugPrintf(" --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
    743 }
    744 /* otherwise check if we have not yet detected infeasibility */
    745 else if( *result == SCIP_FEASIBLE )
    746 {
    747 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, TRUE, FALSE, FALSE, &locresult) );
    748 }
    749
    750 /* evaluate result */
    751 switch( locresult )
    752 {
    753 case SCIP_CUTOFF:
    754 case SCIP_BRANCHED:
    755 assert(*result != SCIP_CUTOFF);
    756 assert(*result != SCIP_BRANCHED);
    757 *result = locresult;
    758 cont = FALSE;
    759 break;
    760 case SCIP_CONSADDED:
    761 assert(*result != SCIP_CUTOFF);
    762 assert(*result != SCIP_BRANCHED);
    763 if( *result != SCIP_CUTOFF )
    764 *result = locresult;
    765 break;
    766 case SCIP_REDUCEDDOM:
    767 assert(*result != SCIP_CUTOFF);
    768 assert(*result != SCIP_BRANCHED);
    769 if( *result != SCIP_CUTOFF
    770 && *result != SCIP_CONSADDED )
    771 *result = locresult;
    772 break;
    773 case SCIP_SEPARATED:
    774 assert(*result != SCIP_CUTOFF);
    775 assert(*result != SCIP_BRANCHED);
    776 if( *result != SCIP_CUTOFF
    777 && *result != SCIP_CONSADDED
    778 && *result != SCIP_REDUCEDDOM )
    779 *result = locresult;
    780 break;
    781 case SCIP_INFEASIBLE:
    782 assert(*result != SCIP_CUTOFF);
    783 assert(*result != SCIP_BRANCHED);
    784 if( *result != SCIP_CUTOFF
    785 && *result != SCIP_CONSADDED
    786 && *result != SCIP_REDUCEDDOM
    787 && *result != SCIP_SEPARATED
    788 && *result != SCIP_BRANCHED )
    789 *result = locresult;
    790 break;
    791 case SCIP_FEASIBLE:
    792 break;
    793 default:
    794 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
    795 return SCIP_INVALIDRESULT;
    796 } /*lint !e788*/
    797 }
    798
    799 SCIPdebugMsg(scip, "enforcement result=%d\n", *result);
    800
    801 return SCIP_OKAY;
    802}
    803
    804
    805/** adds symmetry information of constraint to a symmetry detection graph */
    806static
    808 SCIP* scip, /**< SCIP pointer */
    809 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
    810 SCIP_CONS* cons, /**< constraint */
    811 SYM_GRAPH* graph, /**< symmetry detection graph */
    812 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
    813 )
    814{
    815 SYM_GRAPH* symgraph;
    816 SCIP_CONSHDLR* conshdlr;
    817 SCIP_CONSDATA* consdata;
    818 SCIP_VAR** vars;
    819 SCIP_Real* vals;
    820 SCIP_Real constant;
    821 int nlocvars;
    822 int rootnode;
    823 int subroot = -1;
    824
    825 assert(scip != NULL);
    826 assert(cons != NULL);
    827 assert(graph != NULL);
    828 assert(success != NULL);
    829
    830 *success = TRUE;
    831
    832 consdata = SCIPconsGetData(cons);
    833 assert(consdata != NULL);
    834 assert(consdata->binvar != NULL);
    835 assert(consdata->slackcons != NULL);
    836
    837 /* terminate if slackcons cannot provide a symmetry detection graph */
    838 conshdlr = SCIPconsGetHdlr(consdata->slackcons);
    839 assert(conshdlr != NULL);
    840
    841 if( (symtype == SYM_SYMTYPE_PERM && !SCIPconshdlrSupportsPermsymDetection(conshdlr))
    843 {
    844 *success = FALSE;
    845 return SCIP_OKAY;
    846 }
    847
    848 /* start building the symmetry detection graph for the superindicator constraint */
    849 SCIP_CALL( SCIPaddSymgraphConsnode(scip, graph, cons, 0.0, 0.0, &rootnode) );
    850
    851 /* copy symmetry detection graph of slackcons, use modest estimation for graph size */
    853 15, 15, 1, SCIPgetNVars(scip)) );
    854
    855 if( symtype == SYM_SYMTYPE_PERM )
    856 {
    857 SCIP_CALL( SCIPgetConsPermsymGraph(scip, consdata->slackcons, symgraph, success) );
    858 }
    859 else
    860 {
    861 assert(symtype == SYM_SYMTYPE_SIGNPERM);
    862
    863 SCIP_CALL( SCIPgetConsSignedPermsymGraph(scip, consdata->slackcons, symgraph, success) );
    864 }
    865
    866 if( *success )
    867 {
    868 /* copy the symmetry detection graph and find its root node with index in target graph */
    869 SCIP_CALL( SCIPcopySymgraphAsSubgraph(scip, symgraph, graph, consdata->slackcons, &subroot) );
    870
    871 if( subroot < 0 )
    872 *success = FALSE;
    873
    874 /* connect root of superindicator constraint with root of copied graph */
    875 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, subroot, FALSE, 0.0) );
    876 }
    877 SCIP_CALL( SCIPfreeSymgraph(scip, &symgraph) );
    878
    879 if( !(*success) )
    880 return SCIP_OKAY;
    881
    882 /* connect root node with binary variable (possibly resolve aggregation) */
    885
    886 vars[0] = consdata->binvar;
    887 vals[0] = 1.0;
    888 constant = 0.0;
    889 nlocvars = 1;
    890
    891 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
    892
    893 if( nlocvars > 1 || !SCIPisEQ(scip, vals[0], 1.0) || !SCIPisZero(scip, constant) )
    894 {
    895 int opnodeidx;
    896
    897 /* encode aggregation by a sum-expression and connect it to indicator node */
    898 SCIP_CALL( SCIPaddSymgraphOpnode(scip, graph, (int) SYM_CONSOPTYPE_SUM, &opnodeidx) ); /*lint !e641*/
    899 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, opnodeidx, FALSE, 0.0) );
    900
    901 /* add nodes and edges for variables in aggregation */
    902 SCIP_CALL( SCIPaddSymgraphVarAggregation(scip, graph, opnodeidx, vars, vals, nlocvars, constant) );
    903 }
    904 else if( nlocvars == 1 )
    905 {
    906 int nodeidx;
    907
    908 if( symtype == SYM_SYMTYPE_SIGNPERM )
    909 {
    910 nodeidx = SCIPgetSymgraphVarnodeidx(scip, graph, vars[0]);
    911 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, 1.0) );
    912
    913 nodeidx = SCIPgetSymgraphNegatedVarnodeidx(scip, graph, vars[0]);
    914 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, -1.0) );
    915 }
    916 else
    917 {
    918 nodeidx = SCIPgetSymgraphVarnodeidx(scip, graph, vars[0]);
    919 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, 1.0) );
    920 }
    921 }
    924
    925 return SCIP_OKAY;
    926}
    927
    928
    929/*
    930 * Callback methods of constraint handler
    931 */
    932
    933/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    934static
    935SCIP_DECL_CONSHDLRCOPY(conshdlrCopySuperindicator)
    936{ /*lint --e{715}*/
    937 assert(scip != NULL);
    938 assert(conshdlr != NULL);
    939
    941
    942 /* call inclusion method of constraint handler */
    944
    945 *valid = TRUE;
    946
    947 return SCIP_OKAY;
    948}
    949
    950/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
    951static
    952SCIP_DECL_CONSFREE(consFreeSuperindicator)
    953{ /*lint --e{715}*/
    954 SCIP_CONSHDLRDATA* conshdlrdata;
    955
    956 assert(conshdlr != NULL);
    957 assert(scip != NULL);
    958
    960
    961 SCIPdebugMsg(scip, "freeing superindicator constraint handler data\n");
    962
    963 /* free constraint handler data */
    964 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    965 assert(conshdlrdata != NULL);
    966
    967 SCIPfreeBlockMemory(scip, &conshdlrdata);
    968
    969 SCIPconshdlrSetData(conshdlr, NULL);
    970
    971 return SCIP_OKAY;
    972}
    973
    974/** presolving initialization method of constraint handler (called when presolving is about to begin) */
    975static
    976SCIP_DECL_CONSINITPRE(consInitpreSuperindicator)
    977{ /*lint --e{715}*/
    978 SCIP_CONSDATA* consdata;
    979 int i;
    980
    981 SCIPdebugMsg(scip, "initializing presolving\n");
    982
    983 for( i = nconss-1; i >= 0; i-- )
    984 {
    985 consdata = SCIPconsGetData(conss[i]);
    986 assert(consdata != NULL);
    987
    988 /* make the constraint local to avoid wrong propagation */
    989 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, TRUE) );
    990 }
    991
    992 return SCIP_OKAY;
    993}
    994
    995/** frees specific constraint data */
    996static
    997SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
    998{ /*lint --e{715}*/
    999 assert(conshdlr != NULL);
    1000 assert(consdata != NULL);
    1001 assert(*consdata != NULL);
    1002 assert((*consdata)->slackcons != NULL);
    1003
    1005
    1006 SCIPdebugMsg(scip, "deleting constraint <%s>\n", SCIPconsGetName(cons));
    1007
    1008 /* we have to release the slack constraint also in case we transformed it manually since it is captured automatically
    1009 * in SCIPtransformCons()
    1010 */
    1011 SCIP_CALL( SCIPreleaseCons(scip, &((*consdata)->slackcons)) );
    1012
    1013 /* free memory */
    1014 SCIPfreeBlockMemory(scip, consdata);
    1015
    1016 return SCIP_OKAY;
    1017}
    1018
    1019/** transforms constraint data into data belonging to the transformed problem */
    1020static
    1021SCIP_DECL_CONSTRANS(consTransSuperindicator)
    1022{ /*lint --e{715}*/
    1023 SCIP_CONSDATA* sourcedata;
    1024 SCIP_CONSDATA* targetdata;
    1025 char newname[SCIP_MAXSTRLEN];
    1026
    1027 SCIPdebugMsg(scip, "transforming superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
    1028
    1029 /* get constraint data of source constraint */
    1030 sourcedata = SCIPconsGetData(sourcecons);
    1031 assert(sourcedata != NULL);
    1032
    1033 (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "t_%s", SCIPconsGetName(sourcecons) );
    1034 SCIP_CALL( consdataCreateSuperindicator(scip, &targetdata, sourcedata->binvar, sourcedata->slackcons) );
    1035
    1036 /* create target constraint and capture it at the same time */
    1037 SCIP_CALL( SCIPcreateCons(scip, targetcons, newname, conshdlr, targetdata,
    1038 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
    1039 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
    1040 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons),
    1041 SCIPconsIsStickingAtNode(sourcecons)) );
    1042
    1043 return SCIP_OKAY;
    1044}
    1045
    1046/** LP initialization method of constraint handler */
    1047static
    1048SCIP_DECL_CONSINITLP(consInitlpSuperindicator)
    1049{
    1050 int c;
    1051
    1052 assert(scip != NULL);
    1053 assert(infeasible != NULL);
    1054
    1056
    1057 *infeasible = FALSE;
    1058
    1059 SCIPdebugMsg(scip, "executing initlp callback\n");
    1060
    1061 for( c = nconss-1; c >= 0 && !(*infeasible); c-- )
    1062 {
    1063 SCIP_CONSDATA* consdata;
    1064
    1065 consdata = SCIPconsGetData(conss[c]);
    1066
    1067 assert(consdata != NULL);
    1068 assert(SCIPconsIsInitial(conss[c]));
    1069
    1070 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    1071 {
    1072 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    1073
    1074 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPinitlpCons() on constraint <%s>\n",
    1075 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1076
    1077 SCIP_CALL( SCIPinitlpCons(scip, consdata->slackcons, infeasible) );
    1078 }
    1079 }
    1080
    1081 return SCIP_OKAY;
    1082}
    1083
    1084/** separation method of constraint handler for LP solutions */
    1085static
    1086SCIP_DECL_CONSSEPALP(consSepalpSuperindicator)
    1087{ /*lint --e{715}*/
    1088 int c;
    1089
    1090 assert(conshdlr != NULL);
    1091 assert(conss != NULL);
    1092 assert(result != NULL);
    1093
    1095
    1096 *result = SCIP_DELAYED;
    1097
    1098 SCIPdebugMsg(scip, "executing sepalp callback\n");
    1099
    1100#ifdef SCIP_OUTPUT
    1102#endif
    1103
    1104 /* check all useful constraints */
    1105 for( c = nusefulconss-1; c >= 0 && *result != SCIP_CUTOFF; c-- )
    1106 {
    1107 SCIP_CONSDATA* consdata;
    1108 SCIP_RESULT locresult;
    1109
    1110 consdata = SCIPconsGetData(conss[c]);
    1111 assert(consdata != NULL);
    1112
    1113 locresult = SCIP_DELAYED;
    1114
    1115 /* separate only if binvar is fixed to one */
    1116 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    1117 {
    1118 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    1119
    1120 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPsepalpCons() on constraint <%s>\n",
    1121 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1122
    1123 SCIP_CALL( SCIPsepalpCons(scip, consdata->slackcons, &locresult) );
    1124
    1125 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
    1126 }
    1127
    1128 /* evaluate result value */
    1129 switch( locresult )
    1130 {
    1131 case SCIP_CUTOFF:
    1132 case SCIP_CONSADDED:
    1133 assert(*result != SCIP_CUTOFF);
    1134 *result = locresult;
    1135 break;
    1136 case SCIP_REDUCEDDOM:
    1137 assert(*result != SCIP_CUTOFF);
    1138 if( *result != SCIP_CONSADDED )
    1139 *result = locresult;
    1140 break;
    1141 case SCIP_SEPARATED:
    1142 assert(*result != SCIP_CUTOFF);
    1143 if( *result != SCIP_CONSADDED
    1144 && *result != SCIP_REDUCEDDOM )
    1145 *result = locresult;
    1146 break;
    1147 case SCIP_NEWROUND:
    1148 assert(*result != SCIP_CUTOFF);
    1149 if( *result != SCIP_CONSADDED
    1150 && *result != SCIP_REDUCEDDOM
    1151 && *result != SCIP_SEPARATED )
    1152 *result = locresult;
    1153 break;
    1154 case SCIP_DIDNOTFIND:
    1155 assert(*result != SCIP_CUTOFF);
    1156 if( *result != SCIP_CONSADDED
    1157 && *result != SCIP_REDUCEDDOM
    1158 && *result != SCIP_NEWROUND
    1159 && *result != SCIP_SEPARATED )
    1160 *result = locresult;
    1161 break;
    1162 case SCIP_DIDNOTRUN:
    1163 assert(*result != SCIP_CUTOFF);
    1164 if( *result != SCIP_CONSADDED
    1165 && *result != SCIP_REDUCEDDOM
    1166 && *result != SCIP_NEWROUND
    1167 && *result != SCIP_SEPARATED
    1168 && *result != SCIP_DIDNOTFIND )
    1169 *result = locresult;
    1170 break;
    1171 case SCIP_INFEASIBLE:
    1172 assert(*result != SCIP_CUTOFF);
    1173 if( *result != SCIP_CONSADDED
    1174 && *result != SCIP_REDUCEDDOM
    1175 && *result != SCIP_SEPARATED
    1176 && *result != SCIP_DIDNOTFIND
    1177 && *result != SCIP_DIDNOTRUN
    1178 && *result != SCIP_NEWROUND )
    1179 *result = locresult;
    1180 break;
    1181 case SCIP_DELAYED:
    1182 break;
    1183 default:
    1184 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
    1185 return SCIP_INVALIDRESULT;
    1186 } /*lint !e788*/
    1187 }
    1188
    1189 SCIPdebugMsg(scip, "sepalp result=%d\n", *result);
    1190
    1191 return SCIP_OKAY;
    1192}
    1193
    1194/** separation method of constraint handler for arbitrary primal solutions */
    1195static
    1196SCIP_DECL_CONSSEPASOL(consSepasolSuperindicator)
    1197{ /*lint --e{715}*/
    1198 int c;
    1199
    1200 assert(conshdlr != NULL);
    1201 assert(conss != NULL);
    1202 assert(result != NULL);
    1203
    1205
    1206 *result = SCIP_DELAYED;
    1207
    1208 SCIPdebugMsg(scip, "executing sepasol callback\n");
    1209
    1210#ifdef SCIP_OUTPUT
    1212#endif
    1213
    1214 /* check all the useful constraint */
    1215 for( c = 0; c < nusefulconss && *result != SCIP_CUTOFF; ++c )
    1216 {
    1217 SCIP_CONSDATA* consdata;
    1218 SCIP_RESULT locresult;
    1219
    1220 consdata = SCIPconsGetData(conss[c]);
    1221 assert(consdata != NULL);
    1222
    1223 locresult = SCIP_DELAYED;
    1224
    1225 /* separate only if binvar is fixed to one */
    1226 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    1227 {
    1228 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    1229
    1230 SCIPdebugMsg(scip, "binvar <%s> == 0 --> SCIPsepasolCons() on constraint <%s>\n",
    1231 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1232
    1233 SCIP_CALL( SCIPsepasolCons(scip, consdata->slackcons, sol, &locresult) );
    1234
    1235 SCIPdebugMsgPrint(scip, " --> result=%d\n", locresult);
    1236 }
    1237
    1238 /* evaluate result value */
    1239 switch( locresult )
    1240 {
    1241 case SCIP_CUTOFF:
    1242 case SCIP_CONSADDED:
    1243 assert(*result != SCIP_CUTOFF);
    1244 *result = locresult;
    1245 break;
    1246 case SCIP_REDUCEDDOM:
    1247 assert(*result != SCIP_CUTOFF);
    1248 if( *result != SCIP_CONSADDED )
    1249 *result = locresult;
    1250 break;
    1251 case SCIP_SEPARATED:
    1252 assert(*result != SCIP_CUTOFF);
    1253 if( *result != SCIP_CONSADDED
    1254 && *result != SCIP_REDUCEDDOM )
    1255 *result = locresult;
    1256 break;
    1257 case SCIP_NEWROUND:
    1258 assert(*result != SCIP_CUTOFF);
    1259 if( *result != SCIP_CONSADDED
    1260 && *result != SCIP_REDUCEDDOM
    1261 && *result != SCIP_SEPARATED )
    1262 *result = locresult;
    1263 break;
    1264 case SCIP_DIDNOTFIND:
    1265 assert(*result != SCIP_CUTOFF);
    1266 if( *result != SCIP_CONSADDED
    1267 && *result != SCIP_REDUCEDDOM
    1268 && *result != SCIP_NEWROUND
    1269 && *result != SCIP_SEPARATED )
    1270 *result = locresult;
    1271 break;
    1272 case SCIP_DIDNOTRUN:
    1273 assert(*result != SCIP_CUTOFF);
    1274 if( *result != SCIP_CONSADDED
    1275 && *result != SCIP_REDUCEDDOM
    1276 && *result != SCIP_NEWROUND
    1277 && *result != SCIP_SEPARATED
    1278 && *result != SCIP_DIDNOTFIND )
    1279 *result = locresult;
    1280 break;
    1281 case SCIP_INFEASIBLE:
    1282 assert(*result != SCIP_CUTOFF);
    1283 if( *result != SCIP_CONSADDED
    1284 && *result != SCIP_REDUCEDDOM
    1285 && *result != SCIP_SEPARATED
    1286 && *result != SCIP_DIDNOTFIND
    1287 && *result != SCIP_DIDNOTRUN
    1288 && *result != SCIP_NEWROUND )
    1289 *result = locresult;
    1290 break;
    1291 case SCIP_DELAYED:
    1292 break;
    1293 default:
    1294 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
    1295 return SCIP_INVALIDRESULT;
    1296 } /*lint !e788*/
    1297 }
    1298
    1299 SCIPdebugMsg(scip, "sepa sol result=%d\n", *result);
    1300
    1301 return SCIP_OKAY;
    1302}
    1303
    1304/** constraint enforcing method of constraint handler for LP solutions */
    1305static
    1306SCIP_DECL_CONSENFOLP(consEnfolpSuperindicator)
    1307{ /*lint --e{715}*/
    1308 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, solinfeasible, result) );
    1309
    1310 return SCIP_OKAY;
    1311}
    1312
    1313/** constraint enforcing method of constraint handler for relaxation solutions */
    1314static
    1315SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
    1316{ /*lint --e{715}*/
    1317 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, solinfeasible, result) );
    1318
    1319 return SCIP_OKAY;
    1320}
    1321
    1322/** constraint enforcing method of constraint handler for pseudo solutions */
    1323static
    1324SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
    1325{ /*lint --e{715}*/
    1326 SCIP_Bool cont;
    1327 int i;
    1328
    1329 assert(scip != NULL);
    1330 assert(conshdlr != NULL);
    1331 assert(result != NULL);
    1332
    1333 /* if the solution is infeasible anyway, skip the enforcement */
    1334 if( solinfeasible )
    1335 {
    1336 *result = SCIP_FEASIBLE;
    1337 return SCIP_OKAY;
    1338 }
    1339 else if( objinfeasible )
    1340 {
    1341 *result = SCIP_DIDNOTRUN;
    1342 return SCIP_OKAY;
    1343 }
    1344
    1345 SCIPdebugMsg(scip, "executing enfops callback\n");
    1346
    1347 *result = SCIP_FEASIBLE;
    1348 cont = TRUE;
    1349
    1350 /* check all contraints */
    1351 for( i = nconss-1; i >= 0 && cont; i-- )
    1352 {
    1353 SCIP_CONSDATA* consdata;
    1354 SCIP_RESULT locresult;
    1355
    1356 consdata = SCIPconsGetData(conss[i]);
    1357 assert(consdata != NULL);
    1358
    1359 locresult = SCIP_DIDNOTRUN;
    1360
    1361 /* enforce only if binvar is fixed to one */
    1362 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    1363 {
    1364 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    1365
    1366 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenfopsCons() on constraint <%s>\n",
    1367 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1368
    1369 SCIP_CALL( SCIPenfopsCons(scip, consdata->slackcons, solinfeasible, objinfeasible, &locresult) );
    1370
    1371 SCIPdebugMsgPrint(scip, " --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
    1372 }
    1373 /* otherwise check if we have not yet detected infeasibility */
    1374 else if( *result == SCIP_FEASIBLE || *result == SCIP_DIDNOTRUN )
    1375 {
    1376 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, NULL, TRUE, FALSE, FALSE, &locresult) );
    1377 }
    1378
    1379 /* evaluate result value */
    1380 switch( locresult )
    1381 {
    1382 case SCIP_CUTOFF:
    1383 case SCIP_BRANCHED:
    1384 assert(*result != SCIP_CUTOFF);
    1385 assert(*result != SCIP_BRANCHED);
    1386 *result = locresult;
    1387 cont = FALSE;
    1388 break;
    1389 case SCIP_CONSADDED:
    1390 assert(*result != SCIP_CUTOFF);
    1391 assert(*result != SCIP_BRANCHED);
    1392 if( *result != SCIP_CUTOFF )
    1393 *result = locresult;
    1394 break;
    1395 case SCIP_REDUCEDDOM:
    1396 assert(*result != SCIP_CUTOFF);
    1397 assert(*result != SCIP_BRANCHED);
    1398 if( *result != SCIP_CUTOFF
    1399 && *result != SCIP_CONSADDED )
    1400 *result = locresult;
    1401 break;
    1402 case SCIP_SOLVELP:
    1403 assert(*result != SCIP_CUTOFF);
    1404 assert(*result != SCIP_BRANCHED);
    1405 if( *result != SCIP_CUTOFF
    1406 && *result != SCIP_CONSADDED
    1407 && *result != SCIP_REDUCEDDOM
    1408 && *result != SCIP_BRANCHED )
    1409 *result = locresult;
    1410 break;
    1411 case SCIP_INFEASIBLE:
    1412 assert(*result != SCIP_CUTOFF);
    1413 assert(*result != SCIP_BRANCHED);
    1414 if( *result != SCIP_CUTOFF
    1415 && *result != SCIP_CONSADDED
    1416 && *result != SCIP_REDUCEDDOM
    1417 && *result != SCIP_BRANCHED
    1418 && *result != SCIP_SOLVELP )
    1419 *result = locresult;
    1420 break;
    1421 case SCIP_DIDNOTRUN:
    1422 assert(*result != SCIP_CUTOFF);
    1423 assert(*result != SCIP_BRANCHED);
    1424 if( *result != SCIP_CUTOFF
    1425 && *result != SCIP_CONSADDED
    1426 && *result != SCIP_REDUCEDDOM
    1427 && *result != SCIP_BRANCHED
    1428 && *result != SCIP_SOLVELP
    1429 && *result != SCIP_INFEASIBLE )
    1430 *result = locresult;
    1431 break;
    1432 case SCIP_FEASIBLE:
    1433 assert(*result != SCIP_CUTOFF);
    1434 assert(*result != SCIP_BRANCHED);
    1435 if( *result != SCIP_CUTOFF
    1436 && *result != SCIP_CONSADDED
    1437 && *result != SCIP_REDUCEDDOM
    1438 && *result != SCIP_BRANCHED
    1439 && *result != SCIP_SOLVELP
    1440 && *result != SCIP_INFEASIBLE
    1441 && *result != SCIP_DIDNOTRUN )
    1442 *result = locresult;
    1443 break;
    1444 default:
    1445 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
    1446 return SCIP_INVALIDRESULT;
    1447 } /*lint !e788*/
    1448 }
    1449
    1450 SCIPdebugMsg(scip, "enfops result=%d\n", *result);
    1451
    1452 return SCIP_OKAY;
    1453}
    1454
    1455/** feasibility check method of constraint handler for integral solutions */
    1456static
    1457SCIP_DECL_CONSCHECK(consCheckSuperindicator)
    1458{ /*lint --e{715}*/
    1459 int i;
    1460
    1461 assert(scip != NULL);
    1462 assert(conshdlr != NULL);
    1463 assert(result != NULL);
    1464 assert(sol != NULL);
    1465
    1466 *result = SCIP_FEASIBLE;
    1467
    1468 for( i = nconss-1; i >= 0 && (*result == SCIP_FEASIBLE || completely); i-- )
    1469 {
    1470 SCIP_CONSDATA* consdata;
    1471
    1472 consdata = SCIPconsGetData(conss[i]);
    1473 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, checkintegrality, checklprows, printreason, result) );
    1474 }
    1475
    1476 SCIPdebugMsg(scip, "checked solution from <%s> (checkintegrality=%u, checklprows=%u) --> result=%d (%sfeasible)\n",
    1477 SCIPsolGetHeur(sol) == NULL ? "NULL" : SCIPheurGetName(SCIPsolGetHeur(sol)), checkintegrality, checklprows,
    1478 *result, *result == SCIP_INFEASIBLE ? "in" : "");
    1479
    1480 return SCIP_OKAY;
    1481}
    1482
    1483/** domain propagation method of constraint handler */
    1484static
    1485SCIP_DECL_CONSPROP(consPropSuperindicator)
    1486{ /*lint --e{715}*/
    1487 int i;
    1488
    1489 assert(scip != NULL);
    1490 assert(conshdlr != NULL);
    1491 assert(result != NULL);
    1492
    1493 *result = SCIP_DIDNOTRUN;
    1494
    1495 SCIPdebugMsg(scip, "executing prop callback\n");
    1496
    1497 /* loop over all useful contraints */
    1498 for( i = nusefulconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
    1499 {
    1500 SCIP_CONSDATA* consdata;
    1501 SCIP_RESULT locresult;
    1502
    1503 consdata = SCIPconsGetData(conss[i]);
    1504 assert(consdata != NULL);
    1505
    1506 locresult = SCIP_DIDNOTRUN;
    1507
    1508 /* propagate only if binvar is fixed to one */
    1509 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
    1510 {
    1511 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
    1512
    1513 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
    1514 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1515
    1516 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
    1517 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
    1518 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
    1519
    1520 locresult = SCIP_DIDNOTFIND;
    1521 }
    1522 else if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
    1523 {
    1524 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
    1525
    1526 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> propagating slack constraint <%s>\n",
    1527 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1528
    1529 SCIP_CALL( SCIPpropCons(scip, consdata->slackcons, proptiming, &locresult) );
    1530
    1531 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
    1532 }
    1533 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
    1534 * constraint, and see whether we become infeasible; if this is implemented, the resprop callback must be
    1535 * updated
    1536 */
    1537
    1538 /* evaluate result value */
    1539 switch( locresult )
    1540 {
    1541 case SCIP_CUTOFF:
    1542 case SCIP_DELAYED:
    1543 /* if propagation of one constraint is delayed, we want to propagate again unless the node is cut off */
    1544 assert(*result != SCIP_CUTOFF);
    1545 *result = locresult;
    1546 break;
    1547 case SCIP_REDUCEDDOM:
    1548 assert(*result != SCIP_CUTOFF);
    1549 if( *result != SCIP_DELAYED )
    1550 *result = locresult;
    1551 break;
    1552 case SCIP_DIDNOTFIND:
    1553 assert(*result != SCIP_CUTOFF);
    1554 if( *result != SCIP_REDUCEDDOM
    1555 && *result != SCIP_DELAYED )
    1556 *result = locresult;
    1557 break;
    1558 case SCIP_DIDNOTRUN:
    1559 assert(*result != SCIP_CUTOFF);
    1560 if( *result != SCIP_REDUCEDDOM
    1561 && *result != SCIP_DIDNOTFIND
    1562 && *result != SCIP_DELAYED )
    1563 *result = locresult;
    1564 break;
    1565 default:
    1566 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
    1567 return SCIP_INVALIDRESULT;
    1568 } /*lint !e788*/
    1569 }
    1570
    1571 SCIPdebugMsg(scip, "prop result=%d\n", *result);
    1572
    1573 return SCIP_OKAY;
    1574}
    1575
    1576/** presolving method of constraint handler */
    1577static
    1578SCIP_DECL_CONSPRESOL(consPresolSuperindicator)
    1579{ /*lint --e{715}*/
    1580 int i;
    1581
    1582 assert(scip != NULL);
    1583 assert(conss != NULL);
    1584 assert(conshdlr != NULL);
    1585
    1586 *result = SCIP_DIDNOTRUN;
    1587
    1588 SCIPdebugMsg(scip, "executing presol callback\n");
    1589
    1590 for( i = nconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
    1591 {
    1592 SCIP_CONSDATA* consdata;
    1593 SCIP_RESULT locresult;
    1594
    1595 consdata = SCIPconsGetData(conss[i]);
    1596 assert(consdata != NULL);
    1597
    1598 locresult = SCIP_DIDNOTFIND;
    1599
    1600 /**@todo check whether the slack constraint is added to SCIP; in this case the superindicator can be deleted */
    1601
    1602 /**@todo check whether the slack constraint is a superindicator constraint and presolve */
    1603
    1604 /* if binvar is globally fixed to 1, we add the slack constraint and remove the superindicator */
    1605 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
    1606 {
    1607 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
    1608
    1609 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
    1610 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
    1611
    1612 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
    1613 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
    1614 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
    1615
    1616 locresult = SCIP_SUCCESS;
    1617 }
    1618 /* otherwise try upgrading */
    1619 else
    1620 {
    1621 SCIP_Bool success;
    1622 SCIP_Bool deleted;
    1623
    1624 SCIP_CALL( upgradeSuperindicator(scip, conss[i], &success, &deleted) );
    1625
    1626 /* update statistics */
    1627 if( deleted )
    1628 (*ndelconss)++;
    1629 else if( success )
    1630 (*nupgdconss)++;
    1631
    1632 /**@todo mark if upgrading failed to avoid trying too often; however, since upgrading might fail only due to
    1633 * large domains, we may want to try again later, e.g., if SCIPisPresolveFinished() is TRUE
    1634 */
    1635
    1636 if( deleted || success )
    1637 locresult = SCIP_SUCCESS;
    1638 }
    1639 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
    1640 * constraint, and see whether we become infeasible
    1641 */
    1642
    1643 /* evaluate result value */
    1644 switch( locresult )
    1645 {
    1646 case SCIP_SUCCESS:
    1647 assert(*result != SCIP_CUTOFF);
    1648 if( *result != SCIP_DELAYED )
    1649 *result = locresult;
    1650 break;
    1651 default:
    1652 assert(locresult == SCIP_DIDNOTFIND);
    1653 assert(*result != SCIP_CUTOFF);
    1654 if( *result != SCIP_UNBOUNDED && *result != SCIP_DELAYED && *result != SCIP_SUCCESS )
    1655 *result = locresult;
    1656 break;
    1657 } /*lint !e788*/
    1658 }
    1659
    1660 SCIPdebugMsg(scip, "presol result=%d\n", *result);
    1661
    1662 return SCIP_OKAY;
    1663}
    1664
    1665/** propagation conflict resolving method of constraint handler */
    1666static
    1667SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
    1668{ /*lint --e{715}*/
    1669 SCIP_CONSDATA* consdata;
    1670
    1671 assert(scip != NULL);
    1672 assert(cons != NULL);
    1673 assert(infervar != NULL);
    1674 assert(bdchgidx != NULL);
    1675 assert(result != NULL);
    1676
    1677 SCIPdebugMsg(scip, "executing resprop callback for constraint <%s>\n", SCIPconsGetName(cons));
    1678
    1679 consdata = SCIPconsGetData(cons);
    1680 assert(consdata != NULL);
    1681
    1682 *result = SCIP_DIDNOTFIND;
    1683
    1684 /* check that we only propagated if the binvar is fixed to one */
    1685 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, consdata->binvar, bdchgidx, TRUE), 1.0));
    1686
    1687 /* add tightened lower bound on binvar to conflict set */
    1688 SCIP_CALL( SCIPaddConflictLb(scip, consdata->binvar, bdchgidx) );
    1689
    1690 /* call propagation conflict resolving method for the slack constraint */
    1691 SCIP_CALL( SCIPrespropCons(scip, consdata->slackcons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
    1692
    1693 SCIPdebugMsgPrint(scip, " --> result=%d\n", *result);
    1694
    1695 return SCIP_OKAY;
    1696}
    1697
    1698/** variable rounding lock method of constraint handler */
    1699static
    1700SCIP_DECL_CONSLOCK(consLockSuperindicator)
    1701{ /*lint --e{715}*/
    1702 SCIP_CONSDATA* consdata;
    1703
    1704 assert(scip != NULL);
    1705 assert(locktype == SCIP_LOCKTYPE_MODEL);
    1706
    1707 SCIPdebugMsg(scip, "locking variables for constraint <%s>\n", SCIPconsGetName(cons));
    1708
    1709 consdata = SCIPconsGetData(cons);
    1710 assert(consdata != NULL);
    1711
    1712 /* lock binvar up */
    1713 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvar, locktype, nlocksneg, nlockspos) );
    1714
    1715 /* call lock method for the slack constraint */
    1716 SCIP_CALL( SCIPaddConsLocksType(scip, consdata->slackcons, locktype, nlockspos, nlocksneg) );
    1717
    1718 return SCIP_OKAY;
    1719}
    1720
    1721
    1722/** constraint display method of constraint handler */
    1723static
    1724SCIP_DECL_CONSPRINT(consPrintSuperindicator)
    1725{ /*lint --e{715}*/
    1726 SCIP_CONSDATA* consdata;
    1727 SCIP_VAR* binvar;
    1728 int zeroone;
    1729
    1730 assert(scip != NULL);
    1731 assert(conshdlr != NULL);
    1732 assert(cons != NULL);
    1733
    1735
    1736 consdata = SCIPconsGetData(cons);
    1737 assert(consdata != NULL);
    1738
    1739 /* get binary variable */
    1740 binvar = consdata->binvar;
    1741 assert(binvar != NULL);
    1742
    1743 /* resolve negation if necessary */
    1744 zeroone = 1;
    1746 {
    1747 zeroone = 0;
    1748 binvar = SCIPvarGetNegatedVar(binvar);
    1749 assert(binvar != NULL);
    1750 }
    1751
    1752 /* print name of the binary variable */
    1753 SCIP_CALL( SCIPwriteVarName(scip, file, binvar, TRUE) );
    1754
    1755 /* print implication */
    1756 SCIPinfoMessage(scip, file, " = %d ->", zeroone);
    1757
    1758 /* print slack constraint */
    1759 assert(consdata->slackcons != NULL);
    1760 SCIP_CALL( SCIPprintCons(scip, consdata->slackcons, file) );
    1761
    1762 return SCIP_OKAY;
    1763}
    1764
    1765/** constraint copying method of constraint handler */
    1766static
    1767SCIP_DECL_CONSCOPY(consCopySuperindicator)
    1768{ /*lint --e{715}*/
    1769 SCIP_CONSHDLR* conshdlrslack;
    1770 SCIP_CONSDATA* sourceconsdata;
    1771 SCIP_CONS* sourceslackcons;
    1772 SCIP_CONS* targetslackcons;
    1773 SCIP_VAR* targetbinvar;
    1774 const char* consname;
    1775
    1776 assert(scip != NULL);
    1777 assert(sourcescip != NULL);
    1778 assert(sourcecons != NULL);
    1779
    1781
    1782 *valid = TRUE;
    1783
    1784 if( name != NULL )
    1785 consname = name;
    1786 else
    1787 consname = SCIPconsGetName(sourcecons);
    1788
    1789 SCIPdebugMsg(scip, "copying superindicator constraint <%s> to <%s>\n", SCIPconsGetName(sourcecons), consname);
    1790
    1791 if( modifiable )
    1792 {
    1793 SCIPwarningMessage(scip, "cannot create modifiable superindicator constraint when trying to copy constraint <%s>\n",
    1794 SCIPconsGetName(sourcecons));
    1795 *valid = FALSE;
    1796 return SCIP_OKAY;
    1797 }
    1798
    1799 sourceconsdata = SCIPconsGetData(sourcecons);
    1800 assert(sourceconsdata != NULL);
    1801
    1802 /* get slack constraint */
    1803 sourceslackcons = sourceconsdata->slackcons;
    1804 assert(sourceslackcons != NULL);
    1805
    1806 /* if the slack constraint has been deleted, create an empty linear constraint */
    1807 if( SCIPconsIsDeleted(sourceslackcons) )
    1808 {
    1809 SCIPdebugMsg(scip, "slack constraint <%s> deleted; creating empty linear constraint\n",
    1810 SCIPconsGetName(sourceslackcons));
    1811
    1812 SCIP_CALL( SCIPcreateConsLinear(scip, &targetslackcons, "dummy", 0, NULL, NULL, 0.0, SCIPinfinity(scip),
    1814
    1815 SCIP_CALL( SCIPaddCons(scip, targetslackcons) );
    1816 }
    1817 else
    1818 {
    1819 /* get copied version of slack constraint */
    1820 conshdlrslack = SCIPconsGetHdlr(sourceslackcons);
    1821 assert(conshdlrslack != NULL);
    1822
    1823 /* if copying scip after transforming the original instance before presolving, we need to correct the slack
    1824 * constraint pointer
    1825 */
    1826 assert(!SCIPisTransformed(sourcescip) || SCIPconsIsTransformed(sourceslackcons));
    1827 if( SCIPisTransformed(sourcescip) && !SCIPconsIsTransformed(sourceslackcons) )
    1828 {
    1829 SCIP_CONS* transslackcons;
    1830
    1831 SCIP_CALL( SCIPgetTransformedCons(sourcescip, sourceslackcons, &transslackcons) );
    1832 assert(transslackcons != NULL);
    1833 SCIP_CALL( SCIPreleaseCons(sourcescip, &sourceconsdata->slackcons) );
    1834 SCIP_CALL( SCIPcaptureCons(sourcescip, transslackcons) );
    1835
    1836 sourceconsdata->slackcons = transslackcons;
    1837 sourceslackcons = transslackcons;
    1838 }
    1839
    1840 SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceslackcons, &targetslackcons, conshdlrslack, varmap, consmap,
    1841 SCIPconsGetName(sourceslackcons), SCIPconsIsInitial(sourceslackcons), SCIPconsIsSeparated(sourceslackcons),
    1842 SCIPconsIsEnforced(sourceslackcons), SCIPconsIsChecked(sourceslackcons), SCIPconsIsPropagated(sourceslackcons),
    1843 SCIPconsIsLocal(sourceslackcons), SCIPconsIsModifiable(sourceslackcons), SCIPconsIsDynamic(sourceslackcons),
    1844 SCIPconsIsRemovable(sourceslackcons), SCIPconsIsStickingAtNode(sourceslackcons), global, valid) );
    1845 }
    1846
    1847 /* find copied variable corresponding to binvar */
    1848 if( *valid )
    1849 {
    1850 SCIP_VAR* sourcebinvar;
    1851
    1852 sourcebinvar = sourceconsdata->binvar;
    1853 assert(sourcebinvar != NULL);
    1854
    1855 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcebinvar, &targetbinvar, varmap, consmap, global, valid) );
    1856 }
    1857 else
    1858 targetbinvar = NULL;
    1859
    1860 /* create superindicator constraint */
    1861 if( *valid )
    1862 {
    1863 assert(targetslackcons != NULL);
    1864 assert(targetbinvar != NULL);
    1865 assert(!modifiable);
    1866
    1867 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, consname, targetbinvar, targetslackcons,
    1868 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
    1869 }
    1870
    1871 /* relase slack constraint */
    1872 if( targetslackcons != NULL )
    1873 {
    1874 SCIP_CALL( SCIPreleaseCons(scip, &targetslackcons) );
    1875 }
    1876
    1877 if( !(*valid) )
    1878 {
    1879 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
    1880 }
    1881
    1882 return SCIP_OKAY;
    1883}
    1884
    1885/** constraint parsing method of constraint handler */
    1886static
    1887SCIP_DECL_CONSPARSE(consParseSuperindicator)
    1888{ /*lint --e{715}*/
    1889 SCIP_VAR* binvar;
    1890 SCIP_CONS* slackcons;
    1891 char binvarname[1024];
    1892 const char* slackstr;
    1893 int zeroone;
    1894 int nargs;
    1895
    1896 assert(cons != NULL);
    1897 assert(scip != NULL);
    1898 assert(success != NULL);
    1899 assert(str != NULL);
    1900 assert(name != NULL);
    1901
    1902 *success = FALSE;
    1903
    1904 /* extract binary variable name and value which triggers slack constraint */
    1905 /* coverity[secure_coding] */
    1906 nargs = sscanf(str, " <%1023[^>]>[B] = %d", binvarname, &zeroone);
    1907
    1908 if( nargs != 2 || (zeroone != 0 && zeroone != 1) )
    1909 {
    1910 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
    1911 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
    1912 return SCIP_OKAY;
    1913 }
    1914
    1915 /* extract string describing slack constraint */
    1916 slackstr = strstr(str, "->");
    1917
    1918 if( slackstr == NULL )
    1919 {
    1920 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
    1921 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
    1922 return SCIP_OKAY;
    1923 }
    1924
    1925 slackstr = strstr(slackstr, "[");
    1926
    1927 if( slackstr == NULL )
    1928 {
    1929 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
    1930 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
    1931 return SCIP_OKAY;
    1932 }
    1933
    1934 SCIPdebugMsg(scip, "binvarname=%s, zeroone=%d, slackstr=%s\n", binvarname, zeroone, slackstr);
    1935
    1936 /* get binary variable */
    1937 binvar = SCIPfindVar(scip, binvarname);
    1938 if( binvar == NULL )
    1939 {
    1940 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "unknown variable <%s>\n", binvarname);
    1941 return SCIP_OKAY;
    1942 }
    1943
    1944 /* resolve negation if necessary */
    1945 if( zeroone == 0 )
    1946 {
    1947 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &binvar) );
    1948 }
    1949
    1950 /**@todo get slack constraint name and check whether constraint already exists; however, using only SCIPfindCons() is
    1951 * not sufficient since slack constraints are not added to the problem; do we need something like
    1952 * SCIPfindConsInConshdlr()?; currently, if there are two superindicator constraints with same slack constraint
    1953 * (binvars may be different), then after writing and reading, the slack constraint will be created twice with
    1954 * identical constraint name; this is not incorrect, but might consume more memory or time
    1955 */
    1956
    1957 /* parse slack constraint string */
    1958 SCIP_CALL( SCIPparseCons(scip, &slackcons, slackstr, initial, separate, enforce, check, propagate, local, modifiable,
    1959 dynamic, removable, stickingatnode, success) );
    1960
    1961 if( *success )
    1962 {
    1963 assert(binvar != NULL);
    1964 assert(slackcons != NULL);
    1965
    1966 /* create the superindicator constraint */
    1967 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
    1968 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
    1969
    1970 /* the new superindicator constraint captured the slack constraint, so we can release it now */
    1971 SCIP_CALL( SCIPreleaseCons(scip, &slackcons) );
    1972 }
    1973
    1974 return SCIP_OKAY;
    1975}
    1976
    1977/** constraint method of constraint handler which returns the variables (if possible) */
    1978static
    1979SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
    1980{ /*lint --e{715}*/
    1981 SCIP_CONSDATA* consdata;
    1982
    1983 consdata = SCIPconsGetData(cons);
    1984 assert(consdata != NULL);
    1985
    1986 /* must be ready to hold at least the binary variable */
    1987 if( varssize <= 0 )
    1988 *success = FALSE;
    1989 else
    1990 {
    1991 /* add binary variable */
    1992 vars[0] = consdata->binvar;
    1993
    1994 /* add variables of slack constraint */
    1995 SCIP_CALL( SCIPgetConsVars(scip, consdata->slackcons, &(vars[1]), varssize-1, success) );
    1996 }
    1997
    1998 return SCIP_OKAY;
    1999}
    2000
    2001/** constraint method of constraint handler which returns the number of variables (if possible) */
    2002static
    2003SCIP_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
    2004{ /*lint --e{715}*/
    2005 SCIP_CONSDATA* consdata;
    2006
    2007 consdata = SCIPconsGetData(cons);
    2008 assert(consdata != NULL);
    2009
    2010 /* get number of variables in slack constraint */
    2011 SCIP_CALL( SCIPgetConsNVars(scip, consdata->slackcons, nvars, success) );
    2012
    2013 /* add binary variable */
    2014 if( *success )
    2015 (*nvars)++;
    2016
    2017 return SCIP_OKAY;
    2018}
    2019
    2020
    2021/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
    2022static
    2023SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphSuperindicator)
    2024{ /*lint --e{715}*/
    2025 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
    2026
    2027 return SCIP_OKAY;
    2028}
    2029
    2030
    2031/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
    2032static
    2033SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphSuperindicator)
    2034{ /*lint --e{715}*/
    2035 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
    2036
    2037 return SCIP_OKAY;
    2038}
    2039
    2040
    2041/*
    2042 * constraint specific interface methods
    2043 */
    2044
    2045/** creates the handler for superindicator constraints and includes it in SCIP */
    2047 SCIP* scip /**< SCIP data structure */
    2048 )
    2049{
    2050 SCIP_CONSHDLRDATA* conshdlrdata;
    2051 SCIP_CONSHDLR* conshdlr;
    2052 SCIP_DIALOG* root;
    2053 SCIP_DIALOG* changemenu;
    2054 SCIP_DIALOG* dialog;
    2055
    2056 /* create superindicator constraint handler data */
    2057 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
    2058
    2059 conshdlrdata->nrejects = 0;
    2060
    2061 /* include constraint handler */
    2064 consEnfolpSuperindicator, consEnfopsSuperindicator, consCheckSuperindicator, consLockSuperindicator,
    2065 conshdlrdata) );
    2066
    2067 assert(conshdlr != NULL);
    2068
    2069 /* set non-fundamental callbacks via specific setter functions */
    2070 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySuperindicator, consCopySuperindicator) );
    2071 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSuperindicator) );
    2072 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeSuperindicator) );
    2073 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsSuperindicator) );
    2074 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsSuperindicator) );
    2075 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpSuperindicator) );
    2076 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreSuperindicator) );
    2077 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseSuperindicator) );
    2078 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolSuperindicator, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
    2079 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintSuperindicator) );
    2081 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropSuperindicator) );
    2082 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSuperindicator, consSepasolSuperindicator, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
    2083 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransSuperindicator) );
    2084 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSuperindicator) );
    2085 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphSuperindicator) );
    2086 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphSuperindicator) );
    2087
    2088 /* add dialogs if they are not disabled */
    2089 root = SCIPgetRootDialog(scip);
    2090 if( root != NULL )
    2091 {
    2092 /* find change menu */
    2093 if( !SCIPdialogHasEntry(root, "change") )
    2094 {
    2095 SCIP_CALL( SCIPincludeDialog(scip, &changemenu,
    2096 NULL,
    2097 SCIPdialogExecMenu, NULL, NULL,
    2098 "change", "change the problem", TRUE, NULL) );
    2099 SCIP_CALL( SCIPaddDialogEntry(scip, root, changemenu) );
    2100 SCIP_CALL( SCIPreleaseDialog(scip, &changemenu) );
    2101 }
    2102
    2103 if( SCIPdialogFindEntry(root, "change", &changemenu) != 1 )
    2104 {
    2105 SCIPerrorMessage("change sub menu not found\n");
    2106 return SCIP_PLUGINNOTFOUND;
    2107 }
    2108
    2109 /* add minuc dialog */
    2110 if( !SCIPdialogHasEntry(changemenu, "minuc") )
    2111 {
    2113 NULL,
    2114 SCIPdialogExecChangeMinUC, NULL, NULL,
    2115 "minuc", "transforms the current problem into a MinUC problem minimizing the number of unsatisfied constraints",
    2116 FALSE, NULL) );
    2117 SCIP_CALL( SCIPaddDialogEntry(scip, changemenu, dialog) );
    2118 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
    2119 }
    2120 }
    2121
    2122 /* add constraint handler parameters */
    2124 "constraints/" CONSHDLR_NAME "/checkslacktype",
    2125 "should type of slack constraint be checked when creating superindicator constraint?",
    2126 &conshdlrdata->checkslacktype, TRUE, DEFAULT_CHECKSLACKTYPE, NULL, NULL) );
    2127
    2129 "constraints/" CONSHDLR_NAME "/maxupgdcoeflinear",
    2130 "maximum big-M coefficient of binary variable in upgrade to a linear constraint (relative to smallest coefficient)",
    2131 &conshdlrdata->maxupgdcoeflinear, TRUE, DEFAULT_MAXUPGDCOEFLINEAR, 0.0, 1e15, NULL, NULL) );
    2132
    2134 "constraints/" CONSHDLR_NAME "/upgdprioindicator",
    2135 "priority for upgrading to an indicator constraint (-1: never)",
    2136 &conshdlrdata->upgdprioindicator, TRUE, DEFAULT_UPGDPRIOINDICATOR, -1, INT_MAX, NULL, NULL) );
    2137
    2139 "constraints/" CONSHDLR_NAME "/upgdpriolinear",
    2140 "priority for upgrading to an indicator constraint (-1: never)",
    2141 &conshdlrdata->upgdpriolinear, TRUE, DEFAULT_UPGDPRIOLINEAR, -1, INT_MAX, NULL, NULL) );
    2142
    2143 return SCIP_OKAY;
    2144}
    2145
    2146/** creates and captures a superindicator constraint
    2147 *
    2148 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    2149 */
    2151 SCIP* scip, /**< SCIP data structure */
    2152 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    2153 const char* name, /**< name of constraint */
    2154 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
    2155 SCIP_CONS* slackcons, /**< constraint corresponding to the handled constraint */
    2156 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
    2157 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
    2158 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
    2159 * Usually set to TRUE. */
    2160 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
    2161 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    2162 SCIP_Bool check, /**< should the constraint be checked for feasibility?
    2163 * TRUE for model constraints, FALSE for additional, redundant constraints. */
    2164 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
    2165 * Usually set to TRUE. */
    2166 SCIP_Bool local, /**< is constraint only valid locally?
    2167 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
    2168 SCIP_Bool dynamic, /**< is constraint subject to aging?
    2169 * Usually set to FALSE. Set to TRUE for own cuts which
    2170 * are separated as constraints. */
    2171 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
    2172 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
    2173 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
    2174 * if it may be moved to a more global node?
    2175 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
    2176 )
    2177{
    2178 SCIP_CONSHDLRDATA* conshdlrdata;
    2179 SCIP_CONSHDLR* conshdlr;
    2180 SCIP_CONSDATA* consdata;
    2181 SCIP_Bool modifiable;
    2182
    2183 assert(scip != NULL);
    2184 assert(cons != NULL);
    2185 assert(name != NULL);
    2186 assert(binvar != NULL);
    2187 assert(slackcons != NULL);
    2188
    2189 modifiable = FALSE;
    2190
    2191 /* find the superindicator constraint handler */
    2192 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
    2193 if( conshdlr == NULL )
    2194 {
    2195 SCIPerrorMessage("superindicator constraint handler not found\n");
    2196 return SCIP_PLUGINNOTFOUND;
    2197 }
    2198
    2199 conshdlrdata = SCIPconshdlrGetData(conshdlr);
    2200 assert(conshdlrdata != NULL);
    2201
    2202 /* only allow types of slack constraints that can be handled */
    2203 if( conshdlrdata->checkslacktype &&
    2204 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "and") != 0 &&
    2205 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "bounddisjunction") != 0 &&
    2206 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "conjunction") != 0 &&
    2207 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "disjunction") != 0 &&
    2208 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "knapsack") != 0 &&
    2209 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 &&
    2210 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linking") != 0 &&
    2211 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "logicor") != 0 &&
    2212 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "nonlinear") != 0 &&
    2213 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "or") != 0 &&
    2214 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS1") != 0 &&
    2215 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS2") != 0 &&
    2216 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "cumulative") != 0 &&
    2217 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "varbound") != 0 &&
    2218 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "superindicator") != 0
    2219 )
    2220 {
    2221 if( conshdlrdata->nrejects < 5 )
    2222 {
    2223 SCIPwarningMessage(scip, "rejected creation of superindicator with slack constraint <%s> of type <%s> "
    2224 "(use parameter <checkslacktype> to disable check)\n",
    2225 SCIPconsGetName(slackcons), SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)));
    2226 conshdlrdata->nrejects++;
    2227 }
    2228
    2229 if( conshdlrdata->nrejects == 5 )
    2230 {
    2231 SCIPwarningMessage(scip, "suppressing further warning messages of this type\n");
    2232 conshdlrdata->nrejects++;
    2233 }
    2234
    2235 return SCIP_INVALIDCALL;
    2236 }
    2237
    2238 /* create constraint data */
    2239 SCIP_CALL( consdataCreateSuperindicator(scip, &consdata, binvar, slackcons) );
    2240 assert(consdata != NULL);
    2241
    2242 /* create constraint */
    2243 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
    2244 local, modifiable, dynamic, removable, stickingatnode) );
    2245
    2246 return SCIP_OKAY;
    2247}
    2248
    2249/** creates and captures a superindicator constraint
    2250 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
    2251 * method SCIPcreateConsSuperindicator(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
    2252 *
    2253 * @see SCIPcreateConsSuperindicator() for information about the basic constraint flag configuration
    2254 *
    2255 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
    2256 */
    2258 SCIP* scip, /**< SCIP data structure */
    2259 SCIP_CONS** cons, /**< pointer to hold the created constraint */
    2260 const char* name, /**< name of constraint */
    2261 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
    2262 SCIP_CONS* slackcons /**< constraint corresponding to the handled constraint */
    2263 )
    2264{
    2265 assert(scip != NULL);
    2266 assert(cons != NULL);
    2267 assert(name != NULL);
    2268 assert(binvar != NULL);
    2269 assert(slackcons != NULL);
    2270
    2271 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
    2273
    2274 return SCIP_OKAY;
    2275}
    2276
    2277
    2278/** gets binary variable corresponding to the general indicator constraint */
    2280 SCIP_CONS* cons /**< superindicator constraint */
    2281 )
    2282{
    2283 assert(cons != NULL);
    2284 assert(SCIPconsGetData(cons) != NULL);
    2285
    2287
    2288 return SCIPconsGetData(cons)->binvar;
    2289}
    2290
    2291/** gets the slack constraint corresponding to the general indicator constraint */
    2293 SCIP_CONS* cons /**< superindicator constraint */
    2294 )
    2295{
    2296 assert(cons != NULL);
    2297 assert(SCIPconsGetData(cons) != NULL);
    2298
    2300
    2301 return SCIPconsGetData(cons)->slackcons;
    2302}
    2303
    2304
    2305/*
    2306 * constraint-dependent SCIP methods
    2307 */
    2308
    2309/** transforms the current problem into a MinUC problem (minimizing the number of unsatisfied constraints),
    2310 * a CIP generalization of the MinULR (min. unsatisfied linear relations) problem
    2311 */
    2313 SCIP* scip, /**< SCIP data structure */
    2314 SCIP_Bool* success /**< pointer to store whether all constraints could be transformed */
    2315 )
    2316{
    2317 SCIP_CONS** conss;
    2318 SCIP_CONS** probconss;
    2319 SCIP_VAR** vars;
    2320 char consname[SCIP_MAXSTRLEN];
    2321 char varname[SCIP_MAXSTRLEN];
    2322 int maxbranchprio;
    2323 int ntransconss;
    2324 int nconss;
    2325 int nvars;
    2326 int i;
    2327
    2328 assert(scip != NULL);
    2329 assert(success != NULL);
    2330
    2331 *success = FALSE;
    2332
    2334 {
    2335 SCIPerrorMessage("method <SCIPtransformMinUC> can only be called in problem stage\n");
    2336 return SCIP_INVALIDCALL;
    2337 }
    2338
    2339 /* get variable data */
    2340 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    2341
    2342 /* copy the conss array because it changes when adding and deleting constraints */
    2343 nconss = SCIPgetNConss(scip);
    2344 probconss = SCIPgetConss(scip);
    2345 SCIP_CALL( SCIPduplicateBufferArray(scip, &conss, probconss, nconss) );
    2346
    2347 /* clear objective function and compute maximal branching priority */
    2348 maxbranchprio = 0;
    2349 for( i = nvars-1; i >= 0; i-- )
    2350 {
    2351 SCIP_CALL( SCIPchgVarObj(scip, vars[i], 0.0) );
    2352
    2353 if( SCIPvarGetBranchPriority(vars[i]) > maxbranchprio )
    2354 maxbranchprio = SCIPvarGetBranchPriority(vars[i]);
    2355 }
    2356
    2357 maxbranchprio++;
    2358
    2359 /* transform each constraint to slack constraint in a newly created superindicator constraint; note that we also need
    2360 * to transform superindicator constraints, since their binary variable might have down-locks
    2361 */
    2362 ntransconss = 0;
    2363 for( i = 0; i < nconss; ++i )
    2364 {
    2365 SCIP_CONS* cons;
    2366 SCIP_CONS* supindcons;
    2367 SCIP_VAR* binvar;
    2368 SCIP_VAR* negbinvar;
    2369 SCIP_RETCODE retcode;
    2370
    2371 cons = conss[i];
    2372 assert(cons != NULL);
    2373
    2374 /* create a new binary variable with objective coefficient one */
    2375 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_master", SCIPconsGetName(cons));
    2376
    2377 SCIP_CALL( SCIPcreateVar(scip, &binvar, varname, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
    2378 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
    2379
    2380 /* get negated variable, since we want to minimize the number of violated constraints */
    2381 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
    2382
    2383 /* create superindicator constraint */
    2384 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_super", SCIPconsGetName(cons));
    2385
    2386 retcode = SCIPcreateConsSuperindicator(scip, &supindcons, consname, negbinvar, cons,
    2390
    2391 if( retcode == SCIP_OKAY )
    2392 {
    2393 /* add binary variable and increase its branching priority */
    2394 SCIP_CALL( SCIPaddVar(scip, binvar) );
    2395 SCIP_CALL( SCIPchgVarBranchPriority(scip, binvar, maxbranchprio) );
    2396
    2397 /* add superindicator constraint */
    2398 SCIP_CALL( SCIPaddCons(scip, supindcons) );
    2399
    2400 /* release binary variable and superindicator constraint */
    2401 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
    2402 SCIP_CALL( SCIPreleaseCons(scip, &supindcons) );
    2403
    2404 /* delete slack constraint; it is still captured by the superindicator constraint */
    2405 SCIP_CALL( SCIPdelCons(scip, cons) );
    2406
    2407 ntransconss++;
    2408 }
    2409 else if( retcode == SCIP_INVALIDCALL )
    2410 {
    2411 SCIPdebugMsg(scip, "constraint <%s> of type <%s> could not be transformed to superindicator and was removed\n",
    2413
    2414 /* release binary variable */
    2415 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
    2416
    2417 /* delete slack constraint; this is necessary, because, e.g., the indicator expects its linear slack constraint
    2418 * present in the problem, but this has just be transformed; hence, it cannot function any more and we have to
    2419 * remove it
    2420 */
    2421 SCIP_CALL( SCIPdelCons(scip, cons) );
    2422 }
    2423 else
    2424 {
    2425 /* return all other error codes */
    2426 SCIP_CALL( retcode );
    2427 }
    2428 }
    2429
    2430 if( ntransconss == nconss )
    2431 *success = TRUE;
    2432
    2433 /* minimize the number of violated constraints */
    2435
    2436 /* free the allocated memory for the copied constraint array */
    2437 SCIPfreeBufferArray(scip, &conss);
    2438
    2439 return SCIP_OKAY;
    2440}
    2441
    2442
    2443/*
    2444 * constraint-dependent dialog entries
    2445 */
    2446
    2447/** dialog execution method for the SCIPtransformMinUC() method */
    2448SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
    2449{ /*lint --e{715}*/
    2450 SCIP_Bool success;
    2451
    2452 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
    2453 SCIPdialogMessage(scip, NULL, "\n");
    2454
    2455 switch( SCIPgetStage(scip) )
    2456 {
    2457 case SCIP_STAGE_INIT:
    2458 SCIPdialogMessage(scip, NULL, "no problem exists\n");
    2459 break;
    2460 case SCIP_STAGE_PROBLEM:
    2461 SCIPdialogMessage(scip, NULL, "change problem to MinUC\n");
    2462 SCIPdialogMessage(scip, NULL, "==============\n");
    2463
    2464 SCIP_CALL( SCIPtransformMinUC(scip, &success) );
    2465
    2466 if( !success )
    2467 {
    2468 SCIPdialogMessage(scip, NULL, "some constraints could not be transformed to superindicator constraints and were removed\n");
    2469 }
    2470
    2471 SCIPdialogMessage(scip, NULL, "\n");
    2472 SCIPdialogMessage(scip, NULL, "changed problem has %d variables (%d bin, %d int, %d cont) and %d constraints\n",
    2476
    2477 SCIPdialogMessage(scip, NULL, "increased branching priority of new binary variables");
    2478
    2479 break;
    2485 case SCIP_STAGE_SOLVING:
    2486 case SCIP_STAGE_SOLVED:
    2491 case SCIP_STAGE_FREE:
    2492 SCIPdialogMessage(scip, NULL, "problem has to be in problem stage to create MinUC problem\n");
    2493 break;
    2494 default:
    2495 SCIPerrorMessage("invalid SCIP stage\n");
    2496 return SCIP_INVALIDCALL;
    2497 } /*lint --e{616}*/
    2498
    2499 SCIPdialogMessage(scip, NULL, "\n");
    2500 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
    2501
    2502 return SCIP_OKAY;
    2503}
    constraint handler for indicator constraints
    Constraint handler for linear constraints in their most general form, .
    static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphSuperindicator)
    static SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
    #define DEFAULT_MAXUPGDCOEFLINEAR
    #define CONSHDLR_NEEDSCONS
    #define CONSHDLR_SEPAFREQ
    #define CONSHDLR_CHECKPRIORITY
    #define DEFAULT_UPGDPRIOLINEAR
    #define CONSHDLR_DESC
    static SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
    static SCIP_DECL_CONSINITPRE(consInitpreSuperindicator)
    #define CONSHDLR_PROP_TIMING
    static SCIP_DECL_CONSFREE(consFreeSuperindicator)
    #define CONSHDLR_MAXPREROUNDS
    #define DEFAULT_CHECKSLACKTYPE
    static SCIP_RETCODE upgradeLinearSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
    static SCIP_DECL_CONSLOCK(consLockSuperindicator)
    static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
    static SCIP_DECL_CONSHDLRCOPY(conshdlrCopySuperindicator)
    static SCIP_DECL_CONSSEPALP(consSepalpSuperindicator)
    #define CONSHDLR_SEPAPRIORITY
    static void extractLinearValues(SCIP *scip, SCIP_CONS *cons, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Real *minabscoef)
    #define DEFAULT_UPGDPRIOINDICATOR
    static SCIP_DECL_CONSPRINT(consPrintSuperindicator)
    static SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
    static SCIP_DECL_CONSSEPASOL(consSepasolSuperindicator)
    static SCIP_RETCODE upgradeSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
    static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    static SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
    static SCIP_RETCODE upgradeIndicatorSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
    static SCIP_DECL_CONSPARSE(consParseSuperindicator)
    static SCIP_RETCODE consdataCheckSuperindicator(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
    static SCIP_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
    static SCIP_DECL_CONSINITLP(consInitlpSuperindicator)
    #define CONSHDLR_PROPFREQ
    static SCIP_RETCODE consdataCreateSuperindicator(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR *binvar, SCIP_CONS *slackcons)
    static SCIP_DECL_CONSCOPY(consCopySuperindicator)
    #define CONSHDLR_PRESOLTIMING
    static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphSuperindicator)
    #define CONSHDLR_EAGERFREQ
    static SCIP_DECL_CONSCHECK(consCheckSuperindicator)
    #define CONSHDLR_ENFOPRIORITY
    static SCIP_DECL_CONSENFOLP(consEnfolpSuperindicator)
    #define CONSHDLR_DELAYSEPA
    static SCIP_DECL_CONSPRESOL(consPresolSuperindicator)
    static SCIP_DECL_CONSTRANS(consTransSuperindicator)
    static SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
    #define CONSHDLR_NAME
    static SCIP_DECL_CONSPROP(consPropSuperindicator)
    #define CONSHDLR_DELAYPROP
    constraint handler for indicator constraints over arbitrary constraint types
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_CALL(x)
    Definition: def.h:364
    default user interface dialog
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetBinaryVarSuperindicator(SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_CONS * SCIPgetSlackConsSuperindicator(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, 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)
    SCIP_RETCODE SCIPcreateConsSuperindicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *slackcons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsBasicSuperindicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *slackcons)
    SCIP_RETCODE SCIPincludeConshdlrSuperindicator(SCIP *scip)
    SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, 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, SCIP_Bool global, SCIP_Bool *valid)
    Definition: scip_copy.c:1581
    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:713
    SCIP_Bool SCIPisTransformed(SCIP *scip)
    Definition: scip_general.c:655
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNContVars(SCIP *scip)
    Definition: scip_prob.c:2569
    int SCIPgetNBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2432
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    SCIP_CONS ** SCIPgetConss(SCIP *scip)
    Definition: scip_prob.c:3666
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3420
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2477
    int SCIPgetNContImplVars(SCIP *scip)
    Definition: scip_prob.c:2522
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
    Definition: scip_prob.c:3189
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsgPrint
    Definition: scip_message.h:79
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPdialogMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:191
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
    Definition: scip_cons.c:808
    void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
    Definition: cons.c:4350
    SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_cons.c:540
    SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
    Definition: scip_cons.c:831
    SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
    Definition: scip_cons.c:492
    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:235
    SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
    Definition: scip_cons.c:281
    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:181
    SCIP_Bool SCIPconshdlrSupportsSignedPermsymDetection(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5460
    SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
    Definition: scip_cons.c:900
    SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
    Definition: scip_cons.c:578
    SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
    Definition: scip_cons.c:372
    SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
    Definition: scip_cons.c:323
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4320
    SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
    Definition: scip_cons.c:347
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
    Definition: scip_cons.c:924
    SCIP_Bool SCIPconshdlrSupportsPermsymDetection(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5450
    SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
    Definition: scip_cons.c:624
    SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4340
    SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
    Definition: scip_cons.c:601
    SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
    Definition: scip_cons.c:647
    SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
    Definition: scip_cons.c:854
    SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
    Definition: scip_cons.c:785
    SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
    Definition: scip_cons.c:2621
    SCIP_RETCODE SCIPgetConsSignedPermsymGraph(SCIP *scip, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    Definition: scip_cons.c:2687
    SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
    Definition: cons.c:8423
    SCIP_RETCODE SCIPenfopsCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT *result)
    Definition: scip_cons.c:2163
    SCIP_RETCODE SCIPcheckCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
    Definition: scip_cons.c:2135
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8652
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8413
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8562
    SCIP_RETCODE SCIPenfolpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_RESULT *result)
    Definition: scip_cons.c:2194
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_RETCODE SCIPpropCons(SCIP *scip, SCIP_CONS *cons, SCIP_PROPTIMING proptiming, SCIP_RESULT *result)
    Definition: scip_cons.c:2340
    SCIP_RETCODE SCIPgetConsPermsymGraph(SCIP *scip, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
    Definition: scip_cons.c:2654
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8522
    SCIP_RETCODE SCIPsepalpCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
    Definition: scip_cons.c:2283
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8702
    SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
    Definition: scip_cons.c:2577
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    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:997
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    SCIP_RETCODE SCIPaddConsLocksType(SCIP *scip, SCIP_CONS *cons, SCIP_LOCKTYPE locktype, int nlockspos, int nlocksneg)
    Definition: scip_cons.c:2072
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8393
    SCIP_RETCODE SCIPinitlpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
    Definition: scip_cons.c:2256
    SCIP_RETCODE SCIPrespropCons(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, int inferinfo, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedbd, SCIP_RESULT *result)
    Definition: scip_cons.c:2371
    SCIP_RETCODE SCIPsetConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_Bool local)
    Definition: scip_cons.c:1398
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8642
    SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
    Definition: scip_cons.c:1674
    SCIP_RETCODE SCIPenforelaxCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
    Definition: scip_cons.c:2224
    SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8672
    SCIP_RETCODE SCIPparseCons(SCIP *scip, SCIP_CONS **cons, const char *str, 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, SCIP_Bool *success)
    Definition: scip_cons.c:1081
    SCIP_RETCODE SCIPsepasolCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RESULT *result)
    Definition: scip_cons.c:2310
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
    Definition: scip_cons.c:1584
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8572
    SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_cons.c:1138
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8662
    SCIP_RETCODE SCIPreleaseDialog(SCIP *scip, SCIP_DIALOG **dialog)
    Definition: scip_dialog.c:124
    SCIP_DIALOG * SCIPdialoghdlrGetRoot(SCIP_DIALOGHDLR *dialoghdlr)
    Definition: dialog.c:436
    SCIP_Bool SCIPdialogHasEntry(SCIP_DIALOG *dialog, const char *entryname)
    Definition: dialog.c:1013
    SCIP_RETCODE SCIPdialoghdlrAddHistory(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *command, SCIP_Bool escapecommand)
    Definition: dialog.c:725
    SCIP_RETCODE SCIPincludeDialog(SCIP *scip, SCIP_DIALOG **dialog, SCIP_DECL_DIALOGCOPY((*dialogcopy)), SCIP_DECL_DIALOGEXEC((*dialogexec)), SCIP_DECL_DIALOGDESC((*dialogdesc)), SCIP_DECL_DIALOGFREE((*dialogfree)), const char *name, const char *desc, SCIP_Bool issubmenu, SCIP_DIALOGDATA *dialogdata)
    Definition: scip_dialog.c:59
    SCIP_RETCODE SCIPaddDialogEntry(SCIP *scip, SCIP_DIALOG *dialog, SCIP_DIALOG *subdialog)
    Definition: scip_dialog.c:171
    SCIP_DIALOG * SCIPgetRootDialog(SCIP *scip)
    Definition: scip_dialog.c:157
    int SCIPdialogFindEntry(SCIP_DIALOG *dialog, const char *entryname, SCIP_DIALOG **subdialog)
    Definition: dialog.c:1046
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    SCIP_RETCODE SCIPtransformMinUC(SCIP *scip, SCIP_Bool *success)
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2351
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4274
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
    Definition: scip_var.c:5118
    SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
    Definition: scip_var.c:9917
    SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
    Definition: scip_var.c:2872
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    int SCIPvarGetBranchPriority(SCIP_VAR *var)
    Definition: var.c:24494
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
    Definition: scip_var.c:361
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
    Definition: scip_var.c:2078
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_RETCODE SCIPaddSymgraphEdge(SCIP *scip, SYM_GRAPH *graph, int first, int second, SCIP_Bool hasval, SCIP_Real val)
    SCIP_RETCODE SCIPfreeSymgraph(SCIP *scip, SYM_GRAPH **graph)
    SCIP_RETCODE SCIPaddSymgraphOpnode(SCIP *scip, SYM_GRAPH *graph, int op, int *nodeidx)
    SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    SCIP_RETCODE SCIPcreateSymgraph(SCIP *scip, SYM_SYMTYPE symtype, SYM_GRAPH **graph, SCIP_VAR **symvars, int nsymvars, int nopnodes, int nvalnodes, int nconsnodes, int nedges)
    int SCIPgetSymgraphVarnodeidx(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR *var)
    SCIP_RETCODE SCIPcopySymgraphAsSubgraph(SCIP *scip, SYM_GRAPH *sourcegraph, SYM_GRAPH *targetgraph, SCIP_CONS *sourcecons, int *rootidx)
    SCIP_RETCODE SCIPaddSymgraphConsnode(SCIP *scip, SYM_GRAPH *graph, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, int *nodeidx)
    SCIP_RETCODE SCIPaddSymgraphVarAggregation(SCIP *scip, SYM_GRAPH *graph, int rootidx, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real constant)
    int SCIPgetSymgraphNegatedVarnodeidx(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR *var)
    memory allocation routines
    public methods for managing constraints
    public methods for user interface dialog
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintf
    Definition: pub_message.h:99
    public data structures and miscellaneous methods
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for conflict handler plugins and conflict analysis
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for dialog handler plugins
    general public methods
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1219
    methods for dealing with symmetry detection graphs
    struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
    Definition: type_cons.h:64
    struct SCIP_ConsData SCIP_CONSDATA
    Definition: type_cons.h:65
    @ SCIP_VERBLEVEL_MINIMAL
    Definition: type_message.h:59
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_DELAYED
    Definition: type_result.h:43
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_UNBOUNDED
    Definition: type_result.h:47
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SOLVELP
    Definition: type_result.h:55
    @ SCIP_NEWROUND
    Definition: type_result.h:50
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDRESULT
    Definition: type_retcode.h:53
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PROBLEM
    Definition: type_set.h:45
    @ SCIP_STAGE_INITPRESOLVE
    Definition: type_set.h:48
    @ SCIP_STAGE_SOLVED
    Definition: type_set.h:54
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_TRANSFORMED
    Definition: type_set.h:47
    @ SCIP_STAGE_INITSOLVE
    Definition: type_set.h:52
    @ SCIP_STAGE_EXITPRESOLVE
    Definition: type_set.h:50
    @ SCIP_STAGE_EXITSOLVE
    Definition: type_set.h:55
    @ SCIP_STAGE_INIT
    Definition: type_set.h:44
    @ SCIP_STAGE_FREE
    Definition: type_set.h:57
    @ SCIP_STAGE_FREETRANS
    Definition: type_set.h:56
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    @ SCIP_STAGE_TRANSFORMING
    Definition: type_set.h:46
    @ SCIP_STAGE_PRESOLVED
    Definition: type_set.h:51
    enum SYM_Symtype SYM_SYMTYPE
    Definition: type_symmetry.h:64
    @ SYM_CONSOPTYPE_SUM
    Definition: type_symmetry.h:83
    @ SYM_SYMTYPE_SIGNPERM
    Definition: type_symmetry.h:62
    @ SYM_SYMTYPE_PERM
    Definition: type_symmetry.h:61
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141