cons_pseudoboolean.c
Go to the documentation of this file.
23 * The constraint handler deals with pseudo Boolean constraints. These are constraints of the form
25 * \mbox{lhs} \leq \sum_{k=0}^m c_k \cdot x_k + \sum_{i=0}^n c_i \cdot \prod_{j \in I_i} x_j \leq \mbox{rhs}
32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
68 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
69 #define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
70 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
72 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
73 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
75 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
77 #define DEFAULT_DECOMPOSENORMALPBCONS FALSE /**< decompose all normal pseudo boolean constraint into a "linear" constraint and "and" constraints */
78 #define DEFAULT_DECOMPOSEINDICATORPBCONS TRUE /**< decompose all indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
80 #define DEFAULT_SEPARATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be separated during LP processing */
81 #define DEFAULT_PROPAGATENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be propagated during node processing */
82 #define DEFAULT_REMOVABLENONLINEAR TRUE /**< if decomposed, should the nonlinear constraints be removable */
88 #define HASHSIZE_PSEUDOBOOLEANNONLINEARTERMS 500 /**< minimal size of hash table in and constraint tables */
91 /* - create special linear(knapsack, setppc, logicor, (eqknapsack)) and and-constraints with check flags FALSE, to
92 * get smaller amount of locks on the term variables, do all presolving ...?! in these constraint handlers
94 * - do the checking here, lock and-resultants in both directions and all and-variables according to their
96 * @note this only works if the and-resultant has no objective cofficient, otherwise we need to lock variables also in both directions
98 * - need to keep and constraint pointer for special propagations like if two ands are due to their variables in
102 * check/IP/PseudoBoolean/normalized-PB07/OPT-SMALLINT-NLC/submittedPB07/manquinho/bsg/normalized-bsg_1000_25_1.opb.gz
108 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 5 ;
112 * which "equals" a pseudoboolean constraint: 2 x1 + 2 x2 + 1 x3 x4 + 1 x5 x6 x7 + 1 x8 x9 <= 6 ;
123 /* @todo - in and-constraint better count nfixed zeros in both directions and maybe nfixedones for better propagation
125 * - do better conflict analysis by choosing the earliest fixed variable which led to a conflict instead of maybe
128 * - how to make sure that we aggregate in a right way, when aggregating a resultant and a "normal" variable,
129 * maybe add in SCIPaggregateVars a check for original variables, to prefer them if the variable type is the
130 * same; probably it would be better too if we would aggregate two resultants that the one with less variables
133 * @note since product resultants are artificial, we do not care for their solution value, but this can lead to fixation
134 * of the resultant not representing the product, in 'optimization mode' we do not care, but this might make
140 {
154 };
164 SCIP_LINEARCONSTYPE linconstype; /**< type of linear constraint which represents this pseudoboolean constraint */
198 CONSANDDATA** allconsanddatas; /**< array of all and-constraint data objects inside the whole problem,
210 SCIP_Bool decomposenormalpbcons;/**< decompose the pseudo boolean constraint into a "linear" constraint and "and" constraints */
211 SCIP_Bool decomposeindicatorpbcons;/**< decompose the indicator pseudo boolean constraint into a "linear" constraint and "and" constraints */
222 /** comparison method for sorting consanddatas according to the index of their corresponding resultant variables, if a
223 * consanddata object is delete it is handled like it has an inactive resultant, so this will be put in front while
228 {
295 /** returns TRUE iff both keys are equal; two non-linear terms are equal if they have the same variables */
298 {
388 /** initializes the hashmap and -table used in this constraint handler data for artificial variables and specific
410 SCIP_CALL( SCIPhashtableCreate(&((*conshdlrdata)->hashtable), SCIPblkmem(scip), (*conshdlrdata)->hashtablesize,
415 SCIP_CALL( SCIPhashmapCreate(&((*conshdlrdata)->hashmap), SCIPblkmem(scip), (*conshdlrdata)->hashmapsize) );
438 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas ) );
485 SCIPfreeBlockMemoryArray(scip, &((*conshdlrdata)->allconsanddatas), (*conshdlrdata)->sallconsanddatas );
608 SCIP_VAR**const vars, /**< array to store sorted (after indices) variables of linear constraint */
762 /** calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
763 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
773 SCIP_VAR**const linvars, /**< array to store not and-resultant variables of linear constraint, or NULL */
774 SCIP_Real*const lincoefs, /**< array to store coefficients of not and-resultant variables of linear
777 SCIP_VAR**const andress, /**< array to store and-resultant variables of linear constraint, or NULL */
780 SCIP_Bool*const andnegs, /**< array to store negation status of and-resultant variables of linear
809 /* @note it is necessary that the linear constraint is merged (not needed for negated variables) and sorted after
837 /* if and resultant is not a resultant anymore (meaning the corresponding and-constraint was deleted/upgraded),
844 CONSANDDATA* consanddata = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)(hashmapvar));
948 SCIP_CALL_ABORT( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &newlhs, &newrhs) );
970 SCIP_CALL_ABORT( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
974 SCIP_CALL_ABORT( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars,
992 if( res == andresultant && consdata->andnegs[c] == andnegs[v] && consdata->andcoefs[c] == andcoefs[v] )
995 assert(SCIPvarIsActive(res) || (SCIPvarIsNegated(res) && SCIPvarIsActive(SCIPvarGetNegationVar(res))));
998 /* all and-resultants should be merged, so it is only allowed that each variable exists one time */
1028 /** transforming transformed consanddata object back to original space, if an corresponding original constraint exists,
1104 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(consanddata->vars), andvars, consanddata->nvars) );
1117 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1118 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1119 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1149 assert(consanddata == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddata)));
1150 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons)));
1151 assert(consanddata == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->origcons))));
1167 SCIP_CONS*const lincons, /**< linear constraint with artificial and-resultants representing this pseudoboolean constraint */
1169 SCIP_CONS**const andconss, /**< array of and-constraints which occur in this pseudoboolean constraint */
1171 SCIP_Bool*const andnegs, /**< negation status of and-constraints (or NULL, if no negated resultants) */
1176 SCIP_VAR* const intvar, /**< a artificial variable which was added only for the objective function,
1210 SCIPerrorMessage("left hand side of pseudo boolean constraint greater than right hand side\n");
1255 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1282 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &((*consdata)->andcoefs), andcoefs, nandconss) );
1309 (*consdata)->consanddatas[c] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)andress[c]);
1311 assert((*consdata)->consanddatas[c]->origcons == andconss[c] || (*consdata)->consanddatas[c]->cons == andconss[c]);
1316 if( (*consdata)->consanddatas[c]->origcons != NULL && (*consdata)->consanddatas[c]->cons == NULL )
1322 /* do not capture the and constraint when scip is in transformed mode; this automatically happens in
1325 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->consanddatas[c]->origcons, &((*consdata)->consanddatas[c]->cons)) );
1339 /* resort variables in transformed problem, because the order might change while tranforming */
1362 SCIPsortPtrPtrRealBool((void**)andress, (void**)((*consdata)->consanddatas), (*consdata)->andcoefs, (*consdata)->andnegs, SCIPvarComp, nandconss);
1427 /* count down uses and if necessary release constraints and delete data from hashtable and -map */
1443 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1457 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)));
1458 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->cons)) );
1478 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1498 /* if the consanddata is not used anymore, release the constraint and clear the hashmap- and table */
1511 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1512 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)) );
1544 conshdlrdata->allconsanddatas[d] = conshdlrdata->allconsanddatas[conshdlrdata->nallconsanddatas];
1611 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashtableRetrieve(conshdlrdata->hashtable, (void*)consanddatas[c])));
1612 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons)));
1613 assert(consanddatas[c] == (CONSANDDATA*)(SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddatas[c]->origcons))));
1628 /** check the locks of an AND resultant and removes it from all global structures if the resultant is not locked anymore */
1638 /* the resultant has no locks left and might be dual fixed now, we need to delete all its cliques */
1640 && SCIPvarGetNLocksUpType(res, SCIP_LOCKTYPE_MODEL) == 0 && SCIPgetStage(scip) < SCIP_STAGE_FREETRANS )
1675 /* choose correct variable array to add locks for, we only add locks for now valid variables */
1722 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks */
1827 /* more than one and-constraint is needed, otherwise this pseudoboolean constraint should be upgraded to a linear constraint */
1849 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
1852 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
1853 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
1860 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
1916 SCIPinfoMessage(scip, file, " %+.15g %s<%s>[B]", andcoefs[v], negated ? "~" : "", SCIPvarGetName(aggrvar));
1999 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2089 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"%d", conshdlrdata->nallconsanddatas);
2093 #if 1 /* @todo: check whether we want to branch on artificial variables, the test results show that it is of advantage */
2101 #if 0 /* does not work for since the value of artificial resultants must not be equal to the value computed by their
2121 if( (SCIPvarIsOriginal(resultant) || SCIPvarIsTransformedOrigvar(resultant)) && !SCIPisFeasEQ(scip, debugsolval, val) )
2123 SCIPerrorMessage("computed solution value %g for resultant <%s> violates debug solution value %g\n", val, SCIPvarGetName(resultant), debugsolval);
2159 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(conshdlrdata->allconsanddatas), &(conshdlrdata->sallconsanddatas), SCIPcalcMemGrowSize(scip, conshdlrdata->sallconsanddatas + 1)) );
2246 SCIPconsIsInitial(cons), SCIPconsIsEnforced(cons), SCIPconsIsChecked(cons), SCIPconsIsLocal(cons),
2254 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consdata->consanddatas), &(consdata->sconsanddatas), consdata->sconsanddatas + 1) );
2261 consdata->consanddatas[consdata->nconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res);
2303 SCIP_CALL( lockRoundingAndCons(scip, cons, consdata->consanddatas[consdata->nconsanddatas - 1], val, consdata->lhs, consdata->rhs) );
2412 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2434 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2437 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2438 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2441 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2527 /* check whether the left hand side is increased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
2586 SCIP_CALL( getLinearConsSides(scip, consdata->lincons, consdata->linconstype, &oldlhs, &oldrhs) );
2608 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
2611 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
2612 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
2615 SCIP_CALL( getLinVarsAndAndRess(scip, cons, vars, coefs, nvars, linvars, lincoefs, &nlinvars, andress, andcoefs, andnegs, &nandress) );
2701 /* check whether the right hand side is decreased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
2751 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2828 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2831 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
2836 SCIP_LINEARCONSTYPE*const linconstype /**< pointer to store the type of the linear constraint */
2947 SCIPdebugMsg(scip, "While creating the linear constraint of the pseudoboolean constraint we found %d zero coefficients that were removed\n", nzero);
2962 * - logic or constraints have left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
2974 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3008 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3022 /* check, if linear constraint can be upgraded to set partitioning, packing, or covering constraint
3023 * - all set partitioning / packing / covering constraints consist only of binary variables with a
3030 * - a set partitioning constraint has left hand side of +1.0, and right hand side of +1.0 : x(S) == 1.0
3032 * - a set packing constraint has left hand side of -infinity, and right hand side of +1.0 : x(S) <= 1.0
3034 * - a set covering constraint has left hand side of +1.0, and right hand side of +infinity: x(S) >= 1.0
3042 if( SCIPisEQ(scip, *lhs, *rhs) && (SCIPisEQ(scip, *lhs, 1.0 - ncoeffsnone) || SCIPisEQ(scip, *lhs, ncoeffspone - 1.0)) )
3046 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3080 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3096 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3130 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3148 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a set packing constraint.\n");
3152 SCIPwarningMessage(scip, "Does not expect this, because this constraint should be a logicor constraint.\n");
3157 /* check, if we have to multiply with -1 (negate the positive vars) or with +1 (negate the negative vars) */
3191 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3211 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && (SCIPisInfinity(scip, -*lhs) != SCIPisInfinity(scip, *rhs)) )
3225 /* if the right hand side is non-infinite, we have to negate all variables with negative coefficient;
3226 * otherwise, we have to negate all variables with positive coefficient and multiply the row with -1
3279 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3300 if( upgrconshdlr != NULL && !created && (ncoeffspone + ncoeffsnone + ncoeffspint + ncoeffsnint == nvars) && SCIPisEQ(scip, *lhs, *rhs) )
3310 SCIPdebugMsg(scip, "linear pseudoboolean constraint will be a equality-knapsack constraint\n");
3367 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3389 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3465 SCIPdebugMsg(scip, "checking original pseudo boolean constraint <%s>\n", SCIPconsGetName(cons));
3492 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, coefs, &nvars) );
3495 /* number of variables should be consistent, number of 'real' linear variables plus number of and-constraints should
3512 /* split variables into original and artificial variables and compute activity on normal linear variables (without
3579 /* if after during or before presolving a solution will be transformed into original space and will be checked
3580 * there, but origcons was already removed and only the pointer to the transformed and-constraint is existing
3635 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", lhs - activity);
3651 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - rhs);
3668 /** checks all and-constraints inside the pseudoboolean constraint handler for feasibility of given solution or current
3751 SCIP_HASHMAP*const varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
3753 SCIP_HASHMAP*const consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
3763 SCIP_Bool const removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
3764 SCIP_Bool const stickingatnode, /**< should the constraint always be kept at the node where it was added, even
3840 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, sourcelincons, &targetlincons, conshdlrlinear, varmap, consmap, SCIPconsGetName(sourcelincons),
3841 SCIPconsIsInitial(sourcelincons), SCIPconsIsSeparated(sourcelincons), SCIPconsIsEnforced(sourcelincons), SCIPconsIsChecked(sourcelincons),
3842 SCIPconsIsPropagated(sourcelincons), SCIPconsIsLocal(sourcelincons), SCIPconsIsModifiable(sourcelincons), SCIPconsIsDynamic(sourcelincons),
3849 /* @note due to copying special linear constraints, now leads only to simple linear constraints, we check that
3850 * our target constraint handler is the same as our source constraint handler of the linear constraint,
3883 SCIP_CALL( getLinearConsNVars(targetscip, targetlincons, targetlinconstype, &ntargetlinvars) );
3895 SCIP_CALL( SCIPhashtableCreate(&linconsvarsmap, SCIPblkmem(targetscip), ntargetlinvars, SCIPvarGetHashkey,
3920 targetandresultant = (SCIP_VAR*) SCIPhashmapGetImage(varmap, SCIPgetResultantAnd(sourcescip, oldcons));
3934 SCIP_CALL( SCIPgetConsCopy(sourcescip, targetscip, oldcons, &targetandconss[ntargetandconss], conshdlrand, varmap, consmap, SCIPconsGetName(oldcons),
3935 SCIPconsIsInitial(oldcons), SCIPconsIsSeparated(oldcons), SCIPconsIsEnforced(oldcons), SCIPconsIsChecked(oldcons),
3936 SCIPconsIsPropagated(oldcons), SCIPconsIsLocal(oldcons), SCIPconsIsModifiable(oldcons), SCIPconsIsDynamic(oldcons),
3955 SCIPdebugMsg(sourcescip, "no and-constraints copied for pseudoboolean constraint <%s>\n", SCIPconsGetName(sourcecons));
3977 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, indvar, &indvar, varmap, consmap, global, valid) );
3983 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, intvar, &intvar, varmap, consmap, global, valid) );
3997 SCIP_CALL( getLinearConsSides(targetscip, targetlincons, targetlinconstype, &targetlhs, &targetrhs) );
4004 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
4010 SCIPverbMessage(sourcescip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy constraint <%s>\n", SCIPconsGetName(sourcecons));
4084 assert(consanddata->nnewvars == 0 && ((consanddata->snewvars > 0) == (consanddata->newvars != NULL)));
4126 /* check for changings, if and-constraint did not change we do not need to copy all variables */
4150 SCIP_CALL( SCIPensureBlockMemoryArray(scip, &(consanddata->newvars), &(consanddata->snewvars), nnewvars) );
4174 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4202 CONSANDDATA*const consanddata, /**< CONSANDDATA object for which we want to delete the locks and the
4234 SCIP_Real*const andcoefs, /**< current and-resultants-coeffcients in pseudoboolean constraint */
4235 SCIP_Bool*const andnegs, /**< current negation status of and-resultants in pseudoboolean constraint */
4266 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4281 /* check that consanddata objects are sorted due to the index of the corresponding resultants, and coefficents are
4375 /* collect new consanddata objects in sorted order due to the variable index of corresponding and-resultants */
4382 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4393 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4399 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4432 lhschanged = (SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -newlhs)) || (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -newlhs))
4434 rhschanged = (SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, newrhs)) || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, newrhs))
4438 if( coefsignchanged || lhschanged || rhschanged || newconsanddatas[nnewconsanddatas]->nnewvars > 0)
4443 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4492 SCIP_CALL( removeOldLocks(scip, cons, consanddatas[c], oldandnegs[c] ? -oldandcoefs[c] : oldandcoefs[c],
4509 newconsanddatas[nnewconsanddatas] = (CONSANDDATA*) SCIPhashmapGetImage(conshdlrdata->hashmap, (void*)res2);
4515 SCIP_CALL( addNewLocks(scip, cons, newconsanddatas[nnewconsanddatas], newandnegs[nnewconsanddatas] ?
4548 SCIP_CALL( getLinearConsNVars(scip, consdata->lincons, consdata->linconstype, &(consdata->nlinvars)) );
4560 /* we need to re-sort and-constraints after indices of corresponding and-resultants, since we might have replaced
4563 SCIPsortPtrRealBool((void**)(consdata->consanddatas), consdata->andcoefs, consdata->andnegs, resvarCompWithInactive, consdata->nconsanddatas);
4570 /* check that consanddata objects are sorted with respect to the index of the corresponding resultants */
4626 /* if we have no and-constraints left, we should not be here and this constraint should be deleted (only the linaer should survive) */
4654 SCIP_CALL( getLinearConsVarsData(scip, consdata->lincons, consdata->linconstype, vars, NULL, &nvars) );
4656 /* calculate all not artificial linear variables and all artificial and-resultants which will be ordered like the
4657 * 'consanddatas' such that the and-resultant of the and-constraint is the and-resultant in the 'andress' array
4697 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4714 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4726 /* if variable in and-constraint1 is the negated variable of a normal linear variable, than we can add a
4727 * clique between the and-resultant and the normal linear variable, negated variables are not save in
4749 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4758 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4771 /* if a variable in an and-constraint is in a clique with another normal linear variable, we can add the
4792 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4801 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4867 if( !SCIPvarIsActive(var1) && (!SCIPvarIsNegated(var1) || !SCIPvarIsActive(SCIPvarGetNegationVar(var1))) )
4884 if( !SCIPvarIsActive(var2) && (!SCIPvarIsNegated(var2) || !SCIPvarIsActive(SCIPvarGetNegationVar(var2))) )
4896 /* if a variable in and-constraint1 is the negated variable of a variable in and-constraint2, than we can
4918 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4927 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
4940 /* if a variable in an and-constraint is in a clique with a variable in another and-constraint, we can add
4962 /* @todo: check whether it is better to only add the clique or to add the setppc constraint or do both */
4971 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_clq_%s_%s", SCIPconsGetName(cons), SCIPvarGetName(clqvars[0]), SCIPvarGetName(clqvars[1]) );
5110 assert(consanddata->nnewvars == 0 || (consanddata->newvars != NULL && consanddata->snewvars > 0));
5156 /* the consanddata object is not used anymore, so extract the and constraint and delete other data */
5182 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5208 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart,
5229 SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activescalars, &nactivevars, SCIPgetNVars(scip),
5249 assert(SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(activevars[i]) == SCIP_VARSTATUS_FIXED);
5257 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5268 if( SCIPsortedvecFindPtr((void**)fixedvars, SCIPvarComp, SCIPgetResultantAnd(scip, consanddata->cons), nfixedvars, &pos) )
5300 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5301 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5366 /** update the uses counter of consandata objects which are used in pseudoboolean constraint, that were deleted and
5412 SCIP_CALL( removeOldLocks(scip, cons, consanddata, consdata->andcoefs[c], consdata->lhs, consdata->rhs) );
5446 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5467 /* all inactive variables have a loose, column, fixed or multi-aggregated variable as counterpart, but
5471 * @todo for multi-aggregated variables check also all active representatives for this resultant
5478 assert(SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(fixedvars[w]) == SCIP_VARSTATUS_FIXED);
5491 /* we can only delete and constraints if the resultant is an artificial variable and also active, because
5492 * then the assigned value is not of interest and the artificial and constraint does not need to be
5495 * if this variable is not such an artificial variable we need the IRRELEVANT vartype which should be the
5501 strncmp(SCIPvarGetName(resvar)+2, ARTIFICIALVARNAMEPREFIX, strlen(ARTIFICIALVARNAMEPREFIX)) == 0
5512 /* @note due to aggregations or fixings the resultant may need to be propagated later on, so we can only
5541 assert(SCIPhashmapExists(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)));
5542 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->hashmap, (void*)SCIPgetResultantAnd(scip, consanddata->cons)) );
5555 /* maximal number to enumerate solutions for one pseudoboolean constraint to check for an upgrade to an XOR constraint */
5558 /** calculate result for a given pseudoboolean constraint with given values, this is used to decide whether a
5578 SCIP_Bool*const consanddatanegs, /**< negation status of and resultants in pseudo-boolean constraint */
5616 if( SCIPsortedvecFindPtr((void**)vars, SCIPvarCompActiveAndNegated, linvars[v], nvars, &pos) ) /*lint !e613*/
5642 /* choose correct variable array to add locks for, we only add locks for now valid variables */
5665 assert(!negated[v] || (SCIPvarIsNegated(repvars[v]) && SCIPvarGetNegatedVar(repvars[v]) != NULL));