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_Real const scale, /**< objective scale */
1132  SCIP_VAR**const linvars, /**< array of linear variables */
1133  SCIP_Real*const coefs, /**< array of objective values for linear variables */
1134  int const ncoefs, /**< number of coefficients for linear part */
1135  SCIP_VAR***const terms, /**< array with nonlinear variables */
1136  SCIP_Real*const termcoefs, /**< array of objective values for nonlinear variables */
1137  int*const ntermvars, /**< number of nonlinear variables in the terms */
1138  int const ntermcoefs /**< number of nonlinear coefficients */
1139  )
1140 {
1141  assert(scip != NULL);
1142  assert(opbinput != NULL);
1143  assert(isEndLine(opbinput));
1144  assert(ncoefs == 0 || (linvars != NULL && coefs != NULL));
1145  assert(ntermcoefs == 0 || (terms != NULL && ntermvars != NULL && termcoefs != NULL));
1146 
1147  if( !hasError(opbinput) )
1148  {
1149  SCIP_VAR* var;
1150  int v;
1151  char name[SCIP_MAXSTRLEN];
1152 
1153  if( strcmp(sense, "max" ) == 0 )
1154  opbinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
1155 
1156  /* @todo: what todo with non-linear objectives, maybe create the necessary and-constraints and add the arising linear
1157  * objective (with and-resultants) or add a integer variable to this constraint and put only this variable in the
1158  * objective, for this we need to expand the pseudo-boolean constraints to handle integer variables
1159  *
1160  * integer variant is not implemented
1161  */
1162  if( ntermcoefs > 0 )
1163  {
1164 #if (LINEAROBJECTIVE == TRUE)
1165  /* all non-linear parts are created as and-constraints, even if the same non-linear part was already part of the objective function */
1166 
1167  SCIP_VAR** vars;
1168  int nvars;
1169  int t;
1170  SCIP_CONS* andcons;
1171 
1172  for( t = 0; t < ntermcoefs; ++t )
1173  {
1174  assert(terms != NULL); /* for lint */
1175  assert(ntermvars != NULL);
1176  assert(termcoefs != NULL);
1177 
1178  vars = terms[t];
1179  nvars = ntermvars[t];
1180  assert(vars != NULL);
1181  assert(nvars > 1);
1182 
1183  /* create auxiliary variable */
1184  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"obj_%d", t);
1185  SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, 1.0, termcoefs[t], SCIP_VARTYPE_BINARY,
1186  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1187 
1188  /* @todo: check if it is better to change the branching priority for the artificial variables */
1189 #if 1
1190  /* change branching priority of artificial variable to -1 */
1191  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1192 #endif
1193 
1194  /* add auxiliary variable to the problem */
1195  SCIP_CALL( SCIPaddVar(scip, var) );
1196 
1197 #ifdef WITH_DEBUG_SOLUTION
1198  if( SCIPdebugIsMainscip(scip) )
1199  {
1200  SCIP_Real val = 0.0;
1201 
1202  for( v = nvars - 1; v >= 0; --v )
1203  {
1204  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1205  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1206 
1207  if( val < 0.5 )
1208  break;
1209  }
1210  SCIP_CALL( SCIPdebugAddSolVal(scip, var, (val < 0.5) ? 0.0 : 1.0) );
1211  }
1212 #endif
1213 
1214  /* @todo: check whether all constraint creation flags are the best option */
1215  /* create and-constraint */
1216  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "obj_andcons_%d", t);
1217  SCIP_CALL( SCIPcreateConsAnd(scip, &andcons, name, var, nvars, vars,
1218  TRUE, TRUE, TRUE, TRUE, TRUE,
1219  FALSE, FALSE, FALSE, FALSE, FALSE) );
1220  SCIP_CALL( SCIPaddCons(scip, andcons) );
1221  SCIPdebugPrintCons(scip, andcons, NULL);
1222  SCIP_CALL( SCIPreleaseCons(scip, &andcons) );
1223 
1224  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1225  }
1226 #else /* now the integer variant */
1227  SCIP_CONS* pseudocons;
1228  SCIP_Real lb;
1229  SCIP_Real ub;
1230 
1231  lb = 0.0;
1232  ub = 0.0;
1233 
1234  /* add all non linear coefficients up */
1235  for( v = 0; v < ntermcoefs; ++v )
1236  {
1237  if( termcoefs[v] < 0 )
1238  lb += termcoefs[v];
1239  else
1240  ub += termcoefs[v];
1241  }
1242  /* add all linear coefficients up */
1243  for( v = 0; v < ncoefs; ++v )
1244  {
1245  if( coefs[v] < 0 )
1246  lb += coefs[v];
1247  else
1248  ub += coefs[v];
1249  }
1250  assert(lb < ub);
1251 
1252  /* create auxiliary variable */
1253  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_int_obj");
1254  SCIP_CALL( SCIPcreateVar(scip, &var, name, lb, ub, 1.0, SCIP_VARTYPE_INTEGER,
1255  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1256 
1257  /* @todo: check if it is better to change the branching priority for the artificial variables */
1258 #if 1
1259  /* change branching priority of artificial variable to -1 */
1260  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1261 #endif
1262  /* add auxiliary variable to the problem */
1263  SCIP_CALL( SCIPaddVar(scip, var) );
1264 
1265 #ifdef WITH_DEBUG_SOLUTION
1266  if( SCIPdebugIsMainscip(scip) )
1267  {
1268  SCIP_Real artval = 0.0;
1269  SCIP_Real val;
1270 
1271  for( t = 0; t < ntermcoefs; ++t )
1272  {
1273  vars = terms[t];
1274  nvars = ntermvars[t];
1275  assert(vars != NULL);
1276  assert(nvars > 1);
1277 
1278  for( v = nvars - 1; v >= 0; --v )
1279  {
1280  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1281  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1282 
1283  if( val < 0.5 )
1284  break;
1285  }
1286 
1287  artval += (((val < 0.5) ? 0.0 : 1.0) * termcoefs[t]);
1288  }
1289  assert(SCIPisFeasLE(scip, lb, artval) && SCIPisFeasGE(scip, ub, artval));
1290 
1291  SCIP_CALL( SCIPdebugAddSolVal(scip, var, artval) );
1292  }
1293 #endif
1294 
1295  /* create artificial objection function constraint containing the artificial integer variable */
1296  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_obj_cons");
1297  SCIP_CALL( SCIPcreateConsPseudoboolean(scip, &pseudocons, name, linvars, ncoefs, coefs, terms, ntermcoefs,
1298  ntermvars, termcoefs, NULL, 0.0, FALSE, var, 0.0, 0.0,
1299  TRUE, TRUE, TRUE, TRUE, TRUE,
1300  FALSE, FALSE, FALSE, FALSE, FALSE) );
1301 
1302  SCIP_CALL( SCIPaddCons(scip, pseudocons) );
1303  SCIPdebugPrintCons(scip, pseudocons, NULL);
1304  SCIP_CALL( SCIPreleaseCons(scip, &pseudocons) );
1305 
1306  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1307 
1308  return SCIP_OKAY;
1309 #endif
1310  }
1311  /* set the objective values */
1312  for( v = 0; v < ncoefs; ++v )
1313  {
1314  assert(linvars != NULL); /* for lint */
1315  assert(coefs != NULL);
1316 
1317  if( SCIPvarIsNegated(linvars[v]) )
1318  {
1319  SCIP_VAR* negvar = SCIPvarGetNegationVar(linvars[v]);
1320 
1321  SCIP_CALL( SCIPaddOrigObjoffset(scip, coefs[v]) );
1322  SCIP_CALL( SCIPaddVarObj(scip, negvar, -scale * coefs[v]) );
1323  }
1324  else
1325  {
1326  SCIP_CALL( SCIPaddVarObj(scip, linvars[v], scale * coefs[v]) );
1327  }
1328  }
1329  }
1330 
1331  return SCIP_OKAY;
1332 }
1333 
1334 /** reads the constraints section */
1335 static
1337  SCIP* scip, /**< SCIP data structure */
1338  OPBINPUT* opbinput, /**< OPB reading data */
1339  SCIP_Real objscale, /**< objective scale */
1340  int* nNonlinearConss /**< pointer to store number of nonlinear constraints */
1341  )
1342 {
1343  char name[OPB_MAX_LINELEN];
1344  SCIP_CONS* cons;
1345  SCIP_VAR** linvars;
1346  SCIP_Real* lincoefs;
1347  int nlincoefs;
1348  SCIP_VAR*** terms;
1349  SCIP_Real* termcoefs;
1350  int* ntermvars;
1351  int ntermcoefs;
1352  OPBSENSE sense;
1353  SCIP_RETCODE retcode;
1354  SCIP_Real sidevalue;
1355  SCIP_Real lhs;
1356  SCIP_Real rhs;
1357  SCIP_Bool newsection;
1358  SCIP_Bool initialconss;
1359  SCIP_Bool dynamicconss;
1360  SCIP_Bool dynamicrows;
1361  SCIP_Bool initial;
1362  SCIP_Bool separate;
1363  SCIP_Bool enforce;
1364  SCIP_Bool check;
1365  SCIP_Bool propagate;
1366  SCIP_Bool local;
1367  SCIP_Bool modifiable;
1368  SCIP_Bool dynamic;
1369  SCIP_Bool removable;
1370  SCIP_Bool isNonlinear;
1371  int sidesign;
1372  SCIP_Bool issoftcons;
1373  SCIP_Real weight;
1374  SCIP_VAR* indvar;
1375  char indname[SCIP_MAXSTRLEN];
1376  int t;
1377 
1378  assert(scip != NULL);
1379  assert(opbinput != NULL);
1380  assert(nNonlinearConss != NULL);
1381 
1382  weight = -SCIPinfinity(scip);
1383  retcode = SCIP_OKAY;
1384 
1385  /* read the objective coefficients */
1386  SCIP_CALL( readCoefficients(scip, opbinput, name, &linvars, &lincoefs, &nlincoefs, &terms, &termcoefs, &ntermvars, &ntermcoefs, &newsection, &isNonlinear, &issoftcons, &weight) );
1387 
1388  if( hasError(opbinput) || opbinput->eof )
1389  goto TERMINATE;
1390  if( newsection )
1391  {
1392  if( strcmp(name, "min") == 0 || strcmp(name, "max") == 0 )
1393  {
1394  if( opbinput->wbo )
1395  {
1396  syntaxError(scip, opbinput, "Cannot have an objective function when having soft constraints.\n");
1397  goto TERMINATE;
1398  }
1399 
1400  /* set objective function */
1401  SCIP_CALL( setObjective(scip, opbinput, name, objscale, linvars, lincoefs, nlincoefs, terms, termcoefs, ntermvars, ntermcoefs) );
1402  }
1403  else if( strcmp(name, "soft") == 0 )
1404  {
1405  /* we have a "weighted boolean optimization"-file(wbo) */
1406  opbinput->wbo = TRUE;
1407  if( nlincoefs == 0 )
1408  opbinput->topcost = SCIPinfinity(scip);
1409  else
1410  {
1411  assert(nlincoefs == 1);
1412  assert(lincoefs != NULL);
1413  opbinput->topcost = lincoefs[0];
1414  }
1415  SCIPdebugMsg(scip, "Weighted Boolean Optimization problem has topcost of %g\n", opbinput->topcost);
1416  }
1417  else if( nlincoefs > 0 )
1418  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='");
1419  goto TERMINATE;
1420  }
1421 
1422  /* read the constraint sense */
1423  if( !getNextToken(scip, opbinput) )
1424  {
1425  syntaxError(scip, opbinput, "expected constraint sense.");
1426  goto TERMINATE;
1427  }
1428  if( !isSense(opbinput, &sense) )
1429  {
1430  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='.");
1431  goto TERMINATE;
1432  }
1433 
1434  /* read the right hand side */
1435  sidesign = +1;
1436  if( !getNextToken(scip, opbinput) )
1437  {
1438  syntaxError(scip, opbinput, "missing right hand side");
1439  goto TERMINATE;
1440  }
1441  if( isSign(opbinput, &sidesign) )
1442  {
1443  if( !getNextToken(scip, opbinput) )
1444  {
1445  syntaxError(scip, opbinput, "missing value of right hand side");
1446  goto TERMINATE;
1447  }
1448  }
1449  if( !isValue(scip, opbinput, &sidevalue) )
1450  {
1451  syntaxError(scip, opbinput, "expected value as right hand side");
1452  goto TERMINATE;
1453  }
1454  sidevalue *= sidesign;
1455 
1456  /* check if we reached the line end */
1457  if( !getNextToken(scip, opbinput) || !isEndLine(opbinput) )
1458  {
1459  syntaxError(scip, opbinput, "expected endline character ';'");
1460  goto TERMINATE;
1461  }
1462 
1463  /* assign the left and right hand side, depending on the constraint sense */
1464  switch( sense ) /*lint !e530*/
1465  {
1466  case OPB_SENSE_GE:
1467  lhs = sidevalue;
1468  rhs = SCIPinfinity(scip);
1469  break;
1470  case OPB_SENSE_LE:
1471  lhs = -SCIPinfinity(scip);
1472  rhs = sidevalue;
1473  break;
1474  case OPB_SENSE_EQ:
1475  lhs = sidevalue;
1476  rhs = sidevalue;
1477  break;
1478  case OPB_SENSE_NOTHING:
1479  default:
1480  SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1481  return SCIP_INVALIDDATA;
1482  }
1483 
1484  /* create and add the linear constraint */
1485  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
1486  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
1487  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/dynamicconss", &dynamicconss) );
1488 
1489  initial = initialconss;
1490  separate = TRUE;
1491  enforce = TRUE;
1492  check = TRUE;
1493  propagate = TRUE;
1494  local = FALSE;
1495  modifiable = FALSE;
1496  dynamic = FALSE;/*dynamicconss;*/
1497  removable = dynamicrows;
1498 
1499  /* create corresponding constraint */
1500  if( issoftcons )
1501  {
1502  (void) SCIPsnprintf(indname, SCIP_MAXSTRLEN, INDICATORVARNAME"%d", opbinput->nindvars);
1503  ++(opbinput->nindvars);
1504  SCIP_CALL( createVariable(scip, &indvar, indname) );
1505 
1506  assert(!SCIPisInfinity(scip, -weight));
1507  SCIP_CALL( SCIPchgVarObj(scip, indvar, objscale * weight) );
1508  }
1509  else
1510  indvar = NULL;
1511 
1512  if( ntermcoefs > 0 || issoftcons )
1513  {
1514 #if GENCONSNAMES == TRUE
1515  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean%d", opbinput->consnumber);
1516  ++(opbinput->consnumber);
1517 #else
1518  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean");
1519 #endif
1520  retcode = SCIPcreateConsPseudoboolean(scip, &cons, name, linvars, nlincoefs, lincoefs, terms, ntermcoefs,
1521  ntermvars, termcoefs, indvar, weight, issoftcons, NULL, lhs, rhs,
1522  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1523  if( retcode != SCIP_OKAY )
1524  goto TERMINATE;
1525  }
1526  else
1527  {
1528 #if GENCONSNAMES == TRUE
1529  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear%d", opbinput->consnumber);
1530  ++(opbinput->consnumber);
1531 #else
1532  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear");
1533 #endif
1534  retcode = SCIPcreateConsLinear(scip, &cons, name, nlincoefs, linvars, lincoefs, lhs, rhs,
1535  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1536  if( retcode != SCIP_OKAY )
1537  goto TERMINATE;
1538  }
1539 
1540  SCIP_CALL( SCIPaddCons(scip, cons) );
1541  SCIPdebugMsg(scip, "(line %d) created constraint: ", opbinput->linenumber);
1542  SCIPdebugPrintCons(scip, cons, NULL);
1543  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1544 
1545  if( isNonlinear )
1546  ++(*nNonlinearConss);
1547 
1548  TERMINATE:
1549 
1550  /* free memory */
1551  for( t = ntermcoefs - 1; t >= 0; --t )
1552  {
1553  assert(terms != NULL); /* for lint */
1554  SCIPfreeBufferArrayNull(scip, &(terms[t]));
1555  }
1556 
1557  SCIPfreeBufferArrayNull(scip, &ntermvars);
1558  SCIPfreeBufferArrayNull(scip, &termcoefs);
1559  SCIPfreeBufferArrayNull(scip, &terms);
1560  SCIPfreeBufferArrayNull(scip, &lincoefs);
1561  SCIPfreeBufferArrayNull(scip, &linvars);
1562 
1563  SCIP_CALL( retcode );
1564 
1565  return SCIP_OKAY;
1566 }
1567 
1568 /** tries to read the first comment line which usually contains information about the max size of "and" products */
1569 static
1571  SCIP* scip, /**< SCIP data structure */
1572  OPBINPUT* opbinput, /**< OPB reading data */
1573  SCIP_Real* objscale, /**< pointer to store objective scale */
1574  SCIP_Real* objoffset /**< pointer to store objective offset */
1575  )
1576 {
1577  SCIP_Bool stop;
1578  char* commentstart;
1579  char* nproducts;
1580  char* str;
1581  int i;
1582 
1583  assert(scip != NULL);
1584  assert(opbinput != NULL);
1585  assert(objoffset != NULL);
1586 
1587  stop = FALSE;
1588  commentstart = NULL;
1589  nproducts = NULL;
1590  *objscale = 1.0;
1591  *objoffset = 0.0;
1592  opbinput->linebuf[opbinput->linebufsize - 2] = '\0';
1593 
1594  do
1595  {
1596  if( SCIPfgets(opbinput->linebuf, opbinput->linebufsize, opbinput->file) == NULL )
1597  {
1598  assert( SCIPfeof(opbinput->file) );
1599  break;
1600  }
1601 
1602  /* if line is too long for our buffer reallocate buffer */
1603  while( opbinput->linebuf[opbinput->linebufsize - 2] != '\0' )
1604  {
1605  int newsize;
1606 
1607  newsize = SCIPcalcMemGrowSize(scip, opbinput->linebufsize + 1);
1608  SCIP_CALL_ABORT( SCIPreallocBlockMemoryArray(scip, &opbinput->linebuf, opbinput->linebufsize, newsize) );
1609 
1610  opbinput->linebuf[newsize-2] = '\0';
1611  if ( SCIPfgets(opbinput->linebuf + opbinput->linebufsize - 1, newsize - opbinput->linebufsize + 1, opbinput->file) == NULL )
1612  return SCIP_READERROR;
1613  opbinput->linebufsize = newsize;
1614  }
1615  opbinput->linebuf[opbinput->linebufsize - 1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
1616 
1617  /* read characters after comment symbol */
1618  for( i = 0; commentchars[i] != '\0'; ++i )
1619  {
1620  commentstart = strchr(opbinput->linebuf, commentchars[i]);
1621 
1622  /* found a comment line */
1623  if( commentstart != NULL )
1624  {
1625  /* search for "#product= xyz" in comment line, where xyz represents the number of and constraints */
1626  nproducts = strstr(opbinput->linebuf, "#product= ");
1627  if( nproducts != NULL )
1628  {
1629  const char delimchars[] = " \t";
1630  char* pos;
1631 
1632  nproducts += strlen("#product= ");
1633 
1634  pos = strtok(nproducts, delimchars);
1635 
1636  if( pos != NULL )
1637  {
1638  SCIPdebugMsg(scip, "%d products supposed to be in file.\n", atoi(pos));
1639  }
1640 
1641  pos = strtok (NULL, delimchars);
1642 
1643  if( pos != NULL && strcmp(pos, "sizeproduct=") == 0 )
1644  {
1645  pos = strtok (NULL, delimchars);
1646  if( pos != NULL )
1647  {
1648  SCIPdebugMsg(scip, "sizeproducts = %d\n", atoi(pos));
1649  }
1650  }
1651 
1652  stop = TRUE;
1653  }
1654 
1655  /* search for "Obj. scale : <number>" in comment line */
1656  str = strstr(opbinput->linebuf, "Obj. scale : ");
1657  if( str != NULL )
1658  {
1659  str += strlen("Obj. scale : ");
1660  *objscale = atof(str);
1661  break;
1662  }
1663 
1664  /* search for "Obj. offset : <number>" in comment line */
1665  str = strstr(opbinput->linebuf, "Obj. offset : ");
1666  if( str != NULL )
1667  {
1668  str += strlen("Obj. offset : ");
1669  *objoffset = atof(str);
1670  break;
1671  }
1672 
1673  /* make sure that comment vanishes */
1674  *commentstart = '\0';
1675 
1676  break;
1677  }
1678  }
1679  }
1680  while(commentstart != NULL && !stop);
1681 
1682  return SCIP_OKAY;
1683 }
1684 
1685 /** reads an OPB file */
1686 static
1688  SCIP* scip, /**< SCIP data structure */
1689  OPBINPUT* opbinput, /**< OPB reading data */
1690  const char* filename /**< name of the input file */
1691  )
1692 {
1693  SCIP_Real objscale;
1694  SCIP_Real objoffset;
1695  int nNonlinearConss;
1696  int i;
1697 
1698  assert(scip != NULL);
1699  assert(opbinput != NULL);
1700 
1701  /* open file */
1702  opbinput->file = SCIPfopen(filename, "r");
1703  if( opbinput->file == NULL )
1704  {
1705  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
1706  SCIPprintSysError(filename);
1707  return SCIP_NOFILE;
1708  }
1709 
1710  /* @todo: reading additional information about the number of and constraints in comments to avoid reallocating
1711  * "opbinput.andconss"
1712  */
1713 
1714  /* tries to read the first comment line which usually contains information about the max size of "and" products */
1715  SCIP_CALL( getMaxAndConsDim(scip, opbinput, &objscale, &objoffset) );
1716 
1717  /* create problem */
1718  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1719 
1720  /* opb format supports only minimization; therefore, flip objective sense for negative objective scale */
1721  if( objscale < 0.0 )
1722  opbinput->objsense = (SCIP_OBJSENSE)(-1 * (int)(opbinput->objsense));
1723 
1724  if( ! SCIPisZero(scip, objoffset) )
1725  {
1726  SCIP_CALL( SCIPaddOrigObjoffset(scip, objscale * objoffset) );
1727  }
1728 
1729  nNonlinearConss = 0;
1730 
1731  while( !SCIPfeof( opbinput->file ) && !hasError(opbinput) )
1732  {
1733  SCIP_CALL( readConstraints(scip, opbinput, objscale, &nNonlinearConss) );
1734  }
1735 
1736  /* if we read a wbo file we need to make sure that the top cost won't be exceeded */
1737  if( opbinput->wbo )
1738  {
1739  SCIP_VAR** topcostvars;
1740  SCIP_Real* topcosts;
1741  SCIP_VAR** vars;
1742  int nvars;
1743  int ntopcostvars;
1744  SCIP_Longint topcostrhs;
1745  SCIP_CONS* topcostcons;
1746 
1747  nvars = SCIPgetNVars(scip);
1748  vars = SCIPgetVars(scip);
1749  assert(nvars > 0 || vars != NULL);
1750 
1751  SCIP_CALL( SCIPallocBufferArray(scip, &topcostvars, nvars) );
1752  SCIP_CALL( SCIPallocBufferArray(scip, &topcosts, nvars) );
1753 
1754  ntopcostvars = 0;
1755  for( i = nvars - 1; i >= 0; --i )
1756  if( !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
1757  {
1758  topcostvars[ntopcostvars] = vars[i];
1759  topcosts[ntopcostvars] = SCIPvarGetObj(vars[i]);
1760  ++ntopcostvars;
1761  }
1762 
1763  if( SCIPisIntegral(scip, opbinput->topcost) )
1764  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost - 1);
1765  else
1766  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost);
1767 
1768  SCIP_CALL( SCIPcreateConsLinear(scip, &topcostcons, TOPCOSTCONSNAME, ntopcostvars, topcostvars, topcosts, -SCIPinfinity(scip),
1769  (SCIP_Real) topcostrhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1770  SCIP_CALL( SCIPaddCons(scip, topcostcons) );
1771  SCIPdebugPrintCons(scip, topcostcons, NULL);
1772  SCIP_CALL( SCIPreleaseCons(scip, &topcostcons) );
1773 
1774  SCIPfreeBufferArray(scip, &topcosts);
1775  SCIPfreeBufferArray(scip, &topcostvars);
1776  }
1777 
1778  /* close file */
1779  SCIPfclose(opbinput->file);
1780 
1781  return SCIP_OKAY;
1782 }
1783 
1784 
1785 /*
1786  * Local methods (for writing)
1787  */
1788 
1789 /** transforms given and constraint variables to the corresponding active or negated variables */
1790 static
1792  SCIP*const scip, /**< SCIP data structure */
1793  SCIP_VAR**const vars, /**< vars array to get active variables for */
1794  int const nvars, /**< pointer to number of variables and values in vars and vals array */
1795  SCIP_Bool const transformed /**< transformed constraint? */
1796  )
1797 {
1798  SCIP_Bool negated;
1799  int v;
1800 
1801  assert( scip != NULL );
1802  assert( vars != NULL );
1803  assert( nvars > 0 );
1804 
1805  if( transformed )
1806  {
1807  for( v = nvars - 1; v >= 0; --v )
1808  {
1809  /* gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1810  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1811  */
1812  SCIP_CALL( SCIPgetBinvarRepresentative( scip, vars[v], &vars[v], &negated) );
1813  }
1814  }
1815  else
1816  {
1817  SCIP_Real scalar;
1818  SCIP_Real constant;
1819 
1820  for( v = nvars - 1; v >= 0; --v )
1821  {
1822  scalar = 1.0;
1823  constant = 0.0;
1824 
1825  /* retransforms given variable, scalar and constant to the corresponding original variable, scalar and constant,
1826  * if possible; if the retransformation is impossible, NULL is returned as variable
1827  */
1828  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalar, &constant) );
1829 
1830  if( vars[v] == NULL )
1831  {
1832  SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable.\n");
1833  return SCIP_INVALIDDATA;
1834  }
1835  if( SCIPisEQ(scip, scalar, -1.0) && SCIPisEQ(scip, constant, 1.0) )
1836  {
1837  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &vars[v]) );
1838  }
1839  else
1840  {
1841  if( !SCIPisEQ(scip, scalar, 1.0) || !SCIPisZero(scip, constant) )
1842  {
1843  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);
1844  return SCIP_INVALIDDATA;
1845  }
1846  }
1847  }
1848  }
1849 
1850  return SCIP_OKAY;
1851 }
1852 
1853 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
1854 static
1856  SCIP* scip, /**< SCIP data structure */
1857  SCIP_VAR** vars, /**< vars array to get active variables for */
1858  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
1859  int* nvars, /**< pointer to number of variables and values in vars and vals array */
1860  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
1861  SCIP_Bool transformed /**< transformed constraint? */
1862  )
1863 {
1864  int requiredsize;
1865  int v;
1866 
1867  assert(scip != NULL);
1868  assert(vars != NULL);
1869  assert(scalars != NULL);
1870  assert(nvars != NULL);
1871  assert(constant != NULL);
1872 
1873  if( transformed )
1874  {
1875  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
1876 
1877  if( requiredsize > *nvars )
1878  {
1879  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
1880  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
1881 
1882  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
1883  assert( requiredsize <= *nvars );
1884  }
1885  }
1886  else
1887  for( v = 0; v < *nvars; ++v )
1888  {
1889  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
1890 
1891  if( vars[v] == NULL )
1892  return SCIP_INVALIDDATA;
1893  }
1894 
1895  return SCIP_OKAY;
1896 }
1897 
1898 /* computes all and-resultants and their corresponding constraint variables */
1899 static
1901  SCIP*const scip, /**< SCIP data structure */
1902  SCIP_Bool const transformed, /**< transformed problem? */
1903  SCIP_VAR*** resvars, /**< pointer to store all resultant variables */
1904  int* nresvars, /**< pointer to store the number of all resultant variables */
1905  SCIP_VAR**** andvars, /**< pointer to store to all resultant variables their corresponding active( or negated) and-constraint variables */
1906  int** nandvars, /**< pointer to store the number of all corresponding and-variables to their corresponding resultant variable */
1907  SCIP_Bool*const existandconshdlr, /**< pointer to store whether the and-constrainthandler exists*/
1908  SCIP_Bool*const existands /**< pointer to store if their exists some and-constraints */
1909  )
1910 {
1911  SCIP_CONSHDLR* conshdlr;
1912 
1913  assert(scip != NULL);
1914  assert(resvars != NULL);
1915  assert(nresvars != NULL);
1916  assert(andvars != NULL);
1917  assert(nandvars != NULL);
1918  assert(existandconshdlr != NULL);
1919  assert(existands != NULL);
1920 
1921  *resvars = NULL;
1922  *nandvars = NULL;
1923  *andvars = NULL;
1924  *nresvars = 0;
1925 
1926  /* detect all and-resultants */
1927  conshdlr = SCIPfindConshdlr(scip, "and");
1928  if( conshdlr != NULL )
1929  {
1930  SCIP_CONS** andconss;
1931  int nandconss;
1932  int* shouldnotbeinand;
1933  int a;
1934  int c;
1935  int r;
1936  int v;
1937  int pos;
1938  int ncontainedands;
1939 
1940  andconss = NULL;
1941  nandconss = 0;
1942  *existandconshdlr = TRUE;
1943 
1944  /* if we write the original problem we need to get the original and constraints */
1945  if( !transformed )
1946  {
1947  SCIP_CONS** origconss;
1948  int norigconss;
1949 
1950  origconss = SCIPgetOrigConss(scip);
1951  norigconss = SCIPgetNOrigConss(scip);
1952 
1953  /* allocate memory for all possible and-constraints */
1954  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, norigconss) );
1955 
1956  /* collect all original and-constraints */
1957  for( c = norigconss - 1; c >= 0; --c )
1958  {
1959  conshdlr = SCIPconsGetHdlr(origconss[c]);
1960  assert( conshdlr != NULL );
1961 
1962  if( strcmp(SCIPconshdlrGetName(conshdlr), "and") == 0 )
1963  {
1964  andconss[nandconss] = origconss[c];
1965  ++nandconss;
1966  }
1967  }
1968  }
1969  else
1970  {
1971  nandconss = SCIPconshdlrGetNConss(conshdlr);
1972  andconss = SCIPconshdlrGetConss(conshdlr);
1973  }
1974 
1975  assert(andconss != NULL || nandconss == 0);
1976 
1977  *nresvars = nandconss;
1978 
1979  if( nandconss > 0 )
1980  {
1981  *existands = TRUE;
1982 
1983  assert(andconss != NULL);
1984 
1985  SCIP_CALL( SCIPallocMemoryArray(scip, resvars, *nresvars) );
1986  SCIP_CALL( SCIPallocMemoryArray(scip, andvars, *nresvars) );
1987  SCIP_CALL( SCIPallocMemoryArray(scip, nandvars, *nresvars) );
1988 
1989  /* collect all and-constraint variables */
1990  for( c = nandconss - 1; c >= 0; --c )
1991  {
1992  SCIP_VAR** scipandvars;
1993 
1994  assert(andconss[c] != NULL);
1995 
1996  scipandvars = SCIPgetVarsAnd(scip, andconss[c]);
1997  (*nandvars)[c] = SCIPgetNVarsAnd(scip, andconss[c]);
1998  SCIP_CALL( SCIPduplicateMemoryArray(scip, &((*andvars)[c]), scipandvars, (*nandvars)[c]) ); /*lint !e866 */
1999  SCIP_CALL( getBinVarsRepresentatives(scip, (*andvars)[c], (*nandvars)[c], transformed) );
2000 
2001  (*resvars)[c] = SCIPgetResultantAnd(scip, andconss[c]);
2002 
2003  assert((*andvars)[c] != NULL && (*nandvars)[c] > 0);
2004  assert((*resvars)[c] != NULL);
2005  }
2006 
2007  /* sorted the array */
2008  SCIPsortPtrPtrInt((void**)(*resvars), (void**)(*andvars), (*nandvars), SCIPvarComp, (*nresvars));
2009  }
2010  else
2011  *existands = FALSE;
2012 
2013  SCIP_CALL( SCIPallocBufferArray(scip, &shouldnotbeinand, *nresvars) );
2014 
2015  /* check that all and-constraints doesn't contain any and-resultants, if they do try to resolve this */
2016  /* 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
2017  deleted and the inequality from before needs to be added ) */
2018  assert(*nandvars != NULL || *nresvars == 0);
2019  for( r = *nresvars - 1; r >= 0; --r )
2020  {
2021  ncontainedands = 0;
2022  shouldnotbeinand[ncontainedands] = r;
2023  ++ncontainedands;
2024  v = 0;
2025 
2026  assert(*nandvars != NULL);
2027  while( v < (*nandvars)[r] )
2028  {
2029  assert(*andvars != NULL);
2030  assert(*resvars != NULL);
2031  if( SCIPsortedvecFindPtr((void**)(*resvars), SCIPvarComp, (*andvars)[r][v], *nresvars, &pos) )
2032  {
2033  /* check if the found position "pos" is equal to an already visited and resultant in this constraint,
2034  * than here could exist a directed cycle
2035  */
2036  /* better use tarjan's algorithm
2037  * <http://algowiki.net/wiki/index.php?title=Tarjan%27s_algorithm>,
2038  * <http://en.wikipedia.org/wiki/Tarjan%E2%80%99s_strongly_connected_components_algorithm>
2039  * because it could be that the same resultant is part of this and-constraint and than it would fail
2040  * without no cycle
2041  * Note1: tarjans standard algorithm doesn't find cycle from one node to the same;
2042  * Note2: when tarjan's algorithm find a cycle, it's still possible that this cycle is not "real" e.g.
2043  * y = y ~y z (z can also be a product) where y = 0 follows and therefor only "0 = z" is necessary
2044  */
2045  for( a = ncontainedands - 1; a >= 0; --a )
2046  if( shouldnotbeinand[a] == pos )
2047  {
2048  SCIPwarningMessage(scip, "This should not happen here. The and-constraint with resultant variable: ");
2049  SCIP_CALL( SCIPprintVar(scip, (*resvars)[r], NULL) );
2050  SCIPwarningMessage(scip, "possible contains a loop with and-resultant:");
2051  SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) );
2052 
2053  /* free memory iff necessary */
2054  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2055  if( !transformed )
2056  {
2057  SCIPfreeBufferArray(scip, &andconss);
2058  }
2059  return SCIP_INVALIDDATA;
2060  }
2061  SCIPdebugMsg(scip, "Another and-constraint contains and-resultant:");
2062  SCIPdebug( SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) ) );
2063  SCIPdebugMsg(scip, "Trying to resolve.\n");
2064 
2065  shouldnotbeinand[ncontainedands] = pos;
2066  ++ncontainedands;
2067 
2068  /* try to resolve containing ands */
2069 
2070  /* resize array and number of variables */
2071  (*nandvars)[r] = (*nandvars)[r] + (*nandvars)[pos] - 1;
2072  SCIP_CALL( SCIPreallocMemoryArray(scip, &((*andvars)[r]), (*nandvars)[r]) ); /*lint !e866 */
2073 
2074  /* copy all variables */
2075  for( a = (*nandvars)[pos] - 1; a >= 0; --a )
2076  (*andvars)[r][(*nandvars)[r] - a - 1] = (*andvars)[pos][a];
2077 
2078  /* check same position with new variable, so we do not increase v */
2079  }
2080  else
2081  ++v;
2082  }
2083  }
2084  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2085 
2086  /* free memory iff necessary */
2087  if( !transformed )
2088  {
2089  SCIPfreeBufferArray(scip, &andconss);
2090  }
2091  }
2092  else
2093  {
2094  SCIPdebugMsg(scip, "found no and-constraint-handler\n");
2095  *existands = FALSE;
2096  *existandconshdlr = FALSE;
2097  }
2098 
2099  return SCIP_OKAY;
2100 }
2101 
2102 /** clears the given line buffer */
2103 static
2105  char* linebuffer, /**< line */
2106  int* linecnt /**< number of characters in line */
2107  )
2108 {
2109  assert( linebuffer != NULL );
2110  assert( linecnt != NULL );
2111 
2112  (*linecnt) = 0;
2113  linebuffer[0] = '\0';
2114 }
2115 
2116 
2117 /** ends the given line with '\\0' and prints it to the given file stream */
2118 static
2120  SCIP* scip, /**< SCIP data structure */
2121  FILE* file, /**< output file (or NULL for standard output) */
2122  char* linebuffer, /**< line */
2123  int* linecnt /**< number of characters in line */
2124  )
2125 {
2126  assert( scip != NULL );
2127  assert( linebuffer != NULL );
2128  assert( linecnt != NULL );
2129  assert( 0 <= *linecnt && *linecnt < OPB_MAX_LINELEN );
2130 
2131  if( (*linecnt) > 0 )
2132  {
2133  linebuffer[(*linecnt)] = '\0';
2134  SCIPinfoMessage(scip, file, "%s", linebuffer);
2135  clearBuffer(linebuffer, linecnt);
2136  }
2137 }
2138 
2139 
2140 /** appends extension to line and prints it to the give file stream if the line buffer get full */
2141 static
2143  SCIP* scip, /**< SCIP data structure */
2144  FILE* file, /**< output file (or NULL for standard output) */
2145  char* linebuffer, /**< line buffer */
2146  int* linecnt, /**< number of characters in line */
2147  const char* extension /**< string to extent the line */
2148  )
2149 {
2150  assert(scip != NULL);
2151  assert(linebuffer != NULL);
2152  assert(linecnt != NULL);
2153  assert(extension != NULL);
2154 
2155  if( (*linecnt) + (int) strlen(extension) >= OPB_MAX_LINELEN - 1 )
2156  writeBuffer(scip, file, linebuffer, linecnt);
2157 
2158  /* append extension to linebuffer */
2159  (void) strncat(linebuffer, extension, OPB_MAX_LINELEN - (unsigned int)(*linecnt));
2160  (*linecnt) += (int) strlen(extension);
2161 }
2162 
2163 /** write objective function */
2164 static
2166  SCIP*const scip, /**< SCIP data structure */
2167  FILE*const file, /**< output file, or NULL if standard output should be used */
2168  SCIP_VAR**const vars, /**< array with active (binary) variables */
2169  int const nvars, /**< number of active variables in the problem */
2170  SCIP_VAR** const resvars, /**< array of resultant variables */
2171  int const nresvars, /**< number of resultant variables */
2172  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2173  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2174  SCIP_OBJSENSE const objsense, /**< objective sense */
2175  SCIP_Real const objscale, /**< scalar applied to objective function; external objective value is
2176  * extobj = objsense * objscale * (intobj + objoffset) */
2177  SCIP_Real const objoffset, /**< objective offset from bound shifting and fixing */
2178  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
2179  SCIP_Bool const existands, /**< does some and-constraints exist? */
2180  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
2181  )
2182 {
2183  SCIP_VAR* var;
2184  char linebuffer[OPB_MAX_LINELEN+1];
2185  char buffer[OPB_MAX_LINELEN];
2186  SCIP_Longint mult;
2187  SCIP_Bool objective;
2188  int v;
2189  int linecnt;
2190  int pos;
2191 
2192  assert(scip != NULL);
2193  assert(file != NULL);
2194  assert(vars != NULL || nvars == 0);
2195  assert(resvars != NULL || nresvars == 0);
2196  assert(andvars != NULL || nandvars == NULL);
2197  assert(multisymbol != NULL);
2198 
2199  mult = 1;
2200  objective = !SCIPisZero(scip, objoffset);
2201 
2202  clearBuffer(linebuffer, &linecnt);
2203 
2204  /* check if a objective function exits and compute the multiplier to
2205  * shift the coefficients to integers */
2206  for( v = 0; v < nvars; ++v )
2207  {
2208  var = vars[v]; /*lint !e613 */
2209 
2210 #ifndef NDEBUG
2211  {
2212  /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
2213  if( !transformed )
2214  assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ||
2216  }
2217 #endif
2218 
2219  /* we found a indicator variable so we assume this is a wbo file */
2220  if( strstr(SCIPvarGetName(var), INDICATORVARNAME) != NULL )
2221  {
2222  /* find the topcost linear inequality which gives us the maximal cost which could be violated by our
2223  * solution, which is an artificial constraint and print this at first
2224  *
2225  * @note: only linear constraint handler is enough in problem stage, otherwise it could be any upgraded linear
2226  * constraint which handles pure binary variables
2227  */
2228  SCIP_CONSHDLR* conshdlr;
2229  SCIP_CONS* topcostcons;
2230  SCIP_Bool printed;
2231 
2232  printed = FALSE;
2233  topcostcons = SCIPfindCons(scip, TOPCOSTCONSNAME);
2234 
2235  if( topcostcons != NULL )
2236  {
2237  conshdlr = SCIPconsGetHdlr(topcostcons);
2238  assert(conshdlr != NULL);
2239 
2240  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0 )
2241  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, topcostcons));
2242  else if( strcmp(SCIPconshdlrGetName(conshdlr), "knapsack") == 0 )
2243  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %" SCIP_LONGINT_FORMAT ";\n",
2244  SCIPgetCapacityKnapsack(scip, topcostcons));
2245  else if( strcmp(SCIPconshdlrGetName(conshdlr), "setppc") == 0 )
2246  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2247  else
2248  {
2249  SCIPABORT();
2250  return SCIP_INVALIDDATA; /*lint !e527 */
2251  }
2252  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2253  writeBuffer(scip, file, linebuffer, &linecnt);
2254  printed = TRUE;
2255  }
2256  /* following works only in transformed stage */
2257  else
2258  {
2259  /* first try linear constraints */
2260  conshdlr = SCIPfindConshdlr(scip, "linear");
2261 
2262  if( conshdlr != NULL )
2263  {
2264  SCIP_CONS** conss;
2265  int nconss;
2266  int c;
2267 
2268  conss = SCIPconshdlrGetConss(conshdlr);
2269  nconss = SCIPconshdlrGetNConss(conshdlr);
2270 
2271  assert(conss != NULL || nconss == 0);
2272 
2273  for( c = 0; c < nconss; ++c )
2274  {
2275  SCIP_VAR** linvars;
2276  int nlinvars;
2277  int w;
2278  SCIP_Bool topcostfound;
2279  SCIP_CONS* cons;
2280 
2281  cons = conss[c]; /*lint !e613 */
2282  assert(cons != NULL);
2283 
2284  linvars = SCIPgetVarsLinear(scip, cons);
2285  nlinvars = SCIPgetNVarsLinear(scip, cons);
2286 
2287  assert(linvars != NULL || nlinvars == 0);
2288  topcostfound = FALSE;
2289 
2290  for( w = 0; w < nlinvars; ++w )
2291  {
2292  if( strstr(SCIPvarGetName(linvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2293  topcostfound = TRUE;
2294  else
2295  {
2296  assert(!topcostfound);
2297  topcostfound = FALSE;
2298  }
2299  }
2300 
2301  if( topcostfound )
2302  {
2303  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, cons));
2304  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2305  writeBuffer(scip, file, linebuffer, &linecnt);
2306  printed = TRUE;
2307  break;
2308  }
2309  }
2310  }
2311 
2312  if( !printed )
2313  {
2314  /* second try knapsack constraints */
2315  conshdlr = SCIPfindConshdlr(scip, "knapsack");
2316 
2317  if( conshdlr != NULL )
2318  {
2319  SCIP_CONS** conss;
2320  int nconss;
2321  int c;
2322 
2323  conss = SCIPconshdlrGetConss(conshdlr);
2324  nconss = SCIPconshdlrGetNConss(conshdlr);
2325 
2326  assert(conss != NULL || nconss == 0);
2327 
2328  for( c = 0; c < nconss; ++c )
2329  {
2330  SCIP_VAR** topvars;
2331  int ntopvars;
2332  int w;
2333  SCIP_Bool topcostfound;
2334  SCIP_CONS* cons;
2335 
2336  cons = conss[c]; /*lint !e613 */
2337  assert(cons != NULL);
2338 
2339  topvars = SCIPgetVarsKnapsack(scip, cons);
2340  ntopvars = SCIPgetNVarsKnapsack(scip, cons);
2341 
2342  assert(topvars != NULL || ntopvars == 0);
2343  topcostfound = FALSE;
2344 
2345  for( w = 0; w < ntopvars; ++w )
2346  {
2347  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2348  topcostfound = TRUE;
2349  else
2350  {
2351  assert(!topcostfound);
2352  topcostfound = FALSE;
2353  }
2354  }
2355 
2356  if( topcostfound )
2357  {
2358  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %" SCIP_LONGINT_FORMAT ";\n",
2359  SCIPgetCapacityKnapsack(scip, cons));
2360  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2361  writeBuffer(scip, file, linebuffer, &linecnt);
2362  printed = TRUE;
2363  break;
2364  }
2365  }
2366  }
2367  }
2368 
2369  if( !printed )
2370  {
2371  /* third try setppc constraints */
2372  conshdlr = SCIPfindConshdlr(scip, "setppc");
2373 
2374  if( conshdlr != NULL )
2375  {
2376  SCIP_CONS** conss;
2377  int nconss;
2378  int c;
2379 
2380  conss = SCIPconshdlrGetConss(conshdlr);
2381  nconss = SCIPconshdlrGetNConss(conshdlr);
2382 
2383  assert(conss != NULL || nconss == 0);
2384 
2385  for( c = 0; c < nconss; ++c )
2386  {
2387  SCIP_VAR** topvars;
2388  int ntopvars;
2389  int w;
2390  SCIP_Bool topcostfound;
2391  SCIP_CONS* cons;
2392 
2393  cons = conss[c]; /*lint !e613 */
2394  assert(cons != NULL);
2395 
2396  topvars = SCIPgetVarsSetppc(scip, cons);
2397  ntopvars = SCIPgetNVarsSetppc(scip, cons);
2398 
2399  assert(topvars != NULL || ntopvars == 0);
2400  topcostfound = FALSE;
2401 
2402  for( w = 0; w < ntopvars; ++w )
2403  {
2404  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2405  topcostfound = TRUE;
2406  else
2407  {
2408  assert(!topcostfound);
2409  topcostfound = FALSE;
2410  }
2411  }
2412 
2413  if( topcostfound )
2414  {
2415  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2416  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2417  writeBuffer(scip, file, linebuffer, &linecnt);
2418  printed = TRUE;
2419  break;
2420  }
2421  }
2422  }
2423  }
2424  }
2425 
2426  /* no topcost constraint found, so print empty topcost line, which means there is no upper bound on violated soft constraints */
2427  if( !printed )
2428  {
2429  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: ;\n");
2430  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2431  writeBuffer(scip, file, linebuffer, &linecnt);
2432  }
2433 
2434  return SCIP_OKAY;
2435  }
2436 
2437  if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
2438  {
2439  objective = TRUE;
2440  while( !SCIPisIntegral(scip, SCIPvarGetObj(var) * mult) )
2441  {
2442  assert(mult * 10 > mult);
2443  mult *= 10;
2444  }
2445  }
2446  }
2447 
2448  if( objective )
2449  {
2450  /* opb format supports only minimization; therefore, a maximization problem has to be converted */
2451  if( ( objsense == SCIP_OBJSENSE_MAXIMIZE ) != ( objscale < 0.0 ) )
2452  mult *= -1;
2453 
2454  /* there exist a objective function*/
2455  SCIPinfoMessage(scip, file, "* Obj. scale : %.15g\n", objscale / mult);
2456  SCIPinfoMessage(scip, file, "* Obj. offset : %.15g\n", objoffset * mult);
2457 
2458  clearBuffer(linebuffer, &linecnt);
2459 
2460  SCIPdebugMsg(scip, "print objective function multiplied with %" SCIP_LONGINT_FORMAT "\n", mult);
2461 
2462  appendBuffer(scip, file, linebuffer, &linecnt, "min:");
2463 
2464 #ifndef NDEBUG
2465  if( existands )
2466  {
2467  int c;
2468  /* check that these variables are sorted */
2469  for( c = nresvars - 1; c > 0; --c )
2470  assert(SCIPvarGetIndex(resvars[c]) >= SCIPvarGetIndex(resvars[c - 1])); /*lint !e613 */
2471  }
2472 #endif
2473 
2474  for( v = nvars - 1; v >= 0; --v )
2475  {
2476  SCIP_Bool negated;
2477  var = vars[v]; /*lint !e613 */
2478 
2479  assert(var != NULL);
2480 
2481  if( SCIPisZero(scip, SCIPvarGetObj(var)) )
2482  continue;
2483 
2484  negated = SCIPvarIsNegated(var);
2485 
2486  assert( linecnt != 0 );
2487 
2488  if( SCIPvarGetObj(var) * mult > (SCIP_Real)SCIP_LONGINT_MAX )
2489  {
2490  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));
2491  }
2492 
2493  /* replace and-resultant with corresponding variables */
2494  if( existands && SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2495  {
2496  int a;
2497 
2498  assert(andvars != NULL);
2499  assert(nandvars != NULL);
2500  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2501  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2502 
2503  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2504 
2505  /* print and-vars */
2506  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2507  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "",
2508  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
2509  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2510 
2511  for(a = nandvars[pos] - 2; a >= 0; --a )
2512  {
2513  negated = SCIPvarIsNegated(andvars[pos][a]);
2514 
2515  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2516  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2517  }
2518  }
2519  else
2520  {
2521  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2522  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2523  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2524  }
2525  }
2526 
2527  /* and objective function line ends with a ';' */
2528  appendBuffer(scip, file, linebuffer, &linecnt, " ;\n");
2529  writeBuffer(scip, file, linebuffer, &linecnt);
2530  }
2531 
2532  return SCIP_OKAY;
2533 }
2534 
2535 /* print maybe non linear row in OPB format to file stream */
2536 static
2538  SCIP*const scip, /**< SCIP data structure */
2539  FILE*const file, /**< output file (or NULL for standard output) */
2540  char const*const type, /**< row type ("=" or ">=") */
2541  SCIP_VAR**const vars, /**< array of variables */
2542  SCIP_Real const*const vals, /**< array of values */
2543  int const nvars, /**< number of variables */
2544  SCIP_Real lhs, /**< left hand side */
2545  SCIP_VAR** const resvars, /**< array of resultant variables */
2546  int const nresvars, /**< number of resultant variables */
2547  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2548  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2549  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2550  SCIP_Longint*const mult, /**< multiplier for the coefficients */
2551  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2552  )
2553 {
2554  SCIP_VAR* var;
2555  char buffer[OPB_MAX_LINELEN];
2556  char linebuffer[OPB_MAX_LINELEN + 1];
2557  int v;
2558  int pos;
2559  int linecnt;
2560 
2561  assert(scip != NULL);
2562  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2563  assert(mult != NULL);
2564  assert(resvars != NULL);
2565  assert(nresvars > 0);
2566  assert(andvars != NULL && nandvars != NULL);
2567 
2568  clearBuffer(linebuffer, &linecnt);
2569 
2570  /* check if all coefficients are internal; if not commentstart multiplier */
2571  for( v = 0; v < nvars; ++v )
2572  {
2573  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2574  {
2575  if( ABS(*mult) > ABS(*mult * 10) )
2576  return SCIP_INVALIDDATA;
2577  (*mult) *= 10;
2578  }
2579  }
2580 
2581  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2582  {
2583  if( ABS(*mult) > ABS(*mult * 10) )
2584  return SCIP_INVALIDDATA;
2585  (*mult) *= 10;
2586  }
2587 
2588  /* print comment line if we have to multiply the coefficients to get integrals */
2589  if( ABS(*mult) != 1 )
2590  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2591 
2592 #ifndef NDEBUG
2593  /* check that these variables are sorted */
2594  for( v = nresvars - 1; v > 0; --v )
2595  assert(SCIPvarGetIndex(resvars[v]) >= SCIPvarGetIndex(resvars[v - 1]));
2596 #endif
2597 
2598  /* if we have a soft constraint print the weight*/
2599  if( weight != 0 )
2600  {
2601  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2602  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2603  }
2604 
2605  /* print coefficients */
2606  for( v = 0; v < nvars; ++v )
2607  {
2608  SCIP_Bool negated;
2609 
2610  var = vars[v];
2611  assert( var != NULL );
2612 
2613  negated = SCIPvarIsNegated(var);
2614 
2615  /* replace and-resultant with corresponding variables */
2616  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2617  {
2618  int a;
2619 
2620  assert(andvars != NULL);
2621  assert(nandvars != NULL);
2622  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2623  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2624 
2625  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2626 
2627  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2628  {
2629  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)));
2630  }
2631 
2632  /* print and-vars */
2633  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s",
2634  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "",
2635  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x") );
2636  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2637 
2638  for(a = nandvars[pos] - 2; a >= 0; --a )
2639  {
2640  negated = SCIPvarIsNegated(andvars[pos][a]);
2641 
2642  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2643  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2644  }
2645 
2646  appendBuffer(scip, file, linebuffer, &linecnt, " ");
2647  }
2648  else
2649  {
2650  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2651  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2652  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2653  }
2654  }
2655 
2656  /* print left hand side */
2657  if( SCIPisZero(scip, lhs) )
2658  lhs = 0.0;
2659 
2660  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2661  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2662 
2663  writeBuffer(scip, file, linebuffer, &linecnt);
2664 
2665  return SCIP_OKAY;
2666 }
2667 
2668 
2669 /** prints given maybe non-linear constraint information in OPB format to file stream */
2670 static
2672  SCIP*const scip, /**< SCIP data structure */
2673  FILE*const file, /**< output file (or NULL for standard output) */
2674  SCIP_VAR**const vars, /**< array of variables */
2675  SCIP_Real*const vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2676  int const nvars, /**< number of variables */
2677  SCIP_Real const lhs, /**< left hand side */
2678  SCIP_Real const rhs, /**< right hand side */
2679  SCIP_VAR** const resvars, /**< array of resultant variables */
2680  int const nresvars, /**< number of resultant variables */
2681  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2682  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2683  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2684  SCIP_Bool const transformed, /**< transformed constraint? */
2685  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2686  )
2687 {
2688  SCIP_VAR** activevars;
2689  SCIP_Real* activevals;
2690  SCIP_Real activeconstant;
2691  SCIP_Longint mult;
2692  SCIP_RETCODE retcode;
2693  int nactivevars;
2694  int v;
2695 
2696  assert(scip != NULL);
2697  assert(vars != NULL || nvars == 0);
2698  assert(resvars != NULL);
2699  assert(nresvars > 0);
2700  assert(andvars != NULL && nandvars != NULL);
2701 
2702  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2703  return SCIP_OKAY;
2704 
2705  nactivevars = nvars;
2706  activevars = NULL;
2707  activevals = NULL;
2708  activeconstant = 0.0;
2709 
2710  /* duplicate variable and value array */
2711  if( vars != NULL )
2712  {
2713  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2714  if( vals != NULL )
2715  {
2716  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2717  }
2718  else
2719  {
2720  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2721 
2722  for( v = 0; v < nactivevars; ++v )
2723  activevals[v] = 1.0;
2724  }
2725 
2726  /* retransform given variables to active variables */
2727  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2728  }
2729 
2730  mult = 1;
2731  retcode = SCIP_OKAY;
2732 
2733  /* print row(s) in OPB format */
2734  if( SCIPisEQ(scip, lhs, rhs) )
2735  {
2736  assert( !SCIPisInfinity(scip, rhs) );
2737 
2738  /* equality constraint */
2739  retcode = printNLRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2740  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2741  }
2742  else
2743  {
2744  if( !SCIPisInfinity(scip, -lhs) )
2745  {
2746  /* print inequality ">=" */
2747  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, resvars,
2748  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2749  }
2750 
2751  if( !SCIPisInfinity(scip, rhs) )
2752  {
2753  mult *= -1;
2754 
2755  /* print inequality ">=" and multiplying all coefficients by -1 */
2756  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2757  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2758  }
2759  }
2760 
2761  /* free buffer arrays */
2762  if( vars != NULL )
2763  {
2764  SCIPfreeBufferArray(scip, &activevars);
2765  SCIPfreeBufferArray(scip, &activevals);
2766  }
2767 
2768  return retcode;
2769 }
2770 
2771 
2772 /* print row in OPB format to file stream */
2773 static
2775  SCIP* scip, /**< SCIP data structure */
2776  FILE* file, /**< output file (or NULL for standard output) */
2777  const char* type, /**< row type ("=" or ">=") */
2778  SCIP_VAR** vars, /**< array of variables */
2779  SCIP_Real* vals, /**< array of values */
2780  int nvars, /**< number of variables */
2781  SCIP_Real lhs, /**< left hand side */
2782  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2783  SCIP_Longint* mult, /**< multiplier for the coefficients */
2784  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2785  )
2786 {
2787  SCIP_VAR* var;
2788  char buffer[OPB_MAX_LINELEN];
2789  char linebuffer[OPB_MAX_LINELEN + 1];
2790  int v;
2791  int linecnt;
2792 
2793  assert(scip != NULL);
2794  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2795  assert(mult != NULL);
2796 
2797  clearBuffer(linebuffer, &linecnt);
2798 
2799  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
2800  * we can stop printing because it is an artificial constraint
2801  */
2802  if( nvars > 0 && strstr(SCIPvarGetName(vars[0]), INDICATORVARNAME) != NULL )
2803  return SCIP_OKAY;
2804 
2805  /* check if all coefficients are integral; if not commentstart multiplier */
2806  for( v = 0; v < nvars; ++v )
2807  {
2808  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2809  {
2810  if( ABS(*mult) > ABS(*mult * 10) )
2811  return SCIP_INVALIDDATA;
2812  (*mult) *= 10;
2813  }
2814  }
2815 
2816  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2817  {
2818  if( ABS(*mult) > ABS(*mult * 10) )
2819  return SCIP_INVALIDDATA;
2820  (*mult) *= 10;
2821  }
2822 
2823  /* print comment line if we have to multiply the coefficients to get integrals */
2824  if( ABS(*mult) != 1 )
2825  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2826 
2827  /* if we have a soft constraint print the weight*/
2828  if( weight != 0 )
2829  {
2830  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2831  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2832  }
2833 
2834  /* print coefficients */
2835  for( v = 0; v < nvars; ++v )
2836  {
2837  SCIP_Bool negated;
2838 
2839  var = vars[v];
2840  assert( var != NULL );
2841 
2842  negated = SCIPvarIsNegated(var);
2843 
2844  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2845  {
2846  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)));
2847  }
2848 
2849  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2850  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2851  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2852  }
2853 
2854  /* print left hand side */
2855  if( SCIPisZero(scip, lhs) )
2856  lhs = 0.0;
2857 
2858  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2859  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2860 
2861  writeBuffer(scip, file, linebuffer, &linecnt);
2862 
2863  return SCIP_OKAY;
2864 }
2865 
2866 
2867 /** prints given linear constraint information in OPB format to file stream */
2868 static
2870  SCIP* scip, /**< SCIP data structure */
2871  FILE* file, /**< output file (or NULL for standard output) */
2872  SCIP_VAR** vars, /**< array of variables */
2873  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2874  int nvars, /**< number of variables */
2875  SCIP_Real lhs, /**< left hand side */
2876  SCIP_Real rhs, /**< right hand side */
2877  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2878  SCIP_Bool transformed, /**< transformed constraint? */
2879  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2880  )
2881 {
2882  SCIP_VAR** activevars;
2883  SCIP_Real* activevals;
2884  SCIP_Real activeconstant;
2885  SCIP_Longint mult;
2886  SCIP_RETCODE retcode;
2887  int nactivevars;
2888  int v;
2889 
2890  assert( scip != NULL );
2891  assert( vars != NULL || nvars == 0 );
2892 
2893  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2894  return SCIP_OKAY;
2895 
2896  nactivevars = nvars;
2897  activevars = NULL;
2898  activevals = NULL;
2899  activeconstant = 0.0;
2900 
2901  /* duplicate variable and value array */
2902  if( vars != NULL )
2903  {
2904  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2905  if( vals != NULL )
2906  {
2907  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2908  }
2909  else
2910  {
2911  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2912 
2913  for( v = 0; v < nactivevars; ++v )
2914  activevals[v] = 1.0;
2915  }
2916 
2917  /* retransform given variables to active variables */
2918  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2919  }
2920 
2921  mult = 1;
2922  retcode = SCIP_OKAY;
2923 
2924  /* print row(s) in OPB format */
2925  if( SCIPisEQ(scip, lhs, rhs) )
2926  {
2927  assert( !SCIPisInfinity(scip, rhs) );
2928 
2929  /* equality constraint */
2930  retcode = printRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2931  multisymbol);
2932  }
2933  else
2934  {
2935  if( !SCIPisInfinity(scip, -lhs) )
2936  {
2937  /* print inequality ">=" */
2938  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, weight, &mult,
2939  multisymbol);
2940  }
2941 
2942  if( !SCIPisInfinity(scip, rhs) )
2943  {
2944  mult *= -1;
2945 
2946  /* print inequality ">=" and multiplying all coefficients by -1 */
2947  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2948  multisymbol);
2949  }
2950  }
2951 
2952  /* free buffer arrays */
2953  if( vars != NULL )
2954  {
2955  SCIPfreeBufferArray(scip, &activevars);
2956  SCIPfreeBufferArray(scip, &activevals);
2957  }
2958 
2959  return retcode;
2960 }
2961 
2962 /* print row in OPB format to file stream */
2963 static
2965  SCIP*const scip, /**< SCIP data structure */
2966  FILE*const file, /**< output file (or NULL for standard output) */
2967  const char* type, /**< row type ("=" or ">=") */
2968  SCIP_VAR**const linvars, /**< array of variables */
2969  SCIP_Real*const linvals, /**< array of values */
2970  int const nlinvars, /**< number of variables */
2971  SCIP_VAR***const termvars, /**< term array with array of variables to print */
2972  int*const ntermvars, /**< array with number of variables in each term */
2973  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
2974  int const ntermvals, /**< number non-linear variables in the problem */
2975  SCIP_Bool**const negatedarrays, /**< array of arrays to know which variable in a non-linear part is negated */
2976  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
2977  SCIP_Real lhs, /**< left hand side */
2978  SCIP_Longint* mult, /**< multiplier for the coefficients */
2979  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2980  )
2981 {
2982  SCIP_VAR* var;
2983  char buffer[OPB_MAX_LINELEN];
2984  char linebuffer[OPB_MAX_LINELEN + 1];
2985  int v;
2986  int t;
2987  int linecnt;
2988 
2989  assert(scip != NULL);
2990  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2991  assert(linvars != NULL || nlinvars == 0);
2992  assert(linvals != NULL || nlinvars == 0);
2993  assert(termvars != NULL || ntermvals == 0);
2994  assert(ntermvars != NULL || ntermvals == 0);
2995  assert(termvals != NULL || ntermvals == 0);
2996  assert(negatedarrays != NULL || ntermvals == 0);
2997  assert(mult != NULL);
2998 
2999  clearBuffer(linebuffer, &linecnt);
3000 
3001  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
3002  * we can stop printing because it is an artificial constraint
3003  */
3004  if( ntermvals == 0 && nlinvars > 0 && strstr(SCIPvarGetName(linvars[0]), INDICATORVARNAME) != NULL ) /*lint !e613 */
3005  return SCIP_OKAY;
3006 
3007  /* check if all linear coefficients are internal; if not commentstart multiplier */
3008  for( v = 0; v < nlinvars; ++v )
3009  {
3010  while( !SCIPisIntegral(scip, linvals[v] * (*mult)) ) /*lint !e613 */
3011  {
3012  if( ABS(*mult) > ABS(*mult * 10) )
3013  return SCIP_INVALIDDATA;
3014  (*mult) *= 10;
3015  }
3016  }
3017 
3018  /* check if all non-linear coefficients are internal; if not commentstart multiplier */
3019  for( v = 0; v < ntermvals; ++v )
3020  {
3021  while( !SCIPisIntegral(scip, termvals[v] * (*mult)) ) /*lint !e613 */
3022  {
3023  if( ABS(*mult) > ABS(*mult * 10) )
3024  return SCIP_INVALIDDATA;
3025  (*mult) *= 10;
3026  }
3027  }
3028 
3029  while( !SCIPisIntegral(scip, lhs * (*mult)) )
3030  {
3031  if( ABS(*mult) > ABS(*mult * 10) )
3032  return SCIP_INVALIDDATA;
3033  (*mult) *= 10;
3034  }
3035 
3036  /* print comment line if we have to multiply the coefficients to get integrals */
3037  if( ABS(*mult) != 1 )
3038  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
3039 
3040  /* if indicator variable exist we have a soft constraint */
3041  if( indvar != NULL )
3042  {
3043  SCIP_Real weight;
3044 
3045  weight = SCIPvarGetObj(indvar);
3046  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+g] ", weight);
3047  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3048  }
3049 
3050  /* print linear part */
3051  for( v = 0; v < nlinvars; ++v )
3052  {
3053  SCIP_Bool negated;
3054 
3055  var = linvars[v]; /*lint !e613 */
3056  assert(var != NULL);
3057 
3058  negated = SCIPvarIsNegated(var);
3059 
3060  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
3061  (SCIP_Longint) SCIPround(scip, linvals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x")); /*lint !e613 */
3062  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3063  }
3064 
3065  /* print non-linear part */
3066  for( t = 0; t < ntermvals; ++t )
3067  {
3068  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT, (SCIP_Longint) SCIPround(scip, termvals[t] * (*mult))); /*lint !e613 */
3069  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3070 
3071  for( v = 0; v < ntermvars[t]; ++v ) /*lint !e613 */
3072  {
3073  SCIP_Bool negated;
3074 
3075  var = termvars[t][v]; /*lint !e613 */
3076  assert(var != NULL);
3077 
3078  negated = negatedarrays[t][v]; /*lint !e613 */
3079 
3080  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
3081  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3082  }
3083  appendBuffer(scip, file, linebuffer, &linecnt, " ");
3084  }
3085 
3086  /* print left hand side */
3087  if( SCIPisZero(scip, lhs) )
3088  lhs = 0.0;
3089 
3090  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
3091  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3092 
3093  writeBuffer(scip, file, linebuffer, &linecnt);
3094 
3095  return SCIP_OKAY;
3096 }
3097 
3098 
3099 /** prints given pseudo boolean constraint information in OPB format to file stream */
3100 static
3102  SCIP*const scip, /**< SCIP data structure */
3103  FILE*const file, /**< output file, or NULL if standard output should be used */
3104  SCIP_VAR**const linvars, /**< array with variables of linear part */
3105  SCIP_Real*const linvals, /**< array of coefficients values of linear part */
3106  int const nlinvars, /**< number variables in linear part of the problem */
3107  SCIP_VAR***const termvars, /**< term array with array of variables to print */
3108  int*const ntermvars, /**< array with number of variables in each term */
3109  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
3110  int const ntermvals, /**< number non-linear variables in the problem */
3111  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
3112  SCIP_Real const lhs, /**< left hand side of constraint */
3113  SCIP_Real const rhs, /**< right hand side of constraint */
3114  SCIP_Bool transformed, /**< should the transformed problem be printed ? */
3115  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
3116  )
3117 {
3118  SCIP_VAR*** activetermvars;
3119  SCIP_Bool** negatedarrays;
3120  SCIP_VAR** activelinvars;
3121  SCIP_Real* activelinvals;
3122  int nactivelinvars;
3123  SCIP_Real activelinconstant;
3124  SCIP_Longint mult;
3125  SCIP_RETCODE retcode;
3126  int v;
3127 
3128  assert(scip != NULL);
3129  assert(linvars != NULL || nlinvars == 0);
3130  assert(linvals != NULL || nlinvars == 0);
3131  assert(termvars != NULL || 0 == ntermvals);
3132  assert(ntermvars != NULL || 0 == ntermvals);
3133  assert(termvals != NULL || 0 == ntermvals);
3134  assert(lhs <= rhs);
3135 
3136  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
3137  return SCIP_OKAY;
3138 
3139  activelinconstant = 0.0;
3140 
3141  /* duplicate variable and value array for linear part */
3142  nactivelinvars = nlinvars;
3143  if( nactivelinvars > 0 )
3144  {
3145  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvars, linvars, nactivelinvars ) );
3146  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvals, linvals, nactivelinvars ) );
3147 
3148  /* retransform given variables to active variables */
3149  SCIP_CALL( getActiveVariables(scip, activelinvars, activelinvals, &nactivelinvars, &activelinconstant, transformed) );
3150  }
3151  else
3152  {
3153  activelinvars = NULL;
3154  activelinvals = NULL;
3155  }
3156 
3157  /* create non-linear information for printing */
3158  if( ntermvals > 0 )
3159  {
3160  assert(termvars != NULL);
3161  assert(ntermvars != NULL);
3162  assert(termvals != NULL);
3163 
3164  SCIP_CALL( SCIPallocBufferArray(scip, &activetermvars, ntermvals) );
3165  SCIP_CALL( SCIPallocBufferArray(scip, &negatedarrays, ntermvals) );
3166  for( v = ntermvals - 1; v >= 0; --v )
3167  {
3168  assert(ntermvars[v] > 0); /*lint !e613 */
3169 
3170  if( transformed )
3171  {
3172  SCIP_CALL( SCIPallocBufferArray(scip, &(activetermvars[v]), ntermvars[v]) ); /*lint !e866 */
3173  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3174 
3175  /* get binary representatives of binary variables in non-linear terms */
3176  SCIP_CALL( SCIPgetBinvarRepresentatives(scip, ntermvars[v], termvars[v], activetermvars[v], negatedarrays[v]) );
3177  }
3178  else
3179  {
3180  SCIP_CALL( SCIPduplicateBufferArray(scip, &(activetermvars[v]), termvars[v], ntermvars[v]) ); /*lint !e866 */
3181  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3182  BMSclearMemoryArray(negatedarrays[v], ntermvars[v]); /*lint !e866 */
3183  }
3184  }
3185  }
3186  else
3187  {
3188  activetermvars = NULL;
3189  negatedarrays = NULL;
3190  }
3191 
3192  mult = 1;
3193  retcode = SCIP_OKAY;
3194 
3195  /* print row(s) in OPB format */
3196  if( SCIPisEQ(scip, lhs, rhs) )
3197  {
3198  assert( !SCIPisInfinity(scip, rhs) );
3199 
3200  /* equality constraint */
3201  retcode = printPBRow(scip, file, "=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3202  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3203  }
3204  else
3205  {
3206  if( !SCIPisInfinity(scip, -lhs) )
3207  {
3208  /* print inequality ">=" */
3209  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3210  ntermvars, termvals, ntermvals, negatedarrays, indvar, lhs - activelinconstant, &mult, multisymbol);
3211  }
3212 
3213  if( !SCIPisInfinity(scip, rhs) )
3214  {
3215  mult *= -1;
3216 
3217  /* print inequality ">=" and multiplying all coefficients by -1 */
3218  /* coverity[var_deref_model] */
3219  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3220  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3221  }
3222  }
3223 
3224  /* free buffers for non-linear arrays */
3225  if( ntermvals > 0 )
3226  {
3227  assert(negatedarrays != NULL);
3228  assert(activetermvars != NULL);
3229 
3230  for( v = 0; v < ntermvals; ++v )
3231  {
3232  assert(negatedarrays[v] != NULL);
3233  assert(activetermvars[v] != NULL);
3234  SCIPfreeBufferArray(scip, &(negatedarrays[v]));
3235  SCIPfreeBufferArray(scip, &(activetermvars[v]));
3236  }
3237  SCIPfreeBufferArray(scip, &negatedarrays);
3238  SCIPfreeBufferArray(scip, &activetermvars);
3239  }
3240 
3241  /* free buffer for linear arrays */
3242  if( nactivelinvars > 0 )
3243  {
3244  SCIPfreeBufferArray(scip, &activelinvars);
3245  SCIPfreeBufferArray(scip, &activelinvals);
3246  }
3247 
3248  return retcode;
3249 }
3250 
3251 /** determine total number of linear constraints split into lhs/rhs */
3252 static
3254  SCIP*const scip, /**< SCIP data structure */
3255  SCIP_CONS**const conss, /**< array with constraints of the problem */
3256  int const nconss, /**< number of constraints in the problem */
3257  int* nlinearconss, /**< pointer to store the total number of linear constraints */
3258  int* nsplitlinearconss /**< pointer to store the total number of linear constraints split into lhs/rhs */
3259  )
3260 {
3261  SCIP_CONSHDLR* conshdlr;
3262  const char* conshdlrname;
3263  SCIP_CONS* cons;
3264  int c;
3265 
3266  assert(scip != NULL);
3267  assert(conss != NULL || nconss == 0);
3268  assert(nlinearconss != NULL);
3269  assert(nsplitlinearconss != NULL);
3270 
3271  *nlinearconss = 0;
3272  *nsplitlinearconss = 0;
3273 
3274  /* loop over all constraints */
3275  for( c = 0; c < nconss; ++c )
3276  {
3277  cons = conss[c];
3278  assert(cons != NULL);
3279  conshdlr = SCIPconsGetHdlr(cons); /*lint !e613*/
3280  assert(conshdlr != NULL);
3281 
3282  conshdlrname = SCIPconshdlrGetName(conshdlr);
3283 
3284  if( strcmp(conshdlrname, "linear") == 0 )
3285  {
3286  if( ! SCIPisInfinity(scip, SCIPgetLhsLinear(scip, cons)) )
3287  ++(*nsplitlinearconss);
3288 
3289  if( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, cons)) )
3290  ++(*nsplitlinearconss);
3291 
3292  ++(*nlinearconss);
3293  }
3294 
3295  if( strcmp(conshdlrname, "varbound") == 0 )
3296  {
3297  if( ! SCIPisInfinity(scip, SCIPgetLhsVarbound(scip, cons)) )
3298  ++(*nsplitlinearconss);
3299 
3300  if( ! SCIPisInfinity(scip, SCIPgetRhsVarbound(scip, cons)) )
3301  ++(*nsplitlinearconss);
3302 
3303  ++(*nlinearconss);
3304  }
3305  }
3306 }
3307 
3308 /** write constraints */
3309 static
3311  SCIP*const scip, /**< SCIP data structure */
3312  FILE*const file, /**< output file, or NULL if standard output should be used */
3313  SCIP_CONS**const conss, /**< array with constraints of the problem */
3314  int const nconss, /**< number of constraints in the problem */
3315  SCIP_VAR**const vars, /**< array with active (binary) variables */
3316  int const nvars, /**< number of active variables in the problem */
3317  SCIP_VAR** const resvars, /**< array of resultant variables */
3318  int const nresvars, /**< number of resultant variables */
3319  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3320  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3321  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3322  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
3323  SCIP_Bool const existands, /**< does some and-constraints exist? */
3324  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3325  )
3326 {
3327  SCIP_CONSHDLR* conshdlr;
3328  const char* conshdlrname;
3329  SCIP_CONS* cons;
3330  SCIP_VAR** consvars;
3331  SCIP_Real* consvals;
3332  SCIP_RETCODE retcode;
3333  int nconsvars;
3334  int v, c;
3335  SCIP_HASHMAP* linconssofindicatorsmap = NULL;
3336  SCIP_HASHMAP* linconssofpbsmap = NULL;
3337 
3338  assert(scip != NULL);
3339  assert(file != NULL);
3340  assert(conss != NULL || nconss == 0);
3341  assert(vars != NULL || nvars == 0);
3342  assert(resvars != NULL || nresvars == 0);
3343  assert(andvars != NULL || nandvars == 0);
3344  assert(multisymbol != NULL);
3345 
3346  if( transformed )
3347  {
3348  conshdlr = SCIPfindConshdlr(scip, "indicator");
3349 
3350  /* find artificial linear constraints which correspond to indicator constraints to avoid double printing */
3351  if( conshdlr != NULL )
3352  {
3353  SCIP_CONS** indconss;
3354  int nindconss;
3355 
3356  indconss = SCIPconshdlrGetConss(conshdlr);
3357  nindconss = SCIPconshdlrGetNConss(conshdlr);
3358  assert(indconss != NULL || nindconss == 0);
3359 
3360  if( nindconss > 0 )
3361  {
3362  SCIP_CONS* lincons;
3363 
3364  /* create the linear constraint of indicator constraints hash map */
3365  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nindconss) );
3366  assert(indconss != NULL);
3367 
3368  for( c = 0; c < nindconss; ++c )
3369  {
3370  assert(indconss[c] != NULL);
3371  lincons = SCIPgetLinearConsIndicator(indconss[c]);
3372  assert(lincons != NULL);
3373 
3374  /* insert constraint into mapping between */
3375  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3376  }
3377  }
3378  }
3379 
3380  conshdlr = SCIPfindConshdlr(scip, "pseudoboolean");
3381 
3382  /* find artifical linear constraints which correspond to indicator constraints to avoid double printing */
3383  if( conshdlr != NULL )
3384  {
3385  SCIP_CONS** pbconss;
3386  int npbconss;
3387 
3388  pbconss = SCIPconshdlrGetConss(conshdlr);
3389  npbconss = SCIPconshdlrGetNConss(conshdlr);
3390  assert(pbconss != NULL || npbconss == 0);
3391 
3392  if( npbconss > 0 )
3393  {
3394  SCIP_CONS* lincons;
3395 
3396  /* create the linear constraint of indicator constraints hash map */
3397  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), npbconss) );
3398 
3399  for( c = 0; c < npbconss; ++c )
3400  {
3401  assert(pbconss[c] != NULL); /*lint !e613*/
3402  lincons = SCIPgetLinearConsPseudoboolean(scip, pbconss[c]); /*lint !e613*/
3403  assert(lincons != NULL);
3404 
3405  /* insert constraint into mapping between */
3406  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3407  }
3408  }
3409  }
3410  }
3411  /* in original space we cannot ask the constraint handler for its constraints, therefore we have to loop over all
3412  * original to check for artificial linear once
3413  */
3414  else
3415  {
3416  SCIP_CONS* lincons;
3417  SCIP_Bool pbhashmapcreated = FALSE;
3418  SCIP_Bool indhashmapcreated = FALSE;
3419 
3420  /* loop over all constraint for printing */
3421  for( c = 0; c < nconss; ++c )
3422  {
3423  conshdlr = SCIPconsGetHdlr(conss[c]); /*lint !e613*/
3424  assert(conshdlr != NULL);
3425 
3426  conshdlrname = SCIPconshdlrGetName(conshdlr);
3427 
3428  if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3429  {
3430  if( !pbhashmapcreated )
3431  {
3432  /* create the linear constraint of indicator constraints hash map */
3433  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), nconss) );
3434  pbhashmapcreated = TRUE;
3435  }
3436 
3437  lincons = SCIPgetLinearConsPseudoboolean(scip, conss[c]); /*lint !e613*/
3438  assert(lincons != NULL);
3439 
3440  /* insert constraint into mapping between */
3441  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3442  }
3443  else if( strcmp(conshdlrname, "indicator") == 0 )
3444  {
3445  if( !indhashmapcreated )
3446  {
3447  /* create the linear constraint of indicator constraints hash map */
3448  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nconss) );
3449  indhashmapcreated = TRUE;
3450  }
3451 
3452  lincons = SCIPgetLinearConsIndicator(conss[c]); /*lint !e613*/
3453  assert(lincons != NULL);
3454 
3455  /* insert constraint into mapping between */
3456  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3457  }
3458  }
3459  }
3460 
3461  retcode = SCIP_OKAY;
3462  cons = NULL;
3463 
3464  /* loop over all constraint for printing */
3465  for( c = 0; c < nconss && retcode == SCIP_OKAY; ++c )
3466  {
3467  SCIP_CONS* artcons;
3468 
3469  artcons = NULL;
3470 
3471  cons = conss[c]; /*lint !e613 */
3472  assert(cons != NULL);
3473 
3474  conshdlr = SCIPconsGetHdlr(cons);
3475  assert(conshdlr != NULL);
3476 
3477  conshdlrname = SCIPconshdlrGetName(conshdlr);
3478  assert(transformed == SCIPconsIsTransformed(cons));
3479 
3480  /* in case the transformed is written only constraint are posted which are enabled in the current node */
3481  assert(!transformed || SCIPconsIsEnabled(cons));
3482 
3483  if( linconssofpbsmap != NULL )
3484  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofpbsmap, (void*)cons);
3485  if( artcons == NULL && linconssofindicatorsmap != NULL )
3486  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofindicatorsmap, (void*)cons);
3487 
3488  if( artcons == NULL )
3489  {
3490  if( strcmp(conshdlrname, "linear") == 0 )
3491  {
3492  if( existands )
3493  {
3494  retcode = printNonLinearCons(scip, file,
3495  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3496  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), resvars, nresvars, andvars, nandvars,
3497  0LL, transformed, multisymbol);
3498  }
3499  else
3500  {
3501  retcode = printLinearCons(scip, file,
3502  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3503  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), 0LL, transformed, multisymbol);
3504  }
3505  }
3506  else if( strcmp(conshdlrname, "setppc") == 0 )
3507  {
3508  consvars = SCIPgetVarsSetppc(scip, cons);
3509  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3510 
3511  switch( SCIPgetTypeSetppc(scip, cons) )
3512  {
3514  if( existands )
3515  {
3516  retcode = printNonLinearCons(scip, file, consvars, NULL, nconsvars, 1.0, 1.0, resvars, nresvars,
3517  andvars, nandvars, 0LL, transformed, multisymbol);
3518  }
3519  else
3520  {
3521  retcode = printLinearCons(scip, file,
3522  consvars, NULL, nconsvars, 1.0, 1.0, 0LL, transformed, multisymbol);
3523  }
3524  break;
3526  if( existands )
3527  {
3528  retcode = printNonLinearCons(scip, file,
3529  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, resvars, nresvars, andvars, nandvars,
3530  0LL, transformed, multisymbol);
3531  }
3532  else
3533  {
3534  retcode = printLinearCons(scip, file,
3535  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, 0LL, transformed, multisymbol);
3536  }
3537  break;
3539  if( existands )
3540  {
3541  retcode = printNonLinearCons(scip, file,
3542  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), resvars, nresvars, andvars, nandvars,
3543  0LL, transformed, multisymbol);
3544  }
3545  else
3546  {
3547  retcode = printLinearCons(scip, file,
3548  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3549  }
3550  break;
3551  }
3552  }
3553  else if( strcmp(conshdlrname, "logicor") == 0 )
3554  {
3555  if( existands )
3556  {
3557  retcode = printNonLinearCons(scip, file,
3558  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), 1.0, SCIPinfinity(scip),
3559  resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3560  }
3561  else
3562  {
3563  retcode = printLinearCons(scip, file,
3564  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3565  1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3566  }
3567  }
3568  else if( strcmp(conshdlrname, "knapsack") == 0 )
3569  {
3570  SCIP_Longint* weights;
3571 
3572  consvars = SCIPgetVarsKnapsack(scip, cons);
3573  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3574 
3575  /* copy Longint array to SCIP_Real array */
3576  weights = SCIPgetWeightsKnapsack(scip, cons);
3577  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3578  for( v = 0; v < nconsvars; ++v )
3579  consvals[v] = (SCIP_Real)weights[v];
3580 
3581  if( existands )
3582  {
3583  retcode = printNonLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3584  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), resvars, nresvars, andvars, nandvars,
3585  0LL, transformed, multisymbol);
3586  }
3587  else
3588  {
3589  retcode = printLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3590  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), 0LL, transformed, multisymbol);
3591  }
3592 
3593  SCIPfreeBufferArray(scip, &consvals);
3594  }
3595  else if( strcmp(conshdlrname, "varbound") == 0 )
3596  {
3597  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3598  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3599 
3600  consvars[0] = SCIPgetVarVarbound(scip, cons);
3601  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3602 
3603  consvals[0] = 1.0;
3604  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3605 
3606  if( existands )
3607  {
3608  retcode = printNonLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3609  SCIPgetRhsVarbound(scip, cons), resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3610  }
3611  else
3612  {
3613  retcode = printLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3614  SCIPgetRhsVarbound(scip, cons), 0LL, transformed, multisymbol);
3615  }
3616 
3617  SCIPfreeBufferArray(scip, &consvars);
3618  SCIPfreeBufferArray(scip, &consvals);
3619  }
3620  else if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3621  {
3622  SCIP_VAR*** termvars;
3623  int* ntermvars;
3624  int termvarssize;
3625  SCIP_CONS** andconss;
3626  SCIP_Real* andcoefs ;
3627  SCIP_VAR** linvars;
3628  SCIP_Real* lincoefs ;
3629  int nlinvars;
3630  int t;
3631 
3632  /* get the required array size for the variables array and for the number of variables in each variable array */
3633  termvarssize = SCIPgetNAndsPseudoboolean(scip, cons);
3634  assert(termvarssize >= 0);
3635 
3636  /* allocate temporary memory */
3637  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, termvarssize) );
3638  SCIP_CALL( SCIPallocBufferArray(scip, &termvars, termvarssize) );
3639  SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, termvarssize) );
3640  SCIP_CALL( SCIPallocBufferArray(scip, &ntermvars, termvarssize) );
3641 
3642  /* get all corresponding and-constraints and therefor all variables */
3643  SCIP_CALL( SCIPgetAndDatasPseudoboolean(scip, cons, andconss, andcoefs, &termvarssize) );
3644  for( t = termvarssize - 1; t >= 0; --t )
3645  {
3646  termvars[t] = SCIPgetVarsAnd(scip, andconss[t]);
3647  ntermvars[t] = SCIPgetNVarsAnd(scip, andconss[t]);
3648  }
3649 
3650  /* gets number of linear variables without artificial terms variables of pseudoboolean constraint */
3651  nlinvars = SCIPgetNLinVarsWithoutAndPseudoboolean(scip, cons);
3652 
3653  /* allocate temporary memory */
3654  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinvars) );
3655  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nlinvars) );
3656 
3657  /* gets linear constraint of pseudoboolean constraint */
3658  SCIP_CALL( SCIPgetLinDatasWithoutAndPseudoboolean(scip, cons, linvars, lincoefs, &nlinvars) );
3659 
3660  retcode = printPseudobooleanCons(scip, file, linvars, lincoefs, nlinvars,
3661  termvars, ntermvars, andcoefs, termvarssize, SCIPgetIndVarPseudoboolean(scip, cons),
3662  SCIPgetLhsPseudoboolean(scip, cons), SCIPgetRhsPseudoboolean(scip, cons), transformed, multisymbol);
3663 
3664  /* free temporary memory */
3665  SCIPfreeBufferArray(scip, &lincoefs);
3666  SCIPfreeBufferArray(scip, &linvars);
3667  SCIPfreeBufferArray(scip, &ntermvars);
3668  SCIPfreeBufferArray(scip, &andcoefs);
3669  SCIPfreeBufferArray(scip, &termvars);
3670  SCIPfreeBufferArray(scip, &andconss);
3671  }
3672  else if( strcmp(conshdlrname, "indicator") == 0 )
3673  {
3674  SCIP_CONS* lincons;
3675  SCIP_VAR* indvar;
3676  SCIP_VAR* slackvar;
3677  SCIP_Longint weight;
3678 
3679  /* get artificial binary indicator variables */
3680  indvar = SCIPgetBinaryVarIndicator(cons);
3681  assert(indvar != NULL);
3682 
3683  if( SCIPvarGetStatus(indvar) == SCIP_VARSTATUS_NEGATED )
3684  {
3685  indvar = SCIPvarGetNegationVar(indvar);
3686  assert(indvar != NULL);
3688 
3689  /* get the soft cost of this constraint */
3690  weight = (SCIP_Longint) SCIPvarGetObj(indvar);
3691  }
3692  else
3693  {
3695 
3696  /* get the soft cost of this constraint */
3697  weight = -(SCIP_Longint) SCIPvarGetObj(indvar);
3698  }
3699 
3700  /* get artificial slack variable */
3701  slackvar = SCIPgetSlackVarIndicator(cons);
3702  assert(slackvar != NULL);
3703 
3704  /* only need to print indicator constraints with weights on their indicator variable */
3705  if( weight != 0 )
3706  {
3707  SCIP_VAR** scipvarslinear;
3708  SCIP_Real* scipvalslinear;
3709  SCIP_Bool cont;
3710  int nonbinarypos;
3711 
3712  lincons = SCIPgetLinearConsIndicator(cons);
3713  assert(lincons != NULL);
3714 
3715  nconsvars = SCIPgetNVarsLinear(scip, lincons);
3716  scipvarslinear = SCIPgetVarsLinear(scip, lincons);
3717  scipvalslinear = SCIPgetValsLinear(scip, lincons);
3718 
3719  /* allocate temporary memory */
3720  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, scipvarslinear, nconsvars) );
3721  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, scipvalslinear, nconsvars) );
3722 
3723  nonbinarypos = -1;
3724  cont = FALSE;
3725 
3726  /* find non-binary variable */
3727  for( v = 0; v < nconsvars; ++v )
3728  {
3729  if( SCIPvarGetType(consvars[v]) != SCIP_VARTYPE_BINARY )
3730  {
3731  if( consvars[v] == slackvar )
3732  {
3733  assert(nonbinarypos == -1);
3734  nonbinarypos = v;
3735  }
3736  else
3737  {
3738  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) );
3739  SCIPinfoMessage(scip, file, "* ");
3740  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3741  SCIPinfoMessage(scip, file, ";\n");
3742  cont = TRUE;
3743  break;
3744  }
3745  }
3746  }
3747 
3748  /* if we have not found any non-binary variable we do not print the constraint, maybe we should ??? */
3749  if( nonbinarypos == -1 )
3750  {
3751  SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has no slack variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
3752  SCIPinfoMessage(scip, file, "* ");
3753  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3754  SCIPinfoMessage(scip, file, ";\n");
3755 
3756  /* free temporary memory */
3757  SCIPfreeBufferArray(scip, &consvals);
3758  SCIPfreeBufferArray(scip, &consvars);
3759  continue;
3760  }
3761 
3762  /* if the constraint has more than two non-binary variables is not printable and we go to the next */
3763  if( cont )
3764  {
3765  /* free temporary memory */
3766  SCIPfreeBufferArray(scip, &consvals);
3767  SCIPfreeBufferArray(scip, &consvars);
3768  continue;
3769  }
3770 
3771  assert(0 <= nonbinarypos && nonbinarypos < nconsvars);
3772 
3773  /* remove slackvariable in linear constraint for printing */
3774  --nconsvars;
3775  consvars[nonbinarypos] = consvars[nconsvars];
3776  consvals[nonbinarypos] = consvals[nconsvars];
3777 
3778  if( existands )
3779  {
3780  retcode = printNonLinearCons(scip, file,
3781  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3782  resvars, nresvars, andvars, nandvars,
3783  weight, transformed, multisymbol);
3784  }
3785  else
3786  {
3787  retcode = printLinearCons(scip, file,
3788  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3789  weight, transformed, multisymbol);
3790  }
3791 
3792  /* free temporary memory */
3793  SCIPfreeBufferArray(scip, &consvals);
3794  SCIPfreeBufferArray(scip, &consvars);
3795  }
3796  else
3797  {
3798  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) );
3799  SCIPinfoMessage(scip, file, "* ");
3800  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3801  SCIPinfoMessage(scip, file, ";\n");
3802  }
3803  }
3804  else if( strcmp(conshdlrname, "and") == 0 )
3805  {
3806  /* all resultants of the and constraint will be replaced by all corresponding variables of this constraint,
3807  * so no and-constraint will be printed directly */
3808  assert(existandconshdlr);
3809  }
3810  else
3811  {
3812  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3813  SCIPinfoMessage(scip, file, "* ");
3814  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3815  SCIPinfoMessage(scip, file, ";\n");
3816  }
3817  }
3818  }
3819 
3820  if( retcode == SCIP_INVALIDDATA )
3821  {
3822  assert(cons != NULL);
3823 
3824  SCIPerrorMessage("Cannot print constraint %s with non-integral coefficient or sides in opb-format\n",
3825  SCIPconsGetName(cons));
3826  SCIP_CALL( SCIPprintCons(scip, cons, stderr) );
3827  SCIPinfoMessage(scip, file, ";\n");
3828  }
3829 
3830  if( linconssofpbsmap != NULL )
3831  {
3832  /* free hash map */
3833  SCIPhashmapFree(&linconssofpbsmap);
3834  }
3835  if( linconssofindicatorsmap != NULL )
3836  {
3837  /* free hash map */
3838  SCIPhashmapFree(&linconssofindicatorsmap);
3839  }
3840 
3841  return retcode;
3842 }
3843 
3844 /* write fixed variables (unless already done because they are an and resultant or and variable) */
3845 static
3847  SCIP*const scip, /**< SCIP data structure */
3848  FILE*const file, /**< output file, or NULL if standard output should be used */
3849  SCIP_VAR** vars, /**< array with active (binary) variables */
3850  int nvars, /**< number of active variables in the problem */
3851  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3852  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3853  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3854  )
3855 {
3856  char linebuffer[OPB_MAX_LINELEN+1];
3857  char buffer[OPB_MAX_LINELEN];
3858  int linecnt;
3859  int v;
3860 
3861  assert(scip != NULL);
3862  assert(file != NULL);
3863  assert(vars != NULL || nvars == 0);
3864  assert(printedfixing != NULL);
3865  assert(multisymbol != NULL);
3866 
3867  clearBuffer(linebuffer, &linecnt);
3868 
3869  /* print variables which are fixed */
3870  for( v = 0; v < nvars; ++v )
3871  {
3872  SCIP_VAR* var;
3873  SCIP_Real lb;
3874  SCIP_Real ub;
3875  SCIP_Bool neg = FALSE;
3876 
3877  assert( vars != NULL );
3878  var = vars[v];
3879 
3880  if( transformed )
3881  {
3882  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3883  lb = SCIPvarGetLbLocal(var);
3884  ub = SCIPvarGetUbLocal(var);
3885  }
3886  else
3887  {
3888  lb = SCIPvarGetLbOriginal(var);
3889  ub = SCIPvarGetUbOriginal(var);
3890  }
3891  assert(lb > -0.5 && ub < 1.5);
3892  assert(SCIPisFeasIntegral(scip, lb));
3893  assert(SCIPisFeasIntegral(scip, ub));
3894 
3895  /* print fixed and-resultants */
3896  if( lb > 0.5 || ub < 0.5 )
3897  {
3898  if( transformed ) {
3899  SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &var, &neg) );
3900  }
3901 
3902  if( SCIPhashtableExists(printedfixing, (void*)var) )
3903  continue;
3904 
3905  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
3906  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3907 
3908  /* add variable to the hashmap */
3909  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
3910  }
3911  }
3912 
3913  writeBuffer(scip, file, linebuffer, &linecnt);
3914 
3915  return SCIP_OKAY;
3916 }
3917 
3918 /* write and constraints of inactive but relevant and-resultants and and variables which are fixed to one */
3919 static
3921  SCIP*const scip, /**< SCIP data structure */
3922  FILE*const file, /**< output file, or NULL if standard output should be used */
3923  SCIP_VAR**const resvars, /**< array of resultant variables */
3924  int const nresvars, /**< number of resultant variables */
3925  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3926  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3927  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3928  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3929  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3930  )
3931 {
3932  SCIP_VAR* resvar;
3933  SCIP_Longint rhslhs;
3934  char linebuffer[OPB_MAX_LINELEN+1];
3935  char buffer[OPB_MAX_LINELEN];
3936  int linecnt;
3937  int r, v;
3938 
3939  assert(scip != NULL);
3940  assert(file != NULL);
3941  assert(resvars != NULL || nresvars == 0);
3942  assert(nandvars != NULL || nresvars == 0);
3943  assert(andvars != NULL || nandvars == NULL);
3944  assert(multisymbol != NULL);
3945 
3946  clearBuffer(linebuffer, &linecnt);
3947 
3948  /* print and-variables which are fixed */
3949  /* @todo remove this block here and the hashtable and let writeOpbFixedVars() do the job? */
3950  for( r = nresvars - 1; r >= 0; --r )
3951  {
3952  SCIP_VAR* var;
3953  SCIP_Bool neg;
3954  SCIP_Real lb;
3955  SCIP_Real ub;
3956 
3957  assert( resvars != NULL );
3958  resvar = resvars[r];
3959 
3960  if( transformed )
3961  {
3962  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3963  lb = SCIPvarGetLbLocal(resvar);
3964  ub = SCIPvarGetUbLocal(resvar);
3965  }
3966  else
3967  {
3968  lb = SCIPvarGetLbOriginal(resvar);
3969  ub = SCIPvarGetUbOriginal(resvar);
3970  }
3971 
3972  /* print fixed and-resultants */
3973  if( lb > 0.5 || ub < 0.5 )
3974  {
3975  /* coverity[copy_paste_error] */
3976  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &var, &neg) );
3977 
3978  assert(SCIPisFeasIntegral(scip, lb));
3979  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
3980  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3981 
3982  /* add variable to the hashmap */
3983  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
3984  }
3985 
3986  assert( andvars != NULL && nandvars != NULL );
3987  assert( andvars[r] != NULL || nandvars[r] == 0 );
3988 
3989  /* print fixed and-variables */
3990  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
3991  {
3992  assert( andvars[r] != NULL );
3993  assert( andvars[r][v] != NULL );
3994 
3995  if( transformed )
3996  {
3997  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3998  lb = SCIPvarGetLbLocal(andvars[r][v]);
3999  ub = SCIPvarGetUbLocal(andvars[r][v]);
4000  }
4001  else
4002  {
4003  lb = SCIPvarGetLbOriginal(andvars[r][v]);
4004  ub = SCIPvarGetUbOriginal(andvars[r][v]);
4005  }
4006 
4007  if( lb > 0.5 || ub < 0.5 )
4008  {
4009  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4010 
4011  assert(SCIPisFeasIntegral(scip, lb));
4012  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
4013  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4014 
4015  /* add variable to the hashmap */
4016  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
4017  }
4018  }
4019  }
4020 
4021  /* print and-constraints with fixed and-resultant to zero and all and-constraints with
4022  * aggregated resultant, otherwise we would loose this information
4023  */
4024  for( r = nresvars - 1; r >= 0; --r )
4025  {
4026  assert( resvars != NULL );
4027  resvar = resvars[r];
4028  rhslhs = (SCIPvarGetUbLocal(resvar) < 0.5) ? 0 : ((SCIPvarGetLbLocal(resvar) > 0.5) ? 1 : -1);
4029 
4030  /* if and resultant is fixed to 0 and at least one and-variable is fixed to zero, we don't print this redundant constraint */
4031  if( rhslhs == 0 )
4032  {
4033  SCIP_Bool cont;
4034 
4035  cont = FALSE;
4036 
4037  assert( andvars != NULL && nandvars != NULL );
4038  assert( andvars[r] != NULL || nandvars[r] == 0 );
4039 
4040  /* if resultant variable and one other and variable is already zero, so we did not need to print this and
4041  * constraint because all other variables are free
4042  */
4043  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
4044  {
4045  assert( andvars[r] != NULL );
4046  assert( andvars[r][v] != NULL );
4047 
4048  if( SCIPvarGetUbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4049  {
4050  cont = TRUE;
4051  break;
4052  }
4053  }
4054 
4055  if( cont )
4056  continue;
4057  }
4058  /* if and resultant is fixed to 1 and all and-variable are fixed to 1 too, we don't print this redundant constraint */
4059  else if( rhslhs == 1 )
4060  {
4061  SCIP_Bool cont;
4062 
4063  cont = TRUE;
4064 
4065  assert( andvars != NULL && nandvars != NULL );
4066  assert( andvars[r] != NULL || nandvars[r] == 0 );
4067 
4068  /* if all variables are already fixed to one, we do not need to print this and constraint */
4069  for( v = nandvars[r] - 1; v >= 0; --v )
4070  {
4071  assert( andvars[r] != NULL );
4072  assert( andvars[r][v] != NULL );
4073 
4074  if( SCIPvarGetLbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4075  {
4076  cont = FALSE;
4077  break;
4078  }
4079  }
4080 
4081  if( cont )
4082  continue;
4083  }
4084 
4085  /* print and with fixed or aggregated and-resultant */
4086  /* rhslhs equals to 0 means the and constraint is relevant due to it's not clear on which values the and variables are
4087  * rhslhs equals to 1 means the and constraint is irrelevant cause all and variables have to be 1 too
4088  * rhslhs equals to -1 means the and constraint is relevant cause the variable is only aggregated */
4089  if( !SCIPvarIsActive(resvar) )
4090  {
4091  SCIP_VAR* var;
4092  SCIP_Bool neg;
4093  SCIP_Bool firstprinted;
4094 
4095  firstprinted = FALSE;
4096 
4097  assert( andvars != NULL && nandvars != NULL );
4098  assert( andvars[r] != NULL || nandvars[r] == 0 );
4099 
4100  for( v = nandvars[r] - 1; v >= 0; --v )
4101  {
4102  assert( andvars[r] != NULL );
4103  assert( andvars[r][v] != NULL );
4104 
4105  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4106 
4107  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", (firstprinted) ? multisymbol : "", neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"));
4108  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4109 
4110  firstprinted = TRUE;
4111  }
4112 
4113  /* if the resultant is aggregated we need to print his binary representation */
4114  if( rhslhs == -1 )
4115  {
4116  int pos;
4117 
4118  assert(transformed);
4119 
4120  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &resvar, &neg) );
4121 
4122 #ifndef NDEBUG
4123  if( neg )
4124  assert(SCIPvarIsActive(SCIPvarGetNegationVar(resvar)));
4125  else
4126  assert(SCIPvarIsActive(resvar));
4127 #endif
4128 
4129  /* replace and-resultant with corresponding variables */
4130  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, neg ? SCIPvarGetNegationVar(resvar) : resvar, nresvars, &pos) )
4131  {
4132  SCIP_Bool negated;
4133  int a;
4134 
4135  assert(andvars != NULL);
4136  assert(nandvars != NULL);
4137  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
4138  assert(andvars[pos][nandvars[pos] - 1] != NULL);
4139 
4140  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
4141 
4142  /* print and-vars */
4143  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, neg ? " +1%s%s%s" : " -1%s%s%s", multisymbol, negated ? "~" : "",
4144  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
4145  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4146 
4147  for(a = nandvars[pos] - 2; a >= 0; --a )
4148  {
4149  negated = SCIPvarIsNegated(andvars[pos][a]);
4150 
4151  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
4152  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4153  }
4154 
4155  appendBuffer(scip, file, linebuffer, &linecnt, " ");
4156 
4157  if( neg )
4158  rhslhs = 1;
4159  else
4160  rhslhs = 0;
4161  }
4162  else
4163  {
4164  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " -1%s%s%s", multisymbol, neg ? "~" : "",
4165  strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(resvar) : resvar), "x"));
4166  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4167 
4168  rhslhs = 0;
4169  }
4170  }
4171 
4172  /* print rhslhs */
4173  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " = %" SCIP_LONGINT_FORMAT " ;\n", rhslhs);
4174  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4175 
4176  writeBuffer(scip, file, linebuffer, &linecnt);
4177  }
4178  }
4179 
4180  return SCIP_OKAY;
4181 }
4182 
4183 /* writes problem to file */
4184 static
4186  SCIP* scip, /**< SCIP data structure */
4187  FILE* file, /**< output file, or NULL if standard output should be used */
4188  const char* name, /**< problem name */
4189  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4190  SCIP_OBJSENSE objsense, /**< objective sense */
4191  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4192  * extobj = objsense * objscale * (intobj + objoffset) */
4193  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4194  SCIP_VAR** vars, /**< array with active (binary) variables */
4195  int nvars, /**< number of active variables in the problem */
4196  SCIP_CONS** conss, /**< array with constraints of the problem */
4197  int nconss, /**< number of constraints in the problem */
4198  SCIP_VAR** const resvars, /**< array of resultant variables */
4199  int const nresvars, /**< number of resultant variables */
4200  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
4201  int const*const nandvars, /**< array of numbers of corresponding and-variables */
4202  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
4203  SCIP_Bool const existands, /**< does some and-constraints exist? */
4204  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4205  )
4206 {
4207  char multisymbol[OPB_MAX_LINELEN];
4208  SCIP_HASHTABLE* printedfixing;
4209  SCIP_Bool usesymbol;
4210  SCIP_RETCODE retcode;
4211  int nlinearconss;
4212  int nsplitlinearconss;
4213 
4214  assert( scip != NULL );
4215  assert( vars != NULL || nvars == 0 );
4216  assert( conss != NULL || nconss == 0 );
4217  assert( result != NULL );
4218 
4219  /* check if should use a multipliers symbol star '*' between coefficients and variables */
4220  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/multisymbol", &usesymbol) );
4221  (void) SCIPsnprintf(multisymbol, OPB_MAX_LINELEN, "%s", usesymbol ? " * " : " ");
4222 
4223  /* determine how many linear constraints are split */
4224  determineTotalNumberLinearConss(scip, conss, nconss, &nlinearconss, &nsplitlinearconss);
4225 
4226  /* print statistics as comment to file */
4227  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4228  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4229  SCIPinfoMessage(scip, file, "* Variables : %d (all binary)\n", nvars);
4230  SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss - nlinearconss + nsplitlinearconss);
4231 
4232  /* create a hash table */
4233  SCIP_CALL( SCIPhashtableCreate(&printedfixing, SCIPblkmem(scip), nvars,
4234  SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
4235 
4236  /* write objective function */
4237  SCIP_CALL( writeOpbObjective(scip, file, vars, nvars, resvars, nresvars, andvars, nandvars,
4238  objsense, objscale, objoffset, multisymbol, existands, transformed) );
4239 
4240  /* write constraints */
4241  retcode = writeOpbConstraints(scip, file, conss, nconss, vars, nvars, resvars, nresvars, andvars, nandvars,
4242  multisymbol, existandconshdlr, existands, transformed);
4243 
4244  if( existands && (retcode == SCIP_OKAY) )
4245  {
4246  /* write and constraints of inactive but relevant and-resultants and and-variables which are fixed to one
4247  with no fixed and resultant */
4248  SCIP_CALL( writeOpbRelevantAnds(scip, file, resvars, nresvars, andvars, nandvars, printedfixing, multisymbol, transformed) );
4249  }
4250 
4251  /* write fixed variables */
4252  SCIP_CALL( writeOpbFixedVars(scip, file, vars, nvars, printedfixing, multisymbol, transformed) );
4253 
4254  SCIPhashtableFree(&printedfixing);
4255 
4256  *result = SCIP_SUCCESS;
4257 
4258  return retcode;
4259 }
4260 
4261 
4262 /*
4263  * extern methods
4264  */
4265 
4266 /** reads problem from file */
4268  SCIP* scip, /**< SCIP data structure */
4269  SCIP_READER* reader, /**< the file reader itself */
4270  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
4271  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
4272  )
4273 { /*lint --e{715}*/
4274  OPBINPUT opbinput;
4275  SCIP_RETCODE retcode;
4276  int i;
4277 
4278  assert(scip != NULL); /* for lint */
4279  assert(reader != NULL);
4280 
4281  /* initialize OPB input data */
4282  opbinput.file = NULL;
4283  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &opbinput.linebuf, OPB_MAX_LINELEN) );
4284  opbinput.linebuf[0] = '\0';
4285  opbinput.linebufsize = OPB_MAX_LINELEN;
4286  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.token, OPB_MAX_LINELEN) );
4287  opbinput.token[0] = '\0';
4288  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.tokenbuf, OPB_MAX_LINELEN) );
4289  opbinput.tokenbuf[0] = '\0';
4290  for( i = 0; i < OPB_MAX_PUSHEDTOKENS; ++i )
4291  {
4292  SCIP_CALL( SCIPallocBufferArray(scip, &(opbinput.pushedtokens[i]), OPB_MAX_LINELEN) ); /*lint !e866 */
4293  }
4294 
4295  opbinput.npushedtokens = 0;
4296  opbinput.linenumber = 1;
4297  opbinput.linepos = 0;
4298  opbinput.objsense = SCIP_OBJSENSE_MINIMIZE;
4299  opbinput.eof = FALSE;
4300  opbinput.haserror = FALSE;
4301  opbinput.nproblemcoeffs = 0;
4302  opbinput.wbo = FALSE;
4303  opbinput.topcost = -SCIPinfinity(scip);
4304  opbinput.nindvars = 0;
4305 #if GENCONSNAMES == TRUE
4306  opbinput.consnumber = 0;
4307 #endif
4308 
4309  /* read the file */
4310  retcode = readOPBFile(scip, &opbinput, filename);
4311 
4312  /* free dynamically allocated memory */
4313  for( i = OPB_MAX_PUSHEDTOKENS - 1; i >= 0; --i )
4314  {
4315  SCIPfreeBufferArrayNull(scip, &(opbinput.pushedtokens[i]));
4316  }
4317  SCIPfreeBufferArrayNull(scip, &opbinput.tokenbuf);
4318  SCIPfreeBufferArrayNull(scip, &opbinput.token);
4319  SCIPfreeBlockMemoryArray(scip, &opbinput.linebuf, opbinput.linebufsize);
4320 
4321  if( retcode == SCIP_PLUGINNOTFOUND )
4322  retcode = SCIP_READERROR;
4323 
4324  SCIP_CALL( retcode );
4325 
4326  if( opbinput.nproblemcoeffs > 0 )
4327  {
4328  SCIPwarningMessage(scip, "there might be <%d> coefficients or weight out of range!\n", opbinput.nproblemcoeffs);
4329  }
4330 
4331  /* evaluate the result */
4332  if( opbinput.haserror )
4333  return SCIP_READERROR;
4334  else
4335  {
4336  /* set objective sense */
4337  SCIP_CALL( SCIPsetObjsense(scip, opbinput.objsense) );
4338  *result = SCIP_SUCCESS;
4339  }
4340 
4341  return SCIP_OKAY;
4342 }
4343 
4344 /** writes problem to file */
4346  SCIP* scip, /**< SCIP data structure */
4347  FILE* file, /**< output file, or NULL if standard output should be used */
4348  const char* name, /**< problem name */
4349  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4350  SCIP_OBJSENSE objsense, /**< objective sense */
4351  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4352  * extobj = objsense * objscale * (intobj + objoffset) */
4353  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4354  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
4355  int nvars, /**< number of active variables in the problem */
4356  int nbinvars, /**< number of binary variables */
4357  int nintvars, /**< number of general integer variables */
4358  int nimplvars, /**< number of implicit integer variables */
4359  int ncontvars, /**< number of continuous variables */
4360  SCIP_VAR** fixedvars, /**< array with fixed variables */
4361  int nfixedvars, /**< number of fixed and aggregated variables in the problem */
4362  SCIP_CONS** conss, /**< array with constraints of the problem */
4363  int nconss, /**< number of constraints in the problem */
4364  SCIP_Bool genericnames, /**< should generic variable and constraint names be used */
4365  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4366  )
4367 { /*lint --e{715}*/
4368  SCIP_RETCODE retcode = SCIP_OKAY;
4369 
4370  if( nvars != nbinvars && (nintvars > 0 || SCIPfindConshdlr(scip, "indicator") != NULL
4371  || ncontvars + nimplvars != SCIPconshdlrGetNConss(SCIPfindConshdlr(scip, "indicator"))) )
4372  {
4373  SCIPwarningMessage(scip, "only binary problems can be written in OPB format.\n");
4374  *result = SCIP_DIDNOTRUN;
4375  }
4376  else
4377  {
4378  SCIP_VAR*** andvars;
4379  SCIP_VAR** resvars;
4380  int* nandvars;
4381  SCIP_Bool existands;
4382  SCIP_Bool existandconshdlr;
4383  int nresvars;
4384  int v;
4385 
4386  /* computes all and-resultants and their corresponding constraint variables */
4387  /* coverity[leaked_storage] */
4388  SCIP_CALL( computeAndConstraintInfos(scip, transformed, &resvars, &nresvars, &andvars, &nandvars, &existandconshdlr, &existands) );
4389 
4390  if( genericnames )
4391  {
4392 #ifndef NDEBUG
4393  /* check for correct names for opb-format */
4394  int idx;
4395  int pos;
4396 
4397  for( v = nvars - 1; v >= 0; --v )
4398  {
4399  if( existands )
4400  {
4401  /* and variables are artificial */
4402  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4403  continue;
4404  }
4405 
4406  assert(sscanf(SCIPvarGetName(vars[v]), "x%d", &idx) == 1);
4407  }
4408 #endif
4409  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4410  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4411  }
4412  else
4413  {
4414  SCIP_Bool printed;
4415  int idx;
4416  int pos;
4417 
4418  printed = FALSE;
4419 
4420  /* check if there are already generic names for all (not fixed variables)*/
4421  for( v = nvars - 1; v >= 0; --v )
4422  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4423  {
4424  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 )
4425  {
4426  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4427  SCIP_CALL( SCIPprintVar(scip, vars[v], NULL) );
4428  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4429 
4430  if( transformed )
4431  {
4432  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4433  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4434  }
4435  else
4436  {
4437  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4438  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4439  }
4440  printed = TRUE;
4441  break;
4442  }
4443  }
4444 
4445  if( !printed )
4446  {
4447  /* check if there are already generic names for all (fixed variables)*/
4448  for( v = nfixedvars - 1; v >= 0; --v )
4449  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4450  {
4451  /* coverity[secure_coding] */
4452  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 )
4453  {
4454  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4455  SCIP_CALL( SCIPprintVar(scip, fixedvars[v], NULL) );
4456  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4457 
4458  if( transformed )
4459  {
4460  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4461  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4462  }
4463  else
4464  {
4465  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4466  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4467  }
4468  printed = TRUE;
4469  break;
4470  }
4471  }
4472  }
4473 
4474  if( !printed )
4475  {
4476 #ifndef NDEBUG
4477  for( v = nvars - 1; v >= 0; --v )
4478  {
4479  if( existands )
4480  {
4481  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4482  continue;
4483  }
4484 
4485  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 );
4486  }
4487 #endif
4488  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4489  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4490  }
4491  }
4492 
4493  if( existands )
4494  {
4495  /* free temporary buffers */
4496  assert(resvars != NULL);
4497  assert(andvars != NULL);
4498  assert(nandvars != NULL);
4499 
4500  for( v = nresvars - 1; v >= 0; --v )
4501  {
4502  assert(andvars[v] != NULL);
4503  SCIPfreeMemoryArray(scip, &andvars[v]);
4504  }
4505  SCIPfreeMemoryArray(scip, &nandvars);
4506  SCIPfreeMemoryArray(scip, &andvars);
4507  SCIPfreeMemoryArray(scip, &resvars);
4508  }
4509 
4510  *result = SCIP_SUCCESS;
4511  }
4512 
4513  if( retcode == SCIP_INVALIDDATA )
4514  return SCIP_WRITEERROR;
4515 
4516  return retcode;
4517 }
4518 
4519 /*
4520  * Callback methods of reader
4521  */
4522 
4523 /** copy method for reader plugins (called when SCIP copies plugins) */
4524 static
4525 SCIP_DECL_READERCOPY(readerCopyOpb)
4526 { /*lint --e{715}*/
4527  assert(scip != NULL);
4528  assert(reader != NULL);
4529  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4530 
4531  /* call inclusion method of reader */
4533 
4534  return SCIP_OKAY;
4535 }
4536 
4537 
4538 /** problem reading method of reader */
4539 static
4540 SCIP_DECL_READERREAD(readerReadOpb)
4541 { /*lint --e{715}*/
4542 
4543  SCIP_CALL( SCIPreadOpb(scip, reader, filename, result) );
4544 
4545  return SCIP_OKAY;
4546 }
4547 
4548 
4549 /** problem writing method of reader */
4550 static
4551 SCIP_DECL_READERWRITE(readerWriteOpb)
4552 { /*lint --e{715}*/
4553 
4554  SCIP_CALL( SCIPwriteOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4555  nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, genericnames, result) );
4556 
4557  return SCIP_OKAY;
4558 }
4559 
4560 /*
4561  * reader specific interface methods
4562  */
4563 
4564 /** includes the opb file reader in SCIP */
4566  SCIP* scip /**< SCIP data structure */
4567  )
4568 {
4569  SCIP_READER* reader;
4570 
4571  /* include reader */
4573 
4574  /* set non fundamental callbacks via setter functions */
4575  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOpb) );
4576  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOpb) );
4577  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteOpb) );
4578 
4579  /* add opb reader parameters */
4581  "reading/" READER_NAME "/dynamicconss", "should model constraints be subject to aging?",
4582  NULL, FALSE, FALSE/*TRUE*/, NULL, NULL) ); /* have to be FALSE, otherwise an error might inccur in restart during branch and bound */
4584  "reading/" READER_NAME "/multisymbol", "use '*' between coefficients and variables by writing to problem?",
4585  NULL, TRUE, FALSE, NULL, NULL) );
4586 
4587  return SCIP_OKAY;
4588 }
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:4565
#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:2537
SCIP_RETCODE SCIPaddVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real addobj)
Definition: scip_var.c:4562
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:4185
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:1290
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:9415
#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:17957
#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:1791
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:2964
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:4525
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:4267
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:17727
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:3310
#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:4540
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
static SCIP_RETCODE getMaxAndConsDim(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *objscale, SCIP_Real *objoffset)
Definition: reader_opb.c:1570
public methods for querying solving statistics
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2685
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:1242
Constraint handler for knapsack constraints of the form , x binary and .
static void clearBuffer(char *linebuffer, int *linecnt)
Definition: reader_opb.c:2104
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5151
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:4998
#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:1855
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17847
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5176
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17867
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:4345
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:3161
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17242
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:2947
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:3134
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:3846
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:2774
#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:3253
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:3920
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9461
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:2671
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 void appendBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_opb.c:2142
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17749
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:1900
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:3101
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12764
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
static SCIP_RETCODE setObjective(SCIP *const scip, OPBINPUT *const opbinput, const char *sense, SCIP_Real const scale, 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
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9438
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2296
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
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 SCIPisIntegral(SCIP *scip, SCIP_Real val)
static void writeBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_opb.c:2119
pseudo-Boolean file reader (opb format)
static const SCIP_Real scalars[]
Definition: lp.c:5743
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
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:3042
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:1947
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17361
#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:5127
#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:17581
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:298
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17407
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:17967
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:2165
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:1687
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:4551
#define SCIPABORT()
Definition: def.h:366
public methods for global and local (sub)problems
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE readConstraints(SCIP *scip, OPBINPUT *opbinput, SCIP_Real objscale, int *nNonlinearConss)
Definition: reader_opb.c:1336
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:2869
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:17571
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17397
#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