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-2020 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 "nlpi/pub_expr.h"
29 #include "scip/cons_abspower.h"
30 #include "scip/cons_bivariate.h"
31 #include "scip/cons_indicator.h"
32 #include "scip/cons_knapsack.h"
33 #include "scip/cons_linear.h"
34 #include "scip/cons_logicor.h"
35 #include "scip/cons_nonlinear.h"
36 #include "scip/cons_quadratic.h"
37 #include "scip/cons_setppc.h"
38 #include "scip/cons_soc.h"
39 #include "scip/cons_sos1.h"
40 #include "scip/cons_sos2.h"
41 #include "scip/cons_varbound.h"
42 #include "scip/pub_cons.h"
43 #include "scip/pub_message.h"
44 #include "scip/pub_misc.h"
45 #include "scip/pub_nlp.h"
46 #include "scip/pub_reader.h"
47 #include "scip/pub_var.h"
48 #include "scip/reader_gms.h"
49 #include "scip/scip_cons.h"
50 #include "scip/scip_general.h"
51 #include "scip/scip_mem.h"
52 #include "scip/scip_message.h"
53 #include "scip/scip_numerics.h"
54 #include "scip/scip_param.h"
55 #include "scip/scip_reader.h"
56 #include "scip/scip_var.h"
57 #include <string.h>
58 
59 #ifdef WITH_GAMS
60 #include <sys/stat.h>
61 
62 #include "gmomcc.h"
63 #include "gevmcc.h"
64 
65 #include "reader_gmo.h"
66 #endif
67 
68 
69 #define READER_NAME "gmsreader"
70 #ifdef WITH_GAMS
71 #define READER_DESC "file writer for MI(NL)(SOC)Ps in GAMS file format"
72 #else
73 #define READER_DESC "file reader and writer for MI(NL)(SOC)Ps in GAMS file format"
74 #endif
75 #define READER_EXTENSION "gms"
76 
77 
78 #define GMS_MAX_LINELEN 256
79 #define GMS_MAX_PRINTLEN 256 /**< the maximum length of any line is 255 + '\\0' = 256*/
80 #define GMS_MAX_NAMELEN 64 /**< the maximum length for any name is 63 + '\\0' = 64 */
81 #define GMS_PRINTLEN 100
82 #define GMS_DEFAULT_BIGM 1e+6
83 #define GMS_DEFAULT_INDICATORREFORM 's'
84 #define GMS_DEFAULT_SIGNPOWER FALSE
85 
86 /*
87  * Local methods (for writing)
88  */
89 
90 static const char badchars[] = "#*+/-@$[](){}";
91 
92 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
93 static
95  SCIP* scip, /**< SCIP data structure */
96  SCIP_VAR** vars, /**< vars array to get active variables for */
97  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
98  int* nvars, /**< pointer to number of variables and values in vars and vals array */
99  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
100  SCIP_Bool transformed /**< transformed constraint? */
101  )
102 {
103  int requiredsize;
104  int v;
105 
106  assert( scip != NULL );
107  assert( vars != NULL );
108  assert( scalars != NULL );
109  assert( nvars != NULL );
110  assert( constant != NULL );
111 
112  if( transformed )
113  {
114  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
115 
116  if( requiredsize > *nvars )
117  {
118  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
119  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
120 
121  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
122  assert( requiredsize <= *nvars );
123  }
124  }
125  else
126  {
127  for( v = 0; v < *nvars; ++v )
128  {
129  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
130  }
131  }
132  return SCIP_OKAY;
133 }
134 
135 /** clears the given line buffer */
136 static
138  char* linebuffer, /**< line */
139  int* linecnt /**< number of characters in line */
140  )
141 {
142  assert( linebuffer != NULL );
143  assert( linecnt != NULL );
144 
145  (*linecnt) = 0;
146  linebuffer[0] = '\0';
147 }
148 
149 /** ends the given line with '\\0' and prints it to the given file stream */
150 static
151 void endLine(
152  SCIP* scip, /**< SCIP data structure */
153  FILE* file, /**< output file (or NULL for standard output) */
154  char* linebuffer, /**< line */
155  int* linecnt /**< number of characters in line */
156  )
157 {
158  assert( scip != NULL );
159  assert( linebuffer != NULL );
160  assert( linecnt != NULL );
161 
162  if( (*linecnt) > 0 )
163  {
164  linebuffer[(*linecnt)] = '\0';
165  SCIPinfoMessage(scip, file, "%s\n", linebuffer);
166  clearLine(linebuffer, linecnt);
167  }
168 }
169 
170 /** appends extension to line and prints it to the give file stream if the
171  * line exceeded the length given in the define GMS_PRINTLEN */
172 static
174  SCIP* scip, /**< SCIP data structure */
175  FILE* file, /**< output file (or NULL for standard output) */
176  char* linebuffer, /**< line */
177  int* linecnt, /**< number of characters in line */
178  const char* extension /**< string to extend the line */
179  )
180 {
181  size_t len;
182  assert( scip != NULL );
183  assert( linebuffer != NULL );
184  assert( linecnt != NULL );
185  assert( extension != NULL );
186  assert( strlen(linebuffer) + strlen(extension) < GMS_MAX_PRINTLEN );
187 
188  /* NOTE: avoid
189  * sprintf(linebuffer, "%s%s", linebuffer, extension);
190  * because of overlapping memory areas in memcpy used in sprintf.
191  */
192  len = strlen(linebuffer);
193  (void) strncat(linebuffer, extension, GMS_MAX_PRINTLEN - len);
194 
195  (*linecnt) += (int) strlen(extension);
196 
197  SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)len);
198 
199  if( (*linecnt) > GMS_PRINTLEN )
200  endLine(scip, file, linebuffer, linecnt);
201 }
202 
203 /** appends extension to line and prints it to the give file stream if the
204  * line exceeded the length given in the define GMS_PRINTLEN
205  * indents the line by some spaces if it is a new line */
206 static
208  SCIP* scip, /**< SCIP data structure */
209  FILE* file, /**< output file (or NULL for standard output) */
210  char* linebuffer, /**< line */
211  int* linecnt, /**< number of characters in line */
212  const char* extension /**< string to extend the line */
213  )
214 {
215  if( *linecnt == 0 )
216  /* we start a new line; therefore we indent line */
217  appendLine(scip, file, linebuffer, linecnt, " ");
218 
219  appendLine(scip, file, linebuffer, linecnt, extension);
220 }
221 
222 /** checks string for occurences of bad symbols and replace those by '_' */
223 static
225  char* name /**< string to adjust */
226  )
227 {
228  const char* badchar;
229 
230  assert( name != NULL );
231 
232  for( badchar = badchars; *badchar; ++badchar )
233  {
234  char* c = strchr(name, *badchar);
235 
236  while( c != NULL )
237  {
238  assert( *c == *badchar );
239 
240  *c = '_';
241  c = strchr(c, *badchar);
242  }
243  }
244 }
245 
246 /* print first len-1 characters of name to string s and replace '#', '*', '+', '/', and '-' by '_' if necessary */
247 static
249  SCIP* scip, /**< SCIP data structure */
250  char* t, /**< target string */
251  int len, /**< length of t */
252  const char* name /**< source string or format string */
253  )
254 {
255  SCIP_Bool replaceforbiddenchars;
256 
257  assert( t != NULL );
258  assert( len > 0 );
259 
260  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
261 
262  (void) SCIPsnprintf(t, len, "%s", name);
263 
264  if( replaceforbiddenchars )
265  conformName(t);
266 
267  return SCIP_OKAY;
268 }
269 
270 
271 /* retransform to active variables and print in GAMS format to file stream with surrounding bracket, pre- and suffix */
272 static
274  SCIP* scip, /**< SCIP data structure */
275  FILE* file, /**< output file (or NULL for standard output) */
276  char* linebuffer, /**< line */
277  int* linecnt, /**< number of characters in line */
278  const char* prefix, /**< prefix (maybe NULL) */
279  const char* suffix, /**< suffix (maybe NULL) */
280  int nvars, /**< number of variables */
281  SCIP_VAR** vars, /**< array of variables */
282  SCIP_Real* vals, /**< array of values (or NULL if all ones) */
283  SCIP_Bool transformed /**< transformed constraint? */
284  )
285 {
286  int v;
287  int closingbracket;
288 
289  SCIP_VAR* var;
290  char varname[GMS_MAX_NAMELEN];
291  char buffer[GMS_MAX_PRINTLEN];
292  char ext[GMS_MAX_PRINTLEN];
293 
294  SCIP_VAR** activevars = NULL;
295  SCIP_Real* activevals = NULL;
296  int nactivevars;
297  SCIP_Real activeconstant = 0.0;
298 
299  assert( scip != NULL );
300  assert( vars != NULL || nvars == 0 );
301 
302  if( *linecnt == 0 )
303  /* we start a new line; therefore we tab this line */
304  appendLine(scip, file, linebuffer, linecnt, " ");
305 
306  if( nvars == 0 )
307  {
308  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
309 
310  appendLine(scip, file, linebuffer, linecnt, buffer);
311  }
312  else
313  {
314  nactivevars = nvars;
315 
316  /* duplicate variable and value array */
317  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
318  if( vals != NULL )
319  {
320  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
321  }
322  else
323  {
324  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
325 
326  for( v = 0; v < nactivevars; ++v )
327  activevals[v] = 1.0;
328  }
329 
330  /* retransform given variables to active variables */
331  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
332 
333  assert( nactivevars == 0 || activevals != NULL );
334 
335  if( nactivevars == 0 && SCIPisZero(scip, activeconstant) )
336  {
337  if( *linecnt == 0 )
338  /* we start a new line; therefore we tab this line */
339  appendLine(scip, file, linebuffer, linecnt, " ");
340 
341  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix != NULL ? prefix : "", suffix != NULL ? suffix : "");
342 
343  appendLine(scip, file, linebuffer, linecnt, buffer);
344  }
345  else
346  {
347  /* buffer prefix */
348  (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, "%s(", prefix != NULL ? prefix : "");
349 
350  /* find position of closing bracket */
351  closingbracket = nactivevars;
352  if( SCIPisZero(scip, activeconstant) )
353  {
354  do
355  --closingbracket;
356  while( SCIPisZero(scip, activevals[closingbracket]) && closingbracket > 0 );
357  }
358 
359  /* print active variables */
360  for( v = 0; v < nactivevars; ++v )
361  {
362  var = activevars[v];
363  assert( var != NULL );
364 
365  if( !SCIPisZero(scip, activevals[v]) )
366  {
367  if( *linecnt == 0 )
368  /* we start a new line; therefore we tab this line */
369  appendLine(scip, file, linebuffer, linecnt, " ");
370 
371  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
372 
373  if( SCIPisEQ(scip, activevals[v], 1.0) )
374  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s%s%s%s", ext, strchr(ext, '(') == NULL ? "+" : "",
375  varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
376  else if( SCIPisEQ(scip, activevals[v], -1.0) )
377  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s-%s%s%s", ext,
378  varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
379  else if( strchr(ext, '(') != NULL )
380  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%.15g*%s%s%s", ext,
381  activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
382  else
383  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g*%s%s%s", ext,
384  activevals[v], varname, (v == closingbracket) ? ")" : "", (v == closingbracket && suffix) ? suffix : "");
385 
386  appendLine(scip, file, linebuffer, linecnt, buffer);
387 
388  (void) SCIPsnprintf(ext, GMS_MAX_PRINTLEN, (*linecnt == 0) ? "" : " ");
389  }
390  }
391 
392  /* print active constant */
393  if( !SCIPisZero(scip, activeconstant) )
394  {
395  if( *linecnt == 0 )
396  /* we start a new line; therefore we tab this line */
397  appendLine(scip, file, linebuffer, linecnt, " ");
398 
399  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%+.15g)%s", ext, activeconstant, suffix ? suffix : "");
400 
401  appendLine(scip, file, linebuffer, linecnt, buffer);
402  }
403  /* nothing has been printed, yet */
404  else if( strchr(ext, '(') != NULL )
405  {
406  if( *linecnt == 0 )
407  /* we start a new line; therefore we tab this line */
408  appendLine(scip, file, linebuffer, linecnt, " ");
409 
410  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(0)%s", prefix ? prefix : "", suffix ? suffix : "");
411 
412  appendLine(scip, file, linebuffer, linecnt, buffer);
413  }
414  }
415 
416  /* free buffer arrays */
417  SCIPfreeBufferArray(scip, &activevars);
418  SCIPfreeBufferArray(scip, &activevals);
419  }
420 
421  return SCIP_OKAY;
422 }
423 
424 
425 /* print linear row in GAMS format to file stream (without retransformation to active variables) */
426 static
428  SCIP* scip, /**< SCIP data structure */
429  FILE* file, /**< output file (or NULL for standard output) */
430  const char* rowname, /**< row name */
431  const char* rownameextension, /**< row name extension */
432  const char* type, /**< row type ("=e=", "=l=", or "=g=") */
433  int nvars, /**< number of variables */
434  SCIP_VAR** vars, /**< array of variables */
435  SCIP_Real* vals, /**< array of values */
436  SCIP_Real rhs /**< right hand side */
437  )
438 {
439  int v;
440  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
441  int linecnt;
442 
443  SCIP_VAR* var;
444  char varname[GMS_MAX_NAMELEN];
445  char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
446  char buffer[GMS_MAX_PRINTLEN];
447 
448  assert( scip != NULL );
449  assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0);
450  assert( nvars == 0 || (vars != NULL && vals != NULL) );
451 
452  clearLine(linebuffer, &linecnt);
453 
454  /* start each line with a space */
455  appendLine(scip, file, linebuffer, &linecnt, " ");
456 
457  /* print row name */
458  if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
459  {
460  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
461  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
462  appendLine(scip, file, linebuffer, &linecnt, consname);
463  }
464 
465  /* print coefficients */
466  if( nvars == 0 )
467  {
468  /* we start a new line; therefore we tab this line */
469  if( linecnt == 0 )
470  appendLine(scip, file, linebuffer, &linecnt, " ");
471 
472  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " 0");
473 
474  appendLine(scip, file, linebuffer, &linecnt, buffer);
475  }
476 
477  for( v = 0; v < nvars; ++v )
478  {
479  assert(vars != NULL); /* for lint */
480  assert(vals != NULL);
481 
482  var = vars[v];
483  assert( var != NULL );
484 
485  /* we start a new line; therefore we tab this line */
486  if( linecnt == 0 )
487  appendLine(scip, file, linebuffer, &linecnt, " ");
488 
489  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
490  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g*%s", vals[v], varname);
491 
492  appendLine(scip, file, linebuffer, &linecnt, buffer);
493  }
494 
495  /* print right hand side */
496  if( SCIPisZero(scip, rhs) )
497  rhs = 0.0;
498 
499  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s %.15g;", type, rhs);
500 
501  /* we start a new line; therefore we tab this line */
502  if( linecnt == 0 )
503  appendLine(scip, file, linebuffer, &linecnt, " ");
504  appendLine(scip, file, linebuffer, &linecnt, buffer);
505 
506  endLine(scip, file, linebuffer, &linecnt);
507 
508  return SCIP_OKAY;
509 }
510 
511 
512 /** prints given linear constraint information in GAMS format to file stream */
513 static
515  SCIP* scip, /**< SCIP data structure */
516  FILE* file, /**< output file (or NULL for standard output) */
517  const char* rowname, /**< name of the row */
518  int nvars, /**< number of variables */
519  SCIP_VAR** vars, /**< array of variables */
520  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
521  SCIP_Real lhs, /**< left hand side */
522  SCIP_Real rhs, /**< right hand side */
523  SCIP_Bool transformed /**< transformed constraint? */
524  )
525 {
526  int v;
527  SCIP_VAR** activevars = NULL;
528  SCIP_Real* activevals = NULL;
529  int nactivevars;
530  SCIP_Real activeconstant = 0.0;
531 
532  assert( scip != NULL );
533  assert( rowname != NULL );
534 
535  /* The GAMS format does not forbid that the variable array is empty */
536  assert( nvars == 0 || vars != NULL );
537 
538  assert( lhs <= rhs );
539 
540  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
541  return SCIP_OKAY;
542 
543  nactivevars = nvars;
544  if( nvars > 0 )
545  {
546  /* duplicate variable and value array */
547  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars) );
548  if( vals != NULL )
549  {
550  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars) );
551  }
552  else
553  {
554  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
555 
556  for( v = 0; v < nactivevars; ++v )
557  activevals[v] = 1.0;
558  }
559 
560  /* retransform given variables to active variables */
561  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
562  }
563 
564  /* print row(s) in GAMS format */
565  if( SCIPisEQ(scip, lhs, rhs) )
566  {
567  assert( !SCIPisInfinity(scip, rhs) );
568 
569  /* print equality constraint */
570  SCIP_CALL( printLinearRow(scip, file, rowname, "", "=e=",
571  nactivevars, activevars, activevals, rhs - activeconstant) );
572  }
573  else
574  {
575  if( !SCIPisInfinity(scip, -lhs) )
576  {
577  /* print inequality ">=" */
578  SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
579  nactivevars, activevars, activevals, lhs - activeconstant) );
580  }
581  if( !SCIPisInfinity(scip, rhs) )
582  {
583  /* print inequality "<=" */
584  SCIP_CALL( printLinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
585  nactivevars, activevars, activevals, rhs - activeconstant) );
586  }
587  }
588 
589  if( nvars > 0 )
590  {
591  /* free buffer arrays */
592  SCIPfreeBufferArray(scip, &activevars);
593  SCIPfreeBufferArray(scip, &activevals);
594  }
595 
596  return SCIP_OKAY;
597 }
598 
599 
600 /* print quadratic row in GAMS format to file stream (performing retransformation to active variables) */
601 static
603  SCIP* scip, /**< SCIP data structure */
604  FILE* file, /**< output file (or NULL for standard output) */
605  const char* rowname, /**< row name */
606  const char* rownameextension, /**< row name extension */
607  const char* type, /**< row type ("=e=", "=l=", or "=g=") */
608  int nlinvars, /**< number of linear terms */
609  SCIP_VAR** linvars, /**< variables in linear part */
610  SCIP_Real* lincoeffs, /**< coefficients of variables in linear part */
611  int nquadvarterms, /**< number of quadratic variable terms */
612  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
613  int nbilinterms, /**< number of bilinear terms */
614  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
615  SCIP_Real rhs, /**< right hand side */
616  SCIP_Bool transformed /**< transformed constraint? */
617  )
618 {
619  int t;
620  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
621  int linecnt;
622 
623  SCIP_VAR* var;
624  char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
625  char buffer[GMS_MAX_PRINTLEN];
626 
627  assert( scip != NULL );
628  assert( strlen(rowname) > 0 || strlen(rownameextension) > 0 );
629  assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0 );
630  assert( nlinvars == 0 || (linvars != NULL && lincoeffs != NULL) );
631  assert( nquadvarterms == 0 || quadvarterms != NULL );
632  assert( nbilinterms == 0 || bilinterms != NULL );
633  assert( nquadvarterms > 0 || nbilinterms == 0 );
634 
635  clearLine(linebuffer, &linecnt);
636 
637  /* start each line with a space */
638  appendLine(scip, file, linebuffer, &linecnt, " ");
639 
640  /* print row name */
641  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
642  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
643 
644  appendLine(scip, file, linebuffer, &linecnt, consname);
645 
646  /* print linear terms */
647  if( nlinvars > 0 )
648  {
649  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", " ", nlinvars, linvars, lincoeffs, transformed) );
650  }
651 
652  /* print linear coefficients of quadratic terms */
653  for( t = 0; t < nquadvarterms; ++t )
654  {
655  var = quadvarterms[t].var;
656  assert( var != NULL );
657 
658  if( !SCIPisZero(scip, quadvarterms[t].lincoef) )
659  {
660  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%+.15g*", quadvarterms[t].lincoef);
661 
662  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, NULL, 1, &var, NULL, transformed) );
663  }
664  }
665 
666  /* print square coefficients of quadratic terms */
667  for( t = 0; t < nquadvarterms; ++t )
668  {
669  var = quadvarterms[t].var;
670  assert( var != NULL );
671 
672  if( !SCIPisZero(scip, quadvarterms[t].sqrcoef) )
673  {
674  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%+.15g*sqr", quadvarterms[t].sqrcoef);
675 
676  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, NULL, 1, &var, NULL, transformed) );
677  }
678  }
679 
680  /* print bilinear terms */
681  for( t = 0; t < nbilinterms; ++t )
682  {
683  if( !SCIPisZero(scip, bilinterms[t].coef) )
684  {
685  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%+.15g*", bilinterms[t].coef);
686 
687  /* print first variable (retransformed to active variables) */
688  var = bilinterms[t].var1;
689  assert( var != NULL );
690 
691  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, "", 1, &var, NULL, transformed) );
692 
693  /* print second variable (retransformed to active variables) */
694  var = bilinterms[t].var2;
695  assert( var != NULL );
696 
697  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "*", " ", 1, &var, NULL, transformed) );
698  }
699  }
700 
701  /* print right hand side */
702  if( linecnt == 0 )
703  /* we start a new line; therefore we tab this line */
704  appendLine(scip, file, linebuffer, &linecnt, " ");
705 
706  if( SCIPisZero(scip, rhs) )
707  rhs = 0.0;
708 
709  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s %.15g;", (nlinvars == 0 && nquadvarterms == 0) ? "0 " : "", type, rhs);
710 
711  appendLine(scip, file, linebuffer, &linecnt, buffer);
712 
713  endLine(scip, file, linebuffer, &linecnt);
714 
715  return SCIP_OKAY;
716 }
717 
718 
719 /** prints given quadratic constraint information in GAMS format to file stream */
720 static
722  SCIP* scip, /**< SCIP data structure */
723  FILE* file, /**< output file (or NULL for standard output) */
724  const char* rowname, /**< name of the row */
725  int nlinvars, /**< number of linear terms */
726  SCIP_VAR** linvars, /**< variables in linear part */
727  SCIP_Real* lincoeffs, /**< coefficients of variables in linear part */
728  int nquadvarterms, /**< number of quadratic variable terms */
729  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
730  int nbilinterms, /**< number of bilinear terms */
731  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
732  SCIP_Real lhs, /**< left hand side */
733  SCIP_Real rhs, /**< right hand side */
734  SCIP_Bool transformed /**< transformed constraint? */
735  )
736 {
737  assert( scip != NULL );
738  assert( rowname != NULL );
739  assert( nlinvars == 0 || (linvars != NULL && lincoeffs != NULL) );
740  assert( nquadvarterms == 0 || quadvarterms != NULL );
741  assert( nbilinterms == 0 || bilinterms != NULL );
742  assert( nquadvarterms > 0 || nbilinterms == 0 );
743  assert( lhs <= rhs );
744 
745  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
746  return SCIP_OKAY;
747 
748  /* print row(s) in GAMS format */
749  if( SCIPisEQ(scip, lhs, rhs) )
750  {
751  assert( !SCIPisInfinity(scip, rhs) );
752 
753  /* print equality constraint */
754  SCIP_CALL( printQuadraticRow(scip, file, rowname, "", "=e=",
755  nlinvars, linvars, lincoeffs,
756  nquadvarterms, quadvarterms,
757  nbilinterms, bilinterms, rhs, transformed) );
758  }
759  else
760  {
761  if( !SCIPisInfinity(scip, -lhs) )
762  {
763  /* print inequality ">=" */
764  SCIP_CALL( printQuadraticRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
765  nlinvars, linvars, lincoeffs,
766  nquadvarterms, quadvarterms,
767  nbilinterms, bilinterms, lhs, transformed) );
768  }
769  if( !SCIPisInfinity(scip, rhs) )
770  {
771  /* print inequality "<=" */
772  SCIP_CALL( printQuadraticRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
773  nlinvars, linvars, lincoeffs,
774  nquadvarterms, quadvarterms,
775  nbilinterms, bilinterms, rhs, transformed) );
776  }
777  }
778 
779  return SCIP_OKAY;
780 }
781 
782 /** check GAMS limitations on SOC constraints
783  * returns true of constraint can be written as conic equation in GAMS (using equation type =C=)
784  */
785 static
787  int nlhsvars, /**< number of variables on left hand side */
788  SCIP_VAR** lhsvars, /**< variables on left hand side */
789  SCIP_Real* lhscoeffs, /**< coefficients of variables on left hand side, or NULL if == 1.0 */
790  SCIP_Real* lhsoffsets, /**< offsets of variables on left hand side, or NULL if == 0.0 */
791  SCIP_Real lhsconstant, /**< constant on left hand side */
792  SCIP_VAR* rhsvar, /**< variable on right hand side */
793  SCIP_Real rhscoef, /**< coefficient of variable on right hand side */
794  SCIP_Real rhsoffset /**< offset of variable on right hand side */
795  )
796 {
797  int i;
798 
799  assert(nlhsvars == 0 || lhsvars != NULL);
800 
801  if( rhscoef != 1.0 )
802  return FALSE;
803 
804  if( rhsoffset != 0.0 )
805  return FALSE;
806 
807  if( rhsvar == NULL )
808  return FALSE;
809 
810  if( !SCIPvarIsActive(rhsvar) )
811  return FALSE;
812 
813  if( lhsconstant != 0.0 )
814  return FALSE;
815 
816  if( nlhsvars < 2 )
817  return FALSE;
818 
819  for( i = 0; i < nlhsvars; ++i )
820  {
821  if( lhscoeffs [i] != 1.0 )
822  return FALSE;
823 
824  if( lhsoffsets[i] != 0.0 )
825  return FALSE;
826 
827  if( !SCIPvarIsActive(lhsvars[i]) )
828  return FALSE;
829  }
830 
831  return TRUE;
832 }
833 
834 /* print second order cone row in GAMS format to file stream (performing retransformation to active variables)
835  * The constraints are of the following form:
836  * \f[
837  * \left\{ x \;:\; \sqrt{\gamma + \sum_{i=1}^{n} (\alpha_i\, (x_i + \beta_i))^2} \leq \alpha_{n+1}\, (x_{n+1}+\beta_{n+1}) \right\}.
838  * \f]
839  * */
840 static
842  SCIP* scip, /**< SCIP data structure */
843  FILE* file, /**< output file (or NULL for standard output) */
844  const char* rowname, /**< row name */
845  int nlhsvars, /**< number of variables on left hand side */
846  SCIP_VAR** lhsvars, /**< variables on left hand side */
847  SCIP_Real* lhscoeffs, /**< coefficients of variables on left hand side, or NULL if == 1.0 */
848  SCIP_Real* lhsoffsets, /**< offsets of variables on left hand side, or NULL if == 0.0 */
849  SCIP_Real lhsconstant, /**< constant on left hand side */
850  SCIP_VAR* rhsvar, /**< variable on right hand side */
851  SCIP_Real rhscoef, /**< coefficient of variable on right hand side */
852  SCIP_Real rhsoffset, /**< offset of variable on right hand side */
853  SCIP_Bool transformed /**< transformed constraint? */
854  )
855 {
856  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
857  int linecnt;
858 
859  char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
860  char buffer[GMS_MAX_PRINTLEN];
861 
862  assert( scip != NULL );
863  assert( strlen(rowname) > 0 );
864  assert( nlhsvars == 0 || lhsvars != NULL );
865 
866  clearLine(linebuffer, &linecnt);
867 
868  /* start each line with a space */
869  appendLine(scip, file, linebuffer, &linecnt, " ");
870 
871  /* print row name */
872  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s ..", rowname);
873  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
874 
875  appendLine(scip, file, linebuffer, &linecnt, consname);
876 
877  if( !isGAMSprintableSOC(nlhsvars, lhsvars, lhscoeffs, lhsoffsets, lhsconstant, rhsvar, rhscoef, rhsoffset) )
878  {
879  int t;
880 
881  /* print right-hand side on left */
882  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "sqr(%.15g +", rhsoffset);
883 
884  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, ")", 1, &rhsvar, &rhscoef, transformed) );
885 
886  appendLine(scip, file, linebuffer, &linecnt, " =g= ");
887 
888  /* print left-hand side on right */
889 
890  if( lhsconstant != 0.0 )
891  {
892  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", lhsconstant);
893 
894  appendLine(scip, file, linebuffer, &linecnt, buffer);
895  }
896 
897  for( t = 0; t < nlhsvars; ++t )
898  {
899  assert( lhsvars[t] != NULL );
900 
901  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "+ sqr(%.15g * (%.15g + ", lhscoeffs ? lhscoeffs[t] : 1.0, lhsoffsets ? lhsoffsets[t] : 0.0);
902 
903  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, "))", 1, &lhsvars[t], NULL, transformed) );
904  }
905  }
906  else
907  {
908  /* print right-hand side on left */
909  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", " ", 1, &rhsvar, &rhscoef, transformed) );
910 
911  appendLine(scip, file, linebuffer, &linecnt, " =c= ");
912 
913  /* print left-hand side on right */
914  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", " ", nlhsvars, lhsvars, lhscoeffs, transformed) );
915  }
916 
917  appendLine(scip, file, linebuffer, &linecnt, ";");
918 
919  endLine(scip, file, linebuffer, &linecnt);
920 
921  return SCIP_OKAY;
922 }
923 
924 /* print indicator constraint in some GAMS format to file stream (performing retransformation to active variables)
925  * The constraints are of the following form:
926  * \f[
927  * z = 1 -> s = 0
928  * \f]
929  * */
930 static
932  SCIP* scip, /**< SCIP data structure */
933  FILE* file, /**< output file (or NULL for standard output) */
934  const char* rowname, /**< row name */
935  SCIP_VAR* z, /**< indicating variable (binary) */
936  SCIP_VAR* s, /**< slack variable */
937  SCIP_Bool* sossetdeclr, /**< buffer to store whether we declared the SOS set for indicator reform */
938  SCIP_Bool transformed /**< transformed constraint? */
939  )
940 {
941  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
942  int linecnt;
943  SCIP_Real coef;
944  char indicatorform;
945 
946  char consname[GMS_MAX_NAMELEN + 30];
947  char buffer[GMS_MAX_PRINTLEN];
948 
949  assert( scip != NULL );
950  assert( strlen(rowname) > 0 );
951  assert( z != NULL );
952  assert( s != NULL );
953  assert( SCIPvarIsBinary(z) );
954  assert( sossetdeclr != NULL );
955 
956  clearLine(linebuffer, &linecnt);
957 
958  /* start each line with a space */
959  appendLine(scip, file, linebuffer, &linecnt, " ");
960 
961  SCIP_CALL( SCIPgetCharParam(scip, "reading/gmsreader/indicatorreform", &indicatorform) );
962 
963  switch( indicatorform )
964  {
965  case 'b':
966  {
967  /* print row name */
968  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s ..", rowname);
969  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
970 
971  appendLine(scip, file, linebuffer, &linecnt, consname);
972 
973  /* write as s <= upperbound(s)*(1-z) or s <= upperbound(s) * negation(z) */
974  coef = 1.0;
975  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, " =l= ", 1, &s, &coef, transformed) );
976 
977  coef = SCIPvarGetUbGlobal(s);
978  if( SCIPisInfinity(scip, coef) )
979  {
980  SCIP_CALL( SCIPgetRealParam(scip, "reading/gmsreader/bigmdefault", &coef) );
981 
982  SCIPwarningMessage(scip, "do not have upper bound on slack variable <%s> in indicator constraint <%s>, will use M = %g.\n",
983  SCIPvarGetName(s), rowname, coef);
984  }
985 
986  if( SCIPvarIsNegated(z) )
987  {
988  SCIP_CALL( SCIPgetNegatedVar(scip, z, &z) );
989  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", 1, &z, &coef, transformed) );
990  }
991  else
992  {
993  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g + ", coef);
994 
995  coef = -coef;
996  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, buffer, ";", 1, &z, &coef, transformed) );
997  }
998 
999  break;
1000  }
1001 
1002  case 's':
1003  {
1004  /* write as
1005  * sos1 Variable name_sos(sosset);
1006  * name_soseq(sosset).. name_sos(sosset) =e= s$(sameas(sosset,'slack') + z$(sameas(sosset,'bin'));
1007  */
1008  coef = 1.0;
1009  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
1010 
1011  /* declare set for SOS1 declarations from reformulation of indicator, if needed */
1012  if( !*sossetdeclr )
1013  {
1014  SCIPinfoMessage(scip, file, " Set sosset / slack, bin /;\n");
1015  *sossetdeclr = TRUE;
1016  }
1017 
1018  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "sos1 Variable %s_sos(sosset);", consname);
1019  appendLine(scip, file, linebuffer, &linecnt, buffer);
1020  endLine(scip, file, linebuffer, &linecnt);
1021 
1022  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(sosset).. %s_sos(sosset) =e= ", consname, consname);
1023  appendLine(scip, file, linebuffer, &linecnt, buffer);
1024  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, "$sameas(sosset,'slack')", 1, &s, &coef, transformed) );
1025  if( SCIPvarIsNegated(z) )
1026  {
1027  SCIP_CALL( SCIPgetNegatedVar(scip, z, &z) );
1028  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + (1-(", "))$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
1029  }
1030  else
1031  {
1032  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " + ", "$sameas(sosset,'bin');", 1, &z, &coef, transformed) );
1033  }
1034  endLine(scip, file, linebuffer, &linecnt);
1035 
1036  break;
1037  }
1038 
1039  default:
1040  SCIPerrorMessage("wrong value '%c' for parameter reading/gmsreader/indicatorreform\n", indicatorform);
1041  return SCIP_ERROR;
1042  }
1043 
1044  endLine(scip, file, linebuffer, &linecnt);
1045 
1046  return SCIP_OKAY;
1047 }
1048 
1049 /* print SOS constraint in some GAMS format to file stream (performing retransformation to active variables)
1050  *
1051  * write as
1052  * Set name_sosset /1*nvars/;
1053  * SOS1/2 Variable name_sosvar(name_sosset); name_sosvar.lo(name_sosset) = -inf;
1054  * Equation name_sosequ(e1_sosset);
1055  * name_sosequ(name_sosset).. name_sosvar(e1_sosset) =e=
1056  * vars[0]$sameas(name_sosset, '1') + vars[1]$sameas(name_sosset, '2') + ... + vars[nvars-1]$sameas(name_sosset, nvars);
1057  */
1058 static
1060  SCIP* scip, /**< SCIP data structure */
1061  FILE* file, /**< output file (or NULL for standard output) */
1062  const char* rowname, /**< row name */
1063  int nvars, /**< number of variables in SOS */
1064  SCIP_VAR** vars, /**< variables in SOS */
1065  int sostype, /**< type of SOS: 1 or 2 */
1066  SCIP_Bool transformed /**< transformed constraint? */
1067  )
1068 {
1069  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
1070  int linecnt;
1071  SCIP_Real coef;
1072  int v;
1073 
1074  char consname[GMS_MAX_NAMELEN + 30];
1075  char buffer[GMS_MAX_PRINTLEN];
1076 
1077  assert( scip != NULL );
1078  assert( strlen(rowname) > 0 );
1079  assert( vars != NULL || nvars == 0 );
1080  assert( sostype == 1 || sostype == 2 );
1081 
1082  clearLine(linebuffer, &linecnt);
1083 
1084  /* start each line with a space */
1085  appendLine(scip, file, linebuffer, &linecnt, " ");
1086 
1087  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, rowname) );
1088 
1089  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "Set %s_sosset /1*%d/;", consname, nvars);
1090  appendLine(scip, file, linebuffer, &linecnt, buffer);
1091  endLine(scip, file, linebuffer, &linecnt);
1092 
1093  /* explicitly set lower bound of SOS variables to -inf, as GAMS default is 0.0 */
1094  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " SOS%d Variable %s_sosvar(%s_sosset); %s_sosvar.lo(%s_sosset) = -inf;", sostype, consname, consname, consname, consname);
1095  appendLine(scip, file, linebuffer, &linecnt, buffer);
1096  endLine(scip, file, linebuffer, &linecnt);
1097 
1098  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s(%s_sosset).. %s_sosvar(%s_sosset) =e= ", consname, consname, consname, consname);
1099  appendLine(scip, file, linebuffer, &linecnt, buffer);
1100  endLine(scip, file, linebuffer, &linecnt);
1101 
1102  coef = 1.0;
1103  for( v = 0; v < nvars; ++v )
1104  {
1105  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "$sameas(%s_sosset,'%d')", consname, v+1);
1106  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, v > 0 ? " + " : NULL, buffer, 1, &vars[v], &coef, transformed) ); /*lint !e613*/
1107  }
1108  appendLine(scip, file, linebuffer, &linecnt, ";");
1109  endLine(scip, file, linebuffer, &linecnt);
1110 
1111  return SCIP_OKAY;
1112 }
1113 
1114 /* print signpower row in GAMS format to file stream (performing retransformation to active variables) */
1115 static
1117  SCIP* scip, /**< SCIP data structure */
1118  FILE* file, /**< output file (or NULL for standard output) */
1119  const char* rowname, /**< row name */
1120  const char* rownameextension, /**< row name extension */
1121  const char* type, /**< row type ("=e=", "=l=", or "=g=") */
1122  SCIP_VAR* nonlinvar, /**< nonlinear variable */
1123  SCIP_VAR* linvar, /**< linear variable, may be NULL */
1124  SCIP_Real exponent, /**< exponent of nonlinear variable */
1125  SCIP_Real offset, /**< offset of nonlinear variable */
1126  SCIP_Real coeflinear, /**< coefficient of linear variable */
1127  SCIP_Real rhs, /**< right hand side */
1128  SCIP_Bool transformed, /**< transformed constraint? */
1129  SCIP_Bool signpowerallowed, /**< allowed to use signpower operator in GAMS? */
1130  SCIP_Bool* nsmooth /**< buffer to store whether we printed a nonsmooth function */
1131  )
1132 {
1133  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
1134  int linecnt;
1135  SCIP_Bool nisoddint;
1136  SCIP_Bool fixedsign;
1137 
1138  char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
1139  char buffer[GMS_MAX_PRINTLEN];
1140 
1141  assert( scip != NULL );
1142  assert( strlen(rowname) > 0 || strlen(rownameextension) > 0 );
1143  assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0 );
1144  assert( nonlinvar != NULL );
1145  assert( exponent > 1.0 );
1146  assert( nsmooth != NULL );
1147 
1148  clearLine(linebuffer, &linecnt);
1149 
1150  /* start each line with a space */
1151  appendLine(scip, file, linebuffer, &linecnt, " ");
1152 
1153  /* print row name */
1154  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
1155  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
1156 
1157  appendLine(scip, file, linebuffer, &linecnt, consname);
1158 
1159  /* print nonlinear term
1160  * if not signpowerallowed, then signpow(x,n) is printed as x*abs(x) if n == 2, x*(abs(x)**(n-1)) if n is not 2 and not an odd integer, and as power(x,n) if n is an odd integer
1161  * if signpowerallowed, then signpow(x,n) is printed as power(x,n) if n is an odd integer and as signpower(x,n) otherwiser
1162  */
1163  nisoddint = SCIPisIntegral(scip, exponent) && ((int)SCIPfloor(scip, exponent+0.5))%2 == 1;
1164  fixedsign = !SCIPisNegative(scip, SCIPvarGetLbGlobal(nonlinvar)) || !SCIPisPositive(scip, SCIPvarGetUbGlobal(nonlinvar));
1165  if( !nisoddint && !fixedsign )
1166  {
1167  if( signpowerallowed )
1168  {
1169  if( offset != 0.0 )
1170  {
1171  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "signpower(%g ", offset);
1172  appendLine(scip, file, linebuffer, &linecnt, buffer);
1173  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ",", 1, &nonlinvar, NULL, transformed) );
1174  }
1175  else
1176  {
1177  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "signpower(", ",", 1, &nonlinvar, NULL, transformed) );
1178  }
1179  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%g)", exponent);
1180  appendLine(scip, file, linebuffer, &linecnt, buffer);
1181  }
1182  else
1183  {
1184  if( offset != 0.0 )
1185  {
1186  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "(%g ", offset);
1187  appendLine(scip, file, linebuffer, &linecnt, buffer);
1188  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ") * ", 1, &nonlinvar, NULL, transformed) );
1189  }
1190  else
1191  {
1192  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, NULL, " * ", 1, &nonlinvar, NULL, transformed) );
1193  }
1194 
1195  if( exponent == 2.0)
1196  {
1197  if( offset != 0.0 )
1198  {
1199  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "abs(%g ", offset);
1200  appendLine(scip, file, linebuffer, &linecnt, buffer);
1201  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ")", 1, &nonlinvar, NULL, transformed) );
1202  }
1203  else
1204  {
1205  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "abs", NULL, 1, &nonlinvar, NULL, transformed) );
1206  }
1207  }
1208  else
1209  {
1210  if( offset != 0.0 )
1211  {
1212  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "abs(%g ", offset);
1213  appendLine(scip, file, linebuffer, &linecnt, buffer);
1214  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ")", 1, &nonlinvar, NULL, transformed) );
1215  }
1216  else
1217  {
1218  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "abs", NULL, 1, &nonlinvar, NULL, transformed) );
1219  }
1220  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "**%g", exponent-1.0);
1221  appendLine(scip, file, linebuffer, &linecnt, buffer);
1222  }
1223  }
1224  *nsmooth = TRUE;
1225  }
1226  else if( nisoddint || !SCIPisNegative(scip, SCIPvarGetLbGlobal(nonlinvar)) )
1227  {
1228  if( exponent == 2.0 )
1229  {
1230  if( offset != 0.0 )
1231  {
1232  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "sqr(%g ", offset);
1233  appendLine(scip, file, linebuffer, &linecnt, buffer);
1234  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ")", 1, &nonlinvar, NULL, transformed) );
1235  }
1236  else
1237  {
1238  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "sqr", NULL, 1, &nonlinvar, NULL, transformed) );
1239  }
1240  }
1241  else
1242  {
1243  if( offset != 0.0 )
1244  {
1245  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "power(%g ", offset);
1246  appendLine(scip, file, linebuffer, &linecnt, buffer);
1247  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", ",", 1, &nonlinvar, NULL, transformed) );
1248  }
1249  else
1250  {
1251  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "power(", ",", 1, &nonlinvar, NULL, transformed) );
1252  }
1253  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%g)", exponent);
1254  appendLine(scip, file, linebuffer, &linecnt, buffer);
1255  }
1256  }
1257  else
1258  {
1259  assert(fixedsign && !SCIPisPositive(scip, SCIPvarGetUbGlobal(nonlinvar)));
1260  if( exponent == 2.0 )
1261  {
1262  if( offset != 0.0 )
1263  {
1264  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "-sqr(%g ", -offset);
1265  appendLine(scip, file, linebuffer, &linecnt, buffer);
1266  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "-", ")", 1, &nonlinvar, NULL, transformed) );
1267  }
1268  else
1269  {
1270  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "-sqr(-", ")", 1, &nonlinvar, NULL, transformed) );
1271  }
1272  }
1273  else
1274  {
1275  if( offset != 0.0 )
1276  {
1277  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "-power(%g ", -offset);
1278  appendLine(scip, file, linebuffer, &linecnt, buffer);
1279  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "-", ",", 1, &nonlinvar, NULL, transformed) );
1280  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%g)", exponent);
1281  appendLine(scip, file, linebuffer, &linecnt, buffer);
1282  }
1283  else
1284  {
1285  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "-power(-", ",", 1, &nonlinvar, NULL, transformed) );
1286  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%g)", exponent);
1287  appendLine(scip, file, linebuffer, &linecnt, buffer);
1288  }
1289  }
1290  }
1291 
1292  /* print linear term */
1293  if( linvar != NULL )
1294  {
1295  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, " +", "", 1, &linvar, &coeflinear, transformed) );
1296  }
1297 
1298  /* print right hand side */
1299  if( linecnt == 0 )
1300  {
1301  /* we start a new line; therefore we tab this line */
1302  appendLine(scip, file, linebuffer, &linecnt, " ");
1303  }
1304 
1305  if( SCIPisZero(scip, rhs) )
1306  rhs = 0.0;
1307 
1308  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s %.15g;", type, rhs);
1309 
1310  appendLine(scip, file, linebuffer, &linecnt, buffer);
1311 
1312  endLine(scip, file, linebuffer, &linecnt);
1313 
1314  return SCIP_OKAY;
1315 }
1316 
1317 /* print signpower cons in GAMS format to file stream (performing retransformation to active variables)
1318  */
1319 static
1321  SCIP* scip, /**< SCIP data structure */
1322  FILE* file, /**< output file (or NULL for standard output) */
1323  const char* rowname, /**< row name */
1324  SCIP_VAR* nonlinvar, /**< nonlinear variable */
1325  SCIP_VAR* linvar, /**< linear variable, may be NULL */
1326  SCIP_Real exponent, /**< exponent of nonlinear variable */
1327  SCIP_Real offset, /**< offset of nonlinear variable */
1328  SCIP_Real coeflinear, /**< coefficient of linear variable */
1329  SCIP_Real lhs, /**< left hand side */
1330  SCIP_Real rhs, /**< right hand side */
1331  SCIP_Bool transformed, /**< transformed constraint? */
1332  SCIP_Bool signpowerallowed, /**< allowed to use signpower operator in GAMS? */
1333  SCIP_Bool* nsmooth /**< buffer to store whether we printed a nonsmooth function */
1334  )
1335 {
1336  assert( scip != NULL );
1337  assert( strlen(rowname) > 0 );
1338 
1339  /* print row(s) in GAMS format */
1340  if( SCIPisEQ(scip, lhs, rhs) )
1341  {
1342  assert( !SCIPisInfinity(scip, rhs) );
1343 
1344  /* print equality constraint */
1345  SCIP_CALL( printSignpowerRow(scip, file, rowname, "", "=e=",
1346  nonlinvar, linvar, exponent, offset, coeflinear, rhs, transformed, signpowerallowed, nsmooth) );
1347  }
1348  else
1349  {
1350  if( !SCIPisInfinity(scip, -lhs) )
1351  {
1352  /* print inequality ">=" */
1353  SCIP_CALL( printSignpowerRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
1354  nonlinvar, linvar, exponent, offset, coeflinear, lhs, transformed, signpowerallowed, nsmooth) );
1355  }
1356  if( !SCIPisInfinity(scip, rhs) )
1357  {
1358  /* print inequality "<=" */
1359  SCIP_CALL( printSignpowerRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
1360  nonlinvar, linvar, exponent, offset, coeflinear, rhs, transformed, signpowerallowed, nsmooth) );
1361  }
1362  }
1363 
1364  return SCIP_OKAY;
1365 }
1366 
1367 /* prints expression in GAMS format to file stream */
1368 static
1370  SCIP* scip, /**< SCIP data structure */
1371  FILE* file, /**< output file (or NULL for standard output) */
1372  char* linebuffer, /**< line buffer of length GMS_MAX_PRINTLEN */
1373  int* linecnt, /**< number of characters in line so far */
1374  SCIP_Bool* nsmooth, /**< buffer to store whether we printed a nonsmooth function */
1375  SCIP_Bool transformed, /**< expression belongs to transformed constraint? */
1376  SCIP_EXPR* expr, /**< expression to print */
1377  SCIP_VAR** exprvars /**< variables of expression */
1378  )
1379 {
1380  char buffer[GMS_MAX_PRINTLEN];
1381 
1382  assert(scip != NULL);
1383  assert(linebuffer != NULL);
1384  assert(linecnt != NULL);
1385  assert(expr != NULL);
1386  assert(nsmooth != NULL);
1387 
1388  switch( SCIPexprGetOperator(expr) )
1389  {
1390  case SCIP_EXPR_VARIDX:
1391  {
1392  SCIP_Real one;
1393 
1394  assert(exprvars != NULL);
1395 
1396  one = 1.0;
1397  SCIP_CALL( printActiveVariables(scip, file, linebuffer, linecnt, "", "", 1, &exprvars[SCIPexprGetOpIndex(expr)], &one, transformed) );
1398 
1399  break;
1400  }
1401 
1402  case SCIP_EXPR_PARAM:
1403  {
1404  SCIPwarningMessage(scip, "parameterized expression in GAMS writer. GAMS file will not compile.\n");
1405 
1406  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "param%d", SCIPexprGetOpIndex(expr));
1407  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1408 
1409  break;
1410  }
1411 
1412  case SCIP_EXPR_CONST:
1413  {
1414  if( SCIPexprGetOpReal(expr) < 0.0 )
1415  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "(%.15g)", SCIPexprGetOpReal(expr));
1416  else
1417  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", SCIPexprGetOpReal(expr));
1418  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1419 
1420  break;
1421  }
1422 
1423  case SCIP_EXPR_PLUS:
1424  {
1425  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1426  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1427  appendLineWithIndent(scip, file, linebuffer, linecnt, " + ");
1428  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[1], exprvars) );
1429  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1430  break;
1431  }
1432 
1433  case SCIP_EXPR_MINUS:
1434  {
1435  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1436  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1437  appendLineWithIndent(scip, file, linebuffer, linecnt, " - ");
1438  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[1], exprvars) );
1439  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1440  break;
1441  }
1442 
1443  case SCIP_EXPR_MUL:
1444  {
1445  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1446  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1447  appendLineWithIndent(scip, file, linebuffer, linecnt, " * ");
1448  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[1], exprvars) );
1449  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1450  break;
1451  }
1452 
1453  case SCIP_EXPR_DIV:
1454  {
1455  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1456  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1457  appendLineWithIndent(scip, file, linebuffer, linecnt, " / ");
1458  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[1], exprvars) );
1459  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1460  break;
1461  }
1462 
1463  case SCIP_EXPR_REALPOWER:
1464  {
1465  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1466  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1467  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ")**(%.15g)", SCIPexprGetRealPowerExponent(expr));
1468  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1469  break;
1470  }
1471 
1472  case SCIP_EXPR_INTPOWER:
1473  {
1474  appendLineWithIndent(scip, file, linebuffer, linecnt, "power(");
1475  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1476  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ", %d)", SCIPexprGetIntPowerExponent(expr));
1477  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1478  break;
1479  }
1480 
1481  case SCIP_EXPR_SIGNPOWER:
1482  {
1483  SCIP_Real exponent;
1484  SCIP_Bool nisoddint;
1485 
1486  /* signpow(x,y) is printed as x*abs(x) if y == 2, x*(abs(x) ** (y-1)) if y is not 2 and not an odd integer, and as intpower(x,y) if y is an odd integer
1487  * but if reading/gmsreader/signpower is TRUE, then we print as signpower(x,y), unless y is odd integer
1488  */
1489  exponent = SCIPexprGetSignPowerExponent(expr);
1490  nisoddint = (((SCIP_Real)((int)exponent)) == exponent) && (((int)exponent)%2 == 1);
1491 
1492  if( !nisoddint )
1493  {
1494  SCIP_Bool signpowerallowed;
1495 
1496  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/signpower", &signpowerallowed) );
1497 
1498  if( signpowerallowed )
1499  {
1500  appendLineWithIndent(scip, file, linebuffer, linecnt, " * signpower(");
1501  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1502  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ", %.15g)", exponent);
1503  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1504  }
1505  else
1506  {
1507  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1508  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1509  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1510 
1511  if( exponent == 2.0)
1512  {
1513  appendLineWithIndent(scip, file, linebuffer, linecnt, " * abs(");
1514  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1515  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1516  }
1517  else
1518  {
1519  appendLineWithIndent(scip, file, linebuffer, linecnt, " * abs(");
1520  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1521  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ")**(%g)", SCIPexprGetRealPowerExponent(expr)-1.0);
1522  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1523  }
1524  }
1525  *nsmooth = TRUE;
1526  }
1527  else
1528  {
1529  appendLineWithIndent(scip, file, linebuffer, linecnt, " * power(");
1530  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1531  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ", %.15g)", exponent);
1532  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1533  }
1534 
1535  break;
1536  }
1537 
1538  case SCIP_EXPR_ABS:
1539  case SCIP_EXPR_SIGN:
1540  *nsmooth = TRUE; /*lint -fallthrough*/
1541  case SCIP_EXPR_SQUARE:
1542  case SCIP_EXPR_SQRT:
1543  case SCIP_EXPR_EXP:
1544  case SCIP_EXPR_LOG:
1545  case SCIP_EXPR_SIN:
1546  case SCIP_EXPR_COS:
1547  case SCIP_EXPR_TAN:
1548  /* case SCIP_EXPR_ERF: */
1549  /* case SCIP_EXPR_ERFI: */
1550  case SCIP_EXPR_MIN:
1551  case SCIP_EXPR_MAX:
1552  {
1553  int i;
1554 
1555  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s(", SCIPexpropGetName(SCIPexprGetOperator(expr)));
1556  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1557 
1558  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1559  {
1560  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[i], exprvars) );
1561  if( i + 1 < SCIPexprGetNChildren(expr) )
1562  appendLineWithIndent(scip, file, linebuffer, linecnt, ", ");
1563  }
1564 
1565  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1566  break;
1567  }
1568 
1569  case SCIP_EXPR_SUM:
1570  case SCIP_EXPR_PRODUCT:
1571  {
1572  switch( SCIPexprGetNChildren(expr) )
1573  {
1574  case 0:
1575  {
1576  appendLineWithIndent(scip, file, linebuffer, linecnt, SCIPexprGetOperator(expr) == SCIP_EXPR_SUM ? "0" : "1");
1577  break;
1578  }
1579  case 1:
1580  {
1581  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[0], exprvars) );
1582  break;
1583  }
1584  default:
1585  {
1586  int i;
1587  char opstr[GMS_MAX_PRINTLEN];
1588 
1589  (void) SCIPsnprintf(opstr, GMS_MAX_PRINTLEN, SCIPexprGetOperator(expr) == SCIP_EXPR_SUM ? " + " : " * ");
1590  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1591  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1592  {
1593  if( i > 0 )
1594  {
1595  appendLineWithIndent(scip, file, linebuffer, linecnt, opstr);
1596  }
1597  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[i], exprvars) );
1598  }
1599  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1600  }
1601  }
1602  break;
1603  }
1604 
1605  case SCIP_EXPR_LINEAR:
1606  {
1607  SCIP_Real constant;
1608  int i;
1609 
1610  constant = SCIPexprGetLinearConstant(expr);
1611 
1612  if( SCIPexprGetNChildren(expr) == 0 )
1613  {
1614  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", constant);
1615  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1616  break;
1617  }
1618 
1619  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1620 
1621  if( constant != 0.0 )
1622  {
1623  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", constant);
1624  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1625  }
1626 
1627  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1628  {
1629  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g * ", SCIPexprGetLinearCoefs(expr)[i]);
1630  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1631  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[i], exprvars) );
1632  }
1633 
1634  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1635  break;
1636  }
1637 
1638  case SCIP_EXPR_QUADRATIC:
1639  {
1640  SCIP_Real constant;
1641  int i;
1642  SCIP_QUADELEM* quadelems;
1643  SCIP_Real* lincoefs;
1644 
1645  constant = SCIPexprGetQuadConstant(expr);
1646 
1647  if( SCIPexprGetNChildren(expr) == 0 )
1648  {
1649  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", constant);
1650  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1651  break;
1652  }
1653 
1654  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1655 
1656  if( constant != 0.0 )
1657  {
1658  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", constant);
1659  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1660  }
1661 
1662  lincoefs = SCIPexprGetQuadLinearCoefs(expr);
1663  if( lincoefs != NULL )
1664  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1665  {
1666  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g * ", lincoefs[i]);
1667  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1668  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[i], exprvars) );
1669  }
1670 
1671  quadelems = SCIPexprGetQuadElements(expr);
1672  for( i = 0; i < SCIPexprGetNQuadElements(expr); ++i )
1673  {
1674  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g * ", quadelems[i].coef);
1675  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1676 
1677  if( quadelems[i].idx1 == quadelems[i].idx2 )
1678  {
1679  appendLineWithIndent(scip, file, linebuffer, linecnt, "sqr(");
1680  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[quadelems[i].idx1], exprvars) );
1681  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1682  }
1683  else
1684  {
1685  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[quadelems[i].idx1], exprvars) );
1686  appendLineWithIndent(scip, file, linebuffer, linecnt, " * ");
1687  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[quadelems[i].idx2], exprvars) );
1688  }
1689  }
1690 
1691  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1692  break;
1693  }
1694 
1695  case SCIP_EXPR_POLYNOMIAL:
1696  {
1697  SCIP_EXPRDATA_MONOMIAL* monomdata;
1698  SCIP_Real exponent;
1699  int i;
1700  int j;
1701 
1702  appendLineWithIndent(scip, file, linebuffer, linecnt, "(");
1703 
1704  if( SCIPexprGetPolynomialConstant(expr) != 0.0 || SCIPexprGetNMonomials(expr) == 0 )
1705  {
1706  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%.15g", SCIPexprGetPolynomialConstant(expr));
1707  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1708  }
1709 
1710  for( i = 0; i < SCIPexprGetNMonomials(expr); ++i )
1711  {
1712  monomdata = SCIPexprGetMonomials(expr)[i];
1713  assert(monomdata != NULL);
1714 
1715  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %+.15g", SCIPexprGetMonomialCoef(monomdata));
1716  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1717 
1718  for( j = 0; j < SCIPexprGetMonomialNFactors(monomdata); ++j )
1719  {
1720  appendLineWithIndent(scip, file, linebuffer, linecnt, "*");
1721 
1722  exponent = SCIPexprGetMonomialExponents(monomdata)[j];
1723  if( exponent == 1.0 )
1724  {
1725  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[SCIPexprGetMonomialChildIndices(monomdata)[j]], exprvars) );
1726  }
1727  else if( exponent == 2.0 )
1728  {
1729  appendLineWithIndent(scip, file, linebuffer, linecnt, "sqr(");
1730  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[SCIPexprGetMonomialChildIndices(monomdata)[j]], exprvars) );
1731  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1732  }
1733  else if( exponent == 0.5 )
1734  {
1735  appendLineWithIndent(scip, file, linebuffer, linecnt, "sqrt(");
1736  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[SCIPexprGetMonomialChildIndices(monomdata)[j]], exprvars) );
1737  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1738  }
1739  else if( ((SCIP_Real)((int)exponent)) == exponent )
1740  {
1741  appendLineWithIndent(scip, file, linebuffer, linecnt, "power(");
1742  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[SCIPexprGetMonomialChildIndices(monomdata)[j]], exprvars) );
1743  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ", %d)", (int)SCIPround(scip, exponent));
1744  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1745  }
1746  else
1747  {
1748  SCIP_CALL( printExpr(scip, file, linebuffer, linecnt, nsmooth, transformed, SCIPexprGetChildren(expr)[SCIPexprGetMonomialChildIndices(monomdata)[j]], exprvars) );
1749  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " ** %.15g", exponent);
1750  appendLineWithIndent(scip, file, linebuffer, linecnt, buffer);
1751  }
1752  }
1753  }
1754 
1755  appendLineWithIndent(scip, file, linebuffer, linecnt, ")");
1756  break;
1757  }
1758 
1759  default:
1760  SCIPerrorMessage("unexpected operand %d in expression\n", SCIPexprGetOperator(expr));
1761  return SCIP_OKAY;
1762  } /*lint !e788*/
1763 
1764  return SCIP_OKAY;
1765 }
1766 
1767 /* print nonlinear row in GAMS format to file stream */
1768 static
1770  SCIP* scip, /**< SCIP data structure */
1771  FILE* file, /**< output file (or NULL for standard output) */
1772  const char* rowname, /**< row name */
1773  const char* rownameextension, /**< row name extension */
1774  const char* type, /**< row type ("=e=", "=l=", or "=g=") */
1775  int nlinvars, /**< number of linear terms */
1776  SCIP_VAR** linvars, /**< variables in linear part */
1777  SCIP_Real* lincoeffs, /**< coefficients of variables in linear part */
1778  int nexprtrees, /**< number of expression trees */
1779  SCIP_EXPRTREE** exprtrees, /**< expression trees */
1780  SCIP_Real* exprtreecoefs, /**< expression tree coefficients */
1781  SCIP_Real rhs, /**< right hand side */
1782  SCIP_Bool transformed, /**< transformed constraint? */
1783  SCIP_Bool* nsmooth /**< buffer to store whether we printed a nonsmooth function */
1784  )
1785 {
1786  char linebuffer[GMS_MAX_PRINTLEN+1] = { '\0' };
1787  int linecnt;
1788 
1789  char consname[GMS_MAX_NAMELEN + 3]; /* four extra characters for ' ..' */
1790  char buffer[GMS_MAX_PRINTLEN];
1791 
1792  int i;
1793 
1794  assert( scip != NULL );
1795  assert( strlen(rowname) > 0 || strlen(rownameextension) > 0 );
1796  assert( strcmp(type, "=e=") == 0 || strcmp(type, "=l=") == 0 || strcmp(type, "=g=") == 0 );
1797 
1798  clearLine(linebuffer, &linecnt);
1799 
1800  /* start each line with a space */
1801  appendLine(scip, file, linebuffer, &linecnt, " ");
1802 
1803  /* print row name */
1804  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%s%s ..", rowname, rownameextension);
1805  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN + 3, buffer) );
1806 
1807  appendLine(scip, file, linebuffer, &linecnt, consname);
1808 
1809  /* print nonlinear terms
1810  */
1811  for( i = 0; i < nexprtrees; ++i )
1812  {
1813  assert(exprtrees[i] != NULL);
1814  if( exprtreecoefs[i] != 0.0 )
1815  {
1816  (void) SCIPsnprintf(buffer, GMS_MAX_NAMELEN + 3, "%+g * (", exprtreecoefs[i]);
1817  appendLineWithIndent(scip, file, linebuffer, &linecnt, buffer);
1818  SCIP_CALL( printExpr(scip, file, linebuffer, &linecnt, nsmooth, transformed, SCIPexprtreeGetRoot(exprtrees[i]), SCIPexprtreeGetVars(exprtrees[i])) );
1819  appendLineWithIndent(scip, file, linebuffer, &linecnt, ")");
1820  }
1821  }
1822 
1823  /* print linear terms, do after nonlinear since nonlinear may not print sign in beginning */
1824  if( nlinvars > 0 )
1825  {
1826  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "+", " ", nlinvars, linvars, lincoeffs, transformed) );
1827  }
1828 
1829  /* print right hand side */
1830  if( linecnt == 0 )
1831  /* we start a new line; therefore we tab this line */
1832  appendLine(scip, file, linebuffer, &linecnt, " ");
1833 
1834  if( SCIPisZero(scip, rhs) )
1835  rhs = 0.0;
1836 
1837  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s %.15g;", type, rhs);
1838 
1839  appendLine(scip, file, linebuffer, &linecnt, buffer);
1840 
1841  endLine(scip, file, linebuffer, &linecnt);
1842 
1843  return SCIP_OKAY;
1844 }
1845 
1846 /* print nonlinear row in GAMS format to file stream (performing retransformation to active linear variables)
1847  * */
1848 static
1850  SCIP* scip, /**< SCIP data structure */
1851  FILE* file, /**< output file (or NULL for standard output) */
1852  const char* rowname, /**< row name */
1853  int nlinvars, /**< number of linear terms */
1854  SCIP_VAR** linvars, /**< variables in linear part */
1855  SCIP_Real* lincoeffs, /**< coefficients of variables in linear part */
1856  int nexprtrees, /**< number of expression trees */
1857  SCIP_EXPRTREE** exprtrees, /**< expression trees */
1858  SCIP_Real* exprtreecoefs, /**< expression tree coefficients */
1859  SCIP_Real lhs, /**< left hand side */
1860  SCIP_Real rhs, /**< right hand side */
1861  SCIP_Bool transformed, /**< transformed constraint? */
1862  SCIP_Bool* nsmooth /**< buffer to store whether we printed a nonsmooth function */
1863  )
1864 {
1865  assert( scip != NULL );
1866  assert( strlen(rowname) > 0 );
1867 
1868  /* print row(s) in GAMS format */
1869  if( SCIPisEQ(scip, lhs, rhs) )
1870  {
1871  assert( !SCIPisInfinity(scip, rhs) );
1872 
1873  /* print equality constraint */
1874  SCIP_CALL( printNonlinearRow(scip, file, rowname, "", "=e=",
1875  nlinvars, linvars, lincoeffs, nexprtrees, exprtrees, exprtreecoefs, rhs, transformed, nsmooth) );
1876  }
1877  else
1878  {
1879  if( !SCIPisInfinity(scip, -lhs) )
1880  {
1881  /* print inequality ">=" */
1882  SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", "=g=",
1883  nlinvars, linvars, lincoeffs, nexprtrees, exprtrees, exprtreecoefs, lhs, transformed, nsmooth) );
1884  }
1885  if( !SCIPisInfinity(scip, rhs) )
1886  {
1887  /* print inequality "<=" */
1888  SCIP_CALL( printNonlinearRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "=l=",
1889  nlinvars, linvars, lincoeffs, nexprtrees, exprtrees, exprtreecoefs, rhs, transformed, nsmooth) );
1890  }
1891  }
1892 
1893  return SCIP_OKAY;
1894 }
1895 
1896 /** method check if the variable names are not longer than GMS_MAX_NAMELEN */
1897 static
1899  SCIP* scip, /**< SCIP data structure */
1900  SCIP_VAR** vars, /**< array of variables */
1901  int nvars /**< number of variables */
1902  )
1903 {
1904  int v;
1905  SCIP_VAR* var;
1906  SCIP_Bool replaceforbiddenchars;
1907  const char* badchar;
1908 
1909  assert( scip != NULL );
1910  assert( vars != NULL );
1911 
1912  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
1913 
1914  /* check if the variable names contain any of the bad symbols */
1915  for( badchar = badchars; *badchar; ++badchar )
1916  {
1917  for( v = 0; v < nvars; ++v )
1918  {
1919  var = vars[v];
1920  assert( var != NULL );
1921 
1922  if( strchr(SCIPvarGetName(var), *badchar) != NULL )
1923  {
1924  if( replaceforbiddenchars )
1925  {
1926  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);
1927  }
1928  else
1929  {
1930  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);
1931  }
1932 
1933  break;
1934  }
1935  }
1936  }
1937 
1938  /* check if the variable names are too long */
1939  for( v = 0; v < nvars; ++v )
1940  {
1941  var = vars[v];
1942  assert( var != NULL );
1943 
1944  if( strlen(SCIPvarGetName(var)) > GMS_MAX_NAMELEN )
1945  {
1946  SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; GAMS model might be corrupted.\n",
1947  GMS_MAX_NAMELEN - 1);
1948  break;
1949  }
1950  }
1951 
1952  return SCIP_OKAY;
1953 }
1954 
1955 /** method check if the constraint names are not longer than GMS_MAX_NAMELEN */
1956 static
1958  SCIP* scip, /**< SCIP data structure */
1959  SCIP_CONS** conss, /**< array of constraints */
1960  int nconss, /**< number of constraints */
1961  SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
1962  )
1963 {
1964  int c;
1965  SCIP_CONS* cons;
1966  SCIP_CONSHDLR* conshdlr;
1967  const char* conshdlrname;
1968  SCIP_Bool replaceforbiddenchars;
1969  const char* badchar;
1970 
1971  assert( scip != NULL );
1972  assert( conss != NULL );
1973 
1974  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/replaceforbiddenchars", &replaceforbiddenchars) );
1975 
1976  /* check if the constraint names contain any of the bad symbols */
1977  for( badchar = badchars; *badchar; ++badchar )
1978  {
1979  for( c = 0; c < nconss; ++c )
1980  {
1981  cons = conss[c];
1982  assert( cons != NULL );
1983 
1984  if( strchr(SCIPconsGetName(cons), *badchar) != NULL )
1985  {
1986  if( replaceforbiddenchars )
1987  {
1988  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);
1989  }
1990  else
1991  {
1992  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);
1993  }
1994 
1995  break;
1996  }
1997  }
1998  }
1999 
2000  /* check if the constraint names are too long */
2001  for( c = 0; c < nconss; ++c )
2002  {
2003  cons = conss[c];
2004  assert( cons != NULL );
2005 
2006  /* in case the transformed is written, only constraints are posted which are enabled in the current node */
2007  assert(!transformed || SCIPconsIsEnabled(cons));
2008 
2009  conshdlr = SCIPconsGetHdlr(cons);
2010  assert( conshdlr != NULL );
2011 
2012  conshdlrname = SCIPconshdlrGetName(conshdlr);
2013  assert( transformed == SCIPconsIsTransformed(cons) );
2014 
2015  if( strcmp(conshdlrname, "linear") == 0 || strcmp(conshdlrname, "quadratic") == 0 )
2016  {
2017  SCIP_Real lhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetLhsQuadratic(scip, cons);
2018  SCIP_Real rhs = strcmp(conshdlrname, "linear") == 0 ? SCIPgetLhsLinear(scip, cons) : SCIPgetRhsQuadratic(scip, cons);
2019 
2020  if( SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
2021  {
2022  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
2023  GMS_MAX_NAMELEN - 1);
2024  break;
2025  }
2026  else if( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN - 4 )
2027  {
2028  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
2029  GMS_MAX_NAMELEN - 5);
2030  break;
2031  }
2032  }
2033  else if( strlen(SCIPconsGetName(conss[c])) > GMS_MAX_NAMELEN )
2034  {
2035  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
2036  GMS_MAX_NAMELEN - 1);
2037  break;
2038  }
2039  }
2040  return SCIP_OKAY;
2041 }
2042 
2043 
2044 /*
2045  * Callback methods of reader
2046  */
2047 
2048 /** copy method for reader plugins (called when SCIP copies plugins) */
2049 static
2050 SCIP_DECL_READERCOPY(readerCopyGms)
2051 { /*lint --e{715}*/
2052  assert(scip != NULL);
2053  assert(reader != NULL);
2054  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
2055 
2056  /* call inclusion method of reader */
2058 
2059  return SCIP_OKAY;
2060 }
2061 
2062 #ifdef WITH_GAMS
2063 /** problem reading method of reader */
2064 static
2065 SCIP_DECL_READERREAD(readerReadGms)
2066 {
2067  SCIP_RETCODE ret;
2068  FILE* convertdopt;
2069  char gamscall[SCIP_MAXSTRLEN];
2070  char buffer[GMS_SSSIZE];
2071  int rc;
2072  gmoHandle_t gmo = NULL;
2073  gevHandle_t gev = NULL;
2074 
2075  assert(scip != NULL);
2076  assert(reader != NULL);
2077  assert(filename != NULL);
2078  assert(result != NULL);
2079 
2080  *result = SCIP_DIDNOTRUN;
2081  ret = SCIP_ERROR;
2082 
2083  /* create temporary directory */
2084  mkdir("loadgms.tmp", S_IRWXU);
2085 
2086  /* create empty convertd options file */
2087  convertdopt = fopen("loadgms.tmp/convertd.opt", "w");
2088  if( convertdopt == NULL )
2089  {
2090  SCIPerrorMessage("Could not create convertd options file. Do you have write permissions in execution directory?\n");
2091  goto TERMINATE;
2092  }
2093  fputs(" ", convertdopt);
2094  fclose(convertdopt);
2095 
2096  /* call GAMS with convertd solver to get compiled model instance in temporary directory */
2097  SCIPsnprintf(gamscall, SCIP_MAXSTRLEN, WITH_GAMS "/gams %s LP=CONVERTD RMIP=CONVERTD QCP=CONVERTD RMIQCP=CONVERTD NLP=CONVERTD DNLP=CONVERTD RMINLP=CONVERTD CNS=CONVERTD MIP=CONVERTD MIQCP=CONVERTD MINLP=CONVERTD MCP=CONVERTD MPEC=CONVERTD RMPEC=CONVERTD SCRDIR=loadgms.tmp output=loadgms.tmp/listing optdir=loadgms.tmp optfile=1 pf4=0 solprint=0 limcol=0 limrow=0 pc=2 lo=%d",
2098  filename, SCIPgetVerbLevel(scip) == SCIP_VERBLEVEL_FULL ? 3 : 0);
2099  SCIPdebugMsg(scip, gamscall);
2100  rc = system(gamscall);
2101  if( rc != 0 )
2102  {
2103  SCIPerrorMessage("GAMS call returned with code %d, check loadgms.tmp/listing for details.\n", rc);
2104  /* likely the GAMS model could not be compiled, which we could report as a readerror */
2105  ret = SCIP_READERROR;
2106  goto TERMINATE;
2107  }
2108 
2109  /* initialize GEV library and create GEV */
2110  if( !gevCreateDD(&gev, WITH_GAMS, buffer, sizeof(buffer)) )
2111  {
2112  SCIPerrorMessage(buffer);
2113  goto TERMINATE;
2114  }
2115 
2116  /* initialize GMO library and create GMO */
2117  if( !gmoCreateDD(&gmo, WITH_GAMS, buffer, sizeof(buffer)) )
2118  {
2119  SCIPerrorMessage(buffer);
2120  goto TERMINATE;
2121  }
2122 
2123  /* load control file */
2124  if( gevInitEnvironmentLegacy(gev, "loadgms.tmp/gamscntr.dat") )
2125  {
2126  SCIPerrorMessage("Could not load control file loadgms.tmp/gamscntr.dat\n");
2127  goto TERMINATE;
2128  }
2129 
2130  /* tell GMO about GEV */
2131  if( gmoRegisterEnvironment(gmo, gev, buffer) )
2132  {
2133  SCIPerrorMessage("Error registering GAMS Environment: %s\n", buffer);
2134  goto TERMINATE;
2135  }
2136 
2137  /* load GAMS model instance into GMO */
2138  if( gmoLoadDataLegacy(gmo, buffer) )
2139  {
2140  SCIPerrorMessage("Could not load model data.\n");
2141  goto TERMINATE;
2142  }
2143 
2144  /* create SCIP problem out of GMO, using the magic from reader_gmo in interfaces/gams */
2145  SCIP_CALL( SCIPcreateProblemReaderGmo(scip, gmo, NULL, FALSE) );
2146  *result = SCIP_SUCCESS;
2147 
2148  ret = SCIP_OKAY;
2149 
2150 TERMINATE:
2151  if( gmo != NULL )
2152  gmoFree(&gmo);
2153  if( gev != NULL )
2154  gevFree(&gev);
2155 
2156  /* remove temporary directory content (should have only files and directory itself) */
2157  if( ret != SCIP_READERROR )
2158  system("rm loadgms.tmp/* && rmdir loadgms.tmp");
2159 
2160  return ret;
2161 }
2162 #endif
2163 
2164 /** problem writing method of reader */
2165 static
2166 SCIP_DECL_READERWRITE(readerWriteGms)
2167 { /*lint --e{715}*/
2168  SCIP_CALL( SCIPwriteGms(scip, file, name, transformed, objsense, objscale, objoffset, vars,
2169  nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
2170 
2171  return SCIP_OKAY;
2172 }
2173 
2174 #ifdef WITH_GAMS
2175 /** destructor of reader to free user data (called when SCIP is exiting) */
2176 static
2177 SCIP_DECL_READERFREE(readerFreeGms)
2178 {
2179  if( gmoLibraryLoaded() )
2180  gmoLibraryUnload();
2181  if( gevLibraryLoaded() )
2182  gevLibraryUnload();
2183 
2184  return SCIP_OKAY;
2185 }
2186 #endif
2187 
2188 /*
2189  * reader specific interface methods
2190  */
2191 
2192 /** includes the gms file reader in SCIP */
2194  SCIP* scip /**< SCIP data structure */
2195  )
2196 {
2197  SCIP_READER* reader;
2198 
2199  /* include reader */
2201 
2202  /* set non fundamental callbacks via setter functions */
2203  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyGms) );
2204 #ifdef WITH_GAMS
2205  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadGms) );
2206  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeGms) );
2207 #endif
2208  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteGms) );
2209 
2210  /* add gms reader parameters for writing routines*/
2212  "reading/gmsreader/freeints", "have integer variables no upper bound by default (depending on GAMS version)?",
2213  NULL, FALSE, FALSE, NULL, NULL) );
2214 
2216  "reading/gmsreader/replaceforbiddenchars", "shall characters '#', '*', '+', '/', and '-' in variable and constraint names be replaced by '_'?",
2217  NULL, FALSE, FALSE, NULL, NULL) );
2218 
2220  "reading/gmsreader/bigmdefault", "default M value for big-M reformulation of indicator constraints in case no bound on slack variable is given",
2222 
2224  "reading/gmsreader/indicatorreform", "which reformulation to use for indicator constraints: 'b'ig-M, 's'os1",
2226 
2228  "reading/gmsreader/signpower", "is it allowed to use the gams function signpower(x,a)?",
2230 
2231  return SCIP_OKAY;
2232 }
2233 
2234 
2235 /** writes problem to gms file */
2237  SCIP* scip, /**< SCIP data structure */
2238  FILE* file, /**< output file, or NULL if standard output should be used */
2239  const char* name, /**< problem name */
2240  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
2241  SCIP_OBJSENSE objsense, /**< objective sense */
2242  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
2243  * extobj = objsense * objscale * (intobj + objoffset) */
2244  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
2245  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
2246  int nvars, /**< number of active variables in the problem */
2247  int nbinvars, /**< number of binary variables */
2248  int nintvars, /**< number of general integer variables */
2249  int nimplvars, /**< number of implicit integer variables */
2250  int ncontvars, /**< number of continuous variables */
2251  SCIP_CONS** conss, /**< array with constraints of the problem */
2252  int nconss, /**< number of constraints in the problem */
2253  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
2254  )
2255 {
2256  int c;
2257  int v;
2258  int linecnt;
2259  char linebuffer[GMS_MAX_PRINTLEN+1];
2260 
2261  char varname[GMS_MAX_NAMELEN];
2262  char buffer[GMS_MAX_PRINTLEN];
2263 
2264  SCIP_Real* objcoeffs;
2265 
2266  SCIP_CONSHDLR* conshdlr;
2267  const char* conshdlrname;
2268  SCIP_CONS* cons;
2269 
2270  char consname[GMS_MAX_NAMELEN];
2271 
2272  SCIP_VAR** consvars;
2273  SCIP_Real* consvals;
2274  int nconsvars;
2275 
2276  SCIP_VAR* var;
2277  SCIP_VAR* objvar;
2278  SCIP_Real lb;
2279  SCIP_Real ub;
2280  SCIP_Bool freeints;
2281  SCIP_Bool nondefbounds;
2282  SCIP_Bool nlcons;
2283  SCIP_Bool nqcons;
2284  SCIP_Bool nsmooth;
2285  SCIP_Bool discrete;
2286  SCIP_Bool rangedrow;
2287  SCIP_Bool indicatorsosdef;
2288  SCIP_Bool signpowerallowed;
2289  SCIP_Bool needcomma;
2290 
2291  assert( scip != NULL );
2292  assert( vars != NULL || nvars == 0 );
2293 
2294  /* check if the variable names are not too long */
2295  SCIP_CALL( checkVarnames(scip, vars, nvars) );
2296  /* check if the constraint names are too long */
2297  SCIP_CALL( checkConsnames(scip, conss, nconss, transformed) );
2298 
2299  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/signpower", &signpowerallowed) );
2300 
2301  /* check if the objective is a single continuous variable, so we would not have to introduce an auxiliary variable
2302  * for GAMS
2303  */
2304  objvar = NULL;
2305  if( objscale == 1.0 && objoffset == 0.0 )
2306  {
2307  for( v = 0; v < nvars; ++v )
2308  {
2309  if( SCIPvarGetObj(vars[v]) == 0.0 ) /*lint !e613*/
2310  continue;
2311 
2312  if( objvar == NULL )
2313  {
2314  /* first variable with nonzero obj coefficient
2315  * if not active or having coefficient != 1.0, or being binary/integer, then give up
2316  */
2317  if( !SCIPvarIsActive(vars[v]) || SCIPvarGetObj(vars[v]) != 1.0 ||
2318  SCIPvarGetType(vars[v]) < SCIP_VARTYPE_IMPLINT ) /*lint !e613*/
2319  break;
2320 
2321  objvar = vars[v]; /*lint !e613*/
2322  }
2323  else
2324  {
2325  /* second variable with nonzero obj coefficient -> give up */
2326  objvar = NULL;
2327  break;
2328  }
2329  }
2330  }
2331 
2332  /* print statistics as comment to file */
2333  SCIPinfoMessage(scip, file, "$OFFLISTING\n");
2334  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
2335  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
2336  SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
2337  nvars, nbinvars, nintvars, nimplvars, ncontvars);
2338  SCIPinfoMessage(scip, file, "* Constraints : %d\n\n", nconss);
2339 
2340  /* print flags */
2341  SCIPinfoMessage(scip, file, "$MAXCOL %d\n", GMS_MAX_LINELEN - 1);
2342  SCIPinfoMessage(scip, file, "$OFFDIGIT\n\n");
2343 
2344  /* print variable section */
2345  SCIPinfoMessage(scip, file, "Variables\n");
2346  clearLine(linebuffer, &linecnt);
2347 
2348  if( objvar == NULL )
2349  {
2350  /* auxiliary objective variable */
2351  SCIPinfoMessage(scip, file, " objvar%c", nvars > 0 ? ',' : ';');
2352  }
2353 
2354  /* "model" variables */
2355  for( v = 0; v < nvars; ++v )
2356  {
2357  var = vars[v]; /*lint !e613*/
2358  assert( var != NULL );
2359 
2360  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
2361  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%c", varname, (v < nvars - 1) ? ',' : ';');
2362  appendLine(scip, file, linebuffer, &linecnt, buffer);
2363 
2364  if( (linecnt > 0 && (v == nbinvars - 1 || v == nbinvars + nintvars - 1 ||
2365  v == nbinvars + nintvars + nimplvars - 1)) || v == nvars - 1 )
2366  {
2367  endLine(scip, file, linebuffer, &linecnt);
2368  clearLine(linebuffer, &linecnt);
2369  }
2370  }
2371 
2372  SCIPinfoMessage(scip, file, "\n");
2373 
2374  /* declare binary variables if present */
2375  if( nbinvars > 0 )
2376  {
2377  SCIPinfoMessage(scip, file, "Binary variables\n");
2378  clearLine(linebuffer, &linecnt);
2379 
2380  for( v = 0; v < nbinvars; ++v )
2381  {
2382  var = vars[v]; /*lint !e613*/
2383 
2384  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
2385  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s", varname, (v < nbinvars - 1) ? "," : ";");
2386 
2387  appendLine(scip, file, linebuffer, &linecnt, buffer);
2388  }
2389 
2390  endLine(scip, file, linebuffer, &linecnt);
2391  SCIPinfoMessage(scip, file, "\n");
2392  }
2393 
2394  /* declare integer variables if present */
2395  if( nintvars > 0 )
2396  {
2397  SCIPinfoMessage(scip, file, "Integer variables\n");
2398  clearLine(linebuffer, &linecnt);
2399 
2400  for( v = 0; v < nintvars; ++v )
2401  {
2402  var = vars[nbinvars + v]; /*lint !e613*/
2403 
2404  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
2405  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s", varname, (v < nintvars - 1) ? "," : ";");
2406 
2407  appendLine(scip, file, linebuffer, &linecnt, buffer);
2408  }
2409  endLine(scip, file, linebuffer, &linecnt);
2410  SCIPinfoMessage(scip, file, "\n");
2411  }
2412 
2413  /* print variable bounds */
2414  SCIPinfoMessage(scip, file, "* Variable bounds\n");
2415  SCIP_CALL( SCIPgetBoolParam(scip, "reading/gmsreader/freeints", &freeints) );
2416  nondefbounds = FALSE;
2417 
2418  for( v = 0; v < nvars; ++v )
2419  {
2420  var = vars[v]; /*lint !e613*/
2421  assert( var != NULL );
2422 
2423  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(var)) );
2424 
2425  if( transformed )
2426  {
2427  /* in case the transformed is written only local bounds are posted which are valid in the current node */
2428  lb = SCIPvarGetLbLocal(var);
2429  ub = SCIPvarGetUbLocal(var);
2430  }
2431  else
2432  {
2433  lb = SCIPvarGetLbOriginal(var);
2434  ub = SCIPvarGetUbOriginal(var);
2435  }
2436  assert( lb <= ub );
2437 
2438  /* fixed */
2439  if( SCIPisEQ(scip, lb, ub) )
2440  {
2441  if( v < nintvars )
2442  SCIPinfoMessage(scip, file, " %s.fx = %g;\n", varname, SCIPfloor(scip, lb + 0.5));
2443  else
2444  SCIPinfoMessage(scip, file, " %s.fx = %.15g;\n", varname, lb);
2445  nondefbounds = TRUE;
2446 
2447  /* no need to write lower and upper bounds additionally */
2448  continue;
2449  }
2450 
2451  /* lower bound */
2452  if( v < nbinvars + nintvars )
2453  {
2454  /* default lower bound of binaries and integers is 0 (also in recent gams versions if pf4=0 is given) */
2455  if( !SCIPisZero(scip, lb) )
2456  {
2457  if( !SCIPisInfinity(scip, -lb) )
2458  SCIPinfoMessage(scip, file, " %s.lo = %g;\n", varname, SCIPceil(scip, lb));
2459  else if( freeints )
2460  SCIPinfoMessage(scip, file, " %s.lo = -inf;\n", varname); /* -inf is allowed when running gams with pf4=0, which we assume if freeints is TRUE */
2461  else
2462  SCIPinfoMessage(scip, file, " %s.lo = %g;\n", varname, -SCIPinfinity(scip)); /* sorry, -inf not allowed in gams file here */
2463  nondefbounds = TRUE;
2464  }
2465  }
2466  else if( v >= nbinvars + nintvars && !SCIPisInfinity(scip, -lb) )
2467  {
2468  /* continuous variables are free by default */
2469  SCIPinfoMessage(scip, file, " %s.lo = %.15g;\n", varname, lb);
2470  nondefbounds = TRUE;
2471  }
2472 
2473  /* upper bound */
2474  if( v < nbinvars )
2475  {
2476  if( !SCIPisFeasEQ(scip, ub, 1.0) )
2477  {
2478  SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
2479  nondefbounds = TRUE;
2480  }
2481  }
2482  else if( v < nbinvars + nintvars && !freeints )
2483  {
2484  /* freeints == FALSE: integer variables have upper bound 100 by default */
2485  if( !SCIPisFeasEQ(scip, ub, 100.0) )
2486  {
2487  if( !SCIPisInfinity(scip, ub) )
2488  SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfeasFloor(scip, ub));
2489  else
2490  SCIPinfoMessage(scip, file, " %s.up = +inf;\n", varname);
2491  nondefbounds = TRUE;
2492  }
2493  }
2494  else if( v < nbinvars + nintvars && !SCIPisInfinity(scip, ub) )
2495  {
2496  /* freeints == TRUE: integer variables have no upper bound by default */
2497  SCIPinfoMessage(scip, file, " %s.up = %g;\n", varname, SCIPfloor(scip, ub));
2498  nondefbounds = TRUE;
2499  }
2500  else if( v >= nbinvars + nintvars && !SCIPisInfinity(scip, ub) )
2501  {
2502  /* continuous variables are free by default */
2503  SCIPinfoMessage(scip, file, " %s.up = %.15g;\n", varname, ub);
2504  nondefbounds = TRUE;
2505  }
2506  }
2507 
2508  if( !nondefbounds )
2509  SCIPinfoMessage(scip, file, "* (All other bounds at default value: binary [0,1], integer [%s], continuous [-inf,+inf].)\n", freeints ? "0,+inf" : "0,100");
2510  SCIPinfoMessage(scip, file, "\n");
2511 
2512  /* print equations section */
2513  if( nconss > 0 || objvar == NULL )
2514  {
2515  SCIPinfoMessage(scip, file, "Equations\n");
2516  clearLine(linebuffer, &linecnt);
2517  }
2518  needcomma = FALSE;
2519 
2520  if( objvar == NULL )
2521  {
2522  SCIPinfoMessage(scip, file, " objequ");
2523  needcomma = TRUE;
2524  }
2525 
2526  /* declare equations */
2527  for( c = 0; c < nconss; ++c )
2528  {
2529  cons = conss[c];
2530  assert( cons != NULL );
2531 
2532  conshdlr = SCIPconsGetHdlr(cons);
2533  assert( conshdlr != NULL );
2534 
2535  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
2536  conshdlrname = SCIPconshdlrGetName(conshdlr);
2537  assert( transformed == SCIPconsIsTransformed(cons) );
2538 
2539  rangedrow = strcmp(conshdlrname, "linear") == 0
2540  && !SCIPisInfinity(scip, -SCIPgetLhsLinear(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsLinear(scip, cons))
2541  && !SCIPisEQ(scip, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons));
2542  rangedrow = rangedrow || (strcmp(conshdlrname, "quadratic") == 0
2543  && !SCIPisInfinity(scip, -SCIPgetLhsQuadratic(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsQuadratic(scip, cons))
2544  && !SCIPisEQ(scip, SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons)));
2545  rangedrow = rangedrow || (strcmp(conshdlrname, "nonlinear") == 0
2546  && !SCIPisInfinity(scip, -SCIPgetLhsNonlinear(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsNonlinear(scip, cons))
2547  && !SCIPisEQ(scip, SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons)));
2548  rangedrow = rangedrow || (strcmp(conshdlrname, "abspower") == 0
2549  && !SCIPisInfinity(scip, -SCIPgetLhsAbspower(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsAbspower(scip, cons))
2550  && !SCIPisEQ(scip, SCIPgetLhsAbspower(scip, cons), SCIPgetRhsAbspower(scip, cons)));
2551  rangedrow = rangedrow || (strcmp(conshdlrname, "bivariate") == 0
2552  && !SCIPisInfinity(scip, -SCIPgetLhsBivariate(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsBivariate(scip, cons))
2553  && !SCIPisEQ(scip, SCIPgetLhsBivariate(scip, cons), SCIPgetRhsBivariate(scip, cons)));
2554  rangedrow = rangedrow || (strcmp(conshdlrname, "varbound") == 0
2555  && !SCIPisInfinity(scip, -SCIPgetLhsVarbound(scip, cons)) && !SCIPisInfinity(scip, SCIPgetRhsVarbound(scip, cons))
2556  && !SCIPisEQ(scip, SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons)));
2557 
2558  /* we declare only those constraints which we can print in GAMS format */
2559  if( strcmp(conshdlrname, "knapsack") != 0 && strcmp(conshdlrname, "logicor") != 0 && strcmp(conshdlrname, "setppc") != 0
2560  && strcmp(conshdlrname, "linear") != 0 && strcmp(conshdlrname, "quadratic") != 0 && strcmp(conshdlrname, "varbound") != 0
2561  && strcmp(conshdlrname, "soc") != 0 && strcmp(conshdlrname, "abspower") != 0 && strcmp(conshdlrname, "bivariate") != 0
2562  && strcmp(conshdlrname, "nonlinear") != 0 && strcmp(conshdlrname, "SOS1") != 0 && strcmp(conshdlrname, "SOS2") != 0
2563  && strcmp(conshdlrname, "indicator") != 0 )
2564  {
2565  SCIPwarningMessage(scip, "Constraint type <%s> not supported. Skip writing constraint <%s>.\n", conshdlrname, SCIPconsGetName(cons));
2566  continue;
2567  }
2568 
2569  if( needcomma )
2570  appendLine(scip, file, linebuffer, &linecnt, ",");
2571 
2572  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
2573  if( rangedrow )
2574  {
2575  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s%s%s%s", consname, "_lhs, ", consname, "_rhs");
2576  appendLine(scip, file, linebuffer, &linecnt, buffer);
2577  }
2578  else
2579  {
2580  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " %s", consname);
2581  appendLine(scip, file, linebuffer, &linecnt, buffer);
2582  }
2583  needcomma = TRUE;
2584  }
2585 
2586  if( nconss > 0 || objvar == NULL )
2587  {
2588  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, ";");
2589  appendLine(scip, file, linebuffer, &linecnt, buffer);
2590 
2591  endLine(scip, file, linebuffer, &linecnt);
2592  SCIPinfoMessage(scip, file, "\n");
2593  }
2594 
2595  if( objvar == NULL )
2596  {
2597  /* print objective function equation */
2598  clearLine(linebuffer, &linecnt);
2599  if( objoffset != 0.0 )
2600  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= %.15g + ", objscale * objoffset);
2601  else
2602  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, " objequ .. objvar =e= ");
2603  appendLine(scip, file, linebuffer, &linecnt, buffer);
2604 
2605  SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nvars) );
2606 
2607  for( v = 0; v < nvars; ++v )
2608  {
2609  var = vars[v]; /*lint !e613*/
2610  assert( var != NULL );
2611 
2612  /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
2613  assert( transformed || SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL || SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED );
2614 
2615  objcoeffs[v] = SCIPisZero(scip, SCIPvarGetObj(var)) ? 0.0 : objscale * SCIPvarGetObj(var);
2616  }
2617 
2618  SCIP_CALL( printActiveVariables(scip, file, linebuffer, &linecnt, "", ";", nvars, vars, objcoeffs, transformed) );
2619 
2620  SCIPfreeBufferArray(scip, &objcoeffs);
2621  endLine(scip, file, linebuffer, &linecnt);
2622  SCIPinfoMessage(scip, file, "\n");
2623  }
2624 
2625  /* print constraints */
2626  nlcons = FALSE;
2627  nqcons = FALSE;
2628  nsmooth = FALSE;
2629  discrete = nbinvars > 0 || nintvars > 0;
2630  indicatorsosdef = FALSE;
2631  for( c = 0; c < nconss; ++c )
2632  {
2633  cons = conss[c];
2634  assert( cons != NULL );
2635 
2636  /* in case the transformed is written, only constraints are posted which are enabled in the current node */
2637  assert(!transformed || SCIPconsIsEnabled(cons));
2638 
2639  conshdlr = SCIPconsGetHdlr(cons);
2640  assert( conshdlr != NULL );
2641 
2642  SCIP_CALL( printConformName(scip, consname, GMS_MAX_NAMELEN, SCIPconsGetName(cons)) );
2643  conshdlrname = SCIPconshdlrGetName(conshdlr);
2644  assert( transformed == SCIPconsIsTransformed(cons) );
2645 
2646  if( strcmp(conshdlrname, "knapsack") == 0 )
2647  {
2648  SCIP_Longint* weights;
2649 
2650  consvars = SCIPgetVarsKnapsack(scip, cons);
2651  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
2652 
2653  /* copy Longint array to SCIP_Real array */
2654  weights = SCIPgetWeightsKnapsack(scip, cons);
2655  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
2656  for( v = 0; v < nconsvars; ++v )
2657  consvals[v] = (SCIP_Real)weights[v];
2658 
2659  SCIP_CALL( printLinearCons(scip, file, consname, nconsvars, consvars, consvals,
2660  -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
2661 
2662  SCIPfreeBufferArray(scip, &consvals);
2663  }
2664  else if( strcmp(conshdlrname, "linear") == 0 )
2665  {
2666  SCIP_CALL( printLinearCons(scip, file, consname,
2667  SCIPgetNVarsLinear(scip, cons), SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
2668  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
2669  }
2670  else if( strcmp(conshdlrname, "logicor") == 0 )
2671  {
2672  SCIP_CALL( printLinearCons(scip, file, consname,
2673  SCIPgetNVarsLogicor(scip, cons), SCIPgetVarsLogicor(scip, cons), NULL,
2674  1.0, SCIPinfinity(scip), transformed) );
2675  }
2676  else if( strcmp(conshdlrname, "quadratic") == 0 )
2677  {
2678  SCIP_CALL( printQuadraticCons(scip, file, consname,
2682  SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons), transformed) );
2683 
2684  nlcons = TRUE;
2685  }
2686  else if( strcmp(conshdlrname, "nonlinear") == 0 )
2687  {
2688  /* cons_nonlinear does not have exprtree's at hand during presolve */
2690  && SCIPgetExprgraphNonlinear(scip,conshdlr) != NULL )
2691  {
2692  SCIP_EXPRTREE* exprtree;
2693  SCIP_Real coef;
2694 
2696  coef = 1.0;
2697  SCIP_CALL( printNonlinearCons(scip, file, consname,
2699  1, &exprtree, &coef,
2700  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons), transformed, &nsmooth) );
2701 
2702  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
2703  }
2704  else
2705  {
2706  SCIP_CALL( printNonlinearCons(scip, file, consname,
2709  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons), transformed, &nsmooth) );
2710  }
2711  nlcons = TRUE;
2712  nqcons = TRUE;
2713  }
2714  else if( strcmp(conshdlrname, "bivariate") == 0 )
2715  {
2716  SCIP_EXPRTREE* exprtree;
2717  SCIP_VAR* linvar;
2718  SCIP_Real lincoef;
2719  int exprdegree;
2720  SCIP_Real one;
2721 
2722  exprtree = SCIPgetExprtreeBivariate(scip, cons);
2723  assert(exprtree != NULL);
2724 
2725  linvar = SCIPgetLinearVarBivariate(scip, cons);
2726  lincoef = SCIPgetLinearCoefBivariate(scip, cons);
2727  one = 1.0;
2728  SCIP_CALL( printNonlinearCons(scip, file, consname,
2729  linvar == NULL ? 0 : 1, &linvar, &lincoef,
2730  1, &exprtree, &one,
2731  SCIPgetLhsBivariate(scip, cons), SCIPgetRhsBivariate(scip, cons), transformed, &nsmooth) );
2732 
2733  SCIP_CALL( SCIPexprtreeGetMaxDegree(exprtree, &exprdegree) );
2734  if( exprdegree > 1 )
2735  nlcons = TRUE;
2736  if( exprdegree > 2)
2737  nqcons = TRUE;
2738  }
2739  else if( strcmp(conshdlrname, "setppc") == 0 )
2740  {
2741  consvars = SCIPgetVarsSetppc(scip, cons);
2742  nconsvars = SCIPgetNVarsSetppc(scip, cons);
2743 
2744  switch( SCIPgetTypeSetppc(scip, cons) )
2745  {
2747  SCIP_CALL( printLinearCons(scip, file, consname,
2748  nconsvars, consvars, NULL, 1.0, 1.0, transformed) );
2749  break;
2751  SCIP_CALL( printLinearCons(scip, file, consname,
2752  nconsvars, consvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
2753  break;
2755  SCIP_CALL( printLinearCons(scip, file, consname,
2756  nconsvars, consvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
2757  break;
2758  }
2759  }
2760  else if( strcmp(conshdlrname, "varbound") == 0 )
2761  {
2762  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
2763  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
2764 
2765  consvars[0] = SCIPgetVarVarbound(scip, cons);
2766  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
2767 
2768  consvals[0] = 1.0;
2769  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
2770 
2771  SCIP_CALL( printLinearCons(scip, file, consname,
2772  2, consvars, consvals,
2773  SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
2774 
2775  SCIPfreeBufferArray(scip, &consvars);
2776  SCIPfreeBufferArray(scip, &consvals);
2777  }
2778  else if( strcmp(conshdlrname, "soc") == 0 )
2779  {
2780  SCIP_CALL( printSOCCons(scip, file, consname,
2781  SCIPgetNLhsVarsSOC(scip, cons), SCIPgetLhsVarsSOC(scip, cons), SCIPgetLhsCoefsSOC(scip, cons), SCIPgetLhsOffsetsSOC(scip, cons), SCIPgetLhsConstantSOC(scip, cons),
2782  SCIPgetRhsVarSOC(scip, cons), SCIPgetRhsCoefSOC(scip, cons), SCIPgetRhsOffsetSOC(scip, cons), transformed) );
2783 
2784  nlcons = nlcons || !isGAMSprintableSOC(SCIPgetNLhsVarsSOC(scip, cons), SCIPgetLhsVarsSOC(scip, cons), SCIPgetLhsCoefsSOC(scip, cons), SCIPgetLhsOffsetsSOC(scip, cons), SCIPgetLhsConstantSOC(scip, cons),
2785  SCIPgetRhsVarSOC(scip, cons), SCIPgetRhsCoefSOC(scip, cons), SCIPgetRhsOffsetSOC(scip, cons));
2786  }
2787  else if( strcmp(conshdlrname, "indicator") == 0 )
2788  {
2789  SCIP_CALL( printIndicatorCons(scip, file, consname,
2790  SCIPgetBinaryVarIndicator(cons), SCIPgetSlackVarIndicator(cons), &indicatorsosdef,
2791  transformed) );
2792  }
2793  else if( strcmp(conshdlrname, "abspower") == 0 )
2794  {
2795  SCIP_CALL( printSignpowerCons(scip, file, consname,
2796  SCIPgetNonlinearVarAbspower(scip, cons), SCIPgetLinearVarAbspower(scip, cons),
2797  SCIPgetExponentAbspower(scip, cons), SCIPgetOffsetAbspower(scip, cons), SCIPgetCoefLinearAbspower(scip, cons),
2798  SCIPgetLhsAbspower(scip, cons), SCIPgetRhsAbspower(scip, cons), transformed, signpowerallowed, &nsmooth) );
2799 
2800  nlcons = TRUE;
2801  nqcons = TRUE;
2802  }
2803  else if( strcmp(conshdlrname, "SOS1") == 0 )
2804  {
2805  SCIP_CALL( printSOSCons(scip, file, consname,
2806  SCIPgetNVarsSOS1(scip, cons), SCIPgetVarsSOS1(scip, cons), 1,
2807  transformed) );
2808  discrete = TRUE;
2809  }
2810  else if( strcmp(conshdlrname, "SOS2") == 0 )
2811  {
2812  SCIP_CALL( printSOSCons(scip, file, consname,
2813  SCIPgetNVarsSOS2(scip, cons), SCIPgetVarsSOS2(scip, cons), 2,
2814  transformed) );
2815  discrete = TRUE;
2816  }
2817  else
2818  {
2819  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
2820  SCIPinfoMessage(scip, file, "* ");
2821  SCIP_CALL( SCIPprintCons(scip, cons, file) );
2822  SCIPinfoMessage(scip, file, ";\n");
2823  }
2824 
2825  SCIPinfoMessage(scip, file, "\n");
2826  }
2827  /* if at most quadratic, then cannot have nonsmooth functions */
2828  assert(nlcons || !nsmooth);
2829 
2830  /* print model creation */
2831  SCIPinfoMessage(scip, file, "Model m / all /;\n\n");
2832 
2833  /* set some options to reduce listing file size */
2834  SCIPinfoMessage(scip, file, "option limrow = 0;\n");
2835  SCIPinfoMessage(scip, file, "option limcol = 0;\n\n");
2836 
2837  /* print solve command */
2838  (void) SCIPsnprintf(buffer, GMS_MAX_PRINTLEN, "%s%s",
2839  discrete ? "MI" : "", nlcons ? (nqcons ? ((nsmooth && !discrete) ? "DNLP" : "NLP") : "QCP") : (discrete > 0 ? "P" : "LP"));
2840 
2841  if( objvar != NULL )
2842  {
2843  SCIP_CALL( printConformName(scip, varname, GMS_MAX_NAMELEN, SCIPvarGetName(objvar)) );
2844  }
2845 
2846  SCIPinfoMessage(scip, file, "$if not set %s $set %s %s\n", buffer, buffer, buffer);
2847  SCIPinfoMessage(scip, file, "Solve m using %%%s%% %simizing %s;\n",
2848  buffer, objsense == SCIP_OBJSENSE_MINIMIZE ? "min" : "max", objvar != NULL ? varname : "objvar");
2849 
2850  *result = SCIP_SUCCESS;
2851 
2852  return SCIP_OKAY;
2853 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
SCIP_EXPORT const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:548
#define GMS_MAX_LINELEN
Definition: reader_gms.c:78
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
static SCIP_DECL_READERWRITE(readerWriteGms)
Definition: reader_gms.c:2166
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8186
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE printNonlinearRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoeffs, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *exprtreecoefs, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth)
Definition: reader_gms.c:1769
SCIP_EXPORT SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17167
SCIP_Real SCIPgetLinearCoefBivariate(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE printSignpowerCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR *nonlinvar, SCIP_VAR *linvar, SCIP_Real exponent, SCIP_Real offset, SCIP_Real coeflinear, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool signpowerallowed, SCIP_Bool *nsmooth)
Definition: reader_gms.c:1320
SCIP_VAR * var2
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetExprtreeCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetNonlinearVarAbspower(SCIP *scip, SCIP_CONS *cons)
int * SCIPexprGetMonomialChildIndices(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5922
Constraint handler for variable bound constraints .
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2501
SCIP_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for memory management
static SCIP_RETCODE printExpr(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_Bool *nsmooth, SCIP_Bool transformed, SCIP_EXPR *expr, SCIP_VAR **exprvars)
Definition: reader_gms.c:1369
SCIP_EXPROP SCIPexprGetOperator(SCIP_EXPR *expr)
Definition: expr.c:5695
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10605
#define SCIP_MAXSTRLEN
Definition: def.h:273
SCIP_VAR * var1
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
static SCIP_Bool isGAMSprintableSOC(int nlhsvars, SCIP_VAR **lhsvars, SCIP_Real *lhscoeffs, SCIP_Real *lhsoffsets, SCIP_Real lhsconstant, SCIP_VAR *rhsvar, SCIP_Real rhscoef, SCIP_Real rhsoffset)
Definition: reader_gms.c:786
#define READER_DESC
Definition: reader_gms.c:73
const char * SCIPexpropGetName(SCIP_EXPROP op)
Definition: expr.c:3265
int SCIPgetNExprtreesNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPexprtreeGetMaxDegree(SCIP_EXPRTREE *tree, int *maxdegree)
Definition: expr.c:8712
SCIP_Real SCIPgetCoefLinearAbspower(SCIP *scip, SCIP_CONS *cons)
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_gms.c:137
SCIP_EXPRTREE ** SCIPgetExprtreesNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
constraint handler for indicator constraints
SCIP_Real SCIPexprGetRealPowerExponent(SCIP_EXPR *expr)
Definition: expr.c:5758
int SCIPexprGetOpIndex(SCIP_EXPR *expr)
Definition: expr.c:5725
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17192
SCIP_Real SCIPexprGetPolynomialConstant(SCIP_EXPR *expr)
Definition: expr.c:5890
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:186
SCIP_Real SCIPgetRhsCoefSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5513
#define FALSE
Definition: def.h:73
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17510
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:138
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17177
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Real SCIPgetRhsBivariate(SCIP *scip, SCIP_CONS *cons)
#define GMS_DEFAULT_INDICATORREFORM
Definition: reader_gms.c:83
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsBivariate(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE printConformName(SCIP *scip, char *t, int len, const char *name)
Definition: reader_gms.c:248
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9272
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17335
public methods for problem variables
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_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17131
static SCIP_RETCODE printSignpowerRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR *nonlinvar, SCIP_VAR *linvar, SCIP_Real exponent, SCIP_Real offset, SCIP_Real coeflinear, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool signpowerallowed, SCIP_Bool *nsmooth)
Definition: reader_gms.c:1116
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
constraint handler for second order cone constraints
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
Constraint handler for the set partitioning / packing / covering constraints .
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10580
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
public methods for SCIP variables
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_EXPRTREE * SCIPgetExprtreeBivariate(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetLhsCoefsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5461
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_gms.c:1898
SCIP_Real SCIPgetRhsOffsetSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5526
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPgetCharParam(SCIP *scip, const char *name, char *value)
Definition: scip_param.c:317
public methods for numerical tolerances
SCIP_EXPRDATA_MONOMIAL ** SCIPexprGetMonomials(SCIP_EXPR *expr)
Definition: expr.c:5866
static void appendLineWithIndent(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_gms.c:207
public methods for expressions, expression trees, expression graphs, and related stuff ...
SCIP_VAR * SCIPgetRhsVarSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5500
int SCIPexprGetMonomialNFactors(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5912
int SCIPexprGetIntPowerExponent(SCIP_EXPR *expr)
Definition: expr.c:5769
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:210
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1531
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_gms.c:1957
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:1742
static void conformName(char *name)
Definition: reader_gms.c:224
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17012
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_VAR * SCIPgetLinearVarAbspower(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNLhsVarsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5435
SCIP_Real * SCIPexprGetQuadLinearCoefs(SCIP_EXPR *expr)
Definition: expr.c:5842
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_Real SCIPgetLhsConstantSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5487
SCIP_RETCODE SCIPincludeReaderGms(SCIP *scip)
Definition: reader_gms.c:2193
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
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:2236
SCIP_Real SCIPexprGetQuadConstant(SCIP_EXPR *expr)
Definition: expr.c:5829
static SCIP_RETCODE printQuadraticRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoeffs, int nquadvarterms, SCIP_QUADVARTERM *quadvarterms, int nbilinterms, SCIP_BILINTERM *bilinterms, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_gms.c:602
static SCIP_DECL_READERCOPY(readerCopyGms)
Definition: reader_gms.c:2050
constraint handler for quadratic constraints
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip_reader.c:162
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:273
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
#define SCIP_CALL(x)
Definition: def.h:364
SCIP_Real * SCIPgetLhsOffsetsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5474
#define GMS_MAX_NAMELEN
Definition: reader_gms.c:80
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_gms.c:94
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoeffs, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *exprtreecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed, SCIP_Bool *nsmooth)
Definition: reader_gms.c:1849
SCIP_EXPR * SCIPexprtreeGetRoot(SCIP_EXPRTREE *tree)
Definition: expr.c:8604
public methods for constraint handler plugins and constraints
public methods for NLP management
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:298
#define GMS_MAX_PRINTLEN
Definition: reader_gms.c:79
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:5715
SCIP_Real SCIPexprGetSignPowerExponent(SCIP_EXPR *expr)
Definition: expr.c:5780
#define SCIP_Bool
Definition: def.h:70
SCIP_VERBLEVEL SCIPgetVerbLevel(SCIP *scip)
Definition: scip_message.c:240
#define GMS_DEFAULT_SIGNPOWER
Definition: reader_gms.c:84
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_gms.c:151
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
#define READER_EXTENSION
Definition: reader_gms.c:75
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17672
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
constraint handler for nonlinear constraints
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:5705
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8398
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPexprtreeFree(SCIP_EXPRTREE **tree)
Definition: expr.c:8854
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
SCIP_VAR ** SCIPexprtreeGetVars(SCIP_EXPRTREE *tree)
Definition: nlp.c:103
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetOffsetAbspower(SCIP *scip, SCIP_CONS *cons)
constraint handler for bivariate nonlinear constraints
Constraint handler for linear constraints in their most general form, .
SCIP_EXPORT SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17608
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPexprGetMonomialCoef(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5902
Constraint handler for absolute power constraints .
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17718
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
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:931
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_gms.c:173
#define SCIP_REAL_MAX
Definition: def.h:164
static const char badchars[]
Definition: reader_gms.c:90
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
GAMS file reader and writer.
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17728
#define GMS_DEFAULT_BIGM
Definition: reader_gms.c:82
general public methods
SCIP_Real SCIPgetExponentAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2526
SCIP_Real * SCIPexprGetLinearCoefs(SCIP_EXPR *expr)
Definition: expr.c:5791
static const SCIP_Real scalars[]
Definition: lp.c:5731
SCIP_Real SCIPexprGetOpReal(SCIP_EXPR *expr)
Definition: expr.c:5736
#define READER_NAME
Definition: reader_gms.c:69
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17662
SCIP_EXPRGRAPH * SCIPgetExprgraphNonlinear(SCIP *scip, SCIP_CONSHDLR *conshdlr)
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:1059
SCIP_QUADELEM * SCIPexprGetQuadElements(SCIP_EXPR *expr)
Definition: expr.c:5817
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for message output
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:514
int SCIPexprGetNMonomials(SCIP_EXPR *expr)
Definition: expr.c:5878
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10590
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9249
static SCIP_RETCODE printQuadraticCons(SCIP *scip, FILE *file, const char *rowname, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoeffs, int nquadvarterms, SCIP_QUADVARTERM *quadvarterms, int nbilinterms, SCIP_BILINTERM *bilinterms, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_gms.c:721
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8089
SCIP_RETCODE SCIPexprgraphGetTree(SCIP_EXPRGRAPH *exprgraph, SCIP_EXPRGRAPHNODE *rootnode, SCIP_EXPRTREE **exprtree)
Definition: expr.c:16254
#define SCIP_Real
Definition: def.h:163
public methods for input file readers
#define GMS_PRINTLEN
Definition: reader_gms.c:81
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8109
constraint handler for SOS type 1 constraints
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for message handling
#define SCIP_DECL_READERREAD(x)
Definition: type_reader.h:78
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12540
SCIP_EXPRGRAPHNODE * SCIPgetExprgraphNodeNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPexprGetMonomialExponents(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5932
#define SCIP_Longint
Definition: def.h:148
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4179
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9295
static SCIP_RETCODE printSOCCons(SCIP *scip, FILE *file, const char *rowname, int nlhsvars, SCIP_VAR **lhsvars, SCIP_Real *lhscoeffs, SCIP_Real *lhsoffsets, SCIP_Real lhsconstant, SCIP_VAR *rhsvar, SCIP_Real rhscoef, SCIP_Real rhsoffset, SCIP_Bool transformed)
Definition: reader_gms.c:841
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetLinearVarBivariate(SCIP *scip, SCIP_CONS *cons)
constraint handler for SOS type 2 constraints
SCIP_Real SCIPgetLhsAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetLhsVarsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:5448
SCIP_EXPORT SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17628
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
public methods for reader plugins
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPexprGetLinearConstant(SCIP_EXPR *expr)
Definition: expr.c:5804
int SCIPexprGetNQuadElements(SCIP_EXPR *expr)
Definition: expr.c:5854
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, 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:427
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
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
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
#define SCIP_DECL_READERFREE(x)
Definition: type_reader.h:62
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
memory allocation routines