Scippy

    SCIP

    Solving Constraint Integer Programs

    certificate.cpp
    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 certificate.cpp
    26 * @ingroup OTHER_CFILES
    27 * @brief methods for certificate output
    28 * @author Ambros Gleixner
    29 * @author Daniel Steffy
    30 * @author Leon Eifler
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34#include <stdio.h>
    35#include <assert.h>
    36#include <string.h>
    37#include <map>
    38
    39#include "lpiexact/lpiexact.h"
    40#include "scip/def.h"
    42#include "scip/lp.h"
    43#include "scip/lpexact.h"
    44#include "scip/misc.h"
    45#include "scip/pub_cons.h"
    46#include "scip/pub_lpexact.h"
    47#include "scip/pub_misc.h"
    48#include "scip/pub_message.h"
    49#include "scip/pub_tree.h"
    50#include "scip/pub_var.h"
    51#include "scip/prob.h"
    52#include "scip/cuts.h"
    55#include "scip/scip_exact.h"
    56#include "scip/scip_general.h"
    57#include "scip/scip_lp.h"
    58#include "scip/scip_mem.h"
    59#include "scip/scip_message.h"
    60#include "scip/scip_numerics.h"
    61#include "scip/scip_prob.h"
    62#include "scip/scip_probing.h"
    63#include "scip/scip_sol.h"
    64#include "scip/scip_solve.h"
    66#include "scip/scip_tree.h"
    67#include "scip/set.h"
    68#include "scip/sol.h"
    70#include "scip/struct_lpexact.h"
    71#include "scip/struct_scip.h"
    72#include "scip/struct_stat.h"
    73#include "scip/struct_var.h"
    74#include "scip/var.h"
    75#include "scip/certificate.h"
    76
    77#define SCIP_HASHSIZE_CERTIFICATE 500 /**< size of hash map for certificate -> nodesdata mapping used for certificate output */
    78#define SCIP_MB_TO_CHAR_RATE 1048576.0 /**< conversion rate from MB to characters */
    79
    80/** updates file size and returns whether maximum file size has been reached */
    81static
    83 SCIP_CERTIFICATE* certificate, /**< certificate information */
    84 SCIP_Real nchars /**< number of characters printed */
    85 )
    86{
    87 if( certificate->filesize < certificate->maxfilesize )
    88 certificate->filesize += nchars/(SCIP_MB_TO_CHAR_RATE);
    89 if( certificate->filesize < certificate->maxfilesize )
    90 return TRUE;
    91 return FALSE;
    92}
    93
    94/** checks whether node is a left node or not */
    95static
    97 SCIP_CERTIFICATE* certificate, /**< certificate information */
    98 SCIP_NODE* node /**< node from branch and bound tree */
    99 )
    100{
    102 SCIP_CERTNODEDATA* nodedataparent;
    103
    104 assert(certificate != NULL);
    105 assert(SCIPcertificateIsEnabled(certificate));
    106
    107 assert(node != NULL);
    109
    110 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    112
    113 if( SCIPnodeGetParent(node) == NULL )
    114 return FALSE;
    115
    116 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    117 nodedataparent = (SCIP_CERTNODEDATA*)SCIPhashmapGetImage(certificate->nodedatahash, SCIPnodeGetParent(node));
    118
    119 assert(nodedata->assumptionindex_self != -1);
    120 if( nodedataparent->assumptionindex_left == nodedata->assumptionindex_self )
    121 return TRUE;
    122 else
    123 return FALSE;
    124}
    125
    126/** prints variable bound assumption into certificate
    127 *
    128 * @return index of this bound in the certificate file
    129 */
    130static
    132 SCIP_CERTIFICATE* certificate, /**< certificate information */
    133 SCIP_VAR* var, /**< variable to print assumption for */
    134 SCIP_RATIONAL* boundval, /**< value of the bound */
    135 SCIP_BOUNDTYPE boundtype /**< is it the upper bound? */
    136 )
    137{
    138 assert(certificate != NULL);
    139 assert(SCIPcertificateIsEnabled(certificate));
    140
    141#ifndef NDEBUG
    142 certificate->lastinfo->isbound = TRUE;
    143 certificate->lastinfo->boundtype = boundtype;
    144 certificate->lastinfo->varindex = SCIPvarGetCertificateIndex(var);
    145 certificate->lastinfo->isglobal = FALSE;
    146 certificate->lastinfo->certificateindex = certificate->indexcounter;
    147 SCIPrationalSetRational(certificate->lastinfo->boundval, boundval);
    148#endif
    149
    150 /** @todo it could be better to separate the printing from insertion of variable bound */
    151 SCIPcertificatePrintProofMessage(certificate, "A%lld %c ", certificate->indexcounter, (boundtype == SCIP_BOUNDTYPE_LOWER) ? 'G' : 'L');
    152
    153 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, boundval) );
    154 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1 { asm } -1\n", SCIPvarGetCertificateIndex(var));
    155 certificate->indexcounter++;
    156
    157 return certificate->indexcounter - 1;
    158}
    159
    160/** free nodedata of corresponding node */
    161static
    163 SCIP_CERTIFICATE* certificate, /**< certificate information */
    164 SCIP_NODE* node /**< focus node */
    165 )
    166{
    168
    169 assert(node != NULL);
    170 assert(certificate != NULL);
    171 assert(SCIPcertificateIsEnabled(certificate));
    172
    173 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    175 SCIPrationalFreeBlock(certificate->blkmem, &nodedata->derbound_left);
    176 SCIPrationalFreeBlock(certificate->blkmem, &nodedata->derbound_right);
    177 SCIPrationalFreeBlock(certificate->blkmem, &nodedata->derbound_self);
    178 BMSfreeBlockMemory(certificate->blkmem, &nodedata);
    179 SCIP_CALL( SCIPhashmapRemove(certificate->nodedatahash, node) );
    180
    181 return SCIP_OKAY;
    182}
    183
    184/** prints dual bound to proof section and increments indexcounter */
    185static
    187 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    188 const char* linename, /**< name of the unsplitting line */
    189 SCIP_RATIONAL* lowerbound, /**< pointer to lower bound on the objective, NULL indicating infeasibility */
    190 int len, /**< number of dual multipiers */
    191 SCIP_Longint* ind, /**< index array */
    192 SCIP_RATIONAL** val /**< array of dual multipliers */
    193 )
    194{
    195 /* check whether certificate output should be created */
    196 if( !SCIPcertificateIsEnabled(certificate) )
    197 return SCIP_OKAY;
    198
    199 certificate->indexcounter++;
    200 certificate->lastinfo->isbound = FALSE;
    201
    202 if( linename == NULL )
    203 {
    204 SCIPcertificatePrintProofMessage(certificate, "DualBound_%d ", certificate->indexcounter - 1);
    205 }
    206 else
    207 {
    208 SCIPcertificatePrintProofMessage(certificate, "%s ", linename);
    209 }
    210
    211 if( SCIPrationalIsInfinity(lowerbound) )
    212 {
    213 SCIPcertificatePrintProofMessage(certificate, "G 1 0");
    214 }
    215 else
    216 {
    217 SCIPcertificatePrintProofMessage(certificate, "G ");
    218 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, lowerbound) );
    219 SCIPcertificatePrintProofMessage(certificate, " ");
    220 SCIPcertificatePrintProofMessage(certificate, "OBJ");
    221 }
    222
    223 if( val == NULL )
    224 {
    225 SCIPcertificatePrintProofMessage(certificate, " { lin ... } -1\n");
    226 }
    227 else
    228 {
    229 int i;
    230
    231 SCIPcertificatePrintProofMessage(certificate, " { lin %d", len);
    232
    233 for( i = 0; i < len; i++ )
    234 {
    235 /** @todo perform line breaking before exceeding maximum line length */
    236 assert(!SCIPrationalIsAbsInfinity(val[i]));
    237 SCIPcertificatePrintProofMessage(certificate, " %d ", ind[i]);
    238 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val[i]) );
    239 }
    240 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
    241 }
    242
    243 /* print rounding derivation */
    244 if( !SCIPrationalIsNegInfinity(lowerbound) && certificate->objintegral && !SCIPrationalIsIntegral(lowerbound) )
    245 {
    246 certificate->indexcounter++;
    247 certificate->lastinfo->isbound = FALSE;
    248
    249 SCIPcertificatePrintProofMessage(certificate, "R%d G ", certificate->indexcounter - 1);
    250 SCIPrationalRoundInteger(lowerbound, lowerbound, SCIP_R_ROUND_UPWARDS);
    251
    252 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, lowerbound) );
    253
    254 SCIPcertificatePrintProofMessage(certificate, " ");
    255 SCIPcertificatePrintProofMessage(certificate, "OBJ");
    256 SCIPcertificatePrintProofMessage(certificate, " { rnd 1 %d 1 } -1\n", certificate->indexcounter - 2);
    257 }
    258
    259 return SCIP_OKAY;
    260}
    261
    262/** prints the best solution found */
    263static
    265 SCIP* scip, /**< SCIP data structure */
    266 SCIP_Bool isorigfile, /**< should the original solution be printed or in transformed space */
    267 SCIP_CERTIFICATE* certificate, /**< certificate information */
    268 SCIP_SOL* sol /**< solution to be printed */
    269 )
    270{
    271 SCIP_VAR** vars;
    272 SCIP_RATIONAL** vals;
    273 int nvars;
    274 int nnonz;
    275 int i;
    276
    277 /* check if certificate output should be created */
    278 if( certificate->origfile == NULL )
    279 return SCIP_OKAY;
    280
    281 assert(scip != NULL);
    282
    283 if( sol == NULL )
    284 {
    285 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "SOL 0\n");
    286 return SCIP_OKAY;
    287 }
    288 else if( !SCIPsolIsExact(sol) )
    289 {
    291 }
    292
    293 /* get variables and number of the transformed problem */
    294 if( isorigfile )
    295 {
    296 SCIP_CALL( SCIPgetOrigVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    297 }
    298 else
    299 {
    300 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    301 }
    302
    304
    305 /* get number of non-zero coefficient in the solution */
    306 nnonz = 0;
    307 for( i = 0; i < nvars; i++)
    308 {
    309 SCIPsolGetValExact(vals[i], sol, scip->set, scip->stat, vars[i]);
    310 if( !SCIPrationalIsZero(vals[i]) )
    311 nnonz++;
    312 }
    313
    314 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "SOL 1\nbest %d", nnonz);
    315
    316 for( i = 0; i < nvars; i++ )
    317 {
    318 if( !SCIPrationalIsZero(vals[i]) )
    319 {
    320 /* print the solution into certificate */
    321 SCIPcertificatePrintProblemMessage(certificate, isorigfile, " %d ", SCIPvarGetCertificateIndex(vars[i]));
    322 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, vals[i]) );
    323 }
    324 }
    325 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "\n");
    326
    328
    329 return SCIP_OKAY;
    330}
    331
    332/** updates the current derived bound of the node with newbound, if newbound is better */
    334 SCIP_CERTIFICATE* certificate, /**< certificate information */
    335 SCIP_NODE* node, /**< node data structure */
    336 SCIP_Longint fileindex, /**< index of new bound's proof */
    337 SCIP_RATIONAL* newbound /**< value of new bound */
    338 )
    339{
    341
    342 if( !SCIPcertificateIsEnabled(certificate) )
    343 return SCIP_OKAY;
    344
    345 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    347
    348 /* do nothing if newbound is not better than the current bound */
    349 if( SCIPrationalIsLT(newbound, nodedata->derbound_self) )
    350 return SCIP_OKAY;
    351
    352 nodedata->inheritedbound = FALSE;
    353 nodedata->derindex_self = fileindex;
    354 SCIPrationalSetRational(nodedata->derbound_self, newbound);
    355
    356 return SCIP_OKAY;
    357}
    358
    359/** creates certificate data structure */
    361 SCIP_CERTIFICATE** certificate, /**< pointer to store the certificate information */
    362 SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
    363 )
    364{
    365 SCIP_ALLOC( BMSallocMemory(certificate) );
    366
    367 (*certificate)->messagehdlr = messagehdlr;
    368 (*certificate)->lastinfo = NULL;
    369 (*certificate)->blkmem = NULL;
    370 (*certificate)->indexcounter = 0;
    371 (*certificate)->indexcounter_ori = 0;
    372 (*certificate)->conscounter = 0;
    373 (*certificate)->origfile = NULL;
    374 (*certificate)->transfile = NULL;
    375 (*certificate)->origfilename = NULL;
    376 (*certificate)->derivationfile = NULL;
    377 (*certificate)->derivationfilename = NULL;
    378 (*certificate)->filesize = 0.0;
    379 (*certificate)->maxfilesize = SCIP_REAL_MAX;
    380 (*certificate)->rowdatahash = NULL;
    381 (*certificate)->naggrinfos = 0;
    382 (*certificate)->nmirinfos = 0;
    383 (*certificate)->aggrinfosize = 0;
    384 (*certificate)->mirinfosize = 0;
    385 (*certificate)->nodedatahash = NULL;
    386 (*certificate)->rootbound = NULL;
    387 (*certificate)->finalbound = NULL;
    388 (*certificate)->derindex_root = -1;
    389 (*certificate)->rootinfeas = FALSE;
    390 (*certificate)->objintegral = FALSE;
    391 (*certificate)->workingmirinfo = FALSE;
    392 (*certificate)->workingaggrinfo = FALSE;
    393 (*certificate)->vals = NULL;
    394 (*certificate)->valssize = 0;
    395 (*certificate)->aggrinfo = NULL;
    396 (*certificate)->mirinfo = NULL;
    397 (*certificate)->transfile_initialized = FALSE;
    398
    399 return SCIP_OKAY;
    400}
    401
    402/** frees certificate data structure */
    404 SCIP_CERTIFICATE** certificate /**< pointer to store the certificate information */
    405 )
    406{
    407 assert(certificate != NULL);
    408 assert(*certificate != NULL);
    409 assert((*certificate)->origfile == NULL);
    410 assert((*certificate)->transfile == NULL);
    411 assert((*certificate)->derivationfile == NULL);
    412
    413 BMSfreeMemory(certificate);
    414}
    415
    416/* @todo replace scip pointer by set->scip */
    417/** initializes certificate information and creates files for certificate output */
    419 SCIP* scip, /**< scip data structure */
    420 SCIP_CERTIFICATE* certificate, /**< certificate information */
    421 BMS_BLKMEM* blkmem, /**< block memory */
    422 SCIP_SET* set, /**< global SCIP settings */
    423 SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
    424 )
    425{
    426 int filenamelen;
    427 int bufferlen;
    428 int nvars;
    429 int nintvars;
    430 int nbinvars;
    431 int nboundconss;
    432 int ncertcons;
    433 int ntransvars;
    434 int j;
    435 char* name = NULL;
    436 SCIP_VAR** vars;
    437 SCIP_VAR** transvars;
    438 SCIP_CONS** conss;
    439 SCIP_RATIONAL* lb;
    440 SCIP_RATIONAL* ub;
    441
    442 assert(certificate != NULL);
    443 assert(set != NULL);
    444 assert(set->certificate_filename != NULL);
    445 assert(certificate->derivationfile == NULL);
    446 assert(certificate->nodedatahash == NULL);
    447 assert(certificate->rowdatahash == NULL);
    448
    449 if( !(set->exact_enable) || (set->certificate_filename[0] == '-' && set->certificate_filename[1] == '\0') )
    450 return SCIP_OKAY;
    451
    452 filenamelen = (int) strlen(set->certificate_filename);
    453 SCIP_CALL( SCIPsetAllocBufferArray(set, &name, filenamelen + 1) );
    454 BMScopyMemoryArray(name, set->certificate_filename, filenamelen);
    455 name[filenamelen] = '\0';
    456
    457 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
    458 "storing certificate information in file <%s>\n", set->certificate_filename);
    459
    460 certificate->transfile = SCIPfopen(set->certificate_filename, "wT");
    461 certificate->maxfilesize = set->certificate_maxfilesize;
    462
    463 bufferlen = (int) strlen(name); /*lint !e668*/
    464 SCIP_ALLOC( BMSallocMemoryArray(&certificate->derivationfilename, filenamelen+5) );
    465 SCIP_ALLOC( BMSallocMemoryArray(&certificate->origfilename, filenamelen+5) );
    466 BMScopyMemoryArray(certificate->derivationfilename, name, bufferlen);
    467 BMScopyMemoryArray(certificate->origfilename, name, bufferlen);
    468 certificate->derivationfilename[bufferlen] = '_';
    469 certificate->derivationfilename[bufferlen+1] = 'd';
    470 certificate->derivationfilename[bufferlen+2] = 'e';
    471 certificate->derivationfilename[bufferlen+3] = 'r';
    472 certificate->origfilename[bufferlen] = '_';
    473 certificate->origfilename[bufferlen+1] = 'o';
    474 certificate->origfilename[bufferlen+2] = 'r';
    475 certificate->origfilename[bufferlen+3] = 'i';
    476 certificate->derivationfilename[bufferlen+4] = '\0';
    477 certificate->origfilename[bufferlen+4] = '\0';
    478 certificate->derivationfile = SCIPfopen(certificate->derivationfilename, "wT");
    479 certificate->origfile = SCIPfopen(certificate->origfilename, "wT");
    480
    481 if( certificate->transfile == NULL || certificate->origfile == NULL || certificate->derivationfile == NULL )
    482 {
    483 SCIPerrorMessage("error creating file <%s> and auxiliary certificate files\n", set->certificate_filename);
    484 SCIPprintSysError(set->certificate_filename);
    486 }
    487
    488 /* initialisation of hashmaps and hashtables */
    497
    498 certificate->blkmem = blkmem;
    500
    501 SCIP_CALL( SCIPgetOrigVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
    502 SCIP_CALL( SCIPgetVarsData(scip, &transvars, &ntransvars, NULL, NULL, NULL, NULL) );
    503 nboundconss = 0;
    504 for( j = 0 ; j < nvars ; j++ )
    505 {
    506 lb = SCIPvarGetLbGlobalExact(vars[j]);
    507 ub = SCIPvarGetUbGlobalExact(vars[j]);
    509 nboundconss++;
    511 nboundconss++;
    512 }
    513
    514 /* print the Version Header into certificate */
    516
    517 /* print the Variable Header into certificate */
    518 SCIPcertificatePrintVarHeader(certificate, TRUE, nvars);
    519 for( j = 0; j < nvars; j++ )
    520 {
    521 const char* varname;
    522
    523 varname = SCIPvarGetName(vars[j]);
    524 SCIPvarSetCertificateIndex(vars[j], j);
    525 if( strstr(varname, " ") != NULL || strstr(varname, "\t") != NULL || strstr(varname, "\n") != NULL
    526 || strstr(varname, "\v") != NULL || strstr(varname, "\f") != NULL || strstr(varname, "\r") != NULL )
    527 {
    528 SCIPerrorMessage("Variable name <%s> cannot be printed to certificate file because it contains whitespace.\n",
    529 varname);
    530 return SCIP_ERROR;
    531 }
    532
    533 SCIPcertificatePrintProblemMessage(certificate, TRUE, "%s\n", varname);
    534 }
    535
    536 /* print the Integer Variable Header into certificate */
    537 SCIPcertificatePrintIntHeader(certificate, TRUE, nintvars + nbinvars);
    538 for( j = 0; j < nvars; j++ )
    539 {
    541 {
    543 }
    544 }
    545
    546 {
    547 SCIP_RATIONAL** objcoefs;
    549
    550 for( j = 0; j < nvars; j++)
    551 SCIPrationalSetRational(objcoefs[j], SCIPvarGetObjExact(vars[j]));
    552
    553 /* print the objective function into certificate header */
    554 SCIP_CALL( SCIPcertificateSetAndPrintObjective(certificate, TRUE, blkmem, objcoefs, nvars) );
    555
    556 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &objcoefs, nvars);
    557 }
    558
    559 conss = SCIPgetOrigConss(scip);
    560 ncertcons = 0;
    561 for( j = 0; j < SCIPgetNOrigConss(scip); j++ )
    562 {
    563 SCIP_CONS* cons;
    564 SCIP_CONSHDLR* conshdlr;
    565
    566 cons = conss[j];
    567 conshdlr = SCIPconsGetHdlr(cons);
    568
    569 if( strcmp(SCIPconshdlrGetName(conshdlr), "exactlinear") == 0 )
    570 {
    571 lb = SCIPgetLhsExactLinear(scip, cons);
    572 ub = SCIPgetRhsExactLinear(scip, cons);
    573
    575 ncertcons += 2;
    576 else
    577 ncertcons += 1;
    578 }
    579 else
    580 {
    581 SCIPerrorMessage("Cannot print certificate for non-exact constraints \n");
    582 SCIPABORT();
    583 return SCIP_ERROR;
    584 }
    585 }
    586
    587 SCIPcertificatePrintConsHeader(certificate, TRUE, ncertcons, nboundconss);
    588
    589 for( j = 0; j < SCIPgetNOrigConss(scip); j++ )
    590 {
    591 SCIP_CONS* cons;
    592 cons = conss[j];
    594 }
    595
    596 for( j = 0; j < nvars; j++ )
    597 {
    599 {
    601 }
    603 {
    604 SCIP_CALL( SCIPcertificatePrintBoundCons(certificate, TRUE, NULL, vars[j], SCIPvarGetUbGlobalExact(vars[j]), TRUE) );
    605 }
    606 }
    607
    608 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &certificate->rootbound) );
    609 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &certificate->finalbound) );
    610 certificate->valssize = SCIPgetNVars(scip) + SCIPgetNConss(scip);
    611 SCIP_CALL( SCIPrationalCreateBlockArray(SCIPblkmem(scip), &(certificate->vals), certificate->valssize) );
    612
    613 return SCIP_OKAY;
    614}
    615
    616/** initializes certificate information and creates files for certificate output */
    618 SCIP* scip /**< scip data structure */
    619 )
    620{
    621 int nvars;
    622 int nintvars;
    623 int nbinvars;
    624 int nboundconss;
    625 int ncertcons;
    626 int j;
    627 SCIP_VAR** vars;
    628 SCIP_CONS** conss;
    629 SCIP_RATIONAL* lb;
    630 SCIP_RATIONAL* ub;
    631 SCIP_CERTIFICATE* certificate;
    632 BMS_BLKMEM* blkmem;
    633 SCIP_Bool cutoff;
    634
    635 assert(scip != NULL);
    636 assert(scip->set->certificate_filename != NULL);
    637
    638 certificate = SCIPgetCertificate(scip);
    639 blkmem = SCIPblkmem(scip);
    640 cutoff = FALSE;
    641
    642 assert(certificate != NULL);
    643
    644 if( certificate->transfile_initialized )
    645 return SCIP_OKAY;
    646
    647 /* the transfile is constructed using the (exact) LP, so make sure this is constructed here */
    649 {
    650 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
    651 }
    652
    653 if( certificate->transfile == NULL || certificate->origfile == NULL || certificate->derivationfile == NULL )
    654 {
    655 SCIPerrorMessage("error creating file <%s> and auxiliary certificate files\n", scip->set->certificate_filename);
    656 SCIPprintSysError(scip->set->certificate_filename);
    658 }
    659
    660 certificate->transfile_initialized = TRUE;
    661 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
    662 nboundconss = 0;
    663 for( j = 0 ; j < nvars ; j++ )
    664 {
    665 lb = SCIPvarGetLbGlobalExact(vars[j]);
    666 ub = SCIPvarGetUbGlobalExact(vars[j]);
    668 nboundconss++;
    670 nboundconss++;
    671 }
    672
    673 /* print the Version Header into certificate */
    675
    676 /* print the Variable Header into certificate */
    677 SCIPcertificatePrintVarHeader(certificate, FALSE, nvars);
    678 for( j = 0; j < nvars; j++ )
    679 {
    680 const char* varname;
    681
    682 varname = SCIPvarGetName(vars[j]);
    683 SCIPvarSetCertificateIndex(vars[j], j);
    684 if( strstr(varname, " ") != NULL || strstr(varname, "\t") != NULL || strstr(varname, "\n") != NULL
    685 || strstr(varname, "\v") != NULL || strstr(varname, "\f") != NULL || strstr(varname, "\r") != NULL )
    686 {
    687 SCIPerrorMessage("Variable name <%s> cannot be printed to certificate file because it contains whitespace.\n",
    688 varname);
    689 return SCIP_ERROR;
    690 }
    691
    692 SCIPcertificatePrintProblemMessage(certificate, FALSE, "%s\n", varname);
    693 }
    694
    695 /* print the Integer Variable Header into certificate */
    696 SCIPcertificatePrintIntHeader(certificate, FALSE, nintvars + nbinvars);
    697 for( j = 0; j < nvars; j++ )
    698 {
    700 {
    702 }
    703 }
    704
    705 {
    706 SCIP_RATIONAL** objcoefs;
    708
    709 for( j = 0; j < nvars; j++)
    710 SCIPrationalSetRational(objcoefs[j], SCIPvarGetObjExact(vars[j]));
    711
    712 /* print the objective function into certificate header */
    713 SCIP_CALL( SCIPcertificateSetAndPrintObjective(certificate, FALSE, blkmem, objcoefs, nvars) );
    714
    715 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &objcoefs, nvars);
    716 }
    717
    718 conss = SCIPgetConss(scip);
    719 ncertcons = 0;
    720 for( j = 0; j < SCIPgetNConss(scip); j++ )
    721 {
    722 SCIP_CONS* cons;
    723 SCIP_CONSHDLR* conshdlr;
    724
    725 cons = conss[j];
    726 conshdlr = SCIPconsGetHdlr(cons);
    727
    728 SCIPdebug(SCIPprintCons(scip, conss[j], NULL));
    729
    730 if( strcmp(SCIPconshdlrGetName(conshdlr), "exactlinear") == 0 )
    731 {
    732 lb = SCIPgetLhsExactLinear(scip, cons);
    733 ub = SCIPgetRhsExactLinear(scip, cons);
    734
    736 {
    737 SCIPdebugMessage("constraint is a ranged constraint \n");
    738 ncertcons += 2;
    739 }
    740 else
    741 {
    742 SCIPdebugMessage("constraint only has one side \n");
    743 ncertcons += 1;
    744 }
    745 }
    746 else
    747 {
    748 SCIPerrorMessage("Cannot print certificate for non-exact constraints \n");
    749 SCIPABORT();
    750 return SCIP_ERROR;
    751 }
    752 }
    753
    754 SCIPcertificatePrintConsHeader(certificate, FALSE, ncertcons, nboundconss);
    755
    756 for( j = 0; j < SCIPgetNConss(scip); j++ )
    757 {
    758 SCIP_CONS* cons;
    759 cons = conss[j];
    761 }
    762
    763 for( j = 0; j < nvars; j++ )
    764 {
    766 {
    768 SCIPvarSetLbCertificateIndexGlobal(vars[j], certificate->indexcounter - 1);
    769 }
    771 {
    773 SCIPvarSetUbCertificateIndexGlobal(vars[j], certificate->indexcounter - 1);
    774 }
    775 }
    776
    777 return SCIP_OKAY;
    778}
    779
    780/** concatenates the certificate and the _der file and deletes the _der file */
    781static
    783 SCIP_CERTIFICATE* certificate /**< the certificate pointer */
    784 )
    785{
    786 SCIP_FILE* derivationfile;
    787 char buffer[SCIP_MAXSTRLEN];
    788 size_t size;
    789
    790 derivationfile = SCIPfopen(certificate->derivationfilename, "r");
    791
    792 /* append the derivation file to the problem file */
    793 while( 0 != (size = SCIPfread(buffer, sizeof(char), SCIP_MAXSTRLEN, derivationfile)) )
    794 (void) SCIPfwrite(buffer, sizeof(char), size, certificate->transfile);
    795
    796 SCIPfclose(derivationfile);
    797
    798 /* delete the derivation file */
    799 (void) remove(certificate->derivationfilename);
    800}
    801
    802/** closes the certificate output files */
    804 SCIP* scip /**< scip data structure */
    805 )
    806{
    807 assert(scip != NULL);
    808
    811 SCIP_SET* set = scip->set;
    812
    813 if( !SCIPcertificateIsEnabled(certificate) )
    814 return SCIP_OKAY;
    815
    816 assert(certificate != NULL);
    817
    818 if( certificate->origfile != NULL )
    819 {
    820 SCIP_Bool printingaborted = checkAndUpdateFilesize(certificate, 0) ? FALSE : TRUE;
    821
    822 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
    823 "closing certificate file (wrote approx. %.1f MB%s)\n", certificate->filesize,
    824 printingaborted ? ", aborted printing after reaching max. file size" : "");
    825
    826 if( printingaborted )
    827 {
    828 (void) SCIPfprintf(certificate->origfile, "\n# ... aborted printing: max. file size reached.\n");
    829 (void) SCIPfprintf(certificate->transfile, "\n# ... aborted printing: max. file size reached.\n");
    830 (void) SCIPfprintf(certificate->derivationfile, "\n# ... aborted printing: max. file size reached.\n");
    831 }
    832
    833 if( certificate->derivationfile != NULL )
    834 {
    835 SCIPfclose(certificate->derivationfile);
    836 certificate->derivationfile = NULL;
    837 concatenateCertificate(certificate);
    838 /* if the file is empty (e.g. because we detected infeasibility in presolving) we delete it */
    839 if( certificate->indexcounter == 0 )
    840 {
    841 SCIPdebugMessage("derivation file is empty; deleting it");
    842 (void) remove(set->certificate_filename);
    843 }
    844 }
    845 SCIPfclose(certificate->origfile);
    846 SCIPfclose(certificate->transfile);
    847 certificate->origfile = NULL;
    848 certificate->transfile = NULL;
    849
    851 BMSfreeMemoryArray(&certificate->origfilename);
    852
    853 if( certificate->lastinfo != NULL )
    854 {
    855 SCIPrationalFreeBlock(certificate->blkmem, &certificate->lastinfo->boundval);
    856 BMSfreeBlockMemory(certificate->blkmem, &certificate->lastinfo);
    857 }
    858
    859 if( certificate->rowdatahash)
    860 SCIPhashmapFree(&certificate->rowdatahash);
    861
    862 if( certificate->nodedatahash )
    863 {
    864 assert(SCIPhashmapIsEmpty(certificate->nodedatahash));
    865 SCIPhashmapFree(&certificate->nodedatahash);
    866 }
    867 if( certificate->aggrinfohash )
    868 {
    870 }
    871 if( certificate->mirinfohash )
    872 {
    874 }
    875
    876 SCIPrationalFreeBlock(certificate->blkmem, &certificate->rootbound);
    877 SCIPrationalFreeBlock(certificate->blkmem, &certificate->finalbound);
    878 SCIPrationalFreeBlockArray(certificate->blkmem, &certificate->vals, certificate->valssize);
    879 }
    880
    881 return SCIP_OKAY;
    882}
    883
    884/** returns certificate data structure */
    886 SCIP* scip /**< SCIP data structure */
    887 )
    888{
    889 assert(scip != NULL);
    890 assert(scip->stat != NULL);
    891
    892 return scip->stat->certificate;
    893}
    894
    895/** returns whether the certificate output is activated */
    897 SCIP_CERTIFICATE* certificate /**< certificate information */
    898 )
    899{
    900 if( certificate != NULL && certificate->transfile != NULL && certificate->origfile != NULL && certificate->derivationfile != NULL )
    901 return TRUE;
    902 return FALSE;
    903}
    904
    905/** returns current certificate file size in MB */
    907 SCIP_CERTIFICATE* certificate /**< certificate information */
    908 )
    909{
    910 if( !SCIPcertificateIsEnabled(certificate) )
    911 return 0.0;
    912 else
    913 return certificate->filesize;
    914}
    915
    916/** returns current certificate index (return -1 if certificate not active) */
    918 SCIP_CERTIFICATE* certificate /**< certificate information */
    919 )
    920{
    921 if( !SCIPcertificateIsEnabled(certificate) )
    922 return -1;
    923 else
    924 return certificate->indexcounter;
    925}
    926
    927#ifndef NDEBUG
    928/** checks if information is consistent with printed certificate line */
    930 SCIP_CERTIFICATE* certificate, /**< certificate information */
    931 SCIP_VAR* var, /**< variable that gets changed */
    932 SCIP_BOUNDTYPE boundtype, /**< lb or ub changed? */
    933 SCIP_Real newbound, /**< new bound */
    934 SCIP_Bool needsglobal /**< if the bound needs to be global */
    935 )
    936{
    937 SCIP_Bool consistent;
    938
    939 if( !SCIPcertificateIsEnabled(certificate) )
    940 return TRUE;
    941
    942 assert(certificate != NULL);
    943
    944 consistent = certificate->lastinfo->isbound;
    945 consistent = consistent && certificate->lastinfo->varindex == SCIPvarGetCertificateIndex(var); /*lint !e1785*/
    946 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    947 {
    948 consistent = consistent && certificate->lastinfo->boundtype == SCIP_BOUNDTYPE_LOWER; /*lint !e1785*/
    949 consistent = consistent && SCIPrationalRoundReal(certificate->lastinfo->boundval, SCIP_R_ROUND_DOWNWARDS) >= newbound; /*lint !e1785*/
    950 }
    951 else
    952 {
    953 consistent = consistent && certificate->lastinfo->boundtype == SCIP_BOUNDTYPE_UPPER; /*lint !e1785*/
    954 consistent = consistent && SCIPrationalRoundReal(certificate->lastinfo->boundval, SCIP_R_ROUND_UPWARDS) <= newbound; /*lint !e1785*/
    955 }
    956 consistent = consistent && (!needsglobal || certificate->lastinfo->isglobal); /*lint !e1785*/
    957 consistent = consistent && certificate->lastinfo->certificateindex == certificate->indexcounter - 1; /*lint !e1785*/
    958
    959 return consistent;
    960}
    961#endif
    962
    963/** sets the objective function used when printing dual bounds */
    965 SCIP_CERTIFICATE* certificate, /**< certificate information */
    966 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    967 BMS_BLKMEM* blkmem, /**< block memory */
    968 SCIP_RATIONAL** coefs, /**< objective function coefficients */
    969 int nvars /**< number of variables */
    970 )
    971{
    972 char obj[SCIP_MAXSTRLEN - 2];
    973 int nnonz;
    974 int i;
    975
    976 assert(coefs != NULL);
    977
    978 /* check whether certificate output should be created */
    979 if( !SCIPcertificateIsEnabled(certificate) )
    980 return SCIP_OKAY;
    981
    982 /* create a hash table for the variable bounds (we work on the tranformed problem) */
    983 if( isorigfile )
    984 {
    985 /* create working memory for bound struct */
    986 SCIP_ALLOC( BMSallocBlockMemory(blkmem, &certificate->lastinfo) );
    987 SCIP_CALL( SCIPrationalCreateBlock(blkmem, &certificate->lastinfo->boundval) );
    988 }
    989
    990 nnonz = 0;
    991 for( i = 0; i < nvars; i++ )
    992 {
    993 if( !SCIPrationalIsZero(coefs[i]) )
    994 nnonz++;
    995 }
    996
    997 (void) SCIPsnprintf(obj, SCIP_MAXSTRLEN - 2, "OBJ min\n %d ", nnonz);
    998
    999 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "%s ", obj);
    1000
    1001 for( i = 0; i < nvars; i++ )
    1002 {
    1003 if( !SCIPrationalIsZero(coefs[i]) )
    1004 {
    1005 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "%s%d ", (i > 0 ? " " : ""), i );
    1006 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, coefs[i]) );
    1007 }
    1008 }
    1009
    1010 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "\n");
    1011
    1012 return SCIP_OKAY;
    1013}
    1014
    1015/** prints the last part of the certificate header (RTP range/sol, ...) */
    1017 SCIP* scip, /**< SCIP data structure */
    1018 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1019 SCIP_SET* set, /**< general SCIP settings */
    1020 SCIP_CERTIFICATE* certificate /**< certificate information */
    1021 )
    1022{
    1023 SCIP_RATIONAL* primalbound;
    1024 SCIP_RATIONAL* dualbound;
    1025 SCIP_SOL* bestsol;
    1026
    1027 assert(scip != NULL);
    1028
    1029 /* check whether certificate output should be created */
    1030 if( !SCIPcertificateIsEnabled(certificate) )
    1031 return SCIP_OKAY;
    1032
    1033 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &primalbound) );
    1034 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &dualbound) );
    1035
    1036 /* check status first: OPTIMAL / INFEAS / NOT OPTIMAL */
    1037 if( SCIPisInRestart(scip) )
    1038 return SCIP_ERROR;
    1039
    1041 {
    1042 bestsol = SCIPgetBestSol(scip);
    1043
    1044 if( !SCIPsolIsExact(bestsol) )
    1045 {
    1046 SCIP_CALL( SCIPmakeSolExact(scip, bestsol) );
    1047 }
    1048
    1049 if( isorigfile )
    1050 {
    1052 SCIPgetPrimalboundExact(scip, primalbound);
    1053 }
    1054 else
    1055 {
    1056 SCIPgetUpperboundExact(scip, primalbound);
    1057 }
    1058
    1059 assert(!SCIPrationalIsAbsInfinity(primalbound));
    1060
    1061 /* for the orig file we only print the primal bound, since the derivation happens in the transformed problem */
    1062 if( isorigfile )
    1063 {
    1064 SCIPrationalSetNegInfinity(dualbound);
    1065 /* print RTP range (same when optimal solution found) */
    1066 SCIP_CALL( SCIPcertificatePrintRtpRange(certificate, isorigfile, dualbound, primalbound) );
    1067 }
    1068 else
    1069 {
    1070 SCIP_CALL( SCIPcertificatePrintRtpRange(certificate, isorigfile, primalbound, primalbound) );
    1071 }
    1072
    1073 /* print optimal solution into certificate */
    1074 SCIP_CALL( certificatePrintSol(scip, isorigfile, certificate, bestsol) );
    1075 }
    1077 {
    1078 if( isorigfile )
    1079 {
    1080 SCIPrationalSetNegInfinity(dualbound);
    1081 SCIPrationalSetInfinity(primalbound);
    1082 SCIP_CALL( SCIPcertificatePrintRtpRange(certificate, isorigfile, dualbound, primalbound) );
    1083 }
    1084 else
    1085 {
    1086 SCIPcertificatePrintRtpInfeas(certificate, isorigfile);
    1087 }
    1088
    1089 SCIP_CALL( certificatePrintSol(scip, isorigfile, certificate, NULL) );
    1090 }
    1091 else
    1092 {
    1093 /* two cases to distinguish: a primal bound has been found or not */
    1095 {
    1096 bestsol = SCIPgetBestSol(scip);
    1097 if( isorigfile )
    1098 {
    1100 SCIPgetPrimalboundExact(scip, primalbound);
    1101 }
    1102 else
    1103 {
    1104 SCIPgetUpperboundExact(scip, primalbound);
    1105 }
    1106 }
    1107 else
    1108 {
    1109 bestsol = NULL;
    1110 SCIPrationalSetInfinity(primalbound);
    1111 }
    1112
    1113 if( isorigfile )
    1114 SCIPrationalSetNegInfinity(dualbound);
    1115 else
    1116 SCIPrationalSetRational(dualbound, certificate->finalbound);
    1117
    1118 SCIP_CALL( SCIPcertificatePrintRtpRange(certificate, isorigfile, dualbound, primalbound) );
    1119 SCIP_CALL( certificatePrintSol(scip, isorigfile, certificate, bestsol) );
    1120 }
    1121
    1122 SCIPcertificatePrintDerHeader(certificate, isorigfile);
    1123
    1124 SCIPrationalFreeBuffer(set->buffer, &dualbound);
    1125 SCIPrationalFreeBuffer(set->buffer, &primalbound);
    1126
    1127 return SCIP_OKAY;
    1128}
    1129
    1130/** prints the last part of the certificate header (RTP range/sol, ...) */
    1132 SCIP* scip, /**< SCIP data structure */
    1133 SCIP_CERTIFICATE* certificate /**< certificate information */
    1134 )
    1135{
    1136 assert(scip != NULL);
    1137
    1138 if( !SCIPcertificateIsEnabled(certificate) )
    1139 return SCIP_OKAY;
    1140
    1141 SCIPgetLowerboundExact(scip, certificate->finalbound);
    1142
    1143 return SCIP_OKAY;
    1144}
    1145
    1146/** prints a string to the problem section of the certificate file */
    1148 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1149 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1150 const char* formatstr, /**< format string like in printf() function */
    1151 ... /**< format arguments line in printf() function */
    1152 )
    1153{
    1154 va_list ap;
    1155 char buffer[3 * SCIP_MAXSTRLEN];
    1156
    1157 /* check whether certificate output should be created */
    1158 if( !SCIPcertificateIsEnabled(certificate) )
    1159 return;
    1160
    1161 va_start(ap, formatstr);
    1162 (void) vsnprintf(buffer, 3 * SCIP_MAXSTRLEN, formatstr, ap);
    1163
    1164 if( checkAndUpdateFilesize(certificate, strlen(buffer)) )
    1165 {
    1166 if( isorigfile )
    1167 (void) SCIPfprintf(certificate->origfile, "%s", buffer);
    1168 else
    1169 (void) SCIPfprintf(certificate->transfile, "%s", buffer);
    1170 }
    1171 va_end(ap);
    1172}
    1173
    1174/** prints a string to the proof section of the certificate file */
    1176 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1177 const char* formatstr, /**< format string like in printf() function */
    1178 ... /**< format arguments line in printf() function */
    1179 )
    1180{
    1181 va_list ap;
    1182 char buffer[3 * SCIP_MAXSTRLEN];
    1183
    1184 /* check whether certificate output should be created */
    1185 if( !SCIPcertificateIsEnabled(certificate) )
    1186 return;
    1187
    1188 va_start(ap, formatstr);
    1189 (void) vsnprintf(buffer, 3 * SCIP_MAXSTRLEN, formatstr, ap);
    1190
    1191 if( checkAndUpdateFilesize(certificate, strlen(buffer)) )
    1192 (void) SCIPfprintf(certificate->derivationfile, "%s", buffer);
    1193
    1194 va_end(ap);
    1195}
    1196
    1197
    1198/** prints a rational number to the problem section of the certificate file */
    1200 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1201 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1202 SCIP_RATIONAL* val /**< rational number to print */
    1203 )
    1204{
    1205 int len = SCIPrationalStrLen(val) + 1;
    1206 char* buffer = NULL;
    1207
    1208 /* check whether certificate output should be created */
    1209 if( !SCIPcertificateIsEnabled(certificate) )
    1210 return SCIP_OKAY;
    1211
    1212 SCIP_ALLOC( BMSallocMemoryArray(&buffer, len) );
    1213 (void) SCIPrationalToString(val, buffer, len);
    1214 if( checkAndUpdateFilesize(certificate, strlen(buffer)) )
    1215 {
    1216 if( isorigfile )
    1217 (void) SCIPfputs(buffer, certificate->origfile);
    1218 else
    1219 (void) SCIPfputs(buffer, certificate->transfile);
    1220 }
    1221 BMSfreeMemoryArray(&buffer);
    1222
    1223 return SCIP_OKAY;
    1224}
    1225
    1226
    1227/** prints a rational number to the proof section of the certificate file */
    1229 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1230 SCIP_RATIONAL* val /**< rational number to print */
    1231 )
    1232{
    1233 int len = SCIPrationalStrLen(val) + 1;
    1234 char* buffer = NULL;
    1235
    1236 /* check whether certificate output should be created */
    1237 if( !SCIPcertificateIsEnabled(certificate) )
    1238 return SCIP_OKAY;;
    1239
    1240 SCIP_ALLOC( BMSallocMemoryArray(&buffer, len) );
    1241 (void) SCIPrationalToString(val, buffer, len);
    1242
    1243 if( checkAndUpdateFilesize(certificate, strlen(buffer)) )
    1244 (void) SCIPfputs(buffer, certificate->derivationfile);
    1245
    1246 BMSfreeMemoryArray(&buffer);
    1247
    1248 return SCIP_OKAY;
    1249}
    1250
    1251/** prints a comment to the problem section of the certificate file */
    1253 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1254 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1255 const char* formatstr, /**< format string like in printf() function */
    1256 ... /**< format arguments line in printf() function */
    1257 )
    1258{
    1259 va_list ap;
    1260 char buffer[3 * SCIP_MAXSTRLEN];
    1261
    1262 /* check whether certificate output should be created */
    1263 if( !SCIPcertificateIsEnabled(certificate) )
    1264 return;
    1265
    1266 (void) SCIPfprintf(certificate->origfile, "# ");
    1267
    1268 va_start(ap, formatstr);
    1269 (void) vsnprintf(buffer, 3 * SCIP_MAXSTRLEN, formatstr, ap);
    1270
    1271 if( checkAndUpdateFilesize(certificate, 2 + strlen(buffer)) )
    1272 {
    1273 if( isorigfile )
    1274 (void) SCIPfprintf(certificate->origfile, "%s", buffer);
    1275 else
    1276 (void) SCIPfprintf(certificate->transfile, "%s", buffer);
    1277 }
    1278 va_end(ap);
    1279}
    1280
    1281/** prints a comment to the proof section of the certificate file */
    1283 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1284 const char* formatstr, /**< format string like in printf() function */
    1285 ... /**< format arguments line in printf() function */
    1286 )
    1287{
    1288 va_list ap;
    1289 char buffer[3 * SCIP_MAXSTRLEN];
    1290
    1291 /* check whether certificate output should be created */
    1292 if( !SCIPcertificateIsEnabled(certificate) )
    1293 return;
    1294
    1295 (void) SCIPfprintf(certificate->derivationfile, "# ");
    1296
    1297 va_start(ap, formatstr);
    1298 (void) vsnprintf(buffer, 3 * SCIP_MAXSTRLEN, formatstr, ap);
    1299
    1300 if( checkAndUpdateFilesize(certificate, 2 + strlen(buffer)) )
    1301 (void) SCIPfprintf(certificate->derivationfile, "%s", buffer);
    1302
    1303 va_end(ap);
    1304}
    1305
    1306/** prints version header */
    1308 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1309 SCIP_Bool isorigfile /**< should the line be printed to the origfile or the transfile */
    1310 )
    1311{
    1312 /* check whether certificate output should be created */
    1313 if( !SCIPcertificateIsEnabled(certificate) )
    1314 return;
    1315
    1316 assert(certificate != NULL);
    1317
    1318 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "VER 1.0 \n");
    1319}
    1320
    1321/** prints variable section header */
    1323 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1324 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1325 int nvars /**< number of variables */
    1326 )
    1327{
    1328 assert(nvars >= 0);
    1329
    1330 /* check whether certificate output should be created */
    1331 if( !SCIPcertificateIsEnabled(certificate) )
    1332 return;
    1333
    1334 assert(certificate != NULL);
    1335
    1336 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "VAR %d \n", nvars);
    1337}
    1338
    1339/** prints integer section header */
    1341 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1342 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1343 int nintvars /**< number of integer variables */
    1344 )
    1345{
    1346 assert(nintvars >= 0);
    1347
    1348 /* check whether certificate output should be created */
    1349 if( !SCIPcertificateIsEnabled(certificate) )
    1350 return;
    1351
    1352 assert(certificate != NULL);
    1353
    1354 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "INT %d\n", nintvars);
    1355}
    1356
    1357/** prints constraint section header */
    1359 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1360 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1361 int nconss, /**< number of all constraints */
    1362 int nboundconss /**< number of bound constraints */
    1363 )
    1364{
    1365 assert(nconss >= 0);
    1366
    1367 /* check whether certificate output should be created */
    1368 if( !SCIPcertificateIsEnabled(certificate) )
    1369 return;
    1370
    1371 assert(certificate != NULL);
    1372
    1373 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "CON %d %d\n", nconss + nboundconss, nboundconss);
    1374}
    1375
    1376/** prints derivation section header */
    1378 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1379 SCIP_Bool isorigfile /**< should the line be printed to the origfile or the transfile */
    1380 )
    1381{
    1382 SCIP_Longint nders;
    1383
    1384 /* check whether certificate output should be created */
    1385 if( !SCIPcertificateIsEnabled(certificate) )
    1386 return;
    1387
    1388 assert(certificate != NULL);
    1389
    1390 if( !isorigfile )
    1391 nders = certificate->indexcounter - certificate->conscounter;
    1392 else
    1393 nders = 0;
    1394
    1395 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "DER %d\n", nders);
    1396}
    1397
    1398/** prints constraint */
    1400 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1401 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    1402 const char* consname, /**< name of the constraint */
    1403 const char sense, /**< sense of the constraint, i.e., G, L, or E */
    1404 SCIP_RATIONAL* side, /**< left/right-hand side */
    1405 int len, /**< number of nonzeros */
    1406 int* ind, /**< index array */
    1407 SCIP_RATIONAL** val /**< coefficient array */
    1408 )
    1409{
    1410 SCIP_Longint index;
    1411 int i;
    1412
    1413 /* check whether certificate output should be created */
    1414 if( !SCIPcertificateIsEnabled(certificate) )
    1415 return SCIP_OKAY;
    1416
    1417 index = isorigfile ? certificate->indexcounter_ori : certificate->indexcounter;
    1418
    1419 if( consname == NULL )
    1420 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "C%d %c ", index, sense);
    1421 else
    1422 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "%s %c ", consname, sense);
    1423
    1424 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, side) );
    1425
    1426 SCIPcertificatePrintProblemMessage(certificate, isorigfile, " %d", len);
    1427
    1428 for( i = 0; i < len; i++ )
    1429 {
    1430 /** @todo perform line breaking before exceeding maximum line length */
    1431 SCIPcertificatePrintProblemMessage(certificate, isorigfile, " %d ", ind[i]);
    1432 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, val[i]) );
    1433 }
    1434 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "\n");
    1435
    1436 if( isorigfile )
    1437 certificate->indexcounter_ori++;
    1438 else
    1439 {
    1440 certificate->indexcounter++;
    1441 certificate->lastinfo->isbound = FALSE;
    1442 }
    1443
    1444 if( !isorigfile )
    1445 {
    1446 certificate->conscounter++;
    1447 }
    1448
    1449 return SCIP_OKAY;
    1450}
    1451
    1452/** prints a line for an exact row to the certificate (without derivation)
    1453 *
    1454 * @param alternativerhs is used instead of the real rhs of the row (infinity if real rhs should be used).
    1455 * This is necessary for integer cut where the rhs was rounded down from the original rhs
    1456 */
    1457static
    1459 SCIP_SET* set, /**< global SCIP settings */
    1460 SCIP_CERTIFICATE* certificate, /**< certificate structure */
    1461 SCIP_ROWEXACT* rowexact, /**< exact SCIP row */
    1462 SCIP_Real alternativerhs /**< rhs to be used instead or rowexact->rhs (infinity to disable this) */
    1463 )
    1464{
    1465 SCIP_ROW* row;
    1466 SCIP_RATIONAL* rhs;
    1467 int i;
    1468
    1469 /* check whether certificate output should be created */
    1470 if( !SCIPcertificateIsEnabled(certificate) )
    1471 return SCIP_OKAY;
    1472
    1473 assert(rowexact != NULL);
    1474
    1475 row = SCIProwExactGetRow(rowexact);
    1476 assert(SCIProwGetNNonz(row) == SCIProwExactGetNNonz(rowexact));
    1477
    1478 SCIPcertificatePrintProofMessage(certificate, "L%d_%s %c ", certificate->indexcounter, row->name, 'L');
    1479
    1480 /* if we rounded the rhs in cut tightening we need to first verify the cut without it */
    1481 if( SCIPsetIsInfinity(set, alternativerhs) )
    1482 {
    1483 rhs = SCIProwExactGetRhs(rowexact);
    1484 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, rhs) );
    1485 }
    1486 else
    1487 {
    1488 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &rhs) );
    1489 SCIPrationalSetReal(rhs, alternativerhs);
    1490 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, rhs) );
    1491 SCIPrationalFreeBuffer(set->buffer, &rhs);
    1492 }
    1493
    1494 SCIPcertificatePrintProofMessage(certificate, " %d", SCIProwGetNNonz(row));
    1495
    1496 for( i = 0; i < SCIProwGetNNonz(row); i++ )
    1497 {
    1498 SCIP_RATIONAL* val;
    1499 int varindex;
    1500 /** @todo perform line breaking before exceeding maximum line length */
    1501 assert(rowexact->cols[i]->fpcol->var->index == rowexact->fprow->cols[i]->var->index);
    1502
    1504 val = SCIProwExactGetVals(rowexact)[i];
    1505
    1506 SCIPcertificatePrintProofMessage(certificate, " %d ", varindex);
    1507 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
    1508 }
    1509 certificate->indexcounter++;
    1510 certificate->lastinfo->isbound = FALSE;
    1511
    1512 return SCIP_OKAY;
    1513}
    1514
    1515/** prints mir split for the specified aggrrow */
    1516static
    1518 SCIP_SET* set, /**< SCIP settings */
    1519 SCIP_PROB* prob, /**< SCIP problem data */
    1520 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1521 SCIP_ROW* row /**< row that split should be printed for */
    1522 )
    1523{
    1524 SCIP_MIRINFO* mirinfo;
    1525 SCIP_RATIONAL* val;
    1526 SCIP_VAR** vars;
    1527 int i, j;
    1528 SCIP_Real slackrhs;
    1529 std::map<int, SCIP_Real> coefs;
    1530
    1531 assert(SCIPcertificateIsEnabled(certificate));
    1532 assert(SCIPhashmapExists(certificate->mirinfohash, (void*) row));
    1533
    1534 mirinfo = (SCIP_MIRINFO*) SCIPhashmapGetImage(certificate->mirinfohash, (void*) row);
    1535
    1536 vars = SCIPprobGetVars(prob);
    1537 slackrhs = 0;
    1538
    1539 SCIPrationalDebugMessage("printing split disjunction <= %q \\/ >= %q+1 \n", mirinfo->rhs, mirinfo->rhs);
    1540
    1541 for( i = 0; i < mirinfo->nsplitvars; ++i )
    1542 {
    1543 if( mirinfo->splitcoefficients[i] == 0 )
    1544 continue;
    1545 coefs[SCIPvarGetCertificateIndex(vars[mirinfo->varinds[i]])] += mirinfo->splitcoefficients[i];
    1546 SCIPdebugMessage("+%g%s", mirinfo->splitcoefficients[i], SCIPvarGetName(vars[mirinfo->varinds[i]]));
    1547 }
    1548 for( i = 0; i < mirinfo->nslacks; ++i )
    1549 {
    1550 SCIP_ROW* slackrow = mirinfo->slackrows[i];
    1551 SCIP_Real slackval = mirinfo->slackcoefficients[i];
    1552
    1553 if( slackval == 0 )
    1554 continue;
    1555
    1556 for( j = 0; j < SCIProwGetNNonz(slackrow); ++j)
    1557 {
    1558 SCIP_VAR* var = SCIPcolGetVar(SCIProwGetCols(slackrow)[j]);
    1559 int varidx = SCIPvarGetCertificateIndex(var);
    1560 SCIP_Real rowcoef = SCIProwGetVals(slackrow)[j];
    1561
    1562 assert(SCIPrealIsExactlyIntegral(rowcoef * slackval));
    1563 assert(SCIPvarIsBinary(var) || SCIPvarIsIntegral(var));
    1564 coefs[varidx] += rowcoef * slackval;
    1565 assert(SCIPrealIsExactlyIntegral(coefs[varidx]));
    1566 }
    1567 if( mirinfo->slacksign[i] == 1 )
    1568 {
    1569 assert(SCIPrealIsExactlyIntegral(SCIProwGetRhs(slackrow) - SCIProwGetConstant(slackrow)));
    1570 slackrhs += (SCIProwGetRhs(slackrow) - SCIProwGetConstant(slackrow)) * slackval;
    1571
    1572 assert(SCIPrealIsExactlyIntegral(slackrhs));
    1573 SCIPdebugMessage("+%gsrhs_%s", mirinfo->slackcoefficients[i], SCIProwGetName(mirinfo->slackrows[i]));
    1574 }
    1575 else
    1576 {
    1577 assert(SCIPrealIsExactlyIntegral(SCIProwGetLhs(slackrow) - SCIProwGetConstant(slackrow)));
    1578 slackrhs += (SCIProwGetLhs(slackrow) - SCIProwGetConstant(slackrow)) * slackval;
    1579
    1580 assert(SCIPrealIsExactlyIntegral(slackrhs));
    1581 SCIPdebugMessage("+%gslhs_%s", mirinfo->slackcoefficients[i], SCIProwGetName(mirinfo->slackrows[i]));
    1582 }
    1583 }
    1584
    1585 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &val) );
    1586
    1587 /* transform the split back into original variable space -> undo the bound transformations */
    1588 SCIPcertificatePrintProofMessage(certificate, "A%d_split %c ", certificate->indexcounter, 'L');
    1589
    1590 /* add rhs change from integer slacks and print rhs */
    1591 SCIPrationalAddReal(val, mirinfo->rhs, slackrhs);
    1592 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
    1593
    1594 SCIPcertificatePrintProofMessage(certificate, " %d", coefs.size());
    1595
    1596 for( const auto & coef : coefs )
    1597 {
    1598 /** @todo perform line breaking before exceeding maximum line length */
    1599 int varindex = coef.first;
    1600 SCIPrationalSetReal(val, coef.second);
    1601
    1602 assert(SCIPrationalIsIntegral(val));
    1603
    1604 SCIPcertificatePrintProofMessage(certificate, " %d ", varindex);
    1605 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
    1606 }
    1607
    1608 SCIPcertificatePrintProofMessage(certificate, " { asm } -1 \n");
    1609
    1610 certificate->indexcounter++;
    1611 certificate->lastinfo->isbound = FALSE;
    1612
    1613 SCIPcertificatePrintProofMessage(certificate, "A%d_split %c ", certificate->indexcounter, 'G');
    1614
    1615 SCIPrationalAddReal(val, mirinfo->rhs, slackrhs + 1.0);
    1616 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
    1617
    1618 SCIPcertificatePrintProofMessage(certificate, " %d", coefs.size());
    1619
    1620 for( const auto & coef : coefs )
    1621 {
    1622 /** @todo perform line breaking before exceeding maximum line length */
    1623 int varindex = coef.first;
    1624 SCIPrationalSetReal(val, coef.second);
    1625
    1626 assert(SCIPrationalIsIntegral(val));
    1627
    1628 SCIPcertificatePrintProofMessage(certificate, " %d ", varindex);
    1629 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, val) );
    1630 }
    1631
    1632 SCIPcertificatePrintProofMessage(certificate, " { asm } -1 \n");
    1633
    1634 certificate->indexcounter++;
    1635 certificate->lastinfo->isbound = FALSE;
    1636
    1637 SCIPrationalFreeBuffer(set->buffer, &val);
    1638
    1639 return SCIP_OKAY;
    1640}
    1641
    1642#ifdef SCIP_DISABLED_CODE
    1643/** prints all local bounds that differ from their global bounds as the bounds to take into account */
    1644static
    1645SCIP_RETCODE certificatePrintIncompleteDerStart(
    1646 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    1647 SCIP_ROW** rows, /**< rows to be considered */
    1648 int nrows, /**< number of rows to be considered */
    1649 SCIP_PROB* prob, /**< SCIP problem data */
    1650 SCIP_Bool local /**< TRUE if the cut is only valid locally */
    1651 )
    1652{
    1653 SCIP_VAR** vars;
    1654 int nvars;
    1655 int i;
    1656
    1657 assert(!SCIPcertificateIsEnabled(certificate));
    1658
    1659 vars = SCIPprobGetVars(prob);
    1660 nvars = SCIPprobGetNVars(prob);
    1661
    1662 SCIPcertificatePrintProofMessage(certificate, " { lin incomplete ");
    1663
    1664 /* add non-global bounds */
    1665 for( i = 0; i < nvars; i++ )
    1666 {
    1667 SCIP_VAR* var = vars[i];
    1668 SCIP_Longint index;
    1669
    1671 if( index != -1 )
    1672 {
    1673 assert(index <= certificate->indexcounter);
    1674 SCIPcertificatePrintProofMessage(certificate, " %d ", index);
    1675 }
    1677 if( index != -1 )
    1678 {
    1679 assert(index <= certificate->indexcounter);
    1680 SCIPcertificatePrintProofMessage(certificate, " %d ", index);
    1681 }
    1682 }
    1683
    1684 /* add non-default rows */
    1685 for( i = 0; i < nrows; ++i )
    1686 {
    1687 SCIP_ROWEXACT* rowexact = SCIProwGetRowExact(rows[i]);
    1688 SCIP_Longint key;
    1689
    1690 if( !local && SCIProwIsLocal(rows[i]) )
    1691 continue;
    1692
    1693 if( !SCIPhashmapExists(certificate->rowdatahash, (void*) rowexact) )
    1694 continue;
    1695
    1696 assert(rowexact != NULL);
    1697 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) rowexact));
    1698 key = SCIPhashmapGetImageLong(certificate->rowdatahash, (void*) rowexact);
    1699 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    1700 /* for a ranged row, we need both sides to be safe */
    1701 if( !SCIPrationalIsAbsInfinity(rowexact->lhs) && !SCIPrationalIsAbsInfinity(rowexact->rhs) && !SCIPrationalIsEQ(rowexact->lhs, rowexact->rhs) )
    1702 {
    1703 SCIPcertificatePrintProofMessage(certificate, " %d ", key + 1);
    1704 }
    1705 }
    1706
    1707 return SCIP_OKAY;
    1708}
    1709#endif
    1710
    1711/** prints all local bounds that differ from their global bounds as the bounds to take into account */
    1712static
    1714 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    1715 SCIP_PROB* prob, /**< SCIP problem data */
    1716 SCIP_Bool local /**< TRUE if the cut is only valid locally */
    1717 )
    1718{
    1719 SCIP_VAR** vars;
    1720 int nvars;
    1721 int i;
    1722 int nboundentries;
    1723
    1724 assert(SCIPcertificateIsEnabled(certificate));
    1725
    1726 nboundentries = 0;
    1727
    1728 vars = SCIPprobGetVars(prob);
    1729 nvars = SCIPprobGetNVars(prob);
    1730
    1731 /* count the number of needed entries */
    1732 for( i = 0; i < nvars && local; i++ )
    1733 {
    1734 SCIP_VAR* var = vars[i];
    1736 nboundentries++;
    1738 nboundentries++;
    1739
    1740 assert(!SCIPrationalIsEQ(var->exactdata->glbdom.lb, var->exactdata->locdom.lb) == (var->glbdom.lb != var->locdom.lb));
    1741 assert(!SCIPrationalIsEQ(var->exactdata->glbdom.ub, var->exactdata->locdom.ub) == (var->glbdom.ub != var->locdom.ub));
    1742 }
    1743
    1744 SCIPcertificatePrintProofMessage(certificate, " { lin weak { %d", nboundentries);
    1745
    1746 for( i = 0; i < nvars && nboundentries > 0; i++ )
    1747 {
    1748 SCIP_VAR* var = vars[i];
    1749
    1751 {
    1752 SCIP_Longint index;
    1753 SCIP_RATIONAL* boundval;
    1754
    1756 boundval = SCIPvarGetLbLocalExact(var);
    1757 SCIPcertificatePrintProofMessage(certificate, " L %d %d ", SCIPvarGetCertificateIndex(var), index);
    1758 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, boundval) );
    1759 }
    1761 {
    1762 SCIP_Longint index;
    1763 SCIP_RATIONAL* boundval;
    1764
    1766 boundval = SCIPvarGetUbLocalExact(var);
    1767 SCIPcertificatePrintProofMessage(certificate, " U %d %d ", SCIPvarGetCertificateIndex(var), index);
    1768 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, boundval) );
    1769 }
    1770 }
    1771
    1772 SCIPcertificatePrintProofMessage(certificate, " } ");
    1773
    1774 return SCIP_OKAY;
    1775}
    1776
    1777/** prints verification of row as a MIR cut (viewed as a split cut) */
    1779 SCIP_SET* set, /**< SCIP settings */
    1780 SCIP_LP* lp, /**< SCIP lp data structure */
    1781 SCIP_CERTIFICATE* certificate, /**< certificate information */
    1782 SCIP_PROB* prob, /**< SCIP problem data */
    1783 SCIP_ROW* row, /**< the row to be printed */
    1784 const char sense /**< sense of the constraint, i.e., G, L, or E */
    1785 )
    1786{
    1787 SCIP_ROWEXACT* rowexact;
    1788 SCIP_RATIONAL* tmpval;
    1789 SCIP_RATIONAL* value;
    1790 SCIP_RATIONAL* oneminusf0;
    1791 SCIP_AGGREGATIONINFO* aggrinfo;
    1792 SCIP_Longint leftdisjunctionindex;
    1793 SCIP_Longint rightdisjunctionindex;
    1794 SCIP_MIRINFO* mirinfo;
    1795 int i;
    1796
    1797 /* check whether certificate output should be created */
    1798 if( !SCIPcertificateIsEnabled(certificate) )
    1799 return SCIP_OKAY;
    1800
    1801 assert(row != NULL);
    1802 assert(sense == 'L'); /* for now only this case is needed */
    1803 assert(SCIPhashmapExists(certificate->aggrinfohash, (void*) row));
    1804
    1805 rowexact = SCIProwGetRowExact(row);
    1806
    1807 /* only do something if row does not already exist*/
    1808 if( SCIPhashmapExists(certificate->rowdatahash, (void*) rowexact) )
    1809 return SCIP_OKAY;
    1810
    1811 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmpval) );
    1812 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oneminusf0) );
    1813 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &value) );
    1814
    1815 SCIPdebugMessage("Printing MIR-certifiaction for row ");
    1816 SCIPdebug(SCIProwExactPrint(rowexact, set->scip->messagehdlr, NULL));
    1817
    1818 /* get aggregation info and print aggregation row to certificate */
    1819 aggrinfo = (SCIP_AGGREGATIONINFO*) SCIPhashmapGetImage(certificate->aggrinfohash, (void*) row);
    1820 mirinfo = (SCIP_MIRINFO*) SCIPhashmapGetImage(certificate->mirinfohash, (void*) row);
    1821
    1822 /* compute the correct split from the aggregation row, and print the two assumptions (\xi \le \lfloor \beta \rfloor), and (\xi \ge \lfloor \beta + 1 \rfloor) */
    1823 SCIP_CALL( certificatePrintMirSplit(set, prob, certificate, row) );
    1824
    1825 leftdisjunctionindex = certificate->indexcounter - 2;
    1826 rightdisjunctionindex = certificate->indexcounter - 1;
    1827
    1828 /* if this aggregation depends on another no yet certified MIR cut, we need to print that first */
    1829 for( i = 0; i < aggrinfo->naggrrows; i++ )
    1830 {
    1831 SCIP_ROWEXACT* aggrrow;
    1832 aggrrow = SCIProwGetRowExact(aggrinfo->aggrrows[i]);
    1833 assert(aggrrow != NULL);
    1834 if( !SCIPhashmapExists(certificate->rowdatahash, (void*) aggrrow) )
    1835 {
    1836 SCIP_CALL( SCIPcertificatePrintMirCut(set, lp, certificate, prob, aggrinfo->aggrrows[i], 'L') );
    1837 }
    1838 }
    1839
    1840 /* print possibly missing derivations to the certifiacte */
    1841 for( i = 0; i < aggrinfo->nnegslackrows; i++ )
    1842 {
    1843 SCIP_ROWEXACT* slackrow;
    1844 slackrow = SCIProwGetRowExact(aggrinfo->negslackrows[i]);
    1845
    1846 if( !SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow) )
    1847 {
    1848 SCIP_CALL( SCIPcertificatePrintMirCut(set, lp, certificate, prob, aggrinfo->negslackrows[i], 'L') );
    1849 }
    1850 }
    1851
    1852 /* print possibly missing derivations to the certifiacte */
    1853 for( i = 0; i < mirinfo->nslacks; i++ )
    1854 {
    1855 SCIP_ROWEXACT* slackrow;
    1856 slackrow = SCIProwGetRowExact(mirinfo->slackrows[i]);
    1857
    1858 if( !SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow) )
    1859 {
    1860 SCIP_CALL( SCIPcertificatePrintMirCut(set, lp, certificate, prob, mirinfo->slackrows[i], 'L') );
    1861 }
    1862 }
    1863
    1864 /* print the mir cut with proof 1 * (\xi \le \lfloor \beta \rfloor) - (1/1-f)(\nu \ge 0) */
    1865 /* we dont need the \nu \ge 0 part since it will be taken care of by the vipr completion part */
    1866 assert(rowexact != NULL);
    1867 {
    1868 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, mirinfo->unroundedrhs) );
    1869
    1870 /* calculate 1-f0 */
    1871 SCIPrationalSetReal(oneminusf0, 1.0);
    1872 SCIPrationalDiff(oneminusf0, oneminusf0, mirinfo->frac);
    1873
    1874 SCIP_CALL( certificatePrintWeakDerStart(certificate, prob, SCIProwIsLocal(row)) );
    1875
    1876 /* 1 * (\xi \le \lfloor \beta \rfloor) we also have to add the correct multipliers for the negative slacks that were used here */
    1877 SCIPcertificatePrintProofMessage(certificate, "%d %d ", 1 + aggrinfo->nnegslackrows + mirinfo->nslacks, leftdisjunctionindex);
    1878 /* multiply with scaling parameter that was used during cut computation */
    1879 SCIPrationalSetReal(tmpval, mirinfo->scale);
    1880 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    1881
    1882 SCIPdebugMessage("Verifying left part of split disjunction, multipliers 1 and 1/%g \n", SCIPrationalGetReal(oneminusf0));
    1883
    1884 SCIPdebugMessage("Correcting for negative continous slacks ( needed for v >= 0 part ) \n");
    1885 for( i = 0; i < aggrinfo->nnegslackrows; i++ )
    1886 {
    1887 SCIP_Longint key;
    1888 SCIP_ROWEXACT* slackrow;
    1889 slackrow = SCIProwGetRowExact(aggrinfo->negslackrows[i]);
    1890
    1891 SCIPdebugMessage("adding (weight/(1-f0)) %g times row: ", aggrinfo->substfactor[i]);
    1892 SCIPdebug(SCIProwExactPrint(slackrow, set->scip->messagehdlr, NULL));
    1893 assert(slackrow != NULL);
    1894 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow));
    1895 SCIPrationalSetReal(tmpval, aggrinfo->substfactor[i]);
    1896
    1897 key = SCIPcertificateGetRowIndex(certificate, slackrow, SCIPrationalIsPositive(tmpval));
    1898
    1899 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    1900 SCIPrationalMultReal(tmpval, tmpval, mirinfo->scale);
    1901 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    1902 }
    1903
    1904 SCIPdebugMessage("Correcting for integer slacks ( needed for v >= 0 part ) \n");
    1905 for( i = 0; i < mirinfo->nslacks; i++ )
    1906 {
    1907 SCIP_Longint key;
    1908 SCIP_ROWEXACT* slackrow;
    1909 slackrow = SCIProwGetRowExact(mirinfo->slackrows[i]);
    1910 SCIP_Longint upar;
    1911
    1912 assert(slackrow != NULL);
    1913 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow));
    1914 if( mirinfo->slackroundeddown[i] )
    1915 SCIPrationalSetReal(tmpval, 0);
    1916 else
    1917 {
    1918 /* value = weight * scale * sign -> compute (1 - fr)/(1-f0) where fr is the fractionality of value */
    1919 SCIPrationalSetReal(tmpval, mirinfo->slackweight[i]);
    1920 SCIPrationalMultReal(tmpval, tmpval, mirinfo->slackscale[i]);
    1921 SCIPrationalMultReal(tmpval, tmpval, mirinfo->slacksign[i]);
    1922 (void) SCIPrationalRoundLong(&upar, tmpval, SCIP_R_ROUND_UPWARDS);
    1923 SCIPrationalDiffReal(tmpval, tmpval, upar);
    1924 SCIPrationalNegate(tmpval, tmpval);
    1925 SCIPrationalMultReal(tmpval, tmpval, mirinfo->slacksign[i]);
    1926 SCIPrationalDiv(tmpval, tmpval, oneminusf0);
    1927 SCIPrationalDebugMessage("tmpval 1 %g \n", SCIPrationalGetReal(tmpval));
    1928 SCIPrationalSetReal(tmpval, mirinfo->slackusedcoef[i]);;
    1929 SCIPrationalDiffReal(tmpval, tmpval, mirinfo->slackcoefficients[i]);
    1930 SCIPrationalDebugMessage("tmpval 2 %g (slacksign %d, splitcoef %g, cutval %g) \n", SCIPrationalGetReal(tmpval), mirinfo->slacksign[i], mirinfo->slackcoefficients[i], mirinfo->slackusedcoef[i]);
    1931 }
    1932
    1933 key = SCIPcertificateGetRowIndex(certificate, slackrow, SCIPrationalIsPositive(tmpval));
    1934
    1935 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    1936 SCIPrationalMultReal(tmpval, tmpval, mirinfo->scale);
    1937 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    1938 }
    1939
    1940 SCIPcertificatePrintProofMessage(certificate, " } -1 \n");
    1941
    1942 SCIPdebugMessage("Verifying right part of split disjunction, multipliers -f/(1-f) and 1/1-f \n");
    1943
    1944 /* print the mir cut with proof (-f/1-f) * (\xi \ge \lfloor \beta + 1 \rfloor) + (1/1-f)(\xi - \nu \le \beta) */
    1945 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, mirinfo->unroundedrhs) );
    1946
    1947 SCIP_CALL( certificatePrintWeakDerStart(certificate, prob, SCIProwIsLocal(row)) );
    1948 SCIPcertificatePrintProofMessage(certificate, " %d ", 1 + aggrinfo->naggrrows + aggrinfo->nnegslackrows + mirinfo->nslacks);
    1949
    1950 /* (-f/1-f) * (\xi \ge \lfloor \beta + 1 \rfloor) */
    1951 SCIPcertificatePrintProofMessage(certificate, "%d ", rightdisjunctionindex);
    1952 SCIPrationalSetRational(tmpval, mirinfo->frac);
    1953 SCIPrationalNegate(tmpval, tmpval); /* -f */
    1954 SCIPrationalDiv(tmpval, tmpval, oneminusf0); /* -f/(1-f) */
    1955 /* multiply with scaling factor that was used in cut derivation */
    1956 SCIPrationalMultReal(tmpval, tmpval, mirinfo->scale);
    1957 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    1958
    1959 SCIPrationalDivReal(tmpval, tmpval, mirinfo->scale);
    1960
    1961 SCIPdebugMessage("Correcting for negative continous slacks \n");
    1962 /* we also have to add the correct multipliers for the negative continuous slacks that were used here */
    1963 for( i = 0; i < aggrinfo->nnegslackrows; i++ )
    1964 {
    1965 SCIP_Longint key;
    1966 SCIP_ROWEXACT* slackrow;
    1967 slackrow = SCIProwGetRowExact(aggrinfo->negslackrows[i]);
    1968
    1969 SCIPrationalSetReal(value, -aggrinfo->negslackweights[i]);
    1970 SCIPrationalDiv(value, value, oneminusf0);
    1971 SCIPrationalAddReal(value, value, aggrinfo->substfactor[i]);
    1972 SCIPrationalDebugMessage("adding %q times row (negative continous slacks) (%g aggweight %g substfactor): ", value, -aggrinfo->negslackweights[i] / SCIPrationalGetReal(oneminusf0), aggrinfo->substfactor[i]);
    1973 SCIPdebug(SCIProwExactPrint(slackrow, set->scip->messagehdlr, NULL));
    1974
    1975 assert(slackrow != NULL);
    1976 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow));
    1977
    1978 key = SCIPcertificateGetRowIndex(certificate, slackrow, SCIPrationalIsPositive(value));
    1979
    1980 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    1981 SCIPrationalMultReal(value, value, mirinfo->scale);
    1982 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, value) );
    1983 }
    1984
    1985 SCIPdebugMessage("Correcting for %d integer slacks \n", mirinfo->nrounddownslacks);
    1986 /* we also have to add the correct multipliers for the integer slacks that were used here */
    1987 for( i = 0; i < mirinfo->nslacks; i++ )
    1988 {
    1989 SCIP_Longint key;
    1990 SCIP_ROWEXACT* slackrow;
    1991 slackrow = SCIProwGetRowExact(mirinfo->slackrows[i]);
    1992
    1993 if( mirinfo->slackroundeddown[i] )
    1994 {
    1995 SCIPdebugMessage("Rounded down intger slack on row %s \n", mirinfo->slackrows[i]->name);
    1996 SCIPrationalSetReal(value, mirinfo->slackweight[i]);
    1997 SCIPrationalMultReal(value, value, mirinfo->slackscale[i]);
    1998 SCIPrationalMultReal(value, value, mirinfo->slacksign[i]);
    1999 SCIPrationalDiffReal(value, value, mirinfo->slackcoefficients[i] * (-mirinfo->slacksign[i]));
    2000 SCIPrationalMultReal(value, value, mirinfo->slacksign[i]);
    2001 SCIPrationalDiv(value, value, oneminusf0);
    2002 }
    2003 else
    2004 {
    2005 SCIPdebugMessage("Rounded up intger slack on row %s \n", mirinfo->slackrows[i]->name);
    2006 SCIPrationalSetReal(value, mirinfo->slackweight[i]);
    2007 SCIPrationalMultReal(value, value, mirinfo->slackscale[i]);
    2008 SCIPrationalMultReal(value, value, mirinfo->slacksign[i]);
    2009 SCIPrationalDiffReal(value, value, (mirinfo->slackcoefficients[i] * -mirinfo->slacksign[i]) - 1); /* fr exactly */
    2010 SCIPrationalDiff(value, value, mirinfo->frac); /* fr - f0 */
    2011 SCIPrationalDiv(value, value, oneminusf0); /* (fr-f0) / (1-f0) */
    2012 SCIPrationalAddReal(value, value, (mirinfo->slackcoefficients[i] * -mirinfo->slacksign[i]) - 1); /* (down(ar) + (fr-f0) / (1-f0) */
    2013 SCIPrationalMultReal(value, value, mirinfo->slacksign[i]);
    2014 SCIPrationalDebugMessage("Exact coefficient %q(%g), used coefficient %g\n", value, SCIPrationalGetReal(value), mirinfo->slackusedcoef[i]);
    2015
    2016 SCIPrationalAddReal(value, value, mirinfo->slackusedcoef[i]);
    2017 }
    2018
    2019 SCIPrationalDebugMessage("adding %q(%g) times row: ", value, SCIPrationalGetReal(value));
    2020 SCIPdebug(SCIProwExactPrint(slackrow, set->scip->messagehdlr, NULL));
    2021
    2022 assert(slackrow != NULL);
    2023 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) slackrow));
    2024
    2025 key = SCIPcertificateGetRowIndex(certificate, slackrow, SCIPrationalIsPositive(value));
    2026
    2027 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    2028 SCIPrationalMultReal(value, value, mirinfo->scale);
    2029 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, value) );
    2030 }
    2031
    2032 SCIPdebugMessage("Adding %d aggregation rows \n", aggrinfo->naggrrows);
    2033 /* we also have to add the correct multipliers for the aggregation rows that were used here */
    2034 for( i = 0; i < aggrinfo->naggrrows; i++ )
    2035 {
    2036 SCIP_Longint key;
    2037 SCIP_ROWEXACT* aggrrow;
    2038 aggrrow = SCIProwGetRowExact(aggrinfo->aggrrows[i]);
    2039
    2040 SCIPrationalSetReal(value, aggrinfo->weights[i]);
    2041 SCIPrationalDiv(value, value, oneminusf0);
    2042
    2043 SCIPdebugMessage("adding (%g/%g) = %g times row: ", aggrinfo->weights[i], SCIPrationalGetReal(oneminusf0), SCIPrationalGetReal(value));
    2044 SCIPdebug(SCIProwExactPrint(aggrrow, set->scip->messagehdlr, NULL));
    2045
    2046 assert(aggrrow != NULL);
    2047 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) aggrrow));
    2048
    2049 key = SCIPcertificateGetRowIndex(certificate, aggrrow, SCIPrationalIsPositive(value));
    2050
    2051 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    2052 SCIPrationalMultReal(value, value, mirinfo->scale);
    2053 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, value) );
    2054 }
    2055
    2056 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
    2057 }
    2058#ifdef SCIP_DISABLED_CODE
    2059 /* this was an alternative piece of code to the block right above */
    2060 {
    2061 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, mirinfo->unroundedrhs) );
    2062 SCIP_CALL( certificatePrintIncompleteDerStart(certificate, SCIPlpGetRows(lp), SCIPlpGetNRows(lp), prob, SCIProwIsLocal(row)) );
    2063 SCIPcertificatePrintProofMessage(certificate, " %d } -1\n", leftdisjunctionindex);
    2064
    2065 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, mirinfo->unroundedrhs) );
    2066 SCIP_CALL( certificatePrintIncompleteDerStart(certificate, SCIPlpGetRows(lp), SCIPlpGetNRows(lp), prob, SCIProwIsLocal(row)) );
    2067 SCIPcertificatePrintProofMessage(certificate, " %d } -1\n", rightdisjunctionindex);
    2068 }
    2069#endif
    2070
    2071 /* print the unsplitting of the split disjunction */
    2072 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, mirinfo->unroundedrhs) );
    2073 SCIPcertificatePrintProofMessage(certificate, " { uns %d %d %d %d } -1\n", certificate->indexcounter - 3, leftdisjunctionindex,
    2074 certificate->indexcounter - 2, rightdisjunctionindex);
    2075
    2076 /* if we rounded the rhs we need to still certify that part */
    2077 if( !SCIPsetIsInfinity(set, mirinfo->unroundedrhs) )
    2078 {
    2079 /* print the row with the rounded rhs */
    2080 SCIP_CALL( certificatePrintRow(set, certificate, rowexact, SCIPsetInfinity(set)) );
    2081 SCIPcertificatePrintProofMessage(certificate, " { rnd 1 %d 1 } -1\n", certificate->indexcounter - 2);
    2082 }
    2083 SCIP_CALL( SCIPhashmapInsertLong(certificate->rowdatahash, SCIProwGetRowExact(row), certificate->indexcounter - 1) );
    2084
    2085 SCIP_CALL( SCIPcertificateFreeAggrInfo(set, certificate, lp, aggrinfo, row) );
    2086 SCIP_CALL( SCIPcertificateFreeMirInfo(set, certificate, lp, mirinfo, row) );
    2087
    2088 SCIPrationalFreeBuffer(set->buffer, &value);
    2089 SCIPrationalFreeBuffer(set->buffer, &oneminusf0);
    2090 SCIPrationalFreeBuffer(set->buffer, &tmpval);
    2091
    2092 return SCIP_OKAY;
    2093}
    2094
    2095/** prints a variable bound to the problem section of the certificate file and returns line index */
    2097 SCIP_CERTIFICATE* certificate, /**< certificate information */
    2098 SCIP_Bool isorigfile, /**< should the line be printed to the origfile or the transfile */
    2099 const char* boundname, /**< name of the bound constraint */
    2100 SCIP_VAR* var, /**< variable to print the bound cons for */
    2101 SCIP_RATIONAL* boundval, /**< value of the bound */
    2102 SCIP_Bool isupper /**< is it the upper bound? */
    2103 )
    2104{
    2105 /* check whether certificate output should be created */
    2106 if( !SCIPcertificateIsEnabled(certificate) )
    2107 return SCIP_OKAY;
    2108
    2109 if( !isorigfile )
    2110 {
    2111 certificate->indexcounter++;
    2112 certificate->conscounter++;
    2113
    2114#ifndef NDEBUG
    2115 certificate->lastinfo->isbound = TRUE;
    2116 certificate->lastinfo->boundtype = isupper ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER;
    2117 certificate->lastinfo->varindex = SCIPvarGetCertificateIndex(var);
    2118 certificate->lastinfo->isglobal = TRUE;
    2119 certificate->lastinfo->certificateindex = certificate->indexcounter - 1;
    2120 SCIPrationalSetRational(certificate->lastinfo->boundval, boundval);
    2121#endif
    2122
    2123 if( isupper )
    2124 SCIPvarSetUbCertificateIndexGlobal(var, certificate->indexcounter - 1);
    2125 else
    2126 SCIPvarSetLbCertificateIndexGlobal(var, certificate->indexcounter - 1);
    2127
    2128 if( boundname == NULL )
    2129 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "B%d %c ", certificate->indexcounter - 1, (isupper ? 'L' : 'G'));
    2130 else
    2131 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "%s %c ", boundname, (isupper ? 'L' : 'G'));
    2132 }
    2133 else
    2134 {
    2135 certificate->indexcounter_ori++;
    2136 if( boundname == NULL )
    2137 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "B%d %c ", certificate->indexcounter_ori - 1, (isupper ? 'L' : 'G'));
    2138 else
    2139 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "%s %c ", boundname, (isupper ? 'L' : 'G'));
    2140 }
    2141
    2142 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, boundval) );
    2143 SCIPcertificatePrintProblemMessage(certificate, isorigfile, " 1 %d 1\n", SCIPvarGetCertificateIndex(var));
    2144
    2145 return SCIP_OKAY;
    2146}
    2147
    2148/** installs updated node data in parent node */
    2150 SCIP_CERTIFICATE* certificate, /**< certificate information */
    2151 SCIP_NODE* node, /**< node data structure */
    2152 SCIP_Longint fileindex, /**< index of new bound */
    2153 SCIP_RATIONAL* newbound /**< pointer to value of new bound, NULL if infeasible */
    2154 )
    2155{
    2156 SCIP_CERTNODEDATA* nodedataparent;
    2158
    2159 assert(node != NULL);
    2160 assert(fileindex >= 0);
    2161
    2162 if( !SCIPcertificateIsEnabled(certificate) )
    2163 return SCIP_OKAY;
    2164
    2165 /* retrieve node data */
    2166 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    2168
    2169 if( newbound != NULL && SCIPrationalIsLT(newbound, nodedata->derbound_self) )
    2170 return SCIP_OKAY;
    2171
    2172 /* if the node is the root node, then only update the index and bound */
    2173 if( SCIPnodeGetParent(node) == NULL )
    2174 {
    2175 certificate->derindex_root = fileindex;
    2176 if( newbound == NULL )
    2177 certificate->rootinfeas = TRUE;
    2178 else
    2179 SCIPrationalSetRational(certificate->rootbound, newbound);
    2180 return SCIP_OKAY;
    2181 }
    2182
    2183 /* retrieve parent node data */
    2184 assert(SCIPhashmapExists(certificate->nodedatahash, SCIPnodeGetParent(node)));
    2185 nodedataparent = (SCIP_CERTNODEDATA*)SCIPhashmapGetImage(certificate->nodedatahash, SCIPnodeGetParent(node));
    2186
    2187 /* First we check whether the node is left/right child of its parent node; left/rightfilled tells us if a bound has
    2188 * already been derived for this node. We only install the new bound if the node is not already marked as infeasible
    2189 * and the new bound is better than the current bound if it is filled.
    2190 */
    2191 if( certificateIsLeftNode(certificate, node) )
    2192 {
    2193 if( newbound != NULL && !nodedataparent->leftinfeas && (!nodedataparent->leftfilled || SCIPrationalIsGT(newbound, nodedataparent->derbound_left)) )
    2194 {
    2195 nodedataparent->derindex_left = fileindex;
    2196 SCIPrationalSetRational(nodedataparent->derbound_left, newbound);
    2197 }
    2198 if( newbound == NULL || SCIPrationalIsInfinity(newbound) )
    2199 {
    2200 nodedataparent->derindex_left = fileindex;
    2201 nodedataparent->leftinfeas = TRUE;
    2202 }
    2203 nodedataparent->leftfilled = TRUE;
    2204 }
    2205 else
    2206 {
    2207 if( newbound != NULL && !nodedataparent->rightinfeas && (!nodedataparent->rightfilled || SCIPrationalIsGT(newbound, nodedataparent->derbound_right)) )
    2208 {
    2209 nodedataparent->derindex_right = fileindex;
    2210 SCIPrationalSetRational(nodedataparent->derbound_right, newbound);
    2211 }
    2212 if( newbound == NULL || SCIPrationalIsInfinity(newbound) )
    2213 {
    2214 nodedataparent->rightinfeas = TRUE;
    2215 nodedataparent->derindex_right = fileindex;
    2216 }
    2217 nodedataparent->rightfilled = TRUE;
    2218 }
    2219
    2220 return SCIP_OKAY;
    2221}
    2222
    2223/** prints a dual bound from an exact lp solution */
    2225 SCIP_CERTIFICATE* certificate, /**< scip certificate struct */
    2226 SCIP_LPEXACT* lpexact, /**< the exact lp */
    2227 SCIP_SET* set, /**< scip settings */
    2228 SCIP_NODE* node, /**< the current node */
    2229 SCIP_PROB* prob, /**< problem data */
    2230 SCIP_Bool usefarkas /**< should an infeasibility proof be printed? */
    2231 )
    2232{
    2233 SCIP_RATIONAL** vals;
    2234 SCIP_RATIONAL* val;
    2235 SCIP_RATIONAL* lowerbound;
    2236 SCIP_RATIONAL* farkasrhs;
    2237 SCIP_RATIONAL* tmp;
    2238 SCIP_Longint* ind = NULL;
    2239 int len;
    2240 int i;
    2241 SCIP_Longint key;
    2242
    2243 /* check whether certificate output should be created */
    2244 if( !SCIPcertificateIsEnabled(certificate) )
    2245 return SCIP_OKAY;
    2246
    2247 SCIPdebugMessage("Printing dual bound from exact LP. Certificate index %lld \n", certificate->indexcounter);
    2248
    2249 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
    2250 SCIPlpExactGetObjval(lpexact, set, tmp);
    2251
    2252 /* only print line if bound improved */
    2253 if( !usefarkas && SCIPrationalIsLT(tmp, SCIPnodeGetLowerboundExact(node)) )
    2254 {
    2255 SCIPrationalFreeBuffer(set->buffer, &tmp);
    2256 return SCIP_OKAY;
    2257 }
    2258
    2259 /* init the flag objintegral if at root node */
    2260 if( SCIPnodeGetParent(node) == NULL )
    2261 certificate->objintegral = SCIPprobIsObjIntegral(prob);
    2262
    2263 assert(lpexact != NULL);
    2264 assert(certificate->transfile != NULL);
    2265
    2266 /* if needed extend vals array */
    2267 if( lpexact->ncols + lpexact->nrows > certificate->valssize )
    2268 {
    2269 SCIP_CALL( SCIPrationalReallocBlockArray(certificate->blkmem, &(certificate->vals), certificate->valssize, lpexact->nrows + lpexact->ncols + 50) );
    2270 certificate->valssize = lpexact->ncols + lpexact->nrows + 50;
    2271 }
    2272
    2273 vals = certificate->vals;
    2274
    2275 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &farkasrhs) );
    2276
    2277 SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, (lpexact->nrows + lpexact->ncols)) );
    2278
    2279 len = 0;
    2280 for( i = 0; i < lpexact->ncols; ++i )
    2281 {
    2282 SCIP_COLEXACT* col = lpexact->cols[i];
    2283 SCIP_VAR* var = SCIPcolExactGetVar(col);
    2284
    2285 if( usefarkas )
    2286 val = col->farkascoef;
    2287 else
    2288 val = col->redcost;
    2289
    2290 assert(!SCIPrationalIsAbsInfinity(val));
    2291
    2292 if( !SCIPrationalIsZero(val) )
    2293 {
    2294 if( usefarkas )
    2295 SCIPrationalNegate(vals[len], val);
    2296 else
    2297 SCIPrationalSetRational(vals[len], val);
    2298
    2300
    2301 SCIPrationalDebugMessage("Column %d for var %s has index %l and farkas coef %q \n", col->index, col->var->name, ind[len], val);
    2302
    2303 /* update farkasrhs */
    2304 if( usefarkas )
    2305 {
    2307 SCIPrationalAddProd(farkasrhs, vals[len], val);
    2308 }
    2309 len++;
    2310 }
    2311 }
    2312
    2313 for( i = 0; i < lpexact->nrows; ++i )
    2314 {
    2315 SCIP_ROWEXACT* row;
    2316 row = lpexact->rows[i];
    2317 val = usefarkas ? row->dualfarkas : row->dualsol;
    2318 assert(!SCIPrationalIsAbsInfinity(val));
    2319
    2320 if( !SCIPrationalIsZero(val) )
    2321 {
    2322 SCIPrationalSetRational(vals[len], val);
    2323 key = SCIPhashmapGetImageLong(certificate->rowdatahash, (void*) row);
    2324
    2326 {
    2327 SCIP_CALL( SCIPcertificatePrintMirCut(set, lpexact->fplp, certificate, prob, SCIProwExactGetRow(row), 'L') );
    2328 key = SCIPhashmapGetImageLong(certificate->rowdatahash, (void*) row);
    2329 }
    2330 else if( key == SCIP_LONGINT_MAX && SCIProwExactGetNNonz(row) == 1 )
    2331 {
    2334 }
    2335
    2336 assert(key != SCIP_LONGINT_MAX);
    2337
    2338 ind[len] = key;
    2339 /* if we have a ranged row, and the dual corresponds to the upper bound,
    2340 * the index for the rhs-constraint is one larger in the certificate */
    2341 if( !SCIPrationalIsEQ(row->lhs, row->rhs) && !SCIPrationalIsAbsInfinity(row->lhs) && SCIPrationalIsNegative(val) )
    2342 ind[len] += 1;
    2343
    2344 SCIPrationalDebugMessage("Row (index %d, %s has index %l and farkas coef %q ", row->index, row->fprow->name, ind[len], val);
    2345 SCIPdebug(SCIProwExactPrint(row, set->scip->messagehdlr, NULL) );
    2346
    2347 /* update farkasrhs */
    2348 if( usefarkas )
    2349 {
    2350 val = SCIPrationalIsPositive(vals[len]) ? row->lhs : row->rhs;
    2351 SCIPrationalAddProd(farkasrhs, vals[len], val);
    2352 SCIPrationalDiffProd(farkasrhs, vals[len], row->constant);
    2353 }
    2354
    2355 len++;
    2356 }
    2357 }
    2358
    2359 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lowerbound) );
    2360 if( usefarkas )
    2361 {
    2362 SCIPrationalSetInfinity(lowerbound);
    2363 }
    2364 else
    2365 {
    2366 /* vipr does not accept infinity, so in case of objlimit, get the objval from the lpi */
    2367 if( !SCIPrationalIsInfinity(lpexact->lpobjval) )
    2368 SCIPrationalSetRational(lowerbound, lpexact->lpobjval);
    2369 else
    2370 {
    2371 SCIP_CALL( SCIPlpiExactGetObjval(lpexact->lpiexact, lowerbound) );
    2372 }
    2373 }
    2374
    2375 SCIP_CALL( certificatePrintDualbound(certificate, NULL, lowerbound, len, ind, vals) );
    2376 SCIP_CALL( SCIPcertificateUpdateParentData(certificate, node, certificate->indexcounter - 1, lowerbound) );
    2377 SCIP_CALL( SCIPcertificateUpdateBoundData(certificate, node, certificate->indexcounter - 1, lowerbound) );
    2378
    2379 SCIPrationalFreeBuffer(set->buffer, &lowerbound);
    2381 SCIPrationalFreeBuffer(set->buffer, &farkasrhs);
    2382 SCIPrationalFreeBuffer(set->buffer, &tmp);
    2383
    2384 return SCIP_OKAY;
    2385}
    2386
    2387/** prints a dual bound from the pseudo solution
    2388 *
    2389 * in case of a bound change (branching), this happens before the bound change is processed;
    2390 * therefore we add the option to give on varindex, boundchgindex pair to pass directly to the method
    2391 */
    2393 SCIP_CERTIFICATE* certificate, /**< scip certificate struct */
    2394 SCIP_LPEXACT* lpexact, /**< the exact lp */
    2395 SCIP_NODE* node, /**< current node */
    2396 SCIP_SET* set, /**< scip settings */
    2397 SCIP_PROB* prob, /**< problem data */
    2398 SCIP_Bool lowerchanged, /**< do the modified indices address a change in lb or ub? */
    2399 int modifiedvarindex, /**< index of modified variable, or -1 */
    2400 SCIP_Longint boundchangeindex, /**< index of unprocessed bound change in the certificate, or -1 */
    2401 SCIP_Real psval /**< the pseudo obj value (or inf to use exact lp value) */
    2402 )
    2403{
    2404 SCIP_VAR** vars;
    2405 SCIP_RATIONAL* pseudoobjval;
    2406 SCIP_RATIONAL** bounds;
    2407 SCIP_Longint* dualind = NULL;
    2408 int nvars;
    2409 int duallen;
    2410 int i;
    2411 int nnonzeros;
    2412
    2413 assert(certificate != NULL);
    2414 assert(prob != NULL);
    2415 assert(set != NULL);
    2416 assert((modifiedvarindex >= 0 && boundchangeindex >= 0) || (modifiedvarindex == -1 && boundchangeindex == -1) );
    2417
    2418 /* check whether certificate output should be created */
    2419 if( !SCIPcertificateIsEnabled(certificate) )
    2420 return SCIP_OKAY;
    2421
    2422 /* only print if bound is finite and improving */
    2423 if( SCIPsetIsInfinity(set, -psval) || psval < SCIPnodeGetLowerbound(node) )
    2424 return SCIP_OKAY;
    2425
    2426 /* if at root node set, objintegral flag */
    2427 if( SCIPnodeGetParent(node) == NULL )
    2428 certificate->objintegral = SCIPprobIsObjIntegral(prob);
    2429
    2430 vars = SCIPprobGetVars(prob);
    2431 nvars = SCIPprobGetNVars(prob);
    2432 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &pseudoobjval) );
    2433
    2434 /* infinity means we use the exact lp value */
    2435 if( SCIPsetIsInfinity(set, psval) )
    2436 SCIPlpExactGetPseudoObjval(lpexact, set, pseudoobjval);
    2437 else
    2438 SCIPrationalSetReal(pseudoobjval, psval);
    2439 duallen = SCIPprobGetNObjVars(prob, set);
    2440 SCIP_CALL( SCIPrationalCreateBufferArray(set->buffer, &bounds, duallen) );
    2441 SCIP_CALL( SCIPsetAllocBufferArray(set, &dualind, duallen) );
    2442 /* computes pseudo objective value (with bound change if necessary) */
    2443 /*lint --e{838}*/
    2444
    2445 nnonzeros = 0;
    2446 for( i = 0; i < nvars; i++ )
    2447 {
    2448 SCIP_RATIONAL* obj = SCIPvarGetObjExact(vars[i]);
    2449 if( !SCIPrationalIsZero(obj) )
    2450 {
    2451 SCIPrationalSetRational(bounds[nnonzeros], obj);
    2452
    2453 assert(!SCIPrationalIsAbsInfinity(bounds[nnonzeros]));
    2454
    2455 /* retrieve the line in the certificate of the bound */
    2456 if( SCIPrationalIsPositive(obj) )
    2457 {
    2458 dualind[nnonzeros] = SCIPvarGetLbCertificateIndexLocal(vars[i]);
    2459 if( lowerchanged && modifiedvarindex == SCIPvarGetCertificateIndex(vars[i]) )
    2460 dualind[nnonzeros] = boundchangeindex;
    2461 }
    2462 else
    2463 {
    2464 dualind[nnonzeros] = SCIPvarGetUbCertificateIndexLocal(vars[i]);
    2465 if( !lowerchanged && modifiedvarindex == SCIPvarGetCertificateIndex(vars[i]) )
    2466 dualind[nnonzeros] = boundchangeindex;
    2467 }
    2468
    2469 nnonzeros++;
    2470 }
    2471 }
    2472 assert(nnonzeros == duallen);
    2473
    2474 /* print pseudo solution into certificate file */
    2475 SCIP_CALL( certificatePrintDualbound(certificate, NULL, pseudoobjval, duallen, dualind, bounds) );
    2476
    2477 SCIP_CALL( SCIPcertificateUpdateParentData(certificate, node, certificate->indexcounter - 1,
    2478 pseudoobjval) );
    2479
    2480 SCIP_CALL( SCIPcertificateUpdateBoundData(certificate, node, certificate->indexcounter - 1, pseudoobjval) );
    2481
    2482 SCIPsetFreeBufferArray(set, &dualind);
    2483 SCIPrationalFreeBufferArray(set->buffer, &bounds, nnonzeros);
    2484 SCIPrationalFreeBuffer(set->buffer, &pseudoobjval);
    2485
    2486 return SCIP_OKAY;
    2487}
    2488
    2489/** prints the bound that a node inherits from its parent to the certificate */
    2491 SCIP_SET* set, /**< general SCIP settings */
    2492 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    2493 SCIP_NODE* node /**< node data */
    2494 )
    2495{
    2497 SCIP_RATIONAL* lowerbound;
    2498
    2499 assert(node != NULL);
    2500
    2501 /* check whether certificate output should be created */
    2502 if( !SCIPcertificateIsEnabled(certificate) )
    2503 return SCIP_OKAY;
    2504
    2505 /* certificate is disabled on probing nodes */
    2507 return SCIP_OKAY;
    2508
    2509 /* get the current node data */
    2510 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    2512
    2513 if( nodedata->inheritedbound && nodedata->assumptionindex_self != - 1 )
    2514 {
    2515 SCIP_Longint ind[1];
    2516 SCIP_RATIONAL* val;
    2517
    2518 ind[0] = nodedata->derindex_self;
    2519
    2520 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &lowerbound) );
    2521 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &val) );
    2522
    2523 SCIPrationalSetRational(lowerbound, nodedata->derbound_self);
    2524 SCIPrationalSetFraction(val, 1LL, 1LL);
    2525
    2526 SCIP_CALL( certificatePrintDualbound(certificate, NULL, lowerbound, 1, ind, &val) );
    2527 SCIP_CALL( SCIPcertificateUpdateParentData(certificate, node, certificate->indexcounter - 1, lowerbound) );
    2528
    2529 SCIPrationalFreeBuffer(set->buffer, &lowerbound);
    2530 SCIPrationalFreeBuffer(set->buffer, &val);
    2531 }
    2532
    2533 return SCIP_OKAY;
    2534}
    2535
    2536/** returns the index for a row in the certificate
    2537 *
    2538 * @todo let this method return LONG_MAX if row is not in the hashmap; add method to check existence, and to insert an
    2539 * element, and use these throughout the SCIP core
    2540 */
    2542 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    2543 SCIP_ROWEXACT* row, /**< row to consider */
    2544 SCIP_Bool rhs /**< whether we want the index for the rhs or the lhs */
    2545 )
    2546{
    2547 SCIP_Longint ret = SCIPhashmapGetImageLong(certificate->rowdatahash, row);
    2548 assert( ret != SCIP_LONGINT_MAX );
    2549 /* for ranged rows, the key always corresponds to the >= part of the row;
    2550 therefore we need to increase it by one to get the correct key */
    2551 if( !SCIPrationalIsAbsInfinity(row->rhs) && !SCIPrationalIsAbsInfinity(row->lhs) && !SCIPrationalIsEQ(row->lhs, row->rhs) && rhs)
    2552 ret += 1;
    2553 return ret;
    2554}
    2555
    2556/** updates the parent certificate node data when branching */
    2558 SCIP_SET* set, /**< general SCIP settings */
    2559 SCIP_CERTIFICATE* certificate, /**< certificate information */
    2560 SCIP_STAT* stat, /**< dynamic problem statistics */
    2561 SCIP_LP* lp, /**< LP informations */
    2562 SCIP_NODE* node, /**< node data */
    2563 SCIP_VAR* branchvar, /**< the variable that gets branched on */
    2564 SCIP_BOUNDTYPE boundtype, /**< the bounding type */
    2565 SCIP_Real newbound /**< the new bound */
    2566 )
    2567{
    2568 SCIP_CERTNODEDATA* nodedataparent;
    2570 SCIP_RATIONAL* branchbound;
    2571
    2572 assert(node != NULL);
    2573 assert(stat != NULL);
    2574
    2575 /* check whether certificate output should be created */
    2576 if( !SCIPcertificateIsEnabled(certificate) )
    2577 return SCIP_OKAY;
    2578
    2579 /* certificate is disabled on probing nodes */
    2581 return SCIP_OKAY;
    2582
    2583 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &branchbound) );
    2584 SCIPrationalSetReal(branchbound, newbound);
    2585
    2586 assert(SCIPrationalIsIntegral(branchbound));
    2587
    2589
    2590 if( branchvar != NULL )
    2591 {
    2592 nodedata->assumptionindex_self = printBoundAssumption(certificate, branchvar,
    2593 branchbound, boundtype);
    2594 }
    2595
    2596 if( SCIPnodeGetParent(node) != NULL && certificate->transfile != NULL )
    2597 {
    2598 nodedataparent = (SCIP_CERTNODEDATA*)SCIPhashmapGetImage(certificate->nodedatahash, SCIPnodeGetParent(node));
    2599
    2600 if( branchvar != NULL )
    2601 {
    2602 if( boundtype == SCIP_BOUNDTYPE_UPPER )
    2603 nodedataparent->assumptionindex_right = nodedata->assumptionindex_self;
    2604 if( boundtype == SCIP_BOUNDTYPE_LOWER )
    2605 nodedataparent->assumptionindex_left = nodedata->assumptionindex_self;
    2606 }
    2607 }
    2608
    2609 SCIPrationalFreeBuffer(set->buffer, &branchbound);
    2610
    2611 return SCIP_OKAY;
    2612}
    2613
    2614/** create a new node data structure for the current node */
    2616 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    2617 SCIP_STAT* stat, /**< problem statistics */
    2618 SCIP_NODE* node /**< new node, that was created */
    2619 )
    2620{
    2622
    2623 assert(stat != NULL );
    2624 assert(node != NULL );
    2625
    2626 /* check whether certificate output should be created */
    2627 if( !SCIPcertificateIsEnabled(certificate) )
    2628 return SCIP_OKAY;
    2629
    2630 /* certificate is disabled on probing nodes */
    2632 return SCIP_OKAY;
    2633
    2634 SCIP_ALLOC( BMSallocBlockMemory(certificate->blkmem, &nodedata) );
    2635
    2636 nodedata->derindex_left = -1;
    2637 nodedata->derindex_right = -1;
    2638 nodedata->assumptionindex_left = -1;
    2639 nodedata->assumptionindex_right = -1;
    2640 SCIP_CALL( SCIPrationalCreateString(certificate->blkmem, &nodedata->derbound_left, "-inf") );
    2641 SCIP_CALL( SCIPrationalCreateString(certificate->blkmem, &nodedata->derbound_right, "-inf") );
    2642 SCIP_CALL( SCIPrationalCreateString(certificate->blkmem, &nodedata->derbound_self, "-inf") );
    2643 nodedata->assumptionindex_self = -1;
    2644 nodedata->leftinfeas = FALSE;
    2645 nodedata->leftfilled = FALSE;
    2646 nodedata->rightinfeas = FALSE;
    2647 nodedata->rightfilled = FALSE;
    2648 nodedata->inheritedbound = TRUE;
    2649 nodedata->derindex_self = -1;
    2650 if( SCIPnodeGetParent(node) != NULL )
    2651 {
    2652 SCIP_NODE* parent = SCIPnodeGetParent(node);
    2653 SCIP_CERTNODEDATA* parentdata;
    2654 assert(SCIPhashmapExists(certificate->nodedatahash, parent));
    2655 parentdata = (SCIP_CERTNODEDATA*) SCIPhashmapGetImage(certificate->nodedatahash, (void*) parent);
    2656 assert(parentdata != NULL);
    2657
    2658 nodedata->derindex_self = parentdata->derindex_self;
    2659 SCIPrationalSetRational(nodedata->derbound_self, parentdata->derbound_self);
    2660 }
    2661
    2662 /* link the node to its nodedata in the corresponding hashmap */
    2663 SCIP_CALL( SCIPhashmapSetImage(certificate->nodedatahash, node, (void*)nodedata) );
    2664
    2665 return SCIP_OKAY;
    2666}
    2667
    2668/** prints cutoff bound for objective value **/
    2670 SCIP* scip, /**< SCIP data structure */
    2671 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    2672 SCIP_RATIONAL* bound, /**< the bound */
    2673 SCIP_Longint* certificateline /**< save the line index */
    2674 )
    2675{
    2676 SCIP_RATIONAL* newbound;
    2677
    2678 /* check whether certificate output should be created */
    2679 if( !SCIPcertificateIsEnabled(certificate) )
    2680 return SCIP_OKAY;
    2681
    2685 else
    2686 SCIPrationalSetRational(newbound, bound);
    2687
    2688 SCIPcertificatePrintProofMessage(certificate, "O%d L ", certificate->indexcounter);
    2689 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, newbound) );
    2690 SCIPcertificatePrintProofMessage(certificate, " OBJ { sol } -1\n");
    2691
    2692 certificate->indexcounter++;
    2693 *certificateline = certificate->indexcounter - 1;
    2695
    2696 return SCIP_OKAY;
    2697}
    2698
    2699/** create a new node data structure for the current node */
    2701 SCIP_SET* set, /**< general SCIP settings */
    2702 SCIP_PROB* prob, /**< SCIP problem data */
    2703 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    2704 SCIP_AGGRROW* aggrrow, /**< agrrrow that results from the aggregation */
    2705 SCIP_ROW** aggrrows, /**< array of rows used fo the aggregation */
    2706 SCIP_Real* weights, /**< array of weights */
    2707 int naggrrows, /**< length of the arrays */
    2708 SCIP_Bool local, /**< true if local bound information can be used */
    2709 SCIP_Longint* certificateline /**< pointer to store the certificate line index or NULL */
    2710 )
    2711{
    2712 int i;
    2713 SCIP_RATIONAL* tmpval;
    2714 SCIP_ROWEXACT* rowexact;
    2715 SCIP_VAR** vars;
    2716
    2717 /* check whether certificate output should be created */
    2718 if( !SCIPcertificateIsEnabled(certificate) )
    2719 return SCIP_OKAY;
    2720
    2721 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmpval) );
    2722 vars = SCIPprobGetVars(prob);
    2723
    2724 SCIPdebugMessage("printing certificate for aggrrow: ");
    2725 SCIPdebug(SCIPaggrRowPrint(set->scip, aggrrow, NULL));
    2726
    2727 SCIPcertificatePrintProofMessage(certificate, "AggrRow_%d %c ", certificate->indexcounter, 'L');
    2728
    2729 SCIPrationalSetReal(tmpval, SCIPaggrRowGetRhs(aggrrow));
    2730
    2731 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    2732
    2733 SCIPcertificatePrintProofMessage(certificate, " %d", SCIPaggrRowGetNNz(aggrrow));
    2734
    2735 for( i = 0; i < SCIPaggrRowGetNNz(aggrrow); i++ )
    2736 {
    2737 int varindex;
    2738
    2739 /** @todo perform line breaking before exceeding maximum line length */
    2740 varindex = SCIPvarGetCertificateIndex(vars[SCIPaggrRowGetInds(aggrrow)[i]]);
    2742
    2743 SCIPcertificatePrintProofMessage(certificate, " %d ", varindex);
    2744 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    2745 }
    2746
    2747 SCIP_CALL( certificatePrintWeakDerStart(certificate, prob, local) );
    2748 SCIPcertificatePrintProofMessage(certificate, " %d", naggrrows);
    2749 for( i = 0; i < naggrrows; i++ )
    2750 {
    2751 SCIP_Longint key;
    2752 rowexact = SCIProwGetRowExact(aggrrows[i]);
    2753
    2754 SCIPdebugMessage("adding %g times row: ", weights[i]);
    2755 SCIPdebug(SCIProwExactPrint(rowexact, set->scip->messagehdlr, NULL));
    2756 SCIPrationalSetReal(tmpval, weights[i]);
    2757
    2758 assert(rowexact != NULL);
    2759 assert(SCIPhashmapExists(certificate->rowdatahash, (void*) rowexact));
    2760
    2761 key = SCIPcertificateGetRowIndex(certificate, rowexact, SCIPrationalIsPositive(tmpval));
    2762
    2763 SCIPcertificatePrintProofMessage(certificate, " %d ", key);
    2764 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, tmpval) );
    2765 }
    2766
    2767 SCIPcertificatePrintProofMessage(certificate, " } -1\n");
    2768
    2769 if( certificateline != NULL )
    2770 *certificateline = certificate->indexcounter;
    2771 certificate->indexcounter++;
    2772 certificate->lastinfo->isbound = FALSE;
    2773
    2774 SCIPrationalFreeBuffer(set->buffer, &tmpval);
    2775
    2776 return SCIP_OKAY;
    2777}
    2778
    2779/** free all aggregation information */
    2781 SCIP* scip /**< global SCIP data structure */
    2782 )
    2783{
    2784 SCIP_Longint i;
    2785 SCIP_CERTIFICATE* certificate;
    2786
    2787 certificate = SCIPgetCertificate(scip);
    2788
    2789 /* check whether certificate output should be created */
    2790 if( !SCIPcertificateIsEnabled(certificate) )
    2791 return SCIP_OKAY;
    2792
    2793 if( certificate == NULL || certificate->aggrinfo == NULL )
    2794 return SCIP_OKAY;
    2795
    2796 assert(certificate != NULL);
    2797
    2798 for( i = certificate->naggrinfos - 1; i >= 0; i-- )
    2799 {
    2800 SCIP_CALL( SCIPcertificateFreeAggrInfo(scip->set, certificate, scip->lp, certificate->aggrinfo[i], NULL) );
    2801 }
    2802
    2803 BMSfreeBlockMemoryArray(certificate->blkmem, &certificate->aggrinfo, certificate->aggrinfosize);
    2805 SCIPhashmapFree(&certificate->aggrinfohash);
    2806 certificate->naggrinfos = 0;
    2807 certificate->aggrinfohash = NULL;
    2808
    2809 return SCIP_OKAY;
    2810}
    2811
    2812/** free all mir information */
    2814 SCIP* scip /**< global SCIP data structure */
    2815 )
    2816{
    2817 int i, j;
    2818 SCIP_CERTIFICATE* certificate;
    2819
    2820 certificate = SCIPgetCertificate(scip);
    2821
    2822 /* check whether certificate output should be created */
    2823 if( !SCIPcertificateIsEnabled(certificate) )
    2824 return SCIP_OKAY;
    2825
    2826 if( certificate == NULL || certificate->mirinfo == NULL )
    2827 return SCIP_OKAY;
    2828
    2829 assert(certificate != NULL);
    2830
    2831 for( i = 0; i < certificate->nmirinfos; i++ )
    2832 {
    2833 for( j = 0; j < certificate->mirinfo[i]->nslacks; ++j )
    2834 {
    2835 SCIP_CALL( SCIPreleaseRow(scip, &(certificate->mirinfo[i]->slackrows[j])) );
    2836 }
    2837 SCIPrationalFreeBlock(certificate->blkmem, &certificate->mirinfo[i]->frac);
    2838 SCIPrationalFreeBlock(certificate->blkmem, &certificate->mirinfo[i]->rhs);
    2839 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->varinds), certificate->mirinfo[i]->nsplitvars);
    2840 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->splitcoefficients), certificate->mirinfo[i]->nsplitvars);
    2841 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->upperused), certificate->mirinfo[i]->nsplitvars);
    2842 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->localbdused), certificate->mirinfo[i]->nsplitvars);
    2843 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackrows), certificate->mirinfo[i]->nslacks);
    2844 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slacksign), certificate->mirinfo[i]->nslacks);
    2845 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackcoefficients), certificate->mirinfo[i]->nslacks);
    2846 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackweight), certificate->mirinfo[i]->nslacks);
    2847 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackroundeddown), certificate->mirinfo[i]->nslacks);
    2848 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackscale), certificate->mirinfo[i]->nslacks);
    2849 BMSfreeBlockMemoryArray(certificate->blkmem, &(certificate->mirinfo[i]->slackusedcoef), certificate->mirinfo[i]->nslacks);
    2850 BMSfreeBlockMemory(certificate->blkmem, &certificate->mirinfo[i]);
    2851 }
    2852
    2853 certificate->nmirinfos = 0;
    2854 BMSfreeBlockMemoryArray(certificate->blkmem, &certificate->mirinfo, certificate->mirinfosize);
    2856 SCIPhashmapFree(&certificate->mirinfohash);
    2857
    2858 return SCIP_OKAY;
    2859}
    2860
    2861/** free aggregation information for row */
    2863 SCIP_SET* set, /**< general SCIP settings */
    2864 SCIP_CERTIFICATE* certificate, /**< SCIP certificate structure */
    2865 SCIP_LP* lp, /**< SCIP lp data structure */
    2866 SCIP_AGGREGATIONINFO* aggrinfo, /**< SCIP aggregation info */
    2867 SCIP_ROW* row /**< row that should be freed, or NULL if not needed */
    2868 )
    2869{
    2870 SCIP_Longint arraypos;
    2871 int i;
    2872
    2873 /* check whether certificate output should be created */
    2874 if( !SCIPcertificateIsEnabled(certificate) )
    2875 return SCIP_OKAY;
    2876
    2877 /* remove the (no longer needed aggrinfo), move last element to now freed spot */
    2878 arraypos = aggrinfo->arpos;
    2879
    2880 if( row != NULL )
    2881 {
    2882 SCIP_CALL( SCIPhashmapRemove(certificate->aggrinfohash, (void*) row) );
    2883 }
    2884
    2885 for( i = 0; i < aggrinfo->naggrrows; i++ )
    2886 {
    2887 SCIP_CALL( SCIProwRelease(&(aggrinfo->aggrrows[i]), certificate->blkmem, set, lp) );
    2888 }
    2889 for( i = 0; i < aggrinfo->nnegslackrows; i++ )
    2890 {
    2891 SCIP_CALL( SCIProwRelease(&(aggrinfo->negslackrows[i]), certificate->blkmem, set, lp) );
    2892 }
    2893
    2894 BMSfreeBlockMemoryArray(certificate->blkmem, &(aggrinfo->substfactor), aggrinfo->nnegslackrows);
    2895 BMSfreeBlockMemoryArray(certificate->blkmem, &(aggrinfo->negslackweights), aggrinfo->nnegslackrows);
    2896 BMSfreeBlockMemoryArray(certificate->blkmem, &(aggrinfo->negslackrows), aggrinfo->nnegslackrows);
    2897 BMSfreeBlockMemoryArray(certificate->blkmem, &(aggrinfo->weights), aggrinfo->naggrrows);
    2898 BMSfreeBlockMemoryArray(certificate->blkmem, &(aggrinfo->aggrrows), aggrinfo->naggrrows);
    2899 SCIPaggrRowFree(set->scip, &(aggrinfo->aggrrow));
    2900 BMSfreeBlockMemory(certificate->blkmem, &aggrinfo);
    2901 if( arraypos != certificate->naggrinfos - 1 )
    2902 {
    2903 certificate->aggrinfo[arraypos] = certificate->aggrinfo[certificate->naggrinfos - 1];
    2904 certificate->aggrinfo[arraypos]->arpos = arraypos;
    2905 }
    2906 certificate->naggrinfos--;
    2907
    2908 return SCIP_OKAY;
    2909}
    2910
    2911/** free mir information for row */
    2913 SCIP_SET* set, /**< general SCIP settings */
    2914 SCIP_CERTIFICATE* certificate, /**< SCIP certificate structure */
    2915 SCIP_LP* lp, /**< SCIP lp data structure */
    2916 SCIP_MIRINFO* mirinfo, /**< SCIP mir info */
    2917 SCIP_ROW* row /**< row that should be freed, or NULL if not needed */
    2918 )
    2919{
    2920 SCIP_Longint arraypos;
    2921 int i;
    2922
    2923 /* check whether certificate output should be created */
    2924 if( !SCIPcertificateIsEnabled(certificate) )
    2925 return SCIP_OKAY;
    2926
    2927 /* remove the mirinfo, move last element to the now freed up one */
    2928 arraypos = mirinfo->arpos;
    2929 SCIP_CALL( SCIPhashmapRemove(certificate->mirinfohash, (void*) row) );
    2930 for( i = 0; i < mirinfo->nslacks; ++i)
    2931 {
    2932 SCIP_CALL( SCIProwRelease(&(mirinfo->slackrows[i]), certificate->blkmem, set, lp) );
    2933 }
    2934
    2935 SCIPrationalFreeBlock(certificate->blkmem, &(mirinfo->rhs));
    2936 SCIPrationalFreeBlock(certificate->blkmem, &(mirinfo->frac));
    2937 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->splitcoefficients), mirinfo->nsplitvars);
    2938 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->varinds), mirinfo->nsplitvars);
    2939 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->upperused), mirinfo->nsplitvars);
    2940 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->localbdused), mirinfo->nsplitvars);
    2941
    2942 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackrows), mirinfo->nslacks);
    2943 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slacksign), mirinfo->nslacks);
    2944 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackcoefficients), mirinfo->nslacks);
    2945 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackweight), mirinfo->nslacks);
    2946 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackscale), mirinfo->nslacks);
    2947 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackusedcoef), mirinfo->nslacks);
    2948 BMSfreeBlockMemoryArray(certificate->blkmem, &(mirinfo->slackroundeddown), mirinfo->nslacks);
    2949
    2950 BMSfreeBlockMemory(certificate->blkmem, &mirinfo);
    2951 if( arraypos != certificate->nmirinfos - 1 )
    2952 {
    2953 certificate->mirinfo[arraypos] = certificate->mirinfo[certificate->nmirinfos - 1];
    2954 certificate->mirinfo[arraypos]->arpos = arraypos;
    2955 }
    2956 certificate->nmirinfos--;
    2957
    2958 return SCIP_OKAY;
    2959}
    2960
    2961/** free information that is possibly still stored about this row in the certificate structure */
    2963 SCIP* scip, /**< SCIP data structure */
    2964 SCIP_ROW* row /**< a SCIP row */
    2965 )
    2966{
    2967 SCIP_CERTIFICATE* certificate;
    2968 SCIP_AGGREGATIONINFO* aggrinfo;
    2969 SCIP_MIRINFO* mirinfo;
    2970
    2972 return SCIP_OKAY;
    2973
    2974 certificate = SCIPgetCertificate(scip);
    2975
    2976 /* only do something if row does not already exist*/
    2977 if( SCIPhashmapExists(certificate->rowdatahash, (void*) SCIProwGetRowExact(row)) )
    2978 {
    2979 SCIP_CALL( SCIPhashmapRemove(certificate->rowdatahash, (void*) SCIProwGetRowExact(row)) );
    2980 return SCIP_OKAY;
    2981 }
    2982
    2983 if( certificate->workingaggrinfo || certificate->workingmirinfo )
    2984 return SCIP_OKAY;
    2985
    2986 SCIPdebugMessage("Removing information stored in certificate for row \n");
    2987
    2988 if( (certificate->aggrinfohash != NULL) && SCIPhashmapExists(certificate->aggrinfohash, (void*) row) )
    2989 {
    2990 aggrinfo = (SCIP_AGGREGATIONINFO*) SCIPhashmapGetImage(certificate->aggrinfohash, (void*) row);
    2991 SCIP_CALL( SCIPcertificateFreeAggrInfo(scip->set, certificate, scip->lp, aggrinfo, row) );
    2992 }
    2993
    2994 if( (certificate->mirinfohash != NULL) && SCIPhashmapExists(certificate->mirinfohash, (void*) row) )
    2995 {
    2996 mirinfo = (SCIP_MIRINFO*) SCIPhashmapGetImage(certificate->mirinfohash, (void*) row);
    2997 SCIP_CALL( SCIPcertificateFreeMirInfo(scip->set, certificate, scip->lp, mirinfo, row) );
    2998 }
    2999
    3000 return SCIP_OKAY;
    3001}
    3002
    3003/** create a new node data structure for the current node */
    3005 SCIP* scip, /**< SCIP data structure */
    3006 SCIP_AGGRROW* aggrrow, /**< agrrrow that results from the aggregation */
    3007 SCIP_ROW** aggrrows, /**< array of rows used fo the aggregation */
    3008 SCIP_Real* weights, /**< array of weights */
    3009 int naggrrows, /**< length of the arrays */
    3010 SCIP_ROW** negslackrows, /**< array of rows that are added implicitly with negative slack */
    3011 SCIP_Real* negslackweights, /**< array of negative slack weights */
    3012 int nnegslackrows /**< length of the negative slack array */
    3013 )
    3014{
    3015 int i;
    3016 SCIP_AGGREGATIONINFO* info = NULL;
    3017 SCIP_CERTIFICATE* certificate;
    3018
    3019 assert(scip != NULL );
    3020
    3021 certificate = SCIPgetCertificate(scip);
    3022
    3023 /* check whether certificate output should be created */
    3024 if( !SCIPcertificateIsEnabled(certificate) )
    3025 return SCIP_OKAY;
    3026
    3027 assert(certificate != NULL);
    3028
    3030
    3031 SCIPdebugMessage("adding aggrinfo, with %d rows to certficate \n", naggrrows);
    3032
    3033 SCIP_CALL( SCIPaggrRowCopy(scip, &(info->aggrrow), aggrrow) );
    3034
    3035 info->naggrrows = naggrrows;
    3036 info->nnegslackrows = nnegslackrows;
    3037 info->fileindex = certificate->indexcounter - 1;
    3038
    3039 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(info->aggrrows), naggrrows) );
    3040 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(info->weights), naggrrows) );
    3041 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(info->negslackrows), nnegslackrows) );
    3042 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(info->negslackweights), nnegslackrows) );
    3043 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(info->substfactor), nnegslackrows) );
    3044 for( i = 0; i < naggrrows; i++ )
    3045 {
    3046 SCIPdebugMessage("adding row %s with weight %g to aggrinfo \n", SCIProwGetName(aggrrows[i]), weights[i]);
    3047 info->aggrrows[i] = aggrrows[i];
    3048 info->weights[i] = weights[i];
    3049 SCIProwCapture(aggrrows[i]);
    3050 }
    3051 for( i = 0; i < nnegslackrows; i++ )
    3052 {
    3053 SCIPdebugMessage("adding (implicitly) row %s with negative slack multiplier %g to aggrinfo \n", SCIProwGetName(negslackrows[i]), negslackweights[i]);
    3054 info->negslackrows[i] = negslackrows[i];
    3055 info->negslackweights[i] = negslackweights[i];
    3056 SCIProwCapture(negslackrows[i]);
    3057 }
    3058
    3059 /* link the node to its nodedata in the corresponding hashmap */
    3060 if( certificate->aggrinfosize == certificate->naggrinfos )
    3061 {
    3062 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &certificate->aggrinfo, certificate->aggrinfosize, certificate->aggrinfosize + 100) );
    3063 certificate->aggrinfosize += 100;
    3064 }
    3065 certificate->aggrinfo[certificate->naggrinfos] = info;
    3066 info->arpos = certificate->naggrinfos;
    3067 certificate->naggrinfos++;
    3068 certificate->workingaggrinfo = TRUE;
    3069
    3070 return SCIP_OKAY;
    3071}
    3072
    3073/** create a new split info structure for the current cut */
    3075 SCIP* scip /**< SCIP data structure */
    3076 )
    3077{
    3078 SCIP_MIRINFO* mirinfo;
    3079 SCIP_CERTIFICATE* certificate;
    3080
    3081 assert(scip != NULL );
    3082
    3083 certificate = SCIPgetCertificate(scip);
    3084
    3085 /* check whether certificate output should be created */
    3086 if( !SCIPcertificateIsEnabled(certificate) )
    3087 return SCIP_OKAY;
    3088
    3089 if( certificate->mirinfosize == certificate->nmirinfos )
    3090 {
    3091 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &certificate->mirinfo, certificate->mirinfosize, certificate->mirinfosize + 100) );
    3092 certificate->mirinfosize += 100;
    3093 }
    3094
    3095 SCIP_CALL( SCIPallocBlockMemory(scip, &(certificate->mirinfo[certificate->nmirinfos])) );
    3096
    3097 mirinfo = certificate->mirinfo[certificate->nmirinfos];
    3098
    3099 SCIPdebugMessage("adding mirinfo, with to certficate \n");
    3100
    3103 mirinfo->nlocalvars = 0;
    3104 mirinfo->nslacks = 0;
    3105 mirinfo->nrounddownslacks = 0;
    3106 mirinfo->nsplitvars = SCIPgetNVars(scip);
    3107 mirinfo->arpos = certificate->nmirinfos;
    3108 mirinfo->scale = 1.0;
    3109 mirinfo->unroundedrhs = SCIPinfinity(scip);
    3110
    3121 mirinfo->varinds = NULL;
    3122
    3123 certificate->nmirinfos++;
    3124 certificate->workingmirinfo = TRUE;
    3125
    3126 return SCIP_OKAY;
    3127}
    3128
    3129/** prints unsplitting information to proof section */
    3131 SCIP_SET* set, /**< general SCIP settings */
    3132 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3133 SCIP_NODE* node /**< node data */
    3134 )
    3135{
    3137 SCIP_RATIONAL* lowerbound;
    3138 SCIP_Bool infeas;
    3139
    3140 assert(node != NULL);
    3141
    3142 /* check whether certificate output should be created */
    3143 if( !SCIPcertificateIsEnabled(certificate) )
    3144 return SCIP_OKAY;
    3145
    3146 /* certificate is disabled on probing nodes */
    3148 return SCIP_OKAY;
    3149
    3150 /* get the current node data */
    3151 assert(SCIPhashmapExists(certificate->nodedatahash, node));
    3153 (void) SCIPrationalCreateBuffer(set->buffer, &lowerbound);
    3154 infeas = FALSE;
    3155
    3156 assert(nodedata != NULL);
    3157
    3158 if( nodedata->leftfilled && nodedata->rightfilled )
    3159 {
    3160 if( nodedata->leftinfeas && nodedata->rightinfeas )
    3161 {
    3162 infeas = TRUE;
    3163 SCIPrationalSetInfinity(lowerbound);
    3164 }
    3165 else if( nodedata->leftinfeas )
    3166 SCIPrationalSetRational(lowerbound, nodedata->derbound_right);
    3167 else if( nodedata->rightinfeas )
    3168 SCIPrationalSetRational(lowerbound, nodedata->derbound_left);
    3169 else
    3170 SCIPrationalMin(lowerbound, nodedata->derbound_left, nodedata->derbound_right);
    3171
    3172 if( SCIPrationalIsInfinity(nodedata->derbound_left) && SCIPrationalIsInfinity(nodedata->derbound_right) )
    3173 infeas = TRUE;
    3174
    3175 certificate->indexcounter++;
    3176 certificate->lastinfo->isbound = FALSE;
    3177
    3178 SCIPcertificatePrintProofMessage(certificate, "UnsplitNode%d_%d ", SCIPnodeGetNumber(node), certificate->indexcounter - 1);
    3179
    3180 if( infeas )
    3181 {
    3182 SCIPcertificatePrintProofMessage(certificate, "G 1 0");
    3183 }
    3184 else
    3185 {
    3186 SCIPcertificatePrintProofMessage(certificate, "G ");
    3187 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, lowerbound) );
    3188 SCIPcertificatePrintProofMessage(certificate, " ");
    3189 SCIPcertificatePrintProofMessage(certificate, "OBJ");
    3190 }
    3191
    3192 assert(nodedata->derindex_right < certificate->indexcounter - 1);
    3193 assert(nodedata->derindex_left < certificate->indexcounter - 1);
    3194 assert(SCIPrationalIsGE(lowerbound, SCIPnodeGetLowerboundExact(node)));
    3195 assert(SCIPrationalIsGEReal(lowerbound, SCIPnodeGetLowerbound(node)));
    3196
    3197 SCIPcertificatePrintProofMessage(certificate, " { uns %d %d %d %d } -1\n", nodedata->derindex_left, nodedata->assumptionindex_left,
    3198 nodedata->derindex_right, nodedata->assumptionindex_right);
    3199
    3200 SCIP_CALL( SCIPcertificateUpdateParentData(certificate, node, certificate->indexcounter - 1, lowerbound) );
    3201 }
    3202 else
    3203 {
    3204 SCIPdebugMessage("Node %lld is a leaf! \n", SCIPnodeGetNumber(node));
    3205 /* if a leaf has an inherited bound, we need to print a bound for it and update the parent data
    3206 don't do it if we interrupted the solve, e.g. due to timeout */
    3207 if( nodedata->inheritedbound && nodedata->assumptionindex_self != - 1 )
    3208 {
    3209 SCIP_Longint ind[1];
    3210 SCIP_RATIONAL* val;
    3211
    3212 ind[0] = nodedata->derindex_self;
    3213
    3214 (void) SCIPrationalCreateBuffer(set->buffer, &val);
    3215
    3216 SCIPrationalSetRational(lowerbound, nodedata->derbound_self);
    3217 SCIPrationalSetFraction(val, 1LL, 1LL);
    3218
    3219 SCIP_CALL( certificatePrintDualbound(certificate, NULL, lowerbound, 1, ind, &val) );
    3220 SCIP_CALL( SCIPcertificateUpdateParentData(certificate, node, certificate->indexcounter - 1, lowerbound) );
    3221
    3222 SCIPrationalFreeBuffer(set->buffer, &val);
    3223 }
    3224 }
    3225
    3226 SCIP_CALL( certificateFreeNodeData(certificate, node) );
    3227
    3228 SCIPrationalFreeBuffer(set->buffer, &lowerbound);
    3229
    3230 return SCIP_OKAY;
    3231}
    3232
    3233/** prints RTP section with lowerbound and upperbound range */
    3235 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3236 SCIP_Bool isorigfile, /**< should the original solution be printed or in transformed space */
    3237 SCIP_RATIONAL* lowerbound, /**< pointer to lower bound on the objective */
    3238 SCIP_RATIONAL* upperbound /**< pointer to upper bound on the objective */
    3239 )
    3240{
    3241 /* check whether certificate output should be created */
    3242 if( !SCIPcertificateIsEnabled(certificate) )
    3243 return SCIP_OKAY;
    3244
    3245 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "RTP range ");
    3246 if( SCIPrationalIsNegInfinity(lowerbound) )
    3247 {
    3248 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "-inf");
    3249 }
    3250 else
    3251 {
    3252 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, lowerbound) );
    3253 }
    3254
    3255 SCIPcertificatePrintProblemMessage(certificate, isorigfile, " ");
    3256 if( SCIPrationalIsInfinity(upperbound) )
    3257 {
    3258 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "inf");
    3259 }
    3260 else
    3261 {
    3262 SCIP_CALL( SCIPcertificatePrintProblemRational(certificate, isorigfile, upperbound) );
    3263 }
    3264 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "\n");
    3265
    3266 return SCIP_OKAY;
    3267 }
    3268
    3269/** prints RTP section for infeasibility */
    3271 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3272 SCIP_Bool isorigfile /**< should the original solution be printed or in transformed space */
    3273 )
    3274{
    3275 /* check whether certificate output should be created */
    3276 if( !SCIPcertificateIsEnabled(certificate) )
    3277 return;
    3278
    3279 SCIPcertificatePrintProblemMessage(certificate, isorigfile, "RTP infeas\n");
    3280 }
    3281
    3282/** sets the last bound index for the certificate */
    3284 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3285 SCIP_Longint index /**< index of new bound */
    3286 )
    3287{
    3288 assert(index >= 0);
    3289
    3290 if( SCIPcertificateIsEnabled(certificate) )
    3291 certificate->lastboundindex = index;
    3292
    3293 return SCIP_OKAY;
    3294}
    3295
    3296/** returns the last bound index for the certificate */
    3298 SCIP_CERTIFICATE* certificate /**< certificate data structure */
    3299 )
    3300{
    3301 return SCIPcertificateIsEnabled(certificate) ? certificate->lastboundindex : -1;
    3302}
    3303
    3304/** prints a proof that boundchange is leads to infeasibility */
    3306 SCIP* scip, /**< SCIP data structure */
    3307 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3308 SCIP_VAR* var, /**< variable */
    3309 SCIP_RATIONAL* lb, /**< lower bound */
    3310 SCIP_RATIONAL* ub, /**< upper bound */
    3311 SCIP_Longint lbindex, /**< index of the lower bound */
    3312 SCIP_Longint ubindex /**< index of the upper bound */
    3313 )
    3314{
    3315 SCIP_RATIONAL* lowerbound;
    3316
    3317 if( !SCIPisCertified(scip) )
    3318 return SCIP_OKAY;
    3319
    3320 assert(certificate != NULL);
    3321
    3322 switch( var->varstatus )
    3323 {
    3327 SCIPABORT();
    3328 return SCIP_ERROR;
    3330 if( lb != NULL )
    3331 {
    3332 SCIPrationalMultReal(lb, lb, -1);
    3333 SCIPrationalAddReal(lb, lb, 1.0);
    3334 }
    3335 if( ub != NULL )
    3336 {
    3337 SCIPrationalMultReal(ub, ub, -1);
    3338 SCIPrationalAddReal(ub, ub, 1.0);
    3339 }
    3340 assert( SCIPvarGetNegationConstant(var) == 1 );
    3341 SCIP_CALL( SCIPcertificatePrintCutoffConflictingBounds(scip, certificate, var->negatedvar, ub, lb, ubindex, lbindex) );
    3342 if( lb != NULL )
    3343 {
    3344 SCIPrationalAddReal(lb, lb, -1.0);
    3345 SCIPrationalMultReal(lb, lb, -1);
    3346 }
    3347 if( ub != NULL )
    3348 {
    3349 SCIPrationalAddReal(ub, ub, -1.0);
    3350 SCIPrationalMultReal(ub, ub, -1);
    3351 }
    3352 return SCIP_OKAY;
    3354 {
    3355 if( lb != NULL )
    3357 if( ub != NULL )
    3359
    3362 SCIP_CALL( SCIPcertificatePrintCutoffConflictingBounds(scip, certificate, var->data.aggregate.var, swapBounds ? ub : lb, swapBounds ? lb : ub, swapBounds ? ubindex : lbindex, swapBounds ? lbindex : ubindex) );
    3363 if( lb != NULL )
    3365 if( ub != NULL )
    3367 }
    3368 return SCIP_OKAY;
    3370 break;
    3371 default:
    3372 SCIPABORT();
    3373 return SCIP_ERROR;
    3374 }
    3375
    3376 if( lb == NULL )
    3377 {
    3378 lb = SCIPvarGetLbLocalExact(var);
    3379 lbindex = SCIPvarGetLbCertificateIndexLocal(var);
    3380 }
    3381 if( ub == NULL )
    3382 {
    3383 ub = SCIPvarGetUbLocalExact(var);
    3384 ubindex = SCIPvarGetUbCertificateIndexLocal(var);
    3385 }
    3386 assert( SCIPrationalIsGT(lb, ub) );
    3388
    3389 SCIPcertificatePrintProofMessage(certificate, "BoundConflict%d ", certificate->indexcounter);
    3390 SCIPcertificatePrintProofMessage(certificate, "G ");
    3391 SCIPrationalDiff(lowerbound, lb, ub);
    3392 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, lowerbound) );
    3393 SCIPcertificatePrintProofMessage(certificate, " 0 { lin 2 %d 1 %d -1 } -1\n", lbindex, ubindex);
    3394
    3395 SCIPrationalFreeBuffer(SCIPbuffer(scip), &lowerbound);
    3396
    3398 certificate->indexcounter++;
    3399
    3400 return SCIP_OKAY;
    3401}
    3402
    3403/** prints a proof for a new global bound */
    3405 SCIP* scip, /**< SCIP data structure */
    3406 SCIP_CERTIFICATE* certificate, /**< SCIP certificate */
    3407 SCIP_VAR* var, /**< variable */
    3408 SCIP_BOUNDTYPE boundtype, /**< Whether we have an upper bound or a lower bound */
    3409 SCIP_RATIONAL* value, /**< value of the bound */
    3410 SCIP_Longint certificateindex /**< index in the certificate */
    3411 )
    3412{
    3413 SCIP_RETCODE res;
    3414
    3415 if( !SCIPisCertified(scip) )
    3416 return SCIP_OKAY;
    3417
    3418 assert(certificate != NULL);
    3419
    3420 switch( var->varstatus )
    3421 {
    3425 SCIPABORT();
    3426 return SCIP_ERROR;
    3428 SCIPrationalMultReal(value, value, -1);
    3429 assert( SCIPvarGetNegationConstant(var) == 1 );
    3430 SCIPrationalAddReal(value, value, 1.0);
    3431 res = SCIPcertificatePrintGlobalBound(scip, certificate, var->negatedvar, boundtype == SCIP_BOUNDTYPE_UPPER ? SCIP_BOUNDTYPE_LOWER : SCIP_BOUNDTYPE_UPPER, value, certificateindex);
    3432 SCIPrationalAddReal(value, value, -1.0);
    3433 SCIPrationalMultReal(value, value, -1);
    3434 return res;
    3435 break;
    3437 SCIPrationalDiv(value, value, var->exactdata->aggregate.scalar);
    3440 SCIPrationalMult(value, value, var->exactdata->aggregate.scalar);
    3441 return res;
    3442 break;
    3444 break;
    3445 default:
    3446 SCIPABORT();
    3447 return SCIP_ERROR;
    3448 }
    3449
    3450#ifndef NDEBUG
    3451 certificate->lastinfo->isbound = TRUE;
    3452 certificate->lastinfo->boundtype = boundtype;
    3453 certificate->lastinfo->varindex = SCIPvarGetCertificateIndex(var);
    3454 certificate->lastinfo->isglobal = TRUE;
    3455 certificate->lastinfo->certificateindex = certificate->indexcounter;
    3456 SCIPrationalSetRational(certificate->lastinfo->boundval, value);
    3457#endif
    3458
    3459 SCIPcertificatePrintProofMessage(certificate, "GlobalBound_%d %c ", certificate->indexcounter,
    3460 boundtype == SCIP_BOUNDTYPE_UPPER ? 'L' : 'G');
    3461 SCIP_CALL( SCIPcertificatePrintProofRational(certificate, value) );
    3462 SCIPcertificatePrintProofMessage(certificate, " 1 %d 1 ", SCIPvarGetCertificateIndex(var));
    3463 SCIPcertificatePrintProofMessage(certificate, "{ lin 1 %d 1 } -1 global\n", certificateindex);
    3464
    3465 certificate->indexcounter++;
    3466 return SCIP_OKAY;
    3467}
    3468
    3469/* prints information for constraint to certificate file */
    3471 SCIP* scip, /**< SCIP data structure */
    3472 SCIP_CONS* cons /**< constraint */
    3473 )
    3474{
    3475 SCIP_CERTIFICATE* certificate;
    3476 SCIP_ROWEXACT* row;
    3477 SCIP_RATIONAL* correctedside;
    3478 int* varsindex = NULL;
    3479 int i;
    3480 SCIP_Longint image;
    3481 SCIP_RATIONAL* lhs;
    3482 SCIP_RATIONAL* rhs;
    3483
    3484 /*lint --e{715}*/
    3485 assert(scip != NULL);
    3486 assert(cons != NULL);
    3487
    3488 /* print constraint into certificate output */
    3489 if( !SCIPisCertified(scip) )
    3490 return SCIP_OKAY;
    3491 certificate = SCIPgetCertificate(scip);
    3492 row = SCIPgetRowExactExactLinear(scip, cons);
    3493
    3494 lhs = SCIProwExactGetLhs(row);
    3495 rhs = SCIProwExactGetRhs(row);
    3496
    3497 assert(row != NULL);
    3498
    3499 image = SCIPhashmapGetImageLong(certificate->rowdatahash, row);
    3500 /* add row to hashmap */
    3501 if( image != SCIP_LONGINT_MAX )
    3502 {
    3503 SCIPmessageFPrintWarning(scip->messagehdlr, "%lu \n", (size_t) SCIPhashmapGetImage(certificate->rowdatahash, row));
    3504 SCIPerrorMessage("Duplicate row in certificate row hashmap\n");
    3505 SCIPABORT();
    3506 return SCIP_ERROR;
    3507 }
    3508 else
    3509 {
    3510 SCIP_CALL( SCIPhashmapInsertLong(certificate->rowdatahash, row, certificate->indexcounter) );
    3511 SCIP_CALL( SCIPhashmapInsertLong(certificate->rowdatahash, cons, certificate->indexcounter) );
    3512 assert(SCIPhashmapExists(certificate->rowdatahash, row));
    3513 assert(SCIPhashmapExists(certificate->rowdatahash, cons));
    3514 }
    3515
    3517 for( i = 0; i < SCIProwExactGetNNonz(row); ++i )
    3519
    3521
    3522 /* print constraint */
    3523 if( SCIPrationalIsEQ(lhs, rhs) )
    3524 {
    3525 assert(!SCIPrationalIsAbsInfinity(lhs));
    3527 SCIP_CALL( SCIPcertificatePrintCons(certificate, FALSE, NULL, 'E', correctedside, SCIProwExactGetNNonz(row), varsindex, SCIProwExactGetVals(row)) );
    3528 }
    3529 else
    3530 {
    3531 if( !SCIPrationalIsNegInfinity(lhs) )
    3532 {
    3534 SCIP_CALL( SCIPcertificatePrintCons(certificate, FALSE, NULL, 'G', correctedside, SCIProwExactGetNNonz(row), varsindex, SCIProwExactGetVals(row)) );
    3535 }
    3536 if( !SCIPrationalIsInfinity(rhs) )
    3537 {
    3539 SCIP_CALL( SCIPcertificatePrintCons(certificate, FALSE, NULL, 'L', correctedside, SCIProwExactGetNNonz(row), varsindex, SCIProwExactGetVals(row)) );
    3540 }
    3541 }
    3542
    3543 SCIPrationalFreeBuffer(SCIPbuffer(scip), &correctedside);
    3544 SCIPfreeBufferArray(scip, &varsindex);
    3545
    3546 return SCIP_OKAY;
    3547}
    3548
    3549/** returns the index of the given constraint in the certificate */
    3551 SCIP_CERTIFICATE* certificate, /**< certificate data structure */
    3552 SCIP_CONS* cons, /**< constraint */
    3553 SCIP_RATIONAL* lhs, /**< lhs of the constraint */
    3554 SCIP_RATIONAL* rhs, /**< rhs of the constraint */
    3555 SCIP_Bool useRhs /**< whether to return the index of the rhs or lhs */
    3556 )
    3557{
    3558 SCIP_Longint ret;
    3559
    3560 ret = SCIPhashmapGetImageLong(certificate->rowdatahash, cons);
    3561
    3562 assert( ret != SCIP_LONGINT_MAX );
    3563 if( !SCIPrationalIsAbsInfinity(rhs) && !SCIPrationalIsAbsInfinity(lhs) && !SCIPrationalIsEQ(lhs, rhs) && useRhs)
    3564 ret += 1;
    3565
    3566 assert(ret >= 0);
    3567
    3568 return ret;
    3569}
    static long bound
    SCIP_RETCODE SCIPcertificatePrintInheritedBound(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_NODE *node)
    SCIP_RETCODE SCIPcertificatePrintAggrrow(SCIP_SET *set, SCIP_PROB *prob, SCIP_CERTIFICATE *certificate, SCIP_AGGRROW *aggrrow, SCIP_ROW **aggrrows, SCIP_Real *weights, int naggrrows, SCIP_Bool local, SCIP_Longint *certificateline)
    #define SCIP_MB_TO_CHAR_RATE
    Definition: certificate.cpp:78
    SCIP_RETCODE SCIPcertificatePrintDualboundPseudo(SCIP_CERTIFICATE *certificate, SCIP_LPEXACT *lpexact, SCIP_NODE *node, SCIP_SET *set, SCIP_PROB *prob, SCIP_Bool lowerchanged, int modifiedvarindex, SCIP_Longint boundchangeindex, SCIP_Real psval)
    SCIP_RETCODE SCIPcertificatePrintResult(SCIP *scip, SCIP_Bool isorigfile, SCIP_SET *set, SCIP_CERTIFICATE *certificate)
    #define SCIP_HASHSIZE_CERTIFICATE
    Definition: certificate.cpp:77
    SCIP_RETCODE SCIPconsPrintCertificateExactLinear(SCIP *scip, SCIP_CONS *cons)
    void SCIPcertificateFree(SCIP_CERTIFICATE **certificate)
    static SCIP_RETCODE certificatePrintWeakDerStart(SCIP_CERTIFICATE *certificate, SCIP_PROB *prob, SCIP_Bool local)
    SCIP_CERTIFICATE * SCIPgetCertificate(SCIP *scip)
    static SCIP_RETCODE certificatePrintSol(SCIP *scip, SCIP_Bool isorigfile, SCIP_CERTIFICATE *certificate, SCIP_SOL *sol)
    SCIP_RETCODE SCIPcertificateNewNodeData(SCIP_CERTIFICATE *certificate, SCIP_STAT *stat, SCIP_NODE *node)
    SCIP_RETCODE SCIPcertificateClearMirinfo(SCIP *scip)
    SCIP_Longint SCIPcertificateGetRowIndex(SCIP_CERTIFICATE *certificate, SCIP_ROWEXACT *row, SCIP_Bool rhs)
    static SCIP_RETCODE certificateFreeNodeData(SCIP_CERTIFICATE *certificate, SCIP_NODE *node)
    SCIP_RETCODE SCIPcertificatePrintMirCut(SCIP_SET *set, SCIP_LP *lp, SCIP_CERTIFICATE *certificate, SCIP_PROB *prob, SCIP_ROW *row, const char sense)
    SCIP_RETCODE SCIPcertificateUpdateParentData(SCIP_CERTIFICATE *certificate, SCIP_NODE *node, SCIP_Longint fileindex, SCIP_RATIONAL *newbound)
    SCIP_RETCODE SCIPcertificateInitTransFile(SCIP *scip)
    SCIP_RETCODE SCIPcertificateSetLastBoundIndex(SCIP_CERTIFICATE *certificate, SCIP_Longint index)
    static void concatenateCertificate(SCIP_CERTIFICATE *certificate)
    static SCIP_RETCODE certificatePrintDualbound(SCIP_CERTIFICATE *certificate, const char *linename, SCIP_RATIONAL *lowerbound, int len, SCIP_Longint *ind, SCIP_RATIONAL **val)
    SCIP_RETCODE SCIPcertificateFreeMirInfo(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_LP *lp, SCIP_MIRINFO *mirinfo, SCIP_ROW *row)
    void SCIPcertificatePrintRtpInfeas(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile)
    void SCIPcertificatePrintVersionHeader(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile)
    void SCIPcertificatePrintDerHeader(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile)
    static SCIP_RETCODE certificatePrintMirSplit(SCIP_SET *set, SCIP_PROB *prob, SCIP_CERTIFICATE *certificate, SCIP_ROW *row)
    SCIP_RETCODE SCIPcertificateUpdateBoundData(SCIP_CERTIFICATE *certificate, SCIP_NODE *node, SCIP_Longint fileindex, SCIP_RATIONAL *newbound)
    SCIP_RETCODE SCIPcertificateSaveFinalbound(SCIP *scip, SCIP_CERTIFICATE *certificate)
    SCIP_RETCODE SCIPcertificatePrintDualboundExactLP(SCIP_CERTIFICATE *certificate, SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_NODE *node, SCIP_PROB *prob, SCIP_Bool usefarkas)
    SCIP_RETCODE SCIPcertificatePrintGlobalBound(SCIP *scip, SCIP_CERTIFICATE *certificate, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_RATIONAL *value, SCIP_Longint certificateindex)
    static SCIP_Longint printBoundAssumption(SCIP_CERTIFICATE *certificate, SCIP_VAR *var, SCIP_RATIONAL *boundval, SCIP_BOUNDTYPE boundtype)
    SCIP_Longint SCIPcertificateGetLastBoundIndex(SCIP_CERTIFICATE *certificate)
    SCIP_RETCODE SCIPcertificatePrintProofRational(SCIP_CERTIFICATE *certificate, SCIP_RATIONAL *val)
    SCIP_Bool SCIPcertificateIsEnabled(SCIP_CERTIFICATE *certificate)
    static SCIP_Bool certificateIsLeftNode(SCIP_CERTIFICATE *certificate, SCIP_NODE *node)
    Definition: certificate.cpp:96
    SCIP_RETCODE SCIPcertificatePrintCutoffBound(SCIP *scip, SCIP_CERTIFICATE *certificate, SCIP_RATIONAL *bound, SCIP_Longint *certificateline)
    SCIP_Longint SCIPcertificateGetConsIndex(SCIP_CERTIFICATE *certificate, SCIP_CONS *cons, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool useRhs)
    void SCIPcertificatePrintConsHeader(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, int nconss, int nboundconss)
    SCIP_RETCODE SCIPcertificateClearAggrinfo(SCIP *scip)
    void SCIPcertificatePrintIntHeader(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, int nintvars)
    SCIP_RETCODE SCIPcertificateExit(SCIP *scip)
    SCIP_Longint SCIPcertificateGetCurrentIndex(SCIP_CERTIFICATE *certificate)
    SCIP_RETCODE SCIPcertificatePrintUnsplitting(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_NODE *node)
    SCIP_RETCODE SCIPcertificateInit(SCIP *scip, SCIP_CERTIFICATE *certificate, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
    SCIP_Bool SCIPcertificateEnsureLastBoundInfoConsistent(SCIP_CERTIFICATE *certificate, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real newbound, SCIP_Bool needsglobal)
    SCIP_RETCODE SCIPcertificateFreeRowInfo(SCIP *scip, SCIP_ROW *row)
    SCIP_RETCODE SCIPcertificateFreeAggrInfo(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_LP *lp, SCIP_AGGREGATIONINFO *aggrinfo, SCIP_ROW *row)
    SCIP_RETCODE SCIPcertificateSetAndPrintObjective(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, BMS_BLKMEM *blkmem, SCIP_RATIONAL **coefs, int nvars)
    SCIP_RETCODE SCIPcertificatePrintCutoffConflictingBounds(SCIP *scip, SCIP_CERTIFICATE *certificate, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_Longint lbindex, SCIP_Longint ubindex)
    SCIP_RETCODE SCIPcertificatePrintBoundCons(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, const char *boundname, SCIP_VAR *var, SCIP_RATIONAL *boundval, SCIP_Bool isupper)
    SCIP_RETCODE SCIPcertificateCreate(SCIP_CERTIFICATE **certificate, SCIP_MESSAGEHDLR *messagehdlr)
    SCIP_Real SCIPcertificateGetFilesize(SCIP_CERTIFICATE *certificate)
    SCIP_RETCODE SCIPcertificatePrintCons(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, const char *consname, const char sense, SCIP_RATIONAL *side, int len, int *ind, SCIP_RATIONAL **val)
    void SCIPcertificatePrintProofMessage(SCIP_CERTIFICATE *certificate, const char *formatstr,...)
    static SCIP_RETCODE certificatePrintRow(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_ROWEXACT *rowexact, SCIP_Real alternativerhs)
    SCIP_RETCODE SCIPcertificatePrintRtpRange(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, SCIP_RATIONAL *lowerbound, SCIP_RATIONAL *upperbound)
    void SCIPcertificatePrintProblemComment(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, const char *formatstr,...)
    SCIP_RETCODE SCIPcertificateUpdateBranchingData(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_STAT *stat, SCIP_LP *lp, SCIP_NODE *node, SCIP_VAR *branchvar, SCIP_BOUNDTYPE boundtype, SCIP_Real newbound)
    SCIP_RETCODE SCIPcertificateNewAggrInfo(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_ROW **aggrrows, SCIP_Real *weights, int naggrrows, SCIP_ROW **negslackrows, SCIP_Real *negslackweights, int nnegslackrows)
    void SCIPcertificatePrintProofComment(SCIP_CERTIFICATE *certificate, const char *formatstr,...)
    SCIP_RETCODE SCIPcertificateNewMirInfo(SCIP *scip)
    void SCIPcertificatePrintProblemMessage(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, const char *formatstr,...)
    SCIP_RETCODE SCIPcertificatePrintProblemRational(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, SCIP_RATIONAL *val)
    void SCIPcertificatePrintVarHeader(SCIP_CERTIFICATE *certificate, SCIP_Bool isorigfile, int nvars)
    static SCIP_Bool checkAndUpdateFilesize(SCIP_CERTIFICATE *certificate, SCIP_Real nchars)
    Definition: certificate.cpp:82
    methods for certificate output
    Constraint handler for linear constraints in their most general form, .
    methods for the aggregation rows
    common defines and data types used in all packages of SCIP
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #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_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    size_t SCIPfwrite(const void *ptr, size_t size, size_t nmemb, SCIP_FILE *stream)
    Definition: fileio.c:168
    int SCIPfprintf(SCIP_FILE *stream, const char *format,...)
    Definition: fileio.c:173
    size_t SCIPfread(void *ptr, size_t size, size_t nmemb, SCIP_FILE *stream)
    Definition: fileio.c:163
    int SCIPfclose(SCIP_FILE *fp)
    Definition: fileio.c:232
    int SCIPfputs(const char *s, SCIP_FILE *stream)
    Definition: fileio.c:190
    static const NodeData nodedata[]
    Definition: gastrans.c:83
    SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcertifyConsOrigExactLinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS *cons)
    SCIP_ROWEXACT * SCIPgetRowExactExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    SCIP_RETCODE SCIPgetOrigVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2753
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNOrigConss(SCIP *scip)
    Definition: scip_prob.c:3712
    SCIP_CONS ** SCIPgetConss(SCIP *scip)
    Definition: scip_prob.c:3666
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
    Definition: scip_prob.c:3739
    SCIP_Bool SCIPisObjIntegral(SCIP *scip)
    Definition: scip_prob.c:1801
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3366
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3466
    SCIP_Bool SCIPhashmapIsEmpty(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3566
    SCIP_RETCODE SCIPhashmapInsertLong(SCIP_HASHMAP *hashmap, void *origin, SCIP_Longint image)
    Definition: misc.c:3215
    SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3676
    SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3482
    SCIP_Longint SCIPhashmapGetImageLong(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3324
    SCIP_RETCODE SCIPlpiExactGetObjval(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval)
    SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
    Definition: scip_message.c:88
    SCIP_Bool SCIPrealIsExactlyIntegral(SCIP_Real val)
    Definition: misc.c:9604
    SCIP_Bool SCIPisCertified(SCIP *scip)
    SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
    Definition: lp.c:17425
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_RETCODE SCIPaggrRowCopy(SCIP *scip, SCIP_AGGRROW **aggrrow, SCIP_AGGRROW *source)
    Definition: cuts.c:2758
    SCIP_Real SCIPaggrRowGetRhs(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4068
    void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
    Definition: cuts.c:2700
    int * SCIPaggrRowGetInds(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4028
    void SCIPaggrRowPrint(SCIP *scip, SCIP_AGGRROW *aggrrow, FILE *file)
    Definition: cuts.c:2721
    int SCIPaggrRowGetNNz(SCIP_AGGRROW *aggrrow)
    Definition: cuts.c:4038
    static INLINE SCIP_Real SCIPaggrRowGetValueSafely(SCIP_AGGRROW *aggrrow, int i)
    Definition: cuts.h:287
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPconstructLP(SCIP *scip, SCIP_Bool *cutoff)
    Definition: scip_lp.c:130
    SCIP_Bool SCIPisLPConstructed(SCIP *scip)
    Definition: scip_lp.c:105
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocClearBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:97
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
    Definition: tree.c:8473
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_RATIONAL * SCIPnodeGetLowerboundExact(SCIP_NODE *node)
    Definition: tree.c:8513
    SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
    Definition: tree.c:8483
    SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
    Definition: tree.c:8782
    void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1342
    SCIP_Bool SCIPrationalRoundLong(SCIP_Longint *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2204
    SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:108
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:618
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2085
    SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
    Definition: rational.cpp:796
    void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:461
    int SCIPrationalToString(SCIP_RATIONAL *rational, char *str, int strlen)
    Definition: rational.cpp:1743
    SCIP_RETCODE SCIPrationalCreateBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:196
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalRoundInteger(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2158
    void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1132
    SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1680
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1503
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1474
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:983
    SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1640
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1173
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1606
    SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1691
    SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1512
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:630
    void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
    Definition: rational.cpp:582
    void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1297
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1650
    void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1009
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1660
    void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
    Definition: rational.cpp:501
    SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2110
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:214
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1670
    void SCIPrationalDivReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1147
    SCIP_RETCODE SCIPrationalReallocBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:344
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1404
    void SCIPrationalDiffProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1239
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:518
    void SCIPrationalAddReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:961
    int SCIPrationalStrLen(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1774
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
    Definition: lp.c:17632
    SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
    Definition: lp.c:17696
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
    Definition: lp.c:17652
    SCIP_ROWEXACT * SCIProwGetRowExact(SCIP_ROW *row)
    Definition: lp.c:17959
    SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
    Definition: lp.c:17642
    SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
    Definition: lp.c:17825
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    SCIP_RETCODE SCIPmakeSolExact(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:3146
    SCIP_RETCODE SCIPretransformSolExact(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:3245
    SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
    Definition: sol.c:4150
    SCIP_Bool SCIPisInRestart(SCIP *scip)
    Definition: scip_solve.c:3709
    SCIP_Bool SCIPisPrimalboundSol(SCIP *scip)
    void SCIPgetUpperboundExact(SCIP *scip, SCIP_RATIONAL *result)
    void SCIPgetPrimalboundExact(SCIP *scip, SCIP_RATIONAL *result)
    void SCIPgetLowerboundExact(SCIP *scip, SCIP_RATIONAL *result)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_Longint SCIPvarGetUbCertificateIndexLocal(SCIP_VAR *var)
    Definition: var.c:25188
    void SCIPvarSetLbCertificateIndexGlobal(SCIP_VAR *var, SCIP_Longint certidx)
    Definition: var.c:25162
    SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
    Definition: var.c:23889
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_Longint SCIPvarGetUbCertificateIndexGlobal(SCIP_VAR *var)
    Definition: var.c:25212
    void SCIPvarSetCertificateIndex(SCIP_VAR *var, int certidx)
    Definition: var.c:25109
    int SCIPvarGetCertificateIndex(SCIP_VAR *var)
    Definition: var.c:25098
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Longint SCIPvarGetLbCertificateIndexGlobal(SCIP_VAR *var)
    Definition: var.c:25200
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RATIONAL * SCIPvarGetUbLocalExact(SCIP_VAR *var)
    Definition: var.c:24278
    void SCIPvarSetUbCertificateIndexGlobal(SCIP_VAR *var, SCIP_Longint certidx)
    Definition: var.c:25122
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Longint SCIPvarGetLbCertificateIndexLocal(SCIP_VAR *var)
    Definition: var.c:25176
    SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24130
    SCIP_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
    Definition: var.c:24244
    SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
    Definition: var.c:23910
    SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
    Definition: var.c:24152
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    void SCIProwCapture(SCIP_ROW *row)
    Definition: lp.c:5554
    SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
    Definition: lp.c:18016
    int SCIPlpGetNRows(SCIP_LP *lp)
    Definition: lp.c:18026
    SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:5567
    internal methods for LP management
    SCIP_COLEXACT ** SCIProwExactGetCols(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5026
    SCIP_RATIONAL * SCIProwExactGetRhs(SCIP_ROWEXACT *row)
    Definition: lpexact.c:6266
    void SCIProwExactPrint(SCIP_ROWEXACT *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
    Definition: lpexact.c:4953
    SCIP_ROW * SCIProwExactGetRow(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5069
    SCIP_RATIONAL * SCIProwExactGetConstant(SCIP_ROWEXACT *row)
    Definition: lpexact.c:6277
    SCIP_VAR * SCIPcolExactGetVar(SCIP_COLEXACT *col)
    Definition: lpexact.c:6052
    SCIP_RATIONAL * SCIProwExactGetLhs(SCIP_ROWEXACT *row)
    Definition: lpexact.c:6255
    void SCIPlpExactGetPseudoObjval(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_RATIONAL *res)
    Definition: lpexact.c:7438
    SCIP_RATIONAL ** SCIProwExactGetVals(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5016
    void SCIPlpExactGetObjval(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_RATIONAL *res)
    Definition: lpexact.c:7416
    int SCIProwExactGetNNonz(SCIP_ROWEXACT *row)
    Definition: lpexact.c:5006
    internal methods for exact LP management
    interface methods for specific exact LP solvers
    memory allocation routines
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSfreeMemoryArray(ptr)
    Definition: memory.h:147
    #define BMScopyMemoryArray(ptr, source, num)
    Definition: memory.h:134
    #define BMSfreeBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:467
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    void SCIPmessageFPrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:451
    void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
    Definition: message.c:678
    internal miscellaneous methods
    int SCIPprobGetNObjVars(SCIP_PROB *prob, SCIP_SET *set)
    Definition: prob.c:2423
    SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
    Definition: prob.c:2813
    int SCIPprobGetNVars(SCIP_PROB *prob)
    Definition: prob.c:2868
    SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
    Definition: prob.c:2913
    internal methods for storing and manipulating the main problem
    public methods for managing constraints
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    public methods for branch and bound tree
    public methods for problem variables
    public methods for certified solving
    public methods for exact solving
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for global and local (sub)problems
    public methods for the probing mode
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    public methods for the branch-and-bound tree
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    internal methods for global SCIP settings
    #define SCIPsetFreeBufferArray(set, ptr)
    Definition: set.h:1782
    #define SCIPsetAllocBufferArray(set, ptr, num)
    Definition: set.h:1775
    void SCIPsolGetValExact(SCIP_RATIONAL *res, SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
    Definition: sol.c:2039
    internal methods for storing primal CIP solutions
    SCIP_RATIONAL * scalar
    Definition: struct_var.h:218
    SCIP_RATIONAL * constant
    Definition: struct_var.h:219
    SCIP_VAR * var
    Definition: struct_var.h:212
    SCIP_RATIONAL * boundval
    SCIP_Longint lastboundindex
    SCIP_Longint indexcounter_ori
    SCIP_FILE * derivationfile
    SCIP_Longint indexcounter
    SCIP_HASHMAP * nodedatahash
    SCIP_Longint nmirinfos
    SCIP_MIRINFO ** mirinfo
    SCIP_Longint conscounter
    SCIP_RATIONAL * rootbound
    SCIP_CERTIFICATEBOUND * lastinfo
    SCIP_HASHMAP * mirinfohash
    SCIP_Longint naggrinfos
    SCIP_Longint mirinfosize
    SCIP_Longint aggrinfosize
    SCIP_HASHMAP * rowdatahash
    SCIP_Longint derindex_root
    SCIP_AGGREGATIONINFO ** aggrinfo
    SCIP_RATIONAL ** vals
    SCIP_RATIONAL * finalbound
    SCIP_Bool transfile_initialized
    SCIP_HASHMAP * aggrinfohash
    SCIP_Longint assumptionindex_left
    unsigned int rightfilled
    SCIP_Longint derindex_self
    unsigned int rightinfeas
    SCIP_RATIONAL * derbound_left
    SCIP_RATIONAL * derbound_self
    SCIP_RATIONAL * derbound_right
    SCIP_Longint assumptionindex_right
    SCIP_Longint derindex_left
    SCIP_Longint derindex_right
    SCIP_COL * fpcol
    SCIP_RATIONAL * farkascoef
    SCIP_RATIONAL * redcost
    SCIP_VAR * var
    SCIP_VAR * var
    Definition: struct_lp.h:162
    SCIP_RATIONAL * ub
    Definition: struct_var.h:185
    SCIP_RATIONAL * lb
    Definition: struct_var.h:184
    SCIP_Real lb
    Definition: struct_var.h:176
    SCIP_Real ub
    Definition: struct_var.h:177
    SCIP_COLEXACT ** cols
    SCIP_LPIEXACT * lpiexact
    SCIP_ROWEXACT ** rows
    SCIP_LP * fplp
    SCIP_RATIONAL * lpobjval
    SCIP_Bool diving
    Definition: struct_lp.h:386
    SCIP_Real * slackscale
    SCIP_Real * slackcoefficients
    SCIP_RATIONAL * frac
    SCIP_Longint arpos
    SCIP_ROW ** slackrows
    SCIP_Real * slackweight
    SCIP_Bool * upperused
    SCIP_Real * splitcoefficients
    SCIP_RATIONAL * rhs
    SCIP_Real * slackusedcoef
    SCIP_Real unroundedrhs
    SCIP_Bool * localbdused
    SCIP_Bool * slackroundeddown
    SCIP_ROW * fprow
    SCIP_RATIONAL * dualfarkas
    SCIP_RATIONAL * lhs
    SCIP_COLEXACT ** cols
    SCIP_RATIONAL * rhs
    SCIP_RATIONAL * dualsol
    char * name
    Definition: struct_lp.h:229
    SCIP_COL ** cols
    Definition: struct_lp.h:230
    SCIP_DOMEXACT glbdom
    Definition: struct_var.h:251
    SCIP_AGGREGATEEXACT aggregate
    Definition: struct_var.h:253
    SCIP_DOMEXACT locdom
    Definition: struct_var.h:250
    SCIP_AGGREGATE aggregate
    Definition: struct_var.h:286
    SCIP_VAR * negatedvar
    Definition: struct_var.h:298
    unsigned int varstatus
    Definition: struct_var.h:338
    SCIP_DOM glbdom
    Definition: struct_var.h:279
    char * name
    Definition: struct_var.h:291
    SCIP_VARDATAEXACT * exactdata
    Definition: struct_var.h:290
    SCIP_DOM locdom
    Definition: struct_var.h:280
    union SCIP_Var::@24 data
    int index
    Definition: struct_var.h:310
    data structures for certificate output
    data structures for exact LP management
    SCIP main data structure.
    datastructures for problem statistics
    datastructures for problem variables
    Definition: heur_padm.c:135
    @ SCIP_ROWORIGINTYPE_SEPA
    Definition: type_lp.h:76
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_VERBLEVEL_NORMAL
    Definition: type_message.h:60
    @ SCIP_R_ROUND_UPWARDS
    Definition: type_rational.h:58
    @ SCIP_R_ROUND_DOWNWARDS
    Definition: type_rational.h:57
    @ SCIP_FILECREATEERROR
    Definition: type_retcode.h:48
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STATUS_OPTIMAL
    Definition: type_stat.h:43
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    @ SCIP_NODETYPE_PROBINGNODE
    Definition: type_tree.h:42
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    internal methods for problem variables