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-2014 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  SCIPdebugMessage("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  SCIPdebugMessage("the buffer might be corrupted\n");
318  }
319  else
320  {
321  SCIPfseek(lpinput->file, -(long) strlen(last), SEEK_CUR);
322  SCIPdebugMessage("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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("(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  SCIPdebugMessage("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  SCIP_VAR*** vars, /**< pointer to store the array with variables (must be freed by caller) */
883  SCIP_Real** coefs, /**< pointer to store the array with coefficients (must be freed by caller) */
884  int* ncoefs, /**< pointer to store the number of coefficients */
885  SCIP_VAR*** quadvars1, /**< pointer to store the array with first variables in quadratic terms (must be freed by caller) */
886  SCIP_VAR*** quadvars2, /**< pointer to store the array with second variables in quadratic terms (must be freed by caller) */
887  SCIP_Real** quadcoefs, /**< pointer to store the array with coefficients in quadratic terms (must be freed by caller) */
888  int* nquadcoefs, /**< pointer to store the number of quadratic coefficients */
889  SCIP_Bool* newsection /**< pointer to store whether a new section was encountered */
890  )
891 {
892  SCIP_Bool havesign;
893  SCIP_Bool havevalue;
894  SCIP_Real coef;
895  int coefsign;
896  int coefssize;
897  SCIP_Bool inquadpart;
898  int quadcoefssize;
899  SCIP_VAR* firstquadvar;
900 
901  assert(lpinput != NULL);
902  assert(name != NULL);
903  assert(vars != NULL);
904  assert(coefs != NULL);
905  assert(ncoefs != NULL);
906  assert(quadvars1 != NULL);
907  assert(quadvars2 != NULL);
908  assert(quadcoefs != NULL);
909  assert(nquadcoefs != NULL);
910  assert(newsection != NULL);
911 
912  *vars = NULL;
913  *coefs = NULL;
914  *quadvars1 = NULL;
915  *quadvars2 = NULL;
916  *quadcoefs = NULL;
917  *name = '\0';
918  *ncoefs = 0;
919  *nquadcoefs = 0;
920  *newsection = FALSE;
921  inquadpart = FALSE;
922 
923  /* read the first token, which may be the name of the line */
924  if( getNextToken(scip, lpinput) )
925  {
926  /* check if we reached a new section */
927  if( isNewSection(scip, lpinput) )
928  {
929  *newsection = TRUE;
930  return SCIP_OKAY;
931  }
932 
933  /* remember the token in the token buffer */
934  swapTokenBuffer(lpinput);
935 
936  /* get the next token and check, whether it is a colon */
937  if( getNextToken(scip, lpinput) )
938  {
939  if( strcmp(lpinput->token, ":") == 0 )
940  {
941  /* the second token was a colon: the first token is the line name */
942  (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', LP_MAX_LINELEN);
943 
944  name[LP_MAX_LINELEN - 1] = '\0';
945  SCIPdebugMessage("(line %d) read constraint name: '%s'\n", lpinput->linenumber, name);
946  }
947  else
948  {
949  /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
950  pushToken(lpinput);
951  pushBufferToken(lpinput);
952  }
953  }
954  else
955  {
956  /* there was only one token left: push it back onto the token stack and parse it as coefficient */
957  pushBufferToken(lpinput);
958  }
959  }
960 
961  /* initialize buffers for storing the coefficients */
962  coefssize = LP_INIT_COEFSSIZE;
963  SCIP_CALL( SCIPallocMemoryArray(scip, vars, coefssize) );
964  SCIP_CALL( SCIPallocMemoryArray(scip, coefs, coefssize) );
965 
966  quadcoefssize = LP_INIT_QUADCOEFSSIZE;
967  SCIP_CALL( SCIPallocMemoryArray(scip, quadvars1, quadcoefssize) );
968  SCIP_CALL( SCIPallocMemoryArray(scip, quadvars2, quadcoefssize) );
969  SCIP_CALL( SCIPallocMemoryArray(scip, quadcoefs, quadcoefssize) );
970 
971  /* read the coefficients */
972  coefsign = +1;
973  coef = 1.0;
974  havesign = FALSE;
975  havevalue = FALSE;
976  firstquadvar = NULL;
977  *ncoefs = 0;
978  *nquadcoefs = 0;
979  while( getNextToken(scip, lpinput) )
980  {
981  SCIP_VAR* var;
982 
983  /* check if we read a sign */
984  if( isSign(lpinput, &coefsign) )
985  {
986  SCIPdebugMessage("(line %d) read coefficient sign: %+d\n", lpinput->linenumber, coefsign);
987  havesign = TRUE;
988  continue;
989  }
990 
991  /* check if we read a value */
992  if( isValue(scip, lpinput, &coef) )
993  {
994  SCIPdebugMessage("(line %d) read coefficient value: %g with sign %+d\n", lpinput->linenumber, coef, coefsign);
995  if( havevalue )
996  {
997  syntaxError(scip, lpinput, "two consecutive values.");
998  return SCIP_OKAY;
999  }
1000  havevalue = TRUE;
1001  continue;
1002  }
1003 
1004  /* check if we reached an equation sense */
1005  if( isSense(lpinput, NULL) )
1006  {
1007  if( isobjective )
1008  {
1009  syntaxError(scip, lpinput, "no sense allowed in objective");
1010  return SCIP_OKAY;
1011  }
1012 
1013  /* put the sense back onto the token stack */
1014  pushToken(lpinput);
1015  break;
1016  }
1017 
1018  /* check if we reached a new section, that will be only allowed when having no current sign and value and if we
1019  * are not in the qudratic part
1020  */
1021  if( (isobjective || (!havevalue && !havesign)) && !inquadpart && isNewSection(scip, lpinput) )
1022  {
1023  if( havesign && !havevalue )
1024  {
1025  SCIPwarningMessage(scip, "skipped single sign %c without value or variable in objective\n", coefsign == 1 ? '+' : '-');
1026  }
1027  else if( isobjective && havevalue && !SCIPisZero(scip, coef) )
1028  {
1029  SCIPwarningMessage(scip, "constant term %+g in objective is skipped\n", coef * coefsign);
1030  }
1031 
1032  *newsection = TRUE;
1033  return SCIP_OKAY;
1034  }
1035 
1036  /* check if we start a quadratic part */
1037  if( *lpinput->token == '[' )
1038  {
1039  if( inquadpart )
1040  {
1041  syntaxError(scip, lpinput, "cannot start quadratic part while already in quadratic part.");
1042  return SCIP_OKAY;
1043  }
1044  if( havesign && coefsign != +1 )
1045  {
1046  syntaxError(scip, lpinput, "cannot have '-' in front of quadratic part.");
1047  return SCIP_OKAY;
1048  }
1049  if( havevalue )
1050  {
1051  syntaxError(scip, lpinput, "cannot have value in front of quadratic part.");
1052  return SCIP_OKAY;
1053  }
1054 
1055  SCIPdebugMessage("(line %d) start quadratic part\n", lpinput->linenumber);
1056  inquadpart = TRUE;
1057  continue;
1058  }
1059 
1060  /* check if we end a quadratic part */
1061  if( *lpinput->token == ']' )
1062  {
1063  if( !inquadpart )
1064  {
1065  syntaxError(scip, lpinput, "cannot end quadratic part before starting one.");
1066  return SCIP_OKAY;
1067  }
1068  if( havesign || havevalue || firstquadvar != NULL )
1069  {
1070  if( firstquadvar == NULL )
1071  {
1072  syntaxError(scip, lpinput, "expected value or first quadratic variable.");
1073  }
1074  else
1075  {
1076  syntaxError(scip, lpinput, "expected second quadratic variable.");
1077  }
1078  return SCIP_OKAY;
1079  }
1080 
1081  SCIPdebugMessage("(line %d) end quadratic part\n", lpinput->linenumber);
1082  inquadpart = FALSE;
1083 
1084  if( isobjective )
1085  {
1086  /* quadratic part in objective has to end with '/2' */
1087  if( !getNextToken(scip, lpinput) )
1088  {
1089  syntaxError(scip, lpinput, "expected '/2' after end of quadratic part in objective.");
1090  return SCIP_OKAY;
1091  }
1092  if( strcmp(lpinput->token, "/2") == 0 )
1093  {
1094  SCIPdebugMessage("(line %d) saw '/2' after quadratic part in objective\n", lpinput->linenumber);
1095  }
1096  else if( *lpinput->token == '/' )
1097  {
1098  /* maybe it says '/ 2' */
1099  if( !getNextToken(scip, lpinput) || *lpinput->token == '2' )
1100  {
1101  syntaxError(scip, lpinput, "expected '/2' after end of quadratic part in objective.");
1102  return SCIP_OKAY;
1103  }
1104  SCIPdebugMessage("(line %d) saw '/ 2' after quadratic part in objective\n", lpinput->linenumber);
1105  }
1106  else
1107  {
1108  syntaxError(scip, lpinput, "expected '/2' after end of quadratic part in objective.");
1109  return SCIP_OKAY;
1110  }
1111  }
1112 
1113  continue;
1114  }
1115 
1116  /* check if we are in between two quadratic variables */
1117  if( *lpinput->token == '*' )
1118  {
1119  if( !inquadpart )
1120  {
1121  syntaxError(scip, lpinput, "cannot have '*' outside of quadratic part.");
1122  return SCIP_OKAY;
1123  }
1124  if( firstquadvar == NULL )
1125  {
1126  syntaxError(scip, lpinput, "cannot have '*' before first variable in quadratic term.");
1127  return SCIP_OKAY;
1128  }
1129 
1130  continue;
1131  }
1132 
1133  /* all but the first coefficient need a sign */
1134  if( !inquadpart && *ncoefs > 0 && !havesign )
1135  {
1136  syntaxError(scip, lpinput, "expected sign ('+' or '-') or sense ('<' or '>').");
1137  return SCIP_OKAY;
1138  }
1139  if( inquadpart && *nquadcoefs > 0 && !havesign )
1140  {
1141  syntaxError(scip, lpinput, "expected sign ('+' or '-').");
1142  return SCIP_OKAY;
1143  }
1144 
1145  /* check if the last variable should be squared */
1146  if( *lpinput->token == '^' )
1147  {
1148  if( !inquadpart )
1149  {
1150  syntaxError(scip, lpinput, "cannot have squares ('^2') outside of quadratic part.");
1151  return SCIP_OKAY;
1152  }
1153  if( firstquadvar == NULL )
1154  {
1155  syntaxError(scip, lpinput, "cannot have square '^2' before variable.");
1156  return SCIP_OKAY;
1157  }
1158 
1159  var = firstquadvar;
1160  }
1161  else
1162  {
1163  /* the token is a variable name: get the corresponding variable (or create a new one) */
1164  SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
1165  }
1166 
1167  if( !inquadpart )
1168  {
1169  /* insert the linear coefficient */
1170  SCIPdebugMessage("(line %d) read linear coefficient: %+g<%s>\n", lpinput->linenumber, coefsign * coef, SCIPvarGetName(var));
1171  if( !SCIPisZero(scip, coef) )
1172  {
1173  /* resize the vars and coefs array if needed */
1174  if( *ncoefs >= coefssize )
1175  {
1176  coefssize *= 2;
1177  coefssize = MAX(coefssize, (*ncoefs)+1);
1178  SCIP_CALL( SCIPreallocMemoryArray(scip, vars, coefssize) );
1179  SCIP_CALL( SCIPreallocMemoryArray(scip, coefs, coefssize) );
1180  }
1181  assert(*ncoefs < coefssize);
1182 
1183  /* add coefficient */
1184  (*vars)[*ncoefs] = var;
1185  (*coefs)[*ncoefs] = coefsign * coef;
1186  (*ncoefs)++;
1187  }
1188  }
1189  else
1190  {
1191  if( firstquadvar == NULL )
1192  {
1193  /* if first quadratic variable read, store it and continue; expect second one in next round */
1194  firstquadvar = var;
1195  continue;
1196  }
1197 
1198  /* insert the quadratic coefficient */
1199  SCIPdebugMessage("(line %d) read quadratic coefficient: %+g<%s><%s>\n", lpinput->linenumber, (isobjective ? 0.5 : 1) * coefsign * coef, SCIPvarGetName(firstquadvar), SCIPvarGetName(var));
1200  if( !SCIPisZero(scip, coef) )
1201  {
1202  /* resize the vars and coefs array if needed */
1203  if( *nquadcoefs >= quadcoefssize )
1204  {
1205  quadcoefssize *= 2;
1206  quadcoefssize = MAX(quadcoefssize, (*nquadcoefs)+1);
1207  SCIP_CALL( SCIPreallocMemoryArray(scip, quadvars1, quadcoefssize) );
1208  SCIP_CALL( SCIPreallocMemoryArray(scip, quadvars2, quadcoefssize) );
1209  SCIP_CALL( SCIPreallocMemoryArray(scip, quadcoefs, quadcoefssize) );
1210  }
1211  assert(*nquadcoefs < quadcoefssize);
1212 
1213  /* add coefficient */
1214  (*quadvars1)[*nquadcoefs] = firstquadvar;
1215  (*quadvars2)[*nquadcoefs] = var;
1216  (*quadcoefs)[*nquadcoefs] = coefsign * coef;
1217  if( isobjective )
1218  (*quadcoefs)[*nquadcoefs] /= 2.0;
1219  (*nquadcoefs)++;
1220  }
1221  }
1222 
1223  /* reset the flags and coefficient value for the next coefficient */
1224  coefsign = +1;
1225  coef = 1.0;
1226  havesign = FALSE;
1227  havevalue = FALSE;
1228  firstquadvar = NULL;
1229  }
1230 
1231  return SCIP_OKAY;
1232 }
1233 
1234 /** reads the objective section */
1235 static
1237  SCIP* scip, /**< SCIP data structure */
1238  LPINPUT* lpinput /**< LP reading data */
1239  )
1240 {
1241  char name[LP_MAX_LINELEN];
1242  SCIP_VAR** vars;
1243  SCIP_Real* coefs;
1244  int ncoefs;
1245  SCIP_VAR** quadvars1;
1246  SCIP_VAR** quadvars2;
1247  SCIP_Real* quadcoefs;
1248  int nquadcoefs;
1249  SCIP_Bool newsection;
1250 
1251  assert(lpinput != NULL);
1252 
1253  /* read the objective coefficients */
1254  SCIP_CALL( readCoefficients(scip, lpinput, TRUE, name, &vars, &coefs, &ncoefs, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, &newsection) );
1255  if( !hasError(lpinput) )
1256  {
1257  int i;
1258 
1259  /* set the linear objective values */
1260  for( i = 0; i < ncoefs; ++i )
1261  {
1262  SCIP_CALL( SCIPchgVarObj(scip, vars[i], SCIPvarGetObj(vars[i]) + coefs[i]) );
1263  }
1264 
1265  /* insert dummy variable and constraint to represent quadratic part of objective; note that
1266  * reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model constraints and variables, not
1267  * to an auxiliary objective constraint (otherwise it can happen that an auxiliary objective variable is loose
1268  * with infinite best bound, triggering the problem that an LP that is unbounded because of loose variables with
1269  * infinite best bound cannot be solved)
1270  */
1271  if( nquadcoefs > 0 )
1272  {
1273  SCIP_VAR* quadobjvar;
1274  SCIP_CONS* quadobjcons;
1275  SCIP_Real lhs;
1276  SCIP_Real rhs;
1277  SCIP_Real minusone;
1278 
1279  SCIP_CALL( SCIPcreateVar(scip, &quadobjvar, "quadobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1281  SCIP_CALL( SCIPaddVar(scip, quadobjvar) );
1282 
1283  if( lpinput->objsense == SCIP_OBJSENSE_MINIMIZE )
1284  {
1285  lhs = -SCIPinfinity(scip);
1286  rhs = 0.0;
1287  }
1288  else
1289  {
1290  lhs = 0.0;
1291  rhs = SCIPinfinity(scip);
1292  }
1293 
1294  minusone = -1.0;
1295  SCIP_CALL( SCIPcreateConsQuadratic(scip, &quadobjcons, "quadobj", 1, &quadobjvar, &minusone, nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1296  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1297 
1298  SCIP_CALL( SCIPaddCons(scip, quadobjcons) );
1299  SCIPdebugMessage("(line %d) added constraint <%s> to represent quadratic objective: ", lpinput->linenumber, SCIPconsGetName(quadobjcons));
1300  SCIPdebugPrintCons(scip, quadobjcons, NULL);
1301 
1302  SCIP_CALL( SCIPreleaseCons(scip, &quadobjcons) );
1303  SCIP_CALL( SCIPreleaseVar(scip, &quadobjvar) );
1304  }
1305  }
1306 
1307  /* free memory */
1308  SCIPfreeMemoryArrayNull(scip, &vars);
1309  SCIPfreeMemoryArrayNull(scip, &coefs);
1310  SCIPfreeMemoryArrayNull(scip, &quadvars1);
1311  SCIPfreeMemoryArrayNull(scip, &quadvars2);
1312  SCIPfreeMemoryArrayNull(scip, &quadcoefs);
1313 
1314  return SCIP_OKAY;
1315 }
1316 
1317 /** create indicator constraint */
1318 static
1320  SCIP* scip, /**< SCIP data structure */
1321  LPINPUT* lpinput, /**< LP reading data */
1322  const char* name, /**< name of indicator constraint */
1323  SCIP_VAR* binvar, /**< binary indicator variable */
1324  SCIP_Real binvalue /**< value of indicator part (0/1) */
1325  )
1326 {
1327  char name2[LP_MAX_LINELEN];
1328  SCIP_VAR** linvars;
1329  SCIP_Real* lincoefs;
1330  int nlincoefs;
1331  SCIP_VAR** quadvars1;
1332  SCIP_VAR** quadvars2;
1333  SCIP_Real* quadcoefs;
1334  int nquadcoefs;
1335  SCIP_Bool newsection;
1336  LPSENSE linsense;
1337  SCIP_Real linsidevalue;
1338  int linsidesign;
1339  SCIP_CONS* cons;
1340  SCIP_Real linrhs;
1341  int j;
1342  SCIP_Bool linConsEQ;
1343 
1344  SCIP_Bool initial;
1345  SCIP_Bool separate;
1346  SCIP_Bool enforce;
1347  SCIP_Bool check;
1348  SCIP_Bool propagate;
1349  SCIP_Bool local;
1350  SCIP_Bool dynamic;
1351  SCIP_Bool removable;
1352 
1353  assert( lpinput != NULL );
1354  assert( binvar != NULL );
1355 
1356  /* check that binvalue is 0 or 1 */
1357  if( !SCIPisFeasEQ(scip, binvalue, 0.0) && !SCIPisFeasEQ(scip, binvalue, 1.0) )
1358  {
1359  syntaxError(scip, lpinput, "value for binary variable must be '0' or '1'.");
1360  return SCIP_OKAY;
1361  }
1362 
1363  if( SCIPisFeasEQ(scip, binvalue, 0.0) )
1364  {
1365  SCIP_VAR* negbinvar;
1366  SCIP_Bool infeasible;
1367 
1368  /* At this point we force the variable binvar to be binary, since we need the negated variable. We have to check
1369  * later whether the type of the variable specified in the file agrees with this specification.
1370  */
1371  /* check whether bounds are correct - might already been set if variable is used in another indicator constraint */
1372  if( SCIPvarGetLbGlobal(binvar) < 0.0 )
1373  SCIP_CALL( SCIPchgVarLb(scip, binvar, 0.0) );
1374  if( SCIPvarGetUbGlobal(binvar) > 1.0 )
1375  SCIP_CALL( SCIPchgVarUb(scip, binvar, 1.0) );
1376  SCIP_CALL( SCIPchgVarType(scip, binvar, SCIP_VARTYPE_BINARY, &infeasible) );
1377  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1378 
1379  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
1380  binvar = negbinvar;
1381  assert( binvar != NULL );
1382  }
1383 
1384  /* read linear constraint */
1385  SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name2, &linvars, &lincoefs, &nlincoefs, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, &newsection) );
1386  if( hasError(lpinput) )
1387  goto TERMINATE;
1388  if( newsection )
1389  {
1390  syntaxError(scip, lpinput, "expected constraint.");
1391  goto TERMINATE;
1392  }
1393  if( nquadcoefs > 0 )
1394  {
1395  /* @todo could introduce auxiliary variable and move quadratic part into quadratic constraint? */
1396  syntaxError(scip, lpinput, "quadratic indicator constraints not supported.");
1397  goto TERMINATE;
1398  }
1399  if( name2[0] != '\0' )
1400  {
1401  syntaxError(scip, lpinput, "did not expect name for linear constraint.");
1402  goto TERMINATE;
1403  }
1404 
1405  /* read the constraint sense */
1406  if( !getNextToken(scip, lpinput) || !isSense(lpinput, &linsense) )
1407  {
1408  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1409  goto TERMINATE;
1410  }
1411 
1412  /* read the right hand side */
1413  linsidesign = +1;
1414  if( !getNextToken(scip, lpinput) )
1415  {
1416  syntaxError(scip, lpinput, "missing right hand side.");
1417  goto TERMINATE;
1418  }
1419  if( isSign(lpinput, &linsidesign) )
1420  {
1421  if( !getNextToken(scip, lpinput) )
1422  {
1423  syntaxError(scip, lpinput, "missing value of right hand side.");
1424  goto TERMINATE;
1425  }
1426  }
1427  if( !isValue(scip, lpinput, &linsidevalue) )
1428  {
1429  syntaxError(scip, lpinput, "expected value for right hand side.");
1430  goto TERMINATE;
1431  }
1432  linsidevalue *= linsidesign;
1433 
1434  /* assign the left and right hand side, depending on the constraint sense */
1435  linConsEQ = FALSE;
1436  switch( linsense )
1437  {
1438  case LP_SENSE_GE:
1439  linrhs = -linsidevalue;
1440  for( j = 0; j < nlincoefs; ++j )
1441  lincoefs[j] *= -1;
1442  break;
1443  case LP_SENSE_LE:
1444  linrhs = linsidevalue;
1445  break;
1446  case LP_SENSE_EQ:
1447  linConsEQ = TRUE;
1448  linrhs = linsidevalue;
1449  break;
1450  case LP_SENSE_NOTHING:
1451  default:
1452  SCIPerrorMessage("invalid constraint sense <%d>\n", linsense);
1453  return SCIP_INVALIDDATA;
1454  }
1455 
1456  /* create and add the indicator constraint */
1457  initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
1458  separate = TRUE;
1459  enforce = !lpinput->inusercuts;
1460  check = !lpinput->inusercuts;
1461  propagate = TRUE;
1462  local = FALSE;
1463  dynamic = lpinput->dynamicconss;
1464  removable = lpinput->dynamicrows || lpinput->inusercuts;
1465 
1466  SCIP_CALL( SCIPcreateConsIndicator(scip, &cons, name, binvar, nlincoefs, linvars, lincoefs, linrhs,
1467  initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE) );
1468  SCIP_CALL( SCIPaddCons(scip, cons) );
1469  SCIPdebugMessage("(line %d) created constraint%s: ", lpinput->linenumber,
1470  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1471  SCIPdebugPrintCons(scip, cons, NULL);
1472  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1473 
1474  /* create second constraint if it was an equation */
1475  if( linConsEQ )
1476  {
1477  char newname[SCIP_MAXSTRLEN];
1478 
1479  (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "%s_eqneg", name);
1480 
1481  for( j = 0; j < nlincoefs; ++j )
1482  lincoefs[j] *= -1;
1483  linrhs *= -1;
1484  SCIP_CALL( SCIPcreateConsIndicator(scip, &cons, newname, binvar, nlincoefs, linvars, lincoefs, linrhs,
1485  initial, separate, enforce, check, propagate, local, dynamic, removable, FALSE) );
1486  SCIP_CALL( SCIPaddCons(scip, cons) );
1487  SCIPdebugMessage("(line %d) created constraint%s: ", lpinput->linenumber,
1488  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1489  SCIPdebugPrintCons(scip, cons, NULL);
1490  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1491  }
1492 
1493  TERMINATE:
1494  /* free memory */
1495  SCIPfreeMemoryArrayNull(scip, &linvars);
1496  SCIPfreeMemoryArrayNull(scip, &lincoefs);
1497  SCIPfreeMemoryArrayNull(scip, &quadvars1);
1498  SCIPfreeMemoryArrayNull(scip, &quadvars2);
1499  SCIPfreeMemoryArrayNull(scip, &quadcoefs);
1500 
1501  return SCIP_OKAY;
1502 }
1503 
1504 /** reads the constraints section
1505  *
1506  * Read linear and indicator constraints.
1507  *
1508  * The CPLEX manual says that indicator constraints are of the following form:
1509  *
1510  * [constraintname:] binaryvariable = value -> linear constraint
1511  *
1512  * We also accept "<->".
1513  */
1514 static
1516  SCIP* scip, /**< SCIP data structure */
1517  LPINPUT* lpinput /**< LP reading data */
1518  )
1519 {
1520  char name[LP_MAX_LINELEN];
1521  SCIP_CONS* cons;
1522  SCIP_VAR** vars;
1523  SCIP_Real* coefs;
1524  SCIP_VAR** quadvars1;
1525  SCIP_VAR** quadvars2;
1526  SCIP_Real* quadcoefs;
1527  SCIP_Bool newsection;
1528  LPSENSE sense;
1529  SCIP_Real sidevalue;
1530  SCIP_Real lhs;
1531  SCIP_Real rhs;
1532  SCIP_Bool initial;
1533  SCIP_Bool separate;
1534  SCIP_Bool enforce;
1535  SCIP_Bool check;
1536  SCIP_Bool propagate;
1537  SCIP_Bool local;
1538  SCIP_Bool modifiable;
1539  SCIP_Bool dynamic;
1540  SCIP_Bool removable;
1541  int ncoefs;
1542  int nquadcoefs;
1543  int sidesign;
1544  SCIP_Bool isIndicatorCons;
1545 
1546  assert(lpinput != NULL);
1547 
1548  /* read coefficients */
1549  SCIP_CALL( readCoefficients(scip, lpinput, FALSE, name, &vars, &coefs, &ncoefs, &quadvars1, &quadvars2, &quadcoefs, &nquadcoefs, &newsection) );
1550  if( hasError(lpinput) )
1551  goto TERMINATE;
1552  if( newsection )
1553  {
1554  if( ncoefs > 0 || nquadcoefs > 0 )
1555  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1556  goto TERMINATE;
1557  }
1558 
1559  /* read the constraint sense */
1560  if( !getNextToken(scip, lpinput) || !isSense(lpinput, &sense) )
1561  {
1562  syntaxError(scip, lpinput, "expected constraint sense '<=', '=', or '>='.");
1563  goto TERMINATE;
1564  }
1565 
1566  /* read the right hand side */
1567  sidesign = +1;
1568  if( !getNextToken(scip, lpinput) )
1569  {
1570  syntaxError(scip, lpinput, "missing right hand side.");
1571  goto TERMINATE;
1572  }
1573  if( isSign(lpinput, &sidesign) )
1574  {
1575  if( !getNextToken(scip, lpinput) )
1576  {
1577  syntaxError(scip, lpinput, "missing value of right hand side.");
1578  goto TERMINATE;
1579  }
1580  }
1581  if( !isValue(scip, lpinput, &sidevalue) )
1582  {
1583  syntaxError(scip, lpinput, "expected value as right hand side.");
1584  goto TERMINATE;
1585  }
1586  sidevalue *= sidesign;
1587 
1588  /* assign the left and right hand side, depending on the constraint sense */
1589  switch( sense )
1590  {
1591  case LP_SENSE_GE:
1592  lhs = sidevalue;
1593  rhs = SCIPinfinity(scip);
1594  break;
1595  case LP_SENSE_LE:
1596  lhs = -SCIPinfinity(scip);
1597  rhs = sidevalue;
1598  break;
1599  case LP_SENSE_EQ:
1600  lhs = sidevalue;
1601  rhs = sidevalue;
1602  break;
1603  case LP_SENSE_NOTHING:
1604  default:
1605  SCIPerrorMessage("invalid constraint sense <%d>.\n", sense);
1606  return SCIP_INVALIDDATA;
1607  }
1608 
1609  /* check whether we read the first part of an indicator constraint */
1610  isIndicatorCons = FALSE;
1611  if ( getNextToken(scip, lpinput) && !isNewSection(scip, lpinput) )
1612  {
1613  /* check whether we have '<' from a "<->" string */
1614  if ( *lpinput->token == '<' )
1615  {
1616  SCIP_Bool haveequiv = FALSE;
1617  int linepos = lpinput->linepos-1;
1618 
1619  /* check next token - cannot be a new section */
1620  if ( getNextToken(scip, lpinput) )
1621  {
1622  /* check for "<-" */
1623  if ( *lpinput->token == '-' )
1624  {
1625  /* check next token - cannot be a new section */
1626  if ( getNextToken(scip, lpinput) )
1627  {
1628  /* check for "<->" */
1629  if ( *lpinput->token == '>' )
1630  {
1631  lpinput->linepos = linepos;
1632  strcpy(lpinput->token, "<");
1633  syntaxError(scip, lpinput,
1634  "SCIP does not support equivalence (<->) indicator constraints; consider using the \"->\" form.");
1635  haveequiv = TRUE;
1636  }
1637  }
1638  }
1639  }
1640  if ( ! haveequiv )
1641  {
1642  lpinput->linepos = linepos;
1643  strcpy(lpinput->token, "<");
1644  syntaxError(scip, lpinput, "unexpected \"<\".");
1645  }
1646  goto TERMINATE;
1647  }
1648 
1649  /* check for "->" */
1650  if ( *lpinput->token == '-' )
1651  {
1652  /* remember '-' in token buffer */
1653  swapTokenBuffer(lpinput);
1654 
1655  /* check next token - cannot be a new section */
1656  if( getNextToken(scip, lpinput) )
1657  {
1658  /* check for "->" */
1659  if ( *lpinput->token == '>' )
1660  isIndicatorCons = TRUE;
1661  else
1662  {
1663  /* push back last token and '-' */
1664  pushToken(lpinput);
1665  pushBufferToken(lpinput);
1666  }
1667  }
1668  else
1669  pushBufferToken(lpinput);
1670  }
1671  else
1672  pushToken(lpinput);
1673  }
1674 
1675  if( !isIndicatorCons )
1676  {
1677  /* create and add the linear constraint */
1678  initial = lpinput->initialconss && !lpinput->inlazyconstraints && !lpinput->inusercuts;
1679  separate = TRUE;
1680  enforce = !lpinput->inusercuts;
1681  check = !lpinput->inusercuts;
1682  propagate = TRUE;
1683  local = FALSE;
1684  modifiable = FALSE;
1685  dynamic = lpinput->dynamicconss;
1686  removable = lpinput->dynamicrows || lpinput->inusercuts;
1687  if( nquadcoefs == 0 )
1688  {
1689  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name, ncoefs, vars, coefs, lhs, rhs,
1690  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
1691  }
1692  else
1693  {
1694  SCIP_CALL( SCIPcreateConsQuadratic(scip, &cons, name, ncoefs, vars, coefs,
1695  nquadcoefs, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1696  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) );
1697  }
1698  SCIP_CALL( SCIPaddCons(scip, cons) );
1699  SCIPdebugMessage("(line %d) created constraint%s: ", lpinput->linenumber,
1700  lpinput->inlazyconstraints ? " (lazy)" : (lpinput->inusercuts ? " (user cut)" : ""));
1701  SCIPdebugPrintCons(scip, cons, NULL);
1702  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1703  }
1704  else
1705  {
1706  /* now we should have an indicator constraint */
1707  if( ncoefs != 1 || nquadcoefs > 0 )
1708  {
1709  syntaxError(scip, lpinput, "Indicator part can only consist of one binary variable.");
1710  goto TERMINATE;
1711  }
1712  if( !SCIPisEQ(scip, coefs[0], 1.0) )
1713  {
1714  syntaxError(scip, lpinput, "There cannot be a coefficient before the binary indicator variable.");
1715  goto TERMINATE;
1716  }
1717  if( sense != LP_SENSE_EQ )
1718  {
1719  syntaxError(scip, lpinput, "Indicator part cannot handle equations.");
1720  goto TERMINATE;
1721  }
1722 
1723  SCIP_CALL( createIndicatorConstraint(scip, lpinput, name, vars[0], lhs) );
1724  }
1725 
1726  TERMINATE:
1727  /* free memory */
1728  SCIPfreeMemoryArrayNull(scip, &vars);
1729  SCIPfreeMemoryArrayNull(scip, &coefs);
1730  SCIPfreeMemoryArrayNull(scip, &quadvars1);
1731  SCIPfreeMemoryArrayNull(scip, &quadvars2);
1732  SCIPfreeMemoryArrayNull(scip, &quadcoefs);
1733 
1734  return SCIP_OKAY;
1735 }
1736 
1737 /** reads the bounds section */
1738 static
1740  SCIP* scip, /**< SCIP data structure */
1741  LPINPUT* lpinput /**< LP reading data */
1742  )
1743 {
1744  assert(lpinput != NULL);
1745 
1746  while( getNextToken(scip, lpinput) )
1747  {
1748  SCIP_VAR* var;
1749  SCIP_Real value;
1750  SCIP_Real lb;
1751  SCIP_Real ub;
1752  int sign;
1753  SCIP_Bool hassign;
1754  LPSENSE leftsense;
1755 
1756  /* check if we reached a new section */
1757  if( isNewSection(scip, lpinput) )
1758  return SCIP_OKAY;
1759 
1760  /* default bounds are [0,+inf] */
1761  lb = 0.0;
1762  ub = SCIPinfinity(scip);
1763  leftsense = LP_SENSE_NOTHING;
1764 
1765  /* check if the first token is a sign */
1766  sign = +1;
1767  hassign = isSign(lpinput, &sign);
1768  if( hassign && !getNextToken(scip, lpinput) )
1769  {
1770  syntaxError(scip, lpinput, "expected value.");
1771  return SCIP_OKAY;
1772  }
1773 
1774  /* the first token must be either a value or a variable name */
1775  if( isValue(scip, lpinput, &value) )
1776  {
1777  /* first token is a value: the second token must be a sense */
1778  if( !getNextToken(scip, lpinput) || !isSense(lpinput, &leftsense) )
1779  {
1780  syntaxError(scip, lpinput, "expected bound sense '<=', '=', or '>='.");
1781  return SCIP_OKAY;
1782  }
1783 
1784  /* update the bound corresponding to the sense */
1785  switch( leftsense )
1786  {
1787  case LP_SENSE_GE:
1788  ub = sign * value;
1789  break;
1790  case LP_SENSE_LE:
1791  lb = sign * value;
1792  break;
1793  case LP_SENSE_EQ:
1794  lb = sign * value;
1795  ub = sign * value;
1796  break;
1797  case LP_SENSE_NOTHING:
1798  default:
1799  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1800  return SCIP_INVALIDDATA;
1801  }
1802  }
1803  else if( hassign )
1804  {
1805  syntaxError(scip, lpinput, "expected value.");
1806  return SCIP_OKAY;
1807  }
1808  else
1809  pushToken(lpinput);
1810 
1811  /* the next token must be a variable name */
1812  if( !getNextToken(scip, lpinput) )
1813  {
1814  syntaxError(scip, lpinput, "expected variable name.");
1815  return SCIP_OKAY;
1816  }
1817  SCIP_CALL( getVariable(scip, lpinput->token, &var, NULL) );
1818 
1819  /* the next token might be another sense, or the word "free" */
1820  if( getNextToken(scip, lpinput) )
1821  {
1822  LPSENSE rightsense;
1823 
1824  if( isSense(lpinput, &rightsense) )
1825  {
1826  /* check, if the senses fit */
1827  if( leftsense == LP_SENSE_NOTHING
1828  || (leftsense == LP_SENSE_LE && rightsense == LP_SENSE_LE)
1829  || (leftsense == LP_SENSE_GE && rightsense == LP_SENSE_GE) )
1830  {
1831  if( !getNextToken(scip, lpinput) )
1832  {
1833  syntaxError(scip, lpinput, "expected value or sign.");
1834  return SCIP_OKAY;
1835  }
1836 
1837  /* check if the next token is a sign */
1838  sign = +1;
1839  hassign = isSign(lpinput, &sign);
1840  if( hassign && !getNextToken(scip, lpinput) )
1841  {
1842  syntaxError(scip, lpinput, "expected value.");
1843  return SCIP_OKAY;
1844  }
1845 
1846  /* the next token must be a value */
1847  if( !isValue(scip, lpinput, &value) )
1848  {
1849  syntaxError(scip, lpinput, "expected value.");
1850  return SCIP_OKAY;
1851  }
1852 
1853  /* update the bound corresponding to the sense */
1854  switch( rightsense )
1855  {
1856  case LP_SENSE_GE:
1857  lb = sign * value;
1858  break;
1859  case LP_SENSE_LE:
1860  ub = sign * value;
1861  break;
1862  case LP_SENSE_EQ:
1863  lb = sign * value;
1864  ub = sign * value;
1865  break;
1866  case LP_SENSE_NOTHING:
1867  default:
1868  SCIPerrorMessage("invalid bound sense <%d>\n", leftsense);
1869  return SCIP_INVALIDDATA;
1870  }
1871  }
1872  else
1873  {
1874  syntaxError(scip, lpinput, "the two bound senses do not fit.");
1875  return SCIP_OKAY;
1876  }
1877  }
1878  else if( strcasecmp(lpinput->token, "FREE") == 0 )
1879  {
1880  if( leftsense != LP_SENSE_NOTHING )
1881  {
1882  syntaxError(scip, lpinput, "variable with bound is marked as 'free'.");
1883  return SCIP_OKAY;
1884  }
1885  lb = -SCIPinfinity(scip);
1886  ub = SCIPinfinity(scip);
1887  }
1888  else
1889  {
1890  /* the token was no sense: push it back to the token stack */
1891  pushToken(lpinput);
1892  }
1893  }
1894 
1895  /* change the bounds of the variable if bounds have been given (do not destroy earlier specification of bounds) */
1896  if( lb != 0.0 )
1897  SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
1898  /*lint --e{777}*/
1899  if( ub != SCIPinfinity(scip) )
1900  SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
1901  SCIPdebugMessage("(line %d) new bounds: <%s>[%g,%g]\n", lpinput->linenumber, SCIPvarGetName(var),
1903  }
1904 
1905  return SCIP_OKAY;
1906 }
1907 
1908 /** reads the generals section */
1909 static
1911  SCIP* scip, /**< SCIP data structure */
1912  LPINPUT* lpinput /**< LP reading data */
1913  )
1914 {
1915  assert(lpinput != NULL);
1916 
1917  while( getNextToken(scip, lpinput) )
1918  {
1919  SCIP_VAR* var;
1920  SCIP_Real lb;
1921  SCIP_Real ub;
1922  SCIP_Bool created;
1923  SCIP_Bool infeasible;
1924 
1925  /* check if we reached a new section */
1926  if( isNewSection(scip, lpinput) )
1927  return SCIP_OKAY;
1928 
1929  /* the token must be the name of an existing variable */
1930  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
1931  if( created )
1932  {
1933  syntaxError(scip, lpinput, "unknown variable in generals section.");
1934  return SCIP_OKAY;
1935  }
1936 
1937  lb = SCIPvarGetLbGlobal(var);
1938  ub = SCIPvarGetUbGlobal(var);
1939 
1940  if( !SCIPisFeasIntegral(scip, lb) || !SCIPisFeasIntegral(scip, ub) )
1941  {
1942  SCIPwarningMessage(scip, "variable <%s> declared as integer has non-integral bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
1943  }
1944 
1945  /* mark the variable to be integral */
1946  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1947  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1948  }
1949 
1950  return SCIP_OKAY;
1951 }
1952 
1953 /** reads the binaries section */
1954 static
1956  SCIP* scip, /**< SCIP data structure */
1957  LPINPUT* lpinput /**< LP reading data */
1958  )
1959 {
1960  assert(lpinput != NULL);
1961 
1962  while( getNextToken(scip, lpinput) )
1963  {
1964  SCIP_VAR* var;
1965  SCIP_Real lb;
1966  SCIP_Real ub;
1967  SCIP_Bool created;
1968  SCIP_Bool infeasible;
1969 
1970  /* check if we reached a new section */
1971  if( isNewSection(scip, lpinput) )
1972  return SCIP_OKAY;
1973 
1974  /* the token must be the name of an existing variable */
1975  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
1976  if( created )
1977  {
1978  syntaxError(scip, lpinput, "unknown variable in binaries section.");
1979  return SCIP_OKAY;
1980  }
1981 
1982  lb = SCIPvarGetLbGlobal(var);
1983  ub = SCIPvarGetUbGlobal(var);
1984 
1985  if( (!SCIPisFeasZero(scip, lb) && !SCIPisFeasEQ(scip, lb, 1.0)) ||
1986  (!SCIPisFeasZero(scip, ub) && !SCIPisFeasEQ(scip, ub, 1.0) && !SCIPisInfinity(scip, ub)) )
1987  {
1988  SCIPwarningMessage(scip, "variable <%s> declared as binary has non-binary bounds[%.14g, %.14g] -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), lb, ub);
1989  }
1990 
1991  /* mark the variable to be binary and change its bounds appropriately */
1992  if( SCIPvarGetLbGlobal(var) < 0.0 )
1993  {
1994  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1995  }
1996  if( SCIPvarGetUbGlobal(var) > 1.0 )
1997  {
1998  SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1999  }
2000  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
2001  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
2002  }
2003 
2004  return SCIP_OKAY;
2005 }
2006 
2007 /** reads the semi-continuous section */
2008 static
2010  SCIP* scip, /**< SCIP data structure */
2011  LPINPUT* lpinput /**< LP reading data */
2012  )
2013 {
2014  SCIP_Real oldlb;
2015  char name[SCIP_MAXSTRLEN];
2016  SCIP_CONS* cons;
2017  SCIP_VAR* var;
2018  SCIP_Bool created;
2019 
2020  SCIP_VAR* vars[2];
2021  SCIP_BOUNDTYPE boundtypes[2];
2022  SCIP_Real bounds[2];
2023 
2024  assert(lpinput != NULL);
2025 
2026  /* if section is titles "semi-continuous", then the parser breaks this into parts */
2027  if( strcasecmp(lpinput->token, "SEMI") == 0 )
2028  {
2029  if( !getNextToken(scip, lpinput) )
2030  {
2031  syntaxError(scip, lpinput, "unexpected end.");
2032  return SCIP_OKAY;
2033  }
2034 
2035  if( strcasecmp(lpinput->token, "-") == 0 )
2036  {
2037  if( !getNextToken(scip, lpinput) || strcasecmp(lpinput->token, "CONTINUOUS") != 0 )
2038  {
2039  syntaxError(scip, lpinput, "expected 'CONTINUOUS' after 'SEMI-'.");
2040  return SCIP_OKAY;
2041  }
2042  }
2043  else
2044  {
2045  pushToken(lpinput);
2046  }
2047  }
2048 
2049  while( getNextToken(scip, lpinput) )
2050  {
2051  /* check if we reached a new section */
2052  if( isNewSection(scip, lpinput) )
2053  return SCIP_OKAY;
2054 
2055  /* the token must be the name of an existing variable */
2056  SCIP_CALL( getVariable(scip, lpinput->token, &var, &created) );
2057  if( created )
2058  {
2059  syntaxError(scip, lpinput, "unknown variable in semi-continuous section.");
2060  return SCIP_OKAY;
2061  }
2062 
2063  if( SCIPvarGetLbGlobal(var) <= 0.0 )
2064  {
2065  SCIPdebugMessage("ignore semi-continuity of variable <%s> with negative lower bound %g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
2066  continue;
2067  }
2068 
2069  oldlb = SCIPvarGetLbGlobal(var);
2070 
2071  /* change the lower bound to 0.0 */
2072  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
2073 
2074  /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
2075  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
2076 
2077  vars[0] = var;
2078  vars[1] = var;
2079  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
2080  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
2081  bounds[0] = 0.0;
2082  bounds[1] = oldlb;
2083 
2084  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
2085  !(lpinput->dynamiccols), TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, lpinput->dynamicconss, lpinput->dynamiccols, FALSE) );
2086  SCIP_CALL( SCIPaddCons(scip, cons) );
2087 
2088  SCIPdebugMessage("add bound disjunction constraint for semi-continuity of <%s>:\n\t", SCIPvarGetName(var));
2089  SCIPdebugPrintCons(scip, cons, NULL);
2090 
2091  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2092  }
2093 
2094  return SCIP_OKAY;
2095 }
2096 
2097 /** reads the sos section
2098  *
2099  * The format is as follows:
2100  *
2101  * SOS
2102  * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
2103  * ...
2104  * <constraint name>: [S1|S2]:: {<variable name>:<weight>}
2105  * */
2106 static
2108  SCIP* scip, /**< SCIP data structure */
2109  LPINPUT* lpinput /**< LP reading data */
2110  )
2111 {
2112  SCIP_Bool initial, separate, enforce, check, propagate;
2113  SCIP_Bool local, modifiable, dynamic, removable;
2114  char name[SCIP_MAXSTRLEN];
2115  int cnt = 0;
2116 
2117  assert(lpinput != NULL);
2118 
2119  /* standard settings for SOS constraints: */
2120  initial = lpinput->initialconss;
2121  separate = FALSE;
2122  enforce = TRUE;
2123  check = TRUE;
2124  propagate = TRUE;
2125  local = FALSE;
2126  modifiable = FALSE;
2127  dynamic = lpinput->dynamicconss;
2128  removable = lpinput->dynamicrows;
2129 
2130  while( getNextToken(scip, lpinput) )
2131  {
2132  int type = -1;
2133  SCIP_CONS* cons;
2134 
2135  /* check if we reached a new section */
2136  if( isNewSection(scip, lpinput) )
2137  return SCIP_OKAY;
2138 
2139  /* check for an SOS constraint name */
2140  *name = '\0';
2141 
2142  /* remember the token in the token buffer */
2143  swapTokenBuffer(lpinput);
2144 
2145  /* get the next token and check, whether it is a colon */
2146  if( getNextToken(scip, lpinput) )
2147  {
2148  if( strcmp(lpinput->token, ":") == 0 )
2149  {
2150  /* the second token was a colon: the first token is the constraint name */
2151  (void)SCIPmemccpy(name, lpinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
2152 
2153  name[SCIP_MAXSTRLEN-1] = '\0';
2154  }
2155  else
2156  {
2157  /* the second token was no colon: push the tokens back onto the token stack and parse it next */
2158  pushToken(lpinput);
2159  pushBufferToken(lpinput);
2160  }
2161  }
2162  else
2163  {
2164  /* there was only one token left: push it back onto the token stack and parse it next */
2165  pushBufferToken(lpinput);
2166  }
2167 
2168  /* get type */
2169  if( !getNextToken(scip, lpinput) )
2170  {
2171  syntaxError(scip, lpinput, "expected SOS type: 'S1::' or 'S2::'.");
2172  return SCIP_OKAY;
2173  }
2174  /* check whether constraint name was left out */
2175  if( strcmp(lpinput->token, ":") == 0 )
2176  {
2177  /* we have to push twice ':' and once the type: */
2178  pushToken(lpinput);
2179  lpinput->token[0] = ':';
2180  lpinput->token[1] = '\0';
2181  pushToken(lpinput);
2182  swapTokenBuffer(lpinput);
2183 
2184  /* set artificial name */
2185  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d", ++cnt);
2186  }
2187 
2188  /* check whether it is type 1 or type 2 */
2189  if( strcmp(lpinput->token, "S1") == 0 )
2190  {
2191  type = 1;
2192  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2193  local, modifiable, dynamic, removable) );
2194  }
2195  else if( strcmp(lpinput->token, "S2") == 0 )
2196  {
2197  type = 2;
2198  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2199  local, modifiable, dynamic, removable) );
2200  }
2201  else
2202  {
2203  syntaxError(scip, lpinput, "SOS constraint type other than 1 or 2 appeared.");
2204  return SCIP_OKAY;
2205  }
2206  assert( type == 1 || type == 2 );
2207 
2208  SCIPdebugMessage("created SOS%d constraint <%s>\n", type, name);
2209 
2210  /* make sure that a colons follows */
2211  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2212  {
2213  syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
2214  return SCIP_OKAY;
2215  }
2216 
2217  /* make sure that another colons follows */
2218  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2219  {
2220  syntaxError(scip, lpinput, "SOS constraint type has to be followed by two colons.");
2221  return SCIP_OKAY;
2222  }
2223 
2224  /* parse elements of SOS constraint */
2225  while( getNextToken(scip, lpinput) )
2226  {
2227  SCIP_VAR* var;
2228  SCIP_Real weight;
2229 
2230  /* check if we reached a new section */
2231  if( isNewSection(scip, lpinput) )
2232  break;
2233 
2234  /* remember the token in the token buffer */
2235  swapTokenBuffer(lpinput);
2236 
2237  /* get variable and colon */
2238  var = SCIPfindVar(scip, lpinput->tokenbuf);
2239 
2240  /* if token is a variable name */
2241  if( var == NULL )
2242  {
2243  pushBufferToken(lpinput);
2244  break;
2245  }
2246  else
2247  {
2248  SCIPdebugMessage("found variable <%s>\n", SCIPvarGetName(var));
2249  if( !getNextToken(scip, lpinput) || strcmp(lpinput->token, ":") != 0 )
2250  {
2251  syntaxError(scip, lpinput, "expected colon and weight.");
2252  return SCIP_OKAY;
2253  }
2254  /* check next token */
2255  if( !getNextToken(scip, lpinput) )
2256  {
2257  /* push back token, since it could be the name of a new constraint */
2258  pushToken(lpinput);
2259  pushBufferToken(lpinput);
2260  break;
2261  }
2262  else
2263  {
2264  /* get weight */
2265  if( !isValue(scip, lpinput, &weight) )
2266  {
2267  /* push back token, since it could be the name of a new constraint */
2268  pushToken(lpinput);
2269  pushBufferToken(lpinput);
2270  break;
2271  }
2272  else
2273  {
2274  /* we now know that we have a variable/weight pair -> add variable*/
2275  switch( type )
2276  {
2277  case 1:
2278  SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
2279  break;
2280  case 2:
2281  SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
2282  break;
2283  default:
2284  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2285  SCIPABORT();
2286  return SCIP_INVALIDDATA; /*lint !e527*/
2287  }
2288  SCIPdebugMessage("added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
2289  }
2290  }
2291  }
2292  }
2293 
2294  /* add the SOS constraint */
2295  SCIP_CALL( SCIPaddCons(scip, cons) );
2296  SCIPdebugMessage("(line %d) added constraint <%s>: ", lpinput->linenumber, SCIPconsGetName(cons));
2297  SCIPdebugPrintCons(scip, cons, NULL);
2298  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2299  }
2300 
2301  return SCIP_OKAY;
2302 }
2303 
2304 /** reads an LP file
2305  *
2306  * @todo check whether variables forced to be binary for the creation of indicator constraints are
2307  * really specified to be binary (or general with 0/1 bounds) in the file.
2308  */
2309 static
2311  SCIP* scip, /**< SCIP data structure */
2312  LPINPUT* lpinput, /**< LP reading data */
2313  const char* filename /**< name of the input file */
2314  )
2315 {
2316  assert(lpinput != NULL);
2317 
2318  /* open file */
2319  lpinput->file = SCIPfopen(filename, "r");
2320  if( lpinput->file == NULL )
2321  {
2322  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2323  SCIPprintSysError(filename);
2324  return SCIP_NOFILE;
2325  }
2326 
2327  /* create problem */
2328  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
2329 
2330  /* parse the file */
2331  lpinput->section = LP_START;
2332  while( lpinput->section != LP_END && !hasError(lpinput) )
2333  {
2334  switch( lpinput->section )
2335  {
2336  case LP_START:
2337  SCIP_CALL( readStart(scip, lpinput) );
2338  break;
2339 
2340  case LP_OBJECTIVE:
2341  SCIP_CALL( readObjective(scip, lpinput) );
2342  break;
2343 
2344  case LP_CONSTRAINTS:
2345  SCIP_CALL( readConstraints(scip, lpinput) );
2346  break;
2347 
2348  case LP_BOUNDS:
2349  SCIP_CALL( readBounds(scip, lpinput) );
2350  break;
2351 
2352  case LP_GENERALS:
2353  SCIP_CALL( readGenerals(scip, lpinput) );
2354  break;
2355 
2356  case LP_BINARIES:
2357  SCIP_CALL( readBinaries(scip, lpinput) );
2358  break;
2359 
2360  case LP_SEMICONTINUOUS:
2361  SCIP_CALL( readSemicontinuous(scip, lpinput) );
2362  break;
2363 
2364  case LP_SOS:
2365  SCIP_CALL( readSos(scip, lpinput) );
2366  break;
2367 
2368  case LP_END: /* this is already handled in the while() loop */
2369  default:
2370  SCIPerrorMessage("invalid LP file section <%d>\n", lpinput->section);
2371  return SCIP_INVALIDDATA;
2372  }
2373  }
2374 
2375  /* close file */
2376  SCIPfclose(lpinput->file);
2377 
2378  return SCIP_OKAY;
2379 }
2380 
2381 
2382 /*
2383  * Local methods (for writing)
2384  */
2385 
2386 /** hash key retrieval function for variables */
2387 static
2388 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
2389 { /*lint --e{715}*/
2390  return elem;
2391 }
2392 
2393 /** returns TRUE iff the indices of both variables are equal */
2394 static
2395 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
2396 { /*lint --e{715}*/
2397  if( key1 == key2 )
2398  return TRUE;
2399  return FALSE;
2400 }
2401 
2402 /** returns the hash value of the key */
2403 static
2404 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
2405 { /*lint --e{715}*/
2406  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2407  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2408 }
2409 
2410 
2411 #if 0
2412 /* prints variable name LP format conform; always use this method to stay consistent
2413  *
2414  * 1) variable names should not start with a digit
2415  * 2) avoid variable name starting with an 'e' or 'E' since this notation is reserved for exponential entries
2416  */
2417 static
2418 void printVarName(
2419  SCIP* scip, /**< SCIP data structure */
2420  FILE* file, /**< output file (or NULL for standard output) */
2421  SCIP_VAR* var, /**< variable */
2422  SCIP_Bool genericnames /**< use generic variable names? */
2423  )
2424 {
2425  const char* name;
2426 
2427  assert( scip != NULL );
2428  assert( var != NULL );
2429 
2430  name = SCIPvarGetName(var);
2431  assert( name != NULL );
2432 
2433  if( genericnames || name[0] == '\0' )
2434  SCIPinfoMessage(scip, file, "x%d", SCIPvarGetProbindex(var) + 1);
2435  else
2436  {
2437  if( isdigit((unsigned char)name[0]) || name[0] == 'e' || name[0] == 'E' )
2438  SCIPinfoMessage(scip, file, "_%s", name);
2439  else
2440  SCIPinfoMessage(scip, file, "%s", name);
2441  }
2442 }
2443 #endif
2444 
2445 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
2446 static
2448  SCIP* scip, /**< SCIP data structure */
2449  SCIP_VAR*** vars, /**< pointer to vars array to get active variables for */
2450  SCIP_Real** scalars, /**< pointer to scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
2451  int* nvars, /**< pointer to number of variables and values in vars and vals array */
2452  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
2453  SCIP_Bool transformed /**< transformed constraint? */
2454  )
2455 {
2456  int requiredsize;
2457  int v;
2458 
2459  assert(scip != NULL);
2460  assert(vars != NULL);
2461  assert(scalars != NULL);
2462  assert(*vars != NULL);
2463  assert(*scalars != NULL);
2464  assert(nvars != NULL);
2465  assert(constant != NULL);
2466 
2467  if( transformed )
2468  {
2469  SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
2470 
2471  if( requiredsize > *nvars )
2472  {
2473  SCIP_CALL( SCIPreallocBufferArray(scip, vars, requiredsize) );
2474  SCIP_CALL( SCIPreallocBufferArray(scip, scalars, requiredsize) );
2475 
2476  SCIP_CALL( SCIPgetProbvarLinearSum(scip, *vars, *scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
2477  assert( requiredsize <= *nvars );
2478  }
2479  }
2480  else
2481  {
2482  for( v = 0; v < *nvars; ++v )
2483  {
2484  SCIP_CALL( SCIPvarGetOrigvarSum(&(*vars)[v], &(*scalars)[v], constant) );
2485  }
2486  }
2487  return SCIP_OKAY;
2488 }
2489 
2490 /** clears the given line buffer */
2491 static
2493  char* linebuffer, /**< line */
2494  int* linecnt /**< number of characters in line */
2495  )
2496 {
2497  assert( linebuffer != NULL );
2498  assert( linecnt != NULL );
2499 
2500  (*linecnt) = 0;
2501  linebuffer[0] = '\0';
2502 }
2503 
2504 /** ends the given line with '\\0' and prints it to the given file stream */
2505 static
2506 void endLine(
2507  SCIP* scip, /**< SCIP data structure */
2508  FILE* file, /**< output file (or NULL for standard output) */
2509  char* linebuffer, /**< line */
2510  int* linecnt /**< number of characters in line */
2511  )
2512 {
2513  assert( scip != NULL );
2514  assert( linebuffer != NULL );
2515  assert( linecnt != NULL );
2516 
2517  if( (*linecnt) > 0 )
2518  {
2519  linebuffer[(*linecnt)] = '\0';
2520  SCIPinfoMessage(scip, file, "%s\n", linebuffer);
2521  clearLine(linebuffer, linecnt);
2522  }
2523 }
2524 
2525 /** appends extension to line and prints it to the give file stream if the
2526  * line exceeded the length given in the define LP_PRINTLEN */
2527 static
2529  SCIP* scip, /**< SCIP data structure */
2530  FILE* file, /**< output file (or NULL for standard output) */
2531  char* linebuffer, /**< line */
2532  int* linecnt, /**< number of characters in line */
2533  const char* extension /**< string to extent the line */
2534  )
2535 {
2536  assert( scip != NULL );
2537  assert( linebuffer != NULL );
2538  assert( linecnt != NULL );
2539  assert( extension != NULL );
2540  assert( strlen(linebuffer) + strlen(extension) < LP_MAX_PRINTLEN );
2541 
2542  /* NOTE: avoid
2543  * sprintf(linebuffer, "%s%s", linebuffer, extension);
2544  * because of overlapping memory areas in memcpy used in sprintf.
2545  */
2546  strncat(linebuffer, extension, LP_MAX_PRINTLEN - strlen(linebuffer));
2547 
2548  (*linecnt) += (int) strlen(extension);
2549 
2550  SCIPdebugMessage("linebuffer <%s>, length = %lu\n", linebuffer, (unsigned long)strlen(linebuffer));
2551 
2552  if( (*linecnt) > LP_PRINTLEN )
2553  endLine(scip, file, linebuffer, linecnt);
2554 }
2555 
2556 
2557 /* print row in LP format to file stream */
2558 static
2560  SCIP* scip, /**< SCIP data structure */
2561  FILE* file, /**< output file (or NULL for standard output) */
2562  const char* rowname, /**< row name */
2563  const char* rownameextension, /**< row name extension */
2564  const char* type, /**< row type ("=", "<=", or ">=") */
2565  SCIP_VAR** linvars, /**< array of linear variables */
2566  SCIP_Real* linvals, /**< array of linear coefficient values */
2567  int nlinvars, /**< number of linear variables */
2568  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
2569  int nquadvarterms, /**< number of quadratic variable terms */
2570  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
2571  int nbilinterms, /**< number of bilinear terms */
2572  SCIP_Real rhs /**< right hand side */
2573  )
2574 {
2575  int v;
2576  char linebuffer[LP_MAX_PRINTLEN] = { '\0' };
2577  int linecnt;
2578 
2579  SCIP_VAR* var;
2580  char varname[LP_MAX_NAMELEN];
2581  char varname2[LP_MAX_NAMELEN];
2582  char consname[LP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2583  char buffer[LP_MAX_PRINTLEN];
2584 
2585  assert( scip != NULL );
2586  assert( strcmp(type, "=") == 0 || strcmp(type, "<=") == 0 || strcmp(type, ">=") == 0 );
2587  assert( nlinvars == 0 || (linvars != NULL && linvals != NULL) );
2588  assert( nquadvarterms == 0 || quadvarterms != NULL );
2589 
2590  /* if there is a bilinear term, then there need to be at least two quadratic variables */
2591  assert( nbilinterms == 0 || (bilinterms != NULL && nquadvarterms >= 2) );
2592 
2593  clearLine(linebuffer, &linecnt);
2594 
2595  /* start each line with a space */
2596  appendLine(scip, file, linebuffer, &linecnt, " ");
2597 
2598  /* print row name */
2599  if( strlen(rowname) > 0 || strlen(rownameextension) > 0 )
2600  {
2601  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN + 1, "%s%s:", rowname, rownameextension);
2602  appendLine(scip, file, linebuffer, &linecnt, consname);
2603  }
2604 
2605  /* print coefficients */
2606  for( v = 0; v < nlinvars; ++v )
2607  {
2608  var = linvars[v];
2609  assert( var != NULL );
2610 
2611  /* we start a new line; therefore we tab this line */
2612  if( linecnt == 0 )
2613  appendLine(scip, file, linebuffer, &linecnt, " ");
2614 
2615  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2616  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", linvals[v], varname);
2617 
2618  appendLine(scip, file, linebuffer, &linecnt, buffer);
2619  }
2620 
2621  /* print quadratic part */
2622  if( nquadvarterms > 0 )
2623  {
2624  /* print linear coefficients of quadratic variables */
2625  for( v = 0; v < nquadvarterms; ++v )
2626  {
2627  if( quadvarterms[v].lincoef == 0.0 )
2628  continue;
2629 
2630  /* we start a new line; therefore we tab this line */
2631  if( linecnt == 0 )
2632  appendLine(scip, file, linebuffer, &linecnt, " ");
2633 
2634  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(quadvarterms[v].var));
2635  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", quadvarterms[v].lincoef, varname);
2636 
2637  appendLine(scip, file, linebuffer, &linecnt, buffer);
2638  }
2639 
2640  /* start quadratic part */
2641  appendLine(scip, file, linebuffer, &linecnt, " + [");
2642 
2643  /* print square terms */
2644  for( v = 0; v < nquadvarterms; ++v )
2645  {
2646  if( quadvarterms[v].sqrcoef == 0.0 )
2647  continue;
2648 
2649  /* we start a new line; therefore we tab this line */
2650  if( linecnt == 0 )
2651  appendLine(scip, file, linebuffer, &linecnt, " ");
2652 
2653  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(quadvarterms[v].var));
2654  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s^2", quadvarterms[v].sqrcoef, varname);
2655 
2656  appendLine(scip, file, linebuffer, &linecnt, buffer);
2657  }
2658 
2659  /* print bilinear terms */
2660  for( v = 0; v < nbilinterms; ++v )
2661  {
2662  /* we start a new line; therefore we tab this line */
2663  if( linecnt == 0 )
2664  appendLine(scip, file, linebuffer, &linecnt, " ");
2665 
2666  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(bilinterms[v].var1));
2667  (void) SCIPsnprintf(varname2, LP_MAX_NAMELEN, "%s", SCIPvarGetName(bilinterms[v].var2));
2668  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s * %s", bilinterms[v].coef, varname, varname2);
2669 
2670  appendLine(scip, file, linebuffer, &linecnt, buffer);
2671  }
2672 
2673  /* end quadratic part */
2674  appendLine(scip, file, linebuffer, &linecnt, " ]");
2675  }
2676 
2677  /* print left hand side */
2678  if( SCIPisZero(scip, rhs) )
2679  rhs = 0.0;
2680 
2681  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s %+.15g", type, rhs);
2682 
2683  /* we start a new line; therefore we tab this line */
2684  if( linecnt == 0 )
2685  appendLine(scip, file, linebuffer, &linecnt, " ");
2686  appendLine(scip, file, linebuffer, &linecnt, buffer);
2687 
2688  endLine(scip, file, linebuffer, &linecnt);
2689 }
2690 
2691 
2692 /** prints given (linear or) quadratic constraint information in LP format to file stream */
2693 static
2695  SCIP* scip, /**< SCIP data structure */
2696  FILE* file, /**< output file (or NULL for standard output) */
2697  const char* rowname, /**< name of the row */
2698  SCIP_VAR** linvars, /**< array of linear variables */
2699  SCIP_Real* linvals, /**< array of linear coefficients values (or NULL if all linear coefficient values are 1) */
2700  int nlinvars, /**< number of linear variables */
2701  SCIP_QUADVARTERM* quadvarterms, /**< quadratic variable terms */
2702  int nquadvarterms, /**< number of quadratic variable terms */
2703  SCIP_BILINTERM* bilinterms, /**< bilinear terms */
2704  int nbilinterms, /**< number of bilinear terms */
2705  SCIP_Real lhs, /**< left hand side */
2706  SCIP_Real rhs, /**< right hand side */
2707  SCIP_Bool transformed /**< transformed constraint? */
2708  )
2709 {
2710  int v;
2711  SCIP_VAR** activevars = NULL;
2712  SCIP_Real* activevals = NULL;
2713  int nactivevars;
2714  SCIP_Real activeconstant = 0.0;
2715 
2716  assert( scip != NULL );
2717  assert( rowname != NULL );
2718 
2719  /* The LP format does not forbid that the variable array is empty */
2720  assert( nlinvars == 0 || linvars != NULL );
2721  assert( nquadvarterms == 0 || quadvarterms != NULL );
2722  assert( nbilinterms == 0 || bilinterms != NULL );
2723 
2724  assert( lhs <= rhs );
2725 
2726  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2727  return SCIP_OKAY;
2728 
2729  nactivevars = nlinvars;
2730  if( nlinvars > 0 )
2731  {
2732  /* duplicate variable and value array */
2733  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, linvars, nactivevars ) );
2734  if( linvals != NULL )
2735  {
2736  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, linvals, nactivevars ) );
2737  }
2738  else
2739  {
2740  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2741 
2742  for( v = 0; v < nactivevars; ++v )
2743  activevals[v] = 1.0;
2744  }
2745 
2746  /* retransform given variables to active variables */
2747  SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
2748  }
2749 
2750  /* print row(s) in LP format */
2751  if( SCIPisEQ(scip, lhs, rhs) )
2752  {
2753  assert( !SCIPisInfinity(scip, rhs) );
2754 
2755  /* equal constraint */
2756  printRow(scip, file, rowname, "", "=", activevars, activevals, nactivevars,
2757  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2758  rhs - activeconstant);
2759  }
2760  else
2761  {
2762  if( !SCIPisInfinity(scip, -lhs) )
2763  {
2764  /* print inequality ">=" */
2765  printRow(scip, file, rowname, SCIPisInfinity(scip, rhs) ? "" : "_lhs", ">=",
2766  activevars, activevals, nactivevars,
2767  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2768  lhs - activeconstant);
2769  }
2770  if( !SCIPisInfinity(scip, rhs) )
2771  {
2772  /* print inequality "<=" */
2773  printRow(scip, file, rowname, SCIPisInfinity(scip, -lhs) ? "" : "_rhs", "<=",
2774  activevars, activevals, nactivevars,
2775  quadvarterms, nquadvarterms, bilinterms, nbilinterms,
2776  rhs - activeconstant);
2777  }
2778  }
2779 
2780  if( nlinvars > 0 )
2781  {
2782  /* free buffer arrays */
2783  SCIPfreeBufferArray(scip, &activevars);
2784  SCIPfreeBufferArray(scip, &activevals);
2785  }
2786 
2787  return SCIP_OKAY;
2788 }
2789 
2790 
2791 /** prints given SOS constraint information in LP format to file stream */
2792 static
2794  SCIP* scip, /**< SCIP data structure */
2795  FILE* file, /**< output file (or NULL for standard output) */
2796  const char* rowname, /**< name of the row */
2797  SCIP_VAR** vars, /**< array of variables */
2798  SCIP_Real* weights, /**< array of weight values (or NULL) */
2799  int nvars, /**< number of variables */
2800  int type /**< SOS type (SOS1 or SOS2) */
2801  )
2802 {
2803  int v;
2804 
2805  char linebuffer[LP_MAX_PRINTLEN];
2806  int linecnt;
2807  char buffer[LP_MAX_PRINTLEN];
2808  char varname[LP_MAX_NAMELEN];
2809 
2810  assert( scip != NULL );
2811  assert( file != NULL );
2812  assert( type == 1 || type == 2 );
2813 
2814  clearLine(linebuffer, &linecnt);
2815 
2816  /* start each line with a space */
2817  appendLine(scip, file, linebuffer, &linecnt, " ");
2818  assert( strlen(rowname) < LP_MAX_NAMELEN );
2819 
2820  if( strlen(rowname) > 0 )
2821  {
2822  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, "%s:", rowname);
2823  appendLine(scip, file, linebuffer, &linecnt, buffer);
2824  }
2825 
2826  /* SOS type */
2827  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " S%d::", type);
2828  appendLine(scip, file, linebuffer, &linecnt, buffer);
2829 
2830  for( v = 0; v < nvars; ++v )
2831  {
2832  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(vars[v]));
2833 
2834  if( weights != NULL )
2835  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%.15g", varname, weights[v]);
2836  else
2837  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s:%d", varname, v);
2838 
2839  if(linecnt == 0 )
2840  {
2841  /* we start a new line; therefore we tab this line */
2842  appendLine(scip, file, linebuffer, &linecnt, " ");
2843  }
2844  appendLine(scip, file, linebuffer, &linecnt, buffer);
2845  }
2846 
2847  endLine(scip, file, linebuffer, &linecnt);
2848 }
2849 
2850 /** prints given soc constraint in LP format to file stream */
2851 static
2853  SCIP* scip, /**< SCIP data structure */
2854  FILE* file, /**< output file (or NULL for standard output) */
2855  const char* rowname, /**< name of the row */
2856  SCIP_CONS* cons /**< second order cone constraint */
2857  )
2858 {
2859  int v;
2860  char linebuffer[LP_MAX_PRINTLEN] = { '\0' };
2861  int linecnt;
2862  SCIP_VAR* var;
2863  SCIP_Real coef;
2864  SCIP_Real offset;
2865  char varname[LP_MAX_NAMELEN];
2866  char consname[LP_MAX_NAMELEN + 1]; /* an extra character for ':' */
2867  char buffer[LP_MAX_PRINTLEN];
2868 
2869  SCIP_Real rhs;
2870 
2871  assert( scip != NULL );
2872  assert( rowname != NULL );
2873  assert( cons != NULL );
2874 
2875  /* print constraint in LP format
2876  * the SOC constraint is given as
2877  * sqrt(constant + sum_i (lhscoef_i(lhsvar_i+lhsoffset_i))^2) <= rhscoef(rhsvar+rhsoffset)
2878  * and is printed as
2879  * sum_i (2*lhscoef_i^2 lhs_offset_i) lhsvar_i - (2 * rhscoef^2 * rhsoffset) rhsvar
2880  * + [ sum_i lhscoef_i^2 lhsvar_i^2 - rhscoef^2 rhsvar^2 ]
2881  * <=
2882  * - sum_i lhscoef_i^2 lhs_offset_i^2 - constant + rhscoef^2 rhsoffset^2
2883  */
2884 
2885  clearLine(linebuffer, &linecnt);
2886 
2887  /* start each line with a space */
2888  appendLine(scip, file, linebuffer, &linecnt, " ");
2889 
2890  /* print row name */
2891  if( strlen(rowname) > 0 )
2892  {
2893  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN + 1, "%s:", rowname);
2894  appendLine(scip, file, linebuffer, &linecnt, consname);
2895  }
2896 
2897  rhs = -SCIPgetLhsConstantSOC(scip, cons);
2898 
2899  /* print linear part of left hand side and add constant parts to rhs */
2900  for( v = 0; v < SCIPgetNLhsVarsSOC(scip, cons); ++v )
2901  {
2902  var = SCIPgetLhsVarsSOC(scip, cons)[v];
2903  assert( var != NULL );
2904  offset = SCIPgetLhsOffsetsSOC(scip, cons)[v];
2905  coef = SCIPgetLhsCoefsSOC(scip, cons)[v];
2906 
2907  rhs -= coef * coef * offset * offset;
2908 
2909  if( offset == 0.0 || coef == 0.0 )
2910  continue;
2911 
2912  /* we start a new line; therefore we tab this line */
2913  if( linecnt == 0 )
2914  appendLine(scip, file, linebuffer, &linecnt, " ");
2915 
2916  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2917  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", 2*offset*coef*coef, varname);
2918 
2919  appendLine(scip, file, linebuffer, &linecnt, buffer);
2920  }
2921 
2922  /* print linear part from right hand side and add constant part to rhs */
2923  offset = SCIPgetRhsOffsetSOC(scip, cons);
2924  coef = SCIPgetRhsCoefSOC(scip, cons);
2925  if( offset != 0.0 && coef != 0.0 )
2926  {
2927  var = SCIPgetRhsVarSOC(scip, cons);
2928  assert( var != NULL );
2929 
2930  rhs += coef * coef * offset * offset;
2931 
2932  if( linecnt == 0 )
2933  appendLine(scip, file, linebuffer, &linecnt, " ");
2934 
2935  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2936  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", -2*offset*coef*coef, varname);
2937 
2938  appendLine(scip, file, linebuffer, &linecnt, buffer);
2939  }
2940 
2941  /* start quadratic part */
2942  appendLine(scip, file, linebuffer, &linecnt, " + [");
2943 
2944  /* print quadratic part of left hand side */
2945  for( v = 0; v < SCIPgetNLhsVarsSOC(scip, cons); ++v )
2946  {
2947  var = SCIPgetLhsVarsSOC(scip, cons)[v];
2948  assert( var != NULL );
2949  coef = SCIPgetLhsCoefsSOC(scip, cons)[v];
2950 
2951  if( coef == 0.0 )
2952  continue;
2953 
2954  /* we start a new line; therefore we tab this line */
2955  if( linecnt == 0 )
2956  appendLine(scip, file, linebuffer, &linecnt, " ");
2957 
2958  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2959  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s^2", coef*coef, varname);
2960 
2961  appendLine(scip, file, linebuffer, &linecnt, buffer);
2962  }
2963 
2964  /* print quadratic part of right hand side */
2965  coef = SCIPgetRhsCoefSOC(scip, cons);
2966  if( coef != 0.0 )
2967  {
2968  var = SCIPgetRhsVarSOC(scip, cons);
2969  assert( var != NULL );
2970 
2971  /* we start a new line; therefore we tab this line */
2972  if( linecnt == 0 )
2973  appendLine(scip, file, linebuffer, &linecnt, " ");
2974 
2975  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
2976  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s^2", -coef*coef, varname);
2977 
2978  appendLine(scip, file, linebuffer, &linecnt, buffer);
2979  }
2980 
2981  /* end quadratic part */
2982  appendLine(scip, file, linebuffer, &linecnt, " ]");
2983 
2984  /* print right hand side */
2985  if( SCIPisZero(scip, rhs) )
2986  rhs = 0.0;
2987 
2988  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " <= %+.15g", rhs);
2989 
2990  /* we start a new line; therefore we tab this line */
2991  if( linecnt == 0 )
2992  appendLine(scip, file, linebuffer, &linecnt, " ");
2993  appendLine(scip, file, linebuffer, &linecnt, buffer);
2994 
2995  endLine(scip, file, linebuffer, &linecnt);
2996 
2997  return SCIP_OKAY;
2998 }
2999 
3000 /** prints a linearization of an and-constraint into the given file */
3001 static
3003  SCIP* scip, /**< SCIP data structure */
3004  FILE* file, /**< output file (or NULL for standard output) */
3005  const char* consname, /**< name of the constraint */
3006  SCIP_CONS* cons, /**< and constraint */
3007  SCIP_Bool aggrlinearizationands,/**< print weak or strong realaxation */
3008  SCIP_Bool transformed /**< transformed constraint? */
3009  )
3010 {
3011  SCIP_VAR** vars;
3012  SCIP_VAR** operands;
3013  SCIP_VAR* resultant;
3014  SCIP_Real* vals;
3015  char rowname[LP_MAX_NAMELEN];
3016  int nvars;
3017  int v;
3018 
3019  assert(scip != NULL);
3020  assert(consname != NULL);
3021  assert(cons != NULL);
3022 
3023  nvars = SCIPgetNVarsAnd(scip, cons);
3024  operands = SCIPgetVarsAnd(scip, cons);
3025  resultant = SCIPgetResultantAnd(scip, cons);
3026 
3027  /* allocate buffer array */
3028  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars + 1) );
3029  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars + 1) );
3030 
3031  /* the tight relaxtion, number of and-constraint operands rows */
3032  if( !aggrlinearizationands )
3033  {
3034  vars[0] = resultant;
3035  vals[0] = 1.0;
3036  vals[1] = -1.0;
3037 
3038  /* print operator rows */
3039  for( v = 0; v < nvars; ++v )
3040  {
3041  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_%d", consname, v);
3042  vars[1] = operands[v];
3043 
3044  /* print for each operator a row */
3045  SCIP_CALL( printQuadraticCons(scip, file, rowname,
3046  vars, vals, 2, NULL, 0, NULL, 0, -SCIPinfinity(scip), 0.0, transformed) );
3047  }
3048  }
3049 
3050  /* prepare for next row */
3051  for( v = nvars - 1; v >= 0; --v )
3052  {
3053  vars[v] = operands[v];
3054  vals[v] = -1.0;
3055  }
3056 
3057  vars[nvars] = resultant;
3058 
3059  /* the weak relaxtion, only one constraint */
3060  if( aggrlinearizationands )
3061  {
3062  /* adjust rowname of constraint */
3063  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_operators", consname);
3064 
3065  vals[nvars] = (SCIP_Real) nvars;
3066 
3067  /* print aggregated operator row */
3068  SCIP_CALL( printQuadraticCons(scip, file, rowname,
3069  vars, vals, nvars + 1, NULL, 0, NULL, 0, -SCIPinfinity(scip), 0.0, transformed) );
3070  }
3071 
3072  /* create additional linear constraint */
3073  (void) SCIPsnprintf(rowname, LP_MAX_NAMELEN, "%s_add", consname);
3074 
3075  vals[nvars] = 1.0;
3076 
3077  SCIP_CALL( printQuadraticCons(scip, file, rowname,
3078  vars, vals, nvars + 1, NULL, 0, NULL, 0, -nvars + 1.0, SCIPinfinity(scip), transformed) );
3079 
3080  /* free buffer array */
3081  SCIPfreeBufferArray(scip, &vals);
3082  SCIPfreeBufferArray(scip, &vars);
3083 
3084  return SCIP_OKAY;
3085 }
3086 
3087 /** check whether given variables are aggregated and put them into an array without duplication */
3088 static
3090  SCIP* scip, /**< SCIP data structure */
3091  SCIP_VAR** vars, /**< variable array */
3092  int nvars, /**< number of active variables in the problem */
3093  SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3094  int* naggvars, /**< pointer to number of aggregated variables on output */
3095  int* saggvars, /**< pointer to number of slots in aggvars array */
3096  SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3097  )
3098 {
3099  int v;
3100 
3101  assert( scip != NULL );
3102  assert( aggvars != NULL );
3103  assert( naggvars != NULL );
3104  assert( saggvars != NULL );
3105 
3106  /* check variables */
3107  for( v = 0; v < nvars; ++v )
3108  {
3109  SCIP_VARSTATUS status;
3110  SCIP_VAR* var;
3111 
3112  var = vars[v];
3113  status = SCIPvarGetStatus(var);
3114 
3115  /* collect aggregated variables in a list */
3116  if( status >= SCIP_VARSTATUS_AGGREGATED )
3117  {
3118  assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3119  assert( varAggregated != NULL );
3120 
3121  if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3122  {
3123  /* possibly enlarge array */
3124  if ( *saggvars <= *naggvars )
3125  {
3126  int newsize;
3127  newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3128  assert( newsize > *saggvars );
3129  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3130  *saggvars = newsize;
3131  }
3132 
3133  (*aggvars)[*naggvars] = var;
3134  (*naggvars)++;
3135  SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3136  assert( *naggvars <= *saggvars );
3137  }
3138  }
3139  }
3140  return SCIP_OKAY;
3141 }
3142 
3143 /** print aggregated variable-constraints */
3144 static
3146  SCIP* scip, /**< SCIP data structure */
3147  FILE* file, /**< output file (or NULL for standard output) */
3148  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3149  int nvars, /**< number of active variables in the problem */
3150  int nAggregatedVars, /**< number of aggregated variables */
3151  SCIP_VAR** aggregatedVars /**< array storing the aggregated variables */
3152  )
3153 {
3154  int j;
3155 
3156  SCIP_VAR** activevars;
3157  SCIP_Real* activevals;
3158  int nactivevars;
3159  SCIP_Real activeconstant = 0.0;
3160  char consname[LP_MAX_NAMELEN];
3161 
3162  assert( scip != NULL );
3163 
3164  /* write aggregation constraints */
3165  SCIP_CALL( SCIPallocBufferArray(scip, &activevars, nvars) );
3166  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nvars) );
3167 
3168  for( j = 0; j < nAggregatedVars; ++j )
3169  {
3170  /* set up list to obtain substitution variables */
3171  nactivevars = 1;
3172 
3173  activevars[0] = aggregatedVars[j];
3174  activevals[0] = 1.0;
3175  activeconstant = 0.0;
3176 
3177  /* retransform given variables to active variables */
3178  SCIP_CALL( getActiveVariables(scip, &activevars, &activevals, &nactivevars, &activeconstant, transformed) );
3179 
3180  activevals[nactivevars] = -1.0;
3181  activevars[nactivevars] = aggregatedVars[j];
3182  ++nactivevars;
3183 
3184  /* output constraint */
3185  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(aggregatedVars[j]));
3186  printRow(scip, file, consname, "", "=", activevars, activevals, nactivevars, NULL, 0, NULL, 0, - activeconstant);
3187  }
3188 
3189  /* free buffer arrays */
3190  SCIPfreeBufferArray(scip, &activevars);
3191  SCIPfreeBufferArray(scip, &activevals);
3192 
3193  return SCIP_OKAY;
3194 }
3195 
3196 /** method check if the variable names are not longer than LP_MAX_NAMELEN */
3197 static
3199  SCIP* scip, /**< SCIP data structure */
3200  SCIP_VAR** vars, /**< array of variables */
3201  int nvars /**< number of variables */
3202  )
3203 {
3204  int v;
3205 
3206  assert(scip != NULL);
3207  assert(vars != NULL || nvars == 0);
3208 
3209  /* check if the variable names are not to long */
3210  for( v = 0; v < nvars; ++v )
3211  {
3212  if( strlen(SCIPvarGetName(vars[v])) > LP_MAX_NAMELEN ) /*lint !e613*/
3213  {
3214  SCIPwarningMessage(scip, "there is a variable name which has to be cut down to %d characters; LP might be corrupted\n",
3215  LP_MAX_NAMELEN - 1);
3216  return;
3217  }
3218  }
3219 }
3220 
3221 /** method check if the constraint names are not longer than LP_MAX_NAMELEN */
3222 static
3224  SCIP* scip, /**< SCIP data structure */
3225  SCIP_CONS** conss, /**< array of constraints */
3226  int nconss, /**< number of constraints */
3227  SCIP_Bool transformed /**< TRUE iff problem is the transformed problem */
3228  )
3229 {
3230  int c;
3231  SCIP_CONS* cons;
3232  SCIP_CONSHDLR* conshdlr;
3233  const char* conshdlrname;
3234 
3235  assert( scip != NULL );
3236  assert( conss != NULL || nconss == 0 );
3237 
3238  for( c = 0; c < nconss; ++c )
3239  {
3240  int len;
3241 
3242  assert(conss != NULL); /* for lint */
3243  cons = conss[c];
3244  assert(cons != NULL );
3245 
3246  /* in case the transformed is written only constraints are posted which are enabled in the current node */
3247  assert(!transformed || SCIPconsIsEnabled(cons));
3248 
3249  conshdlr = SCIPconsGetHdlr(cons);
3250  assert( conshdlr != NULL );
3251 
3252  conshdlrname = SCIPconshdlrGetName(conshdlr);
3253  assert( transformed == SCIPconsIsTransformed(cons) );
3254 
3255  len = (int) strlen(SCIPconsGetName(cons));
3256 
3257  if( strcmp(conshdlrname, "linear") == 0 )
3258  {
3259  SCIP_Real lhs = SCIPgetLhsLinear(scip, cons);
3260  SCIP_Real rhs = SCIPgetLhsLinear(scip, cons);
3261 
3262  if( (SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN) || ( !SCIPisEQ(scip, lhs, rhs) && len > LP_MAX_NAMELEN - 4) )
3263  {
3264  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
3265  return;
3266  }
3267  }
3268  else if( len > LP_MAX_NAMELEN )
3269  {
3270  SCIPwarningMessage(scip, "there is a constraint name which has to be cut down to %d characters;\n", LP_MAX_NAMELEN - 1);
3271  return;
3272  }
3273  }
3274 }
3275 
3276 /*
3277  * Callback methods of reader
3278  */
3279 
3280 /** copy method for reader plugins (called when SCIP copies plugins) */
3281 static
3283 { /*lint --e{715}*/
3284  assert(scip != NULL);
3285  assert(reader != NULL);
3286  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3287 
3288  /* call inclusion method of reader */
3289  SCIP_CALL( SCIPincludeReaderLp(scip) );
3290 
3291  return SCIP_OKAY;
3292 }
3293 
3294 /** destructor of reader to free user data (called when SCIP is exiting) */
3295 static
3297 {
3298  SCIP_READERDATA* readerdata;
3299 
3300  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3301  readerdata = SCIPreaderGetData(reader);
3302  assert(readerdata != NULL);
3303  SCIPfreeMemory(scip, &readerdata);
3304 
3305  return SCIP_OKAY;
3306 }
3307 
3308 /** problem reading method of reader */
3309 static
3311 { /*lint --e{715}*/
3312 
3313  SCIP_CALL( SCIPreadLp(scip, reader, filename, result) );
3314 
3315  return SCIP_OKAY;
3316 }
3317 
3318 
3319 /** problem writing method of reader */
3320 static
3322 { /*lint --e{715}*/
3323  assert(reader != NULL);
3324  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3325 
3326  SCIP_CALL( SCIPwriteLp(scip, file, name, transformed, objsense, objscale, objoffset, vars,
3327  nvars, nbinvars, nintvars, nimplvars, ncontvars, conss, nconss, result) );
3328 
3329  return SCIP_OKAY;
3330 }
3331 
3332 
3333 /*
3334  * reader specific interface methods
3335  */
3336 
3337 /** includes the lp file reader in SCIP */
3339  SCIP* scip /**< SCIP data structure */
3340  )
3341 {
3342  SCIP_READERDATA* readerdata;
3343  SCIP_READER* reader;
3344 
3345  /* create reader data */
3346  SCIP_CALL( SCIPallocMemory(scip, &readerdata) );
3347 
3348  /* include reader */
3349  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3350 
3351  /* set non fundamental callbacks via setter functions */
3352  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyLp) );
3353  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeLp) );
3354  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadLp) );
3355  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteLp) );
3356 
3357  /* add lp-reader parameters */
3359  "reading/"READER_NAME"/linearize-and-constraints",
3360  "should possible \"and\" constraint be linearized when writing the lp file?",
3361  &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3363  "reading/"READER_NAME"/aggrlinearization-ands",
3364  "should an aggregated linearization for and constraints be used?",
3365  &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3366 
3367  return SCIP_OKAY;
3368 }
3369 
3370 
3371 /** reads problem from file */
3373  SCIP* scip, /**< SCIP data structure */
3374  SCIP_READER* reader, /**< the file reader itself */
3375  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3376  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
3377  )
3378 { /*lint --e{715}*/
3379  SCIP_RETCODE retcode;
3380  LPINPUT lpinput;
3381  int i;
3382 
3383  /* initialize LP input data */
3384  lpinput.file = NULL;
3385  lpinput.linebuf[0] = '\0';
3386  lpinput.probname[0] = '\0';
3387  lpinput.objname[0] = '\0';
3388  SCIP_CALL( SCIPallocMemoryArray(scip, &lpinput.token, LP_MAX_LINELEN) ); /*lint !e506*/
3389  lpinput.token[0] = '\0';
3390  SCIP_CALL( SCIPallocMemoryArray(scip, &lpinput.tokenbuf, LP_MAX_LINELEN) ); /*lint !e506*/
3391  lpinput.tokenbuf[0] = '\0';
3392  for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
3393  {
3394  SCIP_CALL( SCIPallocMemoryArray(scip, &(lpinput.pushedtokens[i]), LP_MAX_LINELEN) ); /*lint !e866 !e506*/
3395  }
3396 
3397  lpinput.npushedtokens = 0;
3398  lpinput.linenumber = 0;
3399  lpinput.linepos = 0;
3400  lpinput.section = LP_START;
3401  lpinput.objsense = SCIP_OBJSENSE_MINIMIZE;
3402  lpinput.inlazyconstraints = FALSE;
3403  lpinput.inusercuts = FALSE;
3404  lpinput.haserror = FALSE;
3405  lpinput.comment = FALSE;
3406  lpinput.endline = FALSE;
3407  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &(lpinput.initialconss)) );
3408  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &(lpinput.dynamicconss)) );
3409  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &(lpinput.dynamiccols)) );
3410  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &(lpinput.dynamicrows)) );
3411 
3412  /* read the file */
3413  retcode = readLPFile(scip, &lpinput, filename);
3414 
3415  /* free dynamically allocated memory */
3416  SCIPfreeMemoryArray(scip, &lpinput.token);
3417  SCIPfreeMemoryArray(scip, &lpinput.tokenbuf);
3418  for( i = 0; i < LP_MAX_PUSHEDTOKENS; ++i )
3419  {
3420  SCIPfreeMemoryArray(scip, &lpinput.pushedtokens[i]);
3421  }
3422 
3423  /* check for correct return value */
3424  SCIP_CALL( retcode );
3425 
3426  /* evaluate the result */
3427  if( lpinput.haserror )
3428  return SCIP_READERROR;
3429  else
3430  {
3431  /* set objective sense */
3432  SCIP_CALL( SCIPsetObjsense(scip, lpinput.objsense) );
3433  *result = SCIP_SUCCESS;
3434  }
3435 
3436  return SCIP_OKAY;
3437 }
3438 
3439 
3440 /** writes problem to file */
3442  SCIP* scip, /**< SCIP data structure */
3443  FILE* file, /**< output file, or NULL if standard output should be used */
3444  const char* name, /**< problem name */
3445  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3446  SCIP_OBJSENSE objsense, /**< objective sense */
3447  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3448  * extobj = objsense * objscale * (intobj + objoffset) */
3449  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3450  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3451  int nvars, /**< number of active variables in the problem */
3452  int nbinvars, /**< number of binary variables */
3453  int nintvars, /**< number of general integer variables */
3454  int nimplvars, /**< number of implicit integer variables */
3455  int ncontvars, /**< number of continuous variables */
3456  SCIP_CONS** conss, /**< array with constraints of the problem */
3457  int nconss, /**< number of constraints in the problem */
3458  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3459  )
3460 {
3461  SCIP_READER* reader;
3462  SCIP_READERDATA* readerdata;
3463  SCIP_Bool linearizeands;
3464  SCIP_Bool aggrlinearizationands;
3465  int c;
3466  int v;
3467 
3468  int linecnt;
3469  char linebuffer[LP_MAX_PRINTLEN];
3470 
3471  char varname[LP_MAX_NAMELEN];
3472  char buffer[LP_MAX_PRINTLEN];
3473 
3474  SCIP_CONSHDLR* conshdlr;
3475  SCIP_CONSHDLR* conshdlrInd;
3476  const char* conshdlrname;
3477  SCIP_CONS* cons;
3478  SCIP_CONS** consSOS1;
3479  SCIP_CONS** consSOS2;
3480  SCIP_CONS** consQuadratic;
3481  SCIP_CONS** consSOC;
3482  SCIP_CONS** consIndicator;
3483  int nConsSOS1 = 0;
3484  int nConsSOS2 = 0;
3485  int nConsQuadratic = 0;
3486  int nConsSOC = 0;
3487  int nConsIndicator = 0;
3488  char consname[LP_MAX_NAMELEN];
3489 
3490  SCIP_VAR** aggvars;
3491  int naggvars = 0;
3492  int saggvars;
3493  SCIP_HASHTABLE* varAggregated;
3494  SCIP_HASHMAP* consHidden;
3495 
3496  SCIP_VAR** consvars;
3497  SCIP_Real* consvals;
3498  int nconsvars;
3499 
3500  SCIP_VAR* var;
3501  SCIP_Real lb;
3502  SCIP_Real ub;
3503 
3504  assert(scip != NULL);
3505 
3506  /* find indicator constraint handler */
3507  conshdlrInd = SCIPfindConshdlr(scip, "indicator");
3508  consHidden = NULL;
3509 
3510  /* if indicator constraint handler is present */
3511  if( conshdlrInd != NULL )
3512  {
3513  /* create hashtable storing linear constraints that should not be output */
3514  SCIP_CALL( SCIPhashmapCreate(&consHidden, SCIPblkmem(scip), SCIPcalcHashtableSize(1000)) );
3515 
3516  /* loop through indicator constraints (works only in transformed problem) */
3517  if( transformed )
3518  {
3519  SCIP_CONS** consInd;
3520  int nConsInd;
3521 
3522  consInd = SCIPconshdlrGetConss(conshdlrInd);
3523  nConsInd = SCIPconshdlrGetNConss(conshdlrInd);
3524  SCIPdebugMessage("Number of indicator constraints: %d\n", nConsInd);
3525 
3526  for( c = 0; c < nConsInd; ++c )
3527  {
3528  assert( consInd[c] != NULL );
3529  cons = SCIPgetLinearConsIndicator(consInd[c]);
3530 
3531  assert( !SCIPhashmapExists(consHidden, (void*) cons) );
3532  SCIP_CALL( SCIPhashmapSetImage(consHidden, (void*) cons, (void*) TRUE) );
3533  SCIPdebugMessage("Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(cons));
3534  }
3535  }
3536  else
3537  {
3538  /* otherwise we have to pass through all constraints */
3539  for( c = 0; c < nconss; ++c )
3540  {
3541  cons = conss[c];
3542  assert( cons != NULL);
3543 
3544  conshdlr = SCIPconsGetHdlr(cons);
3545  assert( conshdlr != NULL );
3546  conshdlrname = SCIPconshdlrGetName(conshdlr);
3547 
3548  if( strcmp(conshdlrname, "indicator") == 0 )
3549  {
3550  SCIP_CONS* lincons;
3551 
3552  lincons = SCIPgetLinearConsIndicator(cons);
3553  assert( lincons != NULL );
3554 
3555  assert( !SCIPhashmapExists(consHidden, (void*) lincons) );
3556  SCIP_CALL( SCIPhashmapSetImage(consHidden, (void*) lincons, (void*) TRUE) );
3557  SCIPdebugMessage("Marked linear constraint <%s> as hidden.\n", SCIPconsGetName(lincons));
3558  }
3559  }
3560  }
3561  }
3562 
3563  /* check if the variable names are not to long */
3564  checkVarnames(scip, vars, nvars);
3565  /* check if the constraint names are to long */
3566  checkConsnames(scip, conss, nconss, transformed);
3567 
3568  /* print statistics as comment to file */
3569  SCIPinfoMessage(scip, file, "\\ SCIP STATISTICS\n");
3570  SCIPinfoMessage(scip, file, "\\ Problem name : %s\n", name);
3571  SCIPinfoMessage(scip, file, "\\ Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
3572  nvars, nbinvars, nintvars, nimplvars, ncontvars);
3573  SCIPinfoMessage(scip, file, "\\ Constraints : %d\n", nconss);
3574  SCIPinfoMessage(scip, file, "\\ Obj. scale : %.15g\n", objscale);
3575  SCIPinfoMessage(scip, file, "\\ Obj. offset : %.15g\n", objoffset);
3576 
3577  /* print objective sense */
3578  SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "Minimize" : "Maximize");
3579 
3580  clearLine(linebuffer, &linecnt);
3581  appendLine(scip, file, linebuffer, &linecnt, " Obj:");
3582 
3583  for( v = 0; v < nvars; ++v )
3584  {
3585  var = vars[v];
3586 
3587 #ifndef NDEBUG
3588  /* in case the original problem has to be written, the variables have to be either "original" or "negated" */
3589  if( ! transformed )
3591 #endif
3592 
3593  if( SCIPisZero(scip, SCIPvarGetObj(var)) )
3594  continue;
3595 
3596  /* we start a new line; therefore we tab this line */
3597  if( linecnt == 0 )
3598  appendLine(scip, file, linebuffer, &linecnt, " ");
3599 
3600  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var));
3601  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %+.15g %s", SCIPvarGetObj(var), varname );
3602 
3603  appendLine(scip, file, linebuffer, &linecnt, buffer);
3604  }
3605 
3606  endLine(scip, file, linebuffer, &linecnt);
3607 
3608  /* print "Subject to" section */
3609  SCIPinfoMessage(scip, file, "Subject to\n");
3610 
3611  reader = SCIPfindReader(scip, READER_NAME);
3612  if( reader != NULL )
3613  {
3614  readerdata = SCIPreaderGetData(reader);
3615  assert(readerdata != NULL);
3616 
3617  linearizeands = readerdata->linearizeands;
3618  aggrlinearizationands = readerdata->aggrlinearizationands;
3619  }
3620  else
3621  {
3622  linearizeands = DEFAULT_LINEARIZE_ANDS;
3623  aggrlinearizationands = DEFAULT_AGGRLINEARIZATION_ANDS;
3624  }
3625 
3626  /* collect SOS, quadratic, and SOC constraints in array for later output */
3627  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3628  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3629  SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3630  SCIP_CALL( SCIPallocBufferArray(scip, &consSOC, nconss) );
3631  SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3632 
3633  for( c = 0; c < nconss; ++c )
3634  {
3635  cons = conss[c];
3636  assert( cons != NULL);
3637 
3638  /* in case the transformed is written only constraints are posted which are enabled in the current node */
3639  assert(!transformed || SCIPconsIsEnabled(cons));
3640 
3641  /* skip marked constraints in connection with indicator constraints */
3642  if( conshdlrInd != NULL && SCIPhashmapExists(consHidden, (void*) cons) )
3643  {
3644  assert( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear") == 0 );
3645  continue;
3646  }
3647 
3648  conshdlr = SCIPconsGetHdlr(cons);
3649  assert( conshdlr != NULL );
3650 
3651  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons));
3652  conshdlrname = SCIPconshdlrGetName(conshdlr);
3653  assert( transformed == SCIPconsIsTransformed(cons) );
3654 
3655  if( strcmp(conshdlrname, "linear") == 0 )
3656  {
3657  SCIP_CALL( printQuadraticCons(scip, file, consname,
3658  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3659  NULL, 0, NULL, 0, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), transformed) );
3660  }
3661  else if( strcmp(conshdlrname, "setppc") == 0 )
3662  {
3663  consvars = SCIPgetVarsSetppc(scip, cons);
3664  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3665 
3666  switch( SCIPgetTypeSetppc(scip, cons) )
3667  {
3669  SCIP_CALL( printQuadraticCons(scip, file, consname,
3670  consvars, NULL, nconsvars, NULL, 0, NULL, 0, 1.0, 1.0, transformed) );
3671  break;
3673  SCIP_CALL( printQuadraticCons(scip, file, consname,
3674  consvars, NULL, nconsvars, NULL, 0, NULL, 0, -SCIPinfinity(scip), 1.0, transformed) );
3675  break;
3677  SCIP_CALL( printQuadraticCons(scip, file, consname,
3678  consvars, NULL, nconsvars, NULL, 0, NULL, 0, 1.0, SCIPinfinity(scip), transformed) );
3679  break;
3680  }
3681  }
3682  else if( strcmp(conshdlrname, "logicor") == 0 )
3683  {
3684  SCIP_CALL( printQuadraticCons(scip, file, consname,
3685  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3686  NULL, 0, NULL, 0, 1.0, SCIPinfinity(scip), transformed) );
3687  }
3688  else if( strcmp(conshdlrname, "knapsack") == 0 )
3689  {
3690  SCIP_Longint* weights;
3691 
3692  consvars = SCIPgetVarsKnapsack(scip, cons);
3693  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3694 
3695  /* copy Longint array to SCIP_Real array */
3696  weights = SCIPgetWeightsKnapsack(scip, cons);
3697  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3698  for( v = 0; v < nconsvars; ++v )
3699  consvals[v] = (SCIP_Real)weights[v];
3700 
3701  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, nconsvars,
3702  NULL, 0, NULL, 0, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), transformed) );
3703 
3704  SCIPfreeBufferArray(scip, &consvals);
3705  }
3706  else if( strcmp(conshdlrname, "varbound") == 0 )
3707  {
3708  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3709  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3710 
3711  consvars[0] = SCIPgetVarVarbound(scip, cons);
3712  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3713 
3714  consvals[0] = 1.0;
3715  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3716 
3717  SCIP_CALL( printQuadraticCons(scip, file, consname, consvars, consvals, 2, NULL, 0, NULL, 0,
3718  SCIPgetLhsVarbound(scip, cons), SCIPgetRhsVarbound(scip, cons), transformed) );
3719 
3720  SCIPfreeBufferArray(scip, &consvars);
3721  SCIPfreeBufferArray(scip, &consvals);
3722  }
3723  else if( strcmp(conshdlrname, "SOS1") == 0 )
3724  {
3725  /* store constraint */
3726  consSOS1[nConsSOS1++] = cons;
3727  }
3728  else if( strcmp(conshdlrname, "SOS2") == 0 )
3729  {
3730  /* store constraint */
3731  consSOS2[nConsSOS2++] = cons;
3732  }
3733  else if( strcmp(conshdlrname, "indicator") == 0 )
3734  {
3735  SCIP_CONS* lincons;
3736  SCIP_VAR* binvar;
3737  SCIP_VAR* slackvar;
3738  SCIP_VAR** linvars;
3739  SCIP_Real* linvals;
3740  int nlinvars;
3741  int cnt;
3742  int rhs;
3743 
3744  assert( conshdlrInd != NULL );
3745 
3746  lincons = SCIPgetLinearConsIndicator(cons);
3747  binvar = SCIPgetBinaryVarIndicator(cons);
3748  slackvar = SCIPgetSlackVarIndicator(cons);
3749 
3750  assert( lincons != NULL );
3751  assert( binvar != NULL );
3752  assert( slackvar != NULL );
3753 
3754  rhs = 1;
3755  if ( SCIPvarIsNegated(binvar) )
3756  {
3757  rhs = 0;
3758  binvar = SCIPvarGetNegatedVar(binvar);
3759  }
3760 
3761  /* collect linear constraint information (remove slack variable) */
3762  linvars = SCIPgetVarsLinear(scip, lincons);
3763  linvals = SCIPgetValsLinear(scip, lincons);
3764  nlinvars = SCIPgetNVarsLinear(scip, lincons);
3765  assert( linvars != NULL );
3766  assert( linvals != NULL );
3767 
3768  /* linvars always contains slack variable, thus nlinvars >= 1 */
3769  if( nlinvars > 1 && !SCIPconsIsDeleted(lincons) )
3770  {
3771  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(binvar) );
3772  if( strlen(consname) > 0 )
3773  SCIPinfoMessage(scip, file, " %s: %s = %d ->", consname, varname, rhs);
3774  else
3775  SCIPinfoMessage(scip, file, " %s = %d ->", varname, rhs);
3776 
3777  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nlinvars-1) );
3778  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nlinvars-1) );
3779 
3780  cnt = 0;
3781  for( v = 0; v < nlinvars; ++v )
3782  {
3783  var = linvars[v];
3784  if( var != slackvar )
3785  {
3786  consvars[cnt] = var;
3787  consvals[cnt++] = linvals[v];
3788  }
3789  }
3790  /* if slackvariable is fixed, it might have been removed from constraint */
3791  assert( nlinvars == 0 || cnt == nlinvars-1 || SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar)) );
3792 
3793  SCIP_CALL( printQuadraticCons(scip, file, "", consvars, consvals, cnt, NULL, 0, NULL, 0,
3794  SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons), transformed) );
3795 
3796  SCIPfreeBufferArray(scip, &consvars);
3797  SCIPfreeBufferArray(scip, &consvals);
3798  }
3799 
3800  /* store constraint */
3801  consIndicator[nConsIndicator++] = cons;
3802  }
3803  else if( strcmp(conshdlrname, "quadratic") == 0 )
3804  {
3805  SCIP_CALL( printQuadraticCons(scip, file, consname,
3809  SCIPgetNBilinTermsQuadratic(scip, cons), SCIPgetLhsQuadratic(scip, cons),
3810  SCIPgetRhsQuadratic(scip, cons), transformed) );
3811 
3812  consQuadratic[nConsQuadratic++] = cons;
3813  }
3814  else if( strcmp(conshdlrname, "soc") == 0 )
3815  {
3816  SCIP_CALL( printSOCCons(scip, file, consname, cons) );
3817 
3818  consSOC[nConsSOC++] = cons;
3819  }
3820  else if( strcmp(conshdlrname, "and") == 0 )
3821  {
3822  if( linearizeands )
3823  {
3824  SCIP_CALL( printAndCons(scip, file, consname, cons, aggrlinearizationands, transformed) );
3825  }
3826  else
3827  {
3828  SCIPwarningMessage(scip, "change parameter \"reading/"READER_NAME"/linearize-and-constraints\" to TRUE to print and-constraints\n");
3829  SCIPinfoMessage(scip, file, "\\ ");
3830  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3831  SCIPinfoMessage(scip, file, ";\n");
3832  }
3833  }
3834  else
3835  {
3836  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3837  SCIPinfoMessage(scip, file, "\\ ");
3838  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3839  SCIPinfoMessage(scip, file, ";\n");
3840  }
3841  }
3842 
3843  /* allocate array for storing aggregated and negated variables (dynamically adjusted) */
3844  saggvars = MAX(10, nvars);
3845  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
3846 
3847  /* create hashtable for storing aggregated variables */
3848  SCIP_CALL( SCIPhashtableCreate(&varAggregated, SCIPblkmem(scip), 10 * saggvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3849 
3850  /* check for aggregated variables in SOS1 constraints and output aggregations as linear constraints */
3851  for( c = 0; c < nConsSOS1; ++c )
3852  {
3853  cons = consSOS1[c];
3854  consvars = SCIPgetVarsSOS1(scip, cons);
3855  nconsvars = SCIPgetNVarsSOS1(scip, cons);
3856 
3857  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
3858  }
3859 
3860  /* check for aggregated variables in SOS2 constraints and output aggregations as linear constraints */
3861  for( c = 0; c < nConsSOS2; ++c )
3862  {
3863  cons = consSOS2[c];
3864  consvars = SCIPgetVarsSOS2(scip, cons);
3865  nconsvars = SCIPgetNVarsSOS2(scip, cons);
3866 
3867  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varAggregated) );
3868  }
3869 
3870  /* check for aggregated variables in quadratic parts of quadratic constraints and output aggregations as linear constraints */
3871  for( c = 0; c < nConsQuadratic; ++c )
3872  {
3873  cons = consQuadratic[c];
3874  for( v = 0; v < SCIPgetNQuadVarTermsQuadratic(scip, cons); ++v )
3875  {
3876  SCIP_CALL( collectAggregatedVars(scip, &SCIPgetQuadVarTermsQuadratic(scip, cons)[v].var, 1, &aggvars, &naggvars, &saggvars, varAggregated) );
3877  }
3878  }
3879 
3880  /* check for aggregated variables in second order cone constraints and output aggregations as linear constraints */
3881  for( c = 0; c < nConsSOC; ++c )
3882  {
3883  cons = consSOC[c];
3884 
3885  SCIP_CALL( collectAggregatedVars(scip, SCIPgetLhsVarsSOC(scip, cons), SCIPgetNLhsVarsSOC(scip, cons), &aggvars, &naggvars, &saggvars, varAggregated) );
3886  var = SCIPgetRhsVarSOC(scip, cons);
3887  SCIP_CALL( collectAggregatedVars(scip, &var, 1, &aggvars, &naggvars, &saggvars, varAggregated) );
3888  }
3889 
3890  /* check for aggregated variables in indicator constraints and output aggregations as linear constraints */
3891  for( c = 0; c < nConsIndicator; ++c )
3892  {
3893  SCIP_VAR* binvar;
3894 
3895  cons = consIndicator[c];
3896  binvar = SCIPgetBinaryVarIndicator(cons);
3897  if ( ! SCIPvarIsNegated(binvar) )
3898  {
3899  /* we take care of negated variables above, but not of aggregated variables */
3900  SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varAggregated) );
3901  }
3902  }
3903 
3904  /* print aggregation constraints */
3905  SCIP_CALL( printAggregatedCons(scip, file, transformed, nvars, naggvars, aggvars) );
3906 
3907  /* print "Bounds" section */
3908  SCIPinfoMessage(scip, file, "Bounds\n");
3909  for( v = 0; v < nvars; ++v )
3910  {
3911  var = vars[v];
3912  assert( var != NULL );
3913  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3914 
3915  if( transformed )
3916  {
3917  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3918  lb = SCIPvarGetLbLocal(var);
3919  ub = SCIPvarGetUbLocal(var);
3920  }
3921  else
3922  {
3923  lb = SCIPvarGetLbOriginal(var);
3924  ub = SCIPvarGetUbOriginal(var);
3925  }
3926 
3927  if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3928  SCIPinfoMessage(scip, file, " %s free\n", varname);
3929  else
3930  {
3931  /* print lower bound */
3932  if( SCIPisInfinity(scip, -lb) )
3933  SCIPinfoMessage(scip, file, " -inf <= ");
3934  else
3935  {
3936  if( SCIPisZero(scip, lb) )
3937  {
3938  /* variables are nonnegative by default - so we skip these variables */
3939  if( SCIPisInfinity(scip, ub) )
3940  continue;
3941  lb = 0.0;
3942  }
3943 
3944  SCIPinfoMessage(scip, file, " %.15g <= ", lb);
3945  }
3946  /* print variable name */
3947  SCIPinfoMessage(scip, file, "%s", varname);
3948 
3949  /* print upper bound as far this one is not infinity */
3950  if( !SCIPisInfinity(scip, ub) )
3951  SCIPinfoMessage(scip, file, " <= %.15g", ub);
3952 
3953  SCIPinfoMessage(scip, file, "\n");
3954  }
3955  }
3956 
3957  /* output aggregated variables as 'free' */
3958  for( v = 0; v < naggvars; ++v )
3959  {
3960  var = aggvars[v];
3961  assert( var != NULL );
3962  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3963 
3964  SCIPinfoMessage(scip, file, " %s free\n", varname);
3965  }
3966 
3967  /* print binaries section */
3968  if( nbinvars > 0 )
3969  {
3970  SCIPinfoMessage(scip, file, "Binaries\n");
3971 
3972  clearLine(linebuffer, &linecnt);
3973 
3974  /* output active variables */
3975  for( v = 0; v < nvars; ++v )
3976  {
3977  var = vars[v];
3978  assert( var != NULL );
3979 
3980  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3981  {
3982  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3983  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
3984  appendLine(scip, file, linebuffer, &linecnt, buffer);
3985  }
3986  }
3987 
3988  /* possibly output aggregated variables */
3989  for( v = 0; v < naggvars; ++v )
3990  {
3991  var = aggvars[v];
3992  assert( var != NULL );
3993 
3994  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3995  {
3996  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
3997  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
3998  appendLine(scip, file, linebuffer, &linecnt, buffer);
3999  }
4000  }
4001 
4002  endLine(scip, file, linebuffer, &linecnt);
4003  }
4004 
4005  /* print generals section */
4006  if( nintvars > 0 )
4007  {
4008  SCIPinfoMessage(scip, file, "Generals\n");
4009 
4010  /* output active variables */
4011  for( v = 0; v < nvars; ++v )
4012  {
4013  var = vars[v];
4014  assert( var != NULL );
4015 
4016  if( SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER )
4017  {
4018  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4019  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4020  appendLine(scip, file, linebuffer, &linecnt, buffer);
4021  }
4022  }
4023 
4024  /* possibly output aggregated variables */
4025  for( v = 0; v < naggvars; ++v )
4026  {
4027  var = aggvars[v];
4028  assert( var != NULL );
4029 
4030  if( SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER )
4031  {
4032  (void) SCIPsnprintf(varname, LP_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4033  (void) SCIPsnprintf(buffer, LP_MAX_PRINTLEN, " %s", varname);
4034  appendLine(scip, file, linebuffer, &linecnt, buffer);
4035  }
4036  }
4037 
4038  endLine(scip, file, linebuffer, &linecnt);
4039  }
4040 
4041  /* free space */
4042  SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4043  SCIPhashtableFree(&varAggregated);
4044  if( conshdlrInd != NULL )
4045  SCIPhashmapFree(&consHidden);
4046 
4047  /* print SOS section */
4048  if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4049  {
4050  SCIP_Real* weights;
4051  SCIPinfoMessage(scip, file, "SOS\n");
4052 
4053  /* first output SOS1 constraints */
4054  for( c = 0; c < nConsSOS1; ++c )
4055  {
4056  cons = consSOS1[c];
4057  consvars = SCIPgetVarsSOS1(scip, cons);
4058  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4059  weights = SCIPgetWeightsSOS1(scip, cons);
4060 
4061  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4062  printSosCons(scip, file, consname, consvars, weights, nconsvars, 1);
4063  }
4064 
4065  /* next output SOS2 constraints */
4066  for( c = 0; c < nConsSOS2; ++c )
4067  {
4068  cons = consSOS2[c];
4069  consvars = SCIPgetVarsSOS2(scip, cons);
4070  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4071  weights = SCIPgetWeightsSOS2(scip, cons);
4072 
4073  (void) SCIPsnprintf(consname, LP_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4074  printSosCons(scip, file, consname, consvars, weights, nconsvars, 2);
4075  }
4076  }
4077 
4078  /* free space */
4079  SCIPfreeBufferArray(scip, &consIndicator);
4080  SCIPfreeBufferArray(scip, &consSOC);
4081  SCIPfreeBufferArray(scip, &consQuadratic);
4082  SCIPfreeBufferArray(scip, &consSOS2);
4083  SCIPfreeBufferArray(scip, &consSOS1);
4084 
4085  /* end of lp format */
4086  SCIPinfoMessage(scip, file, "%s\n", "End");
4087 
4088  *result = SCIP_SUCCESS;
4089 
4090  return SCIP_OKAY;
4091 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
static void syntaxError(SCIP *scip, LPINPUT *lpinput, const char *msg)
Definition: reader_lp.c:137
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38254
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:38397
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5600
SCIP_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:7491
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
static void checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed)
Definition: reader_lp.c:3223
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:17929
static const char commentchars[]
Definition: reader_lp.c:128
static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
Definition: reader_lp.c:2395
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:15614
SCIP_RETCODE SCIPreadLp(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_lp.c:3372
static SCIP_RETCODE printAndCons(SCIP *scip, FILE *file, const char *consname, SCIP_CONS *cons, SCIP_Bool aggrlinearizationands, SCIP_Bool transformed)
Definition: reader_lp.c:3002
Constraint handler for variable bound constraints .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:38360
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_lp.c:355
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:11962
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:510
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1374
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:19206
enum LpExpType LPEXPTYPE
Definition: reader_lp.c:93
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
static SCIP_RETCODE readCoefficients(SCIP *scip, LPINPUT *lpinput, SCIP_Bool isobjective, char *name, SCIP_VAR ***vars, SCIP_Real **coefs, int *ncoefs, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadcoefs, SCIP_Bool *newsection)
Definition: reader_lp.c:876
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
#define READER_NAME
Definition: reader_lp.c:54
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:9751
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1206
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:13986
#define SCIP_MAXSTRLEN
Definition: def.h:196
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:2438
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4239
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_lp.c:58
#define NULL
Definition: lpi_spx.cpp:129
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_lp.c:2404
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:16426
static SCIP_DECL_READERCOPY(readerCopyLp)
Definition: reader_lp.c:3282
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4209
SCIP_RETCODE SCIPincludeReaderLp(SCIP *scip)
Definition: reader_lp.c:3338
static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
Definition: reader_lp.c:2388
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16380
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9090
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool isSense(LPINPUT *lpinput, LPSENSE *sense)
Definition: reader_lp.c:779
enum LpSense LPSENSE
Definition: reader_lp.c:99
#define LP_MAX_PRINTLEN
Definition: reader_lp.c:69
static SCIP_RETCODE readSemicontinuous(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2009
#define LP_MAX_PUSHEDTOKENS
Definition: reader_lp.c:66
constraint handler for indicator constraints
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2470
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:7846
#define FALSE
Definition: def.h:52
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:1864
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:2413
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
#define TRUE
Definition: def.h:51
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7577
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define LP_PRINTLEN
Definition: reader_lp.c:71
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
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:3089
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:38743
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:17775
int SCIPgetNLhsVarsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4655
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:2388
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:38779
static SCIP_RETCODE readObjective(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1236
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:19185
#define SCIPdebugMessage
Definition: pub_message.h:77
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)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
SCIP_Real * SCIPgetLhsCoefsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4681
Constraint handler for "and" constraints, .
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16227
#define LP_INIT_QUADCOEFSSIZE
Definition: reader_lp.c:68
constraint handler for second order cone constraints
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:23934
static SCIP_Bool isDelimChar(char c)
Definition: reader_lp.c:175
Constraint handler for the set partitioning / packing / covering constraints .
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:22651
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip.c:4367
static SCIP_Bool isNewSection(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:511
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:19215
int SCIPfseek(SCIP_FILE *stream, long offset, int whence)
Definition: fileio.c:199
static SCIP_RETCODE getVariable(SCIP *scip, char *name, SCIP_VAR **var, SCIP_Bool *created)
Definition: reader_lp.c:810
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:1287
static SCIP_DECL_READERFREE(readerFreeLp)
Definition: reader_lp.c:3296
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:3388
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, LPEXPTYPE *exptype)
Definition: reader_lp.c:220
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:15907
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1966
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip.c:4343
static void pushToken(LPINPUT *lpinput)
Definition: reader_lp.c:474
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_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:140
SCIP_Real SCIPgetRhsCoefSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4733
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_VAR ** SCIPgetLhsVarsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4668
static SCIP_RETCODE readSos(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:2107
static SCIP_RETCODE readGenerals(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1910
SCIP_VAR * SCIPgetRhsVarSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4720
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5040
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
static SCIP_Bool getNextLine(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:264
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
static void printSosCons(SCIP *scip, FILE *file, const char *rowname, SCIP_VAR **vars, SCIP_Real *weights, int nvars, int type)
Definition: reader_lp.c:2793
SCIP_READER * SCIPfindReader(SCIP *scip, const char *name)
Definition: scip.c:4431
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:3441
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
LpSense
Definition: reader_lp.c:95
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3873
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:964
static void appendLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_lp.c:2528
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9111
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip.c:15406
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:37940
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:7557
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38648
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:15943
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:1882
constraint handler for quadratic constraints
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:19189
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5065
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:8453
static SCIP_RETCODE readStart(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:855
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:38349
#define SCIP_CALL(x)
Definition: def.h:258
#define LP_INIT_COEFSSIZE
Definition: reader_lp.c:67
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_lp.c:2447
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool getNextToken(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:369
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetRhsOffsetSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4746
#define READER_EXTENSION
Definition: reader_lp.c:56
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip.c:4391
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:15130
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)
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:2694
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:16195
static SCIP_RETCODE readConstraints(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1515
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip.c:20694
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:16436
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:37
public data structures and miscellaneous methods
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:18008
static SCIP_DECL_READERWRITE(readerWriteLp)
Definition: reader_lp.c:3321
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16062
#define SCIP_Bool
Definition: def.h:49
SCIP_Real SCIPgetLhsConstantSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4707
static SCIP_RETCODE readBounds(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1739
void SCIPprintSysError(const char *message)
Definition: misc.c:7515
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip.c:4305
static SCIP_Bool isTokenChar(char c)
Definition: reader_lp.c:196
#define READER_DESC
Definition: reader_lp.c:55
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2369
static void checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars)
Definition: reader_lp.c:3198
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:2559
#define MAX(x, y)
Definition: tclique_def.h:75
static SCIP_DECL_READERREAD(readerReadLp)
Definition: reader_lp.c:3310
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2420
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:7676
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2445
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
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:2270
static SCIP_RETCODE readBinaries(SCIP *scip, LPINPUT *lpinput)
Definition: reader_lp.c:1955
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip.h:19178
static SCIP_Bool isSign(LPINPUT *lpinput, int *sign)
Definition: reader_lp.c:722
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip.h:19167
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:2213
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip.h:19161
Constraint handler for linear constraints in their most general form, .
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
enum LpSection LPSECTION
Definition: reader_lp.c:87
#define LP_MAX_NAMELEN
Definition: reader_lp.c:70
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1256
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1317
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition: reader.c:445
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:10850
static void pushBufferToken(LPINPUT *lpinput)
Definition: reader_lp.c:487
static SCIP_RETCODE createIndicatorConstraint(SCIP *scip, LPINPUT *lpinput, const char *name, SCIP_VAR *binvar, SCIP_Real binvalue)
Definition: reader_lp.c:1319
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
#define DEFAULT_AGGRLINEARIZATION_ANDS
Definition: reader_lp.c:59
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:19176
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16370
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip.c:9387
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip.c:4415
LP file reader.
static const SCIP_Real scalars[]
Definition: lp.c:5431
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1239
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:16316
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
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 LP_MAX_LINELEN
Definition: reader_lp.c:65
static SCIP_RETCODE printAggregatedCons(SCIP *scip, FILE *file, SCIP_Bool transformed, int nvars, int nAggregatedVars, SCIP_VAR **aggregatedVars)
Definition: reader_lp.c:3145
static SCIP_RETCODE readLPFile(SCIP *scip, LPINPUT *lpinput, const char *filename)
Definition: reader_lp.c:2310
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:19217
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16072
LpExpType
Definition: reader_lp.c:89
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:1944
#define SCIP_Real
Definition: def.h:123
LpSection
Definition: reader_lp.c:83
constraint handler for SOS type 1 constraints
static void swapTokenBuffer(LPINPUT *lpinput)
Definition: reader_lp.c:500
static void endLine(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_lp.c:2506
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip.c:10765
static SCIP_RETCODE printSOCCons(SCIP *scip, FILE *file, const char *rowname, SCIP_CONS *cons)
Definition: reader_lp.c:2852
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIP_Longint
Definition: def.h:107
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1499
struct LpInput LPINPUT
Definition: reader_lp.c:126
static SCIP_Bool isValue(SCIP *scip, LPINPUT *lpinput, SCIP_Real *value)
Definition: reader_lp.c:747
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:16336
constraint handler for SOS type 2 constraints
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9132
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:38001
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:98
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:219
constraint handler for bound disjunction constraints
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:2337
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:7644
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip.h:19179
#define SCIPABORT()
Definition: def.h:230
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip.c:3581
static SCIP_Bool hasError(LPINPUT *lpinput)
Definition: reader_lp.c:164
static void clearLine(char *linebuffer, int *linecnt)
Definition: reader_lp.c:2492
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real * SCIPgetLhsOffsetsSOC(SCIP *scip, SCIP_CONS *cons)
Definition: cons_soc.c:4694
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5016