Scippy

SCIP

Solving Constraint Integer Programs

reader_lp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_lp.c
17  * @ingroup DEFPLUGINS_READER
18  * @brief LP file reader
19  * @author Tobias Achterberg
20  * @author Marc Pfetsch
21  * @author Stefan Heinz
22  * @author Stefan Vigerske
23  * @author Michael Winkler
24  * @author Lars Schewe
25  *
26  * @todo write fixed (non-active) variables, e.g., for transformed problem
27  */
28 
29 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
30 
31 #include "blockmemshell/memory.h"
32 #include <ctype.h>
33 #include "scip/cons_and.h"
35 #include "scip/cons_nonlinear.h"
36 #include "scip/cons_indicator.h"
37 #include "scip/cons_knapsack.h"
38 #include "scip/cons_linear.h"
39 #include "scip/cons_logicor.h"
40 #include "scip/cons_setppc.h"
41 #include "scip/cons_sos1.h"
42 #include "scip/cons_sos2.h"
43 #include "scip/cons_varbound.h"
44 #include "scip/pub_cons.h"
45 #include "scip/pub_fileio.h"
46 #include "scip/pub_message.h"
47 #include "scip/pub_misc.h"
48 #include "scip/pub_reader.h"
49 #include "scip/pub_var.h"
50 #include "scip/reader_lp.h"
51 #include "scip/scip_cons.h"
52 #include "scip/scip_mem.h"
53 #include "scip/scip_message.h"
54 #include "scip/scip_numerics.h"
55 #include "scip/scip_param.h"
56 #include "scip/scip_prob.h"
57 #include "scip/scip_reader.h"
58 #include "scip/scip_var.h"
59 #include <stdlib.h>
60 #include <string.h>
61 
62 #if !defined(_WIN32) && !defined(_WIN64)
63 #include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
64 #endif
65 
66 
67 #define READER_NAME "lpreader"
68 #define READER_DESC "file reader for MIPs in IBM CPLEX's LP file format"
69 #define READER_EXTENSION "lp"
70 
71 #define DEFAULT_LINEARIZE_ANDS TRUE /**< Should possible \"and\"-constraints be linearized when writing the lp file? */
72 #define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< Should an aggregated linearization for and constraints be used? */
73 
74 /*
75  * Data structures
76  */
77 
78 #define LP_MAX_LINELEN 65536
79 #define LP_MAX_PUSHEDTOKENS 2
80 #define LP_INIT_COEFSSIZE 8192
81 #define LP_INIT_QUADCOEFSSIZE 16
82 #define LP_MAX_PRINTLEN 561 /**< the maximum length of any line is 560 + '\\0' = 561*/
83 #define LP_MAX_NAMELEN 256 /**< the maximum length for any name is 255 + '\\0' = 256 */
84 #define LP_PRINTLEN 100
85 
86 
87 /** LP reading data */
88 struct SCIP_ReaderData
89 {
90  SCIP_Bool linearizeands;
91  SCIP_Bool aggrlinearizationands;
92 };
93 
94 
95 /** Section in LP File */
97 {
99 };
100 typedef enum LpSection LPSECTION;
101 
103 {
105 };
106 typedef enum LpExpType LPEXPTYPE;
107 
109 {
111 };
112 typedef enum LpSense LPSENSE;
113 
114 /** LP reading data */
115 struct LpInput
116 {
117  SCIP_FILE* file;
118  char linebuf[LP_MAX_LINELEN+1];
119  char probname[LP_MAX_LINELEN];
120  char objname[LP_MAX_LINELEN];
121  char* token;
122  char* tokenbuf;
123  char* pushedtokens[LP_MAX_PUSHEDTOKENS];
124  int npushedtokens;
125  int linenumber;
126  int linepos;
128  SCIP_OBJSENSE objsense;
129  SCIP_Bool inlazyconstraints; /**< whether we are currently reading the section for lazy constraints */
130  SCIP_Bool inusercuts; /**< whether we are currently reading the section for user cuts */
131  SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
132  SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
133  SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
134  SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
135  SCIP_Bool haserror;
136  SCIP_Bool comment;
137  SCIP_Bool endline;
138 };
139 typedef struct LpInput LPINPUT;
140 
141 static const char commentchars[] = "\\";
142 
143 
144 /*
145  * Local methods (for reading)
146  */
147 
148 /** issues an error message and marks the LP data to have errors */
149 static
151  SCIP* scip, /**< SCIP data structure */
152  LPINPUT* lpinput, /**< LP reading data */
153  const char* msg /**< error message */
154  )
155 {
156  char formatstr[256];
157 
158  assert(lpinput != NULL);
159 
160  SCIPerrorMessage("Syntax error in line %d ('%s'): %s \n", lpinput->linenumber, lpinput->token, msg);
161  if( lpinput->linebuf[strlen(lpinput->linebuf)-1] == '\n' )
162  {
163  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", lpinput->linebuf);
164  }
165  else
166  {
167  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", lpinput->linebuf);
168  }
169  (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", lpinput->linepos);
170  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, (const char*)formatstr, "^");
171  lpinput->section = LP_END;
172  lpinput->haserror = TRUE;
173 }
174 
175 /** returns whether a syntax error was detected */
176 static
178  LPINPUT* lpinput /**< LP reading data */
179  )
180 {
181  assert(lpinput != NULL);
182 
183  return lpinput->haserror;
184 }
185 
186 /** returns whether the given character is a token delimiter */
187 static
189  char c /**< input character */
190  )
191 {
192  switch (c)
193  {
194  case ' ':
195  case '\f':
196  case '\n':
197  case '\r':
198  case '\t':
199  case '\v':
200  case '\0':
201  return TRUE;
202  default:
203  return FALSE;
204  }
205 }
206 
207 /** returns whether the given character is a single token */
208 static
210  char c /**< input character */
211  )
212 {
213  switch (c)
214  {
215  case '-':
216  case '+':
217  case ':':
218  case '<':
219  case '>':
220  case '=':
221  case '[':
222  case ']':
223  case '*':
224  case '^':
225  return TRUE;
226  default:
227  return FALSE;
228  }
229 }
230 
231 /** returns whether the current character is member of a value string */
232 static
234  char c, /**< input character */
235  char nextc, /**< next input character */
236  SCIP_Bool firstchar, /**< is the given character the first char of the token? */
237  SCIP_Bool* hasdot, /**< pointer to update the dot flag */
238  LPEXPTYPE* exptype /**< pointer to update the exponent type */
239  )
240 {
241  assert(hasdot != NULL);
242  assert(exptype != NULL);
243 
244  if( isdigit((unsigned char)c) )
245  return TRUE;
246  else if( (*exptype == LP_EXP_NONE) && !(*hasdot) && (c == '.') && ( isdigit((unsigned char)nextc) || isspace((unsigned char)nextc) || nextc == 'e' || nextc == 'E') )
247  { /* note: we allow for numbers like "24311." for which the next character should be a space or exponent sign */
248  *hasdot = TRUE;
249  return TRUE;
250  }
251  else if( !firstchar && (*exptype == LP_EXP_NONE) && (c == 'e' || c == 'E') )
252  {
253  if( nextc == '+' || nextc == '-' )
254  {
255  *exptype = LP_EXP_SIGNED;
256  return TRUE;
257  }
258  else if( isdigit((unsigned char)nextc) )
259  {
260  *exptype = LP_EXP_UNSIGNED;
261  return TRUE;
262  }
263  }
264  else if( (*exptype == LP_EXP_SIGNED) && (c == '+' || c == '-') )
265  {
266  *exptype = LP_EXP_UNSIGNED;
267  return TRUE;
268  }
269 
270  return FALSE;
271 }
272 
273 /** reads the next line from the input file into the line buffer; skips comments;
274  * returns whether a line could be read
275  */
276 static
278  SCIP* scip, /**< SCIP data structure */
279  LPINPUT* lpinput /**< LP reading data */
280  )
281 {
282  int i;
283 
284  assert(lpinput != NULL);
285 
286  /* if we previously detected a comment we have to parse the remaining line away if there is something left */
287  if( !lpinput->endline && lpinput->comment )
288  {
289  SCIPdebugMsg(scip, "Throwing rest of comment away.\n");
290 
291  do
292  {
293  lpinput->linebuf[LP_MAX_LINELEN-2] = '\0';
294  (void)SCIPfgets(lpinput->linebuf, (int) sizeof(lpinput->linebuf), lpinput->file);
295  }
296  while( lpinput->linebuf[LP_MAX_LINELEN-2] != '\0' );
297 
298  lpinput->comment = FALSE;
299  lpinput->endline = TRUE;
300  }
301 
302  /* read next line */
303  lpinput->linepos = 0;
304  lpinput->linebuf[LP_MAX_LINELEN-2] = '\0';
305 
306  if( SCIPfgets(lpinput->linebuf, (int) sizeof(lpinput->linebuf), lpinput->file) == NULL )
307  {
308  /* clear the line, this is really necessary here! */
309  BMSclearMemoryArray(lpinput->linebuf, LP_MAX_LINELEN);
310 
311  return FALSE;
312  }
313 
314  lpinput->linenumber++;
315 
316  /* if line is too long for our buffer correct the buffer and correct position in file */
317  if( lpinput->linebuf[LP_MAX_LINELEN-2] != '\0' )
318  {
319  char* last;
320 
321  /* buffer is full; erase last token since it might be incomplete */
322  lpinput->endline = FALSE;
323  last = strrchr(lpinput->linebuf, ' ');
324 
325  if( last == NULL )
326  {
327  SCIPwarningMessage(scip, "we read %d characters from the file; this might indicate a corrupted input file!",
328  LP_MAX_LINELEN - 2);
329  lpinput->linebuf[LP_MAX_LINELEN-2] = '\0';
330  SCIPdebugMsg(scip, "the buffer might be corrupted\n");
331  }
332  else
333  {
334  SCIPfseek(lpinput->file, -(long) strlen(last), SEEK_CUR);
335  SCIPdebugMsg(scip, "correct buffer, reread the last %ld characters\n", (long) strlen(last));
336  *last = '\0';
337  }
338  }
339  else
340  {
341  /* found end of line */
342  lpinput->endline = TRUE;
343  }
344  lpinput->linebuf[LP_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
345  lpinput->comment = FALSE;
346 
347  /* skip characters after comment symbol */
348  for( i = 0; commentchars[i] != '\0'; ++i )
349  {
350  char* commentstart;
351 
352  commentstart = strchr(lpinput->linebuf, commentchars[i]);
353  if( commentstart != NULL )
354  {
355  *commentstart = '\0';
356  *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
357 
358  lpinput->comment = TRUE;
359  break;
360  }
361  }
362 
363  return TRUE;
364 }
365 
366 /** swaps the addresses of two pointers */
367 static
369  char** pointer1, /**< first pointer */
370  char** pointer2 /**< second pointer */
371  )
372 {
373  char* tmp;
374 
375  tmp = *pointer1;
376  *pointer1 = *pointer2;
377  *pointer2 = tmp;
378 }
379 
380 /** reads the next token from the input file into the token buffer; returns whether a token was read */
381 static
383  SCIP* scip, /**< SCIP data structure */
384  LPINPUT* lpinput /**< LP reading data */
385  )
386 {
387  SCIP_Bool hasdot;
388  LPEXPTYPE exptype;
389  char* buf;
390  int tokenlen;
391 
392  assert(lpinput != NULL);
393  assert(lpinput->linepos < LP_MAX_LINELEN);
394 
395  /* check the token stack */
396  if( lpinput->npushedtokens > 0 )
397  {
398  swapPointers(&lpinput->token, &lpinput->pushedtokens[lpinput->npushedtokens-1]);
399  lpinput->npushedtokens--;
400 
401  SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", lpinput->linenumber, lpinput->token);
402  return TRUE;
403  }
404 
405  /* skip delimiters */
406  buf = lpinput->linebuf;
407  while( isDelimChar(buf[lpinput->linepos]) )
408  {
409  if( buf[lpinput->linepos] == '\0' )
410  {
411  if( !getNextLine(scip, lpinput) )
412  {
413  lpinput->section = LP_END;
414  SCIPdebugMsg(scip, "(line %d) end of file\n", lpinput->linenumber);
415  return FALSE;
416  }
417  assert(lpinput->linepos == 0);
418  }
419  else
420  lpinput->linepos++;
421  }
422  assert(lpinput->linepos < LP_MAX_LINELEN);
423  assert(!isDelimChar(buf[lpinput->linepos]));
424 
425  /* check if the token is a value */
426  hasdot = FALSE;
427  exptype = LP_EXP_NONE;
428  if( isValueChar(buf[lpinput->linepos], buf[lpinput->linepos+1], TRUE, &hasdot, &exptype) )
429  {
430  /* read value token */
431  tokenlen = 0;
432  do
433  {
434  assert(tokenlen < LP_MAX_LINELEN);
435  assert(!isDelimChar(buf[lpinput->linepos]));
436  lpinput->token[tokenlen] = buf[lpinput->linepos];
437  tokenlen++;
438  lpinput->linepos++;
439  }
440  while( isValueChar(buf[lpinput->linepos], buf[lpinput->linepos+1], FALSE, &hasdot, &exptype) );
441  }
442  else
443  {
444  /* read non-value token */
445  tokenlen = 0;
446  do
447  {
448  assert(tokenlen < LP_MAX_LINELEN);
449  lpinput->token[tokenlen] = buf[lpinput->linepos];
450  tokenlen++;
451  lpinput->linepos++;
452  if( tokenlen == 1 && isTokenChar(lpinput->token[0]) )
453  break;
454  }
455  while( !isDelimChar(buf[lpinput->linepos]) && !isTokenChar(buf[lpinput->linepos]) );
456 
457  /* if the token is a power sign '^', skip a following '2'
458  * if the token is an equation sense '<', '>', or '=', skip a following '='
459  * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
460  */
461  if( tokenlen >= 1 && lpinput->token[tokenlen-1] == '^' && buf[lpinput->linepos] == '2' )
462  {
463  lpinput->linepos++;
464  }
465  if( tokenlen >= 1
466  && (lpinput->token[tokenlen-1] == '<' || lpinput->token[tokenlen-1] == '>' || lpinput->token[tokenlen-1] == '=')
467  && buf[lpinput->linepos] == '=' )
468  {
469  lpinput->linepos++;
470  }
471  else if( lpinput->token[tokenlen-1] == '=' && (buf[lpinput->linepos] == '<' || buf[lpinput->linepos] == '>') )
472  {
473  lpinput->token[tokenlen-1] = buf[lpinput->linepos];
474  lpinput->linepos++;
475  }
476  }
477  assert(tokenlen < LP_MAX_LINELEN);
478  lpinput->token[tokenlen] = '\0';
479 
480  SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", lpinput->linenumber, lpinput->token);
481 
482  return TRUE;
483 }
484 
485 /** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
486 static
488  LPINPUT* lpinput /**< LP reading data */
489  )
490 {
491  assert(lpinput != NULL);
492  assert(lpinput->npushedtokens < LP_MAX_PUSHEDTOKENS);
493 
494  swapPointers(&lpinput->pushedtokens[lpinput->npushedtokens], &lpinput->token);
495  lpinput->npushedtokens++;
496 }
497 
498 /** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
499 static
501  LPINPUT* lpinput /**< LP reading data */
502  )
503 {
504  assert(lpinput != NULL);
505  assert(lpinput->npushedtokens < LP_MAX_PUSHEDTOKENS);
506 
507  swapPointers(&lpinput->pushedtokens[lpinput->npushedtokens], &lpinput->tokenbuf);
508  lpinput->npushedtokens++;
509 }
510 
511 /** swaps the current token with the token buffer */
512 static
514  LPINPUT* lpinput /**< LP reading data */
515  )
516 {
517  assert(lpinput != NULL);
518 
519  swapPointers(&lpinput->token, &lpinput->tokenbuf);
520 }
521 
522 /** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
523 static
525  SCIP* scip, /**< SCIP data structure */
526  LPINPUT* lpinput /**< LP reading data */
527  )
528 {
529  SCIP_Bool iscolon;
530  size_t len;
531 
532  assert(lpinput != NULL);
533 
534  /* remember first token by swapping the token buffer */
535  swapTokenBuffer(lpinput);
536 
537  /* look at next token: if this is a ':', the first token is a name and no section keyword */
538  iscolon = FALSE;
539  if( getNextToken(scip, lpinput) )
540  {
541  iscolon = (*lpinput->token == ':');
542  pushToken(lpinput);
543  }
544 
545  /* reinstall the previous token by swapping back the token buffer */
546  swapTokenBuffer(lpinput);
547 
548  /* check for ':' */
549  if( iscolon )
550  return FALSE;
551 
552  len = strlen(lpinput->token);
553  assert(len < LP_MAX_LINELEN);
554 
555  /* the section keywords are at least 2 characters up to 8 or exactly 15 characters long */
556  if( len > 1 && (len < 9 || len == 15) )
557  {
558  char token[16];
559  int c = 0;
560 
561  while( lpinput->token[c] != '\0' )
562  {
563  token[c] = toupper(lpinput->token[c]); /*lint !e734*/
564  ++c;
565  assert(c < 16);
566  }
567  token[c] = '\0';
568 
569  if( (len == 3 && strcmp(token, "MIN") == 0)
570  || (len == 7 && strcmp(token, "MINIMUM") == 0)
571  || (len == 8 && strcmp(token, "MINIMIZE") == 0) )
572  {
573  SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
574  lpinput->section = LP_OBJECTIVE;
575  lpinput->objsense = SCIP_OBJSENSE_MINIMIZE;
576  return TRUE;
577  }
578 
579  if( (len == 3 && strcmp(token, "MAX") == 0)
580  || (len == 7 && strcmp(token, "MAXIMUM") == 0)
581  || (len == 8 && strcmp(token, "MAXIMIZE") == 0) )
582  {
583  SCIPdebugMsg(scip, "(line %d) new section: OBJECTIVE\n", lpinput->linenumber);
584  lpinput->section = LP_OBJECTIVE;
585  lpinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
586  return TRUE;
587  }
588 
589  if( len == 7 && strcmp(token, "SUBJECT") == 0 )
590  {
591  /* check if the next token is 'TO' */
592  swapTokenBuffer(lpinput);
593  if( getNextToken(scip, lpinput) )
594  {
595  if( strcasecmp(lpinput->token, "TO") == 0 )
596  {
597  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
598  lpinput->section = LP_CONSTRAINTS;
599  lpinput->inlazyconstraints = FALSE;
600  lpinput->inusercuts = FALSE;
601  return TRUE;
602  }
603  else
604  pushToken(lpinput);
605  }
606  swapTokenBuffer(lpinput);
607  }
608 
609  if( len == 4 && strcmp(token, "SUCH") == 0 )
610  {
611  /* check if the next token is 'THAT' */
612  swapTokenBuffer(lpinput);
613  if( getNextToken(scip, lpinput) )
614  {
615  if( strcasecmp(lpinput->token, "THAT") == 0 )
616  {
617  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
618  lpinput->section = LP_CONSTRAINTS;
619  lpinput->inlazyconstraints = FALSE;
620  lpinput->inusercuts = FALSE;
621  return TRUE;
622  }
623  else
624  pushToken(lpinput);
625  }
626  swapTokenBuffer(lpinput);
627  }
628 
629  if( (len == 2 && strcmp(token, "ST") == 0)
630  || (len == 3 && strcmp(token, "ST.") == 0)
631  || (len == 4 && strcmp(token, "S.T.") == 0) )
632  {
633  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS\n", lpinput->linenumber);
634  lpinput->section = LP_CONSTRAINTS;
635  lpinput->inlazyconstraints = FALSE;
636  lpinput->inusercuts = FALSE;
637  return TRUE;
638  }
639 
640  if( len == 4 && strcmp(token, "LAZY") == 0 )
641  {
642  /* check if the next token is 'CONSTRAINTS' */
643  swapTokenBuffer(lpinput);
644  if( getNextToken(scip, lpinput) )
645  {
646  if( strcasecmp(lpinput->token, "CONSTRAINTS") == 0 )
647  {
648  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS (lazy)\n", lpinput->linenumber);
649  lpinput->section = LP_CONSTRAINTS;
650  lpinput->inlazyconstraints = TRUE;
651  lpinput->inusercuts = FALSE;
652  return TRUE;
653  }
654  else
655  pushToken(lpinput);
656  }
657  swapTokenBuffer(lpinput);
658  }
659 
660  if( len == 4 && strcmp(token, "USER") == 0 )
661  {
662  /* check if the next token is 'CUTS' */
663  swapTokenBuffer(lpinput);
664  if( getNextToken(scip, lpinput) )
665  {
666  if( strcasecmp(lpinput->token, "CUTS") == 0 )
667  {
668  SCIPdebugMsg(scip, "(line %d) new section: CONSTRAINTS (user cuts)\n", lpinput->linenumber);
669  lpinput->section = LP_CONSTRAINTS;
670  lpinput->inlazyconstraints = FALSE;
671  lpinput->inusercuts = TRUE;
672  return TRUE;
673  }
674  else
675  pushToken(lpinput);
676  }
677  swapTokenBuffer(lpinput);
678  }
679 
680  if( (len == 5 && strcmp(token, "BOUND") == 0)
681  || (len == 6 && strcmp(token, "BOUNDS") == 0) )
682  {
683  SCIPdebugMsg(scip, "(line %d) new section: BOUNDS\n", lpinput->linenumber);
684  lpinput->section = LP_BOUNDS;
685  return TRUE;
686  }
687 
688  if( (len == 3 && (strcmp(token, "GEN") == 0 || strcmp(token, "INT") == 0))
689  || (len == 7 && (strcmp(token, "GENERAL") == 0 || strcmp(token, "INTEGER") == 0))
690  || (len == 8 && (strcmp(token, "GENERALS") == 0 || strcmp(token, "INTEGERS") == 0)) )
691  {
692  SCIPdebugMsg(scip, "(line %d) new section: GENERALS\n", lpinput->linenumber);
693  lpinput->section = LP_GENERALS;
694  return TRUE;
695  }
696 
697  if( (len == 3 && strcmp(token, "BIN") == 0)
698  || (len == 6 && strcmp(token, "BINARY") == 0)
699  || (len == 8 && strcmp(token, "BINARIES") == 0) )
700  {
701  SCIPdebugMsg(scip, "(line %d) new section: BINARIES\n", lpinput->linenumber);
702  lpinput->section = LP_BINARIES;
703  return TRUE;
704  }
705 
706  if( (len == 4 && strcmp(token, "SEMI") == 0)
707  || (len == 5 && strcmp(token, "SEMIS") == 0)
708  || (len == 15 && strcmp(token, "SEMI-CONTINUOUS") == 0) )
709  {
710  SCIPdebugMsg(scip, "(line %d) new section: SEMICONTINUOUS\n", lpinput->linenumber);
711  lpinput->section = LP_SEMICONTINUOUS;
712  return TRUE;
713  }
714 
715  if( len == 3 && strcmp(token, "SOS") == 0 )
716  {
717  SCIPdebugMsg(scip, "(line %d) new section: SOS\n", lpinput->linenumber);
718  lpinput->section = LP_SOS;
719  return TRUE;
720  }
721 
722  if( len == 3 && strcmp(token, "END") == 0 )
723  {
724  SCIPdebugMsg(scip, "(line %d) new section: END\n", lpinput->linenumber);
725  lpinput->section = LP_END;
726  return TRUE;
727  }
728  }
729 
730  return FALSE;
731 }
732 
733 /** returns whether the current token is a sign */
734 static
736  LPINPUT* lpinput, /**< LP reading data */
737  int* sign /**< pointer to update the sign */
738  )
739 {
740  assert(lpinput != NULL);
741  assert(sign != NULL);
742  assert(*sign == +1 || *sign == -1);
743 
744  if( lpinput->token[1] == '\0' )
745  {
746  if( *lpinput->token == '+' )
747  return TRUE;
748  else if( *lpinput->token == '-' )
749  {
750  *sign *= -1;
751  return TRUE;
752  }
753  }
754 
755  return FALSE;
756 }
757 
758 /** returns whether the current token is a value */
759 static
761  SCIP* scip, /**< SCIP data structure */
762  LPINPUT* lpinput, /**< LP reading data */
763  SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
764  )
765 {
766  assert(lpinput != NULL);
767  assert(value != NULL);
768 
769  if( strcasecmp(lpinput->token, "INFINITY") == 0 || strcasecmp(lpinput->token, "INF") == 0 )
770  {
771  *value = SCIPinfinity(scip);
772  return TRUE;
773  }
774  else
775  {
776  double val;
777  char* endptr;
778 
779  val = strtod(lpinput->token, &endptr);
780  if( endptr != lpinput->token && *endptr == '\0' )
781  {
782  *value = val;
783  return TRUE;
784  }
785  }
786 
787  return FALSE;
788 }
789 
790 /** returns whether the current token is an equation sense */
791 static
793  LPINPUT* lpinput, /**< LP reading data */
794  LPSENSE* sense /**< pointer to store the equation sense, or NULL */
795  )
796 {
797  assert(lpinput != NULL);
798 
799  if( strcmp(lpinput->token, "<") == 0 )
800  {
801  if( sense != NULL )
802  *sense = LP_SENSE_LE;
803  return TRUE;
804  }
805  else if( strcmp(lpinput->token, ">") == 0 )
806  {
807  if( sense != NULL )
808  *sense = LP_SENSE_GE;
809  return TRUE;
810  }
811  else if( strcmp(lpinput->token, "=") == 0 )
812  {
813  if( sense != NULL )
814  *sense = LP_SENSE_EQ;
815  return TRUE;
816  }
817 
818  return FALSE;
819 }
820 
821 /** returns the variable with the given name, or creates a new variable if it does not exist */
822 static
824  SCIP* scip, /**< SCIP data structure */
825  char* name, /**< name of the variable */
826  SCIP_VAR** var, /**< pointer to store the variable */
827  SCIP_Bool* created /**< pointer to store whether a new variable was created, or NULL */
828  )
829 {
830  assert(name != NULL);
831  assert(var != NULL);
832 
833  *var = SCIPfindVar(scip, name);
834  if( *var == NULL )
835  {
836  SCIP_VAR* newvar;
837  SCIP_Bool dynamiccols;
838  SCIP_Bool initial;
839  SCIP_Bool removable;
840 
841  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
842  initial = !dynamiccols;
843  removable = dynamiccols;
844 
845  /* create new variable of the given name */
846  SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
847  SCIP_CALL( SCIPcreateVar(scip, &newvar, name, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS,
848  initial, removable, NULL, NULL, NULL, NULL, NULL) );
849  SCIP_CALL( SCIPaddVar(scip, newvar) );
850  *var = newvar;
851 
852  /* because the variable was added to the problem, it is captured by SCIP and we can safely release it right now
853  * without making the returned *var invalid
854  */
855  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
856 
857  if( created != NULL )
858  *created = TRUE;
859  }
860  else if( created != NULL )
861  *created = FALSE;
862 
863  return SCIP_OKAY;
864 }
865 
866 /** reads the header of the file */
867 static
869  SCIP* scip, /**< SCIP data structure */
870  LPINPUT* lpinput /**< LP reading data */
871  )
872 {
873  assert(lpinput != NULL);
874 
875  /* everything before first section is treated as comment */
876  do
877  {
878  /* get token */
879  if( !getNextToken(scip, lpinput) )
880  return SCIP_OKAY;
881  }
882  while( !isNewSection(scip, lpinput) );
883 
884  return SCIP_OKAY;
885 }
886 
887 /** reads an objective or constraint with name and coefficients */
888 static
890  SCIP* scip, /**< SCIP data structure */
891  LPINPUT* lpinput, /**< LP reading data */
892  SCIP_Bool isobjective, /**< indicates whether we are currently reading the coefficients of the objective */
893  char* name, /**< pointer to store the name of the line; must be at least of size
894  * LP_MAX_LINELEN */
895  int* coefssize, /**< size of vars and coefs arrays */
896  SCIP_VAR*** vars, /**< pointer to store the array with variables (must be freed by caller) */
897  SCIP_Real** coefs, /**< pointer to store the array with coefficients (must be freed by caller) */
898  int* ncoefs, /**< pointer to store the number of coefficients */
899  int* quadcoefssize, /**< size of quadvars1, quadvars2, quadcoefs arrays */
900  SCIP_VAR*** quadvars1, /**< pointer to store the array with first variables in quadratic terms (must be freed by caller) */
901  SCIP_VAR*** quadvars2, /**< pointer to store the array with second variables in quadratic terms (must be freed by caller) */
902  SCIP_Real** quadcoefs, /**< pointer to store the array with coefficients in quadratic terms (must be freed by caller) */
903  int* nquadcoefs, /**< pointer to store the number of quadratic coefficients */
904  SCIP_Real* objoffset, /**< pointer to store an objective offset (or NULL if ! isobjective) */
905  SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
906  )
907 {
908  SCIP_VAR* var = NULL;
909  SCIP_Bool havesign;
910  SCIP_Bool havevalue;
911  SCIP_Bool haveobjoffset = FALSE;
912  SCIP_Real coef;
913  int coefsign;
914  SCIP_Bool inquadpart;
915  SCIP_VAR* firstquadvar;
916 
917  assert(lpinput != NULL);
918  assert(name != NULL);
919  assert(coefssize != NULL);
920  assert(vars != NULL);
921  assert(coefs != NULL);
922  assert(ncoefs != NULL);
923  assert(quadcoefssize != NULL);
924  assert(quadvars1 != NULL);
925  assert(quadvars2 != NULL);
926  assert(quadcoefs != NULL);
927  assert(nquadcoefs != NULL);
928  assert(!isobjective || objoffset != NULL);
929  assert(newsection != NULL);
930 
931  *coefssize = 0;
932  *vars = NULL;
933  *coefs = NULL;
934  *quadvars1 = NULL;
935  *quadvars2 = NULL;
936  *quadcoefs = NULL;
937  *name = '\0';
938  *ncoefs = 0;
939  *quadcoefssize = 0;
940  *nquadcoefs = 0;
941  *newsection = FALSE;
942  inquadpart = FALSE;
943 
944  if( isobjective )
945  {
946  assert(objoffset != NULL);
947  *objoffset = 0.0;
948  }
949 
950  /* read the first token, which may be the name of the line */
951  if( getNextToken(scip, lpinput) )
952  {
953  /* check if we reached a new section */
954  if( isNewSection(scip, lpinput) )
955  {
956  *newsection = TRUE;
957  return SCIP_OKAY;
958  }
959 
960  /* remember the token in the token buffer */
961  swapTokenBuffer(lpinput);
962 
963  /* get the next token and check, whether it is a colon */
964  if( getNextToken(scip, lpinput) )
965  {
966  if( strcmp(lpinput->token, ":") == 0 )
967  {
968  /* the second token was a colon: the first token is the line name */
969  (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', LP_MAX_LINELEN);
970 
971  name[LP_MAX_LINELEN - 1] = '\0';
972  SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", lpinput->linenumber, name);
973  }
974  else
975  {
976  /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
977  pushToken(lpinput);
978  pushBufferToken(lpinput);
979  }
980  }
981  else
982  {
983  /* there was only one token left: push it back onto the token stack and parse it as coefficient */
984  pushBufferToken(lpinput);
985  }
986  }
987 
988  /* initialize buffers for storing the coefficients */
989  *coefssize = LP_INIT_COEFSSIZE;
990  SCIP_CALL( SCIPallocBlockMemoryArray(scip, vars, *coefssize) );
991  SCIP_CALL( SCIPallocBlockMemoryArray(scip, coefs, *coefssize) );
992 
993  *quadcoefssize = LP_INIT_QUADCOEFSSIZE;
994  SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadvars1, *quadcoefssize) );
995  SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadvars2, *quadcoefssize) );
996  SCIP_CALL( SCIPallocBlockMemoryArray(scip, quadcoefs, *quadcoefssize) );
997 
998  /* read the coefficients */
999  coefsign = +1;
1000  coef = 1.0;
1001  havesign = FALSE;
1002  havevalue = FALSE;
1003  firstquadvar = NULL;
1004  *ncoefs = 0;
1005  *nquadcoefs = 0;
1006  while( getNextToken(scip, lpinput) )
1007  {
1008  /* check whether we reached a new sign token */
1009  if( lpinput->token[1] == '\0' && ( *lpinput->token == '+' || *lpinput->token == '-' ) )
1010  {
1011  /* check whether we found an objective offset */
1012  if( isobjective && havevalue && var == NULL )
1013  {
1014  assert( objoffset != NULL );
1015  if( haveobjoffset )
1016  {
1017  syntaxError(scip, lpinput, "two objective offsets.");
1018  return SCIP_OKAY;
1019  }
1020  SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * coef);
1021  haveobjoffset = TRUE;
1022  *objoffset = coefsign * coef;
1023  }
1024  }
1025 
1026  /* check if we read a sign */
1027  if( isSign(lpinput, &coefsign) )
1028  {
1029  if( havevalue )
1030  {
1031  syntaxError(scip, lpinput, "sign after value without variable.");
1032  return SCIP_OKAY;
1033  }
1034 
1035  SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", lpinput->linenumber, coefsign);
1036  havesign = TRUE;
1037  continue;
1038  }
1039 
1040  /* check if we read a value */
1041  if( isValue(scip, lpinput, &coef) )
1042  {
1043  SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", lpinput->linenumber, coef, coefsign);
1044  if( havevalue )
1045  {
1046  syntaxError(scip, lpinput, "two consecutive values.");
1047  return SCIP_OKAY;
1048  }
1049  havevalue = TRUE;
1050  continue;
1051  }
1052 
1053  /* check if we reached an equation sense */
1054  if( isSense(lpinput, NULL) )
1055  {
1056  if( isobjective )
1057  {
1058  syntaxError(scip, lpinput, "no sense allowed in objective");
1059  return SCIP_OKAY;
1060  }
1061 
1062  if( havevalue )
1063  {
1064  syntaxError(scip, lpinput, "no constant values allowed for constraints in lp file format");
1065  return SCIP_OKAY;
1066  }
1067 
1068  if( havesign )
1069  {
1070  syntaxError(scip, lpinput, "constaint has sign without a variable");
1071  return SCIP_OKAY;
1072  }
1073 
1074  /* put the sense back onto the token stack */
1075  pushToken(lpinput);
1076  break;
1077  }
1078 
1079  /* check if we reached a new section, that will be only allowed when having no current sign and value and if we
1080  * are not in the qudratic part
1081  */
1082  if( (isobjective || (!havevalue && !havesign)) && !inquadpart && isNewSection(scip, lpinput) )
1083  {
1084  if( havesign && !havevalue )
1085  {
1086  SCIPwarningMessage(scip, "skipped single sign %c without value or variable in objective\n", coefsign == 1 ? '+' : '-');
1087  }
1088  else if( isobjective && havevalue && !SCIPisZero(scip, coef) )
1089  {
1090  assert( objoffset != NULL );
1091  /* check whether we found an objective offset */
1092  if( haveobjoffset )
1093  {
1094  syntaxError(scip, lpinput, "two objective offsets.");
1095  return SCIP_OKAY;
1096  }
1097  SCIPdebugMsg(scip, "(line %d) read objective offset %g\n", lpinput->linenumber, coefsign * coef);
1098  *objoffset = coefsign * coef;
1099  }
1100 
1101  *newsection = TRUE;
1102  return SCIP_OKAY;
1103  }
1104 
1105  /* check if we start a quadratic part */
1106  if( *lpinput->token == '[' )
1107  {
1108  if( inquadpart )
1109  {
1110  syntaxError(scip, lpinput, "cannot start quadratic part while already in quadratic part.");
1111  return SCIP_OKAY;
1112  }
1113  if( havesign && coefsign != +1 )
1114  {
1115  syntaxError(scip, lpinput, "cannot have '-' in front of quadratic part.");
1116  return SCIP_OKAY;
1117  }
1118  if( havevalue )
1119  {
1120  syntaxError(scip, lpinput, "cannot have value in front of quadratic part.");
1121  return SCIP_OKAY;
1122  }
1123 
1124  SCIPdebugMsg(scip, "(line %d) start quadratic part\n", lpinput->linenumber);
1125  inquadpart = TRUE;
1126  continue;
1127  }
1128 
1129  /* check if we end a quadratic part */
1130  if( *lpinput->token == ']' )
1131  {
1132  if( !inquadpart )
1133  {
1134  syntaxError(scip, lpinput, "cannot end quadratic part before starting one.");
1135  return SCIP_OKAY;
1136  }
1137  if( havesign || havevalue || firstquadvar != NULL )
1138  {
1139  if( firstquadvar == NULL )
1140  {
1141  syntaxError(scip, lpinput, "expected value or first quadratic variable.");
1142  }
1143  else
1144  {
1145  syntaxError(scip, lpinput, "expected second quadratic variable.");
1146  }
1147  return SCIP_OKAY;
1148  }
1149 
1150  SCIPdebugMsg(scip, "(line %d) end quadratic part\n", lpinput->linenumber);
1151  inquadpart = FALSE;
1152 
1153  if( isobjective )
1154  {
1155  /* quadratic part in objective has to end with '/2' */
1156  if( !getNextToken(scip, lpinput) )
1157  {
1158  syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
1159  return SCIP_OKAY;
1160  }
1161  if( strcmp(lpinput->token, "/2") == 0 )
1162  {
1163  SCIPdebugMsg(scip, "(line %d) saw '/2' or '/ 2' after quadratic part in objective\n", lpinput->linenumber);
1164  }
1165  else if( *lpinput->token == '/' )
1166  {
1167  /* maybe it says '/ 2' */
1168  if( !getNextToken(scip, lpinput) || *lpinput->token != '2' )
1169  {
1170  syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
1171  return SCIP_OKAY;
1172  }
1173  SCIPdebugMsg(scip, "(line %d) saw '/ 2' after quadratic part in objective\n", lpinput->linenumber);
1174  }
1175  else
1176  {
1177  syntaxError(scip, lpinput, "expected '/2' or '/ 2' after end of quadratic part in objective.");
1178  return SCIP_OKAY;
1179  }
1180  }
1181 
1182  continue;
1183  }
1184 
1185  /* check if we are in between two quadratic variables */
1186  if( *lpinput->token == '*' )
1187  {
1188  if( !inquadpart )
1189  {
1190  syntaxError(scip, lpinput, "cannot have '*' outside of quadratic part.");
1191  return SCIP_OKAY;
1192  }
1193  if( firstquadvar == NULL )
1194  {
1195  syntaxError(scip, lpinput, "cannot have '*' before first variable in quadratic term.");
1196  return SCIP_OKAY;
1197  }
1198 
1199  continue;
1200  }
1201 
1202  /* all but the first coefficient need a sign */
1203  if( !inquadpart && *ncoefs > 0 && !havesign )
1204  {
1205  syntaxError(scip, lpinput, "expected sign ('+' or '-') or sense ('<' or '>').");
1206  return SCIP_OKAY;
1207  }
1208  if( inquadpart && *nquadcoefs > 0 && !havesign )
1209  {
1210  syntaxError(scip, lpinput, "expected sign ('+' or '-').");
1211  return SCIP_OKAY;
1212  }
1213 
1214  /* check if the last variable should be squared */
1215  var = NULL;
1216  if( *lpinput->token == '^' )
1217  {
1218  if( !inquadpart )
1219  {
1220  syntaxError(scip, lpinput, "cannot have squares ('^2') outside of quadratic part.");
1221  return SCIP_OKAY;
1222  }
1223  if( firstquadvar == NULL )
1224  {
1225  syntaxError(scip, lpinput, "cannot have square '^2' before variable.");
1226  return SCIP_OKAY;
1227  }
1228 
1229  var = firstquadvar;
1230  }
1231  else
1232  {
1233  /* the token is a variable name: get the corresponding variable (or create a new one) */
1234  SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
1235  }
1236 
1237  if( !inquadpart )
1238  {
1239  /* insert the linear coefficient */
1240  SCIPdebugMsg(scip, "(line %d) read linear coefficient: %+g<%s>\n", lpinput->linenumber, coefsign * coef, SCIPvarGetName(var));
1241  if( !SCIPisZero(scip, coef) )
1242  {
1243  /* resize the vars and coefs array if needed */
1244  if( *ncoefs >= *coefssize )
1245  {
1246  int oldcoefssize;
1247  oldcoefssize = *coefssize;
1248  *coefssize *= 2;
1249  *coefssize = MAX(*coefssize, (*ncoefs)+1);
1250  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, vars, oldcoefssize, *coefssize) );
1251  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, coefs, oldcoefssize, *coefssize) );
1252  }
1253  assert(*ncoefs < *coefssize);
1254 
1255  /* add coefficient */
1256  (*vars)[*ncoefs] = var;
1257  (*coefs)[*ncoefs] = coefsign * coef;
1258  (*ncoefs)++;
1259  }
1260  }
1261  else
1262  {
1263  if( firstquadvar == NULL )
1264  {
1265  /* if first quadratic variable read, store it and continue; expect second one in next round */
1266  firstquadvar = var;
1267  continue;
1268  }
1269 
1270  /* insert the quadratic coefficient */
1271  SCIPdebugMsg(scip, "(line %d) read quadratic coefficient: %+g<%s><%s>\n", lpinput->linenumber, (isobjective ? 0.5 : 1) * coefsign * coef, SCIPvarGetName(firstquadvar), SCIPvarGetName(var));
1272  if( !SCIPisZero(scip, coef) )
1273  {
1274  /* resize the vars and coefs array if needed */
1275  if( *nquadcoefs >= *quadcoefssize )
1276  {
1277  int oldquadcoefssize;
1278  oldquadcoefssize = *quadcoefssize;
1279  *quadcoefssize *= 2;
1280  *quadcoefssize = MAX(*quadcoefssize, (*nquadcoefs)+1);
1281  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadcoefs, oldquadcoefssize, *quadcoefssize) );
1282  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadvars2, oldquadcoefssize, *quadcoefssize) );
1283  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, quadvars1, oldquadcoefssize, *quadcoefssize) );
1284  }
1285  assert(*nquadcoefs < *quadcoefssize);
1286 
1287  /* add coefficient */
1288  (*quadvars1)[*nquadcoefs] = firstquadvar;
1289  (*quadvars2)[*nquadcoefs] = var;
1290  (*quadcoefs)[*nquadcoefs] = coefsign * coef;
1291  if( isobjective )
1292  (*quadcoefs)[*nquadcoefs] /= 2.0;
1293  (*nquadcoefs)++;
1294  }
1295  }
1296 
1297  /* reset the flags and coefficient value for the next coefficient */
1298  coefsign = +1;
1299  coef = 1.0;
1300  havesign = FALSE;
1301  havevalue = FALSE;
1302  firstquadvar = NULL;
1303  }
1304 
1305  return SCIP_OKAY;
1306 }
1307 
1308 /** reads the objective section */
1309 static
1311  SCIP* scip, /**< SCIP data structure */
1312  LPINPUT* lpinput /**< LP reading data */
1313  )
1314 {
1315  char name[LP_MAX_LINELEN];
1316  SCIP_VAR** vars;
1317  SCIP_Real* coefs;
1318  SCIP_VAR** quadvars1;
1319  SCIP_VAR** quadvars2;
1320  SCIP_Real* quadcoefs;
1321  SCIP_Bool newsection;
1322  SCIP_Real objoffset;
1323  int ncoefs;
1324  int coefssize;
1325  int quadcoefssize;
1326  int nquadcoefs;
1327 
1328  assert(lpinput != NULL);
1329 
1330  /* read the objective coefficients */
1331  SCIP_CALL( readCoefficients(scip, lpinput, TRUE, name, &coefssize, &vars, &coefs, &ncoefs,
1332  &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, &objoffset, &newsection) );
1333 
1334  if( ! SCIPisZero(scip, objoffset) )
1335  {
1336  SCIP_CALL( SCIPaddOrigObjoffset(scip, objoffset) );
1337  }
1338 
1339  if( !hasError(lpinput) )
1340  {
1341  int i;
1342 
1343  /* set the linear objective values */
1344  for( i = 0; i < ncoefs; ++i )
1345  {
1346  assert(vars != NULL); /* for lint */
1347  assert(coefs != NULL);
1348  SCIP_CALL( SCIPchgVarObj(scip, vars[i], SCIPvarGetObj(vars[i]) + coefs[i]) );
1349  }
1350 
1351  /* insert dummy variable and constraint to represent quadratic part of objective; note that
1352  * reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model constraints and variables, not
1353  * to an auxiliary objective constraint (otherwise it can happen that an auxiliary objective variable is loose
1354  * with infinite best bound, triggering the problem that an LP that is unbounded because of loose variables with
1355  * infinite best bound cannot be solved)
1356  */
1357  if( nquadcoefs > 0 )
1358  {
1359  SCIP_VAR* quadobjvar;
1360  SCIP_CONS* quadobjcons;
1361  SCIP_Real lhs;
1362  SCIP_Real rhs;
1363  SCIP_Real minusone;
1364 
1365  SCIP_CALL( SCIPcreateVar(scip, &quadobjvar, "quadobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1367  SCIP_CALL( SCIPaddVar(scip, quadobjvar) );
1368 
1369  if( lpinput->objsense == SCIP_OBJSENSE_MINIMIZE )
1370  {
1371  lhs = -SCIPinfinity(scip);
1372  rhs = 0.0;
1373  }
1374  else
1375  {
1376  lhs = 0.0;
1377  rhs = SCIPinfinity(scip);
1378  }
1379 
1380  minusone = -1.0;
1381  SCIP_CALL( SCIPcreateConsQuadraticNonlinear(scip, &quadobjcons, "quadobj", 1, &quadobjvar, &minusone, nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1382  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1383 
1384  SCIP_CALL( SCIPaddCons(scip, quadobjcons) );
1385  SCIPdebugMsg(scip, "(line %d) added constraint <%s> to represent quadratic objective: ", lpinput->linenumber, SCIPconsGetName(quadobjcons));
1386  SCIPdebugPrintCons(scip, quadobjcons, NULL);
1387 
1388  SCIP_CALL( SCIPreleaseCons(scip, &quadobjcons) );
1389  SCIP_CALL( SCIPreleaseVar(scip, &quadobjvar) );
1390  }
1391  }
1392 
1393  /* free memory */
1394  SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
1395  SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
1396  SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
1397  SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
1398  SCIPfreeBlockMemoryArrayNull(scip, &coefs, coefssize);
1399 
1400  return SCIP_OKAY; /*lint !e438*/
1401 }
1402 
1403 /** create indicator constraint */
1404 static
1406  SCIP* scip, /**< SCIP data structure */
1407  LPINPUT* lpinput, /**< LP reading data */
1408  const char* name, /**< name of indicator constraint */
1409  SCIP_VAR* binvar, /**< binary indicator variable */
1410  SCIP_Real binvalue /**< value of indicator part (0/1) */
1411  )
1412 {
1413  char name2[LP_MAX_LINELEN];
1414  SCIP_VAR** linvars;
1415  SCIP_Real* lincoefs;
1416  SCIP_VAR** quadvars1;
1417  SCIP_VAR** quadvars2;
1418  SCIP_Real* quadcoefs;
1419  SCIP_CONS* cons;
1420  SCIP_RETCODE retcode;
1421  LPSENSE linsense;
1422  SCIP_Real linsidevalue;
1423  SCIP_Real linrhs;
1424  SCIP_Bool newsection;
1425  SCIP_Bool linConsEQ;
1426  SCIP_Bool initial;
1427  SCIP_Bool separate;
1428  SCIP_Bool enforce;
1429  SCIP_Bool check;
1430  SCIP_Bool propagate;
1431  SCIP_Bool local;
1432  SCIP_Bool dynamic;
1433  SCIP_Bool removable;
1434  int lincoefssize;
1435  int quadcoefssize;
1436  int nlincoefs;
1437  int nquadcoefs;
1438  int linsidesign;
1439  int j;
1440 
1441  assert( lpinput != NULL );
1442  assert( binvar != NULL );
1443 
1444  retcode = SCIP_OKAY;
1445 
1446  /* check that binvalue is 0 or 1 */
1447  if( !SCIPisFeasEQ(scip, binvalue, 0.0) && !SCIPisFeasEQ(scip, binvalue, 1.0) )
1448  {
1449  syntaxError(scip, lpinput, "value for binary variable must be '0' or '1'.");
1450  return SCIP_OKAY;
1451  }
1452 
1453  if( SCIPisFeasEQ(scip, binvalue, 0.0) )
1454  {
1455  SCIP_VAR* negbinvar;
1456  SCIP_Bool infeasible;
1457 
1458  /* At this point we force the variable binvar to be binary, since we need the negated variable. We have to check
1459  * later whether the type of the variable specified in the file agrees with this specification.
1460  */
1461  /* check whether bounds are correct - might already been set if variable is used in another indicator constraint */
1462  if( SCIPvarGetLbGlobal(binvar) < 0.0 )
1463  SCIP_CALL( SCIPchgVarLb(scip, binvar, 0.0) );
1464  if( SCIPvarGetUbGlobal(binvar) > 1.0 )
1465  SCIP_CALL( SCIPchgVarUb(scip, binvar, 1.0) );
1466  SCIP_CALL( SCIPchgVarType(scip, binvar, SCIP_VARTYPE_BINARY, &infeasible) );
1467  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1468 
1469  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
1470  binvar = negbinvar;
1471  assert( binvar != NULL );
1472  }
1473 
1474  /* read linear constraint */
1475  SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name2, &lincoefssize, &linvars, &lincoefs, &nlincoefs,
1476  &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, NULL, &newsection) );
1477 
1478  if( hasError(lpinput) )
1479  goto TERMINATE;
1480  if( newsection )
1481  {
1482  syntaxError(scip, lpinput, "expected constraint.");
1483  goto TERMINATE;
1484  }
1485  if( nquadcoefs > 0 )
1486  {
1487  /* @todo could introduce auxiliary variable and move quadratic part into quadratic constraint? */
1488  syntaxError(scip, lpinput, "quadratic indicator constraints not supported.");
1489  goto TERMINATE;
1490  }
1491  if( name2[0] != '\0' )
1492  {
1493  syntaxError(scip, lpinput, "did not expect name for linear constraint.");
1494  goto TERMINATE;
1495  }
1496 
1497  /* read the constraint sense */
1498  if( !getNextToken(scip, lpinput) )
1499  {
1500  syntaxError(scip, lpinput, "missing constraint sense.");
1501  goto TERMINATE;
1502  }
1503  if( !isSense(lpinput, &linsense) )
1504  {
1505  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1506  goto TERMINATE;
1507  }
1508  assert(linsense == LP_SENSE_GE || linsense == LP_SENSE_LE || linsense == LP_SENSE_EQ); /*lint !e530*/
1509 
1510  /* read the right hand side */
1511  linsidesign = +1;
1512  if( !getNextToken(scip, lpinput) )
1513  {
1514  syntaxError(scip, lpinput, "missing right hand side.");
1515  goto TERMINATE;
1516  }
1517  if( isSign(lpinput, &linsidesign) )
1518  {
1519  if( !getNextToken(scip, lpinput) )
1520  {
1521  syntaxError(scip, lpinput, "missing value of right hand side.");
1522  goto TERMINATE;
1523  }
1524  }
1525  if( !isValue(scip, lpinput, &linsidevalue) )
1526  {
1527  syntaxError(scip, lpinput, "expected value for right hand side.");
1528  goto TERMINATE;
1529  }
1530  linsidevalue *= linsidesign;
1531 
1532  /* assign the left and right hand side, depending on the constraint sense */
1533  linConsEQ = FALSE;
1534  switch( linsense ) /*lint !e530*/
1535  {
1536  case LP_SENSE_GE:
1537  linrhs = -linsidevalue;
1538  for( j = 0; j < nlincoefs; ++j )
1539  lincoefs[j] *= -1;
1540  break;
1541  case LP_SENSE_LE:
1542  linrhs = linsidevalue;
1543  break;
1544  case LP_SENSE_EQ:
1545  linConsEQ = TRUE;
1546  linrhs = linsidevalue;
1547  break;
1548  case LP_SENSE_NOTHING:
1549  default:
1550  /* this case cannot occur because it is caught by the syntax check method isSense() above */
1551  SCIPerrorMessage("invalid constraint sense <%d>\n", linsense);
1552  return SCIP_INVALIDDATA;
1553  }
1554  assert(lincoefs != NULL);
1555 
1556  /* create and add the indicator constraint */
1557  initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
1558  separate = TRUE;
1559  enforce = !lpinput->inusercuts;
1560  check = !lpinput->inusercuts;
1561  propagate = TRUE;
1562  local = FALSE;
1563  dynamic = lpinput->dynamicconss;
1564  removable = lpinput->dynamicrows || lpinput->inusercuts;
1565 
1566  retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlincoefs, linvars, lincoefs, linrhs,
1567  initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE);
1568 
1569  if( retcode != SCIP_OKAY )
1570  goto TERMINATE;
1571 
1572  SCIP_CALL( SCIPaddCons(scip, cons) );
1573  SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
1574  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1575  SCIPdebugPrintCons(scip, cons, NULL);
1576  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1577 
1578  /* create second constraint if it was an equation */
1579  if( linConsEQ )
1580  {
1581  char newname[SCIP_MAXSTRLEN];
1582 
1583  (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_eqneg", name);
1584 
1585  for( j = 0; j < nlincoefs; ++j )
1586  lincoefs[j] *= -1;
1587  linrhs *= -1;
1588  retcode = SCIPcreateConsIndicator(scip, &cons, newname, binvar, nlincoefs, linvars, lincoefs, linrhs,
1589  initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE);
1590 
1591  if( retcode != SCIP_OKAY )
1592  goto TERMINATE;
1593 
1594  SCIP_CALL( SCIPaddCons(scip, cons) );
1595  SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
1596  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1597  SCIPdebugPrintCons(scip, cons, NULL);
1598  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1599  }
1600 
1601  TERMINATE:
1602  /* free memory */
1603  SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
1604  SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
1605  SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
1606  SCIPfreeBlockMemoryArrayNull(scip, &lincoefs, lincoefssize);
1607  SCIPfreeBlockMemoryArrayNull(scip, &linvars, lincoefssize);
1608 
1609  SCIP_CALL( retcode );
1610 
1611  return SCIP_OKAY;
1612 }
1613 
1614 /** reads the constraints section
1615  *
1616  * Read linear and indicator constraints.
1617  *
1618  * The CPLEX manual says that indicator constraints are of the following form:
1619  *
1620  * [constraintname:] binaryvariable = value -> linear constraint
1621  *
1622  * We also accept "<->".
1623  */
1624 static
1626  SCIP* scip, /**< SCIP data structure */
1627  LPINPUT* lpinput /**< LP reading data */
1628  )
1629 {
1630  char name[LP_MAX_LINELEN];
1631  SCIP_CONS* cons;
1632  SCIP_VAR** vars;
1633  SCIP_Real* coefs;
1634  SCIP_VAR** quadvars1;
1635  SCIP_VAR** quadvars2;
1636  SCIP_Real* quadcoefs;
1637  LPSENSE sense;
1638  SCIP_RETCODE retcode;
1639  SCIP_Real sidevalue;
1640  SCIP_Real lhs;
1641  SCIP_Real rhs;
1642  SCIP_Bool newsection;
1643  SCIP_Bool initial;
1644  SCIP_Bool separate;
1645  SCIP_Bool enforce;
1646  SCIP_Bool check;
1647  SCIP_Bool propagate;
1648  SCIP_Bool local;
1649  SCIP_Bool modifiable;
1650  SCIP_Bool dynamic;
1651  SCIP_Bool removable;
1652  SCIP_Bool isIndicatorCons;
1653  int ncoefs;
1654  int nquadcoefs;
1655  int sidesign;
1656  int quadcoefssize;
1657  int coefssize;
1658 
1659  assert(lpinput != NULL);
1660 
1661  retcode = SCIP_OKAY;
1662 
1663  /* read coefficients */
1664  SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name, &coefssize, &vars, &coefs, &ncoefs,
1665  &quadcoefssize, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, NULL, &newsection) );
1666 
1667  if( hasError(lpinput) )
1668  goto TERMINATE;
1669  if( newsection )
1670  {
1671  if( ncoefs > 0 || nquadcoefs > 0 )
1672  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1673  goto TERMINATE;
1674  }
1675 
1676  /* read the constraint sense */
1677  if( !getNextToken(scip, lpinput) )
1678  {
1679  syntaxError(scip, lpinput, "missing constraint sense.");
1680  goto TERMINATE;
1681  }
1682  if( !isSense(lpinput, &sense) )
1683  {
1684  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1685  goto TERMINATE;
1686  }
1687  assert(sense == LP_SENSE_GE || sense == LP_SENSE_LE || sense == LP_SENSE_EQ); /*lint !e530*/
1688 
1689  /* read the right hand side */
1690  sidesign = +1;
1691  if( !getNextToken(scip, lpinput) )
1692  {
1693  syntaxError(scip, lpinput, "missing right hand side.");
1694  goto TERMINATE;
1695  }
1696  if( isSign(lpinput, &sidesign) )
1697  {
1698  if( !getNextToken(scip, lpinput) )
1699  {
1700  syntaxError(scip, lpinput, "missing value of right hand side.");
1701  goto TERMINATE;
1702  }
1703  }
1704  if( !isValue(scip, lpinput, &sidevalue) )
1705  {
1706  syntaxError(scip, lpinput, "expected value as right hand side.");
1707  goto TERMINATE;
1708  }
1709  sidevalue *= sidesign;
1710 
1711  /* assign the left and right hand side, depending on the constraint sense */
1712  switch( sense ) /*lint !e530*/
1713  {
1714  case LP_SENSE_GE:
1715  lhs = sidevalue;
1716  rhs = SCIPinfinity(scip);
1717  break;
1718  case LP_SENSE_LE:
1719  lhs = -SCIPinfinity(scip);
1720  rhs = sidevalue;
1721  break;
1722  case LP_SENSE_EQ:
1723  lhs = sidevalue;
1724  rhs = sidevalue;
1725  break;
1726  case LP_SENSE_NOTHING:
1727  default:
1728  /* this case cannot occur because it is caught by the syntax check method isSense() above */
1729  SCIPerrorMessage("invalid constraint sense <%d>.\n", sense);
1730  return SCIP_INVALIDDATA;
1731  }
1732 
1733  /* check whether we read the first part of an indicator constraint */
1734  isIndicatorCons = FALSE;
1735  if ( getNextToken(scip, lpinput) && !isNewSection(scip, lpinput) )
1736  {
1737  /* check whether we have '<' from a "<->" string */
1738  if ( *lpinput->token == '<' )
1739  {
1740  int linepos = lpinput->linepos-1;
1741 
1742  /* check next token - cannot be a new section */
1743  if ( getNextToken(scip, lpinput) )
1744  {
1745  /* check for "<-" */
1746  if ( *lpinput->token == '-' )
1747  {
1748  /* check next token - cannot be a new section */
1749  if ( getNextToken(scip, lpinput) )
1750  {
1751  /* check for "<->" */
1752  if ( *lpinput->token == '>' )
1753  {
1754  lpinput->linepos = linepos;
1755  (void) SCIPsnprintf(lpinput->token, 2, "<");
1756  syntaxError(scip, lpinput,
1757  "SCIP does not support equivalence (<->) indicator constraints; consider using the \"->\" form.");
1758  goto TERMINATE;
1759  }
1760  }
1761  }
1762  }
1763  /* reset the lpinput for further usage as we have no indicator constraint */
1764  lpinput->linepos = linepos;
1765  (void) SCIPsnprintf(lpinput->token, 2, "<");
1766  }
1767 
1768  /* check for "->" */
1769  if ( *lpinput->token == '-' )
1770  {
1771  /* remember '-' in token buffer */
1772  swapTokenBuffer(lpinput);
1773 
1774  /* check next token - cannot be a new section */
1775  if( getNextToken(scip, lpinput) )
1776  {
1777  /* check for "->" */
1778  if ( *lpinput->token == '>' )
1779  isIndicatorCons = TRUE;
1780  else
1781  {
1782  /* push back last token and '-' */
1783  pushToken(lpinput);
1784  pushBufferToken(lpinput);
1785  }
1786  }
1787  else
1788  pushBufferToken(lpinput);
1789  }
1790  else
1791  pushToken(lpinput);
1792  }
1793 
1794  if( !isIndicatorCons )
1795  {
1796  /* create and add the linear constraint */
1797  initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
1798  separate = TRUE;
1799  enforce = !lpinput->inusercuts;
1800  check = !lpinput->inusercuts;
1801  propagate = TRUE;
1802  local = FALSE;
1803  modifiable = FALSE;
1804  dynamic = lpinput->dynamicconss;
1805  removable = lpinput->dynamicrows || lpinput->inusercuts;
1806  if( nquadcoefs == 0 )
1807  {
1808  retcode = SCIPcreateConsLinear(scip, &cons, name, ncoefs, vars, coefs, lhs, rhs,
1809  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1810  }
1811  else
1812  {
1813  retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, name, ncoefs, vars, coefs,
1814  nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1815  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
1816  }
1817 
1818  if( retcode != SCIP_OKAY )
1819  goto TERMINATE;
1820 
1821  SCIP_CALL( SCIPaddCons(scip, cons) );
1822  SCIPdebugMsg(scip, "(line %d) created constraint%s: ", lpinput->linenumber,
1823  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1824  SCIPdebugPrintCons(scip, cons, NULL);
1825  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1826  }
1827  else
1828  {
1829  /* now we should have an indicator constraint */
1830  if( ncoefs != 1 || nquadcoefs > 0 )
1831  {
1832  syntaxError(scip, lpinput, "Indicator part can only consist of one binary variable.");
1833  goto TERMINATE;
1834  }
1835  assert(coefs != NULL);
1836  if( !SCIPisEQ(scip, coefs[0], 1.0) )
1837  {
1838  syntaxError(scip, lpinput, "There cannot be a coefficient before the binary indicator variable.");
1839  goto TERMINATE;
1840  }
1841  if( sense != LP_SENSE_EQ )
1842  {
1843  syntaxError(scip, lpinput, "Indicator part cannot handle equations.");
1844  goto TERMINATE;
1845  }
1846  assert(vars != NULL);
1847  retcode = createIndicatorConstraint(scip, lpinput, name, vars[0], lhs);
1848  }
1849 
1850  TERMINATE:
1851  /* free memory */
1852  SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, quadcoefssize);
1853  SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, quadcoefssize);
1854  SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, quadcoefssize);
1855  SCIPfreeBlockMemoryArrayNull(scip, &coefs, coefssize);
1856  SCIPfreeBlockMemoryArrayNull(scip, &vars, coefssize);
1857 
1858  SCIP_CALL( retcode );
1859 
1860  return SCIP_OKAY;
1861 }
1862 
1863 /** reads the bounds section */
1864 static
1866  SCIP* scip, /**< SCIP data structure */
1867  LPINPUT* lpinput /**< LP reading data */
1868  )
1869 {
1870  assert(lpinput != NULL);
1871 
1872  while( getNextToken(scip, lpinput) )
1873  {
1874  SCIP_VAR* var;
1875  SCIP_Real value;
1876  SCIP_Real lb;
1877  SCIP_Real ub;
1878  int sign;
1879  SCIP_Bool hassign;
1880  LPSENSE leftsense;
1881 
1882  /* check if we reached a new section */
1883  if( isNewSection(scip, lpinput) )
1884  return SCIP_OKAY;
1885 
1886  /* default bounds are [0,+inf] */
1887  lb = 0.0;
1888  ub = SCIPinfinity(scip);
1889  leftsense = LP_SENSE_NOTHING;
1890 
1891  /* check if the first token is a sign */
1892  sign = +1;
1893  hassign = isSign(lpinput, &sign);
1894  if( hassign && !getNextToken(scip, lpinput) )
1895  {
1896  syntaxError(scip, lpinput, "expected value.");
1897  return SCIP_OKAY;
1898  }
1899 
1900  /* the first token must be either a value or a variable name */
1901  if( isValue(scip, lpinput, &value) )
1902  {
1903  /* first token is a value: the second token must be a sense */
1904  if( !getNextToken(scip, lpinput) || !isSense(lpinput, &leftsense) )
1905  {
1906  syntaxError(scip, lpinput, "expected bound sense '<=', '=', or '>='.");
1907  return SCIP_OKAY;
1908  }
1909 
1910  /* update the bound corresponding to the sense */
1911  switch( leftsense )
1912  {
1913  case LP_SENSE_GE:
1914  ub = sign * value;
1915  break;
1916  case LP_SENSE_LE:
1917  lb = sign * value;
1918  break;
1919  case LP_SENSE_EQ:
1920  lb = sign * value;
1921  ub = sign * value;
1922  break;
1923  case LP_SENSE_NOTHING:
1924  default:
1925  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1926  return SCIP_INVALIDDATA;
1927  }
1928  }
1929  else if( hassign )
1930  {
1931  syntaxError(scip, lpinput, "expected value.");
1932  return SCIP_OKAY;
1933  }
1934  else
1935  pushToken(lpinput);
1936 
1937  /* the next token must be a variable name */
1938  if( !getNextToken(scip, lpinput) )
1939  {
1940  syntaxError(scip, lpinput, "expected variable name.");
1941  return SCIP_OKAY;
1942  }
1943  SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
1944 
1945  /* the next token might be another sense, or the word "free" */
1946  if( getNextToken(scip, lpinput) )
1947  {
1948  LPSENSE rightsense;
1949 
1950  if( isSense(lpinput, &rightsense) )
1951  {
1952  /* check, if the senses fit */
1953  if( leftsense == LP_SENSE_NOTHING
1954  || (leftsense == LP_SENSE_LE && rightsense == LP_SENSE_LE)
1955  || (leftsense == LP_SENSE_GE && rightsense == LP_SENSE_GE) )
1956  {
1957  if( !getNextToken(scip, lpinput) )
1958  {
1959  syntaxError(scip, lpinput, "expected value or sign.");
1960  return SCIP_OKAY;
1961  }
1962 
1963  /* check if the next token is a sign */
1964  sign = +1;
1965  hassign = isSign(lpinput, &sign);
1966  if( hassign && !getNextToken(scip, lpinput) )
1967  {
1968  syntaxError(scip, lpinput, "expected value.");
1969  return SCIP_OKAY;
1970  }
1971 
1972  /* the next token must be a value */
1973  if( !isValue(scip, lpinput, &value) )
1974  {
1975  syntaxError(scip, lpinput, "expected value.");
1976  return SCIP_OKAY;
1977  }
1978 
1979  /* update the bound corresponding to the sense */
1980  switch( rightsense )
1981  {
1982  case LP_SENSE_GE:
1983  lb = sign * value;
1984  break;
1985  case LP_SENSE_LE:
1986  ub = sign * value;
1987  break;
1988  case LP_SENSE_EQ:
1989  lb = sign * value;
1990  ub = sign * value;
1991  break;
1992  case LP_SENSE_NOTHING:
1993  default:
1994  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1995  return SCIP_INVALIDDATA;
1996  }
1997  }
1998  else
1999  {
2000  syntaxError(scip, lpinput, "the two bound senses do not fit.");
2001  return SCIP_OKAY;
2002  }
2003  }
2004  else if( strcasecmp(lpinput->token, "FREE") == 0 )
2005  {
2006  if( leftsense != LP_SENSE_NOTHING )
2007  {
2008  syntaxError(scip, lpinput, "variable with bound is marked as 'free'.");
2009  return SCIP_OKAY;
2010  }
2011  lb = -SCIPinfinity(scip);
2012  ub = SCIPinfinity(scip);
2013  }
2014  else
2015  {
2016  /* the token was no sense: push it back to the token stack */
2017  pushToken(lpinput);
2018  }
2019  }
2020 
2021  /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
2022  if( lb != 0.0 )
2023  SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
2024  /*lint --e{777}*/
2025  if( ub != SCIPinfinity(scip) )
2026  SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
2027  SCIPdebugMsg(scip, "(line %d) new bounds: <%s>[%g,%g]\n", lpinput->linenumber, SCIPvarGetName(var),
2029  }
2030 
2031  return SCIP_OKAY;
2032 }
2033 
2034 /** reads the generals section */
2035 static
2037  SCIP* scip, /**< SCIP data structure */
2038  LPINPUT* lpinput /**< LP reading data */
2039  )
2040 {
2041  assert(lpinput != NULL);
2042 
2043  while( getNextToken(scip, lpinput) )
2044  {
2045  SCIP_VAR* var;
2046  SCIP_Real lb;
2047  SCIP_Real ub;
2048  SCIP_Bool created;
2049  SCIP_Bool infeasible;
2050 
2051  /* check if we reached a new section */
2052  if( isNewSection(scip, lpinput) )
2053  return SCIP_OKAY;
2054 
2055  /* the token must be the name of an existing variable */
2056  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
2057  if( created )
2058  {
2059  syntaxError(scip, lpinput, "unknown variable in generals section.");
2060  return SCIP_OKAY;
2061  }
2062 
2063  lb = SCIPvarGetLbGlobal(var);
2064  ub = SCIPvarGetUbGlobal(var);
2065 
2066  if( !SCIPisFeasIntegral(scip, lb) || !SCIPisFeasIntegral(scip, ub) )
2067  {
2068  SCIPwarningMessage(scip, "variable <%s> declared as integer has non-integral bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
2069  }
2070 
2071  /* mark the variable to be integral */
2072  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
2073  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
2074  }
2075 
2076  return SCIP_OKAY;
2077 }
2078 
2079 /** reads the binaries section */
2080 static
2082  SCIP* scip, /**< SCIP data structure */
2083  LPINPUT* lpinput /**< LP reading data */
2084  )
2085 {
2086  assert(lpinput != NULL);
2087 
2088  while( getNextToken(scip, lpinput) )
2089  {
2090  SCIP_VAR* var;
2091  SCIP_Real lb;
2092  SCIP_Real ub;
2093  SCIP_Bool created;
2094  SCIP_Bool infeasible;
2095 
2096  /* check if we reached a new section */
2097  if( isNewSection(scip, lpinput) )
2098  return SCIP_OKAY;
2099 
2100  /* the token must be the name of an existing variable */
2101  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
2102  if( created )
2103  {
2104  syntaxError(scip, lpinput, "unknown variable in binaries section.");
2105  return SCIP_OKAY;
2106  }
2107 
2108  lb = SCIPvarGetLbGlobal(var);
2109  ub = SCIPvarGetUbGlobal(var);
2110 
2111  if( (!SCIPisFeasZero(scip, lb) && !SCIPisFeasEQ(scip, lb, 1.0)) ||
2112  (!SCIPisFeasZero(scip, ub) && !SCIPisFeasEQ(scip, ub, 1.0) && !SCIPisInfinity(scip, ub)) )
2113  {
2114  SCIPwarningMessage(scip, "variable <%s> declared as binary has non-binary bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
2115  }
2116 
2117  /* mark the variable to be binary and change its bounds appropriately */
2118  if( SCIPvarGetLbGlobal(var) < 0.0 )
2119  {
2120  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
2121  }
2122  if( SCIPvarGetUbGlobal(var) > 1.0 )
2123  {
2124  SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
2125  }
2126  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
2127  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
2128  }
2129 
2130  return SCIP_OKAY;
2131 }
2132 
2133 /** reads the semi-continuous section */
2134 static
2136  SCIP* scip, /**< SCIP data structure */
2137  LPINPUT* lpinput /**< LP reading data */
2138  )
2139 {
2140  SCIP_Real oldlb;
2141  char name[SCIP_MAXSTRLEN];
2142  SCIP_CONS* cons;
2143  SCIP_VAR* var;
2144  SCIP_Bool created;
2145 
2146  SCIP_VAR* vars[2];
2147  SCIP_BOUNDTYPE boundtypes[2];
2148  SCIP_Real bounds[2];
2149 
2150  assert(lpinput != NULL);
2151 
2152  /* if section is titles "semi-continuous", then the parser breaks this into parts */
2153  if( strcasecmp(lpinput->token, "SEMI") == 0 )
2154  {
2155  if( !getNextToken(scip, lpinput) )
2156  {
2157  syntaxError(scip, lpinput, "unexpected end.");
2158  return SCIP_OKAY;
2159  }
2160 
2161  if( strcasecmp(lpinput->token, "-") == 0 )
2162  {
2163  if( !getNextToken(scip, lpinput) || strcasecmp(lpinput->token, "CONTINUOUS") != 0 )
2164  {
2165  syntaxError(scip, lpinput, "expected 'CONTINUOUS' after 'SEMI-'.");
2166  return SCIP_OKAY;
2167  }
2168  }
2169  else
2170  {
2171  pushToken(lpinput);
2172  }
2173  }
2174 
2175  while( getNextToken(scip, lpinput) )
2176  {
2177  /* check if we reached a new section */
2178  if( isNewSection(scip, lpinput) )
2179  return SCIP_OKAY;
2180 
2181  /* the token must be the name of an existing variable */
2182  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
2183  if( created )
2184  {
2185  syntaxError(scip, lpinput, "unknown variable in semi-continuous section.");
2186  return SCIP_OKAY;
2187  }
2188 
2189  if( SCIPvarGetLbGlobal(var) <= 0.0 )
2190  {
2191  SCIPdebugMsg(scip, "ignore semi-continuity of variable <%s> with negative lower bound %g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
2192  continue;
2193  }
2194 
2195  oldlb = SCIPvarGetLbGlobal(var);
2196 
2197  /* change the lower bound to 0.0 */
2198  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
2199 
2200  /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
2201  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
2202 
2203  vars[0] = var;
2204  vars[1] = var;
2205  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
2206  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
2207  bounds[0] = 0.0;
2208  bounds[1] = oldlb;
2209 
2210  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
2211  !(lpinput->dynamiccols), TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, lpinput->dynamicconss, lpinput->dynamiccols, FALSE) );
2212  SCIP_CALL( SCIPaddCons(scip, cons) );
2213 
2214  SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity of <%s>:\n\t", SCIPvarGetName(var));
2215  SCIPdebugPrintCons(scip, cons, NULL);
2216 
2217  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2218  }
2219 
2220  return SCIP_OKAY;
2221 }
2222 
2223 /** reads the sos section
2224  *
2225  * The format is as follows:
2226  *
2227  * SOS
2228  * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
2229  * ...
2230  * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
2231  * */
2232 static
2234  SCIP* scip, /**< SCIP data structure */
2235  LPINPUT* lpinput /**< LP reading data */
2236  )
2237 {
2238  SCIP_Bool initial, separate, enforce, check, propagate;
2239  SCIP_Bool local, dynamic, removable;
2240  char name[SCIP_MAXSTRLEN];
2241  int cnt = 0;
2242 
2243  assert(lpinput != NULL);
2244 
2245  /* standard settings for SOS constraints: */
2246  initial = lpinput->initialconss;
2247  separate = TRUE;
2248  enforce = TRUE;
2249  check = TRUE;
2250  propagate = TRUE;
2251  local = FALSE;
2252  dynamic = lpinput->dynamicconss;
2253  removable = lpinput->dynamicrows;
2254 
2255  while( getNextToken(scip, lpinput) )
2256  {
2257  int type = -1;
2258  SCIP_CONS* cons;
2259 
2260  /* check if we reached a new section */
2261  if( isNewSection(scip, lpinput) )
2262  return SCIP_OKAY;
2263 
2264  /* check for an SOS constraint name */
2265  *name = '\0';
2266 
2267  /* remember the token in the token buffer */
2268  swapTokenBuffer(lpinput);
2269 
2270  /* get the next token and check, whether it is a colon */
2271  if( getNextToken(scip, lpinput) )
2272  {
2273  if( strcmp(lpinput->token, ":") == 0 )
2274  {
2275  /* the second token was a colon: the first token is the constraint name */
2276  (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
2277 
2278  name[SCIP_MAXSTRLEN-1] = '\0';
2279  }
2280  else
2281  {
2282  /* the second token was no colon: push the tokens back onto the token stack and parse it next */
2283  pushToken(lpinput);
2284  pushBufferToken(lpinput);
2285  }
2286  }
2287  else
2288  {
2289  /* there was only one token left: push it back onto the token stack and parse it next */
2290  pushBufferToken(lpinput);
2291  }
2292 
2293  /* get type */
2294  if( !getNextToken(scip, lpinput) )
2295  {
2296  syntaxError(scip, lpinput, "expected SOS type: 'S1::' or 'S2::'.");
2297  return SCIP_OKAY;
2298  }
2299  /* check whether constraint name was left out */
2300  if( strcmp(lpinput->token, ":") == 0 )
2301  {
2302  /* we have to push twice ':' and once the type: */
2303  pushToken(lpinput);
2304  lpinput->token[0] = ':';
2305  lpinput->token[1] = '\0';
2306  pushToken(lpinput);
2307  swapTokenBuffer(lpinput);
2308 
2309  /* set artificial name */
2310  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d", ++cnt);
2311  }
2312 
2313  /* check whether it is type 1 or type 2 */
2314  if( strcmp(lpinput->token, "S1") == 0 )
2315  {
2316  type = 1;
2317  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2318  local, dynamic, removable, FALSE) );
2319  }
2320  else if( strcmp(lpinput->token, "S2") == 0 )
2321  {
2322  type = 2;
2323  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2324  local, dynamic, removable, FALSE) );
2325  }
2326  else
2327  {
2328  syntaxError(scip, lpinput, "SOS constraint type other than 1 or 2 appeared.");
2329  return SCIP_OKAY;
2330  }
2331  assert( type == 1 || type == 2 );
2332 
2333  SCIPdebugMsg(scip, "created SOS%d constraint <%s>\n", type, name);
2334 
2335  /* make sure that a colons follows */
2336  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2337  {
2338  syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
2339  return SCIP_OKAY;
2340  }
2341 
2342  /* make sure that another colons follows */
2343  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2344  {
2345  syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
2346  return SCIP_OKAY;
2347  }
2348 
2349  /* parse elements of SOS constraint */
2350  while( getNextToken(scip, lpinput) )
2351  {
2352  SCIP_VAR* var;
2353  SCIP_Real weight;
2354 
2355  /* check if we reached a new section */
2356  if( isNewSection(scip, lpinput) )
2357  break;
2358 
2359  /* remember the token in the token buffer */
2360  swapTokenBuffer(lpinput);
2361 
2362  /* get variable and colon */
2363  var = SCIPfindVar(scip, lpinput->tokenbuf);
2364 
2365  /* if token is a variable name */
2366  if( var == NULL )
2367  {
2368  pushBufferToken(lpinput);
2369  break;
2370  }
2371  else
2372  {
2373  SCIPdebugMsg(scip, "found variable <%s>\n", SCIPvarGetName(var));
2374  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2375  {
2376  syntaxError(scip, lpinput, "expected colon and weight.");
2377  return SCIP_OKAY;
2378  }
2379  /* check next token */
2380  if( !getNextToken(scip, lpinput) )
2381  {
2382  /* push back token, since it could be the name of a new constraint */
2383  pushToken(lpinput);
2384  pushBufferToken(lpinput);
2385  break;
2386  }
2387  else
2388  {
2389  int sign = +1;
2390 
2391  /* get sign */
2392  if( isSign(lpinput, &sign) )
2393  {
2394  (void) getNextToken(scip, lpinput);
2395  }
2396 
2397  /* get weight */
2398  if( !isValue(scip, lpinput, &weight) )
2399  {
2400  /* push back token, since it could be the name of a new constraint */
2401  pushToken(lpinput);
2402  pushBufferToken(lpinput);
2403  break;
2404  }
2405  else
2406  {
2407  /* we now know that we have a variable/weight pair -> add variable*/
2408  switch( type )
2409  {
2410  case 1:
2411  SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, sign * weight) );
2412  break;
2413  case 2:
2414  SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, sign * weight) );
2415  break;
2416  default:
2417  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2418  SCIPABORT();
2419  return SCIP_INVALIDDATA; /*lint !e527*/
2420  }
2421  SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
2422  }
2423  }
2424  }
2425  }
2426 
2427  /* add the SOS constraint */
2428  SCIP_CALL( SCIPaddCons(scip, cons) );
2429  SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", lpinput->linenumber, SCIPconsGetName(cons));
2430  SCIPdebugPrintCons(scip, cons, NULL);
2431  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2432  }
2433 
2434  return SCIP_OKAY;
2435 }
2436 
2437 /** reads an LP file
2438  *
2439  * @todo check whether variables forced to be binary for the creation of indicator constraints are
2440  * really specified to be binary (or general with 0/1 bounds) in the file.
2441  */
2442 static
2444  SCIP* scip, /**< SCIP data structure */
2445  LPINPUT* lpinput, /**< LP reading data */
2446  const char* filename /**< name of the input file */
2447  )
2448 {
2449  assert(lpinput != NULL);
2450 
2451  /* open file */
2452  lpinput->file = SCIPfopen(filename, "r");
2453  if( lpinput->file == NULL )
2454  {
2455  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2456  SCIPprintSysError(filename);
2457  return SCIP_NOFILE;
2458  }
2459 
2460  /* create problem */
2461  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
2462 
2463  /* parse the file */
2464  lpinput->section = LP_START;
2465  while( lpinput->section != LP_END && !hasError(lpinput) )
2466  {
2467  switch( lpinput->section )
2468  {
2469  case LP_START:
2470  SCIP_CALL( readStart(scip, lpinput) );
2471  break;
2472 
2473  case LP_OBJECTIVE:
2474  SCIP_CALL( readObjective(scip, lpinput) );
2475  break;
2476 
2477  case LP_CONSTRAINTS:
2478  SCIP_CALL( readConstraints(scip, lpinput) );
2479  break;
2480 
2481  case LP_BOUNDS:
2482  SCIP_CALL( readBounds(scip, lpinput) );
2483  break;
2484 
2485  case LP_GENERALS:
2486  SCIP_CALL( readGenerals(scip, lpinput) );
2487  break;
2488 
2489  case LP_BINARIES:
2490  SCIP_CALL( readBinaries(scip, lpinput) );
2491  break;
2492 
2493  case LP_SEMICONTINUOUS:
2494  SCIP_CALL( readSemicontinuous(scip, lpinput) );
2495  break;
2496 
2497  case LP_SOS:
2498  SCIP_CALL( readSos(scip, lpinput) );
2499  break;
2500 
2501  case LP_END: /* this is already handled in the while() loop */
2502  default:
2503  SCIPerrorMessage("invalid LP file section <%d>\n", lpinput->section);
2504  return SCIP_INVALIDDATA;
2505  }
2506  }
2507 
2508  /* close file */
2509  SCIPfclose(lpinput->file);
2510 
2511  return SCIP_OKAY;
2512 }
2513 
2514 
2515 /*
2516  * Local methods (for writing)
2517  */
2518 
2519 /** hash key retrieval function for variables */
2520 static
2521 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
2522 { /*lint --e{715}*/
2523  return elem;
2524 }
2525 
2526 /** returns TRUE iff the indices of both variables are equal */
2527 static
2528 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
2529 { /*lint --e{715}*/
2530  if( key1 == key2 )
2531  return TRUE;
2532  return FALSE;
2533 }
2534 
2535 /** returns the hash value of the key */
2536 static
2537 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
2538 { /*lint --e{715}*/
2539  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2540  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2541 }
2542 
2543 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
2544 static
2546  SCIP* scip, /**< SCIP data structure */
2547  SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
2548  SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
2549  int* nvars, /**< pointer to number of variables and values in vars and vals array */
2550  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
2551  SCIP_Bool transformed /**< transformed constraint? */
2552  )
2553 {
2554  int requiredsize;
2555  int v;
2556 
2557  assert(scip != NULL);
2558  assert(vars != NULL);
2559  assert(scalars != NULL);
2560  assert(*vars != NULL);
2561  assert(*scalars != NULL);
2562  assert(nvars != NULL);
2563  assert(constant != NULL);
2564 
2565  if( transformed )
2566  {
2567  SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
2568 
2569  if( requiredsize > *nvars )
2570  {
2571  SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
2572  SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
2573 
2574  SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
2575  assert( requiredsize <= *nvars );
2576  }
2577  }
2578  else
2579  {
2580  for( v = 0; v < *nvars; ++v )
2581  {
2582  SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
2583 
2584  /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
2585  * make sure we get the original variable in that case
2586  */
2587  if( SCIPvarGetStatus((*vars)[v]) == SCIP_VARSTATUS_NEGATED )
2588  {
2589  (*vars)[v] = SCIPvarGetNegatedVar((*vars)[v]);
2590  (*scalars)[v] *= -1.0;
2591  *constant += 1.0;
2592  }
2593  }
2594  }
2595  return SCIP_OKAY;
2596 }
2597 
2598 /** clears the given line buffer */
2599 static
2601  char* linebuffer, /**< line */
2602  int* linecnt /**< number of characters in line */
2603  )
2604 {
2605  assert( linebuffer != NULL );
2606  assert( linecnt != NULL );
2607 
2608  (*linecnt) = 0;
2609  linebuffer[0] = '\0';
2610 }
2611 
2612 /** ends the given line with '\\0' and prints it to the given file stream */
2613 static
2614 void endLine(
2615  SCIP* scip, /**< SCIP data structure */
2616  FILE* file, /**< output file (or NULL for standard output) */
2617  char* linebuffer, /**< line */
2618  int* linecnt /**< number of characters in line */
2619  )
2620 {
2621  assert( scip != NULL );
2622  assert( linebuffer != NULL );
2623  assert( linecnt != NULL );
2624  assert( 0 <= *linecnt && *linecnt < LP_MAX_PRINTLEN );
2625 
2626  if( (*linecnt) > 0 )
2627  {
2628  linebuffer[(*linecnt)] = '\0';
2629  SCIPinfoMessage(scip, file, "%s\n", linebuffer);
2630  clearLine(linebuffer, linecnt);
2631  }
2632 }
2633 
2634 /** appends extension to line and prints it to the give file stream if the
2635  * line exceeded the length given in the define LP_PRINTLEN */
2636 static
2638  SCIP* scip, /**< SCIP data structure */
2639  FILE* file, /**< output file (or NULL for standard output) */
2640  char* linebuffer, /**< line */
2641  int* linecnt, /**< number of characters in line */
2642  const char* extension /**< string to extent the line */
2643  )
2644 {
2645  assert( scip != NULL );
2646  assert( linebuffer != NULL );
2647  assert( linecnt != NULL );
2648  assert( extension != NULL );
2649  assert( strlen(linebuffer) + strlen(extension) < LP_MAX_PRINTLEN );
2650 
2651  /* NOTE: avoid
2652  * sprintf(linebuffer, "%s%s", linebuffer, extension);
2653  * because of overlapping memory areas in memcpy used in sprintf.
2654  */
2655  (void) strncat(linebuffer, extension, LP_MAX_PRINTLEN - strlen(linebuffer));
2656 
2657  (*linecnt) += (int) strlen(extension);
2658 
2659  SCIPdebugMsg(scip, "linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
2660 
2661  if( (*linecnt) > LP_PRINTLEN )
2662  endLine(scip, file, linebuffer, linecnt);
2663 }
2664 
2665 
2666 /* print row in LP format to file stream */
2667 static
2669  SCIP* scip, /**< SCIP data structure */
2670  FILE* file, /**< output file (or NULL for standard output) */
2671  const char* rowname, /**< row name */
2672  const char* rownameextension, /**< row name extension */
2673  const char* type, /**< row type ("=", "<=", or ">=") */
2674  SCIP_VAR** linvars, /**< array of linear variables */
2675  SCIP_Real* linvals, /**< array of linear coefficient values */
2676  int nlinvars, /**< number of linear variables */
2677  SCIP_EXPR* quadexpr, /**< quadratic expression */
2678  SCIP_Real rhs, /**< right hand side */
2679  SCIP_Bool transformed /**< transformed constraint? */
2680  )
2681 {
2682  int v;
2683  char linebuffer[LP_MAX_PRINTLEN+1] = { '\0' };
2684  int linecnt;
2685 
2686  char varname[LP_MAX_NAMELEN];
2687  char varname2[LP_MAX_NAMELEN];
2688  char consname[LP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2689  char buffer[LP_MAX_PRINTLEN];
2690 
2691  assert( scip != NULL );
2692  assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
2693  assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
2694 
2695  clearLine(linebuffer, &linecnt);
2696 
2697  /* start each line with a space */
2698  appendLine(scip, file, linebuffer, &linecnt, " ");
2699 
2700  /* print row name */
2701  if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
2702  {
2703  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
2704  appendLine(scip, file, linebuffer, &linecnt, consname);
2705  }
2706 
2707  /* print coefficients */
2708  for( v = 0; v < nlinvars; ++v )
2709  {
2710  SCIP_VAR* var;
2711 
2712  assert(linvars != NULL); /* for lint */
2713  assert(linvals != NULL);
2714 
2715  var = linvars[v];
2716  assert( var != NULL );
2717 
2718  /* we start a new line; therefore we tab this line */
2719  if( linecnt == 0 )
2720  appendLine(scip, file, linebuffer, &linecnt, " ");
2721 
2722  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2723  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
2724 
2725  appendLine(scip, file, linebuffer, &linecnt, buffer);
2726  }
2727 
2728  /* print quadratic part */
2729  if( quadexpr != NULL )
2730  {
2731  SCIP_EXPR** linexprs;
2732  SCIP_VAR** activevars;
2733  SCIP_Real* activevals;
2734  SCIP_Real* lincoefs;
2735  SCIP_Real constant;
2736  SCIP_Real activeconstant = 0.0;
2737  int nbilinexprterms;
2738  int nactivevars;
2739  int nquadexprs;
2740  int nlinexprs;
2741 
2742  /* get data from the quadratic expression */
2743  SCIPexprGetQuadraticData(quadexpr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprterms,
2744  NULL, NULL);
2745 
2746  /* allocate memory to store active linear variables */
2747  SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nlinexprs) );
2748  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, lincoefs, nlinexprs) );
2749  nactivevars = nlinexprs;
2750 
2751  for( v = 0; v < nlinexprs; ++v )
2752  {
2753  assert(linexprs != NULL && linexprs[v] != NULL);
2754  assert(SCIPisExprVar(scip, linexprs[v]));
2755 
2756  activevars[v] = SCIPgetVarExprVar(linexprs[v]);
2757  assert(activevars[v] != NULL);
2758  }
2759 
2760  /* get active variables */
2761  SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2762  constant += activeconstant;
2763 
2764  /* print linear coefficients of linear variables */
2765  for( v = 0; v < nactivevars; ++v )
2766  {
2767  SCIP_VAR* var;
2768 
2769  assert(activevars != NULL); /* for lint */
2770  assert(activevals != NULL);
2771 
2772  var = activevars[v];
2773  assert( var != NULL );
2774 
2775  /* we start a new line; therefore we tab this line */
2776  if( linecnt == 0 )
2777  appendLine(scip, file, linebuffer, &linecnt, " ");
2778 
2779  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2780  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", activevals[v], varname);
2781 
2782  appendLine(scip, file, linebuffer, &linecnt, buffer);
2783  }
2784 
2785  /* free memory for active linear variables */
2786  SCIPfreeBufferArray(scip, &activevals);
2787  SCIPfreeBufferArray(scip, &activevars);
2788 
2789  /* adjust rhs if there is a constant */
2790  if( constant != 0.0 && !SCIPisInfinity(scip, rhs) )
2791  rhs -= constant;
2792 
2793  /* print linear coefficients of quadratic variables */
2794  for( v = 0; v < nquadexprs; ++v )
2795  {
2796  SCIP_EXPR* expr;
2797  SCIP_VAR* var;
2798  SCIP_Real lincoef;
2799 
2800  /* get linear coefficient and variable of quadratic term */
2801  SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, &lincoef, NULL, NULL, NULL, NULL);
2802  assert(expr != NULL);
2803  assert(SCIPisExprVar(scip, expr));
2804 
2805  var = SCIPgetVarExprVar(expr);
2806  assert(var != NULL);
2807 
2808  if( lincoef == 0.0 )
2809  continue;
2810 
2811  /* we start a new line; therefore we tab this line */
2812  if( linecnt == 0 )
2813  appendLine(scip, file, linebuffer, &linecnt, " ");
2814 
2815  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2816  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", lincoef, varname);
2817 
2818  appendLine(scip, file, linebuffer, &linecnt, buffer);
2819  }
2820 
2821  /* start quadratic part */
2822  appendLine(scip, file, linebuffer, &linecnt, " + [");
2823 
2824  /* print square terms */
2825  for( v = 0; v < nquadexprs; ++v )
2826  {
2827  SCIP_EXPR* expr;
2828  SCIP_VAR* var;
2829  SCIP_Real sqrcoef;
2830 
2831  /* get square coefficient and variable of quadratic term */
2832  SCIPexprGetQuadraticQuadTerm(quadexpr, v, &expr, NULL, &sqrcoef, NULL, NULL, NULL);
2833  assert(expr != NULL);
2834  assert(SCIPisExprVar(scip, expr));
2835 
2836  var = SCIPgetVarExprVar(expr);
2837  assert(var != NULL);
2838 
2839  if( sqrcoef == 0.0 )
2840  continue;
2841 
2842  /* we start a new line; therefore we tab this line */
2843  if( linecnt == 0 )
2844  appendLine(scip, file, linebuffer, &linecnt, " ");
2845 
2846  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2847  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s^2", sqrcoef, varname);
2848 
2849  appendLine(scip, file, linebuffer, &linecnt, buffer);
2850  }
2851 
2852  /* print bilinear terms */
2853  for( v = 0; v < nbilinexprterms; ++v )
2854  {
2855  SCIP_EXPR* expr1;
2856  SCIP_EXPR* expr2;
2857  SCIP_VAR* var1;
2858  SCIP_VAR* var2;
2859  SCIP_Real bilincoef;
2860 
2861  /* get coefficient and variables of bilinear */
2862  SCIPexprGetQuadraticBilinTerm(quadexpr, v, &expr1, &expr2, &bilincoef, NULL, NULL);
2863  assert(expr1 != NULL);
2864  assert(SCIPisExprVar(scip, expr1));
2865  assert(expr2 != NULL);
2866  assert(SCIPisExprVar(scip, expr2));
2867 
2868  var1 = SCIPgetVarExprVar(expr1);
2869  assert(var1 != NULL);
2870  var2 = SCIPgetVarExprVar(expr2);
2871  assert(var2 != NULL);
2872 
2873  /* we start a new line; therefore we tab this line */
2874  if( linecnt == 0 )
2875  appendLine(scip, file, linebuffer, &linecnt, " ");
2876 
2877  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var1));
2878  (void) SCIPsnprintf(varname2, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var2));
2879  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s * %s", bilincoef, varname, varname2);
2880 
2881  appendLine(scip, file, linebuffer, &linecnt, buffer);
2882  }
2883 
2884  /* end quadratic part */
2885  appendLine(scip, file, linebuffer, &linecnt, " ]");
2886  }
2887 
2888  /* print left hand side */
2889  if( SCIPisZero(scip, rhs) )
2890  rhs = 0.0;
2891 
2892  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2893 
2894  /* we start a new line; therefore we tab this line */
2895  if( linecnt == 0 )
2896  appendLine(scip, file, linebuffer, &linecnt, " ");
2897  appendLine(scip, file, linebuffer, &linecnt, buffer);
2898 
2899  endLine(scip, file, linebuffer, &linecnt);
2900 
2901  return SCIP_OKAY;
2902 }
2903 
2904 /** prints given (linear or) quadratic constraint information in LP format to file stream */
2905 static
2907  SCIP* scip, /**< SCIP data structure */
2908  FILE* file, /**< output file (or NULL for standard output) */
2909  const char* rowname, /**< name of the row */
2910  SCIP_VAR** linvars, /**< array of linear variables */
2911  SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
2912  int nlinvars, /**< number of linear variables */
2913  SCIP_EXPR* quadexpr, /**< quadratic expression (or NULL if nlinvars > 0) */
2914  SCIP_Real lhs, /**< left hand side */
2915  SCIP_Real rhs, /**< right hand side */
2916  SCIP_Bool transformed /**< transformed constraint? */
2917  )
2918 {
2919  int v;
2920  SCIP_VAR** activevars = NULL;
2921  SCIP_Real* activevals = NULL;
2922  int nactivevars;
2923  SCIP_Real activeconstant = 0.0;
2924 
2925  assert( scip != NULL );
2926  assert( rowname != NULL );
2927  assert( quadexpr == NULL || nlinvars == 0);
2928 
2929  /* The LP format does not forbid that the variable array is empty */
2930  assert( nlinvars == 0 || linvars != NULL );
2931  assert( lhs <= rhs );
2932 
2933  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2934  return SCIP_OKAY;
2935 
2936  nactivevars = nlinvars;
2937  if( nlinvars > 0 )
2938  {
2939  /* duplicate variable and value array */
2940  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
2941  if( linvals != NULL )
2942  {
2943  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
2944  }
2945  else
2946  {
2947  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2948 
2949  for( v = 0; v < nactivevars; ++v )
2950  activevals[v] = 1.0;
2951  }
2952 
2953  /* retransform given variables to active variables */
2954  SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2955  }
2956 
2957  /* print row(s) in LP format */
2958  if( SCIPisEQ(scip, lhs, rhs) )
2959  {
2960  assert( !SCIPisInfinity(scip, rhs) );
2961 
2962  /* equal constraint */
2963  SCIP_CALL( printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars, quadexpr,
2964  rhs - activeconstant, transformed) );
2965  }
2966  else
2967  {
2968  if( !SCIPisInfinity(scip, -lhs) )
2969  {
2970  /* print inequality ">=" */
2971  SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=", activevars, activevals,
2972  nactivevars, quadexpr, lhs - activeconstant, transformed) );
2973  }
2974  if( !SCIPisInfinity(scip, rhs) )
2975  {
2976  /* print inequality "<=" */
2977  SCIP_CALL( printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=", activevars, activevals,
2978  nactivevars, quadexpr, rhs - activeconstant, transformed) );
2979  }
2980  }
2981 
2982  if( nlinvars > 0 )
2983  {
2984  /* free buffer arrays */
2985  SCIPfreeBufferArray(scip, &activevals);
2986  SCIPfreeBufferArray(scip, &activevars);
2987  }
2988 
2989  return SCIP_OKAY;
2990 }
2991 
2992 /** prints given SOS constraint information in LP format to file stream */
2993 static
2995  SCIP* scip, /**< SCIP data structure */
2996  FILE* file, /**< output file (or NULL for standard output) */
2997  const char* rowname, /**< name of the row */
2998  SCIP_VAR** vars, /**< array of variables */
2999  SCIP_Real* weights, /**< array of weight values (or NULL) */
3000  int nvars, /**< number of variables */
3001  int type /**< SOS type (SOS1 or SOS2) */
3002  )
3003 {
3004  int v;
3005 
3006  char linebuffer[LP_MAX_PRINTLEN+1];
3007  int linecnt;
3008  char buffer[LP_MAX_PRINTLEN];
3009  char varname[LP_MAX_NAMELEN];
3010 
3011  assert( scip != NULL );
3012  assert( file != NULL );
3013  assert( type == 1 || type == 2 );
3014 
3015  clearLine(linebuffer, &linecnt);
3016 
3017  /* start each line with a space */
3018  appendLine(scip, file, linebuffer, &linecnt, " ");
3019  assert( strlen(rowname) < LP_MAX_NAMELEN );
3020 
3021  if( strlen(rowname) > 0 )
3022  {
3023  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, "%s:", rowname);
3024  appendLine(scip, file, linebuffer, &linecnt, buffer);
3025  }
3026 
3027  /* SOS type */
3028  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " S%d::", type);
3029  appendLine(scip, file, linebuffer, &linecnt, buffer);
3030 
3031  for( v = 0; v < nvars; ++v )
3032  {
3033  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[v]));
3034 
3035  if( weights != NULL )
3036  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%.15g", varname, weights[v]);
3037  else
3038  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%d", varname, v);
3039 
3040  if(linecnt == 0 )
3041  {
3042  /* we start a new line; therefore we tab this line */
3043  appendLine(scip, file, linebuffer, &linecnt, " ");
3044  }
3045  appendLine(scip, file, linebuffer, &linecnt, buffer);
3046  }
3047 
3048  endLine(scip, file, linebuffer, &linecnt);
3049 }
3050 
3051 /** prints a linearization of an and-constraint into the given file */
3052 static
3054  SCIP* scip, /**< SCIP data structure */
3055  FILE* file, /**< output file (or NULL for standard output) */
3056  const char* consname, /**< name of the constraint */
3057  SCIP_CONS* cons, /**< and constraint */
3058  SCIP_Bool aggrlinearizationands,/**< print weak or strong realaxation */
3059  SCIP_Bool transformed /**< transformed constraint? */
3060  )
3061 {
3062  SCIP_VAR** vars;
3063  SCIP_VAR** operands;
3064  SCIP_VAR* resultant;
3065  SCIP_Real* vals;
3066  char rowname[LP_MAX_NAMELEN];
3067  int nvars;
3068  int v;
3069 
3070  assert(scip != NULL);
3071  assert(consname != NULL);
3072  assert(cons != NULL);
3073 
3074  nvars = SCIPgetNVarsAnd(scip, cons);
3075  operands = SCIPgetVarsAnd(scip, cons);
3076  resultant = SCIPgetResultantAnd(scip, cons);
3077 
3078  /* allocate buffer array */
3079  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars + 1) );
3080  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars + 1) );
3081 
3082  /* the tight relaxtion, number of and-constraint operands rows */
3083  if( !aggrlinearizationands )
3084  {
3085  vars[0] = resultant;
3086  vals[0] = 1.0;
3087  vals[1] = -1.0;
3088 
3089  /* print operator rows */
3090  for( v = 0; v < nvars; ++v )
3091  {
3092  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_%d", consname, v);
3093  vars[1] = operands[v];
3094 
3095  /* print for each operator a row */
3096  SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, 2, NULL, -SCIPinfinity(scip), 0.0,
3097  transformed) );
3098  }
3099  }
3100 
3101  /* prepare for next row */
3102  for( v = nvars - 1; v >= 0; --v )
3103  {
3104  vars[v] = operands[v];
3105  vals[v] = -1.0;
3106  }
3107 
3108  vars[nvars] = resultant;
3109 
3110  /* the weak relaxtion, only one constraint */
3111  if( aggrlinearizationands )
3112  {
3113  /* adjust rowname of constraint */
3114  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_operators", consname);
3115 
3116  vals[nvars] = (SCIP_Real) nvars;
3117 
3118  /* print aggregated operator row */
3119  SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, nvars + 1, NULL, -SCIPinfinity(scip), 0.0,
3120  transformed) );
3121  }
3122 
3123  /* create additional linear constraint */
3124  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_add", consname);
3125 
3126  vals[nvars] = 1.0;
3127 
3128  SCIP_CALL( printQuadraticCons(scip, file, rowname, vars, vals, nvars + 1, NULL, -nvars + 1.0, SCIPinfinity(scip),
3129  transformed) );
3130 
3131  /* free buffer array */
3132  SCIPfreeBufferArray(scip, &vals);
3133  SCIPfreeBufferArray(scip, &vars);
3134 
3135  return SCIP_OKAY;
3136 }
3137 
3138 /** check whether given variables are aggregated and put them into an array without duplication */
3139 static
3141  SCIP* scip, /**< SCIP data structure */
3142  SCIP_VAR** vars, /**< variable array */
3143  int nvars, /**< number of active variables in the problem */
3144  SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3145  int* naggvars, /**< pointer to number of aggregated variables on output */
3146  int* saggvars, /**< pointer to number of slots in aggvars array */
3147  SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3148  )
3149 {
3150  int v;
3151 
3152  assert( scip != NULL );
3153  assert( aggvars != NULL );
3154  assert( naggvars != NULL );
3155  assert( saggvars != NULL );
3156 
3157  /* check variables */
3158  for( v = 0; v < nvars; ++v )
3159  {
3160  SCIP_VARSTATUS status;
3161  SCIP_VAR* var;
3162 
3163  var = vars[v];
3164  status = SCIPvarGetStatus(var);
3165 
3166  /* collect aggregated variables in a list */
3167  if( status >= SCIP_VARSTATUS_AGGREGATED )
3168  {
3169  assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3170  assert( varAggregated != NULL );
3171 
3172  if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3173  {
3174  /* possibly enlarge array */
3175  if ( *saggvars <= *naggvars )
3176  {
3177  int newsize;
3178  newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3179  assert( newsize > *saggvars );
3180  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3181  *saggvars = newsize;
3182  }
3183 
3184  (*aggvars)[*naggvars] = var;
3185  (*naggvars)++;
3186  SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3187  assert( *naggvars <= *saggvars );
3188  }
3189  }
3190  }
3191  return SCIP_OKAY;
3192 }
3193 
3194 /** print aggregated variable-constraints */
3195 static
3197  SCIP* scip, /**< SCIP data structure */
3198  FILE* file, /**< output file (or NULL for standard output) */
3199  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3200  int nvars, /**< number of active variables in the problem */
3201  int nAggregatedVars, /**< number of aggregated variables */
3202  SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
3203  )
3204 {
3205  int j;
3206 
3207  SCIP_VAR** activevars;
3208  SCIP_Real* activevals;
3209  int nactivevars;
3210  SCIP_Real activeconstant = 0.0;
3211  char consname[LP_MAX_NAMELEN];
3212 
3213  assert( scip != NULL );
3214 
3215  /* write aggregation constraints */
3216  SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
3217  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
3218 
3219  for( j = 0; j < nAggregatedVars; ++j )
3220  {
3221  /* set up list to obtain substitution variables */
3222  nactivevars = 1;
3223 
3224  activevars[0] = aggregatedVars[j];
3225  activevals[0] = 1.0;
3226  activeconstant = 0.0;
3227 
3228  /* retransform given variables to active variables */
3229  SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
3230 
3231  activevals[nactivevars] = -1.0;
3232  activevars[nactivevars] = aggregatedVars[j];
3233  ++nactivevars;
3234 
3235  /* output constraint */
3236  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
3237  SCIP_CALL( printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, - activeconstant,
3238  transformed) );
3239  }
3240 
3241  /* free buffer arrays */
3242  SCIPfreeBufferArray(scip, &activevals);
3243  SCIPfreeBufferArray(scip, &activevars);
3244 
3245  return SCIP_OKAY;
3246 }
3247 
3248 /** method check if the variable names are not longer than LP_MAX_NAMELEN */
3249 static
3251  SCIP* scip, /**< SCIP data structure */
3252  SCIP_VAR** vars, /**< array of variables */
3253  int nvars /**< number of variables */
3254  )
3255 {
3256  SCIP_Bool printwarning;
3257  int v;
3258 
3259  assert(scip != NULL);
3260  assert(vars != NULL || nvars == 0);
3261 
3262  printwarning = TRUE;
3263 
3264  /* check if the variable names are not to long */
3265  for( v = 0; v < nvars; ++v )
3266  {
3267  if( strlen(SCIPvarGetName(vars[v])) > LP_MAX_NAMELEN ) /*lint !e613*/
3268  {
3269  SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; LP might be corrupted\n",
3270  LP_MAX_NAMELEN - 1);
3271  return;
3272  }
3273 
3274  /* check if variable name starts with a digit */
3275  if( printwarning && isdigit((unsigned char)SCIPvarGetName(vars[v])[0]) ) /*lint !e613*/
3276  {
3277  SCIPwarningMessage(scip, "violation of LP format - a variable name starts with a digit; " \
3278  "it is not possible to read the generated LP file with SCIP; " \
3279  "use write/genproblem or write/gentransproblem for generic variable names\n");
3280  printwarning = FALSE;
3281  }
3282  }
3283 }
3284 
3285 /** method check if the constraint names are not longer than LP_MAX_NAMELEN */
3286 static
3288  SCIP* scip, /**< SCIP data structure */
3289  SCIP_CONS** conss, /**< array of constraints */
3290  int nconss, /**< number of constraints */
3291  SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
3292  )
3293 {
3294  int c;
3295  SCIP_CONS* cons;
3296  SCIP_CONSHDLR* conshdlr;
3297  const char* conshdlrname;
3298  SCIP_Bool printwarning = TRUE;
3299 
3300  assert( scip != NULL );
3301  assert( conss != NULL || nconss == 0 );
3302 
3303  for( c = 0; c < nconss; ++c )
3304  {
3305  int len;
3306 
3307  assert(conss != NULL); /* for lint */
3308  cons = conss[c];
3309  assert(cons != NULL );
3310 
3311  /* in case the transformed is written only constraints are posted which are enabled in the current node */
3312  assert(!transformed || SCIPconsIsEnabled(cons));
3313 
3314  conshdlr = SCIPconsGetHdlr(cons);
3315  assert( conshdlr != NULL );
3316 
3317  conshdlrname = SCIPconshdlrGetName(conshdlr);
3318  assert( transformed == SCIPconsIsTransformed(cons) );
3319 
3320  len = (int) strlen(SCIPconsGetName(cons));
3321 
3322  if( strcmp(conshdlrname, "linear") == 0 )
3323  {
3324  SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
3325  SCIP_Real rhs = SCIPgetRhsLinear(scip, cons);
3326 
3327  if( (SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN) || ( !SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN - 4) )
3328  {
3329  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
3330  return;
3331  }
3332  }
3333  else if( len > LP_MAX_NAMELEN )
3334  {
3335  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
3336  return;
3337  }
3338 
3339  /* check if constraint name starts with a digit */
3340  if( printwarning && isdigit((unsigned char)SCIPconsGetName(cons)[0]) )
3341  {
3342  SCIPwarningMessage(scip, "violation of LP format - a constraint name starts with a digit; " \
3343  "it is not possible to read the generated LP file with SCIP; " \
3344  "use write/genproblem or write/gentransproblem for generic variable names\n");
3345  printwarning = FALSE;
3346  }
3347  }
3348 }
3349 
3350 /*
3351  * Callback methods of reader
3352  */
3353 
3354 /** copy method for reader plugins (called when SCIP copies plugins) */
3355 static
3357 { /*lint --e{715}*/
3358  assert(scip != NULL);
3359  assert(reader != NULL);
3360  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3361 
3362  /* call inclusion method of reader */
3364 
3365  return SCIP_OKAY;
3366 }
3367 
3368 /** destructor of reader to free user data (called when SCIP is exiting) */
3369 static
3371 {
3372  SCIP_READERDATA* readerdata;
3373 
3374  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3375  readerdata = SCIPreaderGetData(reader);
3376  assert(readerdata != NULL);
3377  SCIPfreeBlockMemory(scip, &readerdata);
3378 
3379  return SCIP_OKAY;
3380 }
3381 
3382 /** problem reading method of reader */
3383 static
3385 { /*lint --e{715}*/
3386 
3387  SCIP_CALL( SCIPreadLp(scip, reader, filename, result) );
3388 
3389  return SCIP_OKAY;
3390 }
3391 
3392 
3393 /** problem writing method of reader */
3394 static
3396 { /*lint --e{715}*/
3397  assert(reader != NULL);
3398  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3399 
3400  SCIP_CALL( SCIPwriteLp(scip, file, name, transformed, objsense, objscale, objoffset, vars,
3401  nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
3402 
3403  return SCIP_OKAY;
3404 }
3405 
3406 
3407 /*
3408  * reader specific interface methods
3409  */
3410 
3411 /** includes the lp file reader in SCIP */
3413  SCIP* scip /**< SCIP data structure */
3414  )
3415 {
3416  SCIP_READERDATA* readerdata;
3417  SCIP_READER* reader;
3418 
3419  /* create reader data */
3420  SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3421 
3422  /* include reader */
3423  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3424 
3425  /* set non fundamental callbacks via setter functions */
3426  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyLp) );
3427  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeLp) );
3428  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadLp) );
3429  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteLp) );
3430 
3431  /* add lp-reader parameters */
3433  "reading/" READER_NAME "/linearize-and-constraints",
3434  "should possible \"and\" constraint be linearized when writing the lp file?",
3435  &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3437  "reading/" READER_NAME "/aggrlinearization-ands",
3438  "should an aggregated linearization for and constraints be used?",
3439  &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3440 
3441  return SCIP_OKAY;
3442 }
3443 
3444 
3445 /** reads problem from file */
3447  SCIP* scip, /**< SCIP data structure */
3448  SCIP_READER* reader, /**< the file reader itself */
3449  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3450  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
3451  )
3452 { /*lint --e{715}*/
3453  SCIP_RETCODE retcode;
3454  LPINPUT lpinput;
3455  int i;
3456 
3457  assert(scip != NULL);
3458  assert(reader != NULL);
3459 
3460  /* initialize LP input data */
3461  lpinput.file = NULL;
3462  lpinput.linebuf[0] = '\0';
3463  lpinput.probname[0] = '\0';
3464  lpinput.objname[0] = '\0';
3465  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lpinput.token, LP_MAX_LINELEN) ); /*lint !e506*/
3466  lpinput.token[0] = '\0';
3467  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN) ); /*lint !e506*/
3468  lpinput.tokenbuf[0] = '\0';
3469  for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
3470  {
3471  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(lpinput.pushedtokens[i]), LP_MAX_LINELEN) ); /*lint !e866 !e506*/
3472  }
3473 
3474  lpinput.npushedtokens = 0;
3475  lpinput.linenumber = 0;
3476  lpinput.linepos = 0;
3477  lpinput.section = LP_START;
3478  lpinput.objsense = SCIP_OBJSENSE_MINIMIZE;
3479  lpinput.inlazyconstraints = FALSE;
3480  lpinput.inusercuts = FALSE;
3481  lpinput.haserror = FALSE;
3482  lpinput.comment = FALSE;
3483  lpinput.endline = FALSE;
3484 
3485  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(lpinput.initialconss)) );
3486  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(lpinput.dynamicconss)) );
3487  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(lpinput.dynamiccols)) );
3488  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(lpinput.dynamicrows)) );
3489 
3490  /* read the file */
3491  retcode = readLPFile(scip, &lpinput, filename);
3492 
3493  /* free dynamically allocated memory */
3494  for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
3495  {
3496  SCIPfreeBlockMemoryArray(scip, &lpinput.pushedtokens[i], LP_MAX_LINELEN);
3497  }
3498  SCIPfreeBlockMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN);
3499  SCIPfreeBlockMemoryArray(scip, &lpinput.token, LP_MAX_LINELEN);
3500 
3501  if( retcode == SCIP_PLUGINNOTFOUND )
3502  retcode = SCIP_READERROR;
3503 
3504  /* check for correct return value */
3505  SCIP_CALL( retcode );
3506 
3507  /* evaluate the result */
3508  if( lpinput.haserror )
3509  return SCIP_READERROR;
3510  else
3511  {
3512  /* set objective sense */
3513  SCIP_CALL( SCIPsetObjsense(scip, lpinput.objsense) );
3514  *result = SCIP_SUCCESS;
3515  }
3516 
3517  return SCIP_OKAY;
3518 }
3519 
3520 
3521 /** writes problem to file */
3523  SCIP* scip, /**< SCIP data structure */
3524  FILE* file, /**< output file, or NULL if standard output should be used */
3525  const char* name, /**< problem name */
3526  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3527  SCIP_OBJSENSE objsense, /**< objective sense */
3528  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3529  * extobj = objsense * objscale * (intobj + objoffset) */
3530  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3531  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3532  int nvars, /**< number of active variables in the problem */
3533  int nbinvars, /**< number of binary variables */
3534  int nintvars, /**< number of general integer variables */
3535  int nimplvars, /**< number of implicit integer variables */
3536  int ncontvars, /**< number of continuous variables */
3537  SCIP_CONS** conss, /**< array with constraints of the problem */
3538  int nconss, /**< number of constraints in the problem */
3539  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3540  )
3541 {
3542  SCIP_READER* reader;
3543  SCIP_READERDATA* readerdata;
3544  SCIP_Bool linearizeands;
3545  SCIP_Bool aggrlinearizationands;
3546  int c;
3547  int v;
3548 
3549  int linecnt;
3550  char linebuffer[LP_MAX_PRINTLEN+1];
3551 
3552  char varname[LP_MAX_NAMELEN];
3553  char buffer[LP_MAX_PRINTLEN];
3554 
3555  SCIP_CONSHDLR* conshdlr;
3556  SCIP_CONSHDLR* conshdlrInd;
3557  const char* conshdlrname;
3558  SCIP_CONS* cons;
3559  SCIP_CONS** consSOS1;
3560  SCIP_CONS** consSOS2;
3561  SCIP_CONS** consExpr;
3562  SCIP_CONS** consIndicator;
3563  int nConsSOS1 = 0;
3564  int nConsSOS2 = 0;
3565  int nConsExpr = 0;
3566  int nConsIndicator = 0;
3567  char consname[LP_MAX_NAMELEN];
3568 
3569  SCIP_VAR** aggvars;
3570  SCIP_VAR** tmpvars;
3571  int tmpvarssize;
3572  int naggvars = 0;
3573  int saggvars;
3574  SCIP_HASHTABLE* varAggregated;
3575  SCIP_HASHMAP* consHidden;
3576 
3577  SCIP_VAR** consvars;
3578  SCIP_Real* consvals;
3579  int nconsvars;
3580 
3581  SCIP_VAR* var;
3582  SCIP_Real lb;
3583  SCIP_Real ub;
3584 
3585  SCIP_Bool zeroobj;
3586 
3587  assert(scip != NULL);
3588 
3589  /* find indicator constraint handler */
3590  conshdlrInd = SCIPfindConshdlr(scip, "indicator");
3591  consHidden = NULL;
3592 
3593  /* if indicator constraint handler is present */
3594  if( conshdlrInd != NULL )
3595  {
3596  /* create hashtable storing linear constraints that should not be output */
3597  SCIP_CALL( SCIPhashmapCreate(&consHidden, SCIPblkmem(scip), 500) );
3598 
3599  /* loop through indicator constraints (works only in transformed problem) */
3600  if( transformed )
3601  {
3602  SCIP_CONS** consInd;
3603  int nConsInd;
3604 
3605  consInd = SCIPconshdlrGetConss(conshdlrInd);
3606  nConsInd = SCIPconshdlrGetNConss(conshdlrInd);
3607  SCIPdebugMsg(scip, "Number of indicator constraints: %d\n", nConsInd);
3608 
3609  for( c = 0; c < nConsInd; ++c )
3610  {
3611  assert( consInd[c] != NULL );
3612  cons = SCIPgetLinearConsIndicator(consInd[c]);
3613 
3614  assert( !SCIPhashmapExists(consHidden, (void*) cons) );
3615  SCIP_CALL( SCIPhashmapSetImage(consHidden, (void*) cons, (void*) TRUE) );
3616  SCIPdebugMsg(scip, "Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(cons));
3617  }
3618  }
3619  else
3620  {
3621  /* otherwise we have to pass through all constraints */
3622  for( c = 0; c < nconss; ++c )
3623  {
3624  cons = conss[c];
3625  assert( cons != NULL);
3626 
3627  conshdlr = SCIPconsGetHdlr(cons);
3628  assert( conshdlr != NULL );
3629  conshdlrname = SCIPconshdlrGetName(conshdlr);
3630 
3631  if( strcmp(conshdlrname, "indicator") == 0 )
3632  {
3633  SCIP_CONS* lincons;
3634 
3635  lincons = SCIPgetLinearConsIndicator(cons);
3636  assert( lincons != NULL );
3637 
3638  assert( !SCIPhashmapExists(consHidden, (void*) lincons) );
3639  SCIP_CALL( SCIPhashmapSetImage(consHidden, (void*) lincons, (void*) TRUE) );
3640  SCIPdebugMsg(scip, "Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(lincons));
3641  }
3642  }
3643  }
3644  }
3645 
3646  /* check if the variable names are not to long */
3647  checkVarnames(scip, vars, nvars);
3648  /* check if the constraint names are to long */
3649  checkConsnames(scip, conss, nconss, transformed);
3650 
3651  /* print statistics as comment to file */
3652  SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
3653  SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
3654  SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
3655  nvars, nbinvars, nintvars, nimplvars, ncontvars);
3656  SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
3657 
3658  /* print objective sense */
3659  SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
3660 
3661  clearLine(linebuffer, &linecnt);
3662  appendLine(scip, file, linebuffer, &linecnt, " Obj:");
3663 
3664  zeroobj = TRUE;
3665  for( v = 0; v < nvars; ++v )
3666  {
3667  var = vars[v];
3668 
3669 #ifndef NDEBUG
3670  /* in case the original problem has to be written, the variables have to be either "original" or "negated" */
3671  if( ! transformed )
3673 #endif
3674 
3675  if( SCIPisZero(scip, SCIPvarGetObj(var)) )
3676  continue;
3677 
3678  zeroobj = FALSE;
3679 
3680  /* we start a new line; therefore we tab this line */
3681  if( linecnt == 0 )
3682  appendLine(scip, file, linebuffer, &linecnt, " ");
3683 
3684  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
3685  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", objscale * SCIPvarGetObj(var), varname );
3686 
3687  appendLine(scip, file, linebuffer, &linecnt, buffer);
3688  }
3689 
3690  /* add objective offset */
3691  if ( ! SCIPisZero(scip, objoffset) )
3692  {
3693  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g", objscale * objoffset);
3694  appendLine(scip, file, linebuffer, &linecnt, buffer);
3695  }
3696  else
3697  {
3698  /* add a linear term to avoid troubles when reading the lp file with another MIP solver */
3699  if( zeroobj && nvars >= 1 )
3700  {
3701  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[0]));
3702  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " 0 %s", varname );
3703 
3704  appendLine(scip, file, linebuffer, &linecnt, buffer);
3705  }
3706  }
3707 
3708  endLine(scip, file, linebuffer, &linecnt);
3709 
3710  /* print "Subject to" section */
3711  SCIPinfoMessage(scip, file, "Subject to\n");
3712 
3713  reader = SCIPfindReader(scip, READER_NAME);
3714  if( reader != NULL )
3715  {
3716  readerdata = SCIPreaderGetData(reader);
3717  assert(readerdata != NULL);
3718 
3719  linearizeands = readerdata->linearizeands;
3720  aggrlinearizationands = readerdata->aggrlinearizationands;
3721  }
3722  else
3723  {
3724  linearizeands = DEFAULT_LINEARIZE_ANDS;
3725  aggrlinearizationands = DEFAULT_AGGRLINEARIZATION_ANDS;
3726  }
3727 
3728  /* collect SOS, quadratic, and SOC constraints in array for later output */
3729  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3730  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3731  SCIP_CALL( SCIPallocBufferArray(scip, &consExpr, nconss) );
3732  SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3733 
3734  tmpvarssize = SCIPgetNTotalVars(scip);
3735  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
3736 
3737  for( c = 0; c < nconss; ++c )
3738  {
3739  cons = conss[c];
3740  assert( cons != NULL);
3741 
3742  /* in case the transformed is written only constraints are posted which are enabled in the current node */
3743  assert(!transformed || SCIPconsIsEnabled(cons));
3744 
3745  /* skip marked constraints in connection with indicator constraints */
3746  if( conshdlrInd != NULL && SCIPhashmapExists(consHidden, (void*) cons) )
3747  {
3748  assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear") == 0 );
3749  continue;
3750  }
3751 
3752  conshdlr = SCIPconsGetHdlr(cons);
3753  assert( conshdlr != NULL );
3754 
3755  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
3756  conshdlrname = SCIPconshdlrGetName(conshdlr);
3757  assert( transformed == SCIPconsIsTransformed(cons) );
3758 
3759  if( strcmp(conshdlrname, "linear") == 0 )
3760  {
3761  SCIP_CALL( printQuadraticCons(scip, file, consname,
3762  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3763  NULL, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
3764  }
3765  else if( strcmp(conshdlrname, "setppc") == 0 )
3766  {
3767  consvars = SCIPgetVarsSetppc(scip, cons);
3768  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3769 
3770  switch( SCIPgetTypeSetppc(scip, cons) )
3771  {
3773  SCIP_CALL( printQuadraticCons(scip, file, consname,
3774  consvars, NULL, nconsvars, NULL, 1.0, 1.0, transformed) );
3775  break;
3777  SCIP_CALL( printQuadraticCons(scip, file, consname,
3778  consvars, NULL, nconsvars, NULL, -SCIPinfinity(scip), 1.0, transformed) );
3779  break;
3781  SCIP_CALL( printQuadraticCons(scip, file, consname,
3782  consvars, NULL, nconsvars, NULL, 1.0, SCIPinfinity(scip), transformed) );
3783  break;
3784  }
3785  }
3786  else if( strcmp(conshdlrname, "logicor") == 0 )
3787  {
3788  SCIP_CALL( printQuadraticCons(scip, file, consname,
3789  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3790  NULL, 1.0, SCIPinfinity(scip), transformed) );
3791  }
3792  else if( strcmp(conshdlrname, "knapsack") == 0 )
3793  {
3794  SCIP_Longint* weights;
3795 
3796  consvars = SCIPgetVarsKnapsack(scip, cons);
3797  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3798 
3799  /* copy Longint array to SCIP_Real array */
3800  weights = SCIPgetWeightsKnapsack(scip, cons);
3801  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3802  for( v = 0; v < nconsvars; ++v )
3803  consvals[v] = (SCIP_Real)weights[v];
3804 
3805  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
3806  NULL, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
3807 
3808  SCIPfreeBufferArray(scip, &consvals);
3809  }
3810  else if( strcmp(conshdlrname, "varbound") == 0 )
3811  {
3812  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3813  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3814 
3815  consvars[0] = SCIPgetVarVarbound(scip, cons);
3816  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3817 
3818  consvals[0] = 1.0;
3819  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3820 
3821  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL,
3822  SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
3823 
3824  SCIPfreeBufferArray(scip, &consvals);
3825  SCIPfreeBufferArray(scip, &consvars);
3826  }
3827  else if( strcmp(conshdlrname, "SOS1") == 0 )
3828  {
3829  /* store constraint */
3830  consSOS1[nConsSOS1++] = cons;
3831  }
3832  else if( strcmp(conshdlrname, "SOS2") == 0 )
3833  {
3834  /* store constraint */
3835  consSOS2[nConsSOS2++] = cons;
3836  }
3837  else if( strcmp(conshdlrname, "indicator") == 0 )
3838  {
3839  SCIP_CONS* lincons;
3840  SCIP_VAR* binvar;
3841  SCIP_VAR* slackvar;
3842  SCIP_VAR** linvars;
3843  SCIP_Real* linvals;
3844  int nlinvars;
3845  int cnt;
3846  int rhs;
3847 
3848  assert( conshdlrInd != NULL );
3849 
3850  lincons = SCIPgetLinearConsIndicator(cons);
3851  binvar = SCIPgetBinaryVarIndicator(cons);
3852  slackvar = SCIPgetSlackVarIndicator(cons);
3853 
3854  assert( lincons != NULL );
3855  assert( binvar != NULL );
3856  assert( slackvar != NULL );
3857 
3858  rhs = 1;
3859  if ( SCIPvarIsNegated(binvar) )
3860  {
3861  rhs = 0;
3862  binvar = SCIPvarGetNegatedVar(binvar);
3863  }
3864 
3865  /* collect linear constraint information (remove slack variable) */
3866  linvars = SCIPgetVarsLinear(scip, lincons);
3867  linvals = SCIPgetValsLinear(scip, lincons);
3868  nlinvars = SCIPgetNVarsLinear(scip, lincons);
3869  assert( linvars != NULL );
3870  assert( linvals != NULL );
3871 
3872  /* linvars always contains slack variable, thus nlinvars >= 1 */
3873  if( nlinvars > 1 && !SCIPconsIsDeleted(lincons) )
3874  {
3875  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(binvar) );
3876  if( strlen(consname) > 0 )
3877  SCIPinfoMessage(scip, file, " %s: %s = %d ->", consname, varname, rhs);
3878  else
3879  SCIPinfoMessage(scip, file, " %s = %d ->", varname, rhs);
3880 
3881  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nlinvars-1) );
3882  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nlinvars-1) );
3883 
3884  cnt = 0;
3885  for( v = 0; v < nlinvars; ++v )
3886  {
3887  var = linvars[v];
3888  if( var != slackvar )
3889  {
3890  consvars[cnt] = var;
3891  consvals[cnt++] = linvals[v];
3892  }
3893  }
3894  /* if slackvariable is fixed, it might have been removed from constraint */
3895  assert( nlinvars == 0 || cnt == nlinvars-1 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar)) );
3896 
3897  SCIP_CALL( printQuadraticCons(scip, file, "", consvars, consvals, cnt, NULL,
3898  SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons), transformed) );
3899 
3900  SCIPfreeBufferArray(scip, &consvals);
3901  SCIPfreeBufferArray(scip, &consvars);
3902  }
3903 
3904  /* store constraint */
3905  consIndicator[nConsIndicator++] = cons;
3906  }
3907  else if( strcmp(conshdlrname, "nonlinear") == 0 )
3908  {
3909  SCIP_Bool isquadratic;
3910 
3911  /* check whether there is a quadratic representation of the nonlinear constraint */
3912  SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
3913 
3914  /* we cannot handle nonlinear constraint that are not quadratically representable */
3915  if( !isquadratic )
3916  {
3917  SCIPwarningMessage(scip, "constraint handler <%s> cannot print constraint\n", SCIPconshdlrGetName(SCIPconsGetHdlr(cons)));
3918  SCIPinfoMessage(scip, file, "\\ ");
3919  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3920  SCIPinfoMessage(scip, file, ";\n");
3921 
3922  return SCIP_OKAY;
3923  }
3924 
3925  SCIP_CALL( printQuadraticCons(scip, file, consname, NULL, NULL, 0, SCIPgetExprNonlinear(cons),
3926  SCIPgetLhsNonlinear(cons), SCIPgetRhsNonlinear(cons), transformed) );
3927 
3928  consExpr[nConsExpr++] = cons;
3929  }
3930  else if( strcmp(conshdlrname, "and") == 0 )
3931  {
3932  if( linearizeands )
3933  {
3934  SCIP_CALL( printAndCons(scip, file, consname, cons, aggrlinearizationands, transformed) );
3935  }
3936  else
3937  {
3938  SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
3939  SCIPinfoMessage(scip, file, "\\ ");
3940  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3941  SCIPinfoMessage(scip, file, ";\n");
3942  }
3943  }
3944  else
3945  {
3946  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3947  SCIPinfoMessage(scip, file, "\\ ");
3948  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3949  SCIPinfoMessage(scip, file, ";\n");
3950  }
3951  }
3952 
3953  /* allocate array for storing aggregated and negated variables (dynamically adjusted) */
3954  saggvars = MAX(10, nvars);
3955  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
3956 
3957  /* create hashtable for storing aggregated variables */
3958  SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), saggvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3959 
3960  /* check for aggregated variables in SOS1 constraints and output aggregations as linear constraints */
3961  for( c = 0; c < nConsSOS1; ++c )
3962  {
3963  cons = consSOS1[c];
3964  consvars = SCIPgetVarsSOS1(scip, cons);
3965  nconsvars = SCIPgetNVarsSOS1(scip, cons);
3966 
3967  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
3968  }
3969 
3970  /* check for aggregated variables in SOS2 constraints and output aggregations as linear constraints */
3971  for( c = 0; c < nConsSOS2; ++c )
3972  {
3973  cons = consSOS2[c];
3974  consvars = SCIPgetVarsSOS2(scip, cons);
3975  nconsvars = SCIPgetNVarsSOS2(scip, cons);
3976 
3977  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
3978  }
3979 
3980  /* check for aggregated variables in nonlinear constraints and output aggregations as linear constraints */
3981  for( c = 0; c < nConsExpr; ++c )
3982  {
3983  SCIP_Bool success;
3984  int ntmpvars;
3985 
3986  /* get variables of the nonlinear constraint */
3987  SCIP_CALL( SCIPgetConsNVars(scip, consExpr[c], &ntmpvars, &success) );
3988  assert(success);
3989  if( ntmpvars > tmpvarssize )
3990  {
3991  tmpvarssize = SCIPcalcMemGrowSize(scip, ntmpvars);
3992  SCIP_CALL( SCIPreallocBufferArray(scip, &tmpvars, tmpvarssize) );
3993  }
3994  SCIP_CALL( SCIPgetConsVars(scip, consExpr[c], tmpvars, tmpvarssize, &success) );
3995  assert(success);
3996 
3997  SCIP_CALL( collectAggregatedVars(scip, tmpvars, ntmpvars, &aggvars, &naggvars, &saggvars, varAggregated) );
3998  }
3999 
4000  /* check for aggregated variables in indicator constraints and output aggregations as linear constraints */
4001  for( c = 0; c < nConsIndicator; ++c )
4002  {
4003  SCIP_VAR* binvar;
4004 
4005  cons = consIndicator[c];
4006  binvar = SCIPgetBinaryVarIndicator(cons);
4007  if ( ! SCIPvarIsNegated(binvar) )
4008  {
4009  /* we take care of negated variables above, but not of aggregated variables */
4010  SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varAggregated) );
4011  }
4012  }
4013 
4014  /* print aggregation constraints */
4015  SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, naggvars, aggvars) );
4016 
4017  /* print "Bounds" section */
4018  SCIPinfoMessage(scip, file, "Bounds\n");
4019  for( v = 0; v < nvars; ++v )
4020  {
4021  var = vars[v];
4022  assert( var != NULL );
4023  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4024 
4025  if( transformed )
4026  {
4027  /* in case the transformed is written only local bounds are posted which are valid in the current node */
4028  lb = SCIPvarGetLbLocal(var);
4029  ub = SCIPvarGetUbLocal(var);
4030  }
4031  else
4032  {
4033  lb = SCIPvarGetLbOriginal(var);
4034  ub = SCIPvarGetUbOriginal(var);
4035  }
4036 
4037  if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
4038  SCIPinfoMessage(scip, file, " %s free\n", varname);
4039  else
4040  {
4041  /* print lower bound */
4042  if( SCIPisInfinity(scip, -lb) )
4043  SCIPinfoMessage(scip, file, " -inf <= ");
4044  else
4045  {
4046  if( SCIPisZero(scip, lb) )
4047  {
4048  /* variables are nonnegative by default - so we skip these variables */
4049  if( SCIPisInfinity(scip, ub) )
4050  continue;
4051  lb = 0.0;
4052  }
4053 
4054  SCIPinfoMessage(scip, file, " %.15g <= ", lb);
4055  }
4056  /* print variable name */
4057  SCIPinfoMessage(scip, file, "%s", varname);
4058 
4059  /* print upper bound as far this one is not infinity */
4060  if( !SCIPisInfinity(scip, ub) )
4061  SCIPinfoMessage(scip, file, " <= %.15g", ub);
4062 
4063  SCIPinfoMessage(scip, file, "\n");
4064  }
4065  }
4066 
4067  /* output aggregated variables as 'free' */
4068  for( v = 0; v < naggvars; ++v )
4069  {
4070  var = aggvars[v];
4071  assert( var != NULL );
4072  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4073 
4074  SCIPinfoMessage(scip, file, " %s free\n", varname);
4075  }
4076 
4077  /* print binaries section */
4078  if( nbinvars > 0 )
4079  {
4080  SCIPinfoMessage(scip, file, "Binaries\n");
4081 
4082  clearLine(linebuffer, &linecnt);
4083 
4084  /* output active variables */
4085  for( v = 0; v < nvars; ++v )
4086  {
4087  var = vars[v];
4088  assert( var != NULL );
4089 
4090  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
4091  {
4092  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4093  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4094  appendLine(scip, file, linebuffer, &linecnt, buffer);
4095  }
4096  }
4097 
4098  /* possibly output aggregated variables */
4099  for( v = 0; v < naggvars; ++v )
4100  {
4101  var = aggvars[v];
4102  assert( var != NULL );
4103 
4104  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
4105  {
4106  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4107  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4108  appendLine(scip, file, linebuffer, &linecnt, buffer);
4109  }
4110  }
4111 
4112  endLine(scip, file, linebuffer, &linecnt);
4113  }
4114 
4115  /* print generals section */
4116  if( nintvars > 0 )
4117  {
4118  SCIPinfoMessage(scip, file, "Generals\n");
4119 
4120  /* output active variables */
4121  for( v = 0; v < nvars; ++v )
4122  {
4123  var = vars[v];
4124  assert( var != NULL );
4125 
4126  if( SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER )
4127  {
4128  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4129  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4130  appendLine(scip, file, linebuffer, &linecnt, buffer);
4131  }
4132  }
4133 
4134  /* possibly output aggregated variables */
4135  for( v = 0; v < naggvars; ++v )
4136  {
4137  var = aggvars[v];
4138  assert( var != NULL );
4139 
4140  if( SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER )
4141  {
4142  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4143  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4144  appendLine(scip, file, linebuffer, &linecnt, buffer);
4145  }
4146  }
4147 
4148  endLine(scip, file, linebuffer, &linecnt);
4149  }
4150 
4151  /* free space */
4152  SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4153  SCIPhashtableFree(&varAggregated);
4154  if( conshdlrInd != NULL )
4155  SCIPhashmapFree(&consHidden);
4156 
4157  /* print SOS section */
4158  if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4159  {
4160  SCIP_Real* weights;
4161  SCIPinfoMessage(scip, file, "SOS\n");
4162 
4163  /* first output SOS1 constraints */
4164  for( c = 0; c < nConsSOS1; ++c )
4165  {
4166  cons = consSOS1[c];
4167  consvars = SCIPgetVarsSOS1(scip, cons);
4168  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4169  weights = SCIPgetWeightsSOS1(scip, cons);
4170 
4171  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4172  printSosCons(scip, file, consname, consvars, weights, nconsvars, 1);
4173  }
4174 
4175  /* next output SOS2 constraints */
4176  for( c = 0; c < nConsSOS2; ++c )
4177  {
4178  cons = consSOS2[c];
4179  consvars = SCIPgetVarsSOS2(scip, cons);
4180  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4181  weights = SCIPgetWeightsSOS2(scip, cons);
4182 
4183  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4184  printSosCons(scip, file, consname, consvars, weights, nconsvars, 2);
4185  }
4186  }
4187 
4188  /* free space */
4189  SCIPfreeBufferArray(scip, &tmpvars);
4190  SCIPfreeBufferArray(scip, &consIndicator);
4191  SCIPfreeBufferArray(scip, &consExpr);
4192  SCIPfreeBufferArray(scip, &consSOS2);
4193  SCIPfreeBufferArray(scip, &consSOS1);
4194 
4195  /* end of lp format */
4196  SCIPinfoMessage(scip, file, "%s\n", "End");
4197 
4198  *result = SCIP_SUCCESS;
4199 
4200  return SCIP_OKAY;
4201 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
static void syntaxError(SCIP *scip, LPINPUT *lpinput, const char *msg)
Definition: reader_lp.c:150
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
Definition: expr.c:4055
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:90
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8182
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10639
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:84
static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_lp.c:3287
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
static const char commentchars[]
Definition: reader_lp.c:141
static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
Definition: reader_lp.c:2528
static SCIP_RETCODE printAndCons(SCIP *scip, FILE *file, const char *consname, SCIP_CONS *cons, SCIP_Bool aggrlinearizationands, SCIP_Bool transformed)
Definition: reader_lp.c:3053
Constraint handler for variable bound constraints .
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_lp.c:368
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10605
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2487
enum LpExpType LPEXPTYPE
Definition: reader_lp.c:106
public methods for memory management
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1288
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9394
#define READER_NAME
Definition: reader_lp.c:67
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
#define SCIP_MAXSTRLEN
Definition: def.h:293
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:107
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_lp.c:71
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_lp.c:2537
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
static SCIP_DECL_READERCOPY(readerCopyLp)
Definition: reader_lp.c:3356
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2450
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10630
static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
Definition: reader_lp.c:2521
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
static SCIP_Bool isSense(LPINPUT *lpinput, LPSENSE *sense)
Definition: reader_lp.c:792
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:548
enum LpSense LPSENSE
Definition: reader_lp.c:112
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
#define LP_MAX_PRINTLEN
Definition: reader_lp.c:82
static SCIP_RETCODE readSemicontinuous(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2135
#define LP_MAX_PUSHEDTOKENS
Definition: reader_lp.c:79
constraint handler for indicator constraints
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4547
#define FALSE
Definition: def.h:87
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define LP_PRINTLEN
Definition: reader_lp.c:84
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
static SCIP_RETCODE collectAggregatedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR ***aggvars, int *naggvars, int *saggvars, SCIP_HASHTABLE *varAggregated)
Definition: reader_lp.c:3140
LpExpType
Definition: reader_diff.c:74
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8394
public methods for problem variables
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
static SCIP_RETCODE readObjective(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1310
SCIP_READER * SCIPfindReader(SCIP *scip, const char *name)
Definition: scip_reader.c:226
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:123
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2501
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4673
#define LP_INIT_QUADCOEFSSIZE
Definition: reader_lp.c:81
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *rowname, const char *rownameextension, const char *type, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_lp.c:2668
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool isDelimChar(char c)
Definition: reader_lp.c:188
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
public methods for SCIP variables
static SCIP_Bool isNewSection(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:524
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:111
int SCIPfseek(SCIP_FILE *stream, long offset, int whence)
Definition: fileio.c:203
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_VAR **var, SCIP_Bool *created)
Definition: reader_lp.c:823
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
public methods for numerical tolerances
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2236
enum LpSection LPSECTION
Definition: reader_diff.c:72
static SCIP_DECL_READERFREE(readerFreeLp)
Definition: reader_lp.c:3370
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17726
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, LPEXPTYPE *exptype)
Definition: reader_lp.c:233
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3363
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
static void pushToken(LPINPUT *lpinput)
Definition: reader_lp.c:487
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2683
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8173
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:144
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition: reader.c:483
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
struct LpInput LPINPUT
Definition: reader_diff.c:105
public methods for managing constraints
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
Constraint handler for knapsack constraints of the form , x binary and .
static SCIP_RETCODE readSos(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2233
static SCIP_RETCODE readGenerals(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2036
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5154
#define SCIPerrorMessage
Definition: pub_message.h:55
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4175
static SCIP_Bool getNextLine(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:277
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip_cons.c:2558
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2768
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17856
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5179
static void printSosCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **vars, SCIP_Real *weights, int nvars, int type)
Definition: reader_lp.c:2994
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2526
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10513
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:403
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17876
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_lp.c:2637
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:191
SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(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)
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8085
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4763
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, 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)
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4102
#define NULL
Definition: lpi_spx1.cpp:155
static SCIP_RETCODE readStart(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:868
#define SCIP_CALL(x)
Definition: def.h:384
#define LP_INIT_COEFSSIZE
Definition: reader_lp.c:80
int SCIPgetNTotalVars(SCIP *scip)
Definition: scip_prob.c:2567
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1735
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_lp.c:2545
SCIP_RETCODE SCIPincludeReaderLp(SCIP *scip)
Definition: reader_lp.c:3412
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
Definition: graph_load.c:93
static SCIP_Bool getNextToken(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:382
#define READER_EXTENSION
Definition: reader_lp.c:69
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip_cons.c:2514
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4590
public methods for constraint handler plugins and constraints
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
wrapper functions to map file i/o to standard or zlib file i/o
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4510
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE readConstraints(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1625
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:44
public data structures and miscellaneous methods
SCIP_RETCODE SCIPcheckQuadraticNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *isquadratic)
static SCIP_DECL_READERWRITE(readerWriteLp)
Definition: reader_lp.c:3395
#define SCIP_Bool
Definition: def.h:84
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:100
static SCIP_RETCODE readBounds(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1865
void SCIPprintSysError(const char *message)
Definition: misc.c:10664
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
static SCIP_Bool isTokenChar(char c)
Definition: reader_lp.c:209
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9440
#define READER_DESC
Definition: reader_lp.c:68
constraint handler for nonlinear constraints specified by algebraic expressions
static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_lp.c:3250
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2551
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
#define MAX(x, y)
Definition: tclique_def.h:83
static SCIP_DECL_READERREAD(readerReadLp)
Definition: reader_lp.c:3384
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8105
enum LpSense LPSENSE
Definition: reader_diff.c:84
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8214
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17758
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10580
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:105
static SCIP_RETCODE readCoefficients(SCIP *scip, LPINPUT *lpinput, SCIP_Bool isobjective, char *name, int *coefssize, SCIP_VAR ***vars, SCIP_Real **coefs, int *ncoefs, int *quadcoefssize, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadcoefs, SCIP_Real *objoffset, SCIP_Bool *newsection)
Definition: reader_lp.c:889
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:210
static SCIP_RETCODE readBinaries(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2081
static SCIP_Bool isSign(LPINPUT *lpinput, int *sign)
Definition: reader_lp.c:735
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
enum LpSection LPSECTION
Definition: reader_lp.c:100
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12773
#define LP_MAX_NAMELEN
Definition: reader_lp.c:83
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:138
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9417
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2286
static void pushBufferToken(LPINPUT *lpinput)
Definition: reader_lp.c:500
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
static SCIP_RETCODE createIndicatorConstraint(SCIP *scip, LPINPUT *lpinput, const char *name, SCIP_VAR *binvar, SCIP_Real binvalue)
Definition: reader_lp.c:1405
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)
#define DEFAULT_AGGRLINEARIZATION_ANDS
Definition: reader_lp.c:72
LP file reader.
static const SCIP_Real scalars[]
Definition: lp.c:5736
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define LP_MAX_LINELEN
Definition: reader_lp.c:78
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
Definition: reader_lp.c:3196
static SCIP_RETCODE readLPFile(SCIP *scip, LPINPUT *lpinput, const char *filename)
Definition: reader_lp.c:2443
public methods for message output
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1421
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4145
enum LpExpType LPEXPTYPE
Definition: reader_diff.c:78
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3263
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17370
#define SCIP_Real
Definition: def.h:177
public methods for input file readers
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5130
constraint handler for SOS type 1 constraints
static void swapTokenBuffer(LPINPUT *lpinput)
Definition: reader_lp.c:513
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_lp.c:2614
public methods for message handling
LpSection
Definition: reader_diff.c:68
SCIP_RETCODE SCIPreadLp(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_lp.c:3446
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:186
LpSense
Definition: reader_diff.c:80
#define SCIP_Longint
Definition: def.h:162
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17590
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17416
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2599
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
static SCIP_Bool isValue(SCIP *scip, LPINPUT *lpinput, SCIP_Real *value)
Definition: reader_lp.c:760
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10376
constraint handler for SOS type 2 constraints
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos2.c:2351
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:102
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIPallocBlockMemory(scip, subsol))
SCIP_RETCODE SCIPwriteLp(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_lp.c:3522
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:223
constraint handler for bound disjunction constraints
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:356
public methods for global and local (sub)problems
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool hasError(LPINPUT *lpinput)
Definition: reader_lp.c:177
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_lp.c:2600
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE printQuadraticCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **linvars, SCIP_Real *linvals, int nlinvars, SCIP_EXPR *quadexpr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool transformed)
Definition: reader_lp.c:2906
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip_reader.c:162
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1524
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:48
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17406
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:119
memory allocation routines