Scippy

SCIP

Solving Constraint Integer Programs

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