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-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file reader_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( SCIPallocBufferArray(scip, &linvars[row], nterms) );
1145  SCIP_CALL( SCIPallocBufferArray(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( SCIPallocBufferArray(scip, &linvars[c], nlinvars[c]) );
1209  SCIP_CALL( SCIPallocBufferArray(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  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1239  )
1240 {
1241  const XML_NODE* quadcoef;
1242  const XML_NODE* qterm;
1243  const char* attrval;
1244  int* termssize;
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  SCIP_CALL( SCIPallocClearBufferArray(scip, &termssize, nconss + 1) );
1289 
1290  count = 0;
1291  for( qterm = xmlFirstChild(quadcoef); qterm != NULL; qterm = xmlNextSibl(qterm), ++count )
1292  {
1293  /* check for qterm node */
1294  if( strcmp(xmlGetName(qterm), "qTerm") != 0 )
1295  {
1296  SCIPerrorMessage("Expected <qTerm> node under <quadraticCoefficients> node, but got <%s>\n", xmlGetName(qterm));
1297  *doingfine = FALSE;
1298  goto TERMINATE;
1299  }
1300  if( count >= nqterms )
1301  {
1302  SCIPerrorMessage("Too many quadratic terms under <quadraticCoefficients> node, expected %d many, but got at least %d.\n", nqterms, count + 1);
1303  *doingfine = FALSE;
1304  goto TERMINATE;
1305  }
1306 
1307  /* get constraint index, or -1 for objective */
1308  attrval = xmlGetAttrval(qterm, "idx");
1309  if( attrval == NULL )
1310  {
1311  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1312  *doingfine = FALSE;
1313  goto TERMINATE;
1314  }
1315 
1316  considx = (int)strtol(attrval, (char**)&attrval, 10);
1317  if( *attrval != '\0' || considx < -1 || considx >= nconss )
1318  {
1319  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idx"), count);
1320  *doingfine = FALSE;
1321  goto TERMINATE;
1322  }
1323 
1324  /* get index of first variable */
1325  attrval = xmlGetAttrval(qterm, "idxOne");
1326  if( attrval == NULL )
1327  {
1328  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1329  *doingfine = FALSE;
1330  goto TERMINATE;
1331  }
1332 
1333  varidx1 = (int)strtol(attrval, (char**)&attrval, 10);
1334  if( *attrval != '\0' || varidx1 < 0 || varidx1 >= nvars )
1335  {
1336  SCIPerrorMessage("Invalid value '%s' in \"idxOne\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxOne"), count);
1337  *doingfine = FALSE;
1338  goto TERMINATE;
1339  }
1340 
1341  /* get index of second variable */
1342  attrval = xmlGetAttrval(qterm, "idxTwo");
1343  if( attrval == NULL )
1344  {
1345  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1346  *doingfine = FALSE;
1347  goto TERMINATE;
1348  }
1349 
1350  varidx2 = (int)strtol(attrval, (char**)&attrval, 10);
1351  if( *attrval != '\0' || varidx2 < 0 || varidx2 >= nvars )
1352  {
1353  SCIPerrorMessage("Invalid value '%s' in \"idxTwo\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxTwo"), count);
1354  *doingfine = FALSE;
1355  goto TERMINATE;
1356  }
1357 
1358  /* get (optional) coefficient of quadratic term */
1359  attrval = xmlGetAttrval(qterm, "coef");
1360  if( attrval != NULL )
1361  {
1362  coef = strtod(attrval, (char**)&attrval);
1363  if( *attrval != '\0' || (coef != coef) ) /*lint !e777*/
1364  {
1365  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "coef"), count);
1366  *doingfine = FALSE;
1367  goto TERMINATE;
1368  }
1369  }
1370  else
1371  {
1372  /* default is 1.0 according to specification */
1373  coef = 1.0;
1374  }
1375 
1376  /* skip zero coefficients */
1377  if( coef == 0.0 )
1378  continue;
1379 
1380  /* put objective at end of array */
1381  if( considx == -1 )
1382  considx = nconss;
1383 
1384  if( nquadterms[considx] + 1 > termssize[considx] )
1385  {
1386  termssize[considx] = SCIPcalcMemGrowSize(scip, nquadterms[considx] + 1);
1387  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1[considx], termssize[considx]) ); /*lint !e866*/
1388  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2[considx], termssize[considx]) ); /*lint !e866*/
1389  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs[considx], termssize[considx]) ); /*lint !e866*/
1390  }
1391 
1392  quadvars1[considx][nquadterms[considx]] = vars[varidx1];
1393  quadvars2[considx][nquadterms[considx]] = vars[varidx2];
1394  quadcoefs[considx][nquadterms[considx]] = coef;
1395  ++nquadterms[considx];
1396  }
1397 
1398  if( count != nqterms )
1399  {
1400  SCIPerrorMessage("Got only %d quadratic terms under <quadraticCoefficients> node, but expected %d many.\n", count, nqterms);
1401  *doingfine = FALSE;
1402  goto TERMINATE;
1403  }
1404 
1405  TERMINATE:
1406  SCIPfreeBufferArray(scip, &termssize);
1407 
1408  return SCIP_OKAY;
1409 }
1410 
1411 /** transforms OSnL expression tree into SCIP expression */
1412 static
1414  SCIP* scip, /**< SCIP data structure */
1415  SCIP_EXPR** expr, /**< buffer to store pointer to created expression */
1416  const XML_NODE* node, /**< root node of expression to be read */
1417  SCIP_VAR** vars, /**< variables in order of OSiL indices */
1418  int nvars, /**< total number of variables in problem */
1419  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1420  )
1421 {
1422  const char* exprname;
1423 
1424  assert(scip != NULL);
1425  assert(expr != NULL);
1426  assert(node != NULL);
1427  assert(vars != NULL);
1428  assert(doingfine != NULL);
1429 
1430  exprname = xmlGetName(node);
1431  assert(exprname != NULL);
1432 
1433  *expr = NULL;
1434 
1435  /* zero argument operands */
1436  if( strcmp(exprname, "variable") == 0 )
1437  {
1438  const char* attrval;
1439  SCIP_Real coef;
1440  int idx;
1441 
1442  /* read variable index */
1443  attrval = xmlGetAttrval(node, "idx");
1444  if( attrval == NULL )
1445  {
1446  SCIPerrorMessage("Attribute \"idx\" required for <variable> node in nonlinear expression\n");
1447  *doingfine = FALSE;
1448  return SCIP_OKAY;
1449  }
1450 
1451  idx = (int)strtol(attrval, (char**)&attrval, 10);
1452  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1453  {
1454  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "idx"));
1455  *doingfine = FALSE;
1456  return SCIP_OKAY;
1457  }
1458 
1459  /* read variable coefficient */
1460  attrval = xmlGetAttrval(node, "coef");
1461  if( attrval != NULL )
1462  {
1463  coef = strtod(attrval, (char**)&attrval);
1464  if( *attrval != '\0' || !SCIPisFinite(coef) )
1465  {
1466  SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "coef"));
1467  *doingfine = FALSE;
1468  return SCIP_OKAY;
1469  }
1470  }
1471  else
1472  {
1473  coef = 1.0;
1474  }
1475 
1476  /* create variable expression */
1477  SCIP_CALL( SCIPcreateExprVar(scip, expr, vars[idx], NULL, NULL) );
1478 
1479  /* create a sum if the coefficient != 1 */
1480  if( coef != 1.0 )
1481  {
1482  SCIP_EXPR* sumexpr;
1483 
1484  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, expr, &coef, 0.0, NULL, NULL) );
1485 
1486  /* release the variable expression and store the sum */
1487  SCIP_CALL( SCIPreleaseExpr(scip, expr) );
1488  *expr = sumexpr;
1489  }
1490 
1491  return SCIP_OKAY;
1492  }
1493 
1494  if( strcmp(exprname, "number") == 0 )
1495  {
1496  const char* attrval;
1497  SCIP_Real val;
1498 
1499  attrval = xmlGetAttrval(node, "type");
1500  if( attrval != NULL && (strcmp(attrval, "real") != 0) )
1501  {
1502  SCIPerrorMessage("Type '%s' for <number> node in nonlinear expression not supported.\n", attrval);
1503  *doingfine = FALSE;
1504  return SCIP_OKAY;
1505  }
1506 
1507  attrval = xmlGetAttrval(node, "value");
1508  if( attrval != NULL )
1509  {
1510  val = strtod(attrval, (char**)&attrval);
1511  if( *attrval != '\0' || !SCIPisFinite(val) )
1512  {
1513  SCIPerrorMessage("Invalid value '%s' in \"value\" attribute of <number> node in nonlinear expression.\n", xmlGetAttrval(node, "value"));
1514  *doingfine = FALSE;
1515  return SCIP_OKAY;
1516  }
1517  }
1518  else
1519  {
1520  /* according to OSnL.xsd, the value attribute is optional
1521  * I guess the default is the empty string, which should correspond to 0.0
1522  */
1523  val = 0.0;
1524  }
1525 
1526  /* create constant expression */
1527  SCIP_CALL( SCIPcreateExprValue(scip, expr, val, NULL, NULL) );
1528 
1529  return SCIP_OKAY;
1530  }
1531 
1532  if( strcmp(exprname, "PI") == 0 )
1533  {
1534  /* create constant expression with PI value */
1535  SCIP_CALL( SCIPcreateExprValue(scip, expr, M_PI, NULL, NULL) );
1536 
1537  return SCIP_OKAY;
1538  }
1539 
1540  if( strcmp(exprname, "E") == 0 )
1541  {
1542  /* create constant expression with PI value */
1543  SCIP_CALL( SCIPcreateExprValue(scip, expr, M_E, NULL, NULL) );
1544 
1545  return SCIP_OKAY;
1546  }
1547 
1548  /* single argument operands */
1549  if( strcmp(exprname, "negate") == 0 ||
1550  strcmp(exprname, "abs") == 0 ||
1551  strcmp(exprname, "squareRoot") == 0 ||
1552  strcmp(exprname, "sqrt") == 0 ||
1553  strcmp(exprname, "square") == 0 ||
1554  strcmp(exprname, "exp") == 0 ||
1555  strcmp(exprname, "ln") == 0 ||
1556  strcmp(exprname, "log10") == 0 ||
1557  strcmp(exprname, "sin") == 0 ||
1558  strcmp(exprname, "cos") == 0 ||
1559  strcmp(exprname, "erf") == 0
1560  )
1561  {
1562  SCIP_EXPR* arg;
1563 
1564  /* check number of children */
1565  if( xmlFirstChild(node) == NULL || xmlNextSibl(xmlFirstChild(node)) != NULL )
1566  {
1567  SCIPerrorMessage("Expected exactly one child in <%s> node in nonlinear expression\n", exprname);
1568  *doingfine = FALSE;
1569  return SCIP_OKAY;
1570  }
1571 
1572  /* read child expression */
1573  SCIP_CALL( readExpression(scip, &arg, xmlFirstChild(node), vars, nvars, doingfine) );
1574 
1575  if( !*doingfine )
1576  return SCIP_OKAY;
1577  assert(arg != NULL);
1578 
1579  /* create SCIP expression according to expression name */
1580  if( strcmp(exprname, "negate") == 0 )
1581  {
1582  SCIP_Real minusone;
1583 
1584  minusone = -1.0;
1585 
1586  SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &arg, &minusone, 0.0, NULL, NULL) );
1587  }
1588  else if( strcmp(exprname, "abs") == 0 )
1589  {
1590  SCIP_CALL( SCIPcreateExprAbs(scip, expr, arg, NULL, NULL) );
1591  }
1592  else if( strcmp(exprname, "squareRoot") == 0 || strcmp(exprname, "sqrt") == 0 )
1593  {
1594  SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 0.5, NULL, NULL) );
1595  }
1596  else if( strcmp(exprname, "square") == 0 )
1597  {
1598  SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 2.0, NULL, NULL) );
1599  }
1600  else if( strcmp(exprname, "exp") == 0 )
1601  {
1602  SCIP_CALL( SCIPcreateExprExp(scip, expr, arg, NULL, NULL) );
1603  }
1604  else if( strcmp(exprname, "ln") == 0 )
1605  {
1606  SCIP_CALL( SCIPcreateExprLog(scip, expr, arg, NULL, NULL) );
1607  }
1608  else if( strcmp(exprname, "log10") == 0 )
1609  {
1610  SCIP_EXPR* logexpr;
1611  SCIP_Real coef = 1.0/log(10.0);
1612 
1613  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, arg, NULL, NULL) );
1614  SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &logexpr, &coef, 0.0, NULL, NULL) );
1615  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1616  }
1617  else if( strcmp(exprname, "sin") == 0 )
1618  {
1619  SCIP_CALL( SCIPcreateExprSin(scip, expr, arg, NULL, NULL) );
1620  }
1621  else if( strcmp(exprname, "cos") == 0 )
1622  {
1623  SCIP_CALL( SCIPcreateExprCos(scip, expr, arg, NULL, NULL) );
1624  }
1625  else if( strcmp(exprname, "erf") == 0 )
1626  {
1627  SCIPwarningMessage(scip, "Danger! You're entering a construction area. Implementation of support for 'erf' is incomplete.\n");
1628  SCIP_CALL( SCIPcreateExprErf(scip, expr, arg, NULL, NULL) );
1629  }
1630 
1631  /* release argument expression */
1632  SCIP_CALL( SCIPreleaseExpr(scip, &arg) );
1633 
1634  return SCIP_OKAY;
1635  }
1636 
1637  /* two argument operands */
1638  if( strcmp(exprname, "plus") == 0 ||
1639  strcmp(exprname, "minus") == 0 ||
1640  strcmp(exprname, "times") == 0 ||
1641  strcmp(exprname, "divide") == 0 ||
1642  strcmp(exprname, "power") == 0 ||
1643  strcmp(exprname, "signpower") == 0 ||
1644  strcmp(exprname, "log") == 0
1645  )
1646  {
1647  SCIP_EXPR* args[2] = {NULL, NULL};
1648 
1649  /* check number of children */
1650  if( xmlFirstChild(node) == NULL ||
1651  xmlNextSibl(xmlFirstChild(node)) == NULL ||
1652  xmlNextSibl(xmlNextSibl(xmlFirstChild(node))) != NULL )
1653  {
1654  SCIPerrorMessage("Expected exactly two children in <%s> node in nonlinear expression.\n", exprname);
1655  *doingfine = FALSE;
1656  return SCIP_OKAY;
1657  }
1658 
1659  /* read first child expression */
1660  SCIP_CALL( readExpression(scip, &args[0], xmlFirstChild(node), vars, nvars, doingfine) );
1661  if( !*doingfine )
1662  goto TERMINATE_TWO_ARGS;
1663  assert(args[0] != NULL);
1664 
1665  /* read second child expression */
1666  SCIP_CALL( readExpression(scip, &args[1], xmlNextSibl(xmlFirstChild(node)), vars, nvars, doingfine) );
1667  if( !*doingfine )
1668  goto TERMINATE_TWO_ARGS;
1669  assert(args[1] != NULL);
1670 
1671  if( strcmp(exprname, "plus") == 0 )
1672  {
1673  SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, NULL, 0.0, NULL, NULL) );
1674  }
1675  else if( strcmp(exprname, "minus") == 0 )
1676  {
1677  SCIP_Real coefs[2] = {1.0, -1.0};
1678  SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, coefs, 0.0, NULL, NULL) );
1679  }
1680  else if( strcmp(exprname, "times") == 0 )
1681  {
1682  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, args, 1.0, NULL, NULL) );
1683  }
1684  else if( strcmp(exprname, "divide") == 0 )
1685  {
1686  SCIP_EXPR* tmp[2];
1687  SCIP_EXPR* powexpr;
1688 
1689  SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, args[1], -1.0, NULL, NULL) );
1690  tmp[0] = args[0];
1691  tmp[1] = powexpr;
1692  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1693  SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1694  }
1695  else if( strcmp(exprname, "power") == 0 )
1696  {
1697  /* case 1: expr^number */
1698  if( SCIPisExprValue(scip, args[1]) )
1699  {
1700  SCIP_CALL( SCIPcreateExprPow(scip, expr, args[0], SCIPgetValueExprValue(args[1]), NULL, NULL) );
1701  }
1702  /* case 2: number^expr = exp(arg2 * ln(number)) */
1703  else if( SCIPisExprValue(scip, args[0]) )
1704  {
1705  SCIP_Real value = SCIPgetValueExprValue(args[0]);
1706 
1707  if( value <= 0.0 )
1708  {
1709  SCIPerrorMessage("Negative base in <power> node with nonconstant exponent not allowed in nonlinear expression.\n");
1710  *doingfine = FALSE;
1711  goto TERMINATE_TWO_ARGS;
1712  }
1713  else
1714  {
1715  SCIP_EXPR* sumexpr;
1716  SCIP_Real coef = log(value);
1717 
1718  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, &args[1], &coef, 0.0, NULL, NULL) );
1719  SCIP_CALL( SCIPcreateExprExp(scip, expr, sumexpr, NULL, NULL) );
1720  SCIP_CALL( SCIPreleaseExpr(scip, &sumexpr) );
1721  }
1722  }
1723  /* case 3: arg1^arg2 is exp(arg2 * ln(arg1)) */
1724  else
1725  {
1726  SCIP_EXPR* logexpr;
1727  SCIP_EXPR* prodexpr;
1728  SCIP_EXPR* tmp[2];
1729 
1730  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, args[0], NULL, NULL) );
1731  tmp[0] = args[1];
1732  tmp[1] = logexpr;
1733  SCIP_CALL( SCIPcreateExprProduct(scip, &prodexpr, 2, tmp, 1.0, NULL, NULL) );
1734  SCIP_CALL( SCIPcreateExprExp(scip, expr, prodexpr, NULL, NULL) );
1735  SCIP_CALL( SCIPreleaseExpr(scip, &prodexpr) );
1736  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1737  }
1738  }
1739  else if( strcmp(exprname, "signpower") == 0 )
1740  {
1741  /* signpower(expr,number) with number > 1 is the only one we can handle */
1742  if( !SCIPisExprValue(scip, args[1]) )
1743  {
1744  SCIPerrorMessage("Signpower only supported for constant exponents.\n");
1745  *doingfine = FALSE;
1746  goto TERMINATE_TWO_ARGS;
1747  }
1748  if( SCIPgetValueExprValue(args[1]) <= 1.0 )
1749  {
1750  SCIPerrorMessage("Signpower only supported for exponents > 1, but got %g.\n",
1751  SCIPgetValueExprValue(args[1]));
1752  *doingfine = FALSE;
1753  goto TERMINATE_TWO_ARGS;
1754  }
1755 
1756  SCIP_CALL( SCIPcreateExprSignpower(scip, expr, args[0], SCIPgetValueExprValue(args[1]), NULL, NULL) );
1757  }
1758  /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) */
1759  else if( strcmp(exprname, "log") == 0 )
1760  {
1761  SCIP_EXPR* logexpr0;
1762  SCIP_EXPR* logexpr1;
1763  SCIP_EXPR* powexpr;
1764  SCIP_EXPR* tmp[2];
1765 
1766  /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) = ln(arg2) * pow(ln(arg1),-1) */
1767  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr0, args[0], NULL, NULL) );
1768  SCIP_CALL( SCIPcreateExprLog(scip, &logexpr1, args[1], NULL, NULL) );
1769  SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, logexpr0, -1.0, NULL, NULL) );
1770  tmp[0] = logexpr1;
1771  tmp[1] = powexpr;
1772  SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1773 
1774  SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1775  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr1) );
1776  SCIP_CALL( SCIPreleaseExpr(scip, &logexpr0) );
1777  }
1778  else if( strcmp(exprname, "min") == 0 )
1779  {
1780  SCIPerrorMessage("min expressions are not supported\n");
1781  *doingfine = FALSE;
1782  goto TERMINATE_TWO_ARGS;
1783  }
1784  else /* if( strcmp(exprname, "max") == 0 ) */
1785  {
1786  assert(strcmp(exprname, "max") == 0);
1787 
1788  SCIPerrorMessage("max expressions are not supported\n");
1789  *doingfine = FALSE;
1790  goto TERMINATE_TWO_ARGS;
1791  }
1792 
1793 TERMINATE_TWO_ARGS:
1794 
1795  /* release first and second argument expression */
1796  if( args[0] != NULL )
1797  {
1798  SCIP_CALL( SCIPreleaseExpr(scip, &args[0]) );
1799  }
1800  if( args[1] != NULL )
1801  {
1802  SCIP_CALL( SCIPreleaseExpr(scip, &args[1]) );
1803  }
1804 
1805  return SCIP_OKAY;
1806  }
1807 
1808  /* arbitrary argument operands */
1809  if( strcmp(exprname, "sum") == 0 || strcmp(exprname, "product") == 0 )
1810  {
1811  const XML_NODE* argnode;
1812  SCIP_EXPR** args;
1813  int nargs;
1814  int argssize;
1815  int i;
1816 
1817  /* a sum or product w.r.t. 0 arguments is constant */
1818  if( xmlFirstChild(node) == NULL )
1819  {
1820  SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1821 
1822  return SCIP_OKAY;
1823  }
1824 
1825  /* read all child expressions */
1826  argssize = 5;
1827  SCIP_CALL( SCIPallocBufferArray(scip, &args, argssize) );
1828 
1829  nargs = 0;
1830  for( argnode = xmlFirstChild(node); argnode != NULL; argnode = xmlNextSibl(argnode), ++nargs )
1831  {
1832  if( nargs >= argssize )
1833  {
1834  argssize = SCIPcalcMemGrowSize(scip, nargs + 1);
1835  SCIP_CALL( SCIPreallocBufferArray(scip, &args, argssize) );
1836  }
1837  assert(nargs < argssize);
1838 
1839  SCIP_CALL( readExpression(scip, &args[nargs], argnode, vars, nvars, doingfine) );
1840  if( !*doingfine )
1841  {
1842  assert(args[nargs] == NULL);
1843  break;
1844  }
1845  }
1846 
1847  if( *doingfine )
1848  {
1849  switch( nargs )
1850  {
1851  case 0:
1852  {
1853  SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1854  break;
1855  }
1856  case 1:
1857  {
1858  *expr = args[0];
1859  /* capture expression here because args[0] will be released at the end */
1860  SCIPcaptureExpr(*expr);
1861  break;
1862  }
1863 
1864  default:
1865  {
1866  /* create sum or product expression */
1867  if( strcmp(exprname, "sum") == 0 )
1868  {
1869  SCIP_CALL( SCIPcreateExprSum(scip, expr, nargs, args, NULL, 0.0, NULL, NULL) );
1870  }
1871  else
1872  {
1873  SCIP_CALL( SCIPcreateExprProduct(scip, expr, nargs, args, 1.0, NULL, NULL) );
1874  }
1875 
1876  break;
1877  }
1878  }
1879  }
1880 
1881  /* release argument expressions */
1882  for( i = 0; i < nargs; ++i )
1883  {
1884  assert(args[i] != NULL);
1885  SCIP_CALL( SCIPreleaseExpr(scip, &args[i]) );
1886  }
1887 
1888  SCIPfreeBufferArray(scip, &args);
1889 
1890  return SCIP_OKAY;
1891  }
1892 
1893  if( strcmp(exprname, "min") == 0 || strcmp(exprname, "max") == 0 )
1894  {
1895  SCIPerrorMessage("min or max expressions are not supported\n");
1896  *doingfine = FALSE;
1897  return SCIP_OKAY;
1898  }
1899 
1900  if( strcmp(exprname, "quadratic") == 0 )
1901  {
1902  const char* attrval;
1903  const XML_NODE* qterm;
1904  SCIP_VAR** quadvars1;
1905  SCIP_VAR** quadvars2;
1906  SCIP_Real* quadcoefs;
1907  int nquadelems;
1908  int quadelemssize;
1909  int idx;
1910 
1911  quadelemssize = 5;
1912  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, quadelemssize) );
1913  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, quadelemssize) );
1914  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, quadelemssize) );
1915  nquadelems = 0;
1916 
1917  /* read quadratic terms */
1918  for( qterm = xmlFirstChild(node); qterm != NULL; qterm = xmlNextSibl(qterm), ++nquadelems )
1919  {
1920  /* check for qpTerm node */
1921  if( strcmp(xmlGetName(qterm), "qpTerm") != 0 )
1922  {
1923  SCIPerrorMessage("Unexpected <%s> node under <quadratic> node in nonlinear expression, expected <qpTerm>.\n", xmlGetName(qterm));
1924  *doingfine = FALSE;
1925  return SCIP_OKAY;
1926  }
1927 
1928  if( nquadelems >= quadelemssize )
1929  {
1930  quadelemssize = SCIPcalcMemGrowSize(scip, nquadelems + 1);
1931  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, quadelemssize) );
1932  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, quadelemssize) );
1933  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, quadelemssize) );
1934  }
1935  assert(quadelemssize > nquadelems);
1936 
1937  /* get index of first variable */
1938  attrval = xmlGetAttrval(qterm, "idxOne");
1939  if( attrval == NULL )
1940  {
1941  SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1942  *doingfine = FALSE;
1943  return SCIP_OKAY;
1944  }
1945 
1946  idx = (int)strtol(attrval, (char**)&attrval, 10);
1947  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1948  {
1949  SCIPerrorMessage("Invalid value '%s' for \"idxOne\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxOne"), nquadelems);
1950  *doingfine = FALSE;
1951  return SCIP_OKAY;
1952  }
1953  quadvars1[nquadelems] = vars[idx];
1954 
1955  /* get index of second variable */
1956  attrval = xmlGetAttrval(qterm, "idxTwo");
1957  if( attrval == NULL )
1958  {
1959  SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1960  *doingfine = FALSE;
1961  return SCIP_OKAY;
1962  }
1963 
1964  idx = (int)strtol(attrval, (char**)&attrval, 10);
1965  if( *attrval != '\0' || idx < 0 || idx >= nvars )
1966  {
1967  SCIPerrorMessage("Invalid value '%s' for \"idxTwo\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxTwo"), nquadelems);
1968  *doingfine = FALSE;
1969  return SCIP_OKAY;
1970  }
1971  quadvars2[nquadelems] = vars[idx];
1972 
1973  /* get coefficient */
1974  attrval = xmlGetAttrval(qterm, "coef");
1975  if( attrval != NULL )
1976  {
1977  quadcoefs[nquadelems] = strtod(attrval, (char**)&attrval);
1978  if( *attrval != '\0' || !SCIPisFinite(quadcoefs[nquadelems]) ) /*lint !e777*/
1979  {
1980  SCIPerrorMessage("Invalid value '%s' for \"coef\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "coef"), nquadelems);
1981  *doingfine = FALSE;
1982  return SCIP_OKAY;
1983  }
1984  }
1985  else
1986  {
1987  quadcoefs[nquadelems] = 1.0;
1988  }
1989  }
1990 
1991  /* create quadratic expression */
1992  SCIP_CALL( SCIPcreateExprQuadratic(scip, expr, 0, NULL, NULL, nquadelems, quadvars1, quadvars2, quadcoefs, NULL, NULL) );
1993  }
1994 
1995  SCIPerrorMessage("Expression operand <%s> in nonlinear expression not supported by SCIP so far.\n", exprname);
1996  *doingfine = FALSE;
1997 
1998  return SCIP_OKAY;
1999 }
2000 
2001 
2002 /** read nonlinear expressions of constraints and objective */
2003 static
2005  SCIP* scip, /**< SCIP data structure */
2006  const XML_NODE* datanode, /**< XML root node for instance data */
2007  SCIP_VAR** vars, /**< variables in order of OSiL indices */
2008  int nvars, /**< number of variables */
2009  int nconss, /**< number of constraints */
2010  SCIP_EXPR** exprs, /**< array to store for each constraint a nonlinear expression */
2011  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2012  )
2013 {
2014  const XML_NODE* nlexprs;
2015  const XML_NODE* nlexpr;
2016  const char* attrval;
2017  int nnlexprs;
2018  int count;
2019  int considx;
2020 
2021  assert(scip != NULL);
2022  assert(datanode != NULL);
2023  assert(vars != NULL || nvars == 0);
2024  assert(exprs != NULL);
2025  assert(doingfine != NULL);
2026 
2027  nlexprs = xmlFindNodeMaxdepth(datanode, "nonlinearExpressions", 0, 1);
2028 
2029  if( nlexprs == NULL )
2030  return SCIP_OKAY;
2031 
2032  /* get number of nonlinear expressions */
2033  attrval = xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions");
2034  if( attrval == NULL )
2035  {
2036  SCIPerrorMessage("Attribute \"numberOfNonlinearExpressions\" in <nonlinearExpressions> node not found.\n");
2037  *doingfine = FALSE;
2038  return SCIP_OKAY;
2039  }
2040 
2041  nnlexprs = (int)strtol(attrval, (char**)&attrval, 10);
2042  if( *attrval != '\0' || nnlexprs < 0 )
2043  {
2044  SCIPerrorMessage("Invalid value '%s' for \"numberOfNonlinearExpressions\" attribute in <nonlinearExpressions>.\n", xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions"));
2045  *doingfine = FALSE;
2046  return SCIP_OKAY;
2047  }
2048  assert(nnlexprs >= 0);
2049 
2050  /* read nonlinear expressions and store in constraints */
2051  count = 0;
2052  for( nlexpr = xmlFirstChild(nlexprs); nlexpr != NULL; nlexpr = xmlNextSibl(nlexpr), ++count )
2053  {
2054  if( strcmp(xmlGetName(nlexpr), "nl") != 0 )
2055  {
2056  SCIPerrorMessage("Expected <nl> node under <nonlinearExpressions> node, but got '%s'.\n", xmlGetName(nlexpr));
2057  *doingfine = FALSE;
2058  break;
2059  }
2060  if( count >= nnlexprs )
2061  {
2062  SCIPerrorMessage("Too many nonlinear expressions under <nonlinearExpressions> node, expected %d many, but got at least %d.\n", nnlexprs, count + 1);
2063  *doingfine = FALSE;
2064  break;
2065  }
2066 
2067  /* treat empty expression as 0.0 and continue */
2068  if( xmlFirstChild(nlexprs) == NULL )
2069  continue;
2070 
2071  /* get constraint index, or -1 for objective */
2072  attrval = xmlGetAttrval(nlexpr, "idx");
2073  if( attrval == NULL )
2074  {
2075  SCIPerrorMessage("Missing \"idx\" attribute in %d'th <nl> node under <nonlinearExpressions> node.\n", count);
2076  *doingfine = FALSE;
2077  break;
2078  }
2079 
2080  considx = (int)strtol(attrval, (char**)&attrval, 10);
2081  if( *attrval != '\0' || considx < -1 || considx >= nconss )
2082  {
2083  SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <nl> node under <nonlinearExpressions> node.\n", xmlGetAttrval(nlexpr, "idx"), count);
2084  *doingfine = FALSE;
2085  break;
2086  }
2087 
2088  /* turn OSiL expression into SCIP expression and assign indices to variables; store a nonlinear objective at position nconss */
2089  SCIP_CALL( readExpression(scip, considx == -1 ? &exprs[nconss] : &exprs[considx],
2090  xmlFirstChild(nlexpr), vars, nvars, doingfine) );
2091  if( !*doingfine )
2092  return SCIP_OKAY;
2093  }
2094 
2095  return SCIP_OKAY;
2096 }
2097 
2098 
2099 /** read sos1 and sos2 constraints
2100  *
2101  * sos constraints are expected to be given as a node of <instanceData> in the following way:
2102  * @code
2103  * <specialOrderedSets numberOfSpecialOrderedSets="1">
2104  * <sos numberOfVar="2" order="2">
2105  * <var idx="1"></var>
2106  * <var idx="2"></var>
2107  * </sos>
2108  * </specialOrderedSets>
2109  * @endcode
2110  * Weights are determined by the order in which the variables are given
2111  *
2112  */
2113 static
2115  SCIP* scip, /**< SCIP data structure */
2116  const XML_NODE* datanode, /**< XML root node for instance data */
2117  SCIP_VAR** vars, /**< variables in order of OSiL indices */
2118  int nvars, /**< number of variables */
2119  SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
2120  SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
2121  SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
2122  SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2123  )
2124 {
2125  const XML_NODE* soscons;
2126  const XML_NODE* sosvar;
2127  const char* attrval;
2128  int nsoscons;
2129  int nsosvars;
2130  int sosorder;
2131  int type;
2132  int count;
2133  int varcount;
2134  int idx;
2135  SCIP_Bool initial;
2136  SCIP_Bool separate;
2137  SCIP_Bool enforce;
2138  SCIP_Bool check;
2139  SCIP_Bool propagate;
2140  SCIP_Bool local;
2141  SCIP_Bool dynamic;
2142  SCIP_Bool removable;
2143  char name[SCIP_MAXSTRLEN];
2144 
2145  /* standard settings for SOS constraints: */
2146  initial = initialconss;
2147  separate = TRUE;
2148  enforce = TRUE;
2149  check = TRUE;
2150  propagate = TRUE;
2151  local = FALSE;
2152  dynamic = dynamicconss;
2153  removable = dynamicrows;
2154 
2155  soscons= xmlFindNodeMaxdepth(datanode, "specialOrderedSets", 0, 1);
2156 
2157  if( soscons== NULL )
2158  return SCIP_OKAY;
2159 
2160  /* get number of sos constraints */
2161  attrval = xmlGetAttrval(soscons, "numberOfSOS");
2162  if( attrval == NULL )
2163  {
2164  SCIPerrorMessage("Attribute \"numberOfSOS in <specialOrderedSets> node not found.\n");
2165  *doingfine = FALSE;
2166  return SCIP_OKAY;
2167  }
2168 
2169  nsoscons = (int)strtol(attrval, (char**)&attrval, 10);
2170  if( *attrval != '\0' || nsoscons < 0 )
2171  {
2172  SCIPerrorMessage("Invalid value '%s' for \"numberOfSOS\" attribute in <specialOrderedSets>.\n", xmlGetAttrval(soscons, "numberOfSOS"));
2173  *doingfine = FALSE;
2174  return SCIP_OKAY;
2175  }
2176  assert(nsoscons >= 0);
2177 
2178  /* read sos constraints and create corresponding constraint */
2179  count = 0;
2180  for( soscons = xmlFirstChild(soscons); soscons != NULL; soscons = xmlNextSibl(soscons), ++count )
2181  {
2182  SCIP_CONS* cons;
2183 
2184  /* Make sure we get a sos node and not more then announced*/
2185  if( strcmp(xmlGetName(soscons), "sos") != 0 )
2186  {
2187  SCIPerrorMessage("Expected <sos> node under <specialOrderedSet> node, but got '%s'.\n", xmlGetName(soscons));
2188  *doingfine = FALSE;
2189  break;
2190  }
2191 
2192  if( count >= nsoscons)
2193  {
2194  SCIPerrorMessage("Too many sos under <specialOrderedSets> node, expected %d many, but got at least %d.\n", nsoscons, count + 1);
2195  *doingfine = FALSE;
2196  break;
2197  }
2198 
2199  /* get number of variables in this sos constraint */
2200  attrval = xmlGetAttrval(soscons, "numberOfVar");
2201  if( attrval == NULL )
2202  {
2203  SCIPerrorMessage("Attribute \"numberOfVar in <sos> node not found.\n");
2204  *doingfine = FALSE;
2205  return SCIP_OKAY;
2206  }
2207 
2208  nsosvars = (int)strtol(attrval, (char**)&attrval, 10);
2209  if( *attrval != '\0' || nsosvars < 0 )
2210  {
2211  SCIPerrorMessage("Invalid value '%s' for \"numberOfVar\" attribute in <sos>.\n", xmlGetAttrval(soscons, "numberOfVar"));
2212  *doingfine = FALSE;
2213  return SCIP_OKAY;
2214  }
2215  assert(nsosvars >= 0);
2216 
2217  /* get order of this sos constraint */
2218  attrval = xmlGetAttrval(soscons, "type");
2219  if( attrval == NULL )
2220  {
2221  SCIPerrorMessage("Attribute \"order\" in <sos> node not found.\n");
2222  *doingfine = FALSE;
2223  return SCIP_OKAY;
2224  }
2225 
2226  sosorder = (int)strtol(attrval, (char**)&attrval, 10);
2227  if( *attrval != '\0' || sosorder < 0 || sosorder > 2 )
2228  {
2229  SCIPerrorMessage("Invalid/unsupported value '%s' for \"order\" attribute in <sos>.\n", xmlGetAttrval(soscons, "order"));
2230  *doingfine = FALSE;
2231  return SCIP_OKAY;
2232  }
2233  assert(sosorder == 1 || sosorder == 2);
2234  type = sosorder;
2235 
2236  /* set artificial name for sos constraint*/
2237  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d_%d", type, count);
2238 
2239  /* Create sos constraint */
2240  switch( type )
2241  {
2242  case 1:
2243  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2244  local, dynamic, removable, FALSE) );
2245  break;
2246  case 2:
2247  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2248  local, dynamic, removable, FALSE) );
2249  break;
2250  default:
2251  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2252  SCIPABORT();
2253  return SCIP_INVALIDDATA; /*lint !e527*/
2254  }
2255 
2256  varcount = 0;
2257  for( sosvar = xmlFirstChild(soscons); sosvar!= NULL; sosvar = xmlNextSibl(sosvar), ++varcount )
2258  {
2259  /* get variable id*/
2260  attrval = xmlGetAttrval(sosvar, "idx");
2261  if( attrval == NULL )
2262  {
2263  SCIPerrorMessage("Attribute \"idx\" in <var> node below <specialOrderedSets> node not found.\n");
2264  *doingfine = FALSE;
2265  return SCIP_OKAY;
2266  }
2267 
2268  idx = (int)strtol(attrval, (char**)&attrval, 10);
2269  if( *attrval != '\0' || idx < 0 || idx > nvars - 1 )
2270  {
2271  SCIPerrorMessage("Invalid value '%s' for \"idx\" attribute in <var>.\n", xmlGetAttrval(sosvar, "idx"));
2272  *doingfine = FALSE;
2273  return SCIP_OKAY;
2274  }
2275  assert(idx >= 0);
2276 
2277  /* we now know that we have a variable/weight pair -> add variable*/
2278  switch( type )
2279  {
2280  case 1:
2281  SCIP_CALL( SCIPaddVarSOS1(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2282  break;
2283  case 2:
2284  SCIP_CALL( SCIPaddVarSOS2(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2285  break;
2286  /* coverity[dead_error_begin] */
2287  default:
2288  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2289  SCIPABORT();
2290  return SCIP_INVALIDDATA; /*lint !e527*/
2291  }
2292  } /* Close loop over variables in sos constraint */
2293 
2294  /* add the SOS constraint */
2295  SCIP_CALL( SCIPaddCons(scip, cons) );
2296  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2297  }
2298 
2299  return SCIP_OKAY;
2300 }
2301 
2302  /*
2303  * Callback methods of reader
2304  */
2305 
2306 
2307 /** copy method for reader plugins (called when SCIP copies plugins) */
2308 static
2309 SCIP_DECL_READERCOPY(readerCopyOsil)
2310 { /*lint --e{715}*/
2311  assert(scip != NULL);
2312 
2314 
2315  return SCIP_OKAY;
2316 }
2317 
2318 /** problem reading method of reader */
2319 static
2320 SCIP_DECL_READERREAD(readerReadOsil)
2321 { /*lint --e{715}*/
2322  const XML_NODE* header;
2323  const XML_NODE* data;
2324  XML_NODE* start;
2325  SCIP_VAR** vars;
2326  const char* name;
2327  SCIP_RETCODE retcode;
2328  SCIP_Bool doingfine;
2329  SCIP_Bool initialconss;
2330  SCIP_Bool dynamicconss;
2331  SCIP_Bool dynamiccols;
2332  SCIP_Bool dynamicrows;
2333  int nconss;
2334  int nvars;
2335  int c;
2336  int i;
2337 
2338  /* linear parts */
2339  SCIP_VAR*** linvars = NULL;
2340  SCIP_Real** lincoefs = NULL;
2341  int* nlinvars = NULL;
2342 
2343  /* quadratic parts */
2344  SCIP_VAR*** quadvars1 = NULL;
2345  SCIP_VAR*** quadvars2 = NULL;
2346  SCIP_Real** quadcoefs = NULL;
2347  int* nquadterms = NULL;
2348 
2349  /* nonlinear parts */
2350  SCIP_EXPR** nlexprs = NULL;
2351 
2352  assert(scip != NULL);
2353  assert(reader != NULL);
2354  assert(result != NULL);
2355  assert(filename != NULL);
2356 
2357  *result = SCIP_DIDNOTRUN;
2358  retcode = SCIP_READERROR;
2359  doingfine = TRUE;
2360  vars = NULL;
2361  nvars = 0;
2362  nconss = -1;
2363 
2364  /* read OSiL xml file */
2365  start = xmlProcess(filename);
2366 
2367  if( start == NULL )
2368  {
2369  SCIPerrorMessage("Some error occurred when parsing the OSiL XML file '%s'.\n", filename);
2370  goto CLEANUP;
2371  }
2372 
2373  SCIPdebug( xmlShowNode(start) );
2374 
2375  /* parse header to get problem name */
2376  name = filename;
2377  header = xmlFindNodeMaxdepth(start, "instanceHeader", 0, 2);
2378  if( header != NULL )
2379  {
2380  const XML_NODE* namenode;
2381 
2382  namenode = xmlFindNodeMaxdepth(header, "name", 0, 2);
2383 
2384  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2385  name = xmlGetData(xmlFirstChild(namenode));
2386  else
2387  {
2388  namenode = xmlFindNodeMaxdepth(header, "description", 0, 2);
2389 
2390  if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2391  name = xmlGetData(xmlFirstChild(namenode));
2392  }
2393  }
2394 
2395  /* create SCIP problem */
2397 
2398  /* process instance data */
2399  data = xmlFindNodeMaxdepth(start, "instanceData", 0, 2);
2400  if( data == NULL )
2401  {
2402  SCIPerrorMessage("Node <instanceData> not found.\n");
2403  goto CLEANUP;
2404  }
2405 
2406  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
2407  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
2408  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
2409  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
2410 
2411  /* read variables */
2412  SCIP_CALL_TERMINATE( retcode, readVariables(scip, data, &vars, &nvars, initialconss, dynamicconss, dynamiccols, dynamicrows, &doingfine), CLEANUP );
2413  if( !doingfine )
2414  goto CLEANUP;
2415  assert(vars != NULL || nvars == 0);
2416 
2417  /* read objective sense, coefficient, and constant */
2418  SCIP_CALL_TERMINATE( retcode, readObjective(scip, data, vars, nvars, dynamiccols, &doingfine), CLEANUP );
2419  if( !doingfine )
2420  goto CLEANUP;
2421 
2422  /* read total number of constraints */
2423  SCIP_CALL_TERMINATE( retcode, readNConstraints(scip, data, &nconss, &doingfine), CLEANUP );
2424  if( !doingfine )
2425  goto CLEANUP;
2426 
2427  /* allocate memory to store constraint information */
2428  SCIP_CALL( SCIPallocClearBufferArray(scip, &linvars, nconss + 1) );
2429  SCIP_CALL( SCIPallocClearBufferArray(scip, &lincoefs, nconss + 1) );
2430  SCIP_CALL( SCIPallocClearBufferArray(scip, &nlinvars, nconss + 1) );
2431  SCIP_CALL( SCIPallocClearBufferArray(scip, &quadvars1, nconss + 1) );
2432  SCIP_CALL( SCIPallocClearBufferArray(scip, &quadvars2, nconss + 1) );
2433  SCIP_CALL( SCIPallocClearBufferArray(scip, &quadcoefs, nconss + 1) );
2434  SCIP_CALL( SCIPallocClearBufferArray(scip, &nquadterms, nconss + 1) );
2435  SCIP_CALL( SCIPallocClearBufferArray(scip, &nlexprs, nconss + 1) );
2436 
2437  /* read linear coefficients matrix */
2438  SCIP_CALL_TERMINATE( retcode, readLinearCoefs(scip, data, vars, nvars, nconss, linvars, lincoefs, nlinvars, &doingfine), CLEANUP );
2439  if( !doingfine )
2440  goto CLEANUP;
2441 
2442  /* read quadratic coefficients */
2443  SCIP_CALL_TERMINATE( retcode, readQuadraticCoefs(scip, data, vars, nvars, nconss, quadvars1, quadvars2, quadcoefs,
2444  nquadterms, &doingfine), CLEANUP );
2445  if( !doingfine )
2446  goto CLEANUP;
2447 
2448  /* read nonlinear expressions */
2449  SCIP_CALL_TERMINATE( retcode, readNonlinearExprs(scip, data, vars, nvars, nconss, nlexprs, &doingfine), CLEANUP );
2450  if( !doingfine )
2451  goto CLEANUP;
2452 
2453  /* read constraint data; generate constraints */
2454  SCIP_CALL_TERMINATE( retcode, readConstraints(scip, data, nconss, linvars, lincoefs, nlinvars,
2455  quadvars1, quadvars2, quadcoefs, nquadterms, nlexprs, initialconss, dynamicconss, dynamicrows, &doingfine),
2456  CLEANUP );
2457  if( !doingfine )
2458  goto CLEANUP;
2459 
2460  /* add nonlinear objective constraint */
2461  if( nlinvars[nconss] > 0 || nquadterms[nconss] > 0 || nlexprs[nconss] != NULL )
2462  {
2463  SCIP_CALL( createConstraint(scip, linvars[nconss], lincoefs[nconss], nlinvars[nconss],
2464  quadvars1[nconss], quadvars2[nconss], quadcoefs[nconss], nquadterms[nconss], nlexprs[nconss],
2467  "objcons", TRUE, TRUE, FALSE, FALSE) );
2468  }
2469 
2470  /* read sos2 constraints and add to problem */
2471  SCIP_CALL_TERMINATE( retcode, readSOScons(scip, data, vars, nvars, initialconss, dynamicconss, dynamicrows, &doingfine), CLEANUP );
2472  if( !doingfine )
2473  goto CLEANUP;
2474 
2475  *result = SCIP_SUCCESS;
2476  retcode = SCIP_OKAY;
2477 
2478  CLEANUP:
2479  /* free xml data */
2480  if( start != NULL )
2481  xmlFreeNode(start);
2482 
2483  /* free memory for constraint information (position nconss belongs to the nonlinear objective function) */
2484  for( c = nconss; c >= 0; --c )
2485  {
2486  /* free nonlinear parts */
2487  if( nlexprs != NULL && nlexprs[c] != NULL )
2488  {
2489  SCIP_CALL( SCIPreleaseExpr(scip, &nlexprs[c]) );
2490  }
2491 
2492  /* free quadratic parts */
2493  SCIPfreeBufferArrayNull(scip, &quadcoefs[c]);
2494  SCIPfreeBufferArrayNull(scip, &quadvars1[c]);
2495  SCIPfreeBufferArrayNull(scip, &quadvars2[c]);
2496 
2497  /* free linear parts */
2498  SCIPfreeBufferArrayNull(scip, &lincoefs[c]);
2499  SCIPfreeBufferArrayNull(scip, &linvars[c]);
2500  }
2501  SCIPfreeBufferArrayNull(scip, &nlexprs);
2502  SCIPfreeBufferArrayNull(scip, &nquadterms);
2503  SCIPfreeBufferArrayNull(scip, &quadcoefs);
2504  SCIPfreeBufferArrayNull(scip, &quadvars2);
2505  SCIPfreeBufferArrayNull(scip, &quadvars1);
2506  SCIPfreeBufferArrayNull(scip, &nlinvars);
2507  SCIPfreeBufferArrayNull(scip, &lincoefs);
2508  SCIPfreeBufferArrayNull(scip, &linvars);
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
static volatile int nterms
Definition: interrupt.c:47
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:3175
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:2309
public methods for memory management
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:126
#define SCIP_MAXSTRLEN
Definition: def.h:302
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:3199
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:2482
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
#define FALSE
Definition: def.h:96
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
#define TRUE
Definition: def.h:95
#define SCIPdebug(x)
Definition: pub_message.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
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:1399
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:1116
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:2114
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:1079
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:1413
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:2320
#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:10547
#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:1432
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, SCIP_Bool *doingfine)
Definition: reader_osil.c:1228
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17242
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
#define NULL
Definition: lpi_spx1.cpp:164
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:1443
#define SCIP_CALL(x)
Definition: def.h:394
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:4513
#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:93
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:1407
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:1119
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:186
handler for Gaussian error function expressions
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:415
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:206
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:1901
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:10410
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:2383
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:366
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:2004
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:1023
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
memory allocation routines