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