Scippy

    SCIP

    Solving Constraint Integer Programs

    reader_pip.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_pip.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief file reader for polynomial mixed-integer programs in PIP format
    28 * @author Stefan Vigerske
    29 * @author Marc Pfetsch
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    34#include <ctype.h>
    35
    37#include "scip/reader_pip.h"
    38#include "scip/cons_and.h"
    39#include "scip/cons_nonlinear.h"
    40#include "scip/cons_knapsack.h"
    41#include "scip/cons_linear.h"
    42#include "scip/cons_logicor.h"
    43#include "scip/cons_setppc.h"
    44#include "scip/cons_varbound.h"
    45#include "scip/expr_sum.h"
    46#include "scip/expr_var.h"
    47#include "scip/pub_cons.h"
    48#include "scip/pub_expr.h"
    49#include "scip/pub_fileio.h"
    50#include "scip/pub_message.h"
    51#include "scip/pub_misc.h"
    52#include "scip/pub_nlp.h"
    53#include "scip/pub_reader.h"
    54#include "scip/pub_var.h"
    55#include "scip/scip_cons.h"
    56#include "scip/scip_mem.h"
    57#include "scip/scip_message.h"
    58#include "scip/scip_numerics.h"
    59#include "scip/scip_param.h"
    60#include "scip/scip_prob.h"
    61#include "scip/scip_reader.h"
    62#include "scip/scip_var.h"
    63#include <stdlib.h>
    64#include <string.h>
    65#include <ctype.h>
    66
    67#define READER_NAME "pipreader"
    68#define READER_DESC "file reader for polynomial mixed-integer programs in PIP format"
    69#define READER_EXTENSION "pip"
    70
    71
    72/*
    73 * Data structures
    74 */
    75#define PIP_MAX_LINELEN 65536
    76#define PIP_MAX_PUSHEDTOKENS 2
    77#define PIP_INIT_MONOMIALSSIZE 128
    78#define PIP_INIT_FACTORSSIZE 16
    79#define PIP_MAX_PRINTLEN 561 /**< the maximum length of any line is 560 + '\\0' = 561*/
    80#define PIP_MAX_NAMELEN 256 /**< the maximum length for any name is 255 + '\\0' = 256 */
    81#define PIP_PRINTLEN 100
    82
    83/** Section in PIP File */
    85{
    93};
    95
    97{
    103
    105{
    111typedef enum PipSense PIPSENSE;
    112
    113/** PIP reading data */
    114struct PipInput
    115{
    116 SCIP_FILE* file;
    117 char linebuf[PIP_MAX_LINELEN+1];
    118 char probname[PIP_MAX_LINELEN];
    119 char objname[PIP_MAX_LINELEN];
    120 char* token;
    121 char* tokenbuf;
    122 char* pushedtokens[PIP_MAX_PUSHEDTOKENS];
    123 int npushedtokens;
    124 int linenumber;
    125 int linepos;
    126 PIPSECTION section;
    127 SCIP_OBJSENSE objsense;
    128 SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
    129 SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
    130 SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
    131 SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
    132 SCIP_Bool haserror;
    133};
    134typedef struct PipInput PIPINPUT;
    135
    136static const char delimchars[] = " \f\n\r\t\v";
    137static const char tokenchars[] = "-+:<>=*^";
    138static const char commentchars[] = "\\";
    139static const char namechars[] = "!#$%&;?@_"; /* and characters and numbers */
    140
    141
    142/*
    143 * Local methods (for reading)
    144 */
    145
    146/** issues an error message and marks the PIP data to have errors */
    147static
    149 SCIP* scip, /**< SCIP data structure */
    150 PIPINPUT* pipinput, /**< PIP reading data */
    151 const char* msg /**< error message */
    152 )
    153{
    154 char formatstr[256];
    155
    156 assert(pipinput != NULL);
    157
    158 SCIPerrorMessage("Syntax error in line %d: %s ('%s')\n", pipinput->linenumber, msg, pipinput->token);
    159 if( pipinput->linebuf[strlen(pipinput->linebuf)-1] == '\n' )
    160 {
    161 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", pipinput->linebuf);
    162 }
    163 else
    164 {
    165 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", pipinput->linebuf);
    166 }
    167 (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", pipinput->linepos);
    169 pipinput->section = PIP_END;
    170 pipinput->haserror = TRUE;
    171}
    172
    173/** returns whether a syntax error was detected */
    174static
    176 PIPINPUT* pipinput /**< PIP reading data */
    177 )
    178{
    179 assert(pipinput != NULL);
    180
    181 return pipinput->haserror;
    182}
    183
    184/** returns whether the given character is a token delimiter */
    185static
    187 char c /**< input character */
    188 )
    189{
    190 return (c == '\0') || (strchr(delimchars, c) != NULL);
    191}
    192
    193/** returns whether the given character is a single token */
    194static
    196 char c /**< input character */
    197 )
    198{
    199 return (strchr(tokenchars, c) != NULL);
    200}
    201
    202/** returns whether the current character is member of a value string */
    203static
    205 char c, /**< input character */
    206 char nextc, /**< next input character */
    207 SCIP_Bool firstchar, /**< is the given character the first char of the token? */
    208 SCIP_Bool* hasdot, /**< pointer to update the dot flag */
    209 PIPEXPTYPE* exptype /**< pointer to update the exponent type */
    210 )
    211{
    212 assert(hasdot != NULL);
    213 assert(exptype != NULL);
    214
    215 if( isdigit((unsigned char)c) )
    216 return TRUE;
    217 else if( (*exptype == PIP_EXP_NONE) && !(*hasdot) && (c == '.') && isdigit((unsigned char)nextc) )
    218 {
    219 *hasdot = TRUE;
    220 return TRUE;
    221 }
    222 else if( !firstchar && (*exptype == PIP_EXP_NONE) && (c == 'e' || c == 'E') )
    223 {
    224 if( nextc == '+' || nextc == '-' )
    225 {
    226 *exptype = PIP_EXP_SIGNED;
    227 return TRUE;
    228 }
    229 else if( isdigit((unsigned char)nextc) )
    230 {
    231 *exptype = PIP_EXP_UNSIGNED;
    232 return TRUE;
    233 }
    234 }
    235 else if( (*exptype == PIP_EXP_SIGNED) && (c == '+' || c == '-') )
    236 {
    237 *exptype = PIP_EXP_UNSIGNED;
    238 return TRUE;
    239 }
    240
    241 return FALSE;
    242}
    243
    244/** reads the next line from the input file into the line buffer; skips comments;
    245 * returns whether a line could be read
    246 */
    247static
    249 SCIP* scip, /**< SCIP data structure */
    250 PIPINPUT* pipinput /**< PIP reading data */
    251 )
    252{
    253 int i;
    254
    255 assert(scip != NULL); /* for lint */
    256 assert(pipinput != NULL);
    257
    258 /* clear the line */
    259 BMSclearMemoryArray(pipinput->linebuf, PIP_MAX_LINELEN);
    260
    261 /* read next line */
    262 pipinput->linepos = 0;
    263 pipinput->linebuf[PIP_MAX_LINELEN-2] = '\0';
    264 if( SCIPfgets(pipinput->linebuf, (int) sizeof(pipinput->linebuf), pipinput->file) == NULL )
    265 return FALSE;
    266 pipinput->linenumber++;
    267 if( pipinput->linebuf[PIP_MAX_LINELEN-2] != '\0' )
    268 {
    269 SCIPerrorMessage("Error: line %d exceeds %d characters\n", pipinput->linenumber, PIP_MAX_LINELEN-2);
    270 pipinput->haserror = TRUE;
    271 return FALSE;
    272 }
    273 pipinput->linebuf[PIP_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    274
    275 /* skip characters after comment symbol */
    276 for( i = 0; commentchars[i] != '\0'; ++i )
    277 {
    278 char* commentstart;
    279
    280 commentstart = strchr(pipinput->linebuf, commentchars[i]);
    281 if( commentstart != NULL )
    282 {
    283 *commentstart = '\0';
    284 *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    285 }
    286 }
    287
    288 return TRUE;
    289}
    290
    291/** swaps the addresses of two pointers */
    292static
    294 char** pointer1, /**< first pointer */
    295 char** pointer2 /**< second pointer */
    296 )
    297{
    298 char* tmp;
    299
    300 tmp = *pointer1;
    301 *pointer1 = *pointer2;
    302 *pointer2 = tmp;
    303}
    304
    305/** reads the next token from the input file into the token buffer; returns whether a token was read */
    306static
    308 SCIP* scip, /**< SCIP data structure */
    309 PIPINPUT* pipinput /**< PIP reading data */
    310 )
    311{
    312 SCIP_Bool hasdot;
    313 PIPEXPTYPE exptype;
    314 char* buf;
    315 int tokenlen;
    316
    317 assert(pipinput != NULL);
    318 assert(pipinput->linepos < PIP_MAX_LINELEN);
    319
    320 /* check the token stack */
    321 if( pipinput->npushedtokens > 0 )
    322 {
    323 swapPointers(&pipinput->token, &pipinput->pushedtokens[pipinput->npushedtokens-1]);
    324 pipinput->npushedtokens--;
    325 SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", pipinput->linenumber, pipinput->token);
    326 return TRUE;
    327 }
    328
    329 /* skip delimiters */
    330 buf = pipinput->linebuf;
    331 while( isDelimChar(buf[pipinput->linepos]) )
    332 {
    333 if( buf[pipinput->linepos] == '\0' )
    334 {
    335 if( !getNextLine(scip, pipinput) )
    336 {
    337 pipinput->section = PIP_END;
    338 SCIPdebugMsg(scip, "(line %d) end of file\n", pipinput->linenumber);
    339 return FALSE;
    340 }
    341 assert(pipinput->linepos == 0);
    342 }
    343 else
    344 pipinput->linepos++;
    345 }
    346 assert(pipinput->linepos < PIP_MAX_LINELEN);
    347 assert(!isDelimChar(buf[pipinput->linepos]));
    348
    349 /* check if the token is a value */
    350 hasdot = FALSE;
    351 exptype = PIP_EXP_NONE;
    352 if( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], TRUE, &hasdot, &exptype) )
    353 {
    354 /* read value token */
    355 tokenlen = 0;
    356 do
    357 {
    358 assert(tokenlen < PIP_MAX_LINELEN);
    359 assert(!isDelimChar(buf[pipinput->linepos]));
    360 pipinput->token[tokenlen] = buf[pipinput->linepos];
    361 tokenlen++;
    362 pipinput->linepos++;
    363 }
    364 while( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], FALSE, &hasdot, &exptype) );
    365 }
    366 else
    367 {
    368 /* read non-value token */
    369 tokenlen = 0;
    370 do
    371 {
    372 assert(tokenlen < PIP_MAX_LINELEN);
    373 pipinput->token[tokenlen] = buf[pipinput->linepos];
    374 tokenlen++;
    375 pipinput->linepos++;
    376 if( tokenlen == 1 && isTokenChar(pipinput->token[0]) )
    377 break;
    378 }
    379 while( !isDelimChar(buf[pipinput->linepos]) && !isTokenChar(buf[pipinput->linepos]) );
    380
    381 /* if the token is an equation sense '<', '>', or '=', skip a following '='
    382 * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
    383 */
    384 if( tokenlen >= 1
    385 && (pipinput->token[tokenlen-1] == '<' || pipinput->token[tokenlen-1] == '>' || pipinput->token[tokenlen-1] == '=')
    386 && buf[pipinput->linepos] == '=' )
    387 {
    388 pipinput->linepos++;
    389 }
    390 else if( pipinput->token[tokenlen-1] == '=' && (buf[pipinput->linepos] == '<' || buf[pipinput->linepos] == '>') )
    391 {
    392 pipinput->token[tokenlen-1] = buf[pipinput->linepos];
    393 pipinput->linepos++;
    394 }
    395 }
    396 assert(tokenlen < PIP_MAX_LINELEN);
    397 pipinput->token[tokenlen] = '\0';
    398
    399 SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", pipinput->linenumber, pipinput->token);
    400
    401 return TRUE;
    402}
    403
    404/** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
    405static
    407 PIPINPUT* pipinput /**< PIP reading data */
    408 )
    409{
    410 assert(pipinput != NULL);
    411 assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
    412
    413 swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->token);
    414 pipinput->npushedtokens++;
    415}
    416
    417/** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
    418static
    420 PIPINPUT* pipinput /**< PIP reading data */
    421 )
    422{
    423 assert(pipinput != NULL);
    424 assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
    425
    426 swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->tokenbuf);
    427 pipinput->npushedtokens++;
    428}
    429
    430/** swaps the current token with the token buffer */
    431static
    433 PIPINPUT* pipinput /**< PIP reading data */
    434 )
    435{
    436 assert(pipinput != NULL);
    437
    438 swapPointers(&pipinput->token, &pipinput->tokenbuf);
    439}
    440
    441/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
    442static
    444 SCIP* scip, /**< SCIP data structure */
    445 PIPINPUT* pipinput /**< PIP reading data */
    446 )
    447{
    448 SCIP_Bool iscolon;
    449
    450 assert(pipinput != NULL);
    451
    452 /* remember first token by swapping the token buffer */
    453 swapTokenBuffer(pipinput);
    454
    455 /* look at next token: if this is a ':', the first token is a name and no section keyword */
    456 iscolon = FALSE;
    457 if( getNextToken(scip, pipinput) )
    458 {
    459 iscolon = (strcmp(pipinput->token, ":") == 0);
    460 pushToken(pipinput);
    461 }
    462
    463 /* reinstall the previous token by swapping back the token buffer */
    464 swapTokenBuffer(pipinput);
    465
    466 /* check for ':' */
    467 if( iscolon )
    468 return FALSE;
    469
    470 if( SCIPstrcasecmp(pipinput->token, "MINIMIZE") == 0
    471 || SCIPstrcasecmp(pipinput->token, "MINIMUM") == 0
    472 || SCIPstrcasecmp(pipinput->token, "MIN") == 0 )
    473 {
    474 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
    475 pipinput->section = PIP_OBJECTIVE;
    476 pipinput->objsense = SCIP_OBJSENSE_MINIMIZE;
    477 return TRUE;
    478 }
    479
    480 if( SCIPstrcasecmp(pipinput->token, "MAXIMIZE") == 0
    481 || SCIPstrcasecmp(pipinput->token, "MAXIMUM") == 0
    482 || SCIPstrcasecmp(pipinput->token, "MAX") == 0 )
    483 {
    484 SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
    485 pipinput->section = PIP_OBJECTIVE;
    486 pipinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
    487 return TRUE;
    488 }
    489
    490 if( SCIPstrcasecmp(pipinput->token, "SUBJECT") == 0 )
    491 {
    492 /* check if the next token is 'TO' */
    493 swapTokenBuffer(pipinput);
    494 if( getNextToken(scip, pipinput) )
    495 {
    496 if( SCIPstrcasecmp(pipinput->token, "TO") == 0 )
    497 {
    498 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
    499 pipinput->section = PIP_CONSTRAINTS;
    500 return TRUE;
    501 }
    502 else
    503 pushToken(pipinput);
    504 }
    505 swapTokenBuffer(pipinput);
    506 }
    507
    508 if( SCIPstrcasecmp(pipinput->token, "SUCH") == 0 )
    509 {
    510 /* check if the next token is 'THAT' */
    511 swapTokenBuffer(pipinput);
    512 if( getNextToken(scip, pipinput) )
    513 {
    514 if( SCIPstrcasecmp(pipinput->token, "THAT") == 0 )
    515 {
    516 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
    517 pipinput->section = PIP_CONSTRAINTS;
    518 return TRUE;
    519 }
    520 else
    521 pushToken(pipinput);
    522 }
    523 swapTokenBuffer(pipinput);
    524 }
    525
    526 if( SCIPstrcasecmp(pipinput->token, "st") == 0
    527 || SCIPstrcasecmp(pipinput->token, "S.T.") == 0
    528 || SCIPstrcasecmp(pipinput->token, "ST.") == 0 )
    529 {
    530 SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
    531 pipinput->section = PIP_CONSTRAINTS;
    532 return TRUE;
    533 }
    534
    535 if( SCIPstrcasecmp(pipinput->token, "BOUNDS") == 0
    536 || SCIPstrcasecmp(pipinput->token, "BOUND") == 0 )
    537 {
    538 SCIPdebugMsg(scip, "(line %d) new section: BOUNDS\n", pipinput->linenumber);
    539 pipinput->section = PIP_BOUNDS;
    540 return TRUE;
    541 }
    542
    543 if( SCIPstrcasecmp(pipinput->token, "GENERAL") == 0
    544 || SCIPstrcasecmp(pipinput->token, "GENERALS") == 0
    545 || SCIPstrcasecmp(pipinput->token, "GEN") == 0
    546 || SCIPstrcasecmp(pipinput->token, "INTEGER") == 0
    547 || SCIPstrcasecmp(pipinput->token, "INTEGERS") == 0
    548 || SCIPstrcasecmp(pipinput->token, "INT") == 0 )
    549 {
    550 SCIPdebugMsg(scip, "(line %d) new section: GENERALS\n", pipinput->linenumber);
    551 pipinput->section = PIP_GENERALS;
    552 return TRUE;
    553 }
    554
    555 if( SCIPstrcasecmp(pipinput->token, "BINARY") == 0
    556 || SCIPstrcasecmp(pipinput->token, "BINARIES") == 0
    557 || SCIPstrcasecmp(pipinput->token, "BIN") == 0 )
    558 {
    559 SCIPdebugMsg(scip, "(line %d) new section: BINARIES\n", pipinput->linenumber);
    560 pipinput->section = PIP_BINARIES;
    561 return TRUE;
    562 }
    563
    564 if( SCIPstrcasecmp(pipinput->token, "END") == 0 )
    565 {
    566 SCIPdebugMsg(scip, "(line %d) new section: END\n", pipinput->linenumber);
    567 pipinput->section = PIP_END;
    568 return TRUE;
    569 }
    570
    571 return FALSE;
    572}
    573
    574/** returns whether the current token is a sign */
    575static
    577 PIPINPUT* pipinput, /**< PIP reading data */
    578 int* sign /**< pointer to update the sign */
    579 )
    580{
    581 assert(pipinput != NULL);
    582 assert(sign != NULL);
    583 assert(*sign == +1 || *sign == -1);
    584
    585 if( pipinput->token[1] == '\0' )
    586 {
    587 if( *pipinput->token == '+' )
    588 return TRUE;
    589 else if( *pipinput->token == '-' )
    590 {
    591 *sign *= -1;
    592 return TRUE;
    593 }
    594 }
    595
    596 return FALSE;
    597}
    598
    599/** returns whether the current token is a value */
    600static
    602 SCIP* scip, /**< SCIP data structure */
    603 PIPINPUT* pipinput, /**< PIP reading data */
    604 SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
    605 )
    606{
    607 assert(pipinput != NULL);
    608 assert(value != NULL);
    609
    610 if( SCIPstrcasecmp(pipinput->token, "INFINITY") == 0 || SCIPstrcasecmp(pipinput->token, "INF") == 0 )
    611 {
    612 *value = SCIPinfinity(scip);
    613 return TRUE;
    614 }
    615 else
    616 {
    617 double val;
    618 char* endptr;
    619
    620 val = strtod(pipinput->token, &endptr);
    621 if( endptr != pipinput->token && *endptr == '\0' )
    622 {
    623 *value = val;
    624 return TRUE;
    625 }
    626 }
    627
    628 return FALSE;
    629}
    630
    631/** returns whether the current token is an equation sense */
    632static
    634 PIPINPUT* pipinput, /**< PIP reading data */
    635 PIPSENSE* sense /**< pointer to store the equation sense, or NULL */
    636 )
    637{
    638 assert(pipinput != NULL);
    639
    640 if( strcmp(pipinput->token, "<") == 0 )
    641 {
    642 if( sense != NULL )
    643 *sense = PIP_SENSE_LE;
    644 return TRUE;
    645 }
    646 else if( strcmp(pipinput->token, ">") == 0 )
    647 {
    648 if( sense != NULL )
    649 *sense = PIP_SENSE_GE;
    650 return TRUE;
    651 }
    652 else if( strcmp(pipinput->token, "=") == 0 )
    653 {
    654 if( sense != NULL )
    655 *sense = PIP_SENSE_EQ;
    656 return TRUE;
    657 }
    658
    659 return FALSE;
    660}
    661
    662/** returns the variable with the given name, or creates a new variable if it does not exist */
    663static
    665 SCIP* scip, /**< SCIP data structure */
    666 char* name, /**< name of the variable */
    667 SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
    668 SCIP_VAR** var, /**< pointer to store the variable */
    669 SCIP_Bool* created /**< pointer to store whether a new variable was created, or NULL */
    670 )
    671{
    672 assert(name != NULL);
    673 assert(var != NULL);
    674
    675 *var = SCIPfindVar(scip, name);
    676 if( *var == NULL )
    677 {
    678 SCIP_VAR* newvar;
    679
    680 /* create new variable of the given name */
    681 SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
    683 !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
    684 SCIP_CALL( SCIPaddVar(scip, newvar) );
    685 *var = newvar;
    686
    687 /* because the variable was added to the problem, it is captured by SCIP and we can safely release it right now
    688 * without making the returned *var invalid
    689 */
    690 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
    691
    692 if( created != NULL )
    693 *created = TRUE;
    694 }
    695 else if( created != NULL )
    696 *created = FALSE;
    697
    698 return SCIP_OKAY;
    699}
    700
    701/** reads the header of the file */
    702static
    704 SCIP* scip, /**< SCIP data structure */
    705 PIPINPUT* pipinput /**< PIP reading data */
    706 )
    707{
    708 assert(pipinput != NULL);
    709
    710 /* everything before first section is treated as comment */
    711 do
    712 {
    713 /* get token */
    714 if( !getNextToken(scip, pipinput) )
    715 return SCIP_OKAY;
    716 }
    717 while( !isNewSection(scip, pipinput) );
    718
    719 return SCIP_OKAY;
    720}
    721
    722/** ensure that an array of monomials can hold a minimum number of entries */
    723static
    725 SCIP* scip, /**< SCIP data structure */
    726 SCIP_EXPR*** monomials, /**< pointer to current array of monomials */
    727 SCIP_Real** monomialscoef, /**< pointer to current array of monomial coefficients */
    728 int* monomialssize, /**< current size of monomials array at input; new size at exit */
    729 int minnmonomials /**< required minimal size of monomials array */
    730 )
    731{
    732 int newsize;
    733
    734 assert(scip != NULL);
    735 assert(monomials != NULL);
    736 assert(monomialscoef != NULL);
    737 assert(monomialssize != NULL);
    738 assert(*monomials != NULL || *monomialssize == 0);
    739
    740 if( minnmonomials <= *monomialssize )
    741 return SCIP_OKAY;
    742
    743 newsize = SCIPcalcMemGrowSize(scip, minnmonomials);
    744
    745 if( *monomials != NULL )
    746 {
    747 SCIP_CALL( SCIPreallocBufferArray(scip, monomials, newsize) );
    748 }
    749 else
    750 {
    751 SCIP_CALL( SCIPallocBufferArray(scip, monomials, newsize) );
    752 }
    753 if( *monomialscoef != NULL )
    754 {
    755 SCIP_CALL( SCIPreallocBufferArray(scip, monomialscoef, newsize) );
    756 }
    757 else
    758 {
    759 SCIP_CALL( SCIPallocBufferArray(scip, monomialscoef, newsize) );
    760 }
    761 *monomialssize = newsize;
    762
    763 return SCIP_OKAY;
    764}
    765
    766/** ensure that arrays of exponents and variable indices can hold a minimum number of entries */
    767static
    769 SCIP* scip, /**< SCIP data structure */
    770 SCIP_VAR*** vars, /**< pointer to current array of variables */
    771 SCIP_Real** exponents, /**< pointer to current array of exponents */
    772 int* factorssize, /**< current size of arrays at input; new size at exit */
    773 int minnfactors /**< required minimal size of arrays */
    774 )
    775{
    776 int newsize;
    777
    778 assert(scip != NULL);
    779 assert(vars != NULL);
    780 assert(exponents != NULL);
    781 assert(factorssize != NULL);
    782 assert(*exponents != NULL || *factorssize == 0);
    783 assert(*vars != NULL || *factorssize == 0);
    784
    785 if( minnfactors <= *factorssize )
    786 return SCIP_OKAY;
    787
    788 newsize = SCIPcalcMemGrowSize(scip, minnfactors);
    789
    790 if( *exponents != NULL )
    791 {
    792 SCIP_CALL( SCIPreallocBufferArray(scip, exponents, newsize) );
    793 SCIP_CALL( SCIPreallocBufferArray(scip, vars, newsize) );
    794 }
    795 else
    796 {
    797 SCIP_CALL( SCIPallocBufferArray(scip, exponents, newsize) );
    798 SCIP_CALL( SCIPallocBufferArray(scip, vars, newsize) );
    799 }
    800 *factorssize = newsize;
    801
    802 return SCIP_OKAY;
    803}
    804
    805/** reads an objective or constraint with name and coefficients */
    806static
    808 SCIP* scip, /**< SCIP data structure */
    809 PIPINPUT* pipinput, /**< PIP reading data */
    810 char* name, /**< pointer to store the name of the line; must be at least of size
    811 * PIP_MAX_LINELEN */
    812 SCIP_EXPR** expr, /**< pointer to store the constraint function as expression */
    813 SCIP_Bool* islinear, /**< pointer to store polynomial is linear */
    814 SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
    815 )
    816{
    817 SCIP_Bool havesign;
    818 SCIP_Bool havevalue;
    819 SCIP_Real coef;
    820 int coefsign;
    821 int nextcoefsign;
    822 int monomialdegree;
    823 int i;
    824
    825 SCIP_VAR** vars;
    826 SCIP_Real constant;
    827
    828 SCIP_EXPR** monomials;
    829 SCIP_Real* monomialscoef;
    830 int monomialssize;
    831 int nmonomials;
    832
    833 int nfactors;
    834 int factorssize;
    835 SCIP_Real* exponents;
    836
    837 assert(scip != NULL);
    838 assert(pipinput != NULL);
    839 assert(name != NULL);
    840 assert(expr != NULL);
    841 assert(islinear != NULL);
    842 assert(newsection != NULL);
    843
    844 *name = '\0';
    845 *expr = NULL;
    846 *islinear = TRUE;
    847 *newsection = FALSE;
    848
    849 /* read the first token, which may be the name of the line */
    850 if( getNextToken(scip, pipinput) )
    851 {
    852 /* check if we reached a new section */
    853 if( isNewSection(scip, pipinput) )
    854 {
    855 *newsection = TRUE;
    856 return SCIP_OKAY;
    857 }
    858
    859 /* remember the token in the token buffer */
    860 swapTokenBuffer(pipinput);
    861
    862 /* get the next token and check, whether it is a colon */
    863 if( getNextToken(scip, pipinput) )
    864 {
    865 if( strcmp(pipinput->token, ":") == 0 )
    866 {
    867 /* the second token was a colon: the first token is the line name */
    868 (void)SCIPstrncpy(name, pipinput->tokenbuf, PIP_MAX_LINELEN);
    869 SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", pipinput->linenumber, name);
    870 }
    871 else
    872 {
    873 /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
    874 pushToken(pipinput);
    875 pushBufferToken(pipinput);
    876 }
    877 }
    878 else
    879 {
    880 /* there was only one token left: push it back onto the token stack and parse it as coefficient */
    881 pushBufferToken(pipinput);
    882 }
    883 }
    884
    885 /* initialize buffer for storing the monomials */
    886 monomialssize = PIP_INIT_MONOMIALSSIZE;
    887 SCIP_CALL( SCIPallocBufferArray(scip, &monomials, monomialssize) );
    888 SCIP_CALL( SCIPallocBufferArray(scip, &monomialscoef, monomialssize) );
    889
    890 /* initialize buffer for storing the factors in a monomial */
    891 factorssize = PIP_INIT_FACTORSSIZE;
    892 SCIP_CALL( SCIPallocBufferArray(scip, &exponents, factorssize) );
    893 SCIP_CALL( SCIPallocBufferArray(scip, &vars, factorssize) );
    894
    895 /* read the coefficients */
    896 coefsign = +1;
    897 nextcoefsign = +1;
    898 coef = 1.0;
    899 havesign = FALSE;
    900 havevalue = FALSE;
    901 nmonomials = 0;
    902 nfactors = 0;
    903 monomialdegree = 0;
    904 constant = 0.0;
    905 while( getNextToken(scip, pipinput) )
    906 {
    907 SCIP_VAR* var;
    908 SCIP_Bool issense;
    909 SCIP_Bool issign;
    910 SCIP_Bool isnewsection;
    911 SCIP_Real exponent;
    912
    913 issign = FALSE; /* fix compiler warning */
    914 issense = FALSE; /* fix lint warning */
    915 if( (isnewsection = isNewSection(scip, pipinput)) || /*lint !e820*/
    916 (issense = isSense(pipinput, NULL)) || /*lint !e820*/
    917 ((nfactors > 0 || havevalue) && (issign = isSign(pipinput, &nextcoefsign))) ) /*lint !e820*/
    918 {
    919 /* finish the current monomial */
    920 if( nfactors > 0 )
    921 {
    922 if( coefsign * coef != 0.0 )
    923 {
    924 SCIP_CALL( ensureMonomialsSize(scip, &monomials, &monomialscoef, &monomialssize, nmonomials + 1) );
    925 SCIP_CALL( SCIPcreateExprMonomial(scip, &monomials[nmonomials], nfactors, vars, exponents, NULL, NULL) );
    926 monomialscoef[nmonomials] = coefsign * coef;
    927 ++nmonomials;
    928 }
    929 }
    930 else if( havevalue )
    931 {
    932 constant += coefsign * coef;
    933 }
    934
    935 if( monomialdegree > 1 )
    936 *islinear = FALSE;
    937
    938 /* reset variables */
    939 nfactors = 0;
    940 coef = 1.0;
    941 coefsign = +1;
    942 havesign = FALSE;
    943 havevalue = FALSE;
    944 monomialdegree = 0;
    945
    946 if( isnewsection )
    947 {
    948 *newsection = TRUE;
    949 break;
    950 }
    951
    952 if( issense )
    953 {
    954 /* put the sense back onto the token stack */
    955 pushToken(pipinput);
    956 break;
    957 }
    958
    959 if( issign )
    960 {
    961 coefsign = nextcoefsign;
    962 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
    963 havesign = TRUE;
    964 nextcoefsign = +1;
    965 continue;
    966 }
    967 }
    968
    969 /* check if we read a sign */
    970 if( isSign(pipinput, &coefsign) )
    971 {
    972 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
    973
    974 if( nfactors > 0 || havevalue )
    975 {
    976 syntaxError(scip, pipinput, "sign can only be at beginning of monomial");
    977 goto TERMINATE_READPOLYNOMIAL;
    978 }
    979
    980 havesign = TRUE;
    981 continue;
    982 }
    983
    984 /* check if we are in between factors of a monomial */
    985 if( strcmp(pipinput->token, "*") == 0 )
    986 {
    987 if( nfactors == 0 )
    988 {
    989 syntaxError(scip, pipinput, "cannot have '*' before first variable in monomial");
    990 goto TERMINATE_READPOLYNOMIAL;
    991 }
    992
    993 continue;
    994 }
    995
    996 /* all but the first monomial need a sign */
    997 if( nmonomials > 0 && !havesign )
    998 {
    999 syntaxError(scip, pipinput, "expected sign ('+' or '-') or sense ('<' or '>')");
    1000 goto TERMINATE_READPOLYNOMIAL;
    1001 }
    1002
    1003 /* check if we are at an exponent for the last variable */
    1004 if( strcmp(pipinput->token, "^") == 0 )
    1005 {
    1006 if( !getNextToken(scip, pipinput) || !isValue(scip, pipinput, &exponent) )
    1007 {
    1008 syntaxError(scip, pipinput, "expected exponent value after '^'");
    1009 goto TERMINATE_READPOLYNOMIAL;
    1010 }
    1011 if( nfactors == 0 )
    1012 {
    1013 syntaxError(scip, pipinput, "cannot have '^' before first variable in monomial");
    1014 goto TERMINATE_READPOLYNOMIAL;
    1015 }
    1016 exponents[nfactors-1] = exponent; /*lint !e530*/
    1017 if( SCIPisIntegral(scip, exponent) && exponent > 0.0 ) /*lint !e530*/
    1018 monomialdegree += (int)exponent - 1; /*lint !e530*//* -1, because we added +1 when we put the variable into varidxs */
    1019 else
    1020 *islinear = FALSE;
    1021
    1022 SCIPdebugMsg(scip, "(line %d) read exponent value %g for variable %s\n", pipinput->linenumber, exponent,
    1023 SCIPvarGetName(vars[nfactors-1]));
    1024 continue;
    1025 }
    1026
    1027 /* check if we read a value */
    1028 if( isValue(scip, pipinput, &coef) )
    1029 {
    1030 SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", pipinput->linenumber, coef, coefsign);
    1031
    1032 if( havevalue )
    1033 {
    1034 syntaxError(scip, pipinput, "two consecutive values");
    1035 goto TERMINATE_READPOLYNOMIAL;
    1036 }
    1037
    1038 if( nfactors > 0 )
    1039 {
    1040 syntaxError(scip, pipinput, "coefficients can only be at the beginning of a monomial");
    1041 goto TERMINATE_READPOLYNOMIAL;
    1042 }
    1043
    1044 havevalue = TRUE;
    1045 continue;
    1046 }
    1047
    1048 /* the token is a variable name: get the corresponding variable (or create a new one) */
    1049 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
    1050
    1051 /* ensure that there is enough memory to store all factors */
    1052 SCIP_CALL( ensureFactorsSize(scip, &vars, &exponents, &factorssize, nfactors + 1) );
    1053
    1054 /* create and store corresponding variable expression */
    1055 vars[nfactors] = var;
    1056 exponents[nfactors] = 1.0;
    1057 ++nfactors;
    1058 ++monomialdegree;
    1059 }
    1060
    1061 if( nfactors > 0 )
    1062 {
    1063 syntaxError(scip, pipinput, "string ended before monomial has finished");
    1064 goto TERMINATE_READPOLYNOMIAL;
    1065 }
    1066
    1067 /* create sum expression consisting of all monomial expressions */
    1068 SCIP_CALL( SCIPcreateExprSum(scip, expr, nmonomials, monomials, monomialscoef, constant, NULL, NULL) );
    1069
    1070 /* release monomial expressions */
    1071 for( i = 0; i < nmonomials; ++i )
    1072 {
    1073 assert(monomials[i] != NULL);
    1074 SCIP_CALL( SCIPreleaseExpr(scip, &monomials[i]) );
    1075 }
    1076
    1077#ifdef SCIP_DEBUG
    1078 SCIPdebugMsg(scip, "read polynomial: ");
    1079 SCIP_CALL( SCIPprintExpr(scip, *expr, NULL) );
    1080 SCIPinfoMessage(scip, NULL, "\n");
    1081#endif
    1082
    1083 TERMINATE_READPOLYNOMIAL:
    1084 SCIPfreeBufferArray(scip, &vars);
    1085 SCIPfreeBufferArray(scip, &exponents);
    1086 SCIPfreeBufferArray(scip, &monomialscoef);
    1087 SCIPfreeBufferArray(scip, &monomials);
    1088
    1089 return SCIP_OKAY;
    1090}
    1091
    1092/** reads the objective section */
    1093static
    1095 SCIP* scip, /**< SCIP data structure */
    1096 PIPINPUT* pipinput /**< PIP reading data */
    1097 )
    1098{
    1099 char name[PIP_MAX_LINELEN];
    1100 SCIP_EXPR* expr;
    1101 SCIP_Bool linear;
    1102 SCIP_Bool newsection;
    1103 SCIP_Bool initial;
    1105 SCIP_Bool enforce;
    1106 SCIP_Bool check;
    1107 SCIP_Bool propagate;
    1108 SCIP_Bool local;
    1109 SCIP_Bool modifiable;
    1110 SCIP_Bool dynamic;
    1111 SCIP_Bool removable;
    1112
    1113 assert(pipinput != NULL);
    1114
    1115 /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
    1116 * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
    1117 * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded because
    1118 * of loose variables with infinite best bound cannot be solved)
    1119 */
    1120 initial = TRUE;
    1121 separate = TRUE;
    1122 enforce = TRUE;
    1123 check = TRUE;
    1124 propagate = TRUE;
    1125 local = FALSE;
    1126 modifiable = FALSE;
    1127 dynamic = FALSE;
    1128 removable = FALSE;
    1129
    1130 /* read the objective coefficients */
    1131 SCIP_CALL( readPolynomial(scip, pipinput, name, &expr, &linear, &newsection) );
    1132 if( !hasError(pipinput) && expr != NULL )
    1133 {
    1134 SCIP_Real constant = SCIPgetConstantExprSum(expr);
    1135
    1136 /* always create a variable that represents the constant; otherwise, this might lead to numerical issues on
    1137 * instances with a relatively large constant, e.g., popdynm* instances
    1138 */
    1139 if( constant != 0.0 )
    1140 {
    1141 SCIP_VAR* objconst;
    1142 SCIP_CALL( SCIPcreateVarBasic(scip, &objconst, "objconst", 1.0, 1.0, constant, SCIP_VARTYPE_CONTINUOUS) );
    1143 SCIP_CALL( SCIPaddVar(scip, objconst) );
    1144 SCIP_CALL( SCIPreleaseVar(scip, &objconst) );
    1145
    1146 /* remove the constant of the sum expression */
    1147 SCIPsetConstantExprSum(expr, 0.0);
    1148 }
    1149
    1150 if( linear )
    1151 {
    1152 int i;
    1153
    1154 /* set objective coefficients of variables */
    1155 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
    1156 {
    1157 SCIP_EXPR* child;
    1158 SCIP_VAR* var;
    1159 SCIP_Real coef;
    1160
    1161 child = SCIPexprGetChildren(expr)[i];
    1162 assert(child != NULL);
    1163 assert(SCIPisExprVar(scip, child));
    1164
    1165 /* child has to be a variable expression, see SCIPcreateExprMonomial() */
    1166 var = SCIPgetVarExprVar(child);
    1167 assert(var != NULL);
    1168 coef = SCIPgetCoefsExprSum(expr)[i];
    1169
    1170 /* adjust the objective coefficient */
    1171 SCIP_CALL( SCIPchgVarObj(scip, var, SCIPvarGetObj(var) + coef) );
    1172 }
    1173 }
    1174 else /* insert dummy variable and constraint to represent the nonlinear objective */
    1175 {
    1176 SCIP_EXPR* nonlinobjvarexpr;
    1177 SCIP_VAR* nonlinobjvar;
    1178 SCIP_CONS* nonlinobjcons;
    1179 SCIP_Real lhs;
    1180 SCIP_Real rhs;
    1181
    1182 SCIP_CALL( SCIPcreateVar(scip, &nonlinobjvar, "nonlinobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
    1184 SCIP_CALL( SCIPaddVar(scip, nonlinobjvar) );
    1185
    1186 if ( pipinput->objsense == SCIP_OBJSENSE_MINIMIZE )
    1187 {
    1188 lhs = -SCIPinfinity(scip);
    1189 rhs = 0.0;
    1190 }
    1191 else
    1192 {
    1193 lhs = 0.0;
    1194 rhs = SCIPinfinity(scip);
    1195 }
    1196
    1197 /* add created objective variable */
    1198 SCIP_CALL( SCIPcreateExprVar(scip, &nonlinobjvarexpr, nonlinobjvar, NULL, NULL) );
    1199 SCIP_CALL( SCIPappendExprSumExpr(scip, expr, nonlinobjvarexpr, -1.0) );
    1200 SCIP_CALL( SCIPreleaseExpr(scip, &nonlinobjvarexpr) );
    1201
    1202 /* create nonlinear constraint */
    1203 SCIP_CALL( SCIPcreateConsNonlinear(scip, &nonlinobjcons, "nonlinobj", expr, lhs, rhs, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) );
    1204
    1205 SCIP_CALL( SCIPaddCons(scip, nonlinobjcons) );
    1206 SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent nonlinear objective: ", pipinput->linenumber, SCIPconsGetName(nonlinobjcons));
    1207 SCIPdebugPrintCons(scip, nonlinobjcons, NULL);
    1208
    1209 SCIP_CALL( SCIPreleaseCons(scip, &nonlinobjcons) );
    1210 SCIP_CALL( SCIPreleaseVar(scip, &nonlinobjvar) );
    1211 }
    1212 }
    1213
    1214 /* release expression */
    1215 if( expr != NULL )
    1216 {
    1217 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    1218 }
    1219
    1220 return SCIP_OKAY;
    1221}
    1222
    1223/** reads the constraints section */
    1224static
    1226 SCIP* scip, /**< SCIP data structure */
    1227 PIPINPUT* pipinput /**< PIP reading data */
    1228 )
    1229{
    1230 char name[PIP_MAX_LINELEN];
    1231 SCIP_EXPR* expr;
    1232 SCIP_CONS* cons = NULL;
    1233 SCIP_Bool linear;
    1234
    1235 PIPSENSE sense;
    1236 SCIP_Real sidevalue;
    1237 SCIP_Real lhs;
    1238 SCIP_Real rhs;
    1239 SCIP_Bool newsection;
    1240 SCIP_Bool initial;
    1242 SCIP_Bool enforce;
    1243 SCIP_Bool check;
    1244 SCIP_Bool propagate;
    1245 SCIP_Bool local;
    1246 SCIP_Bool modifiable;
    1247 SCIP_Bool dynamic;
    1248 SCIP_Bool removable;
    1249 int sidesign;
    1250
    1251 assert(pipinput != NULL);
    1252
    1253 /* read polynomial */
    1254 SCIP_CALL( readPolynomial(scip, pipinput, name, &expr, &linear, &newsection) );
    1255 if ( hasError(pipinput) )
    1256 return SCIP_READERROR;
    1257 if ( newsection )
    1258 {
    1259 if ( expr != NULL )
    1260 syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
    1261 return SCIP_OKAY;
    1262 }
    1263
    1264 /* read the constraint sense */
    1265 if ( !getNextToken(scip, pipinput) )
    1266 {
    1267 syntaxError(scip, pipinput, "expected constraint sense.");
    1268 return SCIP_READERROR;
    1269 }
    1270 if ( !isSense(pipinput, &sense) )
    1271 {
    1272 syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
    1273 return SCIP_READERROR;
    1274 }
    1275
    1276 /* read the right hand side */
    1277 sidesign = +1;
    1278 if ( !getNextToken(scip, pipinput) )
    1279 {
    1280 syntaxError(scip, pipinput, "missing right hand side");
    1281 return SCIP_READERROR;
    1282 }
    1283 if ( isSign(pipinput, &sidesign) )
    1284 {
    1285 if( !getNextToken(scip, pipinput) )
    1286 {
    1287 syntaxError(scip, pipinput, "missing value of right hand side");
    1288 return SCIP_READERROR;
    1289 }
    1290 }
    1291 if ( !isValue(scip, pipinput, &sidevalue) )
    1292 {
    1293 syntaxError(scip, pipinput, "expected value as right hand side");
    1294 return SCIP_READERROR;
    1295 }
    1296 sidevalue *= sidesign;
    1297
    1298 /* determine settings */
    1299 initial = pipinput->initialconss;
    1300 separate = TRUE;
    1301 enforce = TRUE;
    1302 check = TRUE;
    1303 propagate = TRUE;
    1304 local = FALSE;
    1305 modifiable = FALSE;
    1306 dynamic = pipinput->dynamicconss;
    1307 removable = pipinput->dynamicrows;
    1308
    1309 /* assign the left and right hand side, depending on the constraint sense */
    1310 switch ( sense ) /*lint !e530*/
    1311 {
    1312 case PIP_SENSE_GE:
    1313 lhs = sidevalue;
    1314 rhs = SCIPinfinity(scip);
    1315 break;
    1316 case PIP_SENSE_LE:
    1317 lhs = -SCIPinfinity(scip);
    1318 rhs = sidevalue;
    1319 break;
    1320 case PIP_SENSE_EQ:
    1321 lhs = sidevalue;
    1322 rhs = sidevalue;
    1323 break;
    1324 case PIP_SENSE_NOTHING:
    1325 default:
    1326 SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
    1327 return SCIP_INVALIDDATA;
    1328 }
    1329
    1330 /* linear constraint function */
    1331 if( linear )
    1332 {
    1333 SCIP_VAR** vars;
    1334 SCIP_Real* coefs;
    1335 SCIP_Real constant;
    1336 int nchildren;
    1337 int i;
    1338
    1339 nchildren = SCIPexprGetNChildren(expr);
    1340 constant = SCIPgetConstantExprSum(expr);
    1341 coefs = SCIPgetCoefsExprSum(expr);
    1342
    1343 /* allocate memory to store variables */
    1344 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nchildren) );
    1345
    1346 /* collect variables */
    1347 for( i = 0; i < nchildren; ++i )
    1348 {
    1349 SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
    1350 assert(child != NULL);
    1351 assert(SCIPisExprVar(scip, child));
    1352
    1353 vars[i] = SCIPgetVarExprVar(child);
    1354 assert(vars[i] != NULL);
    1355 }
    1356
    1357 /* adjust lhs and rhs */
    1358 if( !SCIPisInfinity(scip, -lhs) )
    1359 lhs -= constant;
    1360 if( !SCIPisInfinity(scip, rhs) )
    1361 rhs -= constant;
    1362
    1363 /* create linear constraint */
    1364 SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, nchildren, vars, coefs, lhs, rhs, initial, separate, enforce,
    1365 check, propagate, local, modifiable, dynamic, removable, FALSE) );
    1366
    1367 /* free memory */
    1368 SCIPfreeBufferArray(scip, &vars);
    1369 }
    1370 else /* nonlinear constraint function */
    1371 {
    1372 SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, expr, lhs, rhs, initial, separate, enforce, check, propagate,
    1373 local, modifiable, dynamic, removable) );
    1374 }
    1375
    1376 /* add and release constraint */
    1377 assert(cons != NULL);
    1378 SCIP_CALL( SCIPaddCons(scip, cons) );
    1379 SCIPdebugMsg(scip, "(line %d) created constraint: ", pipinput->linenumber);
    1381 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    1382
    1383 /* release expression */
    1384 if( expr != NULL )
    1385 {
    1386 SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
    1387 }
    1388
    1389 return SCIP_OKAY;
    1390}
    1391
    1392/** reads the bounds section */
    1393static
    1395 SCIP* scip, /**< SCIP data structure */
    1396 PIPINPUT* pipinput /**< PIP reading data */
    1397 )
    1398{
    1399 assert(pipinput != NULL);
    1400
    1401 while( getNextToken(scip, pipinput) )
    1402 {
    1403 SCIP_VAR* var;
    1404 SCIP_Real value;
    1405 SCIP_Real lb;
    1406 SCIP_Real ub;
    1407 int sign;
    1408 SCIP_Bool hassign;
    1409 PIPSENSE leftsense;
    1410
    1411 /* check if we reached a new section */
    1412 if( isNewSection(scip, pipinput) )
    1413 return SCIP_OKAY;
    1414
    1415 /* default bounds are [0,+inf] */
    1416 lb = 0.0;
    1417 ub = SCIPinfinity(scip);
    1418 leftsense = PIP_SENSE_NOTHING;
    1419
    1420 /* check if the first token is a sign */
    1421 sign = +1;
    1422 hassign = isSign(pipinput, &sign);
    1423 if( hassign && !getNextToken(scip, pipinput) )
    1424 {
    1425 syntaxError(scip, pipinput, "expected value");
    1426 return SCIP_OKAY;
    1427 }
    1428
    1429 /* the first token must be either a value or a variable name */
    1430 if( isValue(scip, pipinput, &value) )
    1431 {
    1432 /* first token is a value: the second token must be a sense */
    1433 if( !getNextToken(scip, pipinput) || !isSense(pipinput, &leftsense) )
    1434 {
    1435 syntaxError(scip, pipinput, "expected bound sense '<=', '=', or '>='");
    1436 return SCIP_OKAY;
    1437 }
    1438
    1439 /* update the bound corresponding to the sense */
    1440 switch( leftsense )
    1441 {
    1442 case PIP_SENSE_GE:
    1443 ub = sign * value;
    1444 break;
    1445 case PIP_SENSE_LE:
    1446 lb = sign * value;
    1447 break;
    1448 case PIP_SENSE_EQ:
    1449 lb = sign * value;
    1450 ub = sign * value;
    1451 break;
    1452 case PIP_SENSE_NOTHING:
    1453 default:
    1454 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    1455 return SCIP_INVALIDDATA;
    1456 }
    1457 }
    1458 else if( hassign )
    1459 {
    1460 syntaxError(scip, pipinput, "expected value");
    1461 return SCIP_OKAY;
    1462 }
    1463 else
    1464 pushToken(pipinput);
    1465
    1466 /* the next token must be a variable name */
    1467 if( !getNextToken(scip, pipinput) )
    1468 {
    1469 syntaxError(scip, pipinput, "expected variable name");
    1470 return SCIP_OKAY;
    1471 }
    1472 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
    1473
    1474 /* the next token might be another sense, or the word "free" */
    1475 if( getNextToken(scip, pipinput) )
    1476 {
    1477 PIPSENSE rightsense;
    1478
    1479 if( isSense(pipinput, &rightsense) )
    1480 {
    1481 /* check, if the senses fit */
    1482 if( leftsense == PIP_SENSE_NOTHING
    1483 || (leftsense == PIP_SENSE_LE && rightsense == PIP_SENSE_LE)
    1484 || (leftsense == PIP_SENSE_GE && rightsense == PIP_SENSE_GE) )
    1485 {
    1486 if( !getNextToken(scip, pipinput) )
    1487 {
    1488 syntaxError(scip, pipinput, "expected value or sign");
    1489 return SCIP_OKAY;
    1490 }
    1491
    1492 /* check if the next token is a sign */
    1493 sign = +1;
    1494 hassign = isSign(pipinput, &sign);
    1495 if( hassign && !getNextToken(scip, pipinput) )
    1496 {
    1497 syntaxError(scip, pipinput, "expected value");
    1498 return SCIP_OKAY;
    1499 }
    1500
    1501 /* the next token must be a value */
    1502 if( !isValue(scip, pipinput, &value) )
    1503 {
    1504 syntaxError(scip, pipinput, "expected value");
    1505 return SCIP_OKAY;
    1506 }
    1507
    1508 /* update the bound corresponding to the sense */
    1509 switch( rightsense )
    1510 {
    1511 case PIP_SENSE_GE:
    1512 lb = sign * value;
    1513 break;
    1514 case PIP_SENSE_LE:
    1515 ub = sign * value;
    1516 break;
    1517 case PIP_SENSE_EQ:
    1518 lb = sign * value;
    1519 ub = sign * value;
    1520 break;
    1521 case PIP_SENSE_NOTHING:
    1522 default:
    1523 SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
    1524 return SCIP_INVALIDDATA;
    1525 }
    1526 }
    1527 else
    1528 {
    1529 syntaxError(scip, pipinput, "the two bound senses do not fit");
    1530 return SCIP_OKAY;
    1531 }
    1532 }
    1533 else if( SCIPstrcasecmp(pipinput->token, "FREE") == 0 )
    1534 {
    1535 if( leftsense != PIP_SENSE_NOTHING )
    1536 {
    1537 syntaxError(scip, pipinput, "variable with bound is marked as 'free'");
    1538 return SCIP_OKAY;
    1539 }
    1540 lb = -SCIPinfinity(scip);
    1541 ub = SCIPinfinity(scip);
    1542 }
    1543 else
    1544 {
    1545 /* the token was no sense: push it back to the token stack */
    1546 pushToken(pipinput);
    1547 }
    1548 }
    1549
    1550 /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
    1551 if ( lb != 0.0 )
    1552 SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
    1553 /*lint --e{777}*/
    1554 if ( ub != SCIPinfinity(scip) )
    1555 SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
    1556 SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", pipinput->linenumber, SCIPvarGetName(var),
    1558 }
    1559
    1560 return SCIP_OKAY;
    1561}
    1562
    1563/** reads the generals section */
    1564static
    1566 SCIP* scip, /**< SCIP data structure */
    1567 PIPINPUT* pipinput /**< PIP reading data */
    1568 )
    1569{
    1570 assert(pipinput != NULL);
    1571
    1572 while( getNextToken(scip, pipinput) )
    1573 {
    1574 SCIP_VAR* var;
    1575 SCIP_Bool created;
    1576 SCIP_Bool infeasible;
    1577
    1578 /* check if we reached a new section */
    1579 if( isNewSection(scip, pipinput) )
    1580 return SCIP_OKAY;
    1581
    1582 /* the token must be the name of an existing variable */
    1583 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
    1584 if( created )
    1585 {
    1586 syntaxError(scip, pipinput, "unknown variable in generals section");
    1587 return SCIP_OKAY;
    1588 }
    1589
    1590 /* mark the variable to be integral */
    1591 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
    1592 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    1593 }
    1594
    1595 return SCIP_OKAY;
    1596}
    1597
    1598/** reads the binaries section */
    1599static
    1601 SCIP* scip, /**< SCIP data structure */
    1602 PIPINPUT* pipinput /**< PIP reading data */
    1603 )
    1604{
    1605 assert(pipinput != NULL);
    1606
    1607 while( getNextToken(scip, pipinput) )
    1608 {
    1609 SCIP_VAR* var;
    1610 SCIP_Bool created;
    1611 SCIP_Bool infeasible;
    1612
    1613 /* check if we reached a new section */
    1614 if( isNewSection(scip, pipinput) )
    1615 return SCIP_OKAY;
    1616
    1617 /* the token must be the name of an existing variable */
    1618 SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
    1619 if( created )
    1620 {
    1621 syntaxError(scip, pipinput, "unknown variable in binaries section");
    1622 return SCIP_OKAY;
    1623 }
    1624
    1625 /* mark the variable to be binary and change its bounds appropriately */
    1626 if( SCIPvarGetLbGlobal(var) < 0.0 )
    1627 {
    1628 SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
    1629 }
    1630 if( SCIPvarGetUbGlobal(var) > 1.0 )
    1631 {
    1632 SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
    1633 }
    1634 SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
    1635 /* don't assert feasibility here because the presolver will and should detect a infeasibility */
    1636 }
    1637
    1638 return SCIP_OKAY;
    1639}
    1640
    1641/** reads a PIP file
    1642 */
    1643static
    1645 SCIP* scip, /**< SCIP data structure */
    1646 PIPINPUT* pipinput, /**< PIP reading data */
    1647 const char* filename /**< name of the input file */
    1648 )
    1649{
    1650 assert(pipinput != NULL);
    1651
    1652 /* open file */
    1653 pipinput->file = SCIPfopen(filename, "r");
    1654 if( pipinput->file == NULL )
    1655 {
    1656 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    1657 SCIPprintSysError(filename);
    1658 return SCIP_NOFILE;
    1659 }
    1660
    1661 /* create problem */
    1662 SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
    1663
    1664 /* parse the file */
    1665 pipinput->section = PIP_START;
    1666 while( pipinput->section != PIP_END && !hasError(pipinput) )
    1667 {
    1668 switch( pipinput->section )
    1669 {
    1670 case PIP_START:
    1671 SCIP_CALL( readStart(scip, pipinput) );
    1672 break;
    1673
    1674 case PIP_OBJECTIVE:
    1675 SCIP_CALL( readObjective(scip, pipinput) );
    1676 break;
    1677
    1678 case PIP_CONSTRAINTS:
    1679 SCIP_CALL( readConstraints(scip, pipinput) );
    1680 break;
    1681
    1682 case PIP_BOUNDS:
    1683 SCIP_CALL( readBounds(scip, pipinput) );
    1684 break;
    1685
    1686 case PIP_GENERALS:
    1687 SCIP_CALL( readGenerals(scip, pipinput) );
    1688 break;
    1689
    1690 case PIP_BINARIES:
    1691 SCIP_CALL( readBinaries(scip, pipinput) );
    1692 break;
    1693
    1694 case PIP_END: /* this is already handled in the while() loop */
    1695 default:
    1696 SCIPerrorMessage("invalid PIP file section <%d>\n", pipinput->section);
    1697 return SCIP_INVALIDDATA;
    1698 }
    1699 }
    1700
    1701 /* close file */
    1702 SCIPfclose(pipinput->file);
    1703
    1704 return SCIP_OKAY;
    1705}
    1706
    1707
    1708/*
    1709 * Local methods (for writing)
    1710 */
    1711
    1712/** hash key retrieval function for variables */
    1713static
    1715{ /*lint --e{715}*/
    1716 return elem;
    1717}
    1718
    1719/** returns TRUE iff the indices of both variables are equal */
    1720static
    1722{ /*lint --e{715}*/
    1723 if ( key1 == key2 )
    1724 return TRUE;
    1725 return FALSE;
    1726}
    1727
    1728/** returns the hash value of the key */
    1729static
    1731{ /*lint --e{715}*/
    1732 assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
    1733 return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
    1734}
    1735
    1736/** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
    1737static
    1739 SCIP* scip, /**< SCIP data structure */
    1740 SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
    1741 SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
    1742 int* nvars, /**< pointer to number of variables and values in vars and vals array */
    1743 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
    1744 SCIP_Bool transformed /**< transformed constraint? */
    1745 )
    1746{
    1747 int requiredsize;
    1748 int v;
    1749
    1750 assert(scip != NULL);
    1751 assert(vars != NULL);
    1752 assert(scalars != NULL);
    1753 assert(nvars != NULL);
    1754 assert(*vars != NULL || *nvars == 0);
    1755 assert(*scalars != NULL || *nvars == 0);
    1756 assert(constant != NULL);
    1757
    1758 if( transformed )
    1759 {
    1760 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize) );
    1761
    1762 if( requiredsize > *nvars )
    1763 {
    1764 SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
    1765 SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
    1766
    1767 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize) );
    1768 }
    1769 assert( requiredsize == *nvars );
    1770 }
    1771 else
    1772 {
    1773 if( *nvars > 0 && ( *vars == NULL || *scalars == NULL ) ) /*lint !e774 !e845*/
    1774 {
    1775 SCIPerrorMessage("Null pointer in PIP reader\n"); /* should not happen */
    1776 SCIPABORT();
    1777 return SCIP_INVALIDDATA; /*lint !e527*/
    1778 }
    1779
    1780 for( v = 0; v < *nvars; ++v )
    1781 {
    1782 SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
    1783
    1784 /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
    1785 * make sure we get the original variable in that case
    1786 */
    1787 if( SCIPvarGetStatus((*vars)[v]) == SCIP_VARSTATUS_NEGATED )
    1788 {
    1789 (*vars)[v] = SCIPvarGetNegatedVar((*vars)[v]);
    1790 *constant += (*scalars)[v];
    1791 (*scalars)[v] *= -1.0;
    1792 }
    1793 }
    1794 }
    1795 return SCIP_OKAY;
    1796}
    1797
    1798/** checks whether a given expression is a signomial
    1799 *
    1800 * assumes simplified expression
    1801 */
    1802static
    1804 SCIP* scip, /**< SCIP data structure */
    1805 SCIP_EXPR* expr /**< expression */
    1806 )
    1807{
    1808 assert(scip != NULL);
    1809 assert(expr != NULL);
    1810
    1811 if( SCIPisExprVar(scip, expr) || SCIPisExprValue(scip, expr) )
    1812 return TRUE;
    1813
    1814 if( SCIPisExprPower(scip, expr) && SCIPisExprVar(scip, SCIPexprGetChildren(expr)[0]) )
    1815 return TRUE;
    1816
    1817 if( SCIPisExprProduct(scip, expr) )
    1818 {
    1819 SCIP_EXPR* child;
    1820 int c;
    1821
    1822 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    1823 {
    1824 child = SCIPexprGetChildren(expr)[c];
    1825
    1826 if( SCIPisExprVar(scip, child) )
    1827 continue;
    1828
    1829 if( SCIPisExprPower(scip, child) && SCIPisExprVar(scip, SCIPexprGetChildren(child)[0]) )
    1830 continue;
    1831
    1832 /* the pip format does not allow constants here */
    1833
    1834 return FALSE;
    1835 }
    1836
    1837 return TRUE;
    1838 }
    1839
    1840 return FALSE;
    1841}
    1842
    1843/** checks whether a given expression is a sum of signomials (i.e., like a polynomial, but negative and fractional exponents allowed)
    1844 *
    1845 * assumes simplified expression;
    1846 * does not check whether variables in powers with fractional exponent are nonnegative;
    1847 * does not check whether variables in powers with negative exponent are bounded away from zero (the format specification does not require that, too)
    1848 */
    1849static
    1851 SCIP* scip, /**< SCIP data structure */
    1852 SCIP_EXPR* expr /**< expression */
    1853 )
    1854{
    1855 int c;
    1856
    1857 assert(scip != NULL);
    1858 assert(expr != NULL);
    1859
    1860 if( !SCIPisExprSum(scip, expr) )
    1861 return isExprSignomial(scip, expr);
    1862
    1863 /* check whether every term of sum is signomial */
    1864 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    1865 if( !isExprSignomial(scip, SCIPexprGetChildren(expr)[c]) )
    1866 return FALSE;
    1867
    1868 return TRUE;
    1869}
    1870
    1871/** clears the given line buffer */
    1872static
    1874 char* linebuffer, /**< line */
    1875 int* linecnt /**< number of characters in line */
    1876 )
    1877{
    1878 assert( linebuffer != NULL );
    1879 assert( linecnt != NULL );
    1880
    1881 (*linecnt) = 0;
    1882 linebuffer[0] = '\0';
    1883}
    1884
    1885/** ends the given line with '\\0' and prints it to the given file stream */
    1886static
    1888 SCIP* scip, /**< SCIP data structure */
    1889 FILE* file, /**< output file (or NULL for standard output) */
    1890 char* linebuffer, /**< line */
    1891 int* linecnt /**< number of characters in line */
    1892 )
    1893{
    1894 assert( scip != NULL );
    1895 assert( linebuffer != NULL );
    1896 assert( linecnt != NULL );
    1897 assert( 0 <= *linecnt && *linecnt < PIP_MAX_PRINTLEN );
    1898
    1899 if( (*linecnt) > 0 )
    1900 {
    1901 linebuffer[(*linecnt)] = '\0';
    1902 SCIPinfoMessage(scip, file, "%s\n", linebuffer);
    1903 clearLine(linebuffer, linecnt);
    1904 }
    1905}
    1906
    1907/** appends extension to line and prints it to the give file stream if the
    1908 * line exceeded the length given in the define PIP_PRINTLEN */
    1909static
    1911 SCIP* scip, /**< SCIP data structure */
    1912 FILE* file, /**< output file (or NULL for standard output) */
    1913 char* linebuffer, /**< line */
    1914 int* linecnt, /**< number of characters in line */
    1915 const char* extension /**< string to extent the line */
    1916 )
    1917{
    1918 assert( scip != NULL );
    1919 assert( linebuffer != NULL );
    1920 assert( linecnt != NULL );
    1921 assert( extension != NULL );
    1922 assert( strlen(linebuffer) + strlen(extension) < PIP_MAX_PRINTLEN );
    1923
    1924 /* NOTE: avoid
    1925 * sprintf(linebuffer, "%s%s", linebuffer, extension);
    1926 * because of overlapping memory areas in memcpy used in sprintf.
    1927 */
    1928 (void) strncat(linebuffer, extension, PIP_MAX_PRINTLEN - strlen(linebuffer));
    1929
    1930 (*linecnt) += (int) strlen(extension);
    1931
    1932 SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
    1933
    1934 if( (*linecnt) > PIP_PRINTLEN )
    1935 endLine(scip, file, linebuffer, linecnt);
    1936}
    1937
    1938
    1939/** print linear or quadratic row in PIP format to file stream */
    1940static
    1942 SCIP* scip, /**< SCIP data structure */
    1943 FILE* file, /**< output file (or NULL for standard output) */
    1944 const char* rowname, /**< row name */
    1945 const char* rownameextension, /**< row name extension */
    1946 const char* type, /**< row type ("=", "<=", or ">=") */
    1947 SCIP_VAR** linvars, /**< array of linear variables */
    1948 SCIP_Real* linvals, /**< array of linear coefficient values */
    1949 int nlinvars, /**< number of linear variables */
    1950 SCIP_EXPR* quadexpr, /**< quadratic expression */
    1951 SCIP_Real rhs, /**< right hand side */
    1952 SCIP_Bool transformed /**< transformed constraint? */
    1953 )
    1954{
    1955 int v;
    1956 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
    1957 int linecnt;
    1958
    1959 char varname[PIP_MAX_NAMELEN];
    1960 char varname2[PIP_MAX_NAMELEN];
    1961 char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
    1962 char buffer[PIP_MAX_PRINTLEN];
    1963
    1964 assert( scip != NULL );
    1965 assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
    1966 assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
    1967
    1968 clearLine(linebuffer, &linecnt);
    1969
    1970 /* start each line with a space */
    1971 appendLine(scip, file, linebuffer, &linecnt, " ");
    1972
    1973 /* print row name */
    1974 if ( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
    1975 {
    1976 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
    1977 appendLine(scip, file, linebuffer, &linecnt, consname);
    1978 }
    1979
    1980 /* print coefficients */
    1981 for( v = 0; v < nlinvars; ++v )
    1982 {
    1983 SCIP_VAR* var;
    1984
    1985 assert(linvars != NULL); /* for lint */
    1986 assert(linvals != NULL);
    1987
    1988 var = linvars[v];
    1989 assert( var != NULL );
    1990
    1991 /* we start a new line; therefore we tab this line */
    1992 if ( linecnt == 0 )
    1993 appendLine(scip, file, linebuffer, &linecnt, " ");
    1994
    1995 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    1996 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
    1997
    1998 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1999 }
    2000
    2001 /* print quadratic part */
    2002 if( quadexpr != NULL )
    2003 {
    2004 SCIP_EXPR** linexprs;
    2005 SCIP_VAR** activevars;
    2006 SCIP_Real* activevals;
    2007 SCIP_Real* lincoefs;
    2008 SCIP_Real constant;
    2009 SCIP_Real activeconstant = 0.0;
    2010 int nbilinexprterms;
    2011 int nactivevars;
    2012 int nquadexprs;
    2013 int nlinexprs;
    2014
    2015 /* get data from the quadratic expression */
    2016 SCIPexprGetQuadraticData(quadexpr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprterms,
    2017 NULL, NULL);
    2018
    2019 /* allocate memory to store active linear variables */
    2020 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nlinexprs) );
    2021 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, lincoefs, nlinexprs) );
    2022 nactivevars = nlinexprs;
    2023
    2024 for( v = 0; v < nlinexprs; ++v )
    2025 {
    2026 assert(linexprs != NULL && linexprs[v] != NULL);
    2027 assert(SCIPisExprVar(scip, linexprs[v]));
    2028
    2029 activevars[v] = SCIPgetVarExprVar(linexprs[v]);
    2030 assert(activevars[v] != NULL);
    2031 }
    2032
    2033 /* get active variables */
    2034 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    2035 constant += activeconstant;
    2036
    2037 /* print linear coefficients of linear variables */
    2038 for( v = 0; v < nactivevars; ++v )
    2039 {
    2040 SCIP_VAR* var;
    2041
    2042 assert(activevars != NULL); /* for lint */
    2043 assert(activevals != NULL);
    2044
    2045 var = activevars[v];
    2046 assert( var != NULL );
    2047
    2048 /* we start a new line; therefore we tab this line */
    2049 if( linecnt == 0 )
    2050 appendLine(scip, file, linebuffer, &linecnt, " ");
    2051
    2052 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    2053 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", activevals[v], varname);
    2054
    2055 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2056 }
    2057
    2058 /* free memory for active linear variables */
    2059 SCIPfreeBufferArray(scip, &activevals);
    2060 SCIPfreeBufferArray(scip, &activevars);
    2061
    2062 /* adjust rhs if there is a constant */
    2063 if( constant != 0.0 && !SCIPisInfinity(scip, rhs) )
    2064 rhs -= constant;
    2065
    2066 /* print linear coefficients of quadratic variables */
    2067 for( v = 0; v < nquadexprs; ++v )
    2068 {
    2069 SCIP_EXPR* expr;
    2070 SCIP_VAR* var;
    2071 SCIP_Real lincoef;
    2072
    2073 /* get linear coefficient and variable of quadratic term */
    2074 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, &lincoef, NULL, NULL, NULL, NULL);
    2075 assert(expr != NULL);
    2076 assert(SCIPisExprVar(scip, expr));
    2077
    2078 var = SCIPgetVarExprVar(expr);
    2079 assert(var != NULL);
    2080
    2081 if( lincoef == 0.0 )
    2082 continue;
    2083
    2084 /* we start a new line; therefore we tab this line */
    2085 if( linecnt == 0 )
    2086 appendLine(scip, file, linebuffer, &linecnt, " ");
    2087
    2088 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    2089 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", lincoef, varname);
    2090
    2091 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2092 }
    2093
    2094 /* print square terms */
    2095 for( v = 0; v < nquadexprs; ++v )
    2096 {
    2097 SCIP_EXPR* expr;
    2098 SCIP_VAR* var;
    2099 SCIP_Real sqrcoef;
    2100
    2101 /* get square coefficient and variable of quadratic term */
    2102 SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, NULL, &sqrcoef, NULL, NULL, NULL);
    2103 assert(expr != NULL);
    2104 assert(SCIPisExprVar(scip, expr));
    2105
    2106 var = SCIPgetVarExprVar(expr);
    2107 assert(var != NULL);
    2108
    2109 if( sqrcoef == 0.0 )
    2110 continue;
    2111
    2112 /* we start a new line; therefore we tab this line */
    2113 if( linecnt == 0 )
    2114 appendLine(scip, file, linebuffer, &linecnt, " ");
    2115
    2116 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    2117 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^2", sqrcoef, varname);
    2118
    2119 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2120 }
    2121
    2122 /* print bilinear terms */
    2123 for( v = 0; v < nbilinexprterms; ++v )
    2124 {
    2125 SCIP_EXPR* expr1;
    2126 SCIP_EXPR* expr2;
    2127 SCIP_VAR* var1;
    2128 SCIP_VAR* var2;
    2129 SCIP_Real bilincoef;
    2130
    2131 /* get coefficient and variables of bilinear */
    2132 SCIPexprGetQuadraticBilinTerm(quadexpr, v, &expr1, &expr2, &bilincoef, NULL, NULL);
    2133 assert(expr1 != NULL);
    2134 assert(SCIPisExprVar(scip, expr1));
    2135 assert(expr2 != NULL);
    2136 assert(SCIPisExprVar(scip, expr2));
    2137
    2138 var1 = SCIPgetVarExprVar(expr1);
    2139 assert(var1 != NULL);
    2140 var2 = SCIPgetVarExprVar(expr2);
    2141 assert(var2 != NULL);
    2142
    2143 /* we start a new line; therefore we tab this line */
    2144 if( linecnt == 0 )
    2145 appendLine(scip, file, linebuffer, &linecnt, " ");
    2146
    2147 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var1));
    2148 (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var2));
    2149 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s * %s", bilincoef, varname, varname2);
    2150
    2151 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2152 }
    2153 }
    2154
    2155 /* print right hand side */
    2156 if( SCIPisZero(scip, rhs) )
    2157 rhs = 0.0;
    2158
    2159 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
    2160
    2161 /* we start a new line; therefore we tab this line */
    2162 if (linecnt == 0 )
    2163 appendLine(scip, file, linebuffer, &linecnt, " ");
    2164 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2165
    2166 endLine(scip, file, linebuffer, &linecnt);
    2167
    2168 return SCIP_OKAY;
    2169}
    2170
    2171/** print signomial in PIP format to file stream */
    2172static
    2174 SCIP* scip, /**< SCIP data structure */
    2175 FILE* file, /**< output file (or NULL for standard output) */
    2176 char* linebuffer, /**< line buffer to append to */
    2177 int* linecnt, /**< count on line buffer use */
    2178 SCIP_EXPR* expr, /**< sigomial expression */
    2179 SCIP_Real coef, /**< coefficient */
    2180 SCIP_Bool needsign /**< whether a sign needs to be ensured */
    2181 )
    2182{
    2183 char buffer[PIP_MAX_PRINTLEN];
    2184 SCIP_EXPR* child;
    2185 int c;
    2186
    2187 assert(isExprSignomial(scip, expr));
    2188
    2189 if( SCIPisExprProduct(scip, expr) )
    2190 coef *= SCIPgetCoefExprProduct(expr);
    2191
    2192 if( SCIPisExprValue(scip, expr) )
    2193 coef *= SCIPgetValueExprValue(expr);
    2194
    2195 if( REALABS(coef) != 1.0 )
    2196 {
    2197 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, needsign ? " %+.15g " : " %.15g ", coef);
    2198 appendLine(scip, file, linebuffer, linecnt, buffer);
    2199 }
    2200 else if( coef == 1.0 && needsign )
    2201 {
    2202 appendLine(scip, file, linebuffer, linecnt, " + ");
    2203 }
    2204 else if( coef == -1.0 )
    2205 {
    2206 appendLine(scip, file, linebuffer, linecnt, " - ");
    2207 }
    2208 else
    2209 {
    2210 appendLine(scip, file, linebuffer, linecnt, " ");
    2211 }
    2212
    2213 if( SCIPisExprVar(scip, expr) )
    2214 {
    2215 appendLine(scip, file, linebuffer, linecnt, SCIPvarGetName(SCIPgetVarExprVar(expr)));
    2216 return;
    2217 }
    2218
    2219 if( SCIPisExprValue(scip, expr) )
    2220 {
    2221 if( REALABS(coef) == 1.0 )
    2222 {
    2223 /* in this case, we will have printed only a sign or space above, so print also a 1.0 */
    2224 appendLine(scip, file, linebuffer, linecnt, "1.0");
    2225 }
    2226 return;
    2227 }
    2228
    2229 if( SCIPisExprPower(scip, expr) )
    2230 {
    2231 assert(SCIPisExprVar(scip, SCIPexprGetChildren(expr)[0]));
    2232
    2234 appendLine(scip, file, linebuffer, linecnt, buffer);
    2235
    2236 return;
    2237 }
    2238
    2239 assert(SCIPisExprProduct(scip, expr));
    2240 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    2241 {
    2242 child = SCIPexprGetChildren(expr)[c];
    2243
    2244 if( c > 0 )
    2245 appendLine(scip, file, linebuffer, linecnt, " ");
    2246
    2247 if( SCIPisExprVar(scip, child) )
    2248 {
    2249 appendLine(scip, file, linebuffer, linecnt, SCIPvarGetName(SCIPgetVarExprVar(child)));
    2250 continue;
    2251 }
    2252
    2253 assert(SCIPisExprPower(scip, child));
    2254 assert(SCIPisExprVar(scip, SCIPexprGetChildren(child)[0]));
    2255
    2257 appendLine(scip, file, linebuffer, linecnt, buffer);
    2258 }
    2259}
    2260
    2261/** print polynomial row in PIP format to file stream */
    2262static
    2264 SCIP* scip, /**< SCIP data structure */
    2265 FILE* file, /**< output file (or NULL for standard output) */
    2266 const char* rowname, /**< row name */
    2267 const char* rownameextension, /**< row name extension */
    2268 const char* type, /**< row type ("=", "<=", or ">=") */
    2269 SCIP_EXPR* expr, /**< polynomial expression */
    2270 SCIP_Real rhs /**< right hand side */
    2271 )
    2272{
    2273 char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
    2274 char buffer[PIP_MAX_PRINTLEN];
    2275 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
    2276 int linecnt;
    2277
    2278 assert(scip != NULL);
    2279 assert(strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0);
    2280 assert(expr != NULL);
    2281
    2282 clearLine(linebuffer, &linecnt);
    2283
    2284 /* start each line with a space */
    2285 appendLine(scip, file, linebuffer, &linecnt, " ");
    2286
    2287 /* print row name */
    2288 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
    2289 {
    2290 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
    2291 appendLine(scip, file, linebuffer, &linecnt, consname);
    2292 }
    2293
    2294 if( SCIPisExprSum(scip, expr) )
    2295 {
    2296 int c;
    2297 SCIP_Bool needsign = FALSE;
    2298
    2299 if( SCIPgetConstantExprSum(expr) != 0.0 )
    2300 {
    2301 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", SCIPgetConstantExprSum(expr));
    2302 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2303
    2304 needsign = TRUE;
    2305 }
    2306
    2307 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
    2308 {
    2309 printSignomial(scip, file, linebuffer, &linecnt, SCIPexprGetChildren(expr)[c], SCIPgetCoefsExprSum(expr)[c], needsign);
    2310 needsign = TRUE;
    2311 }
    2312 }
    2313 else
    2314 {
    2315 printSignomial(scip, file, linebuffer, &linecnt, expr, 1.0, FALSE);
    2316 }
    2317
    2318 /* print right hand side */
    2319 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
    2320
    2321 /* we start a new line; therefore we tab this line */
    2322 if( linecnt == 0 )
    2323 appendLine(scip, file, linebuffer, &linecnt, " ");
    2324 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2325
    2326 endLine(scip, file, linebuffer, &linecnt);
    2327}
    2328
    2329/** print "and" constraint as row in PIP format to file stream */
    2330static
    2332 SCIP* scip, /**< SCIP data structure */
    2333 FILE* file, /**< output file (or NULL for standard output) */
    2334 const char* rowname, /**< row name */
    2335 SCIP_CONS* cons /**< "and" constraint */
    2336 )
    2337{
    2338 char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
    2339 int linecnt;
    2340 int i;
    2341
    2342 assert(scip != NULL);
    2343 assert(rowname != NULL);
    2344 assert(cons != NULL);
    2345
    2346 clearLine(linebuffer, &linecnt);
    2347
    2348 /* start each line with a space */
    2349 appendLine(scip, file, linebuffer, &linecnt, " ");
    2350
    2351 /* print row name */
    2352 if( strlen(rowname) > 0 )
    2353 {
    2354 appendLine(scip, file, linebuffer, &linecnt, rowname);
    2355 appendLine(scip, file, linebuffer, &linecnt, ":");
    2356 }
    2357
    2358 for( i = 0; i < SCIPgetNVarsAnd(scip, cons); ++i )
    2359 {
    2360 appendLine(scip, file, linebuffer, &linecnt, " ");
    2361 appendLine(scip, file, linebuffer, &linecnt, SCIPvarGetName(SCIPgetVarsAnd(scip, cons)[i]));
    2362 }
    2363
    2364 appendLine(scip, file, linebuffer, &linecnt, " - ");
    2365 appendLine(scip, file, linebuffer, &linecnt, SCIPvarGetName(SCIPgetResultantAnd(scip, cons)));
    2366
    2367 /* we start a new line; therefore we tab this line */
    2368 if( linecnt == 0 )
    2369 appendLine(scip, file, linebuffer, &linecnt, " ");
    2370
    2371 /* print right hand side */
    2372 appendLine(scip, file, linebuffer, &linecnt, " = 0");
    2373
    2374 endLine(scip, file, linebuffer, &linecnt);
    2375}
    2376
    2377/** prints given (linear or) quadratic constraint information in LP format to file stream */
    2378static
    2380 SCIP* scip, /**< SCIP data structure */
    2381 FILE* file, /**< output file (or NULL for standard output) */
    2382 const char* rowname, /**< name of the row */
    2383 SCIP_VAR** linvars, /**< array of linear variables */
    2384 SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
    2385 int nlinvars, /**< number of linear variables */
    2386 SCIP_EXPR* quadexpr, /**< quadratic expression (or NULL if nlinvars > 0) */
    2387 SCIP_Real lhs, /**< left hand side */
    2388 SCIP_Real rhs, /**< right hand side */
    2389 SCIP_Bool transformed /**< transformed constraint? */
    2390 )
    2391{
    2392 int v;
    2393 SCIP_VAR** activevars = NULL;
    2394 SCIP_Real* activevals = NULL;
    2395 int nactivevars;
    2396 SCIP_Real activeconstant = 0.0;
    2397
    2398 assert( scip != NULL );
    2399 assert( rowname != NULL );
    2400
    2401 assert( nlinvars == 0 || linvars != NULL );
    2402 assert( quadexpr == NULL || nlinvars == 0);
    2403 assert( lhs <= rhs );
    2404
    2405 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    2406 return SCIP_OKAY;
    2407
    2408 nactivevars = nlinvars;
    2409 if( nlinvars > 0 )
    2410 {
    2411 /* duplicate variable and value array */
    2412 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
    2413 if( linvals != NULL )
    2414 {
    2415 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
    2416 }
    2417 else
    2418 {
    2419 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
    2420
    2421 for( v = 0; v < nactivevars; ++v )
    2422 activevals[v] = 1.0;
    2423 }
    2424
    2425 /* retransform given variables to active variables */
    2426 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    2427 }
    2428
    2429 /* print row(s) in LP format */
    2430 if( SCIPisEQ(scip, lhs, rhs) )
    2431 {
    2432 assert( !SCIPisInfinity(scip, rhs) );
    2433
    2434 /* equal constraint */
    2435 SCIP_CALL( printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars, quadexpr,
    2436 rhs - activeconstant, transformed) );
    2437 }
    2438 else
    2439 {
    2440 if( !SCIPisInfinity(scip, -lhs) )
    2441 {
    2442 /* print inequality ">=" */
    2443 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", activevars,
    2444 activevals, nactivevars, quadexpr, lhs - activeconstant, transformed) );
    2445 }
    2446 if( !SCIPisInfinity(scip, rhs) )
    2447 {
    2448 /* print inequality "<=" */
    2449 SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", activevars,
    2450 activevals, nactivevars, quadexpr, rhs - activeconstant, transformed) );
    2451 }
    2452 }
    2453
    2454 if( nlinvars > 0 )
    2455 {
    2456 /* free buffer arrays */
    2457 SCIPfreeBufferArray(scip, &activevars);
    2458 SCIPfreeBufferArray(scip, &activevals);
    2459 }
    2460
    2461 return SCIP_OKAY;
    2462}
    2463
    2464/** prints given nonlinear constraint information in LP format to file stream */
    2465static
    2467 SCIP* scip, /**< SCIP data structure */
    2468 FILE* file, /**< output file (or NULL for standard output) */
    2469 const char* rowname, /**< name of the row */
    2470 SCIP_EXPR* expr, /**< polynomial expression */
    2471 SCIP_Real lhs, /**< left hand side */
    2472 SCIP_Real rhs /**< right hand side */
    2473 )
    2474{
    2475 assert(scip != NULL);
    2476 assert(rowname != NULL);
    2477 assert(expr != NULL);
    2478 assert(lhs <= rhs);
    2479
    2480 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    2481 return SCIP_OKAY;
    2482
    2483 /* print row(s) in LP format */
    2484 if( SCIPisEQ(scip, lhs, rhs) )
    2485 {
    2486 assert( !SCIPisInfinity(scip, rhs) );
    2487
    2488 /* equal constraint */
    2489 printRowNl(scip, file, rowname, "", "=", expr, rhs);
    2490 }
    2491 else
    2492 {
    2493 if( !SCIPisInfinity(scip, -lhs) )
    2494 {
    2495 /* print inequality ">=" */
    2496 printRowNl(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", expr, lhs);
    2497 }
    2498 if( !SCIPisInfinity(scip, rhs) )
    2499 {
    2500 /* print inequality "<=" */
    2501 printRowNl(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", expr, rhs);
    2502 }
    2503 }
    2504
    2505 return SCIP_OKAY;
    2506}
    2507
    2508/** check whether given variables are aggregated and put them into an array without duplication */
    2509static
    2511 int nvars, /**< number of active variables in the problem */
    2512 SCIP_VAR** vars, /**< variable array */
    2513 int* nAggregatedVars, /**< number of aggregated variables on output */
    2514 SCIP_VAR*** aggregatedVars, /**< array storing the aggregated variables on output */
    2515 SCIP_HASHTABLE** varAggregated /**< hashtable for checking duplicates */
    2516 )
    2517{
    2518 int j;
    2519
    2520 /* check variables */
    2521 for (j = 0; j < nvars; ++j)
    2522 {
    2523 SCIP_VARSTATUS status;
    2524 SCIP_VAR* var;
    2525
    2526 var = vars[j];
    2527 status = SCIPvarGetStatus(var);
    2528
    2529 /* collect aggregated variables in a list */
    2530 if( status >= SCIP_VARSTATUS_AGGREGATED )
    2531 {
    2532 assert( status == SCIP_VARSTATUS_AGGREGATED ||
    2533 status == SCIP_VARSTATUS_MULTAGGR ||
    2534 status == SCIP_VARSTATUS_NEGATED );
    2535
    2536 if ( ! SCIPhashtableExists(*varAggregated, (void*) var) )
    2537 {
    2538 (*aggregatedVars)[(*nAggregatedVars)++] = var;
    2539 SCIP_CALL( SCIPhashtableInsert(*varAggregated, (void*) var) );
    2540 }
    2541 }
    2542 }
    2543
    2544 return SCIP_OKAY;
    2545}
    2546
    2547
    2548/** print aggregated variable-constraints */
    2549static
    2551 SCIP* scip, /**< SCIP data structure */
    2552 FILE* file, /**< output file (or NULL for standard output) */
    2553 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    2554 int nvars, /**< number of active variables in the problem */
    2555 int nAggregatedVars, /**< number of aggregated variables */
    2556 SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
    2557 )
    2558{
    2559 int j;
    2560
    2561 SCIP_VAR** activevars;
    2562 SCIP_Real* activevals;
    2563 int nactivevars;
    2564 SCIP_Real activeconstant;
    2565 char consname[PIP_MAX_NAMELEN];
    2566
    2567 assert( scip != NULL );
    2568
    2569 /* write aggregation constraints */
    2570 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
    2571 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
    2572
    2573 for (j = 0; j < nAggregatedVars; ++j)
    2574 {
    2575 /* set up list to obtain substitution variables */
    2576 nactivevars = 1;
    2577
    2578 activevars[0] = aggregatedVars[j];
    2579 activevals[0] = 1.0;
    2580 activeconstant = 0.0;
    2581
    2582 /* retransform given variables to active variables */
    2583 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
    2584
    2585 activevals[nactivevars] = -1.0;
    2586 activevars[nactivevars] = aggregatedVars[j];
    2587 ++nactivevars;
    2588
    2589 /* output constraint */
    2590 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
    2591 SCIP_CALL( printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, - activeconstant,
    2592 transformed) );
    2593 }
    2594
    2595 /* free buffer arrays */
    2596 SCIPfreeBufferArray(scip, &activevars);
    2597 SCIPfreeBufferArray(scip, &activevals);
    2598
    2599 return SCIP_OKAY;
    2600}
    2601
    2602/** returns whether name is valid according to PIP specification
    2603 *
    2604 * Checks these two conditions from http://polip.zib.de/pipformat.php:
    2605 * - Names/labels can contain at most 255 characters.
    2606 * - Name/labels have to consist of the following characters: a-z, A-Z, 0-9, "!", "#", "$", "%", "&", ";", "?", "@", "_". They cannot start with a number.
    2607 *
    2608 * In addition checks that the length is not zero.
    2609 */
    2610static
    2612 const char* name /**< name to check */
    2613 )
    2614{
    2615 size_t len;
    2616 size_t i;
    2617
    2618 assert(name != NULL);
    2619
    2620 len = strlen(name); /*lint !e613*/
    2621 if( len > (size_t) PIP_MAX_NAMELEN || len == 0 )
    2622 return FALSE;
    2623
    2624 /* names cannot start with a number */
    2625 if( isdigit((unsigned char)name[0]) )
    2626 return FALSE;
    2627
    2628 for( i = 0; i < len; ++i )
    2629 {
    2630 /* a-z, A-Z, 0-9 are ok */
    2631 if( isalnum((unsigned char)name[i]) )
    2632 continue;
    2633
    2634 /* characters in namechars are ok, too */
    2635 if( strchr(namechars, name[i]) != NULL )
    2636 continue;
    2637
    2638 return FALSE;
    2639 }
    2640
    2641 return TRUE;
    2642}
    2643
    2644
    2645/** method check if the variable names are valid according to PIP specification */
    2646static
    2648 SCIP* scip, /**< SCIP data structure */
    2649 SCIP_VAR** vars, /**< array of variables */
    2650 int nvars /**< number of variables */
    2651 )
    2652{
    2653 int v;
    2654
    2655 assert(scip != NULL);
    2656 assert(vars != NULL || nvars == 0);
    2657
    2658 /* check if the variable names are not too long and have only characters allowed by PIP */
    2659 for( v = 0; v < nvars; ++v )
    2660 {
    2661 if( !isNameValid(SCIPvarGetName(vars[v])) )
    2662 {
    2663 SCIPwarningMessage(scip, "variable name <%s> is not valid (too long or disallowed characters); PIP might be corrupted\n", SCIPvarGetName(vars[v]));
    2664 return;
    2665 }
    2666 }
    2667}
    2668
    2669/** method check if the constraint names are valid according to PIP specification */
    2670static
    2672 SCIP* scip, /**< SCIP data structure */
    2673 SCIP_CONS** conss, /**< array of constraints */
    2674 int nconss, /**< number of constraints */
    2675 SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
    2676 )
    2677{
    2678 int c;
    2679 SCIP_CONS* cons;
    2680 SCIP_CONSHDLR* conshdlr;
    2681 const char* conshdlrname;
    2682
    2683 assert( scip != NULL );
    2684 assert( conss != NULL || nconss == 0 );
    2685
    2686 for( c = 0; c < nconss; ++c )
    2687 {
    2688 assert(conss != NULL); /* for lint */
    2689 cons = conss[c];
    2690 assert(cons != NULL );
    2691
    2692 /* in case the transformed is written only constraints are posted which are enabled in the current node */
    2693 assert(!transformed || SCIPconsIsEnabled(cons));
    2694
    2695 conshdlr = SCIPconsGetHdlr(cons);
    2696 assert( conshdlr != NULL );
    2697
    2698 conshdlrname = SCIPconshdlrGetName(conshdlr);
    2699 assert( transformed == SCIPconsIsTransformed(cons) );
    2700
    2701 if( !isNameValid(SCIPconsGetName(cons)) )
    2702 {
    2703 SCIPwarningMessage(scip, "constraint name <%s> is not valid (too long or unallowed characters); PIP might be corrupted\n", SCIPconsGetName(cons));
    2704 return;
    2705 }
    2706
    2707 if( strcmp(conshdlrname, "linear") == 0 )
    2708 {
    2709 SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
    2710 SCIP_Real rhs = SCIPgetRhsLinear(scip, cons);
    2711
    2712 /* for ranged constraints, we need to be able to append _lhs and _rhs to the constraint name, so need additional 4 characters */
    2713 if( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > (size_t) PIP_MAX_NAMELEN - 4 )
    2714 {
    2715 SCIPwarningMessage(scip, "name of ranged constraint <%s> has to be cut down to %d characters;\n", SCIPconsGetName(conss[c]),
    2716 PIP_MAX_NAMELEN - 1);
    2717 return;
    2718 }
    2719 }
    2720 }
    2721}
    2722
    2723/** writes problem to file
    2724 * @todo add writing cons_pseudoboolean
    2725 */
    2727 SCIP* scip, /**< SCIP data structure */
    2728 FILE* file, /**< output file, or NULL if standard output should be used */
    2729 const char* name, /**< problem name */
    2730 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    2731 SCIP_OBJSENSE objsense, /**< objective sense */
    2732 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    2733 * extobj = objsense * objscale * (intobj + objoffset) */
    2734 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    2735 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
    2736 int nvars, /**< number of active variables in the problem */
    2737 int nbinvars, /**< number of binary variables */
    2738 int nintvars, /**< number of general integer variables */
    2739 int nimplvars, /**< number of implicit integer variables */
    2740 int ncontvars, /**< number of continuous variables */
    2741 SCIP_CONS** conss, /**< array with constraints of the problem */
    2742 int nconss, /**< number of constraints in the problem */
    2743 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    2744 )
    2745{
    2746 int c;
    2747 int v;
    2748
    2749 int linecnt;
    2750 char linebuffer[PIP_MAX_PRINTLEN+1];
    2751
    2752 char varname[PIP_MAX_NAMELEN];
    2753 char buffer[PIP_MAX_PRINTLEN];
    2754
    2755 SCIP_CONSHDLR* conshdlr;
    2756 const char* conshdlrname;
    2757 SCIP_CONS* cons;
    2758 SCIP_CONS** consNonlinear;
    2759 int nConsNonlinear;
    2760 SCIP_CONS** consAnd;
    2761 int nConsAnd;
    2762 char consname[PIP_MAX_NAMELEN];
    2763
    2764 SCIP_VAR** aggregatedVars;
    2765 int nAggregatedVars;
    2766 SCIP_HASHTABLE* varAggregated;
    2767
    2768 SCIP_VAR** tmpvars;
    2769 int tmpvarssize;
    2770
    2771 SCIP_VAR** consvars;
    2772 SCIP_Real* consvals;
    2773 int nconsvars;
    2774
    2775 SCIP_VAR* var;
    2776 SCIP_Real lb;
    2777 SCIP_Real ub;
    2778
    2779 int implintlevel;
    2780 int nintegers = nvars - ncontvars;
    2781 assert(nintegers >= 0);
    2782
    2783 nAggregatedVars = 0;
    2784 nConsNonlinear = 0;
    2785 nConsAnd = 0;
    2786
    2787 /* check if the variable names are not to long */
    2788 checkVarnames(scip, vars, nvars);
    2789
    2790 /* check if the constraint names are to long */
    2791 checkConsnames(scip, conss, nconss, transformed);
    2792
    2793 /* adjust written integrality constraints on implied integral variables based on the implied integral level */
    2794 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
    2795 assert(implintlevel >= -2);
    2796 assert(implintlevel <= 2);
    2797
    2798 /* print statistics as comment to file */
    2799 SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
    2800 SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
    2801 SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
    2802 nvars, nbinvars, nintvars, nimplvars, ncontvars);
    2803 SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
    2804
    2805 /* print objective sense */
    2806 SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
    2807
    2808 clearLine(linebuffer, &linecnt);
    2809 appendLine(scip, file, linebuffer, &linecnt, " Obj:");
    2810
    2811 for (v = 0; v < nvars; ++v)
    2812 {
    2813 var = vars[v];
    2814
    2815#ifndef NDEBUG
    2816 /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
    2817 if ( !transformed )
    2819#endif
    2820
    2821 if ( SCIPisZero(scip, SCIPvarGetObj(var)) )
    2822 continue;
    2823
    2824 /* we start a new line; therefore we tab this line */
    2825 if ( linecnt == 0 )
    2826 appendLine(scip, file, linebuffer, &linecnt, " ");
    2827
    2828 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    2829 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", objscale * SCIPvarGetObj(var), varname );
    2830
    2831 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2832 }
    2833
    2834 if( ! SCIPisZero(scip, objoffset) )
    2835 {
    2836 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", objscale * objoffset);
    2837 appendLine(scip, file, linebuffer, &linecnt, buffer);
    2838 }
    2839
    2840 endLine(scip, file, linebuffer, &linecnt);
    2841
    2842 /* print "Subject to" section */
    2843 SCIPinfoMessage(scip, file, "Subject to\n");
    2844
    2845 /* collect quadratic, nonlinear, absolute power, and, and bivariate constraints in arrays */
    2846 SCIP_CALL( SCIPallocBufferArray(scip, &consNonlinear, nconss) );
    2847 SCIP_CALL( SCIPallocBufferArray(scip, &consAnd, nconss) );
    2848
    2849 tmpvarssize = SCIPgetNTotalVars(scip);
    2850 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
    2851
    2852 for (c = 0; c < nconss; ++c)
    2853 {
    2854 cons = conss[c];
    2855 assert( cons != NULL);
    2856
    2857 /* in case the transformed is written only constraints are posted which are enabled in the current node */
    2858 assert(!transformed || SCIPconsIsEnabled(cons));
    2859
    2860 conshdlr = SCIPconsGetHdlr(cons);
    2861 assert( conshdlr != NULL );
    2862
    2863 (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
    2864 conshdlrname = SCIPconshdlrGetName(conshdlr);
    2865 assert( transformed == SCIPconsIsTransformed(cons) );
    2866
    2867 if( strcmp(conshdlrname, "linear") == 0 )
    2868 {
    2869 SCIP_CALL( printQuadraticCons(scip, file, consname,
    2871 NULL, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
    2872 }
    2873 else if( strcmp(conshdlrname, "setppc") == 0 )
    2874 {
    2875 consvars = SCIPgetVarsSetppc(scip, cons);
    2876 nconsvars = SCIPgetNVarsSetppc(scip, cons);
    2877
    2878 switch( SCIPgetTypeSetppc(scip, cons) )
    2879 {
    2881 SCIP_CALL( printQuadraticCons(scip, file, consname,
    2882 consvars, NULL, nconsvars, NULL, 1.0, 1.0, transformed) );
    2883 break;
    2885 SCIP_CALL( printQuadraticCons(scip, file, consname,
    2886 consvars, NULL, nconsvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
    2887 break;
    2889 SCIP_CALL( printQuadraticCons(scip, file, consname,
    2890 consvars, NULL, nconsvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
    2891 break;
    2892 }
    2893 }
    2894 else if ( strcmp(conshdlrname, "logicor") == 0 )
    2895 {
    2896 SCIP_CALL( printQuadraticCons(scip, file, consname,
    2898 NULL, 1.0, SCIPinfinity(scip), transformed) );
    2899 }
    2900 else if ( strcmp(conshdlrname, "knapsack") == 0 )
    2901 {
    2902 SCIP_Longint* weights;
    2903
    2904 consvars = SCIPgetVarsKnapsack(scip, cons);
    2905 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
    2906
    2907 /* copy Longint array to SCIP_Real array */
    2908 weights = SCIPgetWeightsKnapsack(scip, cons);
    2909 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    2910 for( v = 0; v < nconsvars; ++v )
    2911 consvals[v] = (SCIP_Real)weights[v];
    2912
    2913 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
    2914 NULL, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
    2915
    2916 SCIPfreeBufferArray(scip, &consvals);
    2917 }
    2918 else if ( strcmp(conshdlrname, "varbound") == 0 )
    2919 {
    2920 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
    2921 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
    2922
    2923 consvars[0] = SCIPgetVarVarbound(scip, cons);
    2924 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
    2925
    2926 consvals[0] = 1.0;
    2927 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    2928
    2929 SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL,
    2930 SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
    2931
    2932 SCIPfreeBufferArray(scip, &consvars);
    2933 SCIPfreeBufferArray(scip, &consvals);
    2934 }
    2935 else if( strcmp(conshdlrname, "nonlinear") == 0 )
    2936 {
    2937 SCIP_Bool ispolynomial;
    2938 SCIP_Bool isquadratic;
    2939 SCIP_EXPR* simplifiedexpr = NULL;
    2940
    2941 ispolynomial = isExprPolynomial(scip, SCIPgetExprNonlinear(cons));
    2942 if( !ispolynomial )
    2943 {
    2944 /* simplify expression and check again if polynomial
    2945 * simplifying the expr owned by the cons can have undesired sideffects onto the consdata (the varhashmap can get messed up), so we copy first
    2946 */
    2947 SCIP_EXPR* exprcopy;
    2948 SCIP_Bool changed;
    2949 SCIP_Bool infeasible;
    2950
    2952 SCIP_CALL( SCIPsimplifyExpr(scip, exprcopy, &simplifiedexpr, &changed, &infeasible, NULL, NULL) );
    2953 SCIP_CALL( SCIPreleaseExpr(scip, &exprcopy) );
    2954
    2955 ispolynomial = isExprPolynomial(scip, simplifiedexpr);
    2956 }
    2957
    2958 /* nonlinear constraints that are not polynomial cannot be printed as PIP */
    2959 if( !ispolynomial )
    2960 {
    2961 SCIPwarningMessage(scip, "nonlinear constraint <%s> is not polynomial\n", SCIPconsGetName(cons));
    2962 SCIPinfoMessage(scip, file, "\\ ");
    2963 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    2964 SCIPinfoMessage(scip, file, ";\n");
    2965 }
    2966 else
    2967 {
    2968 /* check whether constraint is even quadratic
    2969 * (we could also skip this and print as polynomial, but the code exists already)
    2970 */
    2971 SCIP_CALL( SCIPcheckExprQuadratic(scip, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons), &isquadratic) );
    2972 if( isquadratic )
    2973 isquadratic = SCIPexprAreQuadraticExprsVariables(simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons));
    2974
    2975 if( isquadratic )
    2976 {
    2977 SCIP_CALL( printQuadraticCons(scip, file, consname, NULL, NULL, 0, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons),
    2978 SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed) );
    2979 }
    2980 else
    2981 {
    2982 SCIP_CALL( printNonlinearCons(scip, file, consname, simplifiedexpr != NULL ? simplifiedexpr : SCIPgetExprNonlinear(cons), SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons)) );
    2983 }
    2984
    2985 consNonlinear[nConsNonlinear++] = cons;
    2986 }
    2987
    2988 if( simplifiedexpr != NULL )
    2989 {
    2990 SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedexpr) );
    2991 }
    2992 }
    2993 else if( strcmp(conshdlrname, "and") == 0 )
    2994 {
    2995 printRowAnd(scip, file, consname, cons);
    2996
    2997 consAnd[nConsAnd++] = cons;
    2998 }
    2999 else
    3000 {
    3001 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
    3002 SCIPinfoMessage(scip, file, "\\ ");
    3003 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    3004 SCIPinfoMessage(scip, file, ";\n");
    3005 }
    3006 }
    3007
    3008 /* create hashtable for storing aggregated variables */
    3009 SCIP_CALL( SCIPallocBufferArray(scip, &aggregatedVars, nvars) );
    3010 SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), nvars/10, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
    3011
    3012 /* check for aggregated variables in nonlinear constraints and output aggregations as linear constraints */
    3013 for( c = 0; c < nConsNonlinear; ++c )
    3014 {
    3015 SCIP_Bool success;
    3016 int ntmpvars;
    3017
    3018 /* get variables of the nonlinear constraint */
    3019 SCIP_CALL( SCIPgetConsNVars(scip, consNonlinear[c], &ntmpvars, &success) );
    3020 assert(success);
    3021 if( ntmpvars > tmpvarssize )
    3022 {
    3023 tmpvarssize = SCIPcalcMemGrowSize(scip, ntmpvars);
    3024 SCIP_CALL( SCIPreallocBufferArray(scip, &tmpvars, tmpvarssize) );
    3025 }
    3026 SCIP_CALL( SCIPgetConsVars(scip, consNonlinear[c], tmpvars, tmpvarssize, &success) );
    3027 assert(success);
    3028
    3029 SCIP_CALL( collectAggregatedVars(ntmpvars, tmpvars, &nAggregatedVars, &aggregatedVars, &varAggregated) );
    3030 }
    3031
    3032 /* check for aggregated variables in and constraints and output aggregations as linear constraints */
    3033 for (c = 0; c < nConsAnd; ++c)
    3034 {
    3035 SCIP_VAR* resultant;
    3036
    3037 cons = consAnd[c];
    3038
    3039 SCIP_CALL( collectAggregatedVars(SCIPgetNVarsAnd(scip, cons), SCIPgetVarsAnd(scip, cons), &nAggregatedVars, &aggregatedVars, &varAggregated) );
    3040
    3041 resultant = SCIPgetResultantAnd(scip, cons);
    3042 SCIP_CALL( collectAggregatedVars(1, &resultant, &nAggregatedVars, &aggregatedVars, &varAggregated) );
    3043 }
    3044
    3045 /* print aggregation constraints */
    3046 SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, nAggregatedVars, aggregatedVars) );
    3047
    3048 /* print "Bounds" section */
    3049 SCIPinfoMessage(scip, file, "Bounds\n");
    3050 for (v = 0; v < nvars; ++v)
    3051 {
    3052 var = vars[v];
    3053 assert( var != NULL );
    3054 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    3055
    3056 if( transformed )
    3057 {
    3058 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    3059 lb = SCIPvarGetLbLocal(var);
    3060 ub = SCIPvarGetUbLocal(var);
    3061 }
    3062 else
    3063 {
    3064 lb = SCIPvarGetLbOriginal(var);
    3065 ub = SCIPvarGetUbOriginal(var);
    3066 }
    3067
    3068 if ( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
    3069 SCIPinfoMessage(scip, file, " %s free\n", varname);
    3070 else
    3071 {
    3072 /* print lower bound */
    3073 if ( SCIPisInfinity(scip, -lb) )
    3074 SCIPinfoMessage(scip, file, " -inf <= ");
    3075 else
    3076 {
    3077 if ( SCIPisZero(scip, lb) )
    3078 {
    3079 /* variables are nonnegative by default - so we skip these variables */
    3080 if ( SCIPisInfinity(scip, ub) )
    3081 continue;
    3082 lb = 0.0;
    3083 }
    3084
    3085 SCIPinfoMessage(scip, file, " %.15g <= ", lb);
    3086 }
    3087 /* print variable name */
    3088 SCIPinfoMessage(scip, file, "%s", varname);
    3089
    3090 /* print upper bound as far this one is not infinity */
    3091 if( !SCIPisInfinity(scip, ub) )
    3092 SCIPinfoMessage(scip, file, " <= %.15g", ub);
    3093
    3094 SCIPinfoMessage(scip, file, "\n");
    3095 }
    3096 }
    3097
    3098 /* output aggregated variables as 'free' */
    3099 for (v = 0; v < nAggregatedVars; ++v)
    3100 {
    3101 var = aggregatedVars[v];
    3102 assert( var != NULL );
    3103 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    3104
    3105 SCIPinfoMessage(scip, file, " %s free\n", varname);
    3106 }
    3107
    3108 /* free space */
    3109 SCIPfreeBufferArray(scip, &aggregatedVars);
    3110 SCIPhashtableFree(&varAggregated);
    3111
    3112 /* print binaries section */
    3113 {
    3114 SCIP_Bool initial = TRUE;
    3115
    3116 /* output active variables */
    3117 for( v = 0; v < nintegers; ++v )
    3118 {
    3119 var = vars[v];
    3120
    3121 if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY || (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    3122 continue;
    3123
    3124 if( initial )
    3125 {
    3126 SCIPinfoMessage(scip, file, "Binaries\n");
    3127 initial = FALSE;
    3128 }
    3129
    3130 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
    3131 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
    3132 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3133 }
    3134
    3135 endLine(scip, file, linebuffer, &linecnt);
    3136 }
    3137
    3138 /* print generals section */
    3139 {
    3140 SCIP_Bool initial = TRUE;
    3141
    3142 /* output active variables */
    3143 for( v = nbinvars; v < nintegers; ++v )
    3144 {
    3145 var = vars[v];
    3146
    3147 switch( SCIPvarGetType(var) )
    3148 {
    3150 continue;
    3152 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    3153 continue;
    3154 break;
    3156 if( (int)SCIPvarGetImplType(var) <= 2 - implintlevel )
    3157 continue;
    3158 break;
    3159 default:
    3160 SCIPerrorMessage("unknown variable type\n");
    3161 return SCIP_INVALIDDATA;
    3162 } /*lint !e788*/
    3163
    3164 if( initial )
    3165 {
    3166 SCIPinfoMessage(scip, file, "Generals\n");
    3167 initial = FALSE;
    3168 }
    3169
    3170 (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
    3171 (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
    3172 appendLine(scip, file, linebuffer, &linecnt, buffer);
    3173 }
    3174
    3175 endLine(scip, file, linebuffer, &linecnt);
    3176 }
    3177
    3178 /* free space */
    3179 SCIPfreeBufferArray(scip, &tmpvars);
    3180 SCIPfreeBufferArray(scip, &consNonlinear);
    3181 SCIPfreeBufferArray(scip, &consAnd);
    3182
    3183 /* end of lp format */
    3184 SCIPinfoMessage(scip, file, "%s\n", "End");
    3185
    3186 *result = SCIP_SUCCESS;
    3187
    3188 return SCIP_OKAY;
    3189}
    3190
    3191/*
    3192 * Callback methods of reader
    3193 */
    3194
    3195/** copy method for reader plugins (called when SCIP copies plugins) */
    3196static
    3198{ /*lint --e{715}*/
    3199 assert(scip != NULL);
    3200 assert(reader != NULL);
    3201 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    3202
    3203 /* call inclusion method of reader */
    3205
    3206 return SCIP_OKAY;
    3207}
    3208
    3209
    3210/** problem reading method of reader */
    3211static
    3213{ /*lint --e{715}*/
    3214
    3215 SCIP_CALL( SCIPreadPip(scip, reader, filename, result) );
    3216
    3217 return SCIP_OKAY;
    3218}
    3219
    3220
    3221/** problem writing method of reader */
    3222static
    3224{ /*lint --e{715}*/
    3225 SCIP_CALL( SCIPwritePip(scip, file, name, transformed, objsense, objscale, objoffset, vars,
    3226 nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
    3227
    3228 return SCIP_OKAY;
    3229}
    3230
    3231
    3232/*
    3233 * reader specific interface methods
    3234 */
    3235
    3236/** includes the pip file reader in SCIP */
    3238 SCIP* scip /**< SCIP data structure */
    3239 )
    3240{
    3241 SCIP_READER* reader;
    3242
    3243 /* include reader */
    3245
    3246 /* set non fundamental callbacks via setter functions */
    3247 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyPip) );
    3248 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadPip) );
    3249 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWritePip) );
    3250
    3251 return SCIP_OKAY;
    3252}
    3253
    3254
    3255/** reads problem from file */
    3257 SCIP* scip, /**< SCIP data structure */
    3258 SCIP_READER* reader, /**< the file reader itself */
    3259 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
    3260 SCIP_RESULT* result /**< pointer to store the result of the file reading call */
    3261 )
    3262{ /*lint --e{715}*/
    3263 PIPINPUT pipinput;
    3264 SCIP_RETCODE retcode;
    3265 int i;
    3266
    3267 assert(scip != NULL); /* for lint */
    3268 assert(reader != NULL);
    3269 assert(result != NULL);
    3270
    3271 *result = SCIP_DIDNOTRUN;
    3272
    3273 /* initialize PIP input data */
    3274 pipinput.file = NULL;
    3275 pipinput.linebuf[0] = '\0';
    3276 pipinput.probname[0] = '\0';
    3277 pipinput.objname[0] = '\0';
    3278 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.token, PIP_MAX_LINELEN) ); /*lint !e506*/
    3279 pipinput.token[0] = '\0';
    3280 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN) ); /*lint !e506*/
    3281 pipinput.tokenbuf[0] = '\0';
    3282 for( i = 0; i < PIP_MAX_PUSHEDTOKENS; ++i )
    3283 {
    3284 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((pipinput.pushedtokens)[i]), PIP_MAX_LINELEN) ); /*lint !e866 !e506*/
    3285 }
    3286
    3287 pipinput.npushedtokens = 0;
    3288 pipinput.linenumber = 0;
    3289 pipinput.linepos = 0;
    3290 pipinput.section = PIP_START;
    3291 pipinput.objsense = SCIP_OBJSENSE_MINIMIZE;
    3292 pipinput.haserror = FALSE;
    3293
    3294 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(pipinput.initialconss)) );
    3295 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(pipinput.dynamicconss)) );
    3296 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(pipinput.dynamiccols)) );
    3297 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(pipinput.dynamicrows)) );
    3298
    3299 /* read the file */
    3300 retcode = readPIPFile(scip, &pipinput, filename);
    3301
    3302 /* free dynamically allocated memory */
    3303 for( i = PIP_MAX_PUSHEDTOKENS - 1; i >= 0 ; --i )
    3304 {
    3305 SCIPfreeBlockMemoryArray(scip, &pipinput.pushedtokens[i], PIP_MAX_LINELEN);
    3306 }
    3307 SCIPfreeBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN);
    3309
    3310 if( retcode == SCIP_PLUGINNOTFOUND )
    3311 retcode = SCIP_READERROR;
    3312
    3313 /* evaluate the result */
    3314 if( pipinput.haserror )
    3315 retcode = SCIP_READERROR;
    3316 else
    3317 {
    3318 /* set objective sense */
    3319 SCIP_CALL( SCIPsetObjsense(scip, pipinput.objsense) );
    3320 *result = SCIP_SUCCESS;
    3321 }
    3322
    3323 SCIP_CALL( retcode );
    3324
    3325 return SCIP_OKAY;
    3326}
    Constraint handler for AND 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 variable bound constraints .
    #define NULL
    Definition: def.h:248
    #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 SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    sum expression handler
    variable expression handler
    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
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetVbdcoefVarbound(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_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
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    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_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_EXPR *expr, 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_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, 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_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 ** 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_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    @ 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 SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_var.c:398
    void SCIPsetConstantExprSum(SCIP_EXPR *expr, SCIP_Real constant)
    Definition: expr_sum.c:1138
    SCIP_RETCODE SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
    Definition: expr_sum.c:1154
    SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_sum.c:1117
    SCIP_RETCODE SCIPwritePip(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
    Definition: reader_pip.c:2726
    SCIP_RETCODE SCIPreadPip(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
    Definition: reader_pip.c:3256
    SCIP_RETCODE SCIPincludeReaderPip(SCIP *scip)
    Definition: reader_pip.c:3237
    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 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
    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 SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    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 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_RETCODE SCIPcreateExprMonomial(SCIP *scip, SCIP_EXPR **expr, int nfactors, SCIP_VAR **vars, SCIP_Real *exponents, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1167
    int SCIPexprGetNChildren(SCIP_EXPR *expr)
    Definition: expr.c:3872
    void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
    Definition: expr.c:4226
    SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
    Definition: expr_pow.c:3448
    SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1490
    SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1479
    SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
    Definition: expr.c:4262
    void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
    Definition: expr.c:4141
    SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1554
    SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1468
    SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
    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 SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
    Definition: scip_expr.c:1512
    SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
    Definition: expr_value.c:298
    SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1501
    SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
    Definition: scip_expr.c:2402
    SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
    Definition: expr.c:3882
    SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
    Definition: expr_sum.c:1569
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    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
    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
    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
    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
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(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 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 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_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    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 SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
    Definition: scip_var.c:184
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    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 SCIPstrncpy(char *t, const char *s, int size)
    Definition: misc.c:10897
    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
    public functions to work with algebraic expressions
    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 NLP management
    public methods for input file readers
    public methods for problem variables
    static SCIP_Bool isExprSignomial(SCIP *scip, SCIP_EXPR *expr)
    Definition: reader_pip.c:1803
    static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
    Definition: reader_pip.c:1738
    static SCIP_RETCODE readPolynomial(SCIP *scip, PIPINPUT *pipinput, char *name, SCIP_EXPR **expr, SCIP_Bool *islinear, SCIP_Bool *newsection)
    Definition: reader_pip.c:807
    #define PIP_MAX_PUSHEDTOKENS
    Definition: reader_pip.c:76
    static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_Bool dynamiccols, SCIP_VAR **var, SCIP_Bool *created)
    Definition: reader_pip.c:664
    static void clearLine(char *linebuffer, int *linecnt)
    Definition: reader_pip.c:1873
    static SCIP_Bool hasError(PIPINPUT *pipinput)
    Definition: reader_pip.c:175
    PipSense
    Definition: reader_pip.c:105
    @ PIP_SENSE_NOTHING
    Definition: reader_pip.c:106
    @ PIP_SENSE_GE
    Definition: reader_pip.c:108
    @ PIP_SENSE_EQ
    Definition: reader_pip.c:109
    @ PIP_SENSE_LE
    Definition: reader_pip.c:107
    static SCIP_Bool isNewSection(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:443
    static SCIP_Bool getNextToken(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:307
    static SCIP_RETCODE readGenerals(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:1565
    static SCIP_RETCODE readStart(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:703
    static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
    Definition: reader_pip.c:1714
    static SCIP_Bool isExprPolynomial(SCIP *scip, SCIP_EXPR *expr)
    Definition: reader_pip.c:1850
    static const char tokenchars[]
    Definition: reader_pip.c:137
    static SCIP_Bool isSign(PIPINPUT *pipinput, int *sign)
    Definition: reader_pip.c:576
    static SCIP_Bool getNextLine(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:248
    #define PIP_PRINTLEN
    Definition: reader_pip.c:81
    static const char commentchars[]
    Definition: reader_pip.c:138
    static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
    Definition: reader_pip.c:2647
    static SCIP_RETCODE ensureMonomialsSize(SCIP *scip, SCIP_EXPR ***monomials, SCIP_Real **monomialscoef, int *monomialssize, int minnmonomials)
    Definition: reader_pip.c:724
    static void printSignomial(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_EXPR *expr, SCIP_Real coef, SCIP_Bool needsign)
    Definition: reader_pip.c:2173
    static const char namechars[]
    Definition: reader_pip.c:139
    static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
    Definition: reader_pip.c:2550
    static SCIP_Bool isNameValid(const char *name)
    Definition: reader_pip.c:2611
    static void swapTokenBuffer(PIPINPUT *pipinput)
    Definition: reader_pip.c:432
    #define READER_DESC
    Definition: reader_pip.c:68
    static SCIP_DECL_READERREAD(readerReadPip)
    Definition: reader_pip.c:3212
    #define PIP_MAX_PRINTLEN
    Definition: reader_pip.c:79
    static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, PIPEXPTYPE *exptype)
    Definition: reader_pip.c:204
    PipSection
    Definition: reader_pip.c:85
    @ PIP_END
    Definition: reader_pip.c:92
    @ PIP_BINARIES
    Definition: reader_pip.c:91
    @ PIP_START
    Definition: reader_pip.c:86
    @ PIP_CONSTRAINTS
    Definition: reader_pip.c:88
    @ PIP_BOUNDS
    Definition: reader_pip.c:89
    @ PIP_GENERALS
    Definition: reader_pip.c:90
    @ PIP_OBJECTIVE
    Definition: reader_pip.c:87
    #define PIP_MAX_NAMELEN
    Definition: reader_pip.c:80
    static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs)
    Definition: reader_pip.c:2466
    struct PipInput PIPINPUT
    Definition: reader_pip.c:134
    static SCIP_RETCODE collectAggregatedVars(int nvars, SCIP_VAR **vars, int *nAggregatedVars, SCIP_VAR ***aggregatedVars, SCIP_HASHTABLE **varAggregated)
    Definition: reader_pip.c:2510
    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_pip.c:2379
    #define READER_EXTENSION
    Definition: reader_pip.c:69
    static SCIP_RETCODE readBinaries(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:1600
    enum PipSection PIPSECTION
    Definition: reader_pip.c:94
    #define PIP_INIT_MONOMIALSSIZE
    Definition: reader_pip.c:77
    enum PipSense PIPSENSE
    Definition: reader_pip.c:111
    static SCIP_Bool isSense(PIPINPUT *pipinput, PIPSENSE *sense)
    Definition: reader_pip.c:633
    static void pushBufferToken(PIPINPUT *pipinput)
    Definition: reader_pip.c:419
    static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
    Definition: reader_pip.c:1887
    static void pushToken(PIPINPUT *pipinput)
    Definition: reader_pip.c:406
    #define READER_NAME
    Definition: reader_pip.c:67
    static SCIP_DECL_READERCOPY(readerCopyPip)
    Definition: reader_pip.c:3197
    static void syntaxError(SCIP *scip, PIPINPUT *pipinput, const char *msg)
    Definition: reader_pip.c:148
    static void printRowAnd(SCIP *scip, FILE *file, const char *rowname, SCIP_CONS *cons)
    Definition: reader_pip.c:2331
    #define PIP_MAX_LINELEN
    Definition: reader_pip.c:75
    #define PIP_INIT_FACTORSSIZE
    Definition: reader_pip.c:78
    static SCIP_Bool isDelimChar(char c)
    Definition: reader_pip.c:186
    static SCIP_RETCODE readConstraints(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:1225
    static void swapPointers(char **pointer1, char **pointer2)
    Definition: reader_pip.c:293
    static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
    Definition: reader_pip.c:1721
    static void printRowNl(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_EXPR *expr, SCIP_Real rhs)
    Definition: reader_pip.c:2263
    static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
    Definition: reader_pip.c:1730
    enum PipExpType PIPEXPTYPE
    Definition: reader_pip.c:102
    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_pip.c:1941
    static SCIP_RETCODE readObjective(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:1094
    static SCIP_RETCODE ensureFactorsSize(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **exponents, int *factorssize, int minnfactors)
    Definition: reader_pip.c:768
    static SCIP_DECL_READERWRITE(readerWritePip)
    Definition: reader_pip.c:3223
    static SCIP_Bool isValue(SCIP *scip, PIPINPUT *pipinput, SCIP_Real *value)
    Definition: reader_pip.c:601
    static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
    Definition: reader_pip.c:2671
    PipExpType
    Definition: reader_pip.c:97
    @ PIP_EXP_SIGNED
    Definition: reader_pip.c:100
    @ PIP_EXP_NONE
    Definition: reader_pip.c:98
    @ PIP_EXP_UNSIGNED
    Definition: reader_pip.c:99
    static SCIP_RETCODE readPIPFile(SCIP *scip, PIPINPUT *pipinput, const char *filename)
    Definition: reader_pip.c:1644
    static const char delimchars[]
    Definition: reader_pip.c:136
    static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
    Definition: reader_pip.c:1910
    static SCIP_RETCODE readBounds(SCIP *scip, PIPINPUT *pipinput)
    Definition: reader_pip.c:1394
    static SCIP_Bool isTokenChar(char c)
    Definition: reader_pip.c:195
    file reader for polynomial mixed-integer programs in PIP format
    public methods for constraint handler plugins and constraints
    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_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
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ 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