Scippy

    SCIP

    Solving Constraint Integer Programs

    event.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 event.c
    26 * @ingroup OTHER_CFILES
    27 * @brief methods and datastructures for managing events
    28 * @author Tobias Achterberg
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    33#include <assert.h>
    34#include <string.h>
    35
    36#include "scip/branch.h"
    37#include "scip/clock.h"
    38#include "scip/event.h"
    39#include "scip/lp.h"
    40#include "scip/lpexact.h"
    41#include "scip/primal.h"
    42#include "scip/pub_event.h"
    43#include "scip/pub_message.h"
    44#include "scip/pub_var.h"
    45#include "scip/rational.h"
    46#include "scip/set.h"
    47#include "scip/struct_event.h"
    48#include "scip/struct_lp.h"
    49#include "scip/struct_set.h"
    50#include "scip/struct_var.h"
    51#include "scip/var.h"
    52
    53/* timing the execution methods for event handling takes a lot of time, so it is disabled */
    54/* #define TIMEEVENTEXEC */
    55
    56
    57/*
    58 * Event handler methods
    59 */
    60
    61/** copies the given event handler to a new scip */
    63 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    64 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
    65 )
    66{
    67 assert(eventhdlr != NULL);
    68 assert(set != NULL);
    69 assert(set->scip != NULL);
    70
    71 if( eventhdlr->eventcopy != NULL )
    72 {
    73 SCIPsetDebugMsg(set, "including event handler %s in subscip %p\n", SCIPeventhdlrGetName(eventhdlr), (void*)set->scip);
    74 SCIP_CALL( eventhdlr->eventcopy(set->scip, eventhdlr) );
    75 }
    76
    77 return SCIP_OKAY;
    78}
    79
    80/** wrapper method to update the exact data of a variable if a bound gets changed */
    81static
    83 SCIP_VAR* var, /**< variable that gets changed */
    84 SCIP_LPEXACT* lp, /**< current LP data */
    85 SCIP_SET* set, /**< global SCIP settings */
    86 SCIP_EVENT* event, /**< event */
    87 SCIP_Bool isUb, /**< is it an upper bound */
    88 SCIP_Bool isGlb /**< is it a global or local bound */
    89 )
    90{
    91 /* do nothing if not in exact solving mode */
    92 if( !set->exact_enable )
    93 return SCIP_OKAY;
    94
    95 assert(var != NULL);
    96 assert(lp != NULL);
    97
    100 {
    101 SCIP_RATIONAL* newbound;
    102 SCIP_RATIONAL* oldbound;
    103
    104 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newbound) );
    105 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oldbound) );
    108
    110 {
    111 if( isUb )
    112 {
    113 SCIP_CALL( SCIPcolExactChgUb(SCIPvarGetColExact(var), set, lp, newbound) );
    114 }
    115 else
    116 {
    117 SCIP_CALL( SCIPcolExactChgLb(SCIPvarGetColExact(var), set, lp, newbound) );
    118 }
    119 }
    120 if( isUb )
    121 {
    122 if( isGlb )
    123 {
    124 SCIP_CALL( SCIPlpExactUpdateVarUbGlobal(lp, set, var, oldbound, newbound) );
    125 }
    126 else
    127 {
    128 SCIP_CALL( SCIPlpExactUpdateVarUb(lp, set, var, oldbound, newbound) );
    129 }
    130 }
    131 else
    132 {
    133 if( isGlb )
    134 {
    135 SCIP_CALL( SCIPlpExactUpdateVarLbGlobal(lp, set, var, oldbound, newbound) );
    136 }
    137 else
    138 {
    139 SCIP_CALL( SCIPlpExactUpdateVarLb(lp, set, var, oldbound, newbound) );
    140 }
    141 }
    142
    143 SCIPrationalFreeBuffer(set->buffer, &oldbound);
    144 SCIPrationalFreeBuffer(set->buffer, &newbound);
    145 }
    146
    147 return SCIP_OKAY;
    148}
    149
    150/** internal method for creating an event handler */
    151static
    153 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
    154 const char* name, /**< name of event handler */
    155 const char* desc, /**< description of event handler */
    156 SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */
    157 SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */
    158 SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */
    159 SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */
    160 SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */
    161 SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */
    162 SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */
    163 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */
    164 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
    165 )
    166{
    167 assert(eventhdlr != NULL);
    168 assert(name != NULL);
    169 assert(desc != NULL);
    170 assert(eventexec != NULL);
    171
    172 SCIP_ALLOC( BMSallocMemory(eventhdlr) );
    173 BMSclearMemory(*eventhdlr);
    174 SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->name, name, strlen(name)+1) );
    175 SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->desc, desc, strlen(desc)+1) );
    176 (*eventhdlr)->eventcopy = eventcopy;
    177 (*eventhdlr)->eventfree = eventfree;
    178 (*eventhdlr)->eventinit = eventinit;
    179 (*eventhdlr)->eventexit = eventexit;
    180 (*eventhdlr)->eventinitsol = eventinitsol;
    181 (*eventhdlr)->eventexitsol = eventexitsol;
    182 (*eventhdlr)->eventdelete = eventdelete;
    183 (*eventhdlr)->eventexec = eventexec;
    184 (*eventhdlr)->eventhdlrdata = eventhdlrdata;
    185 (*eventhdlr)->initialized = FALSE;
    186
    187 /* create clocks */
    188 SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
    189 SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->eventtime, SCIP_CLOCKTYPE_DEFAULT) );
    190
    191 return SCIP_OKAY;
    192}
    193
    194/** creates an event handler */
    196 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
    197 SCIP_SET* set, /**< global SCIP settings */
    198 const char* name, /**< name of event handler */
    199 const char* desc, /**< description of event handler */
    200 SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */
    201 SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */
    202 SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */
    203 SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */
    204 SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */
    205 SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */
    206 SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */
    207 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */
    208 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
    209 )
    210{
    211 assert(eventhdlr != NULL);
    212 assert(set != NULL);
    213
    214 SCIP_CALL_FINALLY( doEventhdlrCreate(eventhdlr, name, desc, eventcopy, eventfree, eventinit, eventexit,
    215 eventinitsol, eventexitsol, eventdelete, eventexec, eventhdlrdata), (void) SCIPeventhdlrFree(eventhdlr, set) );
    216
    217 return SCIP_OKAY;
    218}
    219
    220/** calls destructor and frees memory of event handler */
    222 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
    223 SCIP_SET* set /**< global SCIP settings */
    224 )
    225{
    226 assert(eventhdlr != NULL);
    227 assert(set != NULL);
    228
    229 if( *eventhdlr == NULL )
    230 return SCIP_OKAY;
    231
    232 assert(!(*eventhdlr)->initialized);
    233
    234 /* call destructor of event handler */
    235 if( (*eventhdlr)->eventfree != NULL )
    236 {
    237 SCIP_CALL( (*eventhdlr)->eventfree(set->scip, *eventhdlr) );
    238 }
    239
    240 /* free clocks */
    241 SCIPclockFree(&(*eventhdlr)->eventtime);
    242 SCIPclockFree(&(*eventhdlr)->setuptime);
    243
    244 BMSfreeMemoryArrayNull(&(*eventhdlr)->name);
    245 BMSfreeMemoryArrayNull(&(*eventhdlr)->desc);
    246 BMSfreeMemory(eventhdlr);
    247
    248 return SCIP_OKAY;
    249}
    250
    251/** initializes event handler */
    253 SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
    254 SCIP_SET* set /**< global SCIP settings */
    255 )
    256{
    257 assert(eventhdlr != NULL);
    258 assert(set != NULL);
    259
    260 if( eventhdlr->initialized )
    261 {
    262 SCIPerrorMessage("event handler <%s> already initialized\n", eventhdlr->name);
    263 return SCIP_INVALIDCALL;
    264 }
    265
    266 if( set->misc_resetstat )
    267 {
    268 SCIPclockReset(eventhdlr->setuptime);
    269 SCIPclockReset(eventhdlr->eventtime);
    270 }
    271
    272 if( eventhdlr->eventinit != NULL )
    273 {
    274 /* start timing */
    275 SCIPclockStart(eventhdlr->setuptime, set);
    276
    277 SCIP_CALL( eventhdlr->eventinit(set->scip, eventhdlr) );
    278
    279 /* stop timing */
    280 SCIPclockStop(eventhdlr->setuptime, set);
    281 }
    282 eventhdlr->initialized = TRUE;
    283
    284 return SCIP_OKAY;
    285}
    286
    287/** calls exit method of event handler */
    289 SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
    290 SCIP_SET* set /**< global SCIP settings */
    291 )
    292{
    293 assert(eventhdlr != NULL);
    294 assert(set != NULL);
    295
    296 if( !eventhdlr->initialized )
    297 {
    298 SCIPerrorMessage("event handler <%s> not initialized\n", eventhdlr->name);
    299 return SCIP_INVALIDCALL;
    300 }
    301
    302 if( eventhdlr->eventexit != NULL )
    303 {
    304 /* start timing */
    305 SCIPclockStart(eventhdlr->setuptime, set);
    306
    307 SCIP_CALL( eventhdlr->eventexit(set->scip, eventhdlr) );
    308
    309 /* stop timing */
    310 SCIPclockStop(eventhdlr->setuptime, set);
    311 }
    312 eventhdlr->initialized = FALSE;
    313
    314 return SCIP_OKAY;
    315}
    316
    317/** informs event handler that the branch and bound process is being started */
    319 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    320 SCIP_SET* set /**< global SCIP settings */
    321 )
    322{
    323 assert(eventhdlr != NULL);
    324 assert(set != NULL);
    325
    326 /* call solving process initialization method of event handler */
    327 if( eventhdlr->eventinitsol != NULL )
    328 {
    329 /* start timing */
    330 SCIPclockStart(eventhdlr->setuptime, set);
    331
    332 SCIP_CALL( eventhdlr->eventinitsol(set->scip, eventhdlr) );
    333
    334 /* stop timing */
    335 SCIPclockStop(eventhdlr->setuptime, set);
    336 }
    337
    338 return SCIP_OKAY;
    339}
    340
    341/** informs event handler that the branch and bound process data is being freed */
    343 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    344 SCIP_SET* set /**< global SCIP settings */
    345 )
    346{
    347 assert(eventhdlr != NULL);
    348 assert(set != NULL);
    349
    350 /* call solving process deinitialization method of event handler */
    351 if( eventhdlr->eventexitsol != NULL )
    352 {
    353 /* start timing */
    354 SCIPclockStart(eventhdlr->setuptime, set);
    355
    356 SCIP_CALL( eventhdlr->eventexitsol(set->scip, eventhdlr) );
    357
    358 /* stop timing */
    359 SCIPclockStop(eventhdlr->setuptime, set);
    360 }
    361
    362 return SCIP_OKAY;
    363}
    364
    365/** calls execution method of event handler */
    367 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    368 SCIP_SET* set, /**< global SCIP settings */
    369 SCIP_EVENT* event, /**< event to call event handler with */
    370 SCIP_EVENTDATA* eventdata /**< user data for the issued event */
    371 )
    372{
    373 assert(eventhdlr != NULL);
    374 assert(eventhdlr->eventexec != NULL);
    375 assert(set != NULL);
    376 assert(event != NULL);
    377
    378 SCIPsetDebugMsg(set, "execute event of handler <%s> with event %p of type 0x%" SCIP_EVENTTYPE_FORMAT "\n", eventhdlr->name, (void*)event, event->eventtype);
    379
    380#ifdef TIMEEVENTEXEC
    381 /* start timing */
    382 SCIPclockStart(eventhdlr->eventtime, set);
    383#endif
    384
    385 SCIP_CALL( eventhdlr->eventexec(set->scip, eventhdlr, event, eventdata) );
    386
    387#ifdef TIMEEVENTEXEC
    388 /* stop timing */
    389 SCIPclockStop(eventhdlr->eventtime, set);
    390#endif
    391
    392 return SCIP_OKAY;
    393}
    394
    395/** gets name of event handler */
    397 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    398 )
    399{
    400 assert(eventhdlr != NULL);
    401
    402 return eventhdlr->name;
    403}
    404
    405/** gets user data of event handler */
    407 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    408 )
    409{
    410 assert(eventhdlr != NULL);
    411
    412 return eventhdlr->eventhdlrdata;
    413}
    414
    415/** sets user data of event handler; user has to free old data in advance! */
    417 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    418 SCIP_EVENTHDLRDATA* eventhdlrdata /**< new event handler user data */
    419 )
    420{
    421 assert(eventhdlr != NULL);
    422
    423 eventhdlr->eventhdlrdata = eventhdlrdata;
    424}
    425
    426/** sets copy callback for all events of this event handler */
    428 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    429 SCIP_DECL_EVENTCOPY ((*eventcopy)) /**< copy callback for events */
    430 )
    431{
    432 assert(eventhdlr != NULL);
    433
    434 eventhdlr->eventcopy = eventcopy;
    435}
    436
    437/** sets destructor callback of this event handler */
    439 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    440 SCIP_DECL_EVENTFREE ((*eventfree)) /**< destructor callback of event handler */
    441 )
    442{
    443 assert(eventhdlr != NULL);
    444
    445 eventhdlr->eventfree = eventfree;
    446}
    447
    448/** sets initialization callback of this event handler */
    450 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    451 SCIP_DECL_EVENTINIT ((*eventinit)) /**< initialization callback of event handler */
    452 )
    453{
    454 assert(eventhdlr != NULL);
    455
    456 eventhdlr->eventinit = eventinit;
    457}
    458
    459/** sets deinitialization callback of this event handler */
    461 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    462 SCIP_DECL_EVENTEXIT ((*eventexit)) /**< deinitialization callback of event handler */
    463 )
    464{
    465 assert(eventhdlr != NULL);
    466
    467 eventhdlr->eventexit = eventexit;
    468}
    469
    470/** sets solving process initialization callback of this event handler */
    472 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    473 SCIP_DECL_EVENTINITSOL((*eventinitsol)) /**< solving process initialization callback of event handler */
    474 )
    475{
    476 assert(eventhdlr != NULL);
    477
    478 eventhdlr->eventinitsol = eventinitsol;
    479}
    480
    481/** sets solving process deinitialization callback of this event handler */
    483 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    484 SCIP_DECL_EVENTEXITSOL((*eventexitsol)) /**< solving process deinitialization callback of event handler */
    485 )
    486{
    487 assert(eventhdlr != NULL);
    488
    489 eventhdlr->eventexitsol = eventexitsol;
    490}
    491
    492/** sets callback to free specific event data */
    494 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
    495 SCIP_DECL_EVENTDELETE ((*eventdelete)) /**< callback to free specific event data */
    496 )
    497{
    498 assert(eventhdlr != NULL);
    499
    500 eventhdlr->eventdelete = eventdelete;
    501}
    502
    503/** is event handler initialized? */
    505 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    506 )
    507{
    508 assert(eventhdlr != NULL);
    509
    510 return eventhdlr->initialized;
    511}
    512
    513/** enables or disables all clocks of \p eventhdlr, depending on the value of the flag */
    515 SCIP_EVENTHDLR* eventhdlr, /**< the event handler for which all clocks should be enabled or disabled */
    516 SCIP_Bool enable /**< should the clocks of the event handler be enabled? */
    517 )
    518{
    519 assert(eventhdlr != NULL);
    520
    521 SCIPclockEnableOrDisable(eventhdlr->setuptime, enable);
    522 SCIPclockEnableOrDisable(eventhdlr->eventtime, enable);
    523}
    524
    525/** gets time in seconds used in this event handler for setting up for next stages */
    527 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    528 )
    529{
    530 assert(eventhdlr != NULL);
    531
    532 return SCIPclockGetTime(eventhdlr->setuptime);
    533}
    534
    535/** gets time in seconds used in this event handler, this measurement is currently disabled so this method will return
    536 * 0, define TIMEEVENTEXEC in the beginning of this file to enable
    537 */
    539 SCIP_EVENTHDLR* eventhdlr /**< event handler */
    540 )
    541{
    542 assert(eventhdlr != NULL);
    543
    544 return SCIPclockGetTime(eventhdlr->eventtime);
    545}
    546
    547
    548
    549/*
    550 * Event methods
    551 */
    552
    553
    554/** creates a synchronization event */
    556 SCIP_EVENT** event, /**< pointer to store the event */
    557 BMS_BLKMEM* blkmem /**< block memory */
    558 )
    559{
    560 assert(event != NULL);
    561
    562 /* create event data */
    563 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    564 (*event)->eventtype = SCIP_EVENTTYPE_SYNC;
    565
    566 return SCIP_OKAY;
    567}
    568
    569/*
    570 * simple functions implemented as defines
    571 */
    572
    573/* In debug mode, the following methods are implemented as function calls to ensure
    574 * type validity.
    575 * In optimized mode, the methods are implemented as defines to improve performance.
    576 * However, we want to have them in the library anyways, so we have to undef the defines.
    577 */
    578
    579#undef SCIPeventGetType
    580#undef SCIPeventGetOldobj
    581#undef SCIPeventGetNewobj
    582#undef SCIPeventGetOldtype
    583#undef SCIPeventGetNewtype
    584#undef SCIPeventGetOldbound
    585#undef SCIPeventGetNewbound
    586#undef SCIPeventGetNode
    587#undef SCIPeventGetSol
    588#undef SCIPeventGetRowCol
    589#undef SCIPeventGetRowOldCoefVal
    590#undef SCIPeventGetRowNewCoefVal
    591#undef SCIPeventGetRowOldConstVal
    592#undef SCIPeventGetRowNewConstVal
    593#undef SCIPeventGetRowSide
    594#undef SCIPeventGetRowOldSideVal
    595#undef SCIPeventGetRowNewSideVal
    596
    597/** creates an event for an addition of a variable to the problem */
    599 SCIP_EVENT** event, /**< pointer to store the event */
    600 BMS_BLKMEM* blkmem, /**< block memory */
    601 SCIP_VAR* var /**< variable that was added to the problem */
    602 )
    603{
    604 assert(event != NULL);
    605 assert(blkmem != NULL);
    606
    607 /* create event data */
    608 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    609 (*event)->eventtype = SCIP_EVENTTYPE_VARADDED;
    610 (*event)->data.eventvaradded.var = var;
    611
    612 return SCIP_OKAY;
    613}
    614
    615/** creates an event for a deletion of a variable from the problem */
    617 SCIP_EVENT** event, /**< pointer to store the event */
    618 BMS_BLKMEM* blkmem, /**< block memory */
    619 SCIP_VAR* var /**< variable that is to be deleted from the problem */
    620 )
    621{
    622 assert(event != NULL);
    623 assert(blkmem != NULL);
    624
    625 /* create event data */
    626 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    627 (*event)->eventtype = SCIP_EVENTTYPE_VARDELETED;
    628 (*event)->data.eventvardeleted.var = var;
    629
    630 return SCIP_OKAY;
    631}
    632
    633/** creates an event for a fixing of a variable */
    635 SCIP_EVENT** event, /**< pointer to store the event */
    636 BMS_BLKMEM* blkmem, /**< block memory */
    637 SCIP_VAR* var /**< variable that was fixed */
    638 )
    639{
    640 assert(event != NULL);
    641 assert(blkmem != NULL);
    646
    647 /* create event data */
    648 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    649 (*event)->eventtype = SCIP_EVENTTYPE_VARFIXED;
    650 (*event)->data.eventvarfixed.var = var;
    651
    652 return SCIP_OKAY;
    653}
    654
    655/** creates an event for a change in the number of locks of a variable down to zero or one */
    657 SCIP_EVENT** event, /**< pointer to store the event */
    658 BMS_BLKMEM* blkmem, /**< block memory */
    659 SCIP_VAR* var /**< variable that changed the number of locks */
    660 )
    661{
    662 assert(event != NULL);
    663 assert(blkmem != NULL);
    667
    668 /* create event data */
    669 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    670 (*event)->eventtype = SCIP_EVENTTYPE_VARUNLOCKED;
    671 (*event)->data.eventvarunlocked.var = var;
    672
    673 return SCIP_OKAY;
    674}
    675
    676/** creates an event for a change in the objective value of a variable */
    678 SCIP_EVENT** event, /**< pointer to store the event */
    679 BMS_BLKMEM* blkmem, /**< block memory */
    680 SCIP_VAR* var, /**< variable whose objective value changed */
    681 SCIP_Real oldobj, /**< old objective value before value changed */
    682 SCIP_Real newobj /**< new objective value after value changed */
    683 )
    684{
    685 assert(event != NULL);
    686 assert(blkmem != NULL);
    687 assert(oldobj != newobj || (var->exactdata != NULL)); /*lint !e777*/
    688
    689 /* create event data */
    690 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    691 (*event)->eventtype = SCIP_EVENTTYPE_OBJCHANGED;
    692 (*event)->data.eventobjchg.var = var;
    693 (*event)->data.eventobjchg.oldobj = oldobj;
    694 (*event)->data.eventobjchg.newobj = newobj;
    695 (*event)->data.eventobjchg.oldobjexact = NULL;
    696 (*event)->data.eventobjchg.newobjexact = NULL;
    697
    698 return SCIP_OKAY;
    699}
    700
    701/** creates an event for a change in the global lower bound of a variable */
    703 SCIP_EVENT** event, /**< pointer to store the event */
    704 BMS_BLKMEM* blkmem, /**< block memory */
    705 SCIP_VAR* var, /**< variable whose bound changed */
    706 SCIP_Real oldbound, /**< old bound before bound changed */
    707 SCIP_Real newbound /**< new bound after bound changed */
    708 )
    709{
    710 assert(event != NULL);
    711 assert(blkmem != NULL);
    712 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
    713
    714 /* create event data */
    715 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    716 (*event)->eventtype = SCIP_EVENTTYPE_GLBCHANGED;
    717 (*event)->data.eventbdchg.var = var;
    718 (*event)->data.eventbdchg.oldbound = oldbound;
    719 (*event)->data.eventbdchg.newbound = newbound;
    720 (*event)->data.eventbdchg.oldboundexact = NULL;
    721 (*event)->data.eventbdchg.newboundexact = NULL;
    722
    723 return SCIP_OKAY;
    724}
    725
    726/** creates an event for a change in the global upper bound of a variable */
    728 SCIP_EVENT** event, /**< pointer to store the event */
    729 BMS_BLKMEM* blkmem, /**< block memory */
    730 SCIP_VAR* var, /**< variable whose bound changed */
    731 SCIP_Real oldbound, /**< old bound before bound changed */
    732 SCIP_Real newbound /**< new bound after bound changed */
    733 )
    734{
    735 assert(event != NULL);
    736 assert(blkmem != NULL);
    737 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
    738
    739 /* create event data */
    740 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    741 (*event)->eventtype = SCIP_EVENTTYPE_GUBCHANGED;
    742 (*event)->data.eventbdchg.var = var;
    743 (*event)->data.eventbdchg.oldbound = oldbound;
    744 (*event)->data.eventbdchg.newbound = newbound;
    745 (*event)->data.eventbdchg.oldboundexact = NULL;
    746 (*event)->data.eventbdchg.newboundexact = NULL;
    747
    748 return SCIP_OKAY;
    749}
    750
    751/** creates an event for a change in the lower bound of a variable */
    753 SCIP_EVENT** event, /**< pointer to store the event */
    754 BMS_BLKMEM* blkmem, /**< block memory */
    755 SCIP_VAR* var, /**< variable whose bound changed */
    756 SCIP_Real oldbound, /**< old bound before bound changed */
    757 SCIP_Real newbound /**< new bound after bound changed */
    758 )
    759{
    760 assert(event != NULL);
    761 assert(blkmem != NULL);
    762 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
    763
    764 /* create event data */
    765 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    766 if( newbound > oldbound )
    767 (*event)->eventtype = SCIP_EVENTTYPE_LBTIGHTENED;
    768 else
    769 (*event)->eventtype = SCIP_EVENTTYPE_LBRELAXED;
    770 (*event)->data.eventbdchg.var = var;
    771 (*event)->data.eventbdchg.oldbound = oldbound;
    772 (*event)->data.eventbdchg.newbound = newbound;
    773 (*event)->data.eventbdchg.oldboundexact = NULL;
    774 (*event)->data.eventbdchg.newboundexact = NULL;
    775
    776 return SCIP_OKAY;
    777}
    778
    779/** creates an event for a change in the upper bound of a variable */
    781 SCIP_EVENT** event, /**< pointer to store the event */
    782 BMS_BLKMEM* blkmem, /**< block memory */
    783 SCIP_VAR* var, /**< variable whose bound changed */
    784 SCIP_Real oldbound, /**< old bound before bound changed */
    785 SCIP_Real newbound /**< new bound after bound changed */
    786 )
    787{
    788 assert(event != NULL);
    789 assert(blkmem != NULL);
    790 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
    791
    792 /* create event data */
    793 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    794 if( newbound < oldbound )
    795 (*event)->eventtype = SCIP_EVENTTYPE_UBTIGHTENED;
    796 else
    797 (*event)->eventtype = SCIP_EVENTTYPE_UBRELAXED;
    798 (*event)->data.eventbdchg.var = var;
    799 (*event)->data.eventbdchg.oldbound = oldbound;
    800 (*event)->data.eventbdchg.newbound = newbound;
    801 (*event)->data.eventbdchg.oldboundexact = NULL;
    802 (*event)->data.eventbdchg.newboundexact = NULL;
    803
    804 return SCIP_OKAY;
    805}
    806
    807/** adds the data for the exact changes to existing bound event */
    809 SCIP_EVENT* event, /**< the event */
    810 BMS_BLKMEM* blkmem, /**< block memory */
    811 SCIP_RATIONAL* oldbound, /**< old bound before bound changed */
    812 SCIP_RATIONAL* newbound /**< new bound after bound changed */
    813 )
    814{
    815 assert(event != NULL);
    816 assert(blkmem != NULL);
    817 assert(!SCIPrationalIsEQ(oldbound, newbound));
    818 assert((event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_GBDCHANGED));
    819
    820 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventbdchg.oldboundexact), oldbound) );
    821 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventbdchg.newboundexact), newbound) );
    822
    823 return SCIP_OKAY;
    824}
    825
    826/** adds the data for the exact changes to existing obj event */
    828 SCIP_EVENT* event, /**< the event */
    829 BMS_BLKMEM* blkmem, /**< block memory */
    830 SCIP_RATIONAL* oldobj, /**< old obj before change */
    831 SCIP_RATIONAL* newobj /**< new obj after change */
    832 )
    833{
    834 assert(event != NULL);
    835 assert(blkmem != NULL);
    836 assert(!SCIPrationalIsEQ(oldobj, newobj));
    837
    838 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventobjchg.oldobjexact), oldobj) );
    839 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventobjchg.newobjexact), newobj) );
    840
    841 return SCIP_OKAY;
    842}
    843
    844/** creates an event for an addition of a domain hole to a variable */
    846 SCIP_EVENT** event, /**< pointer to store the event */
    847 BMS_BLKMEM* blkmem, /**< block memory */
    848 SCIP_VAR* var, /**< variable whose bound changed */
    849 SCIP_Real left, /**< left bound of open interval in new hole */
    850 SCIP_Real right /**< right bound of open interval in new hole */
    851 )
    852{
    853 assert(event != NULL);
    854 assert(blkmem != NULL);
    855
    856 /* create event data */
    857 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    858 (*event)->eventtype = SCIP_EVENTTYPE_GHOLEADDED;
    859 (*event)->data.eventhole.var = var;
    860 (*event)->data.eventhole.left = left;
    861 (*event)->data.eventhole.right = right;
    862
    863 return SCIP_OKAY;
    864}
    865
    866/** creates an event for removing a domain hole of a variable */
    868 SCIP_EVENT** event, /**< pointer to store the event */
    869 BMS_BLKMEM* blkmem, /**< block memory */
    870 SCIP_VAR* var, /**< variable whose bound changed */
    871 SCIP_Real left, /**< left bound of open interval in hole */
    872 SCIP_Real right /**< right bound of open interval in hole */
    873 )
    874{
    875 assert(event != NULL);
    876 assert(blkmem != NULL);
    877
    878 /* create event data */
    879 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    880 (*event)->eventtype = SCIP_EVENTTYPE_GHOLEREMOVED;
    881 (*event)->data.eventhole.var = var;
    882 (*event)->data.eventhole.left = left;
    883 (*event)->data.eventhole.right = right;
    884
    885 return SCIP_OKAY;
    886}
    887
    888/** creates an event for an addition of a domain hole to a variable */
    890 SCIP_EVENT** event, /**< pointer to store the event */
    891 BMS_BLKMEM* blkmem, /**< block memory */
    892 SCIP_VAR* var, /**< variable whose bound changed */
    893 SCIP_Real left, /**< left bound of open interval in new hole */
    894 SCIP_Real right /**< right bound of open interval in new hole */
    895 )
    896{
    897 assert(event != NULL);
    898 assert(blkmem != NULL);
    899
    900 /* create event data */
    901 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    902 (*event)->eventtype = SCIP_EVENTTYPE_LHOLEADDED;
    903 (*event)->data.eventhole.var = var;
    904 (*event)->data.eventhole.left = left;
    905 (*event)->data.eventhole.right = right;
    906
    907 return SCIP_OKAY;
    908}
    909
    910/** creates an event for removing a domain hole of a variable */
    912 SCIP_EVENT** event, /**< pointer to store the event */
    913 BMS_BLKMEM* blkmem, /**< block memory */
    914 SCIP_VAR* var, /**< variable whose bound changed */
    915 SCIP_Real left, /**< left bound of open interval in hole */
    916 SCIP_Real right /**< right bound of open interval in hole */
    917 )
    918{
    919 assert(event != NULL);
    920 assert(blkmem != NULL);
    921
    922 /* create event data */
    923 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    924 (*event)->eventtype = SCIP_EVENTTYPE_LHOLEREMOVED;
    925 (*event)->data.eventhole.var = var;
    926 (*event)->data.eventhole.left = left;
    927 (*event)->data.eventhole.right = right;
    928
    929 return SCIP_OKAY;
    930}
    931
    932/** creates an event for an addition to the variable's implications list, clique or variable bounds information */
    934 SCIP_EVENT** event, /**< pointer to store the event */
    935 BMS_BLKMEM* blkmem, /**< block memory */
    936 SCIP_VAR* var /**< variable that was fixed */
    937 )
    938{
    939 assert(event != NULL);
    940 assert(blkmem != NULL);
    942
    943 /* create event data */
    944 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    945 (*event)->eventtype = SCIP_EVENTTYPE_IMPLADDED;
    946 (*event)->data.eventimpladd.var = var;
    947
    948 return SCIP_OKAY;
    949}
    950
    951/** creates an event for changing the type of a variable */
    953 SCIP_EVENT** event, /**< pointer to store the event */
    954 BMS_BLKMEM* blkmem, /**< block memory */
    955 SCIP_VAR* var, /**< variable whose type changed */
    956 SCIP_VARTYPE oldtype, /**< old variable type */
    957 SCIP_VARTYPE newtype /**< new variable type */
    958 )
    959{
    960 assert(event != NULL);
    961 assert(blkmem != NULL);
    962 assert(oldtype != newtype);
    963
    964 /* create event data */
    965 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    966 (*event)->eventtype = SCIP_EVENTTYPE_TYPECHANGED;
    967 (*event)->data.eventtypechg.var = var;
    968 (*event)->data.eventtypechg.oldtype = oldtype;
    969 (*event)->data.eventtypechg.newtype = newtype;
    970
    971 return SCIP_OKAY;
    972}
    973
    974/** creates an event for changing the implied integral type of a variable */
    976 SCIP_EVENT** event, /**< pointer to store the event */
    977 BMS_BLKMEM* blkmem, /**< block memory */
    978 SCIP_VAR* var, /**< variable whose implied type changed */
    979 SCIP_IMPLINTTYPE oldtype, /**< old variable implied type */
    980 SCIP_IMPLINTTYPE newtype /**< new variable implied type */
    981 )
    982{
    983 assert(event != NULL);
    984 assert(blkmem != NULL);
    985 assert(oldtype != newtype);
    986
    987 /* create event data */
    988 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    989 (*event)->eventtype = SCIP_EVENTTYPE_IMPLTYPECHANGED;
    990 (*event)->data.eventimpltypechg.var = var;
    991 (*event)->data.eventimpltypechg.oldtype = oldtype;
    992 (*event)->data.eventimpltypechg.newtype = newtype;
    993
    994 return SCIP_OKAY;
    995}
    996
    997/** creates an event for the addition of a linear row to the separation storage */
    999 SCIP_EVENT** event, /**< pointer to store the event */
    1000 BMS_BLKMEM* blkmem, /**< block memory */
    1001 SCIP_ROW* row /**< row that was added to the separation storage*/
    1002 )
    1003{
    1004 assert(event != NULL);
    1005 assert(blkmem != NULL);
    1006 assert(row != NULL);
    1007
    1008 /* create event data */
    1009 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1010 (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDSEPA;
    1011 (*event)->data.eventrowaddedsepa.row = row;
    1012
    1013 return SCIP_OKAY;
    1014}
    1015
    1016/** creates an event for the deletion of a linear row from the separation storage */
    1018 SCIP_EVENT** event, /**< pointer to store the event */
    1019 BMS_BLKMEM* blkmem, /**< block memory */
    1020 SCIP_ROW* row /**< row that was deleted from the separation storage */
    1021 )
    1022{
    1023 assert(event != NULL);
    1024 assert(blkmem != NULL);
    1025 assert(row != NULL);
    1026
    1027 /* create event data */
    1028 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1029 (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDSEPA;
    1030 (*event)->data.eventrowdeletedsepa.row = row;
    1031
    1032 return SCIP_OKAY;
    1033}
    1034
    1035/** creates an event for the addition of a linear row to the LP */
    1037 SCIP_EVENT** event, /**< pointer to store the event */
    1038 BMS_BLKMEM* blkmem, /**< block memory */
    1039 SCIP_ROW* row /**< row that was added to the LP */
    1040 )
    1041{
    1042 assert(event != NULL);
    1043 assert(blkmem != NULL);
    1044 assert(row != NULL);
    1045
    1046 /* create event data */
    1047 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1048 (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDLP;
    1049 (*event)->data.eventrowaddedlp.row = row;
    1050
    1051 return SCIP_OKAY;
    1052}
    1053
    1054/** creates an event for the deletion of a linear row from the LP */
    1056 SCIP_EVENT** event, /**< pointer to store the event */
    1057 BMS_BLKMEM* blkmem, /**< block memory */
    1058 SCIP_ROW* row /**< row that was deleted from the LP */
    1059 )
    1060{
    1061 assert(event != NULL);
    1062 assert(blkmem != NULL);
    1063 assert(row != NULL);
    1064
    1065 /* create event data */
    1066 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1067 (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDLP;
    1068 (*event)->data.eventrowdeletedlp.row = row;
    1069
    1070 return SCIP_OKAY;
    1071}
    1072
    1073/** creates an event for the change of a coefficient in a linear row */
    1075 SCIP_EVENT** event, /**< pointer to store the event */
    1076 BMS_BLKMEM* blkmem, /**< block memory */
    1077 SCIP_ROW* row, /**< row in which a coefficient changed */
    1078 SCIP_COL* col, /**< column which coefficient changed */
    1079 SCIP_Real oldval, /**< old value of coefficient */
    1080 SCIP_Real newval /**< new value of coefficient */
    1081 )
    1082{
    1083 assert(event != NULL);
    1084 assert(blkmem != NULL);
    1085 assert(row != NULL);
    1086
    1087 /* create event data */
    1088 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1089 (*event)->eventtype = SCIP_EVENTTYPE_ROWCOEFCHANGED;
    1090 (*event)->data.eventrowcoefchanged.row = row;
    1091 (*event)->data.eventrowcoefchanged.col = col;
    1092 (*event)->data.eventrowcoefchanged.oldval = oldval;
    1093 (*event)->data.eventrowcoefchanged.newval = newval;
    1094
    1095 return SCIP_OKAY;
    1096}
    1097
    1098/** creates an event for the change of a constant in a linear row */
    1100 SCIP_EVENT** event, /**< pointer to store the event */
    1101 BMS_BLKMEM* blkmem, /**< block memory */
    1102 SCIP_ROW* row, /**< row in which the constant changed */
    1103 SCIP_Real oldval, /**< old value of constant */
    1104 SCIP_Real newval /**< new value of constant */
    1105 )
    1106{
    1107 assert(event != NULL);
    1108 assert(blkmem != NULL);
    1109 assert(row != NULL);
    1110
    1111 /* create event data */
    1112 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1113 (*event)->eventtype = SCIP_EVENTTYPE_ROWCONSTCHANGED;
    1114 (*event)->data.eventrowconstchanged.row = row;
    1115 (*event)->data.eventrowconstchanged.oldval = oldval;
    1116 (*event)->data.eventrowconstchanged.newval = newval;
    1117
    1118 return SCIP_OKAY;
    1119}
    1120
    1121/** creates an event for the change of a side of a linear row */
    1123 SCIP_EVENT** event, /**< pointer to store the event */
    1124 BMS_BLKMEM* blkmem, /**< block memory */
    1125 SCIP_ROW* row, /**< row which side has changed */
    1126 SCIP_SIDETYPE side, /**< which side has changed */
    1127 SCIP_Real oldval, /**< old value of side */
    1128 SCIP_Real newval /**< new value of side */
    1129 )
    1130{
    1131 assert(event != NULL);
    1132 assert(blkmem != NULL);
    1133 assert(row != NULL);
    1134
    1135 /* create event data */
    1136 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
    1137 (*event)->eventtype = SCIP_EVENTTYPE_ROWSIDECHANGED;
    1138 (*event)->data.eventrowsidechanged.row = row;
    1139 (*event)->data.eventrowsidechanged.side = side;
    1140 (*event)->data.eventrowsidechanged.oldval = oldval;
    1141 (*event)->data.eventrowsidechanged.newval = newval;
    1142
    1143 return SCIP_OKAY;
    1144}
    1145
    1147 SCIP_EVENT* event, /**< event to free */
    1148 BMS_BLKMEM* blkmem /**< block memory buffer */
    1149 )
    1150{
    1151 assert(event != NULL);
    1152 assert(blkmem != NULL);
    1153
    1154 if( ((event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_GBDCHANGED)) && (event)->data.eventbdchg.newboundexact != NULL )
    1155 {
    1156 SCIPrationalFreeBlock(blkmem, &(event)->data.eventbdchg.newboundexact);
    1157 SCIPrationalFreeBlock(blkmem, &(event)->data.eventbdchg.oldboundexact);
    1158 }
    1159
    1160 if( ((event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) && (event)->data.eventobjchg.newobjexact != NULL )
    1161 {
    1162 SCIPrationalFreeBlock(blkmem, &(event)->data.eventobjchg.newobjexact);
    1163 SCIPrationalFreeBlock(blkmem, &(event)->data.eventobjchg.oldobjexact);
    1164 }
    1165}
    1166
    1167/** frees an event */
    1169 SCIP_EVENT** event, /**< event to free */
    1170 BMS_BLKMEM* blkmem /**< block memory buffer */
    1171 )
    1172{
    1173 assert(event != NULL);
    1174 assert(blkmem != NULL);
    1175
    1176 eventFreeExactData(*event, blkmem);
    1177 BMSfreeBlockMemory(blkmem, event);
    1178
    1179 return SCIP_OKAY;
    1180}
    1181
    1182/** disables an event */
    1183static
    1185 SCIP_EVENT* event /**< event to disable */
    1186 )
    1187{
    1188 assert(event != NULL);
    1189
    1190 event->eventtype = SCIP_EVENTTYPE_DISABLED;
    1191}
    1192
    1193/** gets type of event */
    1195 SCIP_EVENT* event /**< event */
    1196 )
    1197{
    1198 assert(event != NULL);
    1199
    1200 return event->eventtype;
    1201}
    1202
    1203/** sets type of event */
    1205 SCIP_EVENT* event, /**< event */
    1206 SCIP_EVENTTYPE eventtype /**< new event type */
    1207 )
    1208{
    1209 assert(event != NULL);
    1210
    1211 event->eventtype = eventtype;
    1212
    1213 return SCIP_OKAY;
    1214}
    1215
    1216/** gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change) */
    1218 SCIP_EVENT* event /**< event */
    1219 )
    1220{
    1221 assert(event != NULL);
    1222
    1223 switch( event->eventtype )
    1224 {
    1226 assert(event->data.eventvaradded.var != NULL);
    1227 return event->data.eventvaradded.var;
    1228
    1230 assert(event->data.eventvardeleted.var != NULL);
    1231 return event->data.eventvardeleted.var;
    1232
    1234 assert(event->data.eventvarfixed.var != NULL);
    1235 return event->data.eventvarfixed.var;
    1236
    1238 assert(event->data.eventvarunlocked.var != NULL);
    1239 return event->data.eventvarunlocked.var;
    1240
    1242 assert(event->data.eventobjchg.var != NULL);
    1243 return event->data.eventobjchg.var;
    1244
    1251 assert(event->data.eventbdchg.var != NULL);
    1252 return event->data.eventbdchg.var;
    1253
    1258 assert(event->data.eventhole.var != NULL);
    1259 return event->data.eventhole.var;
    1260
    1262 assert(event->data.eventimpladd.var != NULL);
    1263 return event->data.eventimpladd.var;
    1264
    1266 assert(event->data.eventtypechg.var != NULL);
    1267 return event->data.eventtypechg.var;
    1268
    1270 assert(event->data.eventimpltypechg.var != NULL);
    1271 return event->data.eventimpltypechg.var;
    1272
    1273 default:
    1274 SCIPerrorMessage("event does not belong to a variable\n");
    1275 SCIPABORT();
    1276 return NULL; /*lint !e527*/
    1277 } /*lint !e788*/
    1278}
    1279
    1280/** sets variable for a variable event */
    1282 SCIP_EVENT* event, /**< event */
    1283 SCIP_VAR* var /**< new variable */
    1284 )
    1285{
    1286 assert(event != NULL);
    1287
    1288 switch( event->eventtype )
    1289 {
    1291 assert(event->data.eventvaradded.var != NULL);
    1292 event->data.eventvaradded.var = var;
    1293 break;
    1294
    1296 assert(event->data.eventvardeleted.var != NULL);
    1297 event->data.eventvardeleted.var = var;
    1298 break;
    1299
    1301 assert(event->data.eventvarfixed.var != NULL);
    1302 event->data.eventvarfixed.var = var;
    1303 break;
    1304
    1306 assert(event->data.eventvarunlocked.var != NULL);
    1307 event->data.eventvarunlocked.var = var;
    1308 break;
    1309
    1311 assert(event->data.eventobjchg.var != NULL);
    1312 event->data.eventobjchg.var = var;
    1313 break;
    1314
    1321 assert(event->data.eventbdchg.var != NULL);
    1322 event->data.eventbdchg.var = var;
    1323 break;
    1324
    1329 assert(event->data.eventhole.var != NULL);
    1330 event->data.eventhole.var = var;
    1331 break;
    1332
    1334 assert(event->data.eventimpladd.var != NULL);
    1335 event->data.eventimpladd.var = var;
    1336 break;
    1337
    1339 assert(event->data.eventtypechg.var != NULL);
    1340 event->data.eventtypechg.var = var;
    1341 break;
    1342
    1344 assert(event->data.eventimpltypechg.var != NULL);
    1345 event->data.eventimpltypechg.var = var;
    1346 break;
    1347
    1348 default:
    1349 SCIPerrorMessage("event does not belong to a variable\n");
    1350 return SCIP_INVALIDDATA;
    1351 } /*lint !e788*/
    1352
    1353 return SCIP_OKAY;
    1354}
    1355
    1356/** gets old objective value for an objective value change event */
    1358 SCIP_EVENT* event /**< event */
    1359 )
    1360{
    1361 assert(event != NULL);
    1362
    1363 if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
    1364 {
    1365 SCIPerrorMessage("event is not an objective value change event\n");
    1366 SCIPABORT();
    1367 return SCIP_INVALID; /*lint !e527*/
    1368 }
    1369
    1370 return event->data.eventobjchg.oldobj;
    1371}
    1372
    1373/** gets new objective value for an objective value change event */
    1375 SCIP_EVENT* event /**< event */
    1376 )
    1377{
    1378 assert(event != NULL);
    1379
    1380 if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
    1381 {
    1382 SCIPerrorMessage("event is not an objective value change event\n");
    1383 SCIPABORT();
    1384 return SCIP_INVALID; /*lint !e527*/
    1385 }
    1386
    1387 return event->data.eventobjchg.newobj;
    1388}
    1389
    1390/** gets old bound for a bound change event */
    1392 SCIP_EVENT* event /**< event */
    1393 )
    1394{
    1395 assert(event != NULL);
    1396
    1397 switch( event->eventtype )
    1398 {
    1405 return event->data.eventbdchg.oldbound;
    1406
    1407 default:
    1408 SCIPerrorMessage("event is not a bound change event\n");
    1409 SCIPABORT();
    1410 return 0.0; /*lint !e527*/
    1411 } /*lint !e788*/
    1412}
    1413
    1414/** gets new bound for a bound change event */
    1416 SCIP_EVENT* event /**< event */
    1417 )
    1418{
    1419 assert(event != NULL);
    1420
    1421 switch( event->eventtype )
    1422 {
    1429 return event->data.eventbdchg.newbound;
    1430
    1431 default:
    1432 SCIPerrorMessage("event is not a bound change event\n");
    1433 SCIPABORT();
    1434 return 0.0; /*lint !e527*/
    1435 } /*lint !e788*/
    1436}
    1437
    1438/** gets new bound for a bound change event */
    1440 SCIP_EVENT* event /**< event */
    1441 )
    1442{
    1443 assert(event != NULL);
    1444 switch( event->eventtype )
    1445 {
    1452 return event->data.eventbdchg.oldboundexact;
    1453
    1454 default:
    1455 SCIPerrorMessage("event is not a bound change event\n");
    1456 SCIPABORT();
    1457 return NULL;
    1458 } /*lint !e788*/
    1459}
    1460
    1461/** gets old variable type for a variable type change event */
    1463 SCIP_EVENT* event /**< event */
    1464 )
    1465{
    1466 assert(event != NULL);
    1467
    1469 {
    1470 SCIPerrorMessage("event is not an variable type change event\n");
    1471 SCIPABORT();
    1472 return SCIP_VARTYPE_CONTINUOUS; /*lint !e527*/
    1473 }
    1474
    1475 return event->data.eventtypechg.oldtype;
    1476}
    1477
    1478/** gets new variable type for a variable type change event */
    1480 SCIP_EVENT* event /**< event */
    1481 )
    1482{
    1483 assert(event != NULL);
    1484
    1486 {
    1487 SCIPerrorMessage("event is not an variable type change event\n");
    1488 SCIPABORT();
    1489 return SCIP_VARTYPE_CONTINUOUS; /*lint !e527*/
    1490 }
    1491
    1492 return event->data.eventtypechg.newtype;
    1493}
    1494
    1495/** gets old implied integral type for an implied integral type change event */
    1497 SCIP_EVENT* event /**< event */
    1498 )
    1499{
    1500 assert(event != NULL);
    1501
    1503 {
    1504 SCIPerrorMessage("event is not an implied integral type change event\n");
    1505 SCIPABORT();
    1506 return SCIP_IMPLINTTYPE_NONE; /*lint !e527*/
    1507 }
    1508
    1509 return event->data.eventimpltypechg.oldtype;
    1510}
    1511
    1512/** gets new implied integral type for an implied integral type change event */
    1514 SCIP_EVENT* event /**< event */
    1515 )
    1516{
    1517 assert(event != NULL);
    1518
    1520 {
    1521 SCIPerrorMessage("event is not an implied integral type change event\n");
    1522 SCIPABORT();
    1523 return SCIP_IMPLINTTYPE_NONE; /*lint !e527*/
    1524 }
    1525
    1526 return event->data.eventimpltypechg.newtype;
    1527}
    1528
    1529/** gets node for a node or LP event */
    1531 SCIP_EVENT* event /**< event */
    1532 )
    1533{
    1534 assert(event != NULL);
    1535
    1537 {
    1538 SCIPerrorMessage("event is neither node nor LP event\n");
    1539 SCIPABORT();
    1540 return NULL; /*lint !e527*/
    1541 }
    1542
    1543 return event->data.node;
    1544}
    1545
    1546/** sets node for a node or LP event */
    1548 SCIP_EVENT* event, /**< event */
    1549 SCIP_NODE* node /**< new node */
    1550 )
    1551{
    1552 assert(event != NULL);
    1553
    1555 {
    1556 SCIPerrorMessage("event is neither node nor LP event\n");
    1557 SCIPABORT();
    1558 return SCIP_INVALIDDATA; /*lint !e527*/
    1559 }
    1560
    1561 event->data.node = node;
    1562
    1563 return SCIP_OKAY;
    1564}
    1565
    1566/** gets solution for a primal solution event */
    1568 SCIP_EVENT* event /**< event */
    1569 )
    1570{
    1571 assert(event != NULL);
    1572
    1573 if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
    1574 {
    1575 SCIPerrorMessage("event is not a primal solution event\n");
    1576 SCIPABORT();
    1577 return NULL; /*lint !e527*/
    1578 }
    1579
    1580 return event->data.sol;
    1581}
    1582
    1583/** sets solution for a primal solution event */
    1585 SCIP_EVENT* event, /**< event */
    1586 SCIP_SOL* sol /**< new primal solution */
    1587 )
    1588{
    1589 assert(event != NULL);
    1590
    1591 if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
    1592 {
    1593 SCIPerrorMessage("event is not a primal solution event\n");
    1594 SCIPABORT();
    1595 return SCIP_INVALIDDATA; /*lint !e527*/
    1596 }
    1597
    1598 event->data.sol = sol;
    1599
    1600 return SCIP_OKAY;
    1601}
    1602
    1603/** gets the left bound of open interval in the hole */
    1605 SCIP_EVENT* event /**< event */
    1606 )
    1607{
    1608 assert(event != NULL);
    1609
    1610 if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
    1611 {
    1612 SCIPerrorMessage("event is not a hole added or removed event\n");
    1613 SCIPABORT();
    1614 return SCIP_INVALID; /*lint !e527*/
    1615 }
    1616
    1617 return event->data.eventhole.left;
    1618}
    1619
    1620/** gets the right bound of open interval in the hole */
    1622 SCIP_EVENT* event /**< event */
    1623 )
    1624{
    1625 assert(event != NULL);
    1626
    1627 if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
    1628 {
    1629 SCIPerrorMessage("event is not a hole added or removed event\n");
    1630 SCIPABORT();
    1631 return SCIP_INVALID; /*lint !e527*/
    1632 }
    1633
    1634 return event->data.eventhole.right;
    1635}
    1636
    1637/** gets row for a row event */
    1639 SCIP_EVENT* event /**< event */
    1640 )
    1641{
    1642 assert(event != NULL);
    1643
    1644 switch( event->eventtype )
    1645 {
    1647 return event->data.eventrowaddedsepa.row;
    1649 return event->data.eventrowdeletedsepa.row;
    1651 return event->data.eventrowaddedlp.row;
    1652 case SCIP_EVENTTYPE_ROWDELETEDLP: /*lint !e30 !e142*/
    1653 return event->data.eventrowdeletedlp.row;
    1654 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /*lint !e30 !e142*/
    1655 return event->data.eventrowcoefchanged.row;
    1656 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /*lint !e30 !e142*/
    1657 return event->data.eventrowconstchanged.row;
    1658 case SCIP_EVENTTYPE_ROWSIDECHANGED: /*lint !e30 !e142*/
    1659 return event->data.eventrowsidechanged.row;
    1660 default:
    1661 SCIPerrorMessage("event does not belong to a row\n");
    1662 SCIPABORT();
    1663 return NULL; /*lint !e527*/
    1664 }
    1665}
    1666
    1667/** gets column for a row change coefficient event */
    1669 SCIP_EVENT* event /**< event */
    1670 )
    1671{
    1672 assert(event != NULL);
    1673
    1674 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
    1675 {
    1676 SCIPerrorMessage("event is not a row coefficient changed event\n");
    1677 SCIPABORT();
    1678 return NULL; /*lint !e527*/
    1679 }
    1680
    1681 return event->data.eventrowcoefchanged.col;
    1682}
    1683
    1684/** gets old coefficient value for a row change coefficient event */
    1686 SCIP_EVENT* event /**< event */
    1687 )
    1688{
    1689 assert(event != NULL);
    1690
    1691 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
    1692 {
    1693 SCIPerrorMessage("event is not a row coefficient changed event\n");
    1694 SCIPABORT();
    1695 return SCIP_INVALID; /*lint !e527*/
    1696 }
    1697
    1698 return event->data.eventrowcoefchanged.oldval;
    1699}
    1700
    1701/** gets new coefficient value for a row change coefficient event */
    1703 SCIP_EVENT* event /**< event */
    1704 )
    1705{
    1706 assert(event != NULL);
    1707
    1708 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
    1709 {
    1710 SCIPerrorMessage("event is not a row coefficient changed event\n");
    1711 SCIPABORT();
    1712 return SCIP_INVALID; /*lint !e527*/
    1713 }
    1714
    1715 return event->data.eventrowcoefchanged.newval;
    1716}
    1717
    1718/** gets old constant value for a row change constant event */
    1720 SCIP_EVENT* event /**< event */
    1721 )
    1722{
    1723 assert(event != NULL);
    1724
    1726 {
    1727 SCIPerrorMessage("event is not a row coefficient changed event\n");
    1728 SCIPABORT();
    1729 return SCIP_INVALID; /*lint !e527*/
    1730 }
    1731
    1732 return event->data.eventrowconstchanged.oldval;
    1733}
    1734
    1735/** gets new constant value for a row change constant event */
    1737 SCIP_EVENT* event /**< event */
    1738 )
    1739{
    1740 assert(event != NULL);
    1741
    1743 {
    1744 SCIPerrorMessage("event is not a row coefficient changed event\n");
    1745 SCIPABORT();
    1746 return SCIP_INVALID; /*lint !e527*/
    1747 }
    1748
    1749 return event->data.eventrowconstchanged.newval;
    1750}
    1751
    1752/** gets side for a row change side event */
    1754 SCIP_EVENT* event /**< event */
    1755 )
    1756{
    1757 assert(event != NULL);
    1758
    1760 {
    1761 SCIPerrorMessage("event is not a row side changed event\n");
    1762 SCIPABORT();
    1763 return SCIP_SIDETYPE_LEFT; /*lint !e527*/
    1764 }
    1765
    1766 return event->data.eventrowsidechanged.side;
    1767}
    1768
    1769/** gets old side value for a row change side event */
    1771 SCIP_EVENT* event /**< event */
    1772 )
    1773{
    1774 assert(event != NULL);
    1775
    1777 {
    1778 SCIPerrorMessage("event is not a row side changed event\n");
    1779 SCIPABORT();
    1780 return SCIP_INVALID; /*lint !e527*/
    1781 }
    1782
    1783 return event->data.eventrowsidechanged.oldval;
    1784}
    1785
    1786/** gets new side value for a row change side event */
    1788 SCIP_EVENT* event /**< event */
    1789 )
    1790{
    1791 assert(event != NULL);
    1792
    1794 {
    1795 SCIPerrorMessage("event is not a row side changed event\n");
    1796 SCIPABORT();
    1797 return SCIP_INVALID; /*lint !e527*/
    1798 }
    1799
    1800 return event->data.eventrowsidechanged.newval;
    1801}
    1802
    1803/** processes event by calling the appropriate event handlers */
    1805 SCIP_EVENT* event, /**< event */
    1806 SCIP_SET* set, /**< global SCIP settings */
    1807 SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
    1808 SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
    1809 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
    1810 SCIP_EVENTFILTER* eventfilter /**< event filter for global events; not needed for variable specific events */
    1811 )
    1812{
    1813 SCIP_VAR* var;
    1814
    1815 assert(event != NULL);
    1816 assert((event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
    1817 assert((event->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
    1818 assert((event->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
    1819
    1820 SCIPsetDebugMsg(set, "processing event of type 0x%" SCIP_EVENTTYPE_FORMAT "\n", event->eventtype);
    1821
    1822 switch( event->eventtype )
    1823 {
    1825 break;
    1826
    1842 case SCIP_EVENTTYPE_ROWDELETEDLP: /*lint !e30 !e142*/
    1843 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /*lint !e30 !e142*/
    1844 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /*lint !e30 !e142*/
    1845 case SCIP_EVENTTYPE_ROWSIDECHANGED: /*lint !e30 !e142*/
    1846 case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
    1847 SCIP_CALL( SCIPeventfilterProcess(eventfilter, set, event) );
    1848 break;
    1849
    1851 var = event->data.eventvardeleted.var;
    1852 assert(var != NULL);
    1853
    1854 /* process variable's event filter */
    1856 break;
    1857
    1859 var = event->data.eventvarfixed.var;
    1860 assert(var != NULL);
    1861
    1862 /* process variable's event filter */
    1864 break;
    1865
    1867 var = event->data.eventvarunlocked.var;
    1868 assert(var != NULL);
    1869
    1870 /* process variable's event filter */
    1872 break;
    1873
    1875 var = event->data.eventobjchg.var;
    1876 assert(var != NULL);
    1877 assert(var->eventqueueindexobj == -1);
    1879
    1880 /* inform LP about the objective change */
    1881 if( SCIPvarGetProbindex(var) >= 0 )
    1882 {
    1884 {
    1886 }
    1888 }
    1889
    1890 /* if in exact solving mode, adjust rational lp data */
    1891 if( set->exact_enable )
    1892 {
    1893 SCIP_RATIONAL* newobj;
    1894 SCIP_RATIONAL* oldobj;
    1895
    1896 if( event->data.eventobjchg.newobjexact != NULL )
    1897 {
    1898 newobj = event->data.eventobjchg.newobjexact;
    1899 oldobj = event->data.eventobjchg.oldobjexact;
    1900 }
    1901 else
    1902 {
    1903 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newobj) );
    1904 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oldobj) );
    1907 }
    1908
    1910 {
    1912 }
    1913 SCIP_CALL( SCIPlpExactUpdateVarObj(set, lp->lpexact, var, oldobj, newobj) );
    1914
    1915 if( event->data.eventobjchg.newobjexact == NULL )
    1916 {
    1917 SCIPrationalFreeBuffer(set->buffer, &oldobj);
    1918 SCIPrationalFreeBuffer(set->buffer, &newobj);
    1919 }
    1920 }
    1921
    1922 /* inform all existing primal solutions about the objective change (only if this is not a temporary change in
    1923 * probing mode)
    1924 */
    1925 if( ! lp->divingobjchg )
    1926 {
    1928 }
    1929
    1930 /* process variable's event filter */
    1932 break;
    1933
    1935 var = event->data.eventbdchg.var;
    1936 assert(var != NULL);
    1937
    1938 /* inform LP about global bound change */
    1940 {
    1941 assert(SCIPvarGetProbindex(var) >= 0);
    1943 event->data.eventbdchg.newbound) );
    1944
    1945 if( event->data.eventbdchg.newboundexact != NULL )
    1946 {
    1948 event->data.eventbdchg.newboundexact) );
    1949 }
    1950 }
    1951
    1952 /* process variable's event filter */
    1954 break;
    1955
    1957 var = event->data.eventbdchg.var;
    1958 assert(var != NULL);
    1959
    1960 /* inform LP about global bound change */
    1962 {
    1963 assert(SCIPvarGetProbindex(var) >= 0);
    1965 event->data.eventbdchg.newbound) );
    1966
    1967 if( event->data.eventbdchg.newboundexact != NULL )
    1968 {
    1970 event->data.eventbdchg.newboundexact) );
    1971 }
    1972 }
    1973
    1974 /* process variable's event filter */
    1976 break;
    1977
    1980 var = event->data.eventbdchg.var;
    1981 assert(var != NULL);
    1982 assert(var->eventqueueindexlb == -1);
    1983
    1984 /* inform LP about bound change and update branching candidates */
    1986 {
    1987 assert(SCIPvarGetProbindex(var) >= 0);
    1989 {
    1991 }
    1993 event->data.eventbdchg.newbound) );
    1994
    1995 if( !lp->probing )
    1996 {
    1997 if( event->data.eventbdchg.newboundexact != NULL )
    1998 {
    2000 {
    2002 }
    2003
    2005 event->data.eventbdchg.newboundexact) );
    2006 }
    2007 else
    2008 {
    2010 }
    2011 }
    2012
    2013 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
    2014 }
    2015
    2016 /* process variable's event filter */
    2018 break;
    2019
    2022 var = event->data.eventbdchg.var;
    2023 assert(var != NULL);
    2024 assert(var->eventqueueindexub == -1);
    2025
    2026 /* inform LP about bound change and update branching candidates */
    2028 {
    2029 assert(SCIPvarGetProbindex(var) >= 0);
    2031 {
    2033 }
    2035 event->data.eventbdchg.newbound) );
    2036
    2037 if( !lp->probing )
    2038 {
    2039 if( event->data.eventbdchg.newboundexact != NULL )
    2040 {
    2042 {
    2044 }
    2045
    2047 event->data.eventbdchg.newboundexact) );
    2048 }
    2049 else
    2050 {
    2051 SCIP_CALL( updateLpExactBoundChange(var, lp->lpexact, set, event, TRUE, FALSE) );
    2052 }
    2053 }
    2054
    2055 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
    2056 }
    2057
    2058 /* process variable's event filter */
    2060 break;
    2061
    2066 var = event->data.eventhole.var;
    2067 assert(var != NULL);
    2068
    2069 /* process variable's event filter */
    2071 break;
    2072
    2074 var = event->data.eventimpladd.var;
    2075 assert(var != NULL);
    2076 assert(!var->eventqueueimpl);
    2077
    2078 /* process variable's event filter */
    2080 break;
    2081
    2083 var = event->data.eventtypechg.var;
    2084 assert(var != NULL);
    2085
    2086 /* process variable's event filter */
    2088 break;
    2089
    2091 var = event->data.eventimpltypechg.var;
    2092 assert(var != NULL);
    2093
    2094 /* process variable's event filter */
    2096 break;
    2097
    2098 default:
    2099 SCIPerrorMessage("unknown event type <%" SCIP_EVENTTYPE_FORMAT ">\n", event->eventtype);
    2100 return SCIP_INVALIDDATA;
    2101 }
    2102
    2103 return SCIP_OKAY;
    2104}
    2105
    2106
    2107
    2108/*
    2109 * Event filter methods
    2110 */
    2111
    2112/** resizes eventfilter arrays to be able to store at least num entries */
    2113static
    2115 SCIP_EVENTFILTER* eventfilter, /**< event filter */
    2116 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2117 SCIP_SET* set, /**< global SCIP settings */
    2118 int num /**< minimal number of node slots in array */
    2119 )
    2120{
    2121 assert(eventfilter != NULL);
    2122 assert(blkmem != NULL);
    2123 assert(set != NULL);
    2124
    2125 if( num > eventfilter->size )
    2126 {
    2127 int newsize;
    2128
    2129 newsize = SCIPsetCalcMemGrowSize(set, num);
    2130 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventtypes, eventfilter->size, newsize) );
    2131 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventhdlrs, eventfilter->size, newsize) );
    2132 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventdata, eventfilter->size, newsize) );
    2133 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->nextpos, eventfilter->size, newsize) );
    2134 eventfilter->size = newsize;
    2135 }
    2136 assert(num <= eventfilter->size);
    2137
    2138 return SCIP_OKAY;
    2139}
    2140
    2141/** creates an event filter */
    2143 SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
    2144 BMS_BLKMEM* blkmem /**< block memory buffer */
    2145 )
    2146{
    2147 assert(eventfilter != NULL);
    2148 assert(blkmem != NULL);
    2149
    2150 SCIP_ALLOC( BMSallocBlockMemory(blkmem, eventfilter) );
    2151 (*eventfilter)->eventtypes = NULL;
    2152 (*eventfilter)->eventhdlrs = NULL;
    2153 (*eventfilter)->eventdata = NULL;
    2154 (*eventfilter)->nextpos = NULL;
    2155 (*eventfilter)->size = 0;
    2156 (*eventfilter)->len = 0;
    2157 (*eventfilter)->firstfreepos = -1;
    2158 (*eventfilter)->firstdeletedpos = -1;
    2159 (*eventfilter)->eventmask = SCIP_EVENTTYPE_DISABLED;
    2160 (*eventfilter)->delayedeventmask = SCIP_EVENTTYPE_DISABLED;
    2161 (*eventfilter)->delayupdates = FALSE;
    2162
    2163 return SCIP_OKAY;
    2164}
    2165
    2166/** frees an event filter and the associated event data entries */
    2168 SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
    2169 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2170 SCIP_SET* set /**< global SCIP settings */
    2171 )
    2172{
    2173 int i;
    2174
    2175 assert(eventfilter != NULL);
    2176 assert(*eventfilter != NULL);
    2177 assert(!(*eventfilter)->delayupdates);
    2178 assert(blkmem != NULL);
    2179 assert(set != NULL);
    2180 assert(set->scip != NULL);
    2181
    2182 /* free event data */
    2183 for( i = 0; i < (*eventfilter)->len; ++i )
    2184 {
    2185 if( (*eventfilter)->eventtypes[i] != SCIP_EVENTTYPE_DISABLED )
    2186 {
    2187 assert((*eventfilter)->eventhdlrs[i] != NULL);
    2188 if( (*eventfilter)->eventhdlrs[i]->eventdelete != NULL )
    2189 {
    2190 SCIP_CALL( (*eventfilter)->eventhdlrs[i]->eventdelete(set->scip, (*eventfilter)->eventhdlrs[i],
    2191 &(*eventfilter)->eventdata[i]) );
    2192 }
    2193 }
    2194 }
    2195
    2196 /* free event filter data */
    2197 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventtypes, (*eventfilter)->size);
    2198 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventhdlrs, (*eventfilter)->size);
    2199 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventdata, (*eventfilter)->size);
    2200 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->nextpos, (*eventfilter)->size);
    2201 BMSfreeBlockMemory(blkmem, eventfilter);
    2202
    2203 return SCIP_OKAY;
    2204}
    2205
    2206/** adds element to event filter */
    2208 SCIP_EVENTFILTER* eventfilter, /**< event filter */
    2209 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2210 SCIP_SET* set, /**< global SCIP settings */
    2211 SCIP_EVENTTYPE eventtype, /**< event type to catch */
    2212 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    2213 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
    2214 int* filterpos /**< pointer to store position of event filter entry, or NULL */
    2215 )
    2216{
    2217 int pos;
    2218
    2219 assert(eventfilter != NULL);
    2220 assert(blkmem != NULL);
    2221 assert(set != NULL);
    2222 assert(eventhdlr != NULL);
    2223
    2224 if( eventfilter->delayupdates )
    2225 {
    2226 /* insert addition to the end of the arrays;
    2227 * in delayed addition we have to add to the end of the arrays, in order to not destroy the validity of the
    2228 * arrays we are currently iterating over
    2229 */
    2230 SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
    2231 pos = eventfilter->len;
    2232 eventfilter->len++;
    2233
    2234 /* update delayed event filter mask */
    2235 eventfilter->delayedeventmask |= eventtype;
    2236 }
    2237 else
    2238 {
    2239 if( eventfilter->firstfreepos == -1 )
    2240 {
    2241 /* insert addition to the end of the arrays */
    2242 SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
    2243 pos = eventfilter->len;
    2244 eventfilter->len++;
    2245 }
    2246 else
    2247 {
    2248 /* use the first free slot to store the added event filter entry */
    2249 pos = eventfilter->firstfreepos;
    2250 assert(0 <= pos && pos < eventfilter->len);
    2251 assert(eventfilter->eventtypes[pos] == SCIP_EVENTTYPE_DISABLED);
    2252 eventfilter->firstfreepos = eventfilter->nextpos[pos];
    2253 assert(-1 <= eventfilter->firstfreepos && eventfilter->firstfreepos < eventfilter->len);
    2254 }
    2255
    2256 /* update event filter mask */
    2257 eventfilter->eventmask |= eventtype;
    2258 }
    2259 assert(0 <= pos && pos < eventfilter->len);
    2260
    2261 eventfilter->eventtypes[pos] = eventtype;
    2262 eventfilter->eventhdlrs[pos] = eventhdlr;
    2263 eventfilter->eventdata[pos] = eventdata;
    2264 eventfilter->nextpos[pos] = -2;
    2265
    2266 if( filterpos != NULL )
    2267 *filterpos = pos;
    2268
    2269 return SCIP_OKAY;
    2270}
    2271
    2272/** linear search for the given entry in event filter */
    2273static
    2275 SCIP_EVENTFILTER*const eventfilter, /**< event filter */
    2276 SCIP_EVENTTYPE const eventtype, /**< event type */
    2277 SCIP_EVENTHDLR*const eventhdlr, /**< event handler to call for the event processing */
    2278 SCIP_EVENTDATA*const eventdata /**< event data to pass to the event handler for the event processing */
    2279 )
    2280{
    2281 int i;
    2282
    2283 assert(eventfilter != NULL);
    2284 assert(eventtype != SCIP_EVENTTYPE_DISABLED);
    2285 assert(eventhdlr != NULL);
    2286
    2287 for( i = eventfilter->len - 1; i >= 0; --i )
    2288 {
    2289 if( eventdata == eventfilter->eventdata[i]
    2290 && eventhdlr == eventfilter->eventhdlrs[i]
    2291 && eventtype == eventfilter->eventtypes[i]
    2292 && eventfilter->nextpos[i] == -2 )
    2293 return i;
    2294 }
    2295
    2296 return -1;
    2297}
    2298
    2299/** deletes element from event filter */
    2301 SCIP_EVENTFILTER* eventfilter, /**< event filter */
    2302 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2303 SCIP_SET* set, /**< global SCIP settings */
    2304 SCIP_EVENTTYPE eventtype, /**< event type */
    2305 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
    2306 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
    2307 int filterpos /**< position of event filter entry, or -1 if unknown */
    2308 )
    2309{
    2310 assert(eventfilter != NULL);
    2311 assert(blkmem != NULL);
    2312 assert(set != NULL);
    2313 assert(eventtype != SCIP_EVENTTYPE_DISABLED);
    2314 assert(eventhdlr != NULL);
    2315 assert(-1 <= filterpos && filterpos < eventfilter->len);
    2316
    2317 /* search position of event filter entry, if not given by the user */
    2318 if( filterpos == -1 )
    2319 filterpos = eventfilterSearch(eventfilter, eventtype, eventhdlr, eventdata);
    2320 if( filterpos == -1 )
    2321 {
    2322 SCIPerrorMessage("no event for event handler %p with data %p and event mask %" SCIP_EVENTTYPE_FORMAT " found in event filter %p\n",
    2323 (void*)eventhdlr, (void*)eventdata, eventtype, (void*)eventfilter);
    2324 return SCIP_INVALIDDATA;
    2325 }
    2326 assert(0 <= filterpos && filterpos < eventfilter->len);
    2327 assert(eventfilter->eventtypes[filterpos] == eventtype);
    2328 assert(eventfilter->eventhdlrs[filterpos] == eventhdlr);
    2329 assert(eventfilter->eventdata[filterpos] == eventdata);
    2330 assert(eventfilter->nextpos[filterpos] == -2);
    2331
    2332 /* if updates are delayed, insert entry into the list of delayed deletions;
    2333 * otherwise, delete the entry from the filter directly and add the slot to the free list
    2334 */
    2335 if( eventfilter->delayupdates )
    2336 {
    2337 /* append filterpos to the list of deleted entries */
    2338 eventfilter->nextpos[filterpos] = eventfilter->firstdeletedpos;
    2339 eventfilter->firstdeletedpos = filterpos;
    2340 }
    2341 else
    2342 {
    2343 /* disable the entry in the filter and add the slot to the free list */
    2344 assert(eventfilter->nextpos[filterpos] == -2);
    2345 eventfilter->eventtypes[filterpos] = SCIP_EVENTTYPE_DISABLED;
    2346 eventfilter->nextpos[filterpos] = eventfilter->firstfreepos;
    2347 eventfilter->firstfreepos = filterpos;
    2348 }
    2349
    2350 return SCIP_OKAY;
    2351}
    2352
    2353/** makes the event filter to delay and buffer all updates until eventfilterProcessUpdates() is called */
    2354static
    2356 SCIP_EVENTFILTER* eventfilter /**< event filter */
    2357 )
    2358{
    2359 assert(eventfilter != NULL);
    2360 assert(!eventfilter->delayupdates);
    2361 assert(eventfilter->delayedeventmask == SCIP_EVENTTYPE_DISABLED);
    2362
    2363 eventfilter->delayupdates = TRUE;
    2364}
    2365
    2366/** processes all delayed additions and deletions */
    2367static
    2369 SCIP_EVENTFILTER* eventfilter /**< event filter */
    2370 )
    2371{
    2372 int pos;
    2373 int nextpos;
    2374
    2375 assert(eventfilter != NULL);
    2376 assert(eventfilter->delayupdates);
    2377
    2378 /* move deleted entries into the free list and disable them */
    2379 pos = eventfilter->firstdeletedpos;
    2380 while( pos != -1 )
    2381 {
    2382 assert(0 <= pos && pos < eventfilter->len);
    2383 assert(eventfilter->eventtypes[pos] != SCIP_EVENTTYPE_DISABLED);
    2384 assert(eventfilter->nextpos[pos] >= -1);
    2385
    2386 nextpos = eventfilter->nextpos[pos];
    2387 eventfilter->nextpos[pos] = eventfilter->firstfreepos;
    2388 eventfilter->firstfreepos = pos;
    2389 eventfilter->eventtypes[pos] = SCIP_EVENTTYPE_DISABLED;
    2390 pos = nextpos;
    2391 }
    2392 eventfilter->firstdeletedpos = -1;
    2393
    2394 /* update event mask */
    2395 eventfilter->eventmask |= eventfilter->delayedeventmask;
    2397
    2398 /* mark the event filter updates to be no longer delayed */
    2399 eventfilter->delayupdates = FALSE;
    2400}
    2401
    2402/** processes the event with all event handlers with matching filter setting */
    2404 SCIP_EVENTFILTER* eventfilter, /**< event filter */
    2405 SCIP_SET* set, /**< global SCIP settings */
    2406 SCIP_EVENT* event /**< event to process */
    2407 )
    2408{
    2409 SCIP_EVENTTYPE eventtype;
    2410 SCIP_EVENTTYPE* eventtypes;
    2411 SCIP_Bool processed;
    2412 int len;
    2413 int i;
    2414
    2415 assert(eventfilter != NULL);
    2416 assert(set != NULL);
    2417 assert(event != NULL);
    2418
    2419 SCIPsetDebugMsg(set, "processing event filter %p (len %d, mask 0x%" SCIP_EVENTTYPE_FORMAT ") with event type 0x%" SCIP_EVENTTYPE_FORMAT "\n",
    2420 (void*)eventfilter, eventfilter->len, eventfilter->eventmask, event->eventtype);
    2421
    2422 eventtype = event->eventtype;
    2423
    2424 /* check if there may be any event handler for specific event */
    2425 if( (eventtype & eventfilter->eventmask) == 0 )
    2426 return SCIP_OKAY;
    2427
    2428 /* delay the updates on this eventfilter, such that changes during event processing to the event filter
    2429 * don't destroy necessary information of the arrays we are currently using
    2430 */
    2431 eventfilterDelayUpdates(eventfilter);
    2432
    2433 /* process the event by calling the event handlers */
    2434 processed = FALSE;
    2435 len = eventfilter->len;
    2436 eventtypes = eventfilter->eventtypes;
    2437 for( i = 0; i < len; ++i )
    2438 {
    2439 /* check, if event is applicable for the filter element */
    2440 if( (eventtype & eventtypes[i]) != 0 )
    2441 {
    2442 /* call event handler */
    2443 SCIP_CALL( SCIPeventhdlrExec(eventfilter->eventhdlrs[i], set, event, eventfilter->eventdata[i]) );
    2444 processed = TRUE;
    2445 }
    2446 }
    2447
    2448 /* update eventfilter mask, if event was not processed by any event handler */
    2449 if( !processed )
    2450 {
    2451 eventfilter->eventmask &= ~event->eventtype;
    2452 SCIPsetDebugMsg(set, " -> event type 0x%" SCIP_EVENTTYPE_FORMAT " not processed. new mask of event filter %p: 0x%" SCIP_EVENTTYPE_FORMAT "\n",
    2453 event->eventtype, (void*)eventfilter, eventfilter->eventmask);
    2454 }
    2455
    2456 /* process delayed events on this eventfilter */
    2457 eventfilterProcessUpdates(eventfilter);
    2458
    2459 return SCIP_OKAY;
    2460}
    2461
    2462
    2463
    2464/*
    2465 * Event queue methods
    2466 */
    2467
    2468/*
    2469 * simple functions implemented as defines
    2470 */
    2471
    2472/* In debug mode, the following methods are implemented as function calls to ensure
    2473 * type validity.
    2474 * In optimized mode, the methods are implemented as defines to improve performance.
    2475 * However, we want to have them in the library anyways, so we have to undef the defines.
    2476 */
    2477
    2478#undef SCIPeventqueueIsDelayed
    2479
    2480/** resizes events array to be able to store at least num entries */
    2481static
    2483 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2484 SCIP_SET* set, /**< global SCIP settings */
    2485 int num /**< minimal number of node slots in array */
    2486 )
    2487{
    2488 assert(eventqueue != NULL);
    2489 assert(set != NULL);
    2490
    2491 if( num > eventqueue->eventssize )
    2492 {
    2493 int newsize;
    2494
    2495 newsize = SCIPsetCalcMemGrowSize(set, num);
    2496 SCIP_ALLOC( BMSreallocMemoryArray(&eventqueue->events, newsize) );
    2497 eventqueue->eventssize = newsize;
    2498 }
    2499 assert(num <= eventqueue->eventssize);
    2500
    2501 return SCIP_OKAY;
    2502}
    2503
    2504/** creates an event queue */
    2506 SCIP_EVENTQUEUE** eventqueue /**< pointer to store the event queue */
    2507 )
    2508{
    2509 assert(eventqueue != NULL);
    2510
    2511 SCIP_ALLOC( BMSallocMemory(eventqueue) );
    2512 (*eventqueue)->events = NULL;
    2513 (*eventqueue)->eventssize = 0;
    2514 (*eventqueue)->nevents = 0;
    2515 (*eventqueue)->delayevents = FALSE;
    2516
    2517 return SCIP_OKAY;
    2518}
    2519
    2520/** frees event queue; there must not be any unprocessed events in the queue! */
    2522 SCIP_EVENTQUEUE** eventqueue /**< pointer to the event queue */
    2523 )
    2524{
    2525 assert(eventqueue != NULL);
    2526 assert(*eventqueue != NULL);
    2527 assert((*eventqueue)->nevents == 0);
    2528
    2529 BMSfreeMemoryArrayNull(&(*eventqueue)->events);
    2530 BMSfreeMemory(eventqueue);
    2531
    2532 return SCIP_OKAY;
    2533}
    2534
    2535/** appends event to the event queue; sets event to NULL afterwards */
    2536static
    2538 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2539 SCIP_SET* set, /**< global SCIP settings */
    2540 SCIP_EVENT** event /**< pointer to event to append to the queue */
    2541 )
    2542{
    2543 assert(eventqueue != NULL);
    2544 assert(eventqueue->delayevents);
    2545 assert(event != NULL);
    2546 assert(*event != NULL);
    2547
    2548 SCIPsetDebugMsg(set, "appending event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p at position %d\n",
    2549 (void*)*event, (*event)->eventtype, (void*)eventqueue, eventqueue->nevents);
    2550
    2551 SCIP_CALL( eventqueueEnsureEventsMem(eventqueue, set, eventqueue->nevents+1) );
    2552 eventqueue->events[eventqueue->nevents] = *event;
    2553 eventqueue->nevents++;
    2554
    2555 *event = NULL;
    2556
    2557 return SCIP_OKAY;
    2558}
    2559
    2560/** processes event or adds event to the event queue */
    2562 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2563 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2564 SCIP_SET* set, /**< global SCIP settings */
    2565 SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
    2566 SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
    2567 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
    2568 SCIP_EVENTFILTER* eventfilter, /**< event filter for global events; not needed for variable specific events */
    2569 SCIP_EVENT** event /**< pointer to event to add to the queue; will be NULL after queue addition */
    2570 )
    2571{
    2572 SCIP_VAR* var;
    2573 SCIP_EVENT* qevent;
    2574 int pos;
    2575
    2576 assert(eventqueue != NULL);
    2577 assert(event != NULL);
    2578 assert(*event != NULL);
    2579 assert(((*event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
    2580 assert(((*event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
    2581 assert(((*event)->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
    2582
    2583 if( !eventqueue->delayevents )
    2584 {
    2585 SCIP_CALL( SCIPeventqueueDelay(eventqueue) );
    2586
    2587 /* immediately process event */
    2588 SCIP_CALL( SCIPeventProcess(*event, set, primal, lp, branchcand, eventfilter) );
    2589 SCIP_CALL( SCIPeventFree(event, blkmem) );
    2590
    2591 SCIP_CALL( SCIPeventqueueProcess(eventqueue, blkmem, set, primal, lp, branchcand, eventfilter) );
    2592 }
    2593 else
    2594 {
    2595 /* delay processing of event by appending it to the event queue */
    2596 SCIPsetDebugMsg(set, "adding event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p\n", (void*)*event, (*event)->eventtype, (void*)eventqueue);
    2597
    2598 switch( (*event)->eventtype )
    2599 {
    2601 SCIPerrorMessage("cannot add a disabled event to the event queue\n");
    2602 return SCIP_INVALIDDATA;
    2603
    2625 case SCIP_EVENTTYPE_ROWADDEDSEPA: /* @todo remove previous DELETEDSEPA event */
    2626 case SCIP_EVENTTYPE_ROWDELETEDSEPA: /* @todo remove previous ADDEDSEPA event */
    2627 case SCIP_EVENTTYPE_ROWADDEDLP: /* @todo remove previous DELETEDLP event */
    2628 case SCIP_EVENTTYPE_ROWDELETEDLP: /* @todo remove previous ADDEDLP event */ /*lint !e30 !e142*/
    2629 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /* @todo merge? */ /*lint !e30 !e142*/
    2630 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /* @todo merge with previous constchanged event */ /*lint !e30 !e142*/
    2631 case SCIP_EVENTTYPE_ROWSIDECHANGED: /* @todo merge with previous sidechanged event */ /*lint !e30 !e142*/
    2632 case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
    2633 /* these events cannot (or need not) be merged; just add them to the queue */
    2634 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
    2635 break;
    2636
    2638 /* changes in objective value may be merged with older changes in objective value */
    2639 var = (*event)->data.eventobjchg.var;
    2640 assert(var != NULL);
    2641 pos = var->eventqueueindexobj;
    2642 if( pos >= 0 )
    2643 {
    2644 /* the objective value change event already exists -> modify it accordingly */
    2645 assert(pos < eventqueue->nevents);
    2646 qevent = eventqueue->events[pos];
    2647 assert(qevent != NULL);
    2648 assert(qevent->eventtype == SCIP_EVENTTYPE_OBJCHANGED);
    2649 assert(qevent->data.eventobjchg.var == var);
    2650 assert(SCIPsetIsEQ(set, (*event)->data.eventobjchg.oldobj, qevent->data.eventobjchg.newobj));
    2651
    2652 SCIPsetDebugMsg(set, " -> merging OBJ event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
    2653 SCIPvarGetName((*event)->data.eventobjchg.var), (*event)->data.eventobjchg.oldobj,
    2654 (*event)->data.eventobjchg.newobj,
    2655 pos, SCIPvarGetName(qevent->data.eventobjchg.var), qevent->data.eventobjchg.oldobj,
    2656 qevent->data.eventobjchg.newobj);
    2657
    2658 qevent->data.eventobjchg.newobj = (*event)->data.eventobjchg.newobj;
    2659 if( qevent->data.eventobjchg.newobj == qevent->data.eventobjchg.oldobj ) /*lint !e777*/
    2660 {
    2661 /* the queued objective value change was reversed -> disable the event in the queue */
    2662 eventFreeExactData(qevent, blkmem);
    2663 eventDisable(qevent);
    2664 var->eventqueueindexobj = -1;
    2665 SCIPsetDebugMsg(set, " -> event disabled\n");
    2666 }
    2667
    2668 /* free the event that is of no use any longer */
    2669 SCIP_CALL( SCIPeventFree(event, blkmem) );
    2670 }
    2671 else
    2672 {
    2673 /* the objective value change event doesn't exist -> add it to the queue, and remember the array index */
    2674 var->eventqueueindexobj = eventqueue->nevents;
    2675 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
    2676 }
    2677 break;
    2678
    2681 /* changes in lower bound may be merged with older changes in lower bound */
    2682 var = (*event)->data.eventbdchg.var;
    2683 assert(var != NULL);
    2684 pos = var->eventqueueindexlb;
    2685 if( pos >= 0 )
    2686 {
    2687 /* the lower bound change event already exists -> modify it accordingly */
    2688 assert(pos < eventqueue->nevents);
    2689 qevent = eventqueue->events[pos];
    2690 assert(qevent != NULL);
    2692 assert(qevent->data.eventbdchg.var == var);
    2693 assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
    2694
    2695 SCIPsetDebugMsg(set, " -> merging LB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
    2696 SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
    2697 (*event)->data.eventbdchg.newbound,
    2698 pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
    2699 qevent->data.eventbdchg.newbound);
    2700
    2701 qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
    2702
    2703 /* possibly update exact bound */
    2704 if( (*event)->data.eventbdchg.newboundexact != NULL )
    2705 {
    2706 if( qevent->data.eventbdchg.newboundexact == NULL )
    2707 {
    2708 SCIP_CALL( SCIPeventAddExactBdChg(qevent, blkmem, (*event)->data.eventbdchg.oldboundexact, (*event)->data.eventbdchg.newboundexact) );
    2709 }
    2710 else
    2711 SCIPrationalSetRational(qevent->data.eventbdchg.newboundexact, (*event)->data.eventbdchg.newboundexact);
    2712 }
    2713 else
    2714 {
    2715 if( qevent->data.eventbdchg.newboundexact != NULL )
    2716 {
    2719 }
    2720 }
    2721
    2722 /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
    2723 if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
    2725 /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
    2726 else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
    2728 else
    2729 {
    2730 /* the queued bound change was reversed -> disable the event in the queue */
    2731 assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
    2732 eventFreeExactData(qevent, blkmem);
    2733 eventDisable(qevent);
    2734 var->eventqueueindexlb = -1;
    2735 SCIPsetDebugMsg(set, " -> event disabled\n");
    2736 }
    2737
    2738 /* free the event that is of no use any longer */
    2739 SCIP_CALL( SCIPeventFree(event, blkmem) );
    2740 }
    2741 else
    2742 {
    2743 /* the lower bound change event doesn't exist -> add it to the queue, and remember the array index */
    2744 var->eventqueueindexlb = eventqueue->nevents;
    2745 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
    2746 }
    2747 break;
    2748
    2751 /* changes in upper bound may be merged with older changes in upper bound */
    2752 var = (*event)->data.eventbdchg.var;
    2753 assert(var != NULL);
    2754 pos = var->eventqueueindexub;
    2755 if( pos >= 0 )
    2756 {
    2757 /* the upper bound change event already exists -> modify it accordingly */
    2758 assert(pos < eventqueue->nevents);
    2759 qevent = eventqueue->events[pos];
    2760 assert(qevent != NULL);
    2762 assert(qevent->data.eventbdchg.var == var);
    2763 assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
    2764
    2765 SCIPsetDebugMsg(set, " -> merging UB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
    2766 SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
    2767 (*event)->data.eventbdchg.newbound,
    2768 pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
    2769 qevent->data.eventbdchg.newbound);
    2770
    2771 qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
    2772
    2773 /* possibly update exact bound */
    2774 if( (*event)->data.eventbdchg.newboundexact != NULL )
    2775 {
    2776 if( qevent->data.eventbdchg.newboundexact == NULL )
    2777 {
    2778 SCIP_CALL( SCIPeventAddExactBdChg(qevent, blkmem, (*event)->data.eventbdchg.oldboundexact, (*event)->data.eventbdchg.newboundexact) );
    2779 }
    2780 else
    2781 SCIPrationalSetRational(qevent->data.eventbdchg.newboundexact, (*event)->data.eventbdchg.newboundexact);
    2782 }
    2783 else
    2784 {
    2785 if( qevent->data.eventbdchg.newboundexact != NULL )
    2786 {
    2789 }
    2790 }
    2791
    2792 /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
    2793 if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
    2795 /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
    2796 else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
    2798 else
    2799 {
    2800 /* the queued bound change was reversed -> disable the event in the queue */
    2801 assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
    2802 eventFreeExactData(qevent, blkmem);
    2803 eventDisable(qevent);
    2804 var->eventqueueindexub = -1;
    2805 SCIPsetDebugMsg(set, " -> event disabled\n");
    2806 }
    2807
    2808 /* free the event that is of no use any longer */
    2809 SCIP_CALL( SCIPeventFree(event, blkmem) );
    2810 }
    2811 else
    2812 {
    2813 /* the upper bound change event doesn't exist -> add it to the queue, and remember the array index */
    2814 var->eventqueueindexub = eventqueue->nevents;
    2815 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
    2816 }
    2817 break;
    2818
    2820 var = (*event)->data.eventimpladd.var;
    2821 assert(var != NULL);
    2822 if( var->eventqueueimpl )
    2823 {
    2824 /* free the event that is of no use any longer */
    2825 SCIP_CALL( SCIPeventFree(event, blkmem) );
    2826 }
    2827 else
    2828 {
    2829 var->eventqueueimpl = TRUE;
    2830 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
    2831 }
    2832 break;
    2833
    2834 default:
    2835 SCIPerrorMessage("unknown event type <%" SCIP_EVENTTYPE_FORMAT ">\n", (*event)->eventtype);
    2836 return SCIP_INVALIDDATA;
    2837 }
    2838 }
    2839
    2840 assert(*event == NULL);
    2841
    2842 return SCIP_OKAY;
    2843}
    2844
    2845/** marks queue to delay incoming events until a call to SCIPeventqueueProcess() */
    2847 SCIP_EVENTQUEUE* eventqueue /**< event queue */
    2848 )
    2849{
    2850 assert(eventqueue != NULL);
    2851 assert(!eventqueue->delayevents);
    2852
    2853 SCIPdebugMessage("event processing is delayed\n");
    2854
    2855 eventqueue->delayevents = TRUE;
    2856
    2857 return SCIP_OKAY;
    2858}
    2859
    2860/** processes all delayed events, marks queue to process events immediately */
    2862 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2863 BMS_BLKMEM* blkmem, /**< block memory buffer */
    2864 SCIP_SET* set, /**< global SCIP settings */
    2865 SCIP_PRIMAL* primal, /**< primal data */
    2866 SCIP_LP* lp, /**< current LP data */
    2867 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2868 SCIP_EVENTFILTER* eventfilter /**< global event filter */
    2869 )
    2870{
    2871 SCIP_EVENT* event;
    2872 int i;
    2873
    2874 assert(eventqueue != NULL);
    2875 assert(eventqueue->delayevents);
    2876
    2877 SCIPsetDebugMsg(set, "processing %d queued events\n", eventqueue->nevents);
    2878
    2879 /* pass events to the responsible event filters
    2880 * During event processing, new events may be raised. We have to loop to the mutable eventqueue->nevents.
    2881 * A loop to something like "nevents = eventqueue->nevents; for(...; i < nevents; ...)" would miss the
    2882 * newly created events. The same holds for eventqueue->events, which can be moved in memory due to
    2883 * memory reallocation in eventqueueAppend().
    2884 */
    2885 for( i = 0; i < eventqueue->nevents; ++i )
    2886 {
    2887 event = eventqueue->events[i];
    2888 assert(event != NULL);
    2889
    2890 SCIPsetDebugMsg(set, "processing event %d of %d events in queue: eventtype=0x%" SCIP_EVENTTYPE_FORMAT "\n", i, eventqueue->nevents, event->eventtype);
    2891
    2892 /* unmark the event queue index of a variable with changed objective value or bounds, and unmark the event queue
    2893 * member flag of a variable with added implication
    2894 */
    2895 if( (event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) != 0 )
    2896 {
    2897 assert(event->data.eventobjchg.var->eventqueueindexobj == i);
    2898 event->data.eventobjchg.var->eventqueueindexobj = -1;
    2899 }
    2900 else if( (event->eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
    2901 {
    2902 assert(event->data.eventbdchg.var->eventqueueindexlb == i);
    2903 event->data.eventbdchg.var->eventqueueindexlb = -1;
    2904 }
    2905 else if( (event->eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0 )
    2906 {
    2907 assert(event->data.eventbdchg.var->eventqueueindexub == i);
    2908 event->data.eventbdchg.var->eventqueueindexub = -1;
    2909 }
    2910 else if( (event->eventtype & SCIP_EVENTTYPE_IMPLADDED) != 0 )
    2911 {
    2912 assert(event->data.eventimpladd.var->eventqueueimpl);
    2913 event->data.eventimpladd.var->eventqueueimpl = FALSE;
    2914 }
    2915
    2916 /* process event */
    2917 SCIP_CALL( SCIPeventProcess(event, set, primal, lp, branchcand, eventfilter) );
    2918
    2919 /* free the event immediately, because additionally raised events during event processing
    2920 * can lead to a large event queue
    2921 */
    2922 SCIP_CALL( SCIPeventFree(&eventqueue->events[i], blkmem) );
    2923 }
    2924
    2925 assert(i == eventqueue->nevents);
    2926 eventqueue->nevents = 0;
    2927 eventqueue->delayevents = FALSE;
    2928
    2929 return SCIP_OKAY;
    2930}
    2931
    2932/** returns TRUE iff events of the queue are delayed until the next SCIPeventqueueProcess() call */
    2934 SCIP_EVENTQUEUE* eventqueue /**< event queue */
    2935 )
    2936{
    2937 assert(eventqueue != NULL);
    2938
    2939 return eventqueue->delayevents;
    2940}
    SCIP_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
    SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
    SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
    SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
    SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
    SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
    SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
    SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
    Definition: branch.c:1169
    internal methods for branching rules and branching candidate storage
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
    Definition: clock.c:260
    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_INVALID
    Definition: def.h:178
    #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 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 SCIPeventhdlrCopyInclude(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
    Definition: event.c:62
    static void eventFreeExactData(SCIP_EVENT *event, BMS_BLKMEM *blkmem)
    Definition: event.c:1146
    SCIP_RETCODE SCIPeventFree(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
    Definition: event.c:1168
    static SCIP_RETCODE eventqueueAppend(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, SCIP_EVENT **event)
    Definition: event.c:2537
    SCIP_RETCODE SCIPeventCreateLbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: event.c:752
    static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
    Definition: event.c:2368
    SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
    Definition: event.c:634
    SCIP_RETCODE SCIPeventhdlrInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
    Definition: event.c:318
    SCIP_RETCODE SCIPeventCreateVarAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
    Definition: event.c:598
    SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:1055
    SCIP_RETCODE SCIPeventhdlrCreate(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: event.c:195
    static SCIP_RETCODE doEventhdlrCreate(SCIP_EVENTHDLR **eventhdlr, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: event.c:152
    SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
    Definition: event.c:2521
    void SCIPeventhdlrSetFree(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
    Definition: event.c:438
    SCIP_RETCODE SCIPeventCreateGholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
    Definition: event.c:867
    SCIP_RETCODE SCIPeventhdlrExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
    Definition: event.c:342
    SCIP_RETCODE SCIPeventCreateUbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: event.c:780
    void SCIPeventhdlrEnableOrDisableClocks(SCIP_EVENTHDLR *eventhdlr, SCIP_Bool enable)
    Definition: event.c:514
    void SCIPeventhdlrSetExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
    Definition: event.c:482
    SCIP_RETCODE SCIPeventCreateVarUnlocked(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
    Definition: event.c:656
    SCIP_RETCODE SCIPeventhdlrExit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
    Definition: event.c:288
    SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
    Definition: event.c:1584
    static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
    Definition: event.c:2482
    SCIP_RETCODE SCIPeventAddExactObjChg(SCIP_EVENT *event, BMS_BLKMEM *blkmem, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj)
    Definition: event.c:827
    void SCIPeventhdlrSetInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
    Definition: event.c:471
    static SCIP_RETCODE updateLpExactBoundChange(SCIP_VAR *var, SCIP_LPEXACT *lp, SCIP_SET *set, SCIP_EVENT *event, SCIP_Bool isUb, SCIP_Bool isGlb)
    Definition: event.c:82
    SCIP_RETCODE SCIPeventCreateObjChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
    Definition: event.c:677
    SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
    Definition: event.c:1547
    SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
    Definition: event.c:2561
    SCIP_RETCODE SCIPeventhdlrFree(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set)
    Definition: event.c:221
    SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
    Definition: event.c:2167
    SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1122
    SCIP_RETCODE SCIPeventCreateRowAddedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:998
    SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
    Definition: event.c:2933
    SCIP_RETCODE SCIPeventAddExactBdChg(SCIP_EVENT *event, BMS_BLKMEM *blkmem, SCIP_RATIONAL *oldbound, SCIP_RATIONAL *newbound)
    Definition: event.c:808
    SCIP_RETCODE SCIPeventCreateGholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
    Definition: event.c:845
    SCIP_RETCODE SCIPeventqueueProcess(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
    Definition: event.c:2861
    SCIP_RETCODE SCIPeventCreateRowDeletedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:1017
    void SCIPeventhdlrSetCopy(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTCOPY((*eventcopy)))
    Definition: event.c:427
    SCIP_RETCODE SCIPeventCreateLholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
    Definition: event.c:889
    void SCIPeventhdlrSetInit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
    Definition: event.c:449
    SCIP_RETCODE SCIPeventhdlrInit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
    Definition: event.c:252
    SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: event.c:2300
    SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
    Definition: event.c:2142
    void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
    Definition: event.c:493
    void SCIPeventhdlrSetExit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
    Definition: event.c:460
    SCIP_RETCODE SCIPeventhdlrExec(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
    Definition: event.c:366
    SCIP_RETCODE SCIPeventChgVar(SCIP_EVENT *event, SCIP_VAR *var)
    Definition: event.c:1281
    SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1099
    SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
    Definition: event.c:1804
    SCIP_RETCODE SCIPeventCreateSync(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
    Definition: event.c:555
    static SCIP_RETCODE eventfilterEnsureMem(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
    Definition: event.c:2114
    SCIP_RETCODE SCIPeventCreateImplAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
    Definition: event.c:933
    SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
    Definition: event.c:1204
    SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
    Definition: event.c:2505
    SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
    Definition: event.c:2403
    SCIP_RETCODE SCIPeventCreateImplTypeChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_IMPLINTTYPE oldtype, SCIP_IMPLINTTYPE newtype)
    Definition: event.c:975
    SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: event.c:2207
    SCIP_RETCODE SCIPeventCreateVarDeleted(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
    Definition: event.c:616
    SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
    Definition: event.c:1074
    SCIP_RETCODE SCIPeventCreateGubChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: event.c:727
    SCIP_RETCODE SCIPeventCreateGlbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
    Definition: event.c:702
    SCIP_RETCODE SCIPeventqueueDelay(SCIP_EVENTQUEUE *eventqueue)
    Definition: event.c:2846
    SCIP_RETCODE SCIPeventCreateLholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
    Definition: event.c:911
    SCIP_RETCODE SCIPeventCreateTypeChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_VARTYPE oldtype, SCIP_VARTYPE newtype)
    Definition: event.c:952
    static int eventfilterSearch(SCIP_EVENTFILTER *const eventfilter, SCIP_EVENTTYPE const eventtype, SCIP_EVENTHDLR *const eventhdlr, SCIP_EVENTDATA *const eventdata)
    Definition: event.c:2274
    static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
    Definition: event.c:2355
    SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: event.c:1036
    static void eventDisable(SCIP_EVENT *event)
    Definition: event.c:1184
    internal methods for managing events
    SCIP_Real SCIPeventhdlrGetSetupTime(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:526
    SCIP_Bool SCIPeventhdlrIsInitialized(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:504
    SCIP_Real SCIPeventhdlrGetTime(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:538
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:406
    void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: event.c:416
    SCIP_Real SCIPeventGetRowOldCoefVal(SCIP_EVENT *event)
    Definition: event.c:1685
    SCIP_RATIONAL * SCIPeventGetOldboundExact(SCIP_EVENT *event)
    Definition: event.c:1439
    SCIP_IMPLINTTYPE SCIPeventGetNewImpltype(SCIP_EVENT *event)
    Definition: event.c:1513
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
    Definition: event.c:1567
    SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
    Definition: event.c:1479
    SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
    Definition: event.c:1621
    SCIP_Real SCIPeventGetHoleLeft(SCIP_EVENT *event)
    Definition: event.c:1604
    SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
    Definition: event.c:1357
    SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
    Definition: event.c:1391
    SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
    Definition: event.c:1217
    SCIP_Real SCIPeventGetRowNewConstVal(SCIP_EVENT *event)
    Definition: event.c:1736
    SCIP_COL * SCIPeventGetRowCol(SCIP_EVENT *event)
    Definition: event.c:1668
    SCIP_Real SCIPeventGetNewobj(SCIP_EVENT *event)
    Definition: event.c:1374
    SCIP_SIDETYPE SCIPeventGetRowSide(SCIP_EVENT *event)
    Definition: event.c:1753
    SCIP_Real SCIPeventGetRowOldSideVal(SCIP_EVENT *event)
    Definition: event.c:1770
    SCIP_IMPLINTTYPE SCIPeventGetOldImpltype(SCIP_EVENT *event)
    Definition: event.c:1496
    SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
    Definition: event.c:1415
    SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
    Definition: event.c:1530
    SCIP_Real SCIPeventGetRowNewCoefVal(SCIP_EVENT *event)
    Definition: event.c:1702
    SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
    Definition: event.c:1787
    SCIP_Real SCIPeventGetRowOldConstVal(SCIP_EVENT *event)
    Definition: event.c:1719
    SCIP_ROW * SCIPeventGetRow(SCIP_EVENT *event)
    Definition: event.c:1638
    SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
    Definition: event.c:1462
    void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:461
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:151
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1404
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_VARSTATUS SCIPvarGetStatusExact(SCIP_VAR *var)
    Definition: var.c:23396
    SCIP_COLEXACT * SCIPvarGetColExact(SCIP_VAR *var)
    Definition: var.c:23694
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
    Definition: lp.c:3997
    SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
    Definition: lp.c:3952
    SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
    Definition: lp.c:14264
    SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
    Definition: lp.c:14226
    SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
    Definition: lp.c:3893
    SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
    Definition: lp.c:14305
    SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
    Definition: lp.c:14343
    SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
    Definition: lp.c:14166
    internal methods for LP management
    SCIP_RETCODE SCIPlpExactUpdateVarObj(SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_VAR *var, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj)
    Definition: lpexact.c:6422
    SCIP_RETCODE SCIPlpExactUpdateVarUb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
    Definition: lpexact.c:6568
    SCIP_RETCODE SCIPlpExactUpdateVarLbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
    Definition: lpexact.c:6469
    SCIP_RETCODE SCIPcolExactChgObj(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newobj)
    Definition: lpexact.c:3001
    SCIP_RETCODE SCIPlpExactUpdateVarLb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
    Definition: lpexact.c:6501
    SCIP_RETCODE SCIPcolExactChgUb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newub)
    Definition: lpexact.c:3093
    SCIP_RETCODE SCIPcolExactChgLb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newlb)
    Definition: lpexact.c:3048
    SCIP_RETCODE SCIPlpExactUpdateVarUbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
    Definition: lpexact.c:6536
    internal methods for exact LP management
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
    Definition: primal.c:2054
    internal methods for collecting primal CIP solutions and primal informations
    public methods for managing events
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public methods for problem variables
    wrapper for rational number arithmetic
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    internal methods for global SCIP settings
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    SCIP_Real oldbound
    Definition: struct_event.h:85
    SCIP_Real newbound
    Definition: struct_event.h:86
    SCIP_RATIONAL * newboundexact
    Definition: struct_event.h:88
    SCIP_VAR * var
    Definition: struct_event.h:89
    SCIP_RATIONAL * oldboundexact
    Definition: struct_event.h:87
    SCIP_EVENTTYPE delayedeventmask
    Definition: struct_event.h:212
    SCIP_EVENTHDLR ** eventhdlrs
    Definition: struct_event.h:204
    SCIP_Bool delayupdates
    Definition: struct_event.h:213
    SCIP_EVENTTYPE eventmask
    Definition: struct_event.h:211
    SCIP_EVENTTYPE * eventtypes
    Definition: struct_event.h:203
    SCIP_EVENTDATA ** eventdata
    Definition: struct_event.h:205
    SCIP_VAR * var
    Definition: struct_event.h:97
    SCIP_RATIONAL * newobjexact
    Definition: struct_event.h:78
    SCIP_Real newobj
    Definition: struct_event.h:76
    SCIP_RATIONAL * oldobjexact
    Definition: struct_event.h:77
    SCIP_Real oldobj
    Definition: struct_event.h:75
    SCIP_VAR * var
    Definition: struct_event.h:79
    SCIP_EVENT ** events
    Definition: struct_event.h:238
    SCIP_Bool delayevents
    Definition: struct_event.h:241
    SCIP_EVENTVARFIXED eventvarfixed
    Definition: struct_event.h:179
    SCIP_EVENTTYPECHG eventtypechg
    Definition: struct_event.h:185
    SCIP_EVENTTYPEIMPLCHG eventimpltypechg
    Definition: struct_event.h:186
    SCIP_EVENTTYPE eventtype
    Definition: struct_event.h:197
    SCIP_EVENTVARUNLOCKED eventvarunlocked
    Definition: struct_event.h:180
    SCIP_EVENTBDCHG eventbdchg
    Definition: struct_event.h:182
    SCIP_EVENTHOLE eventhole
    Definition: struct_event.h:183
    SCIP_EVENTIMPLADD eventimpladd
    Definition: struct_event.h:184
    SCIP_EVENTOBJCHG eventobjchg
    Definition: struct_event.h:181
    SCIP_EVENTVARADDED eventvaradded
    Definition: struct_event.h:177
    union SCIP_Event::@18 data
    SCIP_EVENTVARDELETED eventvardeleted
    Definition: struct_event.h:178
    SCIP_Bool initialized
    Definition: struct_event.h:232
    SCIP_CLOCK * setuptime
    Definition: struct_event.h:230
    SCIP_CLOCK * eventtime
    Definition: struct_event.h:231
    SCIP_EVENTHDLRDATA * eventhdlrdata
    Definition: struct_event.h:229
    SCIP_Bool probing
    Definition: struct_lp.h:384
    SCIP_LPEXACT * lpexact
    Definition: struct_lp.h:309
    SCIP_Bool divingobjchg
    Definition: struct_lp.h:387
    SCIP_EVENTFILTER * eventfilter
    Definition: struct_var.h:303
    int eventqueueindexobj
    Definition: struct_var.h:313
    unsigned int eventqueueimpl
    Definition: struct_var.h:341
    int eventqueueindexlb
    Definition: struct_var.h:314
    int eventqueueindexub
    Definition: struct_var.h:315
    SCIP_VARDATAEXACT * exactdata
    Definition: struct_var.h:290
    union SCIP_Var::@24 data
    datastructures for managing events
    data structures for LP management
    datastructures for global SCIP settings
    datastructures for problem variables
    Definition: heur_padm.c:135
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    #define SCIP_EVENTTYPE_GHOLEADDED
    Definition: type_event.h:81
    #define SCIP_EVENTTYPE_FIRSTLPSOLVED
    Definition: type_event.h:101
    #define SCIP_EVENTTYPE_NODEFEASIBLE
    Definition: type_event.h:94
    #define SCIP_EVENTTYPE_BOUNDCHANGED
    Definition: type_event.h:127
    #define SCIP_EVENTTYPE_VARUNLOCKED
    Definition: type_event.h:73
    #define SCIP_EVENTTYPE_ROWSIDECHANGED
    Definition: type_event.h:115
    #define SCIP_EVENTTYPE_SYNC
    Definition: type_event.h:118
    #define SCIP_EVENTTYPE_ROWADDEDLP
    Definition: type_event.h:111
    #define SCIP_EVENTTYPE_POORSOLFOUND
    Definition: type_event.h:105
    #define SCIP_EVENTTYPE_TYPECHANGED
    Definition: type_event.h:86
    #define SCIP_EVENTTYPE_PRESOLVEROUND
    Definition: type_event.h:90
    #define SCIP_EVENTTYPE_GUBCHANGED
    Definition: type_event.h:76
    #define SCIP_EVENTTYPE_GHOLEREMOVED
    Definition: type_event.h:82
    #define SCIP_EVENTTYPE_GBDCHANGED
    Definition: type_event.h:122
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_UBTIGHTENED
    Definition: type_event.h:79
    #define SCIP_EVENTTYPE_NODEFOCUSED
    Definition: type_event.h:93
    #define SCIP_EVENTTYPE_NODEINFEASIBLE
    Definition: type_event.h:95
    #define SCIP_EVENTTYPE_OBJCHANGED
    Definition: type_event.h:74
    #define SCIP_EVENTTYPE_VARFIXED
    Definition: type_event.h:72
    #define SCIP_EVENTTYPE_VARDELETED
    Definition: type_event.h:71
    struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
    Definition: type_event.h:160
    #define SCIP_EVENTTYPE_NODEEVENT
    Definition: type_event.h:140
    #define SCIP_EVENTTYPE_LHOLEREMOVED
    Definition: type_event.h:84
    #define SCIP_EVENTTYPE_NODEBRANCHED
    Definition: type_event.h:96
    #define SCIP_DECL_EVENTCOPY(x)
    Definition: type_event.h:189
    #define SCIP_EVENTTYPE_LBRELAXED
    Definition: type_event.h:78
    #define SCIP_EVENTTYPE_DUALBOUNDIMPROVED
    Definition: type_event.h:98
    #define SCIP_EVENTTYPE_BESTSOLFOUND
    Definition: type_event.h:106
    #define SCIP_EVENTTYPE_FORMAT
    Definition: type_event.h:157
    #define SCIP_EVENTTYPE_GLBCHANGED
    Definition: type_event.h:75
    #define SCIP_EVENTTYPE_HOLECHANGED
    Definition: type_event.h:130
    #define SCIP_EVENTTYPE_ROWDELETEDSEPA
    Definition: type_event.h:110
    #define SCIP_EVENTTYPE_VARADDED
    Definition: type_event.h:70
    #define SCIP_EVENTTYPE_LBCHANGED
    Definition: type_event.h:123
    #define SCIP_EVENTTYPE_ROWDELETEDLP
    Definition: type_event.h:112
    #define SCIP_EVENTTYPE_UBCHANGED
    Definition: type_event.h:124
    #define SCIP_EVENTTYPE_LHOLEADDED
    Definition: type_event.h:83
    uint64_t SCIP_EVENTTYPE
    Definition: type_event.h:156
    #define SCIP_EVENTTYPE_LPSOLVED
    Definition: type_event.h:102
    #define SCIP_EVENTTYPE_IMPLADDED
    Definition: type_event.h:85
    #define SCIP_EVENTTYPE_ROWCOEFCHANGED
    Definition: type_event.h:113
    #define SCIP_EVENTTYPE_IMPLTYPECHANGED
    Definition: type_event.h:87
    #define SCIP_EVENTTYPE_ROWADDEDSEPA
    Definition: type_event.h:109
    #define SCIP_EVENTTYPE_LPEVENT
    Definition: type_event.h:143
    #define SCIP_EVENTTYPE_NODEDELETE
    Definition: type_event.h:97
    #define SCIP_EVENTTYPE_DISABLED
    Definition: type_event.h:67
    #define SCIP_EVENTTYPE_SOLEVENT
    Definition: type_event.h:147
    #define SCIP_EVENTTYPE_ROWCONSTCHANGED
    Definition: type_event.h:114
    #define SCIP_EVENTTYPE_LBTIGHTENED
    Definition: type_event.h:77
    #define SCIP_EVENTTYPE_UBRELAXED
    Definition: type_event.h:80
    @ SCIP_SIDETYPE_LEFT
    Definition: type_lp.h:65
    enum SCIP_SideType SCIP_SIDETYPE
    Definition: type_lp.h:68
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    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
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73
    internal methods for problem variables