Scippy

SCIP

Solving Constraint Integer Programs

reader_osil.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file reader_osil.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief OS instance language (OSiL) format file reader
28 * @author Stefan Vigerske
29 * @author Ingmar Vierhaus
30 * @author Benjamin Mueller
31 */
32
33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34
35#define _USE_MATH_DEFINES /* to get M_PI and M_E on Windows */ /*lint !750 */
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 */
78static
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 */
292static
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 */
435static
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) */
481static
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 */
626static
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 */
780static
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 */
846static
848 SCIP* scip, /**< SCIP data structure */
849 const XML_NODE* datanode, /**< XML root node for instance data */
850 SCIP_VAR** vars, /**< variables in order of OSiL indices */
851 int nvars, /**< number of variables */
852 int nconss, /**< number of constraints */
853 SCIP_VAR*** linvars, /**< array to store for each constraint the linear variables */
854 SCIP_Real** lincoefs, /**< array to store for each constraint the coefficients of the linear variables */
855 int* nlinvars, /**< array to store for each constraint the total number of linear variables */
856 SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
857 )
858{
859 const XML_NODE* lincoef;
860 const XML_NODE* startnode;
861 const XML_NODE* idxnode;
862 const XML_NODE* valnode;
863 const XML_NODE* elnode;
864 const char* attrval;
865 SCIP_Bool rowmajor;
866 int* start;
867 int* idx;
868 SCIP_Real* val;
869 int nnz;
870 int count;
871 int mult;
872 int incrint;
873 SCIP_Real incrreal;
874
875 assert(scip != NULL);
876 assert(datanode != NULL);
877 assert(vars != NULL || nvars == 0);
878 assert(doingfine != NULL);
879
880 lincoef = xmlFindNodeMaxdepth(datanode, "linearConstraintCoefficients", 0, 1);
881
882 if( lincoef == NULL )
883 return SCIP_OKAY;
884
885 /* get number of linear constraint coefficients */
886 attrval = xmlGetAttrval(lincoef, "numberOfValues");
887 if( attrval == NULL )
888 {
889 SCIPerrorMessage("Attribute \"numberOfValues\" not found for <linearConstraintCoefficients> node.\n");
890 *doingfine = FALSE;
891 return SCIP_OKAY;
892 }
893
894 nnz = (int)strtol(attrval, (char**)&attrval, 10);
895 if( *attrval != '\0' || nnz < 0 )
896 {
897 SCIPerrorMessage("Invalid value '%s' for \"numberOfValues\" attribute in <linearConstraintCoefficients> node.\n", xmlGetAttrval(lincoef, "numberOfValues"));
898 *doingfine = FALSE;
899 return SCIP_OKAY;
900 }
901 assert(nnz >= 0);
902
903 /* check for start, rowIdx, colIdx, and value nodes */
904 startnode = xmlFindNodeMaxdepth(lincoef, "start", 0, 1);
905 if( startnode == NULL )
906 {
907 SCIPerrorMessage("Node <start> not found inside <linearConstraintCoefficients> node.\n");
908 *doingfine = FALSE;
909 return SCIP_OKAY;
910 }
911
912 idxnode = xmlFindNodeMaxdepth(lincoef, "rowIdx", 0, 1);
913 if( idxnode != NULL )
914 {
915 if( xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1) != NULL )
916 {
917 SCIPerrorMessage("Both <rowIdx> and <colIdx> found under <linearConstraintCoefficients> node.\n");
918 *doingfine = FALSE;
919 return SCIP_OKAY;
920 }
921 rowmajor = FALSE;
922 }
923 else
924 {
925 idxnode = xmlFindNodeMaxdepth(lincoef, "colIdx", 0, 1);
926 if( idxnode == NULL )
927 {
928 SCIPerrorMessage("Both <rowIdx> and <colIdx> not found under <linearConstraintCoefficients> node.\n");
929 *doingfine = FALSE;
930 return SCIP_OKAY;
931 }
932 rowmajor = TRUE;
933 }
934
935 valnode = xmlFindNodeMaxdepth(lincoef, "value", 0, 1);
936 if( valnode == NULL )
937 {
938 SCIPerrorMessage("<value> node not found under <linearConstraintCoefficients> node.\n");
939 *doingfine = FALSE;
940 return SCIP_OKAY;
941 }
942
943 start = NULL;
944 idx = NULL;
945 val = NULL;
946
947 /* read row or column start indices */
948 SCIP_CALL( SCIPallocBufferArray(scip, &start, (rowmajor ? nconss : nvars) + 1) );
949
950 count = 0;
951 for( elnode = xmlFirstChild(startnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
952 {
953 /* check for <el> node and read it's data */
954 if( strcmp(xmlGetName(elnode), "el") != 0 )
955 {
956 SCIPerrorMessage("Expected <el> node under <start> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
957 *doingfine = FALSE;
958 goto CLEANUP;
959 }
960 if( count >= (rowmajor ? nconss : nvars) + 1 )
961 {
962 SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
963 *doingfine = FALSE;
964 goto CLEANUP;
965 }
966 if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
967 {
968 SCIPerrorMessage("No data in <el> node in <linearConstraintCoefficients>.\n");
969 *doingfine = FALSE;
970 goto CLEANUP;
971 }
972
973 start[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
974
975 if( *attrval != '\0' || start[count] < 0 || (start[count] > nnz) )
976 {
977 SCIPerrorMessage("Invalid value '%s' in <el> node under <start> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
978 *doingfine = FALSE;
979 goto CLEANUP;
980 }
981
982 /* add additional start-indices according to mult and incr attributes */
983 readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
984 if( !*doingfine )
985 goto CLEANUP;
986
987 for( --mult; mult > 0; --mult )
988 {
989 ++count;
990 if( count >= (rowmajor ? nconss : nvars) + 1 )
991 {
992 SCIPerrorMessage("Too many elements under <start> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", (rowmajor ? nconss : nvars) + 1, count + 1);
993 *doingfine = FALSE;
994 goto CLEANUP;
995 }
996 start[count] = start[count-1] + incrint;
997 }
998 }
999 if( count != (rowmajor ? nconss : nvars) + 1 )
1000 {
1001 SCIPerrorMessage("Got only %d <start> entries in <linearConstraintCoefficients>, but expected %d many.\n", count, (rowmajor ? nconss : nvars) + 1);
1002 *doingfine = FALSE;
1003 goto CLEANUP;
1004 }
1005
1006 /* read row or column indices */
1007 SCIP_CALL( SCIPallocBufferArray(scip, &idx, nnz) );
1008
1009 count = 0;
1010 for( elnode = xmlFirstChild(idxnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
1011 {
1012 /* check for <el> node and read it's data */
1013 if( strcmp(xmlGetName(elnode), "el") != 0 )
1014 {
1015 SCIPerrorMessage("Expected <el> node under <%s> node in <linearConstraintCoefficients>, but got '%s'.\n", rowmajor ? "colIdx" : "rowIdx", xmlGetName(elnode));
1016 *doingfine = FALSE;
1017 goto CLEANUP;
1018 }
1019 if( count >= nnz )
1020 {
1021 SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, but got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
1022 *doingfine = FALSE;
1023 goto CLEANUP;
1024 }
1025 if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
1026 {
1027 SCIPerrorMessage("No data in <el> node under <%s> node in <linearConstraintCoefficients>.\n", rowmajor ? "colIdx" : "rowIdx");
1028 *doingfine = FALSE;
1029 goto CLEANUP;
1030 }
1031
1032 idx[count] = (int)strtol(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval, 10);
1033
1034 if( *attrval != '\0' || idx[count] < 0 || (idx[count] >= (rowmajor ? nvars : nconss)) )
1035 {
1036 SCIPerrorMessage("Invalid value '%s' in <el> node under <%s> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode), rowmajor ? "colIdx" : "rowIdx");
1037 *doingfine = FALSE;
1038 goto CLEANUP;
1039 }
1040
1041 /* add additional indices according to mult and incr attributes */
1042 readMultIncr(elnode, &mult, &incrint, NULL, doingfine);
1043 if( !*doingfine )
1044 goto CLEANUP;
1045
1046 for( --mult; mult > 0; --mult )
1047 {
1048 ++count;
1049 if( count >= nnz )
1050 {
1051 SCIPerrorMessage("Too many elements under <%s> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", rowmajor ? "colIdx" : "rowIdx", nnz, count + 1);
1052 *doingfine = FALSE;
1053 goto CLEANUP;
1054 }
1055 idx[count] = idx[count-1] + incrint;
1056 }
1057 }
1058 if( count != nnz )
1059 {
1060 SCIPerrorMessage("Got only %d entries in <%s> node in <linearConstraintCoefficients>, expected %d many.\n", count, rowmajor ? "colIdx" : "rowIdx", nnz);
1061 *doingfine = FALSE;
1062 goto CLEANUP;
1063 }
1064
1065 /* read coefficient values */
1066 SCIP_CALL( SCIPallocBufferArray(scip, &val, nnz) );
1067
1068 count = 0;
1069 for( elnode = xmlFirstChild(valnode); elnode != NULL; elnode = xmlNextSibl(elnode), ++count )
1070 {
1071 /* check for <el> node and read it's data */
1072 if( strcmp(xmlGetName(elnode), "el") != 0 )
1073 {
1074 SCIPerrorMessage("Expected <el> node under <value> node in <linearConstraintCoefficients>, but got '%s'.\n", xmlGetName(elnode));
1075 *doingfine = FALSE;
1076 goto CLEANUP;
1077 }
1078 if( count >= nnz )
1079 {
1080 SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
1081 *doingfine = FALSE;
1082 goto CLEANUP;
1083 }
1084 if( xmlFirstChild(elnode) == NULL || xmlGetData(xmlFirstChild(elnode)) == NULL )
1085 {
1086 SCIPerrorMessage("No data in <el> node under <value> node in <linearConstraintCoefficients>.\n");
1087 *doingfine = FALSE;
1088 goto CLEANUP;
1089 }
1090
1091 val[count] = strtod(xmlGetData(xmlFirstChild(elnode)), (char**)&attrval);
1092
1093 if( *attrval != '\0' || !SCIPisFinite(val[count]) )
1094 {
1095 SCIPerrorMessage("Invalid value '%s' in <el> node under <value> node in <linearConstraintCoefficients>.\n", xmlGetData(elnode));
1096 *doingfine = FALSE;
1097 goto CLEANUP;
1098 }
1099
1100 /* add additional values according to mult and incr attributes */
1101 readMultIncr(elnode, &mult, NULL, &incrreal, doingfine);
1102 if( !*doingfine )
1103 goto CLEANUP;
1104
1105 for( --mult; mult > 0; --mult )
1106 {
1107 ++count;
1108 if( count >= nnz )
1109 {
1110 SCIPerrorMessage("Too many elements under <value> node in <linearConstraintCoefficients>, expected %d many, got at least %d.\n", nnz, count + 1);
1111 *doingfine = FALSE;
1112 goto CLEANUP;
1113 }
1114 val[count] = val[count-1] + incrreal;
1115 }
1116 }
1117 if( count != nnz )
1118 {
1119 SCIPerrorMessage("Got only %d entries under <value> node in <linearConstraintCoefficients>, expected %d many.\n", count, nnz);
1120 *doingfine = FALSE;
1121 goto CLEANUP;
1122 }
1123
1124 /* add coefficients to linear constraints */
1125 if( rowmajor )
1126 {
1127 int row;
1128 int pos;
1129 for( row = 0; row < nconss; ++row )
1130 {
1131 int nterms;
1132
1133 /* these asserts were checked above */
1134 assert(start[row] >= 0);
1135 assert(start[row+1] >= 0);
1136 assert(start[row] <= nnz);
1137 assert(start[row+1] <= nnz);
1138
1139 assert(linvars[row] == NULL);
1140 assert(lincoefs[row] == NULL);
1141 assert(nlinvars[row] == 0);
1142
1143 nterms = start[row+1] - start[row];
1144 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &linvars[row], nterms) );
1145 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lincoefs[row], nterms) );
1146
1147 for( pos = start[row]; pos < start[row+1]; ++pos )
1148 {
1149 /* these asserts were checked above */
1150 assert(pos >= 0);
1151 assert(pos < nnz);
1152 assert(idx[pos] >= 0);
1153 assert(idx[pos] < nvars);
1154
1155 linvars[row][nlinvars[row]] = vars[idx[pos]];
1156 lincoefs[row][nlinvars[row]] = val[pos];
1157 ++(nlinvars[row]);
1158 }
1159 assert(nlinvars[row] == nterms);
1160 }
1161 }
1162 else
1163 {
1164 int col;
1165 int pos;
1166 int k;
1167
1168 /* allocate memory for the coefficients in iteration k=0; in k=1 fill in the data */
1169 for( k = 0; k < 2; ++k )
1170 {
1171 for( col = 0; col < nvars; ++col )
1172 {
1173 /* these asserts were checked above */
1174 assert(start[col] >= 0);
1175 assert(start[col+1] >= 0);
1176 assert(start[col] <= nnz);
1177 assert(start[col+1] <= nnz);
1178 for( pos = start[col]; pos < start[col+1]; ++pos )
1179 {
1180 int considx = idx[pos];
1181
1182 /* these asserts were checked above */
1183 assert(pos >= 0);
1184 assert(pos < nnz);
1185 assert(considx >= 0);
1186 assert(considx < nconss);
1187
1188 if( k == 0 )
1189 {
1190 ++(nlinvars[considx]);
1191 }
1192 else
1193 {
1194 linvars[considx][nlinvars[considx]] = vars[col];
1195 lincoefs[considx][nlinvars[considx]] = val[pos];
1196 ++(nlinvars[considx]);
1197 }
1198 }
1199 }
1200
1201 /* allocate memory to store the linear coefficients for each constraint after the first iteration */
1202 if( k == 0 )
1203 {
1204 int c;
1205
1206 for( c = 0; c < nconss; ++c )
1207 {
1208 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &linvars[c], nlinvars[c]) );
1209 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &lincoefs[c], nlinvars[c]) );
1210
1211 /* reset nlinvars[c] so it can be used for iteration k=1 */
1212 nlinvars[c] = 0;
1213 }
1214 }
1215 }
1216 }
1217
1218 CLEANUP:
1222
1223 return SCIP_OKAY;
1224}
1225
1226/** read quadratic coefficients of constraints and objective */
1227static
1229 SCIP* scip, /**< SCIP data structure */
1230 const XML_NODE* datanode, /**< XML root node for instance data */
1231 SCIP_VAR** vars, /**< variables in order of OSiL indices */
1232 int nvars, /**< number of variables */
1233 int nconss, /**< number of constraints */
1234 SCIP_VAR*** quadvars1, /**< array to store for each constraint the first variables of the quadratic terms */
1235 SCIP_VAR*** quadvars2, /**< array to store for each constraint the second variables of the quadratic terms */
1236 SCIP_Real** quadcoefs, /**< array to store for each constraint the coefficients of the quadratic terms */
1237 int* nquadterms, /**< array to store for each constraint the total number of quadratic terms */
1238 int* termssize, /**< pointer to store the size of quadvars1, quadvars2, and quadcoefs */
1239 SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1240 )
1241{
1242 const XML_NODE* quadcoef;
1243 const XML_NODE* qterm;
1244 const char* attrval;
1245 SCIP_Real coef;
1246 int nqterms;
1247 int count;
1248 int considx;
1249 int varidx1;
1250 int varidx2;
1251
1252 assert(scip != NULL);
1253 assert(datanode != NULL);
1254 assert(quadvars1 != NULL);
1255 assert(quadvars2 != NULL);
1256 assert(quadcoefs != NULL);
1257 assert(nquadterms != NULL);
1258 assert(doingfine != NULL);
1259
1260 quadcoef = xmlFindNodeMaxdepth(datanode, "quadraticCoefficients", 0, 1);
1261
1262 if( quadcoef == NULL )
1263 return SCIP_OKAY;
1264
1265 /* read number of quadratic terms */
1266 attrval = xmlGetAttrval(quadcoef, "numberOfQuadraticTerms");
1267 if( attrval == NULL )
1268 {
1269 SCIPerrorMessage("Attribute \"numberOfQuadraticTerms\" not found for <quadraticCoefficients> node.\n");
1270 *doingfine = FALSE;
1271 return SCIP_OKAY;
1272 }
1273
1274 nqterms = (int)strtol(attrval, (char**)&attrval, 10);
1275 if( *attrval != '\0' || nqterms < 0 )
1276 {
1277 SCIPerrorMessage("Invalid value '%s' for \"numberOfQuadraticTerms\" attribute of <quadraticCoefficients> node.\n", xmlGetAttrval(quadcoef, "numberOfQuadraticTerms"));
1278 *doingfine = FALSE;
1279 return SCIP_OKAY;
1280 }
1281 assert(nqterms >= 0);
1282
1283 if( nqterms == 0 )
1284 return SCIP_OKAY;
1285
1286 assert(vars != NULL);
1287
1288 count = 0;
1289 for( qterm = xmlFirstChild(quadcoef); qterm != NULL; qterm = xmlNextSibl(qterm), ++count )
1290 {
1291 /* check for qterm node */
1292 if( strcmp(xmlGetName(qterm), "qTerm") != 0 )
1293 {
1294 SCIPerrorMessage("Expected <qTerm> node under <quadraticCoefficients> node, but got <%s>\n", xmlGetName(qterm));
1295 *doingfine = FALSE;
1296 return SCIP_OKAY;
1297 }
1298 if( count >= nqterms )
1299 {
1300 SCIPerrorMessage("Too many quadratic terms under <quadraticCoefficients> node, expected %d many, but got at least %d.\n", nqterms, count + 1);
1301 *doingfine = FALSE;
1302 return SCIP_OKAY;
1303 }
1304
1305 /* get constraint index, or -1 for objective */
1306 attrval = xmlGetAttrval(qterm, "idx");
1307 if( attrval == NULL )
1308 {
1309 SCIPerrorMessage("Missing \"idx\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1310 *doingfine = FALSE;
1311 return SCIP_OKAY;
1312 }
1313
1314 considx = (int)strtol(attrval, (char**)&attrval, 10);
1315 if( *attrval != '\0' || considx < -1 || considx >= nconss )
1316 {
1317 SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idx"), count);
1318 *doingfine = FALSE;
1319 return SCIP_OKAY;
1320 }
1321
1322 /* get index of first variable */
1323 attrval = xmlGetAttrval(qterm, "idxOne");
1324 if( attrval == NULL )
1325 {
1326 SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1327 *doingfine = FALSE;
1328 return SCIP_OKAY;
1329 }
1330
1331 varidx1 = (int)strtol(attrval, (char**)&attrval, 10);
1332 if( *attrval != '\0' || varidx1 < 0 || varidx1 >= nvars )
1333 {
1334 SCIPerrorMessage("Invalid value '%s' in \"idxOne\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxOne"), count);
1335 *doingfine = FALSE;
1336 return SCIP_OKAY;
1337 }
1338
1339 /* get index of second variable */
1340 attrval = xmlGetAttrval(qterm, "idxTwo");
1341 if( attrval == NULL )
1342 {
1343 SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qTerm> node under <quadraticCoefficients> node.\n", count);
1344 *doingfine = FALSE;
1345 return SCIP_OKAY;
1346 }
1347
1348 varidx2 = (int)strtol(attrval, (char**)&attrval, 10);
1349 if( *attrval != '\0' || varidx2 < 0 || varidx2 >= nvars )
1350 {
1351 SCIPerrorMessage("Invalid value '%s' in \"idxTwo\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "idxTwo"), count);
1352 *doingfine = FALSE;
1353 return SCIP_OKAY;
1354 }
1355
1356 /* get (optional) coefficient of quadratic term */
1357 attrval = xmlGetAttrval(qterm, "coef");
1358 if( attrval != NULL )
1359 {
1360 coef = strtod(attrval, (char**)&attrval);
1361 if( *attrval != '\0' || (coef != coef) ) /*lint !e777*/
1362 {
1363 SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of %d'th <qTerm> node under <quadraticCoefficients> node.\n", xmlGetAttrval(qterm, "coef"), count);
1364 *doingfine = FALSE;
1365 return SCIP_OKAY;
1366 }
1367 }
1368 else
1369 {
1370 /* default is 1.0 according to specification */
1371 coef = 1.0;
1372 }
1373
1374 /* skip zero coefficients */
1375 if( coef == 0.0 )
1376 continue;
1377
1378 /* put objective at end of array */
1379 if( considx == -1 )
1380 considx = nconss;
1381
1382 if( nquadterms[considx] + 1 > termssize[considx] )
1383 {
1384 int newsize;
1385
1386 newsize = SCIPcalcMemGrowSize(scip, nquadterms[considx] + 1);
1387 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadvars1[considx], termssize[considx], newsize) ); /*lint !e866*/
1388 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadvars2[considx], termssize[considx], newsize) ); /*lint !e866*/
1389 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &quadcoefs[considx], termssize[considx], newsize) ); /*lint !e866*/
1390 termssize[considx] = newsize;
1391 }
1392
1393 quadvars1[considx][nquadterms[considx]] = vars[varidx1];
1394 quadvars2[considx][nquadterms[considx]] = vars[varidx2];
1395 quadcoefs[considx][nquadterms[considx]] = coef;
1396 ++nquadterms[considx];
1397 }
1398
1399 if( count != nqterms )
1400 {
1401 SCIPerrorMessage("Got only %d quadratic terms under <quadraticCoefficients> node, but expected %d many.\n", count, nqterms);
1402 *doingfine = FALSE;
1403 }
1404
1405 return SCIP_OKAY;
1406}
1407
1408/** transforms OSnL expression tree into SCIP expression */
1409static
1411 SCIP* scip, /**< SCIP data structure */
1412 SCIP_EXPR** expr, /**< buffer to store pointer to created expression */
1413 const XML_NODE* node, /**< root node of expression to be read */
1414 SCIP_VAR** vars, /**< variables in order of OSiL indices */
1415 int nvars, /**< total number of variables in problem */
1416 SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
1417 )
1418{
1419 const char* exprname;
1420
1421 assert(scip != NULL);
1422 assert(expr != NULL);
1423 assert(node != NULL);
1424 assert(vars != NULL);
1425 assert(doingfine != NULL);
1426
1427 exprname = xmlGetName(node);
1428 assert(exprname != NULL);
1429
1430 *expr = NULL;
1431
1432 /* zero argument operands */
1433 if( strcmp(exprname, "variable") == 0 )
1434 {
1435 const char* attrval;
1436 SCIP_Real coef;
1437 int idx;
1438
1439 /* read variable index */
1440 attrval = xmlGetAttrval(node, "idx");
1441 if( attrval == NULL )
1442 {
1443 SCIPerrorMessage("Attribute \"idx\" required for <variable> node in nonlinear expression\n");
1444 *doingfine = FALSE;
1445 return SCIP_OKAY;
1446 }
1447
1448 idx = (int)strtol(attrval, (char**)&attrval, 10);
1449 if( *attrval != '\0' || idx < 0 || idx >= nvars )
1450 {
1451 SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "idx"));
1452 *doingfine = FALSE;
1453 return SCIP_OKAY;
1454 }
1455
1456 /* read variable coefficient */
1457 attrval = xmlGetAttrval(node, "coef");
1458 if( attrval != NULL )
1459 {
1460 coef = strtod(attrval, (char**)&attrval);
1461 if( *attrval != '\0' || !SCIPisFinite(coef) )
1462 {
1463 SCIPerrorMessage("Invalid value '%s' in \"coef\" attribute of <variable> node in nonlinear expression.\n", xmlGetAttrval(node, "coef"));
1464 *doingfine = FALSE;
1465 return SCIP_OKAY;
1466 }
1467 }
1468 else
1469 {
1470 coef = 1.0;
1471 }
1472
1473 /* create variable expression */
1474 SCIP_CALL( SCIPcreateExprVar(scip, expr, vars[idx], NULL, NULL) );
1475
1476 /* create a sum if the coefficient != 1 */
1477 if( coef != 1.0 )
1478 {
1479 SCIP_EXPR* sumexpr;
1480
1481 SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, expr, &coef, 0.0, NULL, NULL) );
1482
1483 /* release the variable expression and store the sum */
1484 SCIP_CALL( SCIPreleaseExpr(scip, expr) );
1485 *expr = sumexpr;
1486 }
1487
1488 return SCIP_OKAY;
1489 }
1490
1491 if( strcmp(exprname, "number") == 0 )
1492 {
1493 const char* attrval;
1494 SCIP_Real val;
1495
1496 attrval = xmlGetAttrval(node, "type");
1497 if( attrval != NULL && (strcmp(attrval, "real") != 0) )
1498 {
1499 SCIPerrorMessage("Type '%s' for <number> node in nonlinear expression not supported.\n", attrval);
1500 *doingfine = FALSE;
1501 return SCIP_OKAY;
1502 }
1503
1504 attrval = xmlGetAttrval(node, "value");
1505 if( attrval != NULL )
1506 {
1507 val = strtod(attrval, (char**)&attrval);
1508 if( *attrval != '\0' || !SCIPisFinite(val) )
1509 {
1510 SCIPerrorMessage("Invalid value '%s' in \"value\" attribute of <number> node in nonlinear expression.\n", xmlGetAttrval(node, "value"));
1511 *doingfine = FALSE;
1512 return SCIP_OKAY;
1513 }
1514 }
1515 else
1516 {
1517 /* according to OSnL.xsd, the value attribute is optional
1518 * I guess the default is the empty string, which should correspond to 0.0
1519 */
1520 val = 0.0;
1521 }
1522
1523 /* create constant expression */
1524 SCIP_CALL( SCIPcreateExprValue(scip, expr, val, NULL, NULL) );
1525
1526 return SCIP_OKAY;
1527 }
1528
1529 if( strcmp(exprname, "PI") == 0 )
1530 {
1531 /* create constant expression with PI value */
1533
1534 return SCIP_OKAY;
1535 }
1536
1537 if( strcmp(exprname, "E") == 0 )
1538 {
1539 /* create constant expression with PI value */
1540 SCIP_CALL( SCIPcreateExprValue(scip, expr, M_E, NULL, NULL) );
1541
1542 return SCIP_OKAY;
1543 }
1544
1545 /* single argument operands */
1546 if( strcmp(exprname, "negate") == 0 ||
1547 strcmp(exprname, "abs") == 0 ||
1548 strcmp(exprname, "squareRoot") == 0 ||
1549 strcmp(exprname, "sqrt") == 0 ||
1550 strcmp(exprname, "square") == 0 ||
1551 strcmp(exprname, "exp") == 0 ||
1552 strcmp(exprname, "ln") == 0 ||
1553 strcmp(exprname, "log10") == 0 ||
1554 strcmp(exprname, "sin") == 0 ||
1555 strcmp(exprname, "cos") == 0 ||
1556 strcmp(exprname, "erf") == 0
1557 )
1558 {
1559 SCIP_EXPR* arg;
1560
1561 /* check number of children */
1562 if( xmlFirstChild(node) == NULL || xmlNextSibl(xmlFirstChild(node)) != NULL )
1563 {
1564 SCIPerrorMessage("Expected exactly one child in <%s> node in nonlinear expression\n", exprname);
1565 *doingfine = FALSE;
1566 return SCIP_OKAY;
1567 }
1568
1569 /* read child expression */
1570 SCIP_CALL( readExpression(scip, &arg, xmlFirstChild(node), vars, nvars, doingfine) );
1571
1572 if( !*doingfine )
1573 return SCIP_OKAY;
1574 assert(arg != NULL);
1575
1576 /* create SCIP expression according to expression name */
1577 if( strcmp(exprname, "negate") == 0 )
1578 {
1579 SCIP_Real minusone;
1580
1581 minusone = -1.0;
1582
1583 SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &arg, &minusone, 0.0, NULL, NULL) );
1584 }
1585 else if( strcmp(exprname, "abs") == 0 )
1586 {
1587 SCIP_CALL( SCIPcreateExprAbs(scip, expr, arg, NULL, NULL) );
1588 }
1589 else if( strcmp(exprname, "squareRoot") == 0 || strcmp(exprname, "sqrt") == 0 )
1590 {
1591 SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 0.5, NULL, NULL) );
1592 }
1593 else if( strcmp(exprname, "square") == 0 )
1594 {
1595 SCIP_CALL( SCIPcreateExprPow(scip, expr, arg, 2.0, NULL, NULL) );
1596 }
1597 else if( strcmp(exprname, "exp") == 0 )
1598 {
1599 SCIP_CALL( SCIPcreateExprExp(scip, expr, arg, NULL, NULL) );
1600 }
1601 else if( strcmp(exprname, "ln") == 0 )
1602 {
1603 SCIP_CALL( SCIPcreateExprLog(scip, expr, arg, NULL, NULL) );
1604 }
1605 else if( strcmp(exprname, "log10") == 0 )
1606 {
1607 SCIP_EXPR* logexpr;
1608 SCIP_Real coef = 1.0/log(10.0);
1609
1610 SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, arg, NULL, NULL) );
1611 SCIP_CALL( SCIPcreateExprSum(scip, expr, 1, &logexpr, &coef, 0.0, NULL, NULL) );
1612 SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1613 }
1614 else if( strcmp(exprname, "sin") == 0 )
1615 {
1616 SCIP_CALL( SCIPcreateExprSin(scip, expr, arg, NULL, NULL) );
1617 }
1618 else if( strcmp(exprname, "cos") == 0 )
1619 {
1620 SCIP_CALL( SCIPcreateExprCos(scip, expr, arg, NULL, NULL) );
1621 }
1622 else if( strcmp(exprname, "erf") == 0 )
1623 {
1624 SCIPwarningMessage(scip, "Danger! You're entering a construction area. Implementation of support for 'erf' is incomplete.\n");
1625 SCIP_CALL( SCIPcreateExprErf(scip, expr, arg, NULL, NULL) );
1626 }
1627
1628 /* release argument expression */
1629 SCIP_CALL( SCIPreleaseExpr(scip, &arg) );
1630
1631 return SCIP_OKAY;
1632 }
1633
1634 /* two argument operands */
1635 if( strcmp(exprname, "plus") == 0 ||
1636 strcmp(exprname, "minus") == 0 ||
1637 strcmp(exprname, "times") == 0 ||
1638 strcmp(exprname, "divide") == 0 ||
1639 strcmp(exprname, "power") == 0 ||
1640 strcmp(exprname, "signpower") == 0 ||
1641 strcmp(exprname, "log") == 0
1642 )
1643 {
1644 SCIP_EXPR* args[2] = {NULL, NULL};
1645
1646 /* check number of children */
1647 if( xmlFirstChild(node) == NULL ||
1648 xmlNextSibl(xmlFirstChild(node)) == NULL ||
1650 {
1651 SCIPerrorMessage("Expected exactly two children in <%s> node in nonlinear expression.\n", exprname);
1652 *doingfine = FALSE;
1653 return SCIP_OKAY;
1654 }
1655
1656 /* read first child expression */
1657 SCIP_CALL( readExpression(scip, &args[0], xmlFirstChild(node), vars, nvars, doingfine) );
1658 if( !*doingfine )
1659 goto TERMINATE_TWO_ARGS;
1660 assert(args[0] != NULL);
1661
1662 /* read second child expression */
1663 SCIP_CALL( readExpression(scip, &args[1], xmlNextSibl(xmlFirstChild(node)), vars, nvars, doingfine) );
1664 if( !*doingfine )
1665 goto TERMINATE_TWO_ARGS;
1666 assert(args[1] != NULL);
1667
1668 if( strcmp(exprname, "plus") == 0 )
1669 {
1670 SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, NULL, 0.0, NULL, NULL) );
1671 }
1672 else if( strcmp(exprname, "minus") == 0 )
1673 {
1674 SCIP_Real coefs[2] = {1.0, -1.0};
1675 SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, args, coefs, 0.0, NULL, NULL) );
1676 }
1677 else if( strcmp(exprname, "times") == 0 )
1678 {
1679 SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, args, 1.0, NULL, NULL) );
1680 }
1681 else if( strcmp(exprname, "divide") == 0 )
1682 {
1683 SCIP_EXPR* tmp[2];
1684 SCIP_EXPR* powexpr;
1685
1686 SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, args[1], -1.0, NULL, NULL) );
1687 tmp[0] = args[0];
1688 tmp[1] = powexpr;
1689 SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1690 SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1691 }
1692 else if( strcmp(exprname, "power") == 0 )
1693 {
1694 /* case 1: expr^number */
1695 if( SCIPisExprValue(scip, args[1]) )
1696 {
1697 SCIP_CALL( SCIPcreateExprPow(scip, expr, args[0], SCIPgetValueExprValue(args[1]), NULL, NULL) );
1698 }
1699 /* case 2: number^expr = exp(arg2 * ln(number)) */
1700 else if( SCIPisExprValue(scip, args[0]) )
1701 {
1702 SCIP_Real value = SCIPgetValueExprValue(args[0]);
1703
1704 if( value <= 0.0 )
1705 {
1706 SCIPerrorMessage("Negative base in <power> node with nonconstant exponent not allowed in nonlinear expression.\n");
1707 *doingfine = FALSE;
1708 goto TERMINATE_TWO_ARGS;
1709 }
1710 else
1711 {
1712 SCIP_EXPR* sumexpr;
1713 SCIP_Real coef = log(value);
1714
1715 SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, &args[1], &coef, 0.0, NULL, NULL) );
1716 SCIP_CALL( SCIPcreateExprExp(scip, expr, sumexpr, NULL, NULL) );
1717 SCIP_CALL( SCIPreleaseExpr(scip, &sumexpr) );
1718 }
1719 }
1720 /* case 3: arg1^arg2 is exp(arg2 * ln(arg1)) */
1721 else
1722 {
1723 SCIP_EXPR* logexpr;
1724 SCIP_EXPR* prodexpr;
1725 SCIP_EXPR* tmp[2];
1726
1727 SCIP_CALL( SCIPcreateExprLog(scip, &logexpr, args[0], NULL, NULL) );
1728 tmp[0] = args[1];
1729 tmp[1] = logexpr;
1730 SCIP_CALL( SCIPcreateExprProduct(scip, &prodexpr, 2, tmp, 1.0, NULL, NULL) );
1731 SCIP_CALL( SCIPcreateExprExp(scip, expr, prodexpr, NULL, NULL) );
1732 SCIP_CALL( SCIPreleaseExpr(scip, &prodexpr) );
1733 SCIP_CALL( SCIPreleaseExpr(scip, &logexpr) );
1734 }
1735 }
1736 else if( strcmp(exprname, "signpower") == 0 )
1737 {
1738 /* signpower(expr,number) with number > 1 is the only one we can handle */
1739 if( !SCIPisExprValue(scip, args[1]) )
1740 {
1741 SCIPerrorMessage("Signpower only supported for constant exponents.\n");
1742 *doingfine = FALSE;
1743 goto TERMINATE_TWO_ARGS;
1744 }
1745 if( SCIPgetValueExprValue(args[1]) <= 1.0 )
1746 {
1747 SCIPerrorMessage("Signpower only supported for exponents > 1, but got %g.\n",
1748 SCIPgetValueExprValue(args[1]));
1749 *doingfine = FALSE;
1750 goto TERMINATE_TWO_ARGS;
1751 }
1752
1754 }
1755 /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) */
1756 else if( strcmp(exprname, "log") == 0 )
1757 {
1758 SCIP_EXPR* logexpr0;
1759 SCIP_EXPR* logexpr1;
1760 SCIP_EXPR* powexpr;
1761 SCIP_EXPR* tmp[2];
1762
1763 /* logarithm of arg2 w.r.t. base arg1 = ln(arg2) / ln(arg1) = ln(arg2) * pow(ln(arg1),-1) */
1764 SCIP_CALL( SCIPcreateExprLog(scip, &logexpr0, args[0], NULL, NULL) );
1765 SCIP_CALL( SCIPcreateExprLog(scip, &logexpr1, args[1], NULL, NULL) );
1766 SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, logexpr0, -1.0, NULL, NULL) );
1767 tmp[0] = logexpr1;
1768 tmp[1] = powexpr;
1769 SCIP_CALL( SCIPcreateExprProduct(scip, expr, 2, tmp, 1.0, NULL, NULL) );
1770
1771 SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
1772 SCIP_CALL( SCIPreleaseExpr(scip, &logexpr1) );
1773 SCIP_CALL( SCIPreleaseExpr(scip, &logexpr0) );
1774 }
1775 else if( strcmp(exprname, "min") == 0 )
1776 {
1777 SCIPerrorMessage("min expressions are not supported\n");
1778 *doingfine = FALSE;
1779 goto TERMINATE_TWO_ARGS;
1780 }
1781 else /* if( strcmp(exprname, "max") == 0 ) */
1782 {
1783 assert(strcmp(exprname, "max") == 0);
1784
1785 SCIPerrorMessage("max expressions are not supported\n");
1786 *doingfine = FALSE;
1787 goto TERMINATE_TWO_ARGS;
1788 }
1789
1790TERMINATE_TWO_ARGS:
1791
1792 /* release first and second argument expression */
1793 if( args[0] != NULL )
1794 {
1795 SCIP_CALL( SCIPreleaseExpr(scip, &args[0]) );
1796 }
1797 if( args[1] != NULL )
1798 {
1799 SCIP_CALL( SCIPreleaseExpr(scip, &args[1]) );
1800 }
1801
1802 return SCIP_OKAY;
1803 }
1804
1805 /* arbitrary argument operands */
1806 if( strcmp(exprname, "sum") == 0 || strcmp(exprname, "product") == 0 )
1807 {
1808 const XML_NODE* argnode;
1809 SCIP_EXPR** args;
1810 int nargs;
1811 int argssize;
1812 int i;
1813
1814 /* a sum or product w.r.t. 0 arguments is constant */
1815 if( xmlFirstChild(node) == NULL )
1816 {
1817 SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1818
1819 return SCIP_OKAY;
1820 }
1821
1822 /* read all child expressions */
1823 argssize = 5;
1824 SCIP_CALL( SCIPallocBufferArray(scip, &args, argssize) );
1825
1826 nargs = 0;
1827 for( argnode = xmlFirstChild(node); argnode != NULL; argnode = xmlNextSibl(argnode), ++nargs )
1828 {
1829 if( nargs >= argssize )
1830 {
1831 argssize = SCIPcalcMemGrowSize(scip, nargs + 1);
1832 SCIP_CALL( SCIPreallocBufferArray(scip, &args, argssize) );
1833 }
1834 assert(nargs < argssize);
1835
1836 SCIP_CALL( readExpression(scip, &args[nargs], argnode, vars, nvars, doingfine) );
1837 if( !*doingfine )
1838 {
1839 assert(args[nargs] == NULL);
1840 break;
1841 }
1842 }
1843
1844 if( *doingfine )
1845 {
1846 switch( nargs )
1847 {
1848 case 0:
1849 {
1850 SCIP_CALL( SCIPcreateExprValue(scip, expr, (strcmp(exprname, "sum") == 0) ? 0.0 : 1.0, NULL, NULL) );
1851 break;
1852 }
1853 case 1:
1854 {
1855 *expr = args[0];
1856 /* capture expression here because args[0] will be released at the end */
1857 SCIPcaptureExpr(*expr);
1858 break;
1859 }
1860
1861 default:
1862 {
1863 /* create sum or product expression */
1864 if( strcmp(exprname, "sum") == 0 )
1865 {
1866 SCIP_CALL( SCIPcreateExprSum(scip, expr, nargs, args, NULL, 0.0, NULL, NULL) );
1867 }
1868 else
1869 {
1870 SCIP_CALL( SCIPcreateExprProduct(scip, expr, nargs, args, 1.0, NULL, NULL) );
1871 }
1872
1873 break;
1874 }
1875 }
1876 }
1877
1878 /* release argument expressions */
1879 for( i = 0; i < nargs; ++i )
1880 {
1881 assert(args[i] != NULL);
1882 SCIP_CALL( SCIPreleaseExpr(scip, &args[i]) );
1883 }
1884
1885 SCIPfreeBufferArray(scip, &args);
1886
1887 return SCIP_OKAY;
1888 }
1889
1890 if( strcmp(exprname, "min") == 0 || strcmp(exprname, "max") == 0 )
1891 {
1892 SCIPerrorMessage("min or max expressions are not supported\n");
1893 *doingfine = FALSE;
1894 return SCIP_OKAY;
1895 }
1896
1897 if( strcmp(exprname, "quadratic") == 0 )
1898 {
1899 const char* attrval;
1900 const XML_NODE* qterm;
1901 SCIP_VAR** quadvars1;
1902 SCIP_VAR** quadvars2;
1903 SCIP_Real* quadcoefs;
1904 int nquadelems;
1905 int quadelemssize;
1906 int idx;
1907
1908 quadelemssize = 5;
1909 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, quadelemssize) );
1910 SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, quadelemssize) );
1911 SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, quadelemssize) );
1912 nquadelems = 0;
1913
1914 /* read quadratic terms */
1915 for( qterm = xmlFirstChild(node); qterm != NULL; qterm = xmlNextSibl(qterm), ++nquadelems )
1916 {
1917 /* check for qpTerm node */
1918 if( strcmp(xmlGetName(qterm), "qpTerm") != 0 )
1919 {
1920 SCIPerrorMessage("Unexpected <%s> node under <quadratic> node in nonlinear expression, expected <qpTerm>.\n", xmlGetName(qterm));
1921 *doingfine = FALSE;
1922 return SCIP_OKAY;
1923 }
1924
1925 if( nquadelems >= quadelemssize )
1926 {
1927 quadelemssize = SCIPcalcMemGrowSize(scip, nquadelems + 1);
1928 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, quadelemssize) );
1929 SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, quadelemssize) );
1930 SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, quadelemssize) );
1931 }
1932 assert(quadelemssize > nquadelems);
1933
1934 /* get index of first variable */
1935 attrval = xmlGetAttrval(qterm, "idxOne");
1936 if( attrval == NULL )
1937 {
1938 SCIPerrorMessage("Missing \"idxOne\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1939 *doingfine = FALSE;
1940 return SCIP_OKAY;
1941 }
1942
1943 idx = (int)strtol(attrval, (char**)&attrval, 10);
1944 if( *attrval != '\0' || idx < 0 || idx >= nvars )
1945 {
1946 SCIPerrorMessage("Invalid value '%s' for \"idxOne\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxOne"), nquadelems);
1947 *doingfine = FALSE;
1948 return SCIP_OKAY;
1949 }
1950 quadvars1[nquadelems] = vars[idx];
1951
1952 /* get index of second variable */
1953 attrval = xmlGetAttrval(qterm, "idxTwo");
1954 if( attrval == NULL )
1955 {
1956 SCIPerrorMessage("Missing \"idxTwo\" attribute in %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", nquadelems);
1957 *doingfine = FALSE;
1958 return SCIP_OKAY;
1959 }
1960
1961 idx = (int)strtol(attrval, (char**)&attrval, 10);
1962 if( *attrval != '\0' || idx < 0 || idx >= nvars )
1963 {
1964 SCIPerrorMessage("Invalid value '%s' for \"idxTwo\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "idxTwo"), nquadelems);
1965 *doingfine = FALSE;
1966 return SCIP_OKAY;
1967 }
1968 quadvars2[nquadelems] = vars[idx];
1969
1970 /* get coefficient */
1971 attrval = xmlGetAttrval(qterm, "coef");
1972 if( attrval != NULL )
1973 {
1974 quadcoefs[nquadelems] = strtod(attrval, (char**)&attrval);
1975 if( *attrval != '\0' || !SCIPisFinite(quadcoefs[nquadelems]) ) /*lint !e777*/
1976 {
1977 SCIPerrorMessage("Invalid value '%s' for \"coef\" attribute of %d'th <qpTerm> node under <quadratic> node in nonlinear expression.\n", xmlGetAttrval(qterm, "coef"), nquadelems);
1978 *doingfine = FALSE;
1979 return SCIP_OKAY;
1980 }
1981 }
1982 else
1983 {
1984 quadcoefs[nquadelems] = 1.0;
1985 }
1986 }
1987
1988 /* create quadratic expression */
1989 SCIP_CALL( SCIPcreateExprQuadratic(scip, expr, 0, NULL, NULL, nquadelems, quadvars1, quadvars2, quadcoefs, NULL, NULL) );
1990 }
1991
1992 SCIPerrorMessage("Expression operand <%s> in nonlinear expression not supported by SCIP so far.\n", exprname);
1993 *doingfine = FALSE;
1994
1995 return SCIP_OKAY;
1996}
1997
1998
1999/** read nonlinear expressions of constraints and objective */
2000static
2002 SCIP* scip, /**< SCIP data structure */
2003 const XML_NODE* datanode, /**< XML root node for instance data */
2004 SCIP_VAR** vars, /**< variables in order of OSiL indices */
2005 int nvars, /**< number of variables */
2006 int nconss, /**< number of constraints */
2007 SCIP_EXPR** exprs, /**< array to store for each constraint a nonlinear expression */
2008 SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2009 )
2010{
2011 const XML_NODE* nlexprs;
2012 const XML_NODE* nlexpr;
2013 const char* attrval;
2014 int nnlexprs;
2015 int count;
2016 int considx;
2017
2018 assert(scip != NULL);
2019 assert(datanode != NULL);
2020 assert(vars != NULL || nvars == 0);
2021 assert(exprs != NULL);
2022 assert(doingfine != NULL);
2023
2024 nlexprs = xmlFindNodeMaxdepth(datanode, "nonlinearExpressions", 0, 1);
2025
2026 if( nlexprs == NULL )
2027 return SCIP_OKAY;
2028
2029 /* get number of nonlinear expressions */
2030 attrval = xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions");
2031 if( attrval == NULL )
2032 {
2033 SCIPerrorMessage("Attribute \"numberOfNonlinearExpressions\" in <nonlinearExpressions> node not found.\n");
2034 *doingfine = FALSE;
2035 return SCIP_OKAY;
2036 }
2037
2038 nnlexprs = (int)strtol(attrval, (char**)&attrval, 10);
2039 if( *attrval != '\0' || nnlexprs < 0 )
2040 {
2041 SCIPerrorMessage("Invalid value '%s' for \"numberOfNonlinearExpressions\" attribute in <nonlinearExpressions>.\n", xmlGetAttrval(nlexprs, "numberOfNonlinearExpressions"));
2042 *doingfine = FALSE;
2043 return SCIP_OKAY;
2044 }
2045 assert(nnlexprs >= 0);
2046
2047 /* read nonlinear expressions and store in constraints */
2048 count = 0;
2049 for( nlexpr = xmlFirstChild(nlexprs); nlexpr != NULL; nlexpr = xmlNextSibl(nlexpr), ++count )
2050 {
2051 if( strcmp(xmlGetName(nlexpr), "nl") != 0 )
2052 {
2053 SCIPerrorMessage("Expected <nl> node under <nonlinearExpressions> node, but got '%s'.\n", xmlGetName(nlexpr));
2054 *doingfine = FALSE;
2055 break;
2056 }
2057 if( count >= nnlexprs )
2058 {
2059 SCIPerrorMessage("Too many nonlinear expressions under <nonlinearExpressions> node, expected %d many, but got at least %d.\n", nnlexprs, count + 1);
2060 *doingfine = FALSE;
2061 break;
2062 }
2063
2064 /* treat empty expression as 0.0 and continue */
2065 if( xmlFirstChild(nlexprs) == NULL )
2066 continue;
2067
2068 /* get constraint index, or -1 for objective */
2069 attrval = xmlGetAttrval(nlexpr, "idx");
2070 if( attrval == NULL )
2071 {
2072 SCIPerrorMessage("Missing \"idx\" attribute in %d'th <nl> node under <nonlinearExpressions> node.\n", count);
2073 *doingfine = FALSE;
2074 break;
2075 }
2076
2077 considx = (int)strtol(attrval, (char**)&attrval, 10);
2078 if( *attrval != '\0' || considx < -1 || considx >= nconss )
2079 {
2080 SCIPerrorMessage("Invalid value '%s' in \"idx\" attribute of %d'th <nl> node under <nonlinearExpressions> node.\n", xmlGetAttrval(nlexpr, "idx"), count);
2081 *doingfine = FALSE;
2082 break;
2083 }
2084
2085 /* turn OSiL expression into SCIP expression and assign indices to variables; store a nonlinear objective at position nconss */
2086 SCIP_CALL( readExpression(scip, considx == -1 ? &exprs[nconss] : &exprs[considx],
2087 xmlFirstChild(nlexpr), vars, nvars, doingfine) );
2088 if( !*doingfine )
2089 return SCIP_OKAY;
2090 }
2091
2092 return SCIP_OKAY;
2093}
2094
2095
2096/** read sos1 and sos2 constraints
2097 *
2098 * sos constraints are expected to be given as a node of <instanceData> in the following way:
2099 * @code
2100 * <specialOrderedSets numberOfSpecialOrderedSets="1">
2101 * <sos numberOfVar="2" order="2">
2102 * <var idx="1"></var>
2103 * <var idx="2"></var>
2104 * </sos>
2105 * </specialOrderedSets>
2106 * @endcode
2107 * Weights are determined by the order in which the variables are given
2108 *
2109 */
2110static
2112 SCIP* scip, /**< SCIP data structure */
2113 const XML_NODE* datanode, /**< XML root node for instance data */
2114 SCIP_VAR** vars, /**< variables in order of OSiL indices */
2115 int nvars, /**< number of variables */
2116 SCIP_Bool initialconss, /**< should model constraints be marked as initial? */
2117 SCIP_Bool dynamicconss, /**< should model constraints be subject to aging? */
2118 SCIP_Bool dynamicrows, /**< should rows be added and removed dynamically to the LP? */
2119 SCIP_Bool* doingfine /**< buffer to indicate whether no errors occurred */
2120 )
2121{
2122 const XML_NODE* soscons;
2123 const XML_NODE* sosvar;
2124 const char* attrval;
2125 int nsoscons;
2126 int nsosvars;
2127 int sosorder;
2128 int type;
2129 int count;
2130 int varcount;
2131 int idx;
2132 SCIP_Bool initial;
2133 SCIP_Bool separate;
2134 SCIP_Bool enforce;
2135 SCIP_Bool check;
2136 SCIP_Bool propagate;
2137 SCIP_Bool local;
2138 SCIP_Bool dynamic;
2139 SCIP_Bool removable;
2140 char name[SCIP_MAXSTRLEN];
2141
2142 /* standard settings for SOS constraints: */
2143 initial = initialconss;
2144 separate = TRUE;
2145 enforce = TRUE;
2146 check = TRUE;
2147 propagate = TRUE;
2148 local = FALSE;
2149 dynamic = dynamicconss;
2150 removable = dynamicrows;
2151
2152 soscons= xmlFindNodeMaxdepth(datanode, "specialOrderedSets", 0, 1);
2153
2154 if( soscons== NULL )
2155 return SCIP_OKAY;
2156
2157 /* get number of sos constraints */
2158 attrval = xmlGetAttrval(soscons, "numberOfSOS");
2159 if( attrval == NULL )
2160 {
2161 SCIPerrorMessage("Attribute \"numberOfSOS in <specialOrderedSets> node not found.\n");
2162 *doingfine = FALSE;
2163 return SCIP_OKAY;
2164 }
2165
2166 nsoscons = (int)strtol(attrval, (char**)&attrval, 10);
2167 if( *attrval != '\0' || nsoscons < 0 )
2168 {
2169 SCIPerrorMessage("Invalid value '%s' for \"numberOfSOS\" attribute in <specialOrderedSets>.\n", xmlGetAttrval(soscons, "numberOfSOS"));
2170 *doingfine = FALSE;
2171 return SCIP_OKAY;
2172 }
2173 assert(nsoscons >= 0);
2174
2175 /* read sos constraints and create corresponding constraint */
2176 count = 0;
2177 for( soscons = xmlFirstChild(soscons); soscons != NULL; soscons = xmlNextSibl(soscons), ++count )
2178 {
2179 SCIP_CONS* cons;
2180
2181 /* Make sure we get a sos node and not more then announced*/
2182 if( strcmp(xmlGetName(soscons), "sos") != 0 )
2183 {
2184 SCIPerrorMessage("Expected <sos> node under <specialOrderedSet> node, but got '%s'.\n", xmlGetName(soscons));
2185 *doingfine = FALSE;
2186 break;
2187 }
2188
2189 if( count >= nsoscons)
2190 {
2191 SCIPerrorMessage("Too many sos under <specialOrderedSets> node, expected %d many, but got at least %d.\n", nsoscons, count + 1);
2192 *doingfine = FALSE;
2193 break;
2194 }
2195
2196 /* get number of variables in this sos constraint */
2197 attrval = xmlGetAttrval(soscons, "numberOfVar");
2198 if( attrval == NULL )
2199 {
2200 SCIPerrorMessage("Attribute \"numberOfVar in <sos> node not found.\n");
2201 *doingfine = FALSE;
2202 return SCIP_OKAY;
2203 }
2204
2205 nsosvars = (int)strtol(attrval, (char**)&attrval, 10);
2206 if( *attrval != '\0' || nsosvars < 0 )
2207 {
2208 SCIPerrorMessage("Invalid value '%s' for \"numberOfVar\" attribute in <sos>.\n", xmlGetAttrval(soscons, "numberOfVar"));
2209 *doingfine = FALSE;
2210 return SCIP_OKAY;
2211 }
2212 assert(nsosvars >= 0);
2213
2214 /* get order of this sos constraint */
2215 attrval = xmlGetAttrval(soscons, "type");
2216 if( attrval == NULL )
2217 {
2218 SCIPerrorMessage("Attribute \"order\" in <sos> node not found.\n");
2219 *doingfine = FALSE;
2220 return SCIP_OKAY;
2221 }
2222
2223 sosorder = (int)strtol(attrval, (char**)&attrval, 10);
2224 if( *attrval != '\0' || sosorder < 0 || sosorder > 2 )
2225 {
2226 SCIPerrorMessage("Invalid/unsupported value '%s' for \"order\" attribute in <sos>.\n", xmlGetAttrval(soscons, "order"));
2227 *doingfine = FALSE;
2228 return SCIP_OKAY;
2229 }
2230 assert(sosorder == 1 || sosorder == 2);
2231 type = sosorder;
2232
2233 /* set artificial name for sos constraint*/
2234 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "SOS%d_%d", type, count);
2235
2236 /* Create sos constraint */
2237 switch( type )
2238 {
2239 case 1:
2240 SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2241 local, dynamic, removable, FALSE) );
2242 break;
2243 case 2:
2244 SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
2245 local, dynamic, removable, FALSE) );
2246 break;
2247 default:
2248 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2249 SCIPABORT();
2250 return SCIP_INVALIDDATA; /*lint !e527*/
2251 }
2252
2253 varcount = 0;
2254 for( sosvar = xmlFirstChild(soscons); sosvar!= NULL; sosvar = xmlNextSibl(sosvar), ++varcount )
2255 {
2256 /* get variable id*/
2257 attrval = xmlGetAttrval(sosvar, "idx");
2258 if( attrval == NULL )
2259 {
2260 SCIPerrorMessage("Attribute \"idx\" in <var> node below <specialOrderedSets> node not found.\n");
2261 *doingfine = FALSE;
2262 return SCIP_OKAY;
2263 }
2264
2265 idx = (int)strtol(attrval, (char**)&attrval, 10);
2266 if( *attrval != '\0' || idx < 0 || idx > nvars - 1 )
2267 {
2268 SCIPerrorMessage("Invalid value '%s' for \"idx\" attribute in <var>.\n", xmlGetAttrval(sosvar, "idx"));
2269 *doingfine = FALSE;
2270 return SCIP_OKAY;
2271 }
2272 assert(idx >= 0);
2273
2274 /* we now know that we have a variable/weight pair -> add variable*/
2275 switch( type )
2276 {
2277 case 1:
2278 SCIP_CALL( SCIPaddVarSOS1(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2279 break;
2280 case 2:
2281 SCIP_CALL( SCIPaddVarSOS2(scip, cons, vars[idx], (SCIP_Real) (nsosvars - varcount)) );
2282 break;
2283 /* coverity[dead_error_begin] */
2284 default:
2285 SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
2286 SCIPABORT();
2287 return SCIP_INVALIDDATA; /*lint !e527*/
2288 }
2289 } /* Close loop over variables in sos constraint */
2290
2291 /* add the SOS constraint */
2292 SCIP_CALL( SCIPaddCons(scip, cons) );
2293 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2294 }
2295
2296 return SCIP_OKAY;
2297}
2298
2299 /*
2300 * Callback methods of reader
2301 */
2302
2303
2304/** copy method for reader plugins (called when SCIP copies plugins) */
2305static
2307{ /*lint --e{715}*/
2308 assert(scip != NULL);
2309
2311
2312 return SCIP_OKAY;
2313}
2314
2315/** problem reading method of reader */
2316static
2318{ /*lint --e{715}*/
2319 const XML_NODE* header;
2320 const XML_NODE* data;
2321 XML_NODE* start;
2322 SCIP_VAR** vars;
2323 const char* name;
2324 SCIP_RETCODE retcode;
2325 SCIP_Bool doingfine;
2326 SCIP_Bool initialconss;
2327 SCIP_Bool dynamicconss;
2328 SCIP_Bool dynamiccols;
2329 SCIP_Bool dynamicrows;
2330 int nconss;
2331 int nvars;
2332 int c;
2333 int i;
2334
2335 /* linear parts */
2336 SCIP_VAR*** linvars = NULL;
2337 SCIP_Real** lincoefs = NULL;
2338 int* nlinvars = NULL;
2339
2340 /* quadratic parts */
2341 SCIP_VAR*** quadvars1 = NULL;
2342 SCIP_VAR*** quadvars2 = NULL;
2343 SCIP_Real** quadcoefs = NULL;
2344 int* nquadterms = NULL;
2345 int* termssize = NULL;
2346
2347 /* nonlinear parts */
2348 SCIP_EXPR** nlexprs = NULL;
2349
2350 assert(scip != NULL);
2351 assert(reader != NULL);
2352 assert(result != NULL);
2353 assert(filename != NULL);
2354
2355 *result = SCIP_DIDNOTRUN;
2356 retcode = SCIP_READERROR;
2357 doingfine = TRUE;
2358 vars = NULL;
2359 nvars = 0;
2360 nconss = -1;
2361
2362 /* read OSiL xml file */
2363 start = xmlProcess(filename);
2364
2365 if( start == NULL )
2366 {
2367 SCIPerrorMessage("Some error occurred when parsing the OSiL XML file '%s'.\n", filename);
2368 goto CLEANUP;
2369 }
2370
2371 SCIPdebug( xmlShowNode(start) );
2372
2373 /* parse header to get problem name */
2374 name = filename;
2375 header = xmlFindNodeMaxdepth(start, "instanceHeader", 0, 2);
2376 if( header != NULL )
2377 {
2378 const XML_NODE* namenode;
2379
2380 namenode = xmlFindNodeMaxdepth(header, "name", 0, 2);
2381
2382 if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2383 name = xmlGetData(xmlFirstChild(namenode));
2384 else
2385 {
2386 namenode = xmlFindNodeMaxdepth(header, "description", 0, 2);
2387
2388 if( namenode != NULL && xmlFirstChild(namenode) != NULL )
2389 name = xmlGetData(xmlFirstChild(namenode));
2390 }
2391 }
2392
2393 /* create SCIP problem */
2395
2396 /* process instance data */
2397 data = xmlFindNodeMaxdepth(start, "instanceData", 0, 2);
2398 if( data == NULL )
2399 {
2400 SCIPerrorMessage("Node <instanceData> not found.\n");
2401 goto CLEANUP;
2402 }
2403
2404 SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
2405 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
2406 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
2407 SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
2408
2409 /* read variables */
2410 SCIP_CALL_TERMINATE( retcode, readVariables(scip, data, &vars, &nvars, initialconss, dynamicconss, dynamiccols, dynamicrows, &doingfine), CLEANUP );
2411 if( !doingfine )
2412 goto CLEANUP;
2413 assert(vars != NULL || nvars == 0);
2414
2415 /* read objective sense, coefficient, and constant */
2416 SCIP_CALL_TERMINATE( retcode, readObjective(scip, data, vars, nvars, dynamiccols, &doingfine), CLEANUP );
2417 if( !doingfine )
2418 goto CLEANUP;
2419
2420 /* read total number of constraints */
2421 SCIP_CALL_TERMINATE( retcode, readNConstraints(scip, data, &nconss, &doingfine), CLEANUP );
2422 if( !doingfine )
2423 goto CLEANUP;
2424
2425 /* allocate memory to store constraint information (use block memory, since the size have to be reallocaed) */
2426 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &linvars, nconss + 1) );
2427 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &lincoefs, nconss + 1) );
2428 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nlinvars, nconss + 1) );
2429 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadvars1, nconss + 1) );
2430 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadvars2, nconss + 1) );
2431 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &quadcoefs, nconss + 1) );
2432 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nquadterms, nconss + 1) );
2433 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &nlexprs, nconss + 1) );
2434 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &termssize, nconss + 1) );
2435
2436 /* read linear coefficients matrix */
2437 SCIP_CALL_TERMINATE( retcode, readLinearCoefs(scip, data, vars, nvars, nconss, linvars, lincoefs, nlinvars, &doingfine), CLEANUP );
2438 if( !doingfine )
2439 goto CLEANUP;
2440
2441 /* read quadratic coefficients */
2442 SCIP_CALL_TERMINATE( retcode, readQuadraticCoefs(scip, data, vars, nvars, nconss, quadvars1, quadvars2, quadcoefs,
2443 nquadterms, termssize, &doingfine), CLEANUP );
2444 if( !doingfine )
2445 goto CLEANUP;
2446
2447 /* read nonlinear expressions */
2448 SCIP_CALL_TERMINATE( retcode, readNonlinearExprs(scip, data, vars, nvars, nconss, nlexprs, &doingfine), CLEANUP );
2449 if( !doingfine )
2450 goto CLEANUP;
2451
2452 /* read constraint data; generate constraints */
2453 SCIP_CALL_TERMINATE( retcode, readConstraints(scip, data, nconss, linvars, lincoefs, nlinvars,
2454 quadvars1, quadvars2, quadcoefs, nquadterms, nlexprs, initialconss, dynamicconss, dynamicrows, &doingfine),
2455 CLEANUP );
2456 if( !doingfine )
2457 goto CLEANUP;
2458
2459 /* add nonlinear objective constraint */
2460 if( nlinvars[nconss] > 0 || nquadterms[nconss] > 0 || nlexprs[nconss] != NULL )
2461 {
2462 SCIP_CALL( createConstraint(scip, linvars[nconss], lincoefs[nconss], nlinvars[nconss],
2463 quadvars1[nconss], quadvars2[nconss], quadcoefs[nconss], nquadterms[nconss], nlexprs[nconss],
2466 "objcons", TRUE, TRUE, FALSE, FALSE) );
2467 }
2468
2469 /* read sos2 constraints and add to problem */
2470 SCIP_CALL_TERMINATE( retcode, readSOScons(scip, data, vars, nvars, initialconss, dynamicconss, dynamicrows, &doingfine), CLEANUP );
2471 if( !doingfine )
2472 goto CLEANUP;
2473
2474 *result = SCIP_SUCCESS;
2475 retcode = SCIP_OKAY;
2476
2477 CLEANUP:
2478 /* free xml data */
2479 if( start != NULL )
2480 xmlFreeNode(start);
2481
2482 /* free memory for constraint information (position nconss belongs to the nonlinear objective function) */
2483 assert(termssize != NULL);
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 SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs[c], termssize[c]);
2494 SCIPfreeBlockMemoryArrayNull(scip, &quadvars2[c], termssize[c]);
2495 SCIPfreeBlockMemoryArrayNull(scip, &quadvars1[c], termssize[c]);
2496
2497 /* free linear parts */
2498 SCIPfreeBlockMemoryArrayNull(scip, &lincoefs[c], nlinvars[c]);
2499 SCIPfreeBlockMemoryArrayNull(scip, &linvars[c], nlinvars[c]);
2500 }
2501 SCIPfreeBlockMemoryArrayNull(scip, &termssize, nconss + 1);
2502 SCIPfreeBlockMemoryArrayNull(scip, &nlexprs, nconss + 1);
2503 SCIPfreeBlockMemoryArrayNull(scip, &nquadterms, nconss + 1);
2504 SCIPfreeBlockMemoryArrayNull(scip, &quadcoefs, nconss + 1);
2505 SCIPfreeBlockMemoryArrayNull(scip, &quadvars2, nconss + 1);
2506 SCIPfreeBlockMemoryArrayNull(scip, &quadvars1, nconss + 1);
2507 SCIPfreeBlockMemoryArrayNull(scip, &nlinvars, nconss + 1);
2508 SCIPfreeBlockMemoryArrayNull(scip, &lincoefs, nconss + 1);
2509 SCIPfreeBlockMemoryArrayNull(scip, &linvars, nconss + 1);
2510
2511 /* free variables */
2512 for( i = 0; i < nvars; ++i )
2513 {
2514 SCIP_CALL( SCIPreleaseVar(scip, &vars[i]) ); /*lint !e613*/
2515 }
2517
2518 /* return read error retcode if something went wrong */
2519 if( !doingfine )
2520 return SCIP_READERROR;
2521
2522 if( retcode == SCIP_PLUGINNOTFOUND )
2523 retcode = SCIP_READERROR;
2524
2525 SCIP_CALL( retcode );
2526
2527 return SCIP_OKAY;
2528}
2529
2530/*
2531 * reader specific interface methods
2532 */
2533
2534/** includes the osil file reader in SCIP */
2536 SCIP* scip /**< SCIP data structure */
2537 )
2538{
2539 SCIP_READER* reader;
2540
2541 /* include osil reader */
2543
2544 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOsil) );
2545 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOsil) );
2546
2547 return SCIP_OKAY;
2548}
constraint handler for bound disjunction constraints
Constraint handler for linear constraints in their most general form, .
constraint handler for nonlinear constraints specified by algebraic expressions
constraint handler for SOS type 1 constraints
constraint handler for SOS type 2 constraints
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_INVALID
Definition: def.h:193
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:346
#define SCIP_CALL(x)
Definition: def.h:374
absolute expression handler
SCIP_RETCODE SCIPcreateExprErf(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_erf.c:257
handler for Gaussian error function expressions
exponential expression handler
logarithm expression handler
power and signed power expression handlers
product expression handler
sum expression handler
handler for sin expressions
constant value expression handler
variable expression handler
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10716
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_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10579
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)
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:2578
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2677
SCIP_RETCODE SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_var.c:390
SCIP_RETCODE SCIPcreateExprProduct(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real coefficient, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
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 SCIPcreateExprCos(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_trig.c:1450
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 SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
Definition: expr_sum.c:1151
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:3217
SCIP_RETCODE SCIPcreateExprLog(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_log.c:630
SCIP_RETCODE SCIPcreateExprExp(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_exp.c:510
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1114
SCIP_RETCODE SCIPcreateExprValue(SCIP *scip, SCIP_EXPR **expr, SCIP_Real value, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_value.c:270
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:3193
SCIP_RETCODE SCIPincludeReaderOsil(SCIP *scip)
Definition: reader_osil.c:2535
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1242
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1225
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
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
#define SCIPisFinite(x)
Definition: pub_misc.h:1933
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_RETCODE SCIPcreateExprQuadratic(SCIP *scip, SCIP_EXPR **expr, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1033
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1453
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1442
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1417
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:294
void SCIPcaptureExpr(SCIP_EXPR *expr)
Definition: scip_expr.c:1409
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
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 SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
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
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4513
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
static volatile int nterms
Definition: interrupt.c:47
memory allocation routines
#define M_PI
Definition: pricer_rpa.c:97
public methods for managing constraints
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebug(x)
Definition: pub_message.h:93
public data structures and miscellaneous methods
public methods for NLP management
public methods for problem variables
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
static SCIP_RETCODE readExpression(SCIP *scip, SCIP_EXPR **expr, const XML_NODE *node, SCIP_VAR **vars, int nvars, SCIP_Bool *doingfine)
Definition: reader_osil.c:1410
static SCIP_DECL_READERREAD(readerReadOsil)
Definition: reader_osil.c:2317
static SCIP_RETCODE readQuadraticCoefs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, int nconss, SCIP_VAR ***quadvars1, SCIP_VAR ***quadvars2, SCIP_Real **quadcoefs, int *nquadterms, int *termssize, SCIP_Bool *doingfine)
Definition: reader_osil.c:1228
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 READER_DESC
Definition: reader_osil.c:70
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
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
#define READER_EXTENSION
Definition: reader_osil.c:71
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
static SCIP_RETCODE readNonlinearExprs(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, int nconss, SCIP_EXPR **exprs, SCIP_Bool *doingfine)
Definition: reader_osil.c:2001
#define READER_NAME
Definition: reader_osil.c:69
static SCIP_RETCODE readSOScons(SCIP *scip, const XML_NODE *datanode, SCIP_VAR **vars, int nvars, SCIP_Bool initialconss, SCIP_Bool dynamicconss, SCIP_Bool dynamicrows, SCIP_Bool *doingfine)
Definition: reader_osil.c:2111
static void readMultIncr(const XML_NODE *node, int *mult, int *incrint, SCIP_Real *incrreal, SCIP_Bool *doingfine)
Definition: reader_osil.c:781
static SCIP_DECL_READERCOPY(readerCopyOsil)
Definition: reader_osil.c:2306
static SCIP_RETCODE readNConstraints(SCIP *scip, const XML_NODE *datanode, int *nconss, SCIP_Bool *doingfine)
Definition: reader_osil.c:436
OS instance language (OSiL) format file reader.
public methods for constraint handler plugins and constraints
public methods for memory management
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for reader plugins
public methods for SCIP variables
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
@ SCIP_OBJSENSE_MAXIMIZE
Definition: type_prob.h:47
@ SCIP_OBJSENSE_MINIMIZE
Definition: type_prob.h:48
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_SUCCESS
Definition: type_result.h:58
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_INTEGER
Definition: type_var.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
declarations for XML parsing
const XML_NODE * xmlFirstChild(const XML_NODE *node)
Definition: xmlparse.c:1469
const XML_NODE * xmlFindNodeMaxdepth(const XML_NODE *node, const char *name, int depth, int maxdepth)
Definition: xmlparse.c:1419
const char * xmlGetName(const XML_NODE *node)
Definition: xmlparse.c:1489
const char * xmlGetAttrval(const XML_NODE *node, const char *name)
Definition: xmlparse.c:1337
struct XML_NODE_struct XML_NODE
Definition: xml.h:50
void xmlShowNode(const XML_NODE *root)
Definition: xmlparse.c:1309
const XML_NODE * xmlNextSibl(const XML_NODE *node)
Definition: xmlparse.c:1449
XML_NODE * xmlProcess(const char *filename)
Definition: xmlparse.c:1085
const char * xmlGetData(const XML_NODE *node)
Definition: xmlparse.c:1509
void xmlFreeNode(XML_NODE *node)
Definition: xmlparse.c:1275