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