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