SCIP

    Solving Constraint Integer Programs

    presol_gateextraction.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 presol_gateextraction.c
    26 * @ingroup DEFPLUGINS_PRESOL
    27 * @brief gateextraction presolver
    28 * @author Michael Winkler
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/cons_and.h"
    35#include "scip/cons_logicor.h"
    36#include "scip/cons_setppc.h"
    38#include "scip/pub_cons.h"
    39#include "scip/pub_message.h"
    40#include "scip/pub_misc.h"
    41#include "scip/pub_misc_sort.h"
    42#include "scip/pub_presol.h"
    43#include "scip/pub_var.h"
    44#include "scip/scip_cons.h"
    45#include "scip/scip_general.h"
    46#include "scip/scip_mem.h"
    47#include "scip/scip_message.h"
    48#include "scip/scip_param.h"
    49#include "scip/scip_presol.h"
    50#include "scip/scip_prob.h"
    51#include "scip/scip_var.h"
    52
    53
    54#define PRESOL_NAME "gateextraction"
    55#define PRESOL_DESC "presolver extracting gate(and)-constraints"
    56#define PRESOL_PRIORITY 1000000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
    57#define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    58#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
    59
    60#define HASHSIZE_LOGICORCONS 500 /**< minimal size of hash table in logicor constraint tables */
    61#define HASHSIZE_SETPPCCONS 500 /**< minimal size of hash table in setppc constraint tables */
    62
    63#define DEFAULT_ONLYSETPART FALSE /**< should only set-partitioning constraints be extracted and no and-constraints */
    64#define DEFAULT_SEARCHEQUATIONS TRUE /**< should we try to extract set-partitioning constraint out of one logicor
    65 * and one corresponding set-packing constraint
    66 */
    67#define DEFAULT_SORTING 1 /**< order logicor contraints to extract big-gates before smaller ones (-1), do
    68 * not order them (0) or order them to extract smaller gates at first (1)
    69 */
    70
    71
    72/* This presolver tries to extract gate-constraints meaning and-constraints and set-partitioning constraints (and could
    73 * be expanded to find xor-constraints too). This is done by detecting linearizations or systems of inequalities which
    74 * form an and-constraint or a set-partitioning constraint. An example:
    75 *
    76 * we have a logicor constraint of the form: x + y + z >= 1
    77 *
    78 * and we also have the following set-packing constraints: (x + y <= 1 and x + z <= 1) <=> (~x + ~y >= 1 and ~x + ~z >= 1)
    79 *
    80 * - these three constraints form an and-constraint: x = ~y * ~z (x = AND(~y,~z))
    81 *
    82 * if an additional set-packing constraint exists: y + z <= 1
    83 *
    84 * - these four constraints form a set-partitioning cons.: x + y + z = 1
    85 *
    86 * some information can be found:
    87 *
    88 * http://www.cs.ubc.ca/~hutter/earg/papers07/cnf-structure.pdf
    89 * http://www.cadence.com/cn/cadence/cadence_labs/Documents/niklas_SAT_2005_Effective.pdf
    90 *
    91 * We also do some check for logicor and set-packing/-partitioning constraint with the same variables to upgrade these
    92 * both constraints into one. For example:
    93 *
    94 * x + y + z >= 1 and x + y + z <= 1 form x + y + z = 1
    95 *
    96 */
    97
    98
    99/*
    100 * Data structures
    101 */
    102
    103
    104/** data object to compare constraint easier */
    106{
    107 SCIP_CONS* cons; /**< pointer the the corresponding constraint */
    108 SCIP_VAR** vars; /**< constraint variables used for hash comparison */
    109 int nvars; /**< number of variables */
    110};
    111typedef struct HashData HASHDATA;
    112
    113
    114/** presolver data */
    115struct SCIP_PresolData
    116{
    117 HASHDATA* setppchashdatas; /**< setppc-hashdata storage */
    118 SCIP_HASHTABLE* hashdatatable; /**< setppc-hashdata hashtable for usable setppc constraints */
    119 SCIP_HASHTABLE* setppchashtable; /**< setppc hashtable for usable setppc constraints */
    120 SCIP_HASHTABLE* logicorhashtable; /**< logicor hashtable for usable logicor constraints */
    121 SCIP_CONS** usefullogicor; /**< array for usable logicors */
    122 int nusefullogicor; /**< number of usable logicors */
    123 int susefullogicor; /**< size of array for usable logicor constraints */
    124 int nsetppchashdatas; /**< number of setppchashdata elements added to the hashtable */
    125 int ssetppchashdatas; /**< size of setppchashdata elements added to the hashtable */
    126 int ngates; /**< number of found gates in presolving */
    127 int firstchangedlogicor;/**< position of the first new/changed logicor constraint in the
    128 * usefullogicor array
    129 */
    130 int maxnvarslogicor; /**< maximal number of variables a logicor constraint has */
    131 int sorting; /**< integer parameter how to sort logicor constraints for extracting gates */
    132 SCIP_Bool usefulsetppcexist; /**< did we find usable set-packing constraints for gate extraction */
    133 SCIP_Bool usefullogicorexist; /**< did we find usable logicor constraints for gate extraction */
    134 SCIP_Bool newsetppchashdatas; /**< flag indicating whether we found new set-packing constraint with two
    135 * variables since the last presolving round
    136 */
    137 SCIP_Bool initialized; /**< was data alredy be initialized */
    138 SCIP_Bool onlysetpart; /**< boolean parameter whetehr we only want to extract linear gates */
    139 SCIP_Bool searchequations; /**< boolean parameter whetehr we want to search for equations arising from
    140 * logicor and setppc constraints
    141 */
    142};
    143
    144
    145/*
    146 * Local methods
    147 */
    148
    149
    150/** returns TRUE iff both keys are equal; two constraints are equal if they have the same pointer */
    151static
    152SCIP_DECL_HASHKEYEQ(hashdataKeyEqCons)
    153{
    154#ifndef NDEBUG
    155 SCIP* scip;
    156#endif
    157 HASHDATA* hashdata1;
    158 HASHDATA* hashdata2;
    159 int v;
    160
    161 hashdata1 = (HASHDATA*)key1;
    162 hashdata2 = (HASHDATA*)key2;
    163#ifndef NDEBUG
    164 scip = (SCIP*)userptr;
    165 assert(scip != NULL);
    166#endif
    167
    168 /* check data structure */
    169 assert(hashdata1->nvars == 2);
    170 assert(hashdata2->nvars == 2);
    171 /* at least one data object needs to be have a real set packing constraint */
    172 /* TODO why does this assert fail on one instance when problem is freed
    173 * using the new hashing: assert(hashdata1->cons != NULL || hashdata2->cons != NULL);
    174 */
    175
    176 for( v = 1; v >= 0; --v )
    177 {
    178 /* tests if variables are equal */
    179 if( hashdata1->vars[v] != hashdata2->vars[v] )
    180 return FALSE;
    181
    182 assert(SCIPvarCompare(hashdata1->vars[v], hashdata2->vars[v]) == 0);
    183 }
    184
    185 /* a hashdata object is only equal if it has the same constraint pointer, or one has no constraint pointer, latter
    186 * means that this hashdata object is derived from a logicor constraint
    187 */
    188 if( hashdata1->cons == NULL || hashdata2->cons == NULL || hashdata1->cons == hashdata2->cons )
    189 return TRUE;
    190 else
    191 return FALSE;
    192}
    193
    194/** returns the hash value of the key */
    195static
    196SCIP_DECL_HASHKEYVAL(hashdataKeyValCons)
    197{ /*lint --e{715}*/
    198 HASHDATA* hashdata;
    199 unsigned int hashval;
    200
    201 hashdata = (HASHDATA*)key;
    202 assert(hashdata != NULL);
    203 assert(hashdata->vars != NULL);
    204 assert(hashdata->nvars == 2);
    205
    206 /* if we have only two variables we store at each 16 bits of the hash value the index of a variable */
    207 hashval = ((unsigned int)SCIPvarGetIndex(hashdata->vars[1]) << 16) + (unsigned int) SCIPvarGetIndex(hashdata->vars[0]); /*lint !e701*/
    208
    209 return hashval;
    210}
    211
    212
    213/** returns TRUE iff both keys are equal; two constraints are equal if they have the same pointer */
    214static
    215SCIP_DECL_HASHKEYEQ(setppcHashdataKeyEqCons)
    216{
    217#ifndef NDEBUG
    218 SCIP* scip;
    219#endif
    220 HASHDATA* hashdata1;
    221 HASHDATA* hashdata2;
    222 int v;
    223
    224 hashdata1 = (HASHDATA*)key1;
    225 hashdata2 = (HASHDATA*)key2;
    226#ifndef NDEBUG
    227 scip = (SCIP*)userptr;
    228 assert(scip != NULL);
    229#endif
    230
    231 /* check data structure */
    232 assert(hashdata1->nvars >= 2);
    233 assert(hashdata2->nvars >= 2);
    234 /* at least one data object needs to be have a real set-packing/partitioning constraint */
    235 assert(hashdata1->cons != NULL || hashdata2->cons != NULL);
    236
    237 if( hashdata1->nvars != hashdata2->nvars )
    238 return FALSE;
    239
    240 for( v = hashdata1->nvars - 1; v >= 0; --v )
    241 {
    242 /* tests if variables are equal */
    243 if( hashdata1->vars[v] != hashdata2->vars[v] )
    244 return FALSE;
    245
    246 assert(SCIPvarCompare(hashdata1->vars[v], hashdata2->vars[v]) == 0);
    247 }
    248
    249 /* a hashdata object is only equal if it has the same constraint pointer, or one has no constraint pointer, latter
    250 * means that this hashdata object is derived from a logicor constraint
    251 */
    252 if( hashdata1->cons == NULL || hashdata2->cons == NULL || hashdata1->cons == hashdata2->cons )
    253 return TRUE;
    254 else
    255 return FALSE;
    256}
    257
    258/** returns the hash value of the key */
    259static
    260SCIP_DECL_HASHKEYVAL(setppcHashdataKeyValCons)
    261{ /*lint --e{715}*/
    262 HASHDATA* hashdata;
    263
    264 hashdata = (HASHDATA*)key;
    265 assert(hashdata != NULL);
    266 assert(hashdata->vars != NULL);
    267 assert(hashdata->nvars >= 2);
    268
    269 return SCIPhashFour(hashdata->nvars, SCIPvarGetIndex(hashdata->vars[0]), \
    270 SCIPvarGetIndex(hashdata->vars[hashdata->nvars/2]), \
    271 SCIPvarGetIndex(hashdata->vars[hashdata->nvars-1]));
    272}
    273
    274/** initialize gateextraction presolver data */
    275static
    277 SCIP_PRESOLDATA* presoldata /**< data object of presolver */
    278 )
    279{
    280 assert(presoldata != NULL);
    281
    282 presoldata->usefullogicor = NULL;
    283 presoldata->nusefullogicor = 0;
    284 presoldata->susefullogicor = 0;
    285 presoldata->firstchangedlogicor = -1;
    286 presoldata->maxnvarslogicor = 0;;
    287 presoldata->nsetppchashdatas = 0;
    288 presoldata->ssetppchashdatas = 0;
    289 presoldata->ngates = 0;
    290 presoldata->usefulsetppcexist = FALSE;
    291 presoldata->usefullogicorexist = FALSE;
    292 presoldata->newsetppchashdatas = FALSE;
    293 presoldata->initialized = FALSE;
    294
    295 presoldata->hashdatatable = NULL;
    296 presoldata->setppchashtable = NULL;
    297 presoldata->logicorhashtable = NULL;
    298}
    299
    300/** initialize gateextraction hashtables */
    301static
    303 SCIP* scip, /**< SCIP data structure */
    304 SCIP_PRESOLDATA* presoldata /**< data object of presolver */
    305 )
    306{
    307 assert(scip != NULL);
    308 assert(presoldata != NULL);
    309
    310 assert(presoldata->nusefullogicor == 0);
    311 assert(presoldata->susefullogicor == 0);
    312 assert(presoldata->nsetppchashdatas == 0);
    313 assert(presoldata->ssetppchashdatas == 0);
    314 assert(presoldata->firstchangedlogicor == -1);
    315 assert(presoldata->ngates == 0);
    316 assert(presoldata->usefullogicorexist == FALSE);
    317 assert(presoldata->usefulsetppcexist == FALSE);
    318 assert(presoldata->newsetppchashdatas == FALSE);
    319 assert(presoldata->initialized == FALSE);
    320
    321 assert(presoldata->hashdatatable == NULL);
    322 assert(presoldata->setppchashtable == NULL);
    323 assert(presoldata->logicorhashtable == NULL);
    324
    325 /* create hashtables */
    326 SCIP_CALL( SCIPhashtableCreate(&(presoldata->hashdatatable), SCIPblkmem(scip), HASHSIZE_SETPPCCONS,
    327 SCIPhashGetKeyStandard, hashdataKeyEqCons, hashdataKeyValCons, (void*) scip) );
    328 SCIP_CALL( SCIPhashtableCreate(&(presoldata->setppchashtable), SCIPblkmem(scip), HASHSIZE_SETPPCCONS,
    329 SCIPhashGetKeyStandard, SCIPhashKeyEqPtr, SCIPhashKeyValPtr, (void*) scip) );
    330 SCIP_CALL( SCIPhashtableCreate(&(presoldata->logicorhashtable), SCIPblkmem(scip), HASHSIZE_LOGICORCONS,
    331 SCIPhashGetKeyStandard, SCIPhashKeyEqPtr, SCIPhashKeyValPtr, (void*) scip) );
    332
    333 return SCIP_OKAY;
    334}
    335
    336
    337/** create useful set-packing information by adding new set-packing constraints with two variables */
    338static
    340 SCIP* scip, /**< SCIP data structure */
    341 SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
    342 SCIP_CONS** setppcs, /**< active setppc constraints */
    343 int nsetppcs, /**< number of active setppc constraints */
    344 SCIP_CONS** logicors, /**< active logicor constraints */
    345 int nlogicors /**< number of active logicor constraints */
    346 )
    347{
    348 SCIP_CONS** usefulconss;
    349 int nusefulconss = 0;
    350 int size;
    351 int c;
    352
    353 assert(scip != NULL);
    354 assert(presoldata != NULL);
    355 assert(setppcs != NULL);
    356 assert(nsetppcs > 0);
    357 assert(logicors != NULL);
    358 assert(nlogicors > 0);
    359 assert(presoldata->setppchashtable != NULL);
    360 assert(presoldata->logicorhashtable != NULL);
    361
    362 presoldata->initialized = TRUE;
    363
    364 size = MAX(nsetppcs, nlogicors);
    365
    366 /* temporary memory for collecting set-packing constraints */
    367 SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, size) );
    368
    369 if( !presoldata->usefulsetppcexist )
    370 {
    371 /* find set-packing constraints with exactly two variables */
    372 for( c = 0; c < nsetppcs; ++c )
    373 {
    374 assert(SCIPconsIsActive(setppcs[c]));
    375
    376 if( !SCIPconsIsModifiable(setppcs[c]) && SCIPconsGetNUpgradeLocks(setppcs[c]) == 0
    378 && SCIPgetNVarsSetppc(scip, setppcs[c]) == 2 )
    379 {
    380 /* insert new element in hashtable */
    381 SCIP_CALL( SCIPhashtableInsert(presoldata->setppchashtable, (void*) setppcs[c]) );
    382
    383 usefulconss[nusefulconss] = setppcs[c];
    384 ++nusefulconss;
    385 }
    386 }
    387
    388 /* add usefulconss constraints to hashdata elements */
    389 if( nusefulconss > 0 )
    390 {
    391 SCIP_Bool negated[2];
    392 int h;
    393
    394 presoldata->usefulsetppcexist = TRUE;
    395 presoldata->ssetppchashdatas = nusefulconss;
    396
    397 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(presoldata->setppchashdatas), nusefulconss) );
    398
    399 h = 0;
    400 for( c = 0; c < nusefulconss; ++c )
    401 {
    402 SCIP_VAR** setppcvars = SCIPgetVarsSetppc(scip, usefulconss[c]);
    403 assert(SCIPconsIsActive(usefulconss[c]));
    404 assert(SCIPgetNVarsSetppc(scip, usefulconss[c]) == 2);
    405
    406 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(presoldata->setppchashdatas[h].vars), setppcvars, 2) );
    407
    408 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[h].vars[0], &(presoldata->setppchashdatas[h].vars[0]), &(negated[0])) );
    409 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[h].vars[1], &(presoldata->setppchashdatas[h].vars[1]), &(negated[1])) );
    410
    411 if( SCIPvarGetStatus(presoldata->setppchashdatas[h].vars[0]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[h].vars[0]) == SCIP_VARSTATUS_MULTAGGR
    412 || SCIPvarGetStatus(presoldata->setppchashdatas[h].vars[1]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[h].vars[1]) == SCIP_VARSTATUS_MULTAGGR )
    413 {
    414 SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[h].vars), 2);
    415 continue;
    416 }
    417
    418 presoldata->setppchashdatas[h].nvars = 2;
    419
    420 /* capture variables */
    421 SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[h].vars[0]) );
    422 SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[h].vars[1]) );
    423
    424 /* order the variables after their index */
    425 if( SCIPvarGetIndex(presoldata->setppchashdatas[h].vars[0]) > SCIPvarGetIndex(presoldata->setppchashdatas[h].vars[1]) )
    426 {
    427 SCIP_VAR* tmp = presoldata->setppchashdatas[h].vars[0];
    428 presoldata->setppchashdatas[h].vars[0] = presoldata->setppchashdatas[h].vars[1];
    429 presoldata->setppchashdatas[h].vars[1] = tmp;
    430 }
    431
    432 presoldata->setppchashdatas[h].cons = usefulconss[c];
    433
    434 SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[h]) );
    435 SCIP_CALL( SCIPcaptureCons(scip, usefulconss[c]) );
    436
    437 ++h;
    438 }
    439 presoldata->nsetppchashdatas = h;
    440
    441 if( presoldata->nsetppchashdatas > 0 )
    442 presoldata->newsetppchashdatas = TRUE;
    443 }
    444 }
    445
    446 nusefulconss = 0;
    447
    448 if( !presoldata->usefullogicorexist )
    449 {
    450 /* capture all logicor constraints */
    451 for( c = 0; c < nlogicors; ++c )
    452 {
    453 assert(SCIPconsIsActive(logicors[c]));
    454
    455 if( !SCIPconsIsModifiable(logicors[c]) && SCIPconsGetNUpgradeLocks(logicors[c]) == 0
    456 && SCIPgetNVarsLogicor(scip, logicors[c]) >= 3 )
    457 {
    458 /* insert new element in hashtable */
    459 SCIP_CALL( SCIPhashtableInsert(presoldata->logicorhashtable, (void*) logicors[c]) );
    460 SCIP_CALL( SCIPcaptureCons(scip, logicors[c]) );
    461
    462 usefulconss[nusefulconss] = logicors[c];
    463 ++nusefulconss;
    464
    465 /* update maximal entries in a logicor constraint */
    466 if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
    467 presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
    468 }
    469 }
    470
    471 /* no usefulconss constraints */
    472 if( nusefulconss > 0 )
    473 {
    474 presoldata->firstchangedlogicor = 0;
    475 presoldata->usefullogicorexist = TRUE;
    476 presoldata->susefullogicor = nusefulconss;
    477 presoldata->nusefullogicor = nusefulconss;
    478 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &presoldata->usefullogicor, usefulconss, presoldata->susefullogicor) );
    479 }
    480 }
    481
    482 /* free temporary memory */
    483 SCIPfreeBufferArray(scip, &usefulconss);
    484
    485 return SCIP_OKAY;
    486}
    487
    488
    489/** remove old setppchashdatas objects, so that the allocated memory will stay low */
    490static
    492 SCIP* scip, /**< SCIP data structure */
    493 SCIP_PRESOLDATA* presoldata /**< data object of presolver */
    494 )
    495{
    496 assert(scip != NULL);
    497 assert(presoldata != NULL);
    498
    499 if( presoldata->usefulsetppcexist )
    500 {
    501 int c;
    502
    503 assert(presoldata->setppchashdatas != NULL || presoldata->nsetppchashdatas == 0);
    504
    505 for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
    506 {
    507 SCIP_Bool removeentry = FALSE;
    508
    509 assert(presoldata->setppchashdatas[c].cons != NULL);
    510
    511 if( SCIPconsIsDeleted(presoldata->setppchashdatas[c].cons)
    512 || SCIPconsIsModifiable(presoldata->setppchashdatas[c].cons)
    513 || SCIPconsGetNUpgradeLocks(presoldata->setppchashdatas[c].cons) >= 1
    514 || SCIPgetTypeSetppc(scip, presoldata->setppchashdatas[c].cons) != SCIP_SETPPCTYPE_PACKING
    515 || SCIPgetNVarsSetppc(scip, presoldata->setppchashdatas[c].cons) != 2 )
    516 {
    517 removeentry = TRUE;
    518 }
    519 else
    520 {
    521 SCIP_VAR* vars[2];
    522 SCIP_Bool negated[2];
    523
    524 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[c].vars[0], &(vars[0]), &(negated[0])) );
    525 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[c].vars[1], &(vars[1]), &(negated[1])) );
    526
    529 || presoldata->setppchashdatas[c].vars[0] != vars[0] || presoldata->setppchashdatas[c].vars[1] != vars[1] )
    530 {
    531 removeentry = TRUE;
    532 }
    533 }
    534
    535 if( removeentry )
    536 {
    537 /* remove constraint from setppc-hashtable */
    538 assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c].cons));
    539 SCIP_CALL( SCIPhashtableRemove(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c].cons) );
    540
    541 /* remove hashdata entry from hashtable */
    542 SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[c]) );
    543
    544 /* release old constraints */
    545 SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->setppchashdatas[c].cons)) );
    546
    547 /* release variables */
    548 SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c].vars[0])) );
    549 SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c].vars[1])) );
    550
    551 /* free memory for variables */
    552 SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[c].vars), 2);
    553
    554 if( c < presoldata->nsetppchashdatas - 1 )
    555 {
    556 /* remove old hashdata entry from hashtable */
    557 SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1]) );
    558 }
    559
    560 /* move last content to free position */
    561 presoldata->setppchashdatas[c].cons = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1].cons;
    562 presoldata->setppchashdatas[c].vars = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1].vars;
    563 presoldata->setppchashdatas[c].nvars = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1].nvars;
    564
    565 if( c < presoldata->nsetppchashdatas - 1 )
    566 {
    567 /* add new hashdata entry from hashtable */
    568 SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[c]) );
    569 }
    570 --(presoldata->nsetppchashdatas);
    571 }
    572 }
    573
    574#ifndef NDEBUG
    575 for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
    576 {
    577 assert(presoldata->setppchashdatas[c].nvars == 2);
    578 assert(presoldata->setppchashdatas[c].vars != NULL);
    579 assert(presoldata->setppchashdatas[c].vars[0] != NULL);
    580 assert(presoldata->setppchashdatas[c].vars[1] != NULL);
    581 assert(presoldata->setppchashdatas[c].cons != NULL);
    582 assert(SCIPconsIsActive(presoldata->setppchashdatas[c].cons));
    583 assert(SCIPhashtableExists(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[c]));
    584 assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c].cons));
    585 }
    586#endif
    587 }
    588
    589 return SCIP_OKAY;
    590}
    591
    592/** refresh useful set-packing information, delete redundant constraints and add new constraints */
    593static
    595 SCIP* scip, /**< SCIP data structure */
    596 SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
    597 SCIP_CONS** setppcs, /**< active setppc constraints */
    598 int nsetppcs, /**< number of active setppc constraints */
    599 SCIP_CONS** logicors, /**< active setppc constraints */
    600 int nlogicors /**< number of active setppc constraints */
    601 )
    602{
    603 int oldnsetppchashdatas;
    604 int c;
    605
    606 assert(scip != NULL);
    607 assert(presoldata != NULL);
    608 assert(setppcs != NULL);
    609 assert(nsetppcs > 0);
    610 assert(logicors != NULL);
    611 assert(nlogicors > 0);
    612 assert(presoldata->initialized);
    613 assert(presoldata->setppchashtable != NULL);
    614 assert(presoldata->logicorhashtable != NULL);
    615
    616 /* check if there already exist some set-packing and some logicor constraints with the right amount of variables */
    617 if( !presoldata->usefulsetppcexist || !presoldata->usefullogicorexist )
    618 {
    619 SCIP_Bool usefullogicorexisted = presoldata->usefullogicorexist;
    620
    621 SCIP_CALL( createPresoldata(scip, presoldata, setppcs, nsetppcs, logicors, nlogicors) );
    622
    623 /* if we already had useful logicor constraints but did not find any useful setppc constraint, the maximal number
    624 * of variables appearing in a logicor constraint was not updated, so we do it here
    625 */
    626 if( usefullogicorexisted && !presoldata->usefulsetppcexist )
    627 {
    628 /* correct maximal number of varables in logicor constraints */
    629 for( c = nlogicors - 1; c >= 0; --c )
    630 {
    631 assert(SCIPconsIsActive(logicors[c]));
    632
    633 /* update maximal entries in a logicor constraint */
    634 if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
    635 presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
    636 }
    637 }
    638
    639 /* no correct logicor or set-packing constraints available, so abort */
    640 if( !presoldata->usefulsetppcexist || !presoldata->usefullogicorexist )
    641 return SCIP_OKAY;
    642 }
    643
    644 /* correct old data */
    645 SCIP_CALL( cleanupHashDatas(scip, presoldata) );
    646
    647 oldnsetppchashdatas = presoldata->nsetppchashdatas;
    648
    649 /* first update setppc part */
    650 /* add new setppc constraints */
    651 for( c = nsetppcs - 1; c >= 0; --c )
    652 {
    653 assert(SCIPconsIsActive(setppcs[c]));
    654
    655 if( !SCIPconsIsModifiable(setppcs[c]) && SCIPconsGetNUpgradeLocks(setppcs[c]) == 0
    657 && SCIPgetNVarsSetppc(scip, setppcs[c]) == 2 )
    658 {
    659 /* check if constraint is new, and correct array size if necessary */
    660 if( !SCIPhashtableExists(presoldata->setppchashtable, (void*) setppcs[c]) )
    661 {
    662 SCIP_VAR** setppcvars;
    663 SCIP_Bool negated[2];
    664
    665 /* resize array if necessary */
    666 if( presoldata->nsetppchashdatas == presoldata->ssetppchashdatas )
    667 {
    668 int newsize;
    669 int d;
    670
    671 newsize = SCIPcalcMemGrowSize(scip, presoldata->nsetppchashdatas + 1);
    672
    673 /* array already at maximal size */
    674 if( newsize <= presoldata->ssetppchashdatas )
    675 return SCIP_NOMEMORY;
    676
    677 /* correct hashtable, remove old elements */
    678 SCIPhashtableRemoveAll(presoldata->hashdatatable);
    679
    680 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(presoldata->setppchashdatas), presoldata->ssetppchashdatas, newsize) );
    681 presoldata->ssetppchashdatas = newsize;
    682
    683 /* add all elements to the hashtable again */
    684 for( d = presoldata->nsetppchashdatas - 1; d >= 0; --d )
    685 {
    686 SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[d]) );
    687 }
    688 }
    689
    690 /* insert new element in hashtable */
    691 SCIP_CALL( SCIPhashtableInsert(presoldata->setppchashtable, (void*) setppcs[c]) );
    692
    693 assert(SCIPgetNVarsSetppc(scip, setppcs[c]) == 2);
    694 setppcvars = SCIPgetVarsSetppc(scip, setppcs[c]);
    695
    696 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars), setppcvars, 2) );
    697 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0], &(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0]), &(negated[0])) );
    698 SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1], &(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1]), &(negated[1])) );
    699
    700 if( SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0]) == SCIP_VARSTATUS_MULTAGGR
    701 || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1]) == SCIP_VARSTATUS_MULTAGGR )
    702 {
    703 SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars), 2);
    704 continue;
    705 }
    706
    707 presoldata->setppchashdatas[presoldata->nsetppchashdatas].nvars = 2;
    708
    709 /* capture variables */
    710 SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0]) );
    711 SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1]) );
    712
    713 /* order the variables after their index */
    714 if( SCIPvarGetIndex(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0]) > SCIPvarGetIndex(presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1]) )
    715 {
    716 SCIP_VAR* tmp = presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0];
    717 presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[0] = presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1];
    718 presoldata->setppchashdatas[presoldata->nsetppchashdatas].vars[1] = tmp;
    719 }
    720
    721 presoldata->setppchashdatas[presoldata->nsetppchashdatas].cons = setppcs[c];
    722
    723 SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[presoldata->nsetppchashdatas]) );
    724 SCIP_CALL( SCIPcaptureCons(scip, setppcs[c]) );
    725
    726 ++(presoldata->nsetppchashdatas);
    727 }
    728 }
    729 }
    730
    731 /* if we found new set-packing constraints, we want to check against all logicors */
    732 if( oldnsetppchashdatas < presoldata->nsetppchashdatas )
    733 presoldata->newsetppchashdatas = TRUE;
    734
    735 /* now logicor part */
    736 /* removed last deleted logicor constraints from local presolver data */
    737 while( presoldata->nusefullogicor > 0 && !SCIPconsIsActive(presoldata->usefullogicor[presoldata->nusefullogicor - 1]) )
    738 {
    739 SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) presoldata->usefullogicor[presoldata->nusefullogicor - 1]) );
    740 SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[presoldata->nusefullogicor - 1])) );
    741
    742 --(presoldata->nusefullogicor);
    743 }
    744
    745 /* remove old inactive logicor constraints */
    746 for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
    747 {
    748 /* update maximal entries in a logicor constraint */
    749 if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]) )
    750 presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]);
    751
    752 if( !SCIPconsIsActive(presoldata->usefullogicor[c]) || SCIPconsIsModifiable(presoldata->usefullogicor[c])
    753 || SCIPconsGetNUpgradeLocks(presoldata->usefullogicor[c]) >= 1
    754 || SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]) < 3 )
    755 {
    756 SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) presoldata->usefullogicor[c]) );
    757 SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[c])) );
    758
    759 presoldata->usefullogicor[c] = presoldata->usefullogicor[presoldata->nusefullogicor - 1];
    760 --(presoldata->nusefullogicor);
    761 }
    762 }
    763
    764 presoldata->firstchangedlogicor = presoldata->nusefullogicor;
    765 assert(presoldata->firstchangedlogicor >= 0);
    766
    767 /* add new logicor constraints */
    768 for( c = nlogicors - 1; c >= 0; --c )
    769 {
    770 assert(SCIPconsIsActive(logicors[c]));
    771
    772 if( !SCIPconsIsModifiable(logicors[c]) && SCIPconsGetNUpgradeLocks(logicors[c]) == 0
    773 && SCIPgetNVarsLogicor(scip, logicors[c]) >= 3 )
    774 {
    775 /* check if constraint is new, and correct array size if necessary */
    776 if( !SCIPhashtableExists(presoldata->logicorhashtable, (void*) logicors[c]) )
    777 {
    778 /* resize array if necessary */
    779 if( presoldata->nusefullogicor == presoldata->susefullogicor )
    780 {
    781 int newsize;
    782
    783 newsize = SCIPcalcMemGrowSize(scip, presoldata->nusefullogicor + 1);
    784
    785 /* array already at maximal size */
    786 if( newsize <= presoldata->susefullogicor )
    787 return SCIP_NOMEMORY;
    788
    789 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(presoldata->usefullogicor), presoldata->susefullogicor, newsize) );
    790 presoldata->susefullogicor = newsize;
    791 }
    792
    793 /* insert new element in hashtable */
    794 SCIP_CALL( SCIPhashtableInsert(presoldata->logicorhashtable, (void*) logicors[c]) );
    795 SCIP_CALL( SCIPcaptureCons(scip, logicors[c]) );
    796
    797 presoldata->usefullogicor[presoldata->nusefullogicor] = logicors[c];
    798 ++(presoldata->nusefullogicor);
    799
    800 /* update maximal entries in a logicor constraint */
    801 if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
    802 presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
    803 }
    804 }
    805 }
    806
    807 return SCIP_OKAY;
    808}
    809
    810
    811/** extract and-constraints and set-partitioning constraints */
    812static
    814 SCIP* scip, /**< SCIP data structure */
    815 SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
    816 int pos, /**< position of logicor in usefullogicor array to presolve */
    817 SCIP_HASHMAP* varmap, /**< variable map mapping inactive variables to their active representation */
    818 SCIP_CONS** gateconss, /**< allocated memory for all gate-constraints */
    819 SCIP_VAR** activevars, /**< allocated memory for active variables */
    820 SCIP_VAR** posresultants, /**< allocated memory for all possible resultant variables */
    821 HASHDATA* hashdata, /**< allocated memory for a hashdata object */
    822 int* ndelconss, /**< pointer to store number of deleted constraints */
    823 int* naddconss /**< pointer to store number of added constraints */
    824 )
    825{
    826 SCIP_VAR** logicorvars;
    827 HASHDATA* hashmaphashdata;
    828 SCIP_CONS* logicor;
    829 SCIP_Bool negated;
    830 int ngateconss;
    831 int nlogicorvars;
    832 int nposresultants;
    833 int d;
    834 int v;
    835
    836 assert(scip != NULL);
    837 assert(presoldata != NULL);
    838 assert(0 <= pos && pos < presoldata->nusefullogicor);
    839 assert(gateconss != NULL);
    840 assert(activevars != NULL);
    841 assert(posresultants != NULL);
    842 assert(hashdata != NULL);
    843 assert(hashdata->vars != NULL);
    844 assert(hashdata->nvars == 2);
    845 assert(hashdata->cons == NULL);
    846 assert(ndelconss != NULL);
    847 assert(naddconss != NULL);
    848
    849 assert(presoldata->usefullogicor != NULL);
    850 logicor = presoldata->usefullogicor[pos];
    851 assert(logicor != NULL);
    852
    853 if( !SCIPconsIsActive(logicor) )
    854 return SCIP_OKAY;
    855
    856 assert(!SCIPconsIsModifiable(logicor));
    857
    858 nlogicorvars = SCIPgetNVarsLogicor(scip, logicor);
    859 assert(nlogicorvars >= 3 && nlogicorvars <= presoldata->maxnvarslogicor);
    860
    861 logicorvars = SCIPgetVarsLogicor(scip, logicor);
    862 assert(logicorvars != NULL);
    863
    864 nposresultants = 0;
    865
    866 /* get active logicor variables and determine all possible resultants */
    867 for( d = nlogicorvars - 1; d >= 0; --d )
    868 {
    869 /* do not work with fixed variables */
    870 if( SCIPvarGetLbLocal(logicorvars[d]) > 0.5 || SCIPvarGetUbLocal(logicorvars[d]) < 0.5 )
    871 return SCIP_OKAY;
    872
    873 activevars[d] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, logicorvars[d]);
    874
    875 if( activevars[d] == NULL )
    876 {
    877 SCIP_CALL( SCIPgetBinvarRepresentative(scip, logicorvars[d], &(activevars[d]), &negated) );
    878 SCIP_CALL( SCIPhashmapInsert(varmap, logicorvars[d], activevars[d]) );
    879 }
    880
    881 /* determine possible resultants a check if the other variables can appear in a set-packing constraint */
    882 if( SCIPvarIsNegated(activevars[d]) )
    883 {
    884 assert(SCIPvarIsActive(SCIPvarGetNegatedVar(activevars[d])));
    885
    886 if( SCIPvarGetNLocksDownType(SCIPvarGetNegatedVar(activevars[d]), SCIP_LOCKTYPE_MODEL) >= nlogicorvars - 1 )
    887 {
    888 posresultants[nposresultants] = activevars[d];
    889 ++nposresultants;
    890 }
    892 return SCIP_OKAY;
    893 }
    894 else
    895 {
    896 assert(SCIPvarIsActive(activevars[d]));
    897
    898 if( SCIPvarGetNLocksUpType(activevars[d], SCIP_LOCKTYPE_MODEL) >= nlogicorvars - 1 )
    899 {
    900 posresultants[nposresultants] = activevars[d];
    901 ++nposresultants;
    902 }
    903 else if( SCIPvarGetNLocksUpType(activevars[d], SCIP_LOCKTYPE_MODEL) == 0 )
    904 return SCIP_OKAY;
    905 }
    906 }
    907
    908 if( nposresultants == 0 )
    909 return SCIP_OKAY;
    910
    911 /* sort variables after indices */
    912 SCIPsortPtr((void**)activevars, SCIPvarComp, nlogicorvars);
    913
    914 /* check that we have really different variables, if not remove the constraint from the hashmap and the data
    915 * storage
    916 */
    917 for( d = nlogicorvars - 1; d > 0; --d )
    918 {
    919 if( SCIPvarGetIndex(activevars[d]) == SCIPvarGetIndex(activevars[d - 1]) )
    920 {
    921 assert(presoldata->usefullogicor[pos] == logicor);
    922
    923 SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) logicor) );
    924 SCIP_CALL( SCIPreleaseCons(scip, &logicor) );
    925
    926 presoldata->usefullogicor[pos] = presoldata->usefullogicor[presoldata->nusefullogicor - 1];
    927 --(presoldata->nusefullogicor);
    928
    929 return SCIP_OKAY;
    930 }
    931 }
    932
    933 ngateconss = 0;
    934
    935 for( d = nposresultants - 1; d >= 0; --d )
    936 {
    937 ngateconss = 0;
    938
    939 for( v = nlogicorvars - 1; v >= 0; --v )
    940 {
    941 if( activevars[v] == posresultants[d] )
    942 continue;
    943
    944 /* variables need to be sorted */
    945 if( SCIPvarCompare(posresultants[d], activevars[v]) > 0 )
    946 {
    947 hashdata->vars[0] = activevars[v];
    948 hashdata->vars[1] = posresultants[d];
    949 }
    950 else
    951 {
    952 hashdata->vars[0] = posresultants[d];
    953 hashdata->vars[1] = activevars[v];
    954 }
    955
    956 hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(presoldata->hashdatatable, (void*) hashdata);
    957
    958 if( hashmaphashdata != NULL && SCIPconsIsActive(hashmaphashdata->cons) )
    959 {
    960 gateconss[ngateconss] = hashmaphashdata->cons;
    961 ++ngateconss;
    962 }
    963 else
    964 break;
    965 }
    966 if( ngateconss == nlogicorvars - 1 )
    967 break;
    968 }
    969
    970 /* @todo, check for clique of all variables except the resultant */
    971 /* check if we have a set-partitioning 'gate' */
    972 if( ngateconss == nlogicorvars - 1 && nlogicorvars == 3 )
    973 {
    974 assert(d >= 0 && d < nposresultants);
    975 assert(ngateconss >= 2);
    976
    977 if( activevars[0] == posresultants[d] )
    978 {
    979 hashdata->vars[0] = activevars[1];
    980 hashdata->vars[1] = activevars[2];
    981 }
    982 else if( activevars[1] == posresultants[d] )
    983 {
    984 hashdata->vars[0] = activevars[0];
    985 hashdata->vars[1] = activevars[2];
    986 }
    987 else
    988 {
    989 assert(activevars[2] == posresultants[d]);
    990 hashdata->vars[0] = activevars[0];
    991 hashdata->vars[1] = activevars[1];
    992 }
    993
    994 hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(presoldata->hashdatatable, (void*) hashdata);
    995 assert(hashmaphashdata == NULL || hashmaphashdata->cons != NULL);
    996
    997 if( hashmaphashdata != NULL && SCIPconsIsActive(hashmaphashdata->cons) )
    998 {
    999 gateconss[ngateconss] = hashmaphashdata->cons;
    1000 ++ngateconss;
    1001 }
    1002 }
    1003
    1004 /* did we find enough (>= number of variables in logicor - 1) set-packing constraints for an upgrade to either
    1005 * an and-constraint or even a set-partitioning constraint
    1006 */
    1007 if( ngateconss == nlogicorvars || (ngateconss >= nlogicorvars - 1 && !presoldata->onlysetpart))
    1008 {
    1009 SCIP_CONS* newcons;
    1010 char name[SCIP_MAXSTRLEN];
    1011 SCIP_Bool initial;
    1013 SCIP_Bool enforce;
    1014 SCIP_Bool check;
    1015 SCIP_Bool propagate;
    1016 SCIP_Bool local;
    1017 SCIP_Bool modifiable;
    1018 SCIP_Bool dynamic;
    1019 SCIP_Bool removable;
    1020 SCIP_Bool stickingatnode;
    1021 int i;
    1022
    1023 assert(ngateconss <= nlogicorvars);
    1024 assert(d >= 0 && d < nposresultants);
    1025
    1026 initial = SCIPconsIsInitial(logicor);
    1027 separate = SCIPconsIsSeparated(logicor);
    1028 enforce = SCIPconsIsEnforced(logicor);
    1029 check = SCIPconsIsChecked(logicor);
    1030 propagate = SCIPconsIsPropagated(logicor);
    1031 local = SCIPconsIsLocal(logicor);
    1032 modifiable = SCIPconsIsModifiable(logicor);
    1033 dynamic = SCIPconsIsDynamic(logicor);
    1034 removable = SCIPconsIsRemovable(logicor);
    1035 stickingatnode = SCIPconsIsStickingAtNode(logicor);
    1036
    1037#ifdef SCIP_DEBUG
    1038 if( ngateconss == nlogicorvars )
    1039 {
    1040 SCIPdebugMsg(scip, "Following constraints form a set-partitioning constraint.\n");
    1041 }
    1042 else
    1043 {
    1044 SCIPdebugMsg(scip, "Following constraints form an and-constraint.\n");
    1045 }
    1046#endif
    1047
    1048 for( v = ngateconss - 1; v >= 0; --v )
    1049 {
    1050 assert(gateconss[v] != NULL);
    1051
    1052 initial |= SCIPconsIsInitial(gateconss[v]);
    1053 separate |= SCIPconsIsSeparated(gateconss[v]);
    1054 enforce |= SCIPconsIsEnforced(gateconss[v]);
    1055 check |= SCIPconsIsChecked(gateconss[v]);
    1056 propagate |= SCIPconsIsPropagated(gateconss[v]);
    1057 local &= SCIPconsIsLocal(gateconss[v]);
    1058 modifiable &= SCIPconsIsModifiable(gateconss[v]);
    1059 dynamic &= SCIPconsIsDynamic(gateconss[v]);
    1060 removable &= SCIPconsIsRemovable(gateconss[v]);
    1061 stickingatnode &= SCIPconsIsStickingAtNode(gateconss[v]);
    1062
    1063 SCIPdebugPrintCons(scip, gateconss[v], NULL);
    1064
    1065 SCIP_CALL( SCIPdelCons(scip, gateconss[v]) );
    1066 ++(*ndelconss);
    1067 }
    1068
    1069 SCIPdebugPrintCons(scip, logicor, NULL);
    1070
    1071 if( ngateconss == nlogicorvars - 1 )
    1072 {
    1073 SCIP_VAR** consvars;
    1074
    1075 assert(!presoldata->onlysetpart);
    1076
    1077 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, ngateconss) );
    1078 i = 0;
    1079
    1080 /* determine and operands */
    1081 for( v = nlogicorvars - 1; v >= 0; --v )
    1082 {
    1083 if( activevars[v] == posresultants[d] )
    1084 continue;
    1085
    1086 SCIP_CALL( SCIPgetNegatedVar(scip, activevars[v], &consvars[i]) );
    1087 ++i;
    1088 }
    1089 assert(i == ngateconss);
    1090
    1091 /* create and add "and" constraint for the extracted gate */
    1092 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "andgate_%d", presoldata->ngates);
    1093 SCIP_CALL( SCIPcreateConsAnd(scip, &newcons, name, posresultants[d], ngateconss, consvars,
    1094 initial, separate, enforce, check, propagate,
    1095 local, modifiable, dynamic, removable, stickingatnode) );
    1096
    1097 SCIPdebugMsg(scip, "-------------->\n");
    1098 SCIPdebugPrintCons(scip, newcons, NULL);
    1099 SCIP_CALL( SCIPaddCons(scip, newcons) );
    1100 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    1101
    1102 ++(*naddconss);
    1103 ++(presoldata->ngates);
    1104
    1105 SCIP_CALL( SCIPdelCons(scip, logicor) );
    1106 ++(*ndelconss);
    1107
    1108 SCIPfreeBufferArray(scip, &consvars);
    1109 }
    1110 else
    1111 {
    1112 assert(ngateconss == nlogicorvars);
    1113
    1114 /* create and add set-partitioning constraint */
    1115 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "setpart_%d", presoldata->ngates);
    1116 SCIP_CALL( SCIPcreateConsSetpart(scip, &newcons, name, nlogicorvars, activevars,
    1117 initial, separate, enforce, check, propagate,
    1118 local, modifiable, dynamic, removable, stickingatnode) );
    1119
    1120 SCIPdebugMsg(scip, "-------------->\n");
    1121 SCIPdebugPrintCons(scip, newcons, NULL);
    1122 SCIP_CALL( SCIPaddCons(scip, newcons) );
    1123 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    1124
    1125 ++(*naddconss);
    1126 ++(presoldata->ngates);
    1127
    1128 SCIP_CALL( SCIPdelCons(scip, logicor) );
    1129 ++(*ndelconss);
    1130 }
    1131 }
    1132
    1133 return SCIP_OKAY;
    1134}
    1135
    1136
    1137/*
    1138 * Callback methods of presolver
    1139 */
    1140
    1141
    1142/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    1143static
    1144SCIP_DECL_PRESOLCOPY(presolCopyGateextraction)
    1145{ /*lint --e{715}*/
    1146 assert(scip != NULL);
    1147 assert(presol != NULL);
    1148
    1150
    1151 /* call inclusion method of presolver */
    1153
    1154 return SCIP_OKAY;
    1155}
    1156
    1157
    1158/** destructor of presolver to free user data (called when SCIP is exiting) */
    1159static
    1160SCIP_DECL_PRESOLFREE(presolFreeGateextraction)
    1161{ /*lint --e{715}*/
    1162 SCIP_PRESOLDATA* presoldata;
    1163
    1164 /* free presolver data */
    1165 presoldata = SCIPpresolGetData(presol);
    1166 assert(presoldata != NULL);
    1167
    1168 if( presoldata->hashdatatable != NULL )
    1169 {
    1170 assert(presoldata->setppchashtable != NULL);
    1171 assert(presoldata->logicorhashtable != NULL);
    1172
    1173 SCIPhashtableFree(&(presoldata->logicorhashtable));
    1174 SCIPhashtableFree(&(presoldata->setppchashtable));
    1175 SCIPhashtableFree(&(presoldata->hashdatatable));
    1176 }
    1177
    1178 SCIPfreeBlockMemory(scip, &presoldata);
    1179 SCIPpresolSetData(presol, NULL);
    1180
    1181 return SCIP_OKAY;
    1182}
    1183
    1184
    1185/** deinitialization method of presolver (called before transformed problem is freed) */
    1186static
    1187SCIP_DECL_PRESOLEXIT(presolExitGateextraction)
    1188{ /*lint --e{715}*/
    1189 SCIP_PRESOLDATA* presoldata;
    1190 int c;
    1191
    1192 /* free presolver data */
    1193 presoldata = SCIPpresolGetData(presol);
    1194 assert(presoldata != NULL);
    1195
    1196 /* release old constraints */
    1197 for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
    1198 {
    1199 SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[c])) );
    1200 }
    1201
    1202 if( presoldata->usefullogicorexist )
    1203 {
    1204 SCIPfreeBlockMemoryArray(scip, &presoldata->usefullogicor, presoldata->susefullogicor);
    1205 }
    1206
    1207 if( presoldata->usefulsetppcexist )
    1208 {
    1209 assert(presoldata->setppchashdatas != NULL || presoldata->nsetppchashdatas == 0);
    1210 for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
    1211 {
    1212 assert(presoldata->setppchashdatas[c].cons != NULL);
    1213 assert(presoldata->setppchashdatas[c].vars != NULL);
    1214
    1215 /* remove constraint from setppc-hashtable */
    1216 assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c].cons));
    1217 SCIP_CALL( SCIPhashtableRemove(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c].cons) );
    1218
    1219 /* remove hashdata entry from hashtable */
    1220 SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) &presoldata->setppchashdatas[c]) );
    1221
    1222 /* release old constraints */
    1223 SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->setppchashdatas[c].cons)) );
    1224
    1225 /* release variables */
    1226 SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c].vars[0])) );
    1227 SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c].vars[1])) );
    1228
    1229 /* free memory for variables */
    1230 SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[c].vars), 2);
    1231 }
    1232
    1233 SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas), presoldata->ssetppchashdatas);
    1234 }
    1235
    1236 if( presoldata->hashdatatable != NULL )
    1237 {
    1238 assert(presoldata->setppchashtable != NULL);
    1239 assert(presoldata->logicorhashtable != NULL);
    1240
    1241 /* clear old hashtable entries */
    1242 SCIPhashtableRemoveAll(presoldata->hashdatatable);
    1243 SCIPhashtableRemoveAll(presoldata->setppchashtable);
    1244 SCIPhashtableRemoveAll(presoldata->logicorhashtable);
    1245 }
    1246
    1247 presoldata->nusefullogicor = 0;
    1248 presoldata->susefullogicor = 0;
    1249 presoldata->nsetppchashdatas = 0;
    1250 presoldata->ssetppchashdatas = 0;
    1251 presoldata->firstchangedlogicor = -1;
    1252 presoldata->ngates = 0;
    1253 presoldata->usefullogicorexist = FALSE;
    1254 presoldata->usefulsetppcexist = FALSE;
    1255 presoldata->newsetppchashdatas = FALSE;
    1256 presoldata->initialized = FALSE;
    1257
    1258 return SCIP_OKAY;
    1259}
    1260
    1261
    1262/** presolving initialization method of presolver (called when presolving is about to begin) */
    1263static
    1264SCIP_DECL_PRESOLINITPRE(presolInitpreGateextraction)
    1265{ /*lint --e{715}*/
    1266 return SCIP_OKAY;
    1267}
    1268
    1269
    1270/** presolving deinitialization method of presolver (called after presolving has been finished) */
    1271static
    1272SCIP_DECL_PRESOLEXITPRE(presolExitpreGateextraction)
    1273{ /*lint --e{715}*/
    1274 return SCIP_OKAY;
    1275}
    1276
    1277
    1278/** execution method of presolver */
    1279static
    1280SCIP_DECL_PRESOLEXEC(presolExecGateextraction)
    1281{ /*lint --e{715}*/
    1282 SCIP_PRESOLDATA* presoldata;
    1283 SCIP_HASHMAP* varmap;
    1284 HASHDATA hashdata;
    1285 SCIP_VAR* tmpvars[2];
    1286 SCIP_CONSHDLR* conshdlrsetppc;
    1287 SCIP_CONSHDLR* conshdlrlogicor;
    1288 SCIP_CONSHDLR* conshdlrand;
    1289 SCIP_CONS** setppcconss;
    1290 SCIP_CONS** logicorconss;
    1291 int nsetppcconss;
    1292 int nlogicorconss;
    1293 int size;
    1294 int c;
    1295 SCIP_Bool paramvalue;
    1296
    1297 assert(scip != NULL);
    1298 assert(presol != NULL);
    1299 assert(result != NULL);
    1300
    1302
    1303 *result = SCIP_DIDNOTRUN;
    1304
    1305#ifdef SCIP_DISABLED_CODE
    1306 /* need to include cons_knapsack on top of this file */
    1307 /* check for possible knapsacks that form with a logicor a weak relaxation of an and-constraint
    1308 *
    1309 * the weak relaxation of an and-constraint looks like:
    1310 * - row1: resvar - v1 - ... - vn >= 1-n
    1311 * - row2: n*resvar - v1 - ... - vn <= 0.0
    1312 *
    1313 * which look like the following contraints
    1314 * - logicor: resvar + ~v1 + ... + ~vn >= 1
    1315 * - knapsack: n*resvar + ~v1 + ... + ~vn <= n
    1316 */
    1317 {
    1318 SCIP_CONSHDLR* conshdlrknapsack;
    1319 SCIP_CONS** knapsackconss;
    1320 int nknapsackconss;
    1321 SCIP_Longint* vals;
    1322 SCIP_Longint capacity;
    1323 int nvars;
    1324
    1325 conshdlrknapsack = SCIPfindConshdlr(scip, "knapsack");
    1326
    1327 /* get number of active constraints */
    1328 knapsackconss = SCIPconshdlrGetConss(conshdlrknapsack);
    1329 nknapsackconss = SCIPconshdlrGetNActiveConss(conshdlrknapsack);
    1330 assert(nknapsackconss >= 0);
    1331 assert(knapsackconss != NULL || nknapsackconss == 0);
    1332
    1333 for( c = nknapsackconss - 1; c >= 0; --c )
    1334 {
    1335 /* not implemented in master branch, but the constraint may be already sorted */
    1336 /*SCIPsortKnapsack(scip, knapsackconss[c]);*/
    1337
    1338 nvars = SCIPgetNVarsKnapsack(scip, knapsackconss[c]);
    1339 vals = SCIPgetWeightsKnapsack(scip, knapsackconss[c]);
    1340 capacity = SCIPgetCapacityKnapsack(scip, knapsackconss[c]);
    1341
    1342 if( nvars > 1 && capacity == nvars - 1 && vals[0] == capacity && vals[1] == 1 )
    1343 {
    1344 printf("possible knapsack for gate extraction\n");
    1345 }
    1346 }
    1347 }
    1348#endif
    1349
    1350 /* get necessary constraint handlers */
    1351 conshdlrsetppc = SCIPfindConshdlr(scip, "setppc");
    1352 conshdlrlogicor = SCIPfindConshdlr(scip, "logicor");
    1353
    1354 if( conshdlrsetppc == NULL || conshdlrlogicor == NULL )
    1355 return SCIP_OKAY;
    1356
    1357 /* get number of active constraints */
    1358 nsetppcconss = SCIPconshdlrGetNActiveConss(conshdlrsetppc);
    1359 assert(nsetppcconss >= 0);
    1360 nlogicorconss = SCIPconshdlrGetNActiveConss(conshdlrlogicor);
    1361 assert(nlogicorconss >= 0);
    1362
    1363 if( nsetppcconss == 0 || nlogicorconss == 0 )
    1364 return SCIP_OKAY;
    1365
    1366 /* get presolver data */
    1367 presoldata = SCIPpresolGetData(presol);
    1368 assert(presoldata != NULL);
    1369
    1370 conshdlrand = SCIPfindConshdlr(scip, "and");
    1371
    1372 /* need and-constraint handler to extract and-gates */
    1373 if( conshdlrand == NULL )
    1374 {
    1375 /* nothing to do when we cannot extract anything */
    1376 if( !presoldata->searchequations )
    1377 return SCIP_OKAY;
    1378 else
    1379 {
    1380 /* make sure that we correct the parameter for only extrating set-partitioning constraints */
    1381 if( SCIPisParamFixed(scip, "presolving/" PRESOL_NAME "/onlysetpart") )
    1382 {
    1383 SCIPwarningMessage(scip, "unfixing parameter <presolving/" PRESOL_NAME "/onlysetpart> in gate extration presolver\n");
    1384 SCIP_CALL( SCIPunfixParam(scip, "presolving/" PRESOL_NAME "/onlysetpart") );
    1385 }
    1386 SCIP_CALL( SCIPsetBoolParam(scip, "presolving/" PRESOL_NAME "/onlysetpart", TRUE) );
    1387 assert(presoldata->onlysetpart);
    1388 }
    1389 }
    1390
    1391 paramvalue = FALSE;
    1392 if( conshdlrand != NULL && SCIPgetBoolParam(scip, "constraints/and/linearize", &paramvalue) == SCIP_OKAY )
    1393 {
    1394 if( paramvalue )
    1395 {
    1396 SCIPwarningMessage(scip, "Gate-presolving is the 'counterpart' of linearizing all and-constraints, so enabling both presolving steps simultaneously does not make sense.\n");
    1397 }
    1398 }
    1399 *result = SCIP_DIDNOTFIND;
    1400
    1401 /* get active constraints */
    1402 SCIP_CALL( SCIPduplicateBufferArray(scip, &setppcconss, SCIPconshdlrGetConss(conshdlrsetppc), nsetppcconss) ); /*lint !e666*/
    1403
    1404 assert(setppcconss != NULL);
    1405 logicorconss = SCIPconshdlrGetConss(conshdlrlogicor);
    1406 assert(logicorconss != NULL);
    1407
    1408 /* first we need to initialized the hashtables if not yet done */
    1409 if( presoldata->hashdatatable == NULL )
    1410 {
    1411 SCIP_CALL( presoldataInitHashtables(scip, presoldata) );
    1412 }
    1413 assert(presoldata->hashdatatable != NULL);
    1414 assert(presoldata->setppchashtable != NULL);
    1415 assert(presoldata->logicorhashtable != NULL);
    1416
    1417 presoldata->newsetppchashdatas = FALSE;
    1418
    1419 if( !presoldata->initialized )
    1420 {
    1421 assert(presoldata->usefullogicor == NULL);
    1422
    1423 /* create useful set-packing information by adding new set-packing constraints with two variables */
    1424 SCIP_CALL( createPresoldata(scip, presoldata, setppcconss, nsetppcconss, logicorconss, nlogicorconss) );
    1425 }
    1426 else
    1427 {
    1428 /* refresh useful set-packing information, delete redundant constraints and add new constraints */
    1429 SCIP_CALL( correctPresoldata(scip, presoldata, setppcconss, nsetppcconss, logicorconss, nlogicorconss) );
    1430 }
    1431 assert(presoldata->initialized);
    1432
    1433 if( presoldata->nusefullogicor == 0 )
    1434 goto TERMINATE;
    1435
    1436 /* move the biggate extraction to front or back by sort the logicors after number of variables */
    1437
    1438 if( presoldata->sorting != 0 )
    1439 {
    1440 int* lengths;
    1441
    1442 SCIP_CALL( SCIPallocBufferArray(scip, &lengths, presoldata->nusefullogicor) );
    1443
    1444 for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
    1445 {
    1446 lengths[c] = SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]);
    1447 }
    1448
    1449 if( presoldata->sorting == -1 )
    1450 SCIPsortDownIntPtr(lengths, (void**)presoldata->usefullogicor, presoldata->nusefullogicor);
    1451 else
    1452 SCIPsortIntPtr(lengths, (void**)presoldata->usefullogicor, presoldata->nusefullogicor);
    1453
    1454 SCIPfreeBufferArray(scip, &lengths);
    1455 }
    1456
    1457 /* maximal number of binary variables */
    1459
    1460 /* create the variable mapping hash map */
    1461 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(scip), size) );
    1462
    1463 /* search for set-partitioning constraints arising from a logicor and a set-packing constraints with equal variables */
    1464 if( presoldata->searchequations && !SCIPisStopped(scip) )
    1465 {
    1466 SCIP_HASHTABLE* setppchashdatatable;
    1467 HASHDATA** setppchashdatas;
    1468 HASHDATA* setppchashdatastore;
    1469 HASHDATA* hashmaphashdata;
    1470 SCIP_CONS* logicor;
    1471 SCIP_CONS* setppc;
    1472 SCIP_VAR** logicorvars;
    1473 SCIP_VAR** setppcvars;
    1474 SCIP_VAR** activevarslogicor;
    1475 SCIP_VAR** activevarssetppc;
    1476 SCIP_Bool negated;
    1477 int nsetppchashdatas;
    1478 int nlogicorvars;
    1479 int nsetppcvars;
    1480 int d;
    1481 int v;
    1482
    1483 assert(nsetppcconss > 0);
    1484
    1485 /* create local hashtable */
    1486 SCIP_CALL( SCIPhashtableCreate(&setppchashdatatable, SCIPblkmem(scip), nsetppcconss, SCIPhashGetKeyStandard, setppcHashdataKeyEqCons, setppcHashdataKeyValCons, (void*) scip) );
    1487
    1488 /* maximal number of binary variables */
    1489 size = presoldata->maxnvarslogicor;
    1490 assert(size >= 3);
    1491
    1492 /* get temporary memory */
    1493 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &setppchashdatastore, nsetppcconss) );
    1494 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &setppchashdatas, nsetppcconss) );
    1495 SCIP_CALL( SCIPallocBufferArray(scip, &activevarssetppc, size) );
    1496 SCIP_CALL( SCIPallocBufferArray(scip, &activevarslogicor, size) );
    1497
    1498 hashdata.cons = NULL;
    1499
    1500 nsetppchashdatas = 0;
    1501
    1502 /* collect all set-packing/-partitioning constraints and corresponding data to be able to search faster */
    1503 for( d = nsetppcconss - 1; d >= 0; --d )
    1504 {
    1505 setppc = setppcconss[d];
    1506 assert(setppc != NULL);
    1507
    1508 if( SCIPconsIsDeleted(setppc) || SCIPconsIsModifiable(setppc) || SCIPconsGetNUpgradeLocks(setppc) >= 1 )
    1509 continue;
    1510
    1511 /* @todo if of interest could also be implemented for set-covering constraints */
    1512#if 1
    1514 continue;
    1515#endif
    1516
    1517 nsetppcvars = SCIPgetNVarsSetppc(scip, setppc);
    1518
    1519 /* to big setppc constraints are picked out */
    1520 if( nsetppcvars < 2 || nsetppcvars > size )
    1521 continue;
    1522
    1523 setppcvars = SCIPgetVarsSetppc(scip, setppc);
    1524 assert(setppcvars != NULL);
    1525
    1526 /* get active setppc variables */
    1527 for( v = nsetppcvars - 1; v >= 0; --v )
    1528 {
    1529 /* do not work with fixed variables */
    1530 if( SCIPvarGetLbLocal(setppcvars[v]) > 0.5 || SCIPvarGetUbLocal(setppcvars[v]) < 0.5 )
    1531 break;
    1532
    1533 activevarssetppc[v] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, setppcvars[v]);
    1534
    1535 if( activevarssetppc[v] == NULL )
    1536 {
    1537 SCIP_CALL( SCIPgetBinvarRepresentative(scip, setppcvars[v], &(activevarssetppc[v]), &negated) );
    1538 SCIP_CALL( SCIPhashmapInsert(varmap, setppcvars[v], activevarssetppc[v]) );
    1539 }
    1540 }
    1541
    1542 /* if we found a fixed variable we want disregard this constraint */
    1543 if( v >= 0 )
    1544 continue;
    1545
    1546 /* variables need to be sorted after indices to be able to do a fast comparison */
    1547 SCIPsortPtr((void**)activevarssetppc, SCIPvarComp, nsetppcvars);
    1548
    1549 setppchashdatas[nsetppchashdatas] = &(setppchashdatastore[nsetppchashdatas]);
    1550
    1551 /* memorize set-packing data */
    1552 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(setppchashdatas[nsetppchashdatas]->vars), activevarssetppc, nsetppcvars) );
    1553
    1554 setppchashdatas[nsetppchashdatas]->nvars = nsetppcvars;
    1555 setppchashdatas[nsetppchashdatas]->cons = setppc;
    1556 /* need to capture this constraint, because it might get deleted during the process */
    1557 SCIP_CALL( SCIPcaptureCons(scip, setppc) );
    1558
    1559 /* add entry to local hashtable */
    1560 SCIP_CALL( SCIPhashtableInsert(setppchashdatatable, (void*) setppchashdatas[nsetppchashdatas]) );
    1561 ++nsetppchashdatas;
    1562 }
    1563
    1564 /* check all (new) logicors against all collected set-packing/-partitioning constraints */
    1565 for( c = nlogicorconss - 1; c >= 0 && !SCIPisStopped(scip); --c )
    1566 {
    1567 logicor = logicorconss[c];
    1568 assert(logicor != NULL);
    1569
    1570 if( SCIPconsIsDeleted(logicor) || SCIPconsIsModifiable(logicor) || SCIPconsGetNUpgradeLocks(logicor) >= 1 )
    1571 continue;
    1572
    1573 nlogicorvars = SCIPgetNVarsLogicor(scip, logicor);
    1574
    1575 if( nlogicorvars < 2 )
    1576 continue;
    1577
    1578 assert(nlogicorvars <= size);
    1579
    1580 logicorvars = SCIPgetVarsLogicor(scip, logicor);
    1581 assert(logicorvars != NULL);
    1582
    1583 /* get active logicor variables */
    1584 for( v = nlogicorvars - 1; v >= 0; --v )
    1585 {
    1586 /* do not work with fixed variables */
    1587 if( SCIPvarGetLbLocal(logicorvars[v]) > 0.5 || SCIPvarGetUbLocal(logicorvars[v]) < 0.5 )
    1588 break;
    1589
    1590 activevarslogicor[v] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, logicorvars[v]);
    1591
    1592 /* if image does not exist, then there is no corresponding set-packing constraint */
    1593 if( activevarslogicor[v] == NULL )
    1594 break;
    1595 }
    1596
    1597 if( v == -1 )
    1598 {
    1599 /* need sorting to be able to find the correct hashdata element */
    1600 SCIPsortPtr((void**)activevarslogicor, SCIPvarComp, nlogicorvars);
    1601
    1602 hashdata.nvars = nlogicorvars;
    1603 hashdata.vars = activevarslogicor;
    1604
    1605 hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(setppchashdatatable, (void*) &hashdata);
    1606 assert(hashmaphashdata == NULL || hashmaphashdata->cons != NULL);
    1607
    1608 if( hashmaphashdata != NULL && !SCIPconsIsDeleted(hashmaphashdata->cons) )
    1609 {
    1610 SCIP_Bool initial;
    1612 SCIP_Bool enforce;
    1613 SCIP_Bool check;
    1614 SCIP_Bool propagate;
    1615 SCIP_Bool local;
    1616 SCIP_Bool modifiable;
    1617 SCIP_Bool dynamic;
    1618 SCIP_Bool removable;
    1619 SCIP_Bool stickingatnode;
    1620
    1621 setppc = hashmaphashdata->cons;
    1622 assert(SCIPconsGetHdlr(setppc) == SCIPfindConshdlr(scip, "setppc"));
    1623
    1624 initial = SCIPconsIsInitial(logicor) || SCIPconsIsInitial(setppc);
    1625 separate = SCIPconsIsSeparated(logicor) || SCIPconsIsSeparated(setppc);
    1626 enforce = SCIPconsIsEnforced(logicor) || SCIPconsIsEnforced(setppc);
    1627 check = SCIPconsIsChecked(logicor) || SCIPconsIsChecked(setppc);
    1628 propagate = SCIPconsIsPropagated(logicor) || SCIPconsIsPropagated(setppc);
    1629 local = SCIPconsIsLocal(logicor) && SCIPconsIsLocal(setppc);
    1630 modifiable = SCIPconsIsModifiable(logicor) && SCIPconsIsModifiable(setppc);
    1631 dynamic = SCIPconsIsDynamic(logicor) && SCIPconsIsDynamic(setppc);
    1632 removable = SCIPconsIsRemovable(logicor) && SCIPconsIsRemovable(setppc);
    1633 stickingatnode = SCIPconsIsStickingAtNode(logicor) && SCIPconsIsStickingAtNode(setppc);
    1634
    1635 /* check if logicor is redundant against a set-partitioning constraint */
    1637 {
    1638 SCIP_CALL( SCIPsetConsInitial(scip, setppc, initial) );
    1640 SCIP_CALL( SCIPsetConsEnforced(scip, setppc, enforce) );
    1641 SCIP_CALL( SCIPsetConsChecked(scip, setppc, check) );
    1642 SCIP_CALL( SCIPsetConsPropagated(scip, setppc, propagate) );
    1643 SCIP_CALL( SCIPsetConsLocal(scip, setppc, local) );
    1644 SCIP_CALL( SCIPsetConsModifiable(scip, setppc, modifiable) );
    1645 SCIP_CALL( SCIPsetConsDynamic(scip, setppc, dynamic) );
    1646 SCIP_CALL( SCIPsetConsRemovable(scip, setppc, removable) );
    1647 SCIP_CALL( SCIPsetConsStickingAtNode(scip, setppc, stickingatnode) );
    1648
    1649 SCIPdebugMsg(scip, "Following logicor is redundant to the set-partitioning constraint.\n");
    1650 SCIPdebugPrintCons(scip, logicor, NULL);
    1651 SCIPdebugPrintCons(scip, setppc, NULL);
    1652 }
    1653 else
    1654 {
    1655 SCIP_CONS* newcons;
    1656 char name[SCIP_MAXSTRLEN];
    1657
    1659
    1660 SCIPdebugMsg(scip, "Following logicor and set-packing constraints form a set-partitioning constraint.\n");
    1661 SCIPdebugPrintCons(scip, logicor, NULL);
    1662 SCIPdebugPrintCons(scip, setppc, NULL);
    1663
    1664 /* create and add set-partitioning constraint */
    1665 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "setpart_%d", presoldata->ngates);
    1666 SCIP_CALL( SCIPcreateConsSetpart(scip, &newcons, name, nlogicorvars, activevarslogicor,
    1667 initial, separate, enforce, check, propagate,
    1668 local, modifiable, dynamic, removable, stickingatnode) );
    1669
    1670 SCIPdebugMsg(scip, "-------------->\n");
    1671 SCIPdebugPrintCons(scip, newcons, NULL);
    1672 SCIP_CALL( SCIPaddCons(scip, newcons) );
    1673 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
    1674
    1675 ++(*naddconss);
    1676 ++(presoldata->ngates);
    1677
    1678 /* delete redundant set-packing constraint */
    1679 SCIP_CALL( SCIPdelCons(scip, setppc) );
    1680 ++(*ndelconss);
    1681 }
    1682
    1683 /* delete redundant logicor constraint */
    1684 SCIP_CALL( SCIPdelCons(scip, logicor) );
    1685 ++(*ndelconss);
    1686 }
    1687 }
    1688 }
    1689
    1690 /* need to clear/release parts of hashdata objects */
    1691 for( d = nsetppchashdatas - 1; d >= 0; --d )
    1692 {
    1693 /* need to release captured constraint */
    1694 SCIP_CALL( SCIPreleaseCons(scip, &(setppchashdatas[d]->cons)) );
    1695 /* need to free copied memory */
    1696 SCIPfreeBlockMemoryArray(scip, &(setppchashdatas[d]->vars), setppchashdatas[d]->nvars);
    1697 }
    1698
    1699 /* delete local hashtable */
    1700 SCIPhashtableFree(&setppchashdatatable);
    1701
    1702 /* free all temporary memory */
    1703 SCIPfreeBufferArray(scip, &activevarslogicor);
    1704 SCIPfreeBufferArray(scip, &activevarssetppc);
    1705 SCIPfreeBlockMemoryArray(scip, &setppchashdatas, nsetppcconss);
    1706 SCIPfreeBlockMemoryArray(scip, &setppchashdatastore, nsetppcconss);
    1707 }
    1708
    1709 /* we do not have any useful set-packing or logicor constraint, or since last run did not get any new constraints, so abort */
    1710 if( presoldata->nsetppchashdatas == 0 || (presoldata->firstchangedlogicor == presoldata->nusefullogicor && !presoldata->newsetppchashdatas) )
    1711 {
    1712 SCIPhashmapFree(&varmap);
    1713 goto TERMINATE;
    1714 }
    1715
    1716 assert(presoldata->usefullogicor != NULL);
    1717 assert(presoldata->nusefullogicor > 0);
    1718 assert(presoldata->firstchangedlogicor >= 0);
    1719 assert(presoldata->nsetppchashdatas > 0);
    1720
    1721 /* search for gates */
    1722 if( presoldata->nsetppchashdatas > 0 && !SCIPisStopped(scip) )
    1723 {
    1724 SCIP_CONS** gateconss;
    1725 SCIP_VAR** activevars;
    1726 SCIP_VAR** posresultants;
    1727 int endloop;
    1728
    1729 /* if we found new setppcs we want to check all logicors again */
    1730 if( presoldata->newsetppchashdatas )
    1731 endloop = 0;
    1732 else
    1733 endloop = MAX(presoldata->firstchangedlogicor, 0);
    1734
    1735 assert(presoldata->maxnvarslogicor >= 3);
    1736 SCIP_CALL( SCIPallocBufferArray(scip, &gateconss, presoldata->maxnvarslogicor) );
    1737 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, presoldata->maxnvarslogicor) );
    1738 SCIP_CALL( SCIPallocBufferArray(scip, &posresultants, presoldata->maxnvarslogicor) );
    1739
    1740 hashdata.nvars = 2;
    1741 hashdata.cons = NULL;
    1742 /* assign array of two variables as temporary storage to hashdata */
    1743 hashdata.vars = tmpvars;
    1744
    1745 /* check all (new) logicors against all set-packing constraints, to extract and-constraints with two or more
    1746 * operands or set-partitioning constraints three or more variables
    1747 */
    1748 for( c = presoldata->nusefullogicor - 1; c >= endloop && !SCIPisStopped(scip); --c )
    1749 {
    1750 assert(presoldata->usefullogicor[c] != NULL);
    1751
    1752 /* logicor constraint has the form: x + y + z >= 1
    1753 *
    1754 * find set-packing constraints: (~x + ~y >= 1 and ~x + ~z >= 1) <=> (x + y <= 1 and x + z <= 1)
    1755 *
    1756 * - these three constraints are equivalent to: x = ~y * ~z (x = AND(~y,~z))
    1757 *
    1758 * if an additional set-packing constraint exists: y + z <= 1
    1759 *
    1760 * - these four constraints are equivalent to: x + y + z = 1
    1761 */
    1762 SCIP_CALL( extractGates(scip, presoldata, c, varmap, gateconss, activevars, posresultants, &hashdata, ndelconss, naddconss) );
    1763 }
    1764
    1765 SCIPfreeBufferArray(scip, &posresultants);
    1766 SCIPfreeBufferArray(scip, &activevars);
    1767 SCIPfreeBufferArray(scip, &gateconss);
    1768 }
    1769
    1770 SCIPhashmapFree(&varmap);
    1771
    1772 TERMINATE:
    1773 SCIPfreeBufferArray(scip, &setppcconss);
    1774
    1775 /* remove old setppchashdatas objects */
    1776 SCIP_CALL( cleanupHashDatas(scip, presoldata) );
    1777
    1778 return SCIP_OKAY;
    1779}
    1780
    1781
    1782/*
    1783 * presolver specific interface methods
    1784 */
    1785
    1786/** creates the gateextraction presolver and includes it in SCIP */
    1788 SCIP* scip /**< SCIP data structure */
    1789 )
    1790{
    1791 SCIP_PRESOLDATA* presoldata;
    1792 SCIP_PRESOL* presol;
    1793
    1794 /* alloc presolve data object */
    1795 SCIP_CALL( SCIPallocBlockMemory(scip, &presoldata) );
    1796
    1797 /* initialize gateextraction presolver data */
    1798 presoldataInit(presoldata);
    1799
    1800 /* include presolver */
    1802 PRESOL_TIMING, presolExecGateextraction, presoldata) );
    1803
    1804 SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyGateextraction) );
    1805 SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeGateextraction) );
    1806 SCIP_CALL( SCIPsetPresolExit(scip, presol, presolExitGateextraction) );
    1807 SCIP_CALL( SCIPsetPresolInitpre(scip, presol, presolInitpreGateextraction) );
    1808 SCIP_CALL( SCIPsetPresolExitpre(scip, presol, presolExitpreGateextraction) );
    1809
    1810 /* add gateextraction presolver parameters */
    1812 "presolving/" PRESOL_NAME "/onlysetpart",
    1813 "should we only try to extract set-partitioning constraints and no and-constraints",
    1814 &presoldata->onlysetpart, TRUE, DEFAULT_ONLYSETPART, NULL, NULL) );
    1815
    1816 /* add gateextraction presolver parameters */
    1818 "presolving/" PRESOL_NAME "/searchequations",
    1819 "should we try to extract set-partitioning constraint out of one logicor and one corresponding set-packing constraint",
    1820 &presoldata->searchequations, TRUE, DEFAULT_SEARCHEQUATIONS, NULL, NULL) );
    1821
    1822 /* add gateextraction presolver parameters */
    1824 "presolving/" PRESOL_NAME "/sorting",
    1825 "order logicor contraints to extract big-gates before smaller ones (-1), do not order them (0) or order them to extract smaller gates at first (1)",
    1826 &presoldata->sorting, TRUE, DEFAULT_SORTING, -1, 1, NULL, NULL) );
    1827
    1828 return SCIP_OKAY;
    1829}
    SCIP_VAR * h
    Definition: circlepacking.c:68
    Constraint handler for AND constraints, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    Constraint handler for the set partitioning / packing / covering constraints .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL(x)
    Definition: def.h:364
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_and.c:5059
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9683
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9701
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9719
    SCIP_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_setppc.c:9493
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    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 SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2647
    #define SCIPhashFour(a, b, c, d)
    Definition: pub_misc.h:573
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
    Definition: misc.c:2743
    SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2665
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
    Definition: scip_param.c:219
    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 SCIPunfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:385
    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 SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
    Definition: scip_param.c:429
    SCIP_RETCODE SCIPincludePresolGateextraction(SCIP *scip)
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4816
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4739
    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 SCIPsetConsStickingAtNode(SCIP *scip, SCIP_CONS *cons, SCIP_Bool stickingatnode)
    Definition: scip_cons.c:1499
    int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
    Definition: cons.c:8845
    SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
    Definition: scip_cons.c:1296
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8592
    SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8522
    SCIP_RETCODE SCIPsetConsDynamic(SCIP *scip, SCIP_CONS *cons, SCIP_Bool dynamic)
    Definition: scip_cons.c:1449
    SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
    Definition: scip_cons.c:1271
    SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
    Definition: scip_cons.c:1321
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8582
    SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
    Definition: cons.c:8454
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8612
    SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
    Definition: cons.c:8632
    SCIP_RETCODE SCIPsetConsModifiable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool modifiable)
    Definition: scip_cons.c:1424
    SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
    Definition: scip_cons.c:1474
    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_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
    Definition: cons.c:8672
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
    Definition: scip_cons.c:1371
    SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
    Definition: scip_cons.c:1346
    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
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #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 SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
    Definition: presol.c:538
    SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
    Definition: presol.c:528
    SCIP_RETCODE SCIPsetPresolExitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXITPRE((*presolexitpre)))
    Definition: scip_presol.c:228
    SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
    Definition: scip_presol.c:164
    SCIP_RETCODE SCIPsetPresolExit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
    Definition: scip_presol.c:196
    SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
    Definition: scip_presol.c:148
    SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
    Definition: scip_presol.c:113
    SCIP_RETCODE SCIPsetPresolInitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINITPRE((*presolinitpre)))
    Definition: scip_presol.c:212
    const char * SCIPpresolGetName(SCIP_PRESOL *presol)
    Definition: presol.c:625
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4380
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    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
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23475
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17319
    SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
    Definition: scip_var.c:2236
    int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
    Definition: var.c:4322
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    void SCIPsortPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    void SCIPsortDownIntPtr(int *intarray, void **ptrarray, int len)
    void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    memory allocation routines
    static SCIP_RETCODE cleanupHashDatas(SCIP *scip, SCIP_PRESOLDATA *presoldata)
    #define PRESOL_NAME
    #define DEFAULT_ONLYSETPART
    static SCIP_RETCODE extractGates(SCIP *scip, SCIP_PRESOLDATA *presoldata, int pos, SCIP_HASHMAP *varmap, SCIP_CONS **gateconss, SCIP_VAR **activevars, SCIP_VAR **posresultants, HASHDATA *hashdata, int *ndelconss, int *naddconss)
    static SCIP_DECL_PRESOLCOPY(presolCopyGateextraction)
    static SCIP_DECL_HASHKEYEQ(hashdataKeyEqCons)
    #define HASHSIZE_SETPPCCONS
    static SCIP_DECL_HASHKEYVAL(hashdataKeyValCons)
    static SCIP_RETCODE presoldataInitHashtables(SCIP *scip, SCIP_PRESOLDATA *presoldata)
    static SCIP_RETCODE createPresoldata(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_CONS **setppcs, int nsetppcs, SCIP_CONS **logicors, int nlogicors)
    static SCIP_DECL_PRESOLFREE(presolFreeGateextraction)
    #define PRESOL_PRIORITY
    #define HASHSIZE_LOGICORCONS
    static SCIP_DECL_PRESOLEXIT(presolExitGateextraction)
    static SCIP_DECL_PRESOLINITPRE(presolInitpreGateextraction)
    static SCIP_DECL_PRESOLEXITPRE(presolExitpreGateextraction)
    static SCIP_DECL_PRESOLEXEC(presolExecGateextraction)
    static void presoldataInit(SCIP_PRESOLDATA *presoldata)
    static SCIP_RETCODE correctPresoldata(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_CONS **setppcs, int nsetppcs, SCIP_CONS **logicors, int nlogicors)
    #define PRESOL_MAXROUNDS
    #define DEFAULT_SORTING
    #define PRESOL_TIMING
    #define DEFAULT_SEARCHEQUATIONS
    #define PRESOL_DESC
    gateextraction presolver
    public methods for managing constraints
    public methods for message output
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for presolvers
    public methods for problem variables
    public methods for constraint handler plugins and constraints
    general public methods
    public methods for memory management
    public methods for message handling
    public methods for SCIP parameter handling
    public methods for presolving plugins
    public methods for global and local (sub)problems
    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
    SCIP_VAR ** vars
    SCIP_CONS * cons
    struct SCIP_PresolData SCIP_PRESOLDATA
    Definition: type_presol.h:51
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_NOMEMORY
    Definition: type_retcode.h:44
    @ 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_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_LOCKTYPE_MODEL
    Definition: type_var.h:141