GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/type_enumerator.h Lines: 54 58 93.1 %
Date: 2021-11-07 Branches: 37 156 23.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Morgan Deters, Tim King, 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
 * Enumerators for types.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__TYPE_ENUMERATOR_H
19
#define CVC5__THEORY__TYPE_ENUMERATOR_H
20
21
#include "base/check.h"
22
#include "base/exception.h"
23
#include "expr/node.h"
24
#include "expr/type_node.h"
25
#include "util/integer.h"
26
27
namespace cvc5 {
28
namespace theory {
29
30
3183
class NoMoreValuesException : public Exception {
31
 public:
32
3183
  NoMoreValuesException(TypeNode n)
33
3183
      : Exception("No more values for type `" + n.toString() + "'")
34
  {
35
3183
  }
36
};/* class NoMoreValuesException */
37
38
5903
class TypeEnumeratorInterface {
39
 public:
40
224863
  TypeEnumeratorInterface(TypeNode type) : d_type(type) {}
41
42
230766
  virtual ~TypeEnumeratorInterface() {}
43
44
  /** Is this enumerator out of constants to enumerate? */
45
  virtual bool isFinished() = 0;
46
47
  /**
48
   * Get the current constant of this type.
49
   *
50
   * @throws NoMoreValuesException if no such constant exists.
51
   */
52
  virtual Node operator*() = 0;
53
54
  /** Increment the pointer to the next available constant. */
55
  virtual TypeEnumeratorInterface& operator++() = 0;
56
57
  /** Clone this enumerator. */
58
  virtual TypeEnumeratorInterface* clone() const = 0;
59
60
  /** Get the type from which we're enumerating constants. */
61
27658
  TypeNode getType() const { return d_type; }
62
63
 private:
64
  const TypeNode d_type;
65
}; /* class TypeEnumeratorInterface */
66
67
/**
68
 * This class stores particular information that is relevant to type
69
 * enumeration. For finite model finding, we set d_fixed_usort=true, and store
70
 * the finite cardinality bounds for each uninterpreted sort encountered in the
71
 * model. For strings, we store the cardinality for the alphabet that we are
72
 * assuming.
73
 */
74
24989
class TypeEnumeratorProperties
75
{
76
public:
77
24989
 TypeEnumeratorProperties(bool fixUSortCard, uint32_t strAlphaCard)
78
24989
     : d_fixed_usort_card(fixUSortCard), d_stringAlphaCard(strAlphaCard)
79
 {
80
24989
 }
81
 Integer getFixedCardinality(TypeNode tn) { return d_fixed_card[tn]; }
82
 bool d_fixed_usort_card;
83
 std::map<TypeNode, Integer> d_fixed_card;
84
 /** Get the alphabet for strings */
85
74
 uint32_t getStringsAlphabetCard() const { return d_stringAlphaCard; }
86
87
private:
88
 /** The cardinality of the alphabet */
89
 uint32_t d_stringAlphaCard;
90
};
91
92
template <class T>
93
236669
class TypeEnumeratorBase : public TypeEnumeratorInterface {
94
public:
95
96
224863
  TypeEnumeratorBase(TypeNode type) :
97
224863
    TypeEnumeratorInterface(type) {
98
224863
  }
99
100
13585
  TypeEnumeratorInterface* clone() const override
101
  {
102
13585
    return new T(static_cast<const T&>(*this));
103
  }
104
105
};/* class TypeEnumeratorBase */
106
107
/** Type enumerator class.
108
 * Enumerates values for a type.
109
 * Its constructor takes the type to enumerate and a pointer to a
110
 * TypeEnumeratorProperties class, which this type enumerator does not own.
111
 */
112
class TypeEnumerator {
113
  TypeEnumeratorInterface* d_te;
114
115
  static TypeEnumeratorInterface* mkTypeEnumerator(
116
      TypeNode type, TypeEnumeratorProperties* tep);
117
118
 public:
119
217079
  TypeEnumerator(TypeNode type, TypeEnumeratorProperties* tep = nullptr)
120
217079
      : d_te(mkTypeEnumerator(type, tep))
121
  {
122
217079
  }
123
124
13583
  TypeEnumerator(const TypeEnumerator& te) :
125
13583
    d_te(te.d_te->clone()) {
126
13583
  }
127
78
  TypeEnumerator(TypeEnumeratorInterface* te) : d_te(te){
128
78
  }
129
2
  TypeEnumerator& operator=(const TypeEnumerator& te) {
130
2
    delete d_te;
131
2
    d_te = te.d_te->clone();
132
2
    return *this;
133
  }
134
135
230740
  ~TypeEnumerator() { delete d_te; }
136
294323
  bool isFinished()
137
  {
138
// On Mac clang, there appears to be a code generation bug in an exception
139
// block here.  For now, there doesn't appear a good workaround; just disable
140
// assertions on that setup.
141
#if defined(CVC5_ASSERTIONS) && !(defined(__clang__))
142
294323
    if(d_te->isFinished()) {
143
      try {
144
3147
        **d_te;
145
        Assert(false) << "expected an NoMoreValuesException to be thrown";
146
3147
      } catch(NoMoreValuesException&) {
147
        // ignore the exception, we're just asserting that it would be thrown
148
        //
149
        // This block can crash on clang 3.0 on Mac OS, perhaps related to
150
        // bug:  http://llvm.org/bugs/show_bug.cgi?id=13359
151
        //
152
        // Hence the #if !(defined(__APPLE__) && defined(__clang__)) above
153
      }
154
    } else {
155
      try {
156
291176
        **d_te;
157
      } catch(NoMoreValuesException&) {
158
        Assert(false) << "didn't expect a NoMoreValuesException to be thrown";
159
      }
160
    }
161
#endif /* CVC5_ASSERTIONS && !(APPLE || clang) */
162
294323
    return d_te->isFinished();
163
  }
164
256522
  Node operator*()
165
  {
166
// On Mac clang, there appears to be a code generation bug in an exception
167
// block above (and perhaps here, too).  For now, there doesn't appear a
168
// good workaround; just disable assertions on that setup.
169
#if defined(CVC5_ASSERTIONS) && !(defined(__APPLE__) && defined(__clang__))
170
    try {
171
513026
      Node n = **d_te;
172
256504
      Assert(n.isConst()) << "Term " << n
173
                          << " from type enumerator is not constant";
174
256504
      Assert(!isFinished());
175
513008
      return n;
176
36
    } catch(NoMoreValuesException&) {
177
18
      Assert(isFinished());
178
18
      throw;
179
    }
180
#else  /* CVC5_ASSERTIONS && !(APPLE || clang) */
181
    return **d_te;
182
#endif /* CVC5_ASSERTIONS && !(APPLE || clang) */
183
  }
184
35668
  TypeEnumerator& operator++()
185
  {
186
35668
    ++*d_te;
187
35668
    return *this;
188
  }
189
2040
  TypeEnumerator operator++(int)
190
  {
191
2040
    TypeEnumerator te = *this;
192
2040
    ++*d_te;
193
2040
    return te;
194
  }
195
196
2082
  TypeNode getType() const { return d_te->getType(); }
197
};/* class TypeEnumerator */
198
199
}  // namespace theory
200
}  // namespace cvc5
201
202
#endif /* CVC5__THEORY__TYPE_ENUMERATOR_H */