Scippy

    SCIP

    Solving Constraint Integer Programs

    reader_opb.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file reader_opb.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief pseudo-Boolean file reader (opb format)
    28 * @author Stefan Heinz
    29 * @author Michael Winkler
    30 * @author Dominik Kamp
    31 *
    32 * This file reader parses the @a opb format and is also used by the @a wbo reader for the @a wbo format. For a
    33 * detailed description of this format see
    34 *
    35 * - http://www.cril.univ-artois.fr/PB07/solver_req.html
    36 * - http://www.cril.univ-artois.fr/PB10/format.pdf
    37 *
    38 * The syntax of the input file format can be described by a simple Backus-Naur
    39 * form. <formula> is the start symbol of this grammar.
    40 *
    41 * <formula>::= <sequence_of_comments>
    42 * [<objective>] | [<softheader>]
    43 * <sequence_of_comments_or_constraints>
    44 *
    45 * <sequence_of_comments>::= <comment> [<sequence_of_comments>]
    46 * <comment>::= "*" <any_sequence_of_characters_other_than_EOL> <EOL>
    47 * <sequence_of_comments_or_constraints>::=<comment_or_constraint> [<sequence_of_comments_or_constraints>]
    48 * <comment_or_constraint>::=<comment>|<constraint>
    49 *
    50 * <objective>::= "min:" <zeroOrMoreSpace> <sum> ";"
    51 * <constraint>::= <sum> <relational_operator> <zeroOrMoreSpace> <integer> <zeroOrMoreSpace> ";"
    52 *
    53 * <sum>::= <weightedterm> | <weightedterm> <sum>
    54 * <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
    55 *
    56 * <integer>::= <unsigned_integer> | "+" <unsigned_integer> | "-" <unsigned_integer>
    57 * <unsigned_integer>::= <digit> | <digit><unsigned_integer>
    58 *
    59 * <relational_operator>::= ">=" | "="
    60 *
    61 * <variablename>::= "x" <unsigned_integer>
    62 *
    63 * <oneOrMoreSpace>::= " " [<oneOrMoreSpace>]
    64 * <zeroOrMoreSpace>::= [" " <zeroOrMoreSpace>]
    65 *
    66 * For linear pseudo-Boolean instances, <term> is defined as
    67 *
    68 * <term>::=<variablename>
    69 *
    70 * For non-linear instances, <term> is defined as
    71 *
    72 * <term>::= <oneOrMoreLiterals>
    73 * <oneOrMoreLiterals>::= <literal> | <literal> <oneOrMoreSpace> <oneOrMoreLiterals>
    74 * <literal>::= <variablename> | "~"<variablename>
    75 *
    76 * For wbo-files are the following additional/changed things possible.
    77 *
    78 * <softheader>::= "soft:" [<unsigned integer>] ";"
    79 *
    80 * <comment_or_constraint>::=<comment>|<constraint>|<softconstraint>
    81 *
    82 * <softconstraint>::= "[" <zeroOrMoreSpace> <unsigned integer> <zeroOrMoreSpace> "]" <constraint>
    83 *
    84 */
    85
    86/* Our parser should also be lax by handling variable names and it's possible to read doubles instead of integer and
    87 * possible some more :). */
    88
    89/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    90
    92#include <ctype.h>
    93#include "scip/cons_and.h"
    94#include "scip/cons_indicator.h"
    95#include "scip/cons_knapsack.h"
    96#include "scip/cons_linear.h"
    98#include "scip/cons_logicor.h"
    100#include "scip/cons_setppc.h"
    101#include "scip/cons_varbound.h"
    102#include "scip/debug.h"
    103#include "scip/pub_cons.h"
    104#include "scip/pub_fileio.h"
    105#include "scip/pub_message.h"
    106#include "scip/pub_misc.h"
    107#include "scip/pub_misc_sort.h"
    108#include "scip/pub_reader.h"
    109#include "scip/pub_var.h"
    110#include "scip/reader_opb.h"
    111#include "scip/rational.h"
    112#include "scip/scip_cons.h"
    113#include "scip/scip_exact.h"
    114#include "scip/scip_mem.h"
    115#include "scip/scip_message.h"
    116#include "scip/scip_numerics.h"
    117#include "scip/scip_param.h"
    118#include "scip/scip_prob.h"
    119#include "scip/scip_reader.h"
    121#include "scip/scip_var.h"
    122#include <stdlib.h>
    123#include <string.h>
    124
    125#define READER_NAME "opbreader"
    126#define READER_DESC "file reader for pseudo-Boolean problem in opb format"
    127#define READER_EXTENSION "opb"
    128
    129#define GENCONSNAMES TRUE /* remove if no constraint names should be generated */
    130#define INDICATORVARNAME "indicatorvar" /* standard part of name for all indicator variables */
    131#define INDICATORSLACKVARNAME "indslack" /* standard part of name for all indicator slack variables; should be the same in cons_indicator */
    132#define TOPCOSTCONSNAME "topcostcons" /* standard name for artificial topcost constraint in wbo problems */
    133
    134/*
    135 * Data structures
    136 */
    137#define OPB_MAX_LINELEN 65536 /**< size of the line buffer for reading or writing */
    138#define OPB_MAX_PUSHEDTOKENS 2
    139#define OPB_INIT_COEFSSIZE 8192
    140#define OPB_MAX_INTSIZE -1 /**< maximum allowed "intsize" (i.e. the number of bits required to represent the
    141 * sum of absolute values of all integers that appear in a constraint or objective
    142 * function) or -1 for unlimited */
    143
    144/** OPB reader data */
    145struct SCIP_ReaderData
    146{
    147 int maxintsize; /**< maximum allowed "intsize" (i.e., the number of bits required
    148 * to represent the sum of absolute values of all integers that
    149 * appear in a constraint or objective function) or -1 for
    150 * unlimited */
    151};
    152
    153/** Section in OPB File */
    155{
    161
    163{
    169typedef enum OpbSense OPBSENSE;
    170
    171/** OPB reading data */
    172struct OpbInput
    173{
    174 SCIP_FILE* file;
    175 char* linebuf;
    176 char* token;
    177 char* tokenbuf;
    178 char* pushedtokens[OPB_MAX_PUSHEDTOKENS];
    179 int npushedtokens;
    180 int linenumber;
    181 int linepos;
    182 int linebufsize;
    183 int intsize;
    184 SCIP_OBJSENSE objsense;
    185 SCIP_Bool eof;
    186 SCIP_Bool haserror;
    187 int nproblemcoeffs;
    188 SCIP_Bool wbo;
    189 SCIP_Real topcost;
    190 int nindvars;
    191#if GENCONSNAMES == TRUE
    192 int consnumber;
    193#endif
    194};
    195
    196typedef struct OpbInput OPBINPUT;
    197
    198static const char commentchars[] = "*";
    199/*
    200 * Local methods (for reading)
    201 */
    202
    203/** issues an error message and marks the OPB data to have errors */
    204static
    206 SCIP* scip, /**< SCIP data structure */
    207 OPBINPUT* opbinput, /**< OPB reading data */
    208 const char* msg /**< error message */
    209 )
    210{
    211 assert(scip != NULL);
    212 assert(opbinput != NULL);
    213
    214 SCIPerrorMessage("Syntax error in line %d: %s found <%s>\n", opbinput->linenumber, msg, opbinput->token);
    215 if( opbinput->linebuf[opbinput->linebufsize - 1] == '\n' )
    216 {
    217 SCIPerrorMessage(" input: %s", opbinput->linebuf);
    218 }
    219 else
    220 {
    221 SCIPerrorMessage(" input: %s\n", opbinput->linebuf);
    222 }
    223
    224 opbinput->haserror = TRUE;
    225}
    226
    227/** returns whether a syntax error was detected */
    228static
    230 OPBINPUT* opbinput /**< OPB reading data */
    231 )
    232{
    233 assert(opbinput != NULL);
    234
    235 return opbinput->haserror;
    236}
    237
    238/** returns whether the given character is a token delimiter */
    239static
    241 char c /**< input character */
    242 )
    243{
    244 switch (c)
    245 {
    246 case ' ':
    247 case '\f':
    248 case '\n':
    249 case '\r':
    250 case '\t':
    251 case '\v':
    252 case '\0':
    253 return TRUE;
    254 default:
    255 return FALSE;
    256 }
    257}
    258
    259/** returns whether the given character is a single token */
    260static
    262 char c /**< input character */
    263 )
    264{
    265 switch (c)
    266 {
    267 case '-':
    268 case '+':
    269 case ':':
    270 case '<':
    271 case '>':
    272 case '=':
    273 case '[':
    274 case ']':
    275 case ';':
    276 return TRUE;
    277 default:
    278 return FALSE;
    279 }
    280}
    281
    282/** returns whether the current character is member of a value string */
    283static
    285 char c, /**< input character */
    286 char nextc, /**< next input character */
    287 SCIP_Bool firstchar, /**< is the given character the first char of the token? */
    288 SCIP_Bool* hasdot, /**< pointer to update the dot flag */
    289 OPBEXPTYPE* exptype /**< pointer to update the exponent type */
    290 )
    291{
    292 assert(hasdot != NULL);
    293 assert(exptype != NULL);
    294
    295 if( isdigit((unsigned char)c) )
    296 return TRUE;
    297 else if( (*exptype == OPB_EXP_NONE) && !(*hasdot) && (c == '.') )
    298 {
    299 *hasdot = TRUE;
    300 return TRUE;
    301 }
    302 else if( !firstchar && (*exptype == OPB_EXP_NONE) && (c == 'e' || c == 'E') )
    303 {
    304 if( nextc == '+' || nextc == '-' )
    305 {
    306 *exptype = OPB_EXP_SIGNED;
    307 return TRUE;
    308 }
    309 else if( isdigit((unsigned char)nextc) )
    310 {
    311 *exptype = OPB_EXP_UNSIGNED;
    312 return TRUE;
    313 }
    314 }
    315 else if( (*exptype == OPB_EXP_SIGNED) && (c == '+' || c == '-') )
    316 {
    317 *exptype = OPB_EXP_UNSIGNED;
    318 return TRUE;
    319 }
    320
    321 return FALSE;
    322}
    323
    324/** reads the next line from the input file into the line buffer; skips comments;
    325 * returns whether a line could be read
    326 */
    327static
    329 SCIP* scip, /**< SCIP data structure */
    330 OPBINPUT* opbinput /**< OPB reading data */
    331 )
    332{
    333 int i;
    334
    335 assert(opbinput != NULL);
    336
    337 /* read next line */
    338 opbinput->linepos = 0;
    339 opbinput->linebuf[opbinput->linebufsize - 2] = '\0';
    340
    341 if( SCIPfgets(opbinput->linebuf, opbinput->linebufsize, opbinput->file) == NULL )
    342 return FALSE;
    343
    344 opbinput->linenumber++;
    345
    346 /* if line is too long for our buffer reallocate buffer */
    347 while( opbinput->linebuf[opbinput->linebufsize - 2] != '\0' )
    348 {
    349 int newsize;
    350
    351 newsize = SCIPcalcMemGrowSize(scip, opbinput->linebufsize + 1);
    352 SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &opbinput->linebuf, opbinput->linebufsize, newsize) );
    353
    354 opbinput->linebuf[newsize-2] = '\0';
    355 if ( SCIPfgets(opbinput->linebuf + opbinput->linebufsize - 1, newsize - opbinput->linebufsize + 1, opbinput->file) == NULL )
    356 return FALSE;
    357 opbinput->linebufsize = newsize;
    358 }
    359
    360 opbinput->linebuf[opbinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    361
    362 /* skip characters after comment symbol */
    363 for( i = 0; commentchars[i] != '\0'; ++i )
    364 {
    365 char* commentstart;
    366
    367 commentstart = strchr(opbinput->linebuf, commentchars[i]);
    368 if( commentstart != NULL )
    369 {
    370 *commentstart = '\0';
    371 *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    372 break;
    373 }
    374 }
    375
    376 SCIPdebugMsg(scip, "%s\n", opbinput->linebuf);
    377
    378 return TRUE;
    379}
    380
    381/** swaps the addresses of two pointers */
    382static
    384 char** pointer1, /**< first pointer */
    385 char** pointer2 /**< second pointer */
    386 )
    387{
    388 char* tmp;
    389
    390 tmp = *pointer1;
    391 *pointer1 = *pointer2;
    392 *pointer2 = tmp;
    393}
    394
    395/** reads the next token from the input file into the token buffer; returns whether a token was read */
    396static
    398 SCIP* scip, /**< SCIP data structure */
    399 OPBINPUT* opbinput /**< OPB reading data */
    400 )
    401{
    402 SCIP_Bool hasdot;
    403 OPBEXPTYPE exptype;
    404 char* buf;
    405 int tokenlen;
    406
    407 assert(opbinput != NULL);
    408 assert(opbinput->linepos < opbinput->linebufsize);
    409
    410 /* check the token stack */
    411 if( opbinput->npushedtokens > 0 )
    412 {
    413 swapPointers(&opbinput->token, &opbinput->pushedtokens[opbinput->npushedtokens-1]);
    414 opbinput->npushedtokens--;
    415 SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", opbinput->linenumber, opbinput->token);
    416 return TRUE;
    417 }
    418
    419 /* skip delimiters */
    420 buf = opbinput->linebuf;
    421 while( isDelimChar(buf[opbinput->linepos]) )
    422 {
    423 if( buf[opbinput->linepos] == '\0' )
    424 {
    425 if( !getNextLine(scip, opbinput) )
    426 {
    427 SCIPdebugMsg(scip, "(line %d) end of file\n", opbinput->linenumber);
    428 return FALSE;
    429 }
    430 assert(opbinput->linepos == 0);
    431 /* update buf, because the linebuffer may have been reallocated */
    432 buf = opbinput->linebuf;
    433 }
    434 else
    435 opbinput->linepos++;
    436 }
    437 assert(opbinput->linepos < opbinput->linebufsize);
    438 assert(!isDelimChar(buf[opbinput->linepos]));
    439
    440 /* check if the token is a value */
    441 hasdot = FALSE;
    442 exptype = OPB_EXP_NONE;
    443 if( isValueChar(buf[opbinput->linepos], buf[opbinput->linepos+1], TRUE, &hasdot, &exptype) )
    444 {
    445 /* read value token */
    446 tokenlen = 0;
    447 do
    448 {
    449 assert(tokenlen < OPB_MAX_LINELEN);
    450 assert(!isDelimChar(buf[opbinput->linepos]));
    451 opbinput->token[tokenlen] = buf[opbinput->linepos];
    452 tokenlen++;
    453 opbinput->linepos++;
    454 }
    455 while( isValueChar(buf[opbinput->linepos], buf[opbinput->linepos+1], FALSE, &hasdot, &exptype) );
    456 }
    457 else
    458 {
    459 /* read non-value token */
    460 tokenlen = 0;
    461 do
    462 {
    463 assert(tokenlen < OPB_MAX_LINELEN);
    464 opbinput->token[tokenlen] = buf[opbinput->linepos];
    465 tokenlen++;
    466 opbinput->linepos++;
    467 if( tokenlen == 1 && isTokenChar(opbinput->token[0]) )
    468 break;
    469 }
    470 while( !isDelimChar(buf[opbinput->linepos]) && !isTokenChar(buf[opbinput->linepos]) );
    471
    472 /* if the token is an equation sense '<', '>', or '=', skip a following '='
    473 * if the token is an equality token '=' and the next character is a '<' or '>',
    474 * replace the token by the inequality sense
    475 */
    476 if( tokenlen >= 1
    477 && (opbinput->token[tokenlen-1] == '<' || opbinput->token[tokenlen-1] == '>' || opbinput->token[tokenlen-1] == '=')
    478 && buf[opbinput->linepos] == '=' )
    479 {
    480 opbinput->linepos++;
    481 }
    482 else if( opbinput->token[tokenlen-1] == '=' && (buf[opbinput->linepos] == '<' || buf[opbinput->linepos] == '>') )
    483 {
    484 opbinput->token[tokenlen-1] = buf[opbinput->linepos];
    485 opbinput->linepos++;
    486 }
    487 }
    488 assert(tokenlen < OPB_MAX_LINELEN);
    489 opbinput->token[tokenlen] = '\0';
    490
    491 SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", opbinput->linenumber, opbinput->token);
    492
    493 return TRUE;
    494}
    495
    496/** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
    497static
    499 OPBINPUT* opbinput /**< OPB reading data */
    500 )
    501{
    502 assert(opbinput != NULL);
    503 assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
    504
    505 swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->token);
    506 opbinput->npushedtokens++;
    507}
    508
    509/** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
    510static
    512 OPBINPUT* opbinput /**< OPB reading data */
    513 )
    514{
    515 assert(opbinput != NULL);
    516 assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
    517
    518 swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->tokenbuf);
    519 opbinput->npushedtokens++;
    520}
    521
    522/** swaps the current token with the token buffer */
    523static
    525 OPBINPUT* opbinput /**< OPB reading data */
    526 )
    527{
    528 assert(opbinput != NULL);
    529
    530 swapPointers(&opbinput->token, &opbinput->tokenbuf);
    531}
    532
    533/** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
    534static
    536 OPBINPUT* opbinput /**< OPB reading data */
    537 )
    538{
    539 assert(opbinput != NULL);
    540
    541 if( *(opbinput->token) == ';')
    542 return TRUE;
    543
    544 return FALSE;
    545}
    546
    547/** returns whether the current token is a sign */
    548static
    550 OPBINPUT* opbinput, /**< OPB reading data */
    551 int* sign /**< pointer to update the sign */
    552 )
    553{
    554 assert(opbinput != NULL);
    555 assert(sign != NULL);
    556 assert(*sign == +1 || *sign == -1);
    557
    558 if( strlen(opbinput->token) == 1 )
    559 {
    560 assert(opbinput->token[1] == '\0');
    561
    562 if( *opbinput->token == '+' )
    563 return TRUE;
    564 else if( *opbinput->token == '-' )
    565 {
    566 *sign *= -1;
    567 return TRUE;
    568 }
    569 }
    570
    571 return FALSE;
    572}
    573
    574/** returns whether the current token is a value */
    575static
    577 SCIP* scip, /**< SCIP data structure */
    578 OPBINPUT* opbinput, /**< OPB reading data */
    579 SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
    580 )
    581{
    582 assert(opbinput != NULL);
    583 assert(value != NULL);
    584
    585 if( SCIPstrcasecmp(opbinput->token, "INFINITY") == 0 || SCIPstrcasecmp(opbinput->token, "INF") == 0 )
    586 {
    587 *value = SCIPinfinity(scip);
    588 return TRUE;
    589 }
    590 else
    591 {
    592 double val;
    593 char* endptr;
    594
    595 val = strtod(opbinput->token, &endptr);
    596 if( endptr != opbinput->token && *endptr == '\0' )
    597 {
    598 *value = val;
    599 if( strlen(opbinput->token) > 18 )
    600 opbinput->nproblemcoeffs++;
    601 return TRUE;
    602 }
    603 }
    604
    605 return FALSE;
    606}
    607
    608/** returns whether the current token is an equation sense */
    609static
    611 OPBINPUT* opbinput, /**< OPB reading data */
    612 OPBSENSE* sense /**< pointer to store the equation sense, or NULL */
    613 )
    614{
    615 assert(opbinput != NULL);
    616
    617 if( strcmp(opbinput->token, "<") == 0 )
    618 {
    619 if( sense != NULL )
    620 *sense = OPB_SENSE_LE;
    621 return TRUE;
    622 }
    623 else if( strcmp(opbinput->token, ">") == 0 )
    624 {
    625 if( sense != NULL )
    626 *sense = OPB_SENSE_GE;
    627 return TRUE;
    628 }
    629 else if( strcmp(opbinput->token, "=") == 0 )
    630 {
    631 if( sense != NULL )
    632 *sense = OPB_SENSE_EQ;
    633 return TRUE;
    634 }
    635
    636 return FALSE;
    637}
    638
    639/** returns whether the current token is a value */
    640static
    642 SCIP* scip, /**< SCIP data structure */
    643 OPBINPUT* opbinput /**< OPB reading data */
    644 )
    645{
    646 assert(scip != NULL);
    647 assert(opbinput != NULL);
    648
    649 if( strcmp(opbinput->token, "[") == 0 )
    650 return TRUE;
    651
    652 return FALSE;
    653}
    654
    655/** returns whether the current token is a value */
    656static
    658 SCIP* scip, /**< SCIP data structure */
    659 OPBINPUT* opbinput /**< OPB reading data */
    660 )
    661{
    662 assert(scip != NULL);
    663 assert(opbinput != NULL);
    664
    665 if( strcmp(opbinput->token, "]") == 0 )
    666 return TRUE;
    667
    668 return FALSE;
    669}
    670
    671/** create binary variable with given name */
    672static
    674 SCIP* scip, /**< SCIP data structure */
    675 SCIP_VAR** var, /**< pointer to store the variable */
    676 char* name /**< name for the variable */
    677 )
    678{
    679 SCIP_VAR* newvar;
    680 SCIP_Bool dynamiccols;
    681 SCIP_Bool initial;
    682 SCIP_Bool removable;
    683
    684 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
    685 initial = !dynamiccols;
    686 removable = dynamiccols;
    687
    688 /* create new variable of the given name */
    689 SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
    690
    691 SCIP_CALL( SCIPcreateVar(scip, &newvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    692 initial, removable, NULL, NULL, NULL, NULL, NULL) );
    693 if( SCIPisExact(scip) )
    694 {
    696 }
    697 SCIP_CALL( SCIPaddVar(scip, newvar) );
    698 *var = newvar;
    699
    700 /* because the variable was added to the problem, it is captured by SCIP and we
    701 * can safely release it right now without making the returned *var invalid */
    702 SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
    703
    704 return SCIP_OKAY;
    705}
    706
    707/** returns the variable with the given name, or creates a new variable if it does not exist */
    708static
    710 SCIP* scip, /**< SCIP data structure */
    711 OPBINPUT* opbinput, /**< OPB reading data */
    712 SCIP_VAR*** vars, /**< pointer to store the variables */
    713 int* nvars, /**< pointer to store the number of variables */
    714 int* varssize /**< pointer to store the varsize, if changed (should already be initialized) */
    715 )
    716{
    717 SCIP_Bool negated;
    718 char* name;
    719
    720 assert(scip != NULL);
    721 assert(opbinput != NULL);
    722 assert(vars != NULL);
    723 assert(nvars != NULL);
    724 assert(varssize != NULL);
    725 assert(*varssize >= 0);
    726
    727 *nvars = 0;
    728
    729 name = opbinput->token;
    730 assert(name != NULL);
    731
    732 /* parse AND terms */
    733 while(!isdigit((unsigned char) *name ) && !isTokenChar(*name) && !opbinput->haserror )
    734 {
    735 SCIP_VAR* var;
    736
    737 negated = FALSE;
    738 if( *name == '~' )
    739 {
    740 negated = TRUE;
    741 ++name;
    742 }
    743
    744 var = SCIPfindVar(scip, name);
    745 if( var == NULL )
    746 {
    747 SCIP_CALL( createVariable(scip, &var, name) );
    748 }
    749
    750 if( negated )
    751 {
    752 SCIP_VAR* negvar;
    753 SCIP_CALL( SCIPgetNegatedVar(scip, var, &negvar) );
    754
    755 var = negvar;
    756 }
    757
    758 /* reallocated memory */
    759 if( *nvars == *varssize )
    760 {
    761 *varssize = SCIPcalcMemGrowSize(scip, *varssize + 1);
    762 SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
    763 }
    764
    765 (*vars)[*nvars] = var;
    766 ++(*nvars);
    767
    768 if( !getNextToken(scip, opbinput) )
    769 opbinput->haserror = TRUE;
    770
    771 name = opbinput->token;
    772 }
    773
    774 /* check if we found at least on variable */
    775 if( *nvars == 0 )
    776 syntaxError(scip, opbinput, "expected a variable name");
    777
    778 pushToken(opbinput);
    779
    780 return SCIP_OKAY;
    781}
    782
    783/** reads an objective or constraint with name and coefficients */
    784static
    786 SCIP*const scip, /**< SCIP data structure */
    787 OPBINPUT*const opbinput, /**< OPB reading data */
    788 char*const name, /**< pointer to store the name of the line; must be at least of size
    789 * OPB_MAX_LINELEN */
    790 SCIP_VAR*** linvars, /**< pointer to store the array with linear variables (must be freed by caller) */
    791 SCIP_Real** lincoefs, /**< pointer to store the array with linear coefficients (must be freed by caller) */
    792 int*const nlincoefs, /**< pointer to store the number of linear coefficients */
    793 int* lincoefssize, /**< pointer to store the size of linvars/lincoefs arrays */
    794 SCIP_VAR**** terms, /**< pointer to store the array with nonlinear variables (must be freed by caller) */
    795 SCIP_Real** termcoefs, /**< pointer to store the array with nonlinear coefficients (must be freed by caller) */
    796 int** ntermvars, /**< pointer to store the number of nonlinear variables in the terms (must be freed by caller) */
    797 int* termcoefssize, /**< pointer to store the size of terms/termcoefs */
    798 int*const ntermcoefs, /**< pointer to store the number of nonlinear coefficients */
    799 SCIP_Bool*const newsection, /**< pointer to store whether a new section was encountered */
    800 SCIP_Bool*const isNonlinear, /**< pointer to store if we have a nonlinear constraint */
    801 SCIP_Bool*const issoftcons, /**< pointer to store whether it is a soft constraint (for wbo files) */
    802 SCIP_Real*const weight /**< pointer to store the weight of the soft constraint */
    803 )
    804{
    805 SCIP_VAR** tmpvars;
    806 SCIP_Real* tmpcoefs;
    807 SCIP_Bool havesign;
    808 SCIP_Bool havevalue;
    809 SCIP_Bool haveweightstart;
    810 SCIP_Bool haveweightend;
    811 SCIP_Real coef;
    812 int coefsign;
    813 int tmpvarssize;
    814 int ntmpcoefs;
    815 int ntmpvars;
    816
    817 assert(opbinput != NULL);
    818 assert(name != NULL);
    819 assert(linvars != NULL);
    820 assert(lincoefs != NULL);
    821 assert(lincoefssize != NULL);
    822 assert(nlincoefs != NULL);
    823 assert(terms != NULL);
    824 assert(termcoefs != NULL);
    825 assert(ntermvars != NULL);
    826 assert(termcoefssize != NULL);
    827 assert(ntermcoefs != NULL);
    828 assert(newsection != NULL);
    829
    830 *linvars = NULL;
    831 *lincoefs = NULL;
    832 *lincoefssize = 0;
    833 *terms = NULL;
    834 *termcoefs = NULL;
    835 *ntermvars = NULL;
    836 *termcoefssize = 0;
    837 *name = '\0';
    838 *nlincoefs = 0;
    839 *ntermcoefs = 0;
    840 *newsection = FALSE;
    841 *isNonlinear = FALSE;
    842 *issoftcons = FALSE;
    843
    844 SCIPdebugMsg(scip, "read coefficients\n");
    845
    846 /* read the first token, which may be the name of the line */
    847 if( getNextToken(scip, opbinput) )
    848 {
    849 /* remember the token in the token buffer */
    850 swapTokenBuffer(opbinput);
    851
    852 /* get the next token and check, whether it is a colon */
    853 if( getNextToken(scip, opbinput) )
    854 {
    855 if( strcmp(opbinput->token, ":") == 0 )
    856 {
    857 /* the second token was a colon ':' the first token is a constraint name */
    858 (void)SCIPmemccpy(name, opbinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
    859
    860 name[SCIP_MAXSTRLEN-1] = '\0';
    861 SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", opbinput->linenumber, name);
    862
    863 /* all but the first coefficient need a sign */
    864 if( strcmp(name, "soft") == 0 && (SCIPgetNVars(scip) > 0 || SCIPgetNConss(scip) > 0) )
    865 {
    866 syntaxError(scip, opbinput, "Soft top cost line needs to be the first non-comment line, and without any objective function.\n");
    867 return SCIP_OKAY;
    868 }
    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 SCIPdebugMsg(scip, "(line %d) constraint has no name\n", opbinput->linenumber);
    874 pushToken(opbinput);
    875 pushBufferToken(opbinput);
    876 }
    877 }
    878 else
    879 {
    880 /* there was only one token left: push it back onto the token stack and parse it as coefficient */
    881 pushBufferToken(opbinput);
    882 }
    883 }
    884 else
    885 {
    886 assert(SCIPfeof( opbinput->file ) );
    887 opbinput->eof = TRUE;
    888 return SCIP_OKAY;
    889 }
    890
    891 /* initialize buffers for storing the coefficients */
    892 *lincoefssize = OPB_INIT_COEFSSIZE;
    893 *termcoefssize = OPB_INIT_COEFSSIZE;
    894 tmpvarssize = OPB_INIT_COEFSSIZE;
    895 SCIP_CALL( SCIPallocBlockMemoryArray(scip, linvars, *lincoefssize) );
    896 SCIP_CALL( SCIPallocBlockMemoryArray(scip, lincoefs, *lincoefssize) );
    897 SCIP_CALL( SCIPallocBlockMemoryArray(scip, terms, *termcoefssize) );
    898 SCIP_CALL( SCIPallocBlockMemoryArray(scip, termcoefs, *termcoefssize) );
    899 SCIP_CALL( SCIPallocBlockMemoryArray(scip, ntermvars, *termcoefssize) );
    900
    901 SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
    902 SCIP_CALL( SCIPallocBufferArray(scip, &tmpcoefs, tmpvarssize) );
    903
    904 /* read the coefficients */
    905 coefsign = +1;
    906 coef = 1.0;
    907 havesign = FALSE;
    908 havevalue = FALSE;
    909 haveweightstart = FALSE;
    910 haveweightend = FALSE;
    911 ntmpcoefs = 0;
    912 ntmpvars = 0;
    913
    914 while( getNextToken(scip, opbinput) && !hasError(opbinput) )
    915 {
    916 if( isEndLine(opbinput) )
    917 {
    918 *newsection = TRUE;
    919 goto TERMINATE;
    920 }
    921
    922 /* check if we reached an equation sense */
    923 if( isSense(opbinput, NULL) )
    924 {
    925 /* put the sense back onto the token stack */
    926 pushToken(opbinput);
    927 goto TERMINATE;
    928 }
    929
    930 /* check if we read a sign */
    931 if( isSign(opbinput, &coefsign) )
    932 {
    933 SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", opbinput->linenumber, coefsign);
    934 havesign = TRUE;
    935 continue;
    936 }
    937
    938 /* check if we read a value */
    939 if( isValue(scip, opbinput, &coef) )
    940 {
    941 /* coefficients without a sign are treated as "+" */
    942 if( (*nlincoefs > 0 || *ntermcoefs > 0 || ntmpcoefs > 0) && !havesign )
    943 {
    944 coefsign = 1;
    945 havesign = TRUE;
    946 }
    947
    948 SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", opbinput->linenumber, coef, coefsign);
    949 if( havevalue )
    950 {
    951 syntaxError(scip, opbinput, "two consecutive values");
    952 goto TERMINATE;
    953 }
    954 havevalue = TRUE;
    955
    956 /* if we read a wbo file, the first line should be something like "soft: <weight>;", where weight is a value or nothing */
    957 if( strcmp(name, "soft") == 0 )
    958 {
    959 assert(ntmpcoefs == 0);
    960
    961 tmpcoefs[ntmpcoefs] = coefsign * coef;
    962 ++ntmpcoefs;
    963 }
    964
    965 continue;
    966 }
    967
    968 /* check if we are reading a soft constraint line, it start with "[<weight>]", where weight is a value */
    969 if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && !havesign && !havevalue && strcmp(name, "soft") != 0 && isStartingSoftConstraintWeight(scip, opbinput) )
    970 {
    971 if( !opbinput->wbo )
    972 {
    973 SCIPwarningMessage(scip, "Found in line %d a soft constraint, without having read a starting top-cost line.\n", opbinput->linenumber);
    974 }
    975 haveweightstart = TRUE;
    976
    977 continue;
    978 }
    979 if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && havevalue && haveweightstart && isEndingSoftConstraintWeight(scip, opbinput) )
    980 {
    981 *weight = coefsign * coef;
    982 SCIPdebugMsg(scip, "(line %d) found soft constraint weight: %g\n", opbinput->linenumber, *weight);
    983
    984 coefsign = +1;
    985 havesign = FALSE;
    986 havevalue = FALSE;
    987 haveweightend = TRUE;
    988 *issoftcons = TRUE;
    989
    990 continue;
    991 }
    992
    993 /* if we read a '[' we should already read a ']', which indicates that we read a soft constraint,
    994 * we have a parsing error */
    995 if( haveweightstart != haveweightend )
    996 {
    997 syntaxError(scip, opbinput, "Wrong soft constraint.");
    998 goto TERMINATE;
    999 }
    1000
    1001 /* if we read the first non-comment line of a wbo file we should never be here */
    1002 if( strcmp(name, "soft") == 0 )
    1003 {
    1004 syntaxError(scip, opbinput, "Wrong soft top cost line.");
    1005 goto TERMINATE;
    1006 }
    1007
    1008 /* the token is a variable name: get the corresponding variables (or create a new ones) */
    1009 SCIP_CALL( getVariableOrTerm(scip, opbinput, &tmpvars, &ntmpvars, &tmpvarssize) );
    1010
    1011 if( ntmpvars > 1 )
    1012 {
    1013 /* insert non-linear term */
    1014 *isNonlinear = TRUE;
    1015
    1016 SCIPdebugMsg(scip, "(line %d) found linear term: %+g", opbinput->linenumber, coefsign * coef);
    1017#ifndef NDEBUG
    1018 {
    1019 int v;
    1020 for( v = 0; v < ntmpvars; ++v )
    1021 {
    1022 SCIPdebugMsgPrint(scip, " %s * ", SCIPvarGetName(tmpvars[v]));
    1023 }
    1024 SCIPdebugMsgPrint(scip, "\n");
    1025 }
    1026#endif
    1027 if( !SCIPisZero(scip, coef) )
    1028 {
    1029 assert(*ntermcoefs <= *termcoefssize);
    1030 /* resize the terms, ntermvars, and termcoefs array if needed */
    1031 if( *ntermcoefs >= *termcoefssize )
    1032 {
    1033 int newsize;
    1034
    1035 newsize = SCIPcalcMemGrowSize(scip, *ntermcoefs + 1);
    1036 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, terms, *termcoefssize, newsize) );
    1037 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, termcoefs, *termcoefssize, newsize) );
    1038 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, ntermvars, *termcoefssize, newsize) );
    1039 *termcoefssize = newsize;
    1040 }
    1041 assert(*ntermcoefs < *termcoefssize);
    1042
    1043 /* get memory for the last term */
    1044 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((*terms)[*ntermcoefs]), ntmpvars) ); /*lint !e866 */
    1045
    1046 /* set the number of variable in this term */
    1047 (*ntermvars)[*ntermcoefs] = ntmpvars;
    1048
    1049 /* add all variables */
    1050 for( --ntmpvars; ntmpvars >= 0; --ntmpvars )
    1051 {
    1052 (*terms)[*ntermcoefs][ntmpvars] = tmpvars[ntmpvars];
    1053 }
    1054 /* add coefficient */
    1055 (*termcoefs)[*ntermcoefs] = coefsign * coef;
    1056
    1057 /***********************/
    1058 if( !SCIPisIntegral(scip, (*termcoefs)[*ntermcoefs]) )
    1059 {
    1060 SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*termcoefs)[*ntermcoefs], opbinput->linenumber);
    1061 }
    1062
    1063 ++(*ntermcoefs);
    1064 }
    1065
    1066 /* reset the flags and coefficient value for the next coefficient */
    1067 coefsign = +1;
    1068 coef = 1.0;
    1069 havesign = FALSE;
    1070 havevalue = FALSE;
    1071 ntmpvars = 0;
    1072 }
    1073 else
    1074 {
    1075 assert(ntmpvars == 1);
    1076 /* insert linear term */
    1077 SCIPdebugMsg(scip, "(line %d) found linear term: %+g<%s>\n", opbinput->linenumber, coefsign * coef, SCIPvarGetName(tmpvars[0]));
    1078 if( !SCIPisZero(scip, coef) )
    1079 {
    1080 assert(*nlincoefs <= *lincoefssize);
    1081 /* resize the vars and coefs array if needed */
    1082 if( *nlincoefs >= *lincoefssize )
    1083 {
    1084 int newsize;
    1085
    1086 newsize = SCIPcalcMemGrowSize(scip, *nlincoefs + 1);
    1087 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, linvars, *lincoefssize, newsize) );
    1088 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, lincoefs, *lincoefssize, newsize) );
    1089 *lincoefssize = newsize;
    1090 }
    1091 assert(*nlincoefs < *lincoefssize);
    1092
    1093 /* add coefficient */
    1094 (*linvars)[*nlincoefs] = tmpvars[0];
    1095 (*lincoefs)[*nlincoefs] = coefsign * coef;
    1096
    1097 /***********************/
    1098 if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
    1099 {
    1100 SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*lincoefs)[*nlincoefs], opbinput->linenumber);
    1101 }
    1102
    1103 ++(*nlincoefs);
    1104 }
    1105
    1106 /* reset the flags and coefficient value for the next coefficient */
    1107 coefsign = +1;
    1108 coef = 1.0;
    1109 havesign = FALSE;
    1110 havevalue = FALSE;
    1111 ntmpvars = 0;
    1112 }
    1113 }
    1114
    1115 TERMINATE:
    1116 if( !opbinput->haserror )
    1117 {
    1118 /* all variables should be in the right arrays */
    1119 assert(ntmpvars == 0);
    1120 /* the following is only the case if we read topcost's of a wbo file, we need to move this topcost value to the
    1121 * right array */
    1122 if( ntmpcoefs > 0 )
    1123 {
    1124 /* maximal one topcost value is possible */
    1125 assert(ntmpcoefs == 1);
    1126 /* no other coefficient should be found here */
    1127 assert(*nlincoefs == 0 && *ntermcoefs == 0);
    1128
    1129 /* copy value */
    1130 (*lincoefs)[*nlincoefs] = tmpcoefs[0];
    1131
    1132 /***********************/
    1133 if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
    1134 {
    1135 SCIPwarningMessage(scip, "topcost not integral.\n");
    1136 }
    1137
    1138 *nlincoefs = 1;
    1139 }
    1140 }
    1141 /* clear memory */
    1142 SCIPfreeBufferArray(scip, &tmpcoefs);
    1143 SCIPfreeBufferArray(scip, &tmpvars);
    1144
    1145 return SCIP_OKAY;
    1146}
    1147
    1148/** set the objective section */
    1149static
    1151 SCIP*const scip, /**< SCIP data structure */
    1152 OPBINPUT*const opbinput, /**< OPB reading data */
    1153 const char* sense, /**< objective sense */
    1154 SCIP_Real const scale, /**< objective scale */
    1155 SCIP_VAR**const linvars, /**< array of linear variables */
    1156 SCIP_Real*const coefs, /**< array of objective values for linear variables */
    1157 int const ncoefs, /**< number of coefficients for linear part */
    1158 SCIP_VAR***const terms, /**< array with nonlinear variables */
    1159 SCIP_Real*const termcoefs, /**< array of objective values for nonlinear variables */
    1160 int*const ntermvars, /**< number of nonlinear variables in the terms */
    1161 int const ntermcoefs /**< number of nonlinear coefficients */
    1162 )
    1163{
    1164 assert(scip != NULL);
    1165 assert(opbinput != NULL);
    1166 assert(isEndLine(opbinput));
    1167 assert(ncoefs == 0 || (linvars != NULL && coefs != NULL));
    1168 assert(ntermcoefs == 0 || (terms != NULL && ntermvars != NULL && termcoefs != NULL));
    1169
    1170 if( !hasError(opbinput) )
    1171 {
    1172 SCIP_VAR* var;
    1173 char name[SCIP_MAXSTRLEN];
    1174 int v;
    1175
    1176#ifndef NDEBUG
    1177 /* check intsize validity for small int instances */
    1178 if( opbinput->intsize >= 0 && opbinput->intsize <= CHAR_BIT * (int)sizeof(unsigned long long) )
    1179 {
    1181 summand = SCIPceil(scip, ABS(summand));
    1182 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1183 unsigned long long presum;
    1184 unsigned long long intsum = (unsigned long long)summand;
    1185
    1186 for( v = 0; v < ncoefs; ++v )
    1187 {
    1188 summand = scale * coefs[v];
    1189 summand = SCIPceil(scip, ABS(summand));
    1190 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1191 presum = intsum;
    1192 intsum += (unsigned long long)summand;
    1193 assert(intsum > presum);
    1194 }
    1195
    1196 for( v = 0; v < ntermcoefs; ++v )
    1197 {
    1198 summand = scale * termcoefs[v];
    1199 summand = SCIPceil(scip, ABS(summand));
    1200 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1201 presum = intsum;
    1202 intsum += (unsigned long long)summand;
    1203 assert(intsum > presum);
    1204 }
    1205
    1206 intsum >>= opbinput->intsize;
    1207 assert(intsum == 0);
    1208 }
    1209#endif
    1210
    1211 if( strcmp(sense, "max" ) == 0 )
    1212 opbinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
    1213
    1214 /* handle non-linear terms by and-constraints */
    1215 if( ntermcoefs > 0 )
    1216 {
    1217 if( SCIPisExact(scip) )
    1218 {
    1219 SCIPerrorMessage("Non-linear objectives are not supported in exact solving mode.\n");
    1220 return SCIP_READERROR;
    1221 }
    1222
    1223 SCIP_VAR** vars;
    1224 int nvars;
    1225 int t;
    1226 SCIP_CONS* andcons;
    1227
    1228 for( t = 0; t < ntermcoefs; ++t )
    1229 {
    1230 assert(terms != NULL); /* for lint */
    1231 assert(ntermvars != NULL);
    1232 assert(termcoefs != NULL);
    1233
    1234 vars = terms[t];
    1235 nvars = ntermvars[t];
    1236 assert(vars != NULL);
    1237 assert(nvars > 1);
    1238
    1239 /* @todo: reuse equivalent terms */
    1240 /* create auxiliary variable */
    1241 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"obj_%d", t);
    1242 SCIP_CALL( SCIPcreateVarImpl(scip, &var, name, 0.0, 1.0, scale * termcoefs[t],
    1244
    1245 /* add auxiliary variable to the problem */
    1246 SCIP_CALL( SCIPaddVar(scip, var) );
    1247
    1248#ifdef WITH_DEBUG_SOLUTION
    1249 if( SCIPdebugIsMainscip(scip) )
    1250 {
    1251 SCIP_Real val = 0.0;
    1252
    1253 for( v = nvars - 1; v >= 0; --v )
    1254 {
    1255 SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
    1256 assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
    1257
    1258 if( val < 0.5 )
    1259 break;
    1260 }
    1261 SCIP_CALL( SCIPdebugAddSolVal(scip, var, (val < 0.5) ? 0.0 : 1.0) );
    1262 }
    1263#endif
    1264
    1265 /* @todo: check whether all constraint creation flags are the best option */
    1266 /* create and-constraint */
    1267 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "obj_andcons_%d", t);
    1268 SCIP_CALL( SCIPcreateConsAnd(scip, &andcons, name, var, nvars, vars,
    1269 TRUE, TRUE, TRUE, TRUE, TRUE,
    1270 FALSE, FALSE, FALSE, FALSE, FALSE) );
    1271 SCIP_CALL( SCIPaddCons(scip, andcons) );
    1272 SCIPdebugPrintCons(scip, andcons, NULL);
    1273 SCIP_CALL( SCIPreleaseCons(scip, &andcons) );
    1274
    1275 SCIP_CALL( SCIPreleaseVar(scip, &var) );
    1276 }
    1277 }
    1278 /* set the objective values */
    1279 for( v = 0; v < ncoefs; ++v )
    1280 {
    1281 assert(linvars != NULL); /* for lint */
    1282 assert(coefs != NULL);
    1283
    1284 if( SCIPisExact(scip) )
    1285 {
    1286 SCIP_RETCODE retcode = SCIP_OKAY;
    1287 SCIP_RATIONAL* obj;
    1288
    1290
    1291 if( SCIPvarIsNegated(linvars[v]) )
    1292 {
    1293 SCIP_VAR* negvar = SCIPvarGetNegationVar(linvars[v]);
    1294
    1295 SCIPrationalSetReal(obj, coefs[v]);
    1296 SCIP_CALL_TERMINATE( retcode, SCIPaddOrigObjoffsetExact(scip, obj), TERMINATE );
    1297
    1298 SCIPrationalMultReal(obj, obj, -scale);
    1299 SCIPrationalAdd(obj, obj, SCIPvarGetObjExact(negvar));
    1300 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, negvar, obj), TERMINATE );
    1301 }
    1302 else
    1303 {
    1304 SCIPrationalSetReal(obj, coefs[v]);
    1305 SCIPrationalMultReal(obj, obj, scale);
    1306 SCIPrationalAdd(obj, obj, SCIPvarGetObjExact(linvars[v]));
    1307 SCIP_CALL_TERMINATE( retcode, SCIPchgVarObjExact(scip, linvars[v], obj), TERMINATE );
    1308 }
    1309
    1310 TERMINATE:
    1312 SCIP_CALL( retcode );
    1313 }
    1314 else
    1315 {
    1316 if( SCIPvarIsNegated(linvars[v]) )
    1317 {
    1318 SCIP_VAR* negvar = SCIPvarGetNegationVar(linvars[v]);
    1319
    1320 SCIP_CALL( SCIPaddOrigObjoffset(scip, coefs[v]) );
    1321 SCIP_CALL( SCIPaddVarObj(scip, negvar, -scale * coefs[v]) );
    1322 }
    1323 else
    1324 {
    1325 SCIP_CALL( SCIPaddVarObj(scip, linvars[v], scale * coefs[v]) );
    1326 }
    1327 }
    1328 }
    1329 }
    1330
    1331 return SCIP_OKAY;
    1332}
    1333
    1334/** reads the constraints section */
    1335static
    1337 SCIP* scip, /**< SCIP data structure */
    1338 OPBINPUT* opbinput, /**< OPB reading data */
    1339 SCIP_Real objscale, /**< objective scale */
    1340 int* nNonlinearConss /**< pointer to store number of nonlinear constraints */
    1341 )
    1342{
    1343 char name[OPB_MAX_LINELEN];
    1344 SCIP_CONS* cons;
    1345 SCIP_VAR** linvars;
    1346 SCIP_Real* lincoefs;
    1347 int lincoefssize;
    1348 int nlincoefs;
    1349 SCIP_VAR*** terms;
    1350 SCIP_Real* termcoefs;
    1351 int* ntermvars;
    1352 int termcoefssize;
    1353 int ntermcoefs;
    1354 OPBSENSE sense;
    1355 SCIP_RETCODE retcode;
    1356 SCIP_Real sidevalue;
    1357 SCIP_Real lhs;
    1358 SCIP_Real rhs;
    1359 SCIP_Bool newsection;
    1360 SCIP_Bool initialconss;
    1361 SCIP_Bool dynamicconss;
    1362 SCIP_Bool dynamicrows;
    1363 SCIP_Bool initial;
    1365 SCIP_Bool enforce;
    1366 SCIP_Bool check;
    1367 SCIP_Bool propagate;
    1368 SCIP_Bool local;
    1369 SCIP_Bool modifiable;
    1370 SCIP_Bool dynamic;
    1371 SCIP_Bool removable;
    1372 SCIP_Bool isNonlinear;
    1373 int sidesign;
    1374 SCIP_Bool issoftcons;
    1375 SCIP_Real weight;
    1376 SCIP_VAR* indvar;
    1377 char indname[SCIP_MAXSTRLEN];
    1378 int t;
    1379
    1380 assert(scip != NULL);
    1381 assert(opbinput != NULL);
    1382 assert(nNonlinearConss != NULL);
    1383
    1384 weight = -SCIPinfinity(scip);
    1385 retcode = SCIP_OKAY;
    1386
    1387 /* read the objective coefficients */
    1388 SCIP_CALL( readCoefficients(scip, opbinput, name, &linvars, &lincoefs, &nlincoefs, &lincoefssize, &terms, &termcoefs, &ntermvars, &termcoefssize,
    1389 &ntermcoefs, &newsection, &isNonlinear, &issoftcons, &weight) );
    1390
    1391 if( hasError(opbinput) || opbinput->eof )
    1392 goto TERMINATE;
    1393 if( newsection )
    1394 {
    1395 if( strcmp(name, "min") == 0 || strcmp(name, "max") == 0 )
    1396 {
    1397 if( opbinput->wbo )
    1398 {
    1399 syntaxError(scip, opbinput, "Cannot have an objective function when having soft constraints.\n");
    1400 goto TERMINATE;
    1401 }
    1402
    1403 /* set objective function */
    1404 SCIP_CALL_TERMINATE( retcode, setObjective(scip, opbinput, name, objscale, linvars, lincoefs, nlincoefs, terms, termcoefs, ntermvars, ntermcoefs), TERMINATE );
    1405 }
    1406 else if( strcmp(name, "soft") == 0 )
    1407 {
    1408 /* we have a "weighted boolean optimization"-file(wbo) */
    1409 opbinput->wbo = TRUE;
    1410 if( nlincoefs == 0 )
    1411 opbinput->topcost = SCIPinfinity(scip);
    1412 else
    1413 {
    1414 assert(nlincoefs == 1);
    1415 assert(lincoefs != NULL);
    1416 opbinput->topcost = lincoefs[0];
    1417 }
    1418 SCIPdebugMsg(scip, "Weighted Boolean Optimization problem has topcost of %g\n", opbinput->topcost);
    1419 }
    1420 else if( nlincoefs > 0 )
    1421 syntaxError(scip, opbinput, "expected constraint sense '=' or '>='");
    1422 goto TERMINATE;
    1423 }
    1424
    1425 /* read the constraint sense */
    1426 if( !getNextToken(scip, opbinput) )
    1427 {
    1428 syntaxError(scip, opbinput, "expected constraint sense.");
    1429 goto TERMINATE;
    1430 }
    1431 if( !isSense(opbinput, &sense) )
    1432 {
    1433 syntaxError(scip, opbinput, "expected constraint sense '=' or '>='.");
    1434 goto TERMINATE;
    1435 }
    1436
    1437 /* read the right hand side */
    1438 sidesign = +1;
    1439 if( !getNextToken(scip, opbinput) )
    1440 {
    1441 syntaxError(scip, opbinput, "missing right hand side");
    1442 goto TERMINATE;
    1443 }
    1444 if( isSign(opbinput, &sidesign) )
    1445 {
    1446 if( !getNextToken(scip, opbinput) )
    1447 {
    1448 syntaxError(scip, opbinput, "missing value of right hand side");
    1449 goto TERMINATE;
    1450 }
    1451 }
    1452 if( !isValue(scip, opbinput, &sidevalue) )
    1453 {
    1454 syntaxError(scip, opbinput, "expected value as right hand side");
    1455 goto TERMINATE;
    1456 }
    1457 sidevalue *= sidesign;
    1458
    1459 /* check if we reached the line end */
    1460 if( !getNextToken(scip, opbinput) || !isEndLine(opbinput) )
    1461 {
    1462 syntaxError(scip, opbinput, "expected endline character ';'");
    1463 goto TERMINATE;
    1464 }
    1465
    1466 /* assign the left and right hand side, depending on the constraint sense */
    1467 switch( sense ) /*lint !e530*/
    1468 {
    1469 case OPB_SENSE_GE:
    1470 lhs = sidevalue;
    1471 rhs = SCIPinfinity(scip);
    1472 break;
    1473 case OPB_SENSE_LE:
    1474 lhs = -SCIPinfinity(scip);
    1475 rhs = sidevalue;
    1476 break;
    1477 case OPB_SENSE_EQ:
    1478 lhs = sidevalue;
    1479 rhs = sidevalue;
    1480 break;
    1481 case OPB_SENSE_NOTHING:
    1482 default:
    1483 SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
    1484 retcode = SCIP_INVALIDDATA;
    1485 goto TERMINATE;
    1486 }
    1487
    1488#ifndef NDEBUG
    1489 /* check intsize validity for small int instances */
    1490 if( opbinput->intsize >= 0 && opbinput->intsize <= CHAR_BIT * (int)sizeof(unsigned long long) )
    1491 {
    1492 SCIP_Real summand = SCIPceil(scip, ABS(sidevalue));
    1493 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1494 unsigned long long presum;
    1495 unsigned long long intsum = (unsigned long long)summand;
    1496
    1497 for( t = 0; t < nlincoefs; ++t )
    1498 {
    1499 summand = SCIPceil(scip, ABS(lincoefs[t]));
    1500 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1501 presum = intsum;
    1502 intsum += (unsigned long long)summand;
    1503 assert(intsum > presum);
    1504 }
    1505
    1506 for( t = 0; t < ntermcoefs; ++t )
    1507 {
    1508 summand = SCIPceil(scip, ABS(termcoefs[t]));
    1509 assert(summand <= (SCIP_Real)ULLONG_MAX);
    1510 presum = intsum;
    1511 intsum += (unsigned long long)summand;
    1512 assert(intsum > presum);
    1513 }
    1514
    1515 intsum >>= opbinput->intsize;
    1516 assert(intsum == 0);
    1517 }
    1518#endif
    1519
    1520 /* create and add the linear constraint */
    1521 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
    1522 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
    1523 SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/dynamicconss", &dynamicconss) );
    1524
    1525 initial = initialconss;
    1526 separate = TRUE;
    1527 enforce = TRUE;
    1528 check = TRUE;
    1529 propagate = TRUE;
    1530 local = FALSE;
    1531 modifiable = FALSE;
    1532 dynamic = FALSE;/*dynamicconss;*/
    1533 removable = dynamicrows;
    1534
    1535 /* create corresponding constraint */
    1536 if( issoftcons )
    1537 {
    1538 (void) SCIPsnprintf(indname, SCIP_MAXSTRLEN, INDICATORVARNAME"%d", opbinput->nindvars);
    1539 ++(opbinput->nindvars);
    1540 SCIP_CALL( createVariable(scip, &indvar, indname) );
    1541
    1542 assert(!SCIPisInfinity(scip, -weight));
    1543 SCIP_CALL( SCIPchgVarObj(scip, indvar, objscale * weight) );
    1544 }
    1545 else
    1546 indvar = NULL;
    1547
    1548 if( ntermcoefs > 0 || issoftcons )
    1549 {
    1550 if( SCIPisExact(scip) )
    1551 {
    1552 SCIPerrorMessage("Non-linear constraints are not supported in exact solving mode.\n");
    1553 retcode = SCIP_READERROR;
    1554 goto TERMINATE;
    1555 }
    1556#if GENCONSNAMES == TRUE
    1557 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean%d", opbinput->consnumber);
    1558 ++(opbinput->consnumber);
    1559#else
    1560 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean");
    1561#endif
    1562 retcode = SCIPcreateConsPseudoboolean(scip, &cons, name, linvars, nlincoefs, lincoefs, terms, ntermcoefs,
    1563 ntermvars, termcoefs, indvar, weight, issoftcons, lhs, rhs, initial, separate, enforce, check, propagate, /*lint !e644*/
    1564 local, modifiable, dynamic, removable, FALSE);
    1565 if( retcode != SCIP_OKAY )
    1566 goto TERMINATE;
    1567 }
    1568 else
    1569 {
    1570#if GENCONSNAMES == TRUE
    1571 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear%d", opbinput->consnumber);
    1572 ++(opbinput->consnumber);
    1573#else
    1574 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear");
    1575#endif
    1576 if( !SCIPisExact(scip) )
    1577 {
    1578 retcode = SCIPcreateConsLinear(scip, &cons, name, nlincoefs, linvars, lincoefs, lhs, rhs, /*lint !e644*/
    1579 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
    1580 }
    1581 else
    1582 {
    1583 SCIP_RATIONAL** lincoefsrat;
    1584 SCIP_RATIONAL* lhsrat;
    1585 SCIP_RATIONAL* rhsrat;
    1586
    1587 SCIP_CALL( SCIPrationalCreateBufferArray(SCIPbuffer(scip), &lincoefsrat, nlincoefs) );
    1590 SCIPrationalSetReal(lhsrat, lhs); /*lint !e644*/
    1591 SCIPrationalSetReal(rhsrat, rhs); /*lint !e644*/
    1592 for( int i = 0; i < nlincoefs; ++i )
    1593 SCIPrationalSetReal(lincoefsrat[i], lincoefs[i]);
    1594 retcode = SCIPcreateConsExactLinear(scip, &cons, name, nlincoefs, linvars, lincoefsrat, lhsrat, rhsrat,
    1595 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
    1598 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &lincoefsrat, nlincoefs);
    1599 }
    1600
    1601 if( retcode != SCIP_OKAY )
    1602 goto TERMINATE;
    1603 }
    1604
    1605 SCIP_CALL( SCIPaddCons(scip, cons) );
    1606 SCIPdebugMsg(scip, "(line %d) created constraint: ", opbinput->linenumber);
    1608 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
    1609
    1610 if( isNonlinear )
    1611 ++(*nNonlinearConss);
    1612
    1613 TERMINATE:
    1614
    1615 /* free memory */
    1616 for( t = ntermcoefs - 1; t >= 0; --t )
    1617 {
    1618 assert(terms != NULL); /* for lint */
    1619 SCIPfreeBlockMemoryArray(scip, &(terms[t]), ntermvars[t]);
    1620 }
    1621
    1622 SCIPfreeBlockMemoryArrayNull(scip, &ntermvars, termcoefssize);
    1623 SCIPfreeBlockMemoryArrayNull(scip, &termcoefs, termcoefssize);
    1624 SCIPfreeBlockMemoryArrayNull(scip, &terms, termcoefssize);
    1625 SCIPfreeBlockMemoryArrayNull(scip, &lincoefs, lincoefssize);
    1626 SCIPfreeBlockMemoryArrayNull(scip, &linvars, lincoefssize);
    1627
    1628 SCIP_CALL( retcode );
    1629
    1630 return SCIP_OKAY;
    1631}
    1632
    1633/** read the first comment line which usually contains information about (1) the max size of "and" products and (2) the
    1634 * "intsize" which represents the number of bits required to represent the sum of the absolute values of all integers
    1635 * that appear in any constraint or the objective */
    1636static
    1638 SCIP* scip, /**< SCIP data structure */
    1639 OPBINPUT* opbinput, /**< OPB reading data */
    1640 SCIP_Real* objscale, /**< pointer to store objective scale */
    1641 SCIP_Real* objoffset /**< pointer to store objective offset */
    1642 )
    1643{
    1644 assert(scip != NULL);
    1645 assert(opbinput != NULL);
    1646 assert(objoffset != NULL);
    1647
    1648 *objscale = 1.0;
    1649 *objoffset = 0.0;
    1650 opbinput->linebuf[opbinput->linebufsize - 2] = '\0';
    1651 opbinput->intsize = -1;
    1652
    1653 while( SCIPfgets(opbinput->linebuf, opbinput->linebufsize, opbinput->file) != NULL )
    1654 {
    1655 char* commentstart;
    1656 char* str;
    1657
    1658 /* if line is too long for our buffer reallocate buffer */
    1659 while( opbinput->linebuf[opbinput->linebufsize - 2] != '\0' )
    1660 {
    1661 int newsize;
    1662
    1663 newsize = SCIPcalcMemGrowSize(scip, opbinput->linebufsize + 1);
    1664 SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &opbinput->linebuf, opbinput->linebufsize, newsize) );
    1665
    1666 opbinput->linebuf[newsize-2] = '\0';
    1667 if ( SCIPfgets(opbinput->linebuf + opbinput->linebufsize - 1, newsize - opbinput->linebufsize + 1, opbinput->file) == NULL )
    1668 return SCIP_READERROR;
    1669 opbinput->linebufsize = newsize;
    1670 }
    1671 opbinput->linebuf[opbinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
    1672
    1673 /* locate comment character */
    1674 commentstart = strpbrk(opbinput->linebuf, commentchars);
    1675
    1676 /* no comment line */
    1677 if( commentstart == NULL )
    1678 break;
    1679
    1680#ifdef SCIP_DISABLED_CODE
    1681 /* search for "#product= xyz" in comment line, where xyz represents the number of and constraints */
    1682 str = strstr(opbinput->linebuf, "#product= ");
    1683 if( str != NULL )
    1684 {
    1685 const char delimchars[] = " \t";
    1686 char* pos;
    1687
    1688 str += strlen("#product= ");
    1689
    1690 pos = strtok(str, delimchars);
    1691
    1692 if( pos != NULL )
    1693 {
    1694 SCIPdebugMsg(scip, "%d products supposed to be in file.\n", atoi(pos));
    1695 }
    1696
    1697 pos = strtok (NULL, delimchars);
    1698
    1699 if( pos != NULL && strcmp(pos, "sizeproduct=") == 0 )
    1700 {
    1701 pos = strtok (NULL, delimchars);
    1702 if( pos != NULL )
    1703 {
    1704 SCIPdebugMsg(scip, "sizeproducts = %d\n", atoi(pos));
    1705 }
    1706 }
    1707 }
    1708#endif
    1709
    1710 /* search for "intsize= xyz" in comment line */
    1711 str = strstr(opbinput->linebuf, "intsize= ");
    1712 if( str != NULL )
    1713 {
    1714 const char delimchars[] = " \t";
    1715 char* pos;
    1716
    1717 str += strlen("intsize= ");
    1718
    1719 pos = strtok(str, delimchars);
    1720
    1721 if( pos != NULL )
    1722 {
    1723 opbinput->intsize = atoi(pos);
    1724 SCIPdebugMsg(scip, "number of bits required to represent sum of the absolute values of all integers appearing in a constraint or objective function = %d\n", opbinput->intsize);
    1725 }
    1726 }
    1727
    1728 /* search for "Obj. scale : <number>" in comment line */
    1729 str = strstr(opbinput->linebuf, "Obj. scale : ");
    1730 if( str != NULL )
    1731 {
    1732 str += strlen("Obj. scale : ");
    1733 *objscale = atof(str);
    1734 }
    1735
    1736 /* search for "Obj. offset : <number>" in comment line */
    1737 str = strstr(opbinput->linebuf, "Obj. offset : ");
    1738 if( str != NULL )
    1739 {
    1740 str += strlen("Obj. offset : ");
    1741 *objoffset = atof(str);
    1742 }
    1743
    1744 /* make sure that comment vanishes */
    1745 *commentstart = '\0';
    1746 }
    1747
    1748 return SCIP_OKAY;
    1749}
    1750
    1751/** reads an OPB file */
    1752static
    1754 SCIP* scip, /**< SCIP data structure */
    1755 SCIP_READER* reader, /**< the file reader itself */
    1756 OPBINPUT* opbinput, /**< OPB reading data */
    1757 const char* filename /**< name of the input file */
    1758 )
    1759{
    1760 SCIP_READERDATA* readerdata = SCIPreaderGetData(reader);
    1761 SCIP_RETCODE retcode = SCIP_OKAY;
    1762 SCIP_Real objscale;
    1763 SCIP_Real objoffset;
    1764 int nNonlinearConss;
    1765 int i;
    1766
    1767 assert(scip != NULL);
    1768 assert(readerdata != NULL);
    1769 assert(opbinput != NULL);
    1770
    1771 /* open file */
    1772 opbinput->file = SCIPfopen(filename, "r");
    1773 if( opbinput->file == NULL )
    1774 {
    1775 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    1776 SCIPprintSysError(filename);
    1777 return SCIP_NOFILE;
    1778 }
    1779
    1780 /* @todo: reading additional information about the number of and constraints in comments to avoid reallocating
    1781 * "opbinput.andconss"
    1782 */
    1783
    1784 /* read the first comment line which contains information about size of products and coefficients */
    1785 SCIP_CALL_TERMINATE( retcode, getCommentLineData(scip, opbinput, &objscale, &objoffset), TERMINATE2 );
    1786
    1787 if( readerdata->maxintsize >= 0 && opbinput->intsize > readerdata->maxintsize )
    1788 {
    1789 SCIPinfoMessage(scip, NULL, "Intsize %d exceeds %d maximum.\n", opbinput->intsize, readerdata->maxintsize);
    1790 retcode = SCIP_INVALIDDATA;
    1791 goto TERMINATE2;
    1792 }
    1793
    1794 /* create problem */
    1795 SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE2 );
    1796
    1797 /* opb format supports only minimization; therefore, flip objective sense for negative objective scale */
    1798 if( objscale < 0.0 )
    1799 opbinput->objsense = (SCIP_OBJSENSE)(-1 * (int)(opbinput->objsense));
    1800
    1801 if( ! SCIPisZero(scip, objoffset) )
    1802 {
    1803 SCIP_CALL_TERMINATE( retcode, SCIPaddOrigObjoffset(scip, objscale * objoffset), TERMINATE2 );
    1804 }
    1805
    1806 nNonlinearConss = 0;
    1807
    1808 while( !SCIPfeof( opbinput->file ) && !hasError(opbinput) )
    1809 {
    1810 SCIP_CALL_TERMINATE( retcode, readConstraints(scip, opbinput, objscale, &nNonlinearConss), TERMINATE2 );
    1811 }
    1812
    1813 /* if we read a wbo file we need to make sure that the top cost won't be exceeded */
    1814 if( opbinput->wbo )
    1815 {
    1816 SCIP_VAR** vars;
    1817 SCIP_VAR** topcostvars;
    1818 SCIP_CONS* topcostcons;
    1819 SCIP_Real* topcosts;
    1820 SCIP_Real topcostrhs;
    1821 int nvars;
    1822 int ntopcostvars;
    1823
    1824 nvars = SCIPgetNVars(scip);
    1825 vars = SCIPgetVars(scip);
    1826 assert(nvars > 0 || vars != NULL);
    1827
    1828 SCIP_CALL( SCIPallocBufferArray(scip, &topcostvars, nvars) );
    1829 SCIP_CALL( SCIPallocBufferArray(scip, &topcosts, nvars) );
    1830
    1831 ntopcostvars = 0;
    1832 for( i = nvars - 1; i >= 0; --i )
    1833 {
    1834 if( !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
    1835 {
    1836 topcostvars[ntopcostvars] = vars[i];
    1837 topcosts[ntopcostvars] = SCIPvarGetObj(vars[i]);
    1838 ++ntopcostvars;
    1839 }
    1840 }
    1841 topcostrhs = SCIPceil(scip, opbinput->topcost - 1.0);
    1842
    1843 if( !SCIPisExact(scip) )
    1844 {
    1845 SCIP_CALL_TERMINATE( retcode, SCIPcreateConsLinear(scip, &topcostcons, TOPCOSTCONSNAME, ntopcostvars, topcostvars, topcosts,
    1846 -SCIPinfinity(scip), topcostrhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE), TERMINATE1 );
    1847 }
    1848 else
    1849 {
    1850 SCIP_RATIONAL** topcostsrat;
    1851 SCIP_RATIONAL* lhs;
    1852 SCIP_RATIONAL* rhs;
    1853
    1854 SCIP_CALL( SCIPrationalCreateBufferArray(SCIPbuffer(scip), &topcostsrat, ntopcostvars) );
    1858 SCIPrationalSetReal(rhs, topcostrhs);
    1859 for( int j = 0; j < ntopcostvars; ++j )
    1860 SCIPrationalSetReal(topcostsrat[j], topcosts[j]);
    1861 retcode = SCIPcreateConsExactLinear(scip, &topcostcons, TOPCOSTCONSNAME, ntopcostvars, topcostvars,
    1862 topcostsrat, lhs, rhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE);
    1865 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &topcostsrat, ntopcostvars);
    1866 if( retcode != SCIP_OKAY )
    1867 goto TERMINATE1;
    1868 }
    1869
    1870 SCIP_CALL_TERMINATE( retcode, SCIPaddCons(scip, topcostcons), TERMINATE1 );
    1871 SCIPdebugPrintCons(scip, topcostcons, NULL);
    1872 SCIP_CALL_TERMINATE( retcode, SCIPreleaseCons(scip, &topcostcons), TERMINATE1 );
    1873
    1874 TERMINATE1:
    1875 SCIPfreeBufferArray(scip, &topcosts);
    1876 SCIPfreeBufferArray(scip, &topcostvars);
    1877 }
    1878
    1879 TERMINATE2:
    1880 /* close file */
    1881 SCIPfclose(opbinput->file);
    1882
    1883 return retcode;
    1884}
    1885
    1886
    1887/*
    1888 * Local methods (for writing)
    1889 */
    1890
    1891/** transforms given and constraint variables to the corresponding active or negated variables */
    1892static
    1894 SCIP*const scip, /**< SCIP data structure */
    1895 SCIP_VAR**const vars, /**< vars array to get active variables for */
    1896 int const nvars, /**< pointer to number of variables and values in vars and vals array */
    1897 SCIP_Bool const transformed /**< transformed constraint? */
    1898 )
    1899{
    1900 SCIP_Bool negated;
    1901 int v;
    1902
    1903 assert( scip != NULL );
    1904 assert( vars != NULL );
    1905 assert( nvars > 0 );
    1906
    1907 if( transformed )
    1908 {
    1909 for( v = nvars - 1; v >= 0; --v )
    1910 {
    1911 /* gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
    1912 * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
    1913 */
    1914 SCIP_CALL( SCIPgetBinvarRepresentative( scip, vars[v], &vars[v], &negated) );
    1915 }
    1916 }
    1917 else
    1918 {
    1919 SCIP_Real scalar;
    1920 SCIP_Real constant;
    1921
    1922 for( v = nvars - 1; v >= 0; --v )
    1923 {
    1924 scalar = 1.0;
    1925 constant = 0.0;
    1926
    1927 /* retransforms given variable, scalar and constant to the corresponding original variable, scalar and constant,
    1928 * if possible; if the retransformation is impossible, NULL is returned as variable
    1929 */
    1930 SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalar, &constant) );
    1931
    1932 if( vars[v] == NULL )
    1933 {
    1934 SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable.\n");
    1935 return SCIP_INVALIDDATA;
    1936 }
    1937 if( SCIPisEQ(scip, scalar, -1.0) && SCIPisEQ(scip, constant, 1.0) )
    1938 {
    1939 SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &vars[v]) );
    1940 }
    1941 else
    1942 {
    1943 if( !SCIPisEQ(scip, scalar, 1.0) || !SCIPisZero(scip, constant) )
    1944 {
    1945 SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable or a negated variable of an original variable (scalar = %g, constant = %g).\n", scalar, constant);
    1946 return SCIP_INVALIDDATA;
    1947 }
    1948 }
    1949 }
    1950 }
    1951
    1952 return SCIP_OKAY;
    1953}
    1954
    1955/** transforms given variables, real scalars, and real constant to the corresponding active variables, real scalars, and real constant */
    1956static
    1958 SCIP* scip, /**< SCIP data structure */
    1959 SCIP_VAR*** vars, /**< vars array to get active variables for */
    1960 SCIP_Real** scalars, /**< real scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
    1961 int* nvars, /**< pointer to number of variables and values in vars and vals array */
    1962 int* varssize, /**< pointer to size of variable array */
    1963 SCIP_Real* constant, /**< pointer to real constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
    1964 SCIP_Bool transformed /**< transformed constraint? */
    1965 )
    1966{
    1967 int requiredsize;
    1968 int v;
    1969
    1970 assert(scip != NULL);
    1971 assert(vars != NULL);
    1972 assert(scalars != NULL);
    1973 assert(nvars != NULL);
    1974 assert(varssize != NULL);
    1975 assert(constant != NULL);
    1976
    1977 if( transformed )
    1978 {
    1979 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize) );
    1980
    1981 if( requiredsize > *varssize )
    1982 {
    1983 SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
    1984 SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
    1985 *varssize = requiredsize;
    1986 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize) );
    1987 }
    1988 assert(requiredsize == *nvars);
    1989 }
    1990 else
    1991 {
    1992 for( v = 0; v < *nvars; ++v )
    1993 {
    1994 SCIP_CALL( SCIPvarGetOrigvarSum(*vars + v, *scalars + v, constant) );
    1995
    1996 if( (*vars)[v] == NULL )
    1997 return SCIP_INVALIDDATA;
    1998 }
    1999 }
    2000
    2001 return SCIP_OKAY;
    2002}
    2003
    2004/** transforms given variables, exact scalars, and exact constant to the corresponding active variables, exact scalars, and exact constant */
    2005static
    2007 SCIP* scip, /**< SCIP data structure */
    2008 SCIP_VAR*** vars, /**< vars array to get active variables for */
    2009 SCIP_RATIONAL*** scalars, /**< exact scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
    2010 int* nvars, /**< pointer to number of variables and values in vars and vals array */
    2011 int* varssize, /**< pointer to size of variable array */
    2012 SCIP_RATIONAL* constant, /**< pointer to exact constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
    2013 SCIP_Bool transformed /**< transformed constraint? */
    2014 )
    2015{
    2016 int requiredsize;
    2017 int v;
    2018
    2019 assert(scip != NULL);
    2020 assert(vars != NULL);
    2021 assert(scalars != NULL);
    2022 assert(nvars != NULL);
    2023 assert(varssize != NULL);
    2024 assert(constant != NULL);
    2025
    2026 if( transformed )
    2027 {
    2028 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize, TRUE) );
    2029
    2030 if( requiredsize > *varssize )
    2031 {
    2032 SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
    2033 SCIP_CALL( SCIPrationalReallocBufferArray(SCIPbuffer(scip), scalars, *varssize, requiredsize) );
    2034 *varssize = requiredsize;
    2035 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize, TRUE) );
    2036 }
    2037 assert(requiredsize == *nvars);
    2038 }
    2039 else
    2040 {
    2041 for( v = 0; v < *nvars; ++v )
    2042 {
    2043 SCIP_CALL( SCIPvarGetOrigvarSumExact(*vars + v, (*scalars)[v], constant) );
    2044
    2045 if( (*vars)[v] == NULL )
    2046 return SCIP_INVALIDDATA;
    2047 }
    2048 }
    2049
    2050 return SCIP_OKAY;
    2051}
    2052
    2053/* computes all and-resultants and their corresponding constraint variables */
    2054static
    2056 SCIP*const scip, /**< SCIP data structure */
    2057 SCIP_Bool const transformed, /**< transformed problem? */
    2058 SCIP_VAR*** resvars, /**< pointer to store all resultant variables */
    2059 int* nresvars, /**< pointer to store the number of all resultant variables */
    2060 SCIP_VAR**** andvars, /**< pointer to store to all resultant variables their corresponding active( or negated) and-constraint variables */
    2061 int** nandvars, /**< pointer to store the number of all corresponding and-variables to their corresponding resultant variable */
    2062 SCIP_Bool*const existandconshdlr, /**< pointer to store whether the and-constrainthandler exists*/
    2063 SCIP_Bool*const existands /**< pointer to store if their exists some and-constraints */
    2064 )
    2065{
    2066 SCIP_CONSHDLR* conshdlr;
    2067
    2068 assert(scip != NULL);
    2069 assert(resvars != NULL);
    2070 assert(nresvars != NULL);
    2071 assert(andvars != NULL);
    2072 assert(nandvars != NULL);
    2073 assert(existandconshdlr != NULL);
    2074 assert(existands != NULL);
    2075
    2076 *resvars = NULL;
    2077 *nandvars = NULL;
    2078 *andvars = NULL;
    2079 *nresvars = 0;
    2080
    2081 /* detect all and-resultants */
    2082 conshdlr = SCIPfindConshdlr(scip, "and");
    2083 if( conshdlr != NULL )
    2084 {
    2085 SCIP_CONS** andconss;
    2086 int nandconss;
    2087 int* shouldnotbeinand;
    2088 int a;
    2089 int c;
    2090 int r;
    2091 int v;
    2092 int pos;
    2093 int ncontainedands;
    2094
    2095 andconss = NULL;
    2096 nandconss = 0;
    2097 *existandconshdlr = TRUE;
    2098
    2099 /* if we write the original problem we need to get the original and constraints */
    2100 if( !transformed )
    2101 {
    2102 SCIP_CONS** origconss;
    2103 int norigconss;
    2104
    2105 origconss = SCIPgetOrigConss(scip);
    2106 norigconss = SCIPgetNOrigConss(scip);
    2107
    2108 /* allocate memory for all possible and-constraints */
    2109 SCIP_CALL( SCIPallocBufferArray(scip, &andconss, norigconss) );
    2110
    2111 /* collect all original and-constraints */
    2112 for( c = norigconss - 1; c >= 0; --c )
    2113 {
    2114 conshdlr = SCIPconsGetHdlr(origconss[c]);
    2115 assert( conshdlr != NULL );
    2116
    2117 if( strcmp(SCIPconshdlrGetName(conshdlr), "and") == 0 )
    2118 {
    2119 andconss[nandconss] = origconss[c];
    2120 ++nandconss;
    2121 }
    2122 }
    2123 }
    2124 else
    2125 {
    2126 nandconss = SCIPconshdlrGetNConss(conshdlr);
    2127 andconss = SCIPconshdlrGetConss(conshdlr);
    2128 }
    2129
    2130 assert(andconss != NULL || nandconss == 0);
    2131
    2132 *nresvars = nandconss;
    2133
    2134 if( nandconss > 0 )
    2135 {
    2136 *existands = TRUE;
    2137
    2138 assert(andconss != NULL);
    2139
    2140 SCIP_CALL( SCIPallocMemoryArray(scip, resvars, *nresvars) );
    2141 SCIP_CALL( SCIPallocMemoryArray(scip, andvars, *nresvars) );
    2142 SCIP_CALL( SCIPallocMemoryArray(scip, nandvars, *nresvars) );
    2143
    2144 /* collect all and-constraint variables */
    2145 for( c = nandconss - 1; c >= 0; --c )
    2146 {
    2147 SCIP_VAR** scipandvars;
    2148
    2149 assert(andconss[c] != NULL);
    2150
    2151 scipandvars = SCIPgetVarsAnd(scip, andconss[c]);
    2152 (*nandvars)[c] = SCIPgetNVarsAnd(scip, andconss[c]);
    2153 SCIP_CALL( SCIPduplicateMemoryArray(scip, &((*andvars)[c]), scipandvars, (*nandvars)[c]) ); /*lint !e866 */
    2154 SCIP_CALL( getBinVarsRepresentatives(scip, (*andvars)[c], (*nandvars)[c], transformed) );
    2155
    2156 (*resvars)[c] = SCIPgetResultantAnd(scip, andconss[c]);
    2157
    2158 assert((*andvars)[c] != NULL && (*nandvars)[c] > 0);
    2159 assert((*resvars)[c] != NULL);
    2160 }
    2161
    2162 /* sorted the array */
    2163 SCIPsortPtrPtrInt((void**)(*resvars), (void**)(*andvars), (*nandvars), SCIPvarComp, (*nresvars));
    2164 }
    2165 else
    2166 *existands = FALSE;
    2167
    2168 SCIP_CALL( SCIPallocBufferArray(scip, &shouldnotbeinand, *nresvars) );
    2169
    2170 /* check that all and-constraints doesn't contain any and-resultants, if they do try to resolve this */
    2171 /* attention: if resolving leads to x = x*y*... , we can't do anything here ( this only means (... >=x and) y >= x, so normally the and-constraint needs to be
    2172 deleted and the inequality from before needs to be added ) */
    2173 assert(*nandvars != NULL || *nresvars == 0);
    2174 for( r = *nresvars - 1; r >= 0; --r )
    2175 {
    2176 ncontainedands = 0;
    2177 shouldnotbeinand[ncontainedands] = r;
    2178 ++ncontainedands;
    2179 v = 0;
    2180
    2181 assert(*nandvars != NULL);
    2182 while( v < (*nandvars)[r] )
    2183 {
    2184 assert(*andvars != NULL);
    2185 assert(*resvars != NULL);
    2186 if( SCIPsortedvecFindPtr((void**)(*resvars), SCIPvarComp, (*andvars)[r][v], *nresvars, &pos) )
    2187 {
    2188 /* check if the found position "pos" is equal to an already visited and resultant in this constraint,
    2189 * than here could exist a directed cycle
    2190 */
    2191 /* better use tarjan's algorithm
    2192 * <http://algowiki.net/wiki/index.php?title=Tarjan%27s_algorithm>,
    2193 * <http://en.wikipedia.org/wiki/Tarjan%E2%80%99s_strongly_connected_components_algorithm>
    2194 * because it could be that the same resultant is part of this and-constraint and than it would fail
    2195 * without no cycle
    2196 * Note1: tarjans standard algorithm doesn't find cycle from one node to the same;
    2197 * Note2: when tarjan's algorithm find a cycle, it's still possible that this cycle is not "real" e.g.
    2198 * y = y ~y z (z can also be a product) where y = 0 follows and therefor only "0 = z" is necessary
    2199 */
    2200 for( a = ncontainedands - 1; a >= 0; --a )
    2201 if( shouldnotbeinand[a] == pos )
    2202 {
    2203 SCIPwarningMessage(scip, "This should not happen here. The and-constraint with resultant variable: ");
    2204 SCIP_CALL( SCIPprintVar(scip, (*resvars)[r], NULL) );
    2205 SCIPwarningMessage(scip, "possible contains a loop with and-resultant:");
    2206 SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) );
    2207
    2208 /* free memory iff necessary */
    2209 SCIPfreeBufferArray(scip, &shouldnotbeinand);
    2210 if( !transformed )
    2211 {
    2212 SCIPfreeBufferArray(scip, &andconss);
    2213 }
    2214 return SCIP_INVALIDDATA;
    2215 }
    2216 SCIPdebugMsg(scip, "Another and-constraint contains and-resultant:");
    2217 SCIPdebug( SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) ) );
    2218 SCIPdebugMsg(scip, "Trying to resolve.\n");
    2219
    2220 shouldnotbeinand[ncontainedands] = pos;
    2221 ++ncontainedands;
    2222
    2223 /* try to resolve containing ands */
    2224
    2225 /* resize array and number of variables */
    2226 (*nandvars)[r] = (*nandvars)[r] + (*nandvars)[pos] - 1;
    2227 SCIP_CALL( SCIPreallocMemoryArray(scip, &((*andvars)[r]), (*nandvars)[r]) ); /*lint !e866 */
    2228
    2229 /* copy all variables */
    2230 for( a = (*nandvars)[pos] - 1; a >= 0; --a )
    2231 (*andvars)[r][(*nandvars)[r] - a - 1] = (*andvars)[pos][a];
    2232
    2233 /* check same position with new variable, so we do not increase v */
    2234 }
    2235 else
    2236 ++v;
    2237 }
    2238 }
    2239 SCIPfreeBufferArray(scip, &shouldnotbeinand);
    2240
    2241 /* free memory iff necessary */
    2242 if( !transformed )
    2243 {
    2244 SCIPfreeBufferArray(scip, &andconss);
    2245 }
    2246 }
    2247 else
    2248 {
    2249 SCIPdebugMsg(scip, "found no and-constraint-handler\n");
    2250 *existands = FALSE;
    2251 *existandconshdlr = FALSE;
    2252 }
    2253
    2254 return SCIP_OKAY;
    2255}
    2256
    2257/** clears the given line buffer */
    2258static
    2260 char* linebuffer, /**< line */
    2261 int* linecnt /**< number of characters in line */
    2262 )
    2263{
    2264 assert( linebuffer != NULL );
    2265 assert( linecnt != NULL );
    2266
    2267 (*linecnt) = 0;
    2268 linebuffer[0] = '\0';
    2269}
    2270
    2271
    2272/** ends the given line with '\\0' and prints it to the given file stream */
    2273static
    2275 SCIP* scip, /**< SCIP data structure */
    2276 FILE* file, /**< output file (or NULL for standard output) */
    2277 char* linebuffer, /**< line */
    2278 int* linecnt /**< number of characters in line */
    2279 )
    2280{
    2281 assert( scip != NULL );
    2282 assert( linebuffer != NULL );
    2283 assert( linecnt != NULL );
    2284 assert( 0 <= *linecnt && *linecnt < OPB_MAX_LINELEN );
    2285
    2286 if( (*linecnt) > 0 )
    2287 {
    2288 linebuffer[(*linecnt)] = '\0';
    2289 SCIPinfoMessage(scip, file, "%s", linebuffer);
    2290 clearBuffer(linebuffer, linecnt);
    2291 }
    2292}
    2293
    2294
    2295/** appends extension to line and prints it to the give file stream if the line buffer get full */
    2296static
    2298 SCIP* scip, /**< SCIP data structure */
    2299 FILE* file, /**< output file (or NULL for standard output) */
    2300 char* linebuffer, /**< line buffer */
    2301 int* linecnt, /**< number of characters in line */
    2302 const char* extension /**< string to extent the line */
    2303 )
    2304{
    2305 assert(scip != NULL);
    2306 assert(linebuffer != NULL);
    2307 assert(linecnt != NULL);
    2308 assert(extension != NULL);
    2309
    2310 if( (*linecnt) + (int) strlen(extension) >= OPB_MAX_LINELEN - 1 )
    2311 writeBuffer(scip, file, linebuffer, linecnt);
    2312
    2313 /* append extension to linebuffer */
    2314 (void) strncat(linebuffer, extension, OPB_MAX_LINELEN - (unsigned int)(*linecnt));
    2315 (*linecnt) += (int) strlen(extension);
    2316}
    2317
    2318/** write objective function */
    2319static
    2321 SCIP*const scip, /**< SCIP data structure */
    2322 FILE*const file, /**< output file, or NULL if standard output should be used */
    2323 SCIP_VAR**const vars, /**< array with active (binary) variables */
    2324 int const nvars, /**< number of active variables in the problem */
    2325 SCIP_VAR** const resvars, /**< array of resultant variables */
    2326 int const nresvars, /**< number of resultant variables */
    2327 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    2328 int const*const nandvars, /**< array of numbers of corresponding and-variables */
    2329 SCIP_OBJSENSE const objsense, /**< objective sense */
    2330 SCIP_Real const objoffset, /**< objective offset from bound shifting and fixing */
    2331 SCIP_Real const objscale, /**< scalar applied to objective function; external objective value is
    2332 * extobj = objsense * objscale * (intobj + objoffset) */
    2333 SCIP_RATIONAL*const objoffsetexact, /**< exact objective offset from bound shifting and fixing */
    2334 SCIP_RATIONAL*const objscaleexact, /**< exact scalar applied to objective function; external objective value is
    2335 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
    2336 char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
    2337 SCIP_Bool const existands, /**< does some and-constraints exist? */
    2338 SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
    2339 )
    2340{
    2341 SCIP_VAR* var;
    2342 char linebuffer[OPB_MAX_LINELEN+1];
    2343 char buffer[OPB_MAX_LINELEN];
    2344 SCIP_Longint mult;
    2345 SCIP_Bool objective;
    2346 int v;
    2347 int linecnt;
    2348 int pos;
    2349
    2350 assert(scip != NULL);
    2351 assert(file != NULL);
    2352 assert(vars != NULL || nvars == 0);
    2353 assert(resvars != NULL || nresvars == 0);
    2354 assert(andvars != NULL || nandvars == NULL);
    2355 assert(multisymbol != NULL);
    2356
    2357 mult = 1;
    2358 objective = !SCIPisZero(scip, objoffset);
    2359
    2360 clearBuffer(linebuffer, &linecnt);
    2361
    2362 /* check if a objective function exits and compute the multiplier to
    2363 * shift the coefficients to integers */
    2364 for( v = 0; v < nvars; ++v )
    2365 {
    2366 var = vars[v]; /*lint !e613 */
    2367
    2368#ifndef NDEBUG
    2369 {
    2370 /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
    2371 if( !transformed )
    2372 assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ||
    2374 }
    2375#endif
    2376
    2377 /* we found a indicator variable so we assume this is a wbo file */
    2378 if( strstr(SCIPvarGetName(var), INDICATORVARNAME) != NULL )
    2379 {
    2380 /* find the topcost linear inequality which gives us the maximal cost which could be violated by our
    2381 * solution, which is an artificial constraint and print this at first
    2382 *
    2383 * @note: only linear constraint handler is enough in problem stage, otherwise it could be any upgraded linear
    2384 * constraint which handles pure binary variables
    2385 */
    2386 SCIP_CONSHDLR* conshdlr;
    2387 SCIP_CONS* topcostcons;
    2388 const char* conshdlrname;
    2389 int written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: ");
    2390
    2391 topcostcons = SCIPfindCons(scip, TOPCOSTCONSNAME);
    2392
    2393 if( topcostcons != NULL )
    2394 {
    2395 conshdlr = SCIPconsGetHdlr(topcostcons);
    2396 assert(conshdlr != NULL);
    2397 conshdlrname = SCIPconshdlrGetName(conshdlr);
    2398 assert(conshdlrname != NULL);
    2399
    2400 if( strcmp(conshdlrname, "linear") == 0 )
    2401 {
    2402 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "%.15g",
    2403 SCIPgetRhsLinear(scip, topcostcons));
    2404 }
    2405 else if( strcmp(conshdlrname, "knapsack") == 0 )
    2406 {
    2407 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "%" SCIP_LONGINT_FORMAT,
    2408 SCIPgetCapacityKnapsack(scip, topcostcons));
    2409 }
    2410 else if( strcmp(conshdlrname, "setppc") == 0 )
    2411 {
    2412 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "1");
    2413 }
    2414 else if( strcmp(conshdlrname, "exactlinear") == 0 )
    2415 {
    2416 assert(SCIPisExact(scip));
    2417 written += SCIPrationalToString(SCIPgetRhsExactLinear(scip, topcostcons),
    2418 buffer + written, OPB_MAX_LINELEN - written);
    2419 }
    2420 else
    2421 {
    2422 SCIPABORT();
    2423 return SCIP_INVALIDDATA; /*lint !e527 */
    2424 }
    2425 }
    2426 /* following works only in transformed stage */
    2427 else
    2428 {
    2429 SCIP_Bool topcostfound = FALSE;
    2430
    2431 /* first try linear constraints */
    2432 {
    2433 conshdlr = SCIPfindConshdlr(scip, "linear");
    2434
    2435 if( conshdlr != NULL )
    2436 {
    2437 SCIP_CONS** conss;
    2438 int nconss;
    2439 int c;
    2440
    2441 conss = SCIPconshdlrGetConss(conshdlr);
    2442 nconss = SCIPconshdlrGetNConss(conshdlr);
    2443 assert(conss != NULL || nconss == 0);
    2444
    2445 for( c = 0; c < nconss; ++c )
    2446 {
    2447 SCIP_VAR** consvars;
    2448 int nconsvars;
    2449 int w;
    2450
    2451 topcostcons = conss[c]; /*lint !e613 */
    2452 assert(topcostcons != NULL);
    2453
    2454 consvars = SCIPgetVarsLinear(scip, topcostcons);
    2455 nconsvars = SCIPgetNVarsLinear(scip, topcostcons);
    2456 assert(consvars != NULL || nconsvars == 0);
    2457
    2458 for( w = 0; w < nconsvars; ++w )
    2459 {
    2460 if( strstr(SCIPvarGetName(consvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
    2461 topcostfound = TRUE;
    2462 else
    2463 {
    2464 assert(!topcostfound);
    2465 topcostfound = FALSE;
    2466 }
    2467 }
    2468
    2469 if( topcostfound )
    2470 {
    2471 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "%.15g",
    2472 SCIPgetRhsLinear(scip, topcostcons));
    2473 break;
    2474 }
    2475 }
    2476 }
    2477 }
    2478
    2479 /* second try knapsack constraints */
    2480 if( !topcostfound )
    2481 {
    2482 conshdlr = SCIPfindConshdlr(scip, "knapsack");
    2483
    2484 if( conshdlr != NULL )
    2485 {
    2486 SCIP_CONS** conss;
    2487 int nconss;
    2488 int c;
    2489
    2490 conss = SCIPconshdlrGetConss(conshdlr);
    2491 nconss = SCIPconshdlrGetNConss(conshdlr);
    2492 assert(conss != NULL || nconss == 0);
    2493
    2494 for( c = 0; c < nconss; ++c )
    2495 {
    2496 SCIP_VAR** consvars;
    2497 int nconsvars;
    2498 int w;
    2499
    2500 topcostcons = conss[c]; /*lint !e613 */
    2501 assert(topcostcons != NULL);
    2502
    2503 consvars = SCIPgetVarsKnapsack(scip, topcostcons);
    2504 nconsvars = SCIPgetNVarsKnapsack(scip, topcostcons);
    2505 assert(consvars != NULL || nconsvars == 0);
    2506
    2507 for( w = 0; w < nconsvars; ++w )
    2508 {
    2509 if( strstr(SCIPvarGetName(consvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
    2510 topcostfound = TRUE;
    2511 else
    2512 {
    2513 assert(!topcostfound);
    2514 topcostfound = FALSE;
    2515 }
    2516 }
    2517
    2518 if( topcostfound )
    2519 {
    2520 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "%" SCIP_LONGINT_FORMAT,
    2521 SCIPgetCapacityKnapsack(scip, topcostcons));
    2522 break;
    2523 }
    2524 }
    2525 }
    2526 }
    2527
    2528 /* third try setppc constraints */
    2529 if( !topcostfound )
    2530 {
    2531 conshdlr = SCIPfindConshdlr(scip, "setppc");
    2532
    2533 if( conshdlr != NULL )
    2534 {
    2535 SCIP_CONS** conss;
    2536 int nconss;
    2537 int c;
    2538
    2539 conss = SCIPconshdlrGetConss(conshdlr);
    2540 nconss = SCIPconshdlrGetNConss(conshdlr);
    2541 assert(conss != NULL || nconss == 0);
    2542
    2543 for( c = 0; c < nconss; ++c )
    2544 {
    2545 SCIP_VAR** consvars;
    2546 int nconsvars;
    2547 int w;
    2548
    2549 topcostcons = conss[c]; /*lint !e613 */
    2550 assert(topcostcons != NULL);
    2551
    2552 consvars = SCIPgetVarsSetppc(scip, topcostcons);
    2553 nconsvars = SCIPgetNVarsSetppc(scip, topcostcons);
    2554 assert(consvars != NULL || nconsvars == 0);
    2555
    2556 for( w = 0; w < nconsvars; ++w )
    2557 {
    2558 if( strstr(SCIPvarGetName(consvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
    2559 topcostfound = TRUE;
    2560 else
    2561 {
    2562 assert(!topcostfound);
    2563 topcostfound = FALSE;
    2564 }
    2565 }
    2566
    2567 if( topcostfound )
    2568 {
    2569 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "1");
    2570 break;
    2571 }
    2572 }
    2573 }
    2574 }
    2575
    2576 /* try exactlinear constraints */
    2577 if( !topcostfound )
    2578 {
    2579 conshdlr = SCIPfindConshdlr(scip, "exactlinear");
    2580
    2581 if( conshdlr != NULL )
    2582 {
    2583 assert(SCIPisExact(scip));
    2584
    2585 SCIP_CONS** conss;
    2586 int nconss;
    2587 int c;
    2588
    2589 conss = SCIPconshdlrGetConss(conshdlr);
    2590 nconss = SCIPconshdlrGetNConss(conshdlr);
    2591 assert(conss != NULL || nconss == 0);
    2592
    2593 for( c = 0; c < nconss; ++c )
    2594 {
    2595 SCIP_VAR** consvars;
    2596 int nconsvars;
    2597 int w;
    2598
    2599 topcostcons = conss[c]; /*lint !e613 */
    2600 assert(topcostcons != NULL);
    2601
    2602 consvars = SCIPgetVarsExactLinear(scip, topcostcons);
    2603 nconsvars = SCIPgetNVarsExactLinear(scip, topcostcons);
    2604 assert(consvars != NULL || nconsvars == 0);
    2605
    2606 for( w = 0; w < nconsvars; ++w )
    2607 {
    2608 if( strstr(SCIPvarGetName(consvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
    2609 topcostfound = TRUE;
    2610 else
    2611 {
    2612 assert(!topcostfound);
    2613 topcostfound = FALSE;
    2614 }
    2615 }
    2616
    2617 if( topcostfound )
    2618 {
    2619 written += SCIPrationalToString(SCIPgetRhsExactLinear(scip, topcostcons),
    2620 buffer + written, OPB_MAX_LINELEN - written);
    2621 break;
    2622 }
    2623 }
    2624 }
    2625 }
    2626 }
    2627
    2628 /* if no topcost constraint found, print empty topcost line, which means there is no upper bound */
    2629 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, ";\n");
    2630 if( written >= OPB_MAX_LINELEN )
    2631 {
    2632 SCIPerrorMessage("line bound reached\n");
    2633 return SCIP_INVALIDDATA;
    2634 }
    2635 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2636
    2637 writeBuffer(scip, file, linebuffer, &linecnt);
    2638
    2639 return SCIP_OKAY;
    2640 }
    2641
    2642 /**@todo determine exact multiplier */
    2643 if( !SCIPisExact(scip) && !SCIPisZero(scip, SCIPvarGetObj(var)) )
    2644 {
    2645 objective = TRUE;
    2646 while( !SCIPisIntegral(scip, SCIPvarGetObj(var) * mult) )
    2647 {
    2648 assert(mult * 10 > mult);
    2649 mult *= 10;
    2650 }
    2651 }
    2652 }
    2653
    2654 /* there exists an objective function */
    2655 if( objective )
    2656 {
    2657 /* write exact objective */
    2658 if( SCIPisExact(scip) )
    2659 {
    2660 SCIP_RATIONAL* obj;
    2661
    2662 /* opb format supports only minimization; therefore, a maximization problem has to be converted */
    2663 if( (objsense == SCIP_OBJSENSE_MAXIMIZE) != (SCIPrationalIsNegative(objscaleexact)) )
    2664 mult *= -1;
    2665 assert(ABS(mult) == 1);
    2666
    2668
    2669 SCIPrationalDivReal(obj, objscaleexact, (SCIP_Real)mult);
    2670 SCIPinfoMessage(scip, file, "* Obj. scale : ");
    2672 SCIPinfoMessage(scip, file, "\n");
    2673 SCIPrationalMultReal(obj, objoffsetexact, (SCIP_Real)mult);
    2674 SCIPinfoMessage(scip, file, "* Obj. offset : ");
    2676 SCIPinfoMessage(scip, file, "\n");
    2677
    2679 }
    2680 /* write real objective */
    2681 else
    2682 {
    2683 /* opb format supports only minimization; therefore, a maximization problem has to be converted */
    2684 if( (objsense == SCIP_OBJSENSE_MAXIMIZE) != (objscale < 0.0) )
    2685 mult *= -1;
    2686
    2687 SCIPinfoMessage(scip, file, "* Obj. scale : %.15g\n", objscale / mult);
    2688 SCIPinfoMessage(scip, file, "* Obj. offset : %.15g\n", objoffset * mult);
    2689 }
    2690
    2691 clearBuffer(linebuffer, &linecnt);
    2692
    2693 SCIPdebugMsg(scip, "print objective function multiplied with %" SCIP_LONGINT_FORMAT "\n", mult);
    2694
    2695 appendBuffer(scip, file, linebuffer, &linecnt, "min:");
    2696
    2697#ifndef NDEBUG
    2698 if( existands )
    2699 {
    2700 int c;
    2701 /* check that these variables are sorted */
    2702 for( c = nresvars - 1; c > 0; --c )
    2703 assert(SCIPvarGetIndex(resvars[c]) >= SCIPvarGetIndex(resvars[c - 1])); /*lint !e613 */
    2704 }
    2705#endif
    2706
    2707 for( v = 0; v < nvars; ++v )
    2708 {
    2709 SCIP_Bool negated;
    2710 var = vars[v]; /*lint !e613 */
    2711
    2712 assert(var != NULL);
    2713
    2714 if( SCIPisZero(scip, SCIPvarGetObj(var)) )
    2715 continue;
    2716
    2717 negated = SCIPvarIsNegated(var);
    2718
    2719 assert( linecnt != 0 );
    2720
    2721 if( SCIPvarGetObj(var) * mult > (SCIP_Real)SCIP_LONGINT_MAX )
    2722 {
    2723 SCIPerrorMessage("Integral objective value to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", mult, SCIPvarGetObj(var), SCIPvarGetObj(var) * mult, (SCIP_Longint) SCIPround(scip, SCIPvarGetObj(var) * mult));
    2724 }
    2725
    2726 /* replace and-resultant with corresponding variables */
    2727 if( existands && SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
    2728 {
    2729 int a;
    2730
    2731 assert(andvars != NULL);
    2732 assert(nandvars != NULL);
    2733 assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
    2734 assert(andvars[pos][nandvars[pos] - 1] != NULL);
    2735
    2736 negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
    2737
    2738 /* print and-vars */
    2739 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
    2740 (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "",
    2741 strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
    2742 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2743
    2744 for(a = nandvars[pos] - 2; a >= 0; --a )
    2745 {
    2746 negated = SCIPvarIsNegated(andvars[pos][a]);
    2747
    2748 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
    2749 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2750 }
    2751 }
    2752 else
    2753 {
    2754 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
    2755 (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
    2756 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2757 }
    2758 }
    2759
    2760 /* and objective function line ends with a ';' */
    2761 appendBuffer(scip, file, linebuffer, &linecnt, ";\n");
    2762 writeBuffer(scip, file, linebuffer, &linecnt);
    2763 }
    2764
    2765 return SCIP_OKAY;
    2766}
    2767
    2768/* print real non-linear row in OPB format to file stream */
    2769static
    2771 SCIP*const scip, /**< SCIP data structure */
    2772 FILE*const file, /**< output file (or NULL for standard output) */
    2773 const char*const type, /**< row type ("=" or ">=") */
    2774 SCIP_VAR**const vars, /**< array of variables */
    2775 SCIP_Real*const vals, /**< array of real values */
    2776 int nvars, /**< number of variables */
    2777 SCIP_Real lhs, /**< real left hand side */
    2778 SCIP_VAR**const resvars, /**< array of resultant variables */
    2779 int nresvars, /**< number of resultant variables */
    2780 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    2781 const int*const nandvars, /**< array of numbers of corresponding and-variables */
    2782 SCIP_Longint weight, /**< if we found a soft constraint this is the integral weight, otherwise 0 */
    2783 SCIP_Longint*const mult, /**< integral multiplier for the coefficients */
    2784 const char*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
    2785 )
    2786{
    2787 SCIP_VAR* var;
    2788 SCIP_Real val;
    2789 SCIP_Bool negated;
    2790 char buffer[OPB_MAX_LINELEN];
    2791 char linebuffer[OPB_MAX_LINELEN + 1];
    2792 int linecnt;
    2793 int pos;
    2794 int written;
    2795 int v;
    2796
    2797 assert(scip != NULL);
    2798 assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
    2799 assert(vars != NULL);
    2800 assert(vals != NULL);
    2801 assert(mult != NULL);
    2802 assert(resvars != NULL);
    2803 assert(nresvars >= 1);
    2804 assert(andvars != NULL);
    2805 assert(nandvars != NULL);
    2806
    2807 clearBuffer(linebuffer, &linecnt);
    2808
    2809 /* check if all coefficients are internal; if not commentstart multiplier */
    2810 for( v = 0; v < nvars; ++v )
    2811 {
    2812 while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
    2813 {
    2814 if( ABS(*mult) > ABS(*mult * 10) )
    2815 {
    2816 SCIPerrorMessage("failed to scale fractional coefficients to integrality because the required multiplier is too large\n");
    2817 return SCIP_INVALIDDATA;
    2818 }
    2819 (*mult) *= 10;
    2820 }
    2821 }
    2822
    2823 while( !SCIPisIntegral(scip, lhs * (*mult)) )
    2824 {
    2825 if( ABS(*mult) > ABS(*mult * 10) )
    2826 {
    2827 SCIPerrorMessage("failed to scale fractional coefficients to integrality because the required multiplier is too large\n");
    2828 return SCIP_INVALIDDATA;
    2829 }
    2830 (*mult) *= 10;
    2831 }
    2832
    2833 /* print comment line if we have to multiply the coefficients to get integrals */
    2834 if( ABS(*mult) != 1 )
    2835 {
    2836 SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n",
    2837 ABS(*mult));
    2838 }
    2839
    2840#ifndef NDEBUG
    2841 /* check that these variables are sorted */
    2842 for( v = nresvars - 1; v > 0; --v )
    2843 assert(SCIPvarGetIndex(resvars[v]) >= SCIPvarGetIndex(resvars[v - 1]));
    2844#endif
    2845
    2846 /* if we have a soft constraint print the weight */
    2847 if( weight != 0 )
    2848 {
    2849 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "]", weight);
    2850 if( written >= OPB_MAX_LINELEN )
    2851 {
    2852 SCIPerrorMessage("line bound reached\n");
    2853 return SCIP_INVALIDDATA;
    2854 }
    2855 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2856 }
    2857
    2858 /* print coefficients */
    2859 for( v = 0; v < nvars; ++v )
    2860 {
    2861 var = vars[v];
    2862 val = vals[v] * (*mult);
    2863 negated = SCIPvarIsNegated(var);
    2864
    2865 /* replace and-resultant with corresponding variables */
    2866 if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
    2867 {
    2868 int a;
    2869
    2870 assert(andvars != NULL);
    2871 assert(nandvars != NULL);
    2872 assert(pos >= 0);
    2873 assert(nandvars[pos] >= 1);
    2874 assert(andvars[pos] != NULL);
    2875 assert(andvars[pos][nandvars[pos] - 1] != NULL);
    2876
    2877 negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
    2878
    2879 if( ABS(val) > (SCIP_Real)SCIP_LONGINT_MAX )
    2880 {
    2881 SCIPerrorMessage("integral coefficient too big (mult = %" SCIP_LONGINT_FORMAT ", mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ") for printing in opb format\n",
    2882 *mult, val, (SCIP_Longint)SCIPround(scip, val));
    2883 }
    2884
    2885 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
    2886 (SCIP_Longint)SCIPround(scip, val), multisymbol, negated ? "~" : "",
    2887 strstr(SCIPvarGetName(negated ? SCIPvarGetNegatedVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
    2888 if( written >= OPB_MAX_LINELEN )
    2889 {
    2890 SCIPerrorMessage("line bound reached\n");
    2891 return SCIP_INVALIDDATA;
    2892 }
    2893 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2894
    2895 /* print and-vars */
    2896 for( a = nandvars[pos] - 2; a >= 0; --a )
    2897 {
    2898 negated = SCIPvarIsNegated(andvars[pos][a]);
    2899
    2900 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "",
    2901 strstr(SCIPvarGetName(negated ? SCIPvarGetNegatedVar(andvars[pos][a]) : andvars[pos][a]), "x"));
    2902 if( written >= OPB_MAX_LINELEN )
    2903 {
    2904 SCIPerrorMessage("line bound reached\n");
    2905 return SCIP_INVALIDDATA;
    2906 }
    2907 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2908 }
    2909 }
    2910 else
    2911 {
    2912 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
    2913 (SCIP_Longint)SCIPround(scip, val), multisymbol, negated ? "~" : "",
    2914 strstr(SCIPvarGetName(negated ? SCIPvarGetNegatedVar(var) : var), "x"));
    2915 if( written >= OPB_MAX_LINELEN )
    2916 {
    2917 SCIPerrorMessage("line bound reached\n");
    2918 return SCIP_INVALIDDATA;
    2919 }
    2920 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2921 }
    2922 }
    2923
    2924 /* print scaled left hand side */
    2925 val = lhs * (*mult);
    2926
    2927 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %s %+" SCIP_LONGINT_FORMAT ";\n", type,
    2928 (SCIP_Longint)SCIPround(scip, val));
    2929 if( written >= OPB_MAX_LINELEN )
    2930 {
    2931 SCIPerrorMessage("line bound reached\n");
    2932 return SCIP_INVALIDDATA;
    2933 }
    2934 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    2935
    2936 writeBuffer(scip, file, linebuffer, &linecnt);
    2937
    2938 return SCIP_OKAY;
    2939}
    2940
    2941/** prints given real non-linear constraint information in OPB format to file stream */
    2942static
    2944 SCIP*const scip, /**< SCIP data structure */
    2945 FILE*const file, /**< output file (or NULL for standard output) */
    2946 SCIP_VAR**const vars, /**< array of variables */
    2947 SCIP_Real*const vals, /**< array of real coefficient values (or NULL if all coefficient values are 1) */
    2948 int nvars, /**< number of variables */
    2949 SCIP_Real lhs, /**< real left hand side */
    2950 SCIP_Real rhs, /**< real right hand side */
    2951 SCIP_VAR**const resvars, /**< array of resultant variables */
    2952 int nresvars, /**< number of resultant variables */
    2953 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    2954 const int*const nandvars, /**< array of numbers of corresponding and-variables */
    2955 SCIP_Longint weight, /**< if we found a soft constraint this is the integral weight, otherwise 0 */
    2956 SCIP_Bool transformed, /**< transformed constraint? */
    2957 const char*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
    2958 )
    2959{
    2960 SCIP_VAR** activevars;
    2961 SCIP_Real* activevals;
    2962 SCIP_Real activeconstant;
    2963 SCIP_Longint mult;
    2964 SCIP_RETCODE retcode;
    2965 int varssize;
    2966 int v;
    2967
    2968 assert(scip != NULL);
    2969 assert(vars != NULL);
    2970 assert(resvars != NULL);
    2971 assert(nresvars >= 1);
    2972 assert(andvars != NULL);
    2973 assert(nandvars != NULL);
    2974
    2975 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    2976 return SCIP_OKAY;
    2977
    2978 /* duplicate variable and value array */
    2979 varssize = nvars;
    2980 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, varssize) );
    2981 if( vals != NULL )
    2982 {
    2983 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, varssize) );
    2984 }
    2985 else
    2986 {
    2987 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, varssize) );
    2988
    2989 for( v = 0; v < nvars; ++v )
    2990 activevals[v] = 1.0;
    2991 }
    2992
    2993 /* retransform given variables to active variables */
    2994 activeconstant = 0.0;
    2995 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nvars, &varssize, &activeconstant, transformed) );
    2996
    2997 /* print row(s) in OPB format */
    2998 retcode = SCIP_OKAY;
    2999 if( SCIPisEQ(scip, lhs, rhs) )
    3000 {
    3001 assert(!SCIPisInfinity(scip, rhs));
    3002 assert(retcode == SCIP_OKAY);
    3003
    3004 /* equality constraint */
    3005 rhs -= activeconstant;
    3006 mult = 1;
    3007 retcode = printNLRow(scip, file, "=", activevars, activevals, nvars, rhs, resvars, nresvars, andvars, nandvars,
    3008 weight, &mult, multisymbol);
    3009 }
    3010 else
    3011 {
    3012 if( !SCIPisInfinity(scip, -lhs) )
    3013 {
    3014 /* print inequality ">=" */
    3015 lhs -= activeconstant;
    3016 mult = 1;
    3017 retcode = printNLRow(scip, file, ">=", activevars, activevals, nvars, lhs, resvars, nresvars, andvars, nandvars,
    3018 weight, &mult, multisymbol);
    3019 }
    3020
    3021 if( !SCIPisInfinity(scip, rhs) )
    3022 {
    3023 /* print inequality ">=" and multiplying all coefficients by -1 */
    3024 rhs -= activeconstant;
    3025 mult = -1;
    3026 retcode = printNLRow(scip, file, ">=", activevars, activevals, nvars, rhs, resvars, nresvars, andvars, nandvars,
    3027 weight, &mult, multisymbol);
    3028 }
    3029 }
    3030
    3031 /* free buffer arrays */
    3032 SCIPfreeBufferArray(scip, &activevals);
    3033 SCIPfreeBufferArray(scip, &activevars);
    3034
    3035 return retcode;
    3036}
    3037
    3038/* print real row in OPB format to file stream */
    3039static
    3041 SCIP* scip, /**< SCIP data structure */
    3042 FILE* file, /**< output file (or NULL for standard output) */
    3043 const char* type, /**< row type ("=" or ">=") */
    3044 SCIP_VAR** vars, /**< array of variables */
    3045 SCIP_Real* vals, /**< array of real values */
    3046 int nvars, /**< number of variables */
    3047 SCIP_Real lhs, /**< real left hand side */
    3048 SCIP_Longint weight, /**< if we found a soft constraint this is the integral weight, otherwise 0 */
    3049 SCIP_Longint* mult, /**< integral multiplier for the coefficients */
    3050 const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
    3051 )
    3052{
    3053 SCIP_VAR* var;
    3054 SCIP_Real val;
    3055 SCIP_Bool negated;
    3056 char buffer[OPB_MAX_LINELEN];
    3057 char linebuffer[OPB_MAX_LINELEN + 1];
    3058 int linecnt;
    3059 int written;
    3060 int v;
    3061
    3062 assert(scip != NULL);
    3063 assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
    3064 assert(vars != NULL || nvars == 0);
    3065 assert(vals != NULL || nvars == 0);
    3066 assert(mult != NULL);
    3067
    3068 clearBuffer(linebuffer, &linecnt);
    3069
    3070 /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
    3071 * we can stop printing because it is an artificial constraint
    3072 */
    3073 if( nvars > 0 && strstr(SCIPvarGetName(vars[0]), INDICATORVARNAME) != NULL )
    3074 return SCIP_OKAY;
    3075
    3076 /* check if all coefficients are integral; if not commentstart multiplier */
    3077 for( v = 0; v < nvars; ++v )
    3078 {
    3079 while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
    3080 {
    3081 if( ABS(*mult) > ABS(*mult * 10) )
    3082 {
    3083 SCIPerrorMessage("failed to scale fractional coefficients to integrality because the required multiplier is too large\n");
    3084 return SCIP_INVALIDDATA;
    3085 }
    3086 (*mult) *= 10;
    3087 }
    3088 }
    3089
    3090 while( !SCIPisIntegral(scip, lhs * (*mult)) )
    3091 {
    3092 if( ABS(*mult) > ABS(*mult * 10) )
    3093 {
    3094 SCIPerrorMessage("failed to scale fractional coefficients to integrality because the required multiplier is too large\n");
    3095 return SCIP_INVALIDDATA;
    3096 }
    3097 (*mult) *= 10;
    3098 }
    3099
    3100 /* print comment line if we have to multiply the coefficients to get integrals */
    3101 if( ABS(*mult) != 1 )
    3102 {
    3103 SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n",
    3104 ABS(*mult));
    3105 }
    3106
    3107 /* if we have a soft constraint print the weight */
    3108 if( weight != 0 )
    3109 {
    3110 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "]", weight);
    3111 if( written >= OPB_MAX_LINELEN )
    3112 {
    3113 SCIPerrorMessage("line bound reached\n");
    3114 return SCIP_INVALIDDATA;
    3115 }
    3116 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3117 }
    3118
    3119 /* print coefficients */
    3120 for( v = 0; v < nvars; ++v )
    3121 {
    3122 var = vars[v];
    3123 val = vals[v] * (*mult);
    3124 negated = SCIPvarIsNegated(var);
    3125
    3126 if( ABS(val) > (SCIP_Real)SCIP_LONGINT_MAX )
    3127 {
    3128 SCIPerrorMessage("integral coefficient too big (mult = %" SCIP_LONGINT_FORMAT ", mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ") for printing in opb format\n",
    3129 *mult, val, (SCIP_Longint)SCIPround(scip, val));
    3130 }
    3131
    3132 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
    3133 (SCIP_Longint)SCIPround(scip, val), multisymbol, negated ? "~" : "",
    3134 strstr(SCIPvarGetName(negated ? SCIPvarGetNegatedVar(var) : var), "x"));
    3135 if( written >= OPB_MAX_LINELEN )
    3136 {
    3137 SCIPerrorMessage("line bound reached\n");
    3138 return SCIP_INVALIDDATA;
    3139 }
    3140 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3141 }
    3142
    3143 /* print scaled left hand side */
    3144 val = lhs * (*mult);
    3145
    3146 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %s %+" SCIP_LONGINT_FORMAT ";\n", type,
    3147 (SCIP_Longint)SCIPround(scip, val));
    3148 if( written >= OPB_MAX_LINELEN )
    3149 {
    3150 SCIPerrorMessage("line bound reached\n");
    3151 return SCIP_INVALIDDATA;
    3152 }
    3153 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3154
    3155 writeBuffer(scip, file, linebuffer, &linecnt);
    3156
    3157 return SCIP_OKAY;
    3158}
    3159
    3160/* print exact row in OPB format to file stream */
    3161static
    3163 SCIP* scip, /**< SCIP data structure */
    3164 FILE* file, /**< output file (or NULL for standard output) */
    3165 const char* type, /**< row type ("=" or ">=") */
    3166 SCIP_VAR** vars, /**< array of variables */
    3167 SCIP_RATIONAL** vals, /**< array of exact values */
    3168 int nvars, /**< number of variables */
    3169 SCIP_RATIONAL* lhs, /**< exact left hand side */
    3170 SCIP_RATIONAL* weight, /**< if we found a soft constraint this is the exact weight, otherwise 0 */
    3171 SCIP_RATIONAL* mult, /**< exact multiplier for the coefficients */
    3172 const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
    3173 )
    3174{
    3175 SCIP_VAR* var;
    3176 SCIP_RATIONAL* val;
    3177 SCIP_Bool negated;
    3178 char buffer[OPB_MAX_LINELEN];
    3179 char linebuffer[OPB_MAX_LINELEN + 1];
    3180 int linecnt;
    3181 int written;
    3182 int v;
    3183
    3184 assert(scip != NULL);
    3185 assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
    3186 assert(vars != NULL || nvars == 0);
    3187 assert(vals != NULL || nvars == 0);
    3188 assert(lhs != NULL);
    3189 assert(weight != NULL);
    3190 assert(mult != NULL);
    3191
    3192 clearBuffer(linebuffer, &linecnt);
    3193
    3194 /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
    3195 * we can stop printing because it is an artificial constraint
    3196 */
    3197 if( nvars > 0 && strstr(SCIPvarGetName(vars[0]), INDICATORVARNAME) != NULL )
    3198 return SCIP_OKAY;
    3199
    3200 /**@todo check if all values are integral; if not commentstart multiplier */
    3201 /**@todo print comment line if we have to multiply the coefficients to get integrals */
    3202
    3203 /* if we have a soft constraint print the weight */
    3204 if( !SCIPrationalIsZero(weight) )
    3205 {
    3206 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[");
    3207 if( !SCIPrationalIsNegative(weight) )
    3208 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "+");
    3209 written += SCIPrationalToString(weight, buffer + written, OPB_MAX_LINELEN - written);
    3210 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "]");
    3211 if( written >= OPB_MAX_LINELEN )
    3212 {
    3213 SCIPerrorMessage("line bound reached\n");
    3214 return SCIP_INVALIDDATA;
    3215 }
    3216 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3217 }
    3218
    3220
    3221 /* print coefficients */
    3222 for( v = 0; v < nvars; ++v )
    3223 {
    3224 var = vars[v];
    3225 SCIPrationalMult(val, vals[v], mult);
    3226 negated = SCIPvarIsNegated(var);
    3227
    3228 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " ");
    3229 if( !SCIPrationalIsNegative(val) )
    3230 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "+");
    3231 written += SCIPrationalToString(val, buffer + written, OPB_MAX_LINELEN - written);
    3232 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "%s%s%s", multisymbol, negated ? "~" : "",
    3233 strstr(SCIPvarGetName(negated ? SCIPvarGetNegatedVar(var) : var), "x"));
    3234 if( written >= OPB_MAX_LINELEN )
    3235 {
    3237 SCIPerrorMessage("line bound reached\n");
    3238 return SCIP_INVALIDDATA;
    3239 }
    3240 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3241 }
    3242
    3243 /* print scaled left hand side */
    3244 SCIPrationalMult(val, lhs, mult);
    3245
    3246 written = SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %s ", type);
    3247 if( !SCIPrationalIsNegative(val) )
    3248 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, "+");
    3249 written += SCIPrationalToString(val, buffer + written, OPB_MAX_LINELEN - written);
    3250 written += SCIPsnprintf(buffer + written, OPB_MAX_LINELEN - written, ";\n");
    3252 if( written >= OPB_MAX_LINELEN )
    3253 {
    3254 SCIPerrorMessage("line bound reached\n");
    3255 return SCIP_INVALIDDATA;
    3256 }
    3257 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    3258
    3259 writeBuffer(scip, file, linebuffer, &linecnt);
    3260
    3261 return SCIP_OKAY;
    3262}
    3263
    3264/** prints given real linear constraint information in OPB format to file stream */
    3265static
    3267 SCIP* scip, /**< SCIP data structure */
    3268 FILE* file, /**< output file (or NULL for standard output) */
    3269 SCIP_VAR** vars, /**< array of variables */
    3270 SCIP_Real* vals, /**< array of real coefficient values (or NULL if all coefficient values are 1) */
    3271 int nvars, /**< number of variables */
    3272 SCIP_Real lhs, /**< real left hand side */
    3273 SCIP_Real rhs, /**< real right hand side */
    3274 SCIP_Longint weight, /**< if we found a soft constraint this is the integral weight, otherwise 0 */
    3275 SCIP_Bool transformed, /**< transformed constraint? */
    3276 const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
    3277 )
    3278{
    3279 SCIP_VAR** activevars = NULL;
    3280 SCIP_Real* activevals = NULL;
    3281 SCIP_Real activeconstant;
    3282 SCIP_Longint mult;
    3283 SCIP_RETCODE retcode;
    3284 int varssize;
    3285 int v;
    3286
    3287 assert(scip != NULL);
    3288 assert(vars != NULL || nvars == 0);
    3289
    3290 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    3291 return SCIP_OKAY;
    3292
    3293 /* duplicate variable and value array */
    3294 varssize = nvars;
    3295 activeconstant = 0.0;
    3296 if( nvars >= 1 )
    3297 {
    3298 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, varssize) );
    3299 if( vals != NULL )
    3300 {
    3301 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, varssize) );
    3302 }
    3303 else
    3304 {
    3305 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, varssize) );
    3306
    3307 for( v = 0; v < nvars; ++v )
    3308 activevals[v] = 1.0;
    3309 }
    3310
    3311 /* retransform given variables to active variables */
    3312 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nvars, &varssize, &activeconstant, transformed) );
    3313 }
    3314
    3315 /* print row(s) in OPB format */
    3316 retcode = SCIP_OKAY;
    3317 if( SCIPisEQ(scip, lhs, rhs) )
    3318 {
    3319 assert(!SCIPisInfinity(scip, rhs));
    3320 assert(retcode == SCIP_OKAY);
    3321
    3322 /* equality constraint */
    3323 rhs -= activeconstant;
    3324 mult = 1;
    3325 retcode = printRow(scip, file, "=", activevars, activevals, nvars, rhs, weight, &mult, multisymbol);
    3326 }
    3327 else
    3328 {
    3329 if( !SCIPisInfinity(scip, -lhs) )
    3330 {
    3331 assert(retcode == SCIP_OKAY);
    3332
    3333 /* print inequality ">=" */
    3334 lhs -= activeconstant;
    3335 mult = 1;
    3336 retcode = printRow(scip, file, ">=", activevars, activevals, nvars, lhs, weight, &mult, multisymbol);
    3337 }
    3338
    3339 if( retcode == SCIP_OKAY && !SCIPisInfinity(scip, rhs) )
    3340 {
    3341 /* print inequality ">=" and multiplying all coefficients by -1 */
    3342 rhs -= activeconstant;
    3343 mult = -1;
    3344 retcode = printRow(scip, file, ">=", activevars, activevals, nvars, rhs, weight, &mult, multisymbol);
    3345 }
    3346 }
    3347
    3348 /* free buffer arrays */
    3349 SCIPfreeBufferArrayNull(scip, &activevals);
    3350 SCIPfreeBufferArrayNull(scip, &activevars);
    3351
    3352 return retcode;
    3353}
    3354
    3355/** prints given exact linear constraint information in OPB format to file stream */
    3356static
    3358 SCIP* scip, /**< SCIP data structure */
    3359 FILE* file, /**< output file (or NULL for standard output) */
    3360 SCIP_VAR** vars, /**< array of variables */
    3361 SCIP_RATIONAL** vals, /**< array of exact coefficient values (or NULL if all coefficient values are 1) */
    3362 int nvars, /**< number of variables */
    3363 SCIP_RATIONAL* lhs, /**< exact left hand side */
    3364 SCIP_RATIONAL* rhs, /**< exact right hand side */
    3365 SCIP_RATIONAL* weight, /**< if we found a soft constraint this is the exact weight, otherwise 0 */
    3366 SCIP_Bool transformed, /**< transformed constraint? */
    3367 const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
    3368 )
    3369{
    3370 SCIP_VAR** activevars = NULL;
    3371 SCIP_RATIONAL** activevals = NULL;
    3372 SCIP_RATIONAL* activeconstant;
    3373 SCIP_RATIONAL* activeside;
    3374 SCIP_RATIONAL* mult;
    3375 SCIP_RETCODE retcode;
    3376 int varssize;
    3377 int v;
    3378
    3379 assert(scip != NULL);
    3380 assert(vars != NULL || nvars == 0);
    3381 assert(lhs != NULL);
    3382 assert(rhs != NULL);
    3383 assert(weight != NULL);
    3384
    3386 return SCIP_OKAY;
    3387
    3388 SCIP_CALL( SCIPrationalCreateBuffer(SCIPbuffer(scip), &activeconstant) );
    3391
    3392 /* duplicate variable and value array */
    3393 varssize = nvars;
    3394 SCIPrationalSetReal(activeconstant, 0.0);
    3395 if( nvars >= 1 )
    3396 {
    3397 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, varssize) );
    3398 if( vals != NULL )
    3399 {
    3400 SCIP_CALL( SCIPrationalCopyBufferArray(SCIPbuffer(scip), &activevals, vals, varssize) );
    3401 }
    3402 else
    3403 {
    3404 SCIP_CALL( SCIPrationalCreateBufferArray(SCIPbuffer(scip), &activevals, varssize) );
    3405
    3406 for( v = 0; v < nvars; ++v )
    3407 SCIPrationalSetReal(activevals[v], 1.0);
    3408 }
    3409
    3410 /* retransform given variables to active variables */
    3411 SCIP_CALL( getActiveVariablesExact(scip, &activevars, &activevals, &nvars, &varssize, activeconstant, transformed) );
    3412 }
    3413
    3414 /* print row(s) in OPB format */
    3415 retcode = SCIP_OKAY;
    3416 if( SCIPrationalIsEQ(lhs, rhs) )
    3417 {
    3418 assert(!SCIPrationalIsInfinity(rhs));
    3419 assert(retcode == SCIP_OKAY);
    3420
    3421 /* equality constraint */
    3422 SCIPrationalDiff(activeside, rhs, activeconstant);
    3423 SCIPrationalSetReal(mult, 1.0);
    3424 retcode = printRowExact(scip, file, "=", activevars, activevals, nvars, activeside, weight, mult, multisymbol);
    3425 }
    3426 else
    3427 {
    3428 if( !SCIPrationalIsNegInfinity(lhs) )
    3429 {
    3430 assert(retcode == SCIP_OKAY);
    3431
    3432 /* print inequality ">=" */
    3433 SCIPrationalDiff(activeside, lhs, activeconstant);
    3434 SCIPrationalSetReal(mult, 1.0);
    3435 retcode = printRowExact(scip, file, ">=", activevars, activevals, nvars, activeside, weight, mult, multisymbol);
    3436 }
    3437
    3438 if( retcode == SCIP_OKAY && !SCIPrationalIsInfinity(rhs) )
    3439 {
    3440 /* print inequality ">=" and multiplying all coefficients by -1 */
    3441 SCIPrationalDiff(activeside, rhs, activeconstant);
    3442 SCIPrationalSetReal(mult, -1.0);
    3443 retcode = printRowExact(scip, file, ">=", activevars, activevals, nvars, activeside, weight, mult, multisymbol);
    3444 }
    3445 }
    3446
    3447 if( activevals != NULL )
    3448 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &activevals, varssize);
    3449 SCIPfreeBufferArrayNull(scip, &activevars);
    3451 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activeside);
    3452 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activeconstant);
    3453
    3454 return retcode;
    3455}
    3456
    3457/** determine total number of split linear and indicator constraints */
    3458static
    3460 SCIP*const scip, /**< SCIP data structure */
    3461 SCIP_CONS**const conss, /**< array with constraints of the problem */
    3462 int const nconss, /**< number of constraints in the problem */
    3463 int* nlinearconss, /**< pointer to store the total number of split linear constraints */
    3464 int* nindicatorconss /**< pointer to store the total number of indicator constraints */
    3465 )
    3466{
    3467 SCIP_CONSHDLR* conshdlr;
    3468 const char* conshdlrname;
    3469 SCIP_CONS* cons;
    3470 int c;
    3471
    3472 assert(scip != NULL);
    3473 assert(conss != NULL || nconss == 0);
    3474 assert(nlinearconss != NULL);
    3475 assert(nindicatorconss != NULL);
    3476
    3477 *nlinearconss = 0;
    3478 *nindicatorconss = 0;
    3479
    3480 /* loop over all constraints */
    3481 for( c = 0; c < nconss; ++c )
    3482 {
    3483 SCIP_Bool success;
    3484
    3485 cons = conss[c];
    3486 assert(cons != NULL);
    3487 conshdlr = SCIPconsGetHdlr(cons); /*lint !e613*/
    3488 assert(conshdlr != NULL);
    3489
    3490 conshdlrname = SCIPconshdlrGetName(conshdlr);
    3491
    3492 if( strcmp(conshdlrname, "and") == 0 )
    3493 continue;
    3494
    3495 if( strcmp(conshdlrname, "pseudoboolean") == 0 )
    3496 {
    3497 if( SCIPgetIndVarPseudoboolean(scip, cons) != NULL )
    3498 ++(*nindicatorconss);
    3499
    3500 continue;
    3501 }
    3502
    3503 if( strcmp(conshdlrname, "indicator") == 0 )
    3504 {
    3505 ++(*nindicatorconss);
    3506
    3507 continue;
    3508 }
    3509
    3510 if( SCIPisExact(scip) )
    3511 {
    3512 SCIP_RATIONAL* lhs;
    3513 SCIP_RATIONAL* rhs;
    3514
    3515 lhs = SCIPconsGetLhsExact(scip, cons, &success);
    3516
    3517 if( !success )
    3518 continue;
    3519
    3520 rhs = SCIPconsGetRhsExact(scip, cons, &success);
    3521
    3522 if( !success )
    3523 continue;
    3524
    3525 if( SCIPrationalIsEQ(lhs, rhs) )
    3526 ++(*nlinearconss);
    3527 else
    3528 {
    3529 if( !SCIPrationalIsNegInfinity(lhs) )
    3530 ++(*nlinearconss);
    3531
    3532 if( !SCIPrationalIsInfinity(rhs) )
    3533 ++(*nlinearconss);
    3534 }
    3535 }
    3536 else
    3537 {
    3538 SCIP_Real lhs;
    3539 SCIP_Real rhs;
    3540
    3541 lhs = SCIPconsGetLhs(scip, cons, &success);
    3542
    3543 if( !success )
    3544 continue;
    3545
    3546 rhs = SCIPconsGetRhs(scip, cons, &success);
    3547
    3548 if( !success )
    3549 continue;
    3550
    3551 if( SCIPisEQ(scip, lhs, rhs) )
    3552 ++(*nlinearconss);
    3553 else
    3554 {
    3555 if( !SCIPisInfinity(scip, -lhs) )
    3556 ++(*nlinearconss);
    3557
    3558 if( !SCIPisInfinity(scip, rhs) )
    3559 ++(*nlinearconss);
    3560 }
    3561 }
    3562 }
    3563}
    3564
    3565/** write constraints */
    3566static
    3568 SCIP*const scip, /**< SCIP data structure */
    3569 FILE*const file, /**< output file, or NULL if standard output should be used */
    3570 SCIP_CONS**const conss, /**< array with constraints of the problem */
    3571 int const nconss, /**< number of constraints in the problem */
    3572 SCIP_VAR**const vars, /**< array with active (binary) variables */
    3573 int const nvars, /**< number of active variables in the problem */
    3574 SCIP_VAR** const resvars, /**< array of resultant variables */
    3575 int const nresvars, /**< number of resultant variables */
    3576 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    3577 int const*const nandvars, /**< array of numbers of corresponding and-variables */
    3578 char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
    3579 SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
    3580 SCIP_Bool const existands, /**< does some and-constraints exist? */
    3581 SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
    3582 )
    3583{
    3584 SCIP_CONSHDLR* conshdlr;
    3585 const char* conshdlrname;
    3586 SCIP_CONS* cons = NULL;
    3587 SCIP_VAR** consvars;
    3588 SCIP_Real* consvals;
    3589 SCIP_Bool topcostfound = FALSE;
    3590 SCIP_RETCODE retcode = SCIP_OKAY;
    3591 int nconsvars;
    3592 int v, c;
    3593 SCIP_HASHMAP* linconssofindicatorsmap = NULL;
    3594 SCIP_HASHMAP* linconssofpbsmap = NULL;
    3595 SCIP_RATIONAL* weightexact = NULL;
    3596 SCIP_Longint weight = 0LL;
    3597
    3598 assert(scip != NULL);
    3599 assert(file != NULL);
    3600 assert(conss != NULL || nconss == 0);
    3601 assert(vars != NULL || nvars == 0);
    3602 assert(resvars != NULL || nresvars == 0);
    3603 assert(andvars != NULL || nandvars == 0);
    3604 assert(multisymbol != NULL);
    3605
    3606 if( SCIPisExact(scip) )
    3607 {
    3609 }
    3610
    3611 if( transformed )
    3612 {
    3613 conshdlr = SCIPfindConshdlr(scip, "indicator");
    3614
    3615 /* find artificial linear constraints which correspond to indicator constraints to avoid double printing */
    3616 if( conshdlr != NULL )
    3617 {
    3618 SCIP_CONS** indconss;
    3619 int nindconss;
    3620
    3621 indconss = SCIPconshdlrGetConss(conshdlr);
    3622 nindconss = SCIPconshdlrGetNConss(conshdlr);
    3623 assert(indconss != NULL || nindconss == 0);
    3624
    3625 if( nindconss > 0 )
    3626 {
    3627 SCIP_CONS* lincons;
    3628
    3629 /* create the linear constraint of indicator constraints hash map */
    3630 SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nindconss) );
    3631 assert(indconss != NULL);
    3632
    3633 for( c = 0; c < nindconss; ++c )
    3634 {
    3635 assert(indconss[c] != NULL);
    3636 lincons = SCIPgetLinearConsIndicator(indconss[c]);
    3637 assert(lincons != NULL);
    3638
    3639 /* insert constraints into mapping */
    3640 SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)indconss[c]) );
    3641 }
    3642 }
    3643 }
    3644
    3645 conshdlr = SCIPfindConshdlr(scip, "pseudoboolean");
    3646
    3647 /* find artifical linear constraints which correspond to indicator constraints to avoid double printing */
    3648 if( conshdlr != NULL )
    3649 {
    3650 SCIP_CONS** pbconss;
    3651 int npbconss;
    3652
    3653 pbconss = SCIPconshdlrGetConss(conshdlr);
    3654 npbconss = SCIPconshdlrGetNConss(conshdlr);
    3655 assert(pbconss != NULL || npbconss == 0);
    3656
    3657 if( npbconss > 0 )
    3658 {
    3659 SCIP_CONS* lincons;
    3660
    3661 /* create the linear constraint of indicator constraints hash map */
    3662 SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), npbconss) );
    3663
    3664 for( c = 0; c < npbconss; ++c )
    3665 {
    3666 assert(pbconss[c] != NULL); /*lint !e613*/
    3667 lincons = SCIPgetLinearConsPseudoboolean(scip, pbconss[c]); /*lint !e613*/
    3668 assert(lincons != NULL);
    3669
    3670 /* insert constraints into mapping */
    3671 SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)pbconss[c]) );
    3672 }
    3673 }
    3674 }
    3675 }
    3676 /* in original space we cannot ask the constraint handler for its constraints, therefore we have to loop over all
    3677 * original constraints to check for artificial linear constraints
    3678 */
    3679 else
    3680 {
    3681 SCIP_CONS* lincons;
    3682 SCIP_Bool pbhashmapcreated = FALSE;
    3683 SCIP_Bool indhashmapcreated = FALSE;
    3684
    3685 /* loop over all constraint for printing */
    3686 for( c = 0; c < nconss; ++c )
    3687 {
    3688 conshdlr = SCIPconsGetHdlr(conss[c]); /*lint !e613*/
    3689 assert(conshdlr != NULL);
    3690
    3691 conshdlrname = SCIPconshdlrGetName(conshdlr);
    3692
    3693 if( strcmp(conshdlrname, "pseudoboolean") == 0 )
    3694 {
    3695 if( !pbhashmapcreated )
    3696 {
    3697 /* create the linear constraint of indicator constraints hash map */
    3698 SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), nconss) );
    3699 pbhashmapcreated = TRUE;
    3700 }
    3701
    3702 lincons = SCIPgetLinearConsPseudoboolean(scip, conss[c]); /*lint !e613*/
    3703 assert(lincons != NULL);
    3704
    3705 /* insert constraints into mapping */
    3706 SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)conss[c]) );
    3707 }
    3708 else if( strcmp(conshdlrname, "indicator") == 0 )
    3709 {
    3710 if( !indhashmapcreated )
    3711 {
    3712 /* create the linear constraint of indicator constraints hash map */
    3713 SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nconss) );
    3714 indhashmapcreated = TRUE;
    3715 }
    3716
    3717 lincons = SCIPgetLinearConsIndicator(conss[c]); /*lint !e613*/
    3718 assert(lincons != NULL);
    3719
    3720 /* insert constraint into mapping */
    3721 SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)conss[c]) );
    3722 }
    3723 }
    3724 }
    3725
    3726 /* loop over all constraint for printing */
    3727 for( c = 0; c < nconss && retcode == SCIP_OKAY; ++c )
    3728 {
    3729 SCIP_CONS* artcons = NULL;
    3730 SCIP_VAR* indvar = NULL;
    3731
    3732 cons = conss[c]; /*lint !e613 */
    3733 assert(cons != NULL);
    3734
    3735 conshdlr = SCIPconsGetHdlr(cons);
    3736 assert(conshdlr != NULL);
    3737
    3738 conshdlrname = SCIPconshdlrGetName(conshdlr);
    3739 assert(transformed == SCIPconsIsTransformed(cons));
    3740
    3741 /* in case the transformed problem is written only constraints are posted which are enabled in the current node */
    3742 assert(!transformed || SCIPconsIsEnabled(cons));
    3743
    3744 if( linconssofindicatorsmap != NULL )
    3745 {
    3746 artcons = (SCIP_CONS*)SCIPhashmapGetImage(linconssofindicatorsmap, (void*)cons);
    3747
    3748 if( artcons != NULL )
    3749 continue;
    3750 }
    3751
    3752 if( weightexact != NULL )
    3753 SCIPrationalSetReal(weightexact, 0.0);
    3754 else
    3755 weight = 0LL;
    3756
    3757 if( linconssofpbsmap != NULL )
    3758 {
    3759 artcons = (SCIP_CONS*)SCIPhashmapGetImage(linconssofpbsmap, (void*)cons);
    3760
    3761 if( artcons != NULL )
    3762 {
    3763 indvar = SCIPgetIndVarPseudoboolean(scip, artcons);
    3764
    3765 if( indvar != NULL )
    3766 {
    3767 SCIP_Bool isweightzero;
    3768
    3769 if( weightexact != NULL )
    3770 {
    3771 SCIPrationalSetRational(weightexact, SCIPvarGetObjExact(indvar));
    3772 isweightzero = SCIPrationalIsZero(weightexact);
    3773 }
    3774 else
    3775 {
    3776 weight = (SCIP_Longint)SCIPround(scip, SCIPvarGetObj(indvar));
    3777 isweightzero = (weight == 0LL);
    3778 }
    3779
    3780 if( isweightzero )
    3781 {
    3782 /* pseudoboolean constraint not printed because weight of this soft constraint is zero */
    3783 SCIPinfoMessage(scip, file, "* ");
    3784 SCIP_CALL( SCIPprintCons(scip, artcons, file) );
    3785 SCIPinfoMessage(scip, file, ";\n");
    3786 continue;
    3787 }
    3788 }
    3789 }
    3790 }
    3791
    3792 /* if we found the topcost linear inequality which gives us the maximal cost which could be violated,
    3793 * we can stop printing because it is an artificial constraint
    3794 */
    3795 if( strstr(SCIPconsGetName(cons), TOPCOSTCONSNAME) != NULL )
    3796 {
    3797 if( topcostfound )
    3798 SCIPwarningMessage(scip, "further topcost constraint <%s> will be considered as hard constraint\n", SCIPconsGetName(cons));
    3799 else
    3800 {
    3801 topcostfound = TRUE;
    3802
    3803 continue;
    3804 }
    3805 }
    3806
    3807 if( strcmp(conshdlrname, "linear") == 0 )
    3808 {
    3809 if( existands )
    3810 {
    3811 retcode = printNonLinearCons(scip, file,
    3813 SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), resvars, nresvars, andvars, nandvars,
    3814 weight, transformed, multisymbol);
    3815 }
    3816 else
    3817 {
    3818 retcode = printLinearCons(scip, file,
    3820 SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), weight, transformed, multisymbol);
    3821 }
    3822 }
    3823 else if( strcmp(conshdlrname, "setppc") == 0 )
    3824 {
    3825 consvars = SCIPgetVarsSetppc(scip, cons);
    3826 nconsvars = SCIPgetNVarsSetppc(scip, cons);
    3827
    3828 switch( SCIPgetTypeSetppc(scip, cons) )
    3829 {
    3831 if( existands )
    3832 {
    3833 retcode = printNonLinearCons(scip, file, consvars, NULL, nconsvars, 1.0, 1.0, resvars, nresvars,
    3834 andvars, nandvars, weight, transformed, multisymbol);
    3835 }
    3836 else
    3837 {
    3838 retcode = printLinearCons(scip, file,
    3839 consvars, NULL, nconsvars, 1.0, 1.0, weight, transformed, multisymbol);
    3840 }
    3841 break;
    3843 if( existands )
    3844 {
    3845 retcode = printNonLinearCons(scip, file,
    3846 consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, resvars, nresvars, andvars, nandvars,
    3847 weight, transformed, multisymbol);
    3848 }
    3849 else
    3850 {
    3851 retcode = printLinearCons(scip, file,
    3852 consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, weight, transformed, multisymbol);
    3853 }
    3854 break;
    3856 if( existands )
    3857 {
    3858 retcode = printNonLinearCons(scip, file,
    3859 consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), resvars, nresvars, andvars, nandvars,
    3860 weight, transformed, multisymbol);
    3861 }
    3862 else
    3863 {
    3864 retcode = printLinearCons(scip, file,
    3865 consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), weight, transformed, multisymbol);
    3866 }
    3867 break;
    3868 }
    3869 }
    3870 else if( strcmp(conshdlrname, "logicor") == 0 )
    3871 {
    3872 if( existands )
    3873 {
    3874 retcode = printNonLinearCons(scip, file,
    3876 resvars, nresvars, andvars, nandvars, weight, transformed, multisymbol);
    3877 }
    3878 else
    3879 {
    3880 retcode = printLinearCons(scip, file,
    3882 1.0, SCIPinfinity(scip), weight, transformed, multisymbol);
    3883 }
    3884 }
    3885 else if( strcmp(conshdlrname, "knapsack") == 0 )
    3886 {
    3887 SCIP_Longint* weights;
    3888
    3889 consvars = SCIPgetVarsKnapsack(scip, cons);
    3890 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
    3891
    3892 /* copy Longint array to SCIP_Real array */
    3893 weights = SCIPgetWeightsKnapsack(scip, cons);
    3894 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    3895 for( v = 0; v < nconsvars; ++v )
    3896 consvals[v] = (SCIP_Real)weights[v];
    3897
    3898 if( existands )
    3899 {
    3900 retcode = printNonLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
    3901 (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), resvars, nresvars, andvars, nandvars,
    3902 weight, transformed, multisymbol);
    3903 }
    3904 else
    3905 {
    3906 retcode = printLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
    3907 (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), weight, transformed, multisymbol);
    3908 }
    3909
    3910 SCIPfreeBufferArray(scip, &consvals);
    3911 }
    3912 else if( strcmp(conshdlrname, "varbound") == 0 )
    3913 {
    3914 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
    3915 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
    3916
    3917 consvars[0] = SCIPgetVarVarbound(scip, cons);
    3918 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
    3919
    3920 consvals[0] = 1.0;
    3921 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    3922
    3923 if( existands )
    3924 {
    3925 retcode = printNonLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
    3926 SCIPgetRhsVarbound(scip, cons), resvars, nresvars, andvars, nandvars, weight, transformed, multisymbol);
    3927 }
    3928 else
    3929 {
    3930 retcode = printLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
    3931 SCIPgetRhsVarbound(scip, cons), weight, transformed, multisymbol);
    3932 }
    3933
    3934 SCIPfreeBufferArray(scip, &consvals);
    3935 SCIPfreeBufferArray(scip, &consvars);
    3936 }
    3937 else if( strcmp(conshdlrname, "exactlinear") == 0 )
    3938 {
    3939 assert(SCIPisExact(scip));
    3940
    3941 /**@todo add printNonLinearConsExact() for printing exact pseudoboolean */
    3942 if( existands )
    3943 retcode = SCIP_INVALIDDATA;
    3944 else
    3945 {
    3946 retcode = printLinearConsExact(scip, file,
    3949 SCIPgetRhsExactLinear(scip, cons), weightexact, transformed, multisymbol);
    3950 }
    3951 }
    3952 else if( strcmp(conshdlrname, "indicator") == 0 )
    3953 {
    3954 SCIP_CONS* lincons;
    3955 SCIP_VAR* slackvar;
    3956
    3957 /* get artificial binary indicator variables */
    3958 indvar = SCIPgetBinaryVarIndicator(cons);
    3959 assert(indvar != NULL);
    3960
    3962 {
    3963 indvar = SCIPvarGetNegationVar(indvar);
    3964 assert(indvar != NULL);
    3966
    3967 /* get the soft cost of this constraint */
    3968 weight = (SCIP_Longint)SCIPround(scip, SCIPvarGetObj(indvar));
    3969 }
    3970 else
    3971 {
    3973
    3974 /* get the soft cost of this constraint */
    3975 weight = (SCIP_Longint)SCIPround(scip, -SCIPvarGetObj(indvar));
    3976 }
    3977
    3978 /* get artificial slack variable */
    3979 slackvar = SCIPgetSlackVarIndicator(cons);
    3980 assert(slackvar != NULL);
    3981
    3982 /* only need to print indicator constraints with weights on their indicator variable */
    3983 if( weight != 0 )
    3984 {
    3985 SCIP_VAR** scipvarslinear;
    3986 SCIP_Real* scipvalslinear;
    3987 SCIP_Bool cont;
    3988 int nonbinarypos;
    3989
    3990 lincons = SCIPgetLinearConsIndicator(cons);
    3991 assert(lincons != NULL);
    3992
    3993 nconsvars = SCIPgetNVarsLinear(scip, lincons);
    3994 scipvarslinear = SCIPgetVarsLinear(scip, lincons);
    3995 scipvalslinear = SCIPgetValsLinear(scip, lincons);
    3996
    3997 /* allocate temporary memory */
    3998 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, scipvarslinear, nconsvars) );
    3999 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, scipvalslinear, nconsvars) );
    4000
    4001 nonbinarypos = -1;
    4002 cont = FALSE;
    4003
    4004 /* find non-binary variable */
    4005 for( v = 0; v < nconsvars; ++v )
    4006 {
    4007 if( SCIPvarGetType(consvars[v]) == SCIP_VARTYPE_CONTINUOUS )
    4008 {
    4009 if( consvars[v] == slackvar )
    4010 {
    4011 assert(nonbinarypos == -1);
    4012 nonbinarypos = v;
    4013 }
    4014 else
    4015 {
    4016 SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has more than one non-binary variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
    4017 SCIPinfoMessage(scip, file, "* ");
    4018 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    4019 SCIPinfoMessage(scip, file, ";\n");
    4020 cont = TRUE;
    4021 break;
    4022 }
    4023 }
    4024 }
    4025
    4026 /* if we have not found any non-binary variable we do not print the constraint, maybe we should ??? */
    4027 if( nonbinarypos == -1 )
    4028 {
    4029 SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has no slack variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
    4030 SCIPinfoMessage(scip, file, "* ");
    4031 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    4032 SCIPinfoMessage(scip, file, ";\n");
    4033
    4034 /* free temporary memory */
    4035 SCIPfreeBufferArray(scip, &consvals);
    4036 SCIPfreeBufferArray(scip, &consvars);
    4037 continue;
    4038 }
    4039
    4040 /* if the constraint has more than two non-binary variables is not printable and we go to the next */
    4041 if( cont )
    4042 {
    4043 /* free temporary memory */
    4044 SCIPfreeBufferArray(scip, &consvals);
    4045 SCIPfreeBufferArray(scip, &consvars);
    4046 continue;
    4047 }
    4048
    4049 assert(0 <= nonbinarypos && nonbinarypos < nconsvars);
    4050
    4051 /* remove slackvariable in linear constraint for printing */
    4052 --nconsvars;
    4053 consvars[nonbinarypos] = consvars[nconsvars];
    4054 consvals[nonbinarypos] = consvals[nconsvars];
    4055
    4056 if( existands )
    4057 {
    4058 retcode = printNonLinearCons(scip, file,
    4059 consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
    4060 resvars, nresvars, andvars, nandvars,
    4061 weight, transformed, multisymbol);
    4062 }
    4063 else
    4064 {
    4065 retcode = printLinearCons(scip, file,
    4066 consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
    4067 weight, transformed, multisymbol);
    4068 }
    4069
    4070 /* free temporary memory */
    4071 SCIPfreeBufferArray(scip, &consvals);
    4072 SCIPfreeBufferArray(scip, &consvars);
    4073 }
    4074 else
    4075 {
    4076 SCIPwarningMessage(scip, "indicator constraint <%s> will not be printed because the indicator variable has no objective value(= weight of this soft constraint)\n", SCIPconsGetName(cons) );
    4077 SCIPinfoMessage(scip, file, "* ");
    4078 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    4079 SCIPinfoMessage(scip, file, ";\n");
    4080 }
    4081 }
    4082 else if( strcmp(conshdlrname, "and") == 0 )
    4083 {
    4084 /* all resultants of the and constraint will be replaced by all corresponding variables of this constraint,
    4085 * so no and-constraint will be printed directly
    4086 */
    4087 assert(existandconshdlr);
    4088 }
    4089 else if( strcmp(conshdlrname, "pseudoboolean") == 0 )
    4090 {
    4091 /* all and-resultants in linear constraints will be replaced by the corresponding variable products,
    4092 * so no pseudoboolean constraint will be printed directly
    4093 */
    4094 assert(existands);
    4095 }
    4096 else
    4097 {
    4098 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
    4099 SCIPinfoMessage(scip, file, "* ");
    4100 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    4101 SCIPinfoMessage(scip, file, ";\n");
    4102 }
    4103 }
    4104
    4105 if( retcode == SCIP_INVALIDDATA )
    4106 {
    4107 assert(cons != NULL);
    4108
    4109 SCIPerrorMessage("Cannot print constraint %s with non-integral coefficient or sides in opb-format\n",
    4110 SCIPconsGetName(cons));
    4111 SCIP_CALL( SCIPprintCons(scip, cons, stderr) );
    4112 SCIPinfoMessage(scip, file, ";\n");
    4113 }
    4114
    4115 if( linconssofpbsmap != NULL )
    4116 SCIPhashmapFree(&linconssofpbsmap);
    4117 if( linconssofindicatorsmap != NULL )
    4118 SCIPhashmapFree(&linconssofindicatorsmap);
    4119 if( weightexact != NULL )
    4120 SCIPrationalFreeBuffer(SCIPbuffer(scip), &weightexact);
    4121
    4122 return retcode;
    4123}
    4124
    4125/* write fixed variables (unless already done because they are an and resultant or and variable) */
    4126static
    4128 SCIP*const scip, /**< SCIP data structure */
    4129 FILE*const file, /**< output file, or NULL if standard output should be used */
    4130 SCIP_VAR** vars, /**< array with active (binary) variables */
    4131 int nvars, /**< number of active variables in the problem */
    4132 SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
    4133 char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
    4134 SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
    4135 )
    4136{
    4137 char linebuffer[OPB_MAX_LINELEN+1];
    4138 char buffer[OPB_MAX_LINELEN];
    4139 int linecnt;
    4140 int v;
    4141
    4142 assert(scip != NULL);
    4143 assert(file != NULL);
    4144 assert(vars != NULL || nvars == 0);
    4145 assert(printedfixing != NULL);
    4146 assert(multisymbol != NULL);
    4147
    4148 clearBuffer(linebuffer, &linecnt);
    4149
    4150 /* print variables which are fixed */
    4151 for( v = 0; v < nvars; ++v )
    4152 {
    4153 SCIP_VAR* var;
    4154 SCIP_Real lb;
    4155 SCIP_Real ub;
    4156 SCIP_Bool neg = FALSE;
    4157
    4158 assert( vars != NULL );
    4159 var = vars[v];
    4160
    4161 if( transformed )
    4162 {
    4163 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    4164 lb = SCIPvarGetLbLocal(var);
    4165 ub = SCIPvarGetUbLocal(var);
    4166 }
    4167 else
    4168 {
    4169 lb = SCIPvarGetLbOriginal(var);
    4170 ub = SCIPvarGetUbOriginal(var);
    4171 }
    4172 assert(lb > -0.5 && ub < 1.5);
    4173 assert(SCIPisFeasIntegral(scip, lb));
    4174 assert(SCIPisFeasIntegral(scip, ub));
    4175
    4176 /* print fixed and-resultants */
    4177 if( lb > 0.5 || ub < 0.5 )
    4178 {
    4179 if( transformed ) {
    4180 SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &var, &neg) );
    4181 }
    4182
    4183 if( SCIPhashtableExists(printedfixing, (void*)var) )
    4184 continue;
    4185
    4186 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %.15g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
    4187 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4188
    4189 /* add variable to the hashmap */
    4190 SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
    4191 }
    4192 }
    4193
    4194 writeBuffer(scip, file, linebuffer, &linecnt);
    4195
    4196 return SCIP_OKAY;
    4197}
    4198
    4199/* write and constraints of inactive but relevant and-resultants and and variables which are fixed to one */
    4200static
    4202 SCIP*const scip, /**< SCIP data structure */
    4203 FILE*const file, /**< output file, or NULL if standard output should be used */
    4204 SCIP_VAR**const resvars, /**< array of resultant variables */
    4205 int const nresvars, /**< number of resultant variables */
    4206 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    4207 int const*const nandvars, /**< array of numbers of corresponding and-variables */
    4208 SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
    4209 char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
    4210 SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
    4211 )
    4212{
    4213 SCIP_VAR* resvar;
    4214 SCIP_Longint rhslhs;
    4215 char linebuffer[OPB_MAX_LINELEN+1];
    4216 char buffer[OPB_MAX_LINELEN];
    4217 int linecnt;
    4218 int r, v;
    4219
    4220 assert(scip != NULL);
    4221 assert(file != NULL);
    4222 assert(resvars != NULL || nresvars == 0);
    4223 assert(nandvars != NULL || nresvars == 0);
    4224 assert(andvars != NULL || nandvars == NULL);
    4225 assert(multisymbol != NULL);
    4226
    4227 clearBuffer(linebuffer, &linecnt);
    4228
    4229 /* print and-variables which are fixed */
    4230 /* @todo remove this block here and the hashtable and let writeOpbFixedVars() do the job? */
    4231 for( r = nresvars - 1; r >= 0; --r )
    4232 {
    4233 SCIP_VAR* var;
    4234 SCIP_Bool neg;
    4235 SCIP_Real lb;
    4236 SCIP_Real ub;
    4237
    4238 assert( resvars != NULL );
    4239 resvar = resvars[r];
    4240
    4241 if( transformed )
    4242 {
    4243 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    4244 lb = SCIPvarGetLbLocal(resvar);
    4245 ub = SCIPvarGetUbLocal(resvar);
    4246 }
    4247 else
    4248 {
    4249 lb = SCIPvarGetLbOriginal(resvar);
    4250 ub = SCIPvarGetUbOriginal(resvar);
    4251 }
    4252
    4253 /* print fixed and-resultants */
    4254 if( lb > 0.5 || ub < 0.5 )
    4255 {
    4256 /* coverity[copy_paste_error] */
    4257 SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &var, &neg) );
    4258
    4259 assert(SCIPisFeasIntegral(scip, lb));
    4260 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " +1%s%s%s = %.15g;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
    4261 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4262
    4263 /* add variable to the hashmap */
    4264 SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
    4265 }
    4266
    4267 assert( andvars != NULL && nandvars != NULL );
    4268 assert( andvars[r] != NULL || nandvars[r] == 0 );
    4269
    4270 /* print fixed and-variables */
    4271 for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
    4272 {
    4273 assert( andvars[r] != NULL );
    4274 assert( andvars[r][v] != NULL );
    4275
    4276 if( transformed )
    4277 {
    4278 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    4279 lb = SCIPvarGetLbLocal(andvars[r][v]);
    4280 ub = SCIPvarGetUbLocal(andvars[r][v]);
    4281 }
    4282 else
    4283 {
    4284 lb = SCIPvarGetLbOriginal(andvars[r][v]);
    4285 ub = SCIPvarGetUbOriginal(andvars[r][v]);
    4286 }
    4287
    4288 if( lb > 0.5 || ub < 0.5 )
    4289 {
    4290 SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
    4291
    4292 assert(SCIPisFeasIntegral(scip, lb));
    4293 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " +1%s%s%s = %.15g;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
    4294 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4295
    4296 /* add variable to the hashmap */
    4297 SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
    4298 }
    4299 }
    4300 }
    4301
    4302 /* print and-constraints with fixed and-resultant to zero and all and-constraints with
    4303 * aggregated resultant, otherwise we would loose this information
    4304 */
    4305 for( r = nresvars - 1; r >= 0; --r )
    4306 {
    4307 assert( resvars != NULL );
    4308 resvar = resvars[r];
    4309 rhslhs = (SCIPvarGetUbLocal(resvar) < 0.5) ? 0 : ((SCIPvarGetLbLocal(resvar) > 0.5) ? 1 : -1);
    4310
    4311 /* if and resultant is fixed to 0 and at least one and-variable is fixed to zero, we don't print this redundant constraint */
    4312 if( rhslhs == 0 )
    4313 {
    4314 SCIP_Bool cont;
    4315
    4316 cont = FALSE;
    4317
    4318 assert( andvars != NULL && nandvars != NULL );
    4319 assert( andvars[r] != NULL || nandvars[r] == 0 );
    4320
    4321 /* if resultant variable and one other and variable is already zero, so we did not need to print this and
    4322 * constraint because all other variables are free
    4323 */
    4324 for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
    4325 {
    4326 assert( andvars[r] != NULL );
    4327 assert( andvars[r][v] != NULL );
    4328
    4329 if( SCIPvarGetUbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
    4330 {
    4331 cont = TRUE;
    4332 break;
    4333 }
    4334 }
    4335
    4336 if( cont )
    4337 continue;
    4338 }
    4339 /* if and resultant is fixed to 1 and all and-variable are fixed to 1 too, we don't print this redundant constraint */
    4340 else if( rhslhs == 1 )
    4341 {
    4342 SCIP_Bool cont;
    4343
    4344 cont = TRUE;
    4345
    4346 assert( andvars != NULL && nandvars != NULL );
    4347 assert( andvars[r] != NULL || nandvars[r] == 0 );
    4348
    4349 /* if all variables are already fixed to one, we do not need to print this and constraint */
    4350 for( v = nandvars[r] - 1; v >= 0; --v )
    4351 {
    4352 assert( andvars[r] != NULL );
    4353 assert( andvars[r][v] != NULL );
    4354
    4355 if( SCIPvarGetLbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
    4356 {
    4357 cont = FALSE;
    4358 break;
    4359 }
    4360 }
    4361
    4362 if( cont )
    4363 continue;
    4364 }
    4365
    4366 /* print and with fixed or aggregated and-resultant */
    4367 /* rhslhs equals to 0 means the and constraint is relevant due to it's not clear on which values the and variables are
    4368 * rhslhs equals to 1 means the and constraint is irrelevant cause all and variables have to be 1 too
    4369 * rhslhs equals to -1 means the and constraint is relevant cause the variable is only aggregated */
    4370 if( !SCIPvarIsActive(resvar) )
    4371 {
    4372 SCIP_VAR* var;
    4373 SCIP_Bool neg;
    4374 SCIP_Bool firstprinted;
    4375
    4376 firstprinted = FALSE;
    4377
    4378 assert( andvars != NULL && nandvars != NULL );
    4379 assert( andvars[r] != NULL || nandvars[r] == 0 );
    4380
    4381 for( v = nandvars[r] - 1; v >= 0; --v )
    4382 {
    4383 assert( andvars[r] != NULL );
    4384 assert( andvars[r][v] != NULL );
    4385
    4386 SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
    4387
    4388 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", (firstprinted) ? multisymbol : "", neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"));
    4389 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4390
    4391 firstprinted = TRUE;
    4392 }
    4393
    4394 /* if the resultant is aggregated we need to print his binary representation */
    4395 if( rhslhs == -1 )
    4396 {
    4397 int pos;
    4398
    4399 assert(transformed);
    4400
    4401 SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &resvar, &neg) );
    4402
    4403#ifndef NDEBUG
    4404 if( neg )
    4405 assert(SCIPvarIsActive(SCIPvarGetNegationVar(resvar)));
    4406 else
    4407 assert(SCIPvarIsActive(resvar));
    4408#endif
    4409
    4410 /* replace and-resultant with corresponding variables */
    4411 if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, neg ? SCIPvarGetNegationVar(resvar) : resvar, nresvars, &pos) )
    4412 {
    4413 SCIP_Bool negated;
    4414 int a;
    4415
    4416 assert(andvars != NULL);
    4417 assert(nandvars != NULL);
    4418 assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
    4419 assert(andvars[pos][nandvars[pos] - 1] != NULL);
    4420
    4421 negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
    4422
    4423 /* print and-vars */
    4424 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, neg ? " +1%s%s%s" : " -1%s%s%s", multisymbol, negated ? "~" : "",
    4425 strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
    4426 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4427
    4428 for(a = nandvars[pos] - 2; a >= 0; --a )
    4429 {
    4430 negated = SCIPvarIsNegated(andvars[pos][a]);
    4431
    4432 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
    4433 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4434 }
    4435
    4436 appendBuffer(scip, file, linebuffer, &linecnt, " ");
    4437
    4438 if( neg )
    4439 rhslhs = 1;
    4440 else
    4441 rhslhs = 0;
    4442 }
    4443 else
    4444 {
    4445 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " -1%s%s%s", multisymbol, neg ? "~" : "",
    4446 strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(resvar) : resvar), "x"));
    4447 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4448
    4449 rhslhs = 0;
    4450 }
    4451 }
    4452
    4453 /* print rhslhs */
    4454 (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " = %+" SCIP_LONGINT_FORMAT ";\n", rhslhs);
    4455 appendBuffer(scip, file, linebuffer, &linecnt, buffer);
    4456
    4457 writeBuffer(scip, file, linebuffer, &linecnt);
    4458 }
    4459 }
    4460
    4461 return SCIP_OKAY;
    4462}
    4463
    4464/* writes problem to file */
    4465static
    4467 SCIP* scip, /**< SCIP data structure */
    4468 FILE* file, /**< output file, or NULL if standard output should be used */
    4469 const char* name, /**< problem name */
    4470 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4471 SCIP_OBJSENSE objsense, /**< objective sense */
    4472 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    4473 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    4474 * extobj = objsense * objscale * (intobj + objoffset) */
    4475 SCIP_RATIONAL* objoffsetexact, /**< exact objective offset from bound shifting and fixing */
    4476 SCIP_RATIONAL* objscaleexact, /**< exact scalar applied to objective function; external objective value is
    4477 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
    4478 SCIP_VAR** vars, /**< array with active (binary) variables */
    4479 int nvars, /**< number of active variables in the problem */
    4480 SCIP_CONS** conss, /**< array with constraints of the problem */
    4481 int nconss, /**< number of constraints in the problem */
    4482 SCIP_VAR** const resvars, /**< array of resultant variables */
    4483 int const nresvars, /**< number of resultant variables */
    4484 SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
    4485 int const*const nandvars, /**< array of numbers of corresponding and-variables */
    4486 SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
    4487 SCIP_Bool const existands, /**< does some and-constraints exist? */
    4488 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    4489 )
    4490{
    4491 char multisymbol[OPB_MAX_LINELEN];
    4492 SCIP_HASHTABLE* printedfixing;
    4493 SCIP_Bool usesymbol;
    4494 SCIP_RETCODE retcode;
    4495 int nlinearconss;
    4496 int nindicatorconss;
    4497
    4498 assert( scip != NULL );
    4499 assert( vars != NULL || nvars == 0 );
    4500 assert( conss != NULL || nconss == 0 );
    4501 assert( result != NULL );
    4502
    4503 /* check if should use a multipliers symbol star '*' between coefficients and variables */
    4504 SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/multisymbol", &usesymbol) );
    4505 (void) SCIPsnprintf(multisymbol, OPB_MAX_LINELEN, "%s", usesymbol ? " * " : " ");
    4506
    4507 /* determine how many split linear and indicator constraints exist */
    4508 determineTotalNumberLinearConss(scip, conss, nconss, &nlinearconss, &nindicatorconss);
    4509
    4510 /* print statistics as comment to file */
    4511 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
    4512 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
    4513 SCIPinfoMessage(scip, file, "* Variables : %d\n", nvars - nresvars - nindicatorconss);
    4514 SCIPinfoMessage(scip, file, "* Constraints : %d\n", nlinearconss);
    4515
    4516 /* create a hash table */
    4517 SCIP_CALL( SCIPhashtableCreate(&printedfixing, SCIPblkmem(scip), nvars,
    4518 SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
    4519
    4520 /* write objective function */
    4521 SCIP_CALL( writeOpbObjective(scip, file, vars, nvars, resvars, nresvars, andvars, nandvars,
    4522 objsense, objoffset, objscale, objoffsetexact, objscaleexact, multisymbol, existands, transformed) );
    4523
    4524 /* write constraints */
    4525 retcode = writeOpbConstraints(scip, file, conss, nconss, vars, nvars, resvars, nresvars, andvars, nandvars,
    4526 multisymbol, existandconshdlr, existands, transformed);
    4527
    4528 if( existands && (retcode == SCIP_OKAY) )
    4529 {
    4530 /* write and constraints of inactive but relevant and-resultants and and-variables which are fixed to one
    4531 with no fixed and resultant */
    4532 SCIP_CALL( writeOpbRelevantAnds(scip, file, resvars, nresvars, andvars, nandvars, printedfixing, multisymbol, transformed) );
    4533 }
    4534
    4535 /* write fixed variables */
    4536 SCIP_CALL( writeOpbFixedVars(scip, file, vars, nvars, printedfixing, multisymbol, transformed) );
    4537
    4538 SCIPhashtableFree(&printedfixing);
    4539
    4540 *result = SCIP_SUCCESS;
    4541
    4542 return retcode;
    4543}
    4544
    4545
    4546/*
    4547 * extern methods
    4548 */
    4549
    4550/** reads problem from file */
    4552 SCIP* scip, /**< SCIP data structure */
    4553 SCIP_READER* reader, /**< the file reader itself */
    4554 const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
    4555 SCIP_RESULT* result /**< pointer to store the result of the file reading call */
    4556 )
    4557{ /*lint --e{715}*/
    4558 OPBINPUT opbinput;
    4559 SCIP_RETCODE retcode;
    4560 int i;
    4561
    4562 assert(scip != NULL); /* for lint */
    4563 assert(reader != NULL);
    4564 assert(result != NULL);
    4565
    4566 *result = SCIP_DIDNOTRUN;
    4567
    4568 /* initialize OPB input data (use block memory because order can change during execution) */
    4569 opbinput.file = NULL;
    4571 opbinput.linebuf[0] = '\0';
    4572 opbinput.linebufsize = OPB_MAX_LINELEN;
    4574 opbinput.token[0] = '\0';
    4576 opbinput.tokenbuf[0] = '\0';
    4577 for( i = 0; i < OPB_MAX_PUSHEDTOKENS; ++i )
    4578 {
    4579 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(opbinput.pushedtokens[i]), OPB_MAX_LINELEN) ); /*lint !e866 */
    4580 }
    4581
    4582 opbinput.npushedtokens = 0;
    4583 opbinput.linenumber = 1;
    4584 opbinput.linepos = 0;
    4585 opbinput.objsense = SCIP_OBJSENSE_MINIMIZE;
    4586 opbinput.eof = FALSE;
    4587 opbinput.haserror = FALSE;
    4588 opbinput.nproblemcoeffs = 0;
    4589 opbinput.wbo = FALSE;
    4590 opbinput.topcost = -SCIPinfinity(scip);
    4591 opbinput.nindvars = 0;
    4592#if GENCONSNAMES == TRUE
    4593 opbinput.consnumber = 0;
    4594#endif
    4595
    4596 /* read the file */
    4597 retcode = readOPBFile(scip, reader, &opbinput, filename);
    4598
    4599 /* free dynamically allocated memory */
    4600 for( i = OPB_MAX_PUSHEDTOKENS - 1; i >= 0; --i )
    4601 {
    4602 SCIPfreeBlockMemoryArray(scip, &(opbinput.pushedtokens[i]), OPB_MAX_LINELEN);
    4603 }
    4604 SCIPfreeBlockMemoryArray(scip, &opbinput.tokenbuf, OPB_MAX_LINELEN);
    4606 SCIPfreeBlockMemoryArray(scip, &opbinput.linebuf, opbinput.linebufsize);
    4607
    4608 if( retcode == SCIP_PLUGINNOTFOUND || retcode == SCIP_INVALIDDATA )
    4609 retcode = SCIP_READERROR;
    4610
    4611 SCIP_CALL( retcode );
    4612
    4613 if( opbinput.nproblemcoeffs > 0 )
    4614 {
    4615 SCIPwarningMessage(scip, "there might be <%d> coefficients or weight out of range!\n", opbinput.nproblemcoeffs);
    4616 }
    4617
    4618 /* evaluate the result */
    4619 if( opbinput.haserror )
    4620 return SCIP_READERROR;
    4621 else
    4622 {
    4623 /* set objective sense */
    4624 SCIP_CALL( SCIPsetObjsense(scip, opbinput.objsense) );
    4625 *result = SCIP_SUCCESS;
    4626 }
    4627
    4628 return SCIP_OKAY;
    4629}
    4630
    4631/** writes problem to file */
    4633 SCIP* scip, /**< SCIP data structure */
    4634 FILE* file, /**< output file, or NULL if standard output should be used */
    4635 const char* name, /**< problem name */
    4636 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    4637 SCIP_OBJSENSE objsense, /**< objective sense */
    4638 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    4639 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    4640 * extobj = objsense * objscale * (intobj + objoffset) */
    4641 SCIP_RATIONAL* objoffsetexact, /**< exact objective offset from bound shifting and fixing */
    4642 SCIP_RATIONAL* objscaleexact, /**< exact scalar applied to objective function; external objective value is
    4643 * extobjexact = objsense * objscaleexact * (intobjexact + objoffsetexact) */
    4644 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
    4645 int nvars, /**< number of active variables in the problem */
    4646 int nbinvars, /**< number of binary variables */
    4647 int nintvars, /**< number of general integer variables */
    4648 int nimplvars, /**< number of implicit integer variables */
    4649 int ncontvars, /**< number of continuous variables */
    4650 SCIP_VAR** fixedvars, /**< array with fixed variables */
    4651 int nfixedvars, /**< number of fixed and aggregated variables in the problem */
    4652 SCIP_CONS** conss, /**< array with constraints of the problem */
    4653 int nconss, /**< number of constraints in the problem */
    4654 SCIP_Bool genericnames, /**< should generic variable and constraint names be used */
    4655 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    4656 ) /*lint --e{715}*/
    4657{ /*lint --e{715}*/
    4658 SCIP_VAR*** andvars;
    4659 SCIP_VAR** resvars;
    4660 SCIP_CONSHDLR* indicatorhdlr = SCIPfindConshdlr(scip, "indicator");
    4661 SCIP_Bool existands;
    4662 SCIP_Bool existandconshdlr;
    4663 SCIP_Bool ispseudoboolean;
    4664 SCIP_RETCODE retcode = SCIP_OKAY;
    4665 int* nandvars;
    4666 int nintegralvars = nvars - ncontvars;
    4667 int nindicatorconss = indicatorhdlr != NULL ? SCIPconshdlrGetNConss(indicatorhdlr) : 0;
    4668 int nresvars;
    4669 int v;
    4670
    4671 /* check whether problem is pseudoboolean */
    4672 ispseudoboolean = (ncontvars <= nindicatorconss);
    4673 for( v = nbinvars; v < nintegralvars && ispseudoboolean; ++v )
    4674 {
    4675 if( !SCIPvarIsBinary(vars[v])
    4676 && ( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER || ++ncontvars > nindicatorconss ) )
    4677 ispseudoboolean = FALSE;
    4678 }
    4679
    4680 if( ispseudoboolean )
    4681 {
    4682 /* computes all and-resultants and their corresponding constraint variables */
    4683 /* coverity[leaked_storage] */
    4684 SCIP_CALL( computeAndConstraintInfos(scip, transformed, &resvars, &nresvars, &andvars, &nandvars, &existandconshdlr, &existands) );
    4685
    4686 if( genericnames )
    4687 {
    4688#ifndef NDEBUG
    4689 /* check for correct names for opb-format */
    4690 int idx;
    4691 int pos;
    4692
    4693 for( v = nvars - 1; v >= 0; --v )
    4694 {
    4695 if( existands )
    4696 {
    4697 /* and variables are artificial */
    4698 if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
    4699 continue;
    4700 }
    4701
    4702 assert(sscanf(SCIPvarGetName(vars[v]), "x%d", &idx) == 1); /* cppcheck-suppress assertWithSideEffect */
    4703 }
    4704#endif
    4705 retcode = writeOpb(scip, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
    4706 vars, nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
    4707 }
    4708 else
    4709 {
    4710 SCIP_Bool printed;
    4711 int idx;
    4712 int pos;
    4713
    4714 printed = FALSE;
    4715
    4716 /* check if there are already generic names for all (not fixed variables)*/
    4717 for( v = nvars - 1; v >= 0; --v )
    4718 if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
    4719 {
    4720 if( sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) == NULL )
    4721 {
    4722 SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
    4723 SCIP_CALL( SCIPprintVar(scip, vars[v], NULL) );
    4724 SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
    4725
    4726 if( transformed )
    4727 {
    4728 SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
    4729 SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
    4730 }
    4731 else
    4732 {
    4733 SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
    4734 SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
    4735 }
    4736 printed = TRUE;
    4737 break;
    4738 }
    4739 }
    4740
    4741 if( !printed )
    4742 {
    4743 /* check if there are already generic names for all (fixed variables)*/
    4744 for( v = nfixedvars - 1; v >= 0; --v )
    4745 if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
    4746 {
    4747 /* coverity[secure_coding] */
    4748 if( sscanf(SCIPvarGetName(fixedvars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(fixedvars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(fixedvars[v]), INDICATORSLACKVARNAME) == NULL )
    4749 {
    4750 SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
    4751 SCIP_CALL( SCIPprintVar(scip, fixedvars[v], NULL) );
    4752 SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
    4753
    4754 if( transformed )
    4755 {
    4756 SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
    4757 SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
    4758 }
    4759 else
    4760 {
    4761 SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
    4762 SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
    4763 }
    4764 printed = TRUE;
    4765 break;
    4766 }
    4767 }
    4768 }
    4769
    4770 if( !printed )
    4771 {
    4772#ifndef NDEBUG
    4773 for( v = nvars - 1; v >= 0; --v )
    4774 {
    4775 if( existands )
    4776 {
    4777 if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
    4778 continue;
    4779 }
    4780
    4781 assert(sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) == 1 || strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) != NULL || strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) != NULL ); /* cppcheck-suppress assertWithSideEffect */
    4782 }
    4783#endif
    4784 retcode = writeOpb(scip, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
    4785 vars, nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
    4786 }
    4787 }
    4788
    4789 if( existands )
    4790 {
    4791 /* free temporary buffers */
    4792 assert(resvars != NULL);
    4793 assert(andvars != NULL);
    4794 assert(nandvars != NULL);
    4795
    4796 for( v = nresvars - 1; v >= 0; --v )
    4797 {
    4798 assert(andvars[v] != NULL);
    4799 SCIPfreeMemoryArray(scip, &andvars[v]);
    4800 }
    4801
    4802 SCIPfreeMemoryArray(scip, &nandvars);
    4803 SCIPfreeMemoryArray(scip, &andvars);
    4804 SCIPfreeMemoryArray(scip, &resvars);
    4805 }
    4806
    4807 *result = SCIP_SUCCESS;
    4808 }
    4809 else
    4810 {
    4811 SCIPwarningMessage(scip, "only binary problems can be written in OPB format.\n");
    4812 *result = SCIP_DIDNOTRUN;
    4813 }
    4814
    4815 if( retcode == SCIP_INVALIDDATA )
    4816 return SCIP_WRITEERROR;
    4817
    4818 return retcode;
    4819}
    4820
    4821/*
    4822 * Callback methods of reader
    4823 */
    4824
    4825/** copy method for reader plugins (called when SCIP copies plugins) */
    4826static
    4828{ /*lint --e{715}*/
    4829 assert(scip != NULL);
    4830 assert(reader != NULL);
    4831 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4832
    4833 /* call inclusion method of reader */
    4835
    4836 return SCIP_OKAY;
    4837}
    4838
    4839
    4840/** destructor of reader to free user data (called when SCIP is exiting) */
    4841static
    4843{
    4844 SCIP_READERDATA* readerdata;
    4845
    4846 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4847 readerdata = SCIPreaderGetData(reader);
    4848 SCIPfreeBlockMemory(scip, &readerdata);
    4849
    4850 return SCIP_OKAY;
    4851}
    4852
    4853
    4854/** problem reading method of reader */
    4855static
    4857{ /*lint --e{715}*/
    4858
    4859 SCIP_CALL( SCIPreadOpb(scip, reader, filename, result) );
    4860
    4861 return SCIP_OKAY;
    4862}
    4863
    4864
    4865/** problem writing method of reader */
    4866static
    4868{ /*lint --e{715}*/
    4869 assert(reader != NULL);
    4870 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    4871
    4872 if( SCIPisExact(scip) )
    4873 {
    4874 SCIPerrorMessage("OPB reader cannot yet write problems in exact solving mode\n");
    4875 return SCIP_WRITEERROR;
    4876 }
    4877
    4878 SCIP_CALL( SCIPwriteOpb(scip, file, name, transformed, objsense, objoffset, objscale, objoffsetexact, objscaleexact,
    4879 vars, nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, genericnames, result) );
    4880
    4881 return SCIP_OKAY;
    4882}
    4883
    4884/*
    4885 * reader specific interface methods
    4886 */
    4887
    4888/** includes the opb file reader in SCIP */
    4890 SCIP* scip /**< SCIP data structure */
    4891 )
    4892{
    4893 SCIP_READERDATA* readerdata;
    4894 SCIP_READER* reader;
    4895
    4896 /* create reader data */
    4897 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
    4898
    4899 /* include reader */
    4901
    4902 /* reader is safe to use in exact solving mode, but exact writing still needs to be implemented */
    4903 SCIPreaderMarkExact(reader);
    4904
    4905 /* set non fundamental callbacks via setter functions */
    4906 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOpb) );
    4907 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeOpb) );
    4908 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOpb) );
    4909 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteOpb) );
    4910
    4911 /* add opb reader parameters */
    4913 "reading/" READER_NAME "/dynamicconss", "should model constraints be subject to aging?",
    4914 NULL, FALSE, FALSE/*TRUE*/, NULL, NULL) ); /* have to be FALSE, otherwise an error might inccur in restart during branch and bound */
    4916 "reading/" READER_NAME "/multisymbol", "use '*' between coefficients and variables by writing to problem?",
    4917 NULL, TRUE, FALSE, NULL, NULL) );
    4918 SCIP_CALL( SCIPaddIntParam(scip, "reading/" READER_NAME "/maxintsize", "maximum allowed 'intsize' (i.e. the number of "
    4919 "bits required to represent the sum of absolute values of all integers that appear in a constraint or "
    4920 "objective function) or -1 for unlimited",
    4921 &readerdata->maxintsize, TRUE, OPB_MAX_INTSIZE, -1, INT_MAX, NULL, NULL) );
    4922
    4923 return SCIP_OKAY;
    4924}
    SCIP_VAR * w
    Definition: circlepacking.c:67
    SCIP_VAR * a
    Definition: circlepacking.c:66
    SCIP_Real * r
    Definition: circlepacking.c:59
    Constraint handler for AND constraints, .
    Constraint handler for linear constraints in their most general form, .
    constraint handler for indicator constraints
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    constraint handler for pseudoboolean constraints
    #define ARTIFICIALVARNAMEPREFIX
    Constraint handler for the set partitioning / packing / covering constraints .
    Constraint handler for variable bound constraints .
    methods for debugging
    #define SCIPdebugGetSolVal(scip, var, val)
    Definition: debug.h:312
    #define SCIPdebugAddSolVal(scip, var, val)
    Definition: debug.h:311
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define ABS(x)
    Definition: def.h:216
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:376
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    int SCIPfeof(SCIP_FILE *stream)
    Definition: fileio.c:227
    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)
    SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_VAR ** SCIPgetVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, 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)
    Definition: cons_and.c:5059
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5248
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    int SCIPgetNVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    SCIP_VAR * SCIPgetIndVarPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
    SCIP_RETCODE SCIPcreateConsPseudoboolean(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR **linvars, int nlinvars, SCIP_Real *linvals, SCIP_VAR ***terms, int nterms, int *ntermvars, SCIP_Real *termvals, SCIP_VAR *indvar, SCIP_Real weight, SCIP_Bool issoftcons, 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 ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9619
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9642
    SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
    SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5223
    SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_CONS * SCIPgetLinearConsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
    SCIP_RATIONAL ** SCIPgetValsExactLinear(SCIP *scip, 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 SCIPreadOpb(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
    Definition: reader_opb.c:4551
    SCIP_RETCODE SCIPwriteOpb(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objoffset, SCIP_Real objscale, SCIP_RATIONAL *objoffsetexact, SCIP_RATIONAL *objscaleexact, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_VAR **fixedvars, int nfixedvars, SCIP_CONS **conss, int nconss, SCIP_Bool genericnames, SCIP_RESULT *result)
    Definition: reader_opb.c:4632
    SCIP_RETCODE SCIPincludeReaderOpb(SCIP *scip)
    Definition: reader_opb.c:4889
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    int SCIPgetNOrigConss(SCIP *scip)
    Definition: scip_prob.c:3712
    SCIP_Real SCIPgetOrigObjoffset(SCIP *scip)
    Definition: scip_prob.c:1529
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:696
    SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:652
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
    Definition: scip_prob.c:1486
    SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
    Definition: scip_prob.c:3739
    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
    SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
    Definition: scip_prob.c:3189
    SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
    Definition: scip_prob.c:3525
    SCIP_RETCODE SCIPaddOrigObjoffsetExact(SCIP *scip, SCIP_RATIONAL *addval)
    Definition: scip_prob.c:1465
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    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
    #define SCIPdebugMsgPrint
    Definition: scip_message.h:79
    SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
    Definition: scip_message.c:88
    #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 SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
    Definition: cons.c:8698
    SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
    Definition: cons.c:8486
    const char * SCIPconsGetName(SCIP_CONS *cons)
    Definition: cons.c:8389
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #define SCIPreallocMemoryArray(scip, ptr, newnum)
    Definition: scip_mem.h:70
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:64
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:76
    #define SCIPfreeMemoryArray(scip, ptr)
    Definition: scip_mem.h:80
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:935
    int SCIPrationalToString(SCIP_RATIONAL *rational, char *str, int strlen)
    Definition: rational.cpp:1743
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:983
    SCIP_RETCODE SCIPrationalCopyBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:267
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1790
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:630
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1650
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1660
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:214
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1670
    void SCIPrationalDivReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1147
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1404
    SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:314
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:518
    SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
    Definition: scip_reader.c:109
    SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
    Definition: scip_reader.c:147
    SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
    Definition: reader.c:605
    SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
    Definition: scip_reader.c:171
    const char * SCIPreaderGetName(SCIP_READER *reader)
    Definition: reader.c:680
    SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
    Definition: scip_reader.c:195
    void SCIPreaderMarkExact(SCIP_READER *reader)
    Definition: reader.c:670
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
    Definition: var.c:23868
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
    Definition: var.c:24020
    SCIP_RETCODE SCIPaddVarExactData(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *lb, SCIP_RATIONAL *ub, SCIP_RATIONAL *obj)
    Definition: scip_var.c:299
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_RETCODE SCIPvarGetOrigvarSumExact(SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
    Definition: var.c:18409
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23652
    SCIP_RETCODE SCIPcreateVarImpl(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, 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:225
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
    Definition: var.c:24063
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPgetProbvarLinearSumExact(SCIP *scip, SCIP_VAR **vars, SCIP_RATIONAL **scalars, int *nvars, int varssize, SCIP_RATIONAL *constant, int *requiredsize, SCIP_Bool mergemultiples)
    Definition: scip_var.c:2443
    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 SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
    Definition: scip_var.c:2166
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
    Definition: var.c:23443
    SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
    Definition: var.c:23878
    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_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
    Definition: scip_var.c:12465
    SCIP_RETCODE SCIPchgVarObjExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newobj)
    Definition: scip_var.c:5420
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
    Definition: scip_var.c:2236
    SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
    Definition: var.c:23910
    SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
    Definition: scip_var.c:5519
    SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
    void SCIPsortPtrPtrInt(void **ptrarray1, void **ptrarray2, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    int SCIPstrcasecmp(const char *s1, const char *s2)
    Definition: misc.c:10863
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    void SCIPprintSysError(const char *message)
    Definition: misc.c:10719
    int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
    Definition: misc.c:10694
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    memory allocation routines
    SCIP_RATIONAL * SCIPconsGetRhsExact(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    Definition: misc_linear.c:176
    SCIP_Real SCIPconsGetLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    Definition: misc_linear.c:112
    SCIP_RATIONAL * SCIPconsGetLhsExact(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    Definition: misc_linear.c:213
    SCIP_Real SCIPconsGetRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
    Definition: misc_linear.c:48
    public methods for managing constraints
    wrapper functions to map file i/o to standard or zlib file i/o
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for input file readers
    public methods for problem variables
    wrapper for rational number arithmetic
    static const char delimchars[]
    Definition: reader_fzn.c:225
    static SCIP_RETCODE writeOpbRelevantAnds(SCIP *const scip, FILE *const file, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
    Definition: reader_opb.c:4201
    OpbExpType
    Definition: reader_opb.c:155
    @ OPB_EXP_SIGNED
    Definition: reader_opb.c:158
    @ OPB_EXP_UNSIGNED
    Definition: reader_opb.c:157
    @ OPB_EXP_NONE
    Definition: reader_opb.c:156
    static SCIP_RETCODE setObjective(SCIP *const scip, OPBINPUT *const opbinput, const char *sense, SCIP_Real const scale, SCIP_VAR **const linvars, SCIP_Real *const coefs, int const ncoefs, SCIP_VAR ***const terms, SCIP_Real *const termcoefs, int *const ntermvars, int const ntermcoefs)
    Definition: reader_opb.c:1150
    static SCIP_RETCODE writeOpb(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objoffset, SCIP_Real objscale, SCIP_RATIONAL *objoffsetexact, SCIP_RATIONAL *objscaleexact, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, int nconss, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_RESULT *result)
    Definition: reader_opb.c:4466
    static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *type, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Longint weight, SCIP_Longint *mult, const char *multisymbol)
    Definition: reader_opb.c:3040
    static void clearBuffer(char *linebuffer, int *linecnt)
    Definition: reader_opb.c:2259
    static SCIP_Bool isSign(OPBINPUT *opbinput, int *sign)
    Definition: reader_opb.c:549
    static SCIP_DECL_READERREAD(readerReadOpb)
    Definition: reader_opb.c:4856
    static SCIP_RETCODE getBinVarsRepresentatives(SCIP *const scip, SCIP_VAR **const vars, int const nvars, SCIP_Bool const transformed)
    Definition: reader_opb.c:1893
    static SCIP_Bool getNextToken(SCIP *scip, OPBINPUT *opbinput)
    Definition: reader_opb.c:397
    static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, OPBEXPTYPE *exptype)
    Definition: reader_opb.c:284
    static SCIP_RETCODE getVariableOrTerm(SCIP *scip, OPBINPUT *opbinput, SCIP_VAR ***vars, int *nvars, int *varssize)
    Definition: reader_opb.c:709
    static SCIP_RETCODE writeOpbFixedVars(SCIP *const scip, FILE *const file, SCIP_VAR **vars, int nvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
    Definition: reader_opb.c:4127
    #define TOPCOSTCONSNAME
    Definition: reader_opb.c:132
    static void swapTokenBuffer(OPBINPUT *opbinput)
    Definition: reader_opb.c:524
    static SCIP_RETCODE printRowExact(SCIP *scip, FILE *file, const char *type, SCIP_VAR **vars, SCIP_RATIONAL **vals, int nvars, SCIP_RATIONAL *lhs, SCIP_RATIONAL *weight, SCIP_RATIONAL *mult, const char *multisymbol)
    Definition: reader_opb.c:3162
    enum OpbSense OPBSENSE
    Definition: reader_opb.c:169
    static SCIP_RETCODE writeOpbObjective(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_OBJSENSE const objsense, SCIP_Real const objoffset, SCIP_Real const objscale, SCIP_RATIONAL *const objoffsetexact, SCIP_RATIONAL *const objscaleexact, char const *const multisymbol, SCIP_Bool const existands, SCIP_Bool const transformed)
    Definition: reader_opb.c:2320
    static SCIP_RETCODE getCommentLineData(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *objscale, SCIP_Real *objoffset)
    Definition: reader_opb.c:1637
    #define INDICATORVARNAME
    Definition: reader_opb.c:130
    static SCIP_RETCODE printLinearCons(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_Longint weight, SCIP_Bool transformed, const char *multisymbol)
    Definition: reader_opb.c:3266
    static const char commentchars[]
    Definition: reader_opb.c:198
    static SCIP_DECL_READERWRITE(readerWriteOpb)
    Definition: reader_opb.c:4867
    static void writeBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
    Definition: reader_opb.c:2274
    static void pushToken(OPBINPUT *opbinput)
    Definition: reader_opb.c:498
    #define READER_DESC
    Definition: reader_opb.c:126
    static SCIP_RETCODE readOPBFile(SCIP *scip, SCIP_READER *reader, OPBINPUT *opbinput, const char *filename)
    Definition: reader_opb.c:1753
    static SCIP_RETCODE computeAndConstraintInfos(SCIP *const scip, SCIP_Bool const transformed, SCIP_VAR ***resvars, int *nresvars, SCIP_VAR ****andvars, int **nandvars, SCIP_Bool *const existandconshdlr, SCIP_Bool *const existands)
    Definition: reader_opb.c:2055
    static SCIP_RETCODE printNonLinearCons(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, SCIP_Real *const vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_VAR **const resvars, int nresvars, SCIP_VAR **const *const andvars, const int *const nandvars, SCIP_Longint weight, SCIP_Bool transformed, const char *const multisymbol)
    Definition: reader_opb.c:2943
    static SCIP_RETCODE printNLRow(SCIP *const scip, FILE *const file, const char *const type, SCIP_VAR **const vars, SCIP_Real *const vals, int nvars, SCIP_Real lhs, SCIP_VAR **const resvars, int nresvars, SCIP_VAR **const *const andvars, const int *const nandvars, SCIP_Longint weight, SCIP_Longint *const mult, const char *const multisymbol)
    Definition: reader_opb.c:2770
    static SCIP_DECL_READERFREE(readerFreeOpb)
    Definition: reader_opb.c:4842
    static SCIP_RETCODE writeOpbConstraints(SCIP *const scip, FILE *const file, SCIP_CONS **const conss, int const nconss, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, char const *const multisymbol, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_Bool const transformed)
    Definition: reader_opb.c:3567
    static void determineTotalNumberLinearConss(SCIP *const scip, SCIP_CONS **const conss, int const nconss, int *nlinearconss, int *nindicatorconss)
    Definition: reader_opb.c:3459
    #define READER_EXTENSION
    Definition: reader_opb.c:127
    static SCIP_Bool isStartingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
    Definition: reader_opb.c:641
    #define OPB_MAX_PUSHEDTOKENS
    Definition: reader_opb.c:138
    static void appendBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
    Definition: reader_opb.c:2297
    static SCIP_Bool getNextLine(SCIP *scip, OPBINPUT *opbinput)
    Definition: reader_opb.c:328
    static SCIP_RETCODE printLinearConsExact(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_RATIONAL **vals, int nvars, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_RATIONAL *weight, SCIP_Bool transformed, const char *multisymbol)
    Definition: reader_opb.c:3357
    static SCIP_Bool isEndLine(OPBINPUT *opbinput)
    Definition: reader_opb.c:535
    #define OPB_INIT_COEFSSIZE
    Definition: reader_opb.c:139
    static SCIP_RETCODE createVariable(SCIP *scip, SCIP_VAR **var, char *name)
    Definition: reader_opb.c:673
    struct OpbInput OPBINPUT
    Definition: reader_opb.c:196
    #define READER_NAME
    Definition: reader_opb.c:125
    static void syntaxError(SCIP *scip, OPBINPUT *opbinput, const char *msg)
    Definition: reader_opb.c:205
    static SCIP_DECL_READERCOPY(readerCopyOpb)
    Definition: reader_opb.c:4827
    static SCIP_RETCODE readConstraints(SCIP *scip, OPBINPUT *opbinput, SCIP_Real objscale, int *nNonlinearConss)
    Definition: reader_opb.c:1336
    static SCIP_Bool isValue(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *value)
    Definition: reader_opb.c:576
    static SCIP_Bool isDelimChar(char c)
    Definition: reader_opb.c:240
    static void swapPointers(char **pointer1, char **pointer2)
    Definition: reader_opb.c:383
    static SCIP_Bool hasError(OPBINPUT *opbinput)
    Definition: reader_opb.c:229
    static void pushBufferToken(OPBINPUT *opbinput)
    Definition: reader_opb.c:511
    static SCIP_Bool isSense(OPBINPUT *opbinput, OPBSENSE *sense)
    Definition: reader_opb.c:610
    static SCIP_RETCODE getActiveVariablesExact(SCIP *scip, SCIP_VAR ***vars, SCIP_RATIONAL ***scalars, int *nvars, int *varssize, SCIP_RATIONAL *constant, SCIP_Bool transformed)
    Definition: reader_opb.c:2006
    #define OPB_MAX_INTSIZE
    Definition: reader_opb.c:140
    enum OpbExpType OPBEXPTYPE
    Definition: reader_opb.c:160
    static SCIP_RETCODE readCoefficients(SCIP *const scip, OPBINPUT *const opbinput, char *const name, SCIP_VAR ***linvars, SCIP_Real **lincoefs, int *const nlincoefs, int *lincoefssize, SCIP_VAR ****terms, SCIP_Real **termcoefs, int **ntermvars, int *termcoefssize, int *const ntermcoefs, SCIP_Bool *const newsection, SCIP_Bool *const isNonlinear, SCIP_Bool *const issoftcons, SCIP_Real *const weight)
    Definition: reader_opb.c:785
    #define INDICATORSLACKVARNAME
    Definition: reader_opb.c:131
    static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, int *varssize, SCIP_Real *constant, SCIP_Bool transformed)
    Definition: reader_opb.c:1957
    static SCIP_Bool isEndingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
    Definition: reader_opb.c:657
    static SCIP_Bool isTokenChar(char c)
    Definition: reader_opb.c:261
    #define OPB_MAX_LINELEN
    Definition: reader_opb.c:137
    OpbSense
    Definition: reader_opb.c:163
    @ OPB_SENSE_GE
    Definition: reader_opb.c:166
    @ OPB_SENSE_NOTHING
    Definition: reader_opb.c:164
    @ OPB_SENSE_LE
    Definition: reader_opb.c:165
    @ OPB_SENSE_EQ
    Definition: reader_opb.c:167
    pseudo-Boolean file reader (opb format)
    public methods for constraint handler plugins and constraints
    public methods for exact solving
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for reader plugins
    public methods for querying solving statistics
    public methods for SCIP variables
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    @ SCIP_OBJSENSE_MAXIMIZE
    Definition: type_prob.h:47
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    enum SCIP_Objsense SCIP_OBJSENSE
    Definition: type_prob.h:50
    struct SCIP_ReaderData SCIP_READERDATA
    Definition: type_reader.h:54
    @ SCIP_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_WRITEERROR
    Definition: type_retcode.h:46
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_IMPLINTTYPE_STRONG
    Definition: type_var.h:106
    @ 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