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