Scippy

    SCIP

    Solving Constraint Integer Programs

    expr.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-2025 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 expr.c
    26 * @ingroup OTHER_CFILES
    27 * @brief functions for algebraic expressions
    28 * @author Ksenia Bestuzheva
    29 * @author Benjamin Mueller
    30 * @author Felipe Serrano
    31 * @author Stefan Vigerske
    32 */
    33
    34#include <assert.h>
    35#include <ctype.h>
    36
    37#include "scip/expr.h"
    38#include "scip/struct_expr.h"
    39#include "scip/pub_misc.h"
    40#include "scip/clock.h"
    41#include "scip/set.h"
    42#include "scip/pub_var.h"
    43#include "scip/pub_message.h"
    44#include "scip/sol.h"
    45#include "scip/tree.h"
    46#include "scip/struct_set.h"
    47#include "scip/struct_stat.h"
    48#include "scip/lapack_calls.h"
    49
    50/*lint -e440*/
    51/*lint -e441*/
    52/*lint -e777*/
    53
    54/*
    55 * Data structures
    56 */
    57
    58/** printing to file data */
    59struct SCIP_ExprPrintData
    60{
    61 FILE* file; /**< file to print to */
    62 SCIP_EXPRITER* iterator; /**< iterator to use */
    63 SCIP_Bool closefile; /**< whether file need to be closed when finished printing */
    64 SCIP_HASHMAP* leaveexprs; /**< hashmap storing leave (no children) expressions */
    65 SCIP_EXPRPRINT_WHAT whattoprint; /**< flags that indicate what to print for each expression */
    66};
    67
    68/*
    69 * Local methods
    70 */
    71
    72/** frees an expression */
    73static
    75 BMS_BLKMEM* blkmem, /**< block memory */
    76 SCIP_EXPR** expr /**< pointer to free the expression */
    77 )
    78{
    79 assert(expr != NULL);
    80 assert(*expr != NULL);
    81 assert((*expr)->nuses == 1);
    82 assert((*expr)->quaddata == NULL);
    83 assert((*expr)->ownerdata == NULL);
    84
    85 /* free children array, if any */
    86 BMSfreeBlockMemoryArrayNull(blkmem, &(*expr)->children, (*expr)->childrensize);
    87
    88 BMSfreeBlockMemory(blkmem, expr);
    89 assert(*expr == NULL);
    90
    91 return SCIP_OKAY;
    92}
    93
    94/*
    95 * quadratic representation of expression
    96 */
    97
    98/** first time seen quadratically and
    99 * seen before linearly --> --nlinterms; assign 2; ++nquadterms
    100 * not seen before linearly --> assing 1; ++nquadterms
    101 *
    102 * seen before --> assign += 1
    103 */
    104static
    106 SCIP_EXPR* expr, /**< the expression */
    107 SCIP_HASHMAP* seenexpr, /**< hash map */
    108 int* nquadterms, /**< number of quadratic terms */
    109 int* nlinterms /**< number of linear terms */
    110 )
    111{
    112 if( SCIPhashmapExists(seenexpr, (void*)expr) )
    113 {
    114 int nseen = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
    115
    116 if( nseen < 0 )
    117 {
    118 /* only seen linearly before */
    119 assert(nseen == -1);
    120
    121 --*nlinterms;
    122 ++*nquadterms;
    123 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, 2) );
    124 }
    125 else
    126 {
    127 assert(nseen > 0);
    128 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, nseen + 1) );
    129 }
    130 }
    131 else
    132 {
    133 ++*nquadterms;
    134 SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)expr, 1) );
    135 }
    136
    137 return SCIP_OKAY;
    138}
    139
    140/** returns a quadexprterm that contains the expr
    141 *
    142 * it either finds one that already exists or creates a new one
    143 */
    144static
    146 BMS_BLKMEM* blkmem, /**< block memory */
    147 SCIP_EXPR* expr, /**< the expression */
    148 SCIP_HASHMAP* expr2idx, /**< map: expr to index in quadexpr->quadexprterms */
    149 SCIP_HASHMAP* seenexpr, /**< map: expr to number of times it was seen */
    150 SCIP_QUADEXPR* quadexpr, /**< data of quadratic representation of expression */
    151 SCIP_QUADEXPR_QUADTERM** quadexprterm /**< buffer to store quadexprterm */
    152 )
    153{
    154 assert(expr != NULL);
    155 assert(expr2idx != NULL);
    156 assert(quadexpr != NULL);
    157 assert(quadexprterm != NULL);
    158
    159 if( SCIPhashmapExists(expr2idx, (void*)expr) )
    160 {
    161 *quadexprterm = &quadexpr->quadexprterms[SCIPhashmapGetImageInt(expr2idx, (void*)expr)];
    162 assert((*quadexprterm)->expr == expr);
    163 }
    164 else
    165 {
    166 SCIP_CALL( SCIPhashmapInsertInt(expr2idx, expr, quadexpr->nquadexprs) );
    167 *quadexprterm = &quadexpr->quadexprterms[quadexpr->nquadexprs];
    168 ++quadexpr->nquadexprs;
    169
    170 (*quadexprterm)->expr = expr;
    171 (*quadexprterm)->sqrcoef = 0.0;
    172 (*quadexprterm)->sqrexpr = NULL;
    173 (*quadexprterm)->lincoef = 0.0;
    174 (*quadexprterm)->nadjbilin = 0;
    175 (*quadexprterm)->adjbilinsize = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
    176 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*quadexprterm)->adjbilin, (*quadexprterm)->adjbilinsize) );
    177 }
    178
    179 return SCIP_OKAY;
    180}
    181
    182
    183/** evaluate and forward-differentiate expression
    184 *
    185 * also initializes derivative and bardot to 0.0
    186 */
    187static
    189 SCIP_SET* set, /**< global SCIP settings */
    190 SCIP_STAT* stat, /**< dynamic problem statistics */
    191 BMS_BLKMEM* blkmem, /**< block memory */
    192 SCIP_EXPR* expr, /**< expression to be evaluated */
    193 SCIP_SOL* sol, /**< solution to be evaluated */
    194 SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
    195 SCIP_SOL* direction /**< direction for directional derivative */
    196 )
    197{
    198 SCIP_EXPRITER* it;
    199
    200 assert(set != NULL);
    201 assert(stat != NULL);
    202 assert(blkmem != NULL);
    203 assert(expr != NULL);
    204
    205 /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
    206 * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
    207 */
    208 expr->evalvalue = SCIP_INVALID;
    209 expr->evaltag = soltag;
    210 expr->dot = SCIP_INVALID;
    211
    212 /* start a new difftag */
    213 ++stat->exprlastdifftag;
    214
    215 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    218
    219 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    220 {
    221 /* evaluate expression only if necessary */
    222 if( soltag == 0 || expr->evaltag != soltag )
    223 {
    224 SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL, expr, &expr->evalvalue, NULL, sol) );
    225
    226 expr->evaltag = soltag;
    227 }
    228
    229 if( expr->evalvalue == SCIP_INVALID )
    230 break;
    231
    232 if( expr->difftag != stat->exprlastdifftag )
    233 {
    234 /* compute forward diff */
    235 SCIP_CALL( SCIPexprhdlrFwDiffExpr(expr->exprhdlr, set, expr, &expr->dot, direction) );
    236
    237 if( expr->dot == SCIP_INVALID )
    238 break;
    239
    240 expr->derivative = 0.0;
    241 expr->bardot = 0.0;
    242 expr->difftag = stat->exprlastdifftag;
    243 }
    244 }
    245
    246 SCIPexpriterFree(&it);
    247
    248 return SCIP_OKAY;
    249}
    250
    251
    252/*
    253 * Public methods
    254 */
    255
    256/* Undo the defines from pub_expr.h, which exist if NDEBUG is defined. */
    257#ifdef NDEBUG
    258#undef SCIPexprhdlrSetCopyFreeHdlr
    259#undef SCIPexprhdlrSetCopyFreeData
    260#undef SCIPexprhdlrSetPrint
    261#undef SCIPexprhdlrSetParse
    262#undef SCIPexprhdlrSetCurvature
    263#undef SCIPexprhdlrSetMonotonicity
    264#undef SCIPexprhdlrSetIntegrality
    265#undef SCIPexprhdlrSetHash
    266#undef SCIPexprhdlrSetCompare
    267#undef SCIPexprhdlrSetDiff
    268#undef SCIPexprhdlrSetIntEval
    269#undef SCIPexprhdlrSetSimplify
    270#undef SCIPexprhdlrSetReverseProp
    271#undef SCIPexprhdlrSetEstimate
    272#undef SCIPexprhdlrSetGetSymdata
    273#undef SCIPexprhdlrGetName
    274#undef SCIPexprhdlrGetDescription
    275#undef SCIPexprhdlrGetPrecedence
    276#undef SCIPexprhdlrGetData
    277#undef SCIPexprhdlrHasPrint
    278#undef SCIPexprhdlrHasBwdiff
    279#undef SCIPexprhdlrHasFwdiff
    280#undef SCIPexprhdlrHasIntEval
    281#undef SCIPexprhdlrHasEstimate
    282#undef SCIPexprhdlrHasInitEstimates
    283#undef SCIPexprhdlrHasSimplify
    284#undef SCIPexprhdlrHasCurvature
    285#undef SCIPexprhdlrHasMonotonicity
    286#undef SCIPexprhdlrHasReverseProp
    287#undef SCIPexprhdlrGetNCreated
    288#undef SCIPexprhdlrGetNIntevalCalls
    289#undef SCIPexprhdlrGetIntevalTime
    290#undef SCIPexprhdlrGetNReversepropCalls
    291#undef SCIPexprhdlrGetReversepropTime
    292#undef SCIPexprhdlrGetNCutoffs
    293#undef SCIPexprhdlrGetNDomainReductions
    294#undef SCIPexprhdlrIncrementNDomainReductions
    295#undef SCIPexprhdlrGetNEstimateCalls
    296#undef SCIPexprhdlrGetEstimateTime
    297#undef SCIPexprhdlrGetNBranchings
    298#undef SCIPexprhdlrIncrementNBranchings
    299#undef SCIPexprhdlrGetNSimplifyCalls
    300#undef SCIPexprhdlrGetSimplifyTime
    301#undef SCIPexprhdlrGetNSimplifications
    302#endif
    303
    304/** create expression handler */
    306 BMS_BLKMEM* blkmem, /**< block memory */
    307 SCIP_EXPRHDLR** exprhdlr, /**< buffer where to store created expression handler */
    308 const char* name, /**< name of expression handler (must not be NULL) */
    309 const char* desc, /**< description of expression handler (can be NULL) */
    310 unsigned int precedence, /**< precedence of expression operation (used for printing) */
    311 SCIP_DECL_EXPREVAL((*eval)), /**< point evaluation callback (must not be NULL) */
    312 SCIP_EXPRHDLRDATA* data /**< data of expression handler (can be NULL) */
    313 )
    314{
    315 assert(exprhdlr != NULL);
    316 assert(name != NULL);
    317
    318 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, exprhdlr) );
    319
    320 SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->name, name, strlen(name)+1) );
    321 if( desc != NULL )
    322 {
    323 SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->desc, desc, strlen(desc)+1) );
    324 }
    325
    326 (*exprhdlr)->precedence = precedence;
    327 (*exprhdlr)->eval = eval;
    328 (*exprhdlr)->data = data;
    329
    330 /* create clocks */
    331 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->estimatetime, SCIP_CLOCKTYPE_DEFAULT) );
    332 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->intevaltime, SCIP_CLOCKTYPE_DEFAULT) );
    333 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->proptime, SCIP_CLOCKTYPE_DEFAULT) );
    334 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->simplifytime, SCIP_CLOCKTYPE_DEFAULT) );
    335
    336 return SCIP_OKAY;
    337}
    338
    339/** frees expression handler */
    341 SCIP_EXPRHDLR** exprhdlr, /**< pointer to expression handler to be freed */
    342 SCIP_SET* set, /**< global SCIP settings */
    343 BMS_BLKMEM* blkmem /**< block memory */
    344 )
    345{
    346 if( (*exprhdlr)->freehdlr != NULL )
    347 {
    348 SCIP_CALL( (*exprhdlr)->freehdlr(set->scip, *exprhdlr, &(*exprhdlr)->data) );
    349 }
    350
    351 /* free clocks */
    352 SCIPclockFree(&(*exprhdlr)->simplifytime);
    353 SCIPclockFree(&(*exprhdlr)->intevaltime);
    354 SCIPclockFree(&(*exprhdlr)->proptime);
    355 SCIPclockFree(&(*exprhdlr)->estimatetime);
    356
    357 BMSfreeMemoryArrayNull(&(*exprhdlr)->desc);
    358 BMSfreeMemoryArray(&(*exprhdlr)->name);
    359
    360 BMSfreeBlockMemory(blkmem, exprhdlr);
    361
    362 return SCIP_OKAY;
    363}
    364
    365/**@addtogroup PublicExprHandlerMethods
    366 * @{
    367 */
    368
    369/** set the expression handler callbacks to copy and free an expression handler */
    371 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    372 SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), /**< handler copy callback (can be NULL) */
    373 SCIP_DECL_EXPRFREEHDLR((*freehdlr)) /**< handler free callback (can be NULL) */
    374 )
    375{
    376 assert(exprhdlr != NULL);
    377
    378 exprhdlr->copyhdlr = copyhdlr;
    379 exprhdlr->freehdlr = freehdlr;
    380}
    381
    382/** set the expression handler callbacks to copy and free expression data */
    384 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    385 SCIP_DECL_EXPRCOPYDATA((*copydata)), /**< expression data copy callback (can be NULL for expressions without data) */
    386 SCIP_DECL_EXPRFREEDATA((*freedata)) /**< expression data free callback (can be NULL if data does not need to be freed) */
    387 )
    388{ /*lint --e{715}*/
    389 assert(exprhdlr != NULL);
    390
    391 exprhdlr->copydata = copydata;
    392 exprhdlr->freedata = freedata;
    393}
    394
    395/** set the print callback of an expression handler */
    397 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    398 SCIP_DECL_EXPRPRINT((*print)) /**< print callback (can be NULL) */
    399 )
    400{
    401 assert(exprhdlr != NULL);
    402
    403 exprhdlr->print = print;
    404}
    405
    406/** set the parse callback of an expression handler */
    408 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    409 SCIP_DECL_EXPRPARSE((*parse)) /**< parse callback (can be NULL) */
    410 )
    411{
    412 assert(exprhdlr != NULL);
    413
    414 exprhdlr->parse = parse;
    415}
    416
    417/** set the curvature detection callback of an expression handler */
    419 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    420 SCIP_DECL_EXPRCURVATURE((*curvature)) /**< curvature detection callback (can be NULL) */
    421 )
    422{
    423 assert(exprhdlr != NULL);
    424
    425 exprhdlr->curvature = curvature;
    426}
    427
    428/** set the monotonicity detection callback of an expression handler */
    430 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    431 SCIP_DECL_EXPRMONOTONICITY((*monotonicity)) /**< monotonicity detection callback (can be NULL) */
    432 )
    433{
    434 assert(exprhdlr != NULL);
    435
    436 exprhdlr->monotonicity = monotonicity;
    437}
    438
    439/** set the integrality detection callback of an expression handler */
    441 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    442 SCIP_DECL_EXPRINTEGRALITY((*integrality)) /**< integrality detection callback (can be NULL) */
    443 )
    444{
    445 assert(exprhdlr != NULL);
    446
    447 exprhdlr->integrality = integrality;
    448}
    449
    450/** set the hash callback of an expression handler */
    452 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    453 SCIP_DECL_EXPRHASH((*hash)) /**< hash callback (can be NULL) */
    454 )
    455{
    456 assert(exprhdlr != NULL);
    457
    458 exprhdlr->hash = hash;
    459}
    460
    461/** set the compare callback of an expression handler */
    463 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    464 SCIP_DECL_EXPRCOMPARE((*compare)) /**< compare callback (can be NULL) */
    465 )
    466{
    467 assert(exprhdlr != NULL);
    468
    469 exprhdlr->compare = compare;
    470}
    471
    472/** set differentiation callbacks of an expression handler */
    474 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    475 SCIP_DECL_EXPRBWDIFF((*bwdiff)), /**< backward derivative evaluation callback (can be NULL) */
    476 SCIP_DECL_EXPRFWDIFF((*fwdiff)), /**< forward derivative evaluation callback (can be NULL) */
    477 SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)) /**< backward-forward derivative evaluation callback (can be NULL) */
    478 )
    479{
    480 assert(exprhdlr != NULL);
    481
    482 exprhdlr->bwdiff = bwdiff;
    483 exprhdlr->fwdiff = fwdiff;
    484 exprhdlr->bwfwdiff = bwfwdiff;
    485}
    486
    487/** set the interval evaluation callback of an expression handler */
    489 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    490 SCIP_DECL_EXPRINTEVAL((*inteval)) /**< interval evaluation callback (can be NULL) */
    491 )
    492{
    493 assert(exprhdlr != NULL);
    494
    495 exprhdlr->inteval = inteval;
    496}
    497
    498/** set the simplify callback of an expression handler */
    500 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    501 SCIP_DECL_EXPRSIMPLIFY((*simplify)) /**< simplify callback (can be NULL) */
    502 )
    503{
    504 assert(exprhdlr != NULL);
    505
    506 exprhdlr->simplify = simplify;
    507}
    508
    509/** set the reverse propagation callback of an expression handler */
    511 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    512 SCIP_DECL_EXPRREVERSEPROP((*reverseprop)) /**< reverse propagation callback (can be NULL) */
    513 )
    514{
    515 assert(exprhdlr != NULL);
    516
    517 exprhdlr->reverseprop = reverseprop;
    518}
    519
    520/** set the symmetry information callback of an expression handler */
    522 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    523 SCIP_DECL_EXPRGETSYMDATA((*getsymdata)) /**< symmetry information callback (can be NULL) */
    524 )
    525{
    526 assert(exprhdlr != NULL);
    527
    528 exprhdlr->getsymdata = getsymdata;
    529}
    530
    531/** set the estimation callbacks of an expression handler */
    533 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    534 SCIP_DECL_EXPRINITESTIMATES((*initestimates)), /**< initial estimators callback (can be NULL) */
    535 SCIP_DECL_EXPRESTIMATE((*estimate)) /**< estimator callback (can be NULL) */
    536 )
    537{
    538 assert(exprhdlr != NULL);
    539
    540 exprhdlr->initestimates = initestimates;
    541 exprhdlr->estimate = estimate;
    542}
    543
    544/** gives the name of an expression handler */
    546 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    547 )
    548{
    549 assert(exprhdlr != NULL);
    550
    551 return exprhdlr->name;
    552}
    553
    554/** gives the description of an expression handler (can be NULL) */
    556 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    557 )
    558{
    559 assert(exprhdlr != NULL);
    560
    561 return exprhdlr->desc;
    562}
    563
    564/** gives the precedence of an expression handler */
    566 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    567 )
    568{
    569 assert(exprhdlr != NULL);
    570
    571 return exprhdlr->precedence;
    572}
    573
    574/** gives the data of an expression handler */
    576 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    577 )
    578{
    579 assert(exprhdlr != NULL);
    580
    581 return exprhdlr->data;
    582}
    583
    584/** returns whether expression handler implements the print callback */
    586 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    587 )
    588{
    589 assert(exprhdlr != NULL);
    590
    591 return exprhdlr->print != NULL;
    592}
    593
    594/** returns whether expression handler implements the backward differentiation callback */
    596 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    597 )
    598{
    599 assert(exprhdlr != NULL);
    600
    601 return exprhdlr->bwdiff != NULL;
    602}
    603
    604/** returns whether expression handler implements the forward differentiation callback */
    606 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    607 )
    608{
    609 assert(exprhdlr != NULL);
    610
    611 return exprhdlr->fwdiff != NULL;
    612}
    613
    614/** returns whether expression handler implements the interval evaluation callback */
    616 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    617 )
    618{
    619 assert(exprhdlr != NULL);
    620
    621 return exprhdlr->inteval != NULL;
    622}
    623
    624/** returns whether expression handler implements the estimator callback */
    626 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    627 )
    628{
    629 assert(exprhdlr != NULL);
    630
    631 return exprhdlr->estimate != NULL;
    632}
    633
    634/** returns whether expression handler implements the initial estimators callback */
    636 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    637 )
    638{
    639 assert(exprhdlr != NULL);
    640
    641 return exprhdlr->initestimates != NULL;
    642}
    643
    644/** returns whether expression handler implements the simplification callback */
    646 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    647 )
    648{
    649 assert(exprhdlr != NULL);
    650
    651 return exprhdlr->simplify != NULL;
    652}
    653
    654/** returns whether expression handler implements the curvature callback */
    656 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    657 )
    658{
    659 assert(exprhdlr != NULL);
    660
    661 return exprhdlr->curvature != NULL;
    662}
    663
    664/** returns whether expression handler implements the monotonicity callback */
    666 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    667 )
    668{
    669 assert(exprhdlr != NULL);
    670
    671 return exprhdlr->monotonicity != NULL;
    672}
    673
    674/** returns whether expression handler implements the reverse propagation callback */
    676 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    677 )
    678{
    679 assert(exprhdlr != NULL);
    680
    681 return exprhdlr->reverseprop != NULL;
    682}
    683
    684/** returns whether expression handler implements the symmetry information callback */
    686 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    687 )
    688{
    689 assert(exprhdlr != NULL);
    690
    691 return exprhdlr->getsymdata != NULL;
    692}
    693
    694/** compares two expression handler w.r.t. their name */
    695SCIP_DECL_SORTPTRCOMP(SCIPexprhdlrComp)
    696{
    697 return strcmp(((SCIP_EXPRHDLR*)elem1)->name, ((SCIP_EXPRHDLR*)elem2)->name);
    698}
    699
    700/** gets number of times an expression has been created with given expression handler */
    702 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    703 )
    704{
    705 assert(exprhdlr != NULL);
    706
    707 return exprhdlr->ncreated;
    708}
    709
    710/** gets number of times the interval evaluation callback was called */
    712 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    713 )
    714{
    715 assert(exprhdlr != NULL);
    716
    717 return exprhdlr->nintevalcalls;
    718}
    719
    720/** gets time spend in interval evaluation callback */
    722 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    723 )
    724{
    725 assert(exprhdlr != NULL);
    726
    727 return SCIPclockGetTime(exprhdlr->intevaltime);
    728}
    729
    730/** gets number of times the reverse propagation callback was called */
    732 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    733 )
    734{
    735 assert(exprhdlr != NULL);
    736
    737 return exprhdlr->npropcalls;
    738}
    739
    740/** gets time spend in reverse propagation callback */
    742 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    743 )
    744{
    745 assert(exprhdlr != NULL);
    746
    747 return SCIPclockGetTime(exprhdlr->proptime);
    748}
    749
    750/** gets number of times an empty interval was found in reverse propagation */
    752 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    753 )
    754{
    755 assert(exprhdlr != NULL);
    756
    757 return exprhdlr->ncutoffs;
    758}
    759
    760/** gets number of times a bound reduction was found in reverse propagation (and accepted by caller) */
    762 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    763 )
    764{
    765 assert(exprhdlr != NULL);
    766
    767 return exprhdlr->ndomreds;
    768}
    769
    770/** increments the domain reductions count of an expression handler */
    772 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    773 int nreductions /**< number of reductions to add to counter */
    774 )
    775{
    776 assert(exprhdlr != NULL);
    777 assert(nreductions >= 0);
    778
    779 exprhdlr->ndomreds += nreductions;
    780}
    781
    782/** gets number of times the estimation callback was called */
    784 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    785 )
    786{
    787 assert(exprhdlr != NULL);
    788
    789 return exprhdlr->nestimatecalls;
    790}
    791
    792/** gets time spend in estimation callback */
    794 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    795 )
    796{
    797 assert(exprhdlr != NULL);
    798
    799 return SCIPclockGetTime(exprhdlr->estimatetime);
    800}
    801
    802/** gets number of times branching candidates reported by of this expression handler were used to
    803 * assemble branching candidates
    804 *
    805 * that is, how often did we consider branching on a child of this expression
    806 */
    808 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    809 )
    810{
    811 assert(exprhdlr != NULL);
    812
    813 return exprhdlr->nbranchscores;
    814}
    815
    816/** increments the branching candidates count of an expression handler */
    818 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    819 )
    820{
    821 assert(exprhdlr != NULL);
    822
    823 ++exprhdlr->nbranchscores;
    824}
    825
    826/** gets number of times the simplify callback was called */
    828 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    829 )
    830{
    831 assert(exprhdlr != NULL);
    832
    833 return exprhdlr->nsimplifycalls;
    834}
    835
    836/** gets time spend in simplify callback */
    838 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    839 )
    840{
    841 assert(exprhdlr != NULL);
    842
    843 return SCIPclockGetTime(exprhdlr->simplifytime);
    844}
    845
    846/** gets number of times the simplify callback found a simplification */
    848 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
    849 )
    850{
    851 assert(exprhdlr != NULL);
    852
    853 return exprhdlr->nsimplified;
    854}
    855
    856/** @} */
    857
    858/** copies the given expression handler to a new scip */
    860 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    861 SCIP_SET* targetset /**< SCIP_SET of SCIP to copy to */
    862 )
    863{
    864 assert(exprhdlr != NULL);
    865 assert(targetset != NULL);
    866 assert(targetset->scip != NULL);
    867
    868 if( exprhdlr->copyhdlr != NULL )
    869 {
    870 SCIPsetDebugMsg(targetset, "including expression handler <%s> in subscip %p\n",
    871 SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
    872 SCIP_CALL( exprhdlr->copyhdlr(targetset->scip, exprhdlr) );
    873 }
    874 else
    875 {
    876 SCIPsetDebugMsg(targetset, "expression handler <%s> cannot be copied to subscip %p due "
    877 "to missing copyhdlr callback\n", SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
    878 }
    879
    880 return SCIP_OKAY;
    881}
    882
    883/** initialization of expression handler (resets statistics) */
    885 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    886 SCIP_SET* set /**< global SCIP settings */
    887 )
    888{
    889 assert(exprhdlr != NULL);
    890
    891 if( set->misc_resetstat )
    892 {
    893 exprhdlr->ncreated = 0;
    894 exprhdlr->nestimatecalls = 0;
    895 exprhdlr->nintevalcalls = 0;
    896 exprhdlr->npropcalls = 0;
    897 exprhdlr->ncutoffs = 0;
    898 exprhdlr->ndomreds = 0;
    899 exprhdlr->nbranchscores = 0;
    900 exprhdlr->nsimplifycalls = 0;
    901 exprhdlr->nsimplified = 0;
    902
    903 SCIPclockReset(exprhdlr->estimatetime);
    904 SCIPclockReset(exprhdlr->intevaltime);
    905 SCIPclockReset(exprhdlr->proptime);
    906 SCIPclockReset(exprhdlr->simplifytime);
    907 }
    908}
    909
    910/** calls the print callback of an expression handler
    911 *
    912 * The method prints an expression.
    913 * It is called while iterating over the expression graph at different stages.
    914 *
    915 * @see SCIP_DECL_EXPRPRINT
    916 */
    918 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    919 SCIP_SET* set, /**< global SCIP settings */
    920 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    921 SCIP_EXPR* expr, /**< expression */
    922 SCIP_EXPRITER_STAGE stage, /**< stage of expression iteration */
    923 int currentchild, /**< index of current child if in stage visitingchild or visitedchild */
    924 unsigned int parentprecedence, /**< precedence of parent */
    925 FILE* file /**< the file to print to */
    926 )
    927{
    928 assert(exprhdlr != NULL);
    929 assert(set != NULL);
    930 assert(expr != NULL);
    931 assert(expr->exprhdlr == exprhdlr);
    932 assert(messagehdlr != NULL);
    933
    934 if( SCIPexprhdlrHasPrint(exprhdlr) )
    935 {
    936 SCIP_CALL( exprhdlr->print(set->scip, expr, stage, currentchild, parentprecedence, file) );
    937 }
    938 else
    939 {
    940 /* default: <hdlrname>(<child1>, <child2>, ...) */
    941 switch( stage )
    942 {
    944 {
    945 SCIPmessageFPrintInfo(messagehdlr, file, "%s", SCIPexprhdlrGetName(expr->exprhdlr));
    946 if( expr->nchildren > 0 )
    947 {
    948 SCIPmessageFPrintInfo(messagehdlr, file, "(");
    949 }
    950 break;
    951 }
    952
    954 {
    955 assert(currentchild >= 0);
    956 assert(currentchild < expr->nchildren);
    957 if( currentchild < expr->nchildren-1 )
    958 {
    959 SCIPmessageFPrintInfo(messagehdlr, file, ", ");
    960 }
    961 else
    962 {
    963 SCIPmessageFPrintInfo(messagehdlr, file, ")");
    964 }
    965
    966 break;
    967 }
    968
    971 default:
    972 break;
    973 }
    974 }
    975
    976 return SCIP_OKAY;
    977}
    978
    979/** calls the parse callback of an expression handler
    980 *
    981 * The method parses an expression.
    982 * It should be called when parsing an expression and an operator with the expr handler name is found.
    983 *
    984 * @see SCIP_DECL_EXPRPARSE
    985 */
    987 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    988 SCIP_SET* set, /**< global SCIP settings */
    989 const char* string, /**< string containing expression to be parse */
    990 const char** endstring, /**< buffer to store the position of string after parsing */
    991 SCIP_EXPR** expr, /**< buffer to store the parsed expression */
    992 SCIP_Bool* success, /**< buffer to store whether the parsing was successful or not */
    993 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
    994 void* ownercreatedata /**< data to pass to ownercreate */
    995 )
    996{
    997 assert(exprhdlr != NULL);
    998 assert(set != NULL);
    999 assert(expr != NULL);
    1000
    1001 *expr = NULL;
    1002
    1003 if( exprhdlr->parse == NULL )
    1004 {
    1005 /* TODO we could just look for a comma separated list of operands and try to initialize the expr with this one?
    1006 * That would be sufficient for sin, cos, exp, log, abs, for example.
    1007 */
    1008 SCIPdebugMessage("Expression handler <%s> has no parsing method.\n", SCIPexprhdlrGetName(exprhdlr));
    1009 *success = FALSE;
    1010 return SCIP_OKAY;
    1011 }
    1012
    1013 /* give control to exprhdlr's parser */
    1014 SCIP_CALL( exprhdlr->parse(set->scip, exprhdlr, string, endstring, expr, success, ownercreate, ownercreatedata) );
    1015
    1016 assert(*success || (*expr == NULL));
    1017
    1018 return SCIP_OKAY;
    1019}
    1020
    1021/** calls the curvature check callback of an expression handler
    1022 *
    1023 * @see SCIP_DECL_EXPRCURVATURE
    1024 */
    1026 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1027 SCIP_SET* set, /**< global SCIP settings */
    1028 SCIP_EXPR* expr, /**< expression to check the curvature for */
    1029 SCIP_EXPRCURV exprcurvature, /**< desired curvature of this expression */
    1030 SCIP_Bool* success, /**< buffer to store whether the desired curvature be obtained */
    1031 SCIP_EXPRCURV* childcurv /**< array to store required curvature for each child */
    1032 )
    1033{
    1034 assert(exprhdlr != NULL);
    1035 assert(set != NULL);
    1036 assert(expr != NULL);
    1037 assert(expr->exprhdlr == exprhdlr);
    1038 assert(success != NULL);
    1039
    1040 *success = FALSE;
    1041
    1042 if( exprhdlr->curvature != NULL )
    1043 {
    1044 SCIP_CALL( exprhdlr->curvature(set->scip, expr, exprcurvature, success, childcurv) );
    1045 }
    1046
    1047 return SCIP_OKAY;
    1048}
    1049
    1050/** calls the monotonicity check callback of an expression handler
    1051 *
    1052 * @see SCIP_DECL_EXPRMONOTONICITY
    1053 */
    1055 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1056 SCIP_SET* set, /**< global SCIP settings */
    1057 SCIP_EXPR* expr, /**< expression to check the monotonicity for */
    1058 int childidx, /**< index of the considered child expression */
    1059 SCIP_MONOTONE* result /**< buffer to store the monotonicity */
    1060 )
    1061{
    1062 assert(exprhdlr != NULL);
    1063 assert(set != NULL);
    1064 assert(expr != NULL);
    1065 assert(expr->exprhdlr == exprhdlr);
    1066 assert(result != NULL);
    1067
    1068 *result = SCIP_MONOTONE_UNKNOWN;
    1069
    1070 /* check whether the expression handler implements the monotonicity callback */
    1071 if( exprhdlr->monotonicity != NULL )
    1072 {
    1073 SCIP_CALL( exprhdlr->monotonicity(set->scip, expr, childidx, result) );
    1074 }
    1075
    1076 return SCIP_OKAY;
    1077}
    1078
    1079/** calls the integrality check callback of an expression handler
    1080 *
    1081 * @see SCIP_DECL_EXPRINTEGRALITY
    1082 */
    1084 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1085 SCIP_SET* set, /**< global SCIP settings */
    1086 SCIP_EXPR* expr, /**< expression to check integrality for */
    1087 SCIP_IMPLINTTYPE* integrality /**< buffer to store the integrality level of the expression */
    1088 )
    1089{
    1090 assert(exprhdlr != NULL);
    1091 assert(set != NULL);
    1092 assert(expr != NULL);
    1093 assert(expr->exprhdlr == exprhdlr);
    1094 assert(integrality != NULL);
    1095
    1096 *integrality = SCIP_IMPLINTTYPE_NONE;
    1097
    1098 /* check whether the expression handler implements the monotonicity callback */
    1099 if( exprhdlr->integrality != NULL )
    1100 {
    1101 SCIP_CALL( exprhdlr->integrality(set->scip, expr, integrality) );
    1102 }
    1103
    1104 return SCIP_OKAY;
    1105}
    1106
    1107/** calls the hash callback of an expression handler
    1108 *
    1109 * The method hashes an expression by taking the hashes of its children into account.
    1110 *
    1111 * @see SCIP_DECL_EXPRHASH
    1112 */
    1114 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1115 SCIP_SET* set, /**< global SCIP settings */
    1116 SCIP_EXPR* expr, /**< expression to be hashed */
    1117 unsigned int* hashkey, /**< buffer to store the hash value */
    1118 unsigned int* childrenhashes /**< array with hash values of children */
    1119 )
    1120{
    1121 assert(exprhdlr != NULL);
    1122 assert(set != NULL);
    1123 assert(expr != NULL);
    1124 assert(expr->exprhdlr == exprhdlr);
    1125 assert(hashkey != NULL);
    1126 assert(childrenhashes != NULL || expr->nchildren == 0);
    1127
    1128 if( expr->exprhdlr->hash != NULL )
    1129 {
    1130 SCIP_CALL( expr->exprhdlr->hash(set->scip, expr, hashkey, childrenhashes) );
    1131 }
    1132 else
    1133 {
    1134 int i;
    1135
    1136 /* compute initial hash from expression handler name if callback is not implemented
    1137 * this can lead to more collisions and thus a larger number of expensive expression compare calls
    1138 */
    1139 *hashkey = 0;
    1140 for( i = 0; expr->exprhdlr->name[i] != '\0'; i++ )
    1141 *hashkey += (unsigned int) expr->exprhdlr->name[i]; /*lint !e571*/
    1142
    1143 *hashkey = SCIPcalcFibHash((SCIP_Real)*hashkey);
    1144
    1145 /* now make use of the hashkeys of the children */
    1146 for( i = 0; i < expr->nchildren; ++i )
    1147 *hashkey ^= childrenhashes[i];
    1148 }
    1149
    1150 return SCIP_OKAY;
    1151}
    1152
    1153/** calls the compare callback of an expression handler
    1154 *
    1155 * The method receives two expressions, expr1 and expr2, and returns
    1156 * - -1 if expr1 < expr2,
    1157 * - 0 if expr1 = expr2,
    1158 * - 1 if expr1 > expr2.
    1159 *
    1160 * @see SCIP_DECL_EXPRCOMPARE
    1161 */
    1163 SCIP_SET* set, /**< global SCIP settings */
    1164 SCIP_EXPR* expr1, /**< first expression in comparison */
    1165 SCIP_EXPR* expr2 /**< second expression in comparison */
    1166 )
    1167{
    1168 int i;
    1169
    1170 assert(expr1 != NULL);
    1171 assert(expr2 != NULL);
    1172 assert(expr1->exprhdlr == expr2->exprhdlr);
    1173
    1174 if( expr1->exprhdlr->compare != NULL )
    1175 {
    1176 /* enforces OR1-OR4 */
    1177 return expr1->exprhdlr->compare(set->scip, expr1, expr2);
    1178 }
    1179
    1180 /* enforces OR5: default comparison method of expressions of the same type:
    1181 * expr1 < expr2 if and only if expr1_i = expr2_i for all i < k and expr1_k < expr2_k.
    1182 * if there is no such k, use number of children to decide
    1183 * if number of children is equal, both expressions are equal
    1184 * @note: Warning, this method doesn't know about expression data. So if your expressions have special data,
    1185 * you must implement the compare callback: SCIP_DECL_EXPRCOMPARE
    1186 */
    1187 for( i = 0; i < expr1->nchildren && i < expr2->nchildren; ++i )
    1188 {
    1189 int compareresult = SCIPexprCompare(set, expr1->children[i], expr2->children[i]);
    1190 if( compareresult != 0 )
    1191 return compareresult;
    1192 }
    1193
    1194 return expr1->nchildren == expr2->nchildren ? 0 : expr1->nchildren < expr2->nchildren ? -1 : 1;
    1195}
    1196
    1197/** calls the evaluation callback of an expression handler
    1198 *
    1199 * The method evaluates an expression by taking the values of its children into account.
    1200 *
    1201 * Further, allows to evaluate w.r.t. given expression and children values instead of those stored in children expressions.
    1202 *
    1203 * @see SCIP_DECL_EXPREVAL
    1204 */
    1206 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1207 SCIP_SET* set, /**< global SCIP settings */
    1208 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
    1209 SCIP_EXPR* expr, /**< expression to be evaluated */
    1210 SCIP_Real* val, /**< buffer to store value of expression */
    1211 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
    1212 SCIP_SOL* sol /**< solution that is evaluated (can be NULL) */
    1213 )
    1214{
    1215 SCIP_Real* origvals = NULL;
    1216
    1217 assert(exprhdlr != NULL);
    1218 assert(set != NULL);
    1219 assert(expr != NULL);
    1220 assert(expr->exprhdlr == exprhdlr);
    1221 assert(exprhdlr->eval != NULL);
    1222 assert(val != NULL);
    1223
    1224 /* temporarily overwrite the evalvalue in all children with values from childrenvals */
    1225 if( childrenvals != NULL && expr->nchildren > 0 )
    1226 {
    1227 int c;
    1228
    1229 assert(bufmem != NULL);
    1230
    1231 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origvals, expr->nchildren) );
    1232
    1233 for( c = 0; c < expr->nchildren; ++c )
    1234 {
    1235 origvals[c] = expr->children[c]->evalvalue;
    1236 expr->children[c]->evalvalue = childrenvals[c];
    1237 }
    1238 }
    1239
    1240 /* call expression eval callback */
    1241 SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
    1242
    1243 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
    1244 if( !SCIPisFinite(*val) )
    1245 *val = SCIP_INVALID;
    1246
    1247 /* restore original evalvalues in children */
    1248 if( origvals != NULL )
    1249 {
    1250 int c;
    1251 for( c = 0; c < expr->nchildren; ++c )
    1252 expr->children[c]->evalvalue = origvals[c];
    1253
    1254 BMSfreeBufferMemoryArray(bufmem, &origvals);
    1255 }
    1256
    1257 return SCIP_OKAY;
    1258}
    1259
    1260/** calls the backward derivative evaluation callback of an expression handler
    1261 *
    1262 * The method should compute the partial derivative of expr w.r.t its child at childidx.
    1263 * That is, it returns
    1264 * \f[
    1265 * \frac{\partial \text{expr}}{\partial \text{child}_{\text{childidx}}}
    1266 * \f]
    1267 *
    1268 * Further, allows to differentiate w.r.t. given expression and children values instead of those stored in children expressions.
    1269 *
    1270 * @see SCIP_DECL_EXPRBWDIFF
    1271 */
    1273 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1274 SCIP_SET* set, /**< global SCIP settings */
    1275 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
    1276 SCIP_EXPR* expr, /**< expression to be differentiated */
    1277 int childidx, /**< index of the child */
    1278 SCIP_Real* derivative, /**< buffer to store the partial derivative w.r.t. the i-th children */
    1279 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
    1280 SCIP_Real exprval /**< value for expression, used only if childrenvals is not NULL */
    1281 )
    1282{
    1283 SCIP_Real* origchildrenvals;
    1284 SCIP_Real origexprval = SCIP_INVALID;
    1285 int c;
    1286
    1287 assert(exprhdlr != NULL);
    1288 assert(set != NULL);
    1289 assert(expr != NULL);
    1290 assert(expr->exprhdlr == exprhdlr);
    1291 assert(derivative != NULL);
    1292
    1293 if( exprhdlr->bwdiff == NULL )
    1294 {
    1295 *derivative = SCIP_INVALID;
    1296 return SCIP_OKAY;
    1297 }
    1298
    1299 if( childrenvals != NULL )
    1300 {
    1301 /* temporarily overwrite the evalvalue in all children and expr with values from childrenvals and exprval, resp. */
    1302 if( expr->nchildren > 0 )
    1303 {
    1304 assert(bufmem != NULL);
    1305 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origchildrenvals, expr->nchildren) );
    1306
    1307 for( c = 0; c < expr->nchildren; ++c )
    1308 {
    1309 origchildrenvals[c] = expr->children[c]->evalvalue;
    1310 expr->children[c]->evalvalue = childrenvals[c];
    1311 }
    1312 }
    1313
    1314 origexprval = expr->evalvalue;
    1315 expr->evalvalue = exprval;
    1316 }
    1317
    1318 SCIP_CALL( expr->exprhdlr->bwdiff(set->scip, expr, childidx, derivative) );
    1319
    1320 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
    1321 if( !SCIPisFinite(*derivative) )
    1322 *derivative = SCIP_INVALID;
    1323
    1324 /* restore original evalvalues in children */
    1325 if( childrenvals != NULL )
    1326 {
    1327 if( expr->nchildren > 0 )
    1328 {
    1329 for( c = 0; c < expr->nchildren; ++c )
    1330 expr->children[c]->evalvalue = origchildrenvals[c]; /*lint !e644*/
    1331
    1332 BMSfreeBufferMemoryArray(bufmem, &origchildrenvals);
    1333 }
    1334
    1335 expr->evalvalue = origexprval;
    1336 }
    1337
    1338 return SCIP_OKAY;
    1339}
    1340
    1341/** calls the forward differentiation callback of an expression handler
    1342 *
    1343 * @see SCIP_DECL_EXPRFWDIFF
    1344 */
    1346 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1347 SCIP_SET* set, /**< global SCIP settings */
    1348 SCIP_EXPR* expr, /**< expression to be differentiated */
    1349 SCIP_Real* dot, /**< buffer to store derivative value */
    1350 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
    1351 )
    1352{
    1353 assert(exprhdlr != NULL);
    1354 assert(set != NULL);
    1355 assert(expr != NULL);
    1356 assert(expr->exprhdlr == exprhdlr);
    1357 assert(dot != NULL);
    1358
    1359 if( exprhdlr->fwdiff == NULL )
    1360 {
    1361 *dot = SCIP_INVALID;
    1362 return SCIP_OKAY;
    1363 }
    1364
    1365 SCIP_CALL( exprhdlr->fwdiff(set->scip, expr, dot, direction) );
    1366
    1367 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
    1368 if( !SCIPisFinite(*dot) )
    1369 *dot = SCIP_INVALID;
    1370
    1371 return SCIP_OKAY;
    1372}
    1373
    1374/** calls the evaluation and forward-differentiation callback of an expression handler
    1375 *
    1376 * The method evaluates an expression by taking the values of its children into account.
    1377 * The method differentiates an expression by taking the values and directional derivatives of its children into account.
    1378 *
    1379 * Further, allows to evaluate and differentiate w.r.t. given values for children instead of those stored in children expressions.
    1380 *
    1381 * It probably doesn't make sense to call this function for a variable-expression if sol and/or direction are not given.
    1382 *
    1383 * @see SCIP_DECL_EXPREVAL
    1384 * @see SCIP_DECL_EXPRFWDIFF
    1385 */
    1387 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1388 SCIP_SET* set, /**< global SCIP settings */
    1389 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
    1390 SCIP_EXPR* expr, /**< expression to be evaluated */
    1391 SCIP_Real* val, /**< buffer to store value of expression */
    1392 SCIP_Real* dot, /**< buffer to store derivative value */
    1393 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
    1394 SCIP_SOL* sol, /**< solution that is evaluated (can be NULL) */
    1395 SCIP_Real* childrendirs, /**< directional derivatives for children, or NULL if dot-values stored in children should be used */
    1396 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions, can be NULL if childrendirs is given) */
    1397 )
    1398{
    1399 SCIP_Real origval;
    1400 SCIP_Real* origvals = NULL;
    1401 SCIP_Real* origdots = NULL;
    1402
    1403 assert(exprhdlr != NULL);
    1404 assert(set != NULL);
    1405 assert(expr != NULL);
    1406 assert(expr->exprhdlr == exprhdlr);
    1407 assert(exprhdlr->eval != NULL);
    1408 assert(val != NULL);
    1409 assert(dot != NULL);
    1410
    1411 /* temporarily overwrite the evalvalue in all children with values from childrenvals */
    1412 if( childrenvals != NULL && expr->nchildren > 0 )
    1413 {
    1414 int c;
    1415
    1416 assert(bufmem != NULL);
    1417
    1418 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origvals, expr->nchildren) );
    1419
    1420 for( c = 0; c < expr->nchildren; ++c )
    1421 {
    1422 origvals[c] = expr->children[c]->evalvalue;
    1423 expr->children[c]->evalvalue = childrenvals[c];
    1424 }
    1425 }
    1426
    1427 /* temporarily overwrite the dot in all children with values from childrendirs */
    1428 if( childrendirs != NULL && expr->nchildren > 0 )
    1429 {
    1430 int c;
    1431
    1432 assert(bufmem != NULL);
    1433
    1434 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origdots, expr->nchildren) );
    1435
    1436 for( c = 0; c < expr->nchildren; ++c )
    1437 {
    1438 origdots[c] = expr->children[c]->dot;
    1439 expr->children[c]->dot = childrendirs[c];
    1440 }
    1441 }
    1442
    1443 /* remember original value */
    1444 origval = expr->evalvalue;
    1445
    1446 /* call expression eval callback */
    1447 SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
    1448
    1449 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
    1450 if( !SCIPisFinite(*val) )
    1451 *val = SCIP_INVALID;
    1452
    1453 /* temporarily overwrite evalvalue of expr, since some exprhdlr (e.g., product) access this value in fwdiff */
    1454 expr->evalvalue = *val;
    1455
    1456 /* call forward-differentiation callback (if available) */
    1457 SCIP_CALL( SCIPexprhdlrFwDiffExpr(exprhdlr, set, expr, dot, direction) );
    1458
    1459 /* restore original value */
    1460 expr->evalvalue = origval;
    1461
    1462 /* restore original dots in children */
    1463 if( origdots != NULL )
    1464 {
    1465 int c;
    1466 for( c = 0; c < expr->nchildren; ++c )
    1467 expr->children[c]->dot = origdots[c];
    1468
    1469 BMSfreeBufferMemoryArray(bufmem, &origdots);
    1470 }
    1471
    1472 /* restore original evalvalues in children */
    1473 if( origvals != NULL )
    1474 {
    1475 int c;
    1476 for( c = 0; c < expr->nchildren; ++c )
    1477 expr->children[c]->evalvalue = origvals[c];
    1478
    1479 BMSfreeBufferMemoryArray(bufmem, &origvals);
    1480 }
    1481
    1482 return SCIP_OKAY;
    1483}
    1484
    1485/** calls the evaluation callback for Hessian directions (backward over forward) of an expression handler
    1486 *
    1487 * @see SCIP_DECL_EXPRBWFWDIFF
    1488 */
    1490 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1491 SCIP_SET* set, /**< global SCIP settings */
    1492 SCIP_EXPR* expr, /**< expression to be differentiated */
    1493 int childidx, /**< index of the child */
    1494 SCIP_Real* bardot, /**< buffer to store derivative value */
    1495 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
    1496 )
    1497{
    1498 assert(exprhdlr != NULL);
    1499 assert(set != NULL);
    1500 assert(expr != NULL);
    1501 assert(expr->exprhdlr == exprhdlr);
    1502 assert(childidx >= 0);
    1503 assert(childidx < expr->nchildren);
    1504 assert(bardot != NULL);
    1505
    1506 if( exprhdlr->bwfwdiff == NULL )
    1507 {
    1508 *bardot = SCIP_INVALID;
    1509 return SCIP_OKAY;
    1510 }
    1511
    1512 SCIP_CALL( expr->exprhdlr->bwfwdiff(set->scip, expr, childidx, bardot, direction) );
    1513
    1514 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
    1515 if( !SCIPisFinite(*bardot) )
    1516 *bardot = SCIP_INVALID;
    1517
    1518 return SCIP_OKAY;
    1519}
    1520
    1521/** calls the interval evaluation callback of an expression handler
    1522 *
    1523 * @see SCIP_DECL_EXPRINTEVAL
    1524 */
    1526 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1527 SCIP_SET* set, /**< global SCIP settings */
    1528 SCIP_EXPR* expr, /**< expression to be evaluated */
    1529 SCIP_INTERVAL* interval, /**< buffer where to store interval */
    1530 SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), /**< callback to be called when interval-evaluating a variable */
    1531 void* intevalvardata /**< data to be passed to intevalvar callback */
    1532 )
    1533{
    1534 assert(exprhdlr != NULL);
    1535 assert(set != NULL);
    1536 assert(expr != NULL);
    1537 assert(expr->exprhdlr == exprhdlr);
    1538 assert(interval != NULL);
    1539
    1540 if( exprhdlr->inteval != NULL )
    1541 {
    1542 SCIPclockStart(exprhdlr->intevaltime, set);
    1543 SCIP_CALL( exprhdlr->inteval(set->scip, expr, interval, intevalvar, intevalvardata) );
    1544 SCIPclockStop(exprhdlr->intevaltime, set);
    1545
    1546 ++exprhdlr->nintevalcalls;
    1547 }
    1548
    1549 return SCIP_OKAY;
    1550}
    1551
    1552/** calls the estimator callback of an expression handler
    1553 *
    1554 * @see SCIP_DECL_EXPRESTIMATE
    1555 */
    1557 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1558 SCIP_SET* set, /**< global SCIP settings */
    1559 SCIP_EXPR* expr, /**< expression to be estimated */
    1560 SCIP_INTERVAL* localbounds, /**< current bounds for children */
    1561 SCIP_INTERVAL* globalbounds, /**< global bounds for children */
    1562 SCIP_Real* refpoint, /**< children values for the reference point where to estimate */
    1563 SCIP_Bool overestimate, /**< whether the expression needs to be over- or underestimated */
    1564 SCIP_Real targetvalue, /**< a value that the estimator shall exceed, can be +/-infinity */
    1565 SCIP_Real* coefs, /**< array to store coefficients of estimator */
    1566 SCIP_Real* constant, /**< buffer to store constant part of estimator */
    1567 SCIP_Bool* islocal, /**< buffer to store whether estimator is valid locally only */
    1568 SCIP_Bool* success, /**< buffer to indicate whether an estimator could be computed */
    1569 SCIP_Bool* branchcand /**< array to indicate which children (not) to consider for branching */
    1570 )
    1571{
    1572 assert(exprhdlr != NULL);
    1573 assert(set != NULL);
    1574 assert(expr != NULL);
    1575 assert(expr->exprhdlr == exprhdlr);
    1576 assert(coefs != NULL);
    1577 assert(islocal != NULL);
    1578 assert(success != NULL);
    1579
    1580 *success = FALSE;
    1581
    1582 if( exprhdlr->estimate != NULL )
    1583 {
    1584 SCIPclockStart(exprhdlr->estimatetime, set);
    1585 SCIP_CALL( exprhdlr->estimate(set->scip, expr, localbounds, globalbounds, refpoint, overestimate, targetvalue,
    1586 coefs, constant, islocal, success, branchcand) );
    1587 SCIPclockStop(exprhdlr->estimatetime, set);
    1588
    1589 /* update statistics */
    1590 ++exprhdlr->nestimatecalls;
    1591 }
    1592
    1593 return SCIP_OKAY;
    1594}
    1595
    1596/** calls the intitial estimators callback of an expression handler
    1597 *
    1598 * @see SCIP_DECL_EXPRINITESTIMATES
    1599 */
    1601 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1602 SCIP_SET* set, /**< global SCIP settings */
    1603 SCIP_EXPR* expr, /**< expression to be estimated */
    1604 SCIP_INTERVAL* bounds, /**< bounds for children */
    1605 SCIP_Bool overestimate, /**< whether the expression shall be overestimated or underestimated */
    1606 SCIP_Real* coefs[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store coefficients of computed estimators */
    1607 SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store constant of computed estimators */
    1608 int* nreturned /**< buffer to store number of estimators that have been computed */
    1609 )
    1610{
    1611 assert(exprhdlr != NULL);
    1612 assert(set != NULL);
    1613 assert(expr != NULL);
    1614 assert(expr->exprhdlr == exprhdlr);
    1615 assert(nreturned != NULL);
    1616
    1617 *nreturned = 0;
    1618
    1619 if( exprhdlr->initestimates )
    1620 {
    1622 SCIP_CALL( exprhdlr->initestimates(set->scip, expr, bounds, overestimate, coefs, constant, nreturned) );
    1624
    1625 ++exprhdlr->nestimatecalls;
    1626 }
    1627
    1628 return SCIP_OKAY;
    1629}
    1630
    1631/** calls the simplification callback of an expression handler
    1632 *
    1633 * @see SCIP_DECL_EXPRSIMPLIFY
    1634 */
    1636 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1637 SCIP_SET* set, /**< global SCIP settings */
    1638 SCIP_EXPR* expr, /**< expression to simplify */
    1639 SCIP_EXPR** simplifiedexpr, /**< buffer to store the simplified expression */
    1640 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
    1641 void* ownercreatedata /**< data to pass to ownercreate */
    1642 )
    1643{
    1644 assert(exprhdlr != NULL);
    1645 assert(set != NULL);
    1646 assert(expr != NULL);
    1647 assert(expr->exprhdlr == exprhdlr);
    1648 assert(simplifiedexpr != NULL);
    1649
    1650 if( exprhdlr->simplify != NULL )
    1651 {
    1653 SCIP_CALL( exprhdlr->simplify(set->scip, expr, simplifiedexpr, ownercreate, ownercreatedata) );
    1655
    1656 /* update statistics */
    1657 ++exprhdlr->nsimplifycalls;
    1658 if( expr != *simplifiedexpr )
    1659 ++exprhdlr->nsimplified;
    1660 }
    1661 else
    1662 {
    1663 *simplifiedexpr = expr;
    1664
    1665 /* if an expression handler doesn't implement simplify, we assume that it is already simplified
    1666 * we have to capture it, since it must simulate a "normal" simplified call in which a new expression is created
    1667 */
    1668 SCIPexprCapture(expr);
    1669 }
    1670
    1671 return SCIP_OKAY;
    1672}
    1673
    1674/** calls the reverse propagation callback of an expression handler
    1675 *
    1676 * The method propagates given bounds over the children of an expression.
    1677 *
    1678 * @see SCIP_DECL_EXPRREVERSEPROP
    1679 */
    1681 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1682 SCIP_SET* set, /**< global SCIP settings */
    1683 SCIP_EXPR* expr, /**< expression to propagate */
    1684 SCIP_INTERVAL bounds, /**< the bounds on the expression that should be propagated */
    1685 SCIP_INTERVAL* childrenbounds, /**< array to store computed bounds for children, initialized with current activity */
    1686 SCIP_Bool* infeasible /**< buffer to store whether a children bounds were propagated to an empty interval */
    1687 )
    1688{
    1689 assert(exprhdlr != NULL);
    1690 assert(set != NULL);
    1691 assert(expr != NULL);
    1692 assert(expr->exprhdlr == exprhdlr);
    1693 assert(childrenbounds != NULL || expr->nchildren == 0);
    1694 assert(infeasible != NULL);
    1695
    1696 *infeasible = FALSE;
    1697
    1698 if( exprhdlr->reverseprop != NULL )
    1699 {
    1700 SCIPclockStart(exprhdlr->proptime, set);
    1701 SCIP_CALL( exprhdlr->reverseprop(set->scip, expr, bounds, childrenbounds, infeasible) );
    1702 SCIPclockStop(exprhdlr->proptime, set);
    1703
    1704 /* update statistics */
    1705 if( *infeasible )
    1706 ++expr->exprhdlr->ncutoffs;
    1707 ++expr->exprhdlr->npropcalls;
    1708 }
    1709
    1710 return SCIP_OKAY;
    1711}
    1712
    1713/**@name Expression Methods */
    1714/**@{ */
    1715
    1716/* from expr.h */
    1717
    1718#ifdef NDEBUG
    1719#undef SCIPexprCapture
    1720#undef SCIPexprIsVar
    1721#undef SCIPexprIsValue
    1722#undef SCIPexprIsSum
    1723#undef SCIPexprIsProduct
    1724#undef SCIPexprIsPower
    1725#endif
    1726
    1727/** creates and captures an expression with given expression data and children */
    1729 SCIP_SET* set, /**< global SCIP settings */
    1730 BMS_BLKMEM* blkmem, /**< block memory */
    1731 SCIP_EXPR** expr, /**< pointer where to store expression */
    1732 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
    1733 SCIP_EXPRDATA* exprdata, /**< expression data (expression assumes ownership) */
    1734 int nchildren, /**< number of children */
    1735 SCIP_EXPR** children, /**< children (can be NULL if nchildren is 0) */
    1736 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
    1737 void* ownercreatedata /**< data to pass to ownercreate */
    1738 )
    1739{
    1740 int c;
    1741
    1742 assert(set != NULL);
    1743 assert(blkmem != NULL);
    1744 assert(expr != NULL);
    1745 assert(exprhdlr != NULL);
    1746 assert(children != NULL || nchildren == 0);
    1747 assert(exprdata == NULL || exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
    1748 assert(exprdata == NULL || exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
    1749
    1750 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, expr) );
    1751
    1752 (*expr)->exprhdlr = exprhdlr;
    1753 (*expr)->exprdata = exprdata;
    1754 (*expr)->activitytag = -1; /* to be less than initial domchgcount */
    1755 (*expr)->curvature = SCIP_EXPRCURV_UNKNOWN;
    1756
    1757 /* initialize activity to entire interval */
    1758 SCIPintervalSetEntire(SCIP_INTERVAL_INFINITY, &(*expr)->activity);
    1759
    1760 if( nchildren > 0 )
    1761 {
    1762 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*expr)->children, children, nchildren) );
    1763 (*expr)->nchildren = nchildren;
    1764 (*expr)->childrensize = nchildren;
    1765
    1766 for( c = 0; c < nchildren; ++c )
    1767 SCIPexprCapture((*expr)->children[c]);
    1768 }
    1769
    1770 SCIPexprCapture(*expr);
    1771
    1772 ++exprhdlr->ncreated;
    1773
    1774 /* initializes the ownerdata */
    1775 if( ownercreate != NULL )
    1776 {
    1777 SCIP_CALL( ownercreate(set->scip, *expr, &(*expr)->ownerdata, &(*expr)->ownerfree, &(*expr)->ownerprint,
    1778 &(*expr)->ownerevalactivity, ownercreatedata) );
    1779 }
    1780
    1781 return SCIP_OKAY;
    1782}
    1783
    1784/** appends child to the children list of expr */
    1786 SCIP_SET* set, /**< global SCIP settings */
    1787 BMS_BLKMEM* blkmem, /**< block memory */
    1788 SCIP_EXPR* expr, /**< expression */
    1789 SCIP_EXPR* child /**< expression to be appended */
    1790 )
    1791{
    1792 assert(set != NULL);
    1793 assert(blkmem != NULL);
    1794 assert(child != NULL);
    1795 assert(expr->nchildren <= expr->childrensize);
    1796
    1797 if( expr->nchildren == expr->childrensize )
    1798 {
    1800 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &expr->children, expr->nchildren, expr->childrensize) );
    1801 }
    1802
    1803 expr->children[expr->nchildren] = child;
    1804 ++expr->nchildren;
    1805
    1806 /* capture child */
    1807 SCIPexprCapture(child);
    1808
    1809 return SCIP_OKAY;
    1810}
    1811
    1812/** overwrites/replaces a child of an expressions
    1813 *
    1814 * @note the old child is released and the newchild is captured, unless they are the same (=same pointer)
    1815 */
    1817 SCIP_SET* set, /**< global SCIP settings */
    1818 SCIP_STAT* stat, /**< dynamic problem statistics */
    1819 BMS_BLKMEM* blkmem, /**< block memory */
    1820 SCIP_EXPR* expr, /**< expression where a child is going to be replaced */
    1821 int childidx, /**< index of child being replaced */
    1822 SCIP_EXPR* newchild /**< the new child */
    1823 )
    1824{
    1825 assert(set != NULL);
    1826 assert(blkmem != NULL);
    1827 assert(expr != NULL);
    1828 assert(newchild != NULL);
    1829 assert(childidx >= 0);
    1830 assert(childidx < expr->nchildren);
    1831
    1832 /* do nothing if child is not changing */
    1833 if( newchild == expr->children[childidx] )
    1834 return SCIP_OKAY;
    1835
    1836 /* capture new child (do this before releasing the old child in case there are equal */
    1837 SCIPexprCapture(newchild);
    1838
    1839 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[childidx])) );
    1840 expr->children[childidx] = newchild;
    1841
    1842 return SCIP_OKAY;
    1843}
    1844
    1845/** remove all children of expr */
    1847 SCIP_SET* set, /**< global SCIP settings */
    1848 SCIP_STAT* stat, /**< dynamic problem statistics */
    1849 BMS_BLKMEM* blkmem, /**< block memory */
    1850 SCIP_EXPR* expr /**< expression */
    1851 )
    1852{
    1853 int c;
    1854
    1855 assert(set != NULL);
    1856 assert(blkmem != NULL);
    1857 assert(expr != NULL);
    1858
    1859 for( c = 0; c < expr->nchildren; ++c )
    1860 {
    1861 assert(expr->children[c] != NULL);
    1862 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[c])) );
    1863 }
    1864
    1865 expr->nchildren = 0;
    1866
    1867 return SCIP_OKAY;
    1868}
    1869
    1870/** copies an expression including subexpressions
    1871 *
    1872 * @note If copying fails due to an expression handler not being available in the targetscip, then *targetexpr will be set to NULL.
    1873 *
    1874 * For all or some expressions, a mapping to an existing expression can be specified via the mapexpr callback.
    1875 * The mapped expression (including its children) will not be copied in this case and its ownerdata will not be touched.
    1876 * If, however, the mapexpr callback returns NULL for the targetexpr, then the expr will be copied in the usual way.
    1877 */
    1879 SCIP_SET* set, /**< global SCIP settings */
    1880 SCIP_STAT* stat, /**< dynamic problem statistics */
    1881 BMS_BLKMEM* blkmem, /**< block memory */
    1882 SCIP_SET* targetset, /**< global SCIP settings data structure where target expression will live */
    1883 SCIP_STAT* targetstat, /**< dynamic problem statistics in target SCIP */
    1884 BMS_BLKMEM* targetblkmem, /**< block memory in target SCIP */
    1885 SCIP_EXPR* sourceexpr, /**< expression to be copied */
    1886 SCIP_EXPR** targetexpr, /**< buffer to store pointer to copy of source expression */
    1887 SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), /**< expression mapping function, or NULL for creating new expressions */
    1888 void* mapexprdata, /**< data of expression mapping function */
    1889 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
    1890 void* ownercreatedata /**< data to pass to ownercreate */
    1891 )
    1892{
    1893 SCIP_EXPRITER* it;
    1894 SCIP_EXPRITER_USERDATA expriteruserdata;
    1895 SCIP_EXPR* expr;
    1896 SCIP* sourcescip = set->scip; /* SCIP data structure corresponding to source expression */
    1897 SCIP* targetscip = targetset->scip; /* SCIP data structure where target expression will live */
    1898
    1899 assert(set != NULL);
    1900 assert(stat != NULL);
    1901 assert(blkmem != NULL);
    1902 assert(targetset != NULL);
    1903 assert(sourceexpr != NULL);
    1904 assert(targetexpr != NULL);
    1905 assert(sourcescip != NULL);
    1906 assert(targetscip != NULL);
    1907
    1908 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    1909 SCIP_CALL( SCIPexpriterInit(it, sourceexpr, SCIP_EXPRITER_DFS, TRUE) ); /*TODO use FALSE, i.e., don't duplicate common subexpr? */
    1911
    1912 expr = sourceexpr;
    1913 while( !SCIPexpriterIsEnd(it) )
    1914 {
    1915 switch( SCIPexpriterGetStageDFS(it) )
    1916 {
    1918 {
    1919 /* create expr that will hold the copy */
    1920 SCIP_EXPRHDLR* targetexprhdlr;
    1921 SCIP_EXPRDATA* targetexprdata;
    1922 SCIP_EXPR* exprcopy = NULL;
    1923
    1924 if( mapexpr != NULL )
    1925 {
    1926 SCIP_CALL( mapexpr(targetscip, &exprcopy, sourcescip, expr, ownercreate, ownercreatedata, mapexprdata) );
    1927 if( exprcopy != NULL )
    1928 {
    1929 /* map callback gave us an expression to use for the copy */
    1930 /* store targetexpr */
    1931 expriteruserdata.ptrval = exprcopy;
    1932 SCIPexpriterSetCurrentUserData(it, expriteruserdata);
    1933
    1934 /* skip subexpression (assume that exprcopy is a complete copy) and continue */
    1935 expr = SCIPexpriterSkipDFS(it);
    1936 continue;
    1937 }
    1938 }
    1939
    1940 /* get the exprhdlr of the target scip */
    1941 if( targetscip != sourcescip )
    1942 {
    1943 targetexprhdlr = SCIPsetFindExprhdlr(targetset, expr->exprhdlr->name);
    1944
    1945 if( targetexprhdlr == NULL )
    1946 {
    1947 /* expression handler not in target scip (probably did not have a copy callback) -> abort */
    1948 expriteruserdata.ptrval = NULL;
    1949 SCIPexpriterSetCurrentUserData(it, expriteruserdata);
    1950
    1951 expr = SCIPexpriterSkipDFS(it);
    1952 continue;
    1953 }
    1954 }
    1955 else
    1956 {
    1957 targetexprhdlr = expr->exprhdlr;
    1958 }
    1959 assert(targetexprhdlr != NULL);
    1960
    1961 /* copy expression data */
    1962 if( expr->exprdata != NULL )
    1963 {
    1964 assert(expr->exprhdlr->copydata != NULL);
    1965 SCIP_CALL( expr->exprhdlr->copydata(targetscip, targetexprhdlr, &targetexprdata, sourcescip, expr) );
    1966 }
    1967 else
    1968 {
    1969 targetexprdata = NULL;
    1970 }
    1971
    1972 /* create in targetexpr an expression of the same type as expr, but without children for now */
    1973 SCIP_CALL( SCIPexprCreate(targetset, targetblkmem, &exprcopy, targetexprhdlr, targetexprdata, 0, NULL,
    1974 ownercreate, ownercreatedata) );
    1975
    1976 /* store targetexpr */
    1977 expriteruserdata.ptrval = exprcopy;
    1978 SCIPexpriterSetCurrentUserData(it, expriteruserdata);
    1979
    1980 break;
    1981 }
    1982
    1984 {
    1985 /* just visited child so a copy of himself should be available; append it */
    1986 SCIP_EXPR* exprcopy;
    1987 SCIP_EXPR* childcopy;
    1988
    1990
    1991 /* get copy of child */
    1993 if( childcopy == NULL )
    1994 {
    1995 /* abort */
    1996 /* release exprcopy (should free also the already copied children) */
    1997 SCIP_CALL( SCIPexprRelease(targetset, targetstat, targetblkmem, (SCIP_EXPR**)&exprcopy) );
    1998
    1999 expriteruserdata.ptrval = NULL;
    2000 SCIPexpriterSetCurrentUserData(it, expriteruserdata);
    2001
    2002 expr = SCIPexpriterSkipDFS(it);
    2003 continue;
    2004 }
    2005
    2006 /* append child to exprcopy */
    2007 SCIP_CALL( SCIPexprAppendChild(targetset, targetblkmem, exprcopy, childcopy) );
    2008
    2009 /* release childcopy (still captured by exprcopy) */
    2010 SCIP_CALL( SCIPexprRelease(targetset, targetstat, targetblkmem, &childcopy) );
    2011
    2012 break;
    2013 }
    2014
    2015 default:
    2016 /* we should never be called in this stage */
    2017 SCIPABORT();
    2018 break;
    2019 }
    2020
    2021 expr = SCIPexpriterGetNext(it);
    2022 }
    2023
    2024 /* the target expression should be stored in the userdata of the sourceexpr (can be NULL if aborted) */
    2025 *targetexpr = (SCIP_EXPR*)SCIPexpriterGetExprUserData(it, sourceexpr).ptrval;
    2026
    2027 SCIPexpriterFree(&it);
    2028
    2029 return SCIP_OKAY;
    2030}
    2031
    2032/** duplicates the given expression without its children */
    2034 SCIP_SET* set, /**< global SCIP settings */
    2035 BMS_BLKMEM* blkmem, /**< block memory */
    2036 SCIP_EXPR* expr, /**< original expression */
    2037 SCIP_EXPR** copyexpr, /**< buffer to store (shallow) duplicate of expr */
    2038 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
    2039 void* ownercreatedata /**< data to pass to ownercreate */
    2040 )
    2041{
    2042 SCIP_EXPRDATA* exprdatacopy = NULL;
    2043
    2044 assert(set != NULL);
    2045 assert(blkmem != NULL);
    2046 assert(expr != NULL);
    2047 assert(copyexpr != NULL);
    2048
    2049 /* copy expression data */
    2050 if( expr->exprdata != NULL )
    2051 {
    2052 assert(expr->exprhdlr->copydata != NULL);
    2053 SCIP_CALL( expr->exprhdlr->copydata(set->scip, expr->exprhdlr, &exprdatacopy, set->scip, expr) );
    2054 }
    2055
    2056 /* create expression with same handler and copied data, but without children */
    2057 SCIP_CALL( SCIPexprCreate(set, blkmem, copyexpr, expr->exprhdlr, exprdatacopy, 0, NULL, ownercreate,
    2058 ownercreatedata) );
    2059
    2060 return SCIP_OKAY;
    2061}
    2062
    2063/** captures an expression (increments usage count) */
    2065 SCIP_EXPR* expr /**< expression */
    2066 )
    2067{
    2068 assert(expr != NULL);
    2069
    2070 ++expr->nuses;
    2071}
    2072
    2073/** releases an expression (decrements usage count and possibly frees expression) */
    2075 SCIP_SET* set, /**< global SCIP settings */
    2076 SCIP_STAT* stat, /**< dynamic problem statistics */
    2077 BMS_BLKMEM* blkmem, /**< block memory */
    2078 SCIP_EXPR** expr /**< pointer to expression */
    2079 )
    2080{
    2081 SCIP_EXPRITER* it;
    2082 SCIP_EXPR* expr2;
    2083
    2084 assert(expr != NULL);
    2085 assert(*expr != NULL);
    2086 assert((*expr)->nuses > 0);
    2087
    2088 if( (*expr)->nuses > 1 )
    2089 {
    2090 --(*expr)->nuses;
    2091 *expr = NULL;
    2092
    2093 return SCIP_OKAY;
    2094 }
    2095
    2096 /* handle the root expr separately: free ownerdata, quaddata, and exprdata first */
    2097
    2098 /* call ownerfree callback, if given
    2099 * we intentially call this also if ownerdata is NULL, so owner can be notified without storing data
    2100 */
    2101 if( (*expr)->ownerfree != NULL )
    2102 {
    2103 SCIP_CALL( (*expr)->ownerfree(set->scip, *expr, &(*expr)->ownerdata) );
    2104 assert((*expr)->ownerdata == NULL);
    2105 }
    2106
    2107 /* free quadratic info */
    2108 SCIPexprFreeQuadratic(blkmem, *expr);
    2109
    2110 /* free expression data */
    2111 if( (*expr)->exprdata != NULL )
    2112 {
    2113 assert((*expr)->exprhdlr->freedata != NULL);
    2114 SCIP_CALL( (*expr)->exprhdlr->freedata(set->scip, *expr) );
    2115 }
    2116
    2117 /* now release and free children, where no longer in use */
    2118 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2121 for( expr2 = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it) ; )
    2122 {
    2123 /* expression should be used by its parent and maybe by the iterator (only the root!)
    2124 * in VISITEDCHILD we assert that expression is only used by its parent
    2125 */
    2126 assert(expr2 != NULL);
    2127 assert(0 <= expr2->nuses && expr2->nuses <= 2);
    2128
    2129 switch( SCIPexpriterGetStageDFS(it) )
    2130 {
    2132 {
    2133 /* check whether a child needs to be visited (nuses == 1)
    2134 * if not, then we still have to release it
    2135 */
    2136 SCIP_EXPR* child;
    2137
    2138 child = SCIPexpriterGetChildExprDFS(it);
    2139 if( child->nuses > 1 )
    2140 {
    2141 /* child is not going to be freed: just release it */
    2142 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &child) );
    2143 expr2 = SCIPexpriterSkipDFS(it);
    2144 continue;
    2145 }
    2146
    2147 assert(child->nuses == 1);
    2148
    2149 /* free child's quaddata, ownerdata, and exprdata when entering child */
    2150 if( child->ownerfree != NULL )
    2151 {
    2152 SCIP_CALL( child->ownerfree(set->scip, child, &child->ownerdata) );
    2153 assert(child->ownerdata == NULL);
    2154 }
    2155
    2156 /* free quadratic info */
    2157 SCIPexprFreeQuadratic(blkmem, child);
    2158
    2159 /* free expression data */
    2160 if( child->exprdata != NULL )
    2161 {
    2162 assert(child->exprhdlr->freedata != NULL);
    2163 SCIP_CALL( child->exprhdlr->freedata(set->scip, child) );
    2164 assert(child->exprdata == NULL);
    2165 }
    2166
    2167 break;
    2168 }
    2169
    2171 {
    2172 /* free child after visiting it */
    2173 SCIP_EXPR* child;
    2174
    2175 child = SCIPexpriterGetChildExprDFS(it);
    2176 /* child should only be used by its parent */
    2177 assert(child->nuses == 1);
    2178
    2179 /* child should have no data associated */
    2180 assert(child->exprdata == NULL);
    2181
    2182 /* free child expression */
    2183 SCIP_CALL( freeExpr(blkmem, &child) );
    2185
    2186 break;
    2187 }
    2188
    2189 default:
    2190 SCIPABORT(); /* we should never be called in this stage */
    2191 break;
    2192 }
    2193
    2194 expr2 = SCIPexpriterGetNext(it);
    2195 }
    2196
    2197 SCIPexpriterFree(&it);
    2198
    2199 /* handle the root expr separately: free its children and itself here */
    2200 SCIP_CALL( freeExpr(blkmem, expr) );
    2201
    2202 return SCIP_OKAY;
    2203}
    2204
    2205/** returns whether an expression is a variable expression */
    2207 SCIP_SET* set, /**< global SCIP settings */
    2208 SCIP_EXPR* expr /**< expression */
    2209 )
    2210{
    2211 assert(set != NULL);
    2212 assert(expr != NULL);
    2213
    2214 return expr->exprhdlr == set->exprhdlrvar;
    2215}
    2216
    2217/** returns whether an expression is a value expression */
    2219 SCIP_SET* set, /**< global SCIP settings */
    2220 SCIP_EXPR* expr /**< expression */
    2221 )
    2222{
    2223 assert(set != NULL);
    2224 assert(expr != NULL);
    2225
    2226 return expr->exprhdlr == set->exprhdlrval;
    2227}
    2228
    2229/** returns whether an expression is a sum expression */
    2231 SCIP_SET* set, /**< global SCIP settings */
    2232 SCIP_EXPR* expr /**< expression */
    2233 )
    2234{
    2235 assert(set != NULL);
    2236 assert(expr != NULL);
    2237
    2238 return expr->exprhdlr == set->exprhdlrsum;
    2239}
    2240
    2241/** returns whether an expression is a product expression */
    2243 SCIP_SET* set, /**< global SCIP settings */
    2244 SCIP_EXPR* expr /**< expression */
    2245 )
    2246{
    2247 assert(set != NULL);
    2248 assert(expr != NULL);
    2249
    2250 return expr->exprhdlr == set->exprhdlrproduct;
    2251}
    2252
    2253/** returns whether an expression is a power expression */
    2255 SCIP_SET* set, /**< global SCIP settings */
    2256 SCIP_EXPR* expr /**< expression */
    2257 )
    2258{
    2259 assert(set != NULL);
    2260 assert(expr != NULL);
    2261
    2262 return expr->exprhdlr == set->exprhdlrpow;
    2263}
    2264
    2265/** print an expression as info-message */
    2267 SCIP_SET* set, /**< global SCIP settings */
    2268 SCIP_STAT* stat, /**< dynamic problem statistics */
    2269 BMS_BLKMEM* blkmem, /**< block memory */
    2270 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2271 FILE* file, /**< file to print to, or NULL for stdout */
    2272 SCIP_EXPR* expr /**< expression to be printed */
    2273 )
    2274{
    2275 SCIP_EXPRITER* it;
    2276 SCIP_EXPRITER_STAGE stage;
    2277 int currentchild;
    2278 unsigned int parentprecedence;
    2279
    2280 assert(set != NULL);
    2281 assert(blkmem != NULL);
    2282 assert(expr != NULL);
    2283
    2284 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2287
    2288 while( !SCIPexpriterIsEnd(it) )
    2289 {
    2290 assert(expr->exprhdlr != NULL);
    2291 stage = SCIPexpriterGetStageDFS(it);
    2292
    2294 currentchild = SCIPexpriterGetChildIdxDFS(it);
    2295 else
    2296 currentchild = -1;
    2297
    2298 if( SCIPexpriterGetParentDFS(it) != NULL )
    2300 else
    2301 parentprecedence = 0;
    2302
    2303 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, stage, currentchild,
    2304 parentprecedence, file) );
    2305
    2306 expr = SCIPexpriterGetNext(it);
    2307 }
    2308
    2309 SCIPexpriterFree(&it);
    2310
    2311 return SCIP_OKAY;
    2312}
    2313
    2314/** initializes printing of expressions in dot format to a give FILE* pointer */
    2316 SCIP_SET* set, /**< global SCIP settings */
    2317 SCIP_STAT* stat, /**< dynamic problem statistics */
    2318 BMS_BLKMEM* blkmem, /**< block memory */
    2319 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
    2320 FILE* file, /**< file to print to, or NULL for stdout */
    2321 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
    2322 )
    2323{
    2324 assert(set != NULL);
    2325 assert(stat != NULL);
    2326 assert(blkmem != NULL);
    2327 assert(printdata != NULL);
    2328
    2329 if( file == NULL )
    2330 file = stdout;
    2331
    2332 SCIP_ALLOC( BMSallocBlockMemory(blkmem, printdata) );
    2333
    2334 (*printdata)->file = file;
    2335 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &(*printdata)->iterator) );
    2336 (*printdata)->closefile = FALSE;
    2337 (*printdata)->whattoprint = whattoprint;
    2338 SCIP_CALL( SCIPhashmapCreate(&(*printdata)->leaveexprs, blkmem, 100) );
    2339
    2340 fputs("strict digraph exprgraph {\n", file);
    2341 fputs("node [fontcolor=white, style=filled, rankdir=LR]\n", file);
    2342
    2343 return SCIP_OKAY;
    2344}
    2345
    2346/** initializes printing of expressions in dot format to a file with given filename */
    2348 SCIP_SET* set, /**< global SCIP settings */
    2349 SCIP_STAT* stat, /**< dynamic problem statistics */
    2350 BMS_BLKMEM* blkmem, /**< block memory */
    2351 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
    2352 const char* filename, /**< name of file to print to */
    2353 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
    2354 )
    2355{
    2356 FILE* f;
    2357
    2358 assert(set != NULL);
    2359 assert(stat != NULL);
    2360 assert(blkmem != NULL);
    2361 assert(printdata != NULL);
    2362 assert(filename != NULL);
    2363
    2364 f = fopen(filename, "w");
    2365 if( f == NULL )
    2366 {
    2367 SCIPerrorMessage("could not open file <%s> for writing\n", filename); /* error code would be in errno */
    2368 return SCIP_FILECREATEERROR;
    2369 }
    2370
    2371 SCIP_CALL_FINALLY( SCIPexprPrintDotInit(set, stat, blkmem, printdata, f, whattoprint),
    2372 fclose(f) );
    2373 (*printdata)->closefile = TRUE;
    2374
    2375 return SCIP_OKAY;
    2376} /*lint !e429*/
    2377
    2378/** main part of printing an expression in dot format */
    2380 SCIP_SET* set, /**< global SCIP settings */
    2381 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2382 SCIP_EXPRPRINTDATA* printdata, /**< data as initialized by \ref SCIPprintExprDotInit() */
    2383 SCIP_EXPR* expr /**< expression to be printed */
    2384 )
    2385{
    2386 SCIP_Real color;
    2387 int c;
    2388
    2389 assert(set != NULL);
    2390 assert(printdata != NULL);
    2391 assert(expr != NULL);
    2392 assert(expr->exprhdlr != NULL);
    2393
    2394 SCIP_CALL( SCIPexpriterInit(printdata->iterator, expr, SCIP_EXPRITER_DFS, FALSE) );
    2395
    2396 while( !SCIPexpriterIsEnd(printdata->iterator) )
    2397 {
    2398 /* print expression as dot node */
    2399
    2400 if( expr->nchildren == 0 )
    2401 {
    2402 SCIP_CALL( SCIPhashmapInsert(printdata->leaveexprs, (void*)expr, NULL) );
    2403 }
    2404
    2405 /* make up some color from the expression type (it's name) */
    2406 color = 0.0;
    2407 for( c = 0; expr->exprhdlr->name[c] != '\0'; ++c )
    2408 color += (tolower((unsigned char)expr->exprhdlr->name[c]) - 'a') / 26.0;
    2409 color = SCIPsetFrac(set, color);
    2410 fprintf(printdata->file, "n%p [fillcolor=\"%g,%g,%g\", label=\"", (void*)expr, color, color, color);
    2411
    2412 if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRHDLR )
    2413 {
    2414 fprintf(printdata->file, "%s\\n", expr->exprhdlr->name);
    2415 }
    2416
    2417 if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRSTRING )
    2418 {
    2419 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_ENTEREXPR, -1, 0,
    2420 printdata->file) );
    2421 for( c = 0; c < expr->nchildren; ++c )
    2422 {
    2423 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITINGCHILD,
    2424 c, 0, printdata->file) );
    2425 fprintf(printdata->file, "c%d", c);
    2426 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITEDCHILD,
    2427 c, 0, printdata->file) );
    2428 }
    2429 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_LEAVEEXPR, -1, 0,
    2430 printdata->file) );
    2431
    2432 fputs("\\n", printdata->file);
    2433 }
    2434
    2435 if( printdata->whattoprint & SCIP_EXPRPRINT_NUSES )
    2436 {
    2437 /* print number of uses */
    2438 fprintf(printdata->file, "%d uses\\n", expr->nuses);
    2439 }
    2440
    2441 if( printdata->whattoprint & SCIP_EXPRPRINT_OWNER )
    2442 {
    2443 /* print ownerdata */
    2444 if( expr->ownerprint != NULL )
    2445 {
    2446 SCIP_CALL( expr->ownerprint(set->scip, printdata->file, expr, expr->ownerdata) );
    2447 }
    2448 else if( expr->ownerdata != NULL )
    2449 {
    2450 fprintf(printdata->file, "owner=%p\\n", (void*)expr->ownerdata);
    2451 }
    2452 }
    2453
    2454 if( printdata->whattoprint & SCIP_EXPRPRINT_EVALVALUE )
    2455 {
    2456 /* print eval value */
    2457 fprintf(printdata->file, "val=%g", expr->evalvalue);
    2458
    2459 if( (printdata->whattoprint & SCIP_EXPRPRINT_EVALTAG) == SCIP_EXPRPRINT_EVALTAG )
    2460 {
    2461 /* print also eval tag */
    2462 fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->evaltag);
    2463 }
    2464 fputs("\\n", printdata->file);
    2465 }
    2466
    2467 if( printdata->whattoprint & SCIP_EXPRPRINT_ACTIVITY )
    2468 {
    2469 /* print activity */
    2470 fprintf(printdata->file, "[%g,%g]", expr->activity.inf, expr->activity.sup);
    2471
    2472 if( (printdata->whattoprint & SCIP_EXPRPRINT_ACTIVITYTAG) == SCIP_EXPRPRINT_ACTIVITYTAG )
    2473 {
    2474 /* print also activity eval tag */
    2475 fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->activitytag);
    2476 }
    2477 fputs("\\n", printdata->file);
    2478 }
    2479
    2480 fputs("\"]\n", printdata->file); /* end of label and end of node */
    2481
    2482 /* add edges from expr to its children */
    2483 for( c = 0; c < expr->nchildren; ++c )
    2484 fprintf(printdata->file, "n%p -> n%p [label=\"c%d\"]\n", (void*)expr, (void*)expr->children[c], c);
    2485
    2486 expr = SCIPexpriterGetNext(printdata->iterator);
    2487 }
    2488
    2489 return SCIP_OKAY;
    2490}
    2491
    2492/** finishes printing of expressions in dot format */
    2494 SCIP_SET* set, /**< global SCIP settings */
    2495 SCIP_STAT* stat, /**< dynamic problem statistics */
    2496 BMS_BLKMEM* blkmem, /**< block memory */
    2497 SCIP_EXPRPRINTDATA** printdata /**< buffer where dot printing data has been stored */
    2498 )
    2499{
    2500 SCIP_EXPR* expr;
    2501 SCIP_HASHMAPENTRY* entry;
    2502 FILE* file;
    2503 int i;
    2504
    2505 assert(set != NULL);
    2506 assert(stat != NULL);
    2507 assert(blkmem != NULL);
    2508 assert(printdata != NULL);
    2509 assert(*printdata != NULL);
    2510
    2511 file = (*printdata)->file;
    2512 assert(file != NULL);
    2513
    2514 /* iterate through all entries of the map */
    2515 fputs("{rank=same;", file);
    2516 for( i = 0; i < SCIPhashmapGetNEntries((*printdata)->leaveexprs); ++i )
    2517 {
    2518 entry = SCIPhashmapGetEntry((*printdata)->leaveexprs, i);
    2519
    2520 if( entry != NULL )
    2521 {
    2522 expr = (SCIP_EXPR*) SCIPhashmapEntryGetOrigin(entry);
    2523 assert(expr != NULL);
    2524 assert(expr->nchildren == 0);
    2525
    2526 fprintf(file, " n%p", (void*)expr);
    2527 }
    2528 }
    2529 fprintf(file, "}\n");
    2530
    2531 fprintf(file, "}\n");
    2532
    2533 SCIPhashmapFree(&(*printdata)->leaveexprs);
    2534
    2535 SCIPexpriterFree(&(*printdata)->iterator);
    2536
    2537 if( (*printdata)->closefile )
    2538 fclose((*printdata)->file);
    2539
    2540 BMSfreeBlockMemory(blkmem, printdata);
    2541
    2542 return SCIP_OKAY;
    2543}
    2544
    2545/** prints structure of an expression a la Maple's dismantle */
    2547 SCIP_SET* set, /**< global SCIP settings */
    2548 SCIP_STAT* stat, /**< dynamic problem statistics */
    2549 BMS_BLKMEM* blkmem, /**< block memory */
    2550 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2551 FILE* file, /**< file to print to, or NULL for stdout */
    2552 SCIP_EXPR* expr /**< expression to dismantle */
    2553 )
    2554{
    2555 SCIP_EXPRITER* it;
    2556 int depth = -1;
    2557
    2558 assert(set != NULL);
    2559 assert(stat != NULL);
    2560 assert(blkmem != NULL);
    2561 assert(messagehdlr != NULL);
    2562 assert(expr != NULL);
    2563
    2564 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2567
    2568 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    2569 {
    2570 switch( SCIPexpriterGetStageDFS(it) )
    2571 {
    2573 {
    2574 int nspaces;
    2575
    2576 ++depth;
    2577 nspaces = 3 * depth;
    2578
    2579 /* use depth of expression to align output */
    2580 SCIPmessageFPrintInfo(messagehdlr, file, "%*s[%s]: ", nspaces, "", expr->exprhdlr->name);
    2581
    2582 if( SCIPexprIsVar(set, expr) )
    2583 {
    2584 SCIP_VAR* var;
    2585
    2586 var = SCIPgetVarExprVar(expr);
    2587 SCIPmessageFPrintInfo(messagehdlr, file, "%s in [%.15g, %.15g]", SCIPvarGetName(var), SCIPvarGetLbLocal(var),
    2588 SCIPvarGetUbLocal(var));
    2589 }
    2590 else if( SCIPexprIsSum(set, expr) )
    2591 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g", SCIPgetConstantExprSum(expr));
    2592 else if( SCIPexprIsProduct(set, expr) )
    2593 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g", SCIPgetCoefExprProduct(expr));
    2594 else if( SCIPexprIsValue(set, expr) )
    2595 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g", SCIPgetValueExprValue(expr));
    2596 else if( SCIPexprIsPower(set, expr) || strcmp(expr->exprhdlr->name, "signpower") == 0)
    2597 SCIPmessageFPrintInfo(messagehdlr, file, "%.15g", SCIPgetExponentExprPow(expr));
    2598
    2599 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
    2600
    2601 if( expr->ownerprint != NULL )
    2602 {
    2603 SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
    2604 SCIP_CALL( expr->ownerprint(set->scip, file, expr, expr->ownerdata) );
    2605 }
    2606
    2607 break;
    2608 }
    2609
    2611 {
    2612 int nspaces = 3 * depth;
    2613
    2614 if( SCIPexprIsSum(set, expr) )
    2615 {
    2616 SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
    2617 SCIPmessageFPrintInfo(messagehdlr, file, "[coef]: %.15g\n", SCIPgetCoefsExprSum(expr)[SCIPexpriterGetChildIdxDFS(it)]);
    2618 }
    2619
    2620 break;
    2621 }
    2622
    2624 {
    2625 --depth;
    2626 break;
    2627 }
    2628
    2629 default:
    2630 /* shouldn't be here */
    2631 SCIPABORT();
    2632 break;
    2633 }
    2634 }
    2635
    2636 SCIPexpriterFree(&it);
    2637
    2638 return SCIP_OKAY;
    2639}
    2640
    2641/** evaluate an expression in a point
    2642 *
    2643 * Iterates over expressions to also evaluate children, if necessary.
    2644 * Value can be received via SCIPexprGetEvalValue().
    2645 * If an evaluation error (division by zero, ...) occurs, this value will
    2646 * be set to SCIP_INVALID.
    2647 *
    2648 * If a nonzero \p soltag is passed, then only (sub)expressions are
    2649 * reevaluated that have a different solution tag. If a soltag of 0
    2650 * is passed, then subexpressions are always reevaluated.
    2651 * The tag is stored together with the value and can be received via
    2652 * SCIPexprGetEvalTag().
    2653 */
    2655 SCIP_SET* set, /**< global SCIP settings */
    2656 SCIP_STAT* stat, /**< dynamic problem statistics */
    2657 BMS_BLKMEM* blkmem, /**< block memory */
    2658 SCIP_EXPR* expr, /**< expression to be evaluated */
    2659 SCIP_SOL* sol, /**< solution to be evaluated */
    2660 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
    2661 )
    2662{
    2663 SCIP_EXPRITER* it;
    2664
    2665 assert(set != NULL);
    2666 assert(stat != NULL);
    2667 assert(blkmem != NULL);
    2668 assert(expr != NULL);
    2669
    2670 /* if value is up-to-date, then nothing to do */
    2671 if( soltag != 0 && expr->evaltag == soltag )
    2672 return SCIP_OKAY;
    2673
    2674 /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
    2675 * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
    2676 */
    2677 expr->evalvalue = SCIP_INVALID;
    2678 expr->evaltag = soltag;
    2679
    2680 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2683
    2684 while( !SCIPexpriterIsEnd(it) )
    2685 {
    2686 switch( SCIPexpriterGetStageDFS(it) )
    2687 {
    2689 {
    2690 SCIP_EXPR* child;
    2691
    2692 if( soltag == 0 )
    2693 break;
    2694
    2695 /* check whether child has been evaluated for that solution already */
    2696 child = SCIPexpriterGetChildExprDFS(it);
    2697 if( soltag == child->evaltag )
    2698 {
    2699 if( child->evalvalue == SCIP_INVALID )
    2700 goto TERMINATE;
    2701
    2702 /* skip this child
    2703 * this already returns the next one, so continue with loop
    2704 */
    2705 expr = SCIPexpriterSkipDFS(it);
    2706 continue;
    2707 }
    2708
    2709 break;
    2710 }
    2711
    2713 {
    2714 SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL , expr, &expr->evalvalue, NULL, sol) );
    2715 expr->evaltag = soltag;
    2716
    2717 if( expr->evalvalue == SCIP_INVALID )
    2718 goto TERMINATE;
    2719
    2720 break;
    2721 }
    2722
    2723 default :
    2724 /* we should never be here */
    2725 SCIPABORT();
    2726 break;
    2727 }
    2728
    2729 expr = SCIPexpriterGetNext(it);
    2730 }
    2731
    2732TERMINATE:
    2733 SCIPexpriterFree(&it);
    2734
    2735 return SCIP_OKAY;
    2736}
    2737
    2738/** evaluates gradient of an expression for a given point
    2739 *
    2740 * Initiates an expression walk to also evaluate children, if necessary.
    2741 * Value can be received via SCIPgetExprPartialDiffNonlinear().
    2742 * If an error (division by zero, ...) occurs, this value will
    2743 * be set to SCIP_INVALID.
    2744 */
    2746 SCIP_SET* set, /**< global SCIP settings */
    2747 SCIP_STAT* stat, /**< dynamic problem statistics */
    2748 BMS_BLKMEM* blkmem, /**< block memory */
    2749 SCIP_EXPR* rootexpr, /**< expression to be evaluated */
    2750 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
    2751 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
    2752 )
    2753{
    2754 SCIP_EXPRITER* it;
    2755 SCIP_EXPR* expr;
    2756 SCIP_EXPR* child;
    2757 SCIP_Real derivative;
    2758 SCIP_Longint difftag;
    2759
    2760 assert(set != NULL);
    2761 assert(stat != NULL);
    2762 assert(blkmem != NULL);
    2763 assert(rootexpr != NULL);
    2764
    2765 /* ensure expression is evaluated */
    2766 SCIP_CALL( SCIPexprEval(set, stat, blkmem, rootexpr, sol, soltag) );
    2767
    2768 /* check if expression could not be evaluated */
    2769 if( SCIPexprGetEvalValue(rootexpr) == SCIP_INVALID )
    2770 {
    2771 rootexpr->derivative = SCIP_INVALID;
    2772 return SCIP_OKAY;
    2773 }
    2774
    2775 if( SCIPexprIsValue(set, rootexpr) )
    2776 {
    2777 rootexpr->derivative = 0.0;
    2778 return SCIP_OKAY;
    2779 }
    2780
    2781 difftag = ++(stat->exprlastdifftag);
    2782
    2783 rootexpr->derivative = 1.0;
    2784 rootexpr->difftag = difftag;
    2785
    2786 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2789
    2790 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    2791 {
    2792 assert(expr->evalvalue != SCIP_INVALID);
    2793 assert(expr->derivative != SCIP_INVALID);
    2794
    2795 child = SCIPexpriterGetChildExprDFS(it);
    2796 assert(child != NULL);
    2797
    2798 /* reset the value of the partial derivative w.r.t. a variable expression if we see it for the first time */
    2799 if( child->difftag != difftag && SCIPexprIsVar(set, child) )
    2800 child->derivative = 0.0;
    2801
    2802 /* update differentiation tag of the child */
    2803 child->difftag = difftag;
    2804
    2805 /* call backward differentiation callback */
    2806 if( SCIPexprIsValue(set, child) )
    2807 {
    2808 derivative = 0.0;
    2809 }
    2810 else
    2811 {
    2812 derivative = SCIP_INVALID;
    2814 &derivative, NULL, 0.0) );
    2815
    2816 if( derivative == SCIP_INVALID )
    2817 {
    2818 rootexpr->derivative = SCIP_INVALID;
    2819 break;
    2820 }
    2821
    2822 assert(SCIPisFinite(derivative)); /* ensured in SCIPexprhdlrBwDiffExpr */
    2823 }
    2824
    2825 /* update partial derivative stored in the child expression
    2826 * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
    2827 * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
    2828 */
    2829 if( !SCIPexprIsVar(set, child) )
    2830 child->derivative = expr->derivative * derivative;
    2831 else
    2832 child->derivative += expr->derivative * derivative;
    2833
    2834 /* even with expr->derivative and derivative being finite, the product may under- or overflow */
    2835 if( !SCIPisFinite(child->derivative) )
    2836 {
    2837 child->derivative = SCIP_INVALID;
    2838 rootexpr->derivative = SCIP_INVALID;
    2839 break;
    2840 }
    2841 }
    2842
    2843 SCIPexpriterFree(&it);
    2844
    2845 return SCIP_OKAY;
    2846}
    2847
    2848/** evaluates Hessian-vector product of an expression for a given point and direction
    2849 *
    2850 * Evaluates children, if necessary.
    2851 * Value can be received via SCIPgetExprPartialDiffGradientDirNonlinear()
    2852 * If an error (division by zero, ...) occurs, this value will
    2853 * be set to SCIP_INVALID.
    2854 */
    2856 SCIP_SET* set, /**< global SCIP settings */
    2857 SCIP_STAT* stat, /**< dynamic problem statistics */
    2858 BMS_BLKMEM* blkmem, /**< block memory */
    2859 SCIP_EXPR* rootexpr, /**< expression to be evaluated */
    2860 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
    2861 SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
    2862 SCIP_SOL* direction /**< direction */
    2863 )
    2864{
    2865 SCIP_EXPRITER* it;
    2866 SCIP_EXPR* expr;
    2867 SCIP_EXPR* child;
    2868 SCIP_Real derivative;
    2869 SCIP_Real hessiandir;
    2870
    2871 assert(set != NULL);
    2872 assert(stat != NULL);
    2873 assert(blkmem != NULL);
    2874 assert(rootexpr != NULL);
    2875
    2876 if( SCIPexprIsValue(set, rootexpr) )
    2877 {
    2878 rootexpr->dot = 0.0;
    2879 rootexpr->bardot = 0.0;
    2880 return SCIP_OKAY;
    2881 }
    2882
    2883 /* evaluate expression and directional derivative */
    2884 SCIP_CALL( evalAndDiff(set, stat, blkmem, rootexpr, sol, soltag, direction) );
    2885
    2886 if( rootexpr->evalvalue == SCIP_INVALID )
    2887 {
    2888 rootexpr->derivative = SCIP_INVALID;
    2889 rootexpr->bardot = SCIP_INVALID;
    2890 return SCIP_OKAY;
    2891 }
    2892
    2893 rootexpr->derivative = 1.0;
    2894
    2895 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    2898
    2899 /* compute reverse diff and bardots: i.e. hessian times direction */
    2900 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    2901 {
    2902 assert(expr->evalvalue != SCIP_INVALID);
    2903
    2904 child = SCIPexpriterGetChildExprDFS(it);
    2905 assert(child != NULL);
    2906
    2907 /* call backward and forward-backward differentiation callback */
    2908 if( SCIPexprIsValue(set, child) )
    2909 {
    2910 derivative = 0.0;
    2911 hessiandir = 0.0;
    2912 }
    2913 else
    2914 {
    2915 derivative = SCIP_INVALID;
    2916 hessiandir = SCIP_INVALID;
    2918 &derivative, NULL, SCIP_INVALID) );
    2920 &hessiandir, NULL) );
    2921
    2922 if( derivative == SCIP_INVALID || hessiandir == SCIP_INVALID )
    2923 {
    2924 rootexpr->derivative = SCIP_INVALID;
    2925 rootexpr->bardot = SCIP_INVALID;
    2926 break;
    2927 }
    2928 }
    2929
    2930 /* update partial derivative and hessian stored in the child expression
    2931 * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
    2932 * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
    2933 */
    2934 if( !SCIPexprIsVar(set, child) )
    2935 {
    2936 child->derivative = expr->derivative * derivative;
    2937 child->bardot = expr->bardot * derivative + expr->derivative * hessiandir;
    2938 }
    2939 else
    2940 {
    2941 child->derivative += expr->derivative * derivative;
    2942 child->bardot += expr->bardot * derivative + expr->derivative * hessiandir;
    2943 }
    2944 }
    2945
    2946 SCIPexpriterFree(&it);
    2947
    2948 return SCIP_OKAY;
    2949}
    2950
    2951/** possibly reevaluates and then returns the activity of the expression
    2952 *
    2953 * Reevaluate activity if currently stored is no longer uptodate.
    2954 * If the expr owner provided a evalactivity-callback, then call this.
    2955 * Otherwise, loop over descendants and compare activitytag with stat's domchgcount, i.e.,
    2956 * whether some bound was changed since last evaluation, to check whether exprhdlrs INTEVAL should be called.
    2957 *
    2958 * @note If expression is set to be integral, then activities are tightened to integral values.
    2959 * Thus, ensure that the integrality information is valid (if set to TRUE; the default (FALSE) is always ok).
    2960 */
    2962 SCIP_SET* set, /**< global SCIP settings */
    2963 SCIP_STAT* stat, /**< dynamic problem statistics */
    2964 BMS_BLKMEM* blkmem, /**< block memory */
    2965 SCIP_EXPR* rootexpr /**< expression */
    2966 )
    2967{
    2968 SCIP_EXPRITER* it;
    2969 SCIP_EXPR* expr;
    2970
    2971 assert(set != NULL);
    2972 assert(stat != NULL);
    2973 assert(blkmem != NULL);
    2974 assert(rootexpr != NULL);
    2975
    2976 if( rootexpr->ownerevalactivity != NULL )
    2977 {
    2978 /* call owner callback for activity-eval */
    2979 SCIP_CALL( rootexpr->ownerevalactivity(set->scip, rootexpr, rootexpr->ownerdata) );
    2980
    2981 return SCIP_OKAY;
    2982 }
    2983
    2984 /* fallback if no callback is given */
    2985
    2986 assert(rootexpr->activitytag <= stat->domchgcount);
    2987
    2988 /* if value is up-to-date, then nothing to do */
    2989 if( rootexpr->activitytag == stat->domchgcount )
    2990 {
    2991#ifdef DEBUG_PROP
    2992 SCIPsetDebugMsg(set, "activitytag of root expr equals domchgcount (%u), skip evalactivity\n", stat->domchgcount);
    2993#endif
    2994
    2995 return SCIP_OKAY;
    2996 }
    2997
    2998 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    3001
    3002 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); )
    3003 {
    3004 switch( SCIPexpriterGetStageDFS(it) )
    3005 {
    3007 {
    3008 /* skip child if it has been evaluated already */
    3009 SCIP_EXPR* child;
    3010
    3011 child = SCIPexpriterGetChildExprDFS(it);
    3012 if( child->activitytag == stat->domchgcount )
    3013 {
    3014 expr = SCIPexpriterSkipDFS(it);
    3015 continue;
    3016 }
    3017
    3018 break;
    3019 }
    3020
    3022 {
    3023 /* we should not have entered this expression if its activity was already uptodate */
    3024 assert(expr->activitytag < stat->domchgcount);
    3025
    3026 /* reset activity to entire if invalid, so we can use it as starting point below */
    3028
    3029#ifdef DEBUG_PROP
    3030 SCIPsetDebugMsg(set, "interval evaluation of expr %p ", (void*)expr);
    3031 SCIP_CALL( SCIPprintExpr(set->scip, expr, NULL) );
    3033#endif
    3034
    3035 /* call the inteval callback of the exprhdlr */
    3036 SCIP_CALL( SCIPexprhdlrIntEvalExpr(expr->exprhdlr, set, expr, &expr->activity, NULL, NULL) );
    3037#ifdef DEBUG_PROP
    3038 SCIPsetDebugMsg(set, " exprhdlr <%s>::inteval = [%.20g, %.20g]", expr->exprhdlr->name, expr->activity.inf,
    3039 expr->activity.sup);
    3040#endif
    3041
    3042 /* if expression is integral, then we try to tighten the interval bounds a bit
    3043 * this should undo the addition of some unnecessary safety added by use of nextafter() in interval
    3044 * arithmetics, e.g., when doing pow() it would be ok to use ceil() and floor(), but for safety we
    3045 * use SCIPceil and SCIPfloor for now the default intevalVar does not relax variables, so can omit
    3046 * expressions without children (constants should be ok, too)
    3047 */
    3048 if( expr->integrality != SCIP_IMPLINTTYPE_NONE && expr->nchildren > 0 )
    3049 {
    3050 if( expr->activity.inf > -SCIP_INTERVAL_INFINITY )
    3051 expr->activity.inf = SCIPsetCeil(set, expr->activity.inf);
    3052 if( expr->activity.sup < SCIP_INTERVAL_INFINITY )
    3053 expr->activity.sup = SCIPsetFloor(set, expr->activity.sup);
    3054#ifdef DEBUG_PROP
    3055 SCIPsetDebugMsg(set, " applying integrality: [%.20g, %.20g]\n", expr->activity.inf, expr->activity.sup);
    3056#endif
    3057 }
    3058
    3059 /* mark activity as empty if either the lower/upper bound is above/below +/- SCIPinfinity()
    3060 * TODO this is a problem if dual-presolve fixed a variable to +/- infinity
    3061 */
    3062 if( SCIPsetIsInfinity(set, expr->activity.inf) || SCIPsetIsInfinity(set, -expr->activity.sup) )
    3063 {
    3064 SCIPsetDebugMsg(set, "treat activity [%g,%g] as empty as beyond infinity\n", expr->activity.inf, expr->activity.sup);
    3065 SCIPintervalSetEmpty(&expr->activity);
    3066 }
    3067
    3068 /* remember that activity is uptodate now */
    3069 expr->activitytag = stat->domchgcount;
    3070
    3071 break;
    3072 }
    3073
    3074 default:
    3075 /* you should never be here */
    3076 SCIPABORT();
    3077 break;
    3078 }
    3079
    3080 expr = SCIPexpriterGetNext(it);
    3081 }
    3082
    3083 SCIPexpriterFree(&it);
    3084
    3085 return SCIP_OKAY;
    3086}
    3087
    3088/** compare expressions
    3089 *
    3090 * @return -1, 0 or 1 if expr1 <, =, > expr2, respectively
    3091 * @note The given expressions are assumed to be simplified.
    3092 */
    3094 SCIP_SET* set, /**< global SCIP settings */
    3095 SCIP_EXPR* expr1, /**< first expression */
    3096 SCIP_EXPR* expr2 /**< second expression */
    3097 )
    3098{
    3099 SCIP_EXPRHDLR* exprhdlr1;
    3100 SCIP_EXPRHDLR* exprhdlr2;
    3101 int retval;
    3102
    3103 exprhdlr1 = expr1->exprhdlr;
    3104 exprhdlr2 = expr2->exprhdlr;
    3105
    3106 /* expressions are of the same kind/type; use compare callback or default method */
    3107 if( exprhdlr1 == exprhdlr2 )
    3108 return SCIPexprhdlrCompareExpr(set, expr1, expr2);
    3109
    3110 /* expressions are of different kind/type */
    3111 /* enforces OR6 */
    3112 if( SCIPexprIsValue(set, expr1) )
    3113 {
    3114 return -1;
    3115 }
    3116 /* enforces OR12 */
    3117 if( SCIPexprIsValue(set, expr2) )
    3118 return -SCIPexprCompare(set, expr2, expr1);
    3119
    3120 /* enforces OR7 */
    3121 if( SCIPexprIsSum(set, expr1) )
    3122 {
    3123 int compareresult;
    3124 int nchildren;
    3125
    3126 nchildren = expr1->nchildren;
    3127 compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
    3128
    3129 if( compareresult != 0 )
    3130 return compareresult;
    3131
    3132 /* "base" of the largest expression of the sum is equal to expr2, coefficient might tell us that
    3133 * expr2 is larger */
    3134 if( SCIPgetCoefsExprSum(expr1)[nchildren-1] < 1.0 )
    3135 return -1;
    3136
    3137 /* largest expression of sum is larger or equal than expr2 => expr1 > expr2 */
    3138 return 1;
    3139 }
    3140 /* enforces OR12 */
    3141 if( SCIPexprIsSum(set, expr2) )
    3142 return -SCIPexprCompare(set, expr2, expr1);
    3143
    3144 /* enforces OR8 */
    3145 if( SCIPexprIsProduct(set, expr1) )
    3146 {
    3147 int compareresult;
    3148 int nchildren;
    3149
    3150 nchildren = expr1->nchildren;
    3151 compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
    3152
    3153 if( compareresult != 0 )
    3154 return compareresult;
    3155
    3156 /* largest expression of product is larger or equal than expr2 => expr1 > expr2 */
    3157 return 1;
    3158 }
    3159 /* enforces OR12 */
    3160 if( SCIPexprIsProduct(set, expr2) )
    3161 return -SCIPexprCompare(set, expr2, expr1);
    3162
    3163 /* enforces OR9 */
    3164 if( SCIPexprIsPower(set, expr1) )
    3165 {
    3166 int compareresult;
    3167
    3168 compareresult = SCIPexprCompare(set, expr1->children[0], expr2);
    3169
    3170 if( compareresult != 0 )
    3171 return compareresult;
    3172
    3173 /* base equal to expr2, exponent might tell us that expr2 is larger */
    3174 if( SCIPgetExponentExprPow(expr1) < 1.0 )
    3175 return -1;
    3176
    3177 /* power expression is larger => expr1 > expr2 */
    3178 return 1;
    3179 }
    3180 /* enforces OR12 */
    3181 if( SCIPexprIsPower(set, expr2) )
    3182 return -SCIPexprCompare(set, expr2, expr1);
    3183
    3184 /* enforces OR10 */
    3185 if( SCIPexprIsVar(set, expr1) )
    3186 return -1;
    3187 /* enforces OR12 */
    3188 if( SCIPexprIsVar(set, expr2) )
    3189 return -SCIPexprCompare(set, expr2, expr1);
    3190
    3191 /* enforces OR11 */
    3192 retval = strcmp(SCIPexprhdlrGetName(exprhdlr1), SCIPexprhdlrGetName(exprhdlr2));
    3193 return retval == 0 ? 0 : retval < 0 ? -1 : 1;
    3194}
    3195
    3196/** simplifies an expression
    3197 *
    3198 * @see SCIPsimplifyExpr
    3199 */
    3201 SCIP_SET* set, /**< global SCIP settings */
    3202 SCIP_STAT* stat, /**< dynamic problem statistics */
    3203 BMS_BLKMEM* blkmem, /**< block memory */
    3204 SCIP_EXPR* rootexpr, /**< expression to be simplified */
    3205 SCIP_EXPR** simplified, /**< buffer to store simplified expression */
    3206 SCIP_Bool* changed, /**< buffer to store if rootexpr actually changed */
    3207 SCIP_Bool* infeasible, /**< buffer to store whether infeasibility has been detected */
    3208 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
    3209 void* ownercreatedata /**< data to pass to ownercreate */
    3210 )
    3211{
    3212 SCIP_EXPR* expr;
    3213 SCIP_EXPRITER* it;
    3214
    3215 assert(rootexpr != NULL);
    3216 assert(simplified != NULL);
    3217 assert(changed != NULL);
    3218 assert(infeasible != NULL);
    3219
    3220 /* simplify bottom up
    3221 * when leaving an expression it simplifies it and stores the simplified expr in its iterators expression data
    3222 * after the child was visited, it is replaced with the simplified expr
    3223 */
    3224 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
    3225 SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) ); /* TODO can we set allowrevisited to FALSE?*/
    3227
    3228 *changed = FALSE;
    3229 *infeasible = FALSE;
    3230 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
    3231 {
    3232 switch( SCIPexpriterGetStageDFS(it) )
    3233 {
    3235 {
    3236 SCIP_EXPR* newchild;
    3237 SCIP_EXPR* child;
    3238
    3240 child = SCIPexpriterGetChildExprDFS(it);
    3241 assert(newchild != NULL);
    3242
    3243 /* if child got simplified, replace it with the new child */
    3244 if( newchild != child )
    3245 {
    3246 SCIP_CALL( SCIPexprReplaceChild(set, stat, blkmem, expr, SCIPexpriterGetChildIdxDFS(it), newchild) );
    3247 }
    3248
    3249 /* we do not need to hold newchild anymore */
    3250 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &newchild) );
    3251
    3252 break;
    3253 }
    3254
    3256 {
    3257 SCIP_EXPR* refexpr = NULL;
    3258 SCIP_EXPRITER_USERDATA iterdata;
    3259
    3260 /* TODO we should do constant folding (handle that all children are value-expressions) here in a generic way
    3261 * instead of reimplementing it in every handler
    3262 */
    3263
    3264 /* use simplification of expression handlers */
    3265 SCIP_CALL( SCIPexprhdlrSimplifyExpr(expr->exprhdlr, set, expr, &refexpr, ownercreate, ownercreatedata) );
    3266 assert(refexpr != NULL);
    3267 if( expr != refexpr )
    3268 *changed = TRUE;
    3269
    3270 iterdata.ptrval = (void*) refexpr;
    3271 SCIPexpriterSetCurrentUserData(it, iterdata);
    3272
    3273 break;
    3274 }
    3275
    3276 default:
    3277 SCIPABORT(); /* we should never be called in this stage */
    3278 break;
    3279 }
    3280 }
    3281
    3282 *simplified = (SCIP_EXPR*)SCIPexpriterGetExprUserData(it, rootexpr).ptrval;
    3283 assert(*simplified != NULL);
    3284
    3285 SCIPexpriterFree(&it);
    3286
    3287 return SCIP_OKAY;
    3288}
    3289
    3290/** method to retrieve symmetry information from an expression
    3291 *
    3292 * @see SCIPgetSymDataExpr
    3293 */
    3295 SCIP_SET* set, /**< global SCIP settings */
    3296 SCIP_EXPR* expr, /**< expression from which information is retrieved */
    3297 SYM_EXPRDATA** symdata /**< buffer to store symmetry information */
    3298 )
    3299{
    3300 SCIP_EXPRHDLR* exprhdlr;
    3301
    3302 assert(set != NULL);
    3303 assert(expr != NULL);
    3304 assert(symdata != NULL);
    3305
    3306 exprhdlr = SCIPexprGetHdlr(expr);
    3307 assert(exprhdlr != NULL);
    3308
    3309 if( exprhdlr->getsymdata != NULL )
    3310 {
    3311 SCIP_CALL( exprhdlr->getsymdata(set->scip, expr, symdata) );
    3312 }
    3313 else
    3314 *symdata = NULL;
    3315
    3316 return SCIP_OKAY;
    3317}
    3318
    3319/** checks whether an expression is quadratic
    3320 *
    3321 * An expression is quadratic if it is either a power expression with exponent 2.0, a product of two expressions,
    3322 * or a sum of terms where at least one is a square or a product of two.
    3323 *
    3324 * Use \ref SCIPexprGetQuadraticData to get data about the representation as quadratic.
    3325 */
    3327 SCIP_SET* set, /**< global SCIP settings */
    3328 BMS_BLKMEM* blkmem, /**< block memory */
    3329 SCIP_EXPR* expr, /**< expression */
    3330 SCIP_Bool* isquadratic /**< buffer to store result */
    3331 )
    3332{
    3333 SCIP_HASHMAP* expr2idx;
    3334 SCIP_HASHMAP* seenexpr = NULL;
    3335 int nquadterms = 0;
    3336 int nlinterms = 0;
    3337 int nbilinterms = 0;
    3338 int c;
    3339
    3340 assert(set != NULL);
    3341 assert(blkmem != NULL);
    3342 assert(expr != NULL);
    3343 assert(isquadratic != NULL);
    3344
    3345 if( expr->quadchecked )
    3346 {
    3347 *isquadratic = expr->quaddata != NULL;
    3348 return SCIP_OKAY;
    3349 }
    3350 assert(expr->quaddata == NULL);
    3351
    3352 expr->quadchecked = TRUE;
    3353 *isquadratic = FALSE;
    3354
    3355 /* check if expression is a quadratic expression */
    3356 SCIPsetDebugMsg(set, "checking if expr %p is quadratic\n", (void*)expr);
    3357
    3358 /* handle single square term */
    3359 if( SCIPexprIsPower(set, expr) && SCIPgetExponentExprPow(expr) == 2.0 )
    3360 {
    3361 SCIPsetDebugMsg(set, "expr %p looks like square: fill data structures\n", (void*)expr);
    3362 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
    3363
    3364 expr->quaddata->nquadexprs = 1;
    3365 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 1) );
    3366 expr->quaddata->quadexprterms[0].expr = expr->children[0];
    3367 expr->quaddata->quadexprterms[0].sqrcoef = 1.0;
    3368
    3369 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr);
    3370
    3371 *isquadratic = TRUE;
    3372 return SCIP_OKAY;
    3373 }
    3374
    3375 /* handle single bilinear term */
    3376 if( SCIPexprIsProduct(set, expr) && SCIPexprGetNChildren(expr) == 2 )
    3377 {
    3378 SCIPsetDebugMsg(set, "expr %p looks like bilinear product: fill data structures\n", (void*)expr);
    3379 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
    3380 expr->quaddata->nquadexprs = 2;
    3381
    3382 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 2) );
    3383 expr->quaddata->quadexprterms[0].expr = SCIPexprGetChildren(expr)[0];
    3384 expr->quaddata->quadexprterms[0].nadjbilin = 1;
    3385 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[0].adjbilin, 1) );
    3386 expr->quaddata->quadexprterms[0].adjbilin[0] = 0;
    3387
    3388 expr->quaddata->quadexprterms[1].expr = SCIPexprGetChildren(expr)[1];
    3389 expr->quaddata->quadexprterms[1].nadjbilin = 1;
    3390 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[1].adjbilin, 1) );
    3391 expr->quaddata->quadexprterms[1].adjbilin[0] = 0;
    3392
    3393 expr->quaddata->nbilinexprterms = 1;
    3394 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, 1) );
    3395 expr->quaddata->bilinexprterms[0].expr1 = SCIPexprGetChildren(expr)[1];
    3396 expr->quaddata->bilinexprterms[0].expr2 = SCIPexprGetChildren(expr)[0];
    3397 expr->quaddata->bilinexprterms[0].coef = 1.0;
    3398
    3399 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr)
    3400 && SCIPexprIsVar(set, expr->quaddata->quadexprterms[1].expr);
    3401
    3402 *isquadratic = TRUE;
    3403 return SCIP_OKAY;
    3404 }
    3405
    3406 /* neither a sum, nor a square, nor a bilinear term */
    3407 if( !SCIPexprIsSum(set, expr) )
    3408 return SCIP_OKAY;
    3409
    3410 SCIP_CALL( SCIPhashmapCreate(&seenexpr, blkmem, 2*SCIPexprGetNChildren(expr)) );
    3411 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    3412 {
    3413 SCIP_EXPR* child;
    3414 SCIP_Real coef;
    3415
    3416 child = SCIPexprGetChildren(expr)[c];
    3417 assert(child != NULL);
    3418
    3419 coef = SCIPgetCoefsExprSum(expr)[c];
    3420 if( coef == 0.0 )
    3421 continue;
    3422
    3423 if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
    3424 {
    3425 SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[0], seenexpr, &nquadterms, &nlinterms) );
    3426 }
    3427 else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
    3428 {
    3429 ++nbilinterms;
    3430 SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[0], seenexpr, &nquadterms, &nlinterms) );
    3431 SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[1], seenexpr, &nquadterms, &nlinterms) );
    3432 }
    3433 else
    3434 {
    3435 /* first time seen linearly --> assign -1; ++nlinterms
    3436 * not first time --> assign +=1;
    3437 */
    3438 if( SCIPhashmapExists(seenexpr, (void*)child) )
    3439 {
    3440 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
    3441
    3442 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)child, SCIPhashmapGetImageInt(seenexpr, (void*)child) + 1) );
    3443 }
    3444 else
    3445 {
    3446 ++nlinterms;
    3447 SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)child, -1) );
    3448 }
    3449 }
    3450 }
    3451
    3452 if( nquadterms == 0 )
    3453 {
    3454 /* only linear sum */
    3455 SCIPhashmapFree(&seenexpr);
    3456 return SCIP_OKAY;
    3457 }
    3458
    3459 SCIPsetDebugMsg(set, "expr %p looks quadratic: fill data structures\n", (void*)expr);
    3460
    3461 /* expr2idx maps expressions to indices; if index > 0, it is its index in the linexprs array, otherwise -index-1 is
    3462 * its index in the quadexprterms array
    3463 */
    3464 SCIP_CALL( SCIPhashmapCreate(&expr2idx, blkmem, nquadterms + nlinterms) );
    3465
    3466 /* allocate memory, etc */
    3467 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
    3468 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, nquadterms) );
    3469 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->linexprs, nlinterms) );
    3470 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->lincoefs, nlinterms) );
    3471 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, nbilinterms) );
    3472
    3474
    3475 expr->quaddata->allexprsarevars = TRUE;
    3476 /* for every term of the sum-expr */
    3477 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    3478 {
    3479 SCIP_EXPR* child;
    3480 SCIP_Real coef;
    3481
    3482 child = SCIPexprGetChildren(expr)[c];
    3483 assert(child != NULL);
    3484
    3485 coef = SCIPgetCoefsExprSum(expr)[c];
    3486 if( coef == 0.0 )
    3487 continue;
    3488
    3489 if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
    3490 {
    3491 SCIP_QUADEXPR_QUADTERM* quadexprterm;
    3492 assert(SCIPexprGetNChildren(child) == 1);
    3493
    3494 child = SCIPexprGetChildren(child)[0];
    3495 assert(SCIPhashmapGetImageInt(seenexpr, (void *)child) > 0);
    3496
    3497 SCIP_CALL( quadDetectGetQuadexprterm(blkmem, child, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
    3498 assert(quadexprterm->expr == child);
    3499 quadexprterm->sqrcoef = coef;
    3500 quadexprterm->sqrexpr = SCIPexprGetChildren(expr)[c];
    3501
    3502 if( expr->quaddata->allexprsarevars )
    3503 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
    3504 }
    3505 else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
    3506 {
    3507 SCIP_QUADEXPR_BILINTERM* bilinexprterm;
    3508 SCIP_QUADEXPR_QUADTERM* quadexprterm;
    3509 SCIP_EXPR* expr1;
    3510 SCIP_EXPR* expr2;
    3511
    3512 assert(SCIPgetCoefExprProduct(child) == 1.0);
    3513
    3514 expr1 = SCIPexprGetChildren(child)[0];
    3515 expr2 = SCIPexprGetChildren(child)[1];
    3516 assert(expr1 != NULL && expr2 != NULL);
    3517
    3518 bilinexprterm = &expr->quaddata->bilinexprterms[expr->quaddata->nbilinexprterms];
    3519
    3520 bilinexprterm->coef = coef;
    3521 if( SCIPhashmapGetImageInt(seenexpr, (void*)expr1) >= SCIPhashmapGetImageInt(seenexpr, (void*)expr2) )
    3522 {
    3523 bilinexprterm->expr1 = expr1;
    3524 bilinexprterm->expr2 = expr2;
    3525 }
    3526 else
    3527 {
    3528 bilinexprterm->expr1 = expr2;
    3529 bilinexprterm->expr2 = expr1;
    3530 }
    3531 bilinexprterm->prodexpr = child;
    3532
    3533 SCIP_CALL( quadDetectGetQuadexprterm(blkmem, expr1, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
    3534 assert(quadexprterm->expr == expr1);
    3535 quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
    3536 ++quadexprterm->nadjbilin;
    3537
    3538 if( expr->quaddata->allexprsarevars )
    3539 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
    3540
    3541 SCIP_CALL( quadDetectGetQuadexprterm(blkmem, expr2, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
    3542 assert(quadexprterm->expr == expr2);
    3543 quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
    3544 ++quadexprterm->nadjbilin;
    3545
    3546 if( expr->quaddata->allexprsarevars )
    3547 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
    3548
    3549 ++expr->quaddata->nbilinexprterms;
    3550
    3551 /* store position of second factor in quadexprterms */
    3552 bilinexprterm->pos2 = SCIPhashmapGetImageInt(expr2idx, (void*)bilinexprterm->expr2);
    3553 }
    3554 else /* linear term */
    3555 {
    3556 if( SCIPhashmapGetImageInt(seenexpr, (void*)child) < 0 )
    3557 {
    3558 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) == -1);
    3559
    3560 /* expression only appears linearly */
    3561 expr->quaddata->linexprs[expr->quaddata->nlinexprs] = child;
    3562 expr->quaddata->lincoefs[expr->quaddata->nlinexprs] = coef;
    3563 expr->quaddata->nlinexprs++;
    3564
    3565 if( expr->quaddata->allexprsarevars )
    3566 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, child);
    3567 }
    3568 else
    3569 {
    3570 /* expression appears non-linearly: set lin coef */
    3571 SCIP_QUADEXPR_QUADTERM* quadexprterm;
    3572 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
    3573
    3574 SCIP_CALL( quadDetectGetQuadexprterm(blkmem, child, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
    3575 assert(quadexprterm->expr == child);
    3576 quadexprterm->lincoef = coef;
    3577
    3578 if( expr->quaddata->allexprsarevars )
    3579 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
    3580 }
    3581 }
    3582 }
    3583 assert(expr->quaddata->nquadexprs == nquadterms);
    3584 assert(expr->quaddata->nlinexprs == nlinterms);
    3585 assert(expr->quaddata->nbilinexprterms == nbilinterms);
    3586
    3587 SCIPhashmapFree(&seenexpr);
    3588 SCIPhashmapFree(&expr2idx);
    3589
    3590 *isquadratic = TRUE;
    3591
    3592 return SCIP_OKAY;
    3593}
    3594
    3595/** frees information on quadratic representation of an expression
    3596 *
    3597 * Reverts SCIPexprCheckQuadratic().
    3598 * Before doing changes to an expression, it can be useful to call this function.
    3599 */
    3601 BMS_BLKMEM* blkmem, /**< block memory */
    3602 SCIP_EXPR* expr /**< expression */
    3603 )
    3604{
    3605 int i;
    3606 int n;
    3607
    3608 assert(blkmem != NULL);
    3609 assert(expr != NULL);
    3610
    3611 expr->quadchecked = FALSE;
    3612
    3613 if( expr->quaddata == NULL )
    3614 return;
    3615
    3616 n = expr->quaddata->nquadexprs;
    3617
    3622 if( expr->quaddata->eigenvectors != NULL ) /* check for NULL here before calculating n*n to avoid (harmless) overflow in case of large n */
    3623 BMSfreeBlockMemoryArray(blkmem, &expr->quaddata->eigenvectors, n * n); /*lint !e647*/
    3624
    3625 for( i = 0; i < n; ++i )
    3626 {
    3629 }
    3631
    3632 BMSfreeBlockMemory(blkmem, &expr->quaddata);
    3633}
    3634
    3635/** Checks the curvature of the quadratic function stored in quaddata
    3636 *
    3637 * For this, it builds the matrix Q of quadratic coefficients and computes its eigenvalues using LAPACK.
    3638 * If Q is
    3639 * - semidefinite positive -> curv is set to convex,
    3640 * - semidefinite negative -> curv is set to concave,
    3641 * - otherwise -> curv is set to unknown.
    3642 *
    3643 * If `assumevarfixed` is given and some expressions in quadratic terms correspond to variables present in
    3644 * this hashmap, then the corresponding rows and columns are ignored in the matrix Q.
    3645 */
    3647 SCIP_SET* set, /**< global SCIP settings */
    3648 BMS_BLKMEM* blkmem, /**< block memory */
    3649 BMS_BUFMEM* bufmem, /**< buffer memory */
    3650 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    3651 SCIP_EXPR* expr, /**< quadratic expression */
    3652 SCIP_EXPRCURV* curv, /**< pointer to store the curvature of quadratics */
    3653 SCIP_HASHMAP* assumevarfixed, /**< hashmap containing variables that should be assumed to be fixed, or NULL */
    3654 SCIP_Bool storeeigeninfo /**< whether the eigenvalues and eigenvectors should be stored */
    3655 )
    3656{
    3657 SCIP_QUADEXPR* quaddata;
    3658 SCIP_HASHMAP* expr2matrix;
    3659 double* matrix;
    3660 double* alleigval;
    3661 int nvars;
    3662 int nn;
    3663 int n;
    3664 int i;
    3665
    3666 assert(set != NULL);
    3667 assert(blkmem != NULL);
    3668 assert(bufmem != NULL);
    3669 assert(messagehdlr != NULL);
    3670 assert(expr != NULL);
    3671 assert(curv != NULL);
    3672
    3673 quaddata = expr->quaddata;
    3674 assert(quaddata != NULL);
    3675
    3676 /* do not store eigen information if we are not considering full matrix */
    3677 if( assumevarfixed != NULL )
    3678 storeeigeninfo = FALSE;
    3679
    3680 if( quaddata->eigeninfostored || (quaddata->curvaturechecked && !storeeigeninfo) )
    3681 {
    3682 *curv = quaddata->curvature;
    3683 /* if we are convex or concave on the full set of variables, then we will also be so on a subset */
    3684 if( assumevarfixed == NULL || quaddata->curvature != SCIP_EXPRCURV_UNKNOWN )
    3685 return SCIP_OKAY;
    3686 }
    3687 assert(quaddata->curvature == SCIP_EXPRCURV_UNKNOWN || assumevarfixed != NULL
    3688 || (storeeigeninfo && !quaddata->eigeninfostored));
    3689
    3690 *curv = SCIP_EXPRCURV_UNKNOWN;
    3691
    3692 n = quaddata->nquadexprs;
    3693
    3694 /* do not check curvature if nn will be too large
    3695 * we want nn * sizeof(real) to fit into an unsigned int, so n must be <= sqrt(uint_max/sizeof(real))
    3696 * sqrt(4294967295/8) = 23170.47500322339
    3697 */
    3698 if( n > 23000 )
    3699 {
    3700 SCIPmessageFPrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL, NULL,
    3701 "number of quadratic variables is too large (%d) to check the curvature\n", n);
    3702 return SCIP_OKAY;
    3703 }
    3704
    3705 /* TODO do some simple tests first; like diagonal entries don't change sign, etc */
    3706
    3707 if( ! SCIPlapackIsAvailable() )
    3708 return SCIP_OKAY;
    3709
    3710 nn = n * n;
    3711 assert(nn > 0);
    3712 assert((unsigned)nn < UINT_MAX / sizeof(SCIP_Real));
    3713
    3714 if( storeeigeninfo )
    3715 {
    3716 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &quaddata->eigenvalues, n));
    3717 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &quaddata->eigenvectors, nn));
    3718
    3719 alleigval = quaddata->eigenvalues;
    3720 matrix = quaddata->eigenvectors;
    3721 }
    3722 else
    3723 {
    3724 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &alleigval, n) );
    3725 SCIP_ALLOC( BMSallocClearBufferMemoryArray(bufmem, &matrix, nn) );
    3726 }
    3727
    3728 SCIP_CALL( SCIPhashmapCreate(&expr2matrix, blkmem, n) );
    3729
    3730 /* fill matrix's diagonal */
    3731 nvars = 0;
    3732 for( i = 0; i < n; ++i )
    3733 {
    3734 SCIP_QUADEXPR_QUADTERM quadexprterm;
    3735
    3736 quadexprterm = quaddata->quadexprterms[i];
    3737
    3738 assert(!SCIPhashmapExists(expr2matrix, (void*)quadexprterm.expr));
    3739
    3740 /* skip expr if it is a variable mentioned in assumevarfixed */
    3741 if( assumevarfixed != NULL && SCIPexprIsVar(set, quadexprterm.expr)
    3742 && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(quadexprterm.expr)) )
    3743 continue;
    3744
    3745 if( quadexprterm.sqrcoef == 0.0 && ! storeeigeninfo )
    3746 {
    3747 assert(quadexprterm.nadjbilin > 0);
    3748 /* SCIPdebugMsg(scip, "var <%s> appears in bilinear term but is not squared
    3749 * --> indefinite quadratic\n", SCIPvarGetName(quadexprterm.var)); */
    3750 goto CLEANUP;
    3751 }
    3752
    3753 matrix[nvars * n + nvars] = quadexprterm.sqrcoef;
    3754
    3755 /* remember row of variable in matrix */
    3756 SCIP_CALL( SCIPhashmapInsert(expr2matrix, (void *)quadexprterm.expr, (void *)(size_t)nvars) );
    3757 nvars++;
    3758 }
    3759
    3760 /* fill matrix's upper-diagonal */
    3761 for( i = 0; i < quaddata->nbilinexprterms; ++i )
    3762 {
    3763 SCIP_QUADEXPR_BILINTERM bilinexprterm;
    3764 int col;
    3765 int row;
    3766
    3767 bilinexprterm = quaddata->bilinexprterms[i];
    3768
    3769 /* each factor should have been added to expr2matrix unless it corresponds to a variable mentioned in assumevarfixed */
    3770 assert(SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr1)
    3771 || (assumevarfixed != NULL && SCIPexprIsVar(set, bilinexprterm.expr1)
    3772 && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(bilinexprterm.expr1))));
    3773 assert(SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr2)
    3774 || (assumevarfixed != NULL && SCIPexprIsVar(set, bilinexprterm.expr2)
    3775 && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(bilinexprterm.expr2))));
    3776
    3777 /* skip bilinear terms where at least one of the factors should be assumed to be fixed
    3778 * (i.e., not present in expr2matrix map) */
    3779 if( !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr1)
    3780 || !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr2) )
    3781 continue;
    3782
    3783 row = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr1);
    3784 col = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr2);
    3785
    3786 assert(row != col);
    3787
    3788 if( row < col )
    3789 matrix[row * n + col] = bilinexprterm.coef / 2.0;
    3790 else
    3791 matrix[col * n + row] = bilinexprterm.coef / 2.0;
    3792 }
    3793
    3794 /* compute eigenvalues */
    3795 if( SCIPlapackComputeEigenvalues(bufmem, storeeigeninfo, n, matrix, alleigval) != SCIP_OKAY )
    3796 {
    3797 SCIPmessagePrintWarning(messagehdlr, "Failed to compute eigenvalues of quadratic coefficient "
    3798 "matrix --> don't know curvature\n");
    3799 goto CLEANUP;
    3800 }
    3801
    3802 /* check convexity */
    3803 if( !SCIPsetIsNegative(set, alleigval[0]) )
    3804 *curv = SCIP_EXPRCURV_CONVEX;
    3805 else if( !SCIPsetIsPositive(set, alleigval[n-1]) )
    3806 *curv = SCIP_EXPRCURV_CONCAVE;
    3807
    3808CLEANUP:
    3809 SCIPhashmapFree(&expr2matrix);
    3810
    3811 if( !storeeigeninfo )
    3812 {
    3813 BMSfreeBufferMemoryArray(bufmem, &matrix);
    3814 BMSfreeBufferMemoryArray(bufmem, &alleigval);
    3815 }
    3816 else
    3817 {
    3818 assert(!quaddata->eigeninfostored);
    3819 quaddata->eigeninfostored = TRUE;
    3820 }
    3821
    3822 /* if checked convexity on full Q matrix, then remember it
    3823 * if indefinite on submatrix, then it will also be indefinite on full matrix, so can remember that, too */
    3824 if( assumevarfixed == NULL || *curv == SCIP_EXPRCURV_UNKNOWN )
    3825 {
    3826 quaddata->curvature = *curv;
    3827 quaddata->curvaturechecked = TRUE;
    3828 }
    3829
    3830 return SCIP_OKAY;
    3831}
    3832
    3833
    3834/* from pub_expr.h */
    3835
    3836#ifdef NDEBUG
    3837#undef SCIPexprGetNUses
    3838#undef SCIPexprGetNChildren
    3839#undef SCIPexprGetChildren
    3840#undef SCIPexprGetHdlr
    3841#undef SCIPexprGetData
    3842#undef SCIPexprSetData
    3843#undef SCIPexprGetOwnerData
    3844#undef SCIPexprGetEvalValue
    3845#undef SCIPexprGetEvalTag
    3846#undef SCIPexprGetDerivative
    3847#undef SCIPexprGetDot
    3848#undef SCIPexprGetBardot
    3849#undef SCIPexprGetDiffTag
    3850#undef SCIPexprGetActivity
    3851#undef SCIPexprGetActivityTag
    3852#undef SCIPexprSetActivity
    3853#undef SCIPexprGetCurvature
    3854#undef SCIPexprSetCurvature
    3855#undef SCIPexprGetIntegrality
    3856#undef SCIPexprIsIntegral
    3857#undef SCIPexprSetIntegrality
    3858#undef SCIPexprAreQuadraticExprsVariables
    3859#endif
    3860
    3861/** gets the number of times the expression is currently captured */
    3863 SCIP_EXPR* expr /**< expression */
    3864 )
    3865{
    3866 assert(expr != NULL);
    3867
    3868 return expr->nuses;
    3869}
    3870
    3871/** gives the number of children of an expression */
    3873 SCIP_EXPR* expr /**< expression */
    3874 )
    3875{
    3876 assert(expr != NULL);
    3877
    3878 return expr->nchildren;
    3879}
    3880
    3881/** gives the children of an expression (can be NULL if no children) */
    3883 SCIP_EXPR* expr /**< expression */
    3884 )
    3885{
    3886 assert(expr != NULL);
    3887
    3888 return expr->children;
    3889}
    3890
    3891/** gets the expression handler of an expression
    3892 *
    3893 * This identifies the type of the expression (sum, variable, ...).
    3894 */
    3896 SCIP_EXPR* expr /**< expression */
    3897 )
    3898{
    3899 assert(expr != NULL);
    3900
    3901 return expr->exprhdlr;
    3902}
    3903
    3904/** gets the expression data of an expression */
    3906 SCIP_EXPR* expr /**< expression */
    3907 )
    3908{
    3909 assert(expr != NULL);
    3910
    3911 return expr->exprdata;
    3912}
    3913
    3914/** sets the expression data of an expression
    3915 *
    3916 * The pointer to possible old data is overwritten and the
    3917 * freedata-callback is not called before.
    3918 * This function is intended to be used by expression handler only.
    3919 */
    3921 SCIP_EXPR* expr, /**< expression */
    3922 SCIP_EXPRDATA* exprdata /**< expression data to be set (can be NULL) */
    3923 )
    3924{
    3925 assert(expr != NULL);
    3926 assert(exprdata == NULL || expr->exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
    3927 assert(exprdata == NULL || expr->exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
    3928
    3929 expr->exprdata = exprdata;
    3930}
    3931
    3932/** gets the data that the owner of an expression has stored in an expression */
    3934 SCIP_EXPR* expr /**< expression */
    3935 )
    3936{
    3937 assert(expr != NULL);
    3938
    3939 return expr->ownerdata;
    3940}
    3941
    3942/** gives the value from the last evaluation of an expression (or SCIP_INVALID if there was an eval error)
    3943 *
    3944 * @see SCIPevalExpr to evaluate the expression at a given solution.
    3945 */
    3947 SCIP_EXPR* expr /**< expression */
    3948 )
    3949{
    3950 assert(expr != NULL);
    3951
    3952 return expr->evalvalue;
    3953}
    3954
    3955/** gives the evaluation tag from the last evaluation, or 0
    3956 *
    3957 * @see SCIPevalExpr
    3958 */
    3960 SCIP_EXPR* expr /**< expression */
    3961 )
    3962{
    3963 assert(expr != NULL);
    3964
    3965 return expr->evaltag;
    3966}
    3967
    3968/** returns the derivative stored in an expression (or SCIP_INVALID if there was an evaluation error)
    3969 *
    3970 * @see SCIPevalExprGradient
    3971 */
    3973 SCIP_EXPR* expr /**< expression */
    3974 )
    3975{
    3976 assert(expr != NULL);
    3977
    3978 return expr->derivative;
    3979}
    3980
    3981/** gives the value of directional derivative from the last evaluation of a directional derivative of
    3982 * expression (or SCIP_INVALID if there was an error)
    3983 *
    3984 * @see SCIPevalExprHessianDir
    3985 */
    3987 SCIP_EXPR* expr /**< expression */
    3988 )
    3989{
    3990 assert(expr != NULL);
    3991
    3992 return expr->dot;
    3993}
    3994
    3995/** gives the value of directional derivative from the last evaluation of a directional derivative of
    3996 * derivative of root (or SCIP_INVALID if there was an error)
    3997 *
    3998 * @see SCIPevalExprHessianDir
    3999 */
    4001 SCIP_EXPR* expr /**< expression */
    4002 )
    4003{
    4004 assert(expr != NULL);
    4005
    4006 return expr->bardot;
    4007}
    4008
    4009/** returns the difftag stored in an expression
    4010 *
    4011 * can be used to check whether partial derivative value is valid
    4012 *
    4013 * @see SCIPevalExprGradient
    4014 */
    4016 SCIP_EXPR* expr /**< expression */
    4017 )
    4018{
    4019 assert(expr != NULL);
    4020
    4021 return expr->difftag;
    4022}
    4023
    4024/** returns the activity that is currently stored for an expression
    4025 *
    4026 * @see SCIPevalExprActivity
    4027 */
    4029 SCIP_EXPR* expr /**< expression */
    4030 )
    4031{
    4032 assert(expr != NULL);
    4033
    4034 return expr->activity;
    4035}
    4036
    4037/** returns the tag associated with the activity of the expression
    4038 *
    4039 * It can depend on the owner of the expression how to interpret this tag.
    4040 * SCIPevalExprActivity() compares with `stat->domchgcount`.
    4041 *
    4042 * @see SCIPevalExprActivity
    4043 */
    4045 SCIP_EXPR* expr /**< expression */
    4046 )
    4047{
    4048 assert(expr != NULL);
    4049
    4050 return expr->activitytag;
    4051}
    4052
    4053/** set the activity with tag for an expression */
    4055 SCIP_EXPR* expr, /**< expression */
    4056 SCIP_INTERVAL activity, /**< new activity */
    4057 SCIP_Longint activitytag /**< tag associated with activity */
    4058 )
    4059{
    4060 assert(expr != NULL);
    4061
    4062 expr->activity = activity;
    4063 expr->activitytag = activitytag;
    4064}
    4065
    4066/** returns the curvature of an expression
    4067 *
    4068 * @note Call SCIPcomputeExprCurvature() before calling this function.
    4069 */
    4071 SCIP_EXPR* expr /**< expression */
    4072 )
    4073{
    4074 assert(expr != NULL);
    4075
    4076 return expr->curvature;
    4077}
    4078
    4079/** sets the curvature of an expression */
    4081 SCIP_EXPR* expr, /**< expression */
    4082 SCIP_EXPRCURV curvature /**< curvature of the expression */
    4083 )
    4084{
    4085 assert(expr != NULL);
    4086
    4087 expr->curvature = curvature;
    4088}
    4089
    4090/** returns implied integrality of an expression */
    4092 SCIP_EXPR* expr /**< expression */
    4093 )
    4094{
    4095 assert(expr != NULL);
    4096
    4097 return expr->integrality;
    4098}
    4099
    4100/** returns whether an expression is integral, i.e. whether the integrality flag is not equal to SCIP_IMPLINTTYPE_NONE */
    4102 SCIP_EXPR* expr /**< expression */
    4103 )
    4104{
    4105 assert(expr != NULL);
    4106
    4107 return expr->integrality != SCIP_IMPLINTTYPE_NONE;
    4108}
    4109
    4110/** sets the integrality flag of an expression */
    4112 SCIP_EXPR* expr, /**< expression */
    4113 SCIP_IMPLINTTYPE integrality /**< integrality level of the expression */
    4114 )
    4115{
    4116 assert(expr != NULL);
    4117
    4118 expr->integrality = integrality;
    4119}
    4120
    4121/** gives the coefficients and expressions that define a quadratic expression
    4122 *
    4123 * It can return the constant part, the number, arguments, and coefficients of the purely linear part
    4124 * and the number of quadratic terms and bilinear terms.
    4125 * Note that for arguments that appear in the quadratic part, a linear coefficient is
    4126 * stored with the quadratic term.
    4127 * Use SCIPexprGetQuadraticQuadTerm() and SCIPexprGetQuadraticBilinTerm()
    4128 * to access the data for a quadratic or bilinear term.
    4129 *
    4130 * It can also return the eigenvalues and the eigenvectors of the matrix \f$Q\f$ when the quadratic is written
    4131 * as \f$x^T Q x + b^T x + c^T y + d\f$, where \f$c^T y\f$ defines the purely linear part.
    4132 * Note, however, that to have access to them one needs to call SCIPcomputeExprQuadraticCurvature()
    4133 * with `storeeigeninfo=TRUE`. If the eigen information was not stored or it failed to be computed,
    4134 * `eigenvalues` and `eigenvectors` will be set to NULL.
    4135 *
    4136 * This function returns pointers to internal data in linexprs and lincoefs.
    4137 * The user must not change this data.
    4138 *
    4139 * @attention SCIPcheckExprQuadratic() needs to be called first to check whether expression is quadratic and initialize the data of the quadratic representation.
    4140 */
    4142 SCIP_EXPR* expr, /**< quadratic expression */
    4143 SCIP_Real* constant, /**< buffer to store constant term, or NULL */
    4144 int* nlinexprs, /**< buffer to store number of expressions that appear linearly, or NULL */
    4145 SCIP_EXPR*** linexprs, /**< buffer to store pointer to array of expressions that appear linearly, or NULL */
    4146 SCIP_Real** lincoefs, /**< buffer to store pointer to array of coefficients of expressions that appear linearly, or NULL */
    4147 int* nquadexprs, /**< buffer to store number of expressions in quadratic terms, or NULL */
    4148 int* nbilinexprs, /**< buffer to store number of bilinear expressions terms, or NULL */
    4149 SCIP_Real** eigenvalues, /**< buffer to store pointer to array of eigenvalues of Q, or NULL */
    4150 SCIP_Real** eigenvectors /**< buffer to store pointer to array of eigenvectors of Q, or NULL */
    4151 )
    4152{
    4153 SCIP_QUADEXPR* quaddata;
    4154
    4155 assert(expr != NULL);
    4156
    4157 quaddata = expr->quaddata;
    4158 assert(quaddata != NULL);
    4159
    4160 if( constant != NULL )
    4161 *constant = quaddata->constant;
    4162 if( nlinexprs != NULL )
    4163 *nlinexprs = quaddata->nlinexprs;
    4164 if( linexprs != NULL )
    4165 *linexprs = quaddata->linexprs;
    4166 if( lincoefs != NULL )
    4167 *lincoefs = quaddata->lincoefs;
    4168 if( nquadexprs != NULL )
    4169 *nquadexprs = quaddata->nquadexprs;
    4170 if( nbilinexprs != NULL )
    4171 *nbilinexprs = quaddata->nbilinexprterms;
    4172 if( eigenvalues != NULL )
    4173 *eigenvalues = quaddata->eigenvalues;
    4174 if( eigenvectors != NULL )
    4175 *eigenvectors = quaddata->eigenvectors;
    4176}
    4177
    4178/** gives the data of a quadratic expression term
    4179 *
    4180 * For a term \f$a \cdot \text{expr}^2 + b \cdot \text{expr} + \sum_i (c_i \cdot \text{expr} \cdot \text{otherexpr}_i)\f$, returns
    4181 * `expr`, \f$a\f$, \f$b\f$, the number of summands, and indices of bilinear terms in the quadratic expressions `bilinexprterms`.
    4182 *
    4183 * This function returns pointers to internal data in adjbilin.
    4184 * The user must not change this data.
    4185 */
    4187 SCIP_EXPR* quadexpr, /**< quadratic expression */
    4188 int termidx, /**< index of quadratic term */
    4189 SCIP_EXPR** expr, /**< buffer to store pointer to argument expression (the 'x') of this term, or NULL */
    4190 SCIP_Real* lincoef, /**< buffer to store linear coefficient of variable, or NULL */
    4191 SCIP_Real* sqrcoef, /**< buffer to store square coefficient of variable, or NULL */
    4192 int* nadjbilin, /**< buffer to store number of bilinear terms this variable is involved in, or NULL */
    4193 int** adjbilin, /**< buffer to store pointer to indices of associated bilinear terms, or NULL */
    4194 SCIP_EXPR** sqrexpr /**< buffer to store pointer to square expression (the 'x^2') of this term or NULL if no square expression, or NULL */
    4195 )
    4196{
    4197 SCIP_QUADEXPR_QUADTERM* quadexprterm;
    4198
    4199 assert(quadexpr != NULL);
    4200 assert(quadexpr->quaddata != NULL);
    4201 assert(quadexpr->quaddata->quadexprterms != NULL);
    4202 assert(termidx >= 0);
    4203 assert(termidx < quadexpr->quaddata->nquadexprs);
    4204
    4205 quadexprterm = &quadexpr->quaddata->quadexprterms[termidx];
    4206
    4207 if( expr != NULL )
    4208 *expr = quadexprterm->expr;
    4209 if( lincoef != NULL )
    4210 *lincoef = quadexprterm->lincoef;
    4211 if( sqrcoef != NULL )
    4212 *sqrcoef = quadexprterm->sqrcoef;
    4213 if( nadjbilin != NULL )
    4214 *nadjbilin = quadexprterm->nadjbilin;
    4215 if( adjbilin != NULL )
    4216 *adjbilin = quadexprterm->adjbilin;
    4217 if( sqrexpr != NULL )
    4218 *sqrexpr = quadexprterm->sqrexpr;
    4219}
    4220
    4221/** gives the data of a bilinear expression term
    4222 *
    4223 * For a term a*expr1*expr2, returns expr1, expr2, a, and
    4224 * the position of the quadratic expression term that uses expr2 in the quadratic expressions `quadexprterms`.
    4225 */
    4227 SCIP_EXPR* expr, /**< quadratic expression */
    4228 int termidx, /**< index of bilinear term */
    4229 SCIP_EXPR** expr1, /**< buffer to store first factor, or NULL */
    4230 SCIP_EXPR** expr2, /**< buffer to store second factor, or NULL */
    4231 SCIP_Real* coef, /**< buffer to coefficient, or NULL */
    4232 int* pos2, /**< buffer to position of expr2 in quadexprterms array of quadratic expression, or NULL */
    4233 SCIP_EXPR** prodexpr /**< buffer to store pointer to expression that is product if first and second factor, or NULL */
    4234 )
    4235{
    4236 SCIP_QUADEXPR_BILINTERM* bilinexprterm;
    4237
    4238 assert(expr != NULL);
    4239 assert(expr->quaddata != NULL);
    4240 assert(expr->quaddata->bilinexprterms != NULL);
    4241 assert(termidx >= 0);
    4242 assert(termidx < expr->quaddata->nbilinexprterms);
    4243
    4244 bilinexprterm = &expr->quaddata->bilinexprterms[termidx];
    4245
    4246 if( expr1 != NULL )
    4247 *expr1 = bilinexprterm->expr1;
    4248 if( expr2 != NULL )
    4249 *expr2 = bilinexprterm->expr2;
    4250 if( coef != NULL )
    4251 *coef = bilinexprterm->coef;
    4252 if( pos2 != NULL )
    4253 *pos2 = bilinexprterm->pos2;
    4254 if( prodexpr != NULL )
    4255 *prodexpr = bilinexprterm->prodexpr;
    4256}
    4257
    4258/** returns whether all expressions that are used in a quadratic expression are variable expressions
    4259 *
    4260 * @return TRUE iff all `linexprs` and `quadexprterms[.].expr` are variable expressions
    4261 */
    4263 SCIP_EXPR* expr /**< quadratic expression */
    4264 )
    4265{
    4266 assert(expr != NULL);
    4267 assert(expr->quaddata != NULL);
    4268
    4269 return expr->quaddata->allexprsarevars;
    4270}
    4271
    4272/** returns a monomial representation of a product expression
    4273 *
    4274 * The array to store all factor expressions needs to be of size the number of
    4275 * children in the expression which is given by SCIPexprGetNChildren().
    4276 *
    4277 * Given a non-trivial monomial expression, the function finds its representation as \f$cx^\alpha\f$, where
    4278 * \f$c\f$ is a real coefficient, \f$x\f$ is a vector of auxiliary or original variables (where some entries can
    4279 * be NULL is the auxiliary variable has not been created yet), and \f$\alpha\f$ is a real vector of exponents.
    4280 *
    4281 * A non-trivial monomial is a product of a least two expressions.
    4282 */
    4284 SCIP_SET* set, /**< global SCIP settings */
    4285 BMS_BLKMEM* blkmem, /**< block memory */
    4286 SCIP_EXPR* expr, /**< expression */
    4287 SCIP_Real* coef, /**< coefficient \f$c\f$ */
    4288 SCIP_Real* exponents, /**< exponents \f$\alpha\f$ */
    4289 SCIP_EXPR** factors /**< factor expressions \f$x\f$ */
    4290 )
    4291{
    4292 SCIP_EXPR* child;
    4293 int c;
    4294 int nexprs;
    4295
    4296 assert(set != NULL);
    4297 assert(blkmem != NULL);
    4298 assert(expr != NULL);
    4299 assert(coef != NULL);
    4300 assert(exponents != NULL);
    4301 assert(factors != NULL);
    4302
    4303 assert(SCIPexprIsProduct(set, expr));
    4304
    4305 *coef = SCIPgetCoefExprProduct(expr);
    4306 nexprs = SCIPexprGetNChildren(expr);
    4307
    4308 for( c = 0; c < nexprs; ++c )
    4309 {
    4310 child = SCIPexprGetChildren(expr)[c];
    4311
    4312 if( SCIPexprIsPower(set, child) )
    4313 {
    4314 exponents[c] = SCIPgetExponentExprPow(child);
    4315 factors[c] = SCIPexprGetChildren(child)[0];
    4316 }
    4317 else
    4318 {
    4319 exponents[c] = 1.0;
    4320 factors[c] = child;
    4321 }
    4322 }
    4323
    4324 return SCIP_OKAY;
    4325}
    4326
    4327/**@} */
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    void SCIPclockReset(SCIP_CLOCK *clck)
    Definition: clock.c:209
    void SCIPclockFree(SCIP_CLOCK **clck)
    Definition: clock.c:185
    SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
    Definition: clock.c:170
    internal methods for clocks and timing issues
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_INTERVAL_INFINITY
    Definition: def.h:180
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:397
    SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
    Definition: expr.c:2266
    SCIP_Bool SCIPexprIsPower(SCIP_SET *set, SCIP_EXPR *expr)
    Definition: expr.c:2254
    SCIP_RETCODE SCIPexprhdlrBwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, int childidx, SCIP_Real *derivative, SCIP_Real *childrenvals, SCIP_Real exprval)
    Definition: expr.c:1272
    SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
    Definition: expr.c:2961
    static SCIP_RETCODE evalAndDiff(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
    Definition: expr.c:188
    SCIP_RETCODE SCIPexprPrintDotInit(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, FILE *file, SCIP_EXPRPRINT_WHAT whattoprint)
    Definition: expr.c:2315
    SCIP_RETCODE SCIPexprCopy(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_SET *targetset, SCIP_STAT *targetstat, BMS_BLKMEM *targetblkmem, SCIP_EXPR *sourceexpr, SCIP_EXPR **targetexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:1878
    SCIP_RETCODE SCIPexprPrintDotInit2(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, const char *filename, SCIP_EXPRPRINT_WHAT whattoprint)
    Definition: expr.c:2347
    SCIP_RETCODE SCIPexprSimplify(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:3200
    SCIP_RETCODE SCIPexprhdlrInitEstimatesExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *bounds, SCIP_Bool overestimate, SCIP_Real *coefs[SCIP_EXPR_MAXINITESTIMATES], SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], int *nreturned)
    Definition: expr.c:1600
    SCIP_RETCODE SCIPexprComputeQuadraticCurvature(SCIP_SET *set, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRCURV *curv, SCIP_HASHMAP *assumevarfixed, SCIP_Bool storeeigeninfo)
    Definition: expr.c:3646
    SCIP_RETCODE SCIPexprGetSymData(SCIP_SET *set, SCIP_EXPR *expr, SYM_EXPRDATA **symdata)
    Definition: expr.c:3294
    SCIP_RETCODE SCIPexprhdlrSimplifyExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPR **simplifiedexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:1635
    SCIP_RETCODE SCIPexprEvalGradient(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag)
    Definition: expr.c:2745
    SCIP_RETCODE SCIPexprReplaceChild(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
    Definition: expr.c:1816
    SCIP_RETCODE SCIPexprhdlrReversePropExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL bounds, SCIP_INTERVAL *childrenbounds, SCIP_Bool *infeasible)
    Definition: expr.c:1680
    SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
    Definition: expr.c:2206
    static SCIP_RETCODE freeExpr(BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
    Definition: expr.c:74
    SCIP_RETCODE SCIPexprCheckQuadratic(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
    Definition: expr.c:3326
    SCIP_RETCODE SCIPexprhdlrFree(SCIP_EXPRHDLR **exprhdlr, SCIP_SET *set, BMS_BLKMEM *blkmem)
    Definition: expr.c:340
    SCIP_RETCODE SCIPexprhdlrPrintExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRITER_STAGE stage, int currentchild, unsigned int parentprecedence, FILE *file)
    Definition: expr.c:917
    SCIP_RETCODE SCIPexprEvalHessianDir(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
    Definition: expr.c:2855
    int SCIPexprCompare(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
    Definition: expr.c:3093
    SCIP_RETCODE SCIPexprhdlrMonotonicityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_MONOTONE *result)
    Definition: expr.c:1054
    SCIP_RETCODE SCIPexprhdlrEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *childrenvals, SCIP_SOL *sol)
    Definition: expr.c:1205
    void SCIPexprhdlrInit(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set)
    Definition: expr.c:884
    SCIP_RETCODE SCIPexprRemoveChildren(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
    Definition: expr.c:1846
    SCIP_RETCODE SCIPexprhdlrIntegralityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_IMPLINTTYPE *integrality)
    Definition: expr.c:1083
    SCIP_RETCODE SCIPexprhdlrCopyInclude(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *targetset)
    Definition: expr.c:859
    SCIP_RETCODE SCIPexprhdlrHashExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, unsigned int *hashkey, unsigned int *childrenhashes)
    Definition: expr.c:1113
    SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
    Definition: expr.c:2218
    SCIP_RETCODE SCIPexprhdlrFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_Real *dot, SCIP_SOL *direction)
    Definition: expr.c:1345
    void SCIPexprCapture(SCIP_EXPR *expr)
    Definition: expr.c:2064
    SCIP_RETCODE SCIPexprhdlrIntEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *interval, SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), void *intevalvardata)
    Definition: expr.c:1525
    static SCIP_RETCODE quadDetectProcessExpr(SCIP_EXPR *expr, SCIP_HASHMAP *seenexpr, int *nquadterms, int *nlinterms)
    Definition: expr.c:105
    SCIP_RETCODE SCIPexprhdlrBwFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_Real *bardot, SCIP_SOL *direction)
    Definition: expr.c:1489
    SCIP_RETCODE SCIPexprPrintDotFinal(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata)
    Definition: expr.c:2493
    SCIP_RETCODE SCIPexprAppendChild(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR *child)
    Definition: expr.c:1785
    SCIP_RETCODE SCIPexprDuplicateShallow(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:2033
    SCIP_RETCODE SCIPexprhdlrParseExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, const char *string, const char **endstring, SCIP_EXPR **expr, SCIP_Bool *success, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:986
    SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
    Definition: expr.c:2074
    SCIP_RETCODE SCIPexprGetMonomialData(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Real *coef, SCIP_Real *exponents, SCIP_EXPR **factors)
    Definition: expr.c:4283
    int SCIPexprhdlrCompareExpr(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
    Definition: expr.c:1162
    SCIP_RETCODE SCIPexprhdlrCurvatureExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPRCURV exprcurvature, SCIP_Bool *success, SCIP_EXPRCURV *childcurv)
    Definition: expr.c:1025
    SCIP_RETCODE SCIPexprDismantle(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
    Definition: expr.c:2546
    SCIP_RETCODE SCIPexprCreate(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPRHDLR *exprhdlr, SCIP_EXPRDATA *exprdata, int nchildren, SCIP_EXPR **children, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr.c:1728
    SCIP_Bool SCIPexprIsProduct(SCIP_SET *set, SCIP_EXPR *expr)
    Definition: expr.c:2242
    SCIP_RETCODE SCIPexprPrintDot(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPRPRINTDATA *printdata, SCIP_EXPR *expr)
    Definition: expr.c:2379
    SCIP_Bool SCIPexprIsSum(SCIP_SET *set, SCIP_EXPR *expr)
    Definition: expr.c:2230
    SCIP_RETCODE SCIPexprhdlrEstimateExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *localbounds, SCIP_INTERVAL *globalbounds, SCIP_Real *refpoint, SCIP_Bool overestimate, SCIP_Real targetvalue, SCIP_Real *coefs, SCIP_Real *constant, SCIP_Bool *islocal, SCIP_Bool *success, SCIP_Bool *branchcand)
    Definition: expr.c:1556
    SCIP_RETCODE SCIPexprhdlrEvalFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *dot, SCIP_Real *childrenvals, SCIP_SOL *sol, SCIP_Real *childrendirs, SCIP_SOL *direction)
    Definition: expr.c:1386
    SCIP_RETCODE SCIPexprhdlrCreate(BMS_BLKMEM *blkmem, SCIP_EXPRHDLR **exprhdlr, const char *name, const char *desc, unsigned int precedence, SCIP_DECL_EXPREVAL((*eval)), SCIP_EXPRHDLRDATA *data)
    Definition: expr.c:305
    static SCIP_RETCODE quadDetectGetQuadexprterm(BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_HASHMAP *expr2idx, SCIP_HASHMAP *seenexpr, SCIP_QUADEXPR *quadexpr, SCIP_QUADEXPR_QUADTERM **quadexprterm)
    Definition: expr.c:145
    void SCIPexprFreeQuadratic(BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
    Definition: expr.c:3600
    SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
    Definition: expr.c:2654
    private functions to work with algebraic expressions
    void SCIPexpriterFree(SCIP_EXPRITER **iterator)
    Definition: expriter.c:446
    SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
    Definition: expriter.c:427
    static SCIP_RETCODE eval(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, const vector< Type > &x, Type &val)
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3304
    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
    int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3584
    SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
    Definition: misc.c:3592
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
    Definition: misc.c:3603
    SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3466
    SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
    Definition: misc.c:3179
    SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
    Definition: misc.c:3400
    unsigned int SCIPcalcFibHash(SCIP_Real v)
    Definition: misc.c:10462
    const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:545
    SCIP_Real SCIPexprhdlrGetEstimateTime(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:793
    SCIP_Bool SCIPexprhdlrHasSimplify(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:645
    SCIP_Longint SCIPexprhdlrGetNDomainReductions(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:761
    void SCIPexprhdlrSetIntegrality(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEGRALITY((*integrality)))
    Definition: expr.c:440
    void SCIPexprhdlrSetCopyFreeData(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYDATA((*copydata)), SCIP_DECL_EXPRFREEDATA((*freedata)))
    Definition: expr.c:383
    void SCIPexprhdlrSetPrint(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPRINT((*print)))
    Definition: expr.c:396
    void SCIPexprhdlrSetGetSymdata(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRGETSYMDATA((*getsymdata)))
    Definition: expr.c:521
    SCIP_Bool SCIPexprhdlrHasCurvature(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:655
    void SCIPexprhdlrSetHash(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRHASH((*hash)))
    Definition: expr.c:451
    void SCIPexprhdlrIncrementNDomainReductions(SCIP_EXPRHDLR *exprhdlr, int nreductions)
    Definition: expr.c:771
    SCIP_EXPRHDLRDATA * SCIPexprhdlrGetData(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:575
    SCIP_Real SCIPexprhdlrGetReversepropTime(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:741
    unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:565
    void SCIPexprhdlrIncrementNBranchings(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:817
    SCIP_Longint SCIPexprhdlrGetNReversepropCalls(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:731
    SCIP_DECL_SORTPTRCOMP(SCIPexprhdlrComp)
    Definition: expr.c:695
    void SCIPexprhdlrSetCopyFreeHdlr(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), SCIP_DECL_EXPRFREEHDLR((*freehdlr)))
    Definition: expr.c:370
    const char * SCIPexprhdlrGetDescription(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:555
    SCIP_Bool SCIPexprhdlrHasFwdiff(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:605
    SCIP_Bool SCIPexprhdlrHasGetSymData(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:685
    SCIP_Bool SCIPexprhdlrHasMonotonicity(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:665
    void SCIPexprhdlrSetDiff(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRBWDIFF((*bwdiff)), SCIP_DECL_EXPRFWDIFF((*fwdiff)), SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)))
    Definition: expr.c:473
    SCIP_Bool SCIPexprhdlrHasReverseProp(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:675
    unsigned int SCIPexprhdlrGetNCreated(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:701
    SCIP_Bool SCIPexprhdlrHasInitEstimates(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:635
    SCIP_Longint SCIPexprhdlrGetNBranchings(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:807
    SCIP_Bool SCIPexprhdlrHasPrint(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:585
    void SCIPexprhdlrSetReverseProp(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRREVERSEPROP((*reverseprop)))
    Definition: expr.c:510
    void SCIPexprhdlrSetParse(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPARSE((*parse)))
    Definition: expr.c:407
    SCIP_Longint SCIPexprhdlrGetNSimplifyCalls(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:827
    SCIP_Real SCIPexprhdlrGetIntevalTime(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:721
    void SCIPexprhdlrSetEstimate(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINITESTIMATES((*initestimates)), SCIP_DECL_EXPRESTIMATE((*estimate)))
    Definition: expr.c:532
    void SCIPexprhdlrSetMonotonicity(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRMONOTONICITY((*monotonicity)))
    Definition: expr.c:429
    void SCIPexprhdlrSetIntEval(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEVAL((*inteval)))
    Definition: expr.c:488
    void SCIPexprhdlrSetCurvature(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCURVATURE((*curvature)))
    Definition: expr.c:418
    SCIP_Bool SCIPexprhdlrHasEstimate(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:625
    SCIP_Real SCIPexprhdlrGetSimplifyTime(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:837
    void SCIPexprhdlrSetCompare(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOMPARE((*compare)))
    Definition: expr.c:462
    SCIP_Longint SCIPexprhdlrGetNIntevalCalls(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:711
    SCIP_Longint SCIPexprhdlrGetNSimplifications(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:847
    SCIP_Longint SCIPexprhdlrGetNCutoffs(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:751
    SCIP_Bool SCIPexprhdlrHasIntEval(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:615
    void SCIPexprhdlrSetSimplify(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRSIMPLIFY((*simplify)))
    Definition: expr.c:499
    SCIP_Bool SCIPexprhdlrHasBwdiff(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:595
    SCIP_Longint SCIPexprhdlrGetNEstimateCalls(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:783
    void SCIPexprSetActivity(SCIP_EXPR *expr, SCIP_INTERVAL activity, SCIP_Longint activitytag)
    Definition: expr.c:4054
    SCIP_IMPLINTTYPE SCIPexprGetIntegrality(SCIP_EXPR *expr)
    Definition: expr.c:4091
    void SCIPexprSetData(SCIP_EXPR *expr, SCIP_EXPRDATA *exprdata)
    Definition: expr.c:3920
    int SCIPexprGetNChildren(SCIP_EXPR *expr)
    Definition: expr.c:3872
    void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
    Definition: expr.c:4226
    SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
    Definition: expr_pow.c:3448
    SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
    Definition: expriter.c:969
    void SCIPexprSetCurvature(SCIP_EXPR *expr, SCIP_EXPRCURV curvature)
    Definition: expr.c:4080
    SCIP_EXPR * SCIPexpriterSkipDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:930
    SCIP_EXPR_OWNERDATA * SCIPexprGetOwnerData(SCIP_EXPR *expr)
    Definition: expr.c:3933
    SCIP_Real SCIPexprGetDerivative(SCIP_EXPR *expr)
    Definition: expr.c:3972
    SCIP_Longint SCIPexprGetEvalTag(SCIP_EXPR *expr)
    Definition: expr.c:3959
    SCIP_Bool SCIPexprIsIntegral(SCIP_EXPR *expr)
    Definition: expr.c:4101
    SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
    Definition: expr.c:4262
    void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
    Definition: expr.c:4141
    SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1554
    SCIP_EXPRITER_USERDATA SCIPexpriterGetCurrentUserData(SCIP_EXPRITER *iterator)
    Definition: expriter.c:756
    SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
    SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
    Definition: expriter.c:683
    void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
    Definition: expriter.c:664
    SCIP_Real SCIPexprGetDot(SCIP_EXPR *expr)
    Definition: expr.c:3986
    SCIP_EXPRDATA * SCIPexprGetData(SCIP_EXPR *expr)
    Definition: expr.c:3905
    SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
    Definition: scip_expr.c:1512
    SCIP_EXPRCURV SCIPexprGetCurvature(SCIP_EXPR *expr)
    Definition: expr.c:4070
    SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:740
    SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
    Definition: expr_value.c:298
    void SCIPexpriterSetCurrentUserData(SCIP_EXPRITER *iterator, SCIP_EXPRITER_USERDATA userdata)
    Definition: expriter.c:806
    SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
    Definition: expr.c:3946
    SCIP_Longint SCIPexprGetActivityTag(SCIP_EXPR *expr)
    Definition: expr.c:4044
    SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
    Definition: expriter.c:858
    SCIP_Real SCIPexprGetBardot(SCIP_EXPR *expr)
    Definition: expr.c:4000
    SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
    Definition: expr.c:3882
    SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1569
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
    Definition: expr.c:4028
    void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
    Definition: expr.c:4186
    int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:707
    SCIP_EXPRITER_USERDATA SCIPexpriterGetChildUserDataDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:771
    SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:696
    void SCIPexprSetIntegrality(SCIP_EXPR *expr, SCIP_IMPLINTTYPE integrality)
    Definition: expr.c:4111
    SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
    Definition: expriter.c:501
    int SCIPexprGetNUses(SCIP_EXPR *expr)
    Definition: expr.c:3862
    SCIP_EXPRITER_USERDATA SCIPexpriterGetExprUserData(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
    Definition: expriter.c:790
    SCIP_Longint SCIPexprGetDiffTag(SCIP_EXPR *expr)
    Definition: expr.c:4015
    SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
    Definition: expr.c:3895
    SCIP_EXPR * SCIPexpriterGetChildExprDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:721
    void SCIPintervalSetEntire(SCIP_Real infinity, SCIP_INTERVAL *resultant)
    void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Bool SCIPlapackIsAvailable(void)
    Definition: lapack_calls.c:121
    SCIP_RETCODE SCIPlapackComputeEigenvalues(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
    Definition: lapack_calls.c:352
    interface methods for lapack functions
    #define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
    Definition: memory.h:462
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSfreeBufferMemoryArray(mem, ptr)
    Definition: memory.h:742
    #define BMSfreeMemoryArray(ptr)
    Definition: memory.h:147
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    #define BMSallocClearBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:455
    #define BMSallocBufferMemoryArray(mem, ptr, num)
    Definition: memory.h:731
    #define BMSallocClearBlockMemory(mem, ptr)
    Definition: memory.h:452
    #define BMSallocClearBufferMemoryArray(mem, ptr, num)
    Definition: memory.h:732
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    void SCIPmessageFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: message.c:706
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    #define SCIPisFinite(x)
    Definition: pub_misc.h:82
    public methods for problem variables
    SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6716
    SCIP_EXPRHDLR * SCIPsetFindExprhdlr(SCIP_SET *set, const char *name)
    Definition: set.c:5426
    SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6728
    SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6648
    SCIP_Real SCIPsetFrac(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6752
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6659
    internal methods for global SCIP settings
    #define SCIPsetDebugMsgPrint
    Definition: set.h:1812
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    internal methods for storing primal CIP solutions
    SCIP_Real dot
    Definition: struct_expr.h:126
    SCIP_EXPRCURV curvature
    Definition: struct_expr.h:138
    SCIP_EXPRDATA * exprdata
    Definition: struct_expr.h:108
    SCIP_Real evalvalue
    Definition: struct_expr.h:124
    SCIP_INTERVAL activity
    Definition: struct_expr.h:134
    SCIP_Longint difftag
    Definition: struct_expr.h:129
    SCIP_EXPRHDLR * exprhdlr
    Definition: struct_expr.h:107
    SCIP_EXPR_OWNERDATA * ownerdata
    Definition: struct_expr.h:118
    SCIP_Bool quadchecked
    Definition: struct_expr.h:147
    SCIP_Longint evaltag
    Definition: struct_expr.h:128
    SCIP_Longint activitytag
    Definition: struct_expr.h:135
    SCIP_IMPLINTTYPE integrality
    Definition: struct_expr.h:141
    int childrensize
    Definition: struct_expr.h:111
    SCIP_Real derivative
    Definition: struct_expr.h:125
    SCIP_EXPR ** children
    Definition: struct_expr.h:112
    SCIP_Real bardot
    Definition: struct_expr.h:127
    SCIP_QUADEXPR * quaddata
    Definition: struct_expr.h:146
    int nchildren
    Definition: struct_expr.h:110
    SCIP_Longint nsimplifycalls
    Definition: struct_expr.h:80
    SCIP_CLOCK * intevaltime
    Definition: struct_expr.h:85
    SCIP_Longint npropcalls
    Definition: struct_expr.h:77
    SCIP_Longint nestimatecalls
    Definition: struct_expr.h:75
    SCIP_CLOCK * simplifytime
    Definition: struct_expr.h:87
    unsigned int precedence
    Definition: struct_expr.h:48
    SCIP_Longint ncutoffs
    Definition: struct_expr.h:78
    unsigned int ncreated
    Definition: struct_expr.h:74
    SCIP_Longint nsimplified
    Definition: struct_expr.h:81
    SCIP_CLOCK * proptime
    Definition: struct_expr.h:86
    SCIP_Longint ndomreds
    Definition: struct_expr.h:79
    SCIP_CLOCK * estimatetime
    Definition: struct_expr.h:84
    SCIP_Longint nintevalcalls
    Definition: struct_expr.h:76
    SCIP_Longint nbranchscores
    Definition: struct_expr.h:82
    SCIP_EXPRHDLRDATA * data
    Definition: struct_expr.h:47
    SCIP_Bool curvaturechecked
    Definition: struct_expr.h:168
    SCIP_QUADEXPR_QUADTERM * quadexprterms
    Definition: struct_expr.h:160
    SCIP_Bool eigeninfostored
    Definition: struct_expr.h:171
    SCIP_Real * lincoefs
    Definition: struct_expr.h:157
    SCIP_EXPR ** linexprs
    Definition: struct_expr.h:156
    SCIP_Bool allexprsarevars
    Definition: struct_expr.h:165
    SCIP_Real constant
    Definition: struct_expr.h:153
    SCIP_EXPRCURV curvature
    Definition: struct_expr.h:167
    SCIP_QUADEXPR_BILINTERM * bilinexprterms
    Definition: struct_expr.h:163
    SCIP_Real * eigenvalues
    Definition: struct_expr.h:172
    SCIP_Real * eigenvectors
    Definition: struct_expr.h:173
    SCIP * scip
    Definition: struct_set.h:77
    SCIP_Longint domchgcount
    Definition: struct_stat.h:116
    SCIP_Longint exprlastdifftag
    Definition: struct_stat.h:130
    structure definitions related to algebraic expressions
    datastructures for global SCIP settings
    datastructures for problem statistics
    Definition: heur_padm.c:135
    internal methods for branch and bound tree
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    #define SCIP_DECL_EXPR_OWNERCREATE(x)
    Definition: type_expr.h:143
    #define SCIP_DECL_EXPRREVERSEPROP(x)
    Definition: type_expr.h:659
    #define SCIP_DECL_EXPRINITESTIMATES(x)
    Definition: type_expr.h:610
    #define SCIP_DECL_EXPRBWFWDIFF(x)
    Definition: type_expr.h:522
    #define SCIP_DECL_EXPRCURVATURE(x)
    Definition: type_expr.h:340
    struct SCIP_ExprhdlrData SCIP_EXPRHDLRDATA
    Definition: type_expr.h:195
    struct SCIP_ExprData SCIP_EXPRDATA
    Definition: type_expr.h:54
    #define SCIP_EXPRPRINT_EXPRSTRING
    Definition: type_expr.h:730
    #define SCIP_DECL_EXPRFREEDATA(x)
    Definition: type_expr.h:268
    SCIP_EXPRCURV
    Definition: type_expr.h:61
    @ SCIP_EXPRCURV_CONVEX
    Definition: type_expr.h:63
    @ SCIP_EXPRCURV_UNKNOWN
    Definition: type_expr.h:62
    @ SCIP_EXPRCURV_CONCAVE
    Definition: type_expr.h:64
    #define SCIP_EXPR_MAXINITESTIMATES
    Definition: type_expr.h:198
    #define SCIP_DECL_EXPRPARSE(x)
    Definition: type_expr.h:312
    #define SCIP_DECL_EXPRBWDIFF(x)
    Definition: type_expr.h:451
    #define SCIP_DECL_EXPRINTEVAL(x)
    Definition: type_expr.h:541
    #define SCIP_EXPRPRINT_OWNER
    Definition: type_expr.h:737
    #define SCIP_EXPRPRINT_ACTIVITYTAG
    Definition: type_expr.h:736
    #define SCIP_DECL_EXPRMONOTONICITY(x)
    Definition: type_expr.h:358
    #define SCIP_EXPRITER_VISITINGCHILD
    Definition: type_expr.h:695
    struct SCIP_Expr_OwnerData SCIP_EXPR_OWNERDATA
    Definition: type_expr.h:80
    SCIP_MONOTONE
    Definition: type_expr.h:70
    @ SCIP_MONOTONE_UNKNOWN
    Definition: type_expr.h:71
    unsigned int SCIP_EXPRPRINT_WHAT
    Definition: type_expr.h:742
    #define SCIP_DECL_EXPR_INTEVALVAR(x)
    Definition: type_expr.h:163
    #define SCIP_DECL_EXPRCOMPARE(x)
    Definition: type_expr.h:412
    #define SCIP_DECL_EXPRSIMPLIFY(x)
    Definition: type_expr.h:634
    #define SCIP_DECL_EXPREVAL(x)
    Definition: type_expr.h:428
    #define SCIP_DECL_EXPRFWDIFF(x)
    Definition: type_expr.h:482
    @ SCIP_EXPRITER_DFS
    Definition: type_expr.h:718
    #define SCIP_EXPRPRINT_ACTIVITY
    Definition: type_expr.h:735
    #define SCIP_DECL_EXPRHASH(x)
    Definition: type_expr.h:393
    #define SCIP_DECL_EXPRCOPYHDLR(x)
    Definition: type_expr.h:210
    #define SCIP_DECL_EXPRPRINT(x)
    Definition: type_expr.h:289
    #define SCIP_EXPRPRINT_EVALVALUE
    Definition: type_expr.h:733
    #define SCIP_DECL_EXPRFREEHDLR(x)
    Definition: type_expr.h:224
    #define SCIP_DECL_EXPR_MAPEXPR(x)
    Definition: type_expr.h:182
    #define SCIP_EXPRPRINT_EXPRHDLR
    Definition: type_expr.h:731
    #define SCIP_EXPRPRINT_EVALTAG
    Definition: type_expr.h:734
    #define SCIP_DECL_EXPRINTEGRALITY(x)
    Definition: type_expr.h:377
    #define SCIP_EXPRPRINT_NUSES
    Definition: type_expr.h:732
    #define SCIP_EXPRITER_VISITEDCHILD
    Definition: type_expr.h:696
    #define SCIP_DECL_EXPRGETSYMDATA(x)
    Definition: type_expr.h:674
    struct SCIP_ExprPrintData SCIP_EXPRPRINTDATA
    Definition: type_expr.h:743
    #define SCIP_DECL_EXPRCOPYDATA(x)
    Definition: type_expr.h:249
    #define SCIP_EXPRITER_LEAVEEXPR
    Definition: type_expr.h:697
    #define SCIP_EXPRITER_ALLSTAGES
    Definition: type_expr.h:698
    #define SCIP_DECL_EXPRESTIMATE(x)
    Definition: type_expr.h:577
    #define SCIP_EXPRITER_ENTEREXPR
    Definition: type_expr.h:694
    unsigned int SCIP_EXPRITER_STAGE
    Definition: type_expr.h:701
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    @ SCIP_FILECREATEERROR
    Definition: type_retcode.h:48
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    enum SCIP_ImplintType SCIP_IMPLINTTYPE
    Definition: type_var.h:117
    @ SCIP_IMPLINTTYPE_NONE
    Definition: type_var.h:90