GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/type_node.h Lines: 157 184 85.3 %
Date: 2021-09-29 Branches: 130 545 23.9 %

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
442663981
  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
2395
  static TypeNode null() {
129
2395
    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
22512003
  bool operator==(const TypeNode& typeNode) const {
153
22512003
    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
5460372
  bool operator!=(const TypeNode& typeNode) const {
163
5460372
    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
36134802
  inline bool operator<(const TypeNode& typeNode) const {
174
36134802
    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
3272917
  inline TypeNode operator[](int i) const {
217
3272917
    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
1863649
  inline unsigned long getId() const {
236
1863649
    return d_nv->getId();
237
  }
238
239
  /**
240
   * Returns the kind of this type node.
241
   *
242
   * @return the kind
243
   */
244
286225312
  inline Kind getKind() const {
245
286225312
    return Kind(d_nv->d_kind);
246
  }
247
248
  /**
249
   * Returns the metakind of this type node.
250
   *
251
   * @return the metakind
252
   */
253
1540
  inline kind::MetaKind getMetaKind() const {
254
1540
    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
325496
  inline iterator begin() {
331
325496
    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
7768
  inline iterator end() {
341
7768
    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
1540
  inline const_iterator begin() const {
350
1540
    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
1540
  inline const_iterator end() const {
360
1540
    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
13981
  inline void toStream(std::ostream& out,
378
                       Language language = Language::LANG_AUTO) const
379
  {
380
13981
    d_nv->toStream(out, -1, 0, language);
381
13981
  }
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
15821463
  bool isNull() const {
397
15821463
    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
13923
inline std::ostream& operator<<(std::ostream& out, const TypeNode& n) {
729
13923
  n.toStream(out, Node::setlanguage::getLanguage(out));
730
13923
  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
13968
TypeNode::substitute(Iterator1 typesBegin,
759
                     Iterator1 typesEnd,
760
                     Iterator2 replacementsBegin,
761
                     Iterator2 replacementsEnd) const {
762
27936
  std::unordered_map<TypeNode, TypeNode> cache;
763
  return substitute(typesBegin, typesEnd,
764
27936
                    replacementsBegin, replacementsEnd, cache);
765
}
766
767
template <class Iterator1, class Iterator2>
768
17368
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
17368
  std::unordered_map<TypeNode, TypeNode>::const_iterator i = cache.find(*this);
777
17368
  if(i != cache.end()) {
778
838
    return (*i).second;
779
  }
780
781
  // otherwise compute
782
16530
  Assert(typesEnd - typesBegin == replacementsEnd - replacementsBegin)
783
      << "Substitution iterator ranges must be equal size";
784
16530
  Iterator1 j = find(typesBegin, typesEnd, *this);
785
16530
  if(j != typesEnd) {
786
26120
    TypeNode tn = *(replacementsBegin + (j - typesBegin));
787
13060
    cache[*this] = tn;
788
13060
    return tn;
789
3470
  } else if(getNumChildren() == 0) {
790
1932
    cache[*this] = *this;
791
1932
    return *this;
792
  } else {
793
3076
    NodeBuilder nb(getKind());
794
1538
    if(getMetaKind() == kind::metakind::PARAMETERIZED) {
795
      // push the operator
796
      nb << TypeNode(d_nv->d_children[0]);
797
    }
798
4938
    for (const TypeNode& tn : *this)
799
    {
800
3400
      nb << tn.substitute(
801
          typesBegin, typesEnd, replacementsBegin, replacementsEnd, cache);
802
    }
803
3076
    TypeNode tn = nb.constructTypeNode();
804
1538
    cache[*this] = tn;
805
1538
    return tn;
806
  }
807
}
808
809
4501201
inline size_t TypeNode::getNumChildren() const {
810
4501201
  return d_nv->getNumChildren();
811
}
812
813
template <class T>
814
227888551
inline const T& TypeNode::getConst() const {
815
227888551
  return d_nv->getConst<T>();
816
}
817
818
27048707
inline TypeNode::TypeNode(const expr::NodeValue* ev) :
819
27048707
  d_nv(const_cast<expr::NodeValue*> (ev)) {
820
27048707
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
821
27048707
  d_nv->inc();
822
27048707
}
823
824
440168821
inline TypeNode::TypeNode(const TypeNode& typeNode) {
825
440168821
  Assert(typeNode.d_nv != NULL) << "Expecting a non-NULL expression value!";
826
440168821
  d_nv = typeNode.d_nv;
827
440168821
  d_nv->inc();
828
440168821
}
829
830
1819761802
inline TypeNode::~TypeNode() {
831
909880901
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
832
909880901
  d_nv->dec();
833
909880901
}
834
835
inline void TypeNode::assignNodeValue(expr::NodeValue* ev) {
836
  d_nv = ev;
837
  d_nv->inc();
838
}
839
840
416303579
inline TypeNode& TypeNode::operator=(const TypeNode& typeNode) {
841
416303579
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
842
416303579
  Assert(typeNode.d_nv != NULL)
843
      << "Expecting a non-NULL expression value on RHS!";
844
416303579
  if(__builtin_expect( ( d_nv != typeNode.d_nv ), true )) {
845
416078338
    d_nv->dec();
846
416078338
    d_nv = typeNode.d_nv;
847
416078338
    d_nv->inc();
848
  }
849
416303579
  return *this;
850
}
851
852
template <class AttrKind>
853
3988982
inline typename AttrKind::value_type TypeNode::
854
getAttribute(const AttrKind&) const {
855
3988982
  return NodeManager::currentNM()->getAttribute(d_nv, AttrKind());
856
}
857
858
template <class AttrKind>
859
4375119
inline bool TypeNode::
860
hasAttribute(const AttrKind&) const {
861
4375119
  return NodeManager::currentNM()->hasAttribute(d_nv, AttrKind());
862
}
863
864
template <class AttrKind>
865
inline bool TypeNode::getAttribute(const AttrKind&, typename AttrKind::value_type& ret) const {
866
  return NodeManager::currentNM()->getAttribute(d_nv, AttrKind(), ret);
867
}
868
869
template <class AttrKind>
870
16876
inline void TypeNode::
871
setAttribute(const AttrKind&, const typename AttrKind::value_type& value) {
872
16876
  NodeManager::currentNM()->setAttribute(d_nv, AttrKind(), value);
873
16876
}
874
875
inline void TypeNode::printAst(std::ostream& out, int indent) const {
876
  d_nv->printAst(out, indent);
877
}
878
879
55033667
inline bool TypeNode::isBoolean() const {
880
  return
881
55033667
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == BOOLEAN_TYPE );
882
}
883
884
132633220
inline bool TypeNode::isInteger() const {
885
  return
886
132633220
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == INTEGER_TYPE );
887
}
888
889
6844043
inline bool TypeNode::isReal() const {
890
  return
891
12994889
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == REAL_TYPE ) ||
892
12994889
    isInteger();
893
}
894
895
5433203
inline bool TypeNode::isString() const {
896
10837611
  return getKind() == kind::TYPE_CONSTANT &&
897
10837611
    getConst<TypeConstant>() == STRING_TYPE;
898
}
899
900
/** Is this a regexp type */
901
2055063
inline bool TypeNode::isRegExp() const {
902
4103141
  return getKind() == kind::TYPE_CONSTANT &&
903
4103141
    getConst<TypeConstant>() == REGEXP_TYPE;
904
 }
905
906
34493
inline bool TypeNode::isRoundingMode() const {
907
44842
  return getKind() == kind::TYPE_CONSTANT &&
908
44842
    getConst<TypeConstant>() == ROUNDINGMODE_TYPE;
909
}
910
911
1101920
inline bool TypeNode::isArray() const {
912
1101920
  return getKind() == kind::ARRAY_TYPE;
913
}
914
915
26671
inline TypeNode TypeNode::getArrayIndexType() const {
916
26671
  Assert(isArray());
917
26671
  return (*this)[0];
918
}
919
920
34180
inline TypeNode TypeNode::getArrayConstituentType() const {
921
34180
  Assert(isArray());
922
34180
  return (*this)[1];
923
}
924
925
184455
inline TypeNode TypeNode::getConstructorRangeType() const {
926
184455
  Assert(isConstructor());
927
184455
  return (*this)[getNumChildren()-1];
928
}
929
930
182883
inline TypeNode TypeNode::getSelectorDomainType() const
931
{
932
182883
  Assert(isSelector());
933
182883
  return (*this)[0];
934
}
935
936
594963
inline TypeNode TypeNode::getSelectorRangeType() const
937
{
938
594963
  Assert(isSelector());
939
594963
  return (*this)[1];
940
}
941
942
738940
inline bool TypeNode::isSet() const {
943
738940
  return getKind() == kind::SET_TYPE;
944
}
945
946
1135532
inline bool TypeNode::isSequence() const
947
{
948
1135532
  return getKind() == kind::SEQUENCE_TYPE;
949
}
950
951
324375
inline TypeNode TypeNode::getSetElementType() const {
952
324375
  Assert(isSet());
953
324375
  return (*this)[0];
954
}
955
956
6656266
inline bool TypeNode::isFunction() const {
957
6656266
  return getKind() == kind::FUNCTION_TYPE;
958
}
959
960
25990
inline bool TypeNode::isFunctionLike() const {
961
  return
962
51944
    getKind() == kind::FUNCTION_TYPE ||
963
51908
    getKind() == kind::CONSTRUCTOR_TYPE ||
964
77875
    getKind() == kind::SELECTOR_TYPE ||
965
51921
    getKind() == kind::TESTER_TYPE;
966
}
967
968
99495
inline bool TypeNode::isPredicate() const {
969
99495
  return isFunction() && getRangeType().isBoolean();
970
}
971
972
inline bool TypeNode::isPredicateLike() const {
973
  return isFunctionLike() && getRangeType().isBoolean();
974
}
975
976
348375
inline TypeNode TypeNode::getRangeType() const {
977
348375
  if(isTester()) {
978
    return NodeManager::currentNM()->booleanType();
979
  }
980
348375
  Assert(isFunction() || isConstructor() || isSelector())
981
      << "Cannot get range type of " << *this;
982
348375
  return (*this)[getNumChildren() - 1];
983
}
984
985
/** Is this a floating-point type of with <code>exp</code> exponent bits
986
    and <code>sig</code> significand bits */
987
inline bool TypeNode::isFloatingPoint(unsigned exp, unsigned sig) const {
988
  return (getKind() == kind::FLOATINGPOINT_TYPE
989
          && getConst<FloatingPointSize>().exponentWidth() == exp
990
          && getConst<FloatingPointSize>().significandWidth() == sig);
991
}
992
993
/** Get the exponent size of this floating-point type */
994
319
inline unsigned TypeNode::getFloatingPointExponentSize() const {
995
319
  Assert(isFloatingPoint());
996
319
  return getConst<FloatingPointSize>().exponentWidth();
997
}
998
999
/** Get the significand size of this floating-point type */
1000
319
inline unsigned TypeNode::getFloatingPointSignificandSize() const {
1001
319
  Assert(isFloatingPoint());
1002
319
  return getConst<FloatingPointSize>().significandWidth();
1003
}
1004
1005
#ifdef CVC5_DEBUG
1006
/**
1007
 * Pretty printer for use within gdb.  This is not intended to be used
1008
 * outside of gdb.  This writes to the Warning() stream and immediately
1009
 * flushes the stream.
1010
 *
1011
 * Note that this function cannot be a template, since the compiler
1012
 * won't instantiate it.  Even if we explicitly instantiate.  (Odd?)
1013
 * So we implement twice.  We mark as __attribute__((used)) so that
1014
 * GCC emits code for it even though static analysis indicates it's
1015
 * never called.
1016
 *
1017
 * Tim's Note: I moved this into the node.h file because this allows gdb
1018
 * to find the symbol, and use it, which is the first standard this code needs
1019
 * to meet. A cleaner solution is welcomed.
1020
 */
1021
static void __attribute__((used)) debugPrintTypeNode(const TypeNode& n) {
1022
  Warning() << Node::setdepth(-1) << Node::dag(true)
1023
            << Node::setlanguage(Language::LANG_AST) << n << std::endl;
1024
  Warning().flush();
1025
}
1026
static void __attribute__((used)) debugPrintTypeNodeNoDag(const TypeNode& n) {
1027
  Warning() << Node::setdepth(-1) << Node::dag(false)
1028
            << Node::setlanguage(Language::LANG_AST) << n << std::endl;
1029
  Warning().flush();
1030
}
1031
static void __attribute__((used)) debugPrintRawTypeNode(const TypeNode& n) {
1032
  n.printAst(Warning(), 0);
1033
  Warning().flush();
1034
}
1035
#endif /* CVC5_DEBUG */
1036
1037
}  // namespace cvc5
1038
1039
#endif /* CVC5__NODE_H */