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