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