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