Scippy

    SCIP

    Solving Constraint Integer Programs

    reader_lp.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file reader_lp.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief LP file reader
    28 * @author Tobias Achterberg
    29 * @author Marc Pfetsch
    30 * @author Stefan Heinz
    31 * @author Stefan Vigerske
    32 * @author Michael Winkler
    33 * @author Lars Schewe
    34 *
    35 * @todo write fixed (non-active) variables, e.g., for transformed problem
    36 */
    37
    38/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    39
    41#include <ctype.h>
    42#include "scip/cons_and.h"
    44#include "scip/cons_nonlinear.h"
    45#include "scip/cons_indicator.h"
    46#include "scip/cons_knapsack.h"
    47#include "scip/cons_linear.h"
    49#include "scip/cons_logicor.h"
    50#include "scip/cons_setppc.h"
    51#include "scip/cons_sos1.h"
    52#include "scip/cons_sos2.h"
    53#include "scip/cons_varbound.h"
    54#include "scip/pub_cons.h"
    55#include "scip/pub_fileio.h"
    56#include "scip/pub_message.h"
    57#include "scip/pub_misc.h"
    58#include "scip/pub_reader.h"
    59#include "scip/pub_var.h"
    60#include "scip/rational.h"
    61#include "scip/reader_lp.h"
    62#include "scip/scip_cons.h"
    63#include "scip/scip_exact.h"
    64#include "scip/scip_mem.h"
    65#include "scip/scip_message.h"
    66#include "scip/scip_numerics.h"
    67#include "scip/scip_param.h"
    68#include "scip/scip_prob.h"
    69#include "scip/scip_reader.h"
    70#include "scip/scip_var.h"
    71#include <stdlib.h>
    72#include <string.h>
    73
    74#define READER_NAME "lpreader"
    75#define READER_DESC "file reader for MIPs in IBM CPLEX's LP file format"
    76#define READER_EXTENSION "lp"
    77
    78#define DEFAULT_LINEARIZE_ANDS TRUE /**< Should possible \"and\"-constraints be linearized when writing the lp file? */
    79#define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< Should an aggregated linearization for and constraints be used? */
    80
    81/*
    82 * Data structures
    83 */
    84
    85#define LP_MAX_LINELEN 65536
    86#define LP_MAX_PUSHEDTOKENS 2
    87#define LP_INIT_COEFSSIZE 8192
    88#define LP_INIT_QUADCOEFSSIZE 16
    89#define LP_MAX_PRINTLEN 561 /**< the maximum length of any line is 560 + '\\0' = 561*/
    90#define LP_MAX_NAMELEN 256 /**< the maximum length for any name is 255 + '\\0' = 256 */
    91#define LP_PRINTLEN 100
    92
    93
    94/** LP reading data */
    95struct SCIP_ReaderData
    96{
    97 SCIP_Bool linearizeands;
    98 SCIP_Bool aggrlinearizationands;
    99};
    100
    101
    102/** Section in LP File */
    104{
    107typedef enum LpSection LPSECTION;
    108
    110{
    113typedef enum LpExpType LPEXPTYPE;
    114
    116{
    119typedef enum LpSense LPSENSE;
    120
    121/** LP reading data */
    122struct LpInput
    123{
    124 SCIP_FILE* file;
    125 char* linebuf;
    126 char probname[LP_MAX_LINELEN];
    127 char objname[LP_MAX_LINELEN];
    128 char* token;
    129 char* tokenbuf;
    130 char* pushedtokens[LP_MAX_PUSHEDTOKENS];
    131 int npushedtokens;
    132 int linenumber;
    133 int linepos;
    134 int linebufsize;
    135 LPSECTION section;
    136 SCIP_OBJSENSE objsense;
    137 SCIP_Bool inlazyconstraints; /**< whether we are currently reading the section for lazy constraints */
    138 SCIP_Bool inusercuts; /**< whether we are currently reading the section for user cuts */
    139 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
    140 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
    141 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
    142 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
    143 SCIP_Bool haserror;
    144};
    145typedef struct LpInput LPINPUT;
    146
    147static const char commentchars[] = "\\";
    148
    149
    150/*
    151 * Local methods (for reading)
    152 */
    153
    154/** issues an error message and marks the LP data to have errors */
    155static
    157 SCIP* scip, /**< SCIP data structure */
    158 LPINPUT* lpinput, /**< LP reading data */
    159 const char* msg /**< error message */
    160 )
    161{
    162 char formatstr[256];
    163
    164 assert(lpinput != NULL);
    165
    166 SCIPerrorMessage("Syntax error in line %d ('%s'): %s \n", lpinput->linenumber, lpinput->token, msg);
    167 if( lpinput->linebuf[lpinput->linebufsize - 1] == '\n' )
    168 {
    169 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", lpinput->linebuf);
    170 }
    171 else
    172 {
    173 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", lpinput->linebuf);
    174 }
    175 (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", lpinput->linepos);
    176 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, (const char*)formatstr, "^");
    177 lpinput->section = LP_END;
    178 lpinput->haserror = TRUE;
    179}
    180
    181/** returns whether a syntax error was detected */
    182static
    184 LPINPUT* lpinput /**< LP reading data */
    185 )
    186{
    187 assert(lpinput != NULL);
    188
    189 return lpinput->haserror;
    190}
    191
    192/** returns whether the given character is a token delimiter */
    193static
    195 char c /**< input character */
    196 )
    197{
    198 switch (c)
    199 {
    200 case ' ':
    201 case '\f':
    202 case '\n':
    203 case '\r':
    204 case '\t':
    205 case '\v':
    206 case '\0':
    207 return TRUE;
    208 default:
    209 return FALSE;
    210 }
    211}
    212
    213/** returns whether the given character is a single token */
    214static
    216 char c /**< input character */
    217 )
    218{
    219 switch (c)
    220 {
    221 case '-':
    222 case '+':
    223 case ':':
    224 case '<':
    225 case '>':
    226 case '=':
    227 case '[':
    228 case ']':
    229 case '*':
    230 case '^':
    231 return TRUE;
    232 default:
    233 return FALSE;
    234 }
    235}
    236
    237/** returns whether the current character is member of a value string */
    238static
    240 char c, /**< input character */
    241 char nextc, /**< next input character */
    242 SCIP_Bool firstchar, /**< is the given character the first char of the token? */
    243 SCIP_Bool* hasdot, /**< pointer to update the dot flag */
    244 LPEXPTYPE* exptype /**< pointer to update the exponent type */
    245 )
    246{
    247 assert(hasdot != NULL);
    248 assert(exptype != NULL);
    249
    250 if( isdigit((unsigned char)c) )
    251 return TRUE;
    252 else if( (*exptype == LP_EXP_NONE) && !(*hasdot) && (c == '.') && ( isdigit((unsigned char)nextc) || isspace((unsigned char)nextc) || nextc == 'e' || nextc == 'E') )
    253 { /* note: we allow for numbers like "24311." for which the next character should be a space or exponent sign */
    254 *hasdot = TRUE;
    255 return TRUE;
    256 }
    257 else if( !firstchar && (*exptype == LP_EXP_NONE) && (c == 'e' || c == 'E') )
    258 {
    259 if( nextc == '+' || nextc == '-' )
    260 {
    261 *exptype = LP_EXP_SIGNED;
    262 return TRUE;
    263 }
    264 else if( isdigit((unsigned char)nextc) )
    265 {
    266 *exptype = LP_EXP_UNSIGNED;
    267 return TRUE;
    268 }
    269 }
    270 else if( (*exptype == LP_EXP_SIGNED) && (c == '+' || c == '-') )
    271 {
    272 *exptype = LP_EXP_UNSIGNED;
    273 return TRUE;
    274 }
    275 else if( c == '/' && isdigit((unsigned char)nextc) )
    276 {
    277 return TRUE;
    278 }
    279 else if( (*exptype == LP_EXP_UNSIGNED) && isdigit((unsigned char)c) )
    280 {
    281 return TRUE;
    282 }
    283 else
    284 return FALSE;
    285
    286 return FALSE;
    287}
    288
    289/** reads the next line from the input file into the line buffer; skips comments;
    290 * returns whether a line could be read
    291 */
    292static
    294 SCIP* scip, /**< SCIP data structure */
    295 LPINPUT* lpinput /**< LP reading data */
    296 )
    297{
    298 int i;
    299
    300 assert(lpinput != NULL);
    301
    302 /* read next line */
    303 lpinput->linepos = 0;
    304 lpinput->linebuf[lpinput->linebufsize - 2] = '\0';
    305
    306 if( SCIPfgets(lpinput->linebuf, lpinput->linebufsize, lpinput->file) == NULL )
    307 {
    308 /* clear the line, this is really necessary here! */
    309 BMSclearMemoryArray(lpinput->linebuf, lpinput->linebufsize);
    310
    311 return FALSE;
    312 }
    313
    314 lpinput->linenumber++;
    315
    316 /* if line is too long for our buffer reallocate buffer */
    317 while( lpinput->linebuf[lpinput->linebufsize - 2] != '\0' )
    318 {
    319 int newsize;
    320
    321 newsize = SCIPcalcMemGrowSize(scip, lpinput->linebufsize + 1);
    322 SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &lpinput->linebuf, lpinput->linebufsize, newsize) );
    323
    324 lpinput->linebuf[newsize-2] = '\0';
    325 if ( SCIPfgets(lpinput->linebuf + lpinput->linebufsize - 1, newsize - lpinput->linebufsize + 1, lpinput->file) == NULL )
    326 return FALSE;
    327 lpinput->linebufsize = newsize;
    328 }
    329 lpinput->linebuf[lpinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    330
    331 /* skip characters after comment symbol */
    332 for( i = 0; commentchars[i] != '\0'; ++i )
    333 {
    334 char* commentstart;
    335
    336 commentstart = strchr(lpinput->linebuf, commentchars[i]);
    337 if( commentstart != NULL )
    338 {
    339 *commentstart = '\0';
    340 *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    341
    342 break;
    343 }
    344 }
    345
    346 return TRUE;
    347}
    348
    349/** swaps the addresses of two pointers */
    350static
    352 char** pointer1, /**< first pointer */
    353 char** pointer2 /**< second pointer */
    354 )
    355{
    356 char* tmp;
    357
    358 tmp = *pointer1;
    359 *pointer1 = *pointer2;
    360 *pointer2 = tmp;
    361}
    362
    363/** reads the next token from the input file into the token buffer; returns whether a token was read */
    364static
    366 SCIP* scip, /**< SCIP data structure */
    367 LPINPUT* lpinput /**< LP reading data */
    368 )
    369{
    370 SCIP_Bool hasdot;
    371 LPEXPTYPE exptype;
    372 char* buf;
    373 int tokenlen;
    374
    375 assert(lpinput != NULL);
    376 assert(lpinput->linepos < lpinput->linebufsize);
    377
    378 /* check the token stack */
    379 if( lpinput->npushedtokens > 0 )
    380 {
    381 swapPointers(&lpinput->token, &lpinput->pushedtokens[lpinput->npushedtokens-1]);
    382 lpinput->npushedtokens--;
    383
    384 SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", lpinput->linenumber, lpinput->token);
    385 return TRUE;
    386 }
    387
    388 /* skip delimiters */
    389 buf = lpinput->linebuf;
    390 while( isDelimChar(buf[lpinput->linepos]) )
    391 {
    392 if( buf[lpinput->linepos] == '\0' )
    393 {
    394 if( !getNextLine(scip, lpinput) )
    395 {
    396 lpinput->section = LP_END;
    397 SCIPdebugMsg(scip, "(line %d) end of file\n", lpinput->linenumber);
    398 return FALSE;
    399 }
    400 assert(lpinput->linepos == 0);
    401 /* update buf, because the linebuffer may have been reallocated */
    402 buf = lpinput->linebuf;
    403 }
    404 else
    405 lpinput->linepos++;
    406 }
    407 assert(lpinput->linepos < lpinput->linebufsize);
    408 assert(!isDelimChar(buf[lpinput->linepos]));
    409
    410 /* check if the token is a value */
    411 hasdot = FALSE;
    412 exptype = LP_EXP_NONE;
    413 if( isValueChar(buf[lpinput->linepos], buf[lpinput->linepos+1], TRUE, &hasdot, &exptype) )
    414 {
    415 /* read value token */
    416 tokenlen = 0;
    417 do
    418 {
    419 assert(tokenlen < LP_MAX_LINELEN);
    420 assert(!isDelimChar(buf[lpinput->linepos]));
    421 lpinput->token[tokenlen] = buf[lpinput->linepos];
    422 tokenlen++;
    423 lpinput->linepos++;
    424 }
    425 while( isValueChar(buf[lpinput->linepos], buf[lpinput->linepos+1], FALSE, &hasdot, &exptype) );
    426 }
    427 else
    428 {
    429 /* read non-value token */
    430 tokenlen = 0;
    431 do
    432 {
    433 assert(tokenlen < LP_MAX_LINELEN);
    434 lpinput->token[tokenlen] = buf[lpinput->linepos];
    435 tokenlen++;
    436 lpinput->linepos++;
    437 if( tokenlen == 1 && isTokenChar(lpinput->token[0]) )
    438 break;
    439 }
    440 while( !isDelimChar(buf[lpinput->linepos]) && !isTokenChar(buf[lpinput->linepos]) );
    441
    442 /* if the token is a power sign '^', skip a following '2'
    443 * if the token is an equation sense '<', '>', or '=', skip a following '='
    444 * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
    445 */
    446 if( tokenlen >= 1 && lpinput->token[tokenlen-1] == '^' && buf[lpinput->linepos] == '2' )
    447 {
    448 lpinput->linepos++;
    449 }
    450 if( tokenlen >= 1
    451 && (lpinput->token[tokenlen-1] == '<' || lpinput->token[tokenlen-1] == '>' || lpinput->token[tokenlen-1] == '=')
    452 && buf[lpinput->linepos] == '=' )
    453 {
    454 lpinput->linepos++;
    455 }
    456 else if( lpinput->token[tokenlen-1] == '=' && (buf[lpinput->linepos] == '<' || buf[lpinput->linepos] == '>') )
    457 {
    458 lpinput->token[tokenlen-1] = buf[lpinput->linepos];
    459 lpinput->linepos++;
    460 }
    461 }
    462 assert(tokenlen < LP_MAX_LINELEN);
    463 lpinput->token[tokenlen] = '\0';
    464
    465 SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", lpinput->linenumber, lpinput->token);
    466
    467 return TRUE;
    468}
    469
    470/** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
    471static
    473 LPINPUT* lpinput /**< LP reading data */
    474 )
    475{
    476 assert(lpinput != NULL);
    477 assert(lpinput->npushedtokens < LP_MAX_PUSHEDTOKENS);
    478
    479 swapPointers(&lpinput->pushedtokens[lpinput->npushedtokens], &lpinput->token);
    480 lpinput->npushedtokens++;
    481}
    482
    483/** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
    484static
    486 LPINPUT* lpinput /**< LP reading data */
    487 )
    488{
    489 assert(lpinput != NULL);
    490 assert(lpinput->npushedtokens < LP_MAX_PUSHEDTOKENS);
    491
    492 swapPointers(&lpinput->pushedtokens[lpinput->npushedtokens], &lpinput->tokenbuf);
    493 lpinput->npushedtokens++;
    494}
    495
    496/** swaps the current token with the token buffer */
    497static
    499 LPINPUT* lpinput /**< LP reading data */
    500 )
    501{
    502 assert(lpinput != NULL);
    503
    504 swapPointers(&lpinput->token, &lpinput->tokenbuf);
    505}
    506
    507/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
    508static
    510 SCIP* scip, /**< SCIP data structure */
    511 LPINPUT* lpinput /**< LP reading data */
    512 )
    513{
    514 SCIP_Bool iscolon;
    515 size_t len;
    516
    517 assert(lpinput != NULL);
    518
    519 /* remember first token by swapping the token buffer */
    520 swapTokenBuffer(lpinput);
    521
    522 /* look at next token: if this is a ':', the first token is a name and no section keyword */
    523 iscolon = FALSE;
    524 if( getNextToken(scip, lpinput) )
    525 {
    526 iscolon = (*lpinput->token == ':');
    527 pushToken(lpinput);
    528 }
    529
    530 /* reinstall the previous token by swapping back the token buffer */
    531 swapTokenBuffer(lpinput);
    532
    533 /* check for ':' */
    534 if( iscolon )
    535 return FALSE;
    536
    537 len = strlen(lpinput->token);
    538 assert(len < LP_MAX_LINELEN);
    539
    540 /* the section keywords are at least 2 characters up to 8 or exactly 15 characters long */
    541 if( len > 1 && (len < 9 || len == 15) )
    542 {
    543 char token[16];
    544 int c = 0;
    545
    546 while( lpinput->token[c] != '\0' )
    547 {
    548 token[c] = toupper((unsigned char)lpinput->token[c]); /*lint !e734*/
    549 ++c;
    550 assert(c < 16);
    551 }
    552 token[c] = '\0';
    553
    554 if( (len == 3 && strcmp(token, "MIN") == 0)
    555 || (len == 7 && strcmp(token, "MINIMUM") == 0)
    556 || (len == 8 && strcmp(token, "MINIMIZE") == 0) )
    557 {
    558 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
    559 lpinput->section = LP_OBJECTIVE;
    560 lpinput->objsense = SCIP_OBJSENSE_MINIMIZE;
    561 return TRUE;
    562 }
    563
    564 if( (len == 3 && strcmp(token, "MAX") == 0)
    565 || (len == 7 && strcmp(token, "MAXIMUM") == 0)
    566 || (len == 8 && strcmp(token, "MAXIMIZE") == 0) )
    567 {
    568 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
    569 lpinput->section = LP_OBJECTIVE;
    570 lpinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
    571 return TRUE;
    572 }
    573
    574 if( len == 7 && strcmp(token, "SUBJECT") == 0 )
    575 {
    576 /* check if the next token is 'TO' */
    577 swapTokenBuffer(lpinput);
    578 if( getNextToken(scip, lpinput) )
    579 {
    580 if( SCIPstrcasecmp(lpinput->token, "TO") == 0 )
    581 {
    582 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
    583 lpinput->section = LP_CONSTRAINTS;
    584 lpinput->inlazyconstraints = FALSE;
    585 lpinput->inusercuts = FALSE;
    586 return TRUE;
    587 }
    588 else
    589 pushToken(lpinput);
    590 }
    591 swapTokenBuffer(lpinput);
    592 }
    593
    594 if( len == 4 && strcmp(token, "SUCH") == 0 )
    595 {
    596 /* check if the next token is 'THAT' */
    597 swapTokenBuffer(lpinput);
    598 if( getNextToken(scip, lpinput) )
    599 {
    600 if( SCIPstrcasecmp(lpinput->token, "THAT") == 0 )
    601 {
    602 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
    603 lpinput->section = LP_CONSTRAINTS;
    604 lpinput->inlazyconstraints = FALSE;
    605 lpinput->inusercuts = FALSE;
    606 return TRUE;
    607 }
    608 else
    609 pushToken(lpinput);
    610 }
    611 swapTokenBuffer(lpinput);
    612 }
    613
    614 if( (len == 2 && strcmp(token, "ST") == 0)
    615 || (len == 3 && strcmp(token, "ST.") == 0)
    616 || (len == 4 && strcmp(token, "S.T.") == 0) )
    617 {
    618 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
    619 lpinput->section = LP_CONSTRAINTS;
    620 lpinput->inlazyconstraints = FALSE;
    621 lpinput->inusercuts = FALSE;
    622 return TRUE;
    623 }
    624
    625 if( len == 4 && strcmp(token, "LAZY") == 0 )
    626 {
    627 /* check if the next token is 'CONSTRAINTS' */
    628 swapTokenBuffer(lpinput);
    629 if( getNextToken(scip, lpinput) )
    630 {
    631 if( SCIPstrcasecmp(lpinput->token, "CONSTRAINTS") == 0 )
    632 {
    633 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS (lazy)\n", lpinput->linenumber);
    634 lpinput->section = LP_CONSTRAINTS;
    635 lpinput->inlazyconstraints = TRUE;
    636 lpinput->inusercuts = FALSE;
    637 return TRUE;
    638 }
    639 else
    640 pushToken(lpinput);
    641 }
    642 swapTokenBuffer(lpinput);
    643 }
    644
    645 if( len == 4 && strcmp(token, "USER") == 0 )
    646 {
    647 /* check if the next token is 'CUTS' */
    648 swapTokenBuffer(lpinput);
    649 if( getNextToken(scip, lpinput) )
    650 {
    651 if( SCIPstrcasecmp(lpinput->token, "CUTS") == 0 )
    652 {
    653 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS (user cuts)\n", lpinput->linenumber);
    654 lpinput->section = LP_CONSTRAINTS;
    655 lpinput->inlazyconstraints = FALSE;
    656 lpinput->inusercuts = TRUE;
    657 return TRUE;
    658 }
    659 else
    660 pushToken(lpinput);
    661 }
    662 swapTokenBuffer(lpinput);
    663 }
    664
    665 if( (len == 5 && strcmp(token, "BOUND") == 0)
    666 || (len == 6 && strcmp(token, "BOUNDS") == 0) )
    667 {
    668 SCIPdebugMsg(scip, "(line %d) new section: BOUNDS\n", lpinput->linenumber);
    669 lpinput->section = LP_BOUNDS;
    670 return TRUE;
    671 }
    672
    673 if( (len == 3 && (strcmp(token, "GEN") == 0 || strcmp(token, "INT") == 0))
    674 || (len == 7 && (strcmp(token, "GENERAL") == 0 || strcmp(token, "INTEGER") == 0))
    675 || (len == 8 && (strcmp(token, "GENERALS") == 0 || strcmp(token, "INTEGERS") == 0)) )
    676 {
    677 SCIPdebugMsg(scip, "(line %d) new section: GENERALS\n", lpinput->linenumber);
    678 lpinput->section = LP_GENERALS;
    679 return TRUE;
    680 }
    681
    682 if( (len == 3 && strcmp(token, "BIN") == 0)
    683 || (len == 6 && strcmp(token, "BINARY") == 0)
    684 || (len == 8 && strcmp(token, "BINARIES") == 0) )
    685 {
    686 SCIPdebugMsg(scip, "(line %d) new section: BINARIES\n", lpinput->linenumber);
    687 lpinput->section = LP_BINARIES;
    688 return TRUE;
    689 }
    690
    691 if( (len == 4 && strcmp(token, "SEMI") == 0)
    692 || (len == 5 && strcmp(token, "SEMIS") == 0)
    693 || (len == 15 && strcmp(token, "SEMI-CONTINUOUS") == 0) )
    694 {
    695 SCIPdebugMsg(scip, "(line %d) new section: SEMICONTINUOUS\n", lpinput->linenumber);
    696 lpinput->section = LP_SEMICONTINUOUS;
    697 return TRUE;
    698 }
    699
    700 if( len == 3 && strcmp(token, "SOS") == 0 )
    701 {
    702 SCIPdebugMsg(scip, "(line %d) new section: SOS\n", lpinput->linenumber);
    703 lpinput->section = LP_SOS;
    704 return TRUE;
    705 }
    706
    707 if( len == 3 && strcmp(token, "END") == 0 )
    708 {
    709 SCIPdebugMsg(scip, "(line %d) new section: END\n", lpinput->linenumber);
    710 lpinput->section = LP_END;
    711 return TRUE;
    712 }
    713 }
    714
    715 return FALSE;
    716}
    717
    718/** returns whether the current token is a sign */
    719static
    721 LPINPUT* lpinput, /**< LP reading data */
    722 int* sign /**< pointer to update the sign */
    723 )
    724{
    725 assert(lpinput != NULL);
    726 assert(sign != NULL);
    727 assert(*sign == +1 || *sign == -1);
    728
    729 if( lpinput->token[1] == '\0' )
    730 {
    731 if( *lpinput->token == '+' )
    732 return TRUE;
    733 else if( *lpinput->token == '-' )
    734 {
    735 *sign *= -1;
    736 return TRUE;
    737 }
    738 }
    739
    740 return FALSE;
    741}
    742
    743/** returns whether the current token is a value */
    744static
    746 SCIP* scip, /**< SCIP data structure */
    747 LPINPUT* lpinput, /**< LP reading data */
    748 SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
    749 )
    750{
    751 assert(lpinput != NULL);
    752 assert(value != NULL);
    753
    754 if( SCIPstrcasecmp(lpinput->token, "INFINITY") == 0 || SCIPstrcasecmp(lpinput->token, "INF") == 0 )
    755 {
    756 *value = SCIPinfinity(scip);
    757 return TRUE;
    758 }
    759 else
    760 {
    761 double val;
    762 char* endptr;
    763
    764 val = strtod(lpinput->token, &endptr);
    765 if( endptr != lpinput->token && *endptr == '\0' )
    766 {
    767 *value = val;
    768 return TRUE;
    769 }
    770 }
    771
    772 return FALSE;
    773}
    774
    775/** returns whether the current token is a value */
    776static
    778 SCIP* scip, /**< SCIP data structure */
    779 LPINPUT* lpinput, /**< LP reading data */
    780 SCIP_RATIONAL* value /**< pointer to store the value (unchanged, if token is no value) */
    781 )
    782{
    783 assert(lpinput != NULL);
    784 assert(value != NULL);
    785
    786 if( SCIPstrcasecmp(lpinput->token, "INFINITY") == 0 || SCIPstrcasecmp(lpinput->token, "INF") == 0 )
    787 {
    789 return TRUE;
    790 }
    791 else
    792 {
    793 double val;
    794
    795 if( isValue(scip, lpinput, &val) || SCIPrationalIsString(lpinput->token) )
    796 {
    797 SCIPrationalSetString(value, lpinput->token);
    798 return TRUE;
    799 }
    800 }
    801
    802 return FALSE;
    803}
    804
    805/** returns whether the current token is an equation sense */
    806static
    808 LPINPUT* lpinput, /**< LP reading data */
    809 LPSENSE* sense /**< pointer to store the equation sense, or NULL */
    810 )
    811{
    812 assert(lpinput != NULL);
    813
    814 if( strcmp(lpinput->token, "<") == 0 )
    815 {
    816 if( sense != NULL )
    817 *sense = LP_SENSE_LE;
    818 return TRUE;
    819 }
    820 else if( strcmp(lpinput->token, ">") == 0 )
    821 {
    822 if( sense != NULL )
    823 *sense = LP_SENSE_GE;
    824 return TRUE;
    825 }
    826 else if( strcmp(lpinput->token, "=") == 0 )
    827 {
    828 if( sense != NULL )
    829 *sense = LP_SENSE_EQ;
    830 return TRUE;
    831 }
    832
    833 return FALSE;
    834}
    835
    836/** returns the variable with the given name, or creates a new variable if it does not exist */
    837static
    839 SCIP* scip, /**< SCIP data structure */
    840 char* name, /**< name of the variable */
    841 SCIP_VAR** var, /**< pointer to store the variable */
    842 SCIP_Bool* created /**< pointer to store whether a new variable was created, or NULL */
    843 )
    844{
    845 assert(name != NULL);
    846 assert(var != NULL);
    847
    848 *var = SCIPfindVar(scip, name);
    849 if( *var == NULL )
    850 {
    851 SCIP_VAR* newvar;
    852 SCIP_Bool dynamiccols;
    853 SCIP_Bool initial;
    854 SCIP_Bool removable;
    855
    856 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
    857 initial = !dynamiccols;
    858 removable = dynamiccols;
    859
    860 /* create new variable of the given name */
    861 SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
    863 initial, removable, NULL, NULL, NULL, NULL, NULL) );
    864 if( SCIPisExact(scip) )
    865 {
    867 }
    868 SCIP_CALL( SCIPaddVar(scip, newvar) );
    869 *var = newvar;
    870
    871 /* because the variable was added to the problem, it is captured by SCIP and we can safely release it right now
    872 * without making the returned *var invalid
    873 */
    874 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
    875
    876 if( created != NULL )
    877 *created = TRUE;
    878 }
    879 else if( created != NULL )
    880 *created = FALSE;
    881
    882 return SCIP_OKAY;
    883}
    884
    885/** reads the header of the file */
    886static
    888 SCIP* scip, /**< SCIP data structure */
    889 LPINPUT* lpinput /**< LP reading data */
    890 )
    891{
    892 assert(lpinput != NULL);
    893
    894 /* everything before first section is treated as comment */
    895 do
    896 {
    897 /* get token */
    898 if( !getNextToken(scip, lpinput) )
    899 return SCIP_OKAY;
    900 }
    901 while( !isNewSection(scip, lpinput) );
    902
    903 return SCIP_OKAY;
    904}
    905
    906/** reads an objective or constraint with name and coefficients */
    907static
    909 SCIP* scip, /**< SCIP data structure */
    910 LPINPUT* lpinput, /**< LP reading data */
    911 SCIP_Bool isobjective, /**< indicates whether we are currently reading the coefficients of the objective */
    912 char* name, /**< pointer to store the name of the line; must be at least of size
    913 * LP_MAX_LINELEN */
    914 int* coefssize, /**< size of vars and coefs arrays */
    915 SCIP_VAR*** vars, /**< pointer to store the array with variables (must be freed by caller) */
    916 SCIP_Real** coefs, /**< pointer to store the array with coefficients (must be freed by caller) */
    917 int* ncoefs, /**< pointer to store the number of coefficients */
    918 int* quadcoefssize, /**< size of quadvars1, quadvars2, quadcoefs arrays */
    919 SCIP_VAR*** quadvars1, /**< pointer to store the array with first variables in quadratic terms (must be freed by caller) */
    920 SCIP_VAR*** quadvars2, /**< pointer to store the array with second variables in quadratic terms (must be freed by caller) */
    921 SCIP_Real** quadcoefs, /**< pointer to store the array with coefficients in quadratic terms (must be freed by caller) */
    922 int* nquadcoefs, /**< pointer to store the number of quadratic coefficients */
    923 SCIP_Real* objoffset, /**< pointer to store an objective offset (or NULL if ! isobjective) */
    924 SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
    925 )
    926{
    927 SCIP_VAR* var = NULL;
    928 SCIP_Bool havesign;
    929 SCIP_Bool havevalue;
    930 SCIP_Bool haveobjoffset = FALSE;
    931 SCIP_Real coef;
    932 int coefsign;
    933 SCIP_Bool inquadpart;
    934 SCIP_VAR* firstquadvar;
    935
    936 assert(lpinput != NULL);
    937 assert(name != NULL);
    938 assert(coefssize != NULL);
    939 assert(vars != NULL);
    940 assert(coefs != NULL);
    941 assert(ncoefs != NULL);
    942 assert(quadcoefssize != NULL);
    943 assert(quadvars1 != NULL);
    944 assert(quadvars2 != NULL);
    945 assert(quadcoefs != NULL);
    946 assert(nquadcoefs != NULL);
    947 assert(!isobjective || objoffset != NULL);
    948 assert(newsection != NULL);
    949
    950 *coefssize = 0;
    951 *vars = NULL;
    952 *coefs = NULL;
    953 *quadvars1 = NULL;
    954 *quadvars2 = NULL;
    955 *quadcoefs = NULL;
    956 *name = '\0';
    957 *ncoefs = 0;
    958 *quadcoefssize = 0;
    959 *nquadcoefs = 0;
    960 *newsection = FALSE;
    961 inquadpart = FALSE;
    962
    963 if( isobjective )
    964 {
    965 assert(objoffset != NULL);
    966 *objoffset = 0.0;
    967 }
    968
    969 /* read the first token, which may be the name of the line */
    970 if( getNextToken(scip, lpinput) )
    971 {
    972 /* check if we reached a new section */
    973 if( isNewSection(scip, lpinput) )
    974 {
    975 *newsection = TRUE;
    976 return SCIP_OKAY;
    977 }
    978
    979 /* remember the token in the token buffer */
    980 swapTokenBuffer(lpinput);
    981
    982 /* get the next token and check, whether it is a colon */
    983 if( getNextToken(scip, lpinput) )
    984 {
    985 if( strcmp(lpinput->token, ":") == 0 )
    986 {
    987 /* the second token was a colon: the first token is the line name */
    988 (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', LP_MAX_LINELEN);
    989
    990 name[LP_MAX_LINELEN - 1] = '\0';
    991 SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", lpinput->linenumber, name);
    992 }
    993 else
    994 {
    995 /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
    996 pushToken(lpinput);
    997 pushBufferToken(lpinput);
    998 }
    999 }
    1000 else
    1001 {
    1002 /* there was only one token left: push it back onto the token stack and parse it as coefficient */
    1003 pushBufferToken(lpinput);
    1004 }
    1005 }
    1006
    1007 /* initialize buffers for storing the coefficients */
    1008 *coefssize = LP_INIT_COEFSSIZE;
    1009 SCIP_CALL( SCIPallocBlockMemoryArray(scip, vars, *coefssize) );
    1010 SCIP_CALL( SCIPallocBlockMemoryArray(scip, coefs, *coefssize) );
    1011
    1012 *quadcoefssize = LP_INIT_QUADCOEFSSIZE;
    1013 SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadvars1, *quadcoefssize) );
    1014 SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadvars2, *quadcoefssize) );
    1015 SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadcoefs, *quadcoefssize) );
    1016
    1017 /* read the coefficients */
    1018 coefsign = +1;
    1019 coef = 1.0;
    1020 havesign = FALSE;
    1021 havevalue = FALSE;
    1022 firstquadvar = NULL;
    1023 *ncoefs = 0;
    1024 *nquadcoefs = 0;
    1025 while( getNextToken(scip, lpinput) )
    1026 {
    1027 /* check whether we reached a new sign token */
    1028 if( lpinput->token[1] == '\0' && ( *lpinput->token == '+' || *lpinput->token == '-' ) )
    1029 {
    1030 /* check whether we found an objective offset */
    1031 if( isobjective && havevalue && var == NULL )
    1032 {
    1033 assert( objoffset != NULL );
    1034 if( haveobjoffset )
    1035 {
    1036 syntaxError(scip, lpinput, "two objective offsets.");
    1037 return SCIP_OKAY;
    1038 }
    1039 SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * coef);
    1040 haveobjoffset = TRUE;
    1041 *objoffset = coefsign * coef;
    1042 }
    1043 }
    1044
    1045 /* check if we read a sign */
    1046 if( isSign(lpinput, &coefsign) )
    1047 {
    1048 if( havevalue )
    1049 {
    1050 syntaxError(scip, lpinput, "sign after value without variable.");
    1051 return SCIP_OKAY;
    1052 }
    1053
    1054 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", lpinput->linenumber, coefsign);
    1055 havesign = TRUE;
    1056 continue;
    1057 }
    1058
    1059 /* check if we read a value */
    1060 if( isValue(scip, lpinput, &coef) )
    1061 {
    1062 SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", lpinput->linenumber, coef, coefsign);
    1063 if( havevalue )
    1064 {
    1065 syntaxError(scip, lpinput, "two consecutive values.");
    1066 return SCIP_OKAY;
    1067 }
    1068 havevalue = TRUE;
    1069 continue;
    1070 }
    1071
    1072 /* check if we reached an equation sense */
    1073 if( isSense(lpinput, NULL) )
    1074 {
    1075 if( isobjective )
    1076 {
    1077 syntaxError(scip, lpinput, "no sense allowed in objective");
    1078 return SCIP_OKAY;
    1079 }
    1080
    1081 if( havevalue )
    1082 {
    1083 syntaxError(scip, lpinput, "no constant values allowed for constraints in lp file format");
    1084 return SCIP_OKAY;
    1085 }
    1086
    1087 if( havesign )
    1088 {
    1089 syntaxError(scip, lpinput, "constaint has sign without a variable");
    1090 return SCIP_OKAY;
    1091 }
    1092
    1093 /* put the sense back onto the token stack */
    1094 pushToken(lpinput);
    1095 break;
    1096 }
    1097
    1098 /* check if we reached a new section, that will be only allowed when having no current sign and value and if we
    1099 * are not in the qudratic part
    1100 */
    1101 if( (isobjective || (!havevalue && !havesign)) && !inquadpart && isNewSection(scip, lpinput) )
    1102 {
    1103 if( havesign && !havevalue )
    1104 {
    1105 SCIPwarningMessage(scip, "skipped single sign %c without value or variable in objective\n", coefsign == 1 ? '+' : '-');
    1106 }
    1107 else if( isobjective && havevalue && !SCIPisZero(scip, coef) )
    1108 {
    1109 assert( objoffset != NULL );
    1110 /* check whether we found an objective offset */
    1111 if( haveobjoffset )
    1112 {
    1113 syntaxError(scip, lpinput, "two objective offsets.");
    1114 return SCIP_OKAY;
    1115 }
    1116 SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * coef);
    1117 *objoffset = coefsign * coef;
    1118 }
    1119
    1120 *newsection = TRUE;
    1121 return SCIP_OKAY;
    1122 }
    1123
    1124 /* check if we start a quadratic part */
    1125 if( *lpinput->token == '[' )
    1126 {
    1127 if( inquadpart )
    1128 {
    1129 syntaxError(scip, lpinput, "cannot start quadratic part while already in quadratic part.");
    1130 return SCIP_OKAY;
    1131 }
    1132 if( havesign && coefsign != +1 )
    1133 {
    1134 syntaxError(scip, lpinput, "cannot have '-' in front of quadratic part.");
    1135 return SCIP_OKAY;
    1136 }
    1137 if( havevalue )
    1138 {
    1139 syntaxError(scip, lpinput, "cannot have value in front of quadratic part.");
    1140 return SCIP_OKAY;
    1141 }
    1142
    1143 SCIPdebugMsg(scip, "(line %d) start quadratic part\n", lpinput->linenumber);
    1144 inquadpart = TRUE;
    1145 continue;
    1146 }
    1147
    1148 /* check if we end a quadratic part */
    1149 if( *lpinput->token == ']' )
    1150 {
    1151 if( !inquadpart )
    1152 {
    1153 syntaxError(scip, lpinput, "cannot end quadratic part before starting one.");
    1154 return SCIP_OKAY;
    1155 }
    1156 if( havesign || havevalue || firstquadvar != NULL )
    1157 {
    1158 if( firstquadvar == NULL )
    1159 {
    1160 syntaxError(scip, lpinput, "expected value or first quadratic variable.");
    1161 }
    1162 else
    1163 {
    1164 syntaxError(scip, lpinput, "expected second quadratic variable.");
    1165 }
    1166 return SCIP_OKAY;
    1167 }
    1168
    1169 SCIPdebugMsg(scip, "(line %d) end quadratic part\n", lpinput->linenumber);
    1170 inquadpart = FALSE;
    1171
    1172 if( isobjective )
    1173 {
    1174 /* quadratic part in objective has to end with '/2' */
    1175 if( !getNextToken(scip, lpinput) )
    1176 {
    1177 syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
    1178 return SCIP_OKAY;
    1179 }
    1180 if( strcmp(lpinput->token, "/2") == 0 )
    1181 {
    1182 SCIPdebugMsg(scip, "(line %d) saw '/2' or '/ 2' after quadratic part in objective\n", lpinput->linenumber);
    1183 }
    1184 else if( *lpinput->token == '/' )
    1185 {
    1186 /* maybe it says '/ 2' */
    1187 if( !getNextToken(scip, lpinput) || *lpinput->token != '2' )
    1188 {
    1189 syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
    1190 return SCIP_OKAY;
    1191 }
    1192 SCIPdebugMsg(scip, "(line %d) saw '/ 2' after quadratic part in objective\n", lpinput->linenumber);
    1193 }
    1194 else
    1195 {
    1196 syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
    1197 return SCIP_OKAY;
    1198 }
    1199 }
    1200
    1201 continue;
    1202 }
    1203
    1204 /* check if we are in between two quadratic variables */
    1205 if( *lpinput->token == '*' )
    1206 {
    1207 if( !inquadpart )
    1208 {
    1209 syntaxError(scip, lpinput, "cannot have '*' outside of quadratic part.");
    1210 return SCIP_OKAY;
    1211 }
    1212 if( firstquadvar == NULL )
    1213 {
    1214 syntaxError(scip, lpinput, "cannot have '*' before first variable in quadratic term.");
    1215 return SCIP_OKAY;
    1216 }
    1217
    1218 continue;
    1219 }
    1220
    1221 /* all but the first coefficient need a sign */
    1222 if( !inquadpart && *ncoefs > 0 && !havesign )
    1223 {
    1224 syntaxError(scip, lpinput, "expected sign ('+' or '-') or sense ('<' or '>').");
    1225 return SCIP_OKAY;
    1226 }
    1227 if( inquadpart && *nquadcoefs > 0 && !havesign )
    1228 {
    1229 syntaxError(scip, lpinput, "expected sign ('+' or '-').");
    1230 return SCIP_OKAY;
    1231 }
    1232
    1233 /* check if the last variable should be squared */
    1234 var = NULL;
    1235 if( *lpinput->token == '^' )
    1236 {
    1237 if( !inquadpart )
    1238 {
    1239 syntaxError(scip, lpinput, "cannot have squares ('^2') outside of quadratic part.");
    1240 return SCIP_OKAY;
    1241 }
    1242 if( firstquadvar == NULL )
    1243 {
    1244 syntaxError(scip, lpinput, "cannot have square '^2' before variable.");
    1245 return SCIP_OKAY;
    1246 }
    1247
    1248 var = firstquadvar;
    1249 }
    1250 else
    1251 {
    1252 /* the token is a variable name: get the corresponding variable (or create a new one) */
    1253 SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
    1254 }
    1255
    1256 if( !inquadpart )
    1257 {
    1258 /* insert the linear coefficient */
    1259 SCIPdebugMsg(scip, "(line %d) read linear coefficient: %+g<%s>\n", lpinput->linenumber, coefsign * coef, SCIPvarGetName(var));
    1260 if( !SCIPisZero(scip, coef) )
    1261 {
    1262 /* resize the vars and coefs array if needed */
    1263 if( *ncoefs >= *coefssize )
    1264 {
    1265 int oldcoefssize;
    1266 oldcoefssize = *coefssize;
    1267 *coefssize *= 2;
    1268 *coefssize = MAX(*coefssize, (*ncoefs)+1);
    1269 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, vars, oldcoefssize, *coefssize) );
    1270 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, coefs, oldcoefssize, *coefssize) );
    1271 }
    1272 assert(*ncoefs < *coefssize);
    1273
    1274 /* add coefficient */
    1275 (*vars)[*ncoefs] = var;
    1276 (*coefs)[*ncoefs] = coefsign * coef;
    1277 (*ncoefs)++;
    1278 }
    1279 }
    1280 else
    1281 {
    1282 if( firstquadvar == NULL )
    1283 {
    1284 /* if first quadratic variable read, store it and continue; expect second one in next round */
    1285 firstquadvar = var;
    1286 continue;
    1287 }
    1288
    1289 /* insert the quadratic coefficient */
    1290 SCIPdebugMsg(scip, "(line %d) read quadratic coefficient: %+g<%s><%s>\n", lpinput->linenumber, (isobjective ? 0.5 : 1) * coefsign * coef, SCIPvarGetName(firstquadvar), SCIPvarGetName(var));
    1291 if( !SCIPisZero(scip, coef) )
    1292 {
    1293 /* resize the vars and coefs array if needed */
    1294 if( *nquadcoefs >= *quadcoefssize )
    1295 {
    1296 int oldquadcoefssize;
    1297 oldquadcoefssize = *quadcoefssize;
    1298 *quadcoefssize *= 2;
    1299 *quadcoefssize = MAX(*quadcoefssize, (*nquadcoefs)+1);
    1300 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadcoefs, oldquadcoefssize, *quadcoefssize) );
    1301 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadvars2, oldquadcoefssize, *quadcoefssize) );
    1302 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadvars1, oldquadcoefssize, *quadcoefssize) );
    1303 }
    1304 assert(*nquadcoefs < *quadcoefssize);
    1305
    1306 /* add coefficient */
    1307 (*quadvars1)[*nquadcoefs] = firstquadvar;
    1308 (*quadvars2)[*nquadcoefs] = var;
    1309 (*quadcoefs)[*nquadcoefs] = coefsign * coef;
    1310 if( isobjective )
    1311 (*quadcoefs)[*nquadcoefs] /= 2.0;
    1312 (*nquadcoefs)++;
    1313 }
    1314 }
    1315
    1316 /* reset the flags and coefficient value for the next coefficient */
    1317 coefsign = +1;
    1318 coef = 1.0;
    1319 havesign = FALSE;
    1320 havevalue = FALSE;
    1321 firstquadvar = NULL;
    1322 }
    1323
    1324 return SCIP_OKAY;
    1325}
    1326
    1327/** reads an objective or constraint with name and coefficients */
    1328static
    1330 SCIP* scip, /**< SCIP data structure */
    1331 LPINPUT* lpinput, /**< LP reading data */
    1332 SCIP_Bool isobjective, /**< indicates whether we are currently reading the coefficients of the objective */
    1333 char* name, /**< pointer to store the name of the line; must be at least of size
    1334 * LP_MAX_LINELEN */
    1335 int* coefssize, /**< size of vars and coefs arrays */
    1336 SCIP_VAR*** vars, /**< pointer to store the array with variables (must be freed by caller) */
    1337 SCIP_RATIONAL*** coefs, /**< pointer to store the array with coefficients (must be freed by caller) */
    1338 int* ncoefs, /**< pointer to store the number of coefficients */
    1339 SCIP_RATIONAL* objoffset, /**< pointer to store an objective offset (or NULL if ! isobjective) */
    1340 SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
    1341 )
    1342{
    1343 SCIP_VAR* var = NULL;
    1344 SCIP_Bool havesign;
    1345 SCIP_Bool havevalue;
    1346 SCIP_Bool haveobjoffset = FALSE;
    1347 SCIP_RATIONAL* coef;
    1348 int coefsign;
    1349 SCIP_Bool inquadpart;
    1350 SCIP_VAR* firstquadvar;
    1351
    1352 assert(lpinput != NULL);
    1353 assert(name != NULL);
    1354 assert(coefssize != NULL);
    1355 assert(vars != NULL);
    1356 assert(coefs != NULL);
    1357 assert(ncoefs != NULL);
    1358 assert(!isobjective || objoffset != NULL);
    1359 assert(newsection != NULL);
    1360
    1361 *coefssize = 0;
    1362 *vars = NULL;
    1363 *coefs = NULL;
    1364 *name = '\0';
    1365 *ncoefs = 0;
    1366 *newsection = FALSE;
    1367 inquadpart = FALSE;
    1368
    1370
    1371 if( isobjective )
    1372 {
    1373 assert(objoffset != NULL);
    1374 SCIPrationalSetReal(objoffset, 0.0);
    1375 }
    1376
    1377 /* read the first token, which may be the name of the line */
    1378 if( getNextToken(scip, lpinput) )
    1379 {
    1380 /* check if we reached a new section */
    1381 if( isNewSection(scip, lpinput) )
    1382 {
    1383 *newsection = TRUE;
    1384 goto TERMINATE;
    1385 }
    1386
    1387 /* remember the token in the token buffer */
    1388 swapTokenBuffer(lpinput);
    1389
    1390 /* get the next token and check, whether it is a colon */
    1391 if( getNextToken(scip, lpinput) )
    1392 {
    1393 if( strcmp(lpinput->token, ":") == 0 )
    1394 {
    1395 /* the second token was a colon: the first token is the line name */
    1396 (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', LP_MAX_LINELEN);
    1397
    1398 name[LP_MAX_LINELEN - 1] = '\0';
    1399 SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", lpinput->linenumber, name);
    1400 }
    1401 else
    1402 {
    1403 /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
    1404 pushToken(lpinput);
    1405 pushBufferToken(lpinput);
    1406 }
    1407 }
    1408 else
    1409 {
    1410 /* there was only one token left: push it back onto the token stack and parse it as coefficient */
    1411 pushBufferToken(lpinput);
    1412 }
    1413 }
    1414
    1415 /* initialize buffers for storing the coefficients */
    1416 *coefssize = LP_INIT_COEFSSIZE;
    1417
    1418 SCIP_CALL( SCIPrationalCreateBlockArray(SCIPblkmem(scip), coefs, *coefssize) );
    1419 SCIP_CALL( SCIPallocBlockMemoryArray(scip, vars, *coefssize) );
    1420
    1421 /* read the coefficients */
    1422 coefsign = +1;
    1423 SCIPrationalSetReal(coef, 1.0);
    1424 havesign = FALSE;
    1425 havevalue = FALSE;
    1426 firstquadvar = NULL;
    1427 *ncoefs = 0;
    1428 while( getNextToken(scip, lpinput) )
    1429 {
    1430 /* check whether we reached a new sign token */
    1431 if( lpinput->token[1] == '\0' && ( *lpinput->token == '+' || *lpinput->token == '-' ) )
    1432 {
    1433 /* check whether we found an objective offset */
    1434 if( isobjective && havevalue && var == NULL )
    1435 {
    1436 assert( objoffset != NULL );
    1437 if( haveobjoffset )
    1438 {
    1439 syntaxError(scip, lpinput, "two objective offsets.");
    1440 goto TERMINATE;
    1441 }
    1442 SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * SCIPrationalGetReal(coef));
    1443 haveobjoffset = TRUE;
    1444 SCIPrationalMultReal(objoffset, coef, (double) coefsign);
    1445 }
    1446 }
    1447
    1448 /* check if we read a sign */
    1449 if( isSign(lpinput, &coefsign) )
    1450 {
    1451 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", lpinput->linenumber, coefsign);
    1452 havesign = TRUE;
    1453 continue;
    1454 }
    1455
    1456 /* check if we read a value */
    1457 if( isValueRational(scip, lpinput, coef) )
    1458 {
    1459 SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", lpinput->linenumber, SCIPrationalGetReal(coef), coefsign);
    1460 if( havevalue )
    1461 {
    1462 syntaxError(scip, lpinput, "two consecutive values.");
    1463 goto TERMINATE;
    1464 }
    1465 havevalue = TRUE;
    1466 continue;
    1467 }
    1468
    1469 /* check if we reached an equation sense */
    1470 if( isSense(lpinput, NULL) )
    1471 {
    1472 if( isobjective )
    1473 {
    1474 syntaxError(scip, lpinput, "no sense allowed in objective");
    1475 goto TERMINATE;
    1476 }
    1477
    1478 /* put the sense back onto the token stack */
    1479 pushToken(lpinput);
    1480 break;
    1481 }
    1482
    1483 /* check if we reached a new section, that will be only allowed when having no current sign and value and if we
    1484 * are not in the qudratic part
    1485 */
    1486 if( (isobjective || (!havevalue && !havesign)) && !inquadpart && isNewSection(scip, lpinput) )
    1487 {
    1488 if( havesign && !havevalue )
    1489 {
    1490 SCIPwarningMessage(scip, "skipped single sign %c without value or variable in objective\n", coefsign == 1 ? '+' : '-');
    1491 }
    1492 else if( isobjective && havevalue && !SCIPrationalIsZero(coef) )
    1493 {
    1494 assert( objoffset != NULL );
    1495 /* check whether we found an objective offset */
    1496 if( haveobjoffset )
    1497 {
    1498 syntaxError(scip, lpinput, "two objective offsets.");
    1499 goto TERMINATE;
    1500 }
    1501 SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * SCIPrationalGetReal(coef));
    1502 SCIPrationalMultReal(objoffset, coef, (double) coefsign);
    1503 }
    1504
    1505 *newsection = TRUE;
    1506 goto TERMINATE;
    1507 }
    1508
    1509 /* check if we start a quadratic part */
    1510 if( *lpinput->token == '[' )
    1511 {
    1512 syntaxError(scip, lpinput, "cannot start quadratic part while in exact solving mode.");
    1513 goto TERMINATE;
    1514 }
    1515
    1516 /* check if we end a quadratic part */
    1517 if( *lpinput->token == ']' )
    1518 {
    1519 syntaxError(scip, lpinput, "cannot end quadratic part while in exact solving mode.");
    1520 goto TERMINATE;
    1521 }
    1522
    1523 /* all but the first coefficient need a sign */
    1524 if( !inquadpart && *ncoefs > 0 && !havesign )
    1525 {
    1526 syntaxError(scip, lpinput, "expected sign ('+' or '-') or sense ('<' or '>').");
    1527 goto TERMINATE;
    1528 }
    1529
    1530 /* check if the last variable should be squared */
    1531 var = NULL;
    1532 if( *lpinput->token == '^' )
    1533 {
    1534 if( !inquadpart )
    1535 {
    1536 syntaxError(scip, lpinput, "cannot have squares ('^2') outside of quadratic part.");
    1537 goto TERMINATE;
    1538 }
    1539 if( firstquadvar == NULL )
    1540 {
    1541 syntaxError(scip, lpinput, "cannot have square '^2' before variable.");
    1542 goto TERMINATE;
    1543 }
    1544
    1545 var = firstquadvar;
    1546 }
    1547 else
    1548 {
    1549 /* the token is a variable name: get the corresponding variable (or create a new one) */
    1550 SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
    1551 }
    1552
    1553 if( !inquadpart )
    1554 {
    1555 /* insert the linear coefficient */
    1556 SCIPdebugMsg(scip, "(line %d) read linear coefficient: %+g<%s>\n", lpinput->linenumber, coefsign * SCIPrationalGetReal(coef), SCIPvarGetName(var));
    1557 if( !SCIPrationalIsZero(coef) )
    1558 {
    1559 /* resize the vars and coefs array if needed */
    1560 if( *ncoefs >= *coefssize )
    1561 {
    1562 int oldcoefssize;
    1563 oldcoefssize = *coefssize;
    1564 *coefssize *= 2;
    1565 *coefssize = MAX(*coefssize, (*ncoefs)+1);
    1566 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, vars, oldcoefssize, *coefssize) );
    1567 SCIP_CALL( SCIPrationalReallocBlockArray(SCIPblkmem(scip), coefs, oldcoefssize, *coefssize) );
    1568 }
    1569 assert(*ncoefs < *coefssize);
    1570
    1571 /* add coefficient */
    1572 (*vars)[*ncoefs] = var;
    1573 SCIPrationalMultReal((*coefs)[*ncoefs], coef, (double) coefsign);
    1574 (*ncoefs)++;
    1575 }
    1576 }
    1577
    1578 /* reset the flags and coefficient value for the next coefficient */
    1579 coefsign = +1;
    1580 SCIPrationalSetReal(coef, 1.0);
    1581 havesign = FALSE;
    1582 havevalue = FALSE;
    1583 firstquadvar = NULL;
    1584 }
    1585
    1586TERMINATE:
    1588
    1589 return SCIP_OKAY;
    1590}
    1591
    1592/** reads the objective section */
    1593static
    1595 SCIP* scip, /**< SCIP data structure */
    1596 LPINPUT* lpinput /**< LP reading data */
    1597 )
    1598{
    1599 char name[LP_MAX_LINELEN];
    1600 SCIP_RETCODE retcode = SCIP_OKAY;
    1601 SCIP_VAR** vars;
    1602 SCIP_RATIONAL** coefs;
    1603 SCIP_Bool newsection;
    1604 SCIP_RATIONAL* objoffset;
    1605 SCIP_RATIONAL* tmpval;
    1606 int ncoefs;
    1607 int coefssize;
    1608
    1609 assert(lpinput != NULL);
    1610
    1613
    1614 /* read the objective coefficients */
    1615 SCIP_CALL_TERMINATE( retcode, readCoefficientsRational(scip, lpinput, TRUE, name, &coefssize, &vars, &coefs, &ncoefs,
    1616 objoffset, &newsection), TERMINATE );
    1617
    1618 if( !SCIPrationalIsZero(objoffset) )
    1619 {
    1620 SCIP_CALL_TERMINATE( retcode, SCIPaddOrigObjoffsetExact(scip, objoffset), TERMINATE );
    1621 }
    1622
    1623 if( !hasError(lpinput) )
    1624 {
    1625 int i;
    1626
    1627 /* set the linear objective values */
    1628 for( i = 0; i < ncoefs; ++i )
    1629 {
    1630 assert(vars != NULL); /* for lint */
    1631 assert(coefs != NULL);
    1632 SCIPrationalAdd(tmpval, SCIPvarGetObjExact(vars[i]), coefs[i]);
    1633 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, vars[i], tmpval), TERMINATE );
    1634 }
    1635 }
    1636
    1637 TERMINATE:
    1638 /* free memory */
    1639 SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
    1640 if( coefs != NULL )
    1641 SCIPrationalFreeBlockArray(SCIPblkmem(scip), &coefs, coefssize);
    1642
    1645
    1646 return retcode; /*lint !e438*/
    1647}
    1648
    1649
    1650/** reads the objective section */
    1651static
    1653 SCIP* scip, /**< SCIP data structure */
    1654 LPINPUT* lpinput /**< LP reading data */
    1655 )
    1656{
    1657 char name[LP_MAX_LINELEN];
    1658 SCIP_VAR** vars;
    1659 SCIP_Real* coefs;
    1660 SCIP_VAR** quadvars1;
    1661 SCIP_VAR** quadvars2;
    1662 SCIP_Real* quadcoefs;
    1663 SCIP_Bool newsection;
    1664 SCIP_Real objoffset;
    1665 int ncoefs;
    1666 int coefssize;
    1667 int quadcoefssize;
    1668 int nquadcoefs;
    1669
    1670 assert(lpinput != NULL);
    1671
    1672 if( SCIPisExact(scip) )
    1673 {
    1675 return SCIP_OKAY;
    1676 }
    1677
    1678 /* read the objective coefficients */
    1679 SCIP_CALL( readCoefficients(scip, lpinput, TRUE, name, &coefssize, &vars, &coefs, &ncoefs,
    1680 &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, &objoffset, &newsection) );
    1681
    1682 if( ! SCIPisZero(scip, objoffset) )
    1683 {
    1684 SCIP_CALL( SCIPaddOrigObjoffset(scip, objoffset) );
    1685 }
    1686
    1687 if( !hasError(lpinput) )
    1688 {
    1689 int i;
    1690
    1691 /* set the linear objective values */
    1692 for( i = 0; i < ncoefs; ++i )
    1693 {
    1694 assert(vars != NULL); /* for lint */
    1695 assert(coefs != NULL);
    1696 SCIP_CALL( SCIPchgVarObj(scip, vars[i], SCIPvarGetObj(vars[i]) + coefs[i]) );
    1697 }
    1698
    1699 /* insert dummy variable and constraint to represent quadratic part of objective; note that
    1700 * reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model constraints and variables, not
    1701 * to an auxiliary objective constraint (otherwise it can happen that an auxiliary objective variable is loose
    1702 * with infinite best bound, triggering the problem that an LP that is unbounded because of loose variables with
    1703 * infinite best bound cannot be solved)
    1704 */
    1705 if( nquadcoefs > 0 )
    1706 {
    1707 SCIP_VAR* quadobjvar;
    1708 SCIP_CONS* quadobjcons;
    1709 SCIP_Real lhs;
    1710 SCIP_Real rhs;
    1711 SCIP_Real minusone;
    1712
    1713 SCIP_CALL( SCIPcreateVar(scip, &quadobjvar, "quadobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
    1715 SCIP_CALL( SCIPaddVar(scip, quadobjvar) );
    1716
    1717 if( lpinput->objsense == SCIP_OBJSENSE_MINIMIZE )
    1718 {
    1719 lhs = -SCIPinfinity(scip);
    1720 rhs = 0.0;
    1721 }
    1722 else
    1723 {
    1724 lhs = 0.0;
    1725 rhs = SCIPinfinity(scip);
    1726 }
    1727
    1728 minusone = -1.0;
    1729 SCIP_CALL( SCIPcreateConsQuadraticNonlinear(scip, &quadobjcons, "quadobj", 1, &quadobjvar, &minusone, nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
    1731
    1732 SCIP_CALL( SCIPaddCons(scip, quadobjcons) );
    1733 SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent quadratic objective: ", lpinput->linenumber, SCIPconsGetName(quadobjcons));
    1734 SCIPdebugPrintCons(scip, quadobjcons, NULL);
    1735
    1736 SCIP_CALL( SCIPreleaseCons(scip, &quadobjcons) );
    1737 SCIP_CALL( SCIPreleaseVar(scip, &quadobjvar) );
    1738 }
    1739 }
    1740
    1741 /* free memory */
    1742 SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
    1743 SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
    1744 SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
    1745 SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
    1746 SCIPfreeBlockMemoryArrayNull(scip, &coefs, coefssize);
    1747
    1748 return SCIP_OKAY; /*lint !e438*/
    1749}
    1750
    1751/** create indicator constraint */
    1752static
    1754 SCIP* scip, /**< SCIP data structure */
    1755 LPINPUT* lpinput, /**< LP reading data */
    1756 const char* name, /**< name of indicator constraint */
    1757 SCIP_VAR* binvar, /**< binary indicator variable */
    1758 SCIP_Real binvalue /**< value of indicator part (0/1) */
    1759 )
    1760{
    1761 char name2[LP_MAX_LINELEN];
    1762 SCIP_VAR** linvars;
    1763 SCIP_Real* lincoefs;
    1764 SCIP_VAR** quadvars1;
    1765 SCIP_VAR** quadvars2;
    1766 SCIP_Real* quadcoefs;
    1767 SCIP_CONS* cons;
    1768 SCIP_RETCODE retcode;
    1769 LPSENSE linsense;
    1770 SCIP_Real linsidevalue;
    1771 SCIP_Real linrhs;
    1772 SCIP_Bool newsection;
    1773 SCIP_Bool linConsEQ;
    1774 SCIP_Bool initial;
    1776 SCIP_Bool enforce;
    1777 SCIP_Bool check;
    1778 SCIP_Bool propagate;
    1779 SCIP_Bool local;
    1780 SCIP_Bool dynamic;
    1781 SCIP_Bool removable;
    1782 int lincoefssize;
    1783 int quadcoefssize;
    1784 int nlincoefs;
    1785 int nquadcoefs;
    1786 int linsidesign;
    1787 int j;
    1788
    1789 assert( lpinput != NULL );
    1790 assert( binvar != NULL );
    1791
    1792 retcode = SCIP_OKAY;
    1793
    1794 /* check that binvalue is 0 or 1 */
    1795 if( !SCIPisFeasEQ(scip, binvalue, 0.0) && !SCIPisFeasEQ(scip, binvalue, 1.0) )
    1796 {
    1797 syntaxError(scip, lpinput, "value for binary variable must be '0' or '1'.");
    1798 return SCIP_OKAY;
    1799 }
    1800
    1801 if( SCIPisFeasEQ(scip, binvalue, 0.0) )
    1802 {
    1803 SCIP_VAR* negbinvar;
    1804 SCIP_Bool infeasible;
    1805
    1806 /* At this point we force the variable binvar to be binary, since we need the negated variable. We have to check
    1807 * later whether the type of the variable specified in the file agrees with this specification.
    1808 */
    1809 /* check whether bounds are correct - might already been set if variable is used in another indicator constraint */
    1810 if( SCIPvarGetLbGlobal(binvar) < 0.0 )
    1811 SCIP_CALL( SCIPchgVarLb(scip, binvar, 0.0) );
    1812 if( SCIPvarGetUbGlobal(binvar) > 1.0 )
    1813 SCIP_CALL( SCIPchgVarUb(scip, binvar, 1.0) );
    1814 SCIP_CALL( SCIPchgVarType(scip, binvar, SCIP_VARTYPE_BINARY, &infeasible) );
    1815 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    1816
    1817 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
    1818 binvar = negbinvar;
    1819 assert( binvar != NULL );
    1820 }
    1821
    1822 /* read linear constraint */
    1823 SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name2, &lincoefssize, &linvars, &lincoefs, &nlincoefs,
    1824 &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, NULL, &newsection) );
    1825
    1826 if( hasError(lpinput) )
    1827 goto TERMINATE;
    1828 if( newsection )
    1829 {
    1830 syntaxError(scip, lpinput, "expected constraint.");
    1831 goto TERMINATE;
    1832 }
    1833 if( nquadcoefs > 0 )
    1834 {
    1835 /* @todo could introduce auxiliary variable and move quadratic part into quadratic constraint? */
    1836 syntaxError(scip, lpinput, "quadratic indicator constraints not supported.");
    1837 goto TERMINATE;
    1838 }
    1839 if( name2[0] != '\0' )
    1840 {
    1841 syntaxError(scip, lpinput, "did not expect name for linear constraint.");
    1842 goto TERMINATE;
    1843 }
    1844
    1845 /* read the constraint sense */
    1846 if( !getNextToken(scip, lpinput) )
    1847 {
    1848 syntaxError(scip, lpinput, "missing constraint sense.");
    1849 goto TERMINATE;
    1850 }
    1851 if( !isSense(lpinput, &linsense) )
    1852 {
    1853 syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
    1854 goto TERMINATE;
    1855 }
    1856 assert(linsense == LP_SENSE_GE || linsense == LP_SENSE_LE || linsense == LP_SENSE_EQ); /*lint !e530*/
    1857
    1858 /* read the right hand side */
    1859 linsidesign = +1;
    1860 if( !getNextToken(scip, lpinput) )
    1861 {
    1862 syntaxError(scip, lpinput, "missing right hand side.");
    1863 goto TERMINATE;
    1864 }
    1865 if( isSign(lpinput, &linsidesign) )
    1866 {
    1867 if( !getNextToken(scip, lpinput) )
    1868 {
    1869 syntaxError(scip, lpinput, "missing value of right hand side.");
    1870 goto TERMINATE;
    1871 }
    1872 }
    1873 if( !isValue(scip, lpinput, &linsidevalue) )
    1874 {
    1875 syntaxError(scip, lpinput, "expected value for right hand side.");
    1876 goto TERMINATE;
    1877 }
    1878 linsidevalue *= linsidesign;
    1879
    1880 /* assign the left and right hand side, depending on the constraint sense */
    1881 linConsEQ = FALSE;
    1882 switch( linsense ) /*lint !e530*/
    1883 {
    1884 case LP_SENSE_GE:
    1885 linrhs = -linsidevalue;
    1886 for( j = 0; j < nlincoefs; ++j )
    1887 lincoefs[j] *= -1;
    1888 break;
    1889 case LP_SENSE_LE:
    1890 linrhs = linsidevalue;
    1891 break;
    1892 case LP_SENSE_EQ:
    1893 linConsEQ = TRUE;
    1894 linrhs = linsidevalue;
    1895 break;
    1896 case LP_SENSE_NOTHING:
    1897 default:
    1898 /* this case cannot occur because it is caught by the syntax check method isSense() above */
    1899 SCIPerrorMessage("invalid constraint sense <%d>\n", linsense);
    1900 return SCIP_INVALIDDATA;
    1901 }
    1902 assert(lincoefs != NULL);
    1903
    1904 /* create and add the indicator constraint */
    1905 initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
    1906 separate = TRUE;
    1907 enforce = !lpinput->inusercuts;
    1908 check = !lpinput->inusercuts;
    1909 propagate = TRUE;
    1910 local = FALSE;
    1911 dynamic = lpinput->dynamicconss;
    1912 removable = lpinput->dynamicrows || lpinput->inusercuts;
    1913
    1914 retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlincoefs, linvars, lincoefs, linrhs,
    1915 initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE);
    1916
    1917 if( retcode != SCIP_OKAY )
    1918 goto TERMINATE;
    1919
    1920 SCIP_CALL( SCIPaddCons(scip, cons) );
    1921 SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
    1922 lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
    1924 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    1925
    1926 /* create second constraint if it was an equation */
    1927 if( linConsEQ )
    1928 {
    1929 char newname[SCIP_MAXSTRLEN];
    1930
    1931 (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_eqneg", name);
    1932
    1933 for( j = 0; j < nlincoefs; ++j )
    1934 lincoefs[j] *= -1;
    1935 linrhs *= -1;
    1936 retcode = SCIPcreateConsIndicator(scip, &cons, newname, binvar, nlincoefs, linvars, lincoefs, linrhs,
    1937 initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE);
    1938
    1939 if( retcode != SCIP_OKAY )
    1940 goto TERMINATE;
    1941
    1942 SCIP_CALL( SCIPaddCons(scip, cons) );
    1943 SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
    1944 lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
    1946 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    1947 }
    1948
    1949 TERMINATE:
    1950 /* free memory */
    1951 SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
    1952 SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
    1953 SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
    1954 SCIPfreeBlockMemoryArrayNull(scip, &lincoefs, lincoefssize);
    1955 SCIPfreeBlockMemoryArrayNull(scip, &linvars, lincoefssize);
    1956
    1957 SCIP_CALL( retcode );
    1958
    1959 return SCIP_OKAY;
    1960}
    1961
    1962/** reads the constraints section
    1963 *
    1964 * Read linear and indicator constraints.
    1965 *
    1966 * The CPLEX manual says that indicator constraints are of the following form:
    1967 *
    1968 * [constraintname:] binaryvariable = value -> linear constraint
    1969 *
    1970 * We also accept "<->".
    1971 */
    1972static
    1974 SCIP* scip, /**< SCIP data structure */
    1975 LPINPUT* lpinput /**< LP reading data */
    1976 )
    1977{
    1978 char name[LP_MAX_LINELEN];
    1979 SCIP_CONS* cons;
    1980 SCIP_VAR** vars;
    1981 SCIP_RATIONAL** coefs;
    1982 LPSENSE sense;
    1983 SCIP_RETCODE retcode;
    1984 SCIP_RATIONAL* sidevalue;
    1985 SCIP_RATIONAL* lhs;
    1986 SCIP_RATIONAL* rhs;
    1987 SCIP_Bool newsection;
    1988 SCIP_Bool initial;
    1990 SCIP_Bool enforce;
    1991 SCIP_Bool check;
    1992 SCIP_Bool propagate;
    1993 SCIP_Bool local;
    1994 SCIP_Bool modifiable;
    1995 SCIP_Bool dynamic;
    1996 SCIP_Bool removable;
    1997 SCIP_Bool isIndicatorCons;
    1998 int ncoefs;
    1999 int sidesign;
    2000 int coefssize;
    2001
    2002 assert(lpinput != NULL);
    2003
    2004 retcode = SCIP_OKAY;
    2005
    2009
    2010 /* read coefficients */
    2011 SCIP_CALL( readCoefficientsRational(scip, lpinput, FALSE, name, &coefssize, &vars, &coefs, &ncoefs,
    2012 NULL, &newsection) );
    2013
    2014 if( hasError(lpinput) )
    2015 goto TERMINATE;
    2016 if( newsection )
    2017 {
    2018 if( ncoefs > 0 )
    2019 syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
    2020 goto TERMINATE;
    2021 }
    2022
    2023 /* read the constraint sense */
    2024 if( !getNextToken(scip, lpinput) )
    2025 {
    2026 syntaxError(scip, lpinput, "missing constraint sense.");
    2027 goto TERMINATE;
    2028 }
    2029 if( !isSense(lpinput, &sense) )
    2030 {
    2031 syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
    2032 goto TERMINATE;
    2033 }
    2034 assert(sense == LP_SENSE_GE || sense == LP_SENSE_LE || sense == LP_SENSE_EQ); /*lint !e530*/
    2035
    2036 /* read the right hand side */
    2037 sidesign = +1;
    2038 if( !getNextToken(scip, lpinput) )
    2039 {
    2040 syntaxError(scip, lpinput, "missing right hand side.");
    2041 goto TERMINATE;
    2042 }
    2043 if( isSign(lpinput, &sidesign) )
    2044 {
    2045 if( !getNextToken(scip, lpinput) )
    2046 {
    2047 syntaxError(scip, lpinput, "missing value of right hand side.");
    2048 goto TERMINATE;
    2049 }
    2050 }
    2051 if( !isValueRational(scip, lpinput, sidevalue) )
    2052 {
    2053 syntaxError(scip, lpinput, "expected value as right hand side.");
    2054 goto TERMINATE;
    2055 }
    2056 SCIPrationalMultReal(sidevalue, sidevalue, (double) sidesign);
    2057
    2058 /* assign the left and right hand side, depending on the constraint sense */
    2059 switch( sense ) /*lint !e530*/
    2060 {
    2061 case LP_SENSE_GE:
    2062 SCIPrationalSetRational(lhs, sidevalue);
    2064 break;
    2065 case LP_SENSE_LE:
    2067 SCIPrationalSetRational(rhs, sidevalue);
    2068 break;
    2069 case LP_SENSE_EQ:
    2070 SCIPrationalSetRational(lhs, sidevalue);
    2071 SCIPrationalSetRational(rhs, sidevalue);
    2072 break;
    2073 case LP_SENSE_NOTHING:
    2074 default:
    2075 /* this case cannot occur because it is caught by the syntax check method isSense() above */
    2076 SCIPerrorMessage("invalid constraint sense <%d>.\n", sense);
    2077 return SCIP_INVALIDDATA;
    2078 }
    2079
    2080 /* check whether we read the first part of an indicator constraint */
    2081 isIndicatorCons = FALSE;
    2082 if ( getNextToken(scip, lpinput) && !isNewSection(scip, lpinput) )
    2083 {
    2084 /* check whether we have '<' from a "<->" string */
    2085 if ( *lpinput->token == '<' )
    2086 {
    2087 int linepos = lpinput->linepos-1;
    2088
    2089 /* check next token - cannot be a new section */
    2090 if ( getNextToken(scip, lpinput) )
    2091 {
    2092 /* check for "<-" */
    2093 if ( *lpinput->token == '-' )
    2094 {
    2095 /* check next token - cannot be a new section */
    2096 if ( getNextToken(scip, lpinput) )
    2097 {
    2098 /* check for "<->" */
    2099 if ( *lpinput->token == '>' )
    2100 {
    2101 lpinput->linepos = linepos;
    2102 (void) SCIPsnprintf(lpinput->token, 2, "<");
    2103 syntaxError(scip, lpinput,
    2104 "SCIP does not support equivalence (<->) indicator constraints; consider using the \"->\" form.");
    2105 goto TERMINATE;
    2106 }
    2107 }
    2108 }
    2109 }
    2110 /* reset the lpinput for further usage as we have no indicator constraint */
    2111 lpinput->linepos = linepos;
    2112 (void) SCIPsnprintf(lpinput->token, 2, "<");
    2113 }
    2114
    2115 /* check for "->" */
    2116 if ( *lpinput->token == '-' )
    2117 {
    2118 /* remember '-' in token buffer */
    2119 swapTokenBuffer(lpinput);
    2120
    2121 /* check next token - cannot be a new section */
    2122 if( getNextToken(scip, lpinput) )
    2123 {
    2124 /* check for "->" */
    2125 if ( *lpinput->token == '>' )
    2126 isIndicatorCons = TRUE;
    2127 else
    2128 {
    2129 /* push back last token and '-' */
    2130 pushToken(lpinput);
    2131 pushBufferToken(lpinput);
    2132 }
    2133 }
    2134 else
    2135 pushBufferToken(lpinput);
    2136 }
    2137 else
    2138 pushToken(lpinput);
    2139 }
    2140
    2141 if( !isIndicatorCons )
    2142 {
    2143 /* create and add the linear constraint */
    2144 initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
    2145 separate = TRUE;
    2146 enforce = !lpinput->inusercuts;
    2147 check = !lpinput->inusercuts;
    2148 propagate = TRUE;
    2149 local = FALSE;
    2150 modifiable = FALSE;
    2151 dynamic = lpinput->dynamicconss;
    2152 removable = lpinput->dynamicrows || lpinput->inusercuts;
    2153
    2154 retcode = SCIPcreateConsExactLinear(scip, &cons, name, ncoefs, vars, coefs, lhs, rhs,
    2155 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
    2156
    2157 if( retcode != SCIP_OKAY )
    2158 goto TERMINATE;
    2159
    2160 SCIP_CALL( SCIPaddCons(scip, cons) );
    2161 SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
    2162 lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
    2164 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    2165 }
    2166 else
    2167 {
    2168 /* now we should have an indicator constraint */
    2169 if( ncoefs != 1 )
    2170 {
    2171 syntaxError(scip, lpinput, "Indicator part can only consist of one binary variable.");
    2172 goto TERMINATE;
    2173 }
    2174 assert(coefs != NULL);
    2175 if( !SCIPrationalIsEQReal(coefs[0], 1.0) )
    2176 {
    2177 syntaxError(scip, lpinput, "There cannot be a coefficient before the binary indicator variable.");
    2178 goto TERMINATE;
    2179 }
    2180 if( sense != LP_SENSE_EQ )
    2181 {
    2182 syntaxError(scip, lpinput, "Indicator part cannot handle equations.");
    2183 goto TERMINATE;
    2184 }
    2185 assert(vars != NULL);
    2186 retcode = createIndicatorConstraint(scip, lpinput, name, vars[0], SCIPrationalGetReal(lhs));
    2187 }
    2188
    2189 TERMINATE:
    2190 /* free memory */
    2191 SCIPrationalFreeBlockArray(SCIPblkmem(scip), &coefs, coefssize);
    2192 SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
    2193
    2197
    2198 SCIP_CALL( retcode );
    2199
    2200 return SCIP_OKAY;
    2201}
    2202
    2203
    2204/** reads the constraints section
    2205 *
    2206 * Read linear and indicator constraints.
    2207 *
    2208 * The CPLEX manual says that indicator constraints are of the following form:
    2209 *
    2210 * [constraintname:] binaryvariable = value -> linear constraint
    2211 *
    2212 * We also accept "<->".
    2213 */
    2214static
    2216 SCIP* scip, /**< SCIP data structure */
    2217 LPINPUT* lpinput /**< LP reading data */
    2218 )
    2219{
    2220 char name[LP_MAX_LINELEN];
    2221 SCIP_CONS* cons;
    2222 SCIP_VAR** vars;
    2223 SCIP_Real* coefs;
    2224 SCIP_VAR** quadvars1;
    2225 SCIP_VAR** quadvars2;
    2226 SCIP_Real* quadcoefs;
    2227 LPSENSE sense;
    2228 SCIP_RETCODE retcode;
    2229 SCIP_Real sidevalue;
    2230 SCIP_Real lhs;
    2231 SCIP_Real rhs;
    2232 SCIP_Bool newsection;
    2233 SCIP_Bool initial;
    2235 SCIP_Bool enforce;
    2236 SCIP_Bool check;
    2237 SCIP_Bool propagate;
    2238 SCIP_Bool local;
    2239 SCIP_Bool modifiable;
    2240 SCIP_Bool dynamic;
    2241 SCIP_Bool removable;
    2242 SCIP_Bool isIndicatorCons;
    2243 int ncoefs;
    2244 int sidesign;
    2245 int nquadcoefs;
    2246 int quadcoefssize;
    2247 int coefssize;
    2248
    2249 assert(lpinput != NULL);
    2250
    2251 retcode = SCIP_OKAY;
    2252
    2253 if( SCIPisExact(scip) )
    2254 {
    2256 return SCIP_OKAY;
    2257 }
    2258
    2259 /* read coefficients */
    2260 SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name, &coefssize, &vars, &coefs, &ncoefs,
    2261 &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, NULL, &newsection) );
    2262
    2263 if( hasError(lpinput) )
    2264 goto TERMINATE;
    2265 if( newsection )
    2266 {
    2267 if( ncoefs > 0 || nquadcoefs > 0 )
    2268 syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
    2269 goto TERMINATE;
    2270 }
    2271
    2272 /* read the constraint sense */
    2273 if( !getNextToken(scip, lpinput) )
    2274 {
    2275 syntaxError(scip, lpinput, "missing constraint sense.");
    2276 goto TERMINATE;
    2277 }
    2278 if( !isSense(lpinput, &sense) )
    2279 {
    2280 syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
    2281 goto TERMINATE;
    2282 }
    2283 assert(sense == LP_SENSE_GE || sense == LP_SENSE_LE || sense == LP_SENSE_EQ); /*lint !e530*/
    2284
    2285 /* read the right hand side */
    2286 sidesign = +1;
    2287 if( !getNextToken(scip, lpinput) )
    2288 {
    2289 syntaxError(scip, lpinput, "missing right hand side.");
    2290 goto TERMINATE;
    2291 }
    2292 if( isSign(lpinput, &sidesign) )
    2293 {
    2294 if( !getNextToken(scip, lpinput) )
    2295 {
    2296 syntaxError(scip, lpinput, "missing value of right hand side.");
    2297 goto TERMINATE;
    2298 }
    2299 }
    2300 if( !isValue(scip, lpinput, &sidevalue) )
    2301 {
    2302 syntaxError(scip, lpinput, "expected value as right hand side.");
    2303 goto TERMINATE;
    2304 }
    2305 sidevalue *= sidesign;
    2306
    2307 /* assign the left and right hand side, depending on the constraint sense */
    2308 switch( sense ) /*lint !e530*/
    2309 {
    2310 case LP_SENSE_GE:
    2311 lhs = sidevalue;
    2312 rhs = SCIPinfinity(scip);
    2313 break;
    2314 case LP_SENSE_LE:
    2315 lhs = -SCIPinfinity(scip);
    2316 rhs = sidevalue;
    2317 break;
    2318 case LP_SENSE_EQ:
    2319 lhs = sidevalue;
    2320 rhs = sidevalue;
    2321 break;
    2322 case LP_SENSE_NOTHING:
    2323 default:
    2324 /* this case cannot occur because it is caught by the syntax check method isSense() above */
    2325 SCIPerrorMessage("invalid constraint sense <%d>.\n", sense);
    2326 return SCIP_INVALIDDATA;
    2327 }
    2328
    2329 /* check whether we read the first part of an indicator constraint */
    2330 isIndicatorCons = FALSE;
    2331 if ( getNextToken(scip, lpinput) && !isNewSection(scip, lpinput) )
    2332 {
    2333 /* check whether we have '<' from a "<->" string */
    2334 if ( *lpinput->token == '<' )
    2335 {
    2336 int linepos = lpinput->linepos-1;
    2337
    2338 /* check next token - cannot be a new section */
    2339 if ( getNextToken(scip, lpinput) )
    2340 {
    2341 /* check for "<-" */
    2342 if ( *lpinput->token == '-' )
    2343 {
    2344 /* check next token - cannot be a new section */
    2345 if ( getNextToken(scip, lpinput) )
    2346 {
    2347 /* check for "<->" */
    2348 if ( *lpinput->token == '>' )
    2349 {
    2350 lpinput->linepos = linepos;
    2351 (void) SCIPsnprintf(lpinput->token, 2, "<");
    2352 syntaxError(scip, lpinput,
    2353 "SCIP does not support equivalence (<->) indicator constraints; consider using the \"->\" form.");
    2354 goto TERMINATE;
    2355 }
    2356 }
    2357 }
    2358 }
    2359 /* reset the lpinput for further usage as we have no indicator constraint */
    2360 lpinput->linepos = linepos;
    2361 (void) SCIPsnprintf(lpinput->token, 2, "<");
    2362 }
    2363
    2364 /* check for "->" */
    2365 if ( *lpinput->token == '-' )
    2366 {
    2367 /* remember '-' in token buffer */
    2368 swapTokenBuffer(lpinput);
    2369
    2370 /* check next token - cannot be a new section */
    2371 if( getNextToken(scip, lpinput) )
    2372 {
    2373 /* check for "->" */
    2374 if ( *lpinput->token == '>' )
    2375 isIndicatorCons = TRUE;
    2376 else
    2377 {
    2378 /* push back last token and '-' */
    2379 pushToken(lpinput);
    2380 pushBufferToken(lpinput);
    2381 }
    2382 }
    2383 else
    2384 pushBufferToken(lpinput);
    2385 }
    2386 else
    2387 pushToken(lpinput);
    2388 }
    2389
    2390 if( !isIndicatorCons )
    2391 {
    2392 /* create and add the linear constraint */
    2393 initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
    2394 separate = TRUE;
    2395 enforce = !lpinput->inusercuts;
    2396 check = !lpinput->inusercuts;
    2397 propagate = TRUE;
    2398 local = FALSE;
    2399 modifiable = FALSE;
    2400 dynamic = lpinput->dynamicconss;
    2401 removable = lpinput->dynamicrows || lpinput->inusercuts;
    2402 if( nquadcoefs == 0 )
    2403 {
    2404 retcode = SCIPcreateConsLinear(scip, &cons, name, ncoefs, vars, coefs, lhs, rhs,
    2405 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
    2406 }
    2407 else
    2408 {
    2409 retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, name, ncoefs, vars, coefs,
    2410 nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
    2411 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
    2412 }
    2413
    2414 if( retcode != SCIP_OKAY )
    2415 goto TERMINATE;
    2416
    2417 SCIP_CALL( SCIPaddCons(scip, cons) );
    2418 SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
    2419 lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
    2421 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    2422 }
    2423 else
    2424 {
    2425 /* now we should have an indicator constraint */
    2426 if( ncoefs != 1 || nquadcoefs > 0 )
    2427 {
    2428 syntaxError(scip, lpinput, "Indicator part can only consist of one binary variable.");
    2429 goto TERMINATE;
    2430 }
    2431 assert(coefs != NULL);
    2432 if( !SCIPisEQ(scip, coefs[0], 1.0) )
    2433 {
    2434 syntaxError(scip, lpinput, "There cannot be a coefficient before the binary indicator variable.");
    2435 goto TERMINATE;
    2436 }
    2437 if( sense != LP_SENSE_EQ )
    2438 {
    2439 syntaxError(scip, lpinput, "Indicator part cannot handle equations.");
    2440 goto TERMINATE;
    2441 }
    2442 assert(vars != NULL);
    2443 retcode = createIndicatorConstraint(scip, lpinput, name, vars[0], lhs);
    2444 }
    2445
    2446 TERMINATE:
    2447 /* free memory */
    2448 SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
    2449 SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
    2450 SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
    2451 SCIPfreeBlockMemoryArrayNull(scip, &coefs, coefssize);
    2452 SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
    2453
    2454 SCIP_CALL( retcode );
    2455
    2456 return SCIP_OKAY;
    2457}
    2458
    2459/** reads the bounds section */
    2460static
    2462 SCIP* scip, /**< SCIP data structure */
    2463 LPINPUT* lpinput /**< LP reading data */
    2464 )
    2465{
    2466 SCIP_RATIONAL* value;
    2467 SCIP_RATIONAL* lb;
    2468 SCIP_RATIONAL* ub;
    2469
    2470 assert(lpinput != NULL);
    2471
    2475
    2476 while( getNextToken(scip, lpinput) )
    2477 {
    2478 SCIP_VAR* var;
    2479
    2480 int sign;
    2481 SCIP_Bool hassign;
    2482 LPSENSE leftsense;
    2483
    2484 /* check if we reached a new section */
    2485 if( isNewSection(scip, lpinput) )
    2486 goto TERMINATE;
    2487
    2488 /* default bounds are [0,+inf] */
    2489 SCIPrationalSetReal(lb, 0.0);
    2491 leftsense = LP_SENSE_NOTHING;
    2492
    2493 /* check if the first token is a sign */
    2494 sign = +1;
    2495 hassign = isSign(lpinput, &sign);
    2496 if( hassign && !getNextToken(scip, lpinput) )
    2497 {
    2498 syntaxError(scip, lpinput, "expected value.");
    2499 goto TERMINATE;
    2500 }
    2501
    2502 /* the first token must be either a value or a variable name */
    2503 if( isValueRational(scip, lpinput, value) )
    2504 {
    2505 /* first token is a value: the second token must be a sense */
    2506 if( !getNextToken(scip, lpinput) || !isSense(lpinput, &leftsense) )
    2507 {
    2508 syntaxError(scip, lpinput, "expected bound sense '<=', '=', or '>='.");
    2509 goto TERMINATE;
    2510 }
    2511
    2512 /* update the bound corresponding to the sense */
    2513 switch( leftsense )
    2514 {
    2515 case LP_SENSE_GE:
    2516 SCIPrationalMultReal(ub, value, (double) sign);
    2517 break;
    2518 case LP_SENSE_LE:
    2519 SCIPrationalMultReal(lb, value, (double) sign);
    2520 break;
    2521 case LP_SENSE_EQ:
    2522 SCIPrationalMultReal(lb, value, (double) sign);
    2523 SCIPrationalMultReal(ub, value, (double) sign);
    2524 break;
    2525 case LP_SENSE_NOTHING:
    2526 default:
    2527 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    2528 return SCIP_INVALIDDATA;
    2529 }
    2530 }
    2531 else if( hassign )
    2532 {
    2533 syntaxError(scip, lpinput, "expected value.");
    2534 goto TERMINATE;
    2535 }
    2536 else
    2537 pushToken(lpinput);
    2538
    2539 /* the next token must be a variable name */
    2540 if( !getNextToken(scip, lpinput) )
    2541 {
    2542 syntaxError(scip, lpinput, "expected variable name.");
    2543 goto TERMINATE;
    2544 }
    2545 SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
    2546
    2547 /* the next token might be another sense, or the word "free" */
    2548 if( getNextToken(scip, lpinput) )
    2549 {
    2550 LPSENSE rightsense;
    2551
    2552 if( isSense(lpinput, &rightsense) )
    2553 {
    2554 /* check, if the senses fit */
    2555 if( leftsense == LP_SENSE_NOTHING
    2556 || (leftsense == LP_SENSE_LE && rightsense == LP_SENSE_LE)
    2557 || (leftsense == LP_SENSE_GE && rightsense == LP_SENSE_GE) )
    2558 {
    2559 if( !getNextToken(scip, lpinput) )
    2560 {
    2561 syntaxError(scip, lpinput, "expected value or sign.");
    2562 goto TERMINATE;
    2563 }
    2564
    2565 /* check if the next token is a sign */
    2566 sign = +1;
    2567 hassign = isSign(lpinput, &sign);
    2568 if( hassign && !getNextToken(scip, lpinput) )
    2569 {
    2570 syntaxError(scip, lpinput, "expected value.");
    2571 goto TERMINATE;
    2572 }
    2573
    2574 /* the next token must be a value */
    2575 if( !isValueRational(scip, lpinput, value) )
    2576 {
    2577 syntaxError(scip, lpinput, "expected value.");
    2578 goto TERMINATE;
    2579 }
    2580
    2581 /* update the bound corresponding to the sense */
    2582 switch( rightsense )
    2583 {
    2584 case LP_SENSE_GE:
    2585 SCIPrationalMultReal(lb, value, (double) sign);
    2586 break;
    2587 case LP_SENSE_LE:
    2588 SCIPrationalMultReal(ub, value, (double) sign);
    2589 break;
    2590 case LP_SENSE_EQ:
    2591 SCIPrationalMultReal(lb, value, (double) sign);
    2592 SCIPrationalMultReal(ub, value, (double) sign);
    2593 break;
    2594 case LP_SENSE_NOTHING:
    2595 default:
    2596 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    2597 return SCIP_INVALIDDATA;
    2598 }
    2599 }
    2600 else
    2601 {
    2602 syntaxError(scip, lpinput, "the two bound senses do not fit.");
    2603 goto TERMINATE;
    2604 }
    2605 }
    2606 else if( SCIPstrcasecmp(lpinput->token, "FREE") == 0 )
    2607 {
    2608 if( leftsense != LP_SENSE_NOTHING )
    2609 {
    2610 syntaxError(scip, lpinput, "variable with bound is marked as 'free'.");
    2611 goto TERMINATE;
    2612 }
    2615 }
    2616 else
    2617 {
    2618 /* the token was no sense: push it back to the token stack */
    2619 pushToken(lpinput);
    2620 }
    2621 }
    2622
    2623 /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
    2624 if( !SCIPrationalIsZero(lb) )
    2625 SCIP_CALL( SCIPchgVarLbExact(scip, var, lb) );
    2626 /*lint --e{777}*/
    2627 if( !SCIPrationalIsInfinity(ub) )
    2628 SCIP_CALL( SCIPchgVarUbExact(scip, var, ub) );
    2629 SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", lpinput->linenumber, SCIPvarGetName(var),
    2631 }
    2632
    2633TERMINATE:
    2637
    2638 return SCIP_OKAY;
    2639}
    2640
    2641
    2642/** reads the bounds section */
    2643static
    2645 SCIP* scip, /**< SCIP data structure */
    2646 LPINPUT* lpinput /**< LP reading data */
    2647 )
    2648{
    2649 assert(lpinput != NULL);
    2650
    2651 if( SCIPisExact(scip) )
    2652 {
    2653 SCIP_CALL( readBoundsRational(scip, lpinput) );
    2654 return SCIP_OKAY;
    2655 }
    2656
    2657 while( getNextToken(scip, lpinput) )
    2658 {
    2659 SCIP_VAR* var;
    2660 SCIP_Real value;
    2661 SCIP_Real lb;
    2662 SCIP_Real ub;
    2663 int sign;
    2664 SCIP_Bool hassign;
    2665 LPSENSE leftsense;
    2666
    2667 /* check if we reached a new section */
    2668 if( isNewSection(scip, lpinput) )
    2669 return SCIP_OKAY;
    2670
    2671 /* default bounds are [0,+inf] */
    2672 lb = 0.0;
    2673 ub = SCIPinfinity(scip);
    2674 leftsense = LP_SENSE_NOTHING;
    2675
    2676 /* check if the first token is a sign */
    2677 sign = +1;
    2678 hassign = isSign(lpinput, &sign);
    2679 if( hassign && !getNextToken(scip, lpinput) )
    2680 {
    2681 syntaxError(scip, lpinput, "expected value.");
    2682 return SCIP_OKAY;
    2683 }
    2684
    2685 /* the first token must be either a value or a variable name */
    2686 if( isValue(scip, lpinput, &value) )
    2687 {
    2688 /* first token is a value: the second token must be a sense */
    2689 if( !getNextToken(scip, lpinput) || !isSense(lpinput, &leftsense) )
    2690 {
    2691 syntaxError(scip, lpinput, "expected bound sense '<=', '=', or '>='.");
    2692 return SCIP_OKAY;
    2693 }
    2694
    2695 /* update the bound corresponding to the sense */
    2696 switch( leftsense )
    2697 {
    2698 case LP_SENSE_GE:
    2699 ub = sign * value;
    2700 break;
    2701 case LP_SENSE_LE:
    2702 lb = sign * value;
    2703 break;
    2704 case LP_SENSE_EQ:
    2705 lb = sign * value;
    2706 ub = sign * value;
    2707 break;
    2708 case LP_SENSE_NOTHING:
    2709 default:
    2710 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    2711 return SCIP_INVALIDDATA;
    2712 }
    2713 }
    2714 else if( hassign )
    2715 {
    2716 syntaxError(scip, lpinput, "expected value.");
    2717 return SCIP_OKAY;
    2718 }
    2719 else
    2720 pushToken(lpinput);
    2721
    2722 /* the next token must be a variable name */
    2723 if( !getNextToken(scip, lpinput) )
    2724 {
    2725 syntaxError(scip, lpinput, "expected variable name.");
    2726 return SCIP_OKAY;
    2727 }
    2728 SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
    2729
    2730 /* the next token might be another sense, or the word "free" */
    2731 if( getNextToken(scip, lpinput) )
    2732 {
    2733 LPSENSE rightsense;
    2734
    2735 if( isSense(lpinput, &rightsense) )
    2736 {
    2737 /* check, if the senses fit */
    2738 if( leftsense == LP_SENSE_NOTHING
    2739 || (leftsense == LP_SENSE_LE && rightsense == LP_SENSE_LE)
    2740 || (leftsense == LP_SENSE_GE && rightsense == LP_SENSE_GE) )
    2741 {
    2742 if( !getNextToken(scip, lpinput) )
    2743 {
    2744 syntaxError(scip, lpinput, "expected value or sign.");
    2745 return SCIP_OKAY;
    2746 }
    2747
    2748 /* check if the next token is a sign */
    2749 sign = +1;
    2750 hassign = isSign(lpinput, &sign);
    2751 if( hassign && !getNextToken(scip, lpinput) )
    2752 {
    2753 syntaxError(scip, lpinput, "expected value.");
    2754 return SCIP_OKAY;
    2755 }
    2756
    2757 /* the next token must be a value */
    2758 if( !isValue(scip, lpinput, &value) )
    2759 {
    2760 syntaxError(scip, lpinput, "expected value.");
    2761 return SCIP_OKAY;
    2762 }
    2763
    2764 /* update the bound corresponding to the sense */
    2765 switch( rightsense )
    2766 {
    2767 case LP_SENSE_GE:
    2768 lb = sign * value;
    2769 break;
    2770 case LP_SENSE_LE:
    2771 ub = sign * value;
    2772 break;
    2773 case LP_SENSE_EQ:
    2774 lb = sign * value;
    2775 ub = sign * value;
    2776 break;
    2777 case LP_SENSE_NOTHING:
    2778 default:
    2779 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    2780 return SCIP_INVALIDDATA;
    2781 }
    2782 }
    2783 else
    2784 {
    2785 syntaxError(scip, lpinput, "the two bound senses do not fit.");
    2786 return SCIP_OKAY;
    2787 }
    2788 }
    2789 else if( SCIPstrcasecmp(lpinput->token, "FREE") == 0 )
    2790 {
    2791 if( leftsense != LP_SENSE_NOTHING )
    2792 {
    2793 syntaxError(scip, lpinput, "variable with bound is marked as 'free'.");
    2794 return SCIP_OKAY;
    2795 }
    2796 lb = -SCIPinfinity(scip);
    2797 ub = SCIPinfinity(scip);
    2798 }
    2799 else
    2800 {
    2801 /* the token was no sense: push it back to the token stack */
    2802 pushToken(lpinput);
    2803 }
    2804 }
    2805
    2806 /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
    2807 if( lb != 0.0 )
    2808 SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
    2809 /*lint --e{777}*/
    2810 if( ub != SCIPinfinity(scip) )
    2811 SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
    2812 SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", lpinput->linenumber, SCIPvarGetName(var),
    2814 }
    2815
    2816 return SCIP_OKAY;
    2817}
    2818
    2819/** reads the generals section */
    2820static
    2822 SCIP* scip, /**< SCIP data structure */
    2823 LPINPUT* lpinput /**< LP reading data */
    2824 )
    2825{
    2826 assert(lpinput != NULL);
    2827
    2828 while( getNextToken(scip, lpinput) )
    2829 {
    2830 SCIP_VAR* var;
    2831 SCIP_Real lb;
    2832 SCIP_Real ub;
    2833 SCIP_Bool created;
    2834 SCIP_Bool infeasible;
    2835
    2836 /* check if we reached a new section */
    2837 if( isNewSection(scip, lpinput) )
    2838 return SCIP_OKAY;
    2839
    2840 /* the token must be the name of an existing variable */
    2841 SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
    2842 if( created )
    2843 {
    2844 syntaxError(scip, lpinput, "unknown variable in generals section.");
    2845 return SCIP_OKAY;
    2846 }
    2847
    2848 lb = SCIPvarGetLbGlobal(var);
    2849 ub = SCIPvarGetUbGlobal(var);
    2850
    2851 if( !SCIPisFeasIntegral(scip, lb) || !SCIPisFeasIntegral(scip, ub) )
    2852 {
    2853 SCIPwarningMessage(scip, "variable <%s> declared as integer has non-integral bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
    2854 }
    2855
    2856 /* mark the variable to be integral */
    2857 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    2858 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    2859 }
    2860
    2861 return SCIP_OKAY;
    2862}
    2863
    2864/** reads the binaries section */
    2865static
    2867 SCIP* scip, /**< SCIP data structure */
    2868 LPINPUT* lpinput /**< LP reading data */
    2869 )
    2870{
    2871 assert(lpinput != NULL);
    2872
    2873 while( getNextToken(scip, lpinput) )
    2874 {
    2875 SCIP_VAR* var;
    2876 SCIP_Real lb;
    2877 SCIP_Real ub;
    2878 SCIP_Bool created;
    2879 SCIP_Bool infeasible;
    2880
    2881 /* check if we reached a new section */
    2882 if( isNewSection(scip, lpinput) )
    2883 return SCIP_OKAY;
    2884
    2885 /* the token must be the name of an existing variable */
    2886 SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
    2887 if( created )
    2888 {
    2889 syntaxError(scip, lpinput, "unknown variable in binaries section.");
    2890 return SCIP_OKAY;
    2891 }
    2892
    2893 lb = SCIPvarGetLbGlobal(var);
    2894 ub = SCIPvarGetUbGlobal(var);
    2895
    2896 if( (!SCIPisFeasZero(scip, lb) && !SCIPisFeasEQ(scip, lb, 1.0)) ||
    2897 (!SCIPisFeasZero(scip, ub) && !SCIPisFeasEQ(scip, ub, 1.0) && !SCIPisInfinity(scip, ub)) )
    2898 {
    2899 SCIPwarningMessage(scip, "variable <%s> declared as binary has non-binary bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
    2900 }
    2901
    2902 /* mark the variable to be binary and change its bounds appropriately */
    2903 if( SCIPvarGetLbGlobal(var) < 0.0 )
    2904 {
    2905 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
    2906 if( SCIPisExact(scip) )
    2907 {
    2908 SCIP_RATIONAL* tmp;
    2910 SCIPrationalSetReal(tmp, 0.0);
    2911 SCIP_CALL( SCIPchgVarLbExact(scip, var, tmp) );
    2913 }
    2914 }
    2915 if( SCIPvarGetUbGlobal(var) > 1.0 )
    2916 {
    2917 SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
    2918 if( SCIPisExact(scip) )
    2919 {
    2920 SCIP_RATIONAL* tmp;
    2922 SCIPrationalSetReal(tmp, 1.0);
    2923 SCIP_CALL( SCIPchgVarUbExact(scip, var, tmp) );
    2925 }
    2926 }
    2927 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
    2928 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    2929 }
    2930
    2931 return SCIP_OKAY;
    2932}
    2933
    2934/** reads the semi-continuous section */
    2935static
    2937 SCIP* scip, /**< SCIP data structure */
    2938 LPINPUT* lpinput /**< LP reading data */
    2939 )
    2940{
    2941 SCIP_Real oldlb;
    2942 char name[SCIP_MAXSTRLEN];
    2943 SCIP_CONS* cons;
    2944 SCIP_VAR* var;
    2945 SCIP_Bool created;
    2946
    2947 SCIP_VAR* vars[2];
    2948 SCIP_BOUNDTYPE boundtypes[2];
    2949 SCIP_Real bounds[2];
    2950
    2951 assert(lpinput != NULL);
    2952
    2953 /* if section is titles "semi-continuous", then the parser breaks this into parts */
    2954 if( SCIPstrcasecmp(lpinput->token, "SEMI") == 0 )
    2955 {
    2956 if( !getNextToken(scip, lpinput) )
    2957 {
    2958 syntaxError(scip, lpinput, "unexpected end.");
    2959 return SCIP_OKAY;
    2960 }
    2961
    2962 if( SCIPstrcasecmp(lpinput->token, "-") == 0 )
    2963 {
    2964 if( !getNextToken(scip, lpinput) || SCIPstrcasecmp(lpinput->token, "CONTINUOUS") != 0 )
    2965 {
    2966 syntaxError(scip, lpinput, "expected 'CONTINUOUS' after 'SEMI-'.");
    2967 return SCIP_OKAY;
    2968 }
    2969 }
    2970 else
    2971 {
    2972 pushToken(lpinput);
    2973 }
    2974 }
    2975
    2976 while( getNextToken(scip, lpinput) )
    2977 {
    2978 /* check if we reached a new section */
    2979 if( isNewSection(scip, lpinput) )
    2980 return SCIP_OKAY;
    2981
    2982 /* the token must be the name of an existing variable */
    2983 SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
    2984 if( created )
    2985 {
    2986 syntaxError(scip, lpinput, "unknown variable in semi-continuous section.");
    2987 return SCIP_OKAY;
    2988 }
    2989
    2990 if( SCIPvarGetLbGlobal(var) <= 0.0 )
    2991 {
    2992 SCIPdebugMsg(scip, "ignore semi-continuity of variable <%s> with negative lower bound %g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
    2993 continue;
    2994 }
    2995
    2996 oldlb = SCIPvarGetLbGlobal(var);
    2997
    2998 /* change the lower bound to 0.0 */
    2999 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
    3000
    3001 /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
    3002 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
    3003
    3004 vars[0] = var;
    3005 vars[1] = var;
    3006 boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
    3007 boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
    3008 bounds[0] = 0.0;
    3009 bounds[1] = oldlb;
    3010
    3011 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
    3012 !(lpinput->dynamiccols), TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, lpinput->dynamicconss, lpinput->dynamiccols, FALSE) );
    3013 SCIP_CALL( SCIPaddCons(scip, cons) );
    3014
    3015 SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity of <%s>:\n\t", SCIPvarGetName(var));
    3017
    3018 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3019 }
    3020
    3021 return SCIP_OKAY;
    3022}
    3023
    3024/** reads the sos section
    3025 *
    3026 * The format is as follows:
    3027 *
    3028 * SOS
    3029 * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
    3030 * ...
    3031 * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
    3032 * */
    3033static
    3035 SCIP* scip, /**< SCIP data structure */
    3036 LPINPUT* lpinput /**< LP reading data */
    3037 )
    3038{
    3039 SCIP_Bool initial, separate, enforce, check, propagate;
    3040 SCIP_Bool local, dynamic, removable;
    3041 char name[SCIP_MAXSTRLEN];
    3042 int cnt = 0;
    3043
    3044 assert(lpinput != NULL);
    3045
    3046 /* standard settings for SOS constraints: */
    3047 initial = lpinput->initialconss;
    3048 separate = TRUE;
    3049 enforce = TRUE;
    3050 check = TRUE;
    3051 propagate = TRUE;
    3052 local = FALSE;
    3053 dynamic = lpinput->dynamicconss;
    3054 removable = lpinput->dynamicrows;
    3055
    3056 while( getNextToken(scip, lpinput) )
    3057 {
    3058 int type = -1;
    3059 SCIP_CONS* cons;
    3060
    3061 /* check if we reached a new section */
    3062 if( isNewSection(scip, lpinput) )
    3063 return SCIP_OKAY;
    3064
    3065 /* check for an SOS constraint name */
    3066 *name = '\0';
    3067
    3068 /* remember the token in the token buffer */
    3069 swapTokenBuffer(lpinput);
    3070
    3071 /* get the next token and check, whether it is a colon */
    3072 if( getNextToken(scip, lpinput) )
    3073 {
    3074 if( strcmp(lpinput->token, ":") == 0 )
    3075 {
    3076 /* the second token was a colon: the first token is the constraint name */
    3077 (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
    3078
    3079 name[SCIP_MAXSTRLEN-1] = '\0';
    3080 }
    3081 else
    3082 {
    3083 /* the second token was no colon: push the tokens back onto the token stack and parse it next */
    3084 pushToken(lpinput);
    3085 pushBufferToken(lpinput);
    3086 }
    3087 }
    3088 else
    3089 {
    3090 /* there was only one token left: push it back onto the token stack and parse it next */
    3091 pushBufferToken(lpinput);
    3092 }
    3093
    3094 /* get type */
    3095 if( !getNextToken(scip, lpinput) )
    3096 {
    3097 syntaxError(scip, lpinput, "expected SOS type: 'S1::' or 'S2::'.");
    3098 return SCIP_OKAY;
    3099 }
    3100 /* check whether constraint name was left out */
    3101 if( strcmp(lpinput->token, ":") == 0 )
    3102 {
    3103 /* we have to push twice ':' and once the type: */
    3104 pushToken(lpinput);
    3105 lpinput->token[0] = ':';
    3106 lpinput->token[1] = '\0';
    3107 pushToken(lpinput);
    3108 swapTokenBuffer(lpinput);
    3109
    3110 /* set artificial name */
    3111 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d", ++cnt);
    3112 }
    3113
    3114 /* check whether it is type 1 or type 2 */
    3115 if( strcmp(lpinput->token, "S1") == 0 )
    3116 {
    3117 type = 1;
    3118 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
    3119 local, dynamic, removable, FALSE) );
    3120 }
    3121 else if( strcmp(lpinput->token, "S2") == 0 )
    3122 {
    3123 type = 2;
    3124 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
    3125 local, dynamic, removable, FALSE) );
    3126 }
    3127 else
    3128 {
    3129 syntaxError(scip, lpinput, "SOS constraint type other than 1 or 2 appeared.");
    3130 return SCIP_OKAY;
    3131 }
    3132 assert( type == 1 || type == 2 );
    3133
    3134 SCIPdebugMsg(scip, "created SOS%d constraint <%s>\n", type, name);
    3135
    3136 /* make sure that a colons follows */
    3137 if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
    3138 {
    3139 syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
    3140 return SCIP_OKAY;
    3141 }
    3142
    3143 /* make sure that another colons follows */
    3144 if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
    3145 {
    3146 syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
    3147 return SCIP_OKAY;
    3148 }
    3149
    3150 /* parse elements of SOS constraint */
    3151 while( getNextToken(scip, lpinput) )
    3152 {
    3153 SCIP_VAR* var;
    3154 SCIP_Real weight;
    3155
    3156 /* check if we reached a new section */
    3157 if( isNewSection(scip, lpinput) )
    3158 break;
    3159
    3160 /* remember the token in the token buffer */
    3161 swapTokenBuffer(lpinput);
    3162
    3163 /* get variable and colon */
    3164 var = SCIPfindVar(scip, lpinput->tokenbuf);
    3165
    3166 /* if token is a variable name */
    3167 if( var == NULL )
    3168 {
    3169 pushBufferToken(lpinput);
    3170 break;
    3171 }
    3172 else
    3173 {
    3174 SCIPdebugMsg(scip, "found variable <%s>\n", SCIPvarGetName(var));
    3175 if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
    3176 {
    3177 syntaxError(scip, lpinput, "expected colon and weight.");
    3178 return SCIP_OKAY;
    3179 }
    3180 /* check next token */
    3181 if( !getNextToken(scip, lpinput) )
    3182 {
    3183 /* push back token, since it could be the name of a new constraint */
    3184 pushToken(lpinput);
    3185 pushBufferToken(lpinput);
    3186 break;
    3187 }
    3188 else
    3189 {
    3190 int sign = +1;
    3191
    3192 /* get sign */
    3193 if( isSign(lpinput, &sign) )
    3194 {
    3195 (void) getNextToken(scip, lpinput);
    3196 }
    3197
    3198 /* get weight */
    3199 if( !isValue(scip, lpinput, &weight) )
    3200 {
    3201 /* push back token, since it could be the name of a new constraint */
    3202 pushToken(lpinput);
    3203 pushBufferToken(lpinput);
    3204 break;
    3205 }
    3206 else
    3207 {
    3208 /* we now know that we have a variable/weight pair -> add variable*/
    3209 switch( type )
    3210 {
    3211 case 1:
    3212 SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, sign * weight) );
    3213 break;
    3214 case 2:
    3215 SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, sign * weight) );
    3216 break;
    3217 default:
    3218 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
    3219 SCIPABORT();
    3220 return SCIP_INVALIDDATA; /*lint !e527*/
    3221 }
    3222 SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
    3223 }
    3224 }
    3225 }
    3226 }
    3227
    3228 /* add the SOS constraint */
    3229 SCIP_CALL( SCIPaddCons(scip, cons) );
    3230 SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", lpinput->linenumber, SCIPconsGetName(cons));
    3232 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    3233 }
    3234
    3235 return SCIP_OKAY;
    3236}
    3237
    3238/** reads an LP file
    3239 *
    3240 * @todo check whether variables forced to be binary for the creation of indicator constraints are
    3241 * really specified to be binary (or general with 0/1 bounds) in the file.
    3242 */
    3243static
    3245 SCIP* scip, /**< SCIP data structure */
    3246 LPINPUT* lpinput, /**< LP reading data */
    3247 const char* filename /**< name of the input file */
    3248 )
    3249{
    3250 SCIP_RETCODE retcode = SCIP_OKAY;
    3251
    3252 assert(lpinput != NULL);
    3253
    3254 /* open file */
    3255 lpinput->file = SCIPfopen(filename, "r");
    3256 if( lpinput->file == NULL )
    3257 {
    3258 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    3259 SCIPprintSysError(filename);
    3260 return SCIP_NOFILE;
    3261 }
    3262
    3263 /* create problem */
    3264 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
    3265
    3266 /* parse the file */
    3267 lpinput->section = LP_START;
    3268 while( lpinput->section != LP_END && !hasError(lpinput) )
    3269 {
    3270 switch( lpinput->section )
    3271 {
    3272 case LP_START:
    3273 SCIP_CALL_TERMINATE( retcode, readStart(scip, lpinput), TERMINATE );
    3274 break;
    3275
    3276 case LP_OBJECTIVE:
    3277 SCIP_CALL_TERMINATE( retcode, readObjective(scip, lpinput), TERMINATE );
    3278 break;
    3279
    3280 case LP_CONSTRAINTS:
    3281 SCIP_CALL_TERMINATE( retcode, readConstraints(scip, lpinput), TERMINATE );
    3282 break;
    3283
    3284 case LP_BOUNDS:
    3285 SCIP_CALL_TERMINATE( retcode, readBounds(scip, lpinput), TERMINATE );
    3286 break;
    3287
    3288 case LP_GENERALS:
    3289 SCIP_CALL_TERMINATE( retcode, readGenerals(scip, lpinput), TERMINATE );
    3290 break;
    3291
    3292 case LP_BINARIES:
    3293 SCIP_CALL_TERMINATE( retcode, readBinaries(scip, lpinput), TERMINATE );
    3294 break;
    3295
    3296 case LP_SEMICONTINUOUS:
    3297 SCIP_CALL_TERMINATE( retcode, readSemicontinuous(scip, lpinput), TERMINATE );
    3298 break;
    3299
    3300 case LP_SOS:
    3301 SCIP_CALL_TERMINATE( retcode, readSos(scip, lpinput), TERMINATE );
    3302 break;
    3303
    3304 case LP_END: /* this is already handled in the while() loop */
    3305 default:
    3306 SCIPerrorMessage("invalid LP file section <%d>\n", lpinput->section);
    3307 retcode = SCIP_INVALIDDATA;
    3308 goto TERMINATE;
    3309 }
    3310 }
    3311
    3312 TERMINATE:
    3313 /* close file */
    3314 SCIPfclose(lpinput->file);
    3315
    3316 return retcode;
    3317}
    3318
    3319
    3320/*
    3321 * Local methods (for writing)
    3322 */
    3323
    3324/** hash key retrieval function for variables */
    3325static
    3327{ /*lint --e{715}*/
    3328 return elem;
    3329}
    3330
    3331/** returns TRUE iff the indices of both variables are equal */
    3332static
    3334{ /*lint --e{715}*/
    3335 if( key1 == key2 )
    3336 return TRUE;
    3337 return FALSE;
    3338}
    3339
    3340/** returns the hash value of the key */
    3341static
    3343{ /*lint --e{715}*/
    3344 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
    3345 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
    3346}
    3347
    3348/** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
    3349static
    3351 SCIP* scip, /**< SCIP data structure */
    3352 SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
    3353 SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
    3354 int* nvars, /**< pointer to number of variables and values in vars and vals array */
    3355 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
    3356 SCIP_Bool transformed /**< transformed constraint? */
    3357 )
    3358{
    3359 int requiredsize;
    3360 int v;
    3361
    3362 assert(scip != NULL);
    3363 assert(vars != NULL);
    3364 assert(scalars != NULL);
    3365 assert(nvars != NULL);
    3366 assert(*vars != NULL || *nvars == 0);
    3367 assert(*scalars != NULL || *nvars == 0);
    3368 assert(constant != NULL);
    3369
    3370 if( transformed )
    3371 {
    3372 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize) );
    3373
    3374 if( requiredsize > *nvars )
    3375 {
    3376 SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
    3377 SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
    3378
    3379 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize) );
    3380 }
    3381 assert( requiredsize == *nvars );
    3382 }
    3383 else
    3384 {
    3385 if( *nvars > 0 && ( *vars == NULL || *scalars == NULL ) ) /*lint !e774 !e845*/
    3386 {
    3387 SCIPerrorMessage("Null pointer in LP reader\n"); /* should not happen */
    3388 SCIPABORT();
    3389 return SCIP_INVALIDDATA; /*lint !e527*/
    3390 }
    3391
    3392 for( v = 0; v < *nvars; ++v )
    3393 {
    3394 SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
    3395
    3396 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
    3397 * make sure we get the original variable in that case
    3398 */
    3399 if( SCIPvarGetStatus((*vars)[v]) == SCIP_VARSTATUS_NEGATED )
    3400 {
    3401 (*vars)[v] = SCIPvarGetNegatedVar((*vars)[v]);
    3402 *constant += (*scalars)[v];
    3403 (*scalars)[v] *= -1.0;
    3404 }
    3405 }
    3406 }
    3407 return SCIP_OKAY;
    3408}
    3409
    3410/** clears the given line buffer */
    3411static
    3413 char* linebuffer, /**< line */
    3414 int* linecnt /**< number of characters in line */
    3415 )
    3416{
    3417 assert( linebuffer != NULL );
    3418 assert( linecnt != NULL );
    3419
    3420 (*linecnt) = 0;
    3421 linebuffer[0] = '\0';
    3422}
    3423
    3424/** ends the given line with '\\0' and prints it to the given file stream */
    3425static
    3427 SCIP* scip, /**< SCIP data structure */
    3428 FILE* file, /**< output file (or NULL for standard output) */
    3429 char* linebuffer, /**< line */
    3430 int* linecnt /**< number of characters in line */
    3431 )
    3432{
    3433 assert( scip != NULL );
    3434 assert( linebuffer != NULL );
    3435 assert( linecnt != NULL );
    3436 assert( 0 <= *linecnt && *linecnt < LP_MAX_PRINTLEN );
    3437
    3438 if( (*linecnt) > 0 )
    3439 {
    3440 linebuffer[(*linecnt)] = '\0';
    3441 SCIPinfoMessage(scip, file, "%s\n", linebuffer);
    3442 clearLine(linebuffer, linecnt);
    3443 }
    3444}
    3445
    3446/** appends extension to line and prints it to the give file stream if the
    3447 * line exceeded the length given in the define LP_PRINTLEN */
    3448static
    3450 SCIP* scip, /**< SCIP data structure */
    3451 FILE* file, /**< output file (or NULL for standard output) */
    3452 char* linebuffer, /**< line */
    3453 int* linecnt, /**< number of characters in line */
    3454 const char* extension /**< string to extent the line */
    3455 )
    3456{
    3457 assert( scip != NULL );
    3458 assert( linebuffer != NULL );
    3459 assert( linecnt != NULL );
    3460 assert( extension != NULL );
    3461 assert( strlen(linebuffer) + strlen(extension) < LP_MAX_PRINTLEN );
    3462
    3463 /* NOTE: avoid
    3464 * sprintf(linebuffer, "%s%s", linebuffer, extension);
    3465 * because of overlapping memory areas in memcpy used in sprintf.
    3466 */
    3467 (void) strncat(linebuffer, extension, LP_MAX_PRINTLEN - strlen(linebuffer));
    3468
    3469 (*linecnt) += (int) strlen(extension);
    3470
    3471 SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
    3472
    3473 if( (*linecnt) > LP_PRINTLEN )
    3474 endLine(scip, file, linebuffer, linecnt);
    3475}
    3476
    3477/* print row in LP format to file stream */
    3478static
    3480 SCIP* scip, /**< SCIP data structure */
    3481 FILE* file, /**< output file (or NULL for standard output) */
    3482 const char* rowname, /**< row name */
    3483 const char* rownameextension, /**< row name extension */
    3484 const char* type, /**< row type ("=", "<=", or ">=") */
    3485 SCIP_VAR** linvars, /**< array of linear variables */
    3486 SCIP_Real* linvals, /**< array of linear coefficient values */
    3487 int nlinvars, /**< number of linear variables */
    3488 SCIP_EXPR* quadexpr, /**< quadratic expression */
    3489 SCIP_Real rhs, /**< right hand side */
    3490 SCIP_Bool transformed /**< transformed constraint? */
    3491 )
    3492{
    3493 char linebuffer[LP_MAX_PRINTLEN + 1] = { '\0' };
    3494 char varname[LP_MAX_NAMELEN];
    3495 char varname2[LP_MAX_NAMELEN];
    3496 char consname[LP_MAX_NAMELEN + 1]; /* an extra character for ':' */
    3497 char buffer[LP_MAX_PRINTLEN];
    3498 int linecnt;
    3499 int written;
    3500 int v;
    3501
    3502 assert(scip != NULL);
    3503 assert(strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0);
    3504 assert(nlinvars == 0 || (linvars != NULL && linvals != NULL));
    3505
    3506 clearLine(linebuffer, &linecnt);
    3507
    3508 /* start each line with a space */
    3509 appendLine(scip, file, linebuffer, &linecnt, " ");
    3510
    3511 /* print row name */
    3512 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
    3513 {
    3514 written = SCIPsnprintf(consname, LP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
    3515 if( written > LP_MAX_NAMELEN )
    3516 {
    3517 SCIPerrorMessage("buffer length exceeded\n");
    3518 return SCIP_INVALIDDATA;
    3519 }
    3520 appendLine(scip, file, linebuffer, &linecnt, consname);
    3521 }
    3522
    3523 /* print coefficients */
    3524 for( v = 0; v < nlinvars; ++v )
    3525 {
    3526 SCIP_VAR* var;
    3527
    3528 assert(linvars != NULL); /* for lint */
    3529 assert(linvals != NULL);
    3530
    3531 var = linvars[v];
    3532 assert(var != NULL);
    3533
    3534 /* we start a new line; therefore we tab this line */
    3535 if( linecnt == 0 )
    3536 appendLine(scip, file, linebuffer, &linecnt, " ");
    3537
    3538 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3539 if( written >= LP_MAX_NAMELEN )
    3540 {
    3541 SCIPerrorMessage("buffer length exceeded\n");
    3542 return SCIP_INVALIDDATA;
    3543 }
    3544 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
    3545 if( written >= LP_MAX_PRINTLEN )
    3546 {
    3547 SCIPerrorMessage("buffer length exceeded\n");
    3548 return SCIP_INVALIDDATA;
    3549 }
    3550 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3551 }
    3552
    3553 /* print quadratic part */
    3554 if( quadexpr != NULL )
    3555 {
    3556 SCIP_EXPR** linexprs;
    3557 SCIP_VAR** activevars;
    3558 SCIP_Real* activevals;
    3559 SCIP_Real* lincoefs;
    3560 SCIP_Real constant;
    3561 SCIP_Real activeconstant = 0.0;
    3562 int nbilinexprterms;
    3563 int nactivevars;
    3564 int nquadexprs;
    3565 int nlinexprs;
    3566
    3567 /* get data from the quadratic expression */
    3568 SCIPexprGetQuadraticData(quadexpr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprterms,
    3569 NULL, NULL);
    3570
    3571 /* allocate memory to store active linear variables */
    3572 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nlinexprs) );
    3573 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, lincoefs, nlinexprs) );
    3574 nactivevars = nlinexprs;
    3575
    3576 for( v = 0; v < nlinexprs; ++v )
    3577 {
    3578 assert(linexprs != NULL && linexprs[v] != NULL);
    3579 assert(SCIPisExprVar(scip, linexprs[v]));
    3580
    3581 activevars[v] = SCIPgetVarExprVar(linexprs[v]);
    3582 assert(activevars[v] != NULL);
    3583 }
    3584
    3585 /* get active variables */
    3586 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    3587 constant += activeconstant;
    3588
    3589 /* print linear coefficients of linear variables */
    3590 for( v = 0; v < nactivevars; ++v )
    3591 {
    3592 SCIP_VAR* var;
    3593
    3594 assert(activevars != NULL); /* for lint */
    3595 assert(activevals != NULL);
    3596
    3597 var = activevars[v];
    3598 assert(var != NULL);
    3599
    3600 /* we start a new line; therefore we tab this line */
    3601 if( linecnt == 0 )
    3602 appendLine(scip, file, linebuffer, &linecnt, " ");
    3603
    3604 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3605 if( written >= LP_MAX_NAMELEN )
    3606 {
    3607 SCIPerrorMessage("buffer length exceeded\n");
    3608 return SCIP_INVALIDDATA;
    3609 }
    3610 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", activevals[v], varname);
    3611 if( written >= LP_MAX_PRINTLEN )
    3612 {
    3613 SCIPerrorMessage("buffer length exceeded\n");
    3614 return SCIP_INVALIDDATA;
    3615 }
    3616 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3617 }
    3618
    3619 /* free memory for active linear variables */
    3620 SCIPfreeBufferArray(scip, &activevals);
    3621 SCIPfreeBufferArray(scip, &activevars);
    3622
    3623 /* adjust rhs if there is a constant */
    3624 if( constant != 0.0 && !SCIPisInfinity(scip, rhs) )
    3625 rhs -= constant;
    3626
    3627 /* print linear coefficients of quadratic variables */
    3628 for( v = 0; v < nquadexprs; ++v )
    3629 {
    3630 SCIP_EXPR* expr;
    3631 SCIP_VAR* var;
    3632 SCIP_Real lincoef;
    3633
    3634 /* get linear coefficient and variable of quadratic term */
    3635 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, &lincoef, NULL, NULL, NULL, NULL);
    3636 assert(expr != NULL);
    3637 assert(SCIPisExprVar(scip, expr));
    3638
    3639 var = SCIPgetVarExprVar(expr);
    3640 assert(var != NULL);
    3641
    3642 if( lincoef == 0.0 )
    3643 continue;
    3644
    3645 /* we start a new line; therefore we tab this line */
    3646 if( linecnt == 0 )
    3647 appendLine(scip, file, linebuffer, &linecnt, " ");
    3648
    3649 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3650 if( written >= LP_MAX_NAMELEN )
    3651 {
    3652 SCIPerrorMessage("buffer length exceeded\n");
    3653 return SCIP_INVALIDDATA;
    3654 }
    3655 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", lincoef, varname);
    3656 if( written >= LP_MAX_PRINTLEN )
    3657 {
    3658 SCIPerrorMessage("buffer length exceeded\n");
    3659 return SCIP_INVALIDDATA;
    3660 }
    3661 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3662 }
    3663
    3664 /* start quadratic part */
    3665 appendLine(scip, file, linebuffer, &linecnt, " + [");
    3666
    3667 /* print square terms */
    3668 for( v = 0; v < nquadexprs; ++v )
    3669 {
    3670 SCIP_EXPR* expr;
    3671 SCIP_VAR* var;
    3672 SCIP_Real sqrcoef;
    3673
    3674 /* get square coefficient and variable of quadratic term */
    3675 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, NULL, &sqrcoef, NULL, NULL, NULL);
    3676 assert(expr != NULL);
    3677 assert(SCIPisExprVar(scip, expr));
    3678
    3679 var = SCIPgetVarExprVar(expr);
    3680 assert(var != NULL);
    3681
    3682 if( sqrcoef == 0.0 )
    3683 continue;
    3684
    3685 /* we start a new line; therefore we tab this line */
    3686 if( linecnt == 0 )
    3687 appendLine(scip, file, linebuffer, &linecnt, " ");
    3688
    3689 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3690 if( written >= LP_MAX_NAMELEN )
    3691 {
    3692 SCIPerrorMessage("buffer length exceeded\n");
    3693 return SCIP_INVALIDDATA;
    3694 }
    3695 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s^2", sqrcoef, varname);
    3696 if( written >= LP_MAX_PRINTLEN )
    3697 {
    3698 SCIPerrorMessage("buffer length exceeded\n");
    3699 return SCIP_INVALIDDATA;
    3700 }
    3701 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3702 }
    3703
    3704 /* print bilinear terms */
    3705 for( v = 0; v < nbilinexprterms; ++v )
    3706 {
    3707 SCIP_EXPR* expr1;
    3708 SCIP_EXPR* expr2;
    3709 SCIP_VAR* var1;
    3710 SCIP_VAR* var2;
    3711 SCIP_Real bilincoef;
    3712
    3713 /* get coefficient and variables of bilinear */
    3714 SCIPexprGetQuadraticBilinTerm(quadexpr, v, &expr1, &expr2, &bilincoef, NULL, NULL);
    3715 assert(expr1 != NULL);
    3716 assert(SCIPisExprVar(scip, expr1));
    3717 assert(expr2 != NULL);
    3718 assert(SCIPisExprVar(scip, expr2));
    3719
    3720 var1 = SCIPgetVarExprVar(expr1);
    3721 assert(var1 != NULL);
    3722 var2 = SCIPgetVarExprVar(expr2);
    3723 assert(var2 != NULL);
    3724
    3725 /* we start a new line; therefore we tab this line */
    3726 if( linecnt == 0 )
    3727 appendLine(scip, file, linebuffer, &linecnt, " ");
    3728
    3729 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var1));
    3730 if( written >= LP_MAX_NAMELEN )
    3731 {
    3732 SCIPerrorMessage("buffer length exceeded\n");
    3733 return SCIP_INVALIDDATA;
    3734 }
    3735 written = SCIPsnprintf(varname2, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var2));
    3736 if( written >= LP_MAX_NAMELEN )
    3737 {
    3738 SCIPerrorMessage("buffer length exceeded\n");
    3739 return SCIP_INVALIDDATA;
    3740 }
    3741 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s * %s", bilincoef, varname, varname2);
    3742 if( written >= LP_MAX_PRINTLEN )
    3743 {
    3744 SCIPerrorMessage("buffer length exceeded\n");
    3745 return SCIP_INVALIDDATA;
    3746 }
    3747 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3748 }
    3749
    3750 /* end quadratic part */
    3751 appendLine(scip, file, linebuffer, &linecnt, " ]");
    3752 }
    3753
    3754 /* print right hand side */
    3755 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
    3756 if( written >= LP_MAX_PRINTLEN )
    3757 {
    3758 SCIPerrorMessage("buffer length exceeded\n");
    3759 return SCIP_INVALIDDATA;
    3760 }
    3761
    3762 /* we start a new line; therefore we tab this line */
    3763 if( linecnt == 0 )
    3764 appendLine(scip, file, linebuffer, &linecnt, " ");
    3765 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3766
    3767 endLine(scip, file, linebuffer, &linecnt);
    3768
    3769 return SCIP_OKAY;
    3770}
    3771
    3772/* print exact row in LP format to file stream */
    3773static
    3775 SCIP* scip, /**< SCIP data structure */
    3776 FILE* file, /**< output file (or NULL for standard output) */
    3777 const char* rowname, /**< row name */
    3778 const char* rownameextension, /**< row name extension */
    3779 const char* type, /**< row type ("=", "<=", or ">=") */
    3780 SCIP_VAR** linvars, /**< array of linear variables */
    3781 SCIP_RATIONAL** linvals, /**< array of linear coefficient values */
    3782 int nlinvars, /**< number of linear variables */
    3783 SCIP_RATIONAL* rhs /**< right hand side */
    3784 )
    3785{
    3786 char linebuffer[LP_MAX_PRINTLEN + 1] = { '\0' };
    3787 char ratbuffer[LP_MAX_PRINTLEN] = { '\0' };
    3788 char varname[LP_MAX_NAMELEN];
    3789 char consname[LP_MAX_NAMELEN + 1]; /* an extra character for ':' */
    3790 char buffer[LP_MAX_PRINTLEN];
    3791 int linecnt;
    3792 int written;
    3793 int v;
    3794
    3795 assert(scip != NULL);
    3796 assert(strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0);
    3797 assert(nlinvars == 0 || (linvars != NULL && linvals != NULL));
    3798
    3799 clearLine(linebuffer, &linecnt);
    3800
    3801 /* start each line with a space */
    3802 appendLine(scip, file, linebuffer, &linecnt, " ");
    3803
    3804 /* print row name */
    3805 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
    3806 {
    3807 written = SCIPsnprintf(consname, LP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
    3808 if( written > LP_MAX_NAMELEN )
    3809 {
    3810 SCIPerrorMessage("buffer length exceeded\n");
    3811 return SCIP_INVALIDDATA;
    3812 }
    3813 appendLine(scip, file, linebuffer, &linecnt, consname);
    3814 }
    3815
    3816 /* print coefficients */
    3817 for( v = 0; v < nlinvars; ++v )
    3818 {
    3819 SCIP_VAR* var;
    3820
    3821 assert(linvars != NULL); /* for lint */
    3822 assert(linvals != NULL);
    3823
    3824 var = linvars[v];
    3825 assert(var != NULL);
    3826
    3827 /* we start a new line; therefore we tab this line */
    3828 if( linecnt == 0 )
    3829 appendLine(scip, file, linebuffer, &linecnt, " ");
    3830
    3831 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3832 if( written >= LP_MAX_NAMELEN )
    3833 {
    3834 SCIPerrorMessage("buffer length exceeded\n");
    3835 return SCIP_INVALIDDATA;
    3836 }
    3837 written = SCIPrationalToString(linvals[v], ratbuffer, LP_MAX_PRINTLEN);
    3838 if( written >= LP_MAX_PRINTLEN )
    3839 {
    3840 SCIPerrorMessage("buffer length exceeded\n");
    3841 return SCIP_INVALIDDATA;
    3842 }
    3843 if( !SCIPrationalIsNegative(linvals[v]) )
    3844 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " +%s %s", ratbuffer, varname);
    3845 else
    3846 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %s", ratbuffer, varname);
    3847 if( written >= LP_MAX_PRINTLEN )
    3848 {
    3849 SCIPerrorMessage("buffer length exceeded\n");
    3850 return SCIP_INVALIDDATA;
    3851 }
    3852 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3853 }
    3854
    3855 /* print right hand side */
    3856 written = SCIPrationalToString(rhs, ratbuffer, LP_MAX_PRINTLEN);
    3857 if( written >= LP_MAX_PRINTLEN )
    3858 {
    3859 SCIPerrorMessage("buffer length exceeded\n");
    3860 return SCIP_INVALIDDATA;
    3861 }
    3862 if( !SCIPrationalIsNegative(rhs) )
    3863 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s +%s", type, ratbuffer);
    3864 else
    3865 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %s", type, ratbuffer);
    3866 if( written >= LP_MAX_PRINTLEN )
    3867 {
    3868 SCIPerrorMessage("buffer length exceeded\n");
    3869 return SCIP_INVALIDDATA;
    3870 }
    3871
    3872 /* we start a new line; therefore we tab this line */
    3873 if( linecnt == 0 )
    3874 appendLine(scip, file, linebuffer, &linecnt, " ");
    3875 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3876
    3877 endLine(scip, file, linebuffer, &linecnt);
    3878
    3879 return SCIP_OKAY;
    3880}
    3881
    3882/** prints given (linear or) quadratic constraint information in LP format to file stream */
    3883static
    3885 SCIP* scip, /**< SCIP data structure */
    3886 FILE* file, /**< output file (or NULL for standard output) */
    3887 const char* rowname, /**< name of the row */
    3888 SCIP_VAR** linvars, /**< array of linear variables */
    3889 SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
    3890 int nlinvars, /**< number of linear variables */
    3891 SCIP_EXPR* quadexpr, /**< quadratic expression (or NULL if nlinvars > 0) */
    3892 SCIP_Real lhs, /**< left hand side */
    3893 SCIP_Real rhs, /**< right hand side */
    3894 SCIP_Bool transformed /**< transformed constraint? */
    3895 )
    3896{
    3897 int v;
    3898 SCIP_VAR** activevars = NULL;
    3899 SCIP_Real* activevals = NULL;
    3900 int nactivevars;
    3901 SCIP_Real activeconstant = 0.0;
    3902
    3903 assert( scip != NULL );
    3904 assert( rowname != NULL );
    3905 assert( quadexpr == NULL || nlinvars == 0);
    3906
    3907 /* The LP format does not forbid that the variable array is empty */
    3908 assert( nlinvars == 0 || linvars != NULL );
    3909 assert( lhs <= rhs );
    3910
    3911 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    3912 return SCIP_OKAY;
    3913
    3914 nactivevars = nlinvars;
    3915 if( nlinvars > 0 )
    3916 {
    3917 /* duplicate variable and value array */
    3918 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
    3919 if( linvals != NULL )
    3920 {
    3921 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
    3922 }
    3923 else
    3924 {
    3925 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
    3926
    3927 for( v = 0; v < nactivevars; ++v )
    3928 activevals[v] = 1.0;
    3929 }
    3930
    3931 /* retransform given variables to active variables */
    3932 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    3933 }
    3934
    3935 /* print row(s) in LP format */
    3936 if( SCIPisEQ(scip, lhs, rhs) )
    3937 {
    3938 assert( !SCIPisInfinity(scip, rhs) );
    3939
    3940 /* equal constraint */
    3941 SCIP_CALL( printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars, quadexpr,
    3942 rhs - activeconstant, transformed) );
    3943 }
    3944 else
    3945 {
    3946 if( !SCIPisInfinity(scip, -lhs) )
    3947 {
    3948 /* print inequality ">=" */
    3949 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", activevars, activevals,
    3950 nactivevars, quadexpr, lhs - activeconstant, transformed) );
    3951 }
    3952 if( !SCIPisInfinity(scip, rhs) )
    3953 {
    3954 /* print inequality "<=" */
    3955 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", activevars, activevals,
    3956 nactivevars, quadexpr, rhs - activeconstant, transformed) );
    3957 }
    3958 }
    3959
    3960 if( nlinvars > 0 )
    3961 {
    3962 /* free buffer arrays */
    3963 SCIPfreeBufferArray(scip, &activevals);
    3964 SCIPfreeBufferArray(scip, &activevars);
    3965 }
    3966
    3967 return SCIP_OKAY;
    3968}
    3969
    3970/** prints given SOS constraint information in LP format to file stream */
    3971static
    3973 SCIP* scip, /**< SCIP data structure */
    3974 FILE* file, /**< output file (or NULL for standard output) */
    3975 const char* rowname, /**< name of the row */
    3976 SCIP_VAR** vars, /**< array of variables */
    3977 SCIP_Real* weights, /**< array of weight values (or NULL) */
    3978 int nvars, /**< number of variables */
    3979 int type /**< SOS type (SOS1 or SOS2) */
    3980 )
    3981{
    3982 int v;
    3983
    3984 char linebuffer[LP_MAX_PRINTLEN+1];
    3985 int linecnt;
    3986 char buffer[LP_MAX_PRINTLEN];
    3987 char varname[LP_MAX_NAMELEN];
    3988
    3989 assert( scip != NULL );
    3990 assert( file != NULL );
    3991 assert( type == 1 || type == 2 );
    3992
    3993 clearLine(linebuffer, &linecnt);
    3994
    3995 /* start each line with a space */
    3996 appendLine(scip, file, linebuffer, &linecnt, " ");
    3997 assert( strlen(rowname) < LP_MAX_NAMELEN );
    3998
    3999 if( strlen(rowname) > 0 )
    4000 {
    4001 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, "%s:", rowname);
    4002 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4003 }
    4004
    4005 /* SOS type */
    4006 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " S%d::", type);
    4007 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4008
    4009 for( v = 0; v < nvars; ++v )
    4010 {
    4011 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[v]));
    4012
    4013 if( weights != NULL )
    4014 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%.15g", varname, weights[v]);
    4015 else
    4016 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%d", varname, v);
    4017
    4018 if(linecnt == 0 )
    4019 {
    4020 /* we start a new line; therefore we tab this line */
    4021 appendLine(scip, file, linebuffer, &linecnt, " ");
    4022 }
    4023 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4024 }
    4025
    4026 endLine(scip, file, linebuffer, &linecnt);
    4027}
    4028
    4029/** prints a linearization of an and-constraint into the given file */
    4030static
    4032 SCIP* scip, /**< SCIP data structure */
    4033 FILE* file, /**< output file (or NULL for standard output) */
    4034 const char* consname, /**< name of the constraint */
    4035 SCIP_CONS* cons, /**< and constraint */
    4036 SCIP_Bool aggrlinearizationands,/**< print weak or strong realaxation */
    4037 SCIP_Bool transformed /**< transformed constraint? */
    4038 )
    4039{
    4040 SCIP_VAR** vars;
    4041 SCIP_VAR** operands;
    4042 SCIP_VAR* resultant;
    4043 SCIP_Real* vals;
    4044 char rowname[LP_MAX_NAMELEN];
    4045 int nvars;
    4046 int v;
    4047
    4048 assert(scip != NULL);
    4049 assert(consname != NULL);
    4050 assert(cons != NULL);
    4051
    4052 nvars = SCIPgetNVarsAnd(scip, cons);
    4053 operands = SCIPgetVarsAnd(scip, cons);
    4054 resultant = SCIPgetResultantAnd(scip, cons);
    4055
    4056 /* allocate buffer array */
    4057 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars + 1) );
    4058 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars + 1) );
    4059
    4060 /* the tight relaxtion, number of and-constraint operands rows */
    4061 if( !aggrlinearizationands )
    4062 {
    4063 vars[0] = resultant;
    4064 vals[0] = 1.0;
    4065 vals[1] = -1.0;
    4066
    4067 /* print operator rows */
    4068 for( v = 0; v < nvars; ++v )
    4069 {
    4070 (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_%d", consname, v);
    4071 vars[1] = operands[v];
    4072
    4073 /* print for each operator a row */
    4074 SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, 2, NULL, -SCIPinfinity(scip), 0.0,
    4075 transformed) );
    4076 }
    4077 }
    4078
    4079 /* prepare for next row */
    4080 for( v = nvars - 1; v >= 0; --v )
    4081 {
    4082 vars[v] = operands[v];
    4083 vals[v] = -1.0;
    4084 }
    4085
    4086 vars[nvars] = resultant;
    4087
    4088 /* the weak relaxtion, only one constraint */
    4089 if( aggrlinearizationands )
    4090 {
    4091 /* adjust rowname of constraint */
    4092 (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_operators", consname);
    4093
    4094 vals[nvars] = (SCIP_Real) nvars;
    4095
    4096 /* print aggregated operator row */
    4097 SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, nvars + 1, NULL, -SCIPinfinity(scip), 0.0,
    4098 transformed) );
    4099 }
    4100
    4101 /* create additional linear constraint */
    4102 (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_add", consname);
    4103
    4104 vals[nvars] = 1.0;
    4105
    4106 SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, nvars + 1, NULL, -nvars + 1.0, SCIPinfinity(scip),
    4107 transformed) );
    4108
    4109 /* free buffer array */
    4110 SCIPfreeBufferArray(scip, &vals);
    4111 SCIPfreeBufferArray(scip, &vars);
    4112
    4113 return SCIP_OKAY;
    4114}
    4115
    4116/** check whether given variables are aggregated and put them into an array without duplication */
    4117static
    4119 SCIP* scip, /**< SCIP data structure */
    4120 SCIP_VAR** vars, /**< variable array */
    4121 int nvars, /**< number of active variables in the problem */
    4122 SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
    4123 int* naggvars, /**< pointer to number of aggregated variables on output */
    4124 int* saggvars, /**< pointer to number of slots in aggvars array */
    4125 SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
    4126 )
    4127{
    4128 int v;
    4129
    4130 assert( scip != NULL );
    4131 assert( aggvars != NULL );
    4132 assert( naggvars != NULL );
    4133 assert( saggvars != NULL );
    4134
    4135 /* check variables */
    4136 for( v = 0; v < nvars; ++v )
    4137 {
    4138 SCIP_VARSTATUS status;
    4139 SCIP_VAR* var;
    4140
    4141 var = vars[v];
    4142 status = SCIPvarGetStatus(var);
    4143
    4144 /* collect aggregated variables in a list */
    4145 if( status >= SCIP_VARSTATUS_AGGREGATED )
    4146 {
    4147 assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
    4148 assert( varAggregated != NULL );
    4149
    4150 if( ! SCIPhashtableExists(varAggregated, (void*) var) )
    4151 {
    4152 /* possibly enlarge array */
    4153 if ( *saggvars <= *naggvars )
    4154 {
    4155 int newsize;
    4156 newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
    4157 assert( newsize > *saggvars );
    4158 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
    4159 *saggvars = newsize;
    4160 }
    4161
    4162 (*aggvars)[*naggvars] = var;
    4163 (*naggvars)++;
    4164 SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
    4165 assert( *naggvars <= *saggvars );
    4166 }
    4167 }
    4168 }
    4169 return SCIP_OKAY;
    4170}
    4171
    4172/** print aggregated variable-constraints */
    4173static
    4175 SCIP* scip, /**< SCIP data structure */
    4176 FILE* file, /**< output file (or NULL for standard output) */
    4177 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4178 int nvars, /**< number of active variables in the problem */
    4179 int nAggregatedVars, /**< number of aggregated variables */
    4180 SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
    4181 )
    4182{
    4183 int j;
    4184
    4185 SCIP_VAR** activevars;
    4186 SCIP_Real* activevals;
    4187 int nactivevars;
    4188 SCIP_Real activeconstant;
    4189 char consname[LP_MAX_NAMELEN];
    4190
    4191 assert( scip != NULL );
    4192
    4193 /* write aggregation constraints */
    4194 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
    4195 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
    4196
    4197 for( j = 0; j < nAggregatedVars; ++j )
    4198 {
    4199 /* set up list to obtain substitution variables */
    4200 nactivevars = 1;
    4201
    4202 activevars[0] = aggregatedVars[j];
    4203 activevals[0] = 1.0;
    4204 activeconstant = 0.0;
    4205
    4206 /* retransform given variables to active variables */
    4207 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    4208
    4209 activevals[nactivevars] = -1.0;
    4210 activevars[nactivevars] = aggregatedVars[j];
    4211 ++nactivevars;
    4212
    4213 /* output constraint */
    4214 (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
    4215 SCIP_CALL( printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, - activeconstant,
    4216 transformed) );
    4217 }
    4218
    4219 /* free buffer arrays */
    4220 SCIPfreeBufferArray(scip, &activevals);
    4221 SCIPfreeBufferArray(scip, &activevars);
    4222
    4223 return SCIP_OKAY;
    4224}
    4225
    4226/** method check if the variable names are not longer than LP_MAX_NAMELEN */
    4227static
    4229 SCIP* scip, /**< SCIP data structure */
    4230 SCIP_VAR** vars, /**< array of variables */
    4231 int nvars /**< number of variables */
    4232 )
    4233{
    4234 SCIP_Bool printwarning;
    4235 int v;
    4236
    4237 assert(scip != NULL);
    4238 assert(vars != NULL || nvars == 0);
    4239
    4240 printwarning = TRUE;
    4241
    4242 /* check if the variable names are not to long */
    4243 for( v = 0; v < nvars; ++v )
    4244 {
    4245 if( strlen(SCIPvarGetName(vars[v])) > LP_MAX_NAMELEN ) /*lint !e613*/
    4246 {
    4247 SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; LP might be corrupted\n",
    4248 LP_MAX_NAMELEN - 1);
    4249 return;
    4250 }
    4251
    4252 /* check if variable name starts with a digit */
    4253 if( printwarning && isdigit((unsigned char)SCIPvarGetName(vars[v])[0]) ) /*lint !e613*/
    4254 {
    4255 SCIPwarningMessage(scip, "violation of LP format - a variable name starts with a digit; " \
    4256 "it is not possible to read the generated LP file with SCIP; " \
    4257 "use write/genproblem or write/gentransproblem for generic variable names\n");
    4258 printwarning = FALSE;
    4259 }
    4260 }
    4261}
    4262
    4263/** method check if the constraint names are not longer than LP_MAX_NAMELEN */
    4264static
    4266 SCIP* scip, /**< SCIP data structure */
    4267 SCIP_CONS** conss, /**< array of constraints */
    4268 int nconss, /**< number of constraints */
    4269 SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
    4270 )
    4271{
    4272 int c;
    4273 SCIP_CONS* cons;
    4274 SCIP_CONSHDLR* conshdlr;
    4275 const char* conshdlrname;
    4276 SCIP_Bool printwarning = TRUE;
    4277
    4278 assert( scip != NULL );
    4279 assert( conss != NULL || nconss == 0 );
    4280
    4281 for( c = 0; c < nconss; ++c )
    4282 {
    4283 int len;
    4284
    4285 assert(conss != NULL); /* for lint */
    4286 cons = conss[c];
    4287 assert(cons != NULL );
    4288
    4289 /* in case the transformed is written only constraints are posted which are enabled in the current node */
    4290 assert(!transformed || SCIPconsIsEnabled(cons));
    4291
    4292 conshdlr = SCIPconsGetHdlr(cons);
    4293 assert( conshdlr != NULL );
    4294
    4295 conshdlrname = SCIPconshdlrGetName(conshdlr);
    4296 assert( transformed == SCIPconsIsTransformed(cons) );
    4297
    4298 len = (int) strlen(SCIPconsGetName(cons));
    4299
    4300 if( strcmp(conshdlrname, "linear") == 0 )
    4301 {
    4302 SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
    4303 SCIP_Real rhs = SCIPgetRhsLinear(scip, cons);
    4304
    4305 if( (SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN) || ( !SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN - 4) )
    4306 {
    4307 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
    4308 return;
    4309 }
    4310 }
    4311 else if( len > LP_MAX_NAMELEN )
    4312 {
    4313 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
    4314 return;
    4315 }
    4316
    4317 /* check if constraint name starts with a digit */
    4318 if( printwarning && isdigit((unsigned char)SCIPconsGetName(cons)[0]) )
    4319 {
    4320 SCIPwarningMessage(scip, "violation of LP format - a constraint name starts with a digit; " \
    4321 "it is not possible to read the generated LP file with SCIP; " \
    4322 "use write/genproblem or write/gentransproblem for generic variable names\n");
    4323 printwarning = FALSE;
    4324 }
    4325 }
    4326}
    4327
    4328/*
    4329 * Callback methods of reader
    4330 */
    4331
    4332/** copy method for reader plugins (called when SCIP copies plugins) */
    4333static
    4335{ /*lint --e{715}*/
    4336 assert(scip != NULL);
    4337 assert(reader != NULL);
    4338 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4339
    4340 /* call inclusion method of reader */
    4342
    4343 return SCIP_OKAY;
    4344}
    4345
    4346/** destructor of reader to free user data (called when SCIP is exiting) */
    4347static
    4349{
    4350 SCIP_READERDATA* readerdata;
    4351
    4352 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4353 readerdata = SCIPreaderGetData(reader);
    4354 assert(readerdata != NULL);
    4355 SCIPfreeBlockMemory(scip, &readerdata);
    4356
    4357 return SCIP_OKAY;
    4358}
    4359
    4360/** problem reading method of reader */
    4361static
    4363{ /*lint --e{715}*/
    4364
    4365 SCIP_CALL( SCIPreadLp(scip, reader, filename, result) );
    4366
    4367 return SCIP_OKAY;
    4368}
    4369
    4370
    4371/** problem writing method of reader */
    4372static
    4374{ /*lint --e{715}*/
    4375 assert(reader != NULL);
    4376 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4377
    4378 SCIP_CALL( SCIPwriteLp(scip, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
    4379 vars, nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
    4380
    4381 return SCIP_OKAY;
    4382}
    4383
    4384
    4385/*
    4386 * reader specific interface methods
    4387 */
    4388
    4389/** includes the lp file reader in SCIP */
    4391 SCIP* scip /**< SCIP data structure */
    4392 )
    4393{
    4394 SCIP_READERDATA* readerdata;
    4395 SCIP_READER* reader;
    4396
    4397 /* create reader data */
    4398 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
    4399
    4400 /* include reader */
    4402
    4403 /* reader is safe to use in exact solving mode */
    4404 SCIPreaderMarkExact(reader);
    4405
    4406 /* set non fundamental callbacks via setter functions */
    4407 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyLp) );
    4408 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeLp) );
    4409 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadLp) );
    4410 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteLp) );
    4411
    4412 /* add lp-reader parameters */
    4414 "reading/" READER_NAME "/linearize-and-constraints",
    4415 "should possible \"and\" constraint be linearized when writing the lp file?",
    4416 &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
    4418 "reading/" READER_NAME "/aggrlinearization-ands",
    4419 "should an aggregated linearization for and constraints be used?",
    4420 &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
    4421
    4422 return SCIP_OKAY;
    4423}
    4424
    4425
    4426/** reads problem from file */
    4428 SCIP* scip, /**< SCIP data structure */
    4429 SCIP_READER* reader, /**< the file reader itself */
    4430 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
    4431 SCIP_RESULT* result /**< pointer to store the result of the file reading call */
    4432 )
    4433{ /*lint --e{715}*/
    4434 SCIP_RETCODE retcode;
    4435 LPINPUT lpinput;
    4436 int i;
    4437
    4438 assert(scip != NULL);
    4439 assert(reader != NULL);
    4440
    4441 /* initialize LP input data */
    4442 lpinput.file = NULL;
    4444 lpinput.linebuf[0] = '\0';
    4445 lpinput.linebufsize = LP_MAX_LINELEN;
    4446 lpinput.probname[0] = '\0';
    4447 lpinput.objname[0] = '\0';
    4448 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lpinput.token, LP_MAX_LINELEN) ); /*lint !e506*/
    4449 lpinput.token[0] = '\0';
    4450 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN) ); /*lint !e506*/
    4451 lpinput.tokenbuf[0] = '\0';
    4452 for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
    4453 {
    4454 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(lpinput.pushedtokens[i]), LP_MAX_LINELEN) ); /*lint !e866 !e506*/
    4455 }
    4456
    4457 lpinput.npushedtokens = 0;
    4458 lpinput.linenumber = 0;
    4459 lpinput.linepos = 0;
    4460 lpinput.section = LP_START;
    4461 lpinput.objsense = SCIP_OBJSENSE_MINIMIZE;
    4462 lpinput.inlazyconstraints = FALSE;
    4463 lpinput.inusercuts = FALSE;
    4464 lpinput.haserror = FALSE;
    4465
    4466 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(lpinput.initialconss)) );
    4467 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(lpinput.dynamicconss)) );
    4468 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(lpinput.dynamiccols)) );
    4469 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(lpinput.dynamicrows)) );
    4470
    4471 /* read the file */
    4472 retcode = readLPFile(scip, &lpinput, filename);
    4473
    4474 /* free dynamically allocated memory */
    4475 for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
    4476 {
    4477 SCIPfreeBlockMemoryArray(scip, &lpinput.pushedtokens[i], LP_MAX_LINELEN);
    4478 }
    4479 SCIPfreeBlockMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN);
    4481 SCIPfreeBlockMemoryArray(scip, &lpinput.linebuf, lpinput.linebufsize);
    4482
    4483 if( retcode == SCIP_PLUGINNOTFOUND || retcode == SCIP_INVALIDDATA )
    4484 retcode = SCIP_READERROR;
    4485
    4486 /* check for correct return value */
    4487 SCIP_CALL( retcode );
    4488
    4489 /* evaluate the result */
    4490 if( lpinput.haserror )
    4491 return SCIP_READERROR;
    4492 else
    4493 {
    4494 /* set objective sense */
    4495 SCIP_CALL( SCIPsetObjsense(scip, lpinput.objsense) );
    4496 *result = SCIP_SUCCESS;
    4497 }
    4498
    4499 return SCIP_OKAY;
    4500}
    4501
    4502/** writes problem to file */
    4504 SCIP* scip, /**< SCIP data structure */
    4505 FILE* file, /**< output file, or NULL if standard output should be used */
    4506 const char* name, /**< problem name */
    4507 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4508 SCIP_OBJSENSE objsense, /**< objective sense */
    4509 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    4510 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    4511 * extobj = objsense * objscale * (intobj + objoffset) */
    4512 SCIP_RATIONAL* objoffsetexact, /**< exact objective offset from bound shifting and fixing */
    4513 SCIP_RATIONAL* objscaleexact, /**< exact scalar applied to objective function; external objective value is
    4514 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
    4515 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
    4516 int nvars, /**< number of active variables in the problem */
    4517 int nbinvars, /**< number of binary variables */
    4518 int nintvars, /**< number of general integer variables */
    4519 int nimplvars, /**< number of implicit integer variables */
    4520 int ncontvars, /**< number of continuous variables */
    4521 SCIP_CONS** conss, /**< array with constraints of the problem */
    4522 int nconss, /**< number of constraints in the problem */
    4523 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    4524 )
    4525{
    4526 SCIP_READER* reader;
    4527 SCIP_READERDATA* readerdata;
    4528 SCIP_Bool linearizeands;
    4529 SCIP_Bool aggrlinearizationands;
    4530
    4531 char linebuffer[LP_MAX_PRINTLEN + 1];
    4532 char varname[LP_MAX_NAMELEN];
    4533 char ratbuffer[LP_MAX_PRINTLEN];
    4534 char buffer[LP_MAX_PRINTLEN];
    4535 int linecnt;
    4536 int written;
    4537 int c;
    4538 int v;
    4539
    4540 SCIP_CONSHDLR* conshdlr;
    4541 SCIP_CONSHDLR* conshdlrInd;
    4542 const char* conshdlrname;
    4543 SCIP_CONS* cons;
    4544 SCIP_CONS** consSOS1;
    4545 SCIP_CONS** consSOS2;
    4546 SCIP_CONS** consExpr;
    4547 SCIP_CONS** consIndicator;
    4548 int nConsSOS1 = 0;
    4549 int nConsSOS2 = 0;
    4550 int nConsExpr = 0;
    4551 int nConsIndicator = 0;
    4552 char consname[LP_MAX_NAMELEN];
    4553
    4554 SCIP_VAR** aggvars;
    4555 SCIP_VAR** tmpvars;
    4556 int tmpvarssize;
    4557 int naggvars = 0;
    4558 int saggvars;
    4559 SCIP_HASHTABLE* varAggregated;
    4560 SCIP_HASHMAP* consHidden;
    4561
    4562 SCIP_VAR** consvars;
    4563 SCIP_Real* consvals;
    4564 int nconsvars;
    4565
    4566 SCIP_VAR* var;
    4567 SCIP_RATIONAL* objexact;
    4568 SCIP_Real obj;
    4569 SCIP_Real lb;
    4570 SCIP_Real ub;
    4571
    4572 SCIP_Bool zeroobj;
    4573 int implintlevel;
    4574 int nintegers = nvars - ncontvars;
    4575 assert(nintegers >= 0);
    4576
    4577 /* find indicator constraint handler */
    4578 conshdlrInd = SCIPfindConshdlr(scip, "indicator");
    4579 consHidden = NULL;
    4580
    4581 /* if indicator constraint handler is present */
    4582 if( conshdlrInd != NULL )
    4583 {
    4584 /* create hashtable storing linear constraints that should not be output */
    4585 SCIP_CALL( SCIPhashmapCreate(&consHidden, SCIPblkmem(scip), 500) );
    4586
    4587 /* loop through indicator constraints (works only in transformed problem) */
    4588 if( transformed )
    4589 {
    4590 SCIP_CONS** consInd;
    4591 int nConsInd;
    4592
    4593 consInd = SCIPconshdlrGetConss(conshdlrInd);
    4594 nConsInd = SCIPconshdlrGetNConss(conshdlrInd);
    4595 SCIPdebugMsg(scip, "Number of indicator constraints: %d\n", nConsInd);
    4596
    4597 for( c = 0; c < nConsInd; ++c )
    4598 {
    4599 assert( consInd[c] != NULL );
    4600 cons = SCIPgetLinearConsIndicator(consInd[c]);
    4601
    4602 assert( !SCIPhashmapExists(consHidden, (void*) cons) );
    4603 SCIP_CALL( SCIPhashmapSetImageInt(consHidden, (void*) cons, 1) );
    4604 SCIPdebugMsg(scip, "Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(cons));
    4605 }
    4606 }
    4607 else
    4608 {
    4609 /* otherwise we have to pass through all constraints */
    4610 for( c = 0; c < nconss; ++c )
    4611 {
    4612 cons = conss[c];
    4613 assert( cons != NULL);
    4614
    4615 conshdlr = SCIPconsGetHdlr(cons);
    4616 assert( conshdlr != NULL );
    4617 conshdlrname = SCIPconshdlrGetName(conshdlr);
    4618
    4619 if( strcmp(conshdlrname, "indicator") == 0 )
    4620 {
    4621 SCIP_CONS* lincons;
    4622
    4623 lincons = SCIPgetLinearConsIndicator(cons);
    4624 assert( lincons != NULL );
    4625
    4626 assert( !SCIPhashmapExists(consHidden, (void*) lincons) );
    4627 SCIP_CALL( SCIPhashmapSetImageInt(consHidden, (void*) lincons, 1) );
    4628 SCIPdebugMsg(scip, "Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(lincons));
    4629 }
    4630 }
    4631 }
    4632 }
    4633
    4634 /* check if the variable names are not to long */
    4635 checkVarnames(scip, vars, nvars);
    4636 /* check if the constraint names are to long */
    4637 checkConsnames(scip, conss, nconss, transformed);
    4638
    4639 /* adjust written integrality constraints on implied integral variables based on the implied integral level */
    4640 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
    4641 assert(implintlevel >= -2);
    4642 assert(implintlevel <= 2);
    4643
    4644 if( SCIPisExact(scip) )
    4645 {
    4647 }
    4648 else
    4649 objexact = NULL;
    4650
    4651 /* print statistics as comment to file */
    4652 SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
    4653 SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
    4654 SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
    4655 nvars, nbinvars, nintvars, nimplvars, ncontvars);
    4656 SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
    4657
    4658 /* print objective sense */
    4659 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
    4660
    4661 clearLine(linebuffer, &linecnt);
    4662 appendLine(scip, file, linebuffer, &linecnt, " Obj:");
    4663
    4664 zeroobj = TRUE;
    4665 for( v = 0; v < nvars; ++v )
    4666 {
    4667 var = vars[v];
    4668
    4669#ifndef NDEBUG
    4670 /* in case the original problem has to be written, the variables have to be either "original" or "negated" */
    4671 if( ! transformed )
    4673#endif
    4674
    4675 /* multiply exact objscale */
    4676 if( objexact != NULL )
    4677 {
    4679
    4680 if( SCIPrationalIsZero(objexact) )
    4681 continue;
    4682
    4683 SCIPrationalMult(objexact, objexact, objscaleexact);
    4684 zeroobj = FALSE;
    4685
    4686 /* we start a new line; therefore we tab this line */
    4687 if( linecnt == 0 )
    4688 appendLine(scip, file, linebuffer, &linecnt, " ");
    4689
    4690 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    4691 if( written >= LP_MAX_NAMELEN )
    4692 {
    4694 SCIPerrorMessage("buffer length exceeded\n");
    4695 return SCIP_INVALIDDATA;
    4696 }
    4697 written = SCIPrationalToString(objexact, ratbuffer, LP_MAX_PRINTLEN);
    4698 if( written >= LP_MAX_PRINTLEN )
    4699 {
    4701 SCIPerrorMessage("buffer length exceeded\n");
    4702 return SCIP_INVALIDDATA;
    4703 }
    4704 if( !SCIPrationalIsNegative(objexact) )
    4705 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " +%s %s", ratbuffer, varname);
    4706 else
    4707 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %s", ratbuffer, varname);
    4708 if( written >= LP_MAX_PRINTLEN )
    4709 {
    4711 SCIPerrorMessage("buffer length exceeded\n");
    4712 return SCIP_INVALIDDATA;
    4713 }
    4714 }
    4715 /* multiply real objscale */
    4716 else
    4717 {
    4718 obj = SCIPvarGetObj(var);
    4719
    4720 if( obj == 0.0 ) /*lint !e777*/
    4721 continue;
    4722
    4723 obj *= objscale;
    4724 zeroobj = FALSE;
    4725
    4726 /* we start a new line; therefore we tab this line */
    4727 if( linecnt == 0 )
    4728 appendLine(scip, file, linebuffer, &linecnt, " ");
    4729
    4730 written = SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    4731 if( written >= LP_MAX_NAMELEN )
    4732 {
    4733 SCIPerrorMessage("buffer length exceeded\n");
    4734 return SCIP_INVALIDDATA;
    4735 }
    4736 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", obj, varname);
    4737 if( written >= LP_MAX_PRINTLEN )
    4738 {
    4739 SCIPerrorMessage("buffer length exceeded\n");
    4740 return SCIP_INVALIDDATA;
    4741 }
    4742 }
    4743
    4744 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4745 }
    4746
    4747 /* add exact objoffset */
    4748 if( objexact != NULL )
    4749 {
    4750 if( zeroobj || !SCIPrationalIsZero(objoffsetexact) )
    4751 {
    4752 SCIPrationalMult(objexact, objoffsetexact, objscaleexact);
    4753
    4754 written = SCIPrationalToString(objexact, ratbuffer, LP_MAX_PRINTLEN);
    4755 if( written >= LP_MAX_PRINTLEN )
    4756 {
    4758 SCIPerrorMessage("buffer length exceeded\n");
    4759 return SCIP_INVALIDDATA;
    4760 }
    4761 if( !SCIPrationalIsNegative(objexact) )
    4762 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " +%s", ratbuffer);
    4763 else
    4764 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", ratbuffer);
    4765 if( written >= LP_MAX_PRINTLEN )
    4766 {
    4768 SCIPerrorMessage("buffer length exceeded\n");
    4769 return SCIP_INVALIDDATA;
    4770 }
    4771
    4772 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4773 }
    4774
    4776 }
    4777 /* add real objoffset */
    4778 else
    4779 {
    4780 if( zeroobj || objoffset != 0.0 ) /*lint !e777*/
    4781 {
    4782 obj = objoffset * objscale;
    4783
    4784 written = SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g", obj);
    4785 if( written >= LP_MAX_PRINTLEN )
    4786 {
    4787 SCIPerrorMessage("buffer length exceeded\n");
    4788 return SCIP_INVALIDDATA;
    4789 }
    4790
    4791 appendLine(scip, file, linebuffer, &linecnt, buffer);
    4792 }
    4793 }
    4794
    4795 endLine(scip, file, linebuffer, &linecnt);
    4796
    4797 /* print "Subject to" section */
    4798 SCIPinfoMessage(scip, file, "Subject to\n");
    4799
    4800 reader = SCIPfindReader(scip, READER_NAME);
    4801 if( reader != NULL )
    4802 {
    4803 readerdata = SCIPreaderGetData(reader);
    4804 assert(readerdata != NULL);
    4805
    4806 linearizeands = readerdata->linearizeands;
    4807 aggrlinearizationands = readerdata->aggrlinearizationands;
    4808 }
    4809 else
    4810 {
    4811 linearizeands = DEFAULT_LINEARIZE_ANDS;
    4812 aggrlinearizationands = DEFAULT_AGGRLINEARIZATION_ANDS;
    4813 }
    4814
    4815 /* collect SOS, quadratic, and SOC constraints in array for later output */
    4816 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
    4817 SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
    4818 SCIP_CALL( SCIPallocBufferArray(scip, &consExpr, nconss) );
    4819 SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
    4820
    4821 tmpvarssize = SCIPgetNTotalVars(scip);
    4822 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
    4823
    4824 for( c = 0; c < nconss; ++c )
    4825 {
    4826 cons = conss[c];
    4827 assert( cons != NULL);
    4828
    4829 /* in case the transformed is written only constraints are posted which are enabled in the current node */
    4830 assert(!transformed || SCIPconsIsEnabled(cons));
    4831
    4832 /* skip marked constraints in connection with indicator constraints */
    4833 if( conshdlrInd != NULL && SCIPhashmapExists(consHidden, (void*) cons) )
    4834 {
    4835 assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear") == 0 );
    4836 continue;
    4837 }
    4838
    4839 conshdlr = SCIPconsGetHdlr(cons);
    4840 assert( conshdlr != NULL );
    4841
    4842 (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
    4843 conshdlrname = SCIPconshdlrGetName(conshdlr);
    4844 assert( transformed == SCIPconsIsTransformed(cons) );
    4845
    4846 if( strcmp(conshdlrname, "linear") == 0 )
    4847 {
    4848 SCIP_CALL( printQuadraticCons(scip, file, consname,
    4850 NULL, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
    4851 }
    4852 else if( strcmp(conshdlrname, "setppc") == 0 )
    4853 {
    4854 consvars = SCIPgetVarsSetppc(scip, cons);
    4855 nconsvars = SCIPgetNVarsSetppc(scip, cons);
    4856
    4857 switch( SCIPgetTypeSetppc(scip, cons) )
    4858 {
    4860 SCIP_CALL( printQuadraticCons(scip, file, consname,
    4861 consvars, NULL, nconsvars, NULL, 1.0, 1.0, transformed) );
    4862 break;
    4864 SCIP_CALL( printQuadraticCons(scip, file, consname,
    4865 consvars, NULL, nconsvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
    4866 break;
    4868 SCIP_CALL( printQuadraticCons(scip, file, consname,
    4869 consvars, NULL, nconsvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
    4870 break;
    4871 }
    4872 }
    4873 else if( strcmp(conshdlrname, "logicor") == 0 )
    4874 {
    4875 SCIP_CALL( printQuadraticCons(scip, file, consname,
    4877 NULL, 1.0, SCIPinfinity(scip), transformed) );
    4878 }
    4879 else if( strcmp(conshdlrname, "knapsack") == 0 )
    4880 {
    4881 SCIP_Longint* weights;
    4882
    4883 consvars = SCIPgetVarsKnapsack(scip, cons);
    4884 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
    4885
    4886 /* copy Longint array to SCIP_Real array */
    4887 weights = SCIPgetWeightsKnapsack(scip, cons);
    4888 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    4889 for( v = 0; v < nconsvars; ++v )
    4890 consvals[v] = (SCIP_Real)weights[v];
    4891
    4892 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
    4893 NULL, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
    4894
    4895 SCIPfreeBufferArray(scip, &consvals);
    4896 }
    4897 else if( strcmp(conshdlrname, "varbound") == 0 )
    4898 {
    4899 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
    4900 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
    4901
    4902 consvars[0] = SCIPgetVarVarbound(scip, cons);
    4903 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
    4904
    4905 consvals[0] = 1.0;
    4906 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    4907
    4908 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL,
    4909 SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
    4910
    4911 SCIPfreeBufferArray(scip, &consvals);
    4912 SCIPfreeBufferArray(scip, &consvars);
    4913 }
    4914 else if( strcmp(conshdlrname, "SOS1") == 0 )
    4915 {
    4916 /* store constraint */
    4917 consSOS1[nConsSOS1++] = cons;
    4918 }
    4919 else if( strcmp(conshdlrname, "SOS2") == 0 )
    4920 {
    4921 /* store constraint */
    4922 consSOS2[nConsSOS2++] = cons;
    4923 }
    4924 else if( strcmp(conshdlrname, "indicator") == 0 )
    4925 {
    4926 SCIP_CONS* lincons;
    4927 SCIP_VAR* binvar;
    4928 SCIP_VAR* slackvar;
    4929 SCIP_VAR** linvars;
    4930 SCIP_Real* linvals;
    4931 int nlinvars;
    4932 int cnt;
    4933 int rhs;
    4934
    4935 assert( conshdlrInd != NULL );
    4936
    4937 lincons = SCIPgetLinearConsIndicator(cons);
    4938 binvar = SCIPgetBinaryVarIndicator(cons);
    4939 slackvar = SCIPgetSlackVarIndicator(cons);
    4940
    4941 assert( lincons != NULL );
    4942 assert( binvar != NULL );
    4943 assert( slackvar != NULL );
    4944
    4945 rhs = 1;
    4946 if ( SCIPvarIsNegated(binvar) )
    4947 {
    4948 rhs = 0;
    4949 binvar = SCIPvarGetNegatedVar(binvar);
    4950 }
    4951
    4952 /* collect linear constraint information (remove slack variable) */
    4953 linvars = SCIPgetVarsLinear(scip, lincons);
    4954 linvals = SCIPgetValsLinear(scip, lincons);
    4955 nlinvars = SCIPgetNVarsLinear(scip, lincons);
    4956 assert( linvars != NULL );
    4957 assert( linvals != NULL );
    4958
    4959 /* linvars always contains slack variable, thus nlinvars >= 1 */
    4960 if( nlinvars > 1 && !SCIPconsIsDeleted(lincons) )
    4961 {
    4962 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(binvar) );
    4963 if( strlen(consname) > 0 )
    4964 SCIPinfoMessage(scip, file, " %s: %s = %d ->", consname, varname, rhs);
    4965 else
    4966 SCIPinfoMessage(scip, file, " %s = %d ->", varname, rhs);
    4967
    4968 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nlinvars-1) );
    4969 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nlinvars-1) );
    4970
    4971 cnt = 0;
    4972 for( v = 0; v < nlinvars; ++v )
    4973 {
    4974 var = linvars[v];
    4975 if( var != slackvar )
    4976 {
    4977 consvars[cnt] = var;
    4978 consvals[cnt++] = linvals[v];
    4979 }
    4980 }
    4981 /* if slackvariable is fixed, it might have been removed from constraint */
    4982 assert( nlinvars == 0 || cnt == nlinvars-1 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar)) );
    4983
    4984 SCIP_CALL( printQuadraticCons(scip, file, "", consvars, consvals, cnt, NULL,
    4985 SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons), transformed) );
    4986
    4987 SCIPfreeBufferArray(scip, &consvals);
    4988 SCIPfreeBufferArray(scip, &consvars);
    4989 }
    4990
    4991 /* store constraint */
    4992 consIndicator[nConsIndicator++] = cons;
    4993 }
    4994 else if( strcmp(conshdlrname, "nonlinear") == 0 )
    4995 {
    4996 SCIP_Bool isquadratic;
    4997 SCIP_EXPR* expr;
    4998
    4999 /* check whether there is a quadratic representation of the nonlinear constraint */
    5000 SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
    5001 if( !isquadratic )
    5002 {
    5003 /* simplify expr and check again whether there is a quadratic representation */
    5004 SCIP_EXPR* exprcopy;
    5005 SCIP_Bool changed;
    5006 SCIP_Bool infeasible;
    5007
    5009 SCIP_CALL( SCIPsimplifyExpr(scip, exprcopy, &expr, &changed, &infeasible, NULL, NULL) );
    5010 SCIP_CALL( SCIPreleaseExpr(scip, &exprcopy) );
    5011 if( changed && !infeasible )
    5012 {
    5013 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, &isquadratic) );
    5014 isquadratic &= SCIPexprAreQuadraticExprsVariables(expr);
    5015 }
    5016 }
    5017 else
    5018 {
    5019 expr = SCIPgetExprNonlinear(cons);
    5020 }
    5021
    5022 /* we cannot handle nonlinear constraint that are not quadratically representable */
    5023 if( !isquadratic )
    5024 {
    5025 SCIPwarningMessage(scip, "nonlinear constraint <%s> not recognized as quadratic: cannot print as LP\n", SCIPconsGetName(cons));
    5026 SCIPinfoMessage(scip, file, "\\ ");
    5027 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    5028 SCIPinfoMessage(scip, file, ";\n");
    5029 }
    5030 else
    5031 {
    5032 SCIP_CALL( printQuadraticCons(scip, file, consname, NULL, NULL, 0, expr,
    5033 SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed) );
    5034
    5035 consExpr[nConsExpr++] = cons;
    5036 }
    5037
    5038 if( expr != SCIPgetExprNonlinear(cons) )
    5039 {
    5040 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    5041 }
    5042 }
    5043 else if( strcmp(conshdlrname, "and") == 0 )
    5044 {
    5045 if( linearizeands )
    5046 {
    5047 SCIP_CALL( printAndCons(scip, file, consname, cons, aggrlinearizationands, transformed) );
    5048 }
    5049 else
    5050 {
    5051 SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
    5052 SCIPinfoMessage(scip, file, "\\ ");
    5053 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    5054 SCIPinfoMessage(scip, file, ";\n");
    5055 }
    5056 }
    5057 else if(strcmp(conshdlrname, "exactlinear") == 0 )
    5058 {
    5060 {
    5061 SCIP_CALL( printRowExact(scip, file, consname, "_", "=",
    5064 }
    5065 else
    5066 {
    5068 {
    5069 SCIP_CALL( printRowExact(scip, file, consname, "_lhs", ">=",
    5072 }
    5074 {
    5075 SCIP_CALL( printRowExact(scip, file, consname, "_rhs", "<=",
    5078 }
    5079 }
    5080 }
    5081 else
    5082 {
    5083 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
    5084 SCIPinfoMessage(scip, file, "\\ ");
    5085 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    5086 SCIPinfoMessage(scip, file, ";\n");
    5087 }
    5088 }
    5089
    5090 /* allocate array for storing aggregated and negated variables (dynamically adjusted) */
    5091 saggvars = MAX(10, nvars);
    5092 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
    5093
    5094 /* create hashtable for storing aggregated variables */
    5095 SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), saggvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
    5096
    5097 /* check for aggregated variables in SOS1 constraints and output aggregations as linear constraints */
    5098 for( c = 0; c < nConsSOS1; ++c )
    5099 {
    5100 cons = consSOS1[c];
    5101 consvars = SCIPgetVarsSOS1(scip, cons);
    5102 nconsvars = SCIPgetNVarsSOS1(scip, cons);
    5103
    5104 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
    5105 }
    5106
    5107 /* check for aggregated variables in SOS2 constraints and output aggregations as linear constraints */
    5108 for( c = 0; c < nConsSOS2; ++c )
    5109 {
    5110 cons = consSOS2[c];
    5111 consvars = SCIPgetVarsSOS2(scip, cons);
    5112 nconsvars = SCIPgetNVarsSOS2(scip, cons);
    5113
    5114 SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
    5115 }
    5116
    5117 /* check for aggregated variables in nonlinear constraints and output aggregations as linear constraints */
    5118 for( c = 0; c < nConsExpr; ++c )
    5119 {
    5120 SCIP_Bool success;
    5121 int ntmpvars;
    5122
    5123 /* get variables of the nonlinear constraint */
    5124 SCIP_CALL( SCIPgetConsNVars(scip, consExpr[c], &ntmpvars, &success) );
    5125 assert(success);
    5126 if( ntmpvars > tmpvarssize )
    5127 {
    5128 tmpvarssize = SCIPcalcMemGrowSize(scip, ntmpvars);
    5129 SCIP_CALL( SCIPreallocBufferArray(scip, &tmpvars, tmpvarssize) );
    5130 }
    5131 SCIP_CALL( SCIPgetConsVars(scip, consExpr[c], tmpvars, tmpvarssize, &success) );
    5132 assert(success);
    5133
    5134 SCIP_CALL( collectAggregatedVars(scip, tmpvars, ntmpvars, &aggvars, &naggvars, &saggvars, varAggregated) );
    5135 }
    5136
    5137 /* check for aggregated variables in indicator constraints and output aggregations as linear constraints */
    5138 for( c = 0; c < nConsIndicator; ++c )
    5139 {
    5140 SCIP_VAR* binvar;
    5141
    5142 cons = consIndicator[c];
    5143 binvar = SCIPgetBinaryVarIndicator(cons);
    5144 if ( ! SCIPvarIsNegated(binvar) )
    5145 {
    5146 /* we take care of negated variables above, but not of aggregated variables */
    5147 SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varAggregated) );
    5148 }
    5149 }
    5150
    5151 /* print aggregation constraints */
    5152 SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, naggvars, aggvars) );
    5153
    5154 /* print "Bounds" section */
    5155 SCIPinfoMessage(scip, file, "Bounds\n");
    5156 for( v = 0; v < nvars; ++v )
    5157 {
    5158 var = vars[v];
    5159 assert( var != NULL );
    5160 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5161
    5162 if( transformed )
    5163 {
    5164 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    5165 lb = SCIPvarGetLbLocal(var);
    5166 ub = SCIPvarGetUbLocal(var);
    5167 }
    5168 else
    5169 {
    5170 lb = SCIPvarGetLbOriginal(var);
    5171 ub = SCIPvarGetUbOriginal(var);
    5172 }
    5173
    5174 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
    5175 SCIPinfoMessage(scip, file, " %s free\n", varname);
    5176 else
    5177 {
    5178 /* print lower bound */
    5179 if( SCIPisInfinity(scip, -lb) )
    5180 SCIPinfoMessage(scip, file, " -inf <= ");
    5181 else
    5182 {
    5183 if( SCIPisZero(scip, lb) )
    5184 {
    5185 /* variables are nonnegative by default - so we skip these variables */
    5186 if( SCIPisInfinity(scip, ub) )
    5187 continue;
    5188 lb = 0.0;
    5189 }
    5190
    5191 SCIPinfoMessage(scip, file, " %.15g <= ", lb);
    5192 }
    5193 /* print variable name */
    5194 SCIPinfoMessage(scip, file, "%s", varname);
    5195
    5196 /* print upper bound as far this one is not infinity */
    5197 if( !SCIPisInfinity(scip, ub) )
    5198 SCIPinfoMessage(scip, file, " <= %.15g", ub);
    5199
    5200 SCIPinfoMessage(scip, file, "\n");
    5201 }
    5202 }
    5203
    5204 /* output aggregated variables as 'free' */
    5205 for( v = 0; v < naggvars; ++v )
    5206 {
    5207 var = aggvars[v];
    5208 assert( var != NULL );
    5209 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5210
    5211 SCIPinfoMessage(scip, file, " %s free\n", varname);
    5212 }
    5213
    5214 /* print binaries section */
    5215 {
    5216 SCIP_Bool initial = TRUE;
    5217
    5218 /* output active variables */
    5219 for( v = 0; v < nintegers; ++v )
    5220 {
    5221 var = vars[v];
    5222
    5223 if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY || (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    5224 continue;
    5225
    5226 if( initial )
    5227 {
    5228 SCIPinfoMessage(scip, file, "Binaries\n");
    5229 initial = FALSE;
    5230 }
    5231
    5232 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5233 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
    5234 appendLine(scip, file, linebuffer, &linecnt, buffer);
    5235 }
    5236
    5237 /* possibly output aggregated variables */
    5238 for( v = 0; v < naggvars; ++v )
    5239 {
    5240 var = aggvars[v];
    5241
    5242 if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY || (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    5243 continue;
    5244
    5245 if( initial )
    5246 {
    5247 SCIPinfoMessage(scip, file, "Binaries\n");
    5248 initial = FALSE;
    5249 }
    5250
    5251 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    5252 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
    5253 appendLine(scip, file, linebuffer, &linecnt, buffer);
    5254 }
    5255
    5256 endLine(scip, file, linebuffer, &linecnt);
    5257 }
    5258
    5259 /* print generals section */
    5260 {
    5261 SCIP_Bool initial = TRUE;
    5262
    5263 /* output active variables */
    5264 for( v = nbinvars; v < nintegers; ++v )
    5265 {
    5266 var = vars[v];
    5267
    5268 switch( SCIPvarGetType(var) )
    5269 {
    5271 continue;
    5273 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    5274 continue;
    5275 break;
    5277 if( (int)SCIPvarGetImplType(var) <= 2 - implintlevel )
    5278 continue;
    5279 break;
    5280 default:
    5281 SCIPerrorMessage("unknown variable type\n");
    5282 return SCIP_INVALIDDATA;
    5283 } /*lint !e788*/
    5284
    5285 if( initial )
    5286 {
    5287 SCIPinfoMessage(scip, file, "Generals\n");
    5288 initial = FALSE;
    5289 }
    5290
    5291 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    5292 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
    5293 appendLine(scip, file, linebuffer, &linecnt, buffer);
    5294 }
    5295
    5296 /* possibly output aggregated variables */
    5297 for( v = 0; v < naggvars; ++v )
    5298 {
    5299 var = aggvars[v];
    5300
    5301 switch( SCIPvarGetType(var) )
    5302 {
    5304 continue;
    5306 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    5307 continue;
    5308 break;
    5310 if( (int)SCIPvarGetImplType(var) <= 2 - implintlevel )
    5311 continue;
    5312 break;
    5313 default:
    5314 SCIPerrorMessage("unknown variable type\n");
    5315 return SCIP_INVALIDDATA;
    5316 } /*lint !e788*/
    5317
    5318 if( initial )
    5319 {
    5320 SCIPinfoMessage(scip, file, "Generals\n");
    5321 initial = FALSE;
    5322 }
    5323
    5324 (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    5325 (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
    5326 appendLine(scip, file, linebuffer, &linecnt, buffer);
    5327 }
    5328
    5329 endLine(scip, file, linebuffer, &linecnt);
    5330 }
    5331
    5332 /* free space */
    5333 SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
    5334 SCIPhashtableFree(&varAggregated);
    5335 if( conshdlrInd != NULL )
    5336 SCIPhashmapFree(&consHidden);
    5337
    5338 /* print SOS section */
    5339 if( nConsSOS1 > 0 || nConsSOS2 > 0 )
    5340 {
    5341 SCIP_Real* weights;
    5342 SCIPinfoMessage(scip, file, "SOS\n");
    5343
    5344 /* first output SOS1 constraints */
    5345 for( c = 0; c < nConsSOS1; ++c )
    5346 {
    5347 cons = consSOS1[c];
    5348 consvars = SCIPgetVarsSOS1(scip, cons);
    5349 nconsvars = SCIPgetNVarsSOS1(scip, cons);
    5350 weights = SCIPgetWeightsSOS1(scip, cons);
    5351
    5352 (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
    5353 printSosCons(scip, file, consname, consvars, weights, nconsvars, 1);
    5354 }
    5355
    5356 /* next output SOS2 constraints */
    5357 for( c = 0; c < nConsSOS2; ++c )
    5358 {
    5359 cons = consSOS2[c];
    5360 consvars = SCIPgetVarsSOS2(scip, cons);
    5361 nconsvars = SCIPgetNVarsSOS2(scip, cons);
    5362 weights = SCIPgetWeightsSOS2(scip, cons);
    5363
    5364 (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
    5365 printSosCons(scip, file, consname, consvars, weights, nconsvars, 2);
    5366 }
    5367 }
    5368
    5369 /* free space */
    5370 SCIPfreeBufferArray(scip, &tmpvars);
    5371 SCIPfreeBufferArray(scip, &consIndicator);
    5372 SCIPfreeBufferArray(scip, &consExpr);
    5373 SCIPfreeBufferArray(scip, &consSOS2);
    5374 SCIPfreeBufferArray(scip, &consSOS1);
    5375
    5376 /* end of lp format */
    5377 SCIPinfoMessage(scip, file, "%s\n", "End");
    5378
    5379 *result = SCIP_SUCCESS;
    5380
    5381 return SCIP_OKAY;
    5382}
    Constraint handler for AND constraints, .
    constraint handler for bound disjunction constraints
    Constraint handler for linear constraints in their most general form, .
    constraint handler for indicator constraints
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    constraint handler for nonlinear constraints specified by algebraic expressions
    Constraint handler for the set partitioning / packing / covering constraints .
    constraint handler for SOS type 1 constraints
    constraint handler for SOS type 2 constraints
    Constraint handler for variable bound constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:376
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    int SCIPfclose(SCIP_FILE *fp)
    Definition: fileio.c:232
    char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
    Definition: fileio.c:200
    SCIP_RETCODE SCIPcheckQuadraticNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *isquadratic)
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2790
    SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2765
    SCIP_VAR ** SCIPgetVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5248
    SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
    Definition: cons_sos1.c:10725
    SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    int SCIPgetNVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_sos1.c:10579
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2740
    SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10844
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9619
    SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9642
    SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    Definition: cons_sos2.c:2578
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10819
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5223
    SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
    int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10794
    SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    SCIP_RATIONAL ** SCIPgetValsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
    Definition: cons_sos2.c:2687
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_RETCODE SCIPreadLp(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
    Definition: reader_lp.c:4427
    SCIP_RETCODE SCIPwriteLp(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objoffset, SCIP_Real objscale, SCIP_RATIONAL *objoffsetexact, SCIP_RATIONAL *objscaleexact, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
    Definition: reader_lp.c:4503
    SCIP_RETCODE SCIPincludeReaderLp(SCIP *scip)
    Definition: reader_lp.c:4390
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
    Definition: scip_prob.c:1486
    SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
    Definition: scip_prob.c:119
    int SCIPgetNTotalVars(SCIP *scip)
    Definition: scip_prob.c:3064
    SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
    Definition: scip_prob.c:3189
    SCIP_RETCODE SCIPaddOrigObjoffsetExact(SCIP *scip, SCIP_RATIONAL *addval)
    Definition: scip_prob.c:1465
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    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_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
    Definition: misc.c:3400
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2647
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
    Definition: scip_cons.c:2621
    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_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
    Definition: cons.c:8518
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
    Definition: scip_cons.c:2577
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8486
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
    Definition: expr.c:4226
    SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
    Definition: expr.c:4262
    void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
    Definition: expr.c:4141
    SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
    Definition: scip_expr.c:1443
    SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1457
    SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
    Definition: scip_expr.c:2402
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
    Definition: expr.c:4186
    SCIP_RETCODE SCIPduplicateExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1307
    SCIP_RETCODE SCIPsimplifyExpr(SCIP *scip, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1798
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:618
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:935
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2085
    SCIP_Bool SCIPrationalIsString(const char *desc)
    Definition: rational.cpp:652
    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
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
    Definition: rational.cpp:716
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:630
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1650
    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_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1437
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1670
    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 SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
    Definition: scip_reader.c:109
    SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
    Definition: scip_reader.c:147
    SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
    Definition: reader.c:605
    SCIP_READER * SCIPfindReader(SCIP *scip, const char *name)
    Definition: scip_reader.c:235
    SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
    Definition: scip_reader.c:171
    const char * SCIPreaderGetName(SCIP_READER *reader)
    Definition: reader.c:680
    SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
    Definition: scip_reader.c:195
    void SCIPreaderMarkExact(SCIP_READER *reader)
    Definition: reader.c:670
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_RETCODE SCIPchgVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
    Definition: scip_var.c:5964
    SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5697
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
    Definition: var.c:24020
    SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
    Definition: scip_var.c:299
    SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:5875
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
    Definition: var.c:24063
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
    Definition: scip_var.c:2378
    SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
    Definition: scip_var.c:10113
    SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
    Definition: var.c:23463
    SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
    Definition: scip_var.c:5420
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_RETCODE SCIPchgVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound)
    Definition: scip_var.c:5786
    SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
    Definition: var.c:23910
    int SCIPstrcasecmp(const char *s1, const char *s2)
    Definition: misc.c:10863
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
    Definition: misc.c:10694
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    public methods for managing constraints
    wrapper functions to map file i/o to standard or zlib file i/o
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    public methods for input file readers
    public methods for problem variables
    wrapper for rational number arithmetic
    enum LpExpType LPEXPTYPE
    Definition: reader_diff.c:83
    struct LpInput LPINPUT
    Definition: reader_diff.c:109
    LpExpType
    Definition: reader_diff.c:80
    LpSection
    Definition: reader_diff.c:74
    enum LpSection LPSECTION
    Definition: reader_diff.c:77
    enum LpSense LPSENSE
    Definition: reader_diff.c:89
    LpSense
    Definition: reader_diff.c:86
    #define LP_MAX_NAMELEN
    Definition: reader_lp.c:90
    static SCIP_DECL_READERWRITE(readerWriteLp)
    Definition: reader_lp.c:4373
    static SCIP_RETCODE printAndCons(SCIP *scip, FILE *file, const char *consname, SCIP_CONS *cons, SCIP_Bool aggrlinearizationands, SCIP_Bool transformed)
    Definition: reader_lp.c:4031
    static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    Definition: reader_lp.c:3350
    #define LP_INIT_COEFSSIZE
    Definition: reader_lp.c:87
    static SCIP_DECL_READERCOPY(readerCopyLp)
    Definition: reader_lp.c:4334
    static SCIP_Bool isSign(LPINPUT *lpinput, int *sign)
    Definition: reader_lp.c:720
    static SCIP_Bool isNewSection(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:509
    #define LP_INIT_QUADCOEFSSIZE
    Definition: reader_lp.c:88
    static void clearLine(char *linebuffer, int *linecnt)
    Definition: reader_lp.c:3412
    static SCIP_Bool hasError(LPINPUT *lpinput)
    Definition: reader_lp.c:183
    static void pushToken(LPINPUT *lpinput)
    Definition: reader_lp.c:472
    static SCIP_Bool getNextLine(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:293
    static SCIP_DECL_READERREAD(readerReadLp)
    Definition: reader_lp.c:4362
    static void swapTokenBuffer(LPINPUT *lpinput)
    Definition: reader_lp.c:498
    static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
    Definition: reader_lp.c:3326
    enum LpExpType LPEXPTYPE
    Definition: reader_lp.c:113
    static SCIP_RETCODE readConstraints(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2215
    static SCIP_RETCODE readBinaries(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2866
    static SCIP_RETCODE readSemicontinuous(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2936
    @ LP_EXP_UNSIGNED
    Definition: reader_lp.c:111
    @ LP_EXP_SIGNED
    Definition: reader_lp.c:111
    @ LP_EXP_NONE
    Definition: reader_lp.c:111
    static SCIP_Bool getNextToken(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:365
    static void printSosCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **vars, SCIP_Real *weights, int nvars, int type)
    Definition: reader_lp.c:3972
    static const char commentchars[]
    Definition: reader_lp.c:147
    static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
    Definition: reader_lp.c:4228
    static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, LPEXPTYPE *exptype)
    Definition: reader_lp.c:239
    #define LP_MAX_LINELEN
    Definition: reader_lp.c:85
    #define LP_MAX_PRINTLEN
    Definition: reader_lp.c:89
    static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
    Definition: reader_lp.c:4174
    static SCIP_RETCODE readGenerals(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2821
    #define READER_DESC
    Definition: reader_lp.c:75
    static SCIP_RETCODE readConstraintsRational(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:1973
    static SCIP_Bool isValueRational(SCIP *scip, LPINPUT *lpinput, SCIP_RATIONAL *value)
    Definition: reader_lp.c:777
    #define LP_MAX_PUSHEDTOKENS
    Definition: reader_lp.c:86
    @ LP_SOS
    Definition: reader_lp.c:105
    @ LP_END
    Definition: reader_lp.c:105
    @ LP_OBJECTIVE
    Definition: reader_lp.c:105
    @ LP_START
    Definition: reader_lp.c:105
    @ LP_GENERALS
    Definition: reader_lp.c:105
    @ LP_SEMICONTINUOUS
    Definition: reader_lp.c:105
    @ LP_CONSTRAINTS
    Definition: reader_lp.c:105
    @ LP_BOUNDS
    Definition: reader_lp.c:105
    @ LP_BINARIES
    Definition: reader_lp.c:105
    static SCIP_RETCODE printQuadraticCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
    Definition: reader_lp.c:3884
    #define READER_EXTENSION
    Definition: reader_lp.c:76
    static SCIP_RETCODE readBoundsRational(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2461
    static SCIP_RETCODE readObjective(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:1652
    static SCIP_Bool isValue(SCIP *scip, LPINPUT *lpinput, SCIP_Real *value)
    Definition: reader_lp.c:745
    #define LP_PRINTLEN
    Definition: reader_lp.c:91
    static SCIP_RETCODE readSos(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:3034
    static SCIP_RETCODE createIndicatorConstraint(SCIP *scip, LPINPUT *lpinput, const char *name, SCIP_VAR *binvar, SCIP_Real binvalue)
    Definition: reader_lp.c:1753
    static void syntaxError(SCIP *scip, LPINPUT *lpinput, const char *msg)
    Definition: reader_lp.c:156
    static void pushBufferToken(LPINPUT *lpinput)
    Definition: reader_lp.c:485
    enum LpSection LPSECTION
    Definition: reader_lp.c:107
    static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
    Definition: reader_lp.c:3426
    static SCIP_RETCODE readCoefficients(SCIP *scip, LPINPUT *lpinput, SCIP_Bool isobjective, char *name, int *coefssize, SCIP_VAR ***vars, SCIP_Real **coefs, int *ncoefs, int *quadcoefssize, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadcoefs, SCIP_Real *objoffset, SCIP_Bool *newsection)
    Definition: reader_lp.c:908
    #define READER_NAME
    Definition: reader_lp.c:74
    static SCIP_Bool isSense(LPINPUT *lpinput, LPSENSE *sense)
    Definition: reader_lp.c:807
    static SCIP_Bool isDelimChar(char c)
    Definition: reader_lp.c:194
    static void swapPointers(char **pointer1, char **pointer2)
    Definition: reader_lp.c:351
    static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
    Definition: reader_lp.c:3333
    static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
    Definition: reader_lp.c:3342
    static SCIP_RETCODE readBounds(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:2644
    static SCIP_RETCODE readObjectiveRational(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:1594
    static SCIP_DECL_READERFREE(readerFreeLp)
    Definition: reader_lp.c:4348
    #define DEFAULT_AGGRLINEARIZATION_ANDS
    Definition: reader_lp.c:79
    enum LpSense LPSENSE
    Definition: reader_lp.c:119
    static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real rhs, SCIP_Bool transformed)
    Definition: reader_lp.c:3479
    static SCIP_RETCODE readCoefficientsRational(SCIP *scip, LPINPUT *lpinput, SCIP_Bool isobjective, char *name, int *coefssize, SCIP_VAR ***vars, SCIP_RATIONAL ***coefs, int *ncoefs, SCIP_RATIONAL *objoffset, SCIP_Bool *newsection)
    Definition: reader_lp.c:1329
    static SCIP_RETCODE readStart(SCIP *scip, LPINPUT *lpinput)
    Definition: reader_lp.c:887
    static SCIP_RETCODE collectAggregatedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR ***aggvars, int *naggvars, int *saggvars, SCIP_HASHTABLE *varAggregated)
    Definition: reader_lp.c:4118
    static SCIP_RETCODE readLPFile(SCIP *scip, LPINPUT *lpinput, const char *filename)
    Definition: reader_lp.c:3244
    static SCIP_RETCODE printRowExact(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_RATIONAL **linvals, int nlinvars, SCIP_RATIONAL *rhs)
    Definition: reader_lp.c:3774
    static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
    Definition: reader_lp.c:4265
    static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
    Definition: reader_lp.c:3449
    static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_VAR **var, SCIP_Bool *created)
    Definition: reader_lp.c:838
    @ LP_SENSE_LE
    Definition: reader_lp.c:117
    @ LP_SENSE_GE
    Definition: reader_lp.c:117
    @ LP_SENSE_NOTHING
    Definition: reader_lp.c:117
    @ LP_SENSE_EQ
    Definition: reader_lp.c:117
    #define DEFAULT_LINEARIZE_ANDS
    Definition: reader_lp.c:78
    static SCIP_Bool isTokenChar(char c)
    Definition: reader_lp.c:215
    LP file reader.
    public methods for constraint handler plugins and constraints
    public methods for exact solving
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for reader plugins
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    @ 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_MINIMAL
    Definition: type_message.h:59
    @ SCIP_OBJSENSE_MAXIMIZE
    Definition: type_prob.h:47
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    enum SCIP_Objsense SCIP_OBJSENSE
    Definition: type_prob.h:50
    struct SCIP_ReaderData SCIP_READERDATA
    Definition: type_reader.h:54
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_NOFILE
    Definition: type_retcode.h:47
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    enum SCIP_Varstatus SCIP_VARSTATUS
    Definition: type_var.h:59