Scippy

SCIP

Solving Constraint Integer Programs

reader_opb.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-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file reader_opb.c
26  * @ingroup DEFPLUGINS_READER
27  * @brief pseudo-Boolean file reader (opb format)
28  * @author Stefan Heinz
29  * @author Michael Winkler
30  *
31  * This file reader parses the @a opb format and is also used by the @a wbo reader for the @a wbo format. For a
32  * detailed description of this format see
33  *
34  * - http://www.cril.univ-artois.fr/PB07/solver_req.html
35  * - http://www.cril.univ-artois.fr/PB10/format.pdf
36  *
37  * The syntax of the input file format can be described by a simple Backus-Naur
38  * form. <formula> is the start symbol of this grammar.
39  *
40  * <formula>::= <sequence_of_comments>
41  * [<objective>] | [<softheader>]
42  * <sequence_of_comments_or_constraints>
43  *
44  * <sequence_of_comments>::= <comment> [<sequence_of_comments>]
45  * <comment>::= "*" <any_sequence_of_characters_other_than_EOL> <EOL>
46  * <sequence_of_comments_or_constraints>::=<comment_or_constraint> [<sequence_of_comments_or_constraints>]
47  * <comment_or_constraint>::=<comment>|<constraint>
48  *
49  * <objective>::= "min:" <zeroOrMoreSpace> <sum> ";"
50  * <constraint>::= <sum> <relational_operator> <zeroOrMoreSpace> <integer> <zeroOrMoreSpace> ";"
51  *
52  * <sum>::= <weightedterm> | <weightedterm> <sum>
53  * <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
54  *
55  * <integer>::= <unsigned_integer> | "+" <unsigned_integer> | "-" <unsigned_integer>
56  * <unsigned_integer>::= <digit> | <digit><unsigned_integer>
57  *
58  * <relational_operator>::= ">=" | "="
59  *
60  * <variablename>::= "x" <unsigned_integer>
61  *
62  * <oneOrMoreSpace>::= " " [<oneOrMoreSpace>]
63  * <zeroOrMoreSpace>::= [" " <zeroOrMoreSpace>]
64  *
65  * For linear pseudo-Boolean instances, <term> is defined as
66  *
67  * <term>::=<variablename>
68  *
69  * For non-linear instances, <term> is defined as
70  *
71  * <term>::= <oneOrMoreLiterals>
72  * <oneOrMoreLiterals>::= <literal> | <literal> <oneOrMoreSpace> <oneOrMoreLiterals>
73  * <literal>::= <variablename> | "~"<variablename>
74  *
75  * For wbo-files are the following additional/changed things possible.
76  *
77  * <softheader>::= "soft:" [<unsigned integer>] ";"
78  *
79  * <comment_or_constraint>::=<comment>|<constraint>|<softconstraint>
80  *
81  * <softconstraint>::= "[" <zeroOrMoreSpace> <unsigned integer> <zeroOrMoreSpace> "]" <constraint>
82  *
83  */
84 
85 /* Our parser should also be lax by handling variable names and it's possible to read doubles instead of integer and
86  * possible some more :). */
87 
88 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
89 
90 #include "blockmemshell/memory.h"
91 #include <ctype.h>
92 #include "scip/cons_and.h"
93 #include "scip/cons_indicator.h"
94 #include "scip/cons_knapsack.h"
95 #include "scip/cons_linear.h"
96 #include "scip/cons_logicor.h"
98 #include "scip/cons_setppc.h"
99 #include "scip/cons_varbound.h"
100 #include "scip/debug.h"
101 #include "scip/pub_cons.h"
102 #include "scip/pub_fileio.h"
103 #include "scip/pub_message.h"
104 #include "scip/pub_misc.h"
105 #include "scip/pub_misc_sort.h"
106 #include "scip/pub_reader.h"
107 #include "scip/pub_var.h"
108 #include "scip/reader_opb.h"
109 #include "scip/scip_cons.h"
110 #include "scip/scip_mem.h"
111 #include "scip/scip_message.h"
112 #include "scip/scip_numerics.h"
113 #include "scip/scip_param.h"
114 #include "scip/scip_prob.h"
115 #include "scip/scip_reader.h"
116 #include "scip/scip_solvingstats.h"
117 #include "scip/scip_var.h"
118 #include <stdlib.h>
119 #include <string.h>
120 
121 #if !defined(_WIN32) && !defined(_WIN64)
122 #include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
123 #endif
124 
125 #define READER_NAME "opbreader"
126 #define READER_DESC "file reader for pseudo-Boolean problem in opb format"
127 #define READER_EXTENSION "opb"
128 
129 #define GENCONSNAMES TRUE /* remove if no constraint names should be generated */
130 #define LINEAROBJECTIVE TRUE /* will all non-linear parts inside the objective function be linearized or will
131  * an artificial integer variable be created which will represent the objective
132  * function
133  */
134 
135 #define INDICATORVARNAME "indicatorvar" /* standard part of name for all indicator variables */
136 #define INDICATORSLACKVARNAME "indslack" /* standard part of name for all indicator slack variables; should be the same in cons_indicator */
137 #define TOPCOSTCONSNAME "topcostcons" /* standard name for artificial topcost constraint in wbo problems */
138 
139 /*
140  * Data structures
141  */
142 #define OPB_MAX_LINELEN 65536 /**< size of the line buffer for reading or writing */
143 #define OPB_MAX_PUSHEDTOKENS 2
144 #define OPB_INIT_COEFSSIZE 8192
145 
146 /** Section in OPB File */
148 {
152 };
153 typedef enum OpbExpType OPBEXPTYPE;
154 
156 {
161 };
162 typedef enum OpbSense OPBSENSE;
163 
164 /** OPB reading data */
165 struct OpbInput
166 {
167  SCIP_FILE* file;
168  char* linebuf;
169  char* token;
170  char* tokenbuf;
171  char* pushedtokens[OPB_MAX_PUSHEDTOKENS];
172  int npushedtokens;
173  int linenumber;
174  int linepos;
175  int linebufsize;
176  SCIP_OBJSENSE objsense;
177  SCIP_Bool eof;
178  SCIP_Bool haserror;
179  int nproblemcoeffs;
180  SCIP_Bool wbo;
181  SCIP_Real topcost;
182  int nindvars;
183 #if GENCONSNAMES == TRUE
184  int consnumber;
185 #endif
186 };
187 
188 typedef struct OpbInput OPBINPUT;
189 
190 static const char commentchars[] = "*";
191 /*
192  * Local methods (for reading)
193  */
194 
195 /** issues an error message and marks the OPB data to have errors */
196 static
198  SCIP* scip, /**< SCIP data structure */
199  OPBINPUT* opbinput, /**< OPB reading data */
200  const char* msg /**< error message */
201  )
202 {
203  assert(scip != NULL);
204  assert(opbinput != NULL);
205 
206  SCIPerrorMessage("Syntax error in line %d: %s found <%s>\n", opbinput->linenumber, msg, opbinput->token);
207  if( opbinput->linebuf[opbinput->linebufsize - 1] == '\n' )
208  {
209  SCIPerrorMessage(" input: %s", opbinput->linebuf);
210  }
211  else
212  {
213  SCIPerrorMessage(" input: %s\n", opbinput->linebuf);
214  }
215 
216  opbinput->haserror = TRUE;
217 }
218 
219 /** returns whether a syntax error was detected */
220 static
222  OPBINPUT* opbinput /**< OPB reading data */
223  )
224 {
225  assert(opbinput != NULL);
226 
227  return opbinput->haserror;
228 }
229 
230 /** returns whether the given character is a token delimiter */
231 static
233  char c /**< input character */
234  )
235 {
236  switch (c)
237  {
238  case ' ':
239  case '\f':
240  case '\n':
241  case '\r':
242  case '\t':
243  case '\v':
244  case '\0':
245  return TRUE;
246  default:
247  return FALSE;
248  }
249 }
250 
251 /** returns whether the given character is a single token */
252 static
254  char c /**< input character */
255  )
256 {
257  switch (c)
258  {
259  case '-':
260  case '+':
261  case ':':
262  case '<':
263  case '>':
264  case '=':
265  case '[':
266  case ']':
267  case ';':
268  return TRUE;
269  default:
270  return FALSE;
271  }
272 }
273 
274 /** returns whether the current character is member of a value string */
275 static
277  char c, /**< input character */
278  char nextc, /**< next input character */
279  SCIP_Bool firstchar, /**< is the given character the first char of the token? */
280  SCIP_Bool* hasdot, /**< pointer to update the dot flag */
281  OPBEXPTYPE* exptype /**< pointer to update the exponent type */
282  )
283 {
284  assert(hasdot != NULL);
285  assert(exptype != NULL);
286 
287  if( isdigit((unsigned char)c) )
288  return TRUE;
289  else if( (*exptype == OPB_EXP_NONE) && !(*hasdot) && (c == '.') )
290  {
291  *hasdot = TRUE;
292  return TRUE;
293  }
294  else if( !firstchar && (*exptype == OPB_EXP_NONE) && (c == 'e' || c == 'E') )
295  {
296  if( nextc == '+' || nextc == '-' )
297  {
298  *exptype = OPB_EXP_SIGNED;
299  return TRUE;
300  }
301  else if( isdigit((unsigned char)nextc) )
302  {
303  *exptype = OPB_EXP_UNSIGNED;
304  return TRUE;
305  }
306  }
307  else if( (*exptype == OPB_EXP_SIGNED) && (c == '+' || c == '-') )
308  {
309  *exptype = OPB_EXP_UNSIGNED;
310  return TRUE;
311  }
312 
313  return FALSE;
314 }
315 
316 /** reads the next line from the input file into the line buffer; skips comments;
317  * returns whether a line could be read
318  */
319 static
321  SCIP* scip, /**< SCIP data structure */
322  OPBINPUT* opbinput /**< OPB reading data */
323  )
324 {
325  int i;
326 
327  assert(opbinput != NULL);
328 
329  /* read next line */
330  opbinput->linepos = 0;
331  opbinput->linebuf[opbinput->linebufsize - 2] = '\0';
332 
333  if( SCIPfgets(opbinput->linebuf, opbinput->linebufsize, opbinput->file) == NULL )
334  return FALSE;
335 
336  opbinput->linenumber++;
337 
338  /* if line is too long for our buffer reallocate buffer */
339  while( opbinput->linebuf[opbinput->linebufsize - 2] != '\0' )
340  {
341  int newsize;
342 
343  newsize = SCIPcalcMemGrowSize(scip, opbinput->linebufsize + 1);
344  SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &opbinput->linebuf, opbinput->linebufsize, newsize) );
345 
346  opbinput->linebuf[newsize-2] = '\0';
347  if ( SCIPfgets(opbinput->linebuf + opbinput->linebufsize - 1, newsize - opbinput->linebufsize + 1, opbinput->file) == NULL )
348  return FALSE;
349  opbinput->linebufsize = newsize;
350  }
351 
352  opbinput->linebuf[opbinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
353 
354  /* skip characters after comment symbol */
355  for( i = 0; commentchars[i] != '\0'; ++i )
356  {
357  char* commentstart;
358 
359  commentstart = strchr(opbinput->linebuf, commentchars[i]);
360  if( commentstart != NULL )
361  {
362  *commentstart = '\0';
363  *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
364  break;
365  }
366  }
367 
368  SCIPdebugMsg(scip, "%s\n", opbinput->linebuf);
369 
370  return TRUE;
371 }
372 
373 /** swaps the addresses of two pointers */
374 static
376  char** pointer1, /**< first pointer */
377  char** pointer2 /**< second pointer */
378  )
379 {
380  char* tmp;
381 
382  tmp = *pointer1;
383  *pointer1 = *pointer2;
384  *pointer2 = tmp;
385 }
386 
387 /** reads the next token from the input file into the token buffer; returns whether a token was read */
388 static
390  SCIP* scip, /**< SCIP data structure */
391  OPBINPUT* opbinput /**< OPB reading data */
392  )
393 {
394  SCIP_Bool hasdot;
395  OPBEXPTYPE exptype;
396  char* buf;
397  int tokenlen;
398 
399  assert(opbinput != NULL);
400  assert(opbinput->linepos < opbinput->linebufsize);
401 
402  /* check the token stack */
403  if( opbinput->npushedtokens > 0 )
404  {
405  swapPointers(&opbinput->token, &opbinput->pushedtokens[opbinput->npushedtokens-1]);
406  opbinput->npushedtokens--;
407  SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", opbinput->linenumber, opbinput->token);
408  return TRUE;
409  }
410 
411  /* skip delimiters */
412  buf = opbinput->linebuf;
413  while( isDelimChar(buf[opbinput->linepos]) )
414  {
415  if( buf[opbinput->linepos] == '\0' )
416  {
417  if( !getNextLine(scip, opbinput) )
418  {
419  SCIPdebugMsg(scip, "(line %d) end of file\n", opbinput->linenumber);
420  return FALSE;
421  }
422  assert(opbinput->linepos == 0);
423  /* update buf, because the linebuffer may have been reallocated */
424  buf = opbinput->linebuf;
425  }
426  else
427  opbinput->linepos++;
428  }
429  assert(opbinput->linepos < opbinput->linebufsize);
430  assert(!isDelimChar(buf[opbinput->linepos]));
431 
432  /* check if the token is a value */
433  hasdot = FALSE;
434  exptype = OPB_EXP_NONE;
435  if( isValueChar(buf[opbinput->linepos], buf[opbinput->linepos+1], TRUE, &hasdot, &exptype) )
436  {
437  /* read value token */
438  tokenlen = 0;
439  do
440  {
441  assert(tokenlen < OPB_MAX_LINELEN);
442  assert(!isDelimChar(buf[opbinput->linepos]));
443  opbinput->token[tokenlen] = buf[opbinput->linepos];
444  tokenlen++;
445  opbinput->linepos++;
446  }
447  while( isValueChar(buf[opbinput->linepos], buf[opbinput->linepos+1], FALSE, &hasdot, &exptype) );
448  }
449  else
450  {
451  /* read non-value token */
452  tokenlen = 0;
453  do
454  {
455  assert(tokenlen < OPB_MAX_LINELEN);
456  opbinput->token[tokenlen] = buf[opbinput->linepos];
457  tokenlen++;
458  opbinput->linepos++;
459  if( tokenlen == 1 && isTokenChar(opbinput->token[0]) )
460  break;
461  }
462  while( !isDelimChar(buf[opbinput->linepos]) && !isTokenChar(buf[opbinput->linepos]) );
463 
464  /* if the token is an equation sense '<', '>', or '=', skip a following '='
465  * if the token is an equality token '=' and the next character is a '<' or '>',
466  * replace the token by the inequality sense
467  */
468  if( tokenlen >= 1
469  && (opbinput->token[tokenlen-1] == '<' || opbinput->token[tokenlen-1] == '>' || opbinput->token[tokenlen-1] == '=')
470  && buf[opbinput->linepos] == '=' )
471  {
472  opbinput->linepos++;
473  }
474  else if( opbinput->token[tokenlen-1] == '=' && (buf[opbinput->linepos] == '<' || buf[opbinput->linepos] == '>') )
475  {
476  opbinput->token[tokenlen-1] = buf[opbinput->linepos];
477  opbinput->linepos++;
478  }
479  }
480  assert(tokenlen < OPB_MAX_LINELEN);
481  opbinput->token[tokenlen] = '\0';
482 
483  SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", opbinput->linenumber, opbinput->token);
484 
485  return TRUE;
486 }
487 
488 /** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
489 static
491  OPBINPUT* opbinput /**< OPB reading data */
492  )
493 {
494  assert(opbinput != NULL);
495  assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
496 
497  swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->token);
498  opbinput->npushedtokens++;
499 }
500 
501 /** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
502 static
504  OPBINPUT* opbinput /**< OPB reading data */
505  )
506 {
507  assert(opbinput != NULL);
508  assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
509 
510  swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->tokenbuf);
511  opbinput->npushedtokens++;
512 }
513 
514 /** swaps the current token with the token buffer */
515 static
517  OPBINPUT* opbinput /**< OPB reading data */
518  )
519 {
520  assert(opbinput != NULL);
521 
522  swapPointers(&opbinput->token, &opbinput->tokenbuf);
523 }
524 
525 /** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
526 static
528  OPBINPUT* opbinput /**< OPB reading data */
529  )
530 {
531  assert(opbinput != NULL);
532 
533  if( *(opbinput->token) == ';')
534  return TRUE;
535 
536  return FALSE;
537 }
538 
539 /** returns whether the current token is a sign */
540 static
542  OPBINPUT* opbinput, /**< OPB reading data */
543  int* sign /**< pointer to update the sign */
544  )
545 {
546  assert(opbinput != NULL);
547  assert(sign != NULL);
548  assert(*sign == +1 || *sign == -1);
549 
550  if( strlen(opbinput->token) == 1 )
551  {
552  assert(opbinput->token[1] == '\0');
553 
554  if( *opbinput->token == '+' )
555  return TRUE;
556  else if( *opbinput->token == '-' )
557  {
558  *sign *= -1;
559  return TRUE;
560  }
561  }
562 
563  return FALSE;
564 }
565 
566 /** returns whether the current token is a value */
567 static
569  SCIP* scip, /**< SCIP data structure */
570  OPBINPUT* opbinput, /**< OPB reading data */
571  SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
572  )
573 {
574  assert(opbinput != NULL);
575  assert(value != NULL);
576 
577  if( strcasecmp(opbinput->token, "INFINITY") == 0 || strcasecmp(opbinput->token, "INF") == 0 )
578  {
579  *value = SCIPinfinity(scip);
580  return TRUE;
581  }
582  else
583  {
584  double val;
585  char* endptr;
586 
587  val = strtod(opbinput->token, &endptr);
588  if( endptr != opbinput->token && *endptr == '\0' )
589  {
590  *value = val;
591  if( strlen(opbinput->token) > 18 )
592  opbinput->nproblemcoeffs++;
593  return TRUE;
594  }
595  }
596 
597  return FALSE;
598 }
599 
600 /** returns whether the current token is an equation sense */
601 static
603  OPBINPUT* opbinput, /**< OPB reading data */
604  OPBSENSE* sense /**< pointer to store the equation sense, or NULL */
605  )
606 {
607  assert(opbinput != NULL);
608 
609  if( strcmp(opbinput->token, "<") == 0 )
610  {
611  if( sense != NULL )
612  *sense = OPB_SENSE_LE;
613  return TRUE;
614  }
615  else if( strcmp(opbinput->token, ">") == 0 )
616  {
617  if( sense != NULL )
618  *sense = OPB_SENSE_GE;
619  return TRUE;
620  }
621  else if( strcmp(opbinput->token, "=") == 0 )
622  {
623  if( sense != NULL )
624  *sense = OPB_SENSE_EQ;
625  return TRUE;
626  }
627 
628  return FALSE;
629 }
630 
631 /** returns whether the current token is a value */
632 static
634  SCIP* scip, /**< SCIP data structure */
635  OPBINPUT* opbinput /**< OPB reading data */
636  )
637 {
638  assert(scip != NULL);
639  assert(opbinput != NULL);
640 
641  if( strcmp(opbinput->token, "[") == 0 )
642  return TRUE;
643 
644  return FALSE;
645 }
646 
647 /** returns whether the current token is a value */
648 static
650  SCIP* scip, /**< SCIP data structure */
651  OPBINPUT* opbinput /**< OPB reading data */
652  )
653 {
654  assert(scip != NULL);
655  assert(opbinput != NULL);
656 
657  if( strcmp(opbinput->token, "]") == 0 )
658  return TRUE;
659 
660  return FALSE;
661 }
662 
663 /** create binary variable with given name */
664 static
666  SCIP* scip, /**< SCIP data structure */
667  SCIP_VAR** var, /**< pointer to store the variable */
668  char* name /**< name for the variable */
669  )
670 {
671  SCIP_VAR* newvar;
672  SCIP_Bool dynamiccols;
673  SCIP_Bool initial;
674  SCIP_Bool removable;
675 
676  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
677  initial = !dynamiccols;
678  removable = dynamiccols;
679 
680  /* create new variable of the given name */
681  SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
682 
683  SCIP_CALL( SCIPcreateVar(scip, &newvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
684  initial, removable, NULL, NULL, NULL, NULL, NULL) );
685  SCIP_CALL( SCIPaddVar(scip, newvar) );
686  *var = newvar;
687 
688  /* because the variable was added to the problem, it is captured by SCIP and we
689  * can safely release it right now without making the returned *var invalid */
690  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
691 
692  return SCIP_OKAY;
693 }
694 
695 /** returns the variable with the given name, or creates a new variable if it does not exist */
696 static
698  SCIP* scip, /**< SCIP data structure */
699  OPBINPUT* opbinput, /**< OPB reading data */
700  SCIP_VAR*** vars, /**< pointer to store the variables */
701  int* nvars, /**< pointer to store the number of variables */
702  int* varssize /**< pointer to store the varsize, if changed (should already be initialized) */
703  )
704 {
705  SCIP_Bool negated;
706  char* name;
707 
708  assert(scip != NULL);
709  assert(opbinput != NULL);
710  assert(vars != NULL);
711  assert(nvars != NULL);
712  assert(varssize != NULL);
713  assert(*varssize >= 0);
714 
715  *nvars = 0;
716 
717  name = opbinput->token;
718  assert(name != NULL);
719 
720  /* parse AND terms */
721  while(!isdigit((unsigned char) *name ) && !isTokenChar(*name) && !opbinput->haserror )
722  {
723  SCIP_VAR* var;
724 
725  negated = FALSE;
726  if( *name == '~' )
727  {
728  negated = TRUE;
729  ++name;
730  }
731 
732  var = SCIPfindVar(scip, name);
733  if( var == NULL )
734  {
735  SCIP_CALL( createVariable(scip, &var, name) );
736  }
737 
738  if( negated )
739  {
740  SCIP_VAR* negvar;
741  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negvar) );
742 
743  var = negvar;
744  }
745 
746  /* reallocated memory */
747  if( *nvars == *varssize )
748  {
749  *varssize = SCIPcalcMemGrowSize(scip, *varssize + 1);
750  SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
751  }
752 
753  (*vars)[*nvars] = var;
754  ++(*nvars);
755 
756  if( !getNextToken(scip, opbinput) )
757  opbinput->haserror = TRUE;
758 
759  name = opbinput->token;
760  }
761 
762  /* check if we found at least on variable */
763  if( *nvars == 0 )
764  syntaxError(scip, opbinput, "expected a variable name");
765 
766  pushToken(opbinput);
767 
768  return SCIP_OKAY;
769 }
770 
771 /** reads an objective or constraint with name and coefficients */
772 static
774  SCIP*const scip, /**< SCIP data structure */
775  OPBINPUT*const opbinput, /**< OPB reading data */
776  char*const name, /**< pointer to store the name of the line; must be at least of size
777  * OPB_MAX_LINELEN */
778  SCIP_VAR*** linvars, /**< pointer to store the array with linear variables (must be freed by caller) */
779  SCIP_Real** lincoefs, /**< pointer to store the array with linear coefficients (must be freed by caller) */
780  int*const nlincoefs, /**< pointer to store the number of linear coefficients */
781  SCIP_VAR**** terms, /**< pointer to store the array with nonlinear variables (must be freed by caller) */
782  SCIP_Real** termcoefs, /**< pointer to store the array with nonlinear coefficients (must be freed by caller) */
783  int** ntermvars, /**< pointer to store the number of nonlinear variables in the terms (must be freed by caller) */
784  int*const ntermcoefs, /**< pointer to store the number of nonlinear coefficients */
785  SCIP_Bool*const newsection, /**< pointer to store whether a new section was encountered */
786  SCIP_Bool*const isNonlinear, /**< pointer to store if we have a nonlinear constraint */
787  SCIP_Bool*const issoftcons, /**< pointer to store whether it is a soft constraint (for wbo files) */
788  SCIP_Real*const weight /**< pointer to store the weight of the soft constraint */
789  )
790 {
791  SCIP_VAR** tmpvars;
792  SCIP_Real* tmpcoefs;
793  SCIP_Bool havesign;
794  SCIP_Bool havevalue;
795  SCIP_Bool haveweightstart;
796  SCIP_Bool haveweightend;
797  SCIP_Real coef;
798  int coefsign;
799  int lincoefssize;
800  int termcoefssize;
801  int tmpvarssize;
802  int ntmpcoefs;
803  int ntmpvars;
804 
805  assert(opbinput != NULL);
806  assert(name != NULL);
807  assert(linvars != NULL);
808  assert(lincoefs != NULL);
809  assert(nlincoefs != NULL);
810  assert(terms != NULL);
811  assert(termcoefs != NULL);
812  assert(ntermvars != NULL);
813  assert(ntermcoefs != NULL);
814  assert(newsection != NULL);
815 
816  *linvars = NULL;
817  *lincoefs = NULL;
818  *terms = NULL;
819  *termcoefs = NULL;
820  *ntermvars = NULL;
821  *name = '\0';
822  *nlincoefs = 0;
823  *ntermcoefs = 0;
824  *newsection = FALSE;
825  *isNonlinear = FALSE;
826  *issoftcons = FALSE;
827 
828  SCIPdebugMsg(scip, "read coefficients\n");
829 
830  /* read the first token, which may be the name of the line */
831  if( getNextToken(scip, opbinput) )
832  {
833  /* remember the token in the token buffer */
834  swapTokenBuffer(opbinput);
835 
836  /* get the next token and check, whether it is a colon */
837  if( getNextToken(scip, opbinput) )
838  {
839  if( strcmp(opbinput->token, ":") == 0 )
840  {
841  /* the second token was a colon ':' the first token is a constraint name */
842  (void)SCIPmemccpy(name, opbinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
843 
844  name[SCIP_MAXSTRLEN-1] = '\0';
845  SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", opbinput->linenumber, name);
846 
847  /* all but the first coefficient need a sign */
848  if( strcmp(name, "soft") == 0 && (SCIPgetNVars(scip) > 0 || SCIPgetNConss(scip) > 0) )
849  {
850  syntaxError(scip, opbinput, "Soft top cost line needs to be the first non-comment line, and without any objective function.\n");
851  return SCIP_OKAY;
852  }
853  }
854  else
855  {
856  /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
857  SCIPdebugMsg(scip, "(line %d) constraint has no name\n", opbinput->linenumber);
858  pushToken(opbinput);
859  pushBufferToken(opbinput);
860  }
861  }
862  else
863  {
864  /* there was only one token left: push it back onto the token stack and parse it as coefficient */
865  pushBufferToken(opbinput);
866  }
867  }
868  else
869  {
870  assert(SCIPfeof( opbinput->file ) );
871  opbinput->eof = TRUE;
872  return SCIP_OKAY;
873  }
874 
875  /* initialize buffers for storing the coefficients */
876  lincoefssize = OPB_INIT_COEFSSIZE;
877  termcoefssize = OPB_INIT_COEFSSIZE;
878  tmpvarssize = OPB_INIT_COEFSSIZE;
879  SCIP_CALL( SCIPallocBufferArray(scip, linvars, lincoefssize) );
880  SCIP_CALL( SCIPallocBufferArray(scip, lincoefs, lincoefssize) );
881  SCIP_CALL( SCIPallocBufferArray(scip, terms, termcoefssize) );
882  SCIP_CALL( SCIPallocBufferArray(scip, termcoefs, termcoefssize) );
883  SCIP_CALL( SCIPallocBufferArray(scip, ntermvars, termcoefssize) );
884  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
885  SCIP_CALL( SCIPallocBufferArray(scip, &tmpcoefs, tmpvarssize) );
886 
887  /* read the coefficients */
888  coefsign = +1;
889  coef = 1.0;
890  havesign = FALSE;
891  havevalue = FALSE;
892  haveweightstart = FALSE;
893  haveweightend = FALSE;
894  ntmpcoefs = 0;
895  ntmpvars = 0;
896 
897  while( getNextToken(scip, opbinput) && !hasError(opbinput) )
898  {
899  if( isEndLine(opbinput) )
900  {
901  *newsection = TRUE;
902  goto TERMINATE;
903  }
904 
905  /* check if we reached an equation sense */
906  if( isSense(opbinput, NULL) )
907  {
908  /* put the sense back onto the token stack */
909  pushToken(opbinput);
910  goto TERMINATE;
911  }
912 
913  /* check if we read a sign */
914  if( isSign(opbinput, &coefsign) )
915  {
916  SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", opbinput->linenumber, coefsign);
917  havesign = TRUE;
918  continue;
919  }
920 
921  /* check if we read a value */
922  if( isValue(scip, opbinput, &coef) )
923  {
924  /* coefficients without a sign are treated as "+" */
925  if( (*nlincoefs > 0 || *ntermcoefs > 0 || ntmpcoefs > 0) && !havesign )
926  {
927  coefsign = 1;
928  havesign = TRUE;
929  }
930 
931  SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", opbinput->linenumber, coef, coefsign);
932  if( havevalue )
933  {
934  syntaxError(scip, opbinput, "two consecutive values");
935  goto TERMINATE;
936  }
937  havevalue = TRUE;
938 
939  /* if we read a wbo file, the first line should be something like "soft: <weight>;", where weight is a value or nothing */
940  if( strcmp(name, "soft") == 0 )
941  {
942  assert(ntmpcoefs == 0);
943 
944  tmpcoefs[ntmpcoefs] = coefsign * coef;
945  ++ntmpcoefs;
946  }
947 
948  continue;
949  }
950 
951  /* check if we are reading a soft constraint line, it start with "[<weight>]", where weight is a value */
952  if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && !havesign && !havevalue && strcmp(name, "soft") != 0 && isStartingSoftConstraintWeight(scip, opbinput) )
953  {
954  if( !opbinput->wbo )
955  {
956  SCIPwarningMessage(scip, "Found in line %d a soft constraint, without having read a starting top-cost line.\n", opbinput->linenumber);
957  }
958  haveweightstart = TRUE;
959 
960  continue;
961  }
962  if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && havevalue && haveweightstart && isEndingSoftConstraintWeight(scip, opbinput) )
963  {
964  *weight = coefsign * coef;
965  SCIPdebugMsg(scip, "(line %d) found soft constraint weight: %g\n", opbinput->linenumber, *weight);
966 
967  coefsign = +1;
968  havesign = FALSE;
969  havevalue = FALSE;
970  haveweightend = TRUE;
971  *issoftcons = TRUE;
972 
973  continue;
974  }
975 
976  /* if we read a '[' we should already read a ']', which indicates that we read a soft constraint,
977  * we have a parsing error */
978  if( haveweightstart != haveweightend )
979  {
980  syntaxError(scip, opbinput, "Wrong soft constraint.");
981  goto TERMINATE;
982  }
983 
984  /* if we read the first non-comment line of a wbo file we should never be here */
985  if( strcmp(name, "soft") == 0 )
986  {
987  syntaxError(scip, opbinput, "Wrong soft top cost line.");
988  goto TERMINATE;
989  }
990 
991  /* the token is a variable name: get the corresponding variables (or create a new ones) */
992  SCIP_CALL( getVariableOrTerm(scip, opbinput, &tmpvars, &ntmpvars, &tmpvarssize) );
993 
994  if( ntmpvars > 1 )
995  {
996  /* insert non-linear term */
997  *isNonlinear = TRUE;
998 
999  SCIPdebugMsg(scip, "(line %d) found linear term: %+g", opbinput->linenumber, coefsign * coef);
1000 #ifndef NDEBUG
1001  {
1002  int v;
1003  for( v = 0; v < ntmpvars; ++v )
1004  {
1005  SCIPdebugMsgPrint(scip, " %s * ", SCIPvarGetName(tmpvars[v]));
1006  }
1007  SCIPdebugMsgPrint(scip, "\n");
1008  }
1009 #endif
1010  if( !SCIPisZero(scip, coef) )
1011  {
1012  assert(*ntermcoefs <= termcoefssize);
1013  /* resize the terms, ntermvars, and termcoefs array if needed */
1014  if( *ntermcoefs == termcoefssize )
1015  {
1016  termcoefssize = SCIPcalcMemGrowSize(scip, termcoefssize + 1);
1017  SCIP_CALL( SCIPreallocBufferArray(scip, terms, termcoefssize) );
1018  SCIP_CALL( SCIPreallocBufferArray(scip, termcoefs, termcoefssize) );
1019  SCIP_CALL( SCIPreallocBufferArray(scip, ntermvars, termcoefssize) );
1020  }
1021  assert(*ntermcoefs < termcoefssize);
1022 
1023  /* get memory for the last term */
1024  SCIP_CALL( SCIPallocBufferArray(scip, &((*terms)[*ntermcoefs]), ntmpvars) ); /*lint !e866 */
1025 
1026  /* set the number of variable in this term */
1027  (*ntermvars)[*ntermcoefs] = ntmpvars;
1028 
1029  /* add all variables */
1030  for( --ntmpvars; ntmpvars >= 0; --ntmpvars )
1031  {
1032  (*terms)[*ntermcoefs][ntmpvars] = tmpvars[ntmpvars];
1033  }
1034  /* add coefficient */
1035  (*termcoefs)[*ntermcoefs] = coefsign * coef;
1036 
1037  /***********************/
1038  if( !SCIPisIntegral(scip, (*termcoefs)[*ntermcoefs]) )
1039  {
1040  SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*termcoefs)[*ntermcoefs], opbinput->linenumber);
1041  }
1042 
1043  ++(*ntermcoefs);
1044  }
1045 
1046  /* reset the flags and coefficient value for the next coefficient */
1047  coefsign = +1;
1048  coef = 1.0;
1049  havesign = FALSE;
1050  havevalue = FALSE;
1051  ntmpvars = 0;
1052  }
1053  else
1054  {
1055  assert(ntmpvars == 1);
1056  /* insert linear term */
1057  SCIPdebugMsg(scip, "(line %d) found linear term: %+g<%s>\n", opbinput->linenumber, coefsign * coef, SCIPvarGetName(tmpvars[0]));
1058  if( !SCIPisZero(scip, coef) )
1059  {
1060  assert(*nlincoefs <= lincoefssize);
1061  /* resize the vars and coefs array if needed */
1062  if( *nlincoefs >= lincoefssize )
1063  {
1064  lincoefssize = SCIPcalcMemGrowSize(scip, lincoefssize + 1);
1065  SCIP_CALL( SCIPreallocBufferArray(scip, linvars, lincoefssize) );
1066  SCIP_CALL( SCIPreallocBufferArray(scip, lincoefs, lincoefssize) );
1067  }
1068  assert(*nlincoefs < lincoefssize);
1069 
1070  /* add coefficient */
1071  (*linvars)[*nlincoefs] = tmpvars[0];
1072  (*lincoefs)[*nlincoefs] = coefsign * coef;
1073 
1074  /***********************/
1075  if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
1076  {
1077  SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*lincoefs)[*nlincoefs], opbinput->linenumber);
1078  }
1079 
1080  ++(*nlincoefs);
1081  }
1082 
1083  /* reset the flags and coefficient value for the next coefficient */
1084  coefsign = +1;
1085  coef = 1.0;
1086  havesign = FALSE;
1087  havevalue = FALSE;
1088  ntmpvars = 0;
1089  }
1090  }
1091 
1092  TERMINATE:
1093  if( !opbinput->haserror )
1094  {
1095  /* all variables should be in the right arrays */
1096  assert(ntmpvars == 0);
1097  /* the following is only the case if we read topcost's of a wbo file, we need to move this topcost value to the
1098  * right array */
1099  if( ntmpcoefs > 0 )
1100  {
1101  /* maximal one topcost value is possible */
1102  assert(ntmpcoefs == 1);
1103  /* no other coefficient should be found here */
1104  assert(*nlincoefs == 0 && *ntermcoefs == 0);
1105 
1106  /* copy value */
1107  (*lincoefs)[*nlincoefs] = tmpcoefs[0];
1108 
1109  /***********************/
1110  if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
1111  {
1112  SCIPwarningMessage(scip, "topcost not integral.\n");
1113  }
1114 
1115  *nlincoefs = 1;
1116  }
1117  }
1118  /* clear memory */
1119  SCIPfreeBufferArray(scip, &tmpcoefs);
1120  SCIPfreeBufferArray(scip, &tmpvars);
1121 
1122  return SCIP_OKAY;
1123 }
1124 
1125 /** set the objective section */
1126 static
1128  SCIP*const scip, /**< SCIP data structure */
1129  OPBINPUT*const opbinput, /**< OPB reading data */
1130  const char* sense, /**< objective sense */
1131  SCIP_VAR**const linvars, /**< array of linear variables */
1132  SCIP_Real*const coefs, /**< array of objective values for linear variables */
1133  int const ncoefs, /**< number of coefficients for linear part */
1134  SCIP_VAR***const terms, /**< array with nonlinear variables */
1135  SCIP_Real*const termcoefs, /**< array of objective values for nonlinear variables */
1136  int*const ntermvars, /**< number of nonlinear variables in the terms */
1137  int const ntermcoefs /**< number of nonlinear coefficients */
1138  )
1139 {
1140  assert(scip != NULL);
1141  assert(opbinput != NULL);
1142  assert(isEndLine(opbinput));
1143  assert(ncoefs == 0 || (linvars != NULL && coefs != NULL));
1144  assert(ntermcoefs == 0 || (terms != NULL && ntermvars != NULL && termcoefs != NULL));
1145 
1146  if( !hasError(opbinput) )
1147  {
1148  SCIP_VAR* var;
1149  int v;
1150  char name[SCIP_MAXSTRLEN];
1151 
1152  if( strcmp(sense, "max" ) == 0 )
1153  opbinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
1154 
1155  /* @todo: what todo with non-linear objectives, maybe create the necessary and-constraints and add the arising linear
1156  * objective (with and-resultants) or add a integer variable to this constraint and put only this variable in the
1157  * objective, for this we need to expand the pseudo-boolean constraints to handle integer variables
1158  *
1159  * integer variant is not implemented
1160  */
1161  if( ntermcoefs > 0 )
1162  {
1163 #if (LINEAROBJECTIVE == TRUE)
1164  /* all non-linear parts are created as and-constraints, even if the same non-linear part was already part of the objective function */
1165 
1166  SCIP_VAR** vars;
1167  int nvars;
1168  int t;
1169  SCIP_CONS* andcons;
1170 
1171  for( t = 0; t < ntermcoefs; ++t )
1172  {
1173  assert(terms != NULL); /* for lint */
1174  assert(ntermvars != NULL);
1175  assert(termcoefs != NULL);
1176 
1177  vars = terms[t];
1178  nvars = ntermvars[t];
1179  assert(vars != NULL);
1180  assert(nvars > 1);
1181 
1182  /* create auxiliary variable */
1183  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"obj_%d", t);
1184  SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, 1.0, termcoefs[t], SCIP_VARTYPE_BINARY,
1185  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1186 
1187  /* @todo: check if it is better to change the branching priority for the artificial variables */
1188 #if 1
1189  /* change branching priority of artificial variable to -1 */
1190  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1191 #endif
1192 
1193  /* add auxiliary variable to the problem */
1194  SCIP_CALL( SCIPaddVar(scip, var) );
1195 
1196 #ifdef WITH_DEBUG_SOLUTION
1197  if( SCIPdebugIsMainscip(scip) )
1198  {
1199  SCIP_Real val = 0.0;
1200 
1201  for( v = nvars - 1; v >= 0; --v )
1202  {
1203  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1204  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1205 
1206  if( val < 0.5 )
1207  break;
1208  }
1209  SCIP_CALL( SCIPdebugAddSolVal(scip, var, (val < 0.5) ? 0.0 : 1.0) );
1210  }
1211 #endif
1212 
1213  /* @todo: check whether all constraint creation flags are the best option */
1214  /* create and-constraint */
1215  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "obj_andcons_%d", t);
1216  SCIP_CALL( SCIPcreateConsAnd(scip, &andcons, name, var, nvars, vars,
1217  TRUE, TRUE, TRUE, TRUE, TRUE,
1218  FALSE, FALSE, FALSE, FALSE, FALSE) );
1219  SCIP_CALL( SCIPaddCons(scip, andcons) );
1220  SCIPdebugPrintCons(scip, andcons, NULL);
1221  SCIP_CALL( SCIPreleaseCons(scip, &andcons) );
1222 
1223  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1224  }
1225 #else /* now the integer variant */
1226  SCIP_CONS* pseudocons;
1227  SCIP_Real lb;
1228  SCIP_Real ub;
1229 
1230  lb = 0.0;
1231  ub = 0.0;
1232 
1233  /* add all non linear coefficients up */
1234  for( v = 0; v < ntermcoefs; ++v )
1235  {
1236  if( termcoefs[v] < 0 )
1237  lb += termcoefs[v];
1238  else
1239  ub += termcoefs[v];
1240  }
1241  /* add all linear coefficients up */
1242  for( v = 0; v < ncoefs; ++v )
1243  {
1244  if( coefs[v] < 0 )
1245  lb += coefs[v];
1246  else
1247  ub += coefs[v];
1248  }
1249  assert(lb < ub);
1250 
1251  /* create auxiliary variable */
1252  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_int_obj");
1253  SCIP_CALL( SCIPcreateVar(scip, &var, name, lb, ub, 1.0, SCIP_VARTYPE_INTEGER,
1254  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1255 
1256  /* @todo: check if it is better to change the branching priority for the artificial variables */
1257 #if 1
1258  /* change branching priority of artificial variable to -1 */
1259  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1260 #endif
1261  /* add auxiliary variable to the problem */
1262  SCIP_CALL( SCIPaddVar(scip, var) );
1263 
1264 #ifdef WITH_DEBUG_SOLUTION
1265  if( SCIPdebugIsMainscip(scip) )
1266  {
1267  SCIP_Real artval = 0.0;
1268  SCIP_Real val;
1269 
1270  for( t = 0; t < ntermcoefs; ++t )
1271  {
1272  vars = terms[t];
1273  nvars = ntermvars[t];
1274  assert(vars != NULL);
1275  assert(nvars > 1);
1276 
1277  for( v = nvars - 1; v >= 0; --v )
1278  {
1279  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1280  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1281 
1282  if( val < 0.5 )
1283  break;
1284  }
1285 
1286  artval += (((val < 0.5) ? 0.0 : 1.0) * termcoefs[t]);
1287  }
1288  assert(SCIPisFeasLE(scip, lb, artval) && SCIPisFeasGE(scip, ub, artval));
1289 
1290  SCIP_CALL( SCIPdebugAddSolVal(scip, var, artval) );
1291  }
1292 #endif
1293 
1294  /* create artificial objection function constraint containing the artificial integer variable */
1295  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_obj_cons");
1296  SCIP_CALL( SCIPcreateConsPseudoboolean(scip, &pseudocons, name, linvars, ncoefs, coefs, terms, ntermcoefs,
1297  ntermvars, termcoefs, NULL, 0.0, FALSE, var, 0.0, 0.0,
1298  TRUE, TRUE, TRUE, TRUE, TRUE,
1299  FALSE, FALSE, FALSE, FALSE, FALSE) );
1300 
1301  SCIP_CALL( SCIPaddCons(scip, pseudocons) );
1302  SCIPdebugPrintCons(scip, pseudocons, NULL);
1303  SCIP_CALL( SCIPreleaseCons(scip, &pseudocons) );
1304 
1305  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1306 
1307  return SCIP_OKAY;
1308 #endif
1309  }
1310  /* set the objective values */
1311  for( v = 0; v < ncoefs; ++v )
1312  {
1313  assert(linvars != NULL); /* for lint */
1314  assert(coefs != NULL);
1315 
1316  if( SCIPvarIsNegated(linvars[v]) )
1317  {
1318  SCIP_VAR* negvar = SCIPvarGetNegationVar(linvars[v]);
1319 
1320  SCIP_CALL( SCIPaddOrigObjoffset(scip, coefs[v]) );
1321  SCIP_CALL( SCIPchgVarObj(scip, negvar, SCIPvarGetObj(negvar) - coefs[v]) );
1322  }
1323  else
1324  {
1325  SCIP_CALL( SCIPchgVarObj(scip, linvars[v], SCIPvarGetObj(linvars[v]) + coefs[v]) );
1326  }
1327  }
1328  }
1329 
1330  return SCIP_OKAY;
1331 }
1332 
1333 /** reads the constraints section */
1334 static
1336  SCIP* scip, /**< SCIP data structure */
1337  OPBINPUT* opbinput, /**< OPB reading data */
1338  int* nNonlinearConss /**< pointer to store number of nonlinear constraints */
1339  )
1340 {
1341  char name[OPB_MAX_LINELEN];
1342  SCIP_CONS* cons;
1343  SCIP_VAR** linvars;
1344  SCIP_Real* lincoefs;
1345  int nlincoefs;
1346  SCIP_VAR*** terms;
1347  SCIP_Real* termcoefs;
1348  int* ntermvars;
1349  int ntermcoefs;
1350  OPBSENSE sense;
1351  SCIP_RETCODE retcode;
1352  SCIP_Real sidevalue;
1353  SCIP_Real lhs;
1354  SCIP_Real rhs;
1355  SCIP_Bool newsection;
1356  SCIP_Bool initialconss;
1357  SCIP_Bool dynamicconss;
1358  SCIP_Bool dynamicrows;
1359  SCIP_Bool initial;
1360  SCIP_Bool separate;
1361  SCIP_Bool enforce;
1362  SCIP_Bool check;
1363  SCIP_Bool propagate;
1364  SCIP_Bool local;
1365  SCIP_Bool modifiable;
1366  SCIP_Bool dynamic;
1367  SCIP_Bool removable;
1368  SCIP_Bool isNonlinear;
1369  int sidesign;
1370  SCIP_Bool issoftcons;
1371  SCIP_Real weight;
1372  SCIP_VAR* indvar;
1373  char indname[SCIP_MAXSTRLEN];
1374  int t;
1375 
1376  assert(scip != NULL);
1377  assert(opbinput != NULL);
1378  assert(nNonlinearConss != NULL);
1379 
1380  weight = -SCIPinfinity(scip);
1381  retcode = SCIP_OKAY;
1382 
1383  /* read the objective coefficients */
1384  SCIP_CALL( readCoefficients(scip, opbinput, name, &linvars, &lincoefs, &nlincoefs, &terms, &termcoefs, &ntermvars, &ntermcoefs, &newsection, &isNonlinear, &issoftcons, &weight) );
1385 
1386  if( hasError(opbinput) || opbinput->eof )
1387  goto TERMINATE;
1388  if( newsection )
1389  {
1390  if( strcmp(name, "min") == 0 || strcmp(name, "max") == 0 )
1391  {
1392  if( opbinput->wbo )
1393  {
1394  syntaxError(scip, opbinput, "Cannot have an objective function when having soft constraints.\n");
1395  goto TERMINATE;
1396  }
1397 
1398  /* set objective function */
1399  SCIP_CALL( setObjective(scip, opbinput, name, linvars, lincoefs, nlincoefs, terms, termcoefs, ntermvars, ntermcoefs) );
1400  }
1401  else if( strcmp(name, "soft") == 0 )
1402  {
1403  /* we have a "weighted boolean optimization"-file(wbo) */
1404  opbinput->wbo = TRUE;
1405  if( nlincoefs == 0 )
1406  opbinput->topcost = SCIPinfinity(scip);
1407  else
1408  {
1409  assert(nlincoefs == 1);
1410  assert(lincoefs != NULL);
1411  opbinput->topcost = lincoefs[0];
1412  }
1413  SCIPdebugMsg(scip, "Weighted Boolean Optimization problem has topcost of %g\n", opbinput->topcost);
1414  }
1415  else if( nlincoefs > 0 )
1416  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='");
1417  goto TERMINATE;
1418  }
1419 
1420  /* read the constraint sense */
1421  if( !getNextToken(scip, opbinput) )
1422  {
1423  syntaxError(scip, opbinput, "expected constraint sense.");
1424  goto TERMINATE;
1425  }
1426  if( !isSense(opbinput, &sense) )
1427  {
1428  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='.");
1429  goto TERMINATE;
1430  }
1431 
1432  /* read the right hand side */
1433  sidesign = +1;
1434  if( !getNextToken(scip, opbinput) )
1435  {
1436  syntaxError(scip, opbinput, "missing right hand side");
1437  goto TERMINATE;
1438  }
1439  if( isSign(opbinput, &sidesign) )
1440  {
1441  if( !getNextToken(scip, opbinput) )
1442  {
1443  syntaxError(scip, opbinput, "missing value of right hand side");
1444  goto TERMINATE;
1445  }
1446  }
1447  if( !isValue(scip, opbinput, &sidevalue) )
1448  {
1449  syntaxError(scip, opbinput, "expected value as right hand side");
1450  goto TERMINATE;
1451  }
1452  sidevalue *= sidesign;
1453 
1454  /* check if we reached the line end */
1455  if( !getNextToken(scip, opbinput) || !isEndLine(opbinput) )
1456  {
1457  syntaxError(scip, opbinput, "expected endline character ';'");
1458  goto TERMINATE;
1459  }
1460 
1461  /* assign the left and right hand side, depending on the constraint sense */
1462  switch( sense ) /*lint !e530*/
1463  {
1464  case OPB_SENSE_GE:
1465  lhs = sidevalue;
1466  rhs = SCIPinfinity(scip);
1467  break;
1468  case OPB_SENSE_LE:
1469  lhs = -SCIPinfinity(scip);
1470  rhs = sidevalue;
1471  break;
1472  case OPB_SENSE_EQ:
1473  lhs = sidevalue;
1474  rhs = sidevalue;
1475  break;
1476  case OPB_SENSE_NOTHING:
1477  default:
1478  SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1479  return SCIP_INVALIDDATA;
1480  }
1481 
1482  /* create and add the linear constraint */
1483  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
1484  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
1485  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/dynamicconss", &dynamicconss) );
1486 
1487  initial = initialconss;
1488  separate = TRUE;
1489  enforce = TRUE;
1490  check = TRUE;
1491  propagate = TRUE;
1492  local = FALSE;
1493  modifiable = FALSE;
1494  dynamic = FALSE;/*dynamicconss;*/
1495  removable = dynamicrows;
1496 
1497  /* create corresponding constraint */
1498  if( issoftcons )
1499  {
1500  (void) SCIPsnprintf(indname, SCIP_MAXSTRLEN, INDICATORVARNAME"%d", opbinput->nindvars);
1501  ++(opbinput->nindvars);
1502  SCIP_CALL( createVariable(scip, &indvar, indname) );
1503 
1504  assert(!SCIPisInfinity(scip, -weight));
1505  SCIP_CALL( SCIPchgVarObj(scip, indvar, weight) );
1506  }
1507  else
1508  indvar = NULL;
1509 
1510  if( ntermcoefs > 0 || issoftcons )
1511  {
1512 #if GENCONSNAMES == TRUE
1513  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean%d", opbinput->consnumber);
1514  ++(opbinput->consnumber);
1515 #else
1516  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean");
1517 #endif
1518  retcode = SCIPcreateConsPseudoboolean(scip, &cons, name, linvars, nlincoefs, lincoefs, terms, ntermcoefs,
1519  ntermvars, termcoefs, indvar, weight, issoftcons, NULL, lhs, rhs,
1520  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1521  if( retcode != SCIP_OKAY )
1522  goto TERMINATE;
1523  }
1524  else
1525  {
1526 #if GENCONSNAMES == TRUE
1527  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear%d", opbinput->consnumber);
1528  ++(opbinput->consnumber);
1529 #else
1530  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear");
1531 #endif
1532  retcode = SCIPcreateConsLinear(scip, &cons, name, nlincoefs, linvars, lincoefs, lhs, rhs,
1533  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1534  if( retcode != SCIP_OKAY )
1535  goto TERMINATE;
1536  }
1537 
1538  SCIP_CALL( SCIPaddCons(scip, cons) );
1539  SCIPdebugMsg(scip, "(line %d) created constraint: ", opbinput->linenumber);
1540  SCIPdebugPrintCons(scip, cons, NULL);
1541  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1542 
1543  if( isNonlinear )
1544  ++(*nNonlinearConss);
1545 
1546  TERMINATE:
1547 
1548  /* free memory */
1549  for( t = ntermcoefs - 1; t >= 0; --t )
1550  {
1551  assert(terms != NULL); /* for lint */
1552  SCIPfreeBufferArrayNull(scip, &(terms[t]));
1553  }
1554 
1555  SCIPfreeBufferArrayNull(scip, &ntermvars);
1556  SCIPfreeBufferArrayNull(scip, &termcoefs);
1557  SCIPfreeBufferArrayNull(scip, &terms);
1558  SCIPfreeBufferArrayNull(scip, &lincoefs);
1559  SCIPfreeBufferArrayNull(scip, &linvars);
1560 
1561  SCIP_CALL( retcode );
1562 
1563  return SCIP_OKAY;
1564 }
1565 
1566 /** tries to read the first comment line which usually contains information about the max size of "and" products */
1567 static
1569  SCIP* scip, /**< SCIP data structure */
1570  OPBINPUT* opbinput, /**< OPB reading data */
1571  SCIP_Real* objoffset /**< pointer to store objective offset */
1572  )
1573 {
1574  SCIP_Bool stop;
1575  char* commentstart;
1576  char* nproducts;
1577  char* str;
1578  int i;
1579 
1580  assert(scip != NULL);
1581  assert(opbinput != NULL);
1582  assert(objoffset != NULL);
1583 
1584  stop = FALSE;
1585  commentstart = NULL;
1586  nproducts = NULL;
1587 
1588  *objoffset = 0.0;
1589  opbinput->linebuf[opbinput->linebufsize - 2] = '\0';
1590 
1591  do
1592  {
1593  if( SCIPfgets(opbinput->linebuf, opbinput->linebufsize, opbinput->file) == NULL )
1594  {
1595  assert( SCIPfeof(opbinput->file) );
1596  break;
1597  }
1598 
1599  /* if line is too long for our buffer reallocate buffer */
1600  while( opbinput->linebuf[opbinput->linebufsize - 2] != '\0' )
1601  {
1602  int newsize;
1603 
1604  newsize = SCIPcalcMemGrowSize(scip, opbinput->linebufsize + 1);
1605  SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &opbinput->linebuf, opbinput->linebufsize, newsize) );
1606 
1607  opbinput->linebuf[newsize-2] = '\0';
1608  if ( SCIPfgets(opbinput->linebuf + opbinput->linebufsize - 1, newsize - opbinput->linebufsize + 1, opbinput->file) == NULL )
1609  return SCIP_READERROR;
1610  opbinput->linebufsize = newsize;
1611  }
1612  opbinput->linebuf[opbinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
1613 
1614 
1615  /* read characters after comment symbol */
1616  for( i = 0; commentchars[i] != '\0'; ++i )
1617  {
1618  commentstart = strchr(opbinput->linebuf, commentchars[i]);
1619 
1620  /* found a comment line */
1621  if( commentstart != NULL )
1622  {
1623  /* search for "#product= xyz" in comment line, where xyz represents the number of and constraints */
1624  nproducts = strstr(opbinput->linebuf, "#product= ");
1625  if( nproducts != NULL )
1626  {
1627  const char delimchars[] = " \t";
1628  char* pos;
1629 
1630  nproducts += strlen("#product= ");
1631 
1632  pos = strtok(nproducts, delimchars);
1633 
1634  if( pos != NULL )
1635  {
1636  SCIPdebugMsg(scip, "%d products supposed to be in file.\n", atoi(pos));
1637  }
1638 
1639  pos = strtok (NULL, delimchars);
1640 
1641  if( pos != NULL && strcmp(pos, "sizeproduct=") == 0 )
1642  {
1643  pos = strtok (NULL, delimchars);
1644  if( pos != NULL )
1645  {
1646  SCIPdebugMsg(scip, "sizeproducts = %d\n", atoi(pos));
1647  }
1648  }
1649 
1650  stop = TRUE;
1651  }
1652 
1653  /* search for "Obj. offset : <number>" in comment line */
1654  str = strstr(opbinput->linebuf, "Obj. offset : ");
1655  if( str != NULL )
1656  {
1657  str += strlen("Obj. offset : ");
1658  *objoffset = atof(str);
1659  break;
1660  }
1661 
1662  /* make sure that comment vanishes */
1663  *commentstart = '\0';
1664 
1665  break;
1666  }
1667  }
1668  }
1669  while(commentstart != NULL && !stop);
1670 
1671  return SCIP_OKAY;
1672 }
1673 
1674 /** reads an OPB file */
1675 static
1677  SCIP* scip, /**< SCIP data structure */
1678  OPBINPUT* opbinput, /**< OPB reading data */
1679  const char* filename /**< name of the input file */
1680  )
1681 {
1682  SCIP_Real objoffset;
1683  int nNonlinearConss;
1684  int i;
1685 
1686  assert(scip != NULL);
1687  assert(opbinput != NULL);
1688 
1689  /* open file */
1690  opbinput->file = SCIPfopen(filename, "r");
1691  if( opbinput->file == NULL )
1692  {
1693  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
1694  SCIPprintSysError(filename);
1695  return SCIP_NOFILE;
1696  }
1697 
1698  /* @todo: reading additional information about the number of and constraints in comments to avoid reallocating
1699  * "opbinput.andconss"
1700  */
1701 
1702  /* tries to read the first comment line which usually contains information about the max size of "and" products */
1703  SCIP_CALL( getMaxAndConsDim(scip, opbinput, &objoffset) );
1704 
1705  /* create problem */
1706  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1707 
1708  if( ! SCIPisZero(scip, objoffset) )
1709  {
1710  SCIP_CALL( SCIPaddOrigObjoffset(scip, objoffset) );
1711  }
1712 
1713  nNonlinearConss = 0;
1714 
1715  while( !SCIPfeof( opbinput->file ) && !hasError(opbinput) )
1716  {
1717  SCIP_CALL( readConstraints(scip, opbinput, &nNonlinearConss) );
1718  }
1719 
1720  /* if we read a wbo file we need to make sure that the top cost won't be exceeded */
1721  if( opbinput->wbo )
1722  {
1723  SCIP_VAR** topcostvars;
1724  SCIP_Real* topcosts;
1725  SCIP_VAR** vars;
1726  int nvars;
1727  int ntopcostvars;
1728  SCIP_Longint topcostrhs;
1729  SCIP_CONS* topcostcons;
1730 
1731  nvars = SCIPgetNVars(scip);
1732  vars = SCIPgetVars(scip);
1733  assert(nvars > 0 || vars != NULL);
1734 
1735  SCIP_CALL( SCIPallocBufferArray(scip, &topcostvars, nvars) );
1736  SCIP_CALL( SCIPallocBufferArray(scip, &topcosts, nvars) );
1737 
1738  ntopcostvars = 0;
1739  for( i = nvars - 1; i >= 0; --i )
1740  if( !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
1741  {
1742  topcostvars[ntopcostvars] = vars[i];
1743  topcosts[ntopcostvars] = SCIPvarGetObj(vars[i]);
1744  ++ntopcostvars;
1745  }
1746 
1747  if( SCIPisIntegral(scip, opbinput->topcost) )
1748  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost - 1);
1749  else
1750  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost);
1751 
1752  SCIP_CALL( SCIPcreateConsLinear(scip, &topcostcons, TOPCOSTCONSNAME, ntopcostvars, topcostvars, topcosts, -SCIPinfinity(scip),
1753  (SCIP_Real) topcostrhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1754  SCIP_CALL( SCIPaddCons(scip, topcostcons) );
1755  SCIPdebugPrintCons(scip, topcostcons, NULL);
1756  SCIP_CALL( SCIPreleaseCons(scip, &topcostcons) );
1757 
1758  SCIPfreeBufferArray(scip, &topcosts);
1759  SCIPfreeBufferArray(scip, &topcostvars);
1760  }
1761 
1762  /* close file */
1763  SCIPfclose(opbinput->file);
1764 
1765  return SCIP_OKAY;
1766 }
1767 
1768 
1769 /*
1770  * Local methods (for writing)
1771  */
1772 
1773 /** transforms given and constraint variables to the corresponding active or negated variables */
1774 static
1776  SCIP*const scip, /**< SCIP data structure */
1777  SCIP_VAR**const vars, /**< vars array to get active variables for */
1778  int const nvars, /**< pointer to number of variables and values in vars and vals array */
1779  SCIP_Bool const transformed /**< transformed constraint? */
1780  )
1781 {
1782  SCIP_Bool negated;
1783  int v;
1784 
1785  assert( scip != NULL );
1786  assert( vars != NULL );
1787  assert( nvars > 0 );
1788 
1789  if( transformed )
1790  {
1791  for( v = nvars - 1; v >= 0; --v )
1792  {
1793  /* gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1794  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1795  */
1796  SCIP_CALL( SCIPgetBinvarRepresentative( scip, vars[v], &vars[v], &negated) );
1797  }
1798  }
1799  else
1800  {
1801  SCIP_Real scalar;
1802  SCIP_Real constant;
1803 
1804  for( v = nvars - 1; v >= 0; --v )
1805  {
1806  scalar = 1.0;
1807  constant = 0.0;
1808 
1809  /* retransforms given variable, scalar and constant to the corresponding original variable, scalar and constant,
1810  * if possible; if the retransformation is impossible, NULL is returned as variable
1811  */
1812  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalar, &constant) );
1813 
1814  if( vars[v] == NULL )
1815  {
1816  SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable.\n");
1817  return SCIP_INVALIDDATA;
1818  }
1819  if( SCIPisEQ(scip, scalar, -1.0) && SCIPisEQ(scip, constant, 1.0) )
1820  {
1821  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &vars[v]) );
1822  }
1823  else
1824  {
1825  if( !SCIPisEQ(scip, scalar, 1.0) || !SCIPisZero(scip, constant) )
1826  {
1827  SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable or a negated variable of an original variable (scalar = %g, constant = %g).\n", scalar, constant);
1828  return SCIP_INVALIDDATA;
1829  }
1830  }
1831  }
1832  }
1833 
1834  return SCIP_OKAY;
1835 }
1836 
1837 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
1838 static
1840  SCIP* scip, /**< SCIP data structure */
1841  SCIP_VAR** vars, /**< vars array to get active variables for */
1842  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
1843  int* nvars, /**< pointer to number of variables and values in vars and vals array */
1844  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
1845  SCIP_Bool transformed /**< transformed constraint? */
1846  )
1847 {
1848  int requiredsize;
1849  int v;
1850 
1851  assert(scip != NULL);
1852  assert(vars != NULL);
1853  assert(scalars != NULL);
1854  assert(nvars != NULL);
1855  assert(constant != NULL);
1856 
1857  if( transformed )
1858  {
1859  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
1860 
1861  if( requiredsize > *nvars )
1862  {
1863  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
1864  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
1865 
1866  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
1867  assert( requiredsize <= *nvars );
1868  }
1869  }
1870  else
1871  for( v = 0; v < *nvars; ++v )
1872  {
1873  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
1874 
1875  if( vars[v] == NULL )
1876  return SCIP_INVALIDDATA;
1877  }
1878 
1879  return SCIP_OKAY;
1880 }
1881 
1882 /* computes all and-resultants and their corresponding constraint variables */
1883 static
1885  SCIP*const scip, /**< SCIP data structure */
1886  SCIP_Bool const transformed, /**< transformed problem? */
1887  SCIP_VAR*** resvars, /**< pointer to store all resultant variables */
1888  int* nresvars, /**< pointer to store the number of all resultant variables */
1889  SCIP_VAR**** andvars, /**< pointer to store to all resultant variables their corresponding active( or negated) and-constraint variables */
1890  int** nandvars, /**< pointer to store the number of all corresponding and-variables to their corresponding resultant variable */
1891  SCIP_Bool*const existandconshdlr, /**< pointer to store whether the and-constrainthandler exists*/
1892  SCIP_Bool*const existands /**< pointer to store if their exists some and-constraints */
1893  )
1894 {
1895  SCIP_CONSHDLR* conshdlr;
1896 
1897  assert(scip != NULL);
1898  assert(resvars != NULL);
1899  assert(nresvars != NULL);
1900  assert(andvars != NULL);
1901  assert(nandvars != NULL);
1902  assert(existandconshdlr != NULL);
1903  assert(existands != NULL);
1904 
1905  *resvars = NULL;
1906  *nandvars = NULL;
1907  *andvars = NULL;
1908  *nresvars = 0;
1909 
1910  /* detect all and-resultants */
1911  conshdlr = SCIPfindConshdlr(scip, "and");
1912  if( conshdlr != NULL )
1913  {
1914  SCIP_CONS** andconss;
1915  int nandconss;
1916  int* shouldnotbeinand;
1917  int a;
1918  int c;
1919  int r;
1920  int v;
1921  int pos;
1922  int ncontainedands;
1923 
1924  andconss = NULL;
1925  nandconss = 0;
1926  *existandconshdlr = TRUE;
1927 
1928  /* if we write the original problem we need to get the original and constraints */
1929  if( !transformed )
1930  {
1931  SCIP_CONS** origconss;
1932  int norigconss;
1933 
1934  origconss = SCIPgetOrigConss(scip);
1935  norigconss = SCIPgetNOrigConss(scip);
1936 
1937  /* allocate memory for all possible and-constraints */
1938  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, norigconss) );
1939 
1940  /* collect all original and-constraints */
1941  for( c = norigconss - 1; c >= 0; --c )
1942  {
1943  conshdlr = SCIPconsGetHdlr(origconss[c]);
1944  assert( conshdlr != NULL );
1945 
1946  if( strcmp(SCIPconshdlrGetName(conshdlr), "and") == 0 )
1947  {
1948  andconss[nandconss] = origconss[c];
1949  ++nandconss;
1950  }
1951  }
1952  }
1953  else
1954  {
1955  nandconss = SCIPconshdlrGetNConss(conshdlr);
1956  andconss = SCIPconshdlrGetConss(conshdlr);
1957  }
1958 
1959  assert(andconss != NULL || nandconss == 0);
1960 
1961  *nresvars = nandconss;
1962 
1963  if( nandconss > 0 )
1964  {
1965  *existands = TRUE;
1966 
1967  assert(andconss != NULL);
1968 
1969  SCIP_CALL( SCIPallocMemoryArray(scip, resvars, *nresvars) );
1970  SCIP_CALL( SCIPallocMemoryArray(scip, andvars, *nresvars) );
1971  SCIP_CALL( SCIPallocMemoryArray(scip, nandvars, *nresvars) );
1972 
1973  /* collect all and-constraint variables */
1974  for( c = nandconss - 1; c >= 0; --c )
1975  {
1976  SCIP_VAR** scipandvars;
1977 
1978  assert(andconss[c] != NULL);
1979 
1980  scipandvars = SCIPgetVarsAnd(scip, andconss[c]);
1981  (*nandvars)[c] = SCIPgetNVarsAnd(scip, andconss[c]);
1982  SCIP_CALL( SCIPduplicateMemoryArray(scip, &((*andvars)[c]), scipandvars, (*nandvars)[c]) ); /*lint !e866 */
1983  SCIP_CALL( getBinVarsRepresentatives(scip, (*andvars)[c], (*nandvars)[c], transformed) );
1984 
1985  (*resvars)[c] = SCIPgetResultantAnd(scip, andconss[c]);
1986 
1987  assert((*andvars)[c] != NULL && (*nandvars)[c] > 0);
1988  assert((*resvars)[c] != NULL);
1989  }
1990 
1991  /* sorted the array */
1992  SCIPsortPtrPtrInt((void**)(*resvars), (void**)(*andvars), (*nandvars), SCIPvarComp, (*nresvars));
1993  }
1994  else
1995  *existands = FALSE;
1996 
1997  SCIP_CALL( SCIPallocBufferArray(scip, &shouldnotbeinand, *nresvars) );
1998 
1999  /* check that all and-constraints doesn't contain any and-resultants, if they do try to resolve this */
2000  /* attention: if resolving leads to x = x*y*... , we can't do anything here ( this only means (... >=x and) y >= x, so normally the and-constraint needs to be
2001  deleted and the inequality from before needs to be added ) */
2002  assert(*nandvars != NULL || *nresvars == 0);
2003  for( r = *nresvars - 1; r >= 0; --r )
2004  {
2005  ncontainedands = 0;
2006  shouldnotbeinand[ncontainedands] = r;
2007  ++ncontainedands;
2008  v = 0;
2009 
2010  assert(*nandvars != NULL);
2011  while( v < (*nandvars)[r] )
2012  {
2013  assert(*andvars != NULL);
2014  assert(*resvars != NULL);
2015  if( SCIPsortedvecFindPtr((void**)(*resvars), SCIPvarComp, (*andvars)[r][v], *nresvars, &pos) )
2016  {
2017  /* check if the found position "pos" is equal to an already visited and resultant in this constraint,
2018  * than here could exist a directed cycle
2019  */
2020  /* better use tarjan's algorithm
2021  * <http://algowiki.net/wiki/index.php?title=Tarjan%27s_algorithm>,
2022  * <http://en.wikipedia.org/wiki/Tarjan%E2%80%99s_strongly_connected_components_algorithm>
2023  * because it could be that the same resultant is part of this and-constraint and than it would fail
2024  * without no cycle
2025  * Note1: tarjans standard algorithm doesn't find cycle from one node to the same;
2026  * Note2: when tarjan's algorithm find a cycle, it's still possible that this cycle is not "real" e.g.
2027  * y = y ~y z (z can also be a product) where y = 0 follows and therefor only "0 = z" is necessary
2028  */
2029  for( a = ncontainedands - 1; a >= 0; --a )
2030  if( shouldnotbeinand[a] == pos )
2031  {
2032  SCIPwarningMessage(scip, "This should not happen here. The and-constraint with resultant variable: ");
2033  SCIP_CALL( SCIPprintVar(scip, (*resvars)[r], NULL) );
2034  SCIPwarningMessage(scip, "possible contains a loop with and-resultant:");
2035  SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) );
2036 
2037  /* free memory iff necessary */
2038  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2039  if( !transformed )
2040  {
2041  SCIPfreeBufferArray(scip, &andconss);
2042  }
2043  return SCIP_INVALIDDATA;
2044  }
2045  SCIPdebugMsg(scip, "Another and-constraint contains and-resultant:");
2046  SCIPdebug( SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) ) );
2047  SCIPdebugMsg(scip, "Trying to resolve.\n");
2048 
2049  shouldnotbeinand[ncontainedands] = pos;
2050  ++ncontainedands;
2051 
2052  /* try to resolve containing ands */
2053 
2054  /* resize array and number of variables */
2055  (*nandvars)[r] = (*nandvars)[r] + (*nandvars)[pos] - 1;
2056  SCIP_CALL( SCIPreallocMemoryArray(scip, &((*andvars)[r]), (*nandvars)[r]) ); /*lint !e866 */
2057 
2058  /* copy all variables */
2059  for( a = (*nandvars)[pos] - 1; a >= 0; --a )
2060  (*andvars)[r][(*nandvars)[r] - a - 1] = (*andvars)[pos][a];
2061 
2062  /* check same position with new variable, so we do not increase v */
2063  }
2064  else
2065  ++v;
2066  }
2067  }
2068  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2069 
2070  /* free memory iff necessary */
2071  if( !transformed )
2072  {
2073  SCIPfreeBufferArray(scip, &andconss);
2074  }
2075  }
2076  else
2077  {
2078  SCIPdebugMsg(scip, "found no and-constraint-handler\n");
2079  *existands = FALSE;
2080  *existandconshdlr = FALSE;
2081  }
2082 
2083  return SCIP_OKAY;
2084 }
2085 
2086 /** clears the given line buffer */
2087 static
2089  char* linebuffer, /**< line */
2090  int* linecnt /**< number of characters in line */
2091  )
2092 {
2093  assert( linebuffer != NULL );
2094  assert( linecnt != NULL );
2095 
2096  (*linecnt) = 0;
2097  linebuffer[0] = '\0';
2098 }
2099 
2100 
2101 /** ends the given line with '\\0' and prints it to the given file stream */
2102 static
2104  SCIP* scip, /**< SCIP data structure */
2105  FILE* file, /**< output file (or NULL for standard output) */
2106  char* linebuffer, /**< line */
2107  int* linecnt /**< number of characters in line */
2108  )
2109 {
2110  assert( scip != NULL );
2111  assert( linebuffer != NULL );
2112  assert( linecnt != NULL );
2113  assert( 0 <= *linecnt && *linecnt < OPB_MAX_LINELEN );
2114 
2115  if( (*linecnt) > 0 )
2116  {
2117  linebuffer[(*linecnt)] = '\0';
2118  SCIPinfoMessage(scip, file, "%s", linebuffer);
2119  clearBuffer(linebuffer, linecnt);
2120  }
2121 }
2122 
2123 
2124 /** appends extension to line and prints it to the give file stream if the line buffer get full */
2125 static
2127  SCIP* scip, /**< SCIP data structure */
2128  FILE* file, /**< output file (or NULL for standard output) */
2129  char* linebuffer, /**< line buffer */
2130  int* linecnt, /**< number of characters in line */
2131  const char* extension /**< string to extent the line */
2132  )
2133 {
2134  assert(scip != NULL);
2135  assert(linebuffer != NULL);
2136  assert(linecnt != NULL);
2137  assert(extension != NULL);
2138 
2139  if( (*linecnt) + (int) strlen(extension) >= OPB_MAX_LINELEN - 1 )
2140  writeBuffer(scip, file, linebuffer, linecnt);
2141 
2142  /* append extension to linebuffer */
2143  (void) strncat(linebuffer, extension, OPB_MAX_LINELEN - (unsigned int)(*linecnt));
2144  (*linecnt) += (int) strlen(extension);
2145 }
2146 
2147 /** write objective function */
2148 static
2150  SCIP*const scip, /**< SCIP data structure */
2151  FILE*const file, /**< output file, or NULL if standard output should be used */
2152  SCIP_VAR**const vars, /**< array with active (binary) variables */
2153  int const nvars, /**< number of active variables in the problem */
2154  SCIP_VAR** const resvars, /**< array of resultant variables */
2155  int const nresvars, /**< number of resultant variables */
2156  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2157  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2158  SCIP_OBJSENSE const objsense, /**< objective sense */
2159  SCIP_Real const objscale, /**< scalar applied to objective function; external objective value is
2160  * extobj = objsense * objscale * (intobj + objoffset) */
2161  SCIP_Real const objoffset, /**< objective offset from bound shifting and fixing */
2162  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
2163  SCIP_Bool const existands, /**< does some and-constraints exist? */
2164  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
2165  )
2166 {
2167  SCIP_VAR* var;
2168  char linebuffer[OPB_MAX_LINELEN+1];
2169  char buffer[OPB_MAX_LINELEN];
2170  SCIP_Longint mult;
2171  SCIP_Bool objective;
2172  int v;
2173  int linecnt;
2174  int pos;
2175 
2176  assert(scip != NULL);
2177  assert(file != NULL);
2178  assert(vars != NULL || nvars == 0);
2179  assert(resvars != NULL || nresvars == 0);
2180  assert(andvars != NULL || nandvars == NULL);
2181  assert(multisymbol != NULL);
2182 
2183  mult = 1;
2184  objective = FALSE;
2185 
2186  clearBuffer(linebuffer, &linecnt);
2187 
2188  /* check if a objective function exits and compute the multiplier to
2189  * shift the coefficients to integers */
2190  for( v = 0; v < nvars; ++v )
2191  {
2192  var = vars[v]; /*lint !e613 */
2193 
2194 #ifndef NDEBUG
2195  {
2196  /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
2197  if( !transformed )
2198  assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ||
2200  }
2201 #endif
2202 
2203  /* we found a indicator variable so we assume this is a wbo file */
2204  if( strstr(SCIPvarGetName(var), INDICATORVARNAME) != NULL )
2205  {
2206  /* find the topcost linear inequality which gives us the maximal cost which could be violated by our
2207  * solution, which is an artificial constraint and print this at first
2208  *
2209  * @note: only linear constraint handler is enough in problem stage, otherwise it could be any upgraded linear
2210  * constraint which handles pure binary variables
2211  */
2212  SCIP_CONSHDLR* conshdlr;
2213  SCIP_CONS* topcostcons;
2214  SCIP_Bool printed;
2215 
2216  printed = FALSE;
2217  topcostcons = SCIPfindCons(scip, TOPCOSTCONSNAME);
2218 
2219  if( topcostcons != NULL )
2220  {
2221  conshdlr = SCIPconsGetHdlr(topcostcons);
2222  assert(conshdlr != NULL);
2223 
2224  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0 )
2225  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, topcostcons));
2226  else if( strcmp(SCIPconshdlrGetName(conshdlr), "knapsack") == 0 )
2227  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %" SCIP_LONGINT_FORMAT ";\n",
2228  SCIPgetCapacityKnapsack(scip, topcostcons));
2229  else if( strcmp(SCIPconshdlrGetName(conshdlr), "setppc") == 0 )
2230  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2231  else
2232  {
2233  SCIPABORT();
2234  return SCIP_INVALIDDATA; /*lint !e527 */
2235  }
2236  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2237  writeBuffer(scip, file, linebuffer, &linecnt);
2238  printed = TRUE;
2239  }
2240  /* following works only in transformed stage */
2241  else
2242  {
2243  /* first try linear constraints */
2244  conshdlr = SCIPfindConshdlr(scip, "linear");
2245 
2246  if( conshdlr != NULL )
2247  {
2248  SCIP_CONS** conss;
2249  int nconss;
2250  int c;
2251 
2252  conss = SCIPconshdlrGetConss(conshdlr);
2253  nconss = SCIPconshdlrGetNConss(conshdlr);
2254 
2255  assert(conss != NULL || nconss == 0);
2256 
2257  for( c = 0; c < nconss; ++c )
2258  {
2259  SCIP_VAR** linvars;
2260  int nlinvars;
2261  int w;
2262  SCIP_Bool topcostfound;
2263  SCIP_CONS* cons;
2264 
2265  cons = conss[c]; /*lint !e613 */
2266  assert(cons != NULL);
2267 
2268  linvars = SCIPgetVarsLinear(scip, cons);
2269  nlinvars = SCIPgetNVarsLinear(scip, cons);
2270 
2271  assert(linvars != NULL || nlinvars == 0);
2272  topcostfound = FALSE;
2273 
2274  for( w = 0; w < nlinvars; ++w )
2275  {
2276  if( strstr(SCIPvarGetName(linvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2277  topcostfound = TRUE;
2278  else
2279  {
2280  assert(!topcostfound);
2281  topcostfound = FALSE;
2282  }
2283  }
2284 
2285  if( topcostfound )
2286  {
2287  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, cons));
2288  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2289  writeBuffer(scip, file, linebuffer, &linecnt);
2290  printed = TRUE;
2291  break;
2292  }
2293  }
2294  }
2295 
2296  if( !printed )
2297  {
2298  /* second try knapsack constraints */
2299  conshdlr = SCIPfindConshdlr(scip, "knapsack");
2300 
2301  if( conshdlr != NULL )
2302  {
2303  SCIP_CONS** conss;
2304  int nconss;
2305  int c;
2306 
2307  conss = SCIPconshdlrGetConss(conshdlr);
2308  nconss = SCIPconshdlrGetNConss(conshdlr);
2309 
2310  assert(conss != NULL || nconss == 0);
2311 
2312  for( c = 0; c < nconss; ++c )
2313  {
2314  SCIP_VAR** topvars;
2315  int ntopvars;
2316  int w;
2317  SCIP_Bool topcostfound;
2318  SCIP_CONS* cons;
2319 
2320  cons = conss[c]; /*lint !e613 */
2321  assert(cons != NULL);
2322 
2323  topvars = SCIPgetVarsKnapsack(scip, cons);
2324  ntopvars = SCIPgetNVarsKnapsack(scip, cons);
2325 
2326  assert(topvars != NULL || ntopvars == 0);
2327  topcostfound = FALSE;
2328 
2329  for( w = 0; w < ntopvars; ++w )
2330  {
2331  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2332  topcostfound = TRUE;
2333  else
2334  {
2335  assert(!topcostfound);
2336  topcostfound = FALSE;
2337  }
2338  }
2339 
2340  if( topcostfound )
2341  {
2342  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %" SCIP_LONGINT_FORMAT ";\n",
2343  SCIPgetCapacityKnapsack(scip, cons));
2344  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2345  writeBuffer(scip, file, linebuffer, &linecnt);
2346  printed = TRUE;
2347  break;
2348  }
2349  }
2350  }
2351  }
2352 
2353  if( !printed )
2354  {
2355  /* third try setppc constraints */
2356  conshdlr = SCIPfindConshdlr(scip, "setppc");
2357 
2358  if( conshdlr != NULL )
2359  {
2360  SCIP_CONS** conss;
2361  int nconss;
2362  int c;
2363 
2364  conss = SCIPconshdlrGetConss(conshdlr);
2365  nconss = SCIPconshdlrGetNConss(conshdlr);
2366 
2367  assert(conss != NULL || nconss == 0);
2368 
2369  for( c = 0; c < nconss; ++c )
2370  {
2371  SCIP_VAR** topvars;
2372  int ntopvars;
2373  int w;
2374  SCIP_Bool topcostfound;
2375  SCIP_CONS* cons;
2376 
2377  cons = conss[c]; /*lint !e613 */
2378  assert(cons != NULL);
2379 
2380  topvars = SCIPgetVarsSetppc(scip, cons);
2381  ntopvars = SCIPgetNVarsSetppc(scip, cons);
2382 
2383  assert(topvars != NULL || ntopvars == 0);
2384  topcostfound = FALSE;
2385 
2386  for( w = 0; w < ntopvars; ++w )
2387  {
2388  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2389  topcostfound = TRUE;
2390  else
2391  {
2392  assert(!topcostfound);
2393  topcostfound = FALSE;
2394  }
2395  }
2396 
2397  if( topcostfound )
2398  {
2399  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2400  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2401  writeBuffer(scip, file, linebuffer, &linecnt);
2402  printed = TRUE;
2403  break;
2404  }
2405  }
2406  }
2407  }
2408  }
2409 
2410  /* no topcost constraint found, so print empty topcost line, which means there is no upper bound on violated soft constraints */
2411  if( !printed )
2412  {
2413  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: ;\n");
2414  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2415  writeBuffer(scip, file, linebuffer, &linecnt);
2416  }
2417 
2418  return SCIP_OKAY;
2419  }
2420 
2421  if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
2422  {
2423  objective = TRUE;
2424  while( !SCIPisIntegral(scip, SCIPvarGetObj(var) * mult) )
2425  {
2426  assert(mult * 10 > mult);
2427  mult *= 10;
2428  }
2429  }
2430  }
2431 
2432  if( objective )
2433  {
2434  /* there exist a objective function*/
2435  SCIPinfoMessage(scip, file, "* Obj. scale : %.15g\n", objscale * mult);
2436  SCIPinfoMessage(scip, file, "* Obj. offset : %.15g\n", objoffset);
2437 
2438  clearBuffer(linebuffer, &linecnt);
2439 
2440  /* opb format supports only minimization; therefore, a maximization problem has to be converted */
2441  if( objsense == SCIP_OBJSENSE_MAXIMIZE )
2442  mult *= -1;
2443 
2444  SCIPdebugMsg(scip, "print objective function multiplied with %" SCIP_LONGINT_FORMAT "\n", mult);
2445 
2446  appendBuffer(scip, file, linebuffer, &linecnt, "min:");
2447 
2448 #ifndef NDEBUG
2449  if( existands )
2450  {
2451  int c;
2452  /* check that these variables are sorted */
2453  for( c = nresvars - 1; c > 0; --c )
2454  assert(SCIPvarGetIndex(resvars[c]) >= SCIPvarGetIndex(resvars[c - 1])); /*lint !e613 */
2455  }
2456 #endif
2457 
2458  for( v = nvars - 1; v >= 0; --v )
2459  {
2460  SCIP_Bool negated;
2461  var = vars[v]; /*lint !e613 */
2462 
2463  assert(var != NULL);
2464 
2465  if( SCIPisZero(scip, SCIPvarGetObj(var)) )
2466  continue;
2467 
2468  negated = SCIPvarIsNegated(var);
2469 
2470  assert( linecnt != 0 );
2471 
2472  if( SCIPvarGetObj(var) * mult > (SCIP_Real)SCIP_LONGINT_MAX )
2473  {
2474  SCIPerrorMessage("Integral objective value to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", mult, SCIPvarGetObj(var), SCIPvarGetObj(var) * mult, (SCIP_Longint) SCIPround(scip, SCIPvarGetObj(var) * mult));
2475  }
2476 
2477  /* replace and-resultant with corresponding variables */
2478  if( existands && SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2479  {
2480  int a;
2481 
2482  assert(andvars != NULL);
2483  assert(nandvars != NULL);
2484  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2485  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2486 
2487  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2488 
2489  /* print and-vars */
2490  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2491  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "",
2492  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
2493  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2494 
2495  for(a = nandvars[pos] - 2; a >= 0; --a )
2496  {
2497  negated = SCIPvarIsNegated(andvars[pos][a]);
2498 
2499  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2500  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2501  }
2502  }
2503  else
2504  {
2505  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2506  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2507  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2508  }
2509  }
2510 
2511  /* and objective function line ends with a ';' */
2512  appendBuffer(scip, file, linebuffer, &linecnt, " ;\n");
2513  writeBuffer(scip, file, linebuffer, &linecnt);
2514  }
2515 
2516  return SCIP_OKAY;
2517 }
2518 
2519 /* print maybe non linear row in OPB format to file stream */
2520 static
2522  SCIP*const scip, /**< SCIP data structure */
2523  FILE*const file, /**< output file (or NULL for standard output) */
2524  char const*const type, /**< row type ("=" or ">=") */
2525  SCIP_VAR**const vars, /**< array of variables */
2526  SCIP_Real const*const vals, /**< array of values */
2527  int const nvars, /**< number of variables */
2528  SCIP_Real lhs, /**< left hand side */
2529  SCIP_VAR** const resvars, /**< array of resultant variables */
2530  int const nresvars, /**< number of resultant variables */
2531  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2532  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2533  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2534  SCIP_Longint*const mult, /**< multiplier for the coefficients */
2535  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2536  )
2537 {
2538  SCIP_VAR* var;
2539  char buffer[OPB_MAX_LINELEN];
2540  char linebuffer[OPB_MAX_LINELEN + 1];
2541  int v;
2542  int pos;
2543  int linecnt;
2544 
2545  assert(scip != NULL);
2546  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2547  assert(mult != NULL);
2548  assert(resvars != NULL);
2549  assert(nresvars > 0);
2550  assert(andvars != NULL && nandvars != NULL);
2551 
2552  clearBuffer(linebuffer, &linecnt);
2553 
2554  /* check if all coefficients are internal; if not commentstart multiplier */
2555  for( v = 0; v < nvars; ++v )
2556  {
2557  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2558  {
2559  if( ABS(*mult) > ABS(*mult * 10) )
2560  return SCIP_INVALIDDATA;
2561  (*mult) *= 10;
2562  }
2563  }
2564 
2565  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2566  {
2567  if( ABS(*mult) > ABS(*mult * 10) )
2568  return SCIP_INVALIDDATA;
2569  (*mult) *= 10;
2570  }
2571 
2572  /* print comment line if we have to multiply the coefficients to get integrals */
2573  if( ABS(*mult) != 1 )
2574  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2575 
2576 #ifndef NDEBUG
2577  /* check that these variables are sorted */
2578  for( v = nresvars - 1; v > 0; --v )
2579  assert(SCIPvarGetIndex(resvars[v]) >= SCIPvarGetIndex(resvars[v - 1]));
2580 #endif
2581 
2582  /* if we have a soft constraint print the weight*/
2583  if( weight != 0 )
2584  {
2585  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2586  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2587  }
2588 
2589  /* print coefficients */
2590  for( v = 0; v < nvars; ++v )
2591  {
2592  SCIP_Bool negated;
2593 
2594  var = vars[v];
2595  assert( var != NULL );
2596 
2597  negated = SCIPvarIsNegated(var);
2598 
2599  /* replace and-resultant with corresponding variables */
2600  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2601  {
2602  int a;
2603 
2604  assert(andvars != NULL);
2605  assert(nandvars != NULL);
2606  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2607  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2608 
2609  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2610 
2611  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2612  {
2613  SCIPerrorMessage("Integral coefficient to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", *mult, vals[v], vals[v] * (*mult), (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)));
2614  }
2615 
2616  /* print and-vars */
2617  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s",
2618  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "",
2619  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x") );
2620  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2621 
2622  for(a = nandvars[pos] - 2; a >= 0; --a )
2623  {
2624  negated = SCIPvarIsNegated(andvars[pos][a]);
2625 
2626  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2627  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2628  }
2629 
2630  appendBuffer(scip, file, linebuffer, &linecnt, " ");
2631  }
2632  else
2633  {
2634  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2635  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2636  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2637  }
2638  }
2639 
2640  /* print left hand side */
2641  if( SCIPisZero(scip, lhs) )
2642  lhs = 0.0;
2643 
2644  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2645  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2646 
2647  writeBuffer(scip, file, linebuffer, &linecnt);
2648 
2649  return SCIP_OKAY;
2650 }
2651 
2652 
2653 /** prints given maybe non-linear constraint information in OPB format to file stream */
2654 static
2656  SCIP*const scip, /**< SCIP data structure */
2657  FILE*const file, /**< output file (or NULL for standard output) */
2658  SCIP_VAR**const vars, /**< array of variables */
2659  SCIP_Real*const vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2660  int const nvars, /**< number of variables */
2661  SCIP_Real const lhs, /**< left hand side */
2662  SCIP_Real const rhs, /**< right hand side */
2663  SCIP_VAR** const resvars, /**< array of resultant variables */
2664  int const nresvars, /**< number of resultant variables */
2665  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2666  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2667  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2668  SCIP_Bool const transformed, /**< transformed constraint? */
2669  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2670  )
2671 {
2672  SCIP_VAR** activevars;
2673  SCIP_Real* activevals;
2674  SCIP_Real activeconstant;
2675  SCIP_Longint mult;
2676  SCIP_RETCODE retcode;
2677  int v;
2678  int nactivevars;
2679 
2680  assert(scip != NULL);
2681  assert(vars != NULL);
2682  assert(nvars > 0);
2683  assert(lhs <= rhs);
2684  assert(resvars != NULL);
2685  assert(nresvars > 0);
2686  assert(andvars != NULL && nandvars != NULL);
2687 
2688  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2689  return SCIP_OKAY;
2690 
2691  activeconstant = 0.0;
2692  nactivevars = nvars;
2693 
2694  /* duplicate variable and value array */
2695  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2696  if( vals != NULL )
2697  {
2698  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2699  }
2700  else
2701  {
2702  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2703 
2704  for( v = 0; v < nactivevars; ++v )
2705  activevals[v] = 1.0;
2706  }
2707 
2708  /* retransform given variables to active variables */
2709  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2710 
2711  mult = 1;
2712  retcode = SCIP_OKAY;
2713 
2714  /* print row(s) in OPB format */
2715  if( SCIPisEQ(scip, lhs, rhs) )
2716  {
2717  assert( !SCIPisInfinity(scip, rhs) );
2718 
2719  /* equality constraint */
2720  retcode = printNLRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2721  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2722  }
2723  else
2724  {
2725  if( !SCIPisInfinity(scip, -lhs) )
2726  {
2727  /* print inequality ">=" */
2728  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, resvars,
2729  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2730  }
2731 
2732  if( !SCIPisInfinity(scip, rhs) )
2733  {
2734  mult *= -1;
2735 
2736  /* print inequality ">=" and multiplying all coefficients by -1 */
2737  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2738  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2739  }
2740  }
2741 
2742  /* free buffer arrays */
2743  SCIPfreeBufferArray(scip, &activevars);
2744  SCIPfreeBufferArray(scip, &activevals);
2745 
2746  return retcode;
2747 }
2748 
2749 
2750 /* print row in OPB format to file stream */
2751 static
2753  SCIP* scip, /**< SCIP data structure */
2754  FILE* file, /**< output file (or NULL for standard output) */
2755  const char* type, /**< row type ("=" or ">=") */
2756  SCIP_VAR** vars, /**< array of variables */
2757  SCIP_Real* vals, /**< array of values */
2758  int nvars, /**< number of variables */
2759  SCIP_Real lhs, /**< left hand side */
2760  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2761  SCIP_Longint* mult, /**< multiplier for the coefficients */
2762  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2763  )
2764 {
2765  SCIP_VAR* var;
2766  char buffer[OPB_MAX_LINELEN];
2767  char linebuffer[OPB_MAX_LINELEN + 1];
2768  int v;
2769  int linecnt;
2770 
2771  assert(scip != NULL);
2772  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2773  assert(mult != NULL);
2774 
2775  clearBuffer(linebuffer, &linecnt);
2776 
2777  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
2778  * we can stop printing because it is an artificial constraint
2779  */
2780  if( nvars > 0 && strstr(SCIPvarGetName(vars[0]), INDICATORVARNAME) != NULL )
2781  return SCIP_OKAY;
2782 
2783  /* check if all coefficients are integral; if not commentstart multiplier */
2784  for( v = 0; v < nvars; ++v )
2785  {
2786  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2787  {
2788  if( ABS(*mult) > ABS(*mult * 10) )
2789  return SCIP_INVALIDDATA;
2790  (*mult) *= 10;
2791  }
2792  }
2793 
2794  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2795  {
2796  if( ABS(*mult) > ABS(*mult * 10) )
2797  return SCIP_INVALIDDATA;
2798  (*mult) *= 10;
2799  }
2800 
2801  /* print comment line if we have to multiply the coefficients to get integrals */
2802  if( ABS(*mult) != 1 )
2803  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2804 
2805  /* if we have a soft constraint print the weight*/
2806  if( weight != 0 )
2807  {
2808  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2809  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2810  }
2811 
2812  /* print coefficients */
2813  for( v = 0; v < nvars; ++v )
2814  {
2815  SCIP_Bool negated;
2816 
2817  var = vars[v];
2818  assert( var != NULL );
2819 
2820  negated = SCIPvarIsNegated(var);
2821 
2822  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2823  {
2824  SCIPerrorMessage("Integral coefficient to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", *mult, vals[v], vals[v] * (*mult), (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)));
2825  }
2826 
2827  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2828  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2829  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2830  }
2831 
2832  /* print left hand side */
2833  if( SCIPisZero(scip, lhs) )
2834  lhs = 0.0;
2835 
2836  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2837  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2838 
2839  writeBuffer(scip, file, linebuffer, &linecnt);
2840 
2841  return SCIP_OKAY;
2842 }
2843 
2844 
2845 /** prints given linear constraint information in OPB format to file stream */
2846 static
2848  SCIP* scip, /**< SCIP data structure */
2849  FILE* file, /**< output file (or NULL for standard output) */
2850  SCIP_VAR** vars, /**< array of variables */
2851  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2852  int nvars, /**< number of variables */
2853  SCIP_Real lhs, /**< left hand side */
2854  SCIP_Real rhs, /**< right hand side */
2855  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2856  SCIP_Bool transformed, /**< transformed constraint? */
2857  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2858  )
2859 {
2860  SCIP_VAR** activevars;
2861  SCIP_Real* activevals;
2862  int nactivevars;
2863  SCIP_Real activeconstant;
2864  SCIP_Longint mult;
2865  SCIP_RETCODE retcode;
2866  int v;
2867 
2868  assert( scip != NULL );
2869  assert( vars != NULL );
2870  assert( nvars > 0 );
2871  assert( lhs <= rhs );
2872 
2873  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2874  return SCIP_OKAY;
2875 
2876  activeconstant = 0.0;
2877 
2878  /* duplicate variable and value array */
2879  nactivevars = nvars;
2880  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2881  if( vals != NULL )
2882  {
2883  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2884  }
2885  else
2886  {
2887  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2888 
2889  for( v = 0; v < nactivevars; ++v )
2890  activevals[v] = 1.0;
2891  }
2892 
2893  /* retransform given variables to active variables */
2894  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2895 
2896  mult = 1;
2897  retcode = SCIP_OKAY;
2898 
2899  /* print row(s) in OPB format */
2900  if( SCIPisEQ(scip, lhs, rhs) )
2901  {
2902  assert( !SCIPisInfinity(scip, rhs) );
2903 
2904  /* equality constraint */
2905  retcode = printRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2906  multisymbol);
2907  }
2908  else
2909  {
2910  if( !SCIPisInfinity(scip, -lhs) )
2911  {
2912  /* print inequality ">=" */
2913  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, weight, &mult,
2914  multisymbol);
2915  }
2916 
2917  if( !SCIPisInfinity(scip, rhs) )
2918  {
2919  mult *= -1;
2920 
2921  /* print inequality ">=" and multiplying all coefficients by -1 */
2922  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2923  multisymbol);
2924  }
2925  }
2926 
2927  /* free buffer arrays */
2928  SCIPfreeBufferArray(scip, &activevars);
2929  SCIPfreeBufferArray(scip, &activevals);
2930 
2931  return retcode;
2932 }
2933 
2934 /* print row in OPB format to file stream */
2935 static
2937  SCIP*const scip, /**< SCIP data structure */
2938  FILE*const file, /**< output file (or NULL for standard output) */
2939  const char* type, /**< row type ("=" or ">=") */
2940  SCIP_VAR**const linvars, /**< array of variables */
2941  SCIP_Real*const linvals, /**< array of values */
2942  int const nlinvars, /**< number of variables */
2943  SCIP_VAR***const termvars, /**< term array with array of variables to print */
2944  int*const ntermvars, /**< array with number of variables in each term */
2945  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
2946  int const ntermvals, /**< number non-linear variables in the problem */
2947  SCIP_Bool**const negatedarrays, /**< array of arrays to know which variable in a non-linear part is negated */
2948  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
2949  SCIP_Real lhs, /**< left hand side */
2950  SCIP_Longint* mult, /**< multiplier for the coefficients */
2951  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2952  )
2953 {
2954  SCIP_VAR* var;
2955  char buffer[OPB_MAX_LINELEN];
2956  char linebuffer[OPB_MAX_LINELEN + 1];
2957  int v;
2958  int t;
2959  int linecnt;
2960 
2961  assert(scip != NULL);
2962  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2963  assert(linvars != NULL || nlinvars == 0);
2964  assert(linvals != NULL || nlinvars == 0);
2965  assert(termvars != NULL || ntermvals == 0);
2966  assert(ntermvars != NULL || ntermvals == 0);
2967  assert(termvals != NULL || ntermvals == 0);
2968  assert(negatedarrays != NULL || ntermvals == 0);
2969  assert(mult != NULL);
2970 
2971  clearBuffer(linebuffer, &linecnt);
2972 
2973  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
2974  * we can stop printing because it is an artificial constraint
2975  */
2976  if( ntermvals == 0 && nlinvars > 0 && strstr(SCIPvarGetName(linvars[0]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2977  return SCIP_OKAY;
2978 
2979  /* check if all linear coefficients are internal; if not commentstart multiplier */
2980  for( v = 0; v < nlinvars; ++v )
2981  {
2982  while( !SCIPisIntegral(scip, linvals[v] * (*mult)) ) /*lint !e613 */
2983  {
2984  if( ABS(*mult) > ABS(*mult * 10) )
2985  return SCIP_INVALIDDATA;
2986  (*mult) *= 10;
2987  }
2988  }
2989 
2990  /* check if all non-linear coefficients are internal; if not commentstart multiplier */
2991  for( v = 0; v < ntermvals; ++v )
2992  {
2993  while( !SCIPisIntegral(scip, termvals[v] * (*mult)) ) /*lint !e613 */
2994  {
2995  if( ABS(*mult) > ABS(*mult * 10) )
2996  return SCIP_INVALIDDATA;
2997  (*mult) *= 10;
2998  }
2999  }
3000 
3001  while( !SCIPisIntegral(scip, lhs * (*mult)) )
3002  {
3003  if( ABS(*mult) > ABS(*mult * 10) )
3004  return SCIP_INVALIDDATA;
3005  (*mult) *= 10;
3006  }
3007 
3008  /* print comment line if we have to multiply the coefficients to get integrals */
3009  if( ABS(*mult) != 1 )
3010  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
3011 
3012  /* if indicator variable exist we have a soft constraint */
3013  if( indvar != NULL )
3014  {
3015  SCIP_Real weight;
3016 
3017  weight = SCIPvarGetObj(indvar);
3018  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+g] ", weight);
3019  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3020  }
3021 
3022  /* print linear part */
3023  for( v = 0; v < nlinvars; ++v )
3024  {
3025  SCIP_Bool negated;
3026 
3027  var = linvars[v]; /*lint !e613 */
3028  assert(var != NULL);
3029 
3030  negated = SCIPvarIsNegated(var);
3031 
3032  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
3033  (SCIP_Longint) SCIPround(scip, linvals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x")); /*lint !e613 */
3034  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3035  }
3036 
3037  /* print non-linear part */
3038  for( t = 0; t < ntermvals; ++t )
3039  {
3040  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT, (SCIP_Longint) SCIPround(scip, termvals[t] * (*mult))); /*lint !e613 */
3041  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3042 
3043  for( v = 0; v < ntermvars[t]; ++v ) /*lint !e613 */
3044  {
3045  SCIP_Bool negated;
3046 
3047  var = termvars[t][v]; /*lint !e613 */
3048  assert(var != NULL);
3049 
3050  negated = negatedarrays[t][v]; /*lint !e613 */
3051 
3052  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
3053  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3054  }
3055  appendBuffer(scip, file, linebuffer, &linecnt, " ");
3056  }
3057 
3058  /* print left hand side */
3059  if( SCIPisZero(scip, lhs) )
3060  lhs = 0.0;
3061 
3062  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
3063  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3064 
3065  writeBuffer(scip, file, linebuffer, &linecnt);
3066 
3067  return SCIP_OKAY;
3068 }
3069 
3070 
3071 /** prints given pseudo boolean constraint information in OPB format to file stream */
3072 static
3074  SCIP*const scip, /**< SCIP data structure */
3075  FILE*const file, /**< output file, or NULL if standard output should be used */
3076  SCIP_VAR**const linvars, /**< array with variables of linear part */
3077  SCIP_Real*const linvals, /**< array of coefficients values of linear part */
3078  int const nlinvars, /**< number variables in linear part of the problem */
3079  SCIP_VAR***const termvars, /**< term array with array of variables to print */
3080  int*const ntermvars, /**< array with number of variables in each term */
3081  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
3082  int const ntermvals, /**< number non-linear variables in the problem */
3083  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
3084  SCIP_Real const lhs, /**< left hand side of constraint */
3085  SCIP_Real const rhs, /**< right hand side of constraint */
3086  SCIP_Bool transformed, /**< should the transformed problem be printed ? */
3087  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
3088  )
3089 {
3090  SCIP_VAR*** activetermvars;
3091  SCIP_Bool** negatedarrays;
3092  SCIP_VAR** activelinvars;
3093  SCIP_Real* activelinvals;
3094  int nactivelinvars;
3095  SCIP_Real activelinconstant;
3096  SCIP_Longint mult;
3097  SCIP_RETCODE retcode;
3098  int v;
3099 
3100  assert(scip != NULL);
3101  assert(linvars != NULL || nlinvars == 0);
3102  assert(linvals != NULL || nlinvars == 0);
3103  assert(termvars != NULL || 0 == ntermvals);
3104  assert(ntermvars != NULL || 0 == ntermvals);
3105  assert(termvals != NULL || 0 == ntermvals);
3106  assert(lhs <= rhs);
3107 
3108  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
3109  return SCIP_OKAY;
3110 
3111  activelinconstant = 0.0;
3112 
3113  /* duplicate variable and value array for linear part */
3114  nactivelinvars = nlinvars;
3115  if( nactivelinvars > 0 )
3116  {
3117  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvars, linvars, nactivelinvars ) );
3118  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvals, linvals, nactivelinvars ) );
3119 
3120  /* retransform given variables to active variables */
3121  SCIP_CALL( getActiveVariables(scip, activelinvars, activelinvals, &nactivelinvars, &activelinconstant, transformed) );
3122  }
3123  else
3124  {
3125  activelinvars = NULL;
3126  activelinvals = NULL;
3127  }
3128 
3129  /* create non-linear information for printing */
3130  if( ntermvals > 0 )
3131  {
3132  assert(termvars != NULL);
3133  assert(ntermvars != NULL);
3134  assert(termvals != NULL);
3135 
3136  SCIP_CALL( SCIPallocBufferArray(scip, &activetermvars, ntermvals) );
3137  SCIP_CALL( SCIPallocBufferArray(scip, &negatedarrays, ntermvals) );
3138  for( v = ntermvals - 1; v >= 0; --v )
3139  {
3140  assert(ntermvars[v] > 0); /*lint !e613 */
3141 
3142  if( transformed )
3143  {
3144  SCIP_CALL( SCIPallocBufferArray(scip, &(activetermvars[v]), ntermvars[v]) ); /*lint !e866 */
3145  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3146 
3147  /* get binary representatives of binary variables in non-linear terms */
3148  SCIP_CALL( SCIPgetBinvarRepresentatives(scip, ntermvars[v], termvars[v], activetermvars[v], negatedarrays[v]) );
3149  }
3150  else
3151  {
3152  SCIP_CALL( SCIPduplicateBufferArray(scip, &(activetermvars[v]), termvars[v], ntermvars[v]) ); /*lint !e866 */
3153  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3154  BMSclearMemoryArray(negatedarrays[v], ntermvars[v]); /*lint !e866 */
3155  }
3156  }
3157  }
3158  else
3159  {
3160  activetermvars = NULL;
3161  negatedarrays = NULL;
3162  }
3163 
3164  mult = 1;
3165  retcode = SCIP_OKAY;
3166 
3167  /* print row(s) in OPB format */
3168  if( SCIPisEQ(scip, lhs, rhs) )
3169  {
3170  assert( !SCIPisInfinity(scip, rhs) );
3171 
3172  /* equality constraint */
3173  retcode = printPBRow(scip, file, "=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3174  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3175  }
3176  else
3177  {
3178  if( !SCIPisInfinity(scip, -lhs) )
3179  {
3180  /* print inequality ">=" */
3181  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3182  ntermvars, termvals, ntermvals, negatedarrays, indvar, lhs - activelinconstant, &mult, multisymbol);
3183  }
3184 
3185  if( !SCIPisInfinity(scip, rhs) )
3186  {
3187  mult *= -1;
3188 
3189  /* print inequality ">=" and multiplying all coefficients by -1 */
3190  /* coverity[var_deref_model] */
3191  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3192  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3193  }
3194  }
3195 
3196  /* free buffers for non-linear arrays */
3197  if( ntermvals > 0 )
3198  {
3199  assert(negatedarrays != NULL);
3200  assert(activetermvars != NULL);
3201 
3202  for( v = 0; v < ntermvals; ++v )
3203  {
3204  assert(negatedarrays[v] != NULL);
3205  assert(activetermvars[v] != NULL);
3206  SCIPfreeBufferArray(scip, &(negatedarrays[v]));
3207  SCIPfreeBufferArray(scip, &(activetermvars[v]));
3208  }
3209  SCIPfreeBufferArray(scip, &negatedarrays);
3210  SCIPfreeBufferArray(scip, &activetermvars);
3211  }
3212 
3213  /* free buffer for linear arrays */
3214  if( nactivelinvars > 0 )
3215  {
3216  SCIPfreeBufferArray(scip, &activelinvars);
3217  SCIPfreeBufferArray(scip, &activelinvals);
3218  }
3219 
3220  return retcode;
3221 }
3222 
3223 /** determine total number of linear constraints split into lhs/rhs */
3224 static
3226  SCIP*const scip, /**< SCIP data structure */
3227  SCIP_CONS**const conss, /**< array with constraints of the problem */
3228  int const nconss, /**< number of constraints in the problem */
3229  int* nlinearconss, /**< pointer to store the total number of linear constraints */
3230  int* nsplitlinearconss /**< pointer to store the total number of linear constraints split into lhs/rhs */
3231  )
3232 {
3233  SCIP_CONSHDLR* conshdlr;
3234  const char* conshdlrname;
3235  SCIP_CONS* cons;
3236  int c;
3237 
3238  assert(scip != NULL);
3239  assert(conss != NULL || nconss == 0);
3240  assert(nlinearconss != NULL);
3241  assert(nsplitlinearconss != NULL);
3242 
3243  *nlinearconss = 0;
3244  *nsplitlinearconss = 0;
3245 
3246  /* loop over all constraints */
3247  for( c = 0; c < nconss; ++c )
3248  {
3249  cons = conss[c];
3250  assert(cons != NULL);
3251  conshdlr = SCIPconsGetHdlr(cons); /*lint !e613*/
3252  assert(conshdlr != NULL);
3253 
3254  conshdlrname = SCIPconshdlrGetName(conshdlr);
3255 
3256  if( strcmp(conshdlrname, "linear") == 0 )
3257  {
3258  if( ! SCIPisInfinity(scip, SCIPgetLhsLinear(scip, cons)) )
3259  ++(*nsplitlinearconss);
3260 
3261  if( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, cons)) )
3262  ++(*nsplitlinearconss);
3263 
3264  ++(*nlinearconss);
3265  }
3266 
3267  if( strcmp(conshdlrname, "varbound") == 0 )
3268  {
3269  if( ! SCIPisInfinity(scip, SCIPgetLhsVarbound(scip, cons)) )
3270  ++(*nsplitlinearconss);
3271 
3272  if( ! SCIPisInfinity(scip, SCIPgetRhsVarbound(scip, cons)) )
3273  ++(*nsplitlinearconss);
3274 
3275  ++(*nlinearconss);
3276  }
3277  }
3278 }
3279 
3280 /** write constraints */
3281 static
3283  SCIP*const scip, /**< SCIP data structure */
3284  FILE*const file, /**< output file, or NULL if standard output should be used */
3285  SCIP_CONS**const conss, /**< array with constraints of the problem */
3286  int const nconss, /**< number of constraints in the problem */
3287  SCIP_VAR**const vars, /**< array with active (binary) variables */
3288  int const nvars, /**< number of active variables in the problem */
3289  SCIP_VAR** const resvars, /**< array of resultant variables */
3290  int const nresvars, /**< number of resultant variables */
3291  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3292  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3293  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3294  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
3295  SCIP_Bool const existands, /**< does some and-constraints exist? */
3296  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3297  )
3298 {
3299  SCIP_CONSHDLR* conshdlr;
3300  const char* conshdlrname;
3301  SCIP_CONS* cons;
3302  SCIP_VAR** consvars;
3303  SCIP_Real* consvals;
3304  SCIP_RETCODE retcode;
3305  int nconsvars;
3306  int v, c;
3307  SCIP_HASHMAP* linconssofindicatorsmap = NULL;
3308  SCIP_HASHMAP* linconssofpbsmap = NULL;
3309 
3310  assert(scip != NULL);
3311  assert(file != NULL);
3312  assert(conss != NULL || nconss == 0);
3313  assert(vars != NULL || nvars == 0);
3314  assert(resvars != NULL || nresvars == 0);
3315  assert(andvars != NULL || nandvars == 0);
3316  assert(multisymbol != NULL);
3317 
3318  if( transformed )
3319  {
3320  conshdlr = SCIPfindConshdlr(scip, "indicator");
3321 
3322  /* find artificial linear constraints which correspond to indicator constraints to avoid double printing */
3323  if( conshdlr != NULL )
3324  {
3325  SCIP_CONS** indconss;
3326  int nindconss;
3327 
3328  indconss = SCIPconshdlrGetConss(conshdlr);
3329  nindconss = SCIPconshdlrGetNConss(conshdlr);
3330  assert(indconss != NULL || nindconss == 0);
3331 
3332  if( nindconss > 0 )
3333  {
3334  SCIP_CONS* lincons;
3335 
3336  /* create the linear constraint of indicator constraints hash map */
3337  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nindconss) );
3338  assert(indconss != NULL);
3339 
3340  for( c = 0; c < nindconss; ++c )
3341  {
3342  assert(indconss[c] != NULL);
3343  lincons = SCIPgetLinearConsIndicator(indconss[c]);
3344  assert(lincons != NULL);
3345 
3346  /* insert constraint into mapping between */
3347  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3348  }
3349  }
3350  }
3351 
3352  conshdlr = SCIPfindConshdlr(scip, "pseudoboolean");
3353 
3354  /* find artifical linear constraints which correspond to indicator constraints to avoid double printing */
3355  if( conshdlr != NULL )
3356  {
3357  SCIP_CONS** pbconss;
3358  int npbconss;
3359 
3360  pbconss = SCIPconshdlrGetConss(conshdlr);
3361  npbconss = SCIPconshdlrGetNConss(conshdlr);
3362  assert(pbconss != NULL || npbconss == 0);
3363 
3364  if( npbconss > 0 )
3365  {
3366  SCIP_CONS* lincons;
3367 
3368  /* create the linear constraint of indicator constraints hash map */
3369  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), npbconss) );
3370 
3371  for( c = 0; c < npbconss; ++c )
3372  {
3373  assert(pbconss[c] != NULL); /*lint !e613*/
3374  lincons = SCIPgetLinearConsPseudoboolean(scip, pbconss[c]); /*lint !e613*/
3375  assert(lincons != NULL);
3376 
3377  /* insert constraint into mapping between */
3378  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3379  }
3380  }
3381  }
3382  }
3383  /* in original space we cannot ask the constraint handler for its constraints, therefore we have to loop over all
3384  * original to check for artificial linear once
3385  */
3386  else
3387  {
3388  SCIP_CONS* lincons;
3389  SCIP_Bool pbhashmapcreated = FALSE;
3390  SCIP_Bool indhashmapcreated = FALSE;
3391 
3392  /* loop over all constraint for printing */
3393  for( c = 0; c < nconss; ++c )
3394  {
3395  conshdlr = SCIPconsGetHdlr(conss[c]); /*lint !e613*/
3396  assert(conshdlr != NULL);
3397 
3398  conshdlrname = SCIPconshdlrGetName(conshdlr);
3399 
3400  if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3401  {
3402  if( !pbhashmapcreated )
3403  {
3404  /* create the linear constraint of indicator constraints hash map */
3405  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), nconss) );
3406  pbhashmapcreated = TRUE;
3407  }
3408 
3409  lincons = SCIPgetLinearConsPseudoboolean(scip, conss[c]); /*lint !e613*/
3410  assert(lincons != NULL);
3411 
3412  /* insert constraint into mapping between */
3413  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3414  }
3415  else if( strcmp(conshdlrname, "indicator") == 0 )
3416  {
3417  if( !indhashmapcreated )
3418  {
3419  /* create the linear constraint of indicator constraints hash map */
3420  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nconss) );
3421  indhashmapcreated = TRUE;
3422  }
3423 
3424  lincons = SCIPgetLinearConsIndicator(conss[c]); /*lint !e613*/
3425  assert(lincons != NULL);
3426 
3427  /* insert constraint into mapping between */
3428  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3429  }
3430  }
3431  }
3432 
3433  retcode = SCIP_OKAY;
3434  cons = NULL;
3435 
3436  /* loop over all constraint for printing */
3437  for( c = 0; c < nconss && retcode == SCIP_OKAY; ++c )
3438  {
3439  SCIP_CONS* artcons;
3440 
3441  artcons = NULL;
3442 
3443  cons = conss[c]; /*lint !e613 */
3444  assert(cons != NULL);
3445 
3446  conshdlr = SCIPconsGetHdlr(cons);
3447  assert(conshdlr != NULL);
3448 
3449  conshdlrname = SCIPconshdlrGetName(conshdlr);
3450  assert(transformed == SCIPconsIsTransformed(cons));
3451 
3452  /* in case the transformed is written only constraint are posted which are enabled in the current node */
3453  assert(!transformed || SCIPconsIsEnabled(cons));
3454 
3455  if( linconssofpbsmap != NULL )
3456  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofpbsmap, (void*)cons);
3457  if( artcons == NULL && linconssofindicatorsmap != NULL )
3458  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofindicatorsmap, (void*)cons);
3459 
3460  if( artcons == NULL )
3461  {
3462  if( strcmp(conshdlrname, "linear") == 0 )
3463  {
3464  if( SCIPgetNVarsLinear(scip, cons) == 0 )
3465  {
3466  if( SCIPisGT(scip, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons)) )
3467  {
3468  SCIPerrorMessage("Cannot print empty violated constraint %s, %g <= %g is not fulfilled\n",
3469  SCIPconsGetName(cons), SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons));
3470  }
3471  continue;
3472  }
3473 
3474  if( existands )
3475  {
3476  retcode = printNonLinearCons(scip, file,
3477  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3478  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), resvars, nresvars, andvars, nandvars,
3479  0LL, transformed, multisymbol);
3480  }
3481  else
3482  {
3483  retcode = printLinearCons(scip, file,
3484  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3485  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), 0LL, transformed, multisymbol);
3486  }
3487  }
3488  else if( strcmp(conshdlrname, "setppc") == 0 )
3489  {
3490  consvars = SCIPgetVarsSetppc(scip, cons);
3491  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3492 
3493  if( nconsvars == 0 )
3494  continue;
3495 
3496  switch( SCIPgetTypeSetppc(scip, cons) )
3497  {
3499  if( existands )
3500  {
3501  retcode = printNonLinearCons(scip, file, consvars, NULL, nconsvars, 1.0, 1.0, resvars, nresvars,
3502  andvars, nandvars, 0LL, transformed, multisymbol);
3503  }
3504  else
3505  {
3506  retcode = printLinearCons(scip, file,
3507  consvars, NULL, nconsvars, 1.0, 1.0, 0LL, transformed, multisymbol);
3508  }
3509  break;
3511  if( existands )
3512  {
3513  retcode = printNonLinearCons(scip, file,
3514  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, resvars, nresvars, andvars, nandvars,
3515  0LL, transformed, multisymbol);
3516  }
3517  else
3518  {
3519  retcode = printLinearCons(scip, file,
3520  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, 0LL, transformed, multisymbol);
3521  }
3522  break;
3524  if( existands )
3525  {
3526  retcode = printNonLinearCons(scip, file,
3527  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), resvars, nresvars, andvars, nandvars,
3528  0LL, transformed, multisymbol);
3529  }
3530  else
3531  {
3532  retcode = printLinearCons(scip, file,
3533  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3534  }
3535  break;
3536  }
3537  }
3538  else if( strcmp(conshdlrname, "logicor") == 0 )
3539  {
3540  if( SCIPgetNVarsLogicor(scip, cons) == 0 )
3541  continue;
3542 
3543  if( existands )
3544  {
3545  retcode = printNonLinearCons(scip, file,
3546  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), 1.0, SCIPinfinity(scip),
3547  resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3548  }
3549  else
3550  {
3551  retcode = printLinearCons(scip, file,
3552  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3553  1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3554  }
3555  }
3556  else if( strcmp(conshdlrname, "knapsack") == 0 )
3557  {
3558  SCIP_Longint* weights;
3559 
3560  consvars = SCIPgetVarsKnapsack(scip, cons);
3561  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3562 
3563  if( nconsvars == 0 )
3564  continue;
3565 
3566  /* copy Longint array to SCIP_Real array */
3567  weights = SCIPgetWeightsKnapsack(scip, cons);
3568  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3569  for( v = 0; v < nconsvars; ++v )
3570  consvals[v] = (SCIP_Real)weights[v];
3571 
3572  if( existands )
3573  {
3574  retcode = printNonLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3575  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), resvars, nresvars, andvars, nandvars,
3576  0LL, transformed, multisymbol);
3577  }
3578  else
3579  {
3580  retcode = printLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3581  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), 0LL, transformed, multisymbol);
3582  }
3583 
3584  SCIPfreeBufferArray(scip, &consvals);
3585  }
3586  else if( strcmp(conshdlrname, "varbound") == 0 )
3587  {
3588  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3589  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3590 
3591  consvars[0] = SCIPgetVarVarbound(scip, cons);
3592  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3593 
3594  consvals[0] = 1.0;
3595  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3596 
3597  if( existands )
3598  {
3599  retcode = printNonLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3600  SCIPgetRhsVarbound(scip, cons), resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3601  }
3602  else
3603  {
3604  retcode = printLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3605  SCIPgetRhsVarbound(scip, cons), 0LL, transformed, multisymbol);
3606  }
3607 
3608  SCIPfreeBufferArray(scip, &consvars);
3609  SCIPfreeBufferArray(scip, &consvals);
3610  }
3611  else if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3612  {
3613  SCIP_VAR*** termvars;
3614  int* ntermvars;
3615  int termvarssize;
3616  SCIP_CONS** andconss;
3617  SCIP_Real* andcoefs ;
3618  SCIP_VAR** linvars;
3619  SCIP_Real* lincoefs ;
3620  int nlinvars;
3621  int t;
3622 
3623  /* get the required array size for the variables array and for the number of variables in each variable array */
3624  termvarssize = SCIPgetNAndsPseudoboolean(scip, cons);
3625  assert(termvarssize >= 0);
3626 
3627  /* allocate temporary memory */
3628  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, termvarssize) );
3629  SCIP_CALL( SCIPallocBufferArray(scip, &termvars, termvarssize) );
3630  SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, termvarssize) );
3631  SCIP_CALL( SCIPallocBufferArray(scip, &ntermvars, termvarssize) );
3632 
3633  /* get all corresponding and-constraints and therefor all variables */
3634  SCIP_CALL( SCIPgetAndDatasPseudoboolean(scip, cons, andconss, andcoefs, &termvarssize) );
3635  for( t = termvarssize - 1; t >= 0; --t )
3636  {
3637  termvars[t] = SCIPgetVarsAnd(scip, andconss[t]);
3638  ntermvars[t] = SCIPgetNVarsAnd(scip, andconss[t]);
3639  }
3640 
3641  /* gets number of linear variables without artificial terms variables of pseudoboolean constraint */
3642  nlinvars = SCIPgetNLinVarsWithoutAndPseudoboolean(scip, cons);
3643 
3644  /* allocate temporary memory */
3645  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinvars) );
3646  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nlinvars) );
3647 
3648  /* gets linear constraint of pseudoboolean constraint */
3649  SCIP_CALL( SCIPgetLinDatasWithoutAndPseudoboolean(scip, cons, linvars, lincoefs, &nlinvars) );
3650 
3651  retcode = printPseudobooleanCons(scip, file, linvars, lincoefs, nlinvars,
3652  termvars, ntermvars, andcoefs, termvarssize, SCIPgetIndVarPseudoboolean(scip, cons),
3653  SCIPgetLhsPseudoboolean(scip, cons), SCIPgetRhsPseudoboolean(scip, cons), transformed, multisymbol);
3654 
3655  /* free temporary memory */
3656  SCIPfreeBufferArray(scip, &lincoefs);
3657  SCIPfreeBufferArray(scip, &linvars);
3658  SCIPfreeBufferArray(scip, &ntermvars);
3659  SCIPfreeBufferArray(scip, &andcoefs);
3660  SCIPfreeBufferArray(scip, &termvars);
3661  SCIPfreeBufferArray(scip, &andconss);
3662  }
3663  else if( strcmp(conshdlrname, "indicator") == 0 )
3664  {
3665  SCIP_CONS* lincons;
3666  SCIP_VAR* indvar;
3667  SCIP_VAR* slackvar;
3668  SCIP_Longint weight;
3669 
3670  /* get artificial binary indicator variables */
3671  indvar = SCIPgetBinaryVarIndicator(cons);
3672  assert(indvar != NULL);
3673 
3674  if( SCIPvarGetStatus(indvar) == SCIP_VARSTATUS_NEGATED )
3675  {
3676  indvar = SCIPvarGetNegationVar(indvar);
3677  assert(indvar != NULL);
3679 
3680  /* get the soft cost of this constraint */
3681  weight = (SCIP_Longint) SCIPvarGetObj(indvar);
3682  }
3683  else
3684  {
3686 
3687  /* get the soft cost of this constraint */
3688  weight = -(SCIP_Longint) SCIPvarGetObj(indvar);
3689  }
3690 
3691  /* get artificial slack variable */
3692  slackvar = SCIPgetSlackVarIndicator(cons);
3693  assert(slackvar != NULL);
3694 
3695  /* only need to print indicator constraints with weights on their indicator variable */
3696  if( weight != 0 )
3697  {
3698  SCIP_VAR** scipvarslinear;
3699  SCIP_Real* scipvalslinear;
3700  SCIP_Bool cont;
3701  int nonbinarypos;
3702 
3703  lincons = SCIPgetLinearConsIndicator(cons);
3704  assert(lincons != NULL);
3705 
3706  nconsvars = SCIPgetNVarsLinear(scip, lincons);
3707  scipvarslinear = SCIPgetVarsLinear(scip, lincons);
3708  scipvalslinear = SCIPgetValsLinear(scip, lincons);
3709 
3710  /* allocate temporary memory */
3711  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, scipvarslinear, nconsvars) );
3712  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, scipvalslinear, nconsvars) );
3713 
3714  nonbinarypos = -1;
3715  cont = FALSE;
3716 
3717  /* find non-binary variable */
3718  for( v = 0; v < nconsvars; ++v )
3719  {
3720  if( SCIPvarGetType(consvars[v]) != SCIP_VARTYPE_BINARY )
3721  {
3722  if( consvars[v] == slackvar )
3723  {
3724  assert(nonbinarypos == -1);
3725  nonbinarypos = v;
3726  }
3727  else
3728  {
3729  SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has more than one non-binary variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
3730  SCIPinfoMessage(scip, file, "* ");
3731  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3732  SCIPinfoMessage(scip, file, ";\n");
3733  cont = TRUE;
3734  break;
3735  }
3736  }
3737  }
3738 
3739  /* if we have not found any non-binary variable we do not print the constraint, maybe we should ??? */
3740  if( nonbinarypos == -1 )
3741  {
3742  SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has no slack variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
3743  SCIPinfoMessage(scip, file, "* ");
3744  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3745  SCIPinfoMessage(scip, file, ";\n");
3746 
3747  /* free temporary memory */
3748  SCIPfreeBufferArray(scip, &consvals);
3749  SCIPfreeBufferArray(scip, &consvars);
3750  continue;
3751  }
3752 
3753  /* if the constraint has more than two non-binary variables is not printable and we go to the next */
3754  if( cont )
3755  {
3756  /* free temporary memory */
3757  SCIPfreeBufferArray(scip, &consvals);
3758  SCIPfreeBufferArray(scip, &consvars);
3759  continue;
3760  }
3761 
3762  assert(0 <= nonbinarypos && nonbinarypos < nconsvars);
3763 
3764  /* remove slackvariable in linear constraint for printing */
3765  --nconsvars;
3766  consvars[nonbinarypos] = consvars[nconsvars];
3767  consvals[nonbinarypos] = consvals[nconsvars];
3768 
3769  if( existands )
3770  {
3771  retcode = printNonLinearCons(scip, file,
3772  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3773  resvars, nresvars, andvars, nandvars,
3774  weight, transformed, multisymbol);
3775  }
3776  else
3777  {
3778  retcode = printLinearCons(scip, file,
3779  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3780  weight, transformed, multisymbol);
3781  }
3782 
3783  /* free temporary memory */
3784  SCIPfreeBufferArray(scip, &consvals);
3785  SCIPfreeBufferArray(scip, &consvars);
3786  }
3787  else
3788  {
3789  SCIPwarningMessage(scip, "indicator constraint <%s> will not be printed because the indicator variable has no objective value(= weight of this soft constraint)\n", SCIPconsGetName(cons) );
3790  SCIPinfoMessage(scip, file, "* ");
3791  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3792  SCIPinfoMessage(scip, file, ";\n");
3793  }
3794  }
3795  else if( strcmp(conshdlrname, "and") == 0 )
3796  {
3797  /* all resultants of the and constraint will be replaced by all corresponding variables of this constraint,
3798  * so no and-constraint will be printed directly */
3799  assert(existandconshdlr);
3800  }
3801  else
3802  {
3803  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3804  SCIPinfoMessage(scip, file, "* ");
3805  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3806  SCIPinfoMessage(scip, file, ";\n");
3807  }
3808  }
3809  }
3810 
3811  if( retcode == SCIP_INVALIDDATA )
3812  {
3813  assert(cons != NULL);
3814 
3815  SCIPerrorMessage("Cannot print constraint %s with non-integral coefficient or sides in opb-format\n",
3816  SCIPconsGetName(cons));
3817  SCIP_CALL( SCIPprintCons(scip, cons, stderr) );
3818  SCIPinfoMessage(scip, file, ";\n");
3819  }
3820 
3821  if( linconssofpbsmap != NULL )
3822  {
3823  /* free hash map */
3824  SCIPhashmapFree(&linconssofpbsmap);
3825  }
3826  if( linconssofindicatorsmap != NULL )
3827  {
3828  /* free hash map */
3829  SCIPhashmapFree(&linconssofindicatorsmap);
3830  }
3831 
3832  return retcode;
3833 }
3834 
3835 /* write fixed variables (unless already done because they are an and resultant or and variable) */
3836 static
3838  SCIP*const scip, /**< SCIP data structure */
3839  FILE*const file, /**< output file, or NULL if standard output should be used */
3840  SCIP_VAR** vars, /**< array with active (binary) variables */
3841  int nvars, /**< number of active variables in the problem */
3842  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3843  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3844  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3845  )
3846 {
3847  char linebuffer[OPB_MAX_LINELEN+1];
3848  char buffer[OPB_MAX_LINELEN];
3849  int linecnt;
3850  int v;
3851 
3852  assert(scip != NULL);
3853  assert(file != NULL);
3854  assert(vars != NULL || nvars == 0);
3855  assert(printedfixing != NULL);
3856  assert(multisymbol != NULL);
3857 
3858  clearBuffer(linebuffer, &linecnt);
3859 
3860  /* print variables which are fixed */
3861  for( v = 0; v < nvars; ++v )
3862  {
3863  SCIP_VAR* var;
3864  SCIP_Real lb;
3865  SCIP_Real ub;
3866  SCIP_Bool neg = FALSE;
3867 
3868  assert( vars != NULL );
3869  var = vars[v];
3870 
3871  if( transformed )
3872  {
3873  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3874  lb = SCIPvarGetLbLocal(var);
3875  ub = SCIPvarGetUbLocal(var);
3876  }
3877  else
3878  {
3879  lb = SCIPvarGetLbOriginal(var);
3880  ub = SCIPvarGetUbOriginal(var);
3881  }
3882  assert(lb > -0.5 && ub < 1.5);
3883  assert(SCIPisFeasIntegral(scip, lb));
3884  assert(SCIPisFeasIntegral(scip, ub));
3885 
3886  /* print fixed and-resultants */
3887  if( lb > 0.5 || ub < 0.5 )
3888  {
3889  if( transformed ) {
3890  SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &var, &neg) );
3891  }
3892 
3893  if( SCIPhashtableExists(printedfixing, (void*)var) )
3894  continue;
3895 
3896  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
3897  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3898 
3899  /* add variable to the hashmap */
3900  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
3901  }
3902  }
3903 
3904  writeBuffer(scip, file, linebuffer, &linecnt);
3905 
3906  return SCIP_OKAY;
3907 }
3908 
3909 /* write and constraints of inactive but relevant and-resultants and and variables which are fixed to one */
3910 static
3912  SCIP*const scip, /**< SCIP data structure */
3913  FILE*const file, /**< output file, or NULL if standard output should be used */
3914  SCIP_VAR**const resvars, /**< array of resultant variables */
3915  int const nresvars, /**< number of resultant variables */
3916  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3917  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3918  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3919  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3920  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3921  )
3922 {
3923  SCIP_VAR* resvar;
3924  SCIP_Longint rhslhs;
3925  char linebuffer[OPB_MAX_LINELEN+1];
3926  char buffer[OPB_MAX_LINELEN];
3927  int linecnt;
3928  int r, v;
3929 
3930  assert(scip != NULL);
3931  assert(file != NULL);
3932  assert(resvars != NULL || nresvars == 0);
3933  assert(nandvars != NULL || nresvars == 0);
3934  assert(andvars != NULL || nandvars == NULL);
3935  assert(multisymbol != NULL);
3936 
3937  clearBuffer(linebuffer, &linecnt);
3938 
3939  /* print and-variables which are fixed */
3940  /* @todo remove this block here and the hashtable and let writeOpbFixedVars() do the job? */
3941  for( r = nresvars - 1; r >= 0; --r )
3942  {
3943  SCIP_VAR* var;
3944  SCIP_Bool neg;
3945  SCIP_Real lb;
3946  SCIP_Real ub;
3947 
3948  assert( resvars != NULL );
3949  resvar = resvars[r];
3950 
3951  if( transformed )
3952  {
3953  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3954  lb = SCIPvarGetLbLocal(resvar);
3955  ub = SCIPvarGetUbLocal(resvar);
3956  }
3957  else
3958  {
3959  lb = SCIPvarGetLbOriginal(resvar);
3960  ub = SCIPvarGetUbOriginal(resvar);
3961  }
3962 
3963  /* print fixed and-resultants */
3964  if( lb > 0.5 || ub < 0.5 )
3965  {
3966  /* coverity[copy_paste_error] */
3967  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &var, &neg) );
3968 
3969  assert(SCIPisFeasIntegral(scip, lb));
3970  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
3971  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3972 
3973  /* add variable to the hashmap */
3974  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
3975  }
3976 
3977  assert( andvars != NULL && nandvars != NULL );
3978  assert( andvars[r] != NULL || nandvars[r] == 0 );
3979 
3980  /* print fixed and-variables */
3981  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
3982  {
3983  assert( andvars[r] != NULL );
3984  assert( andvars[r][v] != NULL );
3985 
3986  if( transformed )
3987  {
3988  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3989  lb = SCIPvarGetLbLocal(andvars[r][v]);
3990  ub = SCIPvarGetUbLocal(andvars[r][v]);
3991  }
3992  else
3993  {
3994  lb = SCIPvarGetLbOriginal(andvars[r][v]);
3995  ub = SCIPvarGetUbOriginal(andvars[r][v]);
3996  }
3997 
3998  if( lb > 0.5 || ub < 0.5 )
3999  {
4000  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4001 
4002  assert(SCIPisFeasIntegral(scip, lb));
4003  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
4004  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4005 
4006  /* add variable to the hashmap */
4007  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
4008  }
4009  }
4010  }
4011 
4012  /* print and-constraints with fixed and-resultant to zero and all and-constraints with
4013  * aggregated resultant, otherwise we would loose this information
4014  */
4015  for( r = nresvars - 1; r >= 0; --r )
4016  {
4017  assert( resvars != NULL );
4018  resvar = resvars[r];
4019  rhslhs = (SCIPvarGetUbLocal(resvar) < 0.5) ? 0 : ((SCIPvarGetLbLocal(resvar) > 0.5) ? 1 : -1);
4020 
4021  /* if and resultant is fixed to 0 and at least one and-variable is fixed to zero, we don't print this redundant constraint */
4022  if( rhslhs == 0 )
4023  {
4024  SCIP_Bool cont;
4025 
4026  cont = FALSE;
4027 
4028  assert( andvars != NULL && nandvars != NULL );
4029  assert( andvars[r] != NULL || nandvars[r] == 0 );
4030 
4031  /* if resultant variable and one other and variable is already zero, so we did not need to print this and
4032  * constraint because all other variables are free
4033  */
4034  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
4035  {
4036  assert( andvars[r] != NULL );
4037  assert( andvars[r][v] != NULL );
4038 
4039  if( SCIPvarGetUbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4040  {
4041  cont = TRUE;
4042  break;
4043  }
4044  }
4045 
4046  if( cont )
4047  continue;
4048  }
4049  /* if and resultant is fixed to 1 and all and-variable are fixed to 1 too, we don't print this redundant constraint */
4050  else if( rhslhs == 1 )
4051  {
4052  SCIP_Bool cont;
4053 
4054  cont = TRUE;
4055 
4056  assert( andvars != NULL && nandvars != NULL );
4057  assert( andvars[r] != NULL || nandvars[r] == 0 );
4058 
4059  /* if all variables are already fixed to one, we do not need to print this and constraint */
4060  for( v = nandvars[r] - 1; v >= 0; --v )
4061  {
4062  assert( andvars[r] != NULL );
4063  assert( andvars[r][v] != NULL );
4064 
4065  if( SCIPvarGetLbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4066  {
4067  cont = FALSE;
4068  break;
4069  }
4070  }
4071 
4072  if( cont )
4073  continue;
4074  }
4075 
4076  /* print and with fixed or aggregated and-resultant */
4077  /* rhslhs equals to 0 means the and constraint is relevant due to it's not clear on which values the and variables are
4078  * rhslhs equals to 1 means the and constraint is irrelevant cause all and variables have to be 1 too
4079  * rhslhs equals to -1 means the and constraint is relevant cause the variable is only aggregated */
4080  if( !SCIPvarIsActive(resvar) )
4081  {
4082  SCIP_VAR* var;
4083  SCIP_Bool neg;
4084  SCIP_Bool firstprinted;
4085 
4086  firstprinted = FALSE;
4087 
4088  assert( andvars != NULL && nandvars != NULL );
4089  assert( andvars[r] != NULL || nandvars[r] == 0 );
4090 
4091  for( v = nandvars[r] - 1; v >= 0; --v )
4092  {
4093  assert( andvars[r] != NULL );
4094  assert( andvars[r][v] != NULL );
4095 
4096  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4097 
4098  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", (firstprinted) ? multisymbol : "", neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"));
4099  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4100 
4101  firstprinted = TRUE;
4102  }
4103 
4104  /* if the resultant is aggregated we need to print his binary representation */
4105  if( rhslhs == -1 )
4106  {
4107  int pos;
4108 
4109  assert(transformed);
4110 
4111  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &resvar, &neg) );
4112 
4113 #ifndef NDEBUG
4114  if( neg )
4115  assert(SCIPvarIsActive(SCIPvarGetNegationVar(resvar)));
4116  else
4117  assert(SCIPvarIsActive(resvar));
4118 #endif
4119 
4120  /* replace and-resultant with corresponding variables */
4121  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, neg ? SCIPvarGetNegationVar(resvar) : resvar, nresvars, &pos) )
4122  {
4123  SCIP_Bool negated;
4124  int a;
4125 
4126  assert(andvars != NULL);
4127  assert(nandvars != NULL);
4128  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
4129  assert(andvars[pos][nandvars[pos] - 1] != NULL);
4130 
4131  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
4132 
4133  /* print and-vars */
4134  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, neg ? " +1%s%s%s" : " -1%s%s%s", multisymbol, negated ? "~" : "",
4135  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
4136  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4137 
4138  for(a = nandvars[pos] - 2; a >= 0; --a )
4139  {
4140  negated = SCIPvarIsNegated(andvars[pos][a]);
4141 
4142  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
4143  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4144  }
4145 
4146  appendBuffer(scip, file, linebuffer, &linecnt, " ");
4147 
4148  if( neg )
4149  rhslhs = 1;
4150  else
4151  rhslhs = 0;
4152  }
4153  else
4154  {
4155  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " -1%s%s%s", multisymbol, neg ? "~" : "",
4156  strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(resvar) : resvar), "x"));
4157  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4158 
4159  rhslhs = 0;
4160  }
4161  }
4162 
4163  /* print rhslhs */
4164  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " = %" SCIP_LONGINT_FORMAT " ;\n", rhslhs);
4165  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4166 
4167  writeBuffer(scip, file, linebuffer, &linecnt);
4168  }
4169  }
4170 
4171  return SCIP_OKAY;
4172 }
4173 
4174 /* writes problem to file */
4175 static
4177  SCIP* scip, /**< SCIP data structure */
4178  FILE* file, /**< output file, or NULL if standard output should be used */
4179  const char* name, /**< problem name */
4180  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4181  SCIP_OBJSENSE objsense, /**< objective sense */
4182  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4183  * extobj = objsense * objscale * (intobj + objoffset) */
4184  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4185  SCIP_VAR** vars, /**< array with active (binary) variables */
4186  int nvars, /**< number of active variables in the problem */
4187  SCIP_CONS** conss, /**< array with constraints of the problem */
4188  int nconss, /**< number of constraints in the problem */
4189  SCIP_VAR** const resvars, /**< array of resultant variables */
4190  int const nresvars, /**< number of resultant variables */
4191  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
4192  int const*const nandvars, /**< array of numbers of corresponding and-variables */
4193  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
4194  SCIP_Bool const existands, /**< does some and-constraints exist? */
4195  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4196  )
4197 {
4198  char multisymbol[OPB_MAX_LINELEN];
4199  SCIP_HASHTABLE* printedfixing;
4200  SCIP_Bool usesymbol;
4201  SCIP_RETCODE retcode;
4202  int nlinearconss;
4203  int nsplitlinearconss;
4204 
4205  assert( scip != NULL );
4206  assert( vars != NULL || nvars == 0 );
4207  assert( conss != NULL || nconss == 0 );
4208  assert( result != NULL );
4209 
4210  /* check if should use a multipliers symbol star '*' between coefficients and variables */
4211  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/multisymbol", &usesymbol) );
4212  (void) SCIPsnprintf(multisymbol, OPB_MAX_LINELEN, "%s", usesymbol ? " * " : " ");
4213 
4214  /* determine how many linear constraints are split */
4215  determineTotalNumberLinearConss(scip, conss, nconss, &nlinearconss, &nsplitlinearconss);
4216 
4217  /* print statistics as comment to file */
4218  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4219  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4220  SCIPinfoMessage(scip, file, "* Variables : %d (all binary)\n", nvars);
4221  SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss - nlinearconss + nsplitlinearconss);
4222 
4223  /* create a hash table */
4224  SCIP_CALL( SCIPhashtableCreate(&printedfixing, SCIPblkmem(scip), nvars,
4225  SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
4226 
4227  /* write objective function */
4228  SCIP_CALL( writeOpbObjective(scip, file, vars, nvars, resvars, nresvars, andvars, nandvars,
4229  objsense, objscale, objoffset, multisymbol, existands, transformed) );
4230 
4231  /* write constraints */
4232  retcode = writeOpbConstraints(scip, file, conss, nconss, vars, nvars, resvars, nresvars, andvars, nandvars,
4233  multisymbol, existandconshdlr, existands, transformed);
4234 
4235  if( existands && (retcode == SCIP_OKAY) )
4236  {
4237  /* write and constraints of inactive but relevant and-resultants and and-variables which are fixed to one
4238  with no fixed and resultant */
4239  SCIP_CALL( writeOpbRelevantAnds(scip, file, resvars, nresvars, andvars, nandvars, printedfixing, multisymbol, transformed) );
4240  }
4241 
4242  /* write fixed variables */
4243  SCIP_CALL( writeOpbFixedVars(scip, file, vars, nvars, printedfixing, multisymbol, transformed) );
4244 
4245  SCIPhashtableFree(&printedfixing);
4246 
4247  *result = SCIP_SUCCESS;
4248 
4249  return retcode;
4250 }
4251 
4252 
4253 /*
4254  * extern methods
4255  */
4256 
4257 /** reads problem from file */
4259  SCIP* scip, /**< SCIP data structure */
4260  SCIP_READER* reader, /**< the file reader itself */
4261  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
4262  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
4263  )
4264 { /*lint --e{715}*/
4265  OPBINPUT opbinput;
4266  SCIP_RETCODE retcode;
4267  int i;
4268 
4269  assert(scip != NULL); /* for lint */
4270  assert(reader != NULL);
4271 
4272  /* initialize OPB input data */
4273  opbinput.file = NULL;
4274  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &opbinput.linebuf, OPB_MAX_LINELEN) );
4275  opbinput.linebuf[0] = '\0';
4276  opbinput.linebufsize = OPB_MAX_LINELEN;
4277  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.token, OPB_MAX_LINELEN) );
4278  opbinput.token[0] = '\0';
4279  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.tokenbuf, OPB_MAX_LINELEN) );
4280  opbinput.tokenbuf[0] = '\0';
4281  for( i = 0; i < OPB_MAX_PUSHEDTOKENS; ++i )
4282  {
4283  SCIP_CALL( SCIPallocBufferArray(scip, &(opbinput.pushedtokens[i]), OPB_MAX_LINELEN) ); /*lint !e866 */
4284  }
4285 
4286  opbinput.npushedtokens = 0;
4287  opbinput.linenumber = 1;
4288  opbinput.linepos = 0;
4289  opbinput.objsense = SCIP_OBJSENSE_MINIMIZE;
4290  opbinput.eof = FALSE;
4291  opbinput.haserror = FALSE;
4292  opbinput.nproblemcoeffs = 0;
4293  opbinput.wbo = FALSE;
4294  opbinput.topcost = -SCIPinfinity(scip);
4295  opbinput.nindvars = 0;
4296 #if GENCONSNAMES == TRUE
4297  opbinput.consnumber = 0;
4298 #endif
4299 
4300  /* read the file */
4301  retcode = readOPBFile(scip, &opbinput, filename);
4302 
4303  /* free dynamically allocated memory */
4304  for( i = OPB_MAX_PUSHEDTOKENS - 1; i >= 0; --i )
4305  {
4306  SCIPfreeBufferArrayNull(scip, &(opbinput.pushedtokens[i]));
4307  }
4308  SCIPfreeBufferArrayNull(scip, &opbinput.tokenbuf);
4309  SCIPfreeBufferArrayNull(scip, &opbinput.token);
4310  SCIPfreeBlockMemoryArray(scip, &opbinput.linebuf, opbinput.linebufsize);
4311 
4312  if( retcode == SCIP_PLUGINNOTFOUND )
4313  retcode = SCIP_READERROR;
4314 
4315  SCIP_CALL( retcode );
4316 
4317  if( opbinput.nproblemcoeffs > 0 )
4318  {
4319  SCIPwarningMessage(scip, "there might be <%d> coefficients or weight out of range!\n", opbinput.nproblemcoeffs);
4320  }
4321 
4322  /* evaluate the result */
4323  if( opbinput.haserror )
4324  return SCIP_READERROR;
4325  else
4326  {
4327  /* set objective sense */
4328  SCIP_CALL( SCIPsetObjsense(scip, opbinput.objsense) );
4329  *result = SCIP_SUCCESS;
4330  }
4331 
4332  return SCIP_OKAY;
4333 }
4334 
4335 /** writes problem to file */
4337  SCIP* scip, /**< SCIP data structure */
4338  FILE* file, /**< output file, or NULL if standard output should be used */
4339  const char* name, /**< problem name */
4340  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4341  SCIP_OBJSENSE objsense, /**< objective sense */
4342  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4343  * extobj = objsense * objscale * (intobj + objoffset) */
4344  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4345  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
4346  int nvars, /**< number of active variables in the problem */
4347  int nbinvars, /**< number of binary variables */
4348  int nintvars, /**< number of general integer variables */
4349  int nimplvars, /**< number of implicit integer variables */
4350  int ncontvars, /**< number of continuous variables */
4351  SCIP_VAR** fixedvars, /**< array with fixed variables */
4352  int nfixedvars, /**< number of fixed and aggregated variables in the problem */
4353  SCIP_CONS** conss, /**< array with constraints of the problem */
4354  int nconss, /**< number of constraints in the problem */
4355  SCIP_Bool genericnames, /**< should generic variable and constraint names be used */
4356  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4357  )
4358 { /*lint --e{715}*/
4359  SCIP_RETCODE retcode = SCIP_OKAY;
4360 
4361  if( nvars != nbinvars && (nintvars > 0 || SCIPfindConshdlr(scip, "indicator") != NULL
4362  || ncontvars + nimplvars != SCIPconshdlrGetNConss(SCIPfindConshdlr(scip, "indicator"))) )
4363  {
4364  SCIPwarningMessage(scip, "only binary problems can be written in OPB format.\n");
4365  *result = SCIP_DIDNOTRUN;
4366  }
4367  else
4368  {
4369  SCIP_VAR*** andvars;
4370  SCIP_VAR** resvars;
4371  int* nandvars;
4372  SCIP_Bool existands;
4373  SCIP_Bool existandconshdlr;
4374  int nresvars;
4375  int v;
4376 
4377  /* computes all and-resultants and their corresponding constraint variables */
4378  /* coverity[leaked_storage] */
4379  SCIP_CALL( computeAndConstraintInfos(scip, transformed, &resvars, &nresvars, &andvars, &nandvars, &existandconshdlr, &existands) );
4380 
4381  if( genericnames )
4382  {
4383 #ifndef NDEBUG
4384  /* check for correct names for opb-format */
4385  int idx;
4386  int pos;
4387 
4388  for( v = nvars - 1; v >= 0; --v )
4389  {
4390  if( existands )
4391  {
4392  /* and variables are artificial */
4393  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4394  continue;
4395  }
4396 
4397  assert(sscanf(SCIPvarGetName(vars[v]), "x%d", &idx) == 1);
4398  }
4399 #endif
4400  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4401  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4402  }
4403  else
4404  {
4405  SCIP_Bool printed;
4406  int idx;
4407  int pos;
4408 
4409  printed = FALSE;
4410 
4411  /* check if there are already generic names for all (not fixed variables)*/
4412  for( v = nvars - 1; v >= 0; --v )
4413  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4414  {
4415  if( sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) == NULL )
4416  {
4417  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4418  SCIP_CALL( SCIPprintVar(scip, vars[v], NULL) );
4419  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4420 
4421  if( transformed )
4422  {
4423  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4424  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4425  }
4426  else
4427  {
4428  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4429  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4430  }
4431  printed = TRUE;
4432  break;
4433  }
4434  }
4435 
4436  if( !printed )
4437  {
4438  /* check if there are already generic names for all (fixed variables)*/
4439  for( v = nfixedvars - 1; v >= 0; --v )
4440  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4441  {
4442  /* coverity[secure_coding] */
4443  if( sscanf(SCIPvarGetName(fixedvars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(fixedvars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(fixedvars[v]), INDICATORSLACKVARNAME) == NULL )
4444  {
4445  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4446  SCIP_CALL( SCIPprintVar(scip, fixedvars[v], NULL) );
4447  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4448 
4449  if( transformed )
4450  {
4451  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4452  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4453  }
4454  else
4455  {
4456  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4457  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4458  }
4459  printed = TRUE;
4460  break;
4461  }
4462  }
4463  }
4464 
4465  if( !printed )
4466  {
4467 #ifndef NDEBUG
4468  for( v = nvars - 1; v >= 0; --v )
4469  {
4470  if( existands )
4471  {
4472  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4473  continue;
4474  }
4475 
4476  assert(sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) == 1 || strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) != NULL || strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) != NULL );
4477  }
4478 #endif
4479  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4480  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4481  }
4482  }
4483 
4484  if( existands )
4485  {
4486  /* free temporary buffers */
4487  assert(resvars != NULL);
4488  assert(andvars != NULL);
4489  assert(nandvars != NULL);
4490 
4491  for( v = nresvars - 1; v >= 0; --v )
4492  {
4493  assert(andvars[v] != NULL);
4494  SCIPfreeMemoryArray(scip, &andvars[v]);
4495  }
4496  SCIPfreeMemoryArray(scip, &nandvars);
4497  SCIPfreeMemoryArray(scip, &andvars);
4498  SCIPfreeMemoryArray(scip, &resvars);
4499  }
4500 
4501  *result = SCIP_SUCCESS;
4502  }
4503 
4504  if( retcode == SCIP_INVALIDDATA )
4505  return SCIP_WRITEERROR;
4506 
4507  return retcode;
4508 }
4509 
4510 /*
4511  * Callback methods of reader
4512  */
4513 
4514 /** copy method for reader plugins (called when SCIP copies plugins) */
4515 static
4516 SCIP_DECL_READERCOPY(readerCopyOpb)
4517 { /*lint --e{715}*/
4518  assert(scip != NULL);
4519  assert(reader != NULL);
4520  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4521 
4522  /* call inclusion method of reader */
4524 
4525  return SCIP_OKAY;
4526 }
4527 
4528 
4529 /** problem reading method of reader */
4530 static
4531 SCIP_DECL_READERREAD(readerReadOpb)
4532 { /*lint --e{715}*/
4533 
4534  SCIP_CALL( SCIPreadOpb(scip, reader, filename, result) );
4535 
4536  return SCIP_OKAY;
4537 }
4538 
4539 
4540 /** problem writing method of reader */
4541 static
4542 SCIP_DECL_READERWRITE(readerWriteOpb)
4543 { /*lint --e{715}*/
4544 
4545  SCIP_CALL( SCIPwriteOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4546  nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, genericnames, result) );
4547 
4548  return SCIP_OKAY;
4549 }
4550 
4551 /*
4552  * reader specific interface methods
4553  */
4554 
4555 /** includes the opb file reader in SCIP */
4557  SCIP* scip /**< SCIP data structure */
4558  )
4559 {
4560  SCIP_READER* reader;
4561 
4562  /* include reader */
4564 
4565  /* set non fundamental callbacks via setter functions */
4566  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOpb) );
4567  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOpb) );
4568  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteOpb) );
4569 
4570  /* add opb reader parameters */
4572  "reading/" READER_NAME "/dynamicconss", "should model constraints be subject to aging?",
4573  NULL, FALSE, FALSE/*TRUE*/, NULL, NULL) ); /* have to be FALSE, otherwise an error might inccur in restart during branch and bound */
4575  "reading/" READER_NAME "/multisymbol", "use '*' between coefficients and variables by writing to problem?",
4576  NULL, TRUE, FALSE, NULL, NULL) );
4577 
4578  return SCIP_OKAY;
4579 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPincludeReaderOpb(SCIP *scip)
Definition: reader_opb.c:4556
#define ARTIFICIALVARNAMEPREFIX
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8187
static void swapTokenBuffer(OPBINPUT *opbinput)
Definition: reader_opb.c:516
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10655
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
#define READER_DESC
Definition: reader_opb.c:126
#define INDICATORVARNAME
Definition: reader_opb.c:135
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1597
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:76
static SCIP_RETCODE printNLRow(SCIP *const scip, FILE *const file, char const *const type, SCIP_VAR **const vars, SCIP_Real const *const vals, int const nvars, SCIP_Real lhs, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Longint weight, SCIP_Longint *const mult, char const *const multisymbol)
Definition: reader_opb.c:2521
Constraint handler for variable bound constraints .
static SCIP_RETCODE writeOpb(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, int nconss, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_RESULT *result)
Definition: reader_opb.c:4176
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2497
public methods for memory management
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1298
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:886
SCIP_RETCODE SCIPgetAndDatasPseudoboolean(SCIP *const scip, SCIP_CONS *const cons, SCIP_CONS **const andconss, SCIP_Real *const andcoefs, int *const nandconss)
static SCIP_RETCODE readCoefficients(SCIP *const scip, OPBINPUT *const opbinput, char *const name, SCIP_VAR ***linvars, SCIP_Real **lincoefs, int *const nlincoefs, SCIP_VAR ****terms, SCIP_Real **termcoefs, int **ntermvars, int *const ntermcoefs, SCIP_Bool *const newsection, SCIP_Bool *const isNonlinear, SCIP_Bool *const issoftcons, SCIP_Real *const weight)
Definition: reader_opb.c:773
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9416
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:80
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
#define SCIP_MAXSTRLEN
Definition: def.h:302
static SCIP_Bool isDelimChar(char c)
Definition: reader_opb.c:232
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:117
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define INDICATORSLACKVARNAME
Definition: reader_opb.c:136
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17979
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:64
SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
static SCIP_RETCODE getBinVarsRepresentatives(SCIP *const scip, SCIP_VAR **const vars, int const nvars, SCIP_Bool const transformed)
Definition: reader_opb.c:1775
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
constraint handler for indicator constraints
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4554
#define FALSE
Definition: def.h:96
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3024
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
#define TRUE
Definition: def.h:95
#define SCIPdebug(x)
Definition: pub_message.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
#define OPB_INIT_COEFSSIZE
Definition: reader_opb.c:144
void SCIPsortPtrPtrInt(void **ptrarray1, void **ptrarray2, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_RETCODE SCIPcreateConsPseudoboolean(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR **linvars, int nlinvars, SCIP_Real *linvals, SCIP_VAR ***terms, int nterms, int *ntermvars, SCIP_Real *termvals, SCIP_VAR *indvar, SCIP_Real weight, SCIP_Bool issoftcons, SCIP_VAR *intvar, 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 SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8399
public methods for problem variables
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE printPBRow(SCIP *const scip, FILE *const file, const char *type, SCIP_VAR **const linvars, SCIP_Real *const linvals, int const nlinvars, SCIP_VAR ***const termvars, int *const ntermvars, SCIP_Real *const termvals, int const ntermvals, SCIP_Bool **const negatedarrays, SCIP_VAR *const indvar, SCIP_Real lhs, SCIP_Longint *mult, const char *multisymbol)
Definition: reader_opb.c:2936
static void pushBufferToken(OPBINPUT *opbinput)
Definition: reader_opb.c:503
#define TOPCOSTCONSNAME
Definition: reader_opb.c:137
static SCIP_DECL_READERCOPY(readerCopyOpb)
Definition: reader_opb.c:4516
enum OpbExpType OPBEXPTYPE
Definition: reader_opb.c:153
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3211
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VAR * SCIPgetIndVarPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
#define SCIP_LONGINT_MAX
Definition: def.h:172
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPreadOpb(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_opb.c:4258
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:102
public methods for SCIP variables
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17749
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
static SCIP_RETCODE writeOpbConstraints(SCIP *const scip, FILE *const file, SCIP_CONS **const conss, int const nconss, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, char const *const multisymbol, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_Bool const transformed)
Definition: reader_opb.c:3282
#define SCIPdebugMsgPrint
Definition: scip_message.h:79
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
static SCIP_RETCODE createVariable(SCIP *scip, SCIP_VAR **var, char *name)
Definition: reader_opb.c:665
static SCIP_DECL_READERREAD(readerReadOpb)
Definition: reader_opb.c:4531
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:2246
public methods for querying solving statistics
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2693
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
SCIP_VAR * w
Definition: circlepacking.c:67
public methods for managing constraints
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1250
Constraint handler for knapsack constraints of the form , x binary and .
static void clearBuffer(char *linebuffer, int *linecnt)
Definition: reader_opb.c:2088
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5166
static SCIP_Bool isEndingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:649
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1644
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, 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)
Definition: cons_and.c:5013
#define SCIPerrorMessage
Definition: pub_message.h:64
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4182
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_opb.c:1839
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2778
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17869
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5191
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17889
static const char delimchars[]
Definition: reader_fzn.c:225
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
SCIP_RETCODE SCIPwriteOpb(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_VAR **fixedvars, int nfixedvars, SCIP_CONS **conss, int nconss, SCIP_Bool genericnames, SCIP_RESULT *result)
Definition: reader_opb.c:4336
int SCIPfeof(SCIP_FILE *stream)
Definition: fileio.c:227
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
OpbSense
Definition: reader_opb.c:155
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8090
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip_mem.h:70
static SCIP_Bool isEndLine(OPBINPUT *opbinput)
Definition: reader_opb.c:527
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
Definition: scip_prob.c:3169
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17264
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3058
SCIP_RETCODE SCIPgetLinDatasWithoutAndPseudoboolean(SCIP *const scip, SCIP_CONS *const cons, SCIP_VAR **const linvars, SCIP_Real *const lincoefs, int *const nlinvars)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
int SCIPgetNLinVarsWithoutAndPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:2955
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
#define NULL
Definition: lpi_spx1.cpp:164
#define READER_EXTENSION
Definition: reader_opb.c:127
#define SCIP_CALL(x)
Definition: def.h:394
static void pushToken(OPBINPUT *opbinput)
Definition: reader_opb.c:490
static SCIP_Bool isValue(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *value)
Definition: reader_opb.c:568
int SCIPgetNOrigConss(SCIP *scip)
Definition: scip_prob.c:3142
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:1738
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE writeOpbFixedVars(SCIP *const scip, FILE *const file, SCIP_VAR **vars, int nvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
Definition: reader_opb.c:3837
static SCIP_Bool isTokenChar(char c)
Definition: reader_opb.c:253
SCIP_Real SCIPgetLhsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *type, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Longint weight, SCIP_Longint *mult, const char *multisymbol)
Definition: reader_opb.c:2752
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:299
OpbExpType
Definition: reader_opb.c:147
static SCIP_Bool isSign(OPBINPUT *opbinput, int *sign)
Definition: reader_opb.c:541
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4597
public methods for constraint handler plugins and constraints
static const char commentchars[]
Definition: reader_opb.c:190
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
wrapper functions to map file i/o to standard or zlib file i/o
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4513
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:93
#define READER_NAME
Definition: reader_opb.c:125
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:109
static SCIP_Bool getNextLine(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:320
static void determineTotalNumberLinearConss(SCIP *const scip, SCIP_CONS **const conss, int const nconss, int *nlinearconss, int *nsplitlinearconss)
Definition: reader_opb.c:3225
void SCIPprintSysError(const char *message)
Definition: misc.c:10680
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, OPBEXPTYPE *exptype)
Definition: reader_opb.c:276
static SCIP_RETCODE writeOpbRelevantAnds(SCIP *const scip, FILE *const file, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
Definition: reader_opb.c:3911
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9462
int SCIPgetNAndsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2482
static SCIP_RETCODE printNonLinearCons(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, SCIP_Real *const vals, int const nvars, SCIP_Real const lhs, SCIP_Real const rhs, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Longint weight, SCIP_Bool const transformed, char const *const multisymbol)
Definition: reader_opb.c:2655
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8110
methods for debugging
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_opb.c:375
SCIP_CONS * SCIPgetLinearConsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
static SCIP_RETCODE readConstraints(SCIP *scip, OPBINPUT *opbinput, int *nNonlinearConss)
Definition: reader_opb.c:1335
static void appendBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_opb.c:2126
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17771
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:114
static SCIP_Bool isSense(OPBINPUT *opbinput, OPBSENSE *sense)
Definition: reader_opb.c:602
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool getNextToken(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:389
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7980
Constraint handler for linear constraints in their most general form, .
static SCIP_RETCODE computeAndConstraintInfos(SCIP *const scip, SCIP_Bool const transformed, SCIP_VAR ***resvars, int *nresvars, SCIP_VAR ****andvars, int **nandvars, SCIP_Bool *const existandconshdlr, SCIP_Bool *const existands)
Definition: reader_opb.c:1884
static SCIP_RETCODE getMaxAndConsDim(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *objoffset)
Definition: reader_opb.c:1568
static SCIP_RETCODE printPseudobooleanCons(SCIP *const scip, FILE *const file, SCIP_VAR **const linvars, SCIP_Real *const linvals, int const nlinvars, SCIP_VAR ***const termvars, int *const ntermvars, SCIP_Real *const termvals, int const ntermvals, SCIP_VAR *const indvar, SCIP_Real const lhs, SCIP_Real const rhs, SCIP_Bool transformed, const char *multisymbol)
Definition: reader_opb.c:3073
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12786
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9439
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2296
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2000
enum OpbSense OPBSENSE
Definition: reader_opb.c:162
static SCIP_Bool hasError(OPBINPUT *opbinput)
Definition: reader_opb.c:221
SCIP_Real * r
Definition: circlepacking.c:59
methods for sorting joint arrays of various types
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 SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
static void writeBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_opb.c:2103
pseudo-Boolean file reader (opb format)
static const SCIP_Real scalars[]
Definition: lp.c:5747
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1676
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE getVariableOrTerm(SCIP *scip, OPBINPUT *opbinput, SCIP_VAR ***vars, int *nvars, int *varssize)
Definition: reader_opb.c:697
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3050
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1119
#define OPB_MAX_PUSHEDTOKENS
Definition: reader_opb.c:143
public methods for message output
SCIP_VAR * a
Definition: circlepacking.c:66
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1955
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17383
static SCIP_RETCODE setObjective(SCIP *const scip, OPBINPUT *const opbinput, const char *sense, SCIP_VAR **const linvars, SCIP_Real *const coefs, int const ncoefs, SCIP_VAR ***const terms, SCIP_Real *const termcoefs, int *const ntermvars, int const ntermcoefs)
Definition: reader_opb.c:1127
#define SCIP_Real
Definition: def.h:186
static void syntaxError(SCIP *scip, OPBINPUT *opbinput, const char *msg)
Definition: reader_opb.c:197
public methods for input file readers
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5142
#define OPB_MAX_LINELEN
Definition: reader_opb.c:142
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for message handling
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
#define SCIP_Longint
Definition: def.h:171
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17603
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:298
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17429
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2609
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
constraint handler for pseudoboolean constraints
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17989
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE writeOpbObjective(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_OBJSENSE const objsense, SCIP_Real const objscale, SCIP_Real const objoffset, char const *const multisymbol, SCIP_Bool const existands, SCIP_Bool const transformed)
Definition: reader_opb.c:2149
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3106
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:132
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
struct OpbInput OPBINPUT
Definition: reader_opb.c:188
#define SCIP_CALL_ABORT(x)
Definition: def.h:373
static SCIP_RETCODE readOPBFile(SCIP *scip, OPBINPUT *opbinput, const char *filename)
Definition: reader_opb.c:1676
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for reader plugins
static SCIP_DECL_READERWRITE(readerWriteOpb)
Definition: reader_opb.c:4542
#define SCIPABORT()
Definition: def.h:366
public methods for global and local (sub)problems
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE printLinearCons(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_Longint weight, SCIP_Bool transformed, const char *multisymbol)
Definition: reader_opb.c:2847
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9885
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
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:57
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17593
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17419
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
SCIP_Real SCIPgetRhsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
memory allocation routines
static SCIP_Bool isStartingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:633