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