GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/type_enumerator.h Lines: 54 58 93.1 %
Date: 2021-11-05 Branches: 39 160 24.4 %

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
1875
class NoMoreValuesException : public Exception {
31
 public:
32
1875
  NoMoreValuesException(TypeNode n)
33
1875
      : Exception("No more values for type `" + n.toString() + "'")
34
  {
35
1875
  }
36
};/* class NoMoreValuesException */
37
38
5887
class TypeEnumeratorInterface {
39
 public:
40
225095
  TypeEnumeratorInterface(TypeNode type) : d_type(type) {}
41
42
230982
  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
26308
  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
24830
class TypeEnumeratorProperties
75
{
76
public:
77
24830
 TypeEnumeratorProperties(bool fixUSortCard, uint32_t strAlphaCard)
78
24830
     : d_fixed_usort_card(fixUSortCard), d_stringAlphaCard(strAlphaCard)
79
 {
80
24830
 }
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
236869
class TypeEnumeratorBase : public TypeEnumeratorInterface {
94
public:
95
96
225095
  TypeEnumeratorBase(TypeNode type) :
97
225095
    TypeEnumeratorInterface(type) {
98
225095
  }
99
100
13527
  TypeEnumeratorInterface* clone() const override
101
  {
102
13527
    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
217367
  TypeEnumerator(TypeNode type, TypeEnumeratorProperties* tep = nullptr)
120
217367
      : d_te(mkTypeEnumerator(type, tep))
121
  {
122
217367
  }
123
124
13525
  TypeEnumerator(const TypeEnumerator& te) :
125
13525
    d_te(te.d_te->clone()) {
126
13525
  }
127
64
  TypeEnumerator(TypeEnumeratorInterface* te) : d_te(te){
128
64
  }
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
230956
  ~TypeEnumerator() { delete d_te; }
136
290258
  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
290258
    if(d_te->isFinished()) {
143
      try {
144
1839
        **d_te;
145
        Assert(false) << "expected an NoMoreValuesException to be thrown";
146
1839
      } 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
288419
        **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
290258
    return d_te->isFinished();
163
  }
164
255297
  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
510576
      Node n = **d_te;
172
255279
      Assert(n.isConst()) << "Term " << n
173
                          << " from type enumerator is not constant";
174
255279
      Assert(!isFinished());
175
510558
      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
32828
  TypeEnumerator& operator++()
185
  {
186
32828
    ++*d_te;
187
32828
    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 */