1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Morgan Deters, Tim King |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS |
8 |
|
* in the top-level source directory and their institutional affiliations. |
9 |
|
* All rights reserved. See the file COPYING in the top-level source |
10 |
|
* directory for licensing information. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* Reference-counted encapsulation of a pointer to node information. |
14 |
|
*/ |
15 |
|
#include "expr/type_node.h" |
16 |
|
|
17 |
|
#include <vector> |
18 |
|
|
19 |
|
#include "expr/datatype_index.h" |
20 |
|
#include "expr/dtype_cons.h" |
21 |
|
#include "expr/node_manager_attributes.h" |
22 |
|
#include "expr/type_properties.h" |
23 |
|
#include "options/base_options.h" |
24 |
|
#include "options/quantifiers_options.h" |
25 |
|
#include "theory/type_enumerator.h" |
26 |
|
#include "util/bitvector.h" |
27 |
|
#include "util/cardinality.h" |
28 |
|
|
29 |
|
using namespace std; |
30 |
|
|
31 |
|
namespace cvc5 { |
32 |
|
|
33 |
9837 |
TypeNode TypeNode::s_null( &expr::NodeValue::null() ); |
34 |
|
|
35 |
2 |
TypeNode TypeNode::substitute( |
36 |
|
const TypeNode& type, |
37 |
|
const TypeNode& replacement, |
38 |
|
std::unordered_map<TypeNode, TypeNode>& cache) const |
39 |
|
{ |
40 |
|
// in cache? |
41 |
2 |
std::unordered_map<TypeNode, TypeNode>::const_iterator i = cache.find(*this); |
42 |
2 |
if(i != cache.end()) { |
43 |
|
return (*i).second; |
44 |
|
} |
45 |
|
|
46 |
|
// otherwise compute |
47 |
4 |
NodeBuilder nb(getKind()); |
48 |
2 |
if(getMetaKind() == kind::metakind::PARAMETERIZED) { |
49 |
|
// push the operator |
50 |
|
nb << TypeNode(d_nv->d_children[0]); |
51 |
|
} |
52 |
6 |
for (TypeNode::const_iterator j = begin(), iend = end(); j != iend; ++j) |
53 |
|
{ |
54 |
4 |
if (*j == type) |
55 |
|
{ |
56 |
4 |
nb << replacement; |
57 |
|
} |
58 |
|
else |
59 |
|
{ |
60 |
|
(*j).substitute(type, replacement); |
61 |
|
} |
62 |
|
} |
63 |
|
|
64 |
|
// put in cache |
65 |
4 |
TypeNode tn = nb.constructTypeNode(); |
66 |
2 |
cache[*this] = tn; |
67 |
2 |
return tn; |
68 |
|
} |
69 |
|
|
70 |
16805 |
Cardinality TypeNode::getCardinality() const { |
71 |
16805 |
return kind::getCardinality(*this); |
72 |
|
} |
73 |
|
|
74 |
|
/** Attribute true for types that have cardinality one */ |
75 |
|
struct TypeCardinalityClassTag |
76 |
|
{ |
77 |
|
}; |
78 |
|
typedef expr::Attribute<TypeCardinalityClassTag, uint64_t> |
79 |
|
TypeCardinalityClassAttr; |
80 |
|
|
81 |
7647159 |
CardinalityClass TypeNode::getCardinalityClass() |
82 |
|
{ |
83 |
|
// check it is already cached |
84 |
7647159 |
if (hasAttribute(TypeCardinalityClassAttr())) |
85 |
|
{ |
86 |
|
return static_cast<CardinalityClass>( |
87 |
7631168 |
getAttribute(TypeCardinalityClassAttr())); |
88 |
|
} |
89 |
15991 |
CardinalityClass ret = CardinalityClass::INFINITE; |
90 |
15991 |
if (isSort()) |
91 |
|
{ |
92 |
1908 |
ret = CardinalityClass::INTERPRETED_ONE; |
93 |
|
} |
94 |
41975 |
else if (isBoolean() || isBitVector() || isFloatingPoint() |
95 |
23203 |
|| isRoundingMode()) |
96 |
|
{ |
97 |
4991 |
ret = CardinalityClass::FINITE; |
98 |
|
} |
99 |
9092 |
else if (isString() || isRegExp() || isSequence() || isReal() || isBag()) |
100 |
|
{ |
101 |
4846 |
ret = CardinalityClass::INFINITE; |
102 |
|
} |
103 |
|
else |
104 |
|
{ |
105 |
|
// recursive case (this may be a parametric sort), we assume infinite for |
106 |
|
// the moment here to prevent infinite loops, which may occur when |
107 |
|
// computing the cardinality of datatype types with foreign types |
108 |
4246 |
setAttribute(TypeCardinalityClassAttr(), static_cast<uint64_t>(ret)); |
109 |
|
|
110 |
4246 |
if (isDatatype()) |
111 |
|
{ |
112 |
4596 |
TypeNode tn = *this; |
113 |
2298 |
const DType& dt = getDType(); |
114 |
2298 |
ret = dt.getCardinalityClass(tn); |
115 |
|
} |
116 |
1948 |
else if (isArray()) |
117 |
|
{ |
118 |
518 |
ret = getArrayConstituentType().getCardinalityClass(); |
119 |
518 |
if (ret == CardinalityClass::FINITE |
120 |
261 |
|| ret == CardinalityClass::INTERPRETED_FINITE) |
121 |
|
{ |
122 |
257 |
CardinalityClass cci = getArrayIndexType().getCardinalityClass(); |
123 |
|
// arrays with both finite element types, we take the max with its |
124 |
|
// index type. |
125 |
257 |
ret = maxCardinalityClass(ret, cci); |
126 |
|
} |
127 |
|
// else, array types whose element type is INFINITE, ONE, or |
128 |
|
// INTERPRETED_ONE have the same cardinality class as their range. |
129 |
|
} |
130 |
1430 |
else if (isSet()) |
131 |
|
{ |
132 |
942 |
CardinalityClass cc = getSetElementType().getCardinalityClass(); |
133 |
942 |
if (cc == CardinalityClass::ONE) |
134 |
|
{ |
135 |
|
// 1 -> 2 |
136 |
19 |
ret = CardinalityClass::FINITE; |
137 |
|
} |
138 |
923 |
else if (ret == CardinalityClass::INTERPRETED_ONE) |
139 |
|
{ |
140 |
|
// maybe 1 -> maybe finite |
141 |
|
ret = CardinalityClass::INTERPRETED_FINITE; |
142 |
|
} |
143 |
|
else |
144 |
|
{ |
145 |
|
// finite or infinite is unchanged |
146 |
923 |
ret = cc; |
147 |
|
} |
148 |
|
} |
149 |
488 |
else if (isFunction()) |
150 |
|
{ |
151 |
485 |
ret = getRangeType().getCardinalityClass(); |
152 |
485 |
if (ret == CardinalityClass::FINITE |
153 |
341 |
|| ret == CardinalityClass::INTERPRETED_FINITE) |
154 |
|
{ |
155 |
|
// we may have a larger cardinality class based on the |
156 |
|
// arguments of the function |
157 |
288 |
std::vector<TypeNode> argTypes = getArgTypes(); |
158 |
369 |
for (size_t i = 0, nargs = argTypes.size(); i < nargs; i++) |
159 |
|
{ |
160 |
225 |
CardinalityClass cca = argTypes[i].getCardinalityClass(); |
161 |
225 |
ret = maxCardinalityClass(ret, cca); |
162 |
|
} |
163 |
|
} |
164 |
|
// else, function types whose range type is INFINITE, ONE, or |
165 |
|
// INTERPRETED_ONE have the same cardinality class as their range. |
166 |
|
} |
167 |
3 |
else if (isConstructor()) |
168 |
|
{ |
169 |
|
// notice that we require computing the cardinality class of the |
170 |
|
// constructor type, which is equivalent to asking how many |
171 |
|
// constructor applications of the given constructor exist. This |
172 |
|
// is used in several places in the decision procedure for datatypes. |
173 |
|
// The cardinality starts with one. |
174 |
3 |
ret = CardinalityClass::ONE; |
175 |
|
// we may have a larger cardinality class based on the |
176 |
|
// arguments of the constructor |
177 |
6 |
std::vector<TypeNode> argTypes = getArgTypes(); |
178 |
7 |
for (size_t i = 0, nargs = argTypes.size(); i < nargs; i++) |
179 |
|
{ |
180 |
4 |
CardinalityClass cca = argTypes[i].getCardinalityClass(); |
181 |
4 |
ret = maxCardinalityClass(ret, cca); |
182 |
|
} |
183 |
|
} |
184 |
|
else |
185 |
|
{ |
186 |
|
// all types we care about should be handled above |
187 |
|
Assert(false); |
188 |
|
} |
189 |
|
} |
190 |
15991 |
setAttribute(TypeCardinalityClassAttr(), static_cast<uint64_t>(ret)); |
191 |
15991 |
return ret; |
192 |
|
} |
193 |
|
|
194 |
|
/** Attribute true for types that are closed enumerable */ |
195 |
|
struct IsClosedEnumerableTag |
196 |
|
{ |
197 |
|
}; |
198 |
|
struct IsClosedEnumerableComputedTag |
199 |
|
{ |
200 |
|
}; |
201 |
|
typedef expr::Attribute<IsClosedEnumerableTag, bool> IsClosedEnumerableAttr; |
202 |
|
typedef expr::Attribute<IsClosedEnumerableComputedTag, bool> |
203 |
|
IsClosedEnumerableComputedAttr; |
204 |
|
|
205 |
84904 |
bool TypeNode::isClosedEnumerable() |
206 |
|
{ |
207 |
|
// check it is already cached |
208 |
84904 |
if (!getAttribute(IsClosedEnumerableComputedAttr())) |
209 |
|
{ |
210 |
2330 |
bool ret = true; |
211 |
2330 |
if (isArray() || isSort() || isCodatatype() || isFunction() || isRegExp()) |
212 |
|
{ |
213 |
505 |
ret = false; |
214 |
|
} |
215 |
1825 |
else if (isSet()) |
216 |
|
{ |
217 |
9 |
ret = getSetElementType().isClosedEnumerable(); |
218 |
|
} |
219 |
1816 |
else if (isSequence()) |
220 |
|
{ |
221 |
|
ret = getSequenceElementType().isClosedEnumerable(); |
222 |
|
} |
223 |
1816 |
else if (isDatatype()) |
224 |
|
{ |
225 |
|
// avoid infinite loops: initially set to true |
226 |
418 |
setAttribute(IsClosedEnumerableAttr(), ret); |
227 |
418 |
setAttribute(IsClosedEnumerableComputedAttr(), true); |
228 |
836 |
TypeNode tn = *this; |
229 |
418 |
const DType& dt = getDType(); |
230 |
1021 |
for (uint32_t i = 0, ncons = dt.getNumConstructors(); i < ncons; i++) |
231 |
|
{ |
232 |
1424 |
for (uint32_t j = 0, nargs = dt[i].getNumArgs(); j < nargs; j++) |
233 |
|
{ |
234 |
1443 |
TypeNode ctn = dt[i][j].getRangeType(); |
235 |
821 |
if (tn != ctn && !ctn.isClosedEnumerable()) |
236 |
|
{ |
237 |
199 |
ret = false; |
238 |
199 |
break; |
239 |
|
} |
240 |
|
} |
241 |
802 |
if (!ret) |
242 |
|
{ |
243 |
199 |
break; |
244 |
|
} |
245 |
|
} |
246 |
|
} |
247 |
2330 |
setAttribute(IsClosedEnumerableAttr(), ret); |
248 |
2330 |
setAttribute(IsClosedEnumerableComputedAttr(), true); |
249 |
2330 |
return ret; |
250 |
|
} |
251 |
82574 |
return getAttribute(IsClosedEnumerableAttr()); |
252 |
|
} |
253 |
|
|
254 |
992251 |
bool TypeNode::isFirstClass() const |
255 |
|
{ |
256 |
1984502 |
return getKind() != kind::CONSTRUCTOR_TYPE && getKind() != kind::SELECTOR_TYPE |
257 |
992251 |
&& getKind() != kind::TESTER_TYPE && getKind() != kind::UPDATER_TYPE |
258 |
2974814 |
&& (getKind() != kind::TYPE_CONSTANT |
259 |
320937 |
|| (getConst<TypeConstant>() != REGEXP_TYPE |
260 |
1311249 |
&& getConst<TypeConstant>() != SEXPR_TYPE)); |
261 |
|
} |
262 |
|
|
263 |
|
bool TypeNode::isWellFounded() const { |
264 |
|
return kind::isWellFounded(*this); |
265 |
|
} |
266 |
|
|
267 |
116425 |
Node TypeNode::mkGroundTerm() const { |
268 |
116425 |
return kind::mkGroundTerm(*this); |
269 |
|
} |
270 |
|
|
271 |
117472 |
Node TypeNode::mkGroundValue() const |
272 |
|
{ |
273 |
234944 |
theory::TypeEnumerator te(*this); |
274 |
234944 |
return *te; |
275 |
|
} |
276 |
|
|
277 |
4852084 |
bool TypeNode::isStringLike() const { return isString() || isSequence(); } |
278 |
|
|
279 |
9535238 |
bool TypeNode::isSubtypeOf(TypeNode t) const { |
280 |
9535238 |
if(*this == t) { |
281 |
8933750 |
return true; |
282 |
|
} |
283 |
601488 |
if(getKind() == kind::TYPE_CONSTANT) { |
284 |
223331 |
switch(getConst<TypeConstant>()) { |
285 |
169448 |
case INTEGER_TYPE: |
286 |
169448 |
return t.getKind() == kind::TYPE_CONSTANT && t.getConst<TypeConstant>() == REAL_TYPE; |
287 |
53883 |
default: |
288 |
53883 |
return false; |
289 |
|
} |
290 |
|
} |
291 |
378157 |
if (isFunction() && t.isFunction()) |
292 |
|
{ |
293 |
3 |
if (!isComparableTo(t)) |
294 |
|
{ |
295 |
|
// incomparable, not subtype |
296 |
|
return false; |
297 |
|
} |
298 |
3 |
return getRangeType().isSubtypeOf(t.getRangeType()); |
299 |
|
} |
300 |
|
// this should only return true for types T1, T2 where we handle equalities between T1 and T2 |
301 |
|
// (more cases go here, if we want to support such cases) |
302 |
378154 |
return false; |
303 |
|
} |
304 |
|
|
305 |
6353365 |
bool TypeNode::isComparableTo(TypeNode t) const { |
306 |
6353365 |
if(*this == t) { |
307 |
6334488 |
return true; |
308 |
|
} |
309 |
18877 |
if(isSubtypeOf(NodeManager::currentNM()->realType())) { |
310 |
16637 |
return t.isSubtypeOf(NodeManager::currentNM()->realType()); |
311 |
|
} |
312 |
2240 |
if (isFunction() && t.isFunction()) |
313 |
|
{ |
314 |
|
// comparable if they have a common type node |
315 |
5 |
return !leastCommonTypeNode(*this, t).isNull(); |
316 |
|
} |
317 |
2235 |
return false; |
318 |
|
} |
319 |
|
|
320 |
40 |
TypeNode TypeNode::getTesterDomainType() const |
321 |
|
{ |
322 |
40 |
Assert(isTester()); |
323 |
40 |
return (*this)[0]; |
324 |
|
} |
325 |
|
|
326 |
7266 |
TypeNode TypeNode::getSequenceElementType() const |
327 |
|
{ |
328 |
7266 |
Assert(isSequence()); |
329 |
7266 |
return (*this)[0]; |
330 |
|
} |
331 |
|
|
332 |
584916 |
TypeNode TypeNode::getBaseType() const { |
333 |
1169832 |
TypeNode realt = NodeManager::currentNM()->realType(); |
334 |
584916 |
if (isSubtypeOf(realt)) { |
335 |
159655 |
return realt; |
336 |
425261 |
} else if (isParametricDatatype()) { |
337 |
1846 |
std::vector<TypeNode> v; |
338 |
2012 |
for(size_t i = 1; i < getNumChildren(); ++i) { |
339 |
1089 |
v.push_back((*this)[i].getBaseType()); |
340 |
|
} |
341 |
923 |
return (*this)[0].getDType().getTypeNode().instantiateParametricDatatype(v); |
342 |
|
} |
343 |
424338 |
return *this; |
344 |
|
} |
345 |
|
|
346 |
12366 |
std::vector<TypeNode> TypeNode::getArgTypes() const { |
347 |
12366 |
vector<TypeNode> args; |
348 |
12366 |
if(isTester()) { |
349 |
|
Assert(getNumChildren() == 1); |
350 |
|
args.push_back((*this)[0]); |
351 |
|
} else { |
352 |
12366 |
Assert(isFunction() || isConstructor() || isSelector()); |
353 |
33224 |
for(unsigned i = 0, i_end = getNumChildren() - 1; i < i_end; ++i) { |
354 |
20858 |
args.push_back((*this)[i]); |
355 |
|
} |
356 |
|
} |
357 |
12366 |
return args; |
358 |
|
} |
359 |
|
|
360 |
3604 |
std::vector<TypeNode> TypeNode::getParamTypes() const { |
361 |
3604 |
vector<TypeNode> params; |
362 |
3604 |
Assert(isParametricDatatype()); |
363 |
9251 |
for(unsigned i = 1, i_end = getNumChildren(); i < i_end; ++i) { |
364 |
5647 |
params.push_back((*this)[i]); |
365 |
|
} |
366 |
3604 |
return params; |
367 |
|
} |
368 |
|
|
369 |
120948 |
bool TypeNode::isTuple() const |
370 |
|
{ |
371 |
120948 |
return (getKind() == kind::DATATYPE_TYPE && getDType().isTuple()); |
372 |
|
} |
373 |
|
|
374 |
194 |
bool TypeNode::isRecord() const |
375 |
|
{ |
376 |
194 |
return (getKind() == kind::DATATYPE_TYPE && getDType().isRecord()); |
377 |
|
} |
378 |
|
|
379 |
36282 |
size_t TypeNode::getTupleLength() const { |
380 |
36282 |
Assert(isTuple()); |
381 |
36282 |
const DType& dt = getDType(); |
382 |
36282 |
Assert(dt.getNumConstructors() == 1); |
383 |
36282 |
return dt[0].getNumArgs(); |
384 |
|
} |
385 |
|
|
386 |
15664 |
vector<TypeNode> TypeNode::getTupleTypes() const { |
387 |
15664 |
Assert(isTuple()); |
388 |
15664 |
const DType& dt = getDType(); |
389 |
15664 |
Assert(dt.getNumConstructors() == 1); |
390 |
15664 |
vector<TypeNode> types; |
391 |
47175 |
for(unsigned i = 0; i < dt[0].getNumArgs(); ++i) { |
392 |
31511 |
types.push_back(dt[0][i].getRangeType()); |
393 |
|
} |
394 |
15664 |
return types; |
395 |
|
} |
396 |
|
|
397 |
|
/** Is this an instantiated datatype type */ |
398 |
1440 |
bool TypeNode::isInstantiatedDatatype() const { |
399 |
1440 |
if(getKind() == kind::DATATYPE_TYPE) { |
400 |
897 |
return true; |
401 |
|
} |
402 |
543 |
if(getKind() != kind::PARAMETRIC_DATATYPE) { |
403 |
|
return false; |
404 |
|
} |
405 |
543 |
const DType& dt = (*this)[0].getDType(); |
406 |
543 |
unsigned n = dt.getNumParameters(); |
407 |
543 |
Assert(n < getNumChildren()); |
408 |
1248 |
for(unsigned i = 0; i < n; ++i) { |
409 |
705 |
if (dt.getParameter(i) == (*this)[i + 1]) |
410 |
|
{ |
411 |
|
return false; |
412 |
|
} |
413 |
|
} |
414 |
543 |
return true; |
415 |
|
} |
416 |
|
|
417 |
1508 |
TypeNode TypeNode::instantiateParametricDatatype( |
418 |
|
const std::vector<TypeNode>& params) const |
419 |
|
{ |
420 |
1508 |
AssertArgument(getKind() == kind::PARAMETRIC_DATATYPE, *this); |
421 |
1508 |
AssertArgument(params.size() == getNumChildren() - 1, *this); |
422 |
1508 |
NodeManager* nm = NodeManager::currentNM(); |
423 |
3016 |
TypeNode cons = nm->mkTypeConst((*this)[0].getConst<DatatypeIndexConstant>()); |
424 |
3016 |
std::vector<TypeNode> paramsNodes; |
425 |
1508 |
paramsNodes.push_back(cons); |
426 |
3318 |
for (const TypeNode& t : params) |
427 |
|
{ |
428 |
1810 |
paramsNodes.push_back(t); |
429 |
|
} |
430 |
3016 |
return nm->mkTypeNode(kind::PARAMETRIC_DATATYPE, paramsNodes); |
431 |
|
} |
432 |
|
|
433 |
54 |
uint64_t TypeNode::getSortConstructorArity() const |
434 |
|
{ |
435 |
54 |
Assert(isSortConstructor() && hasAttribute(expr::SortArityAttr())); |
436 |
54 |
return getAttribute(expr::SortArityAttr()); |
437 |
|
} |
438 |
|
|
439 |
4 |
std::string TypeNode::getName() const |
440 |
|
{ |
441 |
4 |
Assert(isSort() || isSortConstructor()); |
442 |
4 |
return getAttribute(expr::VarNameAttr()); |
443 |
|
} |
444 |
|
|
445 |
50 |
TypeNode TypeNode::instantiateSortConstructor( |
446 |
|
const std::vector<TypeNode>& params) const |
447 |
|
{ |
448 |
50 |
Assert(isSortConstructor()); |
449 |
50 |
return NodeManager::currentNM()->mkSort(*this, params); |
450 |
|
} |
451 |
|
|
452 |
|
/** Is this an instantiated datatype parameter */ |
453 |
5438 |
bool TypeNode::isParameterInstantiatedDatatype(unsigned n) const { |
454 |
5438 |
AssertArgument(getKind() == kind::PARAMETRIC_DATATYPE, *this); |
455 |
5438 |
const DType& dt = (*this)[0].getDType(); |
456 |
5438 |
AssertArgument(n < dt.getNumParameters(), *this); |
457 |
5438 |
return dt.getParameter(n) != (*this)[n + 1]; |
458 |
|
} |
459 |
|
|
460 |
6636732 |
TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){ |
461 |
6636732 |
return commonTypeNode( t0, t1, true ); |
462 |
|
} |
463 |
|
|
464 |
141126 |
TypeNode TypeNode::mostCommonTypeNode(TypeNode t0, TypeNode t1){ |
465 |
141126 |
return commonTypeNode( t0, t1, false ); |
466 |
|
} |
467 |
|
|
468 |
6777886 |
TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) { |
469 |
6777886 |
Assert(NodeManager::currentNM() != NULL) |
470 |
|
<< "There is no current cvc5::NodeManager associated to this thread.\n" |
471 |
|
"Perhaps a public-facing function is missing a NodeManagerScope ?"; |
472 |
|
|
473 |
6777886 |
Assert(!t0.isNull()); |
474 |
6777886 |
Assert(!t1.isNull()); |
475 |
|
|
476 |
6777886 |
if(__builtin_expect( (t0 == t1), true )) { |
477 |
6727124 |
return t0; |
478 |
|
} |
479 |
|
|
480 |
|
// t0 != t1 && |
481 |
50762 |
if(t0.getKind() == kind::TYPE_CONSTANT) { |
482 |
50704 |
switch(t0.getConst<TypeConstant>()) { |
483 |
15170 |
case INTEGER_TYPE: |
484 |
15170 |
if(t1.isInteger()) { |
485 |
|
// t0 == IntegerType && t1.isInteger() |
486 |
|
return t0; //IntegerType |
487 |
15170 |
} else if(t1.isReal()) { |
488 |
|
// t0 == IntegerType && t1.isReal() && !t1.isInteger() |
489 |
15138 |
return isLeast ? t1 : t0; // RealType |
490 |
|
} else { |
491 |
32 |
return TypeNode(); // null type |
492 |
|
} |
493 |
35474 |
case REAL_TYPE: |
494 |
35474 |
if(t1.isReal()) { |
495 |
35474 |
return isLeast ? t0 : t1; // RealType |
496 |
|
} else { |
497 |
|
return TypeNode(); // null type |
498 |
|
} |
499 |
60 |
default: |
500 |
60 |
return TypeNode(); // null type |
501 |
|
} |
502 |
58 |
} else if(t1.getKind() == kind::TYPE_CONSTANT) { |
503 |
22 |
return commonTypeNode(t1, t0, isLeast); // decrease the number of special cases |
504 |
|
} |
505 |
|
|
506 |
|
// t0 != t1 && |
507 |
|
// t0.getKind() == kind::TYPE_CONSTANT && |
508 |
|
// t1.getKind() == kind::TYPE_CONSTANT |
509 |
36 |
switch(t0.getKind()) { |
510 |
12 |
case kind::FUNCTION_TYPE: |
511 |
|
{ |
512 |
12 |
if (t1.getKind() != kind::FUNCTION_TYPE) |
513 |
|
{ |
514 |
4 |
return TypeNode(); |
515 |
|
} |
516 |
|
// must have equal arguments |
517 |
16 |
std::vector<TypeNode> t0a = t0.getArgTypes(); |
518 |
16 |
std::vector<TypeNode> t1a = t1.getArgTypes(); |
519 |
8 |
if (t0a.size() != t1a.size()) |
520 |
|
{ |
521 |
|
// different arities |
522 |
|
return TypeNode(); |
523 |
|
} |
524 |
15 |
for (unsigned i = 0, nargs = t0a.size(); i < nargs; i++) |
525 |
|
{ |
526 |
9 |
if (t0a[i] != t1a[i]) |
527 |
|
{ |
528 |
|
// an argument is different |
529 |
2 |
return TypeNode(); |
530 |
|
} |
531 |
|
} |
532 |
12 |
TypeNode t0r = t0.getRangeType(); |
533 |
12 |
TypeNode t1r = t1.getRangeType(); |
534 |
12 |
TypeNode tr = commonTypeNode(t0r, t1r, isLeast); |
535 |
12 |
std::vector<TypeNode> ftypes; |
536 |
6 |
ftypes.insert(ftypes.end(), t0a.begin(), t0a.end()); |
537 |
6 |
ftypes.push_back(tr); |
538 |
6 |
return NodeManager::currentNM()->mkFunctionType(ftypes); |
539 |
|
} |
540 |
|
break; |
541 |
24 |
case kind::BITVECTOR_TYPE: |
542 |
|
case kind::FLOATINGPOINT_TYPE: |
543 |
|
case kind::SORT_TYPE: |
544 |
|
case kind::CONSTRUCTOR_TYPE: |
545 |
|
case kind::SELECTOR_TYPE: |
546 |
|
case kind::TESTER_TYPE: |
547 |
|
case kind::ARRAY_TYPE: |
548 |
|
case kind::DATATYPE_TYPE: |
549 |
|
case kind::PARAMETRIC_DATATYPE: |
550 |
|
case kind::SEQUENCE_TYPE: |
551 |
|
case kind::SET_TYPE: |
552 |
|
case kind::BAG_TYPE: |
553 |
|
{ |
554 |
|
// we don't support subtyping except for built in types Int and Real. |
555 |
24 |
return TypeNode(); // return null type |
556 |
|
} |
557 |
|
default: |
558 |
|
Unimplemented() << "don't have a commonType for types `" << t0 |
559 |
|
<< "' and `" << t1 << "'"; |
560 |
|
} |
561 |
|
} |
562 |
|
|
563 |
|
Node TypeNode::getEnsureTypeCondition( Node n, TypeNode tn ) { |
564 |
|
TypeNode ntn = n.getType(); |
565 |
|
Assert(ntn.isComparableTo(tn)); |
566 |
|
if( !ntn.isSubtypeOf( tn ) ){ |
567 |
|
if( tn.isInteger() ){ |
568 |
|
if( tn.isSubtypeOf( ntn ) ){ |
569 |
|
return NodeManager::currentNM()->mkNode( kind::IS_INTEGER, n ); |
570 |
|
} |
571 |
|
}else if( tn.isDatatype() && ntn.isDatatype() ){ |
572 |
|
if( tn.isTuple() && ntn.isTuple() ){ |
573 |
|
const DType& dt1 = tn.getDType(); |
574 |
|
const DType& dt2 = ntn.getDType(); |
575 |
|
NodeManager* nm = NodeManager::currentNM(); |
576 |
|
if( dt1[0].getNumArgs()==dt2[0].getNumArgs() ){ |
577 |
|
std::vector< Node > conds; |
578 |
|
for( unsigned i=0; i<dt2[0].getNumArgs(); i++ ){ |
579 |
|
Node s = nm->mkNode( |
580 |
|
kind::APPLY_SELECTOR_TOTAL, dt2[0][i].getSelector(), n); |
581 |
|
Node etc = getEnsureTypeCondition(s, dt1[0][i].getRangeType()); |
582 |
|
if( etc.isNull() ){ |
583 |
|
return Node::null(); |
584 |
|
}else{ |
585 |
|
conds.push_back( etc ); |
586 |
|
} |
587 |
|
} |
588 |
|
if( conds.empty() ){ |
589 |
|
return nm->mkConst(true); |
590 |
|
}else if( conds.size()==1 ){ |
591 |
|
return conds[0]; |
592 |
|
}else{ |
593 |
|
return nm->mkNode(kind::AND, conds); |
594 |
|
} |
595 |
|
} |
596 |
|
} |
597 |
|
} |
598 |
|
return Node::null(); |
599 |
|
}else{ |
600 |
|
return NodeManager::currentNM()->mkConst( true ); |
601 |
|
} |
602 |
|
} |
603 |
|
|
604 |
|
/** Is this a sort kind */ |
605 |
1581691 |
bool TypeNode::isSort() const { |
606 |
1581691 |
return ( getKind() == kind::SORT_TYPE && !hasAttribute(expr::SortArityAttr()) ); |
607 |
|
} |
608 |
|
|
609 |
|
/** Is this a sort constructor kind */ |
610 |
1463 |
bool TypeNode::isSortConstructor() const { |
611 |
1463 |
return getKind() == kind::SORT_TYPE && hasAttribute(expr::SortArityAttr()); |
612 |
|
} |
613 |
|
|
614 |
125175 |
bool TypeNode::isFloatingPoint() const |
615 |
|
{ |
616 |
125175 |
return getKind() == kind::FLOATINGPOINT_TYPE; |
617 |
|
} |
618 |
|
|
619 |
7861120 |
bool TypeNode::isBitVector() const { return getKind() == kind::BITVECTOR_TYPE; } |
620 |
|
|
621 |
7408136 |
bool TypeNode::isDatatype() const |
622 |
|
{ |
623 |
7408136 |
return getKind() == kind::DATATYPE_TYPE |
624 |
7408136 |
|| getKind() == kind::PARAMETRIC_DATATYPE; |
625 |
|
} |
626 |
|
|
627 |
896829 |
bool TypeNode::isParametricDatatype() const |
628 |
|
{ |
629 |
896829 |
return getKind() == kind::PARAMETRIC_DATATYPE; |
630 |
|
} |
631 |
|
|
632 |
7555728 |
bool TypeNode::isConstructor() const |
633 |
|
{ |
634 |
7555728 |
return getKind() == kind::CONSTRUCTOR_TYPE; |
635 |
|
} |
636 |
|
|
637 |
1275861 |
bool TypeNode::isSelector() const { return getKind() == kind::SELECTOR_TYPE; } |
638 |
|
|
639 |
2126939 |
bool TypeNode::isTester() const { return getKind() == kind::TESTER_TYPE; } |
640 |
|
|
641 |
70 |
bool TypeNode::isUpdater() const { return getKind() == kind::UPDATER_TYPE; } |
642 |
|
|
643 |
500486 |
bool TypeNode::isCodatatype() const |
644 |
|
{ |
645 |
500486 |
if (isDatatype()) |
646 |
|
{ |
647 |
499075 |
return getDType().isCodatatype(); |
648 |
|
} |
649 |
1411 |
return false; |
650 |
|
} |
651 |
|
|
652 |
8542 |
bool TypeNode::isSygusDatatype() const |
653 |
|
{ |
654 |
8542 |
if (isDatatype()) |
655 |
|
{ |
656 |
8070 |
return getDType().isSygus(); |
657 |
|
} |
658 |
472 |
return false; |
659 |
|
} |
660 |
|
|
661 |
2039 |
std::string TypeNode::toString() const { |
662 |
4078 |
std::stringstream ss; |
663 |
|
Language outlang = |
664 |
2039 |
(this == &s_null) ? Language::LANG_AUTO : options::outputLanguage(); |
665 |
2039 |
d_nv->toStream(ss, -1, 0, outlang); |
666 |
4078 |
return ss.str(); |
667 |
|
} |
668 |
|
|
669 |
4359113 |
const DType& TypeNode::getDType() const |
670 |
|
{ |
671 |
4359113 |
if (getKind() == kind::DATATYPE_TYPE) |
672 |
|
{ |
673 |
4337477 |
DatatypeIndexConstant dic = getConst<DatatypeIndexConstant>(); |
674 |
4337477 |
return NodeManager::currentNM()->getDTypeForIndex(dic.getIndex()); |
675 |
|
} |
676 |
21636 |
Assert(getKind() == kind::PARAMETRIC_DATATYPE); |
677 |
21636 |
return (*this)[0].getDType(); |
678 |
|
} |
679 |
|
|
680 |
48967 |
bool TypeNode::isBag() const |
681 |
|
{ |
682 |
48967 |
return getKind() == kind::BAG_TYPE; |
683 |
|
} |
684 |
|
|
685 |
3517 |
TypeNode TypeNode::getBagElementType() const |
686 |
|
{ |
687 |
3517 |
Assert(isBag()); |
688 |
3517 |
return (*this)[0]; |
689 |
|
} |
690 |
|
|
691 |
1935 |
bool TypeNode::isBitVector(unsigned size) const |
692 |
|
{ |
693 |
1935 |
return (getKind() == kind::BITVECTOR_TYPE |
694 |
1935 |
&& getConst<BitVectorSize>() == size); |
695 |
|
} |
696 |
|
|
697 |
3623507 |
uint32_t TypeNode::getBitVectorSize() const |
698 |
|
{ |
699 |
3623507 |
Assert(isBitVector()); |
700 |
3623507 |
return getConst<BitVectorSize>(); |
701 |
|
} |
702 |
|
|
703 |
|
} // namespace cvc5 |
704 |
|
|
705 |
|
namespace std { |
706 |
|
|
707 |
2916805 |
size_t hash<cvc5::TypeNode>::operator()(const cvc5::TypeNode& tn) const |
708 |
|
{ |
709 |
2916805 |
return tn.getId(); |
710 |
|
} |
711 |
|
|
712 |
29511 |
} // namespace std |