Scippy

SCIP

Solving Constraint Integer Programs

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