1 /*********************                                                        */
2 /*! \file type_node.cpp
3  ** \verbatim
4  ** Top contributors (to current version):
5  **   Andrew Reynolds, Morgan Deters, Tim King
6  ** This file is part of the CVC4 project.
7  ** Copyright (c) 2009-2019 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.\endverbatim
11  **
12  ** \brief Reference-counted encapsulation of a pointer to node information.
13  **
14  ** Reference-counted encapsulation of a pointer to node information.
15  **/
16 #include "expr/type_node.h"
17 
18 #include <vector>
19 
20 #include "expr/node_manager_attributes.h"
21 #include "expr/type_properties.h"
22 #include "options/base_options.h"
23 #include "options/expr_options.h"
24 #include "options/quantifiers_options.h"
25 #include "options/uf_options.h"
26 
27 using namespace std;
28 
29 namespace CVC4 {
30 
31 TypeNode TypeNode::s_null( &expr::NodeValue::null() );
32 
substitute(const TypeNode & type,const TypeNode & replacement,std::unordered_map<TypeNode,TypeNode,HashFunction> & cache) const33 TypeNode TypeNode::substitute(const TypeNode& type,
34                               const TypeNode& replacement,
35                               std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const {
36   // in cache?
37   std::unordered_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this);
38   if(i != cache.end()) {
39     return (*i).second;
40   }
41 
42   // otherwise compute
43   NodeBuilder<> nb(getKind());
44   if(getMetaKind() == kind::metakind::PARAMETERIZED) {
45     // push the operator
46     nb << TypeNode(d_nv->d_children[0]);
47   }
48   for(TypeNode::const_iterator i = begin(),
49         iend = end();
50       i != iend;
51       ++i) {
52     if(*i == type) {
53       nb << replacement;
54     } else {
55       (*i).substitute(type, replacement);
56     }
57   }
58 
59   // put in cache
60   TypeNode tn = nb.constructTypeNode();
61   cache[*this] = tn;
62   return tn;
63 }
64 
getCardinality() const65 Cardinality TypeNode::getCardinality() const {
66   return kind::getCardinality(*this);
67 }
68 
69 /** Attribute true for types that are interpreted as finite */
70 struct IsInterpretedFiniteTag
71 {
72 };
73 struct IsInterpretedFiniteComputedTag
74 {
75 };
76 typedef expr::Attribute<IsInterpretedFiniteTag, bool> IsInterpretedFiniteAttr;
77 typedef expr::Attribute<IsInterpretedFiniteComputedTag, bool>
78     IsInterpretedFiniteComputedAttr;
79 
isInterpretedFinite()80 bool TypeNode::isInterpretedFinite()
81 {
82   // check it is already cached
83   if (!getAttribute(IsInterpretedFiniteComputedAttr()))
84   {
85     bool isInterpretedFinite = false;
86     if (isSort())
87     {
88       // If the finite model finding flag is set, we treat uninterpreted sorts
89       // as finite. If it is not set, we treat them implicitly as infinite
90       // sorts (that is, their cardinality is not constrained to be finite).
91       isInterpretedFinite = options::finiteModelFind();
92     }
93     else if (isBitVector() || isFloatingPoint())
94     {
95       isInterpretedFinite = true;
96     }
97     else if (isDatatype())
98     {
99       TypeNode tn = *this;
100       const Datatype& dt = getDatatype();
101       isInterpretedFinite = dt.isInterpretedFinite(tn.toType());
102     }
103     else if (isArray())
104     {
105       TypeNode tnc = getArrayConstituentType();
106       if (!tnc.isInterpretedFinite())
107       {
108         // arrays with consistuent type that is infinite are infinite
109         isInterpretedFinite = false;
110       }
111       else if (getArrayIndexType().isInterpretedFinite())
112       {
113         // arrays with both finite consistuent and index types are finite
114         isInterpretedFinite = true;
115       }
116       else
117       {
118         // If the consistuent type of the array has cardinality one, then the
119         // array type has cardinality one, independent of the index type.
120         isInterpretedFinite = tnc.getCardinality().isOne();
121       }
122     }
123     else if (isSet())
124     {
125       isInterpretedFinite = getSetElementType().isInterpretedFinite();
126     }
127     else if (isFunction())
128     {
129       isInterpretedFinite = true;
130       TypeNode tnr = getRangeType();
131       if (!tnr.isInterpretedFinite())
132       {
133         isInterpretedFinite = false;
134       }
135       else
136       {
137         std::vector<TypeNode> argTypes = getArgTypes();
138         for (unsigned i = 0, nargs = argTypes.size(); i < nargs; i++)
139         {
140           if (!argTypes[i].isInterpretedFinite())
141           {
142             isInterpretedFinite = false;
143             break;
144           }
145         }
146         if (!isInterpretedFinite)
147         {
148           // similar to arrays, functions are finite if their range type
149           // has cardinality one, regardless of the arguments.
150           isInterpretedFinite = tnr.getCardinality().isOne();
151         }
152       }
153     }
154     else
155     {
156       // by default, compute the exact cardinality for the type and check
157       // whether it is finite. This should be avoided in general, since
158       // computing cardinalities for types can be highly expensive.
159       isInterpretedFinite = getCardinality().isFinite();
160     }
161     setAttribute(IsInterpretedFiniteAttr(), isInterpretedFinite);
162     setAttribute(IsInterpretedFiniteComputedAttr(), true);
163     return isInterpretedFinite;
164   }
165   return getAttribute(IsInterpretedFiniteAttr());
166 }
167 
168 /** Attribute true for types that are closed enumerable */
169 struct IsClosedEnumerableTag
170 {
171 };
172 struct IsClosedEnumerableComputedTag
173 {
174 };
175 typedef expr::Attribute<IsClosedEnumerableTag, bool> IsClosedEnumerableAttr;
176 typedef expr::Attribute<IsClosedEnumerableComputedTag, bool>
177     IsClosedEnumerableComputedAttr;
178 
isClosedEnumerable()179 bool TypeNode::isClosedEnumerable()
180 {
181   // check it is already cached
182   if (!getAttribute(IsClosedEnumerableComputedAttr()))
183   {
184     bool ret = true;
185     if (isArray() || isSort() || isCodatatype() || isFunction())
186     {
187       ret = false;
188     }
189     else if (isSet())
190     {
191       ret = getSetElementType().isClosedEnumerable();
192     }
193     else if (isDatatype())
194     {
195       // avoid infinite loops: initially set to true
196       setAttribute(IsClosedEnumerableAttr(), ret);
197       setAttribute(IsClosedEnumerableComputedAttr(), true);
198       TypeNode tn = *this;
199       const Datatype& dt = getDatatype();
200       for (unsigned i = 0, ncons = dt.getNumConstructors(); i < ncons; i++)
201       {
202         for (unsigned j = 0, nargs = dt[i].getNumArgs(); j < nargs; j++)
203         {
204           TypeNode ctn = TypeNode::fromType(dt[i][j].getRangeType());
205           if (tn != ctn && !ctn.isClosedEnumerable())
206           {
207             ret = false;
208             break;
209           }
210         }
211         if (!ret)
212         {
213           break;
214         }
215       }
216     }
217     setAttribute(IsClosedEnumerableAttr(), ret);
218     setAttribute(IsClosedEnumerableComputedAttr(), true);
219     return ret;
220   }
221   return getAttribute(IsClosedEnumerableAttr());
222 }
223 
isFirstClass() const224 bool TypeNode::isFirstClass() const {
225   return ( getKind() != kind::FUNCTION_TYPE || options::ufHo() ) &&
226          getKind() != kind::CONSTRUCTOR_TYPE &&
227          getKind() != kind::SELECTOR_TYPE &&
228          getKind() != kind::TESTER_TYPE &&
229          getKind() != kind::SEXPR_TYPE &&
230          ( getKind() != kind::TYPE_CONSTANT ||
231            getConst<TypeConstant>() != REGEXP_TYPE );
232 }
233 
isWellFounded() const234 bool TypeNode::isWellFounded() const {
235   return kind::isWellFounded(*this);
236 }
237 
mkGroundTerm() const238 Node TypeNode::mkGroundTerm() const {
239   return kind::mkGroundTerm(*this);
240 }
241 
isSubtypeOf(TypeNode t) const242 bool TypeNode::isSubtypeOf(TypeNode t) const {
243   if(*this == t) {
244     return true;
245   }
246   if(getKind() == kind::TYPE_CONSTANT) {
247     switch(getConst<TypeConstant>()) {
248     case INTEGER_TYPE:
249       return t.getKind() == kind::TYPE_CONSTANT && t.getConst<TypeConstant>() == REAL_TYPE;
250     default:
251       return false;
252     }
253   }
254   if(isSet() && t.isSet()) {
255     return getSetElementType().isSubtypeOf(t.getSetElementType());
256   }
257   // this should only return true for types T1, T2 where we handle equalities between T1 and T2
258   // (more cases go here, if we want to support such cases)
259   return false;
260 }
261 
isComparableTo(TypeNode t) const262 bool TypeNode::isComparableTo(TypeNode t) const {
263   if(*this == t) {
264     return true;
265   }
266   if(isSubtypeOf(NodeManager::currentNM()->realType())) {
267     return t.isSubtypeOf(NodeManager::currentNM()->realType());
268   }
269   if(isSet() && t.isSet()) {
270     return getSetElementType().isComparableTo(t.getSetElementType());
271   }
272   return false;
273 }
274 
getBaseType() const275 TypeNode TypeNode::getBaseType() const {
276   TypeNode realt = NodeManager::currentNM()->realType();
277   if (isSubtypeOf(realt)) {
278     return realt;
279   } else if (isParametricDatatype()) {
280     vector<Type> v;
281     for(size_t i = 1; i < getNumChildren(); ++i) {
282       v.push_back((*this)[i].getBaseType().toType());
283     }
284     TypeNode tn = TypeNode::fromType((*this)[0].getDatatype().getDatatypeType(v));
285     return tn;
286   }
287   return *this;
288 }
289 
getArgTypes() const290 std::vector<TypeNode> TypeNode::getArgTypes() const {
291   vector<TypeNode> args;
292   if(isTester()) {
293     Assert(getNumChildren() == 1);
294     args.push_back((*this)[0]);
295   } else {
296     Assert(isFunction() || isConstructor() || isSelector());
297     for(unsigned i = 0, i_end = getNumChildren() - 1; i < i_end; ++i) {
298       args.push_back((*this)[i]);
299     }
300   }
301   return args;
302 }
303 
getParamTypes() const304 std::vector<TypeNode> TypeNode::getParamTypes() const {
305   vector<TypeNode> params;
306   Assert(isParametricDatatype());
307   for(unsigned i = 1, i_end = getNumChildren(); i < i_end; ++i) {
308     params.push_back((*this)[i]);
309   }
310   return params;
311 }
312 
313 
314 /** Is this a tuple type? */
isTuple() const315 bool TypeNode::isTuple() const {
316   return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isTuple() );
317 }
318 
319 /** Is this a record type? */
isRecord() const320 bool TypeNode::isRecord() const {
321   return ( getKind() == kind::DATATYPE_TYPE && getDatatype().isRecord() );
322 }
323 
getTupleLength() const324 size_t TypeNode::getTupleLength() const {
325   Assert(isTuple());
326   const Datatype& dt = getDatatype();
327   Assert(dt.getNumConstructors()==1);
328   return dt[0].getNumArgs();
329 }
330 
getTupleTypes() const331 vector<TypeNode> TypeNode::getTupleTypes() const {
332   Assert(isTuple());
333   const Datatype& dt = getDatatype();
334   Assert(dt.getNumConstructors()==1);
335   vector<TypeNode> types;
336   for(unsigned i = 0; i < dt[0].getNumArgs(); ++i) {
337     types.push_back(TypeNode::fromType(dt[0][i].getRangeType()));
338   }
339   return types;
340 }
341 
getRecord() const342 const Record& TypeNode::getRecord() const {
343   Assert(isRecord());
344   const Datatype & dt = getDatatype();
345   return *(dt.getRecord());
346   //return getAttribute(expr::DatatypeRecordAttr()).getConst<Record>();
347 }
348 
getSExprTypes() const349 vector<TypeNode> TypeNode::getSExprTypes() const {
350   Assert(isSExpr());
351   vector<TypeNode> types;
352   for(unsigned i = 0, i_end = getNumChildren(); i < i_end; ++i) {
353     types.push_back((*this)[i]);
354   }
355   return types;
356 }
357 
358 /** Is this an instantiated datatype type */
isInstantiatedDatatype() const359 bool TypeNode::isInstantiatedDatatype() const {
360   if(getKind() == kind::DATATYPE_TYPE) {
361     return true;
362   }
363   if(getKind() != kind::PARAMETRIC_DATATYPE) {
364     return false;
365   }
366   const Datatype& dt = (*this)[0].getDatatype();
367   unsigned n = dt.getNumParameters();
368   Assert(n < getNumChildren());
369   for(unsigned i = 0; i < n; ++i) {
370     if(TypeNode::fromType(dt.getParameter(i)) == (*this)[i + 1]) {
371       return false;
372     }
373   }
374   return true;
375 }
376 
377 /** Is this an instantiated datatype parameter */
isParameterInstantiatedDatatype(unsigned n) const378 bool TypeNode::isParameterInstantiatedDatatype(unsigned n) const {
379   AssertArgument(getKind() == kind::PARAMETRIC_DATATYPE, *this);
380   const Datatype& dt = (*this)[0].getDatatype();
381   AssertArgument(n < dt.getNumParameters(), *this);
382   return TypeNode::fromType(dt.getParameter(n)) != (*this)[n + 1];
383 }
384 
leastCommonTypeNode(TypeNode t0,TypeNode t1)385 TypeNode TypeNode::leastCommonTypeNode(TypeNode t0, TypeNode t1){
386   return commonTypeNode( t0, t1, true );
387 }
388 
mostCommonTypeNode(TypeNode t0,TypeNode t1)389 TypeNode TypeNode::mostCommonTypeNode(TypeNode t0, TypeNode t1){
390   return commonTypeNode( t0, t1, false );
391 }
392 
commonTypeNode(TypeNode t0,TypeNode t1,bool isLeast)393 TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) {
394   Assert( NodeManager::currentNM() != NULL,
395           "There is no current CVC4::NodeManager associated to this thread.\n"
396           "Perhaps a public-facing function is missing a NodeManagerScope ?" );
397 
398   Assert(!t0.isNull());
399   Assert(!t1.isNull());
400 
401   if(__builtin_expect( (t0 == t1), true )) {
402     return t0;
403   }
404 
405   // t0 != t1 &&
406   if(t0.getKind() == kind::TYPE_CONSTANT) {
407     switch(t0.getConst<TypeConstant>()) {
408     case INTEGER_TYPE:
409       if(t1.isInteger()) {
410         // t0 == IntegerType && t1.isInteger()
411         return t0; //IntegerType
412       } else if(t1.isReal()) {
413         // t0 == IntegerType && t1.isReal() && !t1.isInteger()
414         return isLeast ? t1 : t0; // RealType
415       } else {
416         return TypeNode(); // null type
417       }
418     case REAL_TYPE:
419       if(t1.isReal()) {
420         return isLeast ? t0 : t1; // RealType
421       } else {
422         return TypeNode(); // null type
423       }
424     default:
425       return TypeNode(); // null type
426     }
427   } else if(t1.getKind() == kind::TYPE_CONSTANT) {
428     return commonTypeNode(t1, t0, isLeast); // decrease the number of special cases
429   }
430 
431   // t0 != t1 &&
432   // t0.getKind() == kind::TYPE_CONSTANT &&
433   // t1.getKind() == kind::TYPE_CONSTANT
434   switch(t0.getKind()) {
435   case kind::BITVECTOR_TYPE:
436   case kind::FLOATINGPOINT_TYPE:
437   case kind::SORT_TYPE:
438   case kind::CONSTRUCTOR_TYPE:
439   case kind::SELECTOR_TYPE:
440   case kind::TESTER_TYPE:
441   case kind::FUNCTION_TYPE:
442   case kind::ARRAY_TYPE:
443   case kind::DATATYPE_TYPE:
444   case kind::PARAMETRIC_DATATYPE:
445     return TypeNode();
446   case kind::SET_TYPE: {
447     // take the least common subtype of element types
448     TypeNode elementType;
449     if(t1.isSet() && !(elementType = commonTypeNode(t0[0], t1[0], isLeast)).isNull() ) {
450       return NodeManager::currentNM()->mkSetType(elementType);
451     } else {
452       return TypeNode();
453     }
454   }
455   case kind::SEXPR_TYPE:
456     Unimplemented("haven't implemented leastCommonType for symbolic expressions yet");
457   default:
458     Unimplemented("don't have a commonType for types `%s' and `%s'", t0.toString().c_str(), t1.toString().c_str());
459   }
460 }
461 
getEnsureTypeCondition(Node n,TypeNode tn)462 Node TypeNode::getEnsureTypeCondition( Node n, TypeNode tn ) {
463   TypeNode ntn = n.getType();
464   Assert( ntn.isComparableTo( tn ) );
465   if( !ntn.isSubtypeOf( tn ) ){
466     if( tn.isInteger() ){
467       if( tn.isSubtypeOf( ntn ) ){
468         return NodeManager::currentNM()->mkNode( kind::IS_INTEGER, n );
469       }
470     }else if( tn.isDatatype() && ntn.isDatatype() ){
471       if( tn.isTuple() && ntn.isTuple() ){
472         const Datatype& dt1 = tn.getDatatype();
473         const Datatype& dt2 = ntn.getDatatype();
474         if( dt1[0].getNumArgs()==dt2[0].getNumArgs() ){
475           std::vector< Node > conds;
476           for( unsigned i=0; i<dt2[0].getNumArgs(); i++ ){
477             Node s = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( dt2[0][i].getSelector() ), n );
478             Node etc = getEnsureTypeCondition( s, TypeNode::fromType( dt1[0][i].getRangeType() ) );
479             if( etc.isNull() ){
480               return Node::null();
481             }else{
482               conds.push_back( etc );
483             }
484           }
485           if( conds.empty() ){
486             return NodeManager::currentNM()->mkConst( true );
487           }else if( conds.size()==1 ){
488             return conds[0];
489           }else{
490             return NodeManager::currentNM()->mkNode( kind::AND, conds );
491           }
492         }
493       }
494     }
495     return Node::null();
496   }else{
497     return NodeManager::currentNM()->mkConst( true );
498   }
499 }
500 
501 /** Is this a sort kind */
isSort() const502 bool TypeNode::isSort() const {
503   return ( getKind() == kind::SORT_TYPE && !hasAttribute(expr::SortArityAttr()) );
504 }
505 
506 /** Is this a sort constructor kind */
isSortConstructor() const507 bool TypeNode::isSortConstructor() const {
508   return getKind() == kind::SORT_TYPE && hasAttribute(expr::SortArityAttr());
509 }
510 
toString() const511 std::string TypeNode::toString() const {
512   std::stringstream ss;
513   OutputLanguage outlang = (this == &s_null) ? language::output::LANG_AUTO : options::outputLanguage();
514   d_nv->toStream(ss, -1, false, 0, outlang);
515   return ss.str();
516 }
517 
518 
519 }/* CVC4 namespace */
520