1 /*********************                                                        */
2 /*! \file type_node.h
3  ** \verbatim
4  ** Top contributors (to current version):
5  **   Morgan Deters, Dejan Jovanovic, Andrew Reynolds
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 
17 #include "cvc4_private.h"
18 
19 // circular dependency
20 #include "expr/node_value.h"
21 
22 #ifndef __CVC4__TYPE_NODE_H
23 #define __CVC4__TYPE_NODE_H
24 
25 #include <stdint.h>
26 
27 #include <iostream>
28 #include <string>
29 #include <unordered_map>
30 #include <vector>
31 
32 #include "base/cvc4_assert.h"
33 #include "expr/kind.h"
34 #include "expr/metakind.h"
35 #include "util/cardinality.h"
36 
37 namespace CVC4 {
38 
39 class NodeManager;
40 
41 namespace expr {
42   class NodeValue;
43 }/* CVC4::expr namespace */
44 
45 /**
46  * Encapsulation of an NodeValue pointer for Types. The reference count is
47  * maintained in the NodeValue.
48  */
49 class TypeNode {
50 
51 public:
52 
53   // for hash_maps, hash_sets..
54   struct HashFunction {
operatorHashFunction55     size_t operator()(TypeNode node) const {
56       return (size_t) node.getId();
57     }
58   };/* struct HashFunction */
59 
60 private:
61 
62   /**
63    * The NodeValue has access to the private constructors, so that the
64    * iterators can can create new types.
65    */
66   friend class expr::NodeValue;
67 
68   /** A convenient null-valued encapsulated pointer */
69   static TypeNode s_null;
70 
71   /** The referenced NodeValue */
72   expr::NodeValue* d_nv;
73 
74   /**
75    * This constructor is reserved for use by the TypeNode package.
76    */
77   explicit TypeNode(const expr::NodeValue*);
78 
79   friend class NodeManager;
80 
81   template <unsigned nchild_thresh>
82   friend class NodeBuilder;
83 
84   /**
85    * Assigns the expression value and does reference counting. No
86    * assumptions are made on the expression, and should only be used
87    * if we know what we are doing.
88    *
89    * @param ev the expression value to assign
90    */
91   void assignNodeValue(expr::NodeValue* ev);
92 
93   /**
94    * Cache-aware, recursive version of substitute() used by the public
95    * member function with a similar signature.
96    */
97   TypeNode substitute(const TypeNode& type, const TypeNode& replacement,
98                       std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const;
99 
100   /**
101    * Cache-aware, recursive version of substitute() used by the public
102    * member function with a similar signature.
103    */
104   template <class Iterator1, class Iterator2>
105   TypeNode substitute(Iterator1 typesBegin, Iterator1 typesEnd,
106                       Iterator2 replacementsBegin, Iterator2 replacementsEnd,
107                       std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const;
108 
109 public:
110 
111   /** Default constructor, makes a null expression. */
TypeNode()112   TypeNode() : d_nv(&expr::NodeValue::null()) { }
113 
114   /** Copy constructor */
115   TypeNode(const TypeNode& node);
116 
117   /**
118    * Destructor. If ref_count is true it will decrement the reference count
119    * and, if zero, collect the NodeValue.
120    */
121   ~TypeNode();
122 
123   /**
124    * Assignment operator for nodes, copies the relevant information from node
125    * to this node.
126    *
127    * @param typeNode the node to copy
128    * @return reference to this node
129    */
130   TypeNode& operator=(const TypeNode& typeNode);
131 
132   /**
133    * Return the null node.
134    *
135    * @return the null node
136    */
null()137   static TypeNode null() {
138     return s_null;
139   }
140 
141   /**
142    * Substitution of TypeNodes.
143    */
144   inline TypeNode
145   substitute(const TypeNode& type, const TypeNode& replacement) const;
146 
147   /**
148    * Simultaneous substitution of TypeNodes.
149    */
150   template <class Iterator1, class Iterator2>
151   inline TypeNode
152   substitute(Iterator1 typesBegin, Iterator1 typesEnd,
153              Iterator2 replacementsBegin, Iterator2 replacementsEnd) const;
154 
155   /**
156    * Structural comparison operator for expressions.
157    *
158    * @param typeNode the type node to compare to
159    * @return true if expressions are equal, false otherwise
160    */
161   bool operator==(const TypeNode& typeNode) const {
162     return d_nv == typeNode.d_nv;
163   }
164 
165   /**
166    * Structural comparison operator for expressions.
167    *
168    * @param typeNode the type node to compare to
169    * @return true if expressions are equal, false otherwise
170    */
171   bool operator!=(const TypeNode& typeNode) const {
172     return !(*this == typeNode);
173   }
174 
175   /**
176    * We compare by expression ids so, keeping things deterministic and having
177    * that subexpressions have to be smaller than the enclosing expressions.
178    *
179    * @param typeNode the node to compare to
180    * @return true if this expression is lesser
181    */
182   inline bool operator<(const TypeNode& typeNode) const {
183     return d_nv->d_id < typeNode.d_nv->d_id;
184   }
185 
186   /**
187    * We compare by expression ids so, keeping things deterministic and having
188    * that subexpressions have to be smaller than the enclosing expressions.
189    *
190    * @param typeNode the node to compare to
191    * @return true if this expression is lesser or equal
192    */
193   inline bool operator<=(const TypeNode& typeNode) const {
194     return d_nv->d_id <= typeNode.d_nv->d_id;
195   }
196 
197   /**
198    * We compare by expression ids so, keeping things deterministic and having
199    * that subexpressions have to be smaller than the enclosing expressions.
200    *
201    * @param typeNode the node to compare to
202    * @return true if this expression is greater
203    */
204   inline bool operator>(const TypeNode& typeNode) const {
205     return d_nv->d_id > typeNode.d_nv->d_id;
206   }
207 
208   /**
209    * We compare by expression ids so, keeping things deterministic and having
210    * that subexpressions have to be smaller than the enclosing expressions.
211    *
212    * @param typeNode the node to compare to
213    * @return true if this expression is greater or equal
214    */
215   inline bool operator>=(const TypeNode& typeNode) const {
216     return d_nv->d_id >= typeNode.d_nv->d_id;
217   }
218 
219   /**
220    * Returns the i-th child of this node.
221    *
222    * @param i the index of the child
223    * @return the node representing the i-th child
224    */
225   inline TypeNode operator[](int i) const {
226     return TypeNode(d_nv->getChild(i));
227   }
228 
229   /**
230    * PARAMETERIZED-metakinded types (the SORT_TYPE is one of these)
231    * have an operator.  "Little-p parameterized" types (like Array),
232    * are OPERATORs, not PARAMETERIZEDs.
233    */
getOperator()234   inline Node getOperator() const {
235     Assert(getMetaKind() == kind::metakind::PARAMETERIZED);
236     return Node(d_nv->getOperator());
237   }
238 
239   /**
240    * Returns the unique id of this node
241    *
242    * @return the id
243    */
getId()244   inline unsigned long getId() const {
245     return d_nv->getId();
246   }
247 
248   /**
249    * Returns the kind of this type node.
250    *
251    * @return the kind
252    */
getKind()253   inline Kind getKind() const {
254     return Kind(d_nv->d_kind);
255   }
256 
257   /**
258    * Returns the metakind of this type node.
259    *
260    * @return the metakind
261    */
getMetaKind()262   inline kind::MetaKind getMetaKind() const {
263     return kind::metaKindOf(getKind());
264   }
265 
266   /**
267    * Returns the number of children this node has.
268    *
269    * @return the number of children
270    */
271   inline size_t getNumChildren() const;
272 
273   /**
274    * If this is a CONST_* TypeNode, extract the constant from it.
275    */
276   template <class T>
277   inline const T& getConst() const;
278 
279   /**
280    * Returns the value of the given attribute that this has been attached.
281    *
282    * @param attKind the kind of the attribute
283    * @return the value of the attribute
284    */
285   template <class AttrKind>
286   inline typename AttrKind::value_type
287   getAttribute(const AttrKind& attKind) const;
288 
289   // Note that there are two, distinct hasAttribute() declarations for
290   // a reason (rather than using a pointer-valued argument with a
291   // default value): they permit more optimized code in the underlying
292   // hasAttribute() implementations.
293 
294   /**
295    * Returns true if this node has been associated an attribute of
296    * given kind.  Additionally, if a pointer to the value_kind is
297    * give, and the attribute value has been set for this node, it will
298    * be returned.
299    *
300    * @param attKind the kind of the attribute
301    * @return true if this node has the requested attribute
302    */
303   template <class AttrKind>
304   inline bool hasAttribute(const AttrKind& attKind) const;
305 
306   /**
307    * Returns true if this node has been associated an attribute of given kind.
308    * Additionaly, if a pointer to the value_kind is give, and the attribute
309    * value has been set for this node, it will be returned.
310    *
311    * @param attKind the kind of the attribute
312    * @param value where to store the value if it exists
313    * @return true if this node has the requested attribute
314    */
315   template <class AttrKind>
316   inline bool getAttribute(const AttrKind& attKind,
317                            typename AttrKind::value_type& value) const;
318 
319   /**
320    * Sets the given attribute of this node to the given value.
321    *
322    * @param attKind the kind of the atribute
323    * @param value the value to set the attribute to
324    */
325   template <class AttrKind>
326   inline void setAttribute(const AttrKind& attKind,
327                            const typename AttrKind::value_type& value);
328 
329   /** Iterator allowing for scanning through the children. */
330   typedef expr::NodeValue::iterator<TypeNode> iterator;
331   /** Constant iterator allowing for scanning through the children. */
332   typedef expr::NodeValue::iterator<TypeNode> const_iterator;
333 
334   /**
335    * Returns the iterator pointing to the first child.
336    *
337    * @return the iterator
338    */
begin()339   inline iterator begin() {
340     return d_nv->begin<TypeNode>();
341   }
342 
343   /**
344    * Returns the iterator pointing to the end of the children (one
345    * beyond the last one.
346    *
347    * @return the end of the children iterator.
348    */
end()349   inline iterator end() {
350     return d_nv->end<TypeNode>();
351   }
352 
353   /**
354    * Returns the const_iterator pointing to the first child.
355    *
356    * @return the const_iterator
357    */
begin()358   inline const_iterator begin() const {
359     return d_nv->begin<TypeNode>();
360   }
361 
362   /**
363    * Returns the const_iterator pointing to the end of the children
364    * (one beyond the last one.
365    *
366    * @return the end of the children const_iterator.
367    */
end()368   inline const_iterator end() const {
369     return d_nv->end<TypeNode>();
370   }
371 
372   /**
373    * Converts this type into a string representation.
374    *
375    * @return the string representation of this type.
376    */
377   std::string toString() const;
378 
379   /**
380    * Converts this node into a string representation and sends it to the
381    * given stream
382    *
383    * @param out the stream to serialize this node to
384    * @param language the language in which to output
385    */
386   inline void toStream(std::ostream& out, OutputLanguage language = language::output::LANG_AUTO) const {
387     d_nv->toStream(out, -1, false, 0, language);
388   }
389 
390   /**
391    * Very basic pretty printer for Node.
392    *
393    * @param out output stream to print to.
394    * @param indent number of spaces to indent the formula by.
395    */
396   void printAst(std::ostream& out, int indent = 0) const;
397 
398   /**
399    * Returns true if this type is a null type.
400    *
401    * @return true if null
402    */
isNull()403   bool isNull() const {
404     return d_nv == &expr::NodeValue::null();
405   }
406 
407   /**
408    * Convert this TypeNode into a Type using the currently-in-scope
409    * manager.
410    */
411   inline Type toType();
412 
413   /**
414    * Convert a Type into a TypeNode.
415    */
416   inline static TypeNode fromType(const Type& t);
417 
418   /**
419    * Returns the cardinality of this type.
420    *
421    * @return a finite or infinite cardinality
422    */
423   Cardinality getCardinality() const;
424 
425   /**
426    * Is this type interpreted as being finite.
427    * If finite model finding is enabled, this assumes all uninterpreted sorts
428    *   are interpreted as finite.
429    */
430   bool isInterpretedFinite();
431 
432   /** is closed enumerable type
433    *
434    * This returns true if this type has an enumerator that produces constants
435    * that are fully handled by CVC4's quantifier-free theory solvers. Examples
436    * of types that are not closed enumerable are:
437    * (1) uninterpreted sorts,
438    * (2) arrays,
439    * (3) codatatypes,
440    * (4) functions,
441    * (5) parametric sorts involving any of the above.
442    */
443   bool isClosedEnumerable();
444 
445   /**
446    * Is this a first-class type?
447    * First-class types are types for which:
448    * (1) we handle equalities between terms of that type, and
449    * (2) they are allowed to be parameters of parametric types (e.g. index or element types of arrays).
450    *
451    * Examples of types that are not first-class include constructor types,
452    * selector types, tester types, regular expressions and SExprs.
453    */
454   bool isFirstClass() const;
455 
456   /**
457    * Returns whether this type is well-founded.
458    *
459    * @return true iff the type is well-founded
460    */
461   bool isWellFounded() const;
462 
463   /**
464    * Construct and return a ground term of this type.  If the type is
465    * not well founded, this function throws an exception.
466    *
467    * @return a ground term of the type
468    */
469   Node mkGroundTerm() const;
470 
471   /**
472    * Is this type a subtype of the given type?
473    */
474   bool isSubtypeOf(TypeNode t) const;
475 
476   /**
477    * Is this type comparable to the given type (i.e., do they share
478    * a common ancestor in the subtype tree)?
479    */
480   bool isComparableTo(TypeNode t) const;
481 
482   /** Is this the Boolean type? */
483   bool isBoolean() const;
484 
485   /** Is this the Integer type? */
486   bool isInteger() const;
487 
488   /** Is this the Real type? */
489   bool isReal() const;
490 
491   /** Is this the String type? */
492   bool isString() const;
493 
494   /** Is this the Rounding Mode type? */
495   bool isRoundingMode() const;
496 
497   /** Is this an array type? */
498   bool isArray() const;
499 
500   /** Is this a Set type? */
501   bool isSet() const;
502 
503   /** Get the index type (for array types) */
504   TypeNode getArrayIndexType() const;
505 
506   /** Get the element type (for array types) */
507   TypeNode getArrayConstituentType() const;
508 
509   /** Get the return type (for constructor types) */
510   TypeNode getConstructorRangeType() const;
511 
512   /** Get the element type (for set types) */
513   TypeNode getSetElementType() const;
514 
515   /**
516    * Is this a function type?  Function-like things (e.g. datatype
517    * selectors) that aren't actually functions are NOT considered
518    * functions, here.
519    */
520   bool isFunction() const;
521 
522   /**
523    * Is this a function-LIKE type?  Function-like things
524    * (e.g. datatype selectors) that aren't actually functions ARE
525    * considered functions, here.  The main point is that this is used
526    * to avoid anything higher-order: anything function-like cannot be
527    * the argument or return value for anything else function-like.
528    *
529    * Arrays are explicitly *not* function-like for the purposes of
530    * this test.  However, functions still cannot contain anything
531    * function-like.
532    */
533   bool isFunctionLike() const;
534 
535   /**
536    * Get the argument types of a function, datatype constructor,
537    * datatype selector, or datatype tester.
538    */
539   std::vector<TypeNode> getArgTypes() const;
540 
541   /**
542    * Get the paramater types of a parameterized datatype.  Fails an
543    * assertion if this type is not a parametric datatype.
544    */
545   std::vector<TypeNode> getParamTypes() const;
546 
547   /**
548    * Get the range type (i.e., the type of the result) of a function,
549    * datatype constructor, datatype selector, or datatype tester.
550    */
551   TypeNode getRangeType() const;
552 
553   /**
554    * Is this a predicate type?  NOTE: all predicate types are also
555    * function types (so datatype testers are NOT considered
556    * "predicates" for the purpose of this function).
557    */
558   bool isPredicate() const;
559 
560   /**
561    * Is this a predicate-LIKE type?  Predicate-like things
562    * (e.g. datatype testers) that aren't actually predicates ARE
563    * considered predicates, here.
564    *
565    * Arrays are explicitly *not* predicate-like for the purposes of
566    * this test.
567    */
568   bool isPredicateLike() const;
569 
570   /** Is this a tuple type? */
571   bool isTuple() const;
572 
573   /** Get the length of a tuple type */
574   size_t getTupleLength() const;
575 
576   /** Get the constituent types of a tuple type */
577   std::vector<TypeNode> getTupleTypes() const;
578 
579   /** Is this a record type? */
580   bool isRecord() const;
581 
582   /** Get the description of the record type */
583   const Record& getRecord() const;
584 
585   /** Is this a symbolic expression type? */
586   bool isSExpr() const;
587 
588   /** Get the constituent types of a symbolic expression type */
589   std::vector<TypeNode> getSExprTypes() const;
590 
591   /** Is this a regexp type */
592   bool isRegExp() const;
593 
594   /** Is this a floating-point type */
595   bool isFloatingPoint() const;
596 
597   /** Is this a floating-point type of with <code>exp</code> exponent bits
598       and <code>sig</code> significand bits */
599   bool isFloatingPoint(unsigned exp, unsigned sig) const;
600 
601   /** Is this a bit-vector type */
602   bool isBitVector() const;
603 
604   /** Is this a bit-vector type of size <code>size</code> */
605   bool isBitVector(unsigned size) const;
606 
607   /** Is this a datatype type */
608   bool isDatatype() const;
609 
610   /** Is this a parameterized datatype type */
611   bool isParametricDatatype() const;
612 
613   /** Is this a codatatype type */
614   bool isCodatatype() const;
615 
616   /** Is this a fully instantiated datatype type */
617   bool isInstantiatedDatatype() const;
618 
619   /** Is this an instantiated datatype parameter */
620   bool isParameterInstantiatedDatatype(unsigned n) const;
621 
622   /** Is this a constructor type */
623   bool isConstructor() const;
624 
625   /** Is this a selector type */
626   bool isSelector() const;
627 
628   /** Is this a tester type */
629   bool isTester() const;
630 
631   /** Get the Datatype specification from a datatype type */
632   const Datatype& getDatatype() const;
633 
634   /** Get the exponent size of this floating-point type */
635   unsigned getFloatingPointExponentSize() const;
636 
637   /** Get the significand size of this floating-point type */
638   unsigned getFloatingPointSignificandSize() const;
639 
640   /** Get the size of this bit-vector type */
641   unsigned getBitVectorSize() const;
642 
643   /** Is this a sort kind */
644   bool isSort() const;
645 
646   /** Is this a sort constructor kind */
647   bool isSortConstructor() const;
648 
649   /** Get the most general base type of the type */
650   TypeNode getBaseType() const;
651 
652   /**
653    * Returns the leastUpperBound in the extended type lattice of the two types.
654    * If this is \top, i.e. there is no inhabited type that contains both,
655    * a TypeNode such that isNull() is true is returned.
656    *
657    * For more information see: http://cvc4.cs.nyu.edu/wiki/Cvc4_Type_Lattice
658    */
659   static TypeNode leastCommonTypeNode(TypeNode t0, TypeNode t1);
660   static TypeNode mostCommonTypeNode(TypeNode t0, TypeNode t1);
661 
662   /** get ensure type condition
663    *  Return value is a condition that implies that n has type tn.
664   */
665   static Node getEnsureTypeCondition( Node n, TypeNode tn );
666 private:
667   static TypeNode commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast);
668 
669   /**
670    * Indents the given stream a given amount of spaces.
671    *
672    * @param out the stream to indent
673    * @param indent the number of spaces
674    */
indent(std::ostream & out,int indent)675   static void indent(std::ostream& out, int indent) {
676     for(int i = 0; i < indent; i++) {
677       out << ' ';
678     }
679   }
680 
681 };/* class TypeNode */
682 
683 /**
684  * Serializes a given node to the given stream.
685  *
686  * @param out the output stream to use
687  * @param n the node to output to the stream
688  * @return the stream
689  */
690 inline std::ostream& operator<<(std::ostream& out, const TypeNode& n) {
691   n.toStream(out, Node::setlanguage::getLanguage(out));
692   return out;
693 }
694 
695 typedef TypeNode::HashFunction TypeNodeHashFunction;
696 
697 }/* CVC4 namespace */
698 
699 #include "expr/node_manager.h"
700 
701 namespace CVC4 {
702 
toType()703 inline Type TypeNode::toType() {
704   return NodeManager::currentNM()->toType(*this);
705 }
706 
fromType(const Type & t)707 inline TypeNode TypeNode::fromType(const Type& t) {
708   return NodeManager::fromType(t);
709 }
710 
711 inline TypeNode
substitute(const TypeNode & type,const TypeNode & replacement)712 TypeNode::substitute(const TypeNode& type,
713                      const TypeNode& replacement) const {
714   std::unordered_map<TypeNode, TypeNode, HashFunction> cache;
715   return substitute(type, replacement, cache);
716 }
717 
718 template <class Iterator1, class Iterator2>
719 inline TypeNode
substitute(Iterator1 typesBegin,Iterator1 typesEnd,Iterator2 replacementsBegin,Iterator2 replacementsEnd)720 TypeNode::substitute(Iterator1 typesBegin,
721                      Iterator1 typesEnd,
722                      Iterator2 replacementsBegin,
723                      Iterator2 replacementsEnd) const {
724   std::unordered_map<TypeNode, TypeNode, HashFunction> cache;
725   return substitute(typesBegin, typesEnd,
726                     replacementsBegin, replacementsEnd, cache);
727 }
728 
729 template <class Iterator1, class Iterator2>
substitute(Iterator1 typesBegin,Iterator1 typesEnd,Iterator2 replacementsBegin,Iterator2 replacementsEnd,std::unordered_map<TypeNode,TypeNode,HashFunction> & cache)730 TypeNode TypeNode::substitute(Iterator1 typesBegin,
731                               Iterator1 typesEnd,
732                               Iterator2 replacementsBegin,
733                               Iterator2 replacementsEnd,
734                               std::unordered_map<TypeNode, TypeNode, HashFunction>& cache) const {
735   // in cache?
736   std::unordered_map<TypeNode, TypeNode, HashFunction>::const_iterator i = cache.find(*this);
737   if(i != cache.end()) {
738     return (*i).second;
739   }
740 
741   // otherwise compute
742   Assert( typesEnd - typesBegin == replacementsEnd - replacementsBegin,
743           "Substitution iterator ranges must be equal size" );
744   Iterator1 j = find(typesBegin, typesEnd, *this);
745   if(j != typesEnd) {
746     TypeNode tn = *(replacementsBegin + (j - typesBegin));
747     cache[*this] = tn;
748     return tn;
749   } else if(getNumChildren() == 0) {
750     cache[*this] = *this;
751     return *this;
752   } else {
753     NodeBuilder<> nb(getKind());
754     if(getMetaKind() == kind::metakind::PARAMETERIZED) {
755       // push the operator
756       nb << TypeNode(d_nv->d_children[0]);
757     }
758     for(TypeNode::const_iterator i = begin(),
759           iend = end();
760         i != iend;
761         ++i) {
762       nb << (*i).substitute(typesBegin, typesEnd,
763                             replacementsBegin, replacementsEnd, cache);
764     }
765     TypeNode tn = nb.constructTypeNode();
766     cache[*this] = tn;
767     return tn;
768   }
769 }
770 
getNumChildren()771 inline size_t TypeNode::getNumChildren() const {
772   return d_nv->getNumChildren();
773 }
774 
775 template <class T>
getConst()776 inline const T& TypeNode::getConst() const {
777   return d_nv->getConst<T>();
778 }
779 
TypeNode(const expr::NodeValue * ev)780 inline TypeNode::TypeNode(const expr::NodeValue* ev) :
781   d_nv(const_cast<expr::NodeValue*> (ev)) {
782   Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
783   d_nv->inc();
784 }
785 
TypeNode(const TypeNode & typeNode)786 inline TypeNode::TypeNode(const TypeNode& typeNode) {
787   Assert(typeNode.d_nv != NULL, "Expecting a non-NULL expression value!");
788   d_nv = typeNode.d_nv;
789   d_nv->inc();
790 }
791 
~TypeNode()792 inline TypeNode::~TypeNode() {
793   Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
794   d_nv->dec();
795 }
796 
assignNodeValue(expr::NodeValue * ev)797 inline void TypeNode::assignNodeValue(expr::NodeValue* ev) {
798   d_nv = ev;
799   d_nv->inc();
800 }
801 
802 inline TypeNode& TypeNode::operator=(const TypeNode& typeNode) {
803   Assert(d_nv != NULL, "Expecting a non-NULL expression value!");
804   Assert(typeNode.d_nv != NULL,
805          "Expecting a non-NULL expression value on RHS!");
806   if(__builtin_expect( ( d_nv != typeNode.d_nv ), true )) {
807     d_nv->dec();
808     d_nv = typeNode.d_nv;
809     d_nv->inc();
810   }
811   return *this;
812 }
813 
814 template <class AttrKind>
815 inline typename AttrKind::value_type TypeNode::
getAttribute(const AttrKind &)816 getAttribute(const AttrKind&) const {
817   Assert( NodeManager::currentNM() != NULL,
818           "There is no current CVC4::NodeManager associated to this thread.\n"
819           "Perhaps a public-facing function is missing a NodeManagerScope ?" );
820   return NodeManager::currentNM()->getAttribute(d_nv, AttrKind());
821 }
822 
823 template <class AttrKind>
824 inline bool TypeNode::
hasAttribute(const AttrKind &)825 hasAttribute(const AttrKind&) const {
826   Assert( NodeManager::currentNM() != NULL,
827           "There is no current CVC4::NodeManager associated to this thread.\n"
828           "Perhaps a public-facing function is missing a NodeManagerScope ?" );
829   return NodeManager::currentNM()->hasAttribute(d_nv, AttrKind());
830 }
831 
832 template <class AttrKind>
getAttribute(const AttrKind &,typename AttrKind::value_type & ret)833 inline bool TypeNode::getAttribute(const AttrKind&, typename AttrKind::value_type& ret) const {
834   Assert( NodeManager::currentNM() != NULL,
835           "There is no current CVC4::NodeManager associated to this thread.\n"
836           "Perhaps a public-facing function is missing a NodeManagerScope ?" );
837   return NodeManager::currentNM()->getAttribute(d_nv, AttrKind(), ret);
838 }
839 
840 template <class AttrKind>
841 inline void TypeNode::
setAttribute(const AttrKind &,const typename AttrKind::value_type & value)842 setAttribute(const AttrKind&, const typename AttrKind::value_type& value) {
843   Assert( NodeManager::currentNM() != NULL,
844           "There is no current CVC4::NodeManager associated to this thread.\n"
845           "Perhaps a public-facing function is missing a NodeManagerScope ?" );
846   NodeManager::currentNM()->setAttribute(d_nv, AttrKind(), value);
847 }
848 
printAst(std::ostream & out,int indent)849 inline void TypeNode::printAst(std::ostream& out, int indent) const {
850   d_nv->printAst(out, indent);
851 }
852 
isBoolean()853 inline bool TypeNode::isBoolean() const {
854   return
855     ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == BOOLEAN_TYPE );
856 }
857 
isInteger()858 inline bool TypeNode::isInteger() const {
859   return
860     ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == INTEGER_TYPE );
861 }
862 
isReal()863 inline bool TypeNode::isReal() const {
864   return
865     ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == REAL_TYPE ) ||
866     isInteger();
867 }
868 
isString()869 inline bool TypeNode::isString() const {
870   return getKind() == kind::TYPE_CONSTANT &&
871     getConst<TypeConstant>() == STRING_TYPE;
872 }
873 
874 /** Is this a regexp type */
isRegExp()875 inline bool TypeNode::isRegExp() const {
876   return getKind() == kind::TYPE_CONSTANT &&
877     getConst<TypeConstant>() == REGEXP_TYPE;
878  }
879 
isRoundingMode()880 inline bool TypeNode::isRoundingMode() const {
881   return getKind() == kind::TYPE_CONSTANT &&
882     getConst<TypeConstant>() == ROUNDINGMODE_TYPE;
883 }
884 
isArray()885 inline bool TypeNode::isArray() const {
886   return getKind() == kind::ARRAY_TYPE;
887 }
888 
getArrayIndexType()889 inline TypeNode TypeNode::getArrayIndexType() const {
890   Assert(isArray());
891   return (*this)[0];
892 }
893 
getArrayConstituentType()894 inline TypeNode TypeNode::getArrayConstituentType() const {
895   Assert(isArray());
896   return (*this)[1];
897 }
898 
getConstructorRangeType()899 inline TypeNode TypeNode::getConstructorRangeType() const {
900   Assert(isConstructor());
901   return (*this)[getNumChildren()-1];
902 }
903 
isSet()904 inline bool TypeNode::isSet() const {
905   return getKind() == kind::SET_TYPE;
906 }
907 
getSetElementType()908 inline TypeNode TypeNode::getSetElementType() const {
909   Assert(isSet());
910   return (*this)[0];
911 }
912 
isFunction()913 inline bool TypeNode::isFunction() const {
914   return getKind() == kind::FUNCTION_TYPE;
915 }
916 
isFunctionLike()917 inline bool TypeNode::isFunctionLike() const {
918   return
919     getKind() == kind::FUNCTION_TYPE ||
920     getKind() == kind::CONSTRUCTOR_TYPE ||
921     getKind() == kind::SELECTOR_TYPE ||
922     getKind() == kind::TESTER_TYPE;
923 }
924 
isPredicate()925 inline bool TypeNode::isPredicate() const {
926   return isFunction() && getRangeType().isBoolean();
927 }
928 
isPredicateLike()929 inline bool TypeNode::isPredicateLike() const {
930   return isFunctionLike() && getRangeType().isBoolean();
931 }
932 
getRangeType()933 inline TypeNode TypeNode::getRangeType() const {
934   if(isTester()) {
935     return NodeManager::currentNM()->booleanType();
936   }
937   Assert(isFunction() || isConstructor() || isSelector());
938   return (*this)[getNumChildren() - 1];
939 }
940 
941 /** Is this a symbolic expression type? */
isSExpr()942 inline bool TypeNode::isSExpr() const {
943   return getKind() == kind::SEXPR_TYPE;
944 }
945 
946 /** Is this a floating-point type */
isFloatingPoint()947 inline bool TypeNode::isFloatingPoint() const {
948   return getKind() == kind::FLOATINGPOINT_TYPE;
949 }
950 
951 /** Is this a bit-vector type */
isBitVector()952 inline bool TypeNode::isBitVector() const {
953   return getKind() == kind::BITVECTOR_TYPE;
954 }
955 
956 /** Is this a datatype type */
isDatatype()957 inline bool TypeNode::isDatatype() const {
958   return getKind() == kind::DATATYPE_TYPE || getKind() == kind::PARAMETRIC_DATATYPE;
959 }
960 
961 /** Is this a parametric datatype type */
isParametricDatatype()962 inline bool TypeNode::isParametricDatatype() const {
963   return getKind() == kind::PARAMETRIC_DATATYPE;
964 }
965 
966 /** Is this a codatatype type */
isCodatatype()967 inline bool TypeNode::isCodatatype() const {
968   if( isDatatype() ){
969     return getDatatype().isCodatatype();
970   }else{
971     return false;
972   }
973 }
974 
975 /** Is this a constructor type */
isConstructor()976 inline bool TypeNode::isConstructor() const {
977   return getKind() == kind::CONSTRUCTOR_TYPE;
978 }
979 
980 /** Is this a selector type */
isSelector()981 inline bool TypeNode::isSelector() const {
982   return getKind() == kind::SELECTOR_TYPE;
983 }
984 
985 /** Is this a tester type */
isTester()986 inline bool TypeNode::isTester() const {
987   return getKind() == kind::TESTER_TYPE;
988 }
989 
990 /** Is this a floating-point type of with <code>exp</code> exponent bits
991     and <code>sig</code> significand bits */
isFloatingPoint(unsigned exp,unsigned sig)992 inline bool TypeNode::isFloatingPoint(unsigned exp, unsigned sig) const {
993   return
994     ( getKind() == kind::FLOATINGPOINT_TYPE &&
995       getConst<FloatingPointSize>().exponent() == exp &&
996       getConst<FloatingPointSize>().significand() == sig );
997 }
998 
999 /** Is this a bit-vector type of size <code>size</code> */
isBitVector(unsigned size)1000 inline bool TypeNode::isBitVector(unsigned size) const {
1001   return
1002     ( getKind() == kind::BITVECTOR_TYPE && getConst<BitVectorSize>() == size );
1003 }
1004 
1005 /** Get the datatype specification from a datatype type */
getDatatype()1006 inline const Datatype& TypeNode::getDatatype() const {
1007   Assert(isDatatype());
1008   if( getKind() == kind::DATATYPE_TYPE ){
1009     DatatypeIndexConstant dic = getConst<DatatypeIndexConstant>();
1010     return NodeManager::currentNM()->getDatatypeForIndex( dic.getIndex() );
1011   }else{
1012     Assert( getKind() == kind::PARAMETRIC_DATATYPE );
1013     return (*this)[0].getDatatype();
1014   }
1015 }
1016 
1017 /** Get the exponent size of this floating-point type */
getFloatingPointExponentSize()1018 inline unsigned TypeNode::getFloatingPointExponentSize() const {
1019   Assert(isFloatingPoint());
1020   return getConst<FloatingPointSize>().exponent();
1021 }
1022 
1023 /** Get the significand size of this floating-point type */
getFloatingPointSignificandSize()1024 inline unsigned TypeNode::getFloatingPointSignificandSize() const {
1025  Assert(isFloatingPoint());
1026  return getConst<FloatingPointSize>().significand();
1027 }
1028 
1029 /** Get the size of this bit-vector type */
getBitVectorSize()1030 inline unsigned TypeNode::getBitVectorSize() const {
1031   Assert(isBitVector());
1032   return getConst<BitVectorSize>();
1033 }
1034 
1035 #ifdef CVC4_DEBUG
1036 /**
1037  * Pretty printer for use within gdb.  This is not intended to be used
1038  * outside of gdb.  This writes to the Warning() stream and immediately
1039  * flushes the stream.
1040  *
1041  * Note that this function cannot be a template, since the compiler
1042  * won't instantiate it.  Even if we explicitly instantiate.  (Odd?)
1043  * So we implement twice.  We mark as __attribute__((used)) so that
1044  * GCC emits code for it even though static analysis indicates it's
1045  * never called.
1046  *
1047  * Tim's Note: I moved this into the node.h file because this allows gdb
1048  * to find the symbol, and use it, which is the first standard this code needs
1049  * to meet. A cleaner solution is welcomed.
1050  */
debugPrintTypeNode(const TypeNode & n)1051 static void __attribute__((used)) debugPrintTypeNode(const TypeNode& n) {
1052   Warning() << Node::setdepth(-1)
1053             << Node::printtypes(false)
1054             << Node::dag(true)
1055             << Node::setlanguage(language::output::LANG_AST)
1056             << n << std::endl;
1057   Warning().flush();
1058 }
debugPrintTypeNodeNoDag(const TypeNode & n)1059 static void __attribute__((used)) debugPrintTypeNodeNoDag(const TypeNode& n) {
1060   Warning() << Node::setdepth(-1)
1061             << Node::printtypes(false)
1062             << Node::dag(false)
1063             << Node::setlanguage(language::output::LANG_AST)
1064             << n << std::endl;
1065   Warning().flush();
1066 }
debugPrintRawTypeNode(const TypeNode & n)1067 static void __attribute__((used)) debugPrintRawTypeNode(const TypeNode& n) {
1068   n.printAst(Warning(), 0);
1069   Warning().flush();
1070 }
1071 #endif /* CVC4_DEBUG */
1072 
1073 }/* CVC4 namespace */
1074 
1075 #endif /* __CVC4__NODE_H */
1076