1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3 /*
4 * Main authors:
5 * Guido Tack <guido.tack@monash.edu>
6 */
7
8 /* This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11
12 #pragma once
13
14 #include <minizinc/aststring.hh>
15 #include <minizinc/astvec.hh>
16 #include <minizinc/gc.hh>
17 #include <minizinc/type.hh>
18 #include <minizinc/values.hh>
19
20 #include <cstddef>
21 #include <cstdint>
22 #include <iostream>
23 #include <limits>
24 #include <utility>
25 #include <vector>
26
27 namespace MiniZinc {
28
29 class IntLit;
30 class FloatLit;
31 class SetLit;
32 class BoolLit;
33 class StringLit;
34 class Id;
35 class AnonVar;
36 class ArrayLit;
37 class ArrayAccess;
38 class Comprehension;
39 class ITE;
40 class BinOp;
41 class UnOp;
42 class Call;
43 class VarDecl;
44 class Let;
45 class TypeInst;
46
47 class Item;
48 class FunctionI;
49
50 class ExpressionSet;
51 class ExpressionSetIter;
52
53 /// %Location of an expression used during parsing
54 class ParserLocation {
55 protected:
56 /// Source code file name
57 ASTString _filename;
58 /// Line where expression starts
59 unsigned int _firstLine;
60 /// Line where expression ends
61 unsigned int _lastLine;
62 /// Column where expression starts
63 unsigned int _firstColumn;
64 /// Column where expression ends
65 unsigned int _lastColumn;
66
67 public:
68 /// Construct empty location
ParserLocation()69 ParserLocation() : _firstLine(1), _lastLine(1), _firstColumn(0), _lastColumn(0) {}
70
71 /// Construct location
ParserLocation(const ASTString & filename,unsigned int first_line,unsigned int first_column,unsigned int last_line,unsigned int last_column)72 ParserLocation(const ASTString& filename, unsigned int first_line, unsigned int first_column,
73 unsigned int last_line, unsigned int last_column)
74 : _filename(filename),
75 _firstLine(first_line),
76 _lastLine(last_line),
77 _firstColumn(first_column),
78 _lastColumn(last_column) {}
79
filename() const80 ASTString filename() const { return _filename; }
filename(const ASTString & f)81 void filename(const ASTString& f) { _filename = f; }
82
firstLine() const83 unsigned int firstLine() const { return _firstLine; }
firstLine(unsigned int l)84 void firstLine(unsigned int l) { _firstLine = l; }
85
lastLine() const86 unsigned int lastLine() const { return _lastLine; }
lastLine(unsigned int l)87 void lastLine(unsigned int l) { _lastLine = l; }
88
firstColumn() const89 unsigned int firstColumn() const { return _firstColumn; }
firstColumn(unsigned int c)90 void firstColumn(unsigned int c) { _firstColumn = c; }
91
lastColumn() const92 unsigned int lastColumn() const { return _lastColumn; }
lastColumn(unsigned int c)93 void lastColumn(unsigned int c) { _lastColumn = c; }
94
toString() const95 std::string toString() const {
96 std::ostringstream oss;
97 oss << _filename << ":" << _firstLine << "." << _firstColumn;
98 if (_firstLine != _lastLine) {
99 oss << "-" << _lastLine << "." << _lastColumn;
100 } else if (_firstColumn != _lastColumn) {
101 oss << "-" << _lastColumn;
102 }
103 return oss.str();
104 }
105 };
106
107 /// %Location of an expression in the source code
108 class Location {
109 protected:
110 /// Internal representation of a Location
111 /// Layout depends on sizeof pointer and arguments
112 /// 32 bit pointers:
113 /// Layout 1: filename (32 bit), first line (8 bit), last line-first line (7 bit), first column
114 /// (6 bit), last column (7 bit) Layout 2: filename (32 bit), 4 IntLit for the lines/columns
115 /// 64 bit pointers:
116 /// Layout 1: filename (64 bit), first line (20 bit), last line-first line (20 bit), first
117 /// column (10 bit), last column (10 bit) Layout 2: filename (64 bit), 4 IntLit for the
118 /// lines/columns
119 class LocVec : public ASTVec {
120 protected:
121 LocVec(const ASTString& filename, unsigned int first_line, unsigned int first_column,
122 unsigned int last_line, unsigned int last_column);
123 LocVec(const ASTString& filename, IntVal combined);
124
125 public:
126 static LocVec* a(const ASTString& filename, unsigned int first_line, unsigned int first_column,
127 unsigned int last_line, unsigned int last_column);
mark()128 void mark() {
129 _gcMark = 1;
130 if (_data[0] != nullptr) {
131 static_cast<ASTStringData*>(_data[0])->mark();
132 }
133 }
134
135 ASTString filename() const;
136 unsigned int firstLine() const;
137 unsigned int lastLine() const;
138 unsigned int firstColumn() const;
139 unsigned int lastColumn() const;
140 };
141
142 union LI {
143 LocVec* lv;
144 ptrdiff_t t;
145 } _locInfo;
146
lv() const147 LocVec* lv() const {
148 LI li = _locInfo;
149 li.t &= ~static_cast<ptrdiff_t>(1);
150 return li.lv;
151 }
152
153 public:
154 /// Construct empty location
Location()155 Location() { _locInfo.lv = nullptr; }
156
157 /// Construct location
Location(const ASTString & filename,unsigned int first_line,unsigned int first_column,unsigned int last_line,unsigned int last_column)158 Location(const ASTString& filename, unsigned int first_line, unsigned int first_column,
159 unsigned int last_line, unsigned int last_column) {
160 if (last_line < first_line) {
161 throw InternalError("invalid location");
162 }
163 _locInfo.lv = LocVec::a(filename, first_line, first_column, last_line, last_column);
164 }
165
Location(const ParserLocation & loc)166 Location(const ParserLocation& loc) {
167 _locInfo.lv = LocVec::a(loc.filename(), loc.firstLine(), loc.firstColumn(), loc.lastLine(),
168 loc.lastColumn());
169 }
170
171 /// Return string representation
172 std::string toString() const;
173
174 /// Return filename
filename() const175 ASTString filename() const { return lv() != nullptr ? lv()->filename() : ASTString(); }
176
177 /// Return first line number
firstLine() const178 unsigned int firstLine() const { return lv() != nullptr ? lv()->firstLine() : 0; }
179
180 /// Return last line number
lastLine() const181 unsigned int lastLine() const { return lv() != nullptr ? lv()->lastLine() : 0; }
182
183 /// Return first column number
firstColumn() const184 unsigned int firstColumn() const { return lv() != nullptr ? lv()->firstColumn() : 0; }
185
186 /// Return last column number
lastColumn() const187 unsigned int lastColumn() const { return lv() != nullptr ? lv()->lastColumn() : 0; }
188
189 /// Return whether location is introduced by the compiler
isIntroduced() const190 bool isIntroduced() const { return _locInfo.lv == nullptr || ((_locInfo.t & 1) != 0); }
191
192 /// Mark as alive for garbage collection
193 void mark() const;
194
195 /// Return location with introduced flag set
196 Location introduce() const;
197
198 /// Location used for un-allocated expressions
199 static Location nonalloc;
200
201 /// Return true if this is a location for an unallocated expression
isNonAlloc() const202 bool isNonAlloc() const { return this == &Location::nonalloc; }
203
parserLocation() const204 ParserLocation parserLocation() const {
205 return ParserLocation(filename(), firstLine(), firstColumn(), lastLine(), lastColumn());
206 }
207 };
208
209 /// Output operator for locations
210 template <class Char, class Traits>
operator <<(std::basic_ostream<Char,Traits> & os,const Location & loc)211 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
212 const Location& loc) {
213 std::basic_ostringstream<Char, Traits> s;
214 s.copyfmt(os);
215 s.width(0);
216 if (loc.filename() == "") {
217 s << "unknown file";
218 } else {
219 s << loc.filename();
220 }
221 s << ":" << loc.firstLine() << "." << loc.firstColumn();
222 if (loc.firstLine() != loc.lastLine()) {
223 s << "-" << loc.lastLine() << "." << loc.lastColumn();
224 } else if (loc.firstColumn() != loc.lastColumn()) {
225 s << "-" << loc.lastColumn();
226 }
227
228 return os << s.str();
229 }
230
231 /**
232 * \brief Annotations
233 */
234 class Annotation {
235 private:
236 ExpressionSet* _s;
237
238 /// Delete
239 Annotation(const Annotation&);
240 /// Delete
241 Annotation& operator=(const Annotation&);
242
243 public:
Annotation()244 Annotation() : _s(nullptr) {}
245 ~Annotation();
246 bool contains(Expression* e) const;
247 bool containsCall(const ASTString& id) const;
248 bool isEmpty() const;
249 ExpressionSetIter begin() const;
250 ExpressionSetIter end() const;
251 void add(Expression* e);
252 void add(std::vector<Expression*> e);
253 void remove(Expression* e);
254 void removeCall(const ASTString& id);
255 void clear();
256 void merge(const Annotation& ann);
257 Call* getCall(const ASTString& id) const;
258
259 static Annotation empty;
260 };
261
262 /// returns the Annotation specified by the string; returns NULL if not exists
263 Expression* get_annotation(const Annotation& ann, const std::string& str);
264
265 /// returns the Annotation specified by the string; returns NULL if not exists
266 Expression* get_annotation(const Annotation& ann, const ASTString& str);
267
268 /**
269 * \brief Base class for expressions
270 */
271 class Expression : public ASTNode {
272 protected:
273 /// The %MiniZinc type of the expression
274 Type _type;
275 /// The annotations
276 Annotation _ann;
277 /// The location of the expression
278 Location _loc;
279 /// The hash value of the expression
280 size_t _hash;
281
282 public:
283 /// Identifier of the concrete expression type
284 enum ExpressionId {
285 E_INTLIT = ASTNode::NID_END + 1,
286 E_FLOATLIT,
287 E_SETLIT,
288 E_BOOLLIT,
289 E_STRINGLIT,
290 E_ID,
291 E_ANON,
292 E_ARRAYLIT,
293 E_ARRAYACCESS,
294 E_COMP,
295 E_ITE,
296 E_BINOP,
297 E_UNOP,
298 E_CALL,
299 E_VARDECL,
300 E_LET,
301 E_TI,
302 E_TIID,
303 EID_END = E_TIID
304 };
305
isUnboxedVal() const306 bool isUnboxedVal() const {
307 if (sizeof(double) <= sizeof(void*)) {
308 // bit 1 or bit 0 is set
309 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(3)) != 0;
310 } // bit 0 is set
311 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(1)) != 0;
312 }
isUnboxedInt() const313 bool isUnboxedInt() const {
314 if (sizeof(double) <= sizeof(void*)) {
315 // bit 1 is set, bit 0 is not set
316 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(3)) == 2;
317 } // bit 0 is set
318 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(1)) == 1;
319 }
isUnboxedFloatVal() const320 bool isUnboxedFloatVal() const {
321 // bit 0 is set (and doubles fit inside pointers)
322 return (sizeof(double) <= sizeof(void*)) &&
323 (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(1)) == 1;
324 }
325
eid() const326 ExpressionId eid() const {
327 return isUnboxedInt() ? E_INTLIT
328 : isUnboxedFloatVal() ? E_FLOATLIT : static_cast<ExpressionId>(_id);
329 }
330
loc() const331 const Location& loc() const { return isUnboxedVal() ? Location::nonalloc : _loc; }
loc(const Location & l)332 void loc(const Location& l) {
333 if (!isUnboxedVal()) {
334 _loc = l;
335 }
336 }
type() const337 const Type& type() const {
338 return isUnboxedInt() ? Type::unboxedint : isUnboxedFloatVal() ? Type::unboxedfloat : _type;
339 }
340 void type(const Type& t);
hash() const341 size_t hash() const {
342 return isUnboxedInt() ? unboxedIntToIntVal().hash()
343 : isUnboxedFloatVal() ? unboxedFloatToFloatVal().hash() : _hash;
344 }
345
346 protected:
347 /// Combination function for hash values
combineHash(size_t h)348 void combineHash(size_t h) { _hash ^= h + 0x9e3779b9 + (_hash << 6) + (_hash >> 2); }
349 /// Combination function for hash values
combineHash(size_t seed,size_t h)350 static size_t combineHash(size_t seed, size_t h) {
351 seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
352 return seed;
353 }
354
355 /// Compute base hash value
initHash()356 void initHash() { _hash = combineHash(0, _id); }
357
358 /// Check if \a e0 and \a e1 are equal
359 static bool equalInternal(const Expression* e0, const Expression* e1);
360
361 /// Constructor
Expression(const Location & loc,const ExpressionId & eid,const Type & t)362 Expression(const Location& loc, const ExpressionId& eid, const Type& t)
363 : ASTNode(eid), _type(t), _loc(loc) {}
364
365 public:
unboxedIntToIntVal() const366 IntVal unboxedIntToIntVal() const {
367 assert(isUnboxedInt());
368 if (sizeof(double) <= sizeof(void*)) {
369 unsigned long long int i = reinterpret_cast<ptrdiff_t>(this) & ~static_cast<ptrdiff_t>(7);
370 bool pos = ((reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(4)) == 0);
371 if (pos) {
372 return static_cast<long long int>(i >> 3);
373 }
374 return -(static_cast<long long int>(i >> 3));
375 }
376 unsigned long long int i = reinterpret_cast<ptrdiff_t>(this) & ~static_cast<ptrdiff_t>(3);
377 bool pos = ((reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(2)) == 0);
378 if (pos) {
379 return static_cast<long long int>(i >> 2);
380 }
381 return -(static_cast<long long int>(i >> 2));
382 }
intToUnboxedInt(long long int i)383 static IntLit* intToUnboxedInt(long long int i) {
384 static const unsigned int pointerBits = sizeof(void*) * 8;
385 if (sizeof(double) <= sizeof(void*)) {
386 static const long long int maxUnboxedVal =
387 (static_cast<long long int>(1) << (pointerBits - 3)) - static_cast<long long int>(1);
388 if (i < -maxUnboxedVal || i > maxUnboxedVal) {
389 return nullptr;
390 }
391 long long int j = i < 0 ? -i : i;
392 ptrdiff_t ubi_p = (static_cast<ptrdiff_t>(j) << 3) | static_cast<ptrdiff_t>(2);
393 if (i < 0) {
394 ubi_p = ubi_p | static_cast<ptrdiff_t>(4);
395 }
396 return reinterpret_cast<IntLit*>(ubi_p);
397 }
398 static const long long int maxUnboxedVal =
399 (static_cast<long long int>(1) << (pointerBits - 2)) - static_cast<long long int>(1);
400 if (i < -maxUnboxedVal || i > maxUnboxedVal) {
401 return nullptr;
402 }
403 long long int j = i < 0 ? -i : i;
404 ptrdiff_t ubi_p = (static_cast<ptrdiff_t>(j) << 2) | static_cast<ptrdiff_t>(1);
405 if (i < 0) {
406 ubi_p = ubi_p | static_cast<ptrdiff_t>(2);
407 }
408 return reinterpret_cast<IntLit*>(ubi_p);
409 }
unboxedFloatToFloatVal() const410 FloatVal unboxedFloatToFloatVal() const {
411 assert(isUnboxedFloatVal());
412 union {
413 double d;
414 uint64_t bits;
415 const Expression* p;
416 } _u;
417 _u.p = this;
418 _u.bits = _u.bits >> 1;
419 uint64_t exponent = (_u.bits & (static_cast<uint64_t>(0x3FF) << 52)) >> 52;
420 if (exponent != 0) {
421 exponent += 512; // reconstruct original bias of 1023
422 }
423 uint64_t sign = ((_u.bits & (static_cast<uint64_t>(1) << 62)) != 0U ? 1 : 0);
424 _u.bits = (sign << 63) | (exponent << 52) | (_u.bits & static_cast<uint64_t>(0xFFFFFFFFFFFFF));
425 return _u.d;
426 }
doubleToUnboxedFloatVal(double d)427 static FloatLit* doubleToUnboxedFloatVal(double d) {
428 if (sizeof(double) > sizeof(void*)) {
429 return nullptr;
430 }
431 union {
432 double d;
433 uint64_t bits;
434 FloatLit* p;
435 } _u;
436 _u.d = d;
437
438 uint64_t exponent = (_u.bits & (static_cast<uint64_t>(0x7FF) << 52)) >> 52;
439 if (exponent != 0) {
440 if (exponent < 513 || exponent > 1534) {
441 return nullptr; // exponent doesn't fit in 10 bits
442 }
443 exponent -= 512; // make exponent fit in 10 bits, with bias 511
444 }
445 bool sign = (_u.bits & (static_cast<uint64_t>(1) << 63)) != 0;
446
447 _u.bits = _u.bits &
448 ~(static_cast<uint64_t>(0x7FF) << 52); // mask out top 11 bits (previously exponent)
449 _u.bits = (_u.bits << 1) | 1U; // shift by one bit and add tag for double
450 _u.bits =
451 _u.bits | (static_cast<uint64_t>(sign) << 63) | (static_cast<uint64_t>(exponent) << 53);
452 return _u.p;
453 }
454
isTagged() const455 bool isTagged() const {
456 // only bit 2 is set
457 if (isUnboxedVal()) {
458 return false;
459 }
460 if (sizeof(double) <= sizeof(void*)) {
461 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(7)) == 4;
462 }
463 return (reinterpret_cast<ptrdiff_t>(this) & static_cast<ptrdiff_t>(3)) == 2;
464 }
465
tag() const466 Expression* tag() const {
467 assert(!isUnboxedVal());
468 if (sizeof(double) <= sizeof(void*)) {
469 return reinterpret_cast<Expression*>(reinterpret_cast<ptrdiff_t>(this) |
470 static_cast<ptrdiff_t>(4));
471 }
472 return reinterpret_cast<Expression*>(reinterpret_cast<ptrdiff_t>(this) |
473 static_cast<ptrdiff_t>(2));
474 }
untag()475 Expression* untag() {
476 if (isUnboxedVal()) {
477 return this;
478 }
479 if (sizeof(double) <= sizeof(void*)) {
480 return reinterpret_cast<Expression*>(reinterpret_cast<ptrdiff_t>(this) &
481 ~static_cast<ptrdiff_t>(4));
482 }
483 return reinterpret_cast<Expression*>(reinterpret_cast<ptrdiff_t>(this) &
484 ~static_cast<ptrdiff_t>(2));
485 }
486
487 /// Test if expression is of type \a T
488 template <class T>
isa() const489 bool isa() const {
490 #ifdef __clang__
491 #pragma clang diagnostic push
492 #pragma clang diagnostic ignored "-Wtautological-undefined-compare"
493 #endif
494 if (nullptr == this) {
495 throw InternalError("isa: nullptr");
496 }
497 #ifdef __clang__
498 #pragma clang diagnostic pop
499 #endif
500 return isUnboxedInt() ? T::eid == E_INTLIT
501 : isUnboxedFloatVal() ? T::eid == E_FLOATLIT : _id == T::eid;
502 }
503 /// Cast expression to type \a T*
504 template <class T>
cast()505 T* cast() {
506 assert(isa<T>());
507 return static_cast<T*>(this);
508 }
509 /// Cast expression to type \a const T*
510 template <class T>
cast() const511 const T* cast() const {
512 assert(isa<T>());
513 return static_cast<const T*>(this);
514 }
515 /// Cast expression to type \a T* or NULL if types do not match
516 template <class T>
dynamicCast()517 T* dynamicCast() {
518 return isa<T>() ? static_cast<T*>(this) : nullptr;
519 }
520 /// Cast expression to type \a const T* or NULL if types do not match
521 template <class T>
dynamicCast() const522 const T* dynamicCast() const {
523 return isa<T>() ? static_cast<const T*>(this) : nullptr;
524 }
525
526 /// Cast expression to type \a T*
527 template <class T>
cast(Expression * e)528 static T* cast(Expression* e) {
529 return e == nullptr ? nullptr : e->cast<T>();
530 }
531 /// Cast expression to type \a const T*
532 template <class T>
cast(const Expression * e)533 static const T* cast(const Expression* e) {
534 return e == nullptr ? NULL : e->cast<T>();
535 }
536 /// Cast expression to type \a T* or NULL if types do not match
537 template <class T>
dynamicCast(Expression * e)538 static T* dynamicCast(Expression* e) {
539 return e == nullptr ? nullptr : e->dynamicCast<T>();
540 }
541 /// Cast expression to type \a const T* or NULL if types do not match
542 template <class T>
dynamicCast(const Expression * e)543 static const T* dynamicCast(const Expression* e) {
544 return e == nullptr ? NULL : e->dynamicCast<T>();
545 }
546
547 /// Add annotation \a ann to the expression
548 void addAnnotation(Expression* ann);
549
550 /// Add annotation \a ann to the expression
551 void addAnnotations(const std::vector<Expression*>& ann);
552
ann() const553 const Annotation& ann() const { return isUnboxedVal() ? Annotation::empty : _ann; }
ann()554 Annotation& ann() { return isUnboxedVal() ? Annotation::empty : _ann; }
555
556 /// Return hash value of \a e
hash(const Expression * e)557 static size_t hash(const Expression* e) { return e == nullptr ? 0 : e->hash(); }
558
559 /// Check if \a e0 and \a e1 are equal
560 static bool equal(const Expression* e0, const Expression* e1);
561
562 /// Mark \a e as alive for garbage collection
563 static void mark(Expression* e);
564 };
565
566 /// \brief Integer literal expression
567 class IntLit : public Expression {
568 protected:
569 /// The value of this expression
570 IntVal _v;
571 /// Constructor
572 IntLit(const Location& loc, IntVal v);
573
574 public:
575 /// The identifier of this expression type
576 static const ExpressionId eid = E_INTLIT;
577 /// Access value
v() const578 IntVal v() const { return isUnboxedInt() ? unboxedIntToIntVal() : _v; }
579 /// Recompute hash value
580 void rehash();
581 /// Allocate literal
582 static IntLit* a(IntVal v);
583 /// Allocate literal for enumerated type (only used internally for generators)
584 static IntLit* aEnum(IntVal v, unsigned int enumId);
585 };
586 /// \brief Float literal expression
587 class FloatLit : public Expression {
588 protected:
589 /// The value of this expression
590 FloatVal _v;
591 /// Constructor
592 FloatLit(const Location& loc, FloatVal v);
593
594 public:
595 /// The identifier of this expression type
596 static const ExpressionId eid = E_FLOATLIT;
597 /// Access value
v() const598 FloatVal v() const { return isUnboxedFloatVal() ? unboxedFloatToFloatVal() : _v; }
599 /// Recompute hash value
600 void rehash();
601 /// Allocate literal
602 static FloatLit* a(FloatVal v);
603 };
604 /// \brief Set literal expression
605 class SetLit : public Expression {
606 protected:
607 /// The value of this expression
608 ASTExprVec<Expression> _v;
609 union {
610 /// A range-list based representation for an integer set, or NULL
611 IntSetVal* isv;
612 /// A range-list based representation for an float set, or NULL
613 FloatSetVal* fsv;
614 } _u;
615
616 public:
617 /// The identifier of this expression type
618 static const ExpressionId eid = E_SETLIT;
619 /// Construct set \$f\{v1,\dots,vn\}\$f
620 SetLit(const Location& loc, const std::vector<Expression*>& v);
621 /// Construct set \$f\{v1,\dots,vn\}\$f
622 SetLit(const Location& loc, const ASTExprVec<Expression>& v);
623 /// Construct set
624 SetLit(const Location& loc, IntSetVal* isv);
625 /// Construct set
626 SetLit(const Location& loc, FloatSetVal* fsv);
627 /// Access value
v() const628 ASTExprVec<Expression> v() const { return _v; }
629 /// Set value
v(const ASTExprVec<Expression> & val)630 void v(const ASTExprVec<Expression>& val) { _v = val; }
631 /// Access integer set value if present
isv() const632 IntSetVal* isv() const {
633 return (type().bt() == Type::BT_INT || type().bt() == Type::BT_BOOL) ? _u.isv : nullptr;
634 }
635 /// Set integer set value
isv(IntSetVal * val)636 void isv(IntSetVal* val) { _u.isv = val; }
637 /// Access float set value if present
fsv() const638 FloatSetVal* fsv() const { return type().bt() == Type::BT_FLOAT ? _u.fsv : nullptr; }
639 /// Set integer set value
fsv(FloatSetVal * val)640 void fsv(FloatSetVal* val) { _u.fsv = val; }
641 /// Recompute hash value
642 void rehash();
643 };
644 /// \brief Boolean literal expression
645 class BoolLit : public Expression {
646 protected:
647 /// The value of this expression
648 bool _v;
649
650 public:
651 /// The identifier of this expression type
652 static const ExpressionId eid = E_BOOLLIT;
653 /// Constructor
654 BoolLit(const Location& loc, bool v);
655 /// Access value
v() const656 bool v() const { return _v; }
657 /// Recompute hash value
658 void rehash();
659 };
660 /// \brief String literal expression
661 class StringLit : public Expression {
662 protected:
663 /// The value of this expression
664 ASTString _v;
665
666 public:
667 /// The identifier of this expression type
668 static const ExpressionId eid = E_STRINGLIT;
669 /// Constructor
670 StringLit(const Location& loc, const std::string& v);
671 /// Constructor
672 StringLit(const Location& loc, const ASTString& v);
673 /// Access value
v() const674 ASTString v() const { return _v; }
675 /// Set value
v(const ASTString & val)676 void v(const ASTString& val) { _v = val; }
677 /// Recompute hash value
678 void rehash();
679 };
680 /// \brief Identifier expression
681 class Id : public Expression {
682 protected:
683 /// The string identifier
684 union {
685 /// Identifier of called predicate or function
686 ASTString val;
687 /// The predicate or function declaration (or NULL)
688 void* idn;
689 } _vOrIdn = {nullptr};
690 /// The declaration corresponding to this identifier (may be NULL)
691 Expression* _decl;
692
693 public:
694 /// The identifier of this expression type
695 static const ExpressionId eid = E_ID;
696 /// Constructor (\a decl may be NULL)
697 Id(const Location& loc, const std::string& v, VarDecl* decl);
698 /// Constructor (\a decl may be NULL)
699 Id(const Location& loc, const ASTString& v, VarDecl* decl);
700 /// Constructor (\a decl may be NULL)
701 Id(const Location& loc, long long int idn, VarDecl* decl);
702 /// Access identifier
703 ASTString v() const;
hasStr() const704 inline bool hasStr() const {
705 return (reinterpret_cast<ptrdiff_t>(_vOrIdn.idn) & static_cast<ptrdiff_t>(1)) == 0;
706 }
707 /// Set identifier
v(const ASTString & val)708 void v(const ASTString& val) { _vOrIdn.val = val; }
709 /// Access identifier number
710 long long int idn() const;
711 /// Set identifier number
idn(long long int n)712 void idn(long long int n) {
713 _vOrIdn.idn =
714 reinterpret_cast<void*>((static_cast<ptrdiff_t>(n) << 1) | static_cast<ptrdiff_t>(1));
715 rehash();
716 }
717 /// Return identifier or X_INTRODUCED plus identifier number
718 ASTString str() const;
719 /// Access declaration
decl() const720 VarDecl* decl() const {
721 Expression* d = _decl;
722 while ((d != nullptr) && d->isa<Id>()) {
723 d = d->cast<Id>()->_decl;
724 }
725 return Expression::cast<VarDecl>(d);
726 }
727 /// Set declaration
728 void decl(VarDecl* d);
729 /// Redirect to another Id \a id
redirect(Id * id)730 void redirect(Id* id) {
731 assert(_decl == nullptr || _decl->isa<VarDecl>());
732 _decl = id;
733 }
734 /// Recompute hash value
735 void rehash();
736 /// Levenshtein distance to \a other identifier
737 int levenshteinDistance(Id* other) const;
738 };
739 /// \brief Type-inst identifier expression
740 class TIId : public Expression {
741 protected:
742 /// The string identifier
743 ASTString _v;
744
745 public:
746 /// The identifier of this expression type
747 static const ExpressionId eid = E_TIID;
748 /// Constructor
749 TIId(const Location& loc, const std::string& v);
750 /// Constructor
751 TIId(const Location& loc, const ASTString& v);
752 /// Access identifier
v() const753 ASTString v() const { return _v; }
754 /// Set identifier
v(const ASTString & val)755 void v(const ASTString& val) { _v = val; }
756 /// Check whether it is an enum identifier (starting with two $ signs)
isEnum() const757 bool isEnum() const { return _v.c_str()[0] == '$'; }
758 /// Recompute hash value
759 void rehash();
760 };
761 /// \brief Anonymous variable expression
762 class AnonVar : public Expression {
763 public:
764 /// The identifier of this expression type
765 static const ExpressionId eid = E_ANON;
766 /// Constructor
767 AnonVar(const Location& loc);
768 /// Recompute hash value
769 void rehash();
770 };
771 /// \brief Array literal expression
772 class ArrayLit : public Expression {
773 friend class Expression;
774
775 protected:
776 /// The array
777 union {
778 /// An expression vector (if _flag2==false)
779 ASTExprVecO<Expression*>* v;
780 /// Another array literal (if _flag2==true)
781 ArrayLit* al;
782 } _u;
783 /// The declared array dimensions
784 // If _flag2 is true, then this is an array view. In that case,
785 // the _dims array holds the sliced dimensions
786 ASTIntVec _dims;
787 /// Set compressed vector (initial repetitions are removed)
788 void compress(const std::vector<Expression*>& v, const std::vector<int>& dims);
789
790 public:
791 /// Index conversion from slice to original
792 unsigned int origIdx(unsigned int i) const;
793 /// Get element \a i of a sliced array
794 Expression* getSlice(unsigned int i) const;
795 /// Set element \a i of a sliced array
796 void setSlice(unsigned int i, Expression* e);
797
798 /// The identifier of this expression type
799 static const ExpressionId eid = E_ARRAYLIT;
800 /// Constructor
801 ArrayLit(const Location& loc, const std::vector<Expression*>& v,
802 const std::vector<std::pair<int, int> >& dims);
803 /// Constructor (existing content)
804 ArrayLit(const Location& loc, ArrayLit& v, const std::vector<std::pair<int, int> >& dims);
805 /// Constructor (one-dimensional, existing content)
806 ArrayLit(const Location& loc, ArrayLit& v);
807 /// Constructor (one-dimensional)
808 ArrayLit(const Location& loc, const std::vector<Expression*>& v);
809 /// Constructor (two-dimensional)
810 ArrayLit(const Location& loc, const std::vector<std::vector<Expression*> >& v);
811 /// Constructor for slices
812 ArrayLit(const Location& loc, ArrayLit* v, const std::vector<std::pair<int, int> >& dims,
813 const std::vector<std::pair<int, int> >& slice);
814 /// Constructor (one-dimensional)
815 ArrayLit(const Location& loc, const std::vector<KeepAlive>& v);
816 /// Recompute hash value
817 void rehash();
818
819 // The following methods are only used for copying
820
821 /// Access value
getVec() const822 ASTExprVec<Expression> getVec() const {
823 assert(!_flag2);
824 return _u.v;
825 }
826 /// Set value
setVec(const ASTExprVec<Expression> & val)827 void setVec(const ASTExprVec<Expression>& val) {
828 assert(!_flag2);
829 _u.v = val.vec();
830 }
831 /// Get underlying array (if this is an array slice) or NULL
getSliceLiteral() const832 ArrayLit* getSliceLiteral() const { return _flag2 ? _u.al : nullptr; }
833 /// Get underlying _dims vector
dimsInternal() const834 ASTIntVec dimsInternal() const { return _dims; }
835
836 /// Return number of dimensions
837 unsigned int dims() const;
838 /// Return minimum index of dimension \a i
839 int min(unsigned int i) const;
840 /// Return maximum index of dimension \a i
841 int max(unsigned int i) const;
842 /// Return the length of the array
843 unsigned int length() const;
844 /// Turn into 1d array (only used at the end of flattening)
845 void make1d();
846 /// Check if this array was produced by flattening
flat() const847 bool flat() const { return _flag1; }
848 /// Set whether this array was produced by flattening
flat(bool b)849 void flat(bool b) { _flag1 = b; }
850 /// Return size of underlying array
size() const851 unsigned int size() const { return (_flag2 || _u.v->flag()) ? length() : _u.v->size(); }
852 /// Access element \a i
operator [](unsigned int i) const853 Expression* operator[](unsigned int i) const {
854 return (_flag2 || _u.v->flag()) ? getSlice(i) : (*_u.v)[i];
855 }
856 /// Set element \a i
set(unsigned int i,Expression * e)857 void set(unsigned int i, Expression* e) {
858 if (_flag2 || _u.v->flag()) {
859 setSlice(i, e);
860 } else {
861 (*_u.v)[i] = e;
862 }
863 }
864 };
865 /// \brief Array access expression
866 class ArrayAccess : public Expression {
867 protected:
868 /// The array to access
869 Expression* _v;
870 /// The indexes (for all array dimensions)
871 ASTExprVec<Expression> _idx;
872
873 public:
874 /// The identifier of this expression type
875 static const ExpressionId eid = E_ARRAYACCESS;
876 /// Constructor
877 ArrayAccess(const Location& loc, Expression* v, const std::vector<Expression*>& idx);
878 /// Constructor
879 ArrayAccess(const Location& loc, Expression* v, const ASTExprVec<Expression>& idx);
880 /// Access value
v() const881 Expression* v() const { return _v; }
882 /// Set value
v(Expression * val)883 void v(Expression* val) { _v = val; }
884 /// Access index sets
idx() const885 ASTExprVec<Expression> idx() const { return _idx; }
886 /// Set index sets
idx(const ASTExprVec<Expression> & idx)887 void idx(const ASTExprVec<Expression>& idx) { _idx = idx; }
888 /// Recompute hash value
889 void rehash();
890 };
891 /**
892 * \brief Generators for comprehensions
893 *
894 * A generator consists of a list of variable declarations, one for
895 * each generated variable, and the expression to generate. E.g.,
896 * the Zinc expression [ x[i,j,k] | i,j in 1..10, k in 1..5] contains
897 * two generators. The first one has variable declarations for i and j
898 * and the expression 1..10, and the second one has a variable declaration
899 * for k and the expression 1..5.
900 *
901 */
902 class Generator {
903 friend class Comprehension;
904
905 protected:
906 /// Variable declarations
907 std::vector<VarDecl*> _v;
908 /// in-expression
909 Expression* _in;
910 /// where-expression
911 Expression* _where;
912
913 public:
914 /// Allocate
915 Generator(const std::vector<std::string>& v, Expression* in, Expression* where);
916 /// Allocate
917 Generator(const std::vector<ASTString>& v, Expression* in, Expression* where);
918 /// Allocate
919 Generator(const std::vector<Id*>& v, Expression* in, Expression* where);
920 /// Allocate
921 Generator(const std::vector<VarDecl*>& v, Expression* in, Expression* where);
922 /// Allocate single where clause (without generator) at position \a pos
923 Generator(int pos, Expression* where);
924 };
925 /// \brief A list of generators with one where-expression
926 struct Generators {
927 /// %Generators
928 std::vector<Generator> g;
929 /// Constructor
GeneratorsMiniZinc::Generators930 Generators() {}
931 };
932 /// \brief An expression representing an array- or set-comprehension
933 class Comprehension : public Expression {
934 friend class Expression;
935
936 protected:
937 /// The expression to generate
938 Expression* _e;
939 /// A list of generator expressions
940 ASTExprVec<Expression> _g;
941 /// A list of indices where generators start
942 ASTIntVec _gIndex;
943
944 public:
945 /// The identifier of this expression type
946 static const ExpressionId eid = E_COMP;
947 /// Constructor
948 Comprehension(const Location& loc, Expression* e, Generators& g, bool set);
949 /// Recompute hash value
950 void rehash();
951 /// Whether comprehension is a set
952 bool set() const;
953
954 /// Return number of generators
955 unsigned int numberOfGenerators() const;
956 /// Return "in" expression for generator \a i
957 Expression* in(unsigned int i);
958 /// Return "in" expression for generator \a i
959 const Expression* in(unsigned int i) const;
960 /// Return number of declarations for generator \a i
961 unsigned int numberOfDecls(unsigned int i) const;
962 /// Return declaration \a i for generator \a gen
963 VarDecl* decl(unsigned int gen, unsigned int i);
964 /// Return declaration \a i for generator \a gen
965 const VarDecl* decl(unsigned int gen, unsigned int i) const;
966 /// Return where clause for generator \a i
967 Expression* where(unsigned int i);
968 /// Return where clause for generator \a i
969 const Expression* where(unsigned int i) const;
970 /// Return generator body
e() const971 Expression* e() const { return _e; }
972 /// Set generator body
e(Expression * e0)973 void e(Expression* e0) { _e = e0; }
974 /// Re-construct (used for copying)
975 void init(Expression* e, Generators& g);
976 /// Check if \a e contains one of the variables bound by this comprehension
977 bool containsBoundVariable(Expression* e);
978 };
979 /// \brief If-then-else expression
980 class ITE : public Expression {
981 friend class Expression;
982
983 protected:
984 /// List of if-then-pairs
985 ASTExprVec<Expression> _eIfThen;
986 /// Else-expression
987 Expression* _eElse;
988
989 public:
990 /// The identifier of this expression type
991 static const ExpressionId eid = E_ITE;
992 /// Constructor
993 ITE(const Location& loc, const std::vector<Expression*>& e_if_then, Expression* e_else);
size() const994 unsigned int size() const { return static_cast<int>(_eIfThen.size() / 2); }
ifExpr(unsigned int i)995 Expression* ifExpr(unsigned int i) { return _eIfThen[2 * i]; }
thenExpr(unsigned int i)996 Expression* thenExpr(unsigned int i) { return _eIfThen[2 * i + 1]; }
elseExpr()997 Expression* elseExpr() { return _eElse; }
ifExpr(unsigned int i) const998 const Expression* ifExpr(unsigned int i) const { return _eIfThen[2 * i]; }
thenExpr(unsigned int i) const999 const Expression* thenExpr(unsigned int i) const { return _eIfThen[2 * i + 1]; }
elseExpr() const1000 const Expression* elseExpr() const { return _eElse; }
thenExpr(unsigned int i,Expression * e)1001 void thenExpr(unsigned int i, Expression* e) { _eIfThen[2 * i + 1] = e; }
elseExpr(Expression * e)1002 void elseExpr(Expression* e) { _eElse = e; }
1003 /// Recompute hash value
1004 void rehash();
1005 /// Re-construct (used for copying)
1006 void init(const std::vector<Expression*>& e_if_then, Expression* e_else);
1007 };
1008
1009 /// Type of binary operators
1010 enum BinOpType {
1011 BOT_PLUS,
1012 BOT_MINUS,
1013 BOT_MULT,
1014 BOT_DIV,
1015 BOT_IDIV,
1016 BOT_MOD,
1017 BOT_POW,
1018 BOT_LE,
1019 BOT_LQ,
1020 BOT_GR,
1021 BOT_GQ,
1022 BOT_EQ,
1023 BOT_NQ,
1024 BOT_IN,
1025 BOT_SUBSET,
1026 BOT_SUPERSET,
1027 BOT_UNION,
1028 BOT_DIFF,
1029 BOT_SYMDIFF,
1030 BOT_INTERSECT,
1031 BOT_PLUSPLUS,
1032 BOT_EQUIV,
1033 BOT_IMPL,
1034 BOT_RIMPL,
1035 BOT_OR,
1036 BOT_AND,
1037 BOT_XOR,
1038 BOT_DOTDOT
1039 };
1040 /// \brief Binary-operator expression
1041 class BinOp : public Expression {
1042 protected:
1043 /// Left hand side expression
1044 Expression* _e0;
1045 /// Right hand side expression
1046 Expression* _e1;
1047 /// The predicate or function declaration (or NULL)
1048 FunctionI* _decl;
1049
1050 public:
1051 /// The identifier of this expression type
1052 static const ExpressionId eid = E_BINOP;
1053 /// Constructor
1054 BinOp(const Location& loc, Expression* e0, BinOpType op, Expression* e1);
1055 /// Access left hand side
lhs() const1056 Expression* lhs() const { return _e0; }
1057 /// Set left hand side
lhs(Expression * e)1058 void lhs(Expression* e) { _e0 = e; }
1059 /// Access right hand side
rhs() const1060 Expression* rhs() const { return _e1; }
1061 /// Set right hand side
rhs(Expression * e)1062 void rhs(Expression* e) { _e1 = e; }
1063 /// Access argument \a i
arg(int i)1064 Expression* arg(int i) {
1065 assert(i == 0 || i == 1);
1066 return i == 0 ? _e0 : _e1;
1067 }
1068 /// Return number of arguments
argCount()1069 static unsigned int argCount() { return 2; }
1070 /// Access declaration
decl() const1071 FunctionI* decl() const { return _decl; }
1072 /// Set declaration
decl(FunctionI * f)1073 void decl(FunctionI* f) { _decl = f; }
1074 /// Return string representation of the operator
1075 ASTString opToString() const;
1076 /// Recompute hash value
1077 void rehash();
1078 /// Return operator type
1079 BinOpType op() const;
1080 /// Morph into a call
1081 Call* morph(const ASTString& ident, const std::vector<Expression*>& args);
1082 };
1083
1084 /// Type of unary operators
1085 enum UnOpType { UOT_NOT, UOT_PLUS, UOT_MINUS };
1086 /// \brief Unary-operator expressions
1087 class UnOp : public Expression {
1088 protected:
1089 /// %Expression
1090 Expression* _e0;
1091 /// The predicate or function declaration (or NULL)
1092 FunctionI* _decl;
1093
1094 public:
1095 /// The identifier of this expression type
1096 static const ExpressionId eid = E_UNOP;
1097 /// Constructor
1098 UnOp(const Location& loc, UnOpType op, Expression* e);
1099 /// Access expression
e() const1100 Expression* e() const { return _e0; }
1101 /// Set expression
e(Expression * e0)1102 void e(Expression* e0) { _e0 = e0; }
1103 /// Access argument \a i
arg(int i)1104 Expression* arg(int i) {
1105 assert(i == 0);
1106 return _e0;
1107 }
1108 /// Return number of arguments
argCount()1109 static unsigned int argCount() { return 1; }
1110 /// Access declaration
decl() const1111 FunctionI* decl() const { return _decl; }
1112 /// Set declaration
decl(FunctionI * f)1113 void decl(FunctionI* f) { _decl = f; }
1114 ASTString opToString() const;
1115 /// Recompute hash value
1116 void rehash();
1117 /// Return operator type
1118 UnOpType op() const;
1119 };
1120
1121 /// \brief A predicate or function call expression
1122 class Call : public Expression {
1123 friend class Expression;
1124
1125 protected:
1126 union {
1127 /// Identifier of called predicate or function
1128 ASTString id;
1129 /// The predicate or function declaration (or NULL)
1130 FunctionI* decl;
1131 } _uId = {nullptr};
1132 union {
1133 /// Single-argument call (tagged pointer)
1134 Expression* oneArg;
1135 /// Arguments to the call
1136 ASTExprVecO<Expression*>* args;
1137 } _u;
1138 /// Check if _uId contains an id or a decl
1139 bool hasId() const;
1140
1141 public:
1142 /// The identifier of this expression type
1143 static const ExpressionId eid = E_CALL;
1144 /// Constructor
1145 Call(const Location& loc, const std::string& id, const std::vector<Expression*>& args);
1146 /// Constructor
1147 Call(const Location& loc, const ASTString& id, const std::vector<Expression*>& args);
1148 /// Access identifier
1149 ASTString id() const;
1150 /// Set identifier (overwrites decl)
1151 void id(const ASTString& i);
1152 /// Number of arguments
argCount() const1153 unsigned int argCount() const {
1154 return _u.oneArg->isUnboxedVal() || _u.oneArg->isTagged() ? 1 : _u.args->size();
1155 }
1156 /// Access argument \a i
arg(unsigned int i) const1157 Expression* arg(unsigned int i) const {
1158 assert(i < argCount());
1159 if (_u.oneArg->isUnboxedVal() || _u.oneArg->isTagged()) {
1160 assert(i == 0U);
1161 return _u.oneArg->isUnboxedVal() ? _u.oneArg : _u.oneArg->untag();
1162 }
1163 return (*_u.args)[i];
1164 }
1165 /// Set argument \a i
arg(unsigned int i,Expression * e)1166 void arg(unsigned int i, Expression* e) {
1167 assert(i < argCount());
1168 if (_u.oneArg->isUnboxedVal() || _u.oneArg->isTagged()) {
1169 assert(i == 0U);
1170 _u.oneArg = e->isUnboxedVal() ? e : e->tag();
1171 } else {
1172 (*_u.args)[i] = e;
1173 }
1174 }
1175 /// Set arguments
args(const ASTExprVec<Expression> & a)1176 void args(const ASTExprVec<Expression>& a) {
1177 if (a.size() == 1) {
1178 _u.oneArg = a[0]->isUnboxedVal() ? a[0] : a[0]->tag();
1179 } else {
1180 _u.args = a.vec();
1181 assert(!_u.oneArg->isTagged());
1182 }
1183 }
1184 /// Access declaration
1185 FunctionI* decl() const;
1186 /// Set declaration (overwrites id)
1187 void decl(FunctionI* f);
1188 /// Recompute hash value
1189 void rehash();
1190 };
1191 /// \brief A variable declaration expression
1192 class VarDecl : public Expression {
1193 protected:
1194 /// Type-inst of the declared variable
1195 TypeInst* _ti;
1196 /// Identifier
1197 Id* _id;
1198 /// Initialisation expression (can be NULL)
1199 Expression* _e;
1200 /// Flattened version of the VarDecl
1201 WeakRef _flat;
1202 /// Integer payload
1203 int _payload;
1204
1205 public:
1206 /// The identifier of this expression type
1207 static const ExpressionId eid = E_VARDECL;
1208 /// Constructor
1209 VarDecl(const Location& loc, TypeInst* ti, const std::string& id, Expression* e = nullptr);
1210 /// Constructor
1211 VarDecl(const Location& loc, TypeInst* ti, const ASTString& id, Expression* e = nullptr);
1212 /// Constructor
1213 VarDecl(const Location& loc, TypeInst* ti, long long int idn, Expression* e = nullptr);
1214 /// Constructor
1215 VarDecl(const Location& loc, TypeInst* ti, Id* id, Expression* e = nullptr);
1216
1217 /// Access TypeInst
ti() const1218 TypeInst* ti() const { return _ti; }
1219 /// Set TypeInst
ti(TypeInst * t)1220 void ti(TypeInst* t) { _ti = t; }
1221 /// Access identifier
id() const1222 Id* id() const { return _id; }
1223 /// Access initialisation expression
1224 Expression* e() const;
1225 /// Set initialisation expression
1226 void e(Expression* rhs);
1227 /// Access flattened version
flat()1228 VarDecl* flat() { return _flat() != nullptr ? _flat()->cast<VarDecl>() : nullptr; }
1229 /// Set flattened version
1230 void flat(VarDecl* vd);
1231
1232 /// Recompute hash value
1233 void rehash();
1234 /// Whether variable is toplevel
1235 bool toplevel() const;
1236 /// Whether variable is toplevel
1237 void toplevel(bool t);
1238 /// Whether variable is introduced
1239 bool introduced() const;
1240 /// Whether variable is introduced
1241 void introduced(bool t);
1242 /// Whether variable has been evaluated
1243 bool evaluated() const;
1244 /// Whether variable has been evaluated
1245 void evaluated(bool t);
1246 /// Access payload
payload() const1247 int payload() const { return _payload; }
1248 /// Set payload
payload(int i)1249 void payload(int i) { _payload = i; }
1250 /// Put current value on trail
1251 void trail();
1252 };
1253
1254 class EnvI;
1255 class CopyMap;
1256
1257 /// \brief %Let expression
1258 class Let : public Expression {
1259 friend Expression* copy(EnvI& env, CopyMap& m, Expression* e, bool followIds, bool copyFundecls,
1260 bool isFlatModel);
1261 friend class Expression;
1262
1263 protected:
1264 /// List of local declarations
1265 ASTExprVec<Expression> _let;
1266 /// Copy of original local declarations
1267 ASTExprVec<Expression> _letOrig;
1268 /// Body of the let
1269 Expression* _in;
1270
1271 public:
1272 /// The identifier of this expression type
1273 static const ExpressionId eid = E_LET;
1274 /// Constructor
1275 Let(const Location& loc, const std::vector<Expression*>& let, Expression* in);
1276 /// Recompute hash value
1277 void rehash();
1278
1279 /// Access local declarations
let() const1280 ASTExprVec<Expression> let() const { return _let; }
1281 /// Access local declarations
letOrig() const1282 ASTExprVec<Expression> letOrig() const { return _letOrig; }
1283 /// Access body
in() const1284 Expression* in() const { return _in; }
1285
1286 /// Remember current let bindings
1287 void pushbindings();
1288 /// Restore previous let bindings
1289 void popbindings();
1290 };
1291
1292 /// \brief Type-inst expression
1293 class TypeInst : public Expression {
1294 protected:
1295 /// Ranges of an array expression
1296 ASTExprVec<TypeInst> _ranges;
1297 /// Declared domain (or NULL)
1298 Expression* _domain;
1299
1300 public:
1301 /// The identifier of this expression type
1302 static const ExpressionId eid = E_TI;
1303 /// Constructor
1304 TypeInst(const Location& loc, const Type& t, const ASTExprVec<TypeInst>& ranges,
1305 Expression* domain = nullptr);
1306 /// Constructor
1307 TypeInst(const Location& loc, const Type& t, Expression* domain = nullptr);
1308
1309 /// Access ranges
ranges() const1310 ASTExprVec<TypeInst> ranges() const { return _ranges; }
1311 /// Access domain
domain() const1312 Expression* domain() const { return _domain; }
1313 //// Set domain
domain(Expression * d)1314 void domain(Expression* d) { _domain = d; }
1315
1316 /// Set ranges to \a ranges
1317 void setRanges(const std::vector<TypeInst*>& ranges);
isarray() const1318 bool isarray() const { return _ranges.size() > 0; }
1319 bool hasTiVariable() const;
1320 /// Recompute hash value
1321 void rehash();
1322 /// Check if domain is computed from right hand side of variable
computedDomain() const1323 bool computedDomain() const { return _flag1; }
1324 /// Set if domain is computed from right hand side of variable
setComputedDomain(bool b)1325 void setComputedDomain(bool b) { _flag1 = b; }
1326 /// Check if this TypeInst represents an enum
isEnum() const1327 bool isEnum() const { return _flag2; }
1328 /// Set if this TypeInst represents an enum
setIsEnum(bool b)1329 void setIsEnum(bool b) { _flag2 = b; }
1330 };
1331
1332 /**
1333 * \brief Base-class for items
1334 */
1335 class Item : public ASTNode {
1336 protected:
1337 /// Location of the item
1338 Location _loc;
1339
1340 public:
1341 /// Identifier of the concrete item type
1342 enum ItemId {
1343 II_INC = Expression::EID_END + 1,
1344 II_VD,
1345 II_ASN,
1346 II_CON,
1347 II_SOL,
1348 II_OUT,
1349 II_FUN,
1350 II_END = II_FUN
1351 };
iid() const1352 ItemId iid() const { return static_cast<ItemId>(_id); }
1353
loc() const1354 const Location& loc() const { return _loc; }
1355
1356 protected:
1357 /// Constructor
Item(const Location & loc,const ItemId & iid)1358 Item(const Location& loc, const ItemId& iid) : ASTNode(iid), _loc(loc) { _flag1 = false; }
1359
1360 public:
1361 /// Test if item is of type \a T
1362 template <class T>
isa() const1363 bool isa() const {
1364 return _id == T::iid;
1365 }
1366 /// Cast item to type \a T*
1367 template <class T>
cast()1368 T* cast() {
1369 assert(isa<T>());
1370 return static_cast<T*>(this);
1371 }
1372 /// Cast expression to type \a const T*
1373 template <class T>
cast() const1374 const T* cast() const {
1375 assert(isa<T>());
1376 return static_cast<const T*>(this);
1377 }
1378 /// Cast item to type \a T* or NULL if types do not match
1379 template <class T>
dynamicCast()1380 T* dynamicCast() {
1381 return isa<T>() ? static_cast<T*>(this) : nullptr;
1382 }
1383 /// Cast item to type \a const T* or NULL if types do not match
1384 template <class T>
dynamicCast() const1385 const T* dynamicCast() const {
1386 return isa<T>() ? static_cast<const T*>(this) : NULL;
1387 }
1388
1389 /// Cast item to type \a T*
1390 template <class T>
cast(Item * i)1391 static T* cast(Item* i) {
1392 return i == nullptr ? nullptr : i->cast<T>();
1393 }
1394 /// Cast item to type \a const T*
1395 template <class T>
cast(const Item * i)1396 static const T* cast(const Item* i) {
1397 return i == nullptr ? NULL : i->cast<T>();
1398 }
1399 /// Cast item to type \a T* or NULL if types do not match
1400 template <class T>
dynamicCast(Item * i)1401 static T* dynamicCast(Item* i) {
1402 return i == nullptr ? nullptr : i->dynamicCast<T>();
1403 }
1404 /// Cast item to type \a const T* or NULL if types do not match
1405 template <class T>
dynamicCast(const Item * i)1406 static const T* dynamicCast(const Item* i) {
1407 return i == nullptr ? NULL : i->dynamicCast<T>();
1408 }
1409
1410 /// Check if item should be removed
removed() const1411 bool removed() const { return _flag1; }
1412 /// Set flag to remove item
remove()1413 void remove() { _flag1 = true; }
1414 /// Unset remove item flag (only possible if not already removed by compact())
unremove()1415 void unremove() { _flag1 = false; }
1416
1417 /// Mark alive for garbage collection
1418 #if defined(MINIZINC_GC_STATS)
1419 static void mark(Item* item, MINIZINC_GC_STAT_ARGS);
1420 #else
1421 static void mark(Item* item);
1422 #endif
hasMark()1423 bool hasMark() { return _gcMark != 0U; }
1424 };
1425
1426 class Model;
1427
1428 /// \brief Include item
1429 class IncludeI : public Item {
1430 protected:
1431 /// Filename to include
1432 ASTString _f;
1433 /// Model for that file
1434 Model* _m;
1435
1436 public:
1437 /// The identifier of this item type
1438 static const ItemId iid = II_INC;
1439 /// Constructor
1440 IncludeI(const Location& loc, const ASTString& f);
1441 /// Access filename
f() const1442 ASTString f() const { return _f; }
1443 /// Set filename
f(const ASTString & nf)1444 void f(const ASTString& nf) { _f = nf; }
1445 /// Access model
m() const1446 Model* m() const { return _m; }
1447 /// Set the model
m(Model * m0,bool own=true)1448 void m(Model* m0, bool own = true) {
1449 assert(_m == nullptr || m0 == nullptr);
1450 _m = m0;
1451 _flag2 = own;
1452 }
own() const1453 bool own() const { return _flag2; }
1454 };
1455
1456 /// \brief Variable declaration item
1457 class VarDeclI : public Item {
1458 protected:
1459 /// The declaration expression
1460 VarDecl* _e;
1461
1462 public:
1463 /// The identifier of this item type
1464 static const ItemId iid = II_VD;
1465 /// Constructor
1466 VarDeclI(const Location& loc, VarDecl* e);
1467 /// Access expression
e() const1468 VarDecl* e() const { return _e; }
1469 /// Set expression
e(VarDecl * vd)1470 void e(VarDecl* vd) { _e = vd; }
1471 /// Flag used during compilation
flag() const1472 bool flag() const { return _flag2; }
1473 /// Set flag used during compilation
flag(bool b)1474 void flag(bool b) { _flag2 = b; }
1475 };
1476
1477 /// \brief Assign item
1478 class AssignI : public Item {
1479 protected:
1480 /// Identifier of variable to assign to
1481 ASTString _id;
1482 /// Expression to assign to the variable
1483 Expression* _e;
1484 /// Declaration of the variable to assign to
1485 VarDecl* _decl;
1486
1487 public:
1488 /// The identifier of this item type
1489 static const ItemId iid = II_ASN;
1490 /// Constructor
1491 AssignI(const Location& loc, const std::string& id, Expression* e);
1492 /// Constructor
1493 AssignI(const Location& loc, const ASTString& id, Expression* e);
1494 /// Access identifier
id() const1495 ASTString id() const { return _id; }
1496 /// Access expression
e() const1497 Expression* e() const { return _e; }
1498 /// Set expression
e(Expression * e0)1499 void e(Expression* e0) { _e = e0; }
1500 /// Access declaration
decl() const1501 VarDecl* decl() const { return _decl; }
1502 /// Set declaration
decl(VarDecl * d)1503 void decl(VarDecl* d) { _decl = d; }
1504 };
1505
1506 /// \brief Constraint item
1507 class ConstraintI : public Item {
1508 protected:
1509 /// Constraint expression
1510 Expression* _e;
1511
1512 public:
1513 /// The identifier of this item type
1514 static const ItemId iid = II_CON;
1515 /// Constructor
1516 ConstraintI(const Location& loc, Expression* e);
1517 /// Access expression
e() const1518 Expression* e() const { return _e; }
1519 /// Set expression
e(Expression * e0)1520 void e(Expression* e0) { _e = e0; }
1521 /// Flag used during compilation
flag() const1522 bool flag() const { return _flag2; }
1523 /// Set flag used during compilation
flag(bool b)1524 void flag(bool b) { _flag2 = b; }
1525 };
1526
1527 /// \brief Solve item
1528 class SolveI : public Item {
1529 protected:
1530 /// Solve item annotation
1531 Annotation _ann;
1532 /// Expression for minimisation/maximisation (or NULL)
1533 Expression* _e;
1534 /// Constructor
1535 SolveI(const Location& loc, Expression* e);
1536
1537 public:
1538 /// The identifier of this item type
1539 static const ItemId iid = II_SOL;
1540 /// Type of solving
1541 enum SolveType { ST_SAT, ST_MIN, ST_MAX };
1542 /// Allocate solve satisfy item
1543 static SolveI* sat(const Location& loc);
1544 /// Allocate solve minimize item
1545 static SolveI* min(const Location& loc, Expression* e);
1546 /// Allocate solve maximize item
1547 static SolveI* max(const Location& loc, Expression* e);
1548 /// Access solve annotation
ann() const1549 const Annotation& ann() const { return _ann; }
1550 /// Access solve annotation
ann()1551 Annotation& ann() { return _ann; }
1552 /// Access expression for optimisation
e() const1553 Expression* e() const { return _e; }
1554 /// Set expression for optimisation
e(Expression * e0)1555 void e(Expression* e0) { _e = e0; }
1556 /// Return type of solving
1557 SolveType st() const;
1558 /// Set type of solving
1559 void st(SolveType s);
1560 };
1561
1562 /// \brief Output item
1563 class OutputI : public Item {
1564 protected:
1565 /// Expression to output
1566 Expression* _e;
1567
1568 public:
1569 /// The identifier of this item type
1570 static const ItemId iid = II_OUT;
1571 /// Constructor
1572 OutputI(const Location& loc, Expression* e);
1573 /// Access expression
e() const1574 Expression* e() const { return _e; }
1575 /// Update expression
e(Expression * e)1576 void e(Expression* e) { _e = e; }
1577 };
1578
1579 class EnvI;
1580
1581 /// \brief Function declaration item
1582 class FunctionI : public Item {
1583 protected:
1584 /// Identifier of this function
1585 ASTString _id;
1586 /// Type-inst of the return value
1587 TypeInst* _ti;
1588 /// List of parameter declarations
1589 ASTExprVec<VarDecl> _params;
1590 /// Annotation
1591 Annotation _ann;
1592 /// Function body (or NULL)
1593 Expression* _e;
1594 /// Whether function is defined in the standard library
1595 bool _fromStdLib;
1596
1597 public:
1598 /// The identifier of this item type
1599 static const ItemId iid = II_FUN;
1600
1601 /// Type of builtin expression-valued functions
1602 typedef Expression* (*builtin_e)(EnvI&, Call*);
1603 /// Type of builtin int-valued functions
1604 typedef IntVal (*builtin_i)(EnvI&, Call*);
1605 /// Type of builtin bool-valued functions
1606 typedef bool (*builtin_b)(EnvI&, Call*);
1607 /// Type of builtin float-valued functions
1608 typedef FloatVal (*builtin_f)(EnvI&, Call*);
1609 /// Type of builtin set-valued functions
1610 typedef IntSetVal* (*builtin_s)(EnvI&, Call*);
1611 /// Type of builtin string-valued functions
1612 typedef std::string (*builtin_str)(EnvI&, Call*);
1613
1614 /// Builtin functions (or NULL)
1615 struct {
1616 builtin_e e;
1617 builtin_i i;
1618 builtin_f f;
1619 builtin_b b;
1620 builtin_s s;
1621 builtin_str str;
1622 } builtins;
1623
1624 /// Constructor
1625 FunctionI(const Location& loc, const std::string& id, TypeInst* ti,
1626 const std::vector<VarDecl*>& params, Expression* e = nullptr, bool from_stdlib = false);
1627 /// Constructor
1628 FunctionI(const Location& loc, const ASTString& id, TypeInst* ti,
1629 const ASTExprVec<VarDecl>& params, Expression* e = nullptr, bool from_stdlib = false);
1630
1631 /// Access identifier
id() const1632 ASTString id() const { return _id; }
1633 /// Access TypeInst
ti() const1634 TypeInst* ti() const { return _ti; }
1635 /// Access parameters
params() const1636 ASTExprVec<VarDecl> params() const { return _params; }
1637 /// Access annotation
ann() const1638 const Annotation& ann() const { return _ann; }
1639 /// Access annotation
ann()1640 Annotation& ann() { return _ann; }
1641 /// Access body
e() const1642 Expression* e() const { return _e; }
1643 /// Set body
e(Expression * b)1644 void e(Expression* b) { _e = b; }
1645
1646 /** \brief Compute return type given argument types \a ta
1647 */
1648 Type rtype(EnvI& env, const std::vector<Expression*>& ta, bool strictEnums);
1649 /** \brief Compute return type given argument types \a ta
1650 */
1651 Type rtype(EnvI& env, const std::vector<Type>& ta, bool strictEnums);
1652 /** \brief Compute expected type of argument \a n given argument types \a ta
1653 */
1654 Type argtype(EnvI& env, const std::vector<Expression*>& ta, unsigned int n) const;
1655
1656 /// Return whether function is defined in the standard library
fromStdLib() const1657 bool fromStdLib() const { return _fromStdLib; };
1658 };
1659
1660 /**
1661 * \brief Visitor for expressions
1662 *
1663 * This class implements no-ops for all expression types.
1664 * Override the methods to implement custom behaviour.
1665 */
1666 class EVisitor {
1667 public:
1668 /// Visit integer literal
vIntLit(const IntLit &)1669 void vIntLit(const IntLit& /*il*/) {}
1670 /// Visit floating point literal
vFloatLit(const FloatLit &)1671 void vFloatLit(const FloatLit& /*fl*/) {}
1672 /// Visit Boolean literal
vBoolLit(const BoolLit &)1673 void vBoolLit(const BoolLit& /*bl*/) {}
1674 /// Visit set literal
vSetLit(const SetLit &)1675 void vSetLit(const SetLit& /*sl*/) {}
1676 /// Visit string literal
vStringLit(const StringLit &)1677 void vStringLit(const StringLit& /*sl*/) {}
1678 /// Visit identifier
vId(const Id &)1679 void vId(const Id& /*ident*/) {}
1680 /// Visit anonymous variable
vAnonVar(const AnonVar &)1681 void vAnonVar(const AnonVar& /*x*/) {}
1682 /// Visit array literal
vArrayLit(const ArrayLit &)1683 void vArrayLit(const ArrayLit& /*al*/) {}
1684 /// Visit array access
vArrayAccess(const ArrayAccess &)1685 void vArrayAccess(const ArrayAccess& /*aa*/) {}
1686 /// Visit array comprehension
vComprehension(const Comprehension &)1687 void vComprehension(const Comprehension& /*c*/) {}
1688 /// Visit array comprehension (only generator \a gen_i)
vComprehensionGenerator(const Comprehension &,int)1689 void vComprehensionGenerator(const Comprehension& /*c*/, int /*gen_i*/) {}
1690 /// Visit if-then-else
vITE(const ITE &)1691 void vITE(const ITE& /*ite*/) {}
1692 /// Visit binary operator
vBinOp(const BinOp &)1693 void vBinOp(const BinOp& /*bo*/) {}
1694 /// Visit unary operator
vUnOp(const UnOp &)1695 void vUnOp(const UnOp& /*uo*/) {}
1696 /// Visit call
vCall(const Call &)1697 void vCall(const Call& /*c*/) {}
1698 /// Visit let
vLet(const Let &)1699 void vLet(const Let& /*let*/) {}
1700 /// Visit variable declaration
vVarDecl(const VarDecl &)1701 void vVarDecl(const VarDecl& /*vd*/) {}
1702 /// Visit type inst
vTypeInst(const TypeInst &)1703 void vTypeInst(const TypeInst& /*ti*/) {}
1704 /// Visit TIId
vTIId(const TIId &)1705 void vTIId(const TIId& /*tiid*/) {}
1706 /// Determine whether to enter node
enter(Expression *)1707 static bool enter(Expression* /*e*/) { return true; }
1708 /// Exit node after processing has finished
exit(Expression *)1709 void exit(Expression* /*e*/) {}
1710 };
1711
1712 /// Statically allocated constants
1713 class Constants : public GCMarker {
1714 public:
1715 /// Literal true
1716 BoolLit* literalTrue;
1717 /// Variable bound to true
1718 VarDecl* varTrue;
1719 /// Literal false
1720 BoolLit* literalFalse;
1721 /// Variable bound to false
1722 VarDecl* varFalse;
1723 /// Special variable to signal compiler to ignore result
1724 VarDecl* varIgnore;
1725 /// Infinite set
1726 SetLit* infinity;
1727 /// Function item used to keep track of redefined variables
1728 FunctionI* varRedef;
1729 /// Literal absent value
1730 Expression* absent;
1731 /// Identifiers for builtins
1732 struct {
1733 ASTString forall;
1734 ASTString forallReif;
1735 ASTString exists;
1736 ASTString clause;
1737 ASTString bool2int;
1738 ASTString int2float;
1739 ASTString bool2float;
1740 ASTString assert;
1741 ASTString mzn_deprecate; // NOLINT(readability-identifier-naming)
1742 ASTString mzn_symmetry_breaking_constraint; // NOLINT(readability-identifier-naming)
1743 ASTString mzn_redundant_constraint; // NOLINT(readability-identifier-naming)
1744 ASTString trace;
1745
1746 ASTString sum;
1747 ASTString lin_exp; // NOLINT(readability-identifier-naming)
1748 ASTString element;
1749
1750 ASTString show;
1751 ASTString fix;
1752 ASTString output;
1753
1754 struct {
1755 ASTString lin_eq; // NOLINT(readability-identifier-naming)
1756 ASTString lin_le; // NOLINT(readability-identifier-naming)
1757 ASTString lin_ne; // NOLINT(readability-identifier-naming)
1758 ASTString plus;
1759 ASTString minus;
1760 ASTString times;
1761 ASTString div;
1762 ASTString mod;
1763 ASTString lt;
1764 ASTString le;
1765 ASTString gt;
1766 ASTString ge;
1767 ASTString eq;
1768 ASTString ne;
1769 } int_; // NOLINT(readability-identifier-naming)
1770
1771 struct {
1772 ASTString lin_eq; // NOLINT(readability-identifier-naming)
1773 ASTString lin_le; // NOLINT(readability-identifier-naming)
1774 ASTString lin_ne; // NOLINT(readability-identifier-naming)
1775 ASTString plus;
1776 ASTString minus;
1777 ASTString times;
1778 ASTString div;
1779 ASTString mod;
1780 ASTString lt;
1781 ASTString le;
1782 ASTString gt;
1783 ASTString ge;
1784 ASTString eq;
1785 ASTString ne;
1786 } int_reif; // NOLINT(readability-identifier-naming)
1787
1788 struct {
1789 ASTString lin_eq; // NOLINT(readability-identifier-naming)
1790 ASTString lin_le; // NOLINT(readability-identifier-naming)
1791 ASTString lin_lt; // NOLINT(readability-identifier-naming)
1792 ASTString lin_ne; // NOLINT(readability-identifier-naming)
1793 ASTString plus;
1794 ASTString minus;
1795 ASTString times;
1796 ASTString div;
1797 ASTString mod;
1798 ASTString lt;
1799 ASTString le;
1800 ASTString gt;
1801 ASTString ge;
1802 ASTString eq;
1803 ASTString ne;
1804 ASTString in;
1805 ASTString dom;
1806 } float_; // NOLINT(readability-identifier-naming)
1807
1808 struct {
1809 ASTString lin_eq; // NOLINT(readability-identifier-naming)
1810 ASTString lin_le; // NOLINT(readability-identifier-naming)
1811 ASTString lin_lt; // NOLINT(readability-identifier-naming)
1812 ASTString lin_ne; // NOLINT(readability-identifier-naming)
1813 ASTString plus;
1814 ASTString minus;
1815 ASTString times;
1816 ASTString div;
1817 ASTString mod;
1818 ASTString lt;
1819 ASTString le;
1820 ASTString gt;
1821 ASTString ge;
1822 ASTString eq;
1823 ASTString ne;
1824 ASTString in;
1825 } float_reif; // NOLINT(readability-identifier-naming)
1826
1827 ASTString bool_eq; // NOLINT(readability-identifier-naming)
1828 ASTString bool_eq_reif; // NOLINT(readability-identifier-naming)
1829 ASTString bool_not; // NOLINT(readability-identifier-naming)
1830 ASTString array_bool_or; // NOLINT(readability-identifier-naming)
1831 ASTString array_bool_and; // NOLINT(readability-identifier-naming)
1832 ASTString bool_clause; // NOLINT(readability-identifier-naming)
1833 ASTString bool_clause_reif; // NOLINT(readability-identifier-naming)
1834 ASTString bool_xor; // NOLINT(readability-identifier-naming)
1835 ASTString set_eq; // NOLINT(readability-identifier-naming)
1836 ASTString set_in; // NOLINT(readability-identifier-naming)
1837 ASTString set_subset; // NOLINT(readability-identifier-naming)
1838 ASTString set_card; // NOLINT(readability-identifier-naming)
1839 ASTString pow;
1840
1841 ASTString mzn_set_in_internal; // NOLINT(readability-identifier-naming)
1842
1843 ASTString introduced_var; // NOLINT(readability-identifier-naming)
1844 ASTString anonEnumFromStrings;
1845 } ids;
1846
1847 /// Identifiers for Boolean contexts
1848 struct {
1849 Id* root;
1850 Id* pos;
1851 Id* neg;
1852 Id* mix;
1853 } ctx;
1854 /// Common annotations
1855 struct {
1856 Id* output_var; // NOLINT(readability-identifier-naming)
1857 ASTString output_array; // NOLINT(readability-identifier-naming)
1858 Id* add_to_output; // NOLINT(readability-identifier-naming)
1859 Id* output_only; // NOLINT(readability-identifier-naming)
1860 Id* mzn_check_var; // NOLINT(readability-identifier-naming)
1861 ASTString mzn_check_enum_var; // NOLINT(readability-identifier-naming)
1862 Id* is_defined_var; // NOLINT(readability-identifier-naming)
1863 ASTString defines_var; // NOLINT(readability-identifier-naming)
1864 Id* is_reverse_map; // NOLINT(readability-identifier-naming)
1865 Id* promise_total; // NOLINT(readability-identifier-naming)
1866 Id* maybe_partial; // NOLINT(readability-identifier-naming)
1867 ASTString doc_comment; // NOLINT(readability-identifier-naming)
1868 ASTString mzn_path; // NOLINT(readability-identifier-naming)
1869 ASTString is_introduced; // NOLINT(readability-identifier-naming)
1870 Id* user_cut; // NOLINT(readability-identifier-naming) // MIP
1871 Id* lazy_constraint; // NOLINT(readability-identifier-naming) // MIP
1872 Id* mzn_break_here; // NOLINT(readability-identifier-naming)
1873 Id* rhs_from_assignment; // NOLINT(readability-identifier-naming)
1874 Id* domain_change_constraint; // NOLINT(readability-identifier-naming)
1875 ASTString mzn_deprecated; // NOLINT(readability-identifier-naming)
1876 Id* mzn_was_undefined; // NOLINT(readability-identifier-naming)
1877 Id* array_check_form; // NOLINT(readability-identifier-naming)
1878 } ann;
1879
1880 /// Command line options
1881 struct { /// basic MiniZinc command line options
1882 ASTString cmdlineData_str; // NOLINT(readability-identifier-naming)
1883 ASTString cmdlineData_short_str; // NOLINT(readability-identifier-naming)
1884 ASTString datafile_str; // NOLINT(readability-identifier-naming)
1885 ASTString datafile_short_str; // NOLINT(readability-identifier-naming)
1886 ASTString globalsDir_str; // NOLINT(readability-identifier-naming)
1887 ASTString globalsDir_alt_str; // NOLINT(readability-identifier-naming)
1888 ASTString globalsDir_short_str; // NOLINT(readability-identifier-naming)
1889 ASTString help_str; // NOLINT(readability-identifier-naming)
1890 ASTString help_short_str; // NOLINT(readability-identifier-naming)
1891 ASTString ignoreStdlib_str; // NOLINT(readability-identifier-naming)
1892 ASTString include_str; // NOLINT(readability-identifier-naming)
1893 ASTString inputFromStdin_str; // NOLINT(readability-identifier-naming)
1894 ASTString instanceCheckOnly_str; // NOLINT(readability-identifier-naming)
1895 ASTString no_optimize_str; // NOLINT(readability-identifier-naming)
1896 ASTString no_optimize_alt_str; // NOLINT(readability-identifier-naming)
1897 ASTString no_outputOzn_str; // NOLINT(readability-identifier-naming)
1898 ASTString no_outputOzn_short_str; // NOLINT(readability-identifier-naming)
1899 ASTString no_typecheck_str; // NOLINT(readability-identifier-naming)
1900 ASTString newfzn_str; // NOLINT(readability-identifier-naming)
1901 ASTString outputBase_str; // NOLINT(readability-identifier-naming)
1902 ASTString outputFznToStdout_str; // NOLINT(readability-identifier-naming)
1903 ASTString outputFznToStdout_alt_str; // NOLINT(readability-identifier-naming)
1904 ASTString outputOznToFile_str; // NOLINT(readability-identifier-naming)
1905 ASTString outputOznToStdout_str; // NOLINT(readability-identifier-naming)
1906 ASTString outputFznToFile_str; // NOLINT(readability-identifier-naming)
1907 ASTString outputFznToFile_alt_str; // NOLINT(readability-identifier-naming)
1908 ASTString outputFznToFile_short_str; // NOLINT(readability-identifier-naming)
1909 ASTString rangeDomainsOnly_str; // NOLINT(readability-identifier-naming)
1910 ASTString statistics_str; // NOLINT(readability-identifier-naming)
1911 ASTString statistics_short_str; // NOLINT(readability-identifier-naming)
1912 ASTString stdlib_str; // NOLINT(readability-identifier-naming)
1913 ASTString verbose_str; // NOLINT(readability-identifier-naming)
1914 ASTString verbose_short_str; // NOLINT(readability-identifier-naming)
1915 ASTString version_str; // NOLINT(readability-identifier-naming)
1916 ASTString werror_str; // NOLINT(readability-identifier-naming)
1917
1918 struct {
1919 ASTString all_sols_str; // NOLINT(readability-identifier-naming)
1920 ASTString fzn_solver_str; // NOLINT(readability-identifier-naming)
1921 } solver;
1922
1923 } cli;
1924
1925 /// options strings to find setting in Options map
1926 struct {
1927 ASTString cmdlineData;
1928 ASTString datafile;
1929 ASTString datafiles;
1930 ASTString fznToStdout;
1931 ASTString fznToFile;
1932 ASTString globalsDir;
1933 ASTString ignoreStdlib;
1934 ASTString includeDir;
1935 ASTString includePaths;
1936 ASTString instanceCheckOnly;
1937 ASTString inputFromStdin;
1938 ASTString model;
1939 ASTString newfzn;
1940 ASTString noOznOutput;
1941 ASTString optimize;
1942 ASTString outputBase;
1943 ASTString oznToFile;
1944 ASTString oznToStdout;
1945 ASTString rangeDomainsOnly;
1946 ASTString statistics;
1947 ASTString stdlib;
1948 ASTString typecheck;
1949 ASTString verbose;
1950 ASTString werror;
1951
1952 struct {
1953 ASTString allSols;
1954 ASTString numSols;
1955 ASTString threads;
1956 ASTString fzn_solver; // NOLINT(readability-identifier-naming)
1957 ASTString fzn_flags; // NOLINT(readability-identifier-naming)
1958 ASTString fzn_flag; // NOLINT(readability-identifier-naming)
1959 ASTString fzn_time_limit_ms; // NOLINT(readability-identifier-naming)
1960 ASTString fzn_sigint; // NOLINT(readability-identifier-naming)
1961 } solver;
1962
1963 } opts;
1964
1965 /// categories of the command line interface options
1966 struct {
1967 ASTString general;
1968 ASTString io;
1969 ASTString solver;
1970 ASTString translation;
1971 } cli_cat; // NOLINT(readability-identifier-naming)
1972
1973 /// Keep track of allocated integer literals
1974 std::unordered_map<IntVal, WeakRef> integerMap;
1975 /// Keep track of allocated float literals
1976 std::unordered_map<FloatVal, WeakRef> floatMap;
1977 /// Constructor
1978 Constants();
1979 /// Return shared BoolLit
boollit(bool b)1980 BoolLit* boollit(bool b) { return b ? literalTrue : literalFalse; }
1981 static const int max_array_size = std::numeric_limits<int>::max() / 2;
1982
1983 void mark(MINIZINC_GC_STAT_ARGS) override;
1984 };
1985
1986 /// Return static instance
1987 Constants& constants();
1988
1989 } // namespace MiniZinc
1990
1991 #include <minizinc/ast.hpp>
1992