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-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_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 "blockmemshell/memory.h"
26 #include <ctype.h>
27 #include "nlpi/pub_expr.h"
28 #include "scip/cons_abspower.h"
29 #include "scip/cons_and.h"
30 #include "scip/cons_bivariate.h"
31 #include "scip/cons_knapsack.h"
32 #include "scip/cons_linear.h"
33 #include "scip/cons_logicor.h"
34 #include "scip/cons_nonlinear.h"
35 #include "scip/cons_quadratic.h"
36 #include "scip/cons_setppc.h"
37 #include "scip/cons_varbound.h"
38 #include "scip/pub_cons.h"
39 #include "scip/pub_fileio.h"
40 #include "scip/pub_message.h"
41 #include "scip/pub_misc.h"
42 #include "scip/pub_nlp.h"
43 #include "scip/pub_reader.h"
44 #include "scip/pub_var.h"
45 #include "scip/reader_pip.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 
57 #if !defined(_WIN32) && !defined(_WIN64)
58 #include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
59 #endif
60 
61 #define READER_NAME "pipreader"
62 #define READER_DESC "file reader for polynomial mixed-integer programs in PIP format"
63 #define READER_EXTENSION "pip"
64 
65 
66 /*
67  * Data structures
68  */
69 #define PIP_MAX_LINELEN 65536
70 #define PIP_MAX_PUSHEDTOKENS 2
71 #define PIP_INIT_VARSSIZE 256
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 
135 
136 /*
137  * Local methods (for reading)
138  */
139 
140 /** issues an error message and marks the PIP data to have errors */
141 static
143  SCIP* scip, /**< SCIP data structure */
144  PIPINPUT* pipinput, /**< PIP reading data */
145  const char* msg /**< error message */
146  )
147 {
148  char formatstr[256];
149 
150  assert(pipinput != NULL);
151 
152  SCIPerrorMessage("Syntax error in line %d: %s ('%s')\n", pipinput->linenumber, msg, pipinput->token);
153  if( pipinput->linebuf[strlen(pipinput->linebuf)-1] == '\n' )
154  {
155  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", pipinput->linebuf);
156  }
157  else
158  {
159  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", pipinput->linebuf);
160  }
161  (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", pipinput->linepos);
162  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, formatstr, "^");
163  pipinput->section = PIP_END;
164  pipinput->haserror = TRUE;
165 }
166 
167 /** returns whether a syntax error was detected */
168 static
170  PIPINPUT* pipinput /**< PIP reading data */
171  )
172 {
173  assert(pipinput != NULL);
174 
175  return pipinput->haserror;
176 }
177 
178 /** returns whether the given character is a token delimiter */
179 static
181  char c /**< input character */
182  )
183 {
184  return (c == '\0') || (strchr(delimchars, c) != NULL);
185 }
186 
187 /** returns whether the given character is a single token */
188 static
190  char c /**< input character */
191  )
192 {
193  return (strchr(tokenchars, c) != NULL);
194 }
195 
196 /** returns whether the current character is member of a value string */
197 static
199  char c, /**< input character */
200  char nextc, /**< next input character */
201  SCIP_Bool firstchar, /**< is the given character the first char of the token? */
202  SCIP_Bool* hasdot, /**< pointer to update the dot flag */
203  PIPEXPTYPE* exptype /**< pointer to update the exponent type */
204  )
205 {
206  assert(hasdot != NULL);
207  assert(exptype != NULL);
208 
209  if( isdigit((unsigned char)c) )
210  return TRUE;
211  else if( (*exptype == PIP_EXP_NONE) && !(*hasdot) && (c == '.') && isdigit((unsigned char)nextc) )
212  {
213  *hasdot = TRUE;
214  return TRUE;
215  }
216  else if( !firstchar && (*exptype == PIP_EXP_NONE) && (c == 'e' || c == 'E') )
217  {
218  if( nextc == '+' || nextc == '-' )
219  {
220  *exptype = PIP_EXP_SIGNED;
221  return TRUE;
222  }
223  else if( isdigit((unsigned char)nextc) )
224  {
225  *exptype = PIP_EXP_UNSIGNED;
226  return TRUE;
227  }
228  }
229  else if( (*exptype == PIP_EXP_SIGNED) && (c == '+' || c == '-') )
230  {
231  *exptype = PIP_EXP_UNSIGNED;
232  return TRUE;
233  }
234 
235  return FALSE;
236 }
237 
238 /** reads the next line from the input file into the line buffer; skips comments;
239  * returns whether a line could be read
240  */
241 static
243  SCIP* scip, /**< SCIP data structure */
244  PIPINPUT* pipinput /**< PIP reading data */
245  )
246 {
247  int i;
248 
249  assert(scip != NULL); /* for lint */
250  assert(pipinput != NULL);
251 
252  /* clear the line */
253  BMSclearMemoryArray(pipinput->linebuf, PIP_MAX_LINELEN);
254 
255  /* read next line */
256  pipinput->linepos = 0;
257  pipinput->linebuf[PIP_MAX_LINELEN-2] = '\0';
258  if( SCIPfgets(pipinput->linebuf, (int) sizeof(pipinput->linebuf), pipinput->file) == NULL )
259  return FALSE;
260  pipinput->linenumber++;
261  if( pipinput->linebuf[PIP_MAX_LINELEN-2] != '\0' )
262  {
263  SCIPerrorMessage("Error: line %d exceeds %d characters\n", pipinput->linenumber, PIP_MAX_LINELEN-2);
264  pipinput->haserror = TRUE;
265  return FALSE;
266  }
267  pipinput->linebuf[PIP_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
268 
269  /* skip characters after comment symbol */
270  for( i = 0; commentchars[i] != '\0'; ++i )
271  {
272  char* commentstart;
273 
274  commentstart = strchr(pipinput->linebuf, commentchars[i]);
275  if( commentstart != NULL )
276  {
277  *commentstart = '\0';
278  *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
279  }
280  }
281 
282  return TRUE;
283 }
284 
285 /** swaps the addresses of two pointers */
286 static
288  char** pointer1, /**< first pointer */
289  char** pointer2 /**< second pointer */
290  )
291 {
292  char* tmp;
293 
294  tmp = *pointer1;
295  *pointer1 = *pointer2;
296  *pointer2 = tmp;
297 }
298 
299 /** reads the next token from the input file into the token buffer; returns whether a token was read */
300 static
302  SCIP* scip, /**< SCIP data structure */
303  PIPINPUT* pipinput /**< PIP reading data */
304  )
305 {
306  SCIP_Bool hasdot;
307  PIPEXPTYPE exptype;
308  char* buf;
309  int tokenlen;
310 
311  assert(pipinput != NULL);
312  assert(pipinput->linepos < PIP_MAX_LINELEN);
313 
314  /* check the token stack */
315  if( pipinput->npushedtokens > 0 )
316  {
317  swapPointers(&pipinput->token, &pipinput->pushedtokens[pipinput->npushedtokens-1]);
318  pipinput->npushedtokens--;
319  SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", pipinput->linenumber, pipinput->token);
320  return TRUE;
321  }
322 
323  /* skip delimiters */
324  buf = pipinput->linebuf;
325  while( isDelimChar(buf[pipinput->linepos]) )
326  {
327  if( buf[pipinput->linepos] == '\0' )
328  {
329  if( !getNextLine(scip, pipinput) )
330  {
331  pipinput->section = PIP_END;
332  SCIPdebugMsg(scip, "(line %d) end of file\n", pipinput->linenumber);
333  return FALSE;
334  }
335  assert(pipinput->linepos == 0);
336  }
337  else
338  pipinput->linepos++;
339  }
340  assert(pipinput->linepos < PIP_MAX_LINELEN);
341  assert(!isDelimChar(buf[pipinput->linepos]));
342 
343  /* check if the token is a value */
344  hasdot = FALSE;
345  exptype = PIP_EXP_NONE;
346  if( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], TRUE, &hasdot, &exptype) )
347  {
348  /* read value token */
349  tokenlen = 0;
350  do
351  {
352  assert(tokenlen < PIP_MAX_LINELEN);
353  assert(!isDelimChar(buf[pipinput->linepos]));
354  pipinput->token[tokenlen] = buf[pipinput->linepos];
355  tokenlen++;
356  pipinput->linepos++;
357  }
358  while( isValueChar(buf[pipinput->linepos], buf[pipinput->linepos+1], FALSE, &hasdot, &exptype) );
359  }
360  else
361  {
362  /* read non-value token */
363  tokenlen = 0;
364  do
365  {
366  assert(tokenlen < PIP_MAX_LINELEN);
367  pipinput->token[tokenlen] = buf[pipinput->linepos];
368  tokenlen++;
369  pipinput->linepos++;
370  if( tokenlen == 1 && isTokenChar(pipinput->token[0]) )
371  break;
372  }
373  while( !isDelimChar(buf[pipinput->linepos]) && !isTokenChar(buf[pipinput->linepos]) );
374 
375  /* if the token is an equation sense '<', '>', or '=', skip a following '='
376  * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
377  */
378  if( tokenlen >= 1
379  && (pipinput->token[tokenlen-1] == '<' || pipinput->token[tokenlen-1] == '>' || pipinput->token[tokenlen-1] == '=')
380  && buf[pipinput->linepos] == '=' )
381  {
382  pipinput->linepos++;
383  }
384  else if( pipinput->token[tokenlen-1] == '=' && (buf[pipinput->linepos] == '<' || buf[pipinput->linepos] == '>') )
385  {
386  pipinput->token[tokenlen-1] = buf[pipinput->linepos];
387  pipinput->linepos++;
388  }
389  }
390  assert(tokenlen < PIP_MAX_LINELEN);
391  pipinput->token[tokenlen] = '\0';
392 
393  SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", pipinput->linenumber, pipinput->token);
394 
395  return TRUE;
396 }
397 
398 /** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
399 static
401  PIPINPUT* pipinput /**< PIP reading data */
402  )
403 {
404  assert(pipinput != NULL);
405  assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
406 
407  swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->token);
408  pipinput->npushedtokens++;
409 }
410 
411 /** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
412 static
414  PIPINPUT* pipinput /**< PIP reading data */
415  )
416 {
417  assert(pipinput != NULL);
418  assert(pipinput->npushedtokens < PIP_MAX_PUSHEDTOKENS);
419 
420  swapPointers(&pipinput->pushedtokens[pipinput->npushedtokens], &pipinput->tokenbuf);
421  pipinput->npushedtokens++;
422 }
423 
424 /** swaps the current token with the token buffer */
425 static
427  PIPINPUT* pipinput /**< PIP reading data */
428  )
429 {
430  assert(pipinput != NULL);
431 
432  swapPointers(&pipinput->token, &pipinput->tokenbuf);
433 }
434 
435 /** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
436 static
438  SCIP* scip, /**< SCIP data structure */
439  PIPINPUT* pipinput /**< PIP reading data */
440  )
441 {
442  SCIP_Bool iscolon;
443 
444  assert(pipinput != NULL);
445 
446  /* remember first token by swapping the token buffer */
447  swapTokenBuffer(pipinput);
448 
449  /* look at next token: if this is a ':', the first token is a name and no section keyword */
450  iscolon = FALSE;
451  if( getNextToken(scip, pipinput) )
452  {
453  iscolon = (strcmp(pipinput->token, ":") == 0);
454  pushToken(pipinput);
455  }
456 
457  /* reinstall the previous token by swapping back the token buffer */
458  swapTokenBuffer(pipinput);
459 
460  /* check for ':' */
461  if( iscolon )
462  return FALSE;
463 
464  if( strcasecmp(pipinput->token, "MINIMIZE") == 0
465  || strcasecmp(pipinput->token, "MINIMUM") == 0
466  || strcasecmp(pipinput->token, "MIN") == 0 )
467  {
468  SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
469  pipinput->section = PIP_OBJECTIVE;
470  pipinput->objsense = SCIP_OBJSENSE_MINIMIZE;
471  return TRUE;
472  }
473 
474  if( strcasecmp(pipinput->token, "MAXIMIZE") == 0
475  || strcasecmp(pipinput->token, "MAXIMUM") == 0
476  || strcasecmp(pipinput->token, "MAX") == 0 )
477  {
478  SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", pipinput->linenumber);
479  pipinput->section = PIP_OBJECTIVE;
480  pipinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
481  return TRUE;
482  }
483 
484  if( strcasecmp(pipinput->token, "SUBJECT") == 0 )
485  {
486  /* check if the next token is 'TO' */
487  swapTokenBuffer(pipinput);
488  if( getNextToken(scip, pipinput) )
489  {
490  if( strcasecmp(pipinput->token, "TO") == 0 )
491  {
492  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
493  pipinput->section = PIP_CONSTRAINTS;
494  return TRUE;
495  }
496  else
497  pushToken(pipinput);
498  }
499  swapTokenBuffer(pipinput);
500  }
501 
502  if( strcasecmp(pipinput->token, "SUCH") == 0 )
503  {
504  /* check if the next token is 'THAT' */
505  swapTokenBuffer(pipinput);
506  if( getNextToken(scip, pipinput) )
507  {
508  if( strcasecmp(pipinput->token, "THAT") == 0 )
509  {
510  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
511  pipinput->section = PIP_CONSTRAINTS;
512  return TRUE;
513  }
514  else
515  pushToken(pipinput);
516  }
517  swapTokenBuffer(pipinput);
518  }
519 
520  if( strcasecmp(pipinput->token, "st") == 0
521  || strcasecmp(pipinput->token, "S.T.") == 0
522  || strcasecmp(pipinput->token, "ST.") == 0 )
523  {
524  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", pipinput->linenumber);
525  pipinput->section = PIP_CONSTRAINTS;
526  return TRUE;
527  }
528 
529  if( strcasecmp(pipinput->token, "BOUNDS") == 0
530  || strcasecmp(pipinput->token, "BOUND") == 0 )
531  {
532  SCIPdebugMsg(scip, "(line %d) new section: BOUNDS\n", pipinput->linenumber);
533  pipinput->section = PIP_BOUNDS;
534  return TRUE;
535  }
536 
537  if( strcasecmp(pipinput->token, "GENERAL") == 0
538  || strcasecmp(pipinput->token, "GENERALS") == 0
539  || strcasecmp(pipinput->token, "GEN") == 0
540  || strcasecmp(pipinput->token, "INTEGER") == 0
541  || strcasecmp(pipinput->token, "INTEGERS") == 0
542  || strcasecmp(pipinput->token, "INT") == 0 )
543  {
544  SCIPdebugMsg(scip, "(line %d) new section: GENERALS\n", pipinput->linenumber);
545  pipinput->section = PIP_GENERALS;
546  return TRUE;
547  }
548 
549  if( strcasecmp(pipinput->token, "BINARY") == 0
550  || strcasecmp(pipinput->token, "BINARIES") == 0
551  || strcasecmp(pipinput->token, "BIN") == 0 )
552  {
553  SCIPdebugMsg(scip, "(line %d) new section: BINARIES\n", pipinput->linenumber);
554  pipinput->section = PIP_BINARIES;
555  return TRUE;
556  }
557 
558  if( strcasecmp(pipinput->token, "END") == 0 )
559  {
560  SCIPdebugMsg(scip, "(line %d) new section: END\n", pipinput->linenumber);
561  pipinput->section = PIP_END;
562  return TRUE;
563  }
564 
565  return FALSE;
566 }
567 
568 /** returns whether the current token is a sign */
569 static
571  PIPINPUT* pipinput, /**< PIP reading data */
572  int* sign /**< pointer to update the sign */
573  )
574 {
575  assert(pipinput != NULL);
576  assert(sign != NULL);
577  assert(*sign == +1 || *sign == -1);
578 
579  if( pipinput->token[1] == '\0' )
580  {
581  if( *pipinput->token == '+' )
582  return TRUE;
583  else if( *pipinput->token == '-' )
584  {
585  *sign *= -1;
586  return TRUE;
587  }
588  }
589 
590  return FALSE;
591 }
592 
593 /** returns whether the current token is a value */
594 static
596  SCIP* scip, /**< SCIP data structure */
597  PIPINPUT* pipinput, /**< PIP reading data */
598  SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
599  )
600 {
601  assert(pipinput != NULL);
602  assert(value != NULL);
603 
604  if( strcasecmp(pipinput->token, "INFINITY") == 0 || strcasecmp(pipinput->token, "INF") == 0 )
605  {
606  *value = SCIPinfinity(scip);
607  return TRUE;
608  }
609  else
610  {
611  double val;
612  char* endptr;
613 
614  val = strtod(pipinput->token, &endptr);
615  if( endptr != pipinput->token && *endptr == '\0' )
616  {
617  *value = val;
618  return TRUE;
619  }
620  }
621 
622  return FALSE;
623 }
624 
625 /** returns whether the current token is an equation sense */
626 static
628  PIPINPUT* pipinput, /**< PIP reading data */
629  PIPSENSE* sense /**< pointer to store the equation sense, or NULL */
630  )
631 {
632  assert(pipinput != NULL);
633 
634  if( strcmp(pipinput->token, "<") == 0 )
635  {
636  if( sense != NULL )
637  *sense = PIP_SENSE_LE;
638  return TRUE;
639  }
640  else if( strcmp(pipinput->token, ">") == 0 )
641  {
642  if( sense != NULL )
643  *sense = PIP_SENSE_GE;
644  return TRUE;
645  }
646  else if( strcmp(pipinput->token, "=") == 0 )
647  {
648  if( sense != NULL )
649  *sense = PIP_SENSE_EQ;
650  return TRUE;
651  }
652 
653  return FALSE;
654 }
655 
656 /** returns the variable with the given name, or creates a new variable if it does not exist */
657 static
659  SCIP* scip, /**< SCIP data structure */
660  char* name, /**< name of the variable */
661  SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
662  SCIP_VAR** var, /**< pointer to store the variable */
663  SCIP_Bool* created /**< pointer to store whether a new variable was created, or NULL */
664  )
665 {
666  assert(name != NULL);
667  assert(var != NULL);
668 
669  *var = SCIPfindVar(scip, name);
670  if( *var == NULL )
671  {
672  SCIP_VAR* newvar;
673 
674  /* create new variable of the given name */
675  SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
676  SCIP_CALL( SCIPcreateVar(scip, &newvar, name, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS,
677  !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
678  SCIP_CALL( SCIPaddVar(scip, newvar) );
679  *var = newvar;
680 
681  /* because the variable was added to the problem, it is captured by SCIP and we can safely release it right now
682  * without making the returned *var invalid
683  */
684  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
685 
686  if( created != NULL )
687  *created = TRUE;
688  }
689  else if( created != NULL )
690  *created = FALSE;
691 
692  return SCIP_OKAY;
693 }
694 
695 /** reads the header of the file */
696 static
698  SCIP* scip, /**< SCIP data structure */
699  PIPINPUT* pipinput /**< PIP reading data */
700  )
701 {
702  assert(pipinput != NULL);
703 
704  /* everything before first section is treated as comment */
705  do
706  {
707  /* get token */
708  if( !getNextToken(scip, pipinput) )
709  return SCIP_OKAY;
710  }
711  while( !isNewSection(scip, pipinput) );
712 
713  return SCIP_OKAY;
714 }
715 
716 /** ensure that an array of monomials can hold a minimum number of entries */
717 static
719  SCIP* scip, /**< SCIP data structure */
720  SCIP_EXPRDATA_MONOMIAL*** monomials, /**< pointer to current array of monomials */
721  int* monomialssize, /**< current size of monomials array at input; new size at exit */
722  int minnmonomials /**< required minimal size of monomials array */
723  )
724 {
725  int newsize;
726 
727  assert(scip != NULL);
728  assert(monomials != NULL);
729  assert(monomialssize != NULL);
730  assert(*monomials != NULL || *monomialssize == 0);
731 
732  if( minnmonomials <= *monomialssize )
733  return SCIP_OKAY;
734 
735  newsize = SCIPcalcMemGrowSize(scip, minnmonomials);
736 
737  if( *monomials != NULL )
738  {
739  SCIP_CALL( SCIPreallocBufferArray(scip, monomials, newsize) );
740  }
741  else
742  {
743  SCIP_CALL( SCIPallocBufferArray(scip, monomials, newsize) );
744  }
745  *monomialssize = newsize;
746 
747  return SCIP_OKAY;
748 }
749 
750 /** ensure that arrays of exponents and variable indices can hold a minimum number of entries */
751 static
753  SCIP* scip, /**< SCIP data structure */
754  SCIP_Real** exponents, /**< pointer to current array of exponents */
755  int** varidxs, /**< pointer to current array of variable indices */
756  int* factorssize, /**< current size of arrays at input; new size at exit */
757  int minnfactors /**< required minimal size of arrays */
758  )
759 {
760  int newsize;
761 
762  assert(scip != NULL);
763  assert(exponents != NULL);
764  assert(varidxs != NULL);
765  assert(factorssize != NULL);
766  assert(*exponents != NULL || *factorssize == 0);
767  assert(*varidxs != NULL || *factorssize == 0);
768  assert((*exponents != NULL) == (*varidxs != NULL));
769 
770  if( minnfactors <= *factorssize )
771  return SCIP_OKAY;
772 
773  newsize = SCIPcalcMemGrowSize(scip, minnfactors);
774 
775  if( *exponents != NULL )
776  {
777  SCIP_CALL( SCIPreallocBufferArray(scip, exponents, newsize) );
778  SCIP_CALL( SCIPreallocBufferArray(scip, varidxs, newsize) );
779  }
780  else
781  {
782  SCIP_CALL( SCIPallocBufferArray(scip, exponents, newsize) );
783  SCIP_CALL( SCIPallocBufferArray(scip, varidxs, newsize) );
784  }
785  *factorssize = newsize;
786 
787  return SCIP_OKAY;
788 }
789 
790 /** gives index of variable in vars array, inserts it at the end if not existing yet */
791 static
793  SCIP* scip, /**< SCIP data structure */
794  SCIP_VAR*** vars, /**< pointer to current array of variables */
795  int* varssize, /**< current size of variables array at input; new size at exit */
796  int* nvars, /**< number of variables stored in array */
797  SCIP_HASHMAP* varhash, /**< hashmap variables -> indices */
798  SCIP_VAR* var, /**< the variable which index we need */
799  int* varidx /**< pointer to store index of variable in *vars */
800  )
801 {
802  assert(scip != NULL);
803  assert(varssize != NULL);
804  assert(vars != NULL);
805  assert(*vars != NULL || *varssize == 0);
806  assert(nvars != NULL);
807  assert(*nvars <= *varssize);
808  assert(varhash != NULL);
809  assert(var != NULL);
810  assert(varidx != NULL);
811 
812  /* check if we saw this variable before */
813  if( SCIPhashmapExists(varhash, (void*)var) )
814  {
815  *varidx = SCIPhashmapGetImageInt(varhash, (void*)var);
816  assert(*varidx >= 0);
817  assert(*varidx < *nvars);
818 
819  return SCIP_OKAY;
820  }
821 
822  /* since variable is new, add it to the end of vars array and into hashmap */
823 
824  /* ensure enough space in vars array */
825  if( *nvars + 1 > *varssize )
826  {
827  *varssize = SCIPcalcMemGrowSize(scip, *nvars + 1);
828  if( *vars == NULL )
829  {
830  SCIP_CALL( SCIPallocBufferArray(scip, vars, *varssize) );
831  }
832  else
833  {
834  SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
835  }
836  }
837  assert(*vars != NULL); /*lint !e613*/
838 
839  (*vars)[*nvars] = var; /*lint !e613*/
840  SCIP_CALL( SCIPhashmapInsertInt(varhash, (void*)var, (*nvars)) );
841  *varidx = *nvars;
842 
843  ++*nvars;
844 
845  return SCIP_OKAY;
846 }
847 
848 /** reads an objective or constraint with name and coefficients */
849 static
851  SCIP* scip, /**< SCIP data structure */
852  PIPINPUT* pipinput, /**< PIP reading data */
853  char* name, /**< pointer to store the name of the line; must be at least of size
854  * PIP_MAX_LINELEN */
855  SCIP_EXPRTREE** exprtree, /**< pointer to store constraint function as polynomial expression */
856  int* degree, /**< pointer to store degree of polynomial */
857  SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
858  )
859 {
860  SCIP_EXPR* expression;
861  SCIP_Bool havesign;
862  SCIP_Bool havevalue;
863  SCIP_Real coef;
864  int coefsign;
865  int nextcoefsign;
866  int monomialdegree;
867  SCIP_EXPR** varexprs;
868  int i;
869 
870  SCIP_VAR** vars;
871  int varssize;
872  int nvars;
873  SCIP_HASHMAP* varhash;
874 
875  SCIP_Real constant;
876 
877  SCIP_EXPRDATA_MONOMIAL** monomials;
878  int monomialssize;
879  int nmonomials;
880 
881  int nfactors;
882  int factorssize;
883  SCIP_Real* exponents;
884  int* varidxs;
885 
886  assert(scip != NULL);
887  assert(pipinput != NULL);
888  assert(name != NULL);
889  assert(exprtree != NULL);
890  assert(degree != NULL);
891  assert(newsection != NULL);
892 
893  *name = '\0';
894  *exprtree = NULL;
895  *degree = 0;
896  *newsection = FALSE;
897 
898  /* read the first token, which may be the name of the line */
899  if( getNextToken(scip, pipinput) )
900  {
901  /* check if we reached a new section */
902  if( isNewSection(scip, pipinput) )
903  {
904  *newsection = TRUE;
905  return SCIP_OKAY;
906  }
907 
908  /* remember the token in the token buffer */
909  swapTokenBuffer(pipinput);
910 
911  /* get the next token and check, whether it is a colon */
912  if( getNextToken(scip, pipinput) )
913  {
914  if( strcmp(pipinput->token, ":") == 0 )
915  {
916  /* the second token was a colon: the first token is the line name */
917  (void)SCIPstrncpy(name, pipinput->tokenbuf, PIP_MAX_LINELEN);
918  SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", pipinput->linenumber, name);
919  }
920  else
921  {
922  /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
923  pushToken(pipinput);
924  pushBufferToken(pipinput);
925  }
926  }
927  else
928  {
929  /* there was only one token left: push it back onto the token stack and parse it as coefficient */
930  pushBufferToken(pipinput);
931  }
932  }
933 
934  /* initialize buffer for storing the variables */
935  varssize = PIP_INIT_VARSSIZE;
936  SCIP_CALL( SCIPallocBufferArray(scip, &vars, varssize) );
938 
939  /* initialize buffer for storing the monomials */
940  monomialssize = PIP_INIT_MONOMIALSSIZE;
941  SCIP_CALL( SCIPallocBufferArray(scip, &monomials, monomialssize) );
942 
943  /* initialize buffer for storing the factors in a monomial */
944  factorssize = PIP_INIT_FACTORSSIZE;
945  SCIP_CALL( SCIPallocBufferArray(scip, &exponents, factorssize) );
946  SCIP_CALL( SCIPallocBufferArray(scip, &varidxs, factorssize) );
947 
948  /* read the coefficients */
949  coefsign = +1;
950  nextcoefsign = +1;
951  coef = 1.0;
952  havesign = FALSE;
953  havevalue = FALSE;
954  nmonomials = 0;
955  nvars = 0;
956  nfactors = 0;
957  monomialdegree = 0;
958  constant = 0.0;
959  while( getNextToken(scip, pipinput) )
960  {
961  SCIP_VAR* var;
962  int varidx;
963  SCIP_Bool issense;
964  SCIP_Bool issign;
965  SCIP_Bool isnewsection;
966  SCIP_Real exponent;
967 
968  issign = FALSE; /* fix compiler warning */
969  issense = FALSE; /* fix lint warning */
970  if( (isnewsection = isNewSection(scip, pipinput)) || /*lint !e820*/
971  (issense = isSense(pipinput, NULL)) || /*lint !e820*/
972  ((nfactors > 0 || havevalue) && (issign = isSign(pipinput, &nextcoefsign))) ) /*lint !e820*/
973  {
974  /* finish the current monomial */
975  if( nfactors > 0 )
976  {
977  SCIP_CALL( ensureMonomialsSize(scip, &monomials, &monomialssize, nmonomials + 1) );
979  &monomials[nmonomials], coefsign * coef, nfactors, varidxs, exponents) );
980  ++nmonomials;
981  }
982  else if( havevalue)
983  {
984  constant += coefsign * coef;
985  }
986 
987  if( monomialdegree > *degree )
988  *degree = monomialdegree;
989 
990  /* reset variables */
991  nfactors = 0;
992  coef = 1.0;
993  coefsign = +1;
994  havesign = FALSE;
995  havevalue = FALSE;
996  monomialdegree = 0;
997 
998  if( isnewsection )
999  {
1000  *newsection = TRUE;
1001  break;
1002  }
1003 
1004  if( issense )
1005  {
1006  /* put the sense back onto the token stack */
1007  pushToken(pipinput);
1008  break;
1009  }
1010 
1011  if( issign )
1012  {
1013  coefsign = nextcoefsign;
1014  SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
1015  havesign = TRUE;
1016  nextcoefsign = +1;
1017  continue;
1018  }
1019  }
1020 
1021  /* check if we read a sign */
1022  if( isSign(pipinput, &coefsign) )
1023  {
1024  SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", pipinput->linenumber, coefsign);
1025 
1026  if( nfactors > 0 || havevalue )
1027  {
1028  syntaxError(scip, pipinput, "sign can only be at beginning of monomial");
1029  goto TERMINATE_READPOLYNOMIAL;
1030  }
1031 
1032  havesign = TRUE;
1033  continue;
1034  }
1035 
1036  /* check if we are in between factors of a monomial */
1037  if( strcmp(pipinput->token, "*") == 0 )
1038  {
1039  if( nfactors == 0 )
1040  {
1041  syntaxError(scip, pipinput, "cannot have '*' before first variable in monomial");
1042  goto TERMINATE_READPOLYNOMIAL;
1043  }
1044 
1045  continue;
1046  }
1047 
1048  /* all but the first monomial need a sign */
1049  if( nmonomials > 0 && !havesign )
1050  {
1051  syntaxError(scip, pipinput, "expected sign ('+' or '-') or sense ('<' or '>')");
1052  goto TERMINATE_READPOLYNOMIAL;
1053  }
1054 
1055  /* check if we are at an exponent for the last variable */
1056  if( strcmp(pipinput->token, "^") == 0 )
1057  {
1058  if( !getNextToken(scip, pipinput) || !isValue(scip, pipinput, &exponent) )
1059  {
1060  syntaxError(scip, pipinput, "expected exponent value after '^'");
1061  goto TERMINATE_READPOLYNOMIAL;
1062  }
1063  if( nfactors == 0 )
1064  {
1065  syntaxError(scip, pipinput, "cannot have '^' before first variable in monomial");
1066  goto TERMINATE_READPOLYNOMIAL;
1067  }
1068  exponents[nfactors-1] = exponent; /*lint !e530*/
1069  if( SCIPisIntegral(scip, exponent) && exponent > 0.0 ) /*lint !e530*/
1070  monomialdegree += (int)exponent - 1; /*lint !e530*//* -1, because we added +1 when we put the variable into varidxs */
1071  else
1072  monomialdegree = SCIP_EXPR_DEGREEINFINITY;
1073 
1074  SCIPdebugMsg(scip, "(line %d) read exponent value %g for variable %s\n", pipinput->linenumber, exponent,
1075  SCIPvarGetName(vars[varidxs[nfactors-1]]));
1076  continue;
1077  }
1078 
1079  /* check if we read a value */
1080  if( isValue(scip, pipinput, &coef) )
1081  {
1082  SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", pipinput->linenumber, coef, coefsign);
1083 
1084  if( havevalue )
1085  {
1086  syntaxError(scip, pipinput, "two consecutive values");
1087  goto TERMINATE_READPOLYNOMIAL;
1088  }
1089 
1090  if( nfactors > 0 )
1091  {
1092  syntaxError(scip, pipinput, "coefficients can only be at the beginning of a monomial");
1093  goto TERMINATE_READPOLYNOMIAL;
1094  }
1095 
1096  havevalue = TRUE;
1097  continue;
1098  }
1099 
1100  /* the token is a variable name: get the corresponding variable (or create a new one) */
1101  SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
1102 
1103  /* get the index of the variable in the vars array, or add there if not in it yet */
1104  SCIP_CALL( getVariableIndex(scip, &vars, &varssize, &nvars, varhash, var, &varidx) );
1105 
1106  SCIP_CALL( ensureFactorsSize(scip, &exponents, &varidxs, &factorssize, nfactors + 1) );
1107 
1108  exponents[nfactors] = 1.0;
1109  varidxs[nfactors] = varidx;
1110  ++nfactors;
1111  ++monomialdegree;
1112  }
1113 
1114  if( nfactors > 0 )
1115  {
1116  syntaxError(scip, pipinput, "string ended before monomial has finished");
1117  goto TERMINATE_READPOLYNOMIAL;
1118  }
1119 
1120  /* create variable expressions */
1121  SCIP_CALL( SCIPallocBufferArray(scip, &varexprs, nvars) );
1122  for( i = 0; i < nvars; ++i )
1123  {
1124  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &varexprs[i], SCIP_EXPR_VARIDX, i) );
1125  }
1126 
1127  /* create polynomial expression, let polynomial take over ownership of monomials */
1128  SCIP_CALL( SCIPexprCreatePolynomial(SCIPblkmem(scip), &expression, nvars, varexprs,
1129  nmonomials, monomials, constant, FALSE) );
1130 
1131  SCIPfreeBufferArray(scip, &varexprs);
1132 
1133  SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(scip), exprtree, expression, 0, 0, NULL) );
1134  SCIP_CALL( SCIPexprtreeSetVars(*exprtree, nvars, vars) );
1135 
1136  SCIPdebugMsg(scip, "read polynomial of degree %d: ", *degree);
1138  SCIPdebugMsgPrint(scip, "\n");
1139 
1140  TERMINATE_READPOLYNOMIAL:
1141  SCIPfreeBufferArray(scip, &varidxs);
1142  SCIPfreeBufferArray(scip, &exponents);
1143  SCIPfreeBufferArray(scip, &monomials);
1144  SCIPfreeBufferArray(scip, &vars);
1145 
1146  SCIPhashmapFree(&varhash);
1147 
1148  return SCIP_OKAY;
1149 }
1150 
1151 /** given an expression tree that holds a polynomial expression of degree at most two,
1152  * gives the coefficients of the constant, linear, and quadratic part of this expression
1153  */
1154 static
1156  SCIP_EXPRTREE* exprtree, /**< expression tree holding polynomial expression */
1157  SCIP_Real* constant, /**< buffer to store constant monomials */
1158  int* nlinvars, /**< buffer to store number of linear coefficients */
1159  SCIP_VAR** linvars, /**< array to fill with linear variables */
1160  SCIP_Real* lincoefs, /**< array to fill with coefficients of linear variables */
1161  int* nquadterms, /**< buffer to store number of quadratic terms */
1162  SCIP_VAR** quadvars1, /**< array to fill with quadratic variables */
1163  SCIP_VAR** quadvars2, /**< array to fill with quadratic variables */
1164  SCIP_Real* quadcoefs /**< array to fill with coefficients of quadratic terms */
1165  )
1166 {
1167  SCIP_EXPR* expr;
1168  SCIP_EXPRDATA_MONOMIAL** monomials;
1169  int nmonomials;
1170  int varidx;
1171  int i;
1172 
1173  expr = SCIPexprtreeGetRoot(exprtree);
1174  assert(expr != NULL);
1175  assert(SCIPexprGetOperator(expr) == SCIP_EXPR_POLYNOMIAL);
1176  assert(SCIPexprGetNChildren(expr) == SCIPexprtreeGetNVars(exprtree));
1177 
1178  nmonomials = SCIPexprGetNMonomials(expr);
1179  monomials = SCIPexprGetMonomials(expr);
1180 
1181  *constant = SCIPexprGetPolynomialConstant(expr);
1182  *nlinvars = 0;
1183  *nquadterms = 0;
1184  for( i = 0; i < nmonomials; ++i )
1185  {
1186  assert(SCIPexprGetMonomialNFactors(monomials[i]) >= 0);
1187  assert(SCIPexprGetMonomialNFactors(monomials[i]) <= 2);
1188  assert(SCIPexprGetMonomialExponents(monomials[i]) != NULL || SCIPexprGetMonomialNFactors(monomials[i]) == 0);
1189  assert(SCIPexprGetMonomialChildIndices(monomials[i]) != NULL || SCIPexprGetMonomialNFactors(monomials[i]) == 0);
1190 
1191  if( SCIPexprGetMonomialNFactors(monomials[i]) == 0 )
1192  {
1193  /* constant monomial */
1194  *constant += SCIPexprGetMonomialCoef(monomials[i]);
1195  }
1196  else if( SCIPexprGetMonomialNFactors(monomials[i]) == 1 && SCIPexprGetMonomialExponents(monomials[i])[0] == 1.0 )
1197  {
1198  /* linear monomial */
1199  varidx = SCIPexprGetMonomialChildIndices(monomials[i])[0];
1200  assert(varidx >= 0);
1201  assert(varidx < SCIPexprtreeGetNVars(exprtree));
1202  assert(SCIPexprGetOperator(SCIPexprGetChildren(expr)[varidx]) == SCIP_EXPR_VARIDX);
1203  assert(SCIPexprGetOpIndex(SCIPexprGetChildren(expr)[varidx]) == varidx); /* assume that child varidx corresponds to variable varidx */
1204 
1205  lincoefs[*nlinvars] = SCIPexprGetMonomialCoef(monomials[i]);
1206  linvars[*nlinvars] = SCIPexprtreeGetVars(exprtree)[varidx];
1207  ++*nlinvars;
1208  }
1209  else if( SCIPexprGetMonomialNFactors(monomials[i]) == 1 )
1210  {
1211  /* square monomial */
1212  assert(SCIPexprGetMonomialExponents(monomials[i])[0] == 2.0);
1213 
1214  varidx = SCIPexprGetMonomialChildIndices(monomials[i])[0];
1215  assert(varidx >= 0);
1216  assert(varidx < SCIPexprtreeGetNVars(exprtree));
1217  assert(SCIPexprGetOperator(SCIPexprGetChildren(expr)[varidx]) == SCIP_EXPR_VARIDX);
1218  assert(SCIPexprGetOpIndex(SCIPexprGetChildren(expr)[varidx]) == varidx); /* assume that child varidx corresponds to variable varidx */
1219 
1220  quadcoefs[*nquadterms] = SCIPexprGetMonomialCoef(monomials[i]);
1221  quadvars1[*nquadterms] = SCIPexprtreeGetVars(exprtree)[varidx];
1222  quadvars2[*nquadterms] = quadvars1[*nquadterms];
1223  ++*nquadterms;
1224  }
1225  else
1226  {
1227  /* bilinear monomial */
1228  assert(SCIPexprGetMonomialExponents(monomials[i])[0] == 1.0);
1229  assert(SCIPexprGetMonomialExponents(monomials[i])[1] == 1.0);
1230 
1231  quadcoefs[*nquadterms] = SCIPexprGetMonomialCoef(monomials[i]);
1232 
1233  varidx = SCIPexprGetMonomialChildIndices(monomials[i])[0];
1234  assert(varidx >= 0);
1235  assert(varidx < SCIPexprtreeGetNVars(exprtree));
1236  assert(SCIPexprGetOperator(SCIPexprGetChildren(expr)[varidx]) == SCIP_EXPR_VARIDX);
1237  assert(SCIPexprGetOpIndex(SCIPexprGetChildren(expr)[varidx]) == varidx); /* assume that child varidx corresponds to variable varidx */
1238  quadvars1[*nquadterms] = SCIPexprtreeGetVars(exprtree)[varidx];
1239 
1240  varidx = SCIPexprGetMonomialChildIndices(monomials[i])[1];
1241  assert(varidx >= 0);
1242  assert(varidx < SCIPexprtreeGetNVars(exprtree));
1243  assert(SCIPexprGetOperator(SCIPexprGetChildren(expr)[varidx]) == SCIP_EXPR_VARIDX);
1244  assert(SCIPexprGetOpIndex(SCIPexprGetChildren(expr)[varidx]) == varidx); /* assume that child varidx corresponds to variable varidx */
1245  quadvars2[*nquadterms] = SCIPexprtreeGetVars(exprtree)[varidx];
1246 
1247  ++*nquadterms;
1248  }
1249  }
1250 }
1251 
1252 /** reads the objective section */
1253 static
1255  SCIP* scip, /**< SCIP data structure */
1256  PIPINPUT* pipinput /**< PIP reading data */
1257  )
1258 {
1259  char name[PIP_MAX_LINELEN];
1260  SCIP_EXPRTREE* exprtree;
1261  SCIP_EXPR* expr;
1262  int degree;
1263  SCIP_Bool newsection;
1264  int varidx;
1265  int nmonomials;
1266  SCIP_Bool initial;
1267  SCIP_Bool separate;
1268  SCIP_Bool enforce;
1269  SCIP_Bool check;
1270  SCIP_Bool propagate;
1271  SCIP_Bool local;
1272  SCIP_Bool modifiable;
1273  SCIP_Bool dynamic;
1274  SCIP_Bool removable;
1275 
1276  assert(pipinput != NULL);
1277 
1278  /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
1279  * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
1280  * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded because
1281  * of loose variables with infinite best bound cannot be solved)
1282  */
1283  initial = TRUE;
1284  separate = TRUE;
1285  enforce = TRUE;
1286  check = TRUE;
1287  propagate = TRUE;
1288  local = FALSE;
1289  modifiable = FALSE;
1290  dynamic = FALSE;
1291  removable = FALSE;
1292 
1293  /* read the objective coefficients */
1294  SCIP_CALL( readPolynomial(scip, pipinput, name, &exprtree, &degree, &newsection) );
1295  if( !hasError(pipinput) && exprtree != NULL )
1296  {
1297  int i;
1298 
1299  expr = SCIPexprtreeGetRoot(exprtree);
1300  assert(expr != NULL);
1301  assert(SCIPexprGetOperator(expr) == SCIP_EXPR_POLYNOMIAL);
1302 
1303  nmonomials = SCIPexprGetNMonomials(expr);
1304 
1305  assert(degree >= 0);
1306  if( degree == 1 )
1307  {
1308  SCIP_Real coef;
1309  SCIP_VAR* var;
1310  SCIP_EXPRDATA_MONOMIAL** monomials;
1311 
1312  assert(SCIPexprtreeGetVars(exprtree) != NULL);
1313  assert(SCIPexprGetNChildren(expr) == SCIPexprtreeGetNVars(exprtree));
1314 
1315  if( SCIPexprGetPolynomialConstant(expr) != 0.0 )
1316  {
1317  SCIP_VAR* objconst;
1318  SCIP_CALL( SCIPcreateVarBasic(scip, &objconst, "objconst", 1.0, 1.0, SCIPexprGetPolynomialConstant(expr), SCIP_VARTYPE_CONTINUOUS) );
1319  SCIP_CALL( SCIPaddVar(scip, objconst) );
1320  SCIP_CALL( SCIPreleaseVar(scip, &objconst) );
1321  }
1322 
1323  monomials = SCIPexprGetMonomials(expr);
1324 
1325  for( i = 0; i < nmonomials; ++i )
1326  {
1327  assert(SCIPexprGetMonomialNFactors(monomials[i]) == 1);
1328  assert(SCIPexprGetMonomialExponents(monomials[i]) != NULL);
1329  assert(SCIPexprGetMonomialExponents(monomials[i])[0] == 1.0);
1330  assert(SCIPexprGetMonomialChildIndices(monomials[i]) != NULL);
1331 
1332  varidx = SCIPexprGetMonomialChildIndices(monomials[i])[0];
1333  assert(varidx >= 0);
1334  assert(varidx < SCIPexprGetNChildren(expr));
1335  assert(SCIPexprGetOperator(SCIPexprGetChildren(expr)[varidx]) == SCIP_EXPR_VARIDX);
1336  assert(SCIPexprGetOpIndex(SCIPexprGetChildren(expr)[varidx]) == varidx); /* assume that child varidx corresponds to variable varidx */
1337 
1338  coef = SCIPexprGetMonomialCoef(monomials[i]);
1339  var = SCIPexprtreeGetVars(exprtree)[varidx];
1340 
1341  SCIP_CALL( SCIPchgVarObj(scip, var, SCIPvarGetObj(var) + coef) );
1342  }
1343  }
1344  else if( degree == 2 )
1345  {
1346  /* insert dummy variable and constraint to represent quadratic part of objective */
1347 
1348  SCIP_VAR* quadobjvar;
1349  SCIP_CONS* quadobjcons;
1350  SCIP_Real lhs;
1351  SCIP_Real rhs;
1352 
1353  SCIP_Real constant;
1354  int nlinvars;
1355  SCIP_VAR** linvars;
1356  SCIP_Real* lincoefs;
1357  int nquadterms;
1358  SCIP_VAR** quadvars1;
1359  SCIP_VAR** quadvars2;
1360  SCIP_Real* quadcoefs;
1361 
1362  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nmonomials) );
1363  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nmonomials) );
1364  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, nmonomials) );
1365  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, nmonomials) );
1366  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, nmonomials) );
1367 
1368  getLinearAndQuadraticCoefs(exprtree, &constant, &nlinvars, linvars, lincoefs, &nquadterms, quadvars1, quadvars2, quadcoefs);
1369 
1370  SCIP_CALL( SCIPcreateVar(scip, &quadobjvar, "quadobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1372  SCIP_CALL( SCIPaddVar(scip, quadobjvar) );
1373 
1374  if ( pipinput->objsense == SCIP_OBJSENSE_MINIMIZE )
1375  {
1376  lhs = -SCIPinfinity(scip);
1377  rhs = -constant;
1378  }
1379  else
1380  {
1381  lhs = -constant;
1382  rhs = SCIPinfinity(scip);
1383  }
1384 
1385  SCIP_CALL( SCIPcreateConsQuadratic(scip, &quadobjcons, "quadobj", nlinvars, linvars, lincoefs, nquadterms, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1386  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) );
1387 
1388  SCIP_CALL( SCIPaddLinearVarQuadratic(scip, quadobjcons, quadobjvar, -1.0) );
1389 
1390  SCIP_CALL( SCIPaddCons(scip, quadobjcons) );
1391  SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent quadratic objective: ", pipinput->linenumber, SCIPconsGetName(quadobjcons));
1392  SCIPdebugPrintCons(scip, quadobjcons, NULL);
1393 
1394  SCIP_CALL( SCIPreleaseCons(scip, &quadobjcons) );
1395  SCIP_CALL( SCIPreleaseVar(scip, &quadobjvar) );
1396 
1397  /* free memory */
1398  SCIPfreeBufferArray(scip, &linvars);
1399  SCIPfreeBufferArray(scip, &lincoefs);
1400  SCIPfreeBufferArray(scip, &quadvars1);
1401  SCIPfreeBufferArray(scip, &quadvars2);
1402  SCIPfreeBufferArray(scip, &quadcoefs);
1403  }
1404  else if( degree > 2 )
1405  {
1406  /* insert dummy variable and constraint to represent nonlinear part of objective */
1407 
1408  SCIP_VAR* nonlinobjvar;
1409  SCIP_CONS* nonlinobjcons;
1410  SCIP_Real minusone;
1411  SCIP_Real lhs;
1412  SCIP_Real rhs;
1413 
1414  SCIP_CALL( SCIPcreateVar(scip, &nonlinobjvar, "nonlinobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1416  SCIP_CALL( SCIPaddVar(scip, nonlinobjvar) );
1417 
1418  minusone = -1.0;
1419 
1420  if ( pipinput->objsense == SCIP_OBJSENSE_MINIMIZE )
1421  {
1422  lhs = -SCIPinfinity(scip);
1423  rhs = -SCIPexprGetPolynomialConstant(expr);
1424  }
1425  else
1426  {
1427  lhs = -SCIPexprGetPolynomialConstant(expr);
1428  rhs = SCIPinfinity(scip);
1429  }
1430 
1431  SCIP_CALL( SCIPcreateConsNonlinear(scip, &nonlinobjcons, "nonlinobj", 1, &nonlinobjvar, &minusone, 1, &exprtree, NULL, lhs, rhs,
1432  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
1433  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
1434 
1435  SCIP_CALL( SCIPaddCons(scip, nonlinobjcons) );
1436  SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent nonlinear objective: ", pipinput->linenumber, SCIPconsGetName(nonlinobjcons));
1437  SCIPdebugPrintCons(scip, nonlinobjcons, NULL);
1438 
1439  SCIP_CALL( SCIPreleaseCons(scip, &nonlinobjcons) );
1440  SCIP_CALL( SCIPreleaseVar(scip, &nonlinobjvar) );
1441  }
1442  }
1443 
1444  if( exprtree != NULL )
1445  {
1446  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
1447  }
1448 
1449  return SCIP_OKAY;
1450 }
1451 
1452 /** reads the constraints section
1453  */
1454 static
1456  SCIP* scip, /**< SCIP data structure */
1457  PIPINPUT* pipinput /**< PIP reading data */
1458  )
1459 {
1460  char name[PIP_MAX_LINELEN];
1461  SCIP_CONS* cons;
1462  SCIP_EXPRTREE* exprtree;
1463  SCIP_EXPR* expr;
1464  int degree;
1465 
1466  SCIP_Real constant;
1467 
1468  int nlinvars;
1469  SCIP_VAR** linvars;
1470  SCIP_Real* lincoefs;
1471 
1472  int nquadcoefs;
1473  SCIP_VAR** quadvars1;
1474  SCIP_VAR** quadvars2;
1475  SCIP_Real* quadcoefs;
1476 
1477  PIPSENSE sense;
1478  SCIP_RETCODE retcode = SCIP_OKAY;
1479  SCIP_Real sidevalue;
1480  SCIP_Real lhs;
1481  SCIP_Real rhs;
1482  SCIP_Bool newsection;
1483  SCIP_Bool initial;
1484  SCIP_Bool separate;
1485  SCIP_Bool enforce;
1486  SCIP_Bool check;
1487  SCIP_Bool propagate;
1488  SCIP_Bool local;
1489  SCIP_Bool modifiable;
1490  SCIP_Bool dynamic;
1491  SCIP_Bool removable;
1492  int sidesign;
1493  int nmonomials;
1494 
1495  assert(pipinput != NULL);
1496 
1497  /* read polynomial */
1498  SCIP_CALL( readPolynomial(scip, pipinput, name, &exprtree, &degree, &newsection) );
1499  if ( hasError(pipinput) )
1500  goto TERMINATE;
1501  if ( newsection )
1502  {
1503  if ( exprtree != NULL )
1504  syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
1505  goto TERMINATE;
1506  }
1507 
1508  /* read the constraint sense */
1509  if ( !getNextToken(scip, pipinput) || !isSense(pipinput, &sense) )
1510  {
1511  syntaxError(scip, pipinput, "expected constraint sense '<=', '=', or '>='");
1512  goto TERMINATE;
1513  }
1514 
1515  /* read the right hand side */
1516  sidesign = +1;
1517  if ( !getNextToken(scip, pipinput) )
1518  {
1519  syntaxError(scip, pipinput, "missing right hand side");
1520  goto TERMINATE;
1521  }
1522  if ( isSign(pipinput, &sidesign) )
1523  {
1524  if( !getNextToken(scip, pipinput) )
1525  {
1526  syntaxError(scip, pipinput, "missing value of right hand side");
1527  goto TERMINATE;
1528  }
1529  }
1530  if ( !isValue(scip, pipinput, &sidevalue) )
1531  {
1532  syntaxError(scip, pipinput, "expected value as right hand side");
1533  goto TERMINATE;
1534  }
1535  sidevalue *= sidesign;
1536 
1537  /* determine settings */
1538  initial = pipinput->initialconss;
1539  separate = TRUE;
1540  enforce = TRUE;
1541  check = TRUE;
1542  propagate = TRUE;
1543  local = FALSE;
1544  modifiable = FALSE;
1545  dynamic = pipinput->dynamicconss;
1546  removable = pipinput->dynamicrows;
1547 
1548  if( degree > 2 )
1549  {
1550  /* assign the left and right hand side, depending on the constraint sense */
1551  switch ( sense ) /*lint !e530*/
1552  {
1553  case PIP_SENSE_GE:
1554  lhs = sidevalue;
1555  rhs = SCIPinfinity(scip);
1556  break;
1557  case PIP_SENSE_LE:
1558  lhs = -SCIPinfinity(scip);
1559  rhs = sidevalue;
1560  break;
1561  case PIP_SENSE_EQ:
1562  lhs = sidevalue;
1563  rhs = sidevalue;
1564  break;
1565  case PIP_SENSE_NOTHING:
1566  default:
1567  SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1568  return SCIP_INVALIDDATA;
1569  }
1570 
1571  SCIP_CALL_TERMINATE( retcode, SCIPcreateConsNonlinear(scip, &cons, name, 0, NULL, NULL, 1, &exprtree, NULL, lhs, rhs,
1572  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE), TERMINATE );
1573  }
1574  else
1575  {
1576  expr = SCIPexprtreeGetRoot(exprtree);
1577  assert(expr != NULL);
1578  assert(SCIPexprGetOperator(expr) == SCIP_EXPR_POLYNOMIAL);
1579  nmonomials = SCIPexprGetNMonomials(expr);
1580 
1581  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nmonomials) );
1582  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nmonomials) );
1583  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, nmonomials) );
1584  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, nmonomials) );
1585  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, nmonomials) );
1586 
1587  getLinearAndQuadraticCoefs(exprtree, &constant, &nlinvars, linvars, lincoefs, &nquadcoefs, quadvars1, quadvars2, quadcoefs);
1588 
1589  /* assign the left and right hand side, depending on the constraint sense */
1590  switch( sense ) /*lint !e530*/
1591  {
1592  case PIP_SENSE_GE:
1593  lhs = sidevalue - constant;
1594  rhs = SCIPinfinity(scip);
1595  break;
1596  case PIP_SENSE_LE:
1597  lhs = -SCIPinfinity(scip);
1598  rhs = sidevalue - constant;
1599  break;
1600  case PIP_SENSE_EQ:
1601  lhs = sidevalue - constant;
1602  rhs = sidevalue - constant;
1603  break;
1604  case PIP_SENSE_NOTHING:
1605  default:
1606  SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1607  return SCIP_INVALIDDATA;
1608  }
1609 
1610  if( nquadcoefs == 0 )
1611  {
1612  retcode = SCIPcreateConsLinear(scip, &cons, name, nlinvars, linvars, lincoefs, lhs, rhs,
1613  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1614  }
1615  else
1616  {
1617  retcode = SCIPcreateConsQuadratic(scip, &cons, name, nlinvars, linvars, lincoefs,
1618  nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1619  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
1620  }
1621 
1622  /* free memory */
1623  SCIPfreeBufferArray(scip, &quadcoefs);
1624  SCIPfreeBufferArray(scip, &quadvars2);
1625  SCIPfreeBufferArray(scip, &quadvars1);
1626  SCIPfreeBufferArray(scip, &lincoefs);
1627  SCIPfreeBufferArray(scip, &linvars);
1628  }
1629 
1630  if( retcode == SCIP_OKAY )
1631  {
1632  SCIP_CALL( SCIPaddCons(scip, cons) );
1633  SCIPdebugMsg(scip, "(line %d) created constraint: ", pipinput->linenumber);
1634  SCIPdebugPrintCons(scip, cons, NULL);
1635  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1636  }
1637 
1638  TERMINATE:
1639  if( exprtree != NULL )
1640  {
1641  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
1642  }
1643 
1644  if( hasError(pipinput) )
1645  retcode = SCIP_READERROR;
1646 
1647  SCIP_CALL( retcode );
1648 
1649  return SCIP_OKAY;
1650 }
1651 
1652 /** reads the bounds section */
1653 static
1655  SCIP* scip, /**< SCIP data structure */
1656  PIPINPUT* pipinput /**< PIP reading data */
1657  )
1658 {
1659  assert(pipinput != NULL);
1660 
1661  while( getNextToken(scip, pipinput) )
1662  {
1663  SCIP_VAR* var;
1664  SCIP_Real value;
1665  SCIP_Real lb;
1666  SCIP_Real ub;
1667  int sign;
1668  SCIP_Bool hassign;
1669  PIPSENSE leftsense;
1670 
1671  /* check if we reached a new section */
1672  if( isNewSection(scip, pipinput) )
1673  return SCIP_OKAY;
1674 
1675  /* default bounds are [0,+inf] */
1676  lb = 0.0;
1677  ub = SCIPinfinity(scip);
1678  leftsense = PIP_SENSE_NOTHING;
1679 
1680  /* check if the first token is a sign */
1681  sign = +1;
1682  hassign = isSign(pipinput, &sign);
1683  if( hassign && !getNextToken(scip, pipinput) )
1684  {
1685  syntaxError(scip, pipinput, "expected value");
1686  return SCIP_OKAY;
1687  }
1688 
1689  /* the first token must be either a value or a variable name */
1690  if( isValue(scip, pipinput, &value) )
1691  {
1692  /* first token is a value: the second token must be a sense */
1693  if( !getNextToken(scip, pipinput) || !isSense(pipinput, &leftsense) )
1694  {
1695  syntaxError(scip, pipinput, "expected bound sense '<=', '=', or '>='");
1696  return SCIP_OKAY;
1697  }
1698 
1699  /* update the bound corresponding to the sense */
1700  switch( leftsense )
1701  {
1702  case PIP_SENSE_GE:
1703  ub = sign * value;
1704  break;
1705  case PIP_SENSE_LE:
1706  lb = sign * value;
1707  break;
1708  case PIP_SENSE_EQ:
1709  lb = sign * value;
1710  ub = sign * value;
1711  break;
1712  case PIP_SENSE_NOTHING:
1713  default:
1714  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1715  return SCIP_INVALIDDATA;
1716  }
1717  }
1718  else if( hassign )
1719  {
1720  syntaxError(scip, pipinput, "expected value");
1721  return SCIP_OKAY;
1722  }
1723  else
1724  pushToken(pipinput);
1725 
1726  /* the next token must be a variable name */
1727  if( !getNextToken(scip, pipinput) )
1728  {
1729  syntaxError(scip, pipinput, "expected variable name");
1730  return SCIP_OKAY;
1731  }
1732  SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, NULL) );
1733 
1734  /* the next token might be another sense, or the word "free" */
1735  if( getNextToken(scip, pipinput) )
1736  {
1737  PIPSENSE rightsense;
1738 
1739  if( isSense(pipinput, &rightsense) )
1740  {
1741  /* check, if the senses fit */
1742  if( leftsense == PIP_SENSE_NOTHING
1743  || (leftsense == PIP_SENSE_LE && rightsense == PIP_SENSE_LE)
1744  || (leftsense == PIP_SENSE_GE && rightsense == PIP_SENSE_GE) )
1745  {
1746  if( !getNextToken(scip, pipinput) )
1747  {
1748  syntaxError(scip, pipinput, "expected value or sign");
1749  return SCIP_OKAY;
1750  }
1751 
1752  /* check if the next token is a sign */
1753  sign = +1;
1754  hassign = isSign(pipinput, &sign);
1755  if( hassign && !getNextToken(scip, pipinput) )
1756  {
1757  syntaxError(scip, pipinput, "expected value");
1758  return SCIP_OKAY;
1759  }
1760 
1761  /* the next token must be a value */
1762  if( !isValue(scip, pipinput, &value) )
1763  {
1764  syntaxError(scip, pipinput, "expected value");
1765  return SCIP_OKAY;
1766  }
1767 
1768  /* update the bound corresponding to the sense */
1769  switch( rightsense )
1770  {
1771  case PIP_SENSE_GE:
1772  lb = sign * value;
1773  break;
1774  case PIP_SENSE_LE:
1775  ub = sign * value;
1776  break;
1777  case PIP_SENSE_EQ:
1778  lb = sign * value;
1779  ub = sign * value;
1780  break;
1781  case PIP_SENSE_NOTHING:
1782  default:
1783  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1784  return SCIP_INVALIDDATA;
1785  }
1786  }
1787  else
1788  {
1789  syntaxError(scip, pipinput, "the two bound senses do not fit");
1790  return SCIP_OKAY;
1791  }
1792  }
1793  else if( strcasecmp(pipinput->token, "FREE") == 0 )
1794  {
1795  if( leftsense != PIP_SENSE_NOTHING )
1796  {
1797  syntaxError(scip, pipinput, "variable with bound is marked as 'free'");
1798  return SCIP_OKAY;
1799  }
1800  lb = -SCIPinfinity(scip);
1801  ub = SCIPinfinity(scip);
1802  }
1803  else
1804  {
1805  /* the token was no sense: push it back to the token stack */
1806  pushToken(pipinput);
1807  }
1808  }
1809 
1810  /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
1811  if ( lb != 0.0 )
1812  SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
1813  /*lint --e{777}*/
1814  if ( ub != SCIPinfinity(scip) )
1815  SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
1816  SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", pipinput->linenumber, SCIPvarGetName(var),
1818  }
1819 
1820  return SCIP_OKAY;
1821 }
1822 
1823 /** reads the generals section */
1824 static
1826  SCIP* scip, /**< SCIP data structure */
1827  PIPINPUT* pipinput /**< PIP reading data */
1828  )
1829 {
1830  assert(pipinput != NULL);
1831 
1832  while( getNextToken(scip, pipinput) )
1833  {
1834  SCIP_VAR* var;
1835  SCIP_Bool created;
1836  SCIP_Bool infeasible;
1837 
1838  /* check if we reached a new section */
1839  if( isNewSection(scip, pipinput) )
1840  return SCIP_OKAY;
1841 
1842  /* the token must be the name of an existing variable */
1843  SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
1844  if( created )
1845  {
1846  syntaxError(scip, pipinput, "unknown variable in generals section");
1847  return SCIP_OKAY;
1848  }
1849 
1850  /* mark the variable to be integral */
1851  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1852  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1853  }
1854 
1855  return SCIP_OKAY;
1856 }
1857 
1858 /** reads the binaries section */
1859 static
1861  SCIP* scip, /**< SCIP data structure */
1862  PIPINPUT* pipinput /**< PIP reading data */
1863  )
1864 {
1865  assert(pipinput != NULL);
1866 
1867  while( getNextToken(scip, pipinput) )
1868  {
1869  SCIP_VAR* var;
1870  SCIP_Bool created;
1871  SCIP_Bool infeasible;
1872 
1873  /* check if we reached a new section */
1874  if( isNewSection(scip, pipinput) )
1875  return SCIP_OKAY;
1876 
1877  /* the token must be the name of an existing variable */
1878  SCIP_CALL( getVariable(scip, pipinput->token, pipinput->dynamiccols, &var, &created) );
1879  if( created )
1880  {
1881  syntaxError(scip, pipinput, "unknown variable in binaries section");
1882  return SCIP_OKAY;
1883  }
1884 
1885  /* mark the variable to be binary and change its bounds appropriately */
1886  if( SCIPvarGetLbGlobal(var) < 0.0 )
1887  {
1888  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1889  }
1890  if( SCIPvarGetUbGlobal(var) > 1.0 )
1891  {
1892  SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1893  }
1894  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1895  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1896  }
1897 
1898  return SCIP_OKAY;
1899 }
1900 
1901 /** reads a PIP file
1902  */
1903 static
1905  SCIP* scip, /**< SCIP data structure */
1906  PIPINPUT* pipinput, /**< PIP reading data */
1907  const char* filename /**< name of the input file */
1908  )
1909 {
1910  assert(pipinput != NULL);
1911 
1912  /* open file */
1913  pipinput->file = SCIPfopen(filename, "r");
1914  if( pipinput->file == NULL )
1915  {
1916  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
1917  SCIPprintSysError(filename);
1918  return SCIP_NOFILE;
1919  }
1920 
1921  /* create problem */
1922  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1923 
1924  /* parse the file */
1925  pipinput->section = PIP_START;
1926  while( pipinput->section != PIP_END && !hasError(pipinput) )
1927  {
1928  switch( pipinput->section )
1929  {
1930  case PIP_START:
1931  SCIP_CALL( readStart(scip, pipinput) );
1932  break;
1933 
1934  case PIP_OBJECTIVE:
1935  SCIP_CALL( readObjective(scip, pipinput) );
1936  break;
1937 
1938  case PIP_CONSTRAINTS:
1939  SCIP_CALL( readConstraints(scip, pipinput) );
1940  break;
1941 
1942  case PIP_BOUNDS:
1943  SCIP_CALL( readBounds(scip, pipinput) );
1944  break;
1945 
1946  case PIP_GENERALS:
1947  SCIP_CALL( readGenerals(scip, pipinput) );
1948  break;
1949 
1950  case PIP_BINARIES:
1951  SCIP_CALL( readBinaries(scip, pipinput) );
1952  break;
1953 
1954  case PIP_END: /* this is already handled in the while() loop */
1955  default:
1956  SCIPerrorMessage("invalid PIP file section <%d>\n", pipinput->section);
1957  return SCIP_INVALIDDATA;
1958  }
1959  }
1960 
1961  /* close file */
1962  SCIPfclose(pipinput->file);
1963 
1964  return SCIP_OKAY;
1965 }
1966 
1967 
1968 /*
1969  * Local methods (for writing)
1970  */
1971 
1972 /** hash key retrieval function for variables */
1973 static
1974 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
1975 { /*lint --e{715}*/
1976  return elem;
1977 }
1978 
1979 /** returns TRUE iff the indices of both variables are equal */
1980 static
1981 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
1982 { /*lint --e{715}*/
1983  if ( key1 == key2 )
1984  return TRUE;
1985  return FALSE;
1986 }
1987 
1988 /** returns the hash value of the key */
1989 static
1990 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
1991 { /*lint --e{715}*/
1992  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
1993  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
1994 }
1995 
1996 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
1997 static
1999  SCIP* scip, /**< SCIP data structure */
2000  SCIP_VAR** vars, /**< vars array to get active variables for */
2001  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
2002  int* nvars, /**< pointer to number of variables and values in vars and vals array */
2003  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
2004  SCIP_Bool transformed /**< transformed constraint? */
2005  )
2006 {
2007  int requiredsize;
2008  int v;
2009 
2010  assert( scip != NULL );
2011  assert( vars != NULL );
2012  assert( scalars != NULL );
2013  assert( nvars != NULL );
2014  assert( constant != NULL );
2015 
2016  if( transformed )
2017  {
2018  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
2019 
2020  if( requiredsize > *nvars )
2021  {
2022  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
2023  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
2024 
2025  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
2026  assert( requiredsize <= *nvars );
2027  }
2028  }
2029  else
2030  {
2031  for( v = 0; v < *nvars; ++v )
2032  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
2033  }
2034  return SCIP_OKAY;
2035 }
2036 
2037 /** clears the given line buffer */
2038 static
2040  char* linebuffer, /**< line */
2041  int* linecnt /**< number of characters in line */
2042  )
2043 {
2044  assert( linebuffer != NULL );
2045  assert( linecnt != NULL );
2046 
2047  (*linecnt) = 0;
2048  linebuffer[0] = '\0';
2049 }
2050 
2051 /** ends the given line with '\\0' and prints it to the given file stream */
2052 static
2053 void endLine(
2054  SCIP* scip, /**< SCIP data structure */
2055  FILE* file, /**< output file (or NULL for standard output) */
2056  char* linebuffer, /**< line */
2057  int* linecnt /**< number of characters in line */
2058  )
2059 {
2060  assert( scip != NULL );
2061  assert( linebuffer != NULL );
2062  assert( linecnt != NULL );
2063 
2064  if( (*linecnt) > 0 )
2065  {
2066  linebuffer[(*linecnt)] = '\0';
2067  SCIPinfoMessage(scip, file, "%s\n", linebuffer);
2068  clearLine(linebuffer, linecnt);
2069  }
2070 }
2071 
2072 /** appends extension to line and prints it to the give file stream if the
2073  * line exceeded the length given in the define PIP_PRINTLEN */
2074 static
2076  SCIP* scip, /**< SCIP data structure */
2077  FILE* file, /**< output file (or NULL for standard output) */
2078  char* linebuffer, /**< line */
2079  int* linecnt, /**< number of characters in line */
2080  const char* extension /**< string to extent the line */
2081  )
2082 {
2083  assert( scip != NULL );
2084  assert( linebuffer != NULL );
2085  assert( linecnt != NULL );
2086  assert( extension != NULL );
2087  assert( strlen(linebuffer) + strlen(extension) < PIP_MAX_PRINTLEN );
2088 
2089  /* NOTE: avoid
2090  * sprintf(linebuffer, "%s%s", linebuffer, extension);
2091  * because of overlapping memory areas in memcpy used in sprintf.
2092  */
2093  (void) strncat(linebuffer, extension, PIP_MAX_PRINTLEN - strlen(linebuffer));
2094 
2095  (*linecnt) += (int) strlen(extension);
2096 
2097  SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
2098 
2099  if( (*linecnt) > PIP_PRINTLEN )
2100  endLine(scip, file, linebuffer, linecnt);
2101 }
2102 
2103 
2104 /* print row in PIP format to file stream */
2105 static
2107  SCIP* scip, /**< SCIP data structure */
2108  FILE* file, /**< output file (or NULL for standard output) */
2109  const char* rowname, /**< row name */
2110  const char* rownameextension, /**< row name extension */
2111  const char* type, /**< row type ("=", "<=", or ">=") */
2112  SCIP_VAR** linvars, /**< array of linear variables */
2113  SCIP_Real* linvals, /**< array of linear coefficient values */
2114  int nlinvars, /**< number of linear variables */
2115  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
2116  int nquadvarterms, /**< number of quadratic variable terms */
2117  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
2118  int nbilinterms, /**< number of bilinear terms */
2119  SCIP_Real rhs /**< right hand side */
2120  )
2121 {
2122  int v;
2123  char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
2124  int linecnt;
2125 
2126  SCIP_VAR* var;
2127  char varname[PIP_MAX_NAMELEN];
2128  char varname2[PIP_MAX_NAMELEN];
2129  char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2130  char buffer[PIP_MAX_PRINTLEN];
2131 
2132  assert( scip != NULL );
2133  assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
2134  assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
2135  assert( nquadvarterms == 0 || quadvarterms != NULL );
2136 
2137  /* if there is a bilinear term, then there need to be at least two quadratic variables */
2138  assert( nbilinterms == 0 || (bilinterms != NULL && nquadvarterms >= 2) );
2139 
2140  clearLine(linebuffer, &linecnt);
2141 
2142  /* start each line with a space */
2143  appendLine(scip, file, linebuffer, &linecnt, " ");
2144 
2145  /* print row name */
2146  if ( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
2147  {
2148  (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
2149  appendLine(scip, file, linebuffer, &linecnt, consname);
2150  }
2151 
2152  /* print coefficients */
2153  for( v = 0; v < nlinvars; ++v )
2154  {
2155  assert(linvars != NULL); /* for lint */
2156  assert(linvals != NULL);
2157 
2158  var = linvars[v];
2159  assert( var != NULL );
2160 
2161  /* we start a new line; therefore we tab this line */
2162  if ( linecnt == 0 )
2163  appendLine(scip, file, linebuffer, &linecnt, " ");
2164 
2165  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2166  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
2167 
2168  appendLine(scip, file, linebuffer, &linecnt, buffer);
2169  }
2170 
2171  /* print quadratic part */
2172  if( nquadvarterms > 0 )
2173  {
2174  /* print linear coefficients of quadratic variables */
2175  for( v = 0; v < nquadvarterms; ++v )
2176  {
2177  assert(quadvarterms != NULL); /* for lint */
2178 
2179  if( quadvarterms[v].lincoef == 0.0 )
2180  continue;
2181 
2182  /* we start a new line; therefore we tab this line */
2183  if (linecnt == 0 )
2184  appendLine(scip, file, linebuffer, &linecnt, " ");
2185 
2186  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(quadvarterms[v].var));
2187  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", quadvarterms[v].lincoef, varname);
2188 
2189  appendLine(scip, file, linebuffer, &linecnt, buffer);
2190  }
2191 
2192  /* start quadratic part */
2193 
2194  /* print square terms */
2195  for( v = 0; v < nquadvarterms; ++v )
2196  {
2197  assert(quadvarterms != NULL); /* for lint */
2198  if( quadvarterms[v].sqrcoef == 0.0 )
2199  continue;
2200 
2201  /* we start a new line; therefore we tab this line */
2202  if (linecnt == 0 )
2203  appendLine(scip, file, linebuffer, &linecnt, " ");
2204 
2205  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(quadvarterms[v].var));
2206  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^2", quadvarterms[v].sqrcoef, varname);
2207 
2208  appendLine(scip, file, linebuffer, &linecnt, buffer);
2209  }
2210 
2211  /* print bilinear terms */
2212  for( v = 0; v < nbilinterms; ++v )
2213  {
2214  /* we start a new line; therefore we tab this line */
2215  if (linecnt == 0 )
2216  appendLine(scip, file, linebuffer, &linecnt, " ");
2217 
2218  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(bilinterms[v].var1));
2219  (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(bilinterms[v].var2));
2220  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s * %s", bilinterms[v].coef, varname, varname2);
2221 
2222  appendLine(scip, file, linebuffer, &linecnt, buffer);
2223  }
2224  }
2225 
2226  /* print right hand side */
2227  if( SCIPisZero(scip, rhs) )
2228  rhs = 0.0;
2229 
2230  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2231 
2232  /* we start a new line; therefore we tab this line */
2233  if (linecnt == 0 )
2234  appendLine(scip, file, linebuffer, &linecnt, " ");
2235  appendLine(scip, file, linebuffer, &linecnt, buffer);
2236 
2237  endLine(scip, file, linebuffer, &linecnt);
2238 }
2239 
2240 
2241 /* print row in PIP format to file stream */
2242 static
2244  SCIP* scip, /**< SCIP data structure */
2245  FILE* file, /**< output file (or NULL for standard output) */
2246  const char* rowname, /**< row name */
2247  const char* rownameextension, /**< row name extension */
2248  const char* type, /**< row type ("=", "<=", or ">=") */
2249  SCIP_VAR** linvars, /**< array of linear variables */
2250  SCIP_Real* linvals, /**< array of linear coefficient values */
2251  int nlinvars, /**< number of linear variables */
2252  SCIP_EXPRTREE** exprtrees, /**< expression trees */
2253  SCIP_Real* exprtreecoefs, /**< coefficients of expression trees */
2254  int nexprtrees, /**< number of expression trees */
2255  SCIP_Real rhs /**< right hand side */
2256  )
2257 {
2258  int v;
2259  int c;
2260  int e;
2261  char linebuffer[PIP_MAX_PRINTLEN+1] = { '\0' };
2262  int linecnt;
2263 
2264  SCIP_VAR* var;
2265  char varname[PIP_MAX_NAMELEN];
2266  char varname2[PIP_MAX_NAMELEN];
2267  char consname[PIP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2268  char buffer[PIP_MAX_PRINTLEN];
2269 
2270  assert( scip != NULL );
2271  assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
2272  assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
2273  assert( nexprtrees == 0 || exprtrees != NULL );
2274  assert( nexprtrees == 0 || exprtreecoefs != NULL );
2275 
2276  clearLine(linebuffer, &linecnt);
2277 
2278  /* start each line with a space */
2279  appendLine(scip, file, linebuffer, &linecnt, " ");
2280 
2281  /* print row name */
2282  if ( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
2283  {
2284  (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
2285  appendLine(scip, file, linebuffer, &linecnt, consname);
2286  }
2287 
2288  /* print coefficients */
2289  for( v = 0; v < nlinvars; ++v )
2290  {
2291  assert(linvars != NULL); /* for lint */
2292  assert(linvals != NULL);
2293 
2294  var = linvars[v];
2295  assert( var != NULL );
2296 
2297  /* we start a new line; therefore we tab this line */
2298  if ( linecnt == 0 )
2299  appendLine(scip, file, linebuffer, &linecnt, " ");
2300 
2301  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2302  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
2303 
2304  appendLine(scip, file, linebuffer, &linecnt, buffer);
2305  }
2306 
2307  /* print nonlinear part */
2308  for( e = 0; e < nexprtrees; ++e )
2309  {
2310  SCIP_VAR** vars;
2311  SCIP_EXPR* expr;
2312  SCIP_EXPR** children;
2313  int nchildren;
2314 
2315  vars = SCIPexprtreeGetVars(exprtrees[e]);
2316  expr = SCIPexprtreeGetRoot(exprtrees[e]);
2317  children = SCIPexprGetChildren(expr);
2318  nchildren = SCIPexprGetNChildren(expr);
2319  assert(nchildren == 0 || children != NULL);
2320 
2321  /* we start a new line; therefore we tab this line */
2322  if( linecnt == 0 )
2323  appendLine(scip, file, linebuffer, &linecnt, " ");
2324 
2325  /* assert that all children of expr correspond to variables */
2326 #ifndef NDEBUG
2327  for( c = 0; c < nchildren; ++c )
2328  {
2329  assert(SCIPexprGetOperator(children[c]) == SCIP_EXPR_VARIDX);
2330  assert(SCIPexprGetOpIndex(children[c]) >= 0);
2331  assert(SCIPexprGetOpIndex(children[c]) < SCIPexprtreeGetNVars(exprtrees[e]));
2332  }
2333 #endif
2334 
2335  switch( SCIPexprGetOperator(expr) )
2336  {
2337  case SCIP_EXPR_CONST:
2338  {
2339  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", exprtreecoefs[e] * SCIPexprGetOpReal(expr));
2340  appendLine(scip, file, linebuffer, &linecnt, buffer);
2341 
2342  break;
2343  }
2344 
2345  case SCIP_EXPR_VARIDX:
2346  {
2347  assert(SCIPexprGetOpIndex(expr) >= 0);
2348  assert(SCIPexprGetOpIndex(expr) < SCIPexprtreeGetNVars(exprtrees[e]));
2349  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(expr)]));
2350  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", exprtreecoefs[e], varname);
2351 
2352  appendLine(scip, file, linebuffer, &linecnt, buffer);
2353  break;
2354  }
2355 
2356  case SCIP_EXPR_PLUS:
2357  {
2358  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2359  (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[1])]));
2360  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s %+.15g %s", exprtreecoefs[e], varname, exprtreecoefs[e], varname2);
2361 
2362  appendLine(scip, file, linebuffer, &linecnt, buffer);
2363  break;
2364  }
2365 
2366  case SCIP_EXPR_MINUS:
2367  {
2368  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2369  (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[1])]));
2370  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s %+.15g %s", exprtreecoefs[e], varname, -exprtreecoefs[e], varname2);
2371 
2372  appendLine(scip, file, linebuffer, &linecnt, buffer);
2373  break;
2374  }
2375 
2376  case SCIP_EXPR_MUL:
2377  {
2378  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2379  (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[1])]));
2380  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s %s", exprtreecoefs[e], varname, varname2);
2381 
2382  appendLine(scip, file, linebuffer, &linecnt, buffer);
2383  break;
2384  }
2385 
2386  case SCIP_EXPR_SQUARE:
2387  {
2388  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2389  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^2", exprtreecoefs[e], varname);
2390 
2391  appendLine(scip, file, linebuffer, &linecnt, buffer);
2392  break;
2393  }
2394 
2395  case SCIP_EXPR_SQRT:
2396  {
2397  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2398  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^0.5", exprtreecoefs[e], varname);
2399 
2400  appendLine(scip, file, linebuffer, &linecnt, buffer);
2401  break;
2402  }
2403 
2404  case SCIP_EXPR_INTPOWER:
2405  {
2406  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2407  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^%d", exprtreecoefs[e], varname, SCIPexprGetIntPowerExponent(expr));
2408 
2409  appendLine(scip, file, linebuffer, &linecnt, buffer);
2410  break;
2411  }
2412 
2413  case SCIP_EXPR_REALPOWER:
2414  {
2415  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[0])]));
2416  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^%.15g", exprtreecoefs[e], varname, SCIPexprGetRealPowerExponent(expr));
2417 
2418  appendLine(scip, file, linebuffer, &linecnt, buffer);
2419  break;
2420  }
2421 
2422  case SCIP_EXPR_SUM:
2423  {
2424  for( c = 0; c < nchildren; ++c )
2425  {
2426  /* we start a new line; therefore we tab this line */
2427  if( linecnt == 0 )
2428  appendLine(scip, file, linebuffer, &linecnt, " ");
2429 
2430  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[c])]));
2431  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", exprtreecoefs[e], varname);
2432 
2433  appendLine(scip, file, linebuffer, &linecnt, buffer);
2434  }
2435 
2436  break;
2437  }
2438 
2439  case SCIP_EXPR_PRODUCT:
2440  {
2441  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", exprtreecoefs[e]);
2442  appendLine(scip, file, linebuffer, &linecnt, buffer);
2443 
2444  for( c = 0; c < nchildren; ++c )
2445  {
2446  /* we start a new line; therefore we tab this line */
2447  if( linecnt == 0 )
2448  appendLine(scip, file, linebuffer, &linecnt, " ");
2449 
2450  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, " %s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[c])]));
2451  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, varname);
2452 
2453  appendLine(scip, file, linebuffer, &linecnt, buffer);
2454  }
2455 
2456  break;
2457  }
2458 
2459  case SCIP_EXPR_LINEAR:
2460  {
2461  if( SCIPexprGetLinearConstant(expr) != 0.0 )
2462  {
2463  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g ", exprtreecoefs[e] * SCIPexprGetLinearConstant(expr));
2464  appendLine(scip, file, linebuffer, &linecnt, buffer);
2465  }
2466 
2467  for( c = 0; c < nchildren; ++c )
2468  {
2469  /* we start a new line; therefore we tab this line */
2470  if( linecnt == 0 )
2471  appendLine(scip, file, linebuffer, &linecnt, " ");
2472 
2473  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[c])]));
2474  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", exprtreecoefs[e] * SCIPexprGetLinearCoefs(expr)[c], varname);
2475 
2476  appendLine(scip, file, linebuffer, &linecnt, buffer);
2477  }
2478 
2479  break;
2480  }
2481 
2482  case SCIP_EXPR_QUADRATIC:
2483  {
2484  int q;
2485 
2486  if( SCIPexprGetQuadConstant(expr) != 0.0 )
2487  {
2488  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g ", exprtreecoefs[e] * SCIPexprGetQuadConstant(expr));
2489  appendLine(scip, file, linebuffer, &linecnt, buffer);
2490  }
2491 
2492  if( SCIPexprGetQuadLinearCoefs(expr) != NULL )
2493  {
2494  for( c = 0; c < nchildren; ++c )
2495  {
2496  if( SCIPexprGetQuadLinearCoefs(expr)[c] == 0.0 )
2497  continue;
2498 
2499  /* we start a new line; therefore we tab this line */
2500  if( linecnt == 0 )
2501  appendLine(scip, file, linebuffer, &linecnt, " ");
2502 
2503  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[c])]));
2504  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", exprtreecoefs[e] * SCIPexprGetQuadLinearCoefs(expr)[c], varname);
2505 
2506  appendLine(scip, file, linebuffer, &linecnt, buffer);
2507  }
2508  }
2509 
2510  for( q = 0; q < SCIPexprGetNQuadElements(expr); ++q )
2511  {
2512  /* we start a new line; therefore we tab this line */
2513  if( linecnt == 0 )
2514  appendLine(scip, file, linebuffer, &linecnt, " ");
2515 
2516  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[SCIPexprGetQuadElements(expr)[q].idx1])]));
2517 
2518  if( SCIPexprGetQuadElements(expr)[q].idx1 == SCIPexprGetQuadElements(expr)[q].idx2 )
2519  {
2520  /* square term */
2521  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s^2", exprtreecoefs[e] * SCIPexprGetQuadElements(expr)[q].coef, varname);
2522  }
2523  else
2524  {
2525  /* bilinear term */
2526  (void) SCIPsnprintf(varname2, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[SCIPexprGetQuadElements(expr)[q].idx2])]));
2527  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s %s", exprtreecoefs[e] * SCIPexprGetQuadElements(expr)[q].coef, varname, varname2);
2528  }
2529 
2530  appendLine(scip, file, linebuffer, &linecnt, buffer);
2531  }
2532 
2533  break;
2534  }
2535 
2536  case SCIP_EXPR_POLYNOMIAL:
2537  {
2538  SCIP_EXPRDATA_MONOMIAL* monomial;
2539  int m;
2540  int f;
2541 
2542  if( SCIPexprGetPolynomialConstant(expr) != 0.0 )
2543  {
2544  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g ", exprtreecoefs[e] * SCIPexprGetPolynomialConstant(expr));
2545  appendLine(scip, file, linebuffer, &linecnt, buffer);
2546  }
2547 
2548  for( m = 0; m < SCIPexprGetNMonomials(expr); ++m )
2549  {
2550  monomial = SCIPexprGetMonomials(expr)[m];
2551  assert(monomial != NULL);
2552 
2553  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g", exprtreecoefs[e] * SCIPexprGetMonomialCoef(monomial));
2554  appendLine(scip, file, linebuffer, &linecnt, buffer);
2555 
2556  for( f = 0; f < SCIPexprGetMonomialNFactors(monomial); ++f )
2557  {
2558  /* we start a new line; therefore we tab this line */
2559  if( linecnt == 0 )
2560  appendLine(scip, file, linebuffer, &linecnt, " ");
2561 
2562  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[SCIPexprGetOpIndex(children[SCIPexprGetMonomialChildIndices(monomial)[f]])]));
2563  if( SCIPexprGetMonomialExponents(monomial)[f] != 1.0 )
2564  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s^%.15g", varname, SCIPexprGetMonomialExponents(monomial)[f]);
2565  else
2566  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
2567  appendLine(scip, file, linebuffer, &linecnt, buffer);
2568  }
2569  }
2570 
2571  break;
2572  }
2573 
2574  default:
2575  {
2576  /* this should have been caught in SCIPwritePip before */
2577  SCIPerrorMessage("unsupported operator <%s> in writing of polynomial nonlinear constraint\n", SCIPexpropGetName(SCIPexprGetOperator(expr)));
2578  return;
2579  } /*lint !e788*/
2580  } /*lint !e788*/
2581  }
2582 
2583  /* print right hand side */
2584  if( SCIPisZero(scip, rhs) )
2585  rhs = 0.0;
2586 
2587  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2588 
2589  /* we start a new line; therefore we tab this line */
2590  if (linecnt == 0 )
2591  appendLine(scip, file, linebuffer, &linecnt, " ");
2592  appendLine(scip, file, linebuffer, &linecnt, buffer);
2593 
2594  endLine(scip, file, linebuffer, &linecnt);
2595 }
2596 
2597 
2598 /** prints given (linear or) quadratic constraint information in LP format to file stream */
2599 static
2601  SCIP* scip, /**< SCIP data structure */
2602  FILE* file, /**< output file (or NULL for standard output) */
2603  const char* rowname, /**< name of the row */
2604  SCIP_VAR** linvars, /**< array of linear variables */
2605  SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
2606  int nlinvars, /**< number of linear variables */
2607  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
2608  int nquadvarterms, /**< number of quadratic variable terms */
2609  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
2610  int nbilinterms, /**< number of bilinear terms */
2611  SCIP_Real lhs, /**< left hand side */
2612  SCIP_Real rhs, /**< right hand side */
2613  SCIP_Bool transformed /**< transformed constraint? */
2614  )
2615 {
2616  int v;
2617  SCIP_VAR** activevars = NULL;
2618  SCIP_Real* activevals = NULL;
2619  int nactivevars;
2620  SCIP_Real activeconstant = 0.0;
2621 
2622  assert( scip != NULL );
2623  assert( rowname != NULL );
2624 
2625  assert( nlinvars == 0 || linvars != NULL );
2626  assert( nquadvarterms == 0 || quadvarterms != NULL );
2627  assert( nbilinterms == 0 || bilinterms != NULL );
2628 
2629  assert( lhs <= rhs );
2630 
2631  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2632  return SCIP_OKAY;
2633 
2634  nactivevars = nlinvars;
2635  if( nlinvars > 0 )
2636  {
2637  /* duplicate variable and value array */
2638  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
2639  if( linvals != NULL )
2640  {
2641  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
2642  }
2643  else
2644  {
2645  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2646 
2647  for( v = 0; v < nactivevars; ++v )
2648  activevals[v] = 1.0;
2649  }
2650 
2651  /* retransform given variables to active variables */
2652  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2653  }
2654 
2655  /* print row(s) in LP format */
2656  if( SCIPisEQ(scip, lhs, rhs) )
2657  {
2658  assert( !SCIPisInfinity(scip, rhs) );
2659 
2660  /* equal constraint */
2661  printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars,
2662  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2663  rhs - activeconstant);
2664  }
2665  else
2666  {
2667  if( !SCIPisInfinity(scip, -lhs) )
2668  {
2669  /* print inequality ">=" */
2670  printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=",
2671  activevars, activevals, nactivevars,
2672  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2673  lhs - activeconstant);
2674  }
2675  if( !SCIPisInfinity(scip, rhs) )
2676  {
2677  /* print inequality "<=" */
2678  printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=",
2679  activevars, activevals, nactivevars,
2680  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2681  rhs - activeconstant);
2682  }
2683  }
2684 
2685  if( nlinvars > 0 )
2686  {
2687  /* free buffer arrays */
2688  SCIPfreeBufferArray(scip, &activevars);
2689  SCIPfreeBufferArray(scip, &activevals);
2690  }
2691 
2692  return SCIP_OKAY;
2693 }
2694 
2695 /** prints given nonlinear constraint information in LP format to file stream */
2696 static
2698  SCIP* scip, /**< SCIP data structure */
2699  FILE* file, /**< output file (or NULL for standard output) */
2700  const char* rowname, /**< name of the row */
2701  SCIP_VAR** linvars, /**< array of linear variables */
2702  SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
2703  int nlinvars, /**< number of linear variables */
2704  SCIP_EXPRTREE** exprtrees, /**< expression trees */
2705  SCIP_Real* exprtreecoefs, /**< coefficients of expression trees */
2706  int nexprtrees, /**< number of expression trees */
2707  SCIP_Real lhs, /**< left hand side */
2708  SCIP_Real rhs, /**< right hand side */
2709  SCIP_Bool transformed /**< transformed constraint? */
2710  )
2711 {
2712  int v;
2713  SCIP_VAR** activevars = NULL;
2714  SCIP_Real* activevals = NULL;
2715  int nactivevars;
2716  SCIP_Real activeconstant = 0.0;
2717 
2718  assert( scip != NULL );
2719  assert( rowname != NULL );
2720 
2721  assert( nlinvars == 0 || linvars != NULL );
2722  assert( nexprtrees == 0 || exprtrees != NULL );
2723  assert( nexprtrees == 0 || exprtreecoefs != NULL );
2724 
2725  assert( lhs <= rhs );
2726 
2727  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2728  return SCIP_OKAY;
2729 
2730  nactivevars = nlinvars;
2731  if( nlinvars > 0 )
2732  {
2733  /* duplicate variable and value array */
2734  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
2735  if( linvals != NULL )
2736  {
2737  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
2738  }
2739  else
2740  {
2741  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2742 
2743  for( v = 0; v < nactivevars; ++v )
2744  activevals[v] = 1.0;
2745  }
2746 
2747  /* retransform given variables to active variables */
2748  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2749  }
2750 
2751  /* print row(s) in LP format */
2752  if( SCIPisEQ(scip, lhs, rhs) )
2753  {
2754  assert( !SCIPisInfinity(scip, rhs) );
2755 
2756  /* equal constraint */
2757  printRowNl(scip, file, rowname, "", "=", activevars, activevals, nactivevars,
2758  exprtrees, exprtreecoefs, nexprtrees,
2759  rhs - activeconstant);
2760  }
2761  else
2762  {
2763  if( !SCIPisInfinity(scip, -lhs) )
2764  {
2765  /* print inequality ">=" */
2766  printRowNl(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=",
2767  activevars, activevals, nactivevars,
2768  exprtrees, exprtreecoefs, nexprtrees,
2769  lhs - activeconstant);
2770  }
2771  if( !SCIPisInfinity(scip, rhs) )
2772  {
2773  /* print inequality "<=" */
2774  printRowNl(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=",
2775  activevars, activevals, nactivevars,
2776  exprtrees, exprtreecoefs, nexprtrees,
2777  rhs - activeconstant);
2778  }
2779  }
2780 
2781  if( nlinvars > 0 )
2782  {
2783  /* free buffer arrays */
2784  SCIPfreeBufferArray(scip, &activevars);
2785  SCIPfreeBufferArray(scip, &activevals);
2786  }
2787 
2788  return SCIP_OKAY;
2789 }
2790 
2791 /** check whether given variables are aggregated and put them into an array without duplication */
2792 static
2794  int nvars, /**< number of active variables in the problem */
2795  SCIP_VAR** vars, /**< variable array */
2796  int* nAggregatedVars, /**< number of aggregated variables on output */
2797  SCIP_VAR*** aggregatedVars, /**< array storing the aggregated variables on output */
2798  SCIP_HASHTABLE** varAggregated /**< hashtable for checking duplicates */
2799  )
2800 {
2801  int j;
2802 
2803  /* check variables */
2804  for (j = 0; j < nvars; ++j)
2805  {
2806  SCIP_VARSTATUS status;
2807  SCIP_VAR* var;
2808 
2809  var = vars[j];
2810  status = SCIPvarGetStatus(var);
2811 
2812  /* collect aggregated variables in a list */
2813  if( status >= SCIP_VARSTATUS_AGGREGATED )
2814  {
2815  assert( status == SCIP_VARSTATUS_AGGREGATED ||
2816  status == SCIP_VARSTATUS_MULTAGGR ||
2817  status == SCIP_VARSTATUS_NEGATED );
2818 
2819  if ( ! SCIPhashtableExists(*varAggregated, (void*) var) )
2820  {
2821  (*aggregatedVars)[(*nAggregatedVars)++] = var;
2822  SCIP_CALL( SCIPhashtableInsert(*varAggregated, (void*) var) );
2823  }
2824  }
2825  }
2826 
2827  return SCIP_OKAY;
2828 }
2829 
2830 
2831 /** print aggregated variable-constraints */
2832 static
2834  SCIP* scip, /**< SCIP data structure */
2835  FILE* file, /**< output file (or NULL for standard output) */
2836  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
2837  int nvars, /**< number of active variables in the problem */
2838  int nAggregatedVars, /**< number of aggregated variables */
2839  SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
2840  )
2841 {
2842  int j;
2843 
2844  SCIP_VAR** activevars;
2845  SCIP_Real* activevals;
2846  int nactivevars;
2847  SCIP_Real activeconstant = 0.0;
2848  char consname[PIP_MAX_NAMELEN];
2849 
2850  assert( scip != NULL );
2851 
2852  /* write aggregation constraints */
2853  SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
2854  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
2855 
2856  for (j = 0; j < nAggregatedVars; ++j)
2857  {
2858  /* set up list to obtain substitution variables */
2859  nactivevars = 1;
2860 
2861  activevars[0] = aggregatedVars[j];
2862  activevals[0] = 1.0;
2863  activeconstant = 0.0;
2864 
2865  /* retransform given variables to active variables */
2866  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2867 
2868  activevals[nactivevars] = -1.0;
2869  activevars[nactivevars] = aggregatedVars[j];
2870  ++nactivevars;
2871 
2872  /* output constraint */
2873  (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
2874  printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, 0, NULL, 0, - activeconstant);
2875  }
2876 
2877  /* free buffer arrays */
2878  SCIPfreeBufferArray(scip, &activevars);
2879  SCIPfreeBufferArray(scip, &activevals);
2880 
2881  return SCIP_OKAY;
2882 }
2883 
2884 /** method check if the variable names are not longer than PIP_MAX_NAMELEN */
2885 static
2887  SCIP* scip, /**< SCIP data structure */
2888  SCIP_VAR** vars, /**< array of variables */
2889  int nvars /**< number of variables */
2890  )
2891 {
2892  int v;
2893 
2894  assert(scip != NULL);
2895  assert(vars != NULL || nvars == 0);
2896 
2897  /* check if the variable names are not to long */
2898  for( v = 0; v < nvars; ++v )
2899  {
2900  if( strlen(SCIPvarGetName(vars[v])) > PIP_MAX_NAMELEN ) /*lint !e613*/
2901  {
2902  SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; LP might be corrupted\n",
2903  PIP_MAX_NAMELEN - 1);
2904  return;
2905  }
2906  }
2907 }
2908 
2909 /** method check if the constraint names are not longer than PIP_MAX_NAMELEN */
2910 static
2912  SCIP* scip, /**< SCIP data structure */
2913  SCIP_CONS** conss, /**< array of constraints */
2914  int nconss, /**< number of constraints */
2915  SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
2916  )
2917 {
2918  int c;
2919  SCIP_CONS* cons;
2920  SCIP_CONSHDLR* conshdlr;
2921  const char* conshdlrname;
2922 
2923  assert( scip != NULL );
2924  assert( conss != NULL );
2925 
2926  for( c = 0; c < nconss; ++c )
2927  {
2928  cons = conss[c];
2929  assert(cons != NULL );
2930 
2931  /* in case the transformed is written only constraints are posted which are enabled in the current node */
2932  assert(!transformed || SCIPconsIsEnabled(cons));
2933 
2934  conshdlr = SCIPconsGetHdlr(cons);
2935  assert( conshdlr != NULL );
2936 
2937  conshdlrname = SCIPconshdlrGetName(conshdlr);
2938  assert( transformed == SCIPconsIsTransformed(cons) );
2939 
2940  if( strcmp(conshdlrname, "linear") == 0 )
2941  {
2942  SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
2943  SCIP_Real rhs = SCIPgetLhsLinear(scip, cons);
2944 
2945  if( (SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > PIP_MAX_NAMELEN)
2946  || ( !SCIPisEQ(scip, lhs, rhs) && strlen(SCIPconsGetName(conss[c])) > PIP_MAX_NAMELEN - 4) )
2947  {
2948  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
2949  PIP_MAX_NAMELEN - 1);
2950  return;
2951  }
2952  }
2953  else if( strlen(SCIPconsGetName(conss[c])) > PIP_MAX_NAMELEN )
2954  {
2955  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n",
2956  PIP_MAX_NAMELEN - 1);
2957  return;
2958  }
2959  }
2960 }
2961 
2962 /** writes problem to file
2963  * @todo add writing cons_pseudoboolean
2964  */
2966  SCIP* scip, /**< SCIP data structure */
2967  FILE* file, /**< output file, or NULL if standard output should be used */
2968  const char* name, /**< problem name */
2969  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
2970  SCIP_OBJSENSE objsense, /**< objective sense */
2971  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
2972  * extobj = objsense * objscale * (intobj + objoffset) */
2973  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
2974  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
2975  int nvars, /**< number of active variables in the problem */
2976  int nbinvars, /**< number of binary variables */
2977  int nintvars, /**< number of general integer variables */
2978  int nimplvars, /**< number of implicit integer variables */
2979  int ncontvars, /**< number of continuous variables */
2980  SCIP_CONS** conss, /**< array with constraints of the problem */
2981  int nconss, /**< number of constraints in the problem */
2982  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
2983  )
2984 {
2985  int c;
2986  int v;
2987  int e;
2988 
2989  int linecnt;
2990  char linebuffer[PIP_MAX_PRINTLEN+1];
2991 
2992  char varname[PIP_MAX_NAMELEN];
2993  char buffer[PIP_MAX_PRINTLEN];
2994 
2995  SCIP_CONSHDLR* conshdlr;
2996  const char* conshdlrname;
2997  SCIP_CONS* cons;
2998  SCIP_CONS** consQuadratic;
2999  int nConsQuadratic;
3000  SCIP_CONS** consNonlinear;
3001  int nConsNonlinear;
3002  SCIP_CONS** consAbspower;
3003  int nConsAbspower;
3004  SCIP_CONS** consAnd;
3005  int nConsAnd;
3006  SCIP_CONS** consBivariate;
3007  int nConsBivariate;
3008  char consname[PIP_MAX_NAMELEN];
3009 
3010  SCIP_VAR** aggregatedVars;
3011  int nAggregatedVars;
3012  SCIP_HASHTABLE* varAggregated;
3013 
3014  SCIP_VAR** consvars;
3015  SCIP_Real* consvals;
3016  int nconsvars;
3017 
3018  SCIP_VAR* var;
3019  SCIP_Real lb;
3020  SCIP_Real ub;
3021 
3022  SCIP_EXPRTREE* exprtree;
3023  SCIP_EXPR* expr;
3024 
3025  assert( scip != NULL );
3026 
3027  nAggregatedVars = 0;
3028  nConsQuadratic = 0;
3029  nConsNonlinear = 0;
3030  nConsAbspower = 0;
3031  nConsAnd = 0;
3032  nConsBivariate = 0;
3033 
3034  /* check if the variable names are not to long */
3035  checkVarnames(scip, vars, nvars);
3036 
3037  /* check if the constraint names are to long */
3038  checkConsnames(scip, conss, nconss, transformed);
3039 
3040  /* print statistics as comment to file */
3041  SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
3042  SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
3043  SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
3044  nvars, nbinvars, nintvars, nimplvars, ncontvars);
3045  SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
3046  SCIPinfoMessage(scip, file, "\\ Obj. scale : %.15g\n", objscale);
3047  SCIPinfoMessage(scip, file, "\\ Obj. offset : %.15g\n", objoffset);
3048 
3049  /* print objective sense */
3050  SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
3051 
3052  clearLine(linebuffer, &linecnt);
3053  appendLine(scip, file, linebuffer, &linecnt, " Obj:");
3054 
3055  for (v = 0; v < nvars; ++v)
3056  {
3057  var = vars[v];
3058 
3059 #ifndef NDEBUG
3060  /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
3061  if ( !transformed )
3063 #endif
3064 
3065  if ( SCIPisZero(scip, SCIPvarGetObj(var)) )
3066  continue;
3067 
3068  /* we start a new line; therefore we tab this line */
3069  if ( linecnt == 0 )
3070  appendLine(scip, file, linebuffer, &linecnt, " ");
3071 
3072  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
3073  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %+.15g %s", SCIPvarGetObj(var), varname );
3074 
3075  appendLine(scip, file, linebuffer, &linecnt, buffer);
3076  }
3077 
3078  endLine(scip, file, linebuffer, &linecnt);
3079 
3080  /* print "Subject to" section */
3081  SCIPinfoMessage(scip, file, "Subject to\n");
3082 
3083  /* collect quadratic, nonlinear, absolute power, and, and bivariate constraints in arrays */
3084  SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3085  SCIP_CALL( SCIPallocBufferArray(scip, &consNonlinear, nconss) );
3086  SCIP_CALL( SCIPallocBufferArray(scip, &consAbspower, nconss) );
3087  SCIP_CALL( SCIPallocBufferArray(scip, &consAnd, nconss) );
3088  SCIP_CALL( SCIPallocBufferArray(scip, &consBivariate, nconss) );
3089 
3090  for (c = 0; c < nconss; ++c)
3091  {
3092  cons = conss[c];
3093  assert( cons != NULL);
3094 
3095  /* in case the transformed is written only constraints are posted which are enabled in the current node */
3096  assert(!transformed || SCIPconsIsEnabled(cons));
3097 
3098  conshdlr = SCIPconsGetHdlr(cons);
3099  assert( conshdlr != NULL );
3100 
3101  (void) SCIPsnprintf(consname, PIP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
3102  conshdlrname = SCIPconshdlrGetName(conshdlr);
3103  assert( transformed == SCIPconsIsTransformed(cons) );
3104 
3105  if( strcmp(conshdlrname, "linear") == 0 )
3106  {
3107  SCIP_CALL( printQuadraticCons(scip, file, consname,
3108  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3109  NULL, 0, NULL, 0, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
3110  }
3111  else if( strcmp(conshdlrname, "setppc") == 0 )
3112  {
3113  consvars = SCIPgetVarsSetppc(scip, cons);
3114  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3115 
3116  switch( SCIPgetTypeSetppc(scip, cons) )
3117  {
3119  SCIP_CALL( printQuadraticCons(scip, file, consname,
3120  consvars, NULL, nconsvars, NULL, 0, NULL, 0, 1.0, 1.0, transformed) );
3121  break;
3123  SCIP_CALL( printQuadraticCons(scip, file, consname,
3124  consvars, NULL, nconsvars, NULL, 0, NULL, 0, -SCIPinfinity(scip), 1.0, transformed) );
3125  break;
3127  SCIP_CALL( printQuadraticCons(scip, file, consname,
3128  consvars, NULL, nconsvars, NULL, 0, NULL, 0, 1.0, SCIPinfinity(scip), transformed) );
3129  break;
3130  }
3131  }
3132  else if ( strcmp(conshdlrname, "logicor") == 0 )
3133  {
3134  SCIP_CALL( printQuadraticCons(scip, file, consname,
3135  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3136  NULL, 0, NULL, 0, 1.0, SCIPinfinity(scip), transformed) );
3137  }
3138  else if ( strcmp(conshdlrname, "knapsack") == 0 )
3139  {
3140  SCIP_Longint* weights;
3141 
3142  consvars = SCIPgetVarsKnapsack(scip, cons);
3143  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3144 
3145  /* copy Longint array to SCIP_Real array */
3146  weights = SCIPgetWeightsKnapsack(scip, cons);
3147  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3148  for( v = 0; v < nconsvars; ++v )
3149  consvals[v] = (SCIP_Real)weights[v];
3150 
3151  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
3152  NULL, 0, NULL, 0, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
3153 
3154  SCIPfreeBufferArray(scip, &consvals);
3155  }
3156  else if ( strcmp(conshdlrname, "varbound") == 0 )
3157  {
3158  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3159  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3160 
3161  consvars[0] = SCIPgetVarVarbound(scip, cons);
3162  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3163 
3164  consvals[0] = 1.0;
3165  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3166 
3167  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL, 0, NULL, 0,
3168  SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
3169 
3170  SCIPfreeBufferArray(scip, &consvars);
3171  SCIPfreeBufferArray(scip, &consvals);
3172  }
3173  else if( strcmp(conshdlrname, "quadratic") == 0 )
3174  {
3175  SCIP_CALL( printQuadraticCons(scip, file, consname,
3179  SCIPgetNBilinTermsQuadratic(scip, cons), SCIPgetLhsQuadratic(scip, cons),
3180  SCIPgetRhsQuadratic(scip, cons), transformed) );
3181 
3182  consQuadratic[nConsQuadratic++] = cons;
3183  }
3184  else if( strcmp(conshdlrname, "nonlinear") == 0 )
3185  {
3186  SCIP_Bool ispolynomial;
3187  int nexprtrees = SCIPgetNExprtreesNonlinear(scip, cons);
3188 
3189  /* check whether expressions are polynomials (assumed simplified exprtrees) */
3190  ispolynomial = TRUE;
3191  for( e = 0; e < nexprtrees && ispolynomial; ++e )
3192  {
3193  exprtree = SCIPgetExprtreesNonlinear(scip, cons)[e];
3194  expr = SCIPexprtreeGetRoot(exprtree);
3195  assert(expr != NULL);
3196 
3197  /* check if operator is something polynomial */
3198  switch( SCIPexprGetOperator(expr) )
3199  {
3200  case SCIP_EXPR_CONST:
3201  case SCIP_EXPR_VARIDX:
3202  case SCIP_EXPR_PLUS:
3203  case SCIP_EXPR_MINUS:
3204  case SCIP_EXPR_MUL:
3205  case SCIP_EXPR_SQUARE:
3206  case SCIP_EXPR_SQRT:
3207  case SCIP_EXPR_SUM:
3208  case SCIP_EXPR_PRODUCT:
3209  case SCIP_EXPR_LINEAR:
3210  case SCIP_EXPR_QUADRATIC:
3211  break;
3212 
3213  case SCIP_EXPR_INTPOWER:
3214  {
3215  if( SCIPexprGetIntPowerExponent(expr) < 0 )
3216  {
3217  SCIPwarningMessage(scip, "negative exponent %d in intpower in %dth expression tree of constraint <%s> cannot be written in pip format\n", SCIPexprGetIntPowerExponent(expr), e, SCIPconsGetName(cons));
3218  ispolynomial = FALSE;
3219  }
3220 
3221  break;
3222  }
3223 
3224  case SCIP_EXPR_REALPOWER:
3225  {
3226  if( SCIPexprGetRealPowerExponent(expr) < 0.0 )
3227  {
3228  SCIPwarningMessage(scip, "negative exponent %g in realpower in %dth expression tree of constraint <%s> cannot be written in pip format\n", SCIPexprGetRealPowerExponent(expr), e, SCIPconsGetName(cons));
3229  ispolynomial = FALSE;
3230  }
3231 
3232  break;
3233  }
3234 
3235  case SCIP_EXPR_POLYNOMIAL:
3236  {
3237  SCIP_EXPRDATA_MONOMIAL* monomial;
3238  int m;
3239  int f;
3240 
3241  for( m = 0; m < SCIPexprGetNMonomials(expr) && ispolynomial; ++m )
3242  {
3243  monomial = SCIPexprGetMonomials(expr)[m];
3244  for( f = 0; f < SCIPexprGetMonomialNFactors(monomial); ++f )
3245  {
3246  if( SCIPexprGetMonomialExponents(monomial)[f] < 0.0 )
3247  {
3248  SCIPwarningMessage(scip, "negative exponent %g in polynomial in %dth expression tree of constraint <%s> cannot be written in pip format\n", SCIPexprGetMonomialExponents(monomial)[f], e, SCIPconsGetName(cons));
3249  ispolynomial = FALSE;
3250  break;
3251  }
3252  }
3253  }
3254 
3255  break;
3256  }
3257 
3258  default:
3259  SCIPwarningMessage(scip, "expression operand <%s> in %dth expression tree of constraint <%s> cannot be written in pip format\n", SCIPexpropGetName(SCIPexprGetOperator(expr)), e, SCIPconsGetName(cons));
3260  ispolynomial = FALSE;
3261  break;
3262  } /*lint !e788*/
3263 
3264  /* check if all children of root expression correspond to variables */
3265  for( v = 0; v < SCIPexprGetNChildren(expr) && ispolynomial; ++v )
3266  {
3268  {
3269  SCIPwarningMessage(scip, "%dth expression tree of constraint <%s> is not simplified, cannot write in pip format\n", e, SCIPconsGetName(cons));
3270  ispolynomial = FALSE;
3271  }
3272  }
3273  }
3274 
3275  if( ispolynomial )
3276  {
3277  SCIP_CALL( printNonlinearCons(scip, file, consname,
3279  SCIPgetNLinearVarsNonlinear(scip, cons), SCIPgetExprtreesNonlinear(scip, cons),
3281  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons), transformed) );
3282 
3283  consNonlinear[nConsNonlinear++] = cons;
3284  }
3285  else
3286  {
3287  SCIPinfoMessage(scip, file, "\\ ");
3288  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3289  SCIPinfoMessage(scip, file, ";\n");
3290  }
3291  }
3292  else if( strcmp(conshdlrname, "abspower") == 0 )
3293  {
3294  SCIP_VAR* x;
3295  SCIP_Real xoffset;
3296  SCIP_Real exponent;
3297  SCIP_Real treecoef;
3298 
3299  expr = NULL;
3300  treecoef = 1.0;
3301 
3302  x = SCIPgetNonlinearVarAbspower(scip, cons);
3303  xoffset = SCIPgetOffsetAbspower(scip, cons);
3304  exponent = SCIPgetExponentAbspower(scip, cons);
3305 
3306  /* see if we formulate signpower(x+offset,exponent) as usual polynomial */
3307  if( !SCIPisZero(scip, xoffset) )
3308  {
3309  SCIPwarningMessage(scip, "nonzero offset for nonlinear variable in constraint <%s>, cannot write in pip format\n", SCIPconsGetName(cons));
3310  }
3311  if( SCIPisIntegral(scip, exponent) && ((int)SCIPround(scip, exponent) % 2 == 1) )
3312  {
3313  /* exponent is odd integer, so signpower(x,exponent) = x^exponent */
3314  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_VARIDX, 0) );
3315  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_INTPOWER, expr, (int)SCIPround(scip, exponent)) );
3316  }
3317  else if( SCIPisIntegral(scip, exponent) && ((int)SCIPround(scip, exponent) % 2 == 0) && !SCIPisPositive(scip, SCIPvarGetUbGlobal(x)) )
3318  {
3319  /* exponent is even integer and x is negative, so signpower(x,exponent) = -x^exponent */
3320  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_VARIDX, 0) );
3321  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_INTPOWER, expr, (int)SCIPround(scip, exponent)) );
3322  treecoef = -1.0;
3323  }
3324  else if( !SCIPisNegative(scip, SCIPvarGetLbGlobal(x)) )
3325  {
3326  /* x is positive, so signpower(x,exponent) = x^exponent */
3327  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_VARIDX, 0) );
3328  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_REALPOWER, expr, exponent) );
3329  }
3330  else
3331  {
3332  SCIPwarningMessage(scip, "cannot formulate signpower(<%s>, %g) in constraint <%s> as polynomial, cannot write in pip format\n", SCIPvarGetName(x), exponent, SCIPconsGetName(cons));
3333  }
3334 
3335  if( expr != NULL )
3336  {
3337  SCIP_VAR* z;
3338  SCIP_Real zcoef;
3339 
3340  SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(scip), &exprtree, expr, 1, 0, NULL) );
3341  SCIP_CALL( SCIPexprtreeSetVars(exprtree, 1, &x) );
3342 
3343  z = SCIPgetLinearVarAbspower(scip, cons);
3344  zcoef = SCIPgetCoefLinearAbspower(scip, cons);
3345 
3346  SCIP_CALL( printNonlinearCons(scip, file, consname,
3347  &z, &zcoef, 1, &exprtree, &treecoef, 1,
3348  SCIPgetLhsAbspower(scip, cons), SCIPgetRhsAbspower(scip, cons), transformed) );
3349 
3350  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
3351 
3352  consAbspower[nConsAbspower++] = cons;
3353  }
3354  else
3355  {
3356  SCIPinfoMessage(scip, file, "\\ ");
3357  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3358  SCIPinfoMessage(scip, file, ";\n");
3359  }
3360  }
3361  else if( strcmp(conshdlrname, "bivariate") == 0 )
3362  {
3363  SCIP_Bool ispolynomial;
3364 
3365  /* check whether expression is polynomial (simplified exprtree assumed) */
3366  ispolynomial = TRUE;
3367  exprtree = SCIPgetExprtreeBivariate(scip, cons);
3368  expr = SCIPexprtreeGetRoot(exprtree);
3369  assert(expr != NULL);
3370 
3371  /* check if operator is something polynomial */
3372  switch( SCIPexprGetOperator(expr) )
3373  {
3374  case SCIP_EXPR_CONST:
3375  case SCIP_EXPR_VARIDX:
3376  case SCIP_EXPR_PLUS:
3377  case SCIP_EXPR_MINUS:
3378  case SCIP_EXPR_MUL:
3379  case SCIP_EXPR_SQUARE:
3380  case SCIP_EXPR_SQRT:
3381  case SCIP_EXPR_SUM:
3382  case SCIP_EXPR_PRODUCT:
3383  case SCIP_EXPR_LINEAR:
3384  case SCIP_EXPR_QUADRATIC:
3385  break;
3386 
3387  case SCIP_EXPR_INTPOWER:
3388  {
3389  if( SCIPexprGetIntPowerExponent(expr) < 0 )
3390  {
3391  SCIPwarningMessage(scip, "negative exponent %d in intpower of constraint <%s> cannot be written in pip format\n", SCIPexprGetIntPowerExponent(expr), SCIPconsGetName(cons));
3392  ispolynomial = FALSE;
3393  }
3394 
3395  break;
3396  }
3397 
3398  case SCIP_EXPR_REALPOWER:
3399  {
3400  if( SCIPexprGetRealPowerExponent(expr) < 0.0 )
3401  {
3402  SCIPwarningMessage(scip, "negative exponent %g in realpower of constraint <%s> cannot be written in pip format\n", SCIPexprGetRealPowerExponent(expr), SCIPconsGetName(cons));
3403  ispolynomial = FALSE;
3404  }
3405 
3406  break;
3407  }
3408 
3409  case SCIP_EXPR_POLYNOMIAL:
3410  {
3411  SCIP_EXPRDATA_MONOMIAL* monomial;
3412  int m;
3413  int f;
3414 
3415  for( m = 0; m < SCIPexprGetNMonomials(expr) && ispolynomial; ++m )
3416  {
3417  monomial = SCIPexprGetMonomials(expr)[m];
3418  for( f = 0; f < SCIPexprGetMonomialNFactors(monomial); ++f )
3419  {
3420  if( SCIPexprGetMonomialExponents(monomial)[f] < 0.0 )
3421  {
3422  SCIPwarningMessage(scip, "negative exponent %g in polynomial of constraint <%s> cannot be written in pip format\n", SCIPexprGetMonomialExponents(monomial)[f], SCIPconsGetName(cons));
3423  ispolynomial = FALSE;
3424  break;
3425  }
3426  }
3427  }
3428 
3429  break;
3430  }
3431 
3432  default:
3433  SCIPwarningMessage(scip, "expression operand <%s> in constraint <%s> cannot be written in pip format\n", SCIPexpropGetName(SCIPexprGetOperator(expr)), SCIPconsGetName(cons));
3434  ispolynomial = FALSE;
3435  break;
3436  } /*lint !e788*/
3437 
3438  if( ispolynomial )
3439  {
3440  /* check if all children of root expression correspond to variables */
3441  for( v = 0; v < SCIPexprGetNChildren(expr); ++v )
3442  {
3444  {
3445  SCIPwarningMessage(scip, "expression tree of constraint <%s> is not simplified, cannot write in pip format\n", SCIPconsGetName(cons));
3446  ispolynomial = FALSE;
3447  break;
3448  }
3449  }
3450  }
3451 
3452  if( ispolynomial )
3453  {
3454  SCIP_VAR* z;
3455  SCIP_Real zcoef;
3456  SCIP_Real one;
3457 
3458  z = SCIPgetLinearVarBivariate(scip, cons);
3459  zcoef = SCIPgetLinearCoefBivariate(scip, cons);
3460 
3461  one = 1.0;
3462  SCIP_CALL( printNonlinearCons(scip, file, consname,
3463  &z, &zcoef, z == NULL ? 0 : 1, &exprtree, &one, 1,
3464  SCIPgetLhsBivariate(scip, cons), SCIPgetRhsBivariate(scip, cons), transformed) );
3465 
3466  consBivariate[nConsBivariate++] = cons;
3467  }
3468  else
3469  {
3470  SCIPinfoMessage(scip, file, "\\ ");
3471  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3472  SCIPinfoMessage(scip, file, ";\n");
3473  }
3474  }
3475  else if( strcmp(conshdlrname, "and") == 0 )
3476  {
3477  SCIP_EXPR** children;
3478  SCIP_VAR* resultant;
3479  SCIP_Real minusone;
3480  SCIP_Real one;
3481 
3482  /* create expression for product of binaries */
3483  SCIP_CALL( SCIPallocBufferArray(scip, &children, SCIPgetNVarsAnd(scip, cons)) );
3484  for( v = 0; v < SCIPgetNVarsAnd(scip, cons); ++v )
3485  {
3486  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &children[v], SCIP_EXPR_VARIDX, v) );
3487  }
3488  SCIP_CALL( SCIPexprCreate(SCIPblkmem(scip), &expr, SCIP_EXPR_PRODUCT, SCIPgetNVarsAnd(scip, cons), children) );
3489  SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(scip), &exprtree, expr, SCIPgetNVarsAnd(scip, cons), 0, NULL) );
3490  SCIP_CALL( SCIPexprtreeSetVars(exprtree, SCIPgetNVarsAnd(scip, cons), SCIPgetVarsAnd(scip, cons)) );
3491 
3492  resultant = SCIPgetResultantAnd(scip, cons);
3493  minusone = -1.0;
3494 
3495  one = 1.0;
3496  SCIP_CALL( printNonlinearCons(scip, file, consname, &resultant, &minusone, 1, &exprtree, &one, 1, 0.0, 0.0, transformed) );
3497 
3498  SCIP_CALL( SCIPexprtreeFree(&exprtree) );
3499  SCIPfreeBufferArray(scip, &children);
3500 
3501  consAnd[nConsAnd++] = cons;
3502  }
3503  else
3504  {
3505  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3506  SCIPinfoMessage(scip, file, "\\ ");
3507  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3508  SCIPinfoMessage(scip, file, ";\n");
3509  }
3510  }
3511 
3512  /* create hashtable for storing aggregated variables */
3513  SCIP_CALL( SCIPallocBufferArray(scip, &aggregatedVars, nvars) );
3514  SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), nvars/10, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3515 
3516  /* check for aggregated variables in quadratic parts of quadratic constraints and output aggregations as linear constraints */
3517  for (c = 0; c < nConsQuadratic; ++c)
3518  {
3519  cons = consQuadratic[c];
3520  for( v = 0; v < SCIPgetNQuadVarTermsQuadratic(scip, cons); ++v )
3521  {
3523  &nAggregatedVars, &aggregatedVars, &varAggregated) );
3524  }
3525  }
3526 
3527  /* check for aggregated variables in expression trees of nonlinear constraints and output aggregations as linear constraints */
3528  for (c = 0; c < nConsNonlinear; ++c)
3529  {
3530  cons = consNonlinear[c];
3531  for( e = 0; e < SCIPgetNExprtreesNonlinear(scip, cons); ++e )
3532  {
3533  exprtree = SCIPgetExprtreesNonlinear(scip, cons)[e];
3534  assert(exprtree != NULL);
3535 
3536  for( v = 0; v < SCIPexprtreeGetNVars(exprtree); ++v )
3537  {
3539  &nAggregatedVars, &aggregatedVars, &varAggregated) );
3540  }
3541  }
3542  }
3543 
3544  /* check for aggregated variables in absolute power constraints and output aggregations as linear constraints */
3545  for (c = 0; c < nConsAbspower; ++c)
3546  {
3547  SCIP_VAR* spvars[2];
3548 
3549  cons = consAbspower[c];
3550 
3551  spvars[0] = SCIPgetNonlinearVarAbspower(scip, cons);
3552  spvars[1] = SCIPgetLinearVarAbspower(scip, cons);
3553  SCIP_CALL( collectAggregatedVars(2, spvars, &nAggregatedVars, &aggregatedVars, &varAggregated) );
3554  }
3555 
3556  /* check for aggregated variables in and constraints and output aggregations as linear constraints */
3557  for (c = 0; c < nConsAnd; ++c)
3558  {
3559  SCIP_VAR* resultant;
3560 
3561  cons = consAnd[c];
3562 
3563  SCIP_CALL( collectAggregatedVars(SCIPgetNVarsAnd(scip, cons), SCIPgetVarsAnd(scip, cons), &nAggregatedVars, &aggregatedVars, &varAggregated) );
3564 
3565  resultant = SCIPgetResultantAnd(scip, cons);
3566  SCIP_CALL( collectAggregatedVars(1, &resultant, &nAggregatedVars, &aggregatedVars, &varAggregated) );
3567  }
3568 
3569  /* check for aggregated variables in bivariate constraints and output aggregations as linear constraints */
3570  for (c = 0; c < nConsBivariate; ++c)
3571  {
3572  SCIP_VAR* z;
3573 
3574  cons = consBivariate[c];
3575 
3576  assert(SCIPexprtreeGetNVars(SCIPgetExprtreeBivariate(scip, cons)) == 2);
3577  SCIP_CALL( collectAggregatedVars(2, SCIPexprtreeGetVars(SCIPgetExprtreeBivariate(scip, cons)), &nAggregatedVars, &aggregatedVars, &varAggregated) );
3578 
3579  z = SCIPgetLinearVarBivariate(scip, cons);
3580  if( z != NULL )
3581  {
3582  SCIP_CALL( collectAggregatedVars(1, &z, &nAggregatedVars, &aggregatedVars, &varAggregated) );
3583  }
3584  }
3585 
3586  /* print aggregation constraints */
3587  SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, nAggregatedVars, aggregatedVars) );
3588 
3589  /* print "Bounds" section */
3590  SCIPinfoMessage(scip, file, "Bounds\n");
3591  for (v = 0; v < nvars; ++v)
3592  {
3593  var = vars[v];
3594  assert( var != NULL );
3595  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3596 
3597  if( transformed )
3598  {
3599  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3600  lb = SCIPvarGetLbLocal(var);
3601  ub = SCIPvarGetUbLocal(var);
3602  }
3603  else
3604  {
3605  lb = SCIPvarGetLbOriginal(var);
3606  ub = SCIPvarGetUbOriginal(var);
3607  }
3608 
3609  if ( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3610  SCIPinfoMessage(scip, file, " %s free\n", varname);
3611  else
3612  {
3613  /* print lower bound */
3614  if ( SCIPisInfinity(scip, -lb) )
3615  SCIPinfoMessage(scip, file, " -inf <= ");
3616  else
3617  {
3618  if ( SCIPisZero(scip, lb) )
3619  {
3620  /* variables are nonnegative by default - so we skip these variables */
3621  if ( SCIPisInfinity(scip, ub) )
3622  continue;
3623  lb = 0.0;
3624  }
3625 
3626  SCIPinfoMessage(scip, file, " %.15g <= ", lb);
3627  }
3628  /* print variable name */
3629  SCIPinfoMessage(scip, file, "%s", varname);
3630 
3631  /* print upper bound as far this one is not infinity */
3632  if( !SCIPisInfinity(scip, ub) )
3633  SCIPinfoMessage(scip, file, " <= %.15g", ub);
3634 
3635  SCIPinfoMessage(scip, file, "\n");
3636  }
3637  }
3638 
3639  /* output aggregated variables as 'free' */
3640  for (v = 0; v < nAggregatedVars; ++v)
3641  {
3642  var = aggregatedVars[v];
3643  assert( var != NULL );
3644  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3645 
3646  SCIPinfoMessage(scip, file, " %s free\n", varname);
3647  }
3648 
3649  /* free space */
3650  SCIPfreeBufferArray(scip, &aggregatedVars);
3651  SCIPhashtableFree(&varAggregated);
3652 
3653  /* print binaries section */
3654  if ( nbinvars > 0 )
3655  {
3656  SCIPinfoMessage(scip, file, "Binaries\n");
3657 
3658  clearLine(linebuffer, &linecnt);
3659 
3660  for (v = 0; v < nvars; ++v)
3661  {
3662  var = vars[v];
3663  assert( var != NULL );
3664 
3665  if ( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3666  {
3667  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3668  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
3669  appendLine(scip, file, linebuffer, &linecnt, buffer);
3670  }
3671  }
3672 
3673  endLine(scip, file, linebuffer, &linecnt);
3674  }
3675 
3676  /* print generals section */
3677  if ( nintvars > 0 )
3678  {
3679  SCIPinfoMessage(scip, file, "Generals\n");
3680 
3681  for (v = 0; v < nvars; ++v)
3682  {
3683  var = vars[v];
3684  assert( var != NULL );
3685 
3686  if ( SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER )
3687  {
3688  (void) SCIPsnprintf(varname, PIP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3689  (void) SCIPsnprintf(buffer, PIP_MAX_PRINTLEN, " %s", varname);
3690  appendLine(scip, file, linebuffer, &linecnt, buffer);
3691  }
3692  }
3693  endLine(scip, file, linebuffer, &linecnt);
3694  }
3695 
3696  /* free space */
3697  SCIPfreeBufferArray(scip, &consQuadratic);
3698  SCIPfreeBufferArray(scip, &consNonlinear);
3699  SCIPfreeBufferArray(scip, &consAbspower);
3700  SCIPfreeBufferArray(scip, &consAnd);
3701  SCIPfreeBufferArray(scip, &consBivariate);
3702 
3703  /* end of lp format */
3704  SCIPinfoMessage(scip, file, "%s\n", "End");
3705 
3706  *result = SCIP_SUCCESS;
3707 
3708  return SCIP_OKAY;
3709 }
3710 
3711 /*
3712  * Callback methods of reader
3713  */
3714 
3715 /** copy method for reader plugins (called when SCIP copies plugins) */
3716 static
3717 SCIP_DECL_READERCOPY(readerCopyPip)
3718 { /*lint --e{715}*/
3719  assert(scip != NULL);
3720  assert(reader != NULL);
3721  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3722 
3723  /* call inclusion method of reader */
3725 
3726  return SCIP_OKAY;
3727 }
3728 
3729 
3730 /** problem reading method of reader */
3731 static
3732 SCIP_DECL_READERREAD(readerReadPip)
3733 { /*lint --e{715}*/
3734 
3735  SCIP_CALL( SCIPreadPip(scip, reader, filename, result) );
3736 
3737  return SCIP_OKAY;
3738 }
3739 
3740 
3741 /** problem writing method of reader */
3742 static
3743 SCIP_DECL_READERWRITE(readerWritePip)
3744 { /*lint --e{715}*/
3745  SCIP_CALL( SCIPwritePip(scip, file, name, transformed, objsense, objscale, objoffset, vars,
3746  nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
3747 
3748  return SCIP_OKAY;
3749 }
3750 
3751 
3752 /*
3753  * reader specific interface methods
3754  */
3755 
3756 /** includes the pip file reader in SCIP */
3758  SCIP* scip /**< SCIP data structure */
3759  )
3760 {
3761  SCIP_READER* reader;
3762 
3763  /* include reader */
3765 
3766  /* set non fundamental callbacks via setter functions */
3767  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyPip) );
3768  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadPip) );
3769  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWritePip) );
3770 
3771  return SCIP_OKAY;
3772 }
3773 
3774 
3775 /** reads problem from file */
3777  SCIP* scip, /**< SCIP data structure */
3778  SCIP_READER* reader, /**< the file reader itself */
3779  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3780  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
3781  )
3782 { /*lint --e{715}*/
3783  PIPINPUT pipinput;
3784  SCIP_RETCODE retcode;
3785  int i;
3786 
3787  assert(scip != NULL); /* for lint */
3788  assert(reader != NULL);
3789 
3790  /* initialize PIP input data */
3791  pipinput.file = NULL;
3792  pipinput.linebuf[0] = '\0';
3793  pipinput.probname[0] = '\0';
3794  pipinput.objname[0] = '\0';
3795  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.token, PIP_MAX_LINELEN) ); /*lint !e506*/
3796  pipinput.token[0] = '\0';
3797  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN) ); /*lint !e506*/
3798  pipinput.tokenbuf[0] = '\0';
3799  for( i = 0; i < PIP_MAX_PUSHEDTOKENS; ++i )
3800  {
3801  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &((pipinput.pushedtokens)[i]), PIP_MAX_LINELEN) ); /*lint !e866 !e506*/
3802  }
3803 
3804  pipinput.npushedtokens = 0;
3805  pipinput.linenumber = 0;
3806  pipinput.linepos = 0;
3807  pipinput.section = PIP_START;
3808  pipinput.objsense = SCIP_OBJSENSE_MINIMIZE;
3809  pipinput.haserror = FALSE;
3810 
3811  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(pipinput.initialconss)) );
3812  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(pipinput.dynamicconss)) );
3813  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(pipinput.dynamiccols)) );
3814  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(pipinput.dynamicrows)) );
3815 
3816  /* read the file */
3817  retcode = readPIPFile(scip, &pipinput, filename);
3818 
3819  /* free dynamically allocated memory */
3820  for( i = PIP_MAX_PUSHEDTOKENS - 1; i >= 0 ; --i )
3821  {
3822  SCIPfreeBlockMemoryArray(scip, &pipinput.pushedtokens[i], PIP_MAX_LINELEN);
3823  }
3824  SCIPfreeBlockMemoryArray(scip, &pipinput.tokenbuf, PIP_MAX_LINELEN);
3825  SCIPfreeBlockMemoryArray(scip, &pipinput.token, PIP_MAX_LINELEN);
3826 
3827  if( retcode == SCIP_PLUGINNOTFOUND )
3828  retcode = SCIP_READERROR;
3829 
3830  /* evaluate the result */
3831  if( pipinput.haserror )
3832  retcode = SCIP_READERROR;
3833  else
3834  {
3835  /* set objective sense */
3836  SCIP_CALL( SCIPsetObjsense(scip, pipinput.objsense) );
3837  *result = SCIP_SUCCESS;
3838  }
3839 
3840  SCIP_CALL( retcode );
3841 
3842  return SCIP_OKAY;
3843 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_RETCODE SCIPincludeReaderPip(SCIP *scip)
Definition: reader_pip.c:3757
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
static SCIP_RETCODE printNonlinearCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPRTREE **exprtrees, SCIP_Real *exprtreecoefs, int nexprtrees, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_pip.c:2697
static SCIP_RETCODE ensureFactorsSize(SCIP *scip, SCIP_Real **exponents, int **varidxs, int *factorssize, int minnfactors)
Definition: reader_pip.c:752
SCIP_EXPORT const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:548
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)
static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
Definition: reader_pip.c:1974
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPreadPip(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_pip.c:3776
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8186
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:80
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2486
SCIP_Real SCIPgetLinearCoefBivariate(SCIP *scip, SCIP_CONS *cons)
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetExprtreeCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetNonlinearVarAbspower(SCIP *scip, SCIP_CONS *cons)
int * SCIPexprGetMonomialChildIndices(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5922
#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_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
public methods for memory management
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5160
#define PIP_MAX_NAMELEN
Definition: reader_pip.c:75
SCIP_EXPROP SCIPexprGetOperator(SCIP_EXPR *expr)
Definition: expr.c:5695
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2598
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
PipSense
Definition: reader_pip.c:99
static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
Definition: reader_pip.c:2833
static SCIP_RETCODE readConstraints(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1455
const char * SCIPexpropGetName(SCIP_EXPROP op)
Definition: expr.c:3265
int SCIPgetNExprtreesNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsAbspower(SCIP *scip, SCIP_CONS *cons)
#define PIP_MAX_PUSHEDTOKENS
Definition: reader_pip.c:70
SCIP_RETCODE SCIPexprCreateMonomial(BMS_BLKMEM *blkmem, SCIP_EXPRDATA_MONOMIAL **monomial, SCIP_Real coef, int nfactors, int *childidxs, SCIP_Real *exponents)
Definition: expr.c:7037
SCIP_Real SCIPgetCoefLinearAbspower(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE readObjective(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1254
SCIP_EXPRTREE ** SCIPgetExprtreesNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
SCIP_Real SCIPexprGetRealPowerExponent(SCIP_EXPR *expr)
Definition: expr.c:5758
int SCIPexprGetOpIndex(SCIP_EXPR *expr)
Definition: expr.c:5725
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_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
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3131
static SCIP_RETCODE ensureMonomialsSize(SCIP *scip, SCIP_EXPRDATA_MONOMIAL ***monomials, int *monomialssize, int minnmonomials)
Definition: reader_pip.c:718
SCIP_Real SCIPexprGetPolynomialConstant(SCIP_EXPR *expr)
Definition: expr.c:5890
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:186
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_pip.c:2053
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
#define FALSE
Definition: def.h:73
static void printRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_QUADVARTERM *quadvarterms, int nquadvarterms, SCIP_BILINTERM *bilinterms, int nbilinterms, SCIP_Real rhs)
Definition: reader_pip.c:2106
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17515
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:138
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
#define TRUE
Definition: def.h:72
#define SCIPdebug(x)
Definition: pub_message.h:84
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_pip.c:2886
SCIP_Real SCIPgetRhsBivariate(SCIP *scip, SCIP_CONS *cons)
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define READER_DESC
Definition: reader_pip.c:62
SCIP_Real SCIPgetLhsBivariate(SCIP *scip, SCIP_CONS *cons)
#define READER_NAME
Definition: reader_pip.c:61
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9272
public methods for problem variables
PipSection
Definition: reader_pip.c:79
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, PIPEXPTYPE *exptype)
Definition: reader_pip.c:198
static SCIP_RETCODE readBounds(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1654
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
struct PipInput PIPINPUT
Definition: reader_pip.c:129
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
#define READER_EXTENSION
Definition: reader_pip.c:63
SCIP_RETCODE SCIPexprtreeCreate(BMS_BLKMEM *blkmem, SCIP_EXPRTREE **tree, SCIP_EXPR *root, int nvars, int nparams, SCIP_Real *params)
Definition: expr.c:8773
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
Constraint handler for the set partitioning / packing / covering constraints .
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
public methods for SCIP variables
#define PIP_PRINTLEN
Definition: reader_pip.c:76
#define SCIPdebugMsgPrint
Definition: scip_message.h:70
#define SCIPdebugMsg
Definition: scip_message.h:69
#define PIP_MAX_PRINTLEN
Definition: reader_pip.c:74
SCIP_EXPRTREE * SCIPgetExprtreeBivariate(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** x
Definition: circlepacking.c:54
static SCIP_Bool hasError(PIPINPUT *pipinput)
Definition: reader_pip.c:169
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5185
public methods for numerical tolerances
SCIP_EXPRDATA_MONOMIAL ** SCIPexprGetMonomials(SCIP_EXPR *expr)
Definition: expr.c:5866
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:2235
public methods for expressions, expression trees, expression graphs, and related stuff ...
int SCIPexprGetMonomialNFactors(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5912
int SCIPexprGetIntPowerExponent(SCIP_EXPR *expr)
Definition: expr.c:5769
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_pip.c:2075
static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_Bool dynamiccols, SCIP_VAR **var, SCIP_Bool *created)
Definition: reader_pip.c:658
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3220
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:210
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:144
enum PipSection PIPSECTION
Definition: reader_pip.c:89
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3362
SCIP_Real coef
Definition: type_expr.h:104
static const char delimchars[]
Definition: reader_pip.c:131
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
static const char tokenchars[]
Definition: reader_pip.c:132
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1742
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
int SCIPstrncpy(char *t, const char *s, int size)
Definition: misc.c:10633
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4677
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_VAR * SCIPgetLinearVarAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPexprGetQuadLinearCoefs(SCIP_EXPR *expr)
Definition: expr.c:5842
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPexprtreePrintWithNames(SCIP_EXPRTREE *tree, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: nlp.c:174
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
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
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
#define PIP_MAX_LINELEN
Definition: reader_pip.c:69
SCIP_Real SCIPexprGetQuadConstant(SCIP_EXPR *expr)
Definition: expr.c:5829
constraint handler for quadratic constraints
static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_pip.c:2911
static SCIP_Bool isValue(SCIP *scip, PIPINPUT *pipinput, SCIP_Real *value)
Definition: reader_pip.c:595
#define NULL
Definition: lpi_spx1.cpp:155
file reader for polynomial mixed-integer programs in PIP format
int SCIPexprtreeGetNVars(SCIP_EXPRTREE *tree)
Definition: expr.c:8614
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *nonlincoefs, 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)
#define SCIP_CALL(x)
Definition: def.h:364
SCIP_RETCODE SCIPexprCreatePolynomial(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, int nmonomials, SCIP_EXPRDATA_MONOMIAL **monomials, SCIP_Real constant, SCIP_Bool copymonomials)
Definition: expr.c:6634
static SCIP_DECL_READERWRITE(readerWritePip)
Definition: reader_pip.c:3743
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_pip.c:287
Definition: grphload.c:88
static SCIP_Bool isSense(PIPINPUT *pipinput, PIPSENSE *sense)
Definition: reader_pip.c:627
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPR * SCIPexprtreeGetRoot(SCIP_EXPRTREE *tree)
Definition: expr.c:8604
public methods for constraint handler plugins and constraints
public methods for NLP management
wrapper functions to map file i/o to standard or zlib file i/o
static SCIP_Bool isDelimChar(char c)
Definition: reader_pip.c:180
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
static SCIP_Bool isNewSection(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:437
public data structures and miscellaneous methods
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:5715
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2285
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_pip.c:1990
#define SCIP_Bool
Definition: def.h:70
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3013
enum PipSense PIPSENSE
Definition: reader_pip.c:106
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
SCIP_RETCODE SCIPexprtreeSetVars(SCIP_EXPRTREE *tree, int nvars, SCIP_VAR **vars)
Definition: nlp.c:113
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
enum PipExpType PIPEXPTYPE
Definition: reader_pip.c:97
constraint handler for nonlinear constraints
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:91
static void pushToken(PIPINPUT *pipinput)
Definition: reader_pip.c:400
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
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:5705
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8398
static void pushBufferToken(PIPINPUT *pipinput)
Definition: reader_pip.c:413
SCIP_RETCODE SCIPexprCreate(BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPROP op,...)
Definition: expr.c:5975
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPexprtreeFree(SCIP_EXPRTREE **tree)
Definition: expr.c:8854
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:100
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5136
static SCIP_Bool isSign(PIPINPUT *pipinput, int *sign)
Definition: reader_pip.c:570
SCIP_VAR ** SCIPexprtreeGetVars(SCIP_EXPRTREE *tree)
Definition: nlp.c:103
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetOffsetAbspower(SCIP *scip, SCIP_CONS *cons)
static void swapTokenBuffer(PIPINPUT *pipinput)
Definition: reader_pip.c:426
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
constraint handler for bivariate nonlinear constraints
Constraint handler for linear constraints in their most general form, .
SCIP_EXPORT SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17613
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define SCIP_EXPR_DEGREEINFINITY
Definition: type_expr.h:116
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
static SCIP_RETCODE readPIPFile(SCIP *scip, PIPINPUT *pipinput, const char *filename)
Definition: reader_pip.c:1904
SCIP_Real SCIPexprGetMonomialCoef(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5902
Constraint handler for absolute power constraints .
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4767
static SCIP_DECL_READERCOPY(readerCopyPip)
Definition: reader_pip.c:3717
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2679
#define PIP_INIT_VARSSIZE
Definition: reader_pip.c:71
static SCIP_RETCODE collectAggregatedVars(int nvars, SCIP_VAR **vars, int *nAggregatedVars, SCIP_VAR ***aggregatedVars, SCIP_HASHTABLE **varAggregated)
Definition: reader_pip.c:2793
SCIP_RETCODE SCIPaddLinearVarQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real coef)
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
static SCIP_DECL_READERREAD(readerReadPip)
Definition: reader_pip.c:3732
PipExpType
Definition: reader_pip.c:91
static SCIP_RETCODE readBinaries(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1860
SCIP_Real SCIPgetExponentAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPexprGetLinearCoefs(SCIP_EXPR *expr)
Definition: expr.c:5791
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4514
static const SCIP_Real scalars[]
Definition: lp.c:5731
SCIP_Real SCIPexprGetOpReal(SCIP_EXPR *expr)
Definition: expr.c:5736
static SCIP_RETCODE readGenerals(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:1825
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE readStart(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:697
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
SCIP_QUADELEM * SCIPexprGetQuadElements(SCIP_EXPR *expr)
Definition: expr.c:5817
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_pip.c:2039
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
Definition: reader_pip.c:1981
public methods for message output
int SCIPexprGetNMonomials(SCIP_EXPR *expr)
Definition: expr.c:5878
static SCIP_RETCODE printQuadraticCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_QUADVARTERM *quadvarterms, int nquadvarterms, SCIP_BILINTERM *bilinterms, int nbilinterms, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_pip.c:2600
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10590
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9249
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3047
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8089
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1252
#define SCIP_Real
Definition: def.h:163
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:2965
public methods for input file readers
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:385
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8109
static void getLinearAndQuadraticCoefs(SCIP_EXPRTREE *exprtree, SCIP_Real *constant, int *nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int *nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs)
Definition: reader_pip.c:1155
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
static void printRowNl(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPRTREE **exprtrees, SCIP_Real *exprtreecoefs, int nexprtrees, SCIP_Real rhs)
Definition: reader_pip.c:2243
public methods for message handling
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12545
static SCIP_Bool isTokenChar(char c)
Definition: reader_pip.c:189
SCIP_Real * SCIPexprGetMonomialExponents(SCIP_EXPRDATA_MONOMIAL *monomial)
Definition: expr.c:5932
void SCIPprintSysError(const char *message)
Definition: misc.c:10499
static SCIP_Bool getNextLine(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:242
#define SCIP_Longint
Definition: def.h:148
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4179
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9295
static SCIP_RETCODE getVariableIndex(SCIP *scip, SCIP_VAR ***vars, int *varssize, int *nvars, SCIP_HASHMAP *varhash, SCIP_VAR *var, int *varidx)
Definition: reader_pip.c:792
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2764
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetLinearVarBivariate(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsQuadratic(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, 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)
static const char commentchars[]
Definition: reader_pip.c:133
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_Real SCIPgetLhsAbspower(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17633
static void syntaxError(SCIP *scip, PIPINPUT *pipinput, const char *msg)
Definition: reader_pip.c:142
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:223
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8155
public methods for reader plugins
static SCIP_RETCODE readPolynomial(SCIP *scip, PIPINPUT *pipinput, char *name, SCIP_EXPRTREE **exprtree, int *degree, SCIP_Bool *newsection)
Definition: reader_pip.c:850
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPexprGetLinearConstant(SCIP_EXPR *expr)
Definition: expr.c:5804
public methods for global and local (sub)problems
int SCIPexprGetNQuadElements(SCIP_EXPR *expr)
Definition: expr.c:5854
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool getNextToken(SCIP *scip, PIPINPUT *pipinput)
Definition: reader_pip.c:301
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_pip.c:1998
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17350
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
memory allocation routines