A set of benchmarks to compare a new prototype MiniZinc implementation
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#ifndef __MINIZINC_TYPE_HH__
13#define __MINIZINC_TYPE_HH__
14
15#include <cassert>
16#include <sstream>
17#include <string>
18
19namespace MiniZinc {
20
21class EnvI;
22
23/// Type of a MiniZinc expression
24class Type {
25public:
26 /// Type-inst
27 enum TypeInst { TI_PAR, TI_VAR };
28 /// Basic type
29 enum BaseType { BT_BOOL, BT_INT, BT_FLOAT, BT_STRING, BT_ANN, BT_TOP, BT_BOT, BT_UNKNOWN };
30 /// Whether the expression is plain or set
31 enum SetType { ST_PLAIN, ST_SET };
32 /// Whether the expression is normal or optional
33 enum OptType { OT_PRESENT, OT_OPTIONAL };
34 /// Whether the par expression contains a var argument
35 enum ContainsVarType { CV_NO, CV_YES };
36
37private:
38 unsigned int _ti : 1;
39 unsigned int _bt : 4;
40 unsigned int _st : 1;
41 unsigned int _ot : 1;
42 unsigned int _cv : 1;
43 /** \brief Enumerated type identifier
44 * This is an index into a table in the Env. It is currently limited to
45 * 4095 different enumerated type identifiers.
46 * For a non-array type, this maps directly to the identity of the enum.
47 * For an array type, it maps to a tuple of enum identities.
48 */
49 unsigned int _enumId : 12;
50 /// Number of array dimensions
51 int _dim : 7;
52
53public:
54 /// Default constructor
55 Type(void)
56 : _ti(TI_PAR),
57 _bt(BT_UNKNOWN),
58 _st(ST_PLAIN),
59 _ot(OT_PRESENT),
60 _cv(CV_NO),
61 _enumId(0),
62 _dim(0) {}
63
64 /// Access type-inst
65 TypeInst ti(void) const { return static_cast<TypeInst>(_ti); }
66 /// Set type-inst
67 void ti(const TypeInst& t) {
68 _ti = t;
69 if (t == TI_VAR) _cv = CV_YES;
70 }
71
72 /// Access basic type
73 BaseType bt(void) const { return static_cast<BaseType>(_bt); }
74 /// Set basic type
75 void bt(const BaseType& b) { _bt = b; }
76
77 /// Access set type
78 SetType st(void) const { return static_cast<SetType>(_st); }
79 /// Set set type
80 void st(const SetType& s) { _st = s; }
81
82 /// Access opt type
83 OptType ot(void) const { return static_cast<OptType>(_ot); }
84 /// Set opt type
85 void ot(const OptType& o) { _ot = o; }
86
87 /// Access var-in-par type
88 bool cv(void) const { return static_cast<ContainsVarType>(_cv) == CV_YES; }
89 /// Set var-in-par type
90 void cv(bool b) { _cv = b ? CV_YES : CV_NO; }
91
92 /// Access enum identifier
93 unsigned int enumId(void) const { return _enumId; }
94 /// Set enum identifier
95 void enumId(unsigned int eid) { _enumId = eid; }
96
97 /// Access dimensions
98 int dim(void) const { return _dim; }
99 /// Set dimensions
100 void dim(int d) {
101 _dim = d;
102 assert(_dim == d);
103 }
104
105protected:
106 /// Constructor
107 Type(const TypeInst& ti, const BaseType& bt, const SetType& st, unsigned int enumId, int dim)
108 : _ti(ti),
109 _bt(bt),
110 _st(st),
111 _ot(OT_PRESENT),
112 _cv(ti == TI_VAR ? CV_YES : CV_NO),
113 _enumId(enumId),
114 _dim(dim) {}
115
116public:
117 static Type parint(int dim = 0) { return Type(TI_PAR, BT_INT, ST_PLAIN, 0, dim); }
118 static Type parenum(unsigned int enumId, int dim = 0) {
119 return Type(TI_PAR, BT_INT, ST_PLAIN, enumId, dim);
120 }
121 static Type parbool(int dim = 0) { return Type(TI_PAR, BT_BOOL, ST_PLAIN, 0, dim); }
122 static Type parfloat(int dim = 0) { return Type(TI_PAR, BT_FLOAT, ST_PLAIN, 0, dim); }
123 static Type parstring(int dim = 0) { return Type(TI_PAR, BT_STRING, ST_PLAIN, 0, dim); }
124 static Type partop(int dim = 0) { return Type(TI_PAR, BT_TOP, ST_PLAIN, 0, dim); }
125 static Type ann(int dim = 0) { return Type(TI_PAR, BT_ANN, ST_PLAIN, 0, dim); }
126 static Type parsetint(int dim = 0) { return Type(TI_PAR, BT_INT, ST_SET, 0, dim); }
127 static Type parsetenum(unsigned int enumId, int dim = 0) {
128 return Type(TI_PAR, BT_INT, ST_SET, enumId, dim);
129 }
130 static Type parsetbool(int dim = 0) { return Type(TI_PAR, BT_BOOL, ST_SET, 0, dim); }
131 static Type parsetfloat(int dim = 0) { return Type(TI_PAR, BT_FLOAT, ST_SET, 0, dim); }
132 static Type parsetstring(int dim = 0) { return Type(TI_PAR, BT_STRING, ST_SET, 0, dim); }
133 static Type varint(int dim = 0) { return Type(TI_VAR, BT_INT, ST_PLAIN, 0, dim); }
134 static Type varenumint(unsigned int enumId, int dim = 0) {
135 return Type(TI_VAR, BT_INT, ST_PLAIN, enumId, dim);
136 }
137 static Type varbool(int dim = 0) { return Type(TI_VAR, BT_BOOL, ST_PLAIN, 0, dim); }
138 static Type varfloat(int dim = 0) { return Type(TI_VAR, BT_FLOAT, ST_PLAIN, 0, dim); }
139 static Type varsetint(int dim = 0) { return Type(TI_VAR, BT_INT, ST_SET, 0, dim); }
140 static Type varbot(int dim = 0) { return Type(TI_VAR, BT_BOT, ST_PLAIN, 0, dim); }
141 static Type bot(int dim = 0) { return Type(TI_PAR, BT_BOT, ST_PLAIN, 0, dim); }
142 static Type top(int dim = 0) { return Type(TI_PAR, BT_TOP, ST_PLAIN, 0, dim); }
143 static Type vartop(int dim = 0) { return Type(TI_VAR, BT_TOP, ST_PLAIN, 0, dim); }
144 static Type optvartop(int dim = 0) {
145 Type t(TI_VAR, BT_TOP, ST_PLAIN, 0, dim);
146 t._ot = OT_OPTIONAL;
147 return t;
148 }
149 static Type optpartop(int dim = 0) {
150 Type t(TI_PAR, BT_TOP, ST_PLAIN, 0, dim);
151 t._ot = OT_OPTIONAL;
152 return t;
153 }
154
155 static Type unboxedint;
156 static Type unboxedfloat;
157
158 bool isunknown(void) const { return _bt == BT_UNKNOWN; }
159 bool isplain(void) const { return _dim == 0 && _st == ST_PLAIN && _ot == OT_PRESENT; }
160 bool isint(void) const { return _dim == 0 && _st == ST_PLAIN && _bt == BT_INT; }
161 bool isbot(void) const { return _bt == BT_BOT; }
162 bool isfloat(void) const { return _dim == 0 && _st == ST_PLAIN && _bt == BT_FLOAT; }
163 bool isbool(void) const { return _dim == 0 && _st == ST_PLAIN && _bt == BT_BOOL; }
164 bool isstring(void) const { return isplain() && _bt == BT_STRING; }
165 bool isvar(void) const { return _ti != TI_PAR; }
166 bool isvarbool(void) const {
167 return _ti == TI_VAR && _dim == 0 && _st == ST_PLAIN && _bt == BT_BOOL && _ot == OT_PRESENT;
168 }
169 bool isvarfloat(void) const {
170 return _ti == TI_VAR && _dim == 0 && _st == ST_PLAIN && _bt == BT_FLOAT && _ot == OT_PRESENT;
171 }
172 bool isvarint(void) const {
173 return _ti == TI_VAR && _dim == 0 && _st == ST_PLAIN && _bt == BT_INT && _ot == OT_PRESENT;
174 }
175 bool ispar(void) const { return _ti == TI_PAR; }
176 bool isopt(void) const { return _ot == OT_OPTIONAL; }
177 bool ispresent(void) const { return _ot == OT_PRESENT; }
178 bool is_set(void) const { return _dim == 0 && _st == ST_SET; }
179 bool isintset(void) const { return is_set() && (_bt == BT_INT || _bt == BT_BOT); }
180 bool isboolset(void) const { return is_set() && (_bt == BT_BOOL || _bt == BT_BOT); }
181 bool isfloatset(void) const { return is_set() && (_bt == BT_FLOAT || _bt == BT_BOT); }
182 bool isann(void) const { return isplain() && _bt == BT_ANN; }
183 bool isintarray(void) const {
184 return _dim == 1 && _st == ST_PLAIN && _ot == OT_PRESENT && _bt == BT_INT;
185 }
186 bool isboolarray(void) const {
187 return _dim == 1 && _st == ST_PLAIN && _ot == OT_PRESENT && _bt == BT_BOOL;
188 }
189 bool isintsetarray(void) const { return _dim == 1 && _st == ST_SET && _bt == BT_INT; }
190
191 bool operator==(const Type& t) const {
192 return _ti == t._ti && _bt == t._bt && _st == t._st && _ot == t._ot && _dim == t._dim;
193 }
194 bool operator!=(const Type& t) const { return !this->operator==(t); }
195 // protected:
196
197 int toInt(void) const {
198 return +((1 - static_cast<int>(_st)) << 28) + (static_cast<int>(_bt) << 24) +
199 (static_cast<int>(_ti) << 21) + (static_cast<int>(_ot) << 20) +
200 (static_cast<int>(_enumId) << 8) + (_dim == -1 ? 1 : (_dim == 0 ? 0 : _dim + 1));
201 }
202 static Type fromInt(int i) {
203 Type t;
204 t._st = 1 - static_cast<SetType>((i >> 28) & 0x1);
205 t._bt = static_cast<BaseType>((i >> 24) & 0xF);
206 t._ti = static_cast<TypeInst>((i >> 21) & 0x7);
207 t._ot = static_cast<OptType>((i >> 20) & 0x1);
208 t._enumId = static_cast<unsigned int>((i >> 8) & 0xFFF);
209 int dim = (i & 0x7F);
210 t._dim = (dim == 0 ? 0 : (dim == 1 ? -1 : dim - 1));
211 return t;
212 }
213 std::string toString(EnvI& env) const;
214 std::string nonEnumToString(void) const;
215
216public:
217 /// Check if \a bt0 is a subtype of \a bt1
218 static bool bt_subtype(const Type& t0, const Type& t1, bool strictEnums) {
219 if (t0.bt() == t1.bt() &&
220 (!strictEnums || t0.dim() != 0 || (t0.enumId() == t1.enumId() || t1.enumId() == 0)))
221 return true;
222 switch (t0.bt()) {
223 case BT_BOOL:
224 return (t1.bt() == BT_INT || t1.bt() == BT_FLOAT);
225 case BT_INT:
226 return t1.bt() == BT_FLOAT;
227 default:
228 return false;
229 }
230 }
231
232 /// Check if this type is a subtype of \a t
233 bool isSubtypeOf(const Type& t, bool strictEnums) const {
234 if (_dim == 0 && t._dim != 0 && _st == ST_SET && t._st == ST_PLAIN &&
235 (bt() == BT_BOT || bt_subtype(*this, t, false) || t.bt() == BT_TOP) && _ti == TI_PAR &&
236 (_ot == OT_PRESENT || _ot == t._ot))
237 return true;
238 // either same dimension or t has variable dimension
239 if (_dim != t._dim && (_dim == 0 || t._dim != -1)) return false;
240 // same type, this is present or both optional
241 if (_ti == t._ti && bt_subtype(*this, t, strictEnums) && _st == t._st)
242 return _ot == OT_PRESENT || _ot == t._ot;
243 // this is par other than that same type as t
244 if (_ti == TI_PAR && bt_subtype(*this, t, strictEnums) && _st == t._st)
245 return _ot == OT_PRESENT || _ot == t._ot;
246 if (_ti == TI_PAR && t._bt == BT_BOT) return true;
247 if ((_ti == t._ti || _ti == TI_PAR) && _bt == BT_BOT && (_st == t._st || _st == ST_PLAIN))
248 return _ot == OT_PRESENT || _ot == t._ot;
249 if (t._bt == BT_TOP && (_ot == OT_PRESENT || _ot == t._ot) &&
250 (t._st == ST_PLAIN || _st == t._st) && (_ti == TI_PAR || t._ti == TI_VAR))
251 return true;
252 return false;
253 }
254
255 /// Compare types
256 int cmp(const Type& t) const { return toInt() < t.toInt() ? -1 : (toInt() > t.toInt() ? 1 : 0); }
257};
258
259}; // namespace MiniZinc
260
261#endif