GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/type_node.h Lines: 160 192 83.3 %
Date: 2021-09-17 Branches: 150 743 20.2 %

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