1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * Main author: Matthieu Herrmann, Monash University, Melbourne, Australia. 2019 9 */ 10 11 #pragma once 12 13 #include <minizinc/ast.hh> 14 #include <minizinc/astvec.hh> 15 #include <minizinc/solvers/nl/nl_components.hh> 16 17 #include <map> 18 #include <ostream> 19 #include <set> 20 #include <string> 21 22 // This files declare data-structure describing the various components of a nl files. 23 // A nl files is composed of two main parts: a header and a list of segments. 24 // The header contains statistics and meta information about the model. 25 // The segments allow to describe the model, i.e. the variables, the constraints and objectives. 26 // The order of the segments and, when relevant, the order of their content 27 // (e.g. a segment declaring a list of variables) matters. 28 29 /** NL File. 30 * Good to know: 31 * * We use string as variable unique identifier. 32 * Given a MZN variable declaration (can be obtain from a MZN variable), the 'getVarName' 33 * helper produces the string. 34 * * In our case, we only have one 'solve' per file. 35 * * NL file use double everywhere. Hence, even with dealing with integer variable, we store 36 * the information with double. 37 * 38 */ 39 40 namespace MiniZinc { 41 42 // --- --- --- NL Files 43 class NLFile { 44 public: 45 /* *** *** *** Helpers *** *** *** */ 46 47 /** Create a string representing the name (and unique identifier) from an identifier. */ 48 static std::string getVarName(const Id* id); 49 50 /** Create a string representing the name (and unique identifier) of a variable from a variable 51 * declaration. */ 52 static std::string getVarName(const VarDecl& vd); 53 54 /** Create a string representing the name (and unique identifier) of a constraint from a specific 55 * call expression. */ 56 static std::string getConstraintName(const Call& c); 57 58 /** Extract an array literal from an expression. */ 59 static const ArrayLit& getArrayLit(const Expression* e); 60 61 /** Create a vector of double from a vector containing Expression being integer literal IntLit. */ 62 static std::vector<double> fromVecInt(const ArrayLit& v_int); 63 64 /** Create a vector of double from a vector containing Expression being float literal FloatLit. */ 65 static std::vector<double> fromVecFloat(const ArrayLit& v_fp); 66 67 /** Create a vector of variable names from a vector containing Expression being identifier Id. */ 68 static std::vector<std::string> fromVecId(const ArrayLit& v_id); 69 70 /* *** *** *** Phase 1: collecting data from MZN *** *** *** */ 71 72 // Variables collection, identified by name 73 // Needs ordering, see phase 2 74 std::map<std::string, NLVar> variables = {}; 75 76 // Algebraic constraints collection, identified by name 77 // Needs ordering, see phase 2 78 std::map<std::string, NLAlgCons> constraints = {}; 79 80 // Logical constraints do not need ordering: 81 std::vector<NLLogicalCons> logicalConstraints = {}; 82 83 // Objective field. Only one, so we do not need ordering. 84 NLObjective objective = {}; 85 86 // Output arrays 87 std::vector<NLArray> outputArrays = {}; 88 89 /** Add a solve goal in the NL File. In our case, we can only have one and only one solve goal. */ 90 void addSolve(SolveI::SolveType st, const Expression* e); 91 92 /** Add a variable declaration in the NL File. 93 * This function pre-analyse the declaration VarDecl, then delegate to addVarDeclInteger or 94 * addVarDeclFloat. Analyse a variable declaration 'vd' of type 'ti' with an 'rhs'. The variable 95 * declaration gives us access to the variable name while the type allows us to discriminate 96 * between integer, floating point value and arrays. Array are ignored (not declared): if we 97 * encouter an array in a constraint, we can find the array through the variable (ot it is a 98 * litteral). Notes: - We use -Glinear, so we do not have boolean. 99 * - This will change TODO keep checking comment and code consistency. 100 * 101 * RHS is for arrays: it contains the definition of the array. 102 * 103 * The type also gives us the domain, which can be: 104 * NULL: no restriction over the variable 105 * SetLit: Gives us a lower and upper bound 106 * If a variable is bounded only on one side, then the domain is NULL and the bound is expressed 107 * through a constraint. 108 */ 109 void addVarDecl(const VarDecl& vd, const TypeInst& ti, const Expression& rhs); 110 111 /** Add an integer variable declaration to the NL File. */ 112 void addVarDeclInteger(const std::string& name, const IntSetVal* isv, bool toReport); 113 114 /** Add a floating point variable declaration to the NL File. */ 115 void addVarDeclFloat(const std::string& name, const FloatSetVal* fsv, bool toReport); 116 117 // --- --- --- Constraints analysis 118 119 /** Add a constraint to the NL File. 120 * This method is a dispatcher for all the other constraints methods below. */ 121 void analyseConstraint(const Call& c); 122 123 // --- --- --- Helpers 124 125 /** Create a token from an expression representing a variable. 126 * ONLY USE FOR CONSTRAINT, NOT OBJECTIVES! (UPDATE VARIABLES FLAG FOR CONSTRAINTS) 127 */ 128 static NLToken getTokenFromVar(const Expression* e); 129 130 /** Create a token from an expression representing either a variable or an integer numeric value. 131 * ONLY USE FOR CONSTRAINT, NOT OBJECTIVES! 132 */ 133 static NLToken getTokenFromVarOrInt(const Expression* e); 134 135 /** Create a token from an expression representing either a variable or a floating point numeric 136 * value. ONLY USE FOR CONSTRAINT, NOT OBJECTIVES! 137 */ 138 static NLToken getTokenFromVarOrFloat(const Expression* e); 139 140 /** Update an expression graph (only by appending token) with a linear combination 141 * of coefficients and variables. 142 * ONLY USE FOR CONSTRAINTS, NOT OBJECTIVES! 143 */ 144 static void makeSigmaMult(std::vector<NLToken>& expressionGraph, 145 const std::vector<double>& coeffs, 146 const std::vector<std::string>& vars); 147 148 // --- --- --- Linear Builders 149 // Use an array of literals 'coeffs' := c.arg(0), an array of variables 'vars' := c.arg(1), 150 // and a variable or literal 'value' := c.arg(2). 151 // [coeffs] and value are fixed (no variable allowed). 152 // The call is needed to create the name. However, the extraction of the coefficients and the 153 // value is left to the calling function as this could be use with both integer and floating point 154 // (we only have floating point in NL) 155 156 /** Create a linear constraint [coeffs] *+ [vars] = value. */ 157 void linconsEq(const Call& c, const std::vector<double>& coeffs, 158 const std::vector<std::string>& vars, const NLToken& value); 159 160 /** Create a linear constraint [coeffs] *+ [vars] <= value. */ 161 void linconsLe(const Call& c, const std::vector<double>& coeffs, 162 const std::vector<std::string>& vars, const NLToken& value); 163 164 /** Create a linear logical constraint [coeffs] *+ [vars] PREDICATE value. 165 * Use a generic comparison operator. 166 * Warnings: - Creates a logical constraint 167 * - Only use for conmparisons that cannot be expressed with '=' xor '<='. 168 */ 169 void linconsPredicate(const Call& c, NLToken::OpCode oc, const std::vector<double>& coeffs, 170 const std::vector<std::string>& vars, const NLToken& value); 171 172 // --- --- --- Non Linear Builders 173 // For predicates, uses 2 variables or literals: x := c.arg(0), y := c.arg(1) 174 // x PREDICATE y 175 176 // For unary operations, uses 2 variables or literals: x := c.arg(0), y := c.arg(1) 177 // OPEARTOR x = y 178 179 // For binary operations, uses 3 variables or literals: x := c.arg(0), y := c.arg(1), and z := 180 // c.arg(2). x OPERATOR y = z 181 182 /** Create a non linear constraint x = y 183 * Use the jacobian and the bound on constraint to translate into x - y = 0 184 * Simply update the bound if one is a constant. 185 */ 186 void nlconsEq(const Call& c, const NLToken& x, const NLToken& y); 187 188 /** Create a non linear constraint x <= y 189 * Use the jacobian and the bound on constraint to translate into x - y <= 0 190 * Simply update the bound if one is a constant. 191 */ 192 void nlconsLe(const Call& c, const NLToken& x, const NLToken& y); 193 194 /** Create a non linear constraint with a predicate: x PREDICATE y 195 * Use a generic comparison operator. 196 * Warnings: - Creates a logical constraint 197 * - Only use for conmparisons that cannot be expressed with '=' xor '<='. 198 */ 199 void nlconsPredicate(const Call& c, NLToken::OpCode oc, const NLToken& x, const NLToken& y); 200 201 /** Create a non linear constraint with a binary operator: x OPERATOR y = z */ 202 void nlconsOperatorBinary(const Call& c, NLToken::OpCode oc, const NLToken& x, const NLToken& y, 203 const NLToken& z); 204 205 /** Create a non linear constraint with a binary operator: x OPERATOR y = z. 206 * OPERATOR is now a Multiop, with a count of 2 (so the choice of the method to use depends on 207 * the LN implementation) */ 208 void nlconsOperatorBinary(const Call& c, NLToken::MOpCode moc, const NLToken& x, const NLToken& y, 209 const NLToken& z); 210 211 /** Create a non linear constraint with an unary operator: OPERATOR x = y */ 212 void nlconsOperatorUnary(const Call& c, NLToken::OpCode oc, const NLToken& x, const NLToken& y); 213 214 /** Create a non linear constraint, specialized for log2 unary operator: Log2(x) = y */ 215 void nlconsOperatorUnaryLog2(const Call& c, const NLToken& x, const NLToken& y); 216 217 // --- --- --- Integer Linear Constraints 218 219 /** Linar constraint: [coeffs] *+ [vars] = value */ 220 // NOLINTNEXTLINE(readability-identifier-naming) 221 void consint_lin_eq(const Call& c); 222 223 /** Linar constraint: [coeffs] *+ [vars] =< value */ 224 // NOLINTNEXTLINE(readability-identifier-naming) 225 void consint_lin_le(const Call& c); 226 227 /** Linar constraint: [coeffs] *+ [vars] != value */ 228 // NOLINTNEXTLINE(readability-identifier-naming) 229 void consint_lin_ne(const Call& c); 230 231 // --- --- --- Integer Non Linear Predicate Constraints 232 233 /** Non linear constraint x = y */ 234 // NOLINTNEXTLINE(readability-identifier-naming) 235 void consint_eq(const Call& c); 236 237 /** Non linear constraint x <= y */ 238 // NOLINTNEXTLINE(readability-identifier-naming) 239 void consint_le(const Call& c); 240 241 /** Non linear constraint x != y */ 242 // NOLINTNEXTLINE(readability-identifier-naming) 243 void consint_ne(const Call& c); 244 245 // --- --- --- Integer Non Linear Binary Operator Constraints 246 247 /** Non linear constraint x + y = z */ 248 // NOLINTNEXTLINE(readability-identifier-naming) 249 void consint_plus(const Call& c); 250 251 /** Non linear constraint x * y = z */ 252 // NOLINTNEXTLINE(readability-identifier-naming) 253 void consint_times(const Call& c); 254 255 /** Non linear constraint x / y = z */ 256 // NOLINTNEXTLINE(readability-identifier-naming) 257 void consint_div(const Call& c); 258 259 /** Non linear constraint x mod y = z */ 260 // NOLINTNEXTLINE(readability-identifier-naming) 261 void consint_mod(const Call& c); 262 263 /** Non linear constraint x pow y = z */ 264 // NOLINTNEXTLINE(readability-identifier-naming) 265 void int_pow(const Call& c); 266 267 /** Non linear constraint max(x, y) = z */ 268 // NOLINTNEXTLINE(readability-identifier-naming) 269 void int_max(const Call& c); 270 271 /** Non linear constraint min(x, y) = z */ 272 // NOLINTNEXTLINE(readability-identifier-naming) 273 void int_min(const Call& c); 274 275 // --- --- --- Integer Non Linear Unary Operator Constraints 276 277 // NOLINTNEXTLINE(readability-identifier-naming) 278 void int_abs(const Call& c); 279 280 // --- --- --- Floating Point Linear Constraints 281 282 /** Linar constraint: [coeffs] *+ [vars] = value */ 283 // NOLINTNEXTLINE(readability-identifier-naming) 284 void consfp_lin_eq(const Call& c); 285 286 /** Linar constraint: [coeffs] *+ [vars] = value */ 287 // NOLINTNEXTLINE(readability-identifier-naming) 288 void consfp_lin_le(const Call& c); 289 290 /** Linar constraint: [coeffs] *+ [vars] != value */ 291 // NOLINTNEXTLINE(readability-identifier-naming) 292 void consfp_lin_ne(const Call& c); 293 294 /** Linar constraint: [coeffs] *+ [vars] < value */ 295 // NOLINTNEXTLINE(readability-identifier-naming) 296 void consfp_lin_lt(const Call& c); 297 298 // --- --- --- Floating Point Non Linear Predicate Constraints 299 300 /** Non linear constraint x = y */ 301 // NOLINTNEXTLINE(readability-identifier-naming) 302 void consfp_eq(const Call& c); 303 304 /** Non linear constraint x <= y */ 305 // NOLINTNEXTLINE(readability-identifier-naming) 306 void consfp_le(const Call& c); 307 308 /** Non linear constraint x != y */ 309 // NOLINTNEXTLINE(readability-identifier-naming) 310 void consfp_ne(const Call& c); 311 312 /** Non linear constraint x < y */ 313 // NOLINTNEXTLINE(readability-identifier-naming) 314 void consfp_lt(const Call& c); 315 316 // --- --- --- Floating Point Non Linear Binary Operator Constraints 317 318 /** Non linear constraint x + y = z */ 319 // NOLINTNEXTLINE(readability-identifier-naming) 320 void consfp_plus(const Call& c); 321 322 /** Non linear constraint x - y = z */ 323 // NOLINTNEXTLINE(readability-identifier-naming) 324 void consfp_minus(const Call& c); 325 326 /** Non linear constraint x * y = z */ 327 // NOLINTNEXTLINE(readability-identifier-naming) 328 void consfp_times(const Call& c); 329 330 /** Non linear constraint x / y = z */ 331 // NOLINTNEXTLINE(readability-identifier-naming) 332 void consfp_div(const Call& c); 333 334 /** Non linear constraint x mod y = z */ 335 // NOLINTNEXTLINE(readability-identifier-naming) 336 void consfp_mod(const Call& c); 337 338 /** Non linear constraint x pow y = z */ 339 // NOLINTNEXTLINE(readability-identifier-naming) 340 void float_pow(const Call& c); 341 342 /** Non linear constraint max(x, y) = z */ 343 // NOLINTNEXTLINE(readability-identifier-naming) 344 void float_max(const Call& c); 345 346 /** Non linear constraint min(x, y) = z */ 347 // NOLINTNEXTLINE(readability-identifier-naming) 348 void float_min(const Call& c); 349 350 // --- --- --- Floating Point Non Linear Unary Operator Constraints 351 352 /** Non linear constraint abs x = y */ 353 // NOLINTNEXTLINE(readability-identifier-naming) 354 void float_abs(const Call& c); 355 356 /** Non linear constraint acos x = y */ 357 // NOLINTNEXTLINE(readability-identifier-naming) 358 void float_acos(const Call& c); 359 360 /** Non linear constraint acosh x = y */ 361 // NOLINTNEXTLINE(readability-identifier-naming) 362 void float_acosh(const Call& c); 363 364 /** Non linear constraint asin x = y */ 365 // NOLINTNEXTLINE(readability-identifier-naming) 366 void float_asin(const Call& c); 367 368 /** Non linear constraint asinh x = y */ 369 // NOLINTNEXTLINE(readability-identifier-naming) 370 void float_asinh(const Call& c); 371 372 /** Non linear constraint atan x = y */ 373 // NOLINTNEXTLINE(readability-identifier-naming) 374 void float_atan(const Call& c); 375 376 /** Non linear constraint atanh x = y */ 377 // NOLINTNEXTLINE(readability-identifier-naming) 378 void float_atanh(const Call& c); 379 380 /** Non linear constraint cos x = y */ 381 // NOLINTNEXTLINE(readability-identifier-naming) 382 void float_cos(const Call& c); 383 384 /** Non linear constraint cosh x = y */ 385 // NOLINTNEXTLINE(readability-identifier-naming) 386 void float_cosh(const Call& c); 387 388 /** Non linear constraint exp x = y */ 389 // NOLINTNEXTLINE(readability-identifier-naming) 390 void float_exp(const Call& c); 391 392 /** Non linear constraint ln x = y */ 393 // NOLINTNEXTLINE(readability-identifier-naming) 394 void float_ln(const Call& c); 395 396 /** Non linear constraint log10 x = y */ 397 // NOLINTNEXTLINE(readability-identifier-naming) 398 void float_log10(const Call& c); 399 400 /** Non linear constraint log2 x = y */ 401 // NOLINTNEXTLINE(readability-identifier-naming) 402 void float_log2(const Call& c); 403 404 /** Non linear constraint sqrt x = y */ 405 // NOLINTNEXTLINE(readability-identifier-naming) 406 void float_sqrt(const Call& c); 407 408 /** Non linear constraint sin x = y */ 409 // NOLINTNEXTLINE(readability-identifier-naming) 410 void float_sin(const Call& c); 411 412 /** Non linear constraint sinh x = y */ 413 // NOLINTNEXTLINE(readability-identifier-naming) 414 void float_sinh(const Call& c); 415 416 /** Non linear constraint tan x = y */ 417 // NOLINTNEXTLINE(readability-identifier-naming) 418 void float_tan(const Call& c); 419 420 /** Non linear constraint tanh x = y */ 421 // NOLINTNEXTLINE(readability-identifier-naming) 422 void float_tanh(const Call& c); 423 424 // --- --- --- Other 425 426 /** Integer x to floating point y. Constraint x = y translated into x - y = 0. */ 427 // NOLINTNEXTLINE(readability-identifier-naming) 428 void int2float(const Call& c); 429 430 /* *** *** *** Phase 2: processing *** *** *** */ 431 432 void phase2(); 433 434 // Ordering of variables according to "hooking your solver" 435 /* Meaning of the names (total, then by appearance order in the tables below) 436 n_var total number of variables 437 nlvc number of variables appearing nonlinearly in constraints 438 nlvo number of variables appearing nonlinearly in objectives 439 nwv number of linear arcs 440 niv number of "other" integer variables 441 nbv number of binary variables 442 443 444 Order of variables (yes, the way things are counted is... "special".) 445 Category Count 446 --- --- --- --- | --- --- --- --- --- 447 nonlinear max(nlvc, nlvo) // See below for order on 448 non linear variables linear arcs nwv // Not 449 implemented other linear n_var − (max {nlvc, nlvo} + niv + nbv + nwv) // Linear 450 Continuous binary nbv // Booleans 451 other integer niv // Linear Integer 452 453 454 455 Order of non linear variables (see 'nonlinear' above) 456 Meaning of the names: 457 nlvb number of variables appearing nonlinearly in both constraints and 458 objectives nlvbi number of integer variables appearing nonlinearly in both 459 constraints and objectives nlvc number of variables appearing nonlinearly in 460 constraints nlvci number of integer variables appearing nonlinearly in constraints 461 **only** nlvo number of variables appearing nonlinearly in objectives nlvoi number 462 of integer variables appearing nonlinearly in objectives **only** 463 464 Category Count 465 --- --- --- --- --- --- --- --- --- --- --- --- --- | --- --- --- --- --- 466 Continuous in BOTH an objective AND a constraint | nlvb - nlvbi 467 Integer, in BOTH an objective AND a constraint | nlvbi 468 Continuous, in constraints only | nlvc − (nlvb + nlvci) 469 Integer, in constraints only | nlvci 470 Continous, in objectives only | nlvo − (nlvc + nlvoi) 471 Integer, in objectives only | nlvoi 472 */ 473 474 /** Non Linear Continuous Variables in BOTH an objective and a constraint. */ 475 // NOLINTNEXTLINE(readability-identifier-naming) 476 std::vector<std::string> vname_nlcv_both = {}; 477 478 /** Non Linear Integer Variables in BOTH an objective and a constraint. */ 479 // NOLINTNEXTLINE(readability-identifier-naming) 480 std::vector<std::string> vname_nliv_both = {}; 481 482 /** Non Linear Continuous Variables in CONStraints only. */ 483 // NOLINTNEXTLINE(readability-identifier-naming) 484 std::vector<std::string> vname_nlcv_cons = {}; 485 486 /** Non Linear Integer Variables in CONStraints only. */ 487 // NOLINTNEXTLINE(readability-identifier-naming) 488 std::vector<std::string> vname_nliv_cons = {}; 489 490 /** Non Linear Continuous Variables in OBJectives only. */ 491 // NOLINTNEXTLINE(readability-identifier-naming) 492 std::vector<std::string> vname_nlcv_obj = {}; 493 494 /** Non Linear Integer Variables in OBJectives only. */ 495 // NOLINTNEXTLINE(readability-identifier-naming) 496 std::vector<std::string> vname_nliv_obj = {}; 497 498 /** Linear arcs. (Network not implemented) */ 499 // NOLINTNEXTLINE(readability-identifier-naming) 500 std::vector<std::string> vname_larc_all = {}; 501 502 /** Linear Continuous Variables (ALL of them). */ 503 // NOLINTNEXTLINE(readability-identifier-naming) 504 std::vector<std::string> vname_lcv_all = {}; 505 506 /** Binary Variables (ALL of them). */ 507 // NOLINTNEXTLINE(readability-identifier-naming) 508 std::vector<std::string> vname_bv_all = {}; 509 510 /** Linear Integer Variables (ALL of them). */ 511 // NOLINTNEXTLINE(readability-identifier-naming) 512 std::vector<std::string> vname_liv_all = {}; 513 514 /** Contained all ordered variable names. Mapping variable index -> variable name */ 515 std::vector<std::string> vnames = {}; 516 517 /** Mapping variable name -> variable index */ 518 std::map<std::string, int> variableIndexes = {}; 519 520 // --- --- --- Simple tests 521 522 bool hasIntegerVars() const; 523 524 bool hasContinousVars() const; 525 526 // --- --- --- Variables counts 527 528 // When the phase 2 is done, all the following counts should be available. 529 // taken from "hooking your solver" and used in the above explanatios 530 531 /** Total number of variables. */ 532 unsigned int varCount() const; 533 534 /** Number of variables appearing nonlinearly in constraints. */ 535 unsigned int lvcCount() const; 536 537 /** Number of variables appearing nonlinearly in objectives. */ 538 unsigned int lvoCount() const; 539 540 /** Number of variables appearing nonlinearly in both constraints and objectives.*/ 541 unsigned int lvbCount() const; 542 543 /** Number of integer variables appearing nonlinearly in both constraints and objectives.*/ 544 unsigned int lvbiCount() const; 545 546 /** Number of integer variables appearing nonlinearly in constraints **only**.*/ 547 unsigned int lvciCount() const; 548 549 /** Number of integer variables appearing nonlinearly in objectives **only**.*/ 550 unsigned int lvoiCount() const; 551 552 /** Number of linear arcs .*/ 553 unsigned int wvCount() const; 554 555 /** Number of "other" integer variables.*/ 556 unsigned int ivCount() const; 557 558 /** Number of binary variables.*/ 559 unsigned int bvCount() const; 560 561 /** Accumulation of Jacobian counts. */ 562 unsigned int jacobianCount() const; 563 564 // Ordering of constraints according to "hooking your solver" 565 /* Meaning of the names: 566 n_con Total number of constraint 567 nlc Number of nonlinear general constraint, including network constraint 568 nlnc Number of nonlinear network constraint 569 lnc Number of linear network constraint 570 571 Order of constraints: 572 Category Count 573 --- --- --- --- --- | --- --- --- --- --- 574 Nonlinear general nlc - nlnc 575 Nonlinear network nlnc 576 Linear network lnc 577 Linear general n_con - (nlc + lnc) 578 */ 579 580 /** Nonlinear general constraints. */ 581 // NOLINTNEXTLINE(readability-identifier-naming) 582 std::vector<std::string> cnames_nl_general = {}; 583 584 /** Nonlinear network constraints. */ 585 // NOLINTNEXTLINE(readability-identifier-naming) 586 std::vector<std::string> cnames_nl_network = {}; 587 588 /** Linear network constraints. */ 589 // NOLINTNEXTLINE(readability-identifier-naming) 590 std::vector<std::string> cnames_lin_network = {}; 591 592 /** Linear general constraints. */ 593 // NOLINTNEXTLINE(readability-identifier-naming) 594 std::vector<std::string> cnames_lin_general = {}; 595 596 /** Contained all ordered algebraic (and network if they were implemented) constraints names. 597 * Mapping constraint index -> constraint name 598 */ 599 std::vector<std::string> cnames = {}; 600 601 /** Mapping constraint name -> contraint index */ 602 std::map<std::string, int> constraintIndexes = {}; 603 604 // Count of algebraic constraints: 605 // The header needs to know how many range algebraic constraints and equality algebraic 606 // constraints we have. 607 /** Number of range algebraic constraints */ 608 int algConsRangeCount = 0; 609 /** equality algebraic constraints */ 610 int algConsEqCount = 0; 611 612 /* *** *** *** Constructor *** *** *** */ 613 614 NLFile() = default; 615 616 /* *** *** *** Printable *** *** *** */ 617 618 /** Print the NLFile on a stream. 619 * Note: this is not the 'Printable' interface as we do not pass any nl_file (that would be 620 * 'this') as a reference. 621 */ 622 std::ostream& printToStream(std::ostream& o) const; 623 624 private: 625 unsigned int _jacobianCount = 0; 626 }; 627 628 } // End of NameSpace MiniZinc 629