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