Scippy

SCIP

Solving Constraint Integer Programs

reader_osil.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-2024 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_osil.c
26  * @ingroup DEFPLUGINS_READER
27  * @brief OS instance language (OSiL) format file reader
28  * @author Stefan Vigerske
29  * @author Ingmar Vierhaus
30  * @author Benjamin Mueller
31  */
32 
33 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34 
35 #define _USE_MATH_DEFINES /* to get M_PI and M_E on Windows */ /*lint !750 */
36 #include "blockmemshell/memory.h"
38 #include "scip/cons_nonlinear.h"
39 #include "scip/cons_linear.h"
40 #include "scip/cons_sos1.h"
41 #include "scip/cons_sos2.h"
42 #include "scip/expr_abs.h"
43 #include "scip/expr_erf.h"
44 #include "scip/expr_exp.h"
45 #include "scip/expr_log.h"
46 #include "scip/expr_pow.h"
47 #include "scip/expr_product.h"
48 #include "scip/expr_sum.h"
49 #include "scip/expr_trig.h"
50 #include "scip/expr_value.h"
51 #include "scip/expr_var.h"
52 #include "scip/pub_cons.h"
53 #include "scip/pub_message.h"
54 #include "scip/pub_misc.h"
55 #include "scip/pub_nlp.h"
56 #include "scip/pub_var.h"
57 #include "scip/reader_osil.h"
58 #include "scip/scip_cons.h"
59 #include "scip/scip_mem.h"
60 #include "scip/scip_numerics.h"
61 #include "scip/scip_param.h"
62 #include "scip/scip_prob.h"
63 #include "scip/scip_reader.h"
64 #include "scip/scip_var.h"
65 #include <stdlib.h>
66 #include <string.h>
67 #include "xml/xml.h"
68 
69 #define READER_NAME "osilreader"
70 #define READER_DESC "file reader for OS instance language (OSiL) format"
71 #define READER_EXTENSION "osil"
72 
73 /*
74  * Local methods
75  */
76 
77 /** create variables with bounds and type according to xml data */
78 static
80  SCIP* scip, /**< SCIP data structure */
81  const XML_NODE* datanode, /**< XML root node for instance data */
82  SCIP_VAR*** vars, /**< buffer to store pointer to variable array */
83  int* nvars, /**< buffer to store number of variables */
84  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
85  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
86  SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
87  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
88  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
89  )
90 {
91  const XML_NODE* variables;
92  const XML_NODE* varnode;
93  const char* attrval;
94  int varssize;
95 
96  assert(scip != NULL);
97  assert(datanode != NULL);
98  assert(vars != NULL);
99  assert(nvars != NULL);
100  assert(doingfine != NULL);
101 
102  *vars = NULL;
103  *nvars = 0;
104 
105  variables = xmlFindNodeMaxdepth(datanode, "variables", 0, 1);
106 
107  if( variables == NULL )
108  {
109  /* no variables: strange but ok so far */
110  return SCIP_OKAY;
111  }
112 
113  /* get number of variables */
114  attrval = xmlGetAttrval(variables, "numberOfVariables");
115  if( attrval == NULL )
116  {
117  SCIPerrorMessage("Attribute \"numberOfVariables\" not found in <variables> node.\n");
118  *doingfine = FALSE;
119  return SCIP_OKAY;
120  }
121 
122  varssize = (int)strtol(attrval, (char**)&attrval, 10);
123  if( *attrval != '\0' || varssize < 0 )
124  {
125  SCIPerrorMessage("Invalid value '%s' for \"numberOfVariables\" attribute.\n", xmlGetAttrval(variables, "numberOfVariables"));
126  *doingfine = FALSE;
127  return SCIP_OKAY;
128  }
129  assert(varssize >= 0);
130 
131  SCIP_CALL( SCIPallocBufferArray(scip, vars, varssize) );
132 
133  /* parse variable nodes, create SCIP vars and add to problem
134  * create bounddisjunction constraints for semicontinuous/semiinteger variables
135  */
136  for( varnode = xmlFirstChild(variables); varnode != NULL; varnode = xmlNextSibl(varnode) )
137  {
138  const char* varname;
139  SCIP_VARTYPE vartype;
140  SCIP_Real varlb;
141  SCIP_Real varub;
142  SCIP_Real semibound;
143 
144  if( varssize == *nvars )
145  {
146  SCIPerrorMessage("Expected %d variables, got at least %d many.\n", varssize, *nvars+1);
147  *doingfine = FALSE;
148  return SCIP_OKAY;
149  }
150 
151  /* find variable name */
152  varname = xmlGetAttrval(varnode, "name");
153 
154  /* check for mult attribute */
155  attrval = xmlGetAttrval(varnode, "mult");
156  if( attrval != NULL && strcmp(attrval, "1") != 0 )
157  {
158  SCIPerrorMessage("Variable attribute 'mult' not supported (while parsing variable <%s>)\n", varname);
159  *doingfine = FALSE;
160  return SCIP_OKAY;
161  }
162 
163  /* find variable lower bound (default is 0.0 !) */
164  attrval = xmlGetAttrval(varnode, "lb");
165  if( attrval == NULL )
166  varlb = 0.0;
167  else if( strcmp(attrval, "-INF") == 0 )
168  varlb = -SCIPinfinity(scip);
169  else if( strcmp(attrval, "INF") == 0 )
170  varlb = SCIPinfinity(scip);
171  else
172  {
173  varlb = strtod(attrval, (char**)&attrval);
174  if( *attrval != '\0' )
175  {
176  SCIPerrorMessage("Error parsing variable lower bound '%s' for variable <%s>\n", attrval, varname);
177  *doingfine = FALSE;
178  return SCIP_OKAY;
179  }
180  }
181 
182  /* find variable upper bound (default is infinity) */
183  attrval = xmlGetAttrval(varnode, "ub");
184  if( attrval == NULL )
185  varub = SCIPinfinity(scip);
186  else if( strcmp(attrval, "-INF") == 0 )
187  varub = -SCIPinfinity(scip);
188  else if( strcmp(attrval, "INF") == 0 )
189  varub = SCIPinfinity(scip);
190  else
191  {
192  varub = strtod(attrval, (char**)&attrval);
193  if( *attrval != '\0' )
194  {
195  SCIPerrorMessage("Error parsing variable upper bound '%s' for variable <%s>\n", attrval, varname);
196  *doingfine = FALSE;
197  return SCIP_OKAY;
198  }
199  }
200 
201  semibound = SCIP_INVALID;
202 
203  /* find variable type (default is continuous)
204  * adjust variable lower bound for semicontinuous variables
205  */
206  attrval = xmlGetAttrval(varnode, "type");
207  if( attrval == NULL )
208  vartype = SCIP_VARTYPE_CONTINUOUS;
209  else switch( *attrval )
210  {
211  case 'C':
212  vartype = SCIP_VARTYPE_CONTINUOUS;
213  break;
214  case 'B':
215  vartype = SCIP_VARTYPE_BINARY;
216  if( varub > 1.0 )
217  varub = 1.0;
218  break;
219  case 'I':
220  vartype = SCIP_VARTYPE_INTEGER;
221  break;
222  case 'D':
223  vartype = SCIP_VARTYPE_CONTINUOUS;
224  if( varlb > 0.0 )
225  semibound = varlb;
226  varlb = 0.0;
227  break;
228  case 'J':
229  vartype = SCIP_VARTYPE_INTEGER;
230  if( varlb > 0.0 )
231  semibound = varlb;
232  varlb = 0.0;
233  break;
234  default:
235  SCIPerrorMessage("Unsupported variable type '%s' for variable <%s>\n", attrval, varname);
236  *doingfine = FALSE;
237  return SCIP_OKAY;
238  }
239 
240  if( vartype != SCIP_VARTYPE_CONTINUOUS )
241  {
242  varlb = SCIPceil(scip, varlb);
243  varub = SCIPfloor(scip, varub);
244  }
245 
246  /* create SCIP variable */
247  SCIP_CALL( SCIPcreateVar(scip, &(*vars)[*nvars], varname, varlb, varub, 0.0, vartype, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
248  assert((*vars)[*nvars] != NULL);
249 
250  /* add variable to problem */
251  SCIP_CALL( SCIPaddVar(scip, (*vars)[*nvars]) );
252 
253  /* if variable is actually semicontinuous or semiintegral, create bounddisjunction constraint (var <= 0.0 || var >= semibound) */
254  if( semibound != SCIP_INVALID ) /*lint !e777*/
255  {
256  SCIP_CONS* cons;
257  SCIP_VAR* consvars[2];
258  SCIP_BOUNDTYPE boundtypes[2];
259  SCIP_Real bounds[2];
260  char name[SCIP_MAXSTRLEN];
261 
262  consvars[0] = (*vars)[*nvars];
263  consvars[1] = (*vars)[*nvars];
264 
265  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
266  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
267 
268  bounds[0] = 0.0;
269  bounds[1] = semibound;
270 
271  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_semibound", SCIPvarGetName((*vars)[*nvars]));
272 
273  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, consvars, boundtypes, bounds,
274  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) );
275  SCIP_CALL( SCIPaddCons(scip, cons) );
276  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
277  }
278 
279  ++*nvars;
280  }
281  if( *nvars < varssize )
282  {
283  SCIPerrorMessage("Expected %d variables, but got only %d many.\n", varssize, *nvars);
284  *doingfine = FALSE;
285  return SCIP_OKAY;
286  }
287 
288  return SCIP_OKAY;
289 }
290 
291 /** setup linear coefficients and constant of objective and objective sense */
292 static
294  SCIP* scip, /**< SCIP data structure */
295  const XML_NODE* datanode, /**< XML root node for instance data */
296  SCIP_VAR** vars, /**< variables in order of OSiL indices */
297  int nvars, /**< number of variables */
298  SCIP_Bool dynamiccols, /**< should columns be added and removed dynamically to the LP? */
299  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
300  )
301 {
302  const XML_NODE* objective;
303  const XML_NODE* coefnode;
304  const char* attrval;
305 
306  assert(scip != NULL);
307  assert(datanode != NULL);
308  assert(vars != NULL || nvars == 0);
309  assert(doingfine != NULL);
310 
311  /* check for first objective */
312  objective = xmlFindNodeMaxdepth(datanode, "obj", 0, 2);
313 
314  /* if no objective, then nothing to do here */
315  if( objective == NULL )
316  return SCIP_OKAY;
317 
318  /* check for mult attribute */
319  attrval = xmlGetAttrval(objective, "mult");
320  if( attrval != NULL && strcmp(attrval, "1") != 0 )
321  {
322  SCIPerrorMessage("Objective attribute 'mult' not supported.\n");
323  *doingfine = FALSE;
324  return SCIP_OKAY;
325  }
326 
327  /* objective sense */
328  attrval = xmlGetAttrval(objective, "maxOrMin");
329  if( attrval == NULL )
330  {
331  SCIPerrorMessage("Objective sense missing.\n");
332  *doingfine = FALSE;
333  return SCIP_OKAY;
334  }
335  else if( strcmp(attrval, "min") == 0 )
336  {
338  }
339  else if( strcmp(attrval, "max") == 0 )
340  {
342  }
343  else
344  {
345  SCIPerrorMessage("Cannot parse objective sense '%s'.\n", attrval);
346  *doingfine = FALSE;
347  return SCIP_OKAY;
348  }
349 
350  /* objective coefficients */
351  for( coefnode = xmlFirstChild(objective); coefnode != NULL; coefnode = xmlNextSibl(coefnode) )
352  {
353  SCIP_Real val;
354  int idx;
355 
356  /* get variable index */
357  attrval = xmlGetAttrval(coefnode, "idx");
358  if( attrval == NULL )
359  {
360  SCIPerrorMessage("Missing \"idx\" attribute in objective coefficient.\n");
361  *doingfine = FALSE;
362  return SCIP_OKAY;
363  }
364  idx = (int)strtol(attrval, (char**)&attrval, 10);
365  if( *attrval != '\0' )
366  {
367  SCIPerrorMessage("Error parsing variable index '%s' of objective coefficient.\n", xmlGetAttrval(coefnode, "idx"));
368  *doingfine = FALSE;
369  return SCIP_OKAY;
370  }
371 
372  if( idx < 0 || idx >= nvars )
373  {
374  SCIPerrorMessage("Invalid variable index '%d' of objective coefficient.\n", idx);
375  *doingfine = FALSE;
376  return SCIP_OKAY;
377  }
378 
379  /* get coefficient value */
380  if( xmlFirstChild(coefnode) == NULL || xmlGetData(xmlFirstChild(coefnode)) == NULL )
381  {
382  SCIPerrorMessage("No objective coefficient stored for %d'th variable (<%s>).\n", idx, SCIPvarGetName(vars[idx])); /*lint !e613*/
383  *doingfine = FALSE;
384  return SCIP_OKAY;
385  }
386 
387  attrval = xmlGetData(xmlFirstChild(coefnode));
388  val = strtod(attrval, (char**)&attrval);
389  if( *attrval != '\0' )
390  {
391  SCIPerrorMessage("Error parsing objective coefficient value '%s' for %d'th variable (<%s>).\n", xmlGetData(xmlFirstChild(coefnode)), idx, SCIPvarGetName(vars[idx])); /*lint !e613*/
392  *doingfine = FALSE;
393  return SCIP_OKAY;
394  }
395 
396  /* change objective coefficient of SCIP variable */
397  SCIP_CALL( SCIPchgVarObj(scip, vars[idx], val) ); /*lint !e613*/
398  }
399 
400  /* objective constant: model as fixed variable, if nonzero */
401  attrval = xmlGetAttrval(objective, "constant");
402  if( attrval != NULL )
403  {
404  SCIP_Real objconst;
405 
406  objconst = strtod(attrval, (char**)&attrval);
407  if( *attrval != '\0' )
408  {
409  SCIPerrorMessage("Error parsing objective constant '%s'\n", xmlGetAttrval(objective, "constant"));
410  *doingfine = FALSE;
411  return SCIP_OKAY;
412  }
413 
414  if( objconst != 0.0 )
415  {
416  SCIP_VAR* objconstvar;
417 
418  SCIP_CALL( SCIPcreateVar(scip, &objconstvar, "objconstvar", objconst, objconst, 1.0, SCIP_VARTYPE_CONTINUOUS, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
419  SCIP_CALL( SCIPaddVar(scip, objconstvar) );
420  SCIP_CALL( SCIPreleaseVar(scip, &objconstvar) );
421  }
422  }
423 
424  if( xmlNextSibl(objective) != NULL )
425  {
426  SCIPerrorMessage("Multiple objectives not supported by SCIP.\n");
427  *doingfine = FALSE;
428  return SCIP_OKAY;
429  }
430 
431  return SCIP_OKAY;
432 }
433 
434 /** helper method to get the total number of constraints */
435 static
437  SCIP* scip, /**< SCIP data structure */
438  const XML_NODE* datanode, /**< XML root node for instance data */
439  int* nconss, /**< pointer to store the total number of constraints */
440  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
441  )
442 {
443  const XML_NODE* constraints;
444  const char* attrval;
445 
446  assert(scip != NULL);
447  assert(datanode != NULL);
448  assert(nconss != NULL);
449  assert(doingfine != NULL);
450 
451  *nconss = 0;
452 
453  constraints = xmlFindNodeMaxdepth(datanode, "constraints", 0, 1);
454 
455  /* if no constraints, then nothing to do here */
456  if( constraints == NULL )
457  return SCIP_OKAY;
458 
459  /* read number of constraints */
460  attrval = xmlGetAttrval(constraints, "numberOfConstraints");
461  if( attrval == NULL )
462  {
463  SCIPerrorMessage("Attribute \"numberOfConstraints\" not found in <constraints> node.\n");
464  *doingfine = FALSE;
465  return SCIP_OKAY;
466  }
467 
468  *nconss = (int)strtol(attrval, (char**)&attrval, 10);
469  if( *attrval != '\0' || *nconss < 0 )
470  {
471  SCIPerrorMessage("Invalid value '%s' for \"numberOfConstraints\" attribute.\n", xmlGetAttrval(constraints, "numberOfConstraints"));
472  *doingfine = FALSE;
473  return SCIP_OKAY;
474  }
475  assert(*nconss >= 0);
476 
477  return SCIP_OKAY;
478 }
479 
480 /** helper method to create and add a constraint (or a nonlinear objective constraint) */
481 static
483  SCIP* scip, /**< SCIP data structure */
484  SCIP_VAR** linvars, /**< array containing the linear variables (might be NULL) */
485  SCIP_Real* lincoefs, /**< array containing the coefficients of the linear variables (might be NULL) */
486  int nlinvars, /**< the total number of linear variables */
487  SCIP_VAR** quadvars1, /**< array containing the first variables of the quadratic terms (might be NULL) */
488  SCIP_VAR** quadvars2, /**< array containing the second variables of the quadratic terms (might be NULL) */
489  SCIP_Real* quadcoefs, /**< array containing the coefficients of the quadratic terms (might be NULL) */
490  int nquadterms, /**< the total number of quadratic terms */
491  SCIP_EXPR* nlexpr, /**< the nonlinear part (might be NULL) */
492  SCIP_Real lhs, /**< left-hand side */
493  SCIP_Real rhs, /**< right-hand side */
494  const char* name, /**< name of the constraint */
495  SCIP_Bool objcons, /**< whether to add an objective constraints */
496  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
497  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
498  SCIP_Bool dynamicrows /**< should rows be added and removed dynamically to the LP? */
499  )
500 {
501  SCIP_CONS* cons;
502  SCIP_VAR* objvar = NULL;
503 
504  assert(nlinvars >= 0);
505  assert(nquadterms >= 0);
506 
507  /* create objective variable, if requested */
508  if( objcons )
509  {
510  SCIP_CALL( SCIPcreateVar(scip, &objvar, "nlobjvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
512  SCIP_CALL( SCIPaddVar(scip, objvar) );
513  }
514 
515  /* linear constraint (can be empty) */
516  if( nquadterms == 0 && nlexpr == NULL )
517  {
518  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, name,
519  nlinvars, linvars, lincoefs, lhs, rhs, initialconss,
520  TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows, FALSE) );
521 
522  /* add objective variable, if requested */
523  if( objcons )
524  {
525  assert(objvar != NULL);
526  SCIP_CALL( SCIPaddCoefLinear(scip, cons, objvar, -1.0) );
527  }
528  }
529  /* nonlinear constraint */
530  else
531  {
532  SCIP_EXPR* expr = NULL;
533  SCIP_EXPR* varexpr = NULL;
534 
535  /* create variable expression for objvar */
536  if( objcons )
537  {
538  SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, objvar, NULL, NULL) );
539  }
540 
541  /* check whether there is a quadratic part */
542  if( nlinvars > 0 || nquadterms > 0 )
543  {
544  /* create quadratic expression; note that this is always a sum */
545  SCIP_CALL( SCIPcreateExprQuadratic(scip, &expr, nlinvars, linvars, lincoefs,
546  nquadterms, quadvars1, quadvars2, quadcoefs, NULL, NULL) );
547  assert(SCIPisExprSum(scip, expr));
548 
549  /* add nonlinear expression as a child to expr */
550  if( nlexpr != NULL )
551  {
552  SCIP_CALL( SCIPappendExprSumExpr(scip, expr, nlexpr, 1.0) );
553  }
554 
555  /* add expression that represents the objective variable as a child to expr */
556  if( varexpr != NULL )
557  {
558  SCIP_CALL( SCIPappendExprSumExpr(scip, expr, varexpr, -1.0) );
559  }
560 
561  /* create nonlinear constraint */
562  SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, expr, lhs, rhs,
563  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows) );
564 
565  /* release created expression */
566  SCIP_CALL( SCIPreleaseExpr(scip, &expr) );
567  }
568 
569  /* there is no quadratic part but we might need to take care of the objective variable */
570  else
571  {
572  assert(nlexpr != NULL);
573 
574  if( objcons )
575  {
576  SCIP_EXPR* sumexpr;
577  SCIP_EXPR* children[2] = {nlexpr, varexpr};
578  SCIP_Real coefs[2] = {1.0, -1.0};
579 
580  assert(varexpr != NULL);
581 
582  /* create sum expression */
583  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 2, children, coefs, 0.0, NULL, NULL) );
584 
585  /* create nonlinear constraint */
586  SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, sumexpr, lhs, rhs,
587  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows) );
588 
589  /* release sum expression */
590  SCIP_CALL( SCIPreleaseExpr(scip, &sumexpr) );
591  }
592  else
593  {
594  /* create nonlinear constraint */
595  SCIP_CALL( SCIPcreateConsNonlinear(scip, &cons, name, nlexpr, lhs, rhs,
596  initialconss, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamicrows) );
597  }
598  }
599 
600  /* release variable expression */
601  if( objcons )
602  {
603  assert(varexpr != NULL);
604  SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
605  }
606  }
607 
608  /* add and release constraint */
609  SCIP_CALL( SCIPaddCons(scip, cons) );
610  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
611 
612  /* release objective variable */
613  if( objcons )
614  {
615  assert(objvar != NULL);
616  SCIP_CALL( SCIPreleaseVar(scip, &objvar) );
617  }
618 
619  return SCIP_OKAY;
620 }
621 
622 
623 /** reads constraint-specific information; creates and adds linear and nonlinear constraints based on the
624  * information that have been collected by @ref readLinearCoefs, @ref readQuadraticCoefs, and @ref readNonlinearExprs
625  */
626 static
628  SCIP* scip, /**< SCIP data structure */
629  const XML_NODE* datanode, /**< XML root node for instance data */
630  int nconss, /**< total number of constraints */
631  SCIP_VAR*** linvars, /**< array containing for each constraint the linear variables */
632  SCIP_Real** lincoefs, /**< array containing for each constraint the coefficients of the linear variables */
633  int* nlinvars, /**< array containing for each constraint the total number of linear variables */
634  SCIP_VAR*** quadvars1, /**< array containing for each constraint the first variables of the quadratic terms */
635  SCIP_VAR*** quadvars2, /**< array containing for each constraint the second variables of the quadratic terms */
636  SCIP_Real** quadcoefs, /**< array containing for each constraint the coefficients of the quadratic terms */
637  int* nquadterms, /**< array containing for each constraint the total number of quadratic terms */
638  SCIP_EXPR** nlexprs, /**< array containing for each constraint the nonlinear part */
639  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
640  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
641  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
642  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
643  )
644 {
645  const XML_NODE* constraints;
646  const XML_NODE* consnode;
647  const char* attrval;
648  char name[SCIP_MAXSTRLEN];
649  int c = 0;
650 
651  assert(scip != NULL);
652  assert(datanode != NULL);
653  assert(doingfine != NULL);
654  assert(linvars != NULL);
655  assert(lincoefs != NULL);
656  assert(nlinvars != NULL);
657  assert(quadvars1 != NULL);
658  assert(quadvars2 != NULL);
659  assert(quadcoefs != NULL);
660  assert(nquadterms != NULL);
661  assert(nlexprs != NULL);
662 
663  constraints = xmlFindNodeMaxdepth(datanode, "constraints", 0, 1);
664 
665  /* if no constraints, then nothing to do here */
666  if( constraints == NULL )
667  return SCIP_OKAY;
668 
669  /* read constraint names, lhs, rhs, constant */
670  for( consnode = xmlFirstChild(constraints); consnode != NULL; consnode = xmlNextSibl(consnode) )
671  {
672  const char* consname;
673  SCIP_Real conslhs;
674  SCIP_Real consrhs;
675 
676  if( c == nconss )
677  {
678  SCIPerrorMessage("Expected %d constraints, but got at least %d many.\n", nconss, c+1);
679  *doingfine = FALSE;
680  return SCIP_OKAY;
681  }
682 
683  /* find constraint name */
684  consname = xmlGetAttrval(consnode, "name");
685  if( consname == NULL )
686  {
687  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "cons%d", c);
688  consname = name;
689  }
690 
691  /* check for mult attribute */
692  attrval = xmlGetAttrval(consnode, "mult");
693  if( attrval != NULL && strcmp(attrval, "1") != 0 )
694  {
695  SCIPerrorMessage("Constraint attribute 'mult' not supported (while parsing constraint <%s>).\n", consname);
696  *doingfine = FALSE;
697  return SCIP_OKAY;
698  }
699 
700  /* find constraint lower bound (=lhs) (default is -infinity) */
701  attrval = xmlGetAttrval(consnode, "lb");
702  if( attrval == NULL )
703  conslhs = -SCIPinfinity(scip);
704  else if( strcmp(attrval, "-INF") == 0 )
705  conslhs = -SCIPinfinity(scip);
706  else if( strcmp(attrval, "INF") == 0 )
707  conslhs = SCIPinfinity(scip);
708  else
709  {
710  conslhs = strtod(attrval, (char**)&attrval);
711  if( *attrval != '\0' )
712  {
713  SCIPerrorMessage("Error parsing constraint lower bound '%s' for constraint <%s>.\n", attrval, consname);
714  *doingfine = FALSE;
715  return SCIP_OKAY;
716  }
717  }
718 
719  /* find constraint upper bound (=rhs) (default is +infinity) */
720  attrval = xmlGetAttrval(consnode, "ub");
721  if( attrval == NULL )
722  consrhs = SCIPinfinity(scip);
723  else if( strcmp(attrval, "-INF") == 0 )
724  consrhs = -SCIPinfinity(scip);
725  else if( strcmp(attrval, "INF") == 0 )
726  consrhs = SCIPinfinity(scip);
727  else
728  {
729  consrhs = strtod(attrval, (char**)&attrval);
730  if( *attrval != '\0' )
731  {
732  SCIPerrorMessage("Error parsing constraint upper bound '%s' for constraint <%s>.\n", attrval, consname);
733  *doingfine = FALSE;
734  return SCIP_OKAY;
735  }
736  }
737 
738  /* find constraint constant (default is 0.0) and substract from lhs/rhs */
739  attrval = xmlGetAttrval(consnode, "constant");
740  if( attrval != NULL )
741  {
742  SCIP_Real consconstant;
743 
744  consconstant = strtod(attrval, (char**)&attrval);
745  if( *attrval != '\0' )
746  {
747  SCIPerrorMessage("Error parsing constraint constant '%s' for constraint <%s>.\n", attrval, consname);
748  *doingfine = FALSE;
749  return SCIP_OKAY;
750  }
751  if( conslhs > -SCIPinfinity(scip) )
752  conslhs -= consconstant;
753  if( consrhs < SCIPinfinity(scip) )
754  consrhs -= consconstant;
755  }
756 
757  /* create, add, and release constraint */
758  SCIP_CALL( createConstraint(scip, linvars[c], lincoefs[c], nlinvars[c],
759  quadvars1[c], quadvars2[c], quadcoefs[c], nquadterms[c], nlexprs[c],
760  conslhs, consrhs, consname, FALSE, initialconss, dynamicconss, dynamicrows) );
761 
762  ++c;
763  }
764 
765  if( c != nconss )
766  {
767  SCIPerrorMessage("Got %d constraints, but expected %d many.\n", c, nconss);
768  *doingfine = FALSE;
769  return SCIP_OKAY;
770  }
771 
772  return SCIP_OKAY;
773 }
774 
775 /** reads mult and incr attributes of an OSiL node
776  *
777  * if mult attribute is not present, then returns mult=1
778  * if incr attribute is not present, then returns incrint=0 and incrreal=0
779  */
780 static
782  const XML_NODE* node, /**< XML node to read attributes from */
783  int* mult, /**< buffer to store mult */
784  int* incrint, /**< buffer to store incr as int, or NULL if no int expected */
785  SCIP_Real* incrreal, /**< buffer to store incr as real, or NULL if no real expected */
786  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
787  )
788 {
789  const char* attrval;
790 
791  assert(node != NULL);
792  assert(mult != NULL);
793  assert(doingfine != NULL);
794 
795  *mult = 1;
796  if( incrint != NULL )
797  *incrint = 0;
798  if( incrreal != NULL )
799  *incrreal = 0.0;
800 
801  attrval = xmlGetAttrval(node, "mult");
802  if( attrval == NULL )
803  return;
804 
805  /* read "mult" attribute */
806  *mult = (int)strtol(attrval, (char**)&attrval, 10);
807  if( *attrval != '\0' || *mult < 1 )
808  {
809  SCIPerrorMessage("Invalid value '%s' in \"mult\" attribute of node.\n", xmlGetAttrval(node, "mult"));
810  *doingfine = FALSE;
811  return;
812  }
813 
814  if( *mult == 1 )
815  return;
816 
817  /* read "incr" attribute */
818  attrval = xmlGetAttrval(node, "incr");
819  if( attrval == NULL )
820  return;
821 
822  if( incrint != NULL )
823  {
824  *incrint = (int)strtol(attrval, (char**)&attrval, 10);
825  if( *attrval != '\0' )
826  {
827  SCIPerrorMessage("Invalid value '%s' in \"incr\" attribute of node.\n", xmlGetAttrval(node, "incr"));
828  *doingfine = FALSE;
829  return;
830  }
831  }
832 
833  if( incrreal != NULL )
834  {
835  *incrreal = strtod(attrval, (char**)&attrval);
836  if( *attrval != '\0' || !SCIPisFinite(*incrreal) )
837  {
838  SCIPerrorMessage("Invalid value '%s' in \"incr\" attribute of node.\n", xmlGetAttrval(node, "incr"));
839  *doingfine = FALSE;
840  return;
841  }
842  }
843 }
844 
845 /** parse linear coefficients of constraints */
846 static
848  SCIP* scip, /**< SCIP data structure */
849  const XML_NODE* datanode, /**< XML root node for instance data */
850  SCIP_VAR** vars, /**< variables in order of OSiL indices */
851  int nvars, /**< number of variables */
852  int nconss, /**< number of constraints */
853  SCIP_VAR*** linvars, /**< array to store for each constraint the linear variables */
854  SCIP_Real** lincoefs, /**< array to store for each constraint the coefficients of the linear variables */
855  int* nlinvars, /**< array to store for each constraint the total number of linear variables */
856  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
857  )
858 {
859  const XML_NODE* lincoef;
860  const XML_NODE* startnode;
861  const XML_NODE* idxnode;
862  const XML_NODE* valnode;
863  const XML_NODE* elnode;
864  const char* attrval;
865  SCIP_Bool rowmajor;
866  int* start;
867  int* idx;
868  SCIP_Real* val;
869  int nnz;
870  int count;
871  int mult;
872  int incrint;
873  SCIP_Real incrreal;
874 
875  assert(scip != NULL);
876  assert(datanode != NULL);
877  assert(vars != NULL || nvars == 0);
878  assert(doingfine != NULL);
879 
880  lincoef = xmlFindNodeMaxdepth(datanode, "linearConstraintCoefficients", 0, 1);
881 
882  if( lincoef == NULL )
883  return SCIP_OKAY;
884 
885  /* get number of linear constraint coefficients */
886  attrval = xmlGetAttrval(lincoef, "numberOfValues");
887  if( attrval == NULL )
888  {
889  SCIPerrorMessage("Attribute \"numberOfValues\" not found for <linearConstraintCoefficients> node.\n");
890  *doingfine = FALSE;
891  return SCIP_OKAY;
892  }
893 
894  nnz = (int)strtol(attrval, (char**)&attrval, 10);
895  if( *attrval != '\0' || nnz < 0 )
896  {
897  SCIPerrorMessage("Invalid value '%s' for \"numberOfValues\" attribute in <linearConstraintCoefficients> node.\n", xmlGetAttrval(lincoef, "numberOfValues"));
898  *doingfine = FALSE;
899  return SCIP_OKAY;
900  }
901  assert(nnz >= 0);
902 
903  /* check for start, rowIdx, colIdx, and value nodes */
904  startnode = xmlFindNodeMaxdepth(lincoef, "start", 0, 1);
905  if( startnode == NULL )
906  {
907  SCIPerrorMessage("Node <start> not found inside <linearConstraintCoefficients> node.\n");
908  *doingfine = FALSE;
909  return SCIP_OKAY;
910  }
911 
912  idxnode = xmlFindNodeMaxdepth(lincoef, "rowIdx", 0, 1);
913  if( idxnode != NULL )
914  {
915  if( xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1) != NULL )
916  {
917  SCIPerrorMessage("Both <rowIdx> and <colIdx> found under <linearConstraintCoefficients> node.\n");
918  *doingfine = FALSE;
919  return SCIP_OKAY;
920  }
921  rowmajor = FALSE;
922  }
923  else
924  {
925  idxnode = xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1);
926  if( idxnode == NULL )
927  {
928  SCIPerrorMessage("Both <rowIdx> and <colIdx> not found under <linearConstraintCoefficients> node.\n");
929  *doingfine = FALSE;
930  return SCIP_OKAY;
931  }
932  rowmajor = TRUE;
933  }
934 
935  valnode = xmlFindNodeMaxdepth(lincoef, "value", 0, 1);
936  if( valnode == NULL )
937  {
938  SCIPerrorMessage("<value> node not found under <linearConstraintCoefficients> node.\n");
939  *doingfine = FALSE;
940  return SCIP_OKAY;
941  }
942 
943  start = NULL;
944  idx = NULL;
945  val = NULL;
946 
947  /* read row or column start indices */
948  SCIP_CALL( SCIPallocBufferArray(scip, &start, (rowmajor ? nconss : nvars) + 1) );
949 
950  count = 0;
951  for( elnode = xmlFirstChild(startnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
952  {
953  /* check for <el> node and read it's data */
954  if( strcmp(xmlGetName(elnode), "el") != 0 )
955  {
956  SCIPerrorMessage("Expected <el> node under <start> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
957  *doingfine = FALSE;
958  goto CLEANUP;
959  }
960  if( count >= (rowmajor ? nconss : nvars) + 1 )
961  {
962  SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
963  *doingfine = FALSE;
964  goto CLEANUP;
965  }
966  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
967  {
968  SCIPerrorMessage("No data in <el> node in <linearConstraintCoefficients>.\n");
969  *doingfine = FALSE;
970  goto CLEANUP;
971  }
972 
973  start[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
974 
975  if( *attrval != '\0' || start[count] < 0 || (start[count] > nnz) )
976  {
977  SCIPerrorMessage("Invalid value '%s' in <el> node under <start> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
978  *doingfine = FALSE;
979  goto CLEANUP;
980  }
981 
982  /* add additional start-indices according to mult and incr attributes */
983  readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
984  if( !*doingfine )
985  goto CLEANUP;
986 
987  for( --mult; mult > 0; --mult )
988  {
989  ++count;
990  if( count >= (rowmajor ? nconss : nvars) + 1 )
991  {
992  SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
993  *doingfine = FALSE;
994  goto CLEANUP;
995  }
996  start[count] = start[count-1] + incrint;
997  }
998  }
999  if( count != (rowmajor ? nconss : nvars) + 1 )
1000  {
1001  SCIPerrorMessage("Got only %d <start> entries in <linearConstraintCoefficients>, but expected %d many.\n", count, (rowmajor ? nconss : nvars) + 1);
1002  *doingfine = FALSE;
1003  goto CLEANUP;
1004  }
1005 
1006  /* read row or column indices */
1007  SCIP_CALL( SCIPallocBufferArray(scip, &idx, nnz) );
1008 
1009  count = 0;
1010  for( elnode = xmlFirstChild(idxnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
1011  {
1012  /* check for <el> node and read it's data */
1013  if( strcmp(xmlGetName(elnode), "el") != 0 )
1014  {
1015  SCIPerrorMessage("Expected <el> node under <%s> node in <linearConstraintCoefficients>, but got '%s'.\n", rowmajor ? "colIdx" : "rowIdx", xmlGetName(elnode));
1016  *doingfine = FALSE;
1017  goto CLEANUP;
1018  }
1019  if( count >= nnz )
1020  {
1021  SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, but got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
1022  *doingfine = FALSE;
1023  goto CLEANUP;
1024  }
1025  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
1026  {
1027  SCIPerrorMessage("No data in <el> node under <%s> node in <linearConstraintCoefficients>.\n", rowmajor ? "colIdx" : "rowIdx");
1028  *doingfine = FALSE;
1029  goto CLEANUP;
1030  }
1031 
1032  idx[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
1033 
1034  if( *attrval != '\0' || idx[count] < 0 || (idx[count] >= (rowmajor ? nvars : nconss)) )
1035  {
1036  SCIPerrorMessage("Invalid value '%s' in <el> node under <%s> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode), rowmajor ? "colIdx" : "rowIdx");
1037  *doingfine = FALSE;
1038  goto CLEANUP;
1039  }
1040 
1041  /* add additional indices according to mult and incr attributes */
1042  readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
1043  if( !*doingfine )
1044  goto CLEANUP;
1045 
1046  for( --mult; mult > 0; --mult )
1047  {
1048  ++count;
1049  if( count >= nnz )
1050  {
1051  SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
1052  *doingfine = FALSE;
1053  goto CLEANUP;
1054  }
1055  idx[count] = idx[count-1] + incrint;
1056  }
1057  }
1058  if( count != nnz )
1059  {
1060  SCIPerrorMessage("Got only %d entries in <%s> node in <linearConstraintCoefficients>, expected %d many.\n", count, rowmajor ? "colIdx" : "rowIdx", nnz);
1061  *doingfine = FALSE;
1062  goto CLEANUP;
1063  }
1064 
1065  /* read coefficient values */
1066  SCIP_CALL( SCIPallocBufferArray(scip, &val, nnz) );
1067 
1068  count = 0;
1069  for( elnode = xmlFirstChild(valnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
1070  {
1071  /* check for <el> node and read it's data */
1072  if( strcmp(xmlGetName(elnode), "el") != 0 )
1073  {
1074  SCIPerrorMessage("Expected <el> node under <value> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
1075  *doingfine = FALSE;
1076  goto CLEANUP;
1077  }
1078  if( count >= nnz )
1079  {
1080  SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
1081  *doingfine = FALSE;
1082  goto CLEANUP;
1083  }
1084  if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
1085  {
1086  SCIPerrorMessage("No data in <el> node under <value> node in <linearConstraintCoefficients>.\n");
1087  *doingfine = FALSE;
1088  goto CLEANUP;
1089  }
1090 
1091  val[count] = strtod(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval);
1092 
1093  if( *attrval != '\0' || !SCIPisFinite(val[count]) )
1094  {
1095  SCIPerrorMessage("Invalid value '%s' in <el> node under <value> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
1096  *doingfine = FALSE;
1097  goto CLEANUP;
1098  }
1099 
1100  /* add additional values according to mult and incr attributes */
1101  readMultIncr(elnode, &mult, NULL, &incrreal, doingfine);
1102  if( !*doingfine )
1103  goto CLEANUP;
1104 
1105  for( --mult; mult > 0; --mult )
1106  {
1107  ++count;
1108  if( count >= nnz )
1109  {
1110  SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
1111  *doingfine = FALSE;
1112  goto CLEANUP;
1113  }
1114  val[count] = val[count-1] + incrreal;
1115  }
1116  }
1117  if( count != nnz )
1118  {
1119  SCIPerrorMessage("Got only %d entries under <value> node in <linearConstraintCoefficients>, expected %d many.\n", count, nnz);
1120  *doingfine = FALSE;
1121  goto CLEANUP;
1122  }
1123 
1124  /* add coefficients to linear constraints */
1125  if( rowmajor )
1126  {
1127  int row;
1128  int pos;
1129  for( row = 0; row < nconss; ++row )
1130  {
1131  int nterms;
1132 
1133  /* these asserts were checked above */
1134  assert(start[row] >= 0);
1135  assert(start[row+1] >= 0);
1136  assert(start[row] <= nnz);
1137  assert(start[row+1] <= nnz);
1138 
1139  assert(linvars[row] == NULL);
1140  assert(lincoefs[row] == NULL);
1141  assert(nlinvars[row] == 0);
1142 
1143  nterms = start[row+1] - start[row];
1144  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &linvars[row], nterms) );
1145  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lincoefs[row], nterms) );
1146 
1147  for( pos = start[row]; pos < start[row+1]; ++pos )
1148  {
1149  /* these asserts were checked above */
1150  assert(pos >= 0);
1151  assert(pos < nnz);
1152  assert(idx[pos] >= 0);
1153  assert(idx[pos] < nvars);
1154 
1155  linvars[row][nlinvars[row]] = vars[idx[pos]];
1156  lincoefs[row][nlinvars[row]] = val[pos];
1157  ++(nlinvars[row]);
1158  }
1159  assert(nlinvars[row] == nterms);
1160  }
1161  }
1162  else
1163  {
1164  int col;
1165  int pos;
1166  int k;
1167 
1168  /* allocate memory for the coefficients in iteration k=0; in k=1 fill in the data */
1169  for( k = 0; k < 2; ++k )
1170  {
1171  for( col = 0; col < nvars; ++col )
1172  {
1173  /* these asserts were checked above */
1174  assert(start[col] >= 0);
1175  assert(start[col+1] >= 0);
1176  assert(start[col] <= nnz);
1177  assert(start[col+1] <= nnz);
1178  for( pos = start[col]; pos < start[col+1]; ++pos )
1179  {
1180  int considx = idx[pos];
1181 
1182  /* these asserts were checked above */
1183  assert(pos >= 0);
1184  assert(pos < nnz);
1185  assert(considx >= 0);
1186  assert(considx < nconss);
1187 
1188  if( k == 0 )
1189  {
1190  ++(nlinvars[considx]);
1191  }
1192  else
1193  {
1194  linvars[considx][nlinvars[considx]] = vars[col];
1195  lincoefs[considx][nlinvars[considx]] = val[pos];
1196  ++(nlinvars[considx]);
1197  }
1198  }
1199  }
1200 
1201  /* allocate memory to store the linear coefficients for each constraint after the first iteration */
1202  if( k == 0 )
1203  {
1204  int c;
1205 
1206  for( c = 0; c < nconss; ++c )
1207  {
1208  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &linvars[c], nlinvars[c]) );
1209  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lincoefs[c], nlinvars[c]) );
1210 
1211  /* reset nlinvars[c] so it can be used for iteration k=1 */
1212  nlinvars[c] = 0;
1213  }
1214  }
1215  }
1216  }
1217 
1218  CLEANUP:
1219  SCIPfreeBufferArrayNull(scip, &val);
1220  SCIPfreeBufferArrayNull(scip, &idx);
1221  SCIPfreeBufferArrayNull(scip, &start);
1222 
1223  return SCIP_OKAY;
1224 }
1225 
1226 /** read quadratic coefficients of constraints and objective */
1227 static
1229  SCIP* scip, /**< SCIP data structure */
1230  const XML_NODE* datanode, /**< XML root node for instance data */
1231  SCIP_VAR** vars, /**< variables in order of OSiL indices */
1232  int nvars, /**< number of variables */
1233  int nconss, /**< number of constraints */
1234  SCIP_VAR*** quadvars1, /**< array to store for each constraint the first variables of the quadratic terms */
1235  SCIP_VAR*** quadvars2, /**< array to store for each constraint the second variables of the quadratic terms */
1236  SCIP_Real** quadcoefs, /**< array to store for each constraint the coefficients of the quadratic terms */
1237  int* nquadterms, /**< array to store for each constraint the total number of quadratic terms */
1238  int* termssize, /**< pointer to store the size of quadvars1, quadvars2, and quadcoefs */
1239  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1240  )
1241 {
1242  const XML_NODE* quadcoef;
1243  const XML_NODE* qterm;
1244  const char* attrval;
1245  SCIP_Real coef;
1246  int nqterms;
1247  int count;
1248  int considx;
1249  int varidx1;
1250  int varidx2;
1251 
1252  assert(scip != NULL);
1253  assert(datanode != NULL);
1254  assert(quadvars1 != NULL);
1255  assert(quadvars2 != NULL);
1256  assert(quadcoefs != NULL);
1257  assert(nquadterms != NULL);
1258  assert(doingfine != NULL);
1259 
1260  quadcoef = xmlFindNodeMaxdepth(datanode, "quadraticCoefficients", 0, 1);
1261 
1262  if( quadcoef == NULL )
1263  return SCIP_OKAY;
1264 
1265  /* read number of quadratic terms */
1266  attrval = xmlGetAttrval(quadcoef, "numberOfQuadraticTerms");
1267  if( attrval == NULL )
1268  {
1269  SCIPerrorMessage("Attribute \"numberOfQuadraticTerms\" not found for <quadraticCoefficients> node.\n");
1270  *doingfine = FALSE;
1271  return SCIP_OKAY;
1272  }
1273 
1274  nqterms = (int)strtol(attrval, (char**)&attrval, 10);
1275  if( *attrval != '\0' || nqterms < 0 )
1276  {
1277  SCIPerrorMessage("Invalid value '%s' for \"numberOfQuadraticTerms\" attribute of <quadraticCoefficients> node.\n", xmlGetAttrval(quadcoef, "numberOfQuadraticTerms"));
1278  *doingfine = FALSE;
1279  return SCIP_OKAY;
1280  }
1281  assert(nqterms >= 0);
1282 
1283  if( nqterms == 0 )
1284  return SCIP_OKAY;
1285 
1286  assert(vars != NULL);
1287 
1288  count = 0;
1289  for( qterm = xmlFirstChild(quadcoef); qterm != NULL; qterm = xmlNextSibl(qterm), ++count )
1290  {
1291  /* check for qterm node */
1292  if( strcmp(xmlGetName(qterm), "qTerm") != 0 )
1293  {
1294  SCIPerrorMessage("Expected <qTerm> node under <quadraticCoefficients> node, but got <%s>\n", xmlGetName(qterm));
1295  *doingfine = FALSE;
1296  return SCIP_OKAY;
1297  }
1298  if( count >= nqterms )
1299  {
1300  SCIPerrorMessage("Too many quadratic terms under <quadraticCoefficients> node, expected %d many, but got at least %d.\n", nqterms, count + 1);
1301  *doingfine = FALSE;
1302  return SCIP_OKAY;
1303  }
1304 
1305  /* get constraint index, or -1 for objective */
1306  attrval = xmlGetAttrval(qterm, "idx");
1307  if( attrval == NULL )
1308  {
1309  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1310  *doingfine = FALSE;
1311  return SCIP_OKAY;
1312  }
1313 
1314  considx = (int)strtol(attrval, (char**)&attrval, 10);
1315  if( *attrval != '\0' || considx < -1 || considx >= nconss )
1316  {
1317  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idx"), count);
1318  *doingfine = FALSE;
1319  return SCIP_OKAY;
1320  }
1321 
1322  /* get index of first variable */
1323  attrval = xmlGetAttrval(qterm, "idxOne");
1324  if( attrval == NULL )
1325  {
1326  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1327  *doingfine = FALSE;
1328  return SCIP_OKAY;
1329  }
1330 
1331  varidx1 = (int)strtol(attrval, (char**)&attrval, 10);
1332  if( *attrval != '\0' || varidx1 < 0 || varidx1 >= nvars )
1333  {
1334  SCIPerrorMessage("Invalid value '%s' in \"idxOne\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxOne"), count);
1335  *doingfine = FALSE;
1336  return SCIP_OKAY;
1337  }
1338 
1339  /* get index of second variable */
1340  attrval = xmlGetAttrval(qterm, "idxTwo");
1341  if( attrval == NULL )
1342  {
1343  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1344  *doingfine = FALSE;
1345  return SCIP_OKAY;
1346  }
1347 
1348  varidx2 = (int)strtol(attrval, (char**)&attrval, 10);
1349  if( *attrval != '\0' || varidx2 < 0 || varidx2 >= nvars )
1350  {
1351  SCIPerrorMessage("Invalid value '%s' in \"idxTwo\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxTwo"), count);
1352  *doingfine = FALSE;
1353  return SCIP_OKAY;
1354  }
1355 
1356  /* get (optional) coefficient of quadratic term */
1357  attrval = xmlGetAttrval(qterm, "coef");
1358  if( attrval != NULL )
1359  {
1360  coef = strtod(attrval, (char**)&attrval);
1361  if( *attrval != '\0' || (coef != coef) ) /*lint !e777*/
1362  {
1363  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "coef"), count);
1364  *doingfine = FALSE;
1365  return SCIP_OKAY;
1366  }
1367  }
1368  else
1369  {
1370  /* default is 1.0 according to specification */
1371  coef = 1.0;
1372  }
1373 
1374  /* skip zero coefficients */
1375  if( coef == 0.0 )
1376  continue;
1377 
1378  /* put objective at end of array */
1379  if( considx == -1 )
1380  considx = nconss;
1381 
1382  if( nquadterms[considx] + 1 > termssize[considx] )
1383  {
1384  int newsize;
1385 
1386  newsize = SCIPcalcMemGrowSize(scip, nquadterms[considx] + 1);
1387  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadvars1[considx], termssize[considx], newsize) ); /*lint !e866*/
1388  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadvars2[considx], termssize[considx], newsize) ); /*lint !e866*/
1389  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadcoefs[considx], termssize[considx], newsize) ); /*lint !e866*/
1390  termssize[considx] = newsize;
1391  }
1392 
1393  quadvars1[considx][nquadterms[considx]] = vars[varidx1];
1394  quadvars2[considx][nquadterms[considx]] = vars[varidx2];
1395  quadcoefs[considx][nquadterms[considx]] = coef;
1396  ++nquadterms[considx];
1397  }
1398 
1399  if( count != nqterms )
1400  {
1401  SCIPerrorMessage("Got only %d quadratic terms under <quadraticCoefficients> node, but expected %d many.\n", count, nqterms);
1402  *doingfine = FALSE;
1403  }
1404 
1405  return SCIP_OKAY;
1406 }
1407 
1408 /** transforms OSnL expression tree into SCIP expression */
1409 static
1411  SCIP* scip, /**< SCIP data structure */
1412  SCIP_EXPR** expr, /**< buffer to store pointer to created expression */
1413  const XML_NODE* node, /**< root node of expression to be read */
1414  SCIP_VAR** vars, /**< variables in order of OSiL indices */
1415  int nvars, /**< total number of variables in problem */
1416  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1417  )
1418 {
1419  const char* exprname;
1420 
1421  assert(scip != NULL);
1422  assert(expr != NULL);
1423  assert(node != NULL);
1424  assert(vars != NULL);
1425  assert(doingfine != NULL);
1426 
1427  exprname = xmlGetName(node);
1428  assert(exprname != NULL);
1429 
1430  *expr = NULL;
1431 
1432  /* zero argument operands */
1433  if( strcmp(exprname, "variable") == 0 )
1434  {
1435  const char* attrval;
1436  SCIP_Real coef;
1437  int idx;
1438 
1439  /* read variable index */
1440  attrval = xmlGetAttrval(node, "idx");
1441  if( attrval == NULL )
1442  {
1443  SCIPerrorMessage("Attribute \"idx\" required for <variable> node in nonlinear expression\n");
1444  *doingfine = FALSE;
1445  return SCIP_OKAY;
1446  }
1447 
1448  idx = (int)strtol(attrval, (char**)&attrval, 10);
1449  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1450  {
1451  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "idx"));
1452  *doingfine = FALSE;
1453  return SCIP_OKAY;
1454  }
1455 
1456  /* read variable coefficient */
1457  attrval = xmlGetAttrval(node, "coef");
1458  if( attrval != NULL )
1459  {
1460  coef = strtod(attrval, (char**)&attrval);
1461  if( *attrval != '\0' || !SCIPisFinite(coef) )
1462  {
1463  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "coef"));
1464  *doingfine = FALSE;
1465  return SCIP_OKAY;
1466  }
1467  }
1468  else
1469  {
1470  coef = 1.0;
1471  }
1472 
1473  /* create variable expression */
1474  SCIP_CALL( SCIPcreateExprVar(scip, expr, vars[idx], NULL, NULL) );
1475 
1476  /* create a sum if the coefficient != 1 */
1477  if( coef != 1.0 )
1478  {
1479  SCIP_EXPR* sumexpr;
1480 
1481  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, expr, &coef, 0.0, NULL, NULL) );
1482 
1483  /* release the variable expression and store the sum */
1484  SCIP_CALL( SCIPreleaseExpr(scip, expr) );
1485  *expr = sumexpr;
1486  }
1487 
1488  return SCIP_OKAY;
1489  }
1490 
1491  if( strcmp(exprname, "number") == 0 )
1492  {
1493  const char* attrval;
1494  SCIP_Real val;
1495 
1496  attrval = xmlGetAttrval(node, "type");
1497  if( attrval != NULL && (strcmp(attrval, "real") != 0) )
1498  {
1499  SCIPerrorMessage("Type '%s' for <number> node in nonlinear expression not supported.\n", attrval);
1500  *doingfine = FALSE;
1501  return SCIP_OKAY;
1502  }
1503 
1504  attrval = xmlGetAttrval(node, "value");
1505  if( attrval != NULL )
1506  {
1507  val = strtod(attrval, (char**)&attrval);
1508  if( *attrval != '\0' || !SCIPisFinite(val) )
1509  {
1510  SCIPerrorMessage("Invalid value '%s' in \"value\" attribute of <number> node in nonlinear expression.\n", xmlGetAttrval(node, "value"));
1511  *doingfine = FALSE;
1512  return SCIP_OKAY;
1513  }
1514  }
1515  else
1516  {
1517  /* according to OSnL.xsd, the value attribute is optional
1518  * I guess the default is the empty string, which should correspond to 0.0
1519  */
1520  val = 0.0;
1521  }
1522 
1523  /* create constant expression */
1524  SCIP_CALL( SCIPcreateExprValue(scip, expr, val, NULL, NULL) );
1525 
1526  return SCIP_OKAY;
1527  }
1528 
1529  if( strcmp(exprname, "PI") == 0 )
1530  {
1531  /* create constant expression with PI value */
1532  SCIP_CALL( SCIPcreateExprValue(scip, expr, M_PI, NULL, NULL) );
1533 
1534  return SCIP_OKAY;
1535  }
1536 
1537  if( strcmp(exprname, "E") == 0 )
1538  {
1539  /* create constant expression with PI value */
1540  SCIP_CALL( SCIPcreateExprValue(scip, expr, M_E, NULL, NULL) );
1541 
1542  return SCIP_OKAY;
1543  }
1544 
1545  /* single argument operands */
1546  if( strcmp(exprname, "negate") == 0 ||
1547  strcmp(exprname, "abs") == 0 ||
1548  strcmp(exprname, "squareRoot") == 0 ||
1549  strcmp(exprname, "sqrt") == 0 ||
1550  strcmp(exprname, "square") == 0 ||
1551  strcmp(exprname, "exp") == 0 ||
1552  strcmp(exprname, "ln") == 0 ||
1553  strcmp(exprname, "log10") == 0 ||
1554  strcmp(exprname, "sin") == 0 ||
1555  strcmp(exprname, "cos") == 0 ||
1556  strcmp(exprname, "erf") == 0
1557  )
1558  {
1559  SCIP_EXPR* arg;
1560 
1561  /* check number of children */
1562  if( xmlFirstChild(node) == NULL || xmlNextSibl(xmlFirstChild(node)) != NULL )
1563  {
1564  SCIPerrorMessage("Expected exactly one child in <%s> node in nonlinear expression\n", exprname);
1565  *doingfine = FALSE;
1566  return SCIP_OKAY;
1567  }
1568 
1569  /* read child expression */
1570  SCIP_CALL( readExpression(scip, &arg, xmlFirstChild(node), vars, nvars, doingfine) );
1571 
1572  if( !*doingfine )
1573  return SCIP_OKAY;
1574  assert(arg != NULL);
1575 
1576  /* create SCIP expression according to expression name */
1577  if( strcmp(exprname, "negate") == 0 )
1578  {
1579  SCIP_Real minusone;
1580 
1581  minusone = -1.0;
1582 
1583  SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &arg, &minusone, 0.0, NULL, NULL) );
1584  }
1585  else if( strcmp(exprname, "abs") == 0 )
1586  {
1587  SCIP_CALL( SCIPcreateExprAbs(scip, expr, arg, NULL, NULL) );
1588  }
1589  else if( strcmp(exprname, "squareRoot") == 0 || strcmp(exprname, "sqrt") == 0 )
1590  {
1591  SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 0.5, NULL, NULL) );
1592  }
1593  else if( strcmp(exprname, "square") == 0 )
1594  {
1595  SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 2.0, NULL, NULL) );
1596  }
1597  else if( strcmp(exprname, "exp") == 0 )
1598  {
1599  SCIP_CALL( SCIPcreateExprExp(scip, expr, arg, NULL, NULL) );
1600  }
1601  else if( strcmp(exprname, "ln") == 0 )
1602  {
1603  SCIP_CALL( SCIPcreateExprLog(scip, expr, arg, NULL, NULL) );
1604  }
1605  else if( strcmp(exprname, "log10") == 0 )
1606  {
1607  SCIP_EXPR* logexpr;
1608  SCIP_Real coef = 1.0/log(10.0);
1609 
1610  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, arg, NULL, NULL) );
1611  SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &logexpr, &coef, 0.0, NULL, NULL) );
1612  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1613  }
1614  else if( strcmp(exprname, "sin") == 0 )
1615  {
1616  SCIP_CALL( SCIPcreateExprSin(scip, expr, arg, NULL, NULL) );
1617  }
1618  else if( strcmp(exprname, "cos") == 0 )
1619  {
1620  SCIP_CALL( SCIPcreateExprCos(scip, expr, arg, NULL, NULL) );
1621  }
1622  else if( strcmp(exprname, "erf") == 0 )
1623  {
1624  SCIPwarningMessage(scip, "Danger! You're entering a construction area. Implementation of support for 'erf' is incomplete.\n");
1625  SCIP_CALL( SCIPcreateExprErf(scip, expr, arg, NULL, NULL) );
1626  }
1627 
1628  /* release argument expression */
1629  SCIP_CALL( SCIPreleaseExpr(scip, &arg) );
1630 
1631  return SCIP_OKAY;
1632  }
1633 
1634  /* two argument operands */
1635  if( strcmp(exprname, "plus") == 0 ||
1636  strcmp(exprname, "minus") == 0 ||
1637  strcmp(exprname, "times") == 0 ||
1638  strcmp(exprname, "divide") == 0 ||
1639  strcmp(exprname, "power") == 0 ||
1640  strcmp(exprname, "signpower") == 0 ||
1641  strcmp(exprname, "log") == 0
1642  )
1643  {
1644  SCIP_EXPR* args[2] = {NULL, NULL};
1645 
1646  /* check number of children */
1647  if( xmlFirstChild(node) == NULL ||
1648  xmlNextSibl(xmlFirstChild(node)) == NULL ||
1649  xmlNextSibl(xmlNextSibl(xmlFirstChild(node))) != NULL )
1650  {
1651  SCIPerrorMessage("Expected exactly two children in <%s> node in nonlinear expression.\n", exprname);
1652  *doingfine = FALSE;
1653  return SCIP_OKAY;
1654  }
1655 
1656  /* read first child expression */
1657  SCIP_CALL( readExpression(scip, &args[0], xmlFirstChild(node), vars, nvars, doingfine) );
1658  if( !*doingfine )
1659  goto TERMINATE_TWO_ARGS;
1660  assert(args[0] != NULL);
1661 
1662  /* read second child expression */
1663  SCIP_CALL( readExpression(scip, &args[1], xmlNextSibl(xmlFirstChild(node)), vars, nvars, doingfine) );
1664  if( !*doingfine )
1665  goto TERMINATE_TWO_ARGS;
1666  assert(args[1] != NULL);
1667 
1668  if( strcmp(exprname, "plus") == 0 )
1669  {
1670  SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, NULL, 0.0, NULL, NULL) );
1671  }
1672  else if( strcmp(exprname, "minus") == 0 )
1673  {
1674  SCIP_Real coefs[2] = {1.0, -1.0};
1675  SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, coefs, 0.0, NULL, NULL) );
1676  }
1677  else if( strcmp(exprname, "times") == 0 )
1678  {
1679  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, args, 1.0, NULL, NULL) );
1680  }
1681  else if( strcmp(exprname, "divide") == 0 )
1682  {
1683  SCIP_EXPR* tmp[2];
1684  SCIP_EXPR* powexpr;
1685 
1686  SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, args[1], -1.0, NULL, NULL) );
1687  tmp[0] = args[0];
1688  tmp[1] = powexpr;
1689  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1690  SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1691  }
1692  else if( strcmp(exprname, "power") == 0 )
1693  {
1694  /* case 1: expr^number */
1695  if( SCIPisExprValue(scip, args[1]) )
1696  {
1697  SCIP_CALL( SCIPcreateExprPow(scip, expr, args[0], SCIPgetValueExprValue(args[1]), NULL, NULL) );
1698  }
1699  /* case 2: number^expr = exp(arg2 * ln(number)) */
1700  else if( SCIPisExprValue(scip, args[0]) )
1701  {
1702  SCIP_Real value = SCIPgetValueExprValue(args[0]);
1703 
1704  if( value <= 0.0 )
1705  {
1706  SCIPerrorMessage("Negative base in <power> node with nonconstant exponent not allowed in nonlinear expression.\n");
1707  *doingfine = FALSE;
1708  goto TERMINATE_TWO_ARGS;
1709  }
1710  else
1711  {
1712  SCIP_EXPR* sumexpr;
1713  SCIP_Real coef = log(value);
1714 
1715  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, &args[1], &coef, 0.0, NULL, NULL) );
1716  SCIP_CALL( SCIPcreateExprExp(scip, expr, sumexpr, NULL, NULL) );
1717  SCIP_CALL( SCIPreleaseExpr(scip, &sumexpr) );
1718  }
1719  }
1720  /* case 3: arg1^arg2 is exp(arg2 * ln(arg1)) */
1721  else
1722  {
1723  SCIP_EXPR* logexpr;
1724  SCIP_EXPR* prodexpr;
1725  SCIP_EXPR* tmp[2];
1726 
1727  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, args[0], NULL, NULL) );
1728  tmp[0] = args[1];
1729  tmp[1] = logexpr;
1730  SCIP_CALL( SCIPcreateExprProduct(scip, &prodexpr, 2, tmp, 1.0, NULL, NULL) );
1731  SCIP_CALL( SCIPcreateExprExp(scip, expr, prodexpr, NULL, NULL) );
1732  SCIP_CALL( SCIPreleaseExpr(scip, &prodexpr) );
1733  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1734  }
1735  }
1736  else if( strcmp(exprname, "signpower") == 0 )
1737  {
1738  /* signpower(expr,number) with number > 1 is the only one we can handle */
1739  if( !SCIPisExprValue(scip, args[1]) )
1740  {
1741  SCIPerrorMessage("Signpower only supported for constant exponents.\n");
1742  *doingfine = FALSE;
1743  goto TERMINATE_TWO_ARGS;
1744  }
1745  if( SCIPgetValueExprValue(args[1]) <= 1.0 )
1746  {
1747  SCIPerrorMessage("Signpower only supported for exponents > 1, but got %g.\n",
1748  SCIPgetValueExprValue(args[1]));
1749  *doingfine = FALSE;
1750  goto TERMINATE_TWO_ARGS;
1751  }
1752 
1753  SCIP_CALL( SCIPcreateExprSignpower(scip, expr, args[0], SCIPgetValueExprValue(args[1]), NULL, NULL) );
1754  }
1755  /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) */
1756  else if( strcmp(exprname, "log") == 0 )
1757  {
1758  SCIP_EXPR* logexpr0;
1759  SCIP_EXPR* logexpr1;
1760  SCIP_EXPR* powexpr;
1761  SCIP_EXPR* tmp[2];
1762 
1763  /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) = ln(arg2) * pow(ln(arg1),-1) */
1764  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr0, args[0], NULL, NULL) );
1765  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr1, args[1], NULL, NULL) );
1766  SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, logexpr0, -1.0, NULL, NULL) );
1767  tmp[0] = logexpr1;
1768  tmp[1] = powexpr;
1769  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1770 
1771  SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1772  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr1) );
1773  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr0) );
1774  }
1775  else if( strcmp(exprname, "min") == 0 )
1776  {
1777  SCIPerrorMessage("min expressions are not supported\n");
1778  *doingfine = FALSE;
1779  goto TERMINATE_TWO_ARGS;
1780  }
1781  else /* if( strcmp(exprname, "max") == 0 ) */
1782  {
1783  assert(strcmp(exprname, "max") == 0);
1784 
1785  SCIPerrorMessage("max expressions are not supported\n");
1786  *doingfine = FALSE;
1787  goto TERMINATE_TWO_ARGS;
1788  }
1789 
1790 TERMINATE_TWO_ARGS:
1791 
1792  /* release first and second argument expression */
1793  if( args[0] != NULL )
1794  {
1795  SCIP_CALL( SCIPreleaseExpr(scip, &args[0]) );
1796  }
1797  if( args[1] != NULL )
1798  {
1799  SCIP_CALL( SCIPreleaseExpr(scip, &args[1]) );
1800  }
1801 
1802  return SCIP_OKAY;
1803  }
1804 
1805  /* arbitrary argument operands */
1806  if( strcmp(exprname, "sum") == 0 || strcmp(exprname, "product") == 0 )
1807  {
1808  const XML_NODE* argnode;
1809  SCIP_EXPR** args;
1810  int nargs;
1811  int argssize;
1812  int i;
1813 
1814  /* a sum or product w.r.t. 0 arguments is constant */
1815  if( xmlFirstChild(node) == NULL )
1816  {
1817  SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1818 
1819  return SCIP_OKAY;
1820  }
1821 
1822  /* read all child expressions */
1823  argssize = 5;
1824  SCIP_CALL( SCIPallocBufferArray(scip, &args, argssize) );
1825 
1826  nargs = 0;
1827  for( argnode = xmlFirstChild(node); argnode != NULL; argnode = xmlNextSibl(argnode), ++nargs )
1828  {
1829  if( nargs >= argssize )
1830  {
1831  argssize = SCIPcalcMemGrowSize(scip, nargs + 1);
1832  SCIP_CALL( SCIPreallocBufferArray(scip, &args, argssize) );
1833  }
1834  assert(nargs < argssize);
1835 
1836  SCIP_CALL( readExpression(scip, &args[nargs], argnode, vars, nvars, doingfine) );
1837  if( !*doingfine )
1838  {
1839  assert(args[nargs] == NULL);
1840  break;
1841  }
1842  }
1843 
1844  if( *doingfine )
1845  {
1846  switch( nargs )
1847  {
1848  case 0:
1849  {
1850  SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1851  break;
1852  }
1853  case 1:
1854  {
1855  *expr = args[0];
1856  /* capture expression here because args[0] will be released at the end */
1857  SCIPcaptureExpr(*expr);
1858  break;
1859  }
1860 
1861  default:
1862  {
1863  /* create sum or product expression */
1864  if( strcmp(exprname, "sum") == 0 )
1865  {
1866  SCIP_CALL( SCIPcreateExprSum(scip, expr, nargs, args, NULL, 0.0, NULL, NULL) );
1867  }
1868  else
1869  {
1870  SCIP_CALL( SCIPcreateExprProduct(scip, expr, nargs, args, 1.0, NULL, NULL) );
1871  }
1872 
1873  break;
1874  }
1875  }
1876  }
1877 
1878  /* release argument expressions */
1879  for( i = 0; i < nargs; ++i )
1880  {
1881  assert(args[i] != NULL);
1882  SCIP_CALL( SCIPreleaseExpr(scip, &args[i]) );
1883  }
1884 
1885  SCIPfreeBufferArray(scip, &args);
1886 
1887  return SCIP_OKAY;
1888  }
1889 
1890  if( strcmp(exprname, "min") == 0 || strcmp(exprname, "max") == 0 )
1891  {
1892  SCIPerrorMessage("min or max expressions are not supported\n");
1893  *doingfine = FALSE;
1894  return SCIP_OKAY;
1895  }
1896 
1897  if( strcmp(exprname, "quadratic") == 0 )
1898  {
1899  const char* attrval;
1900  const XML_NODE* qterm;
1901  SCIP_VAR** quadvars1;
1902  SCIP_VAR** quadvars2;
1903  SCIP_Real* quadcoefs;
1904  int nquadelems;
1905  int quadelemssize;
1906  int idx;
1907 
1908  quadelemssize = 5;
1909  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, quadelemssize) );
1910  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, quadelemssize) );
1911  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, quadelemssize) );
1912  nquadelems = 0;
1913 
1914  /* read quadratic terms */
1915  for( qterm = xmlFirstChild(node); qterm != NULL; qterm = xmlNextSibl(qterm), ++nquadelems )
1916  {
1917  /* check for qpTerm node */
1918  if( strcmp(xmlGetName(qterm), "qpTerm") != 0 )
1919  {
1920  SCIPerrorMessage("Unexpected <%s> node under <quadratic> node in nonlinear expression, expected <qpTerm>.\n", xmlGetName(qterm));
1921  *doingfine = FALSE;
1922  return SCIP_OKAY;
1923  }
1924 
1925  if( nquadelems >= quadelemssize )
1926  {
1927  quadelemssize = SCIPcalcMemGrowSize(scip, nquadelems + 1);
1928  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, quadelemssize) );
1929  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, quadelemssize) );
1930  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, quadelemssize) );
1931  }
1932  assert(quadelemssize > nquadelems);
1933 
1934  /* get index of first variable */
1935  attrval = xmlGetAttrval(qterm, "idxOne");
1936  if( attrval == NULL )
1937  {
1938  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1939  *doingfine = FALSE;
1940  return SCIP_OKAY;
1941  }
1942 
1943  idx = (int)strtol(attrval, (char**)&attrval, 10);
1944  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1945  {
1946  SCIPerrorMessage("Invalid value '%s' for \"idxOne\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxOne"), nquadelems);
1947  *doingfine = FALSE;
1948  return SCIP_OKAY;
1949  }
1950  quadvars1[nquadelems] = vars[idx];
1951 
1952  /* get index of second variable */
1953  attrval = xmlGetAttrval(qterm, "idxTwo");
1954  if( attrval == NULL )
1955  {
1956  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1957  *doingfine = FALSE;
1958  return SCIP_OKAY;
1959  }
1960 
1961  idx = (int)strtol(attrval, (char**)&attrval, 10);
1962  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1963  {
1964  SCIPerrorMessage("Invalid value '%s' for \"idxTwo\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxTwo"), nquadelems);
1965  *doingfine = FALSE;
1966  return SCIP_OKAY;
1967  }
1968  quadvars2[nquadelems] = vars[idx];
1969 
1970  /* get coefficient */
1971  attrval = xmlGetAttrval(qterm, "coef");
1972  if( attrval != NULL )
1973  {
1974  quadcoefs[nquadelems] = strtod(attrval, (char**)&attrval);
1975  if( *attrval != '\0' || !SCIPisFinite(quadcoefs[nquadelems]) ) /*lint !e777*/
1976  {
1977  SCIPerrorMessage("Invalid value '%s' for \"coef\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "coef"), nquadelems);
1978  *doingfine = FALSE;
1979  return SCIP_OKAY;
1980  }
1981  }
1982  else
1983  {
1984  quadcoefs[nquadelems] = 1.0;
1985  }
1986  }
1987 
1988  /* create quadratic expression */
1989  SCIP_CALL( SCIPcreateExprQuadratic(scip, expr, 0, NULL, NULL, nquadelems, quadvars1, quadvars2, quadcoefs, NULL, NULL) );
1990  }
1991 
1992  SCIPerrorMessage("Expression operand <%s> in nonlinear expression not supported by SCIP so far.\n", exprname);
1993  *doingfine = FALSE;
1994 
1995  return SCIP_OKAY;
1996 }
1997 
1998 
1999 /** read nonlinear expressions of constraints and objective */
2000 static
2002  SCIP* scip, /**< SCIP data structure */
2003  const XML_NODE* datanode, /**< XML root node for instance data */
2004  SCIP_VAR** vars, /**< variables in order of OSiL indices */
2005  int nvars, /**< number of variables */
2006  int nconss, /**< number of constraints */
2007  SCIP_EXPR** exprs, /**< array to store for each constraint a nonlinear expression */
2008  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2009  )
2010 {
2011  const XML_NODE* nlexprs;
2012  const XML_NODE* nlexpr;
2013  const char* attrval;
2014  int nnlexprs;
2015  int count;
2016  int considx;
2017 
2018  assert(scip != NULL);
2019  assert(datanode != NULL);
2020  assert(vars != NULL || nvars == 0);
2021  assert(exprs != NULL);
2022  assert(doingfine != NULL);
2023 
2024  nlexprs = xmlFindNodeMaxdepth(datanode, "nonlinearExpressions", 0, 1);
2025 
2026  if( nlexprs == NULL )
2027  return SCIP_OKAY;
2028 
2029  /* get number of nonlinear expressions */
2030  attrval = xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions");
2031  if( attrval == NULL )
2032  {
2033  SCIPerrorMessage("Attribute \"numberOfNonlinearExpressions\" in <nonlinearExpressions> node not found.\n");
2034  *doingfine = FALSE;
2035  return SCIP_OKAY;
2036  }
2037 
2038  nnlexprs = (int)strtol(attrval, (char**)&attrval, 10);
2039  if( *attrval != '\0' || nnlexprs < 0 )
2040  {
2041  SCIPerrorMessage("Invalid value '%s' for \"numberOfNonlinearExpressions\" attribute in <nonlinearExpressions>.\n", xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions"));
2042  *doingfine = FALSE;
2043  return SCIP_OKAY;
2044  }
2045  assert(nnlexprs >= 0);
2046 
2047  /* read nonlinear expressions and store in constraints */
2048  count = 0;
2049  for( nlexpr = xmlFirstChild(nlexprs); nlexpr != NULL; nlexpr = xmlNextSibl(nlexpr), ++count )
2050  {
2051  if( strcmp(xmlGetName(nlexpr), "nl") != 0 )
2052  {
2053  SCIPerrorMessage("Expected <nl> node under <nonlinearExpressions> node, but got '%s'.\n", xmlGetName(nlexpr));
2054  *doingfine = FALSE;
2055  break;
2056  }
2057  if( count >= nnlexprs )
2058  {
2059  SCIPerrorMessage("Too many nonlinear expressions under <nonlinearExpressions> node, expected %d many, but got at least %d.\n", nnlexprs, count + 1);
2060  *doingfine = FALSE;
2061  break;
2062  }
2063 
2064  /* treat empty expression as 0.0 and continue */
2065  if( xmlFirstChild(nlexprs) == NULL )
2066  continue;
2067 
2068  /* get constraint index, or -1 for objective */
2069  attrval = xmlGetAttrval(nlexpr, "idx");
2070  if( attrval == NULL )
2071  {
2072  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <nl> node under <nonlinearExpressions> node.\n", count);
2073  *doingfine = FALSE;
2074  break;
2075  }
2076 
2077  considx = (int)strtol(attrval, (char**)&attrval, 10);
2078  if( *attrval != '\0' || considx < -1 || considx >= nconss )
2079  {
2080  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <nl> node under <nonlinearExpressions> node.\n", xmlGetAttrval(nlexpr, "idx"), count);
2081  *doingfine = FALSE;
2082  break;
2083  }
2084 
2085  /* turn OSiL expression into SCIP expression and assign indices to variables; store a nonlinear objective at position nconss */
2086  SCIP_CALL( readExpression(scip, considx == -1 ? &exprs[nconss] : &exprs[considx],
2087  xmlFirstChild(nlexpr), vars, nvars, doingfine) );
2088  if( !*doingfine )
2089  return SCIP_OKAY;
2090  }
2091 
2092  return SCIP_OKAY;
2093 }
2094 
2095 
2096 /** read sos1 and sos2 constraints
2097  *
2098  * sos constraints are expected to be given as a node of <instanceData> in the following way:
2099  * @code
2100  * <specialOrderedSets numberOfSpecialOrderedSets="1">
2101  * <sos numberOfVar="2" order="2">
2102  * <var idx="1"></var>
2103  * <var idx="2"></var>
2104  * </sos>
2105  * </specialOrderedSets>
2106  * @endcode
2107  * Weights are determined by the order in which the variables are given
2108  *
2109  */
2110 static
2112  SCIP* scip, /**< SCIP data structure */
2113  const XML_NODE* datanode, /**< XML root node for instance data */
2114  SCIP_VAR** vars, /**< variables in order of OSiL indices */
2115  int nvars, /**< number of variables */
2116  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
2117  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
2118  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
2119  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2120  )
2121 {
2122  const XML_NODE* soscons;
2123  const XML_NODE* sosvar;
2124  const char* attrval;
2125  int nsoscons;
2126  int nsosvars;
2127  int sosorder;
2128  int type;
2129  int count;
2130  int varcount;
2131  int idx;
2132  SCIP_Bool initial;
2133  SCIP_Bool separate;
2134  SCIP_Bool enforce;
2135  SCIP_Bool check;
2136  SCIP_Bool propagate;
2137  SCIP_Bool local;
2138  SCIP_Bool dynamic;
2139  SCIP_Bool removable;
2140  char name[SCIP_MAXSTRLEN];
2141 
2142  /* standard settings for SOS constraints: */
2143  initial = initialconss;
2144  separate = TRUE;
2145  enforce = TRUE;
2146  check = TRUE;
2147  propagate = TRUE;
2148  local = FALSE;
2149  dynamic = dynamicconss;
2150  removable = dynamicrows;
2151 
2152  soscons= xmlFindNodeMaxdepth(datanode, "specialOrderedSets", 0, 1);
2153 
2154  if( soscons== NULL )
2155  return SCIP_OKAY;
2156 
2157  /* get number of sos constraints */
2158  attrval = xmlGetAttrval(soscons, "numberOfSOS");
2159  if( attrval == NULL )
2160  {
2161  SCIPerrorMessage("Attribute \"numberOfSOS in <specialOrderedSets> node not found.\n");
2162  *doingfine = FALSE;
2163  return SCIP_OKAY;
2164  }
2165 
2166  nsoscons = (int)strtol(attrval, (char**)&attrval, 10);
2167  if( *attrval != '\0' || nsoscons < 0 )
2168  {
2169  SCIPerrorMessage("Invalid value '%s' for \"numberOfSOS\" attribute in <specialOrderedSets>.\n", xmlGetAttrval(soscons, "numberOfSOS"));
2170  *doingfine = FALSE;
2171  return SCIP_OKAY;
2172  }
2173  assert(nsoscons >= 0);
2174 
2175  /* read sos constraints and create corresponding constraint */
2176  count = 0;
2177  for( soscons = xmlFirstChild(soscons); soscons != NULL; soscons = xmlNextSibl(soscons), ++count )
2178  {
2179  SCIP_CONS* cons;
2180 
2181  /* Make sure we get a sos node and not more then announced*/
2182  if( strcmp(xmlGetName(soscons), "sos") != 0 )
2183  {
2184  SCIPerrorMessage("Expected <sos> node under <specialOrderedSet> node, but got '%s'.\n", xmlGetName(soscons));
2185  *doingfine = FALSE;
2186  break;
2187  }
2188 
2189  if( count >= nsoscons)
2190  {
2191  SCIPerrorMessage("Too many sos under <specialOrderedSets> node, expected %d many, but got at least %d.\n", nsoscons, count + 1);
2192  *doingfine = FALSE;
2193  break;
2194  }
2195 
2196  /* get number of variables in this sos constraint */
2197  attrval = xmlGetAttrval(soscons, "numberOfVar");
2198  if( attrval == NULL )
2199  {
2200  SCIPerrorMessage("Attribute \"numberOfVar in <sos> node not found.\n");
2201  *doingfine = FALSE;
2202  return SCIP_OKAY;
2203  }
2204 
2205  nsosvars = (int)strtol(attrval, (char**)&attrval, 10);
2206  if( *attrval != '\0' || nsosvars < 0 )
2207  {
2208  SCIPerrorMessage("Invalid value '%s' for \"numberOfVar\" attribute in <sos>.\n", xmlGetAttrval(soscons, "numberOfVar"));
2209  *doingfine = FALSE;
2210  return SCIP_OKAY;
2211  }
2212  assert(nsosvars >= 0);
2213 
2214  /* get order of this sos constraint */
2215  attrval = xmlGetAttrval(soscons, "type");
2216  if( attrval == NULL )
2217  {
2218  SCIPerrorMessage("Attribute \"order\" in <sos> node not found.\n");
2219  *doingfine = FALSE;
2220  return SCIP_OKAY;
2221  }
2222 
2223  sosorder = (int)strtol(attrval, (char**)&attrval, 10);
2224  if( *attrval != '\0' || sosorder < 0 || sosorder > 2 )
2225  {
2226  SCIPerrorMessage("Invalid/unsupported value '%s' for \"order\" attribute in <sos>.\n", xmlGetAttrval(soscons, "order"));
2227  *doingfine = FALSE;
2228  return SCIP_OKAY;
2229  }
2230  assert(sosorder == 1 || sosorder == 2);
2231  type = sosorder;
2232 
2233  /* set artificial name for sos constraint*/
2234  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d_%d", type, count);
2235 
2236  /* Create sos constraint */
2237  switch( type )
2238  {
2239  case 1:
2240  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2241  local, dynamic, removable, FALSE) );
2242  break;
2243  case 2:
2244  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2245  local, dynamic, removable, FALSE) );
2246  break;
2247  default:
2248  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2249  SCIPABORT();
2250  return SCIP_INVALIDDATA; /*lint !e527*/
2251  }
2252 
2253  varcount = 0;
2254  for( sosvar = xmlFirstChild(soscons); sosvar!= NULL; sosvar = xmlNextSibl(sosvar), ++varcount )
2255  {
2256  /* get variable id*/
2257  attrval = xmlGetAttrval(sosvar, "idx");
2258  if( attrval == NULL )
2259  {
2260  SCIPerrorMessage("Attribute \"idx\" in <var> node below <specialOrderedSets> node not found.\n");
2261  *doingfine = FALSE;
2262  return SCIP_OKAY;
2263  }
2264 
2265  idx = (int)strtol(attrval, (char**)&attrval, 10);
2266  if( *attrval != '\0' || idx < 0 || idx > nvars - 1 )
2267  {
2268  SCIPerrorMessage("Invalid value '%s' for \"idx\" attribute in <var>.\n", xmlGetAttrval(sosvar, "idx"));
2269  *doingfine = FALSE;
2270  return SCIP_OKAY;
2271  }
2272  assert(idx >= 0);
2273 
2274  /* we now know that we have a variable/weight pair -> add variable*/
2275  switch( type )
2276  {
2277  case 1:
2278  SCIP_CALL( SCIPaddVarSOS1(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2279  break;
2280  case 2:
2281  SCIP_CALL( SCIPaddVarSOS2(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2282  break;
2283  /* coverity[dead_error_begin] */
2284  default:
2285  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2286  SCIPABORT();
2287  return SCIP_INVALIDDATA; /*lint !e527*/
2288  }
2289  } /* Close loop over variables in sos constraint */
2290 
2291  /* add the SOS constraint */
2292  SCIP_CALL( SCIPaddCons(scip, cons) );
2293  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2294  }
2295 
2296  return SCIP_OKAY;
2297 }
2298 
2299  /*
2300  * Callback methods of reader
2301  */
2302 
2303 
2304 /** copy method for reader plugins (called when SCIP copies plugins) */
2305 static
2306 SCIP_DECL_READERCOPY(readerCopyOsil)
2307 { /*lint --e{715}*/
2308  assert(scip != NULL);
2309 
2311 
2312  return SCIP_OKAY;
2313 }
2314 
2315 /** problem reading method of reader */
2316 static
2317 SCIP_DECL_READERREAD(readerReadOsil)
2318 { /*lint --e{715}*/
2319  const XML_NODE* header;
2320  const XML_NODE* data;
2321  XML_NODE* start;
2322  SCIP_VAR** vars;
2323  const char* name;
2324  SCIP_RETCODE retcode;
2325  SCIP_Bool doingfine;
2326  SCIP_Bool initialconss;
2327  SCIP_Bool dynamicconss;
2328  SCIP_Bool dynamiccols;
2329  SCIP_Bool dynamicrows;
2330  int nconss;
2331  int nvars;
2332  int c;
2333  int i;
2334 
2335  /* linear parts */
2336  SCIP_VAR*** linvars = NULL;
2337  SCIP_Real** lincoefs = NULL;
2338  int* nlinvars = NULL;
2339 
2340  /* quadratic parts */
2341  SCIP_VAR*** quadvars1 = NULL;
2342  SCIP_VAR*** quadvars2 = NULL;
2343  SCIP_Real** quadcoefs = NULL;
2344  int* nquadterms = NULL;
2345  int* termssize = NULL;
2346 
2347  /* nonlinear parts */
2348  SCIP_EXPR** nlexprs = NULL;
2349 
2350  assert(scip != NULL);
2351  assert(reader != NULL);
2352  assert(result != NULL);
2353  assert(filename != NULL);
2354 
2355  *result = SCIP_DIDNOTRUN;
2356  retcode = SCIP_READERROR;
2357  doingfine = TRUE;
2358  vars = NULL;
2359  nvars = 0;
2360  nconss = -1;
2361 
2362  /* read OSiL xml file */
2363  start = xmlProcess(filename);
2364 
2365  if( start == NULL )
2366  {
2367  SCIPerrorMessage("Some error occurred when parsing the OSiL XML file '%s'.\n", filename);
2368  goto CLEANUP;
2369  }
2370 
2371  SCIPdebug( xmlShowNode(start) );
2372 
2373  /* parse header to get problem name */
2374  name = filename;
2375  header = xmlFindNodeMaxdepth(start, "instanceHeader", 0, 2);
2376  if( header != NULL )
2377  {
2378  const XML_NODE* namenode;
2379 
2380  namenode = xmlFindNodeMaxdepth(header, "name", 0, 2);
2381 
2382  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2383  name = xmlGetData(xmlFirstChild(namenode));
2384  else
2385  {
2386  namenode = xmlFindNodeMaxdepth(header, "description", 0, 2);
2387 
2388  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2389  name = xmlGetData(xmlFirstChild(namenode));
2390  }
2391  }
2392 
2393  /* create SCIP problem */
2395 
2396  /* process instance data */
2397  data = xmlFindNodeMaxdepth(start, "instanceData", 0, 2);
2398  if( data == NULL )
2399  {
2400  SCIPerrorMessage("Node <instanceData> not found.\n");
2401  goto CLEANUP;
2402  }
2403 
2404  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
2405  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
2406  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
2407  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
2408 
2409  /* read variables */
2410  SCIP_CALL_TERMINATE( retcode, readVariables(scip, data, &vars, &nvars, initialconss, dynamicconss, dynamiccols, dynamicrows, &doingfine), CLEANUP );
2411  if( !doingfine )
2412  goto CLEANUP;
2413  assert(vars != NULL || nvars == 0);
2414 
2415  /* read objective sense, coefficient, and constant */
2416  SCIP_CALL_TERMINATE( retcode, readObjective(scip, data, vars, nvars, dynamiccols, &doingfine), CLEANUP );
2417  if( !doingfine )
2418  goto CLEANUP;
2419 
2420  /* read total number of constraints */
2421  SCIP_CALL_TERMINATE( retcode, readNConstraints(scip, data, &nconss, &doingfine), CLEANUP );
2422  if( !doingfine )
2423  goto CLEANUP;
2424 
2425  /* allocate memory to store constraint information (use block memory, since the size have to be reallocaed) */
2426  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &linvars, nconss + 1) );
2427  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &lincoefs, nconss + 1) );
2428  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nlinvars, nconss + 1) );
2429  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadvars1, nconss + 1) );
2430  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadvars2, nconss + 1) );
2431  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadcoefs, nconss + 1) );
2432  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nquadterms, nconss + 1) );
2433  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nlexprs, nconss + 1) );
2434  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &termssize, nconss + 1) );
2435 
2436  /* read linear coefficients matrix */
2437  SCIP_CALL_TERMINATE( retcode, readLinearCoefs(scip, data, vars, nvars, nconss, linvars, lincoefs, nlinvars, &doingfine), CLEANUP );
2438  if( !doingfine )
2439  goto CLEANUP;
2440 
2441  /* read quadratic coefficients */
2442  SCIP_CALL_TERMINATE( retcode, readQuadraticCoefs(scip, data, vars, nvars, nconss, quadvars1, quadvars2, quadcoefs,
2443  nquadterms, termssize, &doingfine), CLEANUP );
2444  if( !doingfine )
2445  goto CLEANUP;
2446 
2447  /* read nonlinear expressions */
2448  SCIP_CALL_TERMINATE( retcode, readNonlinearExprs(scip, data, vars, nvars, nconss, nlexprs, &doingfine), CLEANUP );
2449  if( !doingfine )
2450  goto CLEANUP;
2451 
2452  /* read constraint data; generate constraints */
2453  SCIP_CALL_TERMINATE( retcode, readConstraints(scip, data, nconss, linvars, lincoefs, nlinvars,
2454  quadvars1, quadvars2, quadcoefs, nquadterms, nlexprs, initialconss, dynamicconss, dynamicrows, &doingfine),
2455  CLEANUP );
2456  if( !doingfine )
2457  goto CLEANUP;
2458 
2459  /* add nonlinear objective constraint */
2460  if( nlinvars[nconss] > 0 || nquadterms[nconss] > 0 || nlexprs[nconss] != NULL )
2461  {
2462  SCIP_CALL( createConstraint(scip, linvars[nconss], lincoefs[nconss], nlinvars[nconss],
2463  quadvars1[nconss], quadvars2[nconss], quadcoefs[nconss], nquadterms[nconss], nlexprs[nconss],
2466  "objcons", TRUE, TRUE, FALSE, FALSE) );
2467  }
2468 
2469  /* read sos2 constraints and add to problem */
2470  SCIP_CALL_TERMINATE( retcode, readSOScons(scip, data, vars, nvars, initialconss, dynamicconss, dynamicrows, &doingfine), CLEANUP );
2471  if( !doingfine )
2472  goto CLEANUP;
2473 
2474  *result = SCIP_SUCCESS;
2475  retcode = SCIP_OKAY;
2476 
2477  CLEANUP:
2478  /* free xml data */
2479  if( start != NULL )
2480  xmlFreeNode(start);
2481 
2482  /* free memory for constraint information (position nconss belongs to the nonlinear objective function) */
2483  for( c = nconss; c >= 0; --c )
2484  {
2485  /* free nonlinear parts */
2486  if( nlexprs != NULL && nlexprs[c] != NULL )
2487  {
2488  SCIP_CALL( SCIPreleaseExpr(scip, &nlexprs[c]) );
2489  }
2490 
2491  /* free quadratic parts */
2492  SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs[c], termssize[c]);
2493  SCIPfreeBlockMemoryArrayNull(scip, &quadvars2[c], termssize[c]);
2494  SCIPfreeBlockMemoryArrayNull(scip, &quadvars1[c], termssize[c]);
2495 
2496  /* free linear parts */
2497  SCIPfreeBlockMemoryArrayNull(scip, &lincoefs[c], nlinvars[c]);
2498  SCIPfreeBlockMemoryArrayNull(scip, &linvars[c], nlinvars[c]);
2499  }
2500  SCIPfreeBlockMemoryArrayNull(scip, &termssize, nconss + 1);
2501  SCIPfreeBlockMemoryArrayNull(scip, &nlexprs, nconss + 1);
2502  SCIPfreeBlockMemoryArrayNull(scip, &nquadterms, nconss + 1);
2503  SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, nconss + 1);
2504  SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, nconss + 1);
2505  SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, nconss + 1);
2506  SCIPfreeBlockMemoryArrayNull(scip, &nlinvars, nconss + 1);
2507  SCIPfreeBlockMemoryArrayNull(scip, &lincoefs, nconss + 1);
2508  SCIPfreeBlockMemoryArrayNull(scip, &linvars, nconss + 1);
2509 
2510  /* free variables */
2511  for( i = 0; i < nvars; ++i )
2512  {
2513  SCIP_CALL( SCIPreleaseVar(scip, &vars[i]) ); /*lint !e613*/
2514  }
2515  SCIPfreeBufferArrayNull(scip, &vars);
2516 
2517  /* return read error retcode if something went wrong */
2518  if( !doingfine )
2519  return SCIP_READERROR;
2520 
2521  if( retcode == SCIP_PLUGINNOTFOUND )
2522  retcode = SCIP_READERROR;
2523 
2524  SCIP_CALL( retcode );
2525 
2526  return SCIP_OKAY;
2527 }
2528 
2529 /*
2530  * reader specific interface methods
2531  */
2532 
2533 /** includes the osil file reader in SCIP */
2535  SCIP* scip /**< SCIP data structure */
2536  )
2537 {
2538  SCIP_READER* reader;
2539 
2540  /* include osil reader */
2542 
2543  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOsil) );
2544  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOsil) );
2545 
2546  return SCIP_OKAY;
2547 }
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
static volatile int nterms
Definition: interrupt.c:47
#define NULL
Definition: def.h:267
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
SCIP_RETCODE SCIPcreateExprPow(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_pow.c:3194
public methods for SCIP parameter handling
#define READER_EXTENSION
Definition: reader_osil.c:71
#define READER_NAME
Definition: reader_osil.c:69
static SCIP_DECL_READERCOPY(readerCopyOsil)
Definition: reader_osil.c:2306
public methods for memory management
#define SCIP_MAXSTRLEN
Definition: def.h:288
SCIP_RETCODE SCIPcreateExprSignpower(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_pow.c:3218
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
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
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2670
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1250
#define FALSE
Definition: def.h:94
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
#define TRUE
Definition: def.h:93
#define SCIPdebug(x)
Definition: pub_message.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
public methods for problem variables
XML_NODE * xmlProcess(const char *filename)
Definition: xmlparse.c:1085
OS instance language (OSiL) format file reader.
const XML_NODE * xmlFirstChild(const XML_NODE *node)
Definition: xmlparse.c:1469
SCIP_RETCODE SCIPcreateExprExp(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_exp.c:510
const char * xmlGetData(const XML_NODE *node)
Definition: xmlparse.c:1509
SCIP_RETCODE SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_var.c:390
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
void SCIPcaptureExpr(SCIP_EXPR *expr)
Definition: scip_expr.c:1409
variable expression handler
public methods for SCIP variables
SCIP_RETCODE SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
Definition: expr_sum.c:1151
static SCIP_RETCODE readSOScons(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:2111
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1114
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
public methods for numerical tolerances
void xmlShowNode(const XML_NODE *root)
Definition: xmlparse.c:1309
static SCIP_RETCODE readExpression(SCIP *scip, SCIP_EXPR **expr, const XML_NODE *node, SCIP_VAR **vars, int nvars, SCIP_Bool *doingfine)
Definition: reader_osil.c:1410
public methods for managing constraints
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1242
#define READER_DESC
Definition: reader_osil.c:70
static SCIP_DECL_READERREAD(readerReadOsil)
Definition: reader_osil.c:2317
#define SCIPerrorMessage
Definition: pub_message.h:64
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
struct XML_NODE_struct XML_NODE
Definition: xml.h:50
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10716
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
const XML_NODE * xmlFindNodeMaxdepth(const XML_NODE *node, const char *name, int depth, int maxdepth)
Definition: xmlparse.c:1419
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1442
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17420
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPcreateExprProduct(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real coefficient, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
power and signed power expression handlers
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1453
#define SCIP_CALL(x)
Definition: def.h:380
static SCIP_RETCODE readQuadraticCoefs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, int nconss, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadterms, int *termssize, SCIP_Bool *doingfine)
Definition: reader_osil.c:1228
SCIP_RETCODE SCIPcreateExprValue(SCIP *scip, SCIP_EXPR **expr, SCIP_Real value, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_value.c:270
public methods for constraint handler plugins and constraints
public methods for NLP management
SCIP_RETCODE SCIPincludeReaderOsil(SCIP *scip)
Definition: reader_osil.c:2534
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4515
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
public data structures and miscellaneous methods
SCIP_RETCODE SCIPcreateExprErf(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_erf.c:257
logarithm expression handler
#define SCIP_Bool
Definition: def.h:91
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
SCIP_RETCODE SCIPcreateExprAbs(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_abs.c:528
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1417
constraint handler for nonlinear constraints specified by algebraic expressions
handler for sin expressions
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_RETCODE createConstraint(SCIP *scip, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nlinvars, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, int nquadterms, SCIP_EXPR *nlexpr, SCIP_Real lhs, SCIP_Real rhs, const char *name, SCIP_Bool objcons, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows)
Definition: reader_osil.c:482
Constraint handler for linear constraints in their most general form, .
const char * xmlGetName(const XML_NODE *node)
Definition: xmlparse.c:1489
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
SCIP_RETCODE SCIPcreateExprLog(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_log.c:630
absolute expression handler
constant value expression handler
#define M_PI
Definition: pricer_rpa.c:97
static SCIP_RETCODE readNConstraints(SCIP *scip, const XML_NODE *datanode, int *nconss, SCIP_Bool *doingfine)
Definition: reader_osil.c:436
static SCIP_RETCODE readObjective(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_Bool dynamiccols, SCIP_Bool *doingfine)
Definition: reader_osil.c:293
product expression handler
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)
static void readMultIncr(const XML_NODE *node, int *mult, int *incrint, SCIP_Real *incrreal, SCIP_Bool *doingfine)
Definition: reader_osil.c:781
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
const char * xmlGetAttrval(const XML_NODE *node, const char *name)
Definition: xmlparse.c:1337
SCIP_RETCODE SCIPcreateExprSin(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_trig.c:1430
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_RETCODE SCIPcreateExprCos(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_trig.c:1450
public methods for message output
#define SCIP_Real
Definition: def.h:173
handler for Gaussian error function expressions
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:401
static SCIP_RETCODE readVariables(SCIP *scip, const XML_NODE *datanode, SCIP_VAR ***vars, int *nvars, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamiccols, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:79
constraint handler for SOS type 1 constraints
static SCIP_RETCODE readLinearCoefs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, int nconss, SCIP_VAR ***linvars, SCIP_Real **lincoefs, int *nlinvars, SCIP_Bool *doingfine)
Definition: reader_osil.c:847
#define SCIP_INVALID
Definition: def.h:193
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:294
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
#define SCIPisFinite(x)
Definition: pub_misc.h:1933
declarations for XML parsing
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1225
sum expression handler
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10579
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
constraint handler for SOS type 2 constraints
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos2.c:2571
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
void xmlFreeNode(XML_NODE *node)
Definition: xmlparse.c:1275
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
constraint handler for bound disjunction constraints
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:352
public methods for global and local (sub)problems
static SCIP_RETCODE readNonlinearExprs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, int nconss, SCIP_EXPR **exprs, SCIP_Bool *doingfine)
Definition: reader_osil.c:2001
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
exponential expression handler
static SCIP_RETCODE readConstraints(SCIP *scip, const XML_NODE *datanode, int nconss, SCIP_VAR ***linvars, SCIP_Real **lincoefs, int *nlinvars, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadterms, SCIP_EXPR **nlexprs, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:627
const XML_NODE * xmlNextSibl(const XML_NODE *node)
Definition: xmlparse.c:1449
SCIP_RETCODE SCIPcreateExprQuadratic(SCIP *scip, SCIP_EXPR **expr, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1033
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
memory allocation routines