Scippy

    SCIP

    Solving Constraint Integer Programs

    reader_gms.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_gms.c
    26 * @ingroup DEFPLUGINS_READER
    27 * @brief GAMS file writer
    28 * @author Ambros Gleixner
    29 * @author Stefan Vigerske
    30 *
    31 * @todo Check for words reserved for GAMS.
    32 */
    33
    34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    35
    37#include "scip/cons_and.h"
    38#include "scip/cons_nonlinear.h"
    39#include "scip/cons_indicator.h"
    40#include "scip/cons_knapsack.h"
    41#include "scip/cons_linear.h"
    42#include "scip/cons_logicor.h"
    43#include "scip/cons_setppc.h"
    44#include "scip/cons_sos1.h"
    45#include "scip/cons_sos2.h"
    46#include "scip/cons_varbound.h"
    47#include "scip/pub_cons.h"
    48#include "scip/pub_message.h"
    49#include "scip/pub_misc.h"
    50#include "scip/pub_reader.h"
    51#include "scip/pub_var.h"
    52#include "scip/reader_gms.h"
    53#include "scip/scip_cons.h"
    54#include "scip/scip_general.h"
    55#include "scip/scip_mem.h"
    56#include "scip/scip_message.h"
    57#include "scip/scip_numerics.h"
    58#include "scip/scip_param.h"
    59#include "scip/scip_reader.h"
    60#include "scip/scip_var.h"
    61#include "scip/expr_abs.h"
    62#include <string.h>
    63
    64#define READER_NAME "gmsreader"
    65#define READER_DESC "file writer for (MI)(N)LPs in GAMS file format"
    66#define READER_EXTENSION "gms"
    67
    68
    69#define GMS_MAX_LINELEN 256
    70#define GMS_MAX_PRINTLEN 256 /**< the maximum length of any line is 255 + '\\0' = 256*/
    71#define GMS_MAX_NAMELEN 64 /**< the maximum length for any name is 63 + '\\0' = 64 */
    72#define GMS_PRINTLEN 100
    73#define GMS_DEFAULT_BIGM 1e+6
    74#define GMS_DEFAULT_INDICATORREFORM 's'
    75
    76/*
    77 * Local methods (for writing)
    78 */
    79
    80static const char badchars[] = "#*+/-@$[](){}";
    81
    82/** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
    83static
    85 SCIP* scip, /**< SCIP data structure */
    86 SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
    87 SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
    88 int* nvars, /**< pointer to number of variables and values in vars and vals array */
    89 int* varssize, /**< pointer to length of vars and scalars array */
    90 SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
    91 SCIP_Bool transformed /**< transformed constraint? */
    92 )
    93{
    94 int requiredsize;
    95 int v;
    96
    97 assert( scip != NULL );
    98 assert( vars != NULL );
    99 assert( *vars != NULL );
    100 assert( scalars != NULL );
    101 assert( *scalars != NULL );
    102 assert( nvars != NULL );
    103 assert( varssize != NULL );
    104 assert( *varssize >= *nvars );
    105 assert( constant != NULL );
    106
    107 if( transformed )
    108 {
    109 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize) );
    110
    111 if( requiredsize > *varssize )
    112 {
    113 *varssize = SCIPcalcMemGrowSize(scip, requiredsize);
    114 SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
    116
    117 SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *varssize, constant, &requiredsize) );
    118 assert(requiredsize <= *varssize);
    119 }
    120 assert(requiredsize == *nvars);
    121 }
    122 else
    123 {
    124 for( v = 0; v < *nvars; ++v )
    125 {
    126 SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
    127 }
    128 }
    129
    130 return SCIP_OKAY;
    131}
    132
    133/** clears the given line buffer */
    134static
    136 char* linebuffer, /**< line */
    137 int* linecnt /**< number of characters in line */
    138 )
    139{
    140 assert( linebuffer != NULL );
    141 assert( linecnt != NULL );
    142
    143 (*linecnt) = 0;
    144 linebuffer[0] = '\0';
    145}
    146
    147/** ends the given line with '\\0' and prints it to the given file stream, with a newline at the end */
    148static
    150 SCIP* scip, /**< SCIP data structure */
    151 FILE* file, /**< output file (or NULL for standard output) */
    152 char* linebuffer, /**< line */
    153 int* linecnt /**< number of characters in line */
    154 )
    155{
    156 assert( scip != NULL );
    157 assert( linebuffer != NULL );
    158 assert( linecnt != NULL );
    159 assert( 0 <= *linecnt && *linecnt < GMS_MAX_LINELEN );
    160
    161 if( (*linecnt) > 0 )
    162 {
    163 linebuffer[(*linecnt)] = '\0';
    164 SCIPinfoMessage(scip, file, "%s\n", linebuffer);
    165 clearLine(linebuffer, linecnt);
    166 }
    167}
    168
    169/** ends the given line with '\\0' and prints it to the given file stream, without a newline at the end */
    170static
    172 SCIP* scip, /**< SCIP data structure */
    173 FILE* file, /**< output file (or NULL for standard output) */
    174 char* linebuffer, /**< line */
    175 int* linecnt /**< number of characters in line */
    176 )
    177{
    178 assert( scip != NULL );
    179 assert( linebuffer != NULL );
    180 assert( linecnt != NULL );
    181 assert( 0 <= *linecnt && *linecnt < GMS_MAX_LINELEN );
    182
    183 if( (*linecnt) > 0 )
    184 {
    185 linebuffer[(*linecnt)] = '\0';
    186 SCIPinfoMessage(scip, file, "%s", linebuffer);
    187 clearLine(linebuffer, linecnt);
    188 }
    189}
    190
    191/** appends extension to line and prints it to the give file stream if the
    192 * line exceeded the length given in the define GMS_PRINTLEN */
    193static
    195 SCIP* scip, /**< SCIP data structure */
    196 FILE* file, /**< output file (or NULL for standard output) */
    197 char* linebuffer, /**< line */
    198 int* linecnt, /**< number of characters in line */
    199 const char* extension /**< string to extend the line */
    200 )
    201{
    202 size_t len;
    203 assert( scip != NULL );
    204 assert( linebuffer != NULL );
    205 assert( linecnt != NULL );
    206 assert( extension != NULL );
    207 assert( strlen(linebuffer) + strlen(extension) < GMS_MAX_PRINTLEN );
    208
    209 /* NOTE: avoid
    210 * sprintf(linebuffer, "%s%s", linebuffer, extension);
    211 * because of overlapping memory areas in memcpy used in sprintf.
    212 */
    213 len = strlen(linebuffer);
    214 (void) strncat(linebuffer, extension, GMS_MAX_PRINTLEN - len);
    215
    216 (*linecnt) += (int) strlen(extension);
    217
    218 SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)len);
    219
    220 if( (*linecnt) > GMS_PRINTLEN )
    221 endLine(scip, file, linebuffer, linecnt);
    222}
    223
    224/** checks string for occurences of bad symbols and replace those by '_' */
    225static
    227 char* name /**< string to adjust */
    228 )
    229{
    230 const char* badchar;
    231
    232 assert( name != NULL );
    233
    234 for( badchar = badchars; *badchar; ++badchar )
    235 {
    236 char* c = strchr(name, *badchar);
    237
    238 while( c != NULL )
    239 {
    240 assert( *c == *badchar );
    241
    242 *c = '_';
    243 c = strchr(c, *badchar);
    244 }
    245 }
    246}
    247
    248/* print first len-1 characters of name to string s and replace '#', '*', '+', '/', and '-' by '_' if necessary */
    249static
    251 SCIP* scip, /**< SCIP data structure */
    252 char* t, /**< target string */
    253 int len, /**< length of t */
    254 const char* name /**< source string or format string */
    255 )
    256{
    257 SCIP_Bool replaceforbiddenchars;
    258
    259 assert( t != NULL );
    260 assert( len > 0 );
    261
    262 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
    263
    264 (void) SCIPsnprintf(t, len, "%s", name);
    265
    266 if( replaceforbiddenchars )
    267 conformName(t);
    268
    269 return SCIP_OKAY;
    270}
    271
    272
    273/* retransform to active variables and print in GAMS format to file stream with surrounding bracket, pre- and suffix */
    274static
    276 SCIP* scip, /**< SCIP data structure */
    277 FILE* file, /**< output file (or NULL for standard output) */
    278 char* linebuffer, /**< line */
    279 int* linecnt, /**< number of characters in line */
    280 const char* prefix, /**< prefix (maybe NULL) */
    281 const char* suffix, /**< suffix (maybe NULL) */
    282 int nvars, /**< number of variables */
    283 SCIP_VAR** vars, /**< array of variables */
    284 SCIP_Real* vals, /**< array of values (or NULL if all ones) */
    285 SCIP_Bool transformed /**< transformed constraint? */
    286 )
    287{
    288 int v;
    289 int closingbracket;
    290
    291 SCIP_VAR* var;
    292 char varname[GMS_MAX_NAMELEN];
    293 char buffer[GMS_MAX_PRINTLEN];
    294 char ext[GMS_MAX_PRINTLEN];
    295
    296 SCIP_VAR** activevars = NULL;
    297 SCIP_Real* activevals = NULL;
    298 int nactivevars;
    299 int activevarssize;
    300 SCIP_Real activeconstant = 0.0;
    301
    302 assert( scip != NULL );
    303 assert( vars != NULL || nvars == 0 );
    304
    305 if( *linecnt == 0 )
    306 /* we start a new line; therefore we tab this line */
    307 appendLine(scip, file, linebuffer, linecnt, " ");
    308
    309 if( nvars == 0 )
    310 {
    311 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
    312
    313 appendLine(scip, file, linebuffer, linecnt, buffer);
    314 }
    315 else
    316 {
    317 nactivevars = nvars;
    318
    319 /* duplicate variable and value array */
    320 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
    321 if( vals != NULL )
    322 {
    323 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
    324 }
    325 else
    326 {
    327 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
    328
    329 for( v = 0; v < nactivevars; ++v )
    330 activevals[v] = 1.0;
    331 }
    332 activevarssize = nactivevars;
    333
    334 /* retransform given variables to active variables */
    335 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activevarssize, &activeconstant, transformed) );
    336
    337 assert( nactivevars == 0 || activevals != NULL );
    338
    339 if( nactivevars == 0 && SCIPisZero(scip, activeconstant) )
    340 {
    341 if( *linecnt == 0 )
    342 /* we start a new line; therefore we tab this line */
    343 appendLine(scip, file, linebuffer, linecnt, " ");
    344
    345 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
    346
    347 appendLine(scip, file, linebuffer, linecnt, buffer);
    348 }
    349 else
    350 {
    351 /* buffer prefix */
    352 (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, "%s(", prefix != NULL ? prefix : "");
    353
    354 /* find position of closing bracket */
    355 closingbracket = nactivevars;
    356 if( SCIPisZero(scip, activeconstant) )
    357 {
    358 do
    359 --closingbracket;
    360 while( SCIPisZero(scip, activevals[closingbracket]) && closingbracket > 0 );
    361 }
    362
    363 /* print active variables */
    364 for( v = 0; v < nactivevars; ++v )
    365 {
    366 var = activevars[v];
    367 assert( var != NULL );
    368
    369 if( !SCIPisZero(scip, activevals[v]) )
    370 {
    371 if( *linecnt == 0 )
    372 /* we start a new line; therefore we tab this line */
    373 appendLine(scip, file, linebuffer, linecnt, " ");
    374
    376
    377 if( SCIPisEQ(scip, activevals[v], 1.0) )
    378 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s%s%s%s", ext, strchr(ext, '(') == NULL ? "+" : "",
    379 varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
    380 else if( SCIPisEQ(scip, activevals[v], -1.0) )
    381 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s-%s%s%s", ext,
    382 varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
    383 else if( strchr(ext, '(') != NULL )
    384 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%.15g*%s%s%s", ext,
    385 activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
    386 else
    387 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g*%s%s%s", ext,
    388 activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
    389
    390 appendLine(scip, file, linebuffer, linecnt, buffer);
    391
    392 (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, (*linecnt == 0) ? "" : " ");
    393 }
    394 }
    395
    396 /* print active constant */
    397 if( !SCIPisZero(scip, activeconstant) )
    398 {
    399 if( *linecnt == 0 )
    400 /* we start a new line; therefore we tab this line */
    401 appendLine(scip, file, linebuffer, linecnt, " ");
    402
    403 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g)%s", ext, activeconstant, suffix ? suffix : "");
    404
    405 appendLine(scip, file, linebuffer, linecnt, buffer);
    406 }
    407 /* nothing has been printed, yet */
    408 else if( strchr(ext, '(') != NULL )
    409 {
    410 if( *linecnt == 0 )
    411 /* we start a new line; therefore we tab this line */
    412 appendLine(scip, file, linebuffer, linecnt, " ");
    413
    414 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix ? prefix : "", suffix ? suffix : "");
    415
    416 appendLine(scip, file, linebuffer, linecnt, buffer);
    417 }
    418 }
    419
    420 /* free buffer arrays */
    421 SCIPfreeBufferArray(scip, &activevars);
    422 SCIPfreeBufferArray(scip, &activevals);
    423 }
    424
    425 return SCIP_OKAY;
    426}
    427
    428
    429/* print linear row in GAMS format to file stream (without retransformation to active variables) */
    430static
    432 SCIP* scip, /**< SCIP data structure */
    433 FILE* file, /**< output file (or NULL for standard output) */
    434 const char* rowname, /**< row name */
    435 const char* rownameextension, /**< row name extension */
    436 const char* type, /**< row type ("=e=", "=l=", or "=g=") */
    437 int nvars, /**< number of variables */
    438 SCIP_VAR** vars, /**< array of variables */
    439 SCIP_Real* vals, /**< array of values */
    440 SCIP_Real rhs /**< right hand side */
    441 )
    442{
    443 int v;
    444 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
    445 int linecnt;
    446
    447 SCIP_VAR* var;
    448 char varname[GMS_MAX_NAMELEN];
    449 char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
    450 char buffer[GMS_MAX_PRINTLEN];
    451
    452 assert( scip != NULL );
    453 assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0);
    454 assert( nvars == 0 || (vars != NULL && vals != NULL) );
    455
    456 clearLine(linebuffer, &linecnt);
    457
    458 /* start each line with a space */
    459 appendLine(scip, file, linebuffer, &linecnt, " ");
    460
    461 /* print row name */
    462 if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
    463 {
    464 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
    465 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
    466 appendLine(scip, file, linebuffer, &linecnt, consname);
    467 }
    468
    469 /* print coefficients */
    470 if( nvars == 0 )
    471 {
    472 /* we start a new line; therefore we tab this line */
    473 if( linecnt == 0 )
    474 appendLine(scip, file, linebuffer, &linecnt, " ");
    475
    476 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " 0");
    477
    478 appendLine(scip, file, linebuffer, &linecnt, buffer);
    479 }
    480
    481 for( v = 0; v < nvars; ++v )
    482 {
    483 assert(vars != NULL); /* for lint */
    484 assert(vals != NULL);
    485
    486 var = vars[v];
    487 assert( var != NULL );
    488
    489 /* we start a new line; therefore we tab this line */
    490 if( linecnt == 0 )
    491 appendLine(scip, file, linebuffer, &linecnt, " ");
    492
    494 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g*%s", vals[v], varname);
    495
    496 appendLine(scip, file, linebuffer, &linecnt, buffer);
    497 }
    498
    499 /* print right hand side */
    500 if( SCIPisZero(scip, rhs) )
    501 rhs = 0.0;
    502
    503 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s %.15g;", type, rhs);
    504
    505 /* we start a new line; therefore we tab this line */
    506 if( linecnt == 0 )
    507 appendLine(scip, file, linebuffer, &linecnt, " ");
    508 appendLine(scip, file, linebuffer, &linecnt, buffer);
    509
    510 endLine(scip, file, linebuffer, &linecnt);
    511
    512 return SCIP_OKAY;
    513}
    514
    515
    516/** prints given linear constraint information in GAMS format to file stream */
    517static
    519 SCIP* scip, /**< SCIP data structure */
    520 FILE* file, /**< output file (or NULL for standard output) */
    521 const char* rowname, /**< name of the row */
    522 int nvars, /**< number of variables */
    523 SCIP_VAR** vars, /**< array of variables */
    524 SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
    525 SCIP_Real lhs, /**< left hand side */
    526 SCIP_Real rhs, /**< right hand side */
    527 SCIP_Bool transformed /**< transformed constraint? */
    528 )
    529{
    530 int v;
    531 SCIP_VAR** activevars = NULL;
    532 SCIP_Real* activevals = NULL;
    533 int nactivevars;
    534 SCIP_Real activeconstant = 0.0;
    535 int activevarssize;
    536
    537 assert( scip != NULL );
    538 assert( rowname != NULL );
    539
    540 /* The GAMS format does not forbid that the variable array is empty */
    541 assert( nvars == 0 || vars != NULL );
    542
    543 assert( lhs <= rhs );
    544
    545 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
    546 return SCIP_OKAY;
    547
    548 nactivevars = nvars;
    549 if( nvars > 0 )
    550 {
    551 /* duplicate variable and value array */
    552 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
    553 if( vals != NULL )
    554 {
    555 SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
    556 }
    557 else
    558 {
    559 SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
    560
    561 for( v = 0; v < nactivevars; ++v )
    562 activevals[v] = 1.0;
    563 }
    564 activevarssize = nactivevars;
    565
    566 /* retransform given variables to active variables */
    567 SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activevarssize, &activeconstant, transformed) );
    568 }
    569
    570 /* print row(s) in GAMS format */
    571 if( SCIPisEQ(scip, lhs, rhs) )
    572 {
    573 assert( !SCIPisInfinity(scip, rhs) );
    574
    575 /* print equality constraint */
    576 SCIP_CALL( printLinearRow(scip, file, rowname, "", "=e=",
    577 nactivevars, activevars, activevals, rhs - activeconstant) );
    578 }
    579 else
    580 {
    581 if( !SCIPisInfinity(scip, -lhs) )
    582 {
    583 /* print inequality ">=" */
    584 SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
    585 nactivevars, activevars, activevals, lhs - activeconstant) );
    586 }
    587 if( !SCIPisInfinity(scip, rhs) )
    588 {
    589 /* print inequality "<=" */
    590 SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
    591 nactivevars, activevars, activevals, rhs - activeconstant) );
    592 }
    593 }
    594
    595 if( nvars > 0 )
    596 {
    597 /* free buffer arrays */
    598 SCIPfreeBufferArray(scip, &activevars);
    599 SCIPfreeBufferArray(scip, &activevals);
    600 }
    601
    602 return SCIP_OKAY;
    603}
    604
    605
    606/* print indicator constraint in some GAMS format to file stream (performing retransformation to active variables)
    607 * The constraints are of the following form:
    608 * \f[
    609 * z = 1 -> s = 0
    610 * \f]
    611 * */
    612static
    614 SCIP* scip, /**< SCIP data structure */
    615 FILE* file, /**< output file (or NULL for standard output) */
    616 const char* rowname, /**< row name */
    617 SCIP_VAR* z, /**< indicating variable (binary) */
    618 SCIP_VAR* s, /**< slack variable */
    619 SCIP_Bool* sossetdeclr, /**< buffer to store whether we declared the SOS set for indicator reform */
    620 SCIP_Bool transformed /**< transformed constraint? */
    621 )
    622{
    623 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
    624 int linecnt;
    625 SCIP_Real coef;
    626 char indicatorform;
    627
    628 char consname[GMS_MAX_NAMELEN + 30];
    629 char buffer[GMS_MAX_PRINTLEN];
    630
    631 assert( scip != NULL );
    632 assert( strlen(rowname) > 0 );
    633 assert( z != NULL );
    634 assert( s != NULL );
    635 assert( SCIPvarIsBinary(z) );
    636 assert( sossetdeclr != NULL );
    637
    638 clearLine(linebuffer, &linecnt);
    639
    640 /* start each line with a space */
    641 appendLine(scip, file, linebuffer, &linecnt, " ");
    642
    643 SCIP_CALL( SCIPgetCharParam(scip, "reading/gmsreader/indicatorreform", &indicatorform) );
    644
    645 switch( indicatorform )
    646 {
    647 case 'b':
    648 {
    649 /* print row name */
    650 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s ..", rowname);
    651 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
    652
    653 appendLine(scip, file, linebuffer, &linecnt, consname);
    654
    655 /* write as s <= upperbound(s)*(1-z) or s <= upperbound(s) * negation(z) */
    656 coef = 1.0;
    657 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, " =l= ", 1, &s, &coef, transformed) );
    658
    659 coef = SCIPvarGetUbGlobal(s);
    660 if( SCIPisInfinity(scip, coef) )
    661 {
    662 SCIP_CALL( SCIPgetRealParam(scip, "reading/gmsreader/bigmdefault", &coef) );
    663
    664 SCIPwarningMessage(scip, "do not have upper bound on slack variable <%s> in indicator constraint <%s>, will use M = %g.\n",
    665 SCIPvarGetName(s), rowname, coef);
    666 }
    667
    668 if( SCIPvarIsNegated(z) )
    669 {
    671 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", 1, &z, &coef, transformed) );
    672 }
    673 else
    674 {
    675 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g + ", coef);
    676
    677 coef = -coef;
    678 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, ";", 1, &z, &coef, transformed) );
    679 }
    680
    681 break;
    682 }
    683
    684 case 's':
    685 {
    686 /* write as
    687 * sos1 Variable name_sos(sosset);
    688 * name_soseq(sosset).. name_sos(sosset) =e= s$(sameas(sosset,'slack') + z$(sameas(sosset,'bin'));
    689 */
    690 coef = 1.0;
    691 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
    692
    693 /* declare set for SOS1 declarations from reformulation of indicator, if needed */
    694 if( !*sossetdeclr )
    695 {
    696 SCIPinfoMessage(scip, file, " Set sosset / slack, bin /;\n");
    697 *sossetdeclr = TRUE;
    698 }
    699
    700 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "sos1 Variable %s_sos(sosset);", consname);
    701 appendLine(scip, file, linebuffer, &linecnt, buffer);
    702 endLine(scip, file, linebuffer, &linecnt);
    703
    704 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(sosset).. %s_sos(sosset) =e= ", consname, consname);
    705 appendLine(scip, file, linebuffer, &linecnt, buffer);
    706 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, "$sameas(sosset,'slack')", 1, &s, &coef, transformed) );
    707 if( SCIPvarIsNegated(z) )
    708 {
    710 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + (1-(", "))$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
    711 }
    712 else
    713 {
    714 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + ", "$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
    715 }
    716 endLine(scip, file, linebuffer, &linecnt);
    717
    718 break;
    719 }
    720
    721 default:
    722 SCIPerrorMessage("wrong value '%c' for parameter reading/gmsreader/indicatorreform\n", indicatorform);
    723 return SCIP_ERROR;
    724 }
    725
    726 endLine(scip, file, linebuffer, &linecnt);
    727
    728 return SCIP_OKAY;
    729}
    730
    731/* print SOS constraint in some GAMS format to file stream (performing retransformation to active variables)
    732 *
    733 * write as
    734 * Set name_sosset /1*nvars/;
    735 * SOS1/2 Variable name_sosvar(name_sosset); name_sosvar.lo(name_sosset) = -inf;
    736 * Equation name_sosequ(e1_sosset);
    737 * name_sosequ(name_sosset).. name_sosvar(e1_sosset) =e=
    738 * vars[0]$sameas(name_sosset, '1') + vars[1]$sameas(name_sosset, '2') + ... + vars[nvars-1]$sameas(name_sosset, nvars);
    739 */
    740static
    742 SCIP* scip, /**< SCIP data structure */
    743 FILE* file, /**< output file (or NULL for standard output) */
    744 const char* rowname, /**< row name */
    745 int nvars, /**< number of variables in SOS */
    746 SCIP_VAR** vars, /**< variables in SOS */
    747 int sostype, /**< type of SOS: 1 or 2 */
    748 SCIP_Bool transformed /**< transformed constraint? */
    749 )
    750{
    751 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
    752 int linecnt;
    753 SCIP_Real coef;
    754 int v;
    755
    756 char consname[GMS_MAX_NAMELEN + 30];
    757 char buffer[GMS_MAX_PRINTLEN];
    758
    759 assert( scip != NULL );
    760 assert( strlen(rowname) > 0 );
    761 assert( vars != NULL || nvars == 0 );
    762 assert( sostype == 1 || sostype == 2 );
    763
    764 clearLine(linebuffer, &linecnt);
    765
    766 /* start each line with a space */
    767 appendLine(scip, file, linebuffer, &linecnt, " ");
    768
    769 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
    770
    771 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "Set %s_sosset /1*%d/;", consname, nvars);
    772 appendLine(scip, file, linebuffer, &linecnt, buffer);
    773 endLine(scip, file, linebuffer, &linecnt);
    774
    775 /* explicitly set lower bound of SOS variables to -inf, as GAMS default is 0.0 */
    776 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " SOS%d Variable %s_sosvar(%s_sosset); %s_sosvar.lo(%s_sosset) = -inf;", sostype, consname, consname, consname, consname);
    777 appendLine(scip, file, linebuffer, &linecnt, buffer);
    778 endLine(scip, file, linebuffer, &linecnt);
    779
    780 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(%s_sosset).. %s_sosvar(%s_sosset) =e= ", consname, consname, consname, consname);
    781 appendLine(scip, file, linebuffer, &linecnt, buffer);
    782 endLine(scip, file, linebuffer, &linecnt);
    783
    784 coef = 1.0;
    785 for( v = 0; v < nvars; ++v )
    786 {
    787 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "$sameas(%s_sosset,'%d')", consname, v+1);
    788 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, v > 0 ? " + " : NULL, buffer, 1, &vars[v], &coef, transformed) ); /*lint !e613*/
    789 }
    790 appendLine(scip, file, linebuffer, &linecnt, ";");
    791 endLine(scip, file, linebuffer, &linecnt);
    792
    793 return SCIP_OKAY;
    794}
    795
    796/** print "and" constraint using a product of binary variables (performing retransformation to active variables) */
    797static
    799 SCIP* scip, /**< SCIP data structure */
    800 FILE* file, /**< output file (or NULL for standard output) */
    801 const char* rowname, /**< row name */
    802 int nvars, /**< number of variables in and */
    803 SCIP_VAR** vars, /**< variables in and */
    804 SCIP_VAR* resultant, /**< resultant variable */
    805 SCIP_Bool transformed /**< transformed constraint? */
    806 )
    807{
    808 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
    809 int linecnt;
    810 char name[GMS_MAX_NAMELEN];
    811 char buffer[GMS_MAX_PRINTLEN];
    812 SCIP_VAR** activevars = NULL;
    813 SCIP_Real* activecoefs = NULL;
    814 int nactivevars;
    815 int activevarssize;
    816 SCIP_Real activeconstant = 0.0;
    817 SCIP_Bool needsign;
    818 int i, v;
    819
    820 assert( scip != NULL );
    821 assert( strlen(rowname) > 0 );
    822 assert( vars != NULL );
    823 assert( nvars > 0 );
    824 assert( resultant != NULL );
    825
    826 activevarssize = 5;
    827 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, activevarssize) );
    828 SCIP_CALL( SCIPallocBufferArray(scip, &activecoefs, activevarssize) );
    829
    830 clearLine(linebuffer, &linecnt);
    831
    832 /* start each line with a space */
    833 appendLine(scip, file, linebuffer, &linecnt, " ");
    834
    835 /* print equation name */
    836 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s ..", rowname);
    838 appendLine(scip, file, linebuffer, &linecnt, name);
    839
    840 for( v = 0; v < nvars; ++v )
    841 {
    842 /* if we start a new line, tab this line */
    843 if( linecnt == 0 )
    844 appendLine(scip, file, linebuffer, &linecnt, " ");
    845
    846 activevars[0] = vars[v];
    847 activecoefs[0] = 1.0;
    848 nactivevars = 1;
    849
    850 SCIP_CALL( getActiveVariables(scip, &activevars, &activecoefs, &nactivevars, &activevarssize, &activeconstant, transformed) );
    851
    852 if( nactivevars == 1 && activecoefs[0] == 1.0 && activeconstant == 0.0 )
    853 {
    854 buffer[0] = ' ';
    855 SCIP_CALL( printConformName(scip, buffer+1, GMS_MAX_NAMELEN, SCIPvarGetName(activevars[0])) );
    856 appendLine(scip, file, linebuffer, &linecnt, buffer);
    857 }
    858 else
    859 {
    860 appendLine(scip, file, linebuffer, &linecnt, " (");
    861
    862 needsign = FALSE;
    863 if( activeconstant != 0.0 )
    864 {
    865 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", activeconstant);
    866 appendLine(scip, file, linebuffer, &linecnt, buffer);
    867 needsign = TRUE;
    868 }
    869
    870 for( i = 0; i < nactivevars; ++i )
    871 {
    872 if( REALABS(activecoefs[i]) != 1.0 )
    873 {
    874 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, needsign ? "%+.15g*" : "%.15g*", activecoefs[i]);
    875 appendLine(scip, file, linebuffer, &linecnt, buffer);
    876 }
    877 else if( activecoefs[i] == 1.0 && needsign )
    878 {
    879 appendLine(scip, file, linebuffer, &linecnt, "+");
    880 }
    881 else if( activecoefs[i] == -1.0 )
    882 {
    883 appendLine(scip, file, linebuffer, &linecnt, "-");
    884 }
    885
    887 appendLine(scip, file, linebuffer, &linecnt, name);
    888
    889 needsign = TRUE;
    890 }
    891
    892 appendLine(scip, file, linebuffer, &linecnt, ")");
    893 }
    894
    895 if( v < nvars - 1 )
    896 appendLine(scip, file, linebuffer, &linecnt, " *");
    897 }
    898
    899 /* if we start a new line, tab this line */
    900 if( linecnt == 0 )
    901 appendLine(scip, file, linebuffer, &linecnt, " ");
    902
    903 /* print right hand side */
    904 appendLine(scip, file, linebuffer, &linecnt, " =e= ");
    905
    906 activevars[0] = resultant;
    907 activecoefs[0] = 1.0;
    908 nactivevars = 1;
    909
    910 SCIP_CALL( getActiveVariables(scip, &activevars, &activecoefs, &nactivevars, &activevarssize, &activeconstant, transformed) );
    911
    912 needsign = FALSE;
    913 if( activeconstant != 0.0 )
    914 {
    915 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", activeconstant);
    916 appendLine(scip, file, linebuffer, &linecnt, buffer);
    917 needsign = TRUE;
    918 }
    919
    920 for( i = 0; i < nactivevars; ++i )
    921 {
    922 if( REALABS(activecoefs[i]) != 1.0 )
    923 {
    924 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, needsign ? "%+.15g*" : "%.15g*", activecoefs[i]);
    925 appendLine(scip, file, linebuffer, &linecnt, buffer);
    926 }
    927 else if( activecoefs[i] == 1.0 && needsign )
    928 {
    929 appendLine(scip, file, linebuffer, &linecnt, "+");
    930 }
    931 else if( activecoefs[i] == -1.0 )
    932 {
    933 appendLine(scip, file, linebuffer, &linecnt, "-");
    934 }
    935
    937 appendLine(scip, file, linebuffer, &linecnt, name);
    938
    939 needsign = TRUE;
    940 }
    941
    942 appendLine(scip, file, linebuffer, &linecnt, ";");
    943 endLine(scip, file, linebuffer, &linecnt);
    944
    945 SCIPfreeBufferArray(scip, &activecoefs);
    946 SCIPfreeBufferArray(scip, &activevars);
    947
    948 return SCIP_OKAY;
    949}
    950
    951/** prints expression in GAMS format to file stream */
    952static
    954 SCIP* scip, /**< SCIP data structure */
    955 FILE* file, /**< output file (or NULL for standard output) */
    956 char* linebuffer, /**< line buffer of length GMS_MAX_PRINTLEN */
    957 int* linecnt, /**< number of characters in line so far */
    958 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
    959 SCIP_Bool* nqcons, /**< buffer to update whether we are still quadratic */
    960 SCIP_Bool transformed, /**< expression belongs to transformed constraint? */
    961 SCIP_EXPR* expr /**< expression to print */
    962 )
    963{
    964 SCIP_EXPRITER* it;
    966 int currentchild;
    967 unsigned int parentprecedence;
    968 long int fpos;
    969 SCIP_VAR** activevars = NULL;
    970 SCIP_Real* activecoefs = NULL;
    971 int nactivevars;
    972 int activevarssize;
    973 SCIP_Real activeconstant = 0.0;
    974 char varname[GMS_MAX_NAMELEN];
    975 unsigned int sumprecedence;
    976
    977 assert(scip != NULL);
    978 assert(linebuffer != NULL);
    979 assert(linecnt != NULL);
    980 assert(nsmooth != NULL);
    981 assert(nqcons != NULL);
    982 assert(expr != NULL);
    983
    984 if( file == NULL )
    985 file = stdout;
    986
    987 appendLine(scip, file, linebuffer, linecnt, " ");
    988
    989 /* store file position at begin of current line */
    990 fpos = ftell(file) - *linecnt;
    991
    992 /* print out current buffer, as we print the expression directly to file */
    993 endLineNoNewline(scip, file, linebuffer, linecnt);
    994
    995 activevarssize = 5;
    996 SCIP_CALL( SCIPallocBufferArray(scip, &activevars, activevarssize) );
    997 SCIP_CALL( SCIPallocBufferArray(scip, &activecoefs, activevarssize) );
    998
    1002
    1004
    1005 while( !SCIPexpriterIsEnd(it) )
    1006 {
    1007 stage = SCIPexpriterGetStageDFS(it);
    1008
    1010 currentchild = SCIPexpriterGetChildIdxDFS(it);
    1011 else
    1012 currentchild = -1;
    1013
    1014 if( SCIPexpriterGetParentDFS(it) != NULL )
    1016 else
    1017 parentprecedence = 0;
    1018
    1019 /* print a newline, if we have printed at least GMS_PRINTLEN chars since the last newline */
    1020 if( ftell(file) > fpos + GMS_PRINTLEN )
    1021 {
    1022 SCIPinfoMessage(scip, file, "\n ");
    1023 /* store file position at begin of current line again; the -5 is for the whitespace we printed already */
    1024 fpos = ftell(file) - 5;
    1025 }
    1026
    1027 if( SCIPisExprVar(scip, expr) )
    1028 {
    1029 /* special handler for variables:
    1030 * - map to active variables
    1031 * - pass variable name through printConformName
    1032 */
    1033 if( stage == SCIP_EXPRITER_ENTEREXPR )
    1034 {
    1035 activevars[0] = SCIPgetVarExprVar(expr);
    1036 activecoefs[0] = 1.0;
    1037 nactivevars = 1;
    1038
    1039 SCIP_CALL( getActiveVariables(scip, &activevars, &activecoefs, &nactivevars, &activevarssize, &activeconstant, transformed) );
    1040
    1041 if( nactivevars == 1 && activecoefs[0] == 1.0 && activeconstant == 0.0 )
    1042 {
    1043 SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(activevars[0])) );
    1044 SCIPinfoMessage(scip, file, "%s", varname);
    1045 }
    1046 else
    1047 {
    1048 SCIP_Bool needsign = FALSE;
    1049 int i;
    1050
    1051 /* do as in print of expr_sum: an opening parenthesis may be required */
    1052 if( sumprecedence <= parentprecedence )
    1053 SCIPinfoMessage(scip, file, "(");
    1054
    1055 if( activeconstant != 0.0 )
    1056 {
    1057 SCIPinfoMessage(scip, file, "%.15g", activeconstant);
    1058 needsign = TRUE;
    1059 }
    1060 for( i = 0; i < nactivevars; ++i )
    1061 {
    1062 if( REALABS(activecoefs[i]) != 1.0 )
    1063 {
    1064 SCIPinfoMessage(scip, file, needsign ? "%+.15g*" : "%.15g*", activecoefs[i]);
    1065 }
    1066 else if( activecoefs[i] == 1.0 && needsign )
    1067 {
    1068 SCIPinfoMessage(scip, file, "+");
    1069 }
    1070 else if( activecoefs[i] == -1.0 )
    1071 {
    1072 SCIPinfoMessage(scip, file, "-");
    1073 }
    1074
    1075 SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(activevars[i])) );
    1076 SCIPinfoMessage(scip, file, "%s", varname);
    1077
    1078 needsign = TRUE;
    1079
    1080 /* check whether it is time for a linebreak */
    1081 if( ftell(file) > fpos + GMS_PRINTLEN )
    1082 {
    1083 SCIPinfoMessage(scip, file, "\n ");
    1084 fpos = ftell(file) - 5;
    1085 }
    1086 }
    1087
    1088 if( sumprecedence <= parentprecedence )
    1089 SCIPinfoMessage(scip, file, ")");
    1090 }
    1091 }
    1092 }
    1093 else if( SCIPisExprPower(scip, expr) )
    1094 {
    1095 /* special handler for power */
    1096 SCIP_Real exponent = SCIPgetExponentExprPow(expr);
    1097
    1098 if( exponent == 2.0 )
    1099 {
    1100 /* write squares as "sqr(child)" */
    1101 if( stage == SCIP_EXPRITER_ENTEREXPR )
    1102 SCIPinfoMessage(scip, file, "sqr(");
    1103 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
    1104 SCIPinfoMessage(scip, file, ")");
    1105 }
    1106 else if( EPSISINT(exponent, 0.0) ) /*lint !e835*/
    1107 {
    1108 /* write integer powers as "power(child, exponent)" */
    1109 if( stage == SCIP_EXPRITER_ENTEREXPR )
    1110 SCIPinfoMessage(scip, file, "power(");
    1111 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
    1112 SCIPinfoMessage(scip, file, ",%.15g)", exponent);
    1113 /* if power but not square, then we are no longer quadratic */
    1114 *nqcons = FALSE;
    1115 }
    1116 else if( exponent == 0.5 )
    1117 {
    1118 /* write square roots as "sqrt(child)" */
    1119 if( stage == SCIP_EXPRITER_ENTEREXPR )
    1120 SCIPinfoMessage(scip, file, "sqrt(");
    1121 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
    1122 SCIPinfoMessage(scip, file, ")");
    1123 *nqcons = FALSE;
    1124 }
    1125 else
    1126 {
    1127 /* write any other power as "(child)**exponent" */
    1128 if( stage == SCIP_EXPRITER_ENTEREXPR )
    1129 SCIPinfoMessage(scip, file, "(");
    1130 else if( stage == SCIP_EXPRITER_LEAVEEXPR )
    1131 SCIPinfoMessage(scip, file, exponent >= 0.0 ? ")**%.15g" : ")**(%.15g)", exponent);
    1132 *nqcons = FALSE;
    1133 }
    1134 }
    1135 else
    1136 {
    1137 /* for any other expression, use the print callback of the exprhdlr */
    1138 SCIP_CALL( SCIPcallExprPrint(scip, expr, stage, currentchild, parentprecedence, file) );
    1139
    1140 if( !*nsmooth )
    1141 {
    1142 /* check for expression types that require changing modeltype from NLP to DNLP: currently only abs */
    1143 if( SCIPisExprAbs(scip, expr) )
    1144 {
    1145 *nsmooth = TRUE;
    1146 *nqcons = FALSE;
    1147 }
    1148 }
    1149
    1150 /* if still quadratic, then check whether expression type is one that cannot occur in quadratics
    1151 * allowed are sum, product, value, var, and power; the latter two were handled above
    1152 */
    1153 if( *nqcons && !SCIPisExprSum(scip, expr) && !SCIPisExprProduct(scip, expr) && !SCIPisExprValue(scip, expr) )
    1154 *nqcons = FALSE;
    1155 }
    1156
    1157 expr = SCIPexpriterGetNext(it);
    1158 }
    1159
    1160 SCIPfreeExpriter(&it);
    1161
    1162 SCIPfreeBufferArray(scip, &activecoefs);
    1163 SCIPfreeBufferArray(scip, &activevars);
    1164
    1165 return SCIP_OKAY;
    1166}
    1167
    1168/** print nonlinear row in GAMS format to file stream */
    1169static
    1171 SCIP* scip, /**< SCIP data structure */
    1172 FILE* file, /**< output file (or NULL for standard output) */
    1173 const char* rowname, /**< row name */
    1174 const char* rownameextension, /**< row name extension */
    1175 const char* type, /**< row type ("=e=", "=l=", or "=g=") */
    1176 SCIP_EXPR* expr, /**< expression */
    1177 SCIP_Real rhs, /**< right hand side */
    1178 SCIP_Bool transformed, /**< transformed constraint? */
    1179 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
    1180 SCIP_Bool* nqcons /**< buffer to update whether we are still quadratic */
    1181 )
    1182{
    1183 char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
    1184 int linecnt;
    1185 char consname[GMS_MAX_NAMELEN + 3];
    1186 char buffer[GMS_MAX_PRINTLEN];
    1187
    1188 assert( scip != NULL );
    1189 assert( strlen(rowname) > 0 || strlen(rownameextension) > 0 );
    1190 assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0 );
    1191
    1192 clearLine(linebuffer, &linecnt);
    1193
    1194 /* start each line with a space */
    1195 appendLine(scip, file, linebuffer, &linecnt, " ");
    1196
    1197 /* print row name */
    1198 (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
    1199 SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
    1200 appendLine(scip, file, linebuffer, &linecnt, consname);
    1201
    1202 SCIP_CALL( printExpr(scip, file, linebuffer, &linecnt, nsmooth, nqcons, transformed, expr) );
    1203
    1204 /* print right hand side */
    1205 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s %.15g;", type, rhs);
    1206 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1207
    1208 endLine(scip, file, linebuffer, &linecnt);
    1209
    1210 return SCIP_OKAY;
    1211}
    1212
    1213/** print nonlinear row in GAMS format to file stream (performing retransformation to active linear variables) */
    1214static
    1216 SCIP* scip, /**< SCIP data structure */
    1217 FILE* file, /**< output file (or NULL for standard output) */
    1218 const char* rowname, /**< row name */
    1219 SCIP_EXPR* expr, /**< expression */
    1220 SCIP_Real lhs, /**< left hand side */
    1221 SCIP_Real rhs, /**< right hand side */
    1222 SCIP_Bool transformed, /**< transformed constraint? */
    1223 SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
    1224 SCIP_Bool* nqcons /**< buffer to update whether we are still quadratic */
    1225 )
    1226{
    1227 assert( scip != NULL );
    1228 assert( strlen(rowname) > 0 );
    1229
    1230 /* print row(s) in GAMS format */
    1231 if( SCIPisEQ(scip, lhs, rhs) )
    1232 {
    1233 assert( !SCIPisInfinity(scip, rhs) );
    1234
    1235 /* print equality constraint */
    1236 SCIP_CALL( printNonlinearRow(scip, file, rowname, "", "=e=", expr, rhs, transformed, nsmooth, nqcons) );
    1237 }
    1238 else
    1239 {
    1240 if( !SCIPisInfinity(scip, -lhs) )
    1241 {
    1242 /* print inequality ">=" */
    1243 SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=", expr, lhs, transformed, nsmooth, nqcons) );
    1244 }
    1245 if( !SCIPisInfinity(scip, rhs) )
    1246 {
    1247 /* print inequality "<=" */
    1248 SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=", expr, rhs, transformed, nsmooth, nqcons) );
    1249 }
    1250 }
    1251
    1252 if( *nqcons )
    1253 {
    1254 /* if we are still at most quadratic, check whether that is still the case when considering current constraint */
    1255 SCIP_CALL( SCIPcheckExprQuadratic(scip, expr, nqcons) );
    1256 if( *nqcons )
    1257 *nqcons = SCIPexprAreQuadraticExprsVariables(expr);
    1258 }
    1259
    1260 return SCIP_OKAY;
    1261}
    1262
    1263/** method check if the variable names are not longer than GMS_MAX_NAMELEN */
    1264static
    1266 SCIP* scip, /**< SCIP data structure */
    1267 SCIP_VAR** vars, /**< array of variables */
    1268 int nvars /**< number of variables */
    1269 )
    1270{
    1271 int v;
    1272 SCIP_VAR* var;
    1273 SCIP_Bool replaceforbiddenchars;
    1274 const char* badchar;
    1275
    1276 assert( scip != NULL );
    1277 assert( vars != NULL );
    1278
    1279 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
    1280
    1281 /* check if the variable names contain any of the bad symbols */
    1282 for( badchar = badchars; *badchar; ++badchar )
    1283 {
    1284 for( v = 0; v < nvars; ++v )
    1285 {
    1286 var = vars[v];
    1287 assert( var != NULL );
    1288
    1289 if( strchr(SCIPvarGetName(var), *badchar) != NULL )
    1290 {
    1291 if( replaceforbiddenchars )
    1292 {
    1293 SCIPinfoMessage(scip, NULL, "there is a variable name with symbol '%c', not allowed in GAMS format; all '%c' replaced by '_' (consider using 'write genproblem'/'write gentransproblem').\n", *badchar, *badchar);
    1294 }
    1295 else
    1296 {
    1297 SCIPwarningMessage(scip, "there is a variable name with symbol '%c', not allowed in GAMS format; use 'write genproblem'/'write gentransproblem', or set 'reading/gmsreader/replaceforbiddenchars' to TRUE and risk duplicate variable names.\n", *badchar);
    1298 }
    1299
    1300 break;
    1301 }
    1302 }
    1303 }
    1304
    1305 /* check if the variable names are too long */
    1306 for( v = 0; v < nvars; ++v )
    1307 {
    1308 var = vars[v];
    1309 assert( var != NULL );
    1310
    1311 if( strlen(SCIPvarGetName(var)) > GMS_MAX_NAMELEN )
    1312 {
    1313 SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; GAMS model might be corrupted.\n",
    1314 GMS_MAX_NAMELEN - 1);
    1315 break;
    1316 }
    1317 }
    1318
    1319 return SCIP_OKAY;
    1320}
    1321
    1322/** method check if the constraint names are not longer than GMS_MAX_NAMELEN */
    1323static
    1325 SCIP* scip, /**< SCIP data structure */
    1326 SCIP_CONS** conss, /**< array of constraints */
    1327 int nconss, /**< number of constraints */
    1328 SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
    1329 )
    1330{
    1331 int c;
    1332 SCIP_CONS* cons;
    1333 SCIP_CONSHDLR* conshdlr;
    1334 const char* conshdlrname;
    1335 SCIP_Bool replaceforbiddenchars;
    1336 const char* badchar;
    1337
    1338 assert( scip != NULL );
    1339 assert( conss != NULL );
    1340
    1341 SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
    1342
    1343 /* check if the constraint names contain any of the bad symbols */
    1344 for( badchar = badchars; *badchar; ++badchar )
    1345 {
    1346 for( c = 0; c < nconss; ++c )
    1347 {
    1348 cons = conss[c];
    1349 assert( cons != NULL );
    1350
    1351 if( strchr(SCIPconsGetName(cons), *badchar) != NULL )
    1352 {
    1353 if( replaceforbiddenchars )
    1354 {
    1355 SCIPinfoMessage(scip, NULL, "there is a constraint name with symbol '%c', not allowed in GAMS format; all '%c' replaced by '_' (consider using 'write genproblem'/'write gentransproblem').\n", *badchar, *badchar);
    1356 }
    1357 else
    1358 {
    1359 SCIPwarningMessage(scip, "there is a constraint name with symbol '%c', not allowed in GAMS format; use 'write genproblem'/'write gentransproblem', or set 'reading/gmsreader/replaceforbiddenchars' to TRUE and risk duplicate variable names.\n", *badchar);
    1360 }
    1361
    1362 break;
    1363 }
    1364 }
    1365 }
    1366
    1367 /* check if the constraint names are too long */
    1368 for( c = 0; c < nconss; ++c )
    1369 {
    1370 cons = conss[c];
    1371 assert( cons != NULL );
    1372
    1373 /* in case the transformed is written, only constraints are posted which are enabled in the current node */
    1374 assert(!transformed || SCIPconsIsEnabled(cons));
    1375
    1376 conshdlr = SCIPconsGetHdlr(cons);
    1377 assert( conshdlr != NULL );
    1378
    1379 conshdlrname = SCIPconshdlrGetName(conshdlr);
    1380 assert( transformed == SCIPconsIsTransformed(cons) );
    1381
    1382 if( strcmp(conshdlrname, "linear") == 0 || strcmp(conshdlrname, "nonlinear") == 0 )
    1383 {
    1384 SCIP_Real lhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetLhsNonlinear(cons);
    1385 SCIP_Real rhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetRhsNonlinear(cons);
    1386
    1387 if( SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
    1388 {
    1389 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
    1390 GMS_MAX_NAMELEN - 1);
    1391 break;
    1392 }
    1393 else if( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN - 4 )
    1394 {
    1395 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
    1396 GMS_MAX_NAMELEN - 5);
    1397 break;
    1398 }
    1399 }
    1400 else if( strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
    1401 {
    1402 SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
    1403 GMS_MAX_NAMELEN - 1);
    1404 break;
    1405 }
    1406 }
    1407 return SCIP_OKAY;
    1408}
    1409
    1410
    1411/*
    1412 * Callback methods of reader
    1413 */
    1414
    1415/** copy method for reader plugins (called when SCIP copies plugins) */
    1416static
    1418{ /*lint --e{715}*/
    1419 assert(scip != NULL);
    1420 assert(reader != NULL);
    1421 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
    1422
    1423 /* call inclusion method of reader */
    1425
    1426 return SCIP_OKAY;
    1427}
    1428
    1429
    1430/** problem writing method of reader */
    1431static
    1433{ /*lint --e{715}*/
    1434 SCIP_CALL( SCIPwriteGms(scip, file, name, transformed, objsense, objscale, objoffset, vars,
    1435 nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
    1436
    1437 return SCIP_OKAY;
    1438}
    1439
    1440/*
    1441 * reader specific interface methods
    1442 */
    1443
    1444/** includes the gms file reader in SCIP */
    1446 SCIP* scip /**< SCIP data structure */
    1447 )
    1448{
    1449 SCIP_READER* reader;
    1450
    1451 /* include reader */
    1453
    1454 /* set non fundamental callbacks via setter functions */
    1455 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyGms) );
    1456 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteGms) );
    1457
    1458 /* add gms reader parameters for writing routines*/
    1460 "reading/gmsreader/replaceforbiddenchars", "shall characters '#', '*', '+', '/', and '-' in variable and constraint names be replaced by '_'?",
    1461 NULL, FALSE, FALSE, NULL, NULL) );
    1462
    1464 "reading/gmsreader/bigmdefault", "default M value for big-M reformulation of indicator constraints in case no bound on slack variable is given",
    1466
    1468 "reading/gmsreader/indicatorreform", "which reformulation to use for indicator constraints: 'b'ig-M, 's'os1",
    1470
    1471 return SCIP_OKAY;
    1472}
    1473
    1474
    1475/** writes problem to gms file */
    1477 SCIP* scip, /**< SCIP data structure */
    1478 FILE* file, /**< output file, or NULL if standard output should be used */
    1479 const char* name, /**< problem name */
    1480 SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
    1481 SCIP_OBJSENSE objsense, /**< objective sense */
    1482 SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
    1483 * extobj = objsense * objscale * (intobj + objoffset) */
    1484 SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
    1485 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
    1486 int nvars, /**< number of active variables in the problem */
    1487 int nbinvars, /**< number of binary variables */
    1488 int nintvars, /**< number of general integer variables */
    1489 int nimplvars, /**< number of implicit integer variables */
    1490 int ncontvars, /**< number of continuous variables */
    1491 SCIP_CONS** conss, /**< array with constraints of the problem */
    1492 int nconss, /**< number of constraints in the problem */
    1493 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
    1494 )
    1495{
    1496 int c;
    1497 int v;
    1498 int linecnt;
    1499 char linebuffer[GMS_MAX_PRINTLEN+1];
    1500
    1501 char varname[GMS_MAX_NAMELEN];
    1502 char buffer[GMS_MAX_PRINTLEN];
    1503
    1504 SCIP_Real* objcoeffs;
    1505
    1506 SCIP_CONSHDLR* conshdlr;
    1507 const char* conshdlrname;
    1508 SCIP_CONS* cons;
    1509
    1510 char consname[GMS_MAX_NAMELEN];
    1511
    1512 SCIP_VAR** consvars;
    1513 SCIP_Real* consvals;
    1514 int nconsvars;
    1515
    1516 SCIP_VAR* var;
    1517 SCIP_VAR* objvar;
    1518 SCIP_Real lb;
    1519 SCIP_Real ub;
    1520 SCIP_Bool nondefbounds;
    1521 SCIP_Bool nlcons = FALSE; /* whether there are nonlinear constraints */
    1522 SCIP_Bool nqcons = TRUE; /* whether nonlinear constraints are at most quadratic */
    1523 SCIP_Bool nsmooth = FALSE; /* whether there are nonsmooth nonlinear constraints */
    1524 SCIP_Bool discrete;
    1525 SCIP_Bool rangedrow;
    1526 SCIP_Bool indicatorsosdef;
    1527 SCIP_Bool needcomma;
    1528
    1529 SCIP_VARTYPE vartype;
    1530 int implintlevel;
    1531 int nintegers = nvars - ncontvars;
    1532 assert(nintegers >= 0);
    1533
    1534 /* check if the variable names are not too long */
    1535 SCIP_CALL( checkVarnames(scip, vars, nvars) );
    1536 /* check if the constraint names are too long */
    1537 SCIP_CALL( checkConsnames(scip, conss, nconss, transformed) );
    1538
    1539 /* check if the objective is a single continuous variable, so we would not have to introduce an auxiliary variable
    1540 * for GAMS
    1541 */
    1542 objvar = NULL;
    1543 if( objscale == 1.0 && objoffset == 0.0 )
    1544 {
    1545 for( v = 0; v < nvars; ++v )
    1546 {
    1547 var = vars[v];
    1548
    1549 if( SCIPvarGetObj(var) == 0.0 ) /*lint !e613*/
    1550 continue;
    1551
    1552 if( objvar == NULL )
    1553 {
    1554 /* first variable with nonzero obj coefficient
    1555 * if not active or having coefficient != 1.0, or being binary/integer, then give up
    1556 */
    1557 if( !SCIPvarIsActive(var) || SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS || SCIPvarGetObj(var) != 1.0 ) /*lint !e613*/
    1558 break;
    1559
    1560 objvar = var; /*lint !e613*/
    1561 }
    1562 else
    1563 {
    1564 /* second variable with nonzero obj coefficient -> give up */
    1565 objvar = NULL;
    1566 break;
    1567 }
    1568 }
    1569 }
    1570
    1571 /* adjust written integrality constraints on implied integral variables based on the implied integral level */
    1572 SCIP_CALL( SCIPgetIntParam(scip, "write/implintlevel", &implintlevel) );
    1573 assert(implintlevel >= -2);
    1574 assert(implintlevel <= 2);
    1575
    1576 /* print statistics as comment to file */
    1577 SCIPinfoMessage(scip, file, "$OFFLISTING\n");
    1578 SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
    1579 SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
    1580 SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
    1581 nvars, nbinvars, nintvars, nimplvars, ncontvars);
    1582 SCIPinfoMessage(scip, file, "* Constraints : %d\n\n", nconss);
    1583
    1584 /* print flags */
    1585 SCIPinfoMessage(scip, file, "$MAXCOL %d\n", GMS_MAX_LINELEN - 1);
    1586 SCIPinfoMessage(scip, file, "$OFFDIGIT\n\n");
    1587
    1588 /* print variable section */
    1589 SCIPinfoMessage(scip, file, "Variables\n");
    1590 clearLine(linebuffer, &linecnt);
    1591
    1592 if( objvar == NULL )
    1593 {
    1594 /* auxiliary objective variable */
    1595 SCIPinfoMessage(scip, file, " objvar%c", nvars > 0 ? ',' : ';');
    1596 }
    1597
    1598 /* "model" variables */
    1599 for( v = 0; v < nvars; ++v )
    1600 {
    1601 var = vars[v];
    1602
    1604 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%c", varname, (v < nvars - 1) ? ',' : ';');
    1605 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1606
    1607 if( (linecnt > 0 && (v == nbinvars - 1 || v == nbinvars + nintvars - 1 ||
    1608 v == nbinvars + nintvars + nimplvars - 1)) || v == nvars - 1 )
    1609 endLine(scip, file, linebuffer, &linecnt);
    1610 }
    1611
    1612 SCIPinfoMessage(scip, file, "\n");
    1613 discrete = FALSE;
    1614
    1615 /* declare binary variables if present */
    1616 {
    1617 SCIP_Bool initial = TRUE;
    1618
    1619 /* output active variables */
    1620 for( v = 0; v < nintegers; ++v )
    1621 {
    1622 var = vars[v];
    1623
    1624 if( SCIPvarGetType(var) != SCIP_VARTYPE_BINARY || (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    1625 continue;
    1626
    1627 if( initial )
    1628 SCIPinfoMessage(scip, file, "Binary variables\n");
    1629
    1631 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, initial ? " %s" : ", %s", varname);
    1632 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1633 initial = FALSE;
    1634 }
    1635
    1636 if( !initial )
    1637 {
    1638 appendLine(scip, file, linebuffer, &linecnt, ";\n");
    1639 endLine(scip, file, linebuffer, &linecnt);
    1640 discrete = TRUE;
    1641 }
    1642 }
    1643
    1644 /* declare integer variables if present */
    1645 {
    1646 SCIP_Bool initial = TRUE;
    1647
    1648 /* output active variables */
    1649 for( v = nbinvars; v < nintegers; ++v )
    1650 {
    1651 var = vars[v];
    1652
    1653 switch( SCIPvarGetType(var) )
    1654 {
    1656 continue;
    1658 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    1659 continue;
    1660 break;
    1662 if( (int)SCIPvarGetImplType(var) <= 2 - implintlevel )
    1663 continue;
    1664 break;
    1665 default:
    1666 SCIPerrorMessage("unknown variable type\n");
    1667 return SCIP_INVALIDDATA;
    1668 } /*lint !e788*/
    1669
    1670 if( initial )
    1671 SCIPinfoMessage(scip, file, "Integer variables\n");
    1672
    1674 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, initial ? " %s" : ", %s", varname);
    1675 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1676 initial = FALSE;
    1677 }
    1678
    1679 if( !initial )
    1680 {
    1681 appendLine(scip, file, linebuffer, &linecnt, ";\n");
    1682 endLine(scip, file, linebuffer, &linecnt);
    1683 discrete = TRUE;
    1684 }
    1685 }
    1686
    1687 /* print variable bounds */
    1688 SCIPinfoMessage(scip, file, "* Variable bounds\n");
    1689 nondefbounds = FALSE;
    1690
    1691 for( v = 0; v < nvars; ++v )
    1692 {
    1693 var = vars[v];
    1694 vartype = SCIPvarGetType(var);
    1695
    1696 /* determine written type */
    1697 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    1698 {
    1699 if( (int)SCIPvarGetImplType(var) > 2 - implintlevel )
    1700 vartype = SCIP_VARTYPE_INTEGER;
    1701 }
    1702 else
    1703 {
    1704 if( (int)SCIPvarGetImplType(var) > 2 + implintlevel )
    1705 vartype = SCIP_VARTYPE_CONTINUOUS;
    1706 }
    1707
    1709
    1710 if( transformed )
    1711 {
    1712 /* in case the transformed is written only local bounds are posted which are valid in the current node */
    1713 lb = SCIPvarGetLbLocal(var);
    1714 ub = SCIPvarGetUbLocal(var);
    1715 }
    1716 else
    1717 {
    1718 lb = SCIPvarGetLbOriginal(var);
    1719 ub = SCIPvarGetUbOriginal(var);
    1720 }
    1721 assert( lb <= ub );
    1722
    1723 /* fixed */
    1724 if( SCIPisEQ(scip, lb, ub) )
    1725 {
    1726 if( vartype == SCIP_VARTYPE_CONTINUOUS )
    1727 SCIPinfoMessage(scip, file, " %s.fx = %.15g;\n", varname, lb);
    1728 else
    1729 SCIPinfoMessage(scip, file, " %s.fx = %g;\n", varname, SCIPfloor(scip, lb + 0.5));
    1730 nondefbounds = TRUE;
    1731
    1732 /* no need to write lower and upper bounds additionally */
    1733 continue;
    1734 }
    1735
    1736 /* lower bound */
    1737 if( vartype != SCIP_VARTYPE_CONTINUOUS )
    1738 {
    1739 /* default lower bound of binaries and integers is 0 */
    1740 if( !SCIPisZero(scip, lb) )
    1741 {
    1742 if( !SCIPisInfinity(scip, -lb) )
    1743 SCIPinfoMessage(scip, file, " %s.lo = %g;\n", varname, SCIPceil(scip, lb));
    1744 else
    1745 SCIPinfoMessage(scip, file, " %s.lo = -inf;\n", varname);
    1746 nondefbounds = TRUE;
    1747 }
    1748 }
    1749 else if( !SCIPisInfinity(scip, -lb) )
    1750 {
    1751 /* continuous variables are free by default */
    1752 SCIPinfoMessage(scip, file, " %s.lo = %.15g;\n", varname, lb);
    1753 nondefbounds = TRUE;
    1754 }
    1755
    1756 /* upper bound */
    1757 if( vartype == SCIP_VARTYPE_BINARY )
    1758 {
    1759 /* binary variables have default upper bound 1.0 */
    1760 if( !SCIPisFeasEQ(scip, ub, 1.0) )
    1761 {
    1762 SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
    1763 nondefbounds = TRUE;
    1764 }
    1765 }
    1766 else if( vartype == SCIP_VARTYPE_INTEGER )
    1767 {
    1768 /* integer variables have default upper bound +inf */
    1769 if( !SCIPisInfinity(scip, ub) )
    1770 {
    1771 SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
    1772 nondefbounds = TRUE;
    1773 }
    1774 }
    1775 else if( !SCIPisInfinity(scip, ub) )
    1776 {
    1777 assert(vartype == SCIP_VARTYPE_CONTINUOUS);
    1778 /* continuous variables have default upper bound +inf */
    1779 SCIPinfoMessage(scip, file, " %s.up = %.15g;\n", varname, ub);
    1780 nondefbounds = TRUE;
    1781 }
    1782 }
    1783
    1784 if( !nondefbounds )
    1785 SCIPinfoMessage(scip, file, "* (All other bounds at default value: binary [0,1], integer [0,+inf], continuous [-inf,+inf].)\n");
    1786 SCIPinfoMessage(scip, file, "\n");
    1787
    1788 /* print equations section */
    1789 if( nconss > 0 || objvar == NULL )
    1790 {
    1791 SCIPinfoMessage(scip, file, "Equations\n");
    1792 clearLine(linebuffer, &linecnt);
    1793 }
    1794 needcomma = FALSE;
    1795
    1796 if( objvar == NULL )
    1797 {
    1798 SCIPinfoMessage(scip, file, " objequ");
    1799 needcomma = TRUE;
    1800 }
    1801
    1802 /* declare equations */
    1803 for( c = 0; c < nconss; ++c )
    1804 {
    1805 cons = conss[c];
    1806 assert( cons != NULL );
    1807
    1808 conshdlr = SCIPconsGetHdlr(cons);
    1809 assert( conshdlr != NULL );
    1810
    1812 conshdlrname = SCIPconshdlrGetName(conshdlr);
    1813 assert( transformed == SCIPconsIsTransformed(cons) );
    1814
    1815 rangedrow = strcmp(conshdlrname, "linear") == 0
    1818 rangedrow = rangedrow || (strcmp(conshdlrname, "nonlinear") == 0
    1821 rangedrow = rangedrow || (strcmp(conshdlrname, "varbound") == 0
    1824
    1825 /* we declare only those constraints which we can print in GAMS format */
    1826 if( strcmp(conshdlrname, "knapsack") != 0 && strcmp(conshdlrname, "logicor") != 0 && strcmp(conshdlrname, "setppc") != 0
    1827 && strcmp(conshdlrname, "linear") != 0 && strcmp(conshdlrname, "SOS1") != 0 && strcmp(conshdlrname, "SOS2") != 0
    1828 && strcmp(conshdlrname, "nonlinear") != 0 && strcmp(conshdlrname, "and") != 0
    1829 && strcmp(conshdlrname, "varbound") != 0
    1830 && strcmp(conshdlrname, "indicator") != 0 )
    1831 {
    1832 SCIPwarningMessage(scip, "Constraint type <%s> not supported. Skip writing constraint <%s>.\n", conshdlrname, SCIPconsGetName(cons));
    1833 continue;
    1834 }
    1835
    1836 if( needcomma )
    1837 appendLine(scip, file, linebuffer, &linecnt, ",");
    1838
    1840 if( rangedrow )
    1841 {
    1842 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s%s%s", consname, "_lhs, ", consname, "_rhs");
    1843 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1844 }
    1845 else
    1846 {
    1847 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s", consname);
    1848 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1849 }
    1850 needcomma = TRUE;
    1851 }
    1852
    1853 if( nconss > 0 || objvar == NULL )
    1854 {
    1855 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ";");
    1856 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1857
    1858 endLine(scip, file, linebuffer, &linecnt);
    1859 SCIPinfoMessage(scip, file, "\n");
    1860 }
    1861
    1862 if( objvar == NULL )
    1863 {
    1864 /* print objective function equation */
    1865 clearLine(linebuffer, &linecnt);
    1866 if( objoffset != 0.0 )
    1867 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= %.15g + ", objscale * objoffset);
    1868 else
    1869 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= ");
    1870 appendLine(scip, file, linebuffer, &linecnt, buffer);
    1871
    1872 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nvars) );
    1873
    1874 for( v = 0; v < nvars; ++v )
    1875 {
    1876 var = vars[v];
    1877
    1878 /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
    1879 assert( transformed || SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL || SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED );
    1880
    1881 objcoeffs[v] = SCIPisZero(scip, SCIPvarGetObj(var)) ? 0.0 : objscale * SCIPvarGetObj(var);
    1882 }
    1883
    1884 SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", nvars, vars, objcoeffs, transformed) );
    1885
    1886 SCIPfreeBufferArray(scip, &objcoeffs);
    1887 endLine(scip, file, linebuffer, &linecnt);
    1888 SCIPinfoMessage(scip, file, "\n");
    1889 }
    1890
    1891 /* print constraints */
    1892 indicatorsosdef = FALSE;
    1893 for( c = 0; c < nconss; ++c )
    1894 {
    1895 cons = conss[c];
    1896 assert( cons != NULL );
    1897
    1898 /* in case the transformed is written, only constraints are posted which are enabled in the current node */
    1899 assert(!transformed || SCIPconsIsEnabled(cons));
    1900
    1901 conshdlr = SCIPconsGetHdlr(cons);
    1902 assert( conshdlr != NULL );
    1903
    1905 conshdlrname = SCIPconshdlrGetName(conshdlr);
    1906 assert( transformed == SCIPconsIsTransformed(cons) );
    1907
    1908 if( strcmp(conshdlrname, "knapsack") == 0 )
    1909 {
    1910 SCIP_Longint* weights;
    1911
    1912 consvars = SCIPgetVarsKnapsack(scip, cons);
    1913 nconsvars = SCIPgetNVarsKnapsack(scip, cons);
    1914
    1915 /* copy Longint array to SCIP_Real array */
    1916 weights = SCIPgetWeightsKnapsack(scip, cons);
    1917 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
    1918 for( v = 0; v < nconsvars; ++v )
    1919 consvals[v] = (SCIP_Real)weights[v];
    1920
    1921 SCIP_CALL( printLinearCons(scip, file, consname, nconsvars, consvars, consvals,
    1922 -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
    1923
    1924 SCIPfreeBufferArray(scip, &consvals);
    1925 }
    1926 else if( strcmp(conshdlrname, "linear") == 0 )
    1927 {
    1928 SCIP_CALL( printLinearCons(scip, file, consname,
    1930 SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
    1931 }
    1932 else if( strcmp(conshdlrname, "logicor") == 0 )
    1933 {
    1934 SCIP_CALL( printLinearCons(scip, file, consname,
    1936 1.0, SCIPinfinity(scip), transformed) );
    1937 }
    1938 else if( strcmp(conshdlrname, "nonlinear") == 0 )
    1939 {
    1940 SCIP_CALL( printNonlinearCons(scip, file, consname,
    1941 SCIPgetExprNonlinear(cons), SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed, &nsmooth, &nqcons) );
    1942 nlcons = TRUE;
    1943 }
    1944 else if( strcmp(conshdlrname, "setppc") == 0 )
    1945 {
    1946 consvars = SCIPgetVarsSetppc(scip, cons);
    1947 nconsvars = SCIPgetNVarsSetppc(scip, cons);
    1948
    1949 switch( SCIPgetTypeSetppc(scip, cons) )
    1950 {
    1952 SCIP_CALL( printLinearCons(scip, file, consname,
    1953 nconsvars, consvars, NULL, 1.0, 1.0, transformed) );
    1954 break;
    1956 SCIP_CALL( printLinearCons(scip, file, consname,
    1957 nconsvars, consvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
    1958 break;
    1960 SCIP_CALL( printLinearCons(scip, file, consname,
    1961 nconsvars, consvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
    1962 break;
    1963 }
    1964 }
    1965 else if( strcmp(conshdlrname, "varbound") == 0 )
    1966 {
    1967 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
    1968 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
    1969
    1970 consvars[0] = SCIPgetVarVarbound(scip, cons);
    1971 consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
    1972
    1973 consvals[0] = 1.0;
    1974 consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
    1975
    1976 SCIP_CALL( printLinearCons(scip, file, consname,
    1977 2, consvars, consvals,
    1978 SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
    1979
    1980 SCIPfreeBufferArray(scip, &consvars);
    1981 SCIPfreeBufferArray(scip, &consvals);
    1982 }
    1983 else if( strcmp(conshdlrname, "indicator") == 0 )
    1984 {
    1985 SCIP_CALL( printIndicatorCons(scip, file, consname,
    1986 SCIPgetBinaryVarIndicator(cons), SCIPgetSlackVarIndicator(cons), &indicatorsosdef,
    1987 transformed) );
    1988 }
    1989 else if( strcmp(conshdlrname, "SOS1") == 0 )
    1990 {
    1991 SCIP_CALL( printSOSCons(scip, file, consname,
    1992 SCIPgetNVarsSOS1(scip, cons), SCIPgetVarsSOS1(scip, cons), 1,
    1993 transformed) );
    1994 discrete = TRUE;
    1995 }
    1996 else if( strcmp(conshdlrname, "SOS2") == 0 )
    1997 {
    1998 SCIP_CALL( printSOSCons(scip, file, consname,
    1999 SCIPgetNVarsSOS2(scip, cons), SCIPgetVarsSOS2(scip, cons), 2,
    2000 transformed) );
    2001 discrete = TRUE;
    2002 }
    2003 else if( strcmp(conshdlrname, "and") == 0 )
    2004 {
    2005 SCIP_CALL( printAndCons(scip, file, consname,
    2007 transformed) );
    2008 nlcons = TRUE;
    2009 /* disable nqcons if no longer quadratic */
    2010 if( SCIPgetNVarsAnd(scip, cons) > 2 )
    2011 nqcons = FALSE;
    2012 }
    2013 else
    2014 {
    2015 SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
    2016 SCIPinfoMessage(scip, file, "* ");
    2017 SCIP_CALL( SCIPprintCons(scip, cons, file) );
    2018 SCIPinfoMessage(scip, file, ";\n");
    2019 }
    2020
    2021 SCIPinfoMessage(scip, file, "\n");
    2022 }
    2023 /* if at most quadratic, then cannot have nonsmooth functions */
    2024 assert(nlcons || !nsmooth);
    2025
    2026 /* print model creation */
    2027 SCIPinfoMessage(scip, file, "Model m / all /;\n\n");
    2028
    2029 /* set some options to reduce listing file size */
    2030 SCIPinfoMessage(scip, file, "option limrow = 0;\n");
    2031 SCIPinfoMessage(scip, file, "option limcol = 0;\n");
    2032 /* if GAMS >= 24.2, then set option to ensure default upper bound on integer vars is inf (since 32.1 this is also the default) */
    2033 SCIPinfoMessage(scip, file, "$if gamsversion 242 option intvarup = 0;\n\n");
    2034
    2035 /* print solve command */
    2036 (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s",
    2037 discrete ? "MI" : "", nlcons ? (nqcons ? "QCP" : ((nsmooth && !discrete) ? "DNLP" : "NLP")) : (discrete ? "P" : "LP"));
    2038
    2039 if( objvar != NULL )
    2040 {
    2042 }
    2043
    2044 SCIPinfoMessage(scip, file, "$if not set %s $set %s %s\n", buffer, buffer, buffer);
    2045 SCIPinfoMessage(scip, file, "Solve m using %%%s%% %simizing %s;\n",
    2046 buffer, objsense == SCIP_OBJSENSE_MINIMIZE ? "min" : "max", objvar != NULL ? varname : "objvar");
    2047
    2048 *result = SCIP_SUCCESS;
    2049
    2050 return SCIP_OKAY;
    2051}
    Constraint handler for AND constraints, .
    constraint handler for indicator constraints
    Constraint handler for knapsack constraints of the form , x binary and .
    Constraint handler for linear constraints in their most general form, .
    Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
    constraint handler for nonlinear constraints specified by algebraic expressions
    Constraint handler for the set partitioning / packing / covering constraints .
    constraint handler for SOS type 1 constraints
    constraint handler for SOS type 2 constraints
    Constraint handler for variable bound constraints .
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define EPSISINT(x, eps)
    Definition: def.h:195
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    absolute expression handler
    int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2765
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5248
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9596
    int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos2.c:2740
    SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9619
    SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
    SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
    SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_setppc.c:9642
    SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10819
    SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
    SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
    SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5223
    SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
    int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_sos1.c:10794
    SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
    @ SCIP_SETPPCTYPE_PARTITIONING
    Definition: cons_setppc.h:87
    @ SCIP_SETPPCTYPE_COVERING
    Definition: cons_setppc.h:89
    @ SCIP_SETPPCTYPE_PACKING
    Definition: cons_setppc.h:88
    SCIP_Bool SCIPisExprAbs(SCIP *scip, SCIP_EXPR *expr)
    Definition: expr_abs.c:546
    SCIP_RETCODE SCIPwriteGms(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
    Definition: reader_gms.c:1476
    SCIP_RETCODE SCIPincludeReaderGms(SCIP *scip)
    Definition: reader_gms.c:1445
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #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 SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:167
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    SCIP_RETCODE SCIPgetCharParam(SCIP *scip, const char *name, char *value)
    Definition: scip_param.c:326
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
    Definition: scip_cons.c:2536
    SCIP_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
    unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:565
    SCIP_EXPRHDLR * SCIPgetExprhdlrSum(SCIP *scip)
    Definition: scip_expr.c:928
    SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
    Definition: expr_pow.c:3448
    SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1490
    SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
    Definition: expriter.c:969
    SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1479
    SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
    Definition: expr.c:4262
    SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1468
    void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
    Definition: expriter.c:664
    SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1457
    SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
    Definition: scip_expr.c:2362
    SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:740
    SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1501
    SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
    Definition: expriter.c:858
    SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
    Definition: scip_expr.c:2402
    SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
    Definition: expr_var.c:424
    int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:707
    void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
    Definition: scip_expr.c:2376
    SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
    Definition: expriter.c:696
    SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
    Definition: expriter.c:501
    SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
    Definition: expr.c:3895
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
    Definition: scip_reader.c:109
    SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
    Definition: scip_reader.c:147
    const char * SCIPreaderGetName(SCIP_READER *reader)
    Definition: reader.c:680
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(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_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_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
    Definition: var.c:24063
    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_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
    Definition: var.c:23463
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static const SCIP_Real scalars[]
    Definition: lp.c:5959
    memory allocation routines
    public methods for managing constraints
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    public methods for input file readers
    public methods for problem variables
    static SCIP_DECL_READERWRITE(readerWriteGms)
    Definition: reader_gms.c:1432
    static void clearLine(char *linebuffer, int *linecnt)
    Definition: reader_gms.c:135
    static SCIP_DECL_READERCOPY(readerCopyGms)
    Definition: reader_gms.c:1417
    static SCIP_RETCODE printAndCons(SCIP *scip, FILE *file, const char *rowname, int nvars, SCIP_VAR **vars, SCIP_VAR *resultant, SCIP_Bool transformed)
    Definition: reader_gms.c:798
    #define GMS_MAX_PRINTLEN
    Definition: reader_gms.c:70
    #define GMS_PRINTLEN
    Definition: reader_gms.c:72
    static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth, SCIP_Bool *nqcons)
    Definition: reader_gms.c:1215
    static SCIP_RETCODE printSOSCons(SCIP *scip, FILE *file, const char *rowname, int nvars, SCIP_VAR **vars, int sostype, SCIP_Bool transformed)
    Definition: reader_gms.c:741
    static void endLineNoNewline(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
    Definition: reader_gms.c:171
    #define GMS_DEFAULT_INDICATORREFORM
    Definition: reader_gms.c:74
    static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
    Definition: reader_gms.c:1265
    static SCIP_RETCODE printLinearRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs)
    Definition: reader_gms.c:431
    static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
    Definition: reader_gms.c:1324
    static SCIP_RETCODE printNonlinearRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_EXPR *expr, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth, SCIP_Bool *nqcons)
    Definition: reader_gms.c:1170
    #define READER_DESC
    Definition: reader_gms.c:65
    #define GMS_DEFAULT_BIGM
    Definition: reader_gms.c:73
    static SCIP_RETCODE printLinearCons(SCIP *scip, FILE *file, const char *rowname, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
    Definition: reader_gms.c:518
    static SCIP_RETCODE printConformName(SCIP *scip, char *t, int len, const char *name)
    Definition: reader_gms.c:250
    static SCIP_RETCODE printActiveVariables(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *prefix, const char *suffix, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Bool transformed)
    Definition: reader_gms.c:275
    static void conformName(char *name)
    Definition: reader_gms.c:226
    #define GMS_MAX_NAMELEN
    Definition: reader_gms.c:71
    #define READER_EXTENSION
    Definition: reader_gms.c:66
    static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
    Definition: reader_gms.c:149
    static SCIP_RETCODE printIndicatorCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR *z, SCIP_VAR *s, SCIP_Bool *sossetdeclr, SCIP_Bool transformed)
    Definition: reader_gms.c:613
    #define READER_NAME
    Definition: reader_gms.c:64
    static SCIP_RETCODE printExpr(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_Bool *nsmooth, SCIP_Bool *nqcons, SCIP_Bool transformed, SCIP_EXPR *expr)
    Definition: reader_gms.c:953
    static const char badchars[]
    Definition: reader_gms.c:80
    #define GMS_MAX_LINELEN
    Definition: reader_gms.c:69
    static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
    Definition: reader_gms.c:194
    static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, int *varssize, SCIP_Real *constant, SCIP_Bool transformed)
    Definition: reader_gms.c:84
    GAMS file reader and writer.
    public methods for constraint handler plugins and constraints
    general public methods
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for reader plugins
    public methods for SCIP variables
    #define SCIP_EXPRITER_VISITINGCHILD
    Definition: type_expr.h:695
    @ SCIP_EXPRITER_DFS
    Definition: type_expr.h:718
    #define SCIP_EXPRITER_VISITEDCHILD
    Definition: type_expr.h:696
    #define SCIP_EXPRITER_LEAVEEXPR
    Definition: type_expr.h:697
    #define SCIP_EXPRITER_ALLSTAGES
    Definition: type_expr.h:698
    #define SCIP_EXPRITER_ENTEREXPR
    Definition: type_expr.h:694
    unsigned int SCIP_EXPRITER_STAGE
    Definition: type_expr.h:701
    @ SCIP_OBJSENSE_MINIMIZE
    Definition: type_prob.h:48
    enum SCIP_Objsense SCIP_OBJSENSE
    Definition: type_prob.h:50
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_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_NEGATED
    Definition: type_var.h:57
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73