GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/type_node.h Lines: 165 194 85.1 %
Date: 2021-05-22 Branches: 154 727 21.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.h"
33
#include "util/cardinality_class.h"
34
35
namespace cvc5 {
36
37
class NodeManager;
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
791417930
  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
4206
  static TypeNode null() {
129
4206
    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
36225814
  bool operator==(const TypeNode& typeNode) const {
153
36225814
    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
7881950
  bool operator!=(const TypeNode& typeNode) const {
163
7881950
    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
52867754
  inline bool operator<(const TypeNode& typeNode) const {
174
52867754
    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
4377865
  inline TypeNode operator[](int i) const {
217
4377865
    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
3039551
  inline unsigned long getId() const {
236
3039551
    return d_nv->getId();
237
  }
238
239
  /**
240
   * Returns the kind of this type node.
241
   *
242
   * @return the kind
243
   */
244
475406839
  inline Kind getKind() const {
245
475406839
    return Kind(d_nv->d_kind);
246
  }
247
248
  /**
249
   * Returns the metakind of this type node.
250
   *
251
   * @return the metakind
252
   */
253
1996
  inline kind::MetaKind getMetaKind() const {
254
1996
    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
605786
  inline iterator begin() {
331
605786
    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
11246
  inline iterator end() {
341
11246
    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
1996
  inline const_iterator begin() const {
350
1996
    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
1996
  inline const_iterator end() const {
360
1996
    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
19865
  inline void toStream(std::ostream& out, OutputLanguage language = language::output::LANG_AUTO) const {
378
19865
    d_nv->toStream(out, -1, 0, language);
379
19865
  }
380
381
  /**
382
   * Very basic pretty printer for Node.
383
   *
384
   * @param out output stream to print to.
385
   * @param indent number of spaces to indent the formula by.
386
   */
387
  void printAst(std::ostream& out, int indent = 0) const;
388
389
  /**
390
   * Returns true if this type is a null type.
391
   *
392
   * @return true if null
393
   */
394
26597285
  bool isNull() const {
395
26597285
    return d_nv == &expr::NodeValue::null();
396
  }
397
398
  /**
399
   * Returns the cardinality of this type.
400
   *
401
   * @return a finite or infinite cardinality
402
   */
403
  Cardinality getCardinality() const;
404
  /**
405
   * Get the cardinality class of this type node. The cardinality class
406
   * is static for each type node and does not depend on the state of the
407
   * solver. For details on cardinality classes, see util/cardinality_class.h
408
   *
409
   * @return the cardinality class
410
   */
411
  CardinalityClass getCardinalityClass();
412
413
  /** is closed enumerable type
414
   *
415
   * This returns true if this type has an enumerator that produces constants
416
   * that are fully handled by cvc5's quantifier-free theory solvers. Examples
417
   * of types that are not closed enumerable are:
418
   * (1) uninterpreted sorts,
419
   * (2) arrays,
420
   * (3) codatatypes,
421
   * (4) functions,
422
   * (5) parametric sorts involving any of the above.
423
   */
424
  bool isClosedEnumerable();
425
426
  /**
427
   * Is this a first-class type?
428
   * First-class types are types for which:
429
   * (1) we handle equalities between terms of that type, and
430
   * (2) they are allowed to be parameters of parametric types (e.g. index or element types of arrays).
431
   *
432
   * Examples of types that are not first-class include constructor types,
433
   * selector types, tester types, regular expressions and SExprs.
434
   */
435
  bool isFirstClass() const;
436
437
  /**
438
   * Returns whether this type is well-founded.
439
   *
440
   * @return true iff the type is well-founded
441
   */
442
  bool isWellFounded() const;
443
444
  /**
445
   * Construct and return a ground term of this type.  If the type is
446
   * not well founded, this function throws an exception.
447
   *
448
   * @return a ground term of the type
449
   */
450
  Node mkGroundTerm() const;
451
452
  /**
453
   * Construct and return a ground value of this type.  If the type is
454
   * not well founded, this function throws an exception.
455
   *
456
   * @return a ground value of the type
457
   */
458
  Node mkGroundValue() const;
459
460
  /**
461
   * Is this type a subtype of the given type?
462
   */
463
  bool isSubtypeOf(TypeNode t) const;
464
465
  /**
466
   * Is this type comparable to the given type (i.e., do they share
467
   * a common ancestor in the subtype tree)?
468
   */
469
  bool isComparableTo(TypeNode t) const;
470
471
  /** Is this the Boolean type? */
472
  bool isBoolean() const;
473
474
  /** Is this the Integer type? */
475
  bool isInteger() const;
476
477
  /** Is this the Real type? */
478
  bool isReal() const;
479
480
  /** Is this the String type? */
481
  bool isString() const;
482
483
  /** Is this a string-like type? (string or sequence) */
484
  bool isStringLike() const;
485
486
  /** Is this the Rounding Mode type? */
487
  bool isRoundingMode() const;
488
489
  /** Is this an array type? */
490
  bool isArray() const;
491
492
  /** Is this a Set type? */
493
  bool isSet() const;
494
495
  /** Is this a Bag type? */
496
  bool isBag() const;
497
498
  /** Is this a Sequence type? */
499
  bool isSequence() const;
500
501
  /** Get the index type (for array types) */
502
  TypeNode getArrayIndexType() const;
503
504
  /** Get the element type (for array types) */
505
  TypeNode getArrayConstituentType() const;
506
507
  /** Get the return type (for constructor types) */
508
  TypeNode getConstructorRangeType() const;
509
510
  /** Get the domain type (for selector types) */
511
  TypeNode getSelectorDomainType() const;
512
513
  /** Get the return type (for selector types) */
514
  TypeNode getSelectorRangeType() const;
515
516
  /** Get the domain type (for tester types) */
517
  TypeNode getTesterDomainType() const;
518
519
  /** Get the element type (for set types) */
520
  TypeNode getSetElementType() const;
521
522
  /** Get the element type (for bag types) */
523
  TypeNode getBagElementType() const;
524
525
  /** Get the element type (for sequence types) */
526
  TypeNode getSequenceElementType() const;
527
  /**
528
   * Is this a function type?  Function-like things (e.g. datatype
529
   * selectors) that aren't actually functions are NOT considered
530
   * functions, here.
531
   */
532
  bool isFunction() const;
533
534
  /**
535
   * Is this a function-LIKE type?  Function-like things
536
   * (e.g. datatype selectors) that aren't actually functions ARE
537
   * considered functions, here.  The main point is that this is used
538
   * to avoid anything higher-order: anything function-like cannot be
539
   * the argument or return value for anything else function-like.
540
   *
541
   * Arrays are explicitly *not* function-like for the purposes of
542
   * this test.  However, functions still cannot contain anything
543
   * function-like.
544
   */
545
  bool isFunctionLike() const;
546
547
  /**
548
   * Get the argument types of a function, datatype constructor,
549
   * datatype selector, or datatype tester.
550
   */
551
  std::vector<TypeNode> getArgTypes() const;
552
553
  /**
554
   * Get the paramater types of a parameterized datatype.  Fails an
555
   * assertion if this type is not a parametric datatype.
556
   */
557
  std::vector<TypeNode> getParamTypes() const;
558
559
  /**
560
   * Get the range type (i.e., the type of the result) of a function,
561
   * datatype constructor, datatype selector, or datatype tester.
562
   */
563
  TypeNode getRangeType() const;
564
565
  /**
566
   * Is this a predicate type?  NOTE: all predicate types are also
567
   * function types (so datatype testers are NOT considered
568
   * "predicates" for the purpose of this function).
569
   */
570
  bool isPredicate() const;
571
572
  /**
573
   * Is this a predicate-LIKE type?  Predicate-like things
574
   * (e.g. datatype testers) that aren't actually predicates ARE
575
   * considered predicates, here.
576
   *
577
   * Arrays are explicitly *not* predicate-like for the purposes of
578
   * this test.
579
   */
580
  bool isPredicateLike() const;
581
582
  /** Is this a tuple type? */
583
  bool isTuple() const;
584
585
  /** Is this a record type? */
586
  bool isRecord() const;
587
588
  /** Get the length of a tuple type */
589
  size_t getTupleLength() const;
590
591
  /** Get the constituent types of a tuple type */
592
  std::vector<TypeNode> getTupleTypes() const;
593
594
  /** Is this a regexp type */
595
  bool isRegExp() const;
596
597
  /** Is this a floating-point type */
598
  bool isFloatingPoint() const;
599
600
  /** Is this a floating-point type of with <code>exp</code> exponent bits
601
      and <code>sig</code> significand bits */
602
  bool isFloatingPoint(unsigned exp, unsigned sig) const;
603
604
  /** Is this a bit-vector type */
605
  bool isBitVector() const;
606
607
  /** Is this a bit-vector type of size <code>size</code> */
608
  bool isBitVector(unsigned size) const;
609
610
  /** Is this a datatype type */
611
  bool isDatatype() const;
612
613
  /** Is this a parameterized datatype type */
614
  bool isParametricDatatype() const;
615
616
  /** Is this a codatatype type */
617
  bool isCodatatype() const;
618
619
  /** Is this a fully instantiated datatype type */
620
  bool isInstantiatedDatatype() const;
621
622
  /** Is this a sygus datatype type */
623
  bool isSygusDatatype() const;
624
625
  /**
626
   * Get instantiated datatype type. The type on which this method is called
627
   * should be a parametric datatype whose parameter list is the same size as
628
   * argument params. This constructs the instantiated version of this
629
   * parametric datatype, e.g. passing (par (A) (List A)), { Int } ) to this
630
   * method returns (List Int).
631
   */
632
  TypeNode instantiateParametricDatatype(
633
      const std::vector<TypeNode>& params) const;
634
635
  /** Is this an instantiated datatype parameter */
636
  bool isParameterInstantiatedDatatype(unsigned n) const;
637
638
  /** Is this a constructor type */
639
  bool isConstructor() const;
640
641
  /** Is this a selector type */
642
  bool isSelector() const;
643
644
  /** Is this a tester type */
645
  bool isTester() const;
646
647
  /** Is this a datatype updater type */
648
  bool isUpdater() const;
649
650
  /** Get the internal Datatype specification from a datatype type */
651
  const DType& getDType() const;
652
653
  /** Get the exponent size of this floating-point type */
654
  unsigned getFloatingPointExponentSize() const;
655
656
  /** Get the significand size of this floating-point type */
657
  unsigned getFloatingPointSignificandSize() const;
658
659
  /** Get the size of this bit-vector type */
660
  unsigned getBitVectorSize() const;
661
662
  /** Is this a sort kind */
663
  bool isSort() const;
664
665
  /** Is this a sort constructor kind */
666
  bool isSortConstructor() const;
667
668
  /** Get sort constructor arity */
669
  uint64_t getSortConstructorArity() const;
670
671
  /**
672
   * Get name, for uninterpreted sorts and uninterpreted sort constructors.
673
   */
674
  std::string getName() const;
675
676
  /**
677
   * Instantiate a sort constructor type. The type on which this method is
678
   * called should be a sort constructor type whose parameter list is the
679
   * same size as argument params. This constructs the instantiated version of
680
   * this sort constructor. For example, this is a sort constructor, e.g.
681
   * declared via (declare-sort U 2), then calling this method with
682
   * { Int, Int } will generate the instantiated sort (U Int Int).
683
   */
684
  TypeNode instantiateSortConstructor(
685
      const std::vector<TypeNode>& params) const;
686
687
  /** Get the most general base type of the type */
688
  TypeNode getBaseType() const;
689
690
  /**
691
   * Returns the leastUpperBound in the extended type lattice of the two types.
692
   * If this is \top, i.e. there is no inhabited type that contains both,
693
   * a TypeNode such that isNull() is true is returned.
694
   */
695
  static TypeNode leastCommonTypeNode(TypeNode t0, TypeNode t1);
696
  static TypeNode mostCommonTypeNode(TypeNode t0, TypeNode t1);
697
698
  /** get ensure type condition
699
   *  Return value is a condition that implies that n has type tn.
700
  */
701
  static Node getEnsureTypeCondition( Node n, TypeNode tn );
702
private:
703
  static TypeNode commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast);
704
705
  /**
706
   * Indents the given stream a given amount of spaces.
707
   *
708
   * @param out the stream to indent
709
   * @param indent the number of spaces
710
   */
711
  static void indent(std::ostream& out, int indent) {
712
    for(int i = 0; i < indent; i++) {
713
      out << ' ';
714
    }
715
  }
716
717
};/* class TypeNode */
718
719
/**
720
 * Serializes a given node to the given stream.
721
 *
722
 * @param out the output stream to use
723
 * @param n the node to output to the stream
724
 * @return the stream
725
 */
726
19821
inline std::ostream& operator<<(std::ostream& out, const TypeNode& n) {
727
19821
  n.toStream(out, Node::setlanguage::getLanguage(out));
728
19821
  return out;
729
}
730
731
}  // namespace cvc5
732
733
namespace std {
734
735
template <>
736
struct hash<cvc5::TypeNode>
737
{
738
  size_t operator()(const cvc5::TypeNode& tn) const;
739
};
740
741
}  // namespace std
742
743
#include "expr/node_manager.h"
744
745
namespace cvc5 {
746
747
inline TypeNode
748
2
TypeNode::substitute(const TypeNode& type,
749
                     const TypeNode& replacement) const {
750
4
  std::unordered_map<TypeNode, TypeNode> cache;
751
4
  return substitute(type, replacement, cache);
752
}
753
754
template <class Iterator1, class Iterator2>
755
inline TypeNode
756
15078
TypeNode::substitute(Iterator1 typesBegin,
757
                     Iterator1 typesEnd,
758
                     Iterator2 replacementsBegin,
759
                     Iterator2 replacementsEnd) const {
760
30156
  std::unordered_map<TypeNode, TypeNode> cache;
761
  return substitute(typesBegin, typesEnd,
762
30156
                    replacementsBegin, replacementsEnd, cache);
763
}
764
765
template <class Iterator1, class Iterator2>
766
19530
TypeNode TypeNode::substitute(
767
    Iterator1 typesBegin,
768
    Iterator1 typesEnd,
769
    Iterator2 replacementsBegin,
770
    Iterator2 replacementsEnd,
771
    std::unordered_map<TypeNode, TypeNode>& cache) const
772
{
773
  // in cache?
774
19530
  std::unordered_map<TypeNode, TypeNode>::const_iterator i = cache.find(*this);
775
19530
  if(i != cache.end()) {
776
1124
    return (*i).second;
777
  }
778
779
  // otherwise compute
780
18406
  Assert(typesEnd - typesBegin == replacementsEnd - replacementsBegin)
781
      << "Substitution iterator ranges must be equal size";
782
18406
  Iterator1 j = find(typesBegin, typesEnd, *this);
783
18406
  if(j != typesEnd) {
784
27786
    TypeNode tn = *(replacementsBegin + (j - typesBegin));
785
13893
    cache[*this] = tn;
786
13893
    return tn;
787
4513
  } else if(getNumChildren() == 0) {
788
2519
    cache[*this] = *this;
789
2519
    return *this;
790
  } else {
791
3988
    NodeBuilder nb(getKind());
792
1994
    if(getMetaKind() == kind::metakind::PARAMETERIZED) {
793
      // push the operator
794
      nb << TypeNode(d_nv->d_children[0]);
795
    }
796
6446
    for (const TypeNode& tn : *this)
797
    {
798
4452
      nb << tn.substitute(
799
          typesBegin, typesEnd, replacementsBegin, replacementsEnd, cache);
800
    }
801
3988
    TypeNode tn = nb.constructTypeNode();
802
1994
    cache[*this] = tn;
803
1994
    return tn;
804
  }
805
}
806
807
5392360
inline size_t TypeNode::getNumChildren() const {
808
5392360
  return d_nv->getNumChildren();
809
}
810
811
template <class T>
812
392088550
inline const T& TypeNode::getConst() const {
813
392088550
  return d_nv->getConst<T>();
814
}
815
816
41740672
inline TypeNode::TypeNode(const expr::NodeValue* ev) :
817
41740672
  d_nv(const_cast<expr::NodeValue*> (ev)) {
818
41740672
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
819
41740672
  d_nv->inc();
820
41740672
}
821
822
785430252
inline TypeNode::TypeNode(const TypeNode& typeNode) {
823
785430252
  Assert(typeNode.d_nv != NULL) << "Expecting a non-NULL expression value!";
824
785430252
  d_nv = typeNode.d_nv;
825
785430252
  d_nv->inc();
826
785430252
}
827
828
3237176590
inline TypeNode::~TypeNode() {
829
1618588295
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
830
1618588295
  d_nv->dec();
831
1618588295
}
832
833
inline void TypeNode::assignNodeValue(expr::NodeValue* ev) {
834
  d_nv = ev;
835
  d_nv->inc();
836
}
837
838
750531816
inline TypeNode& TypeNode::operator=(const TypeNode& typeNode) {
839
750531816
  Assert(d_nv != NULL) << "Expecting a non-NULL expression value!";
840
750531816
  Assert(typeNode.d_nv != NULL)
841
      << "Expecting a non-NULL expression value on RHS!";
842
750531816
  if(__builtin_expect( ( d_nv != typeNode.d_nv ), true )) {
843
750197239
    d_nv->dec();
844
750197239
    d_nv = typeNode.d_nv;
845
750197239
    d_nv->inc();
846
  }
847
750531816
  return *this;
848
}
849
850
template <class AttrKind>
851
7184595
inline typename AttrKind::value_type TypeNode::
852
getAttribute(const AttrKind&) const {
853
7184595
  Assert(NodeManager::currentNM() != NULL)
854
      << "There is no current cvc5::NodeManager associated to this thread.\n"
855
         "Perhaps a public-facing function is missing a NodeManagerScope ?";
856
7184595
  return NodeManager::currentNM()->getAttribute(d_nv, AttrKind());
857
}
858
859
template <class AttrKind>
860
7813086
inline bool TypeNode::
861
hasAttribute(const AttrKind&) const {
862
7813086
  Assert(NodeManager::currentNM() != NULL)
863
      << "There is no current cvc5::NodeManager associated to this thread.\n"
864
         "Perhaps a public-facing function is missing a NodeManagerScope ?";
865
7813086
  return NodeManager::currentNM()->hasAttribute(d_nv, AttrKind());
866
}
867
868
template <class AttrKind>
869
inline bool TypeNode::getAttribute(const AttrKind&, typename AttrKind::value_type& ret) const {
870
  Assert(NodeManager::currentNM() != NULL)
871
      << "There is no current cvc5::NodeManager associated to this thread.\n"
872
         "Perhaps a public-facing function is missing a NodeManagerScope ?";
873
  return NodeManager::currentNM()->getAttribute(d_nv, AttrKind(), ret);
874
}
875
876
template <class AttrKind>
877
24775
inline void TypeNode::
878
setAttribute(const AttrKind&, const typename AttrKind::value_type& value) {
879
24775
  Assert(NodeManager::currentNM() != NULL)
880
      << "There is no current cvc5::NodeManager associated to this thread.\n"
881
         "Perhaps a public-facing function is missing a NodeManagerScope ?";
882
24775
  NodeManager::currentNM()->setAttribute(d_nv, AttrKind(), value);
883
24775
}
884
885
inline void TypeNode::printAst(std::ostream& out, int indent) const {
886
  d_nv->printAst(out, indent);
887
}
888
889
100894384
inline bool TypeNode::isBoolean() const {
890
  return
891
100894384
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == BOOLEAN_TYPE );
892
}
893
894
237346090
inline bool TypeNode::isInteger() const {
895
  return
896
237346090
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == INTEGER_TYPE );
897
}
898
899
11362676
inline bool TypeNode::isReal() const {
900
  return
901
20264157
    ( getKind() == kind::TYPE_CONSTANT && getConst<TypeConstant>() == REAL_TYPE ) ||
902
20264157
    isInteger();
903
}
904
905
4031590
inline bool TypeNode::isString() const {
906
8000546
  return getKind() == kind::TYPE_CONSTANT &&
907
8000546
    getConst<TypeConstant>() == STRING_TYPE;
908
}
909
910
/** Is this a regexp type */
911
1182773
inline bool TypeNode::isRegExp() const {
912
2356550
  return getKind() == kind::TYPE_CONSTANT &&
913
2356550
    getConst<TypeConstant>() == REGEXP_TYPE;
914
 }
915
916
32219
inline bool TypeNode::isRoundingMode() const {
917
40481
  return getKind() == kind::TYPE_CONSTANT &&
918
40481
    getConst<TypeConstant>() == ROUNDINGMODE_TYPE;
919
}
920
921
1434046
inline bool TypeNode::isArray() const {
922
1434046
  return getKind() == kind::ARRAY_TYPE;
923
}
924
925
34660
inline TypeNode TypeNode::getArrayIndexType() const {
926
34660
  Assert(isArray());
927
34660
  return (*this)[0];
928
}
929
930
42523
inline TypeNode TypeNode::getArrayConstituentType() const {
931
42523
  Assert(isArray());
932
42523
  return (*this)[1];
933
}
934
935
250620
inline TypeNode TypeNode::getConstructorRangeType() const {
936
250620
  Assert(isConstructor());
937
250620
  return (*this)[getNumChildren()-1];
938
}
939
940
284241
inline TypeNode TypeNode::getSelectorDomainType() const
941
{
942
284241
  Assert(isSelector());
943
284241
  return (*this)[0];
944
}
945
946
750361
inline TypeNode TypeNode::getSelectorRangeType() const
947
{
948
750361
  Assert(isSelector());
949
750361
  return (*this)[1];
950
}
951
952
1366257
inline bool TypeNode::isSet() const {
953
1366257
  return getKind() == kind::SET_TYPE;
954
}
955
956
755515
inline bool TypeNode::isSequence() const
957
{
958
755515
  return getKind() == kind::SEQUENCE_TYPE;
959
}
960
961
702858
inline TypeNode TypeNode::getSetElementType() const {
962
702858
  Assert(isSet());
963
702858
  return (*this)[0];
964
}
965
966
7829571
inline bool TypeNode::isFunction() const {
967
7829571
  return getKind() == kind::FUNCTION_TYPE;
968
}
969
970
39870
inline bool TypeNode::isFunctionLike() const {
971
  return
972
79664
    getKind() == kind::FUNCTION_TYPE ||
973
79588
    getKind() == kind::CONSTRUCTOR_TYPE ||
974
119424
    getKind() == kind::SELECTOR_TYPE ||
975
79630
    getKind() == kind::TESTER_TYPE;
976
}
977
978
92999
inline bool TypeNode::isPredicate() const {
979
92999
  return isFunction() && getRangeType().isBoolean();
980
}
981
982
inline bool TypeNode::isPredicateLike() const {
983
  return isFunctionLike() && getRangeType().isBoolean();
984
}
985
986
626780
inline TypeNode TypeNode::getRangeType() const {
987
626780
  if(isTester()) {
988
    return NodeManager::currentNM()->booleanType();
989
  }
990
626780
  Assert(isFunction() || isConstructor() || isSelector())
991
      << "Cannot get range type of " << *this;
992
626780
  return (*this)[getNumChildren() - 1];
993
}
994
995
/** Is this a floating-point type of with <code>exp</code> exponent bits
996
    and <code>sig</code> significand bits */
997
inline bool TypeNode::isFloatingPoint(unsigned exp, unsigned sig) const {
998
  return (getKind() == kind::FLOATINGPOINT_TYPE
999
          && getConst<FloatingPointSize>().exponentWidth() == exp
1000
          && getConst<FloatingPointSize>().significandWidth() == sig);
1001
}
1002
1003
/** Is this a bit-vector type of size <code>size</code> */
1004
1804
inline bool TypeNode::isBitVector(unsigned size) const {
1005
  return
1006
1804
    ( getKind() == kind::BITVECTOR_TYPE && getConst<BitVectorSize>() == size );
1007
}
1008
1009
/** Get the exponent size of this floating-point type */
1010
175
inline unsigned TypeNode::getFloatingPointExponentSize() const {
1011
175
  Assert(isFloatingPoint());
1012
175
  return getConst<FloatingPointSize>().exponentWidth();
1013
}
1014
1015
/** Get the significand size of this floating-point type */
1016
175
inline unsigned TypeNode::getFloatingPointSignificandSize() const {
1017
175
  Assert(isFloatingPoint());
1018
175
  return getConst<FloatingPointSize>().significandWidth();
1019
}
1020
1021
/** Get the size of this bit-vector type */
1022
5828399
inline unsigned TypeNode::getBitVectorSize() const {
1023
5828399
  Assert(isBitVector());
1024
5828399
  return getConst<BitVectorSize>();
1025
}
1026
1027
#ifdef CVC5_DEBUG
1028
/**
1029
 * Pretty printer for use within gdb.  This is not intended to be used
1030
 * outside of gdb.  This writes to the Warning() stream and immediately
1031
 * flushes the stream.
1032
 *
1033
 * Note that this function cannot be a template, since the compiler
1034
 * won't instantiate it.  Even if we explicitly instantiate.  (Odd?)
1035
 * So we implement twice.  We mark as __attribute__((used)) so that
1036
 * GCC emits code for it even though static analysis indicates it's
1037
 * never called.
1038
 *
1039
 * Tim's Note: I moved this into the node.h file because this allows gdb
1040
 * to find the symbol, and use it, which is the first standard this code needs
1041
 * to meet. A cleaner solution is welcomed.
1042
 */
1043
static void __attribute__((used)) debugPrintTypeNode(const TypeNode& n) {
1044
  Warning() << Node::setdepth(-1)
1045
            << Node::dag(true)
1046
            << Node::setlanguage(language::output::LANG_AST)
1047
            << n << std::endl;
1048
  Warning().flush();
1049
}
1050
static void __attribute__((used)) debugPrintTypeNodeNoDag(const TypeNode& n) {
1051
  Warning() << Node::setdepth(-1)
1052
            << Node::dag(false)
1053
            << Node::setlanguage(language::output::LANG_AST)
1054
            << n << std::endl;
1055
  Warning().flush();
1056
}
1057
static void __attribute__((used)) debugPrintRawTypeNode(const TypeNode& n) {
1058
  n.printAst(Warning(), 0);
1059
  Warning().flush();
1060
}
1061
#endif /* CVC5_DEBUG */
1062
1063
}  // namespace cvc5
1064
1065
#endif /* CVC5__NODE_H */