GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/dtype_cons.h Lines: 2 2 100.0 %
Date: 2021-09-29 Branches: 8 16 50.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Tim King
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
 * A class representing a datatype definition.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__EXPR__DTYPE_CONS_H
19
#define CVC5__EXPR__DTYPE_CONS_H
20
21
#include <map>
22
#include <string>
23
#include <vector>
24
#include "expr/dtype_selector.h"
25
#include "expr/node.h"
26
#include "expr/type_node.h"
27
#include "util/cardinality_class.h"
28
29
namespace cvc5 {
30
31
/**
32
 * The Node-level representation of a constructor for a datatype, which
33
 * currently resides in the Expr-level DatatypeConstructor class
34
 * (expr/datatype.h).
35
 */
36
3676
class DTypeConstructor
37
{
38
  friend class DType;
39
40
 public:
41
  /**
42
   * Create a new datatype constructor with the given name for the
43
   * constructor and the same name (prefixed with "is_") for the
44
   * tester.  The actual constructor and tester (meaning, the Nodes
45
   * representing operators for these entities) aren't created until
46
   * resolution time.
47
   *
48
   * weight is the value that this constructor carries when computing size
49
   * for SyGuS. For example, if A, B, C have weights 0, 1, and 3 respectively,
50
   * then C( B( A() ), B( A() ) ) has size 5.
51
   */
52
  DTypeConstructor(std::string name, unsigned weight = 1);
53
54
17528
  ~DTypeConstructor() {}
55
  /**
56
   * Add an argument (i.e., a data field) of the given name and type
57
   * to this constructor.  Selector names need not be unique;
58
   * they are for convenience and pretty-printing only.
59
   */
60
  void addArg(std::string selectorName, TypeNode selectorType);
61
  /**
62
   * Add an argument, given a pointer to a selector object.
63
   */
64
  void addArg(std::shared_ptr<DTypeSelector> a);
65
  /**
66
   * Add a self-referential (i.e., a data field) of the given name
67
   * to this Datatype constructor that refers to the enclosing
68
   * Datatype.  For example, using the familiar "nat" Datatype, to
69
   * create the "pred" field for "succ" constructor, one uses
70
   * succ::addArgSelf("pred")---the actual Type
71
   * cannot be passed because the Datatype is still under
72
   * construction.  Selector names need not be unique; they are for
73
   * convenience and pretty-printing only.
74
   *
75
   * This is a special case of
76
   * DTypeConstructor::addArg(std::string).
77
   */
78
  void addArgSelf(std::string selectorName);
79
80
  /** Get the name of this constructor. */
81
  const std::string& getName() const;
82
83
  /**
84
   * Get the constructor operator of this constructor.  The
85
   * DType must be resolved.
86
   */
87
  Node getConstructor() const;
88
89
  /**
90
   * Get the tester operator of this constructor.  The
91
   * DType must be resolved.
92
   */
93
  Node getTester() const;
94
  //-------------------------------------- sygus
95
  /** set sygus
96
   *
97
   * Set that this constructor is a sygus datatype constructor that encodes
98
   * operator op.
99
   */
100
  void setSygus(Node op);
101
  /** get sygus op
102
   *
103
   * This method returns the operator or term that this constructor represents
104
   * in the sygus encoding. This may be a builtin operator, defined function,
105
   * variable, or constant that this constructor encodes in this deep embedding.
106
   */
107
  Node getSygusOp() const;
108
  /** is this a sygus identity function?
109
   *
110
   * This returns true if the sygus operator of this datatype constructor is
111
   * of the form (lambda (x) x).
112
   */
113
  bool isSygusIdFunc() const;
114
  /** get weight
115
   *
116
   * Get the weight of this constructor. This value is used when computing the
117
   * size of datatype terms that involve this constructor.
118
   */
119
  unsigned getWeight() const;
120
  //-------------------------------------- end sygus
121
122
  /**
123
   * Get the number of arguments (so far) of this DType constructor.
124
   */
125
  size_t getNumArgs() const;
126
  /**
127
   * Get the list of arguments to this constructor.
128
   */
129
  const std::vector<std::shared_ptr<DTypeSelector> >& getArgs() const;
130
  /**
131
   * Get the specialized constructor type for a parametric
132
   * constructor; this call is only permitted after resolution.
133
   * Given a (concrete) returnType, the constructor's concrete
134
   * type in this parametric datatype is returned.
135
   *
136
   * For instance, if the datatype is list[T], with constructor
137
   * "cons[T]" of type "T -> list[T] -> list[T]", then calling
138
   * this function with "list[int]" will return the concrete
139
   * "cons" constructor type for lists of int---namely,
140
   * "int -> list[int] -> list[int]".
141
   */
142
  TypeNode getSpecializedConstructorType(TypeNode returnType) const;
143
144
  /**
145
   * Return the cardinality of this constructor (the product of the
146
   * cardinalities of its arguments).
147
   */
148
  Cardinality getCardinality(TypeNode t) const;
149
150
  /**
151
   * Return the cardinality class, which indicates if the type has cardinality
152
   * one, is finite or infinite, possibly dependent on uninterpreted sorts being
153
   * finite.
154
   *
155
   * Note that the cardinality of a constructor is equivalent to asking how
156
   * many applications of this constructor exist.
157
   */
158
  CardinalityClass getCardinalityClass(TypeNode t) const;
159
160
  /**
161
   * Has finite external argument type. This returns true if this constructor
162
   * has an argument type that is not a datatype and is interpreted as a
163
   * finite type. This function can only be called for resolved constructors.
164
   *
165
   */
166
  bool hasFiniteExternalArgType(TypeNode t) const;
167
168
  /**
169
   * Returns true iff this constructor has already been
170
   * resolved.
171
   */
172
  bool isResolved() const;
173
174
  /** Get the ith DTypeConstructor arg. */
175
  const DTypeSelector& operator[](size_t index) const;
176
177
  /**
178
   * Get argument type. Returns the return type of the i^th selector of this
179
   * constructor.
180
   */
181
  TypeNode getArgType(size_t i) const;
182
183
  /** get selector internal
184
   *
185
   * This gets the selector for the index^th argument
186
   * of this constructor. The type dtt is the datatype
187
   * type whose datatype is the owner of this constructor,
188
   * where this type may be an instantiated parametric datatype.
189
   *
190
   * If shared selectors are enabled,
191
   * this returns a shared (constructor-agnotic) selector, which
192
   * in the terminology of "DTypes with Shared Selectors", is:
193
   *   sel_{dtt}^{T,atos(T,C,index)}
194
   * where C is this constructor, and T is the type
195
   * of the index^th field of this constructor.
196
   * The semantics of sel_{dtt}^{T,n}( t ) is the n^th field of
197
   * type T of constructor term t if one exists, or is
198
   * unconstrained otherwise.
199
   */
200
  Node getSelectorInternal(TypeNode dtt, size_t index) const;
201
202
  /** get selector index internal
203
   *
204
   * This gets the argument number of this constructor
205
   * that the selector sel accesses. It returns -1 if the
206
   * selector sel is not a selector for this constructor.
207
   *
208
   * In the terminology of "DTypes with Shared Selectors",
209
   * if sel is sel_{dtt}^{T,index} for some (T, index), where
210
   * dtt is the datatype type whose datatype is the owner
211
   * of this constructor, then this method returns
212
   *   stoa(T,C,index)
213
   */
214
  int getSelectorIndexInternal(Node sel) const;
215
  /** get selector index for name
216
   *
217
   * Returns the index of selector with the given name, or -1 if it
218
   * does not exist.
219
   */
220
  int getSelectorIndexForName(const std::string& name) const;
221
222
  /** involves external type
223
   *
224
   * Get whether this constructor has a subfield
225
   * in any constructor that is not a datatype type.
226
   */
227
  bool involvesExternalType() const;
228
  /** involves uninterpreted type
229
   *
230
   * Get whether this constructor has a subfield
231
   * in any constructor that is an uninterpreted type.
232
   */
233
  bool involvesUninterpretedType() const;
234
  /** prints this datatype constructor to stream */
235
  void toStream(std::ostream& out) const;
236
237
 private:
238
  /** resolve
239
   *
240
   * This resolves (initializes) the constructor. For details
241
   * on how datatypes and their constructors are resolved, see
242
   * documentation for DType::resolve.
243
   */
244
  bool resolve(TypeNode self,
245
               const std::map<std::string, TypeNode>& resolutions,
246
               const std::vector<TypeNode>& placeholders,
247
               const std::vector<TypeNode>& replacements,
248
               const std::vector<TypeNode>& paramTypes,
249
               const std::vector<TypeNode>& paramReplacements,
250
               size_t cindex);
251
252
  /** Helper function for resolving parametric datatypes.
253
   *
254
   * This replaces instances of the TypeNode produced for unresolved
255
   * parametric datatypes, with the corresponding resolved TypeNode.  For
256
   * example, take the parametric definition of a list,
257
   *    list[T] = cons(car : T, cdr : list[T]) | null.
258
   * If "range" is the unresolved parametric datatype:
259
   *   DATATYPE list =
260
   *    cons(car: SORT_TAG_1,
261
   *         cdr: SORT_TAG_2(SORT_TAG_1)) | null END;,
262
   * this function will return the resolved type:
263
   *   DATATYPE list =
264
   *    cons(car: SORT_TAG_1,
265
   *         cdr: (list PARAMETERIC_DATATYPE SORT_TAG_1)) | null END;
266
   */
267
  TypeNode doParametricSubstitution(
268
      TypeNode range,
269
      const std::vector<TypeNode>& paramTypes,
270
      const std::vector<TypeNode>& paramReplacements);
271
272
  /** compute the cardinality of this datatype */
273
  Cardinality computeCardinality(TypeNode t,
274
                                 std::vector<TypeNode>& processing) const;
275
  /** compute whether this datatype is well-founded */
276
  bool computeWellFounded(std::vector<TypeNode>& processing) const;
277
  /** compute ground term
278
   *
279
   * This method is used for constructing a term that is an application
280
   * of this constructor whose type is t.
281
   *
282
   * The argument processing is the set of datatype types we are currently
283
   * traversing. This is used to avoid infinite loops.
284
   *
285
   * The argument gt caches the ground terms we have computed so far.
286
   *
287
   * The argument isValue is whether we are constructing a constant value. If
288
   * this flag is false, we are constructing a canonical ground term that is
289
   * not necessarily constant.
290
   */
291
  Node computeGroundTerm(TypeNode t,
292
                         std::vector<TypeNode>& processing,
293
                         std::map<TypeNode, Node>& gt,
294
                         bool isValue) const;
295
  /**
296
   * Compute cardinality info, returns a pair where its first component is
297
   * an identifier indicating the cardinality type of this constructor for
298
   * type t, and a Boolean indicating whether the constructor has any arguments
299
   * that have finite external type.
300
   */
301
  std::pair<CardinalityClass, bool> computeCardinalityInfo(TypeNode t) const;
302
  /** compute shared selectors
303
   * This computes the maps d_sharedSelectors and d_sharedSelectorIndex.
304
   */
305
  void computeSharedSelectors(TypeNode domainType) const;
306
  /** the name of the constructor */
307
  std::string d_name;
308
  /** the name of the tester */
309
  std::string d_testerName;
310
  /** the constructor expression */
311
  Node d_constructor;
312
  /** the tester for this constructor */
313
  Node d_tester;
314
  /** the arguments of this constructor */
315
  std::vector<std::shared_ptr<DTypeSelector> > d_args;
316
  /** sygus operator */
317
  Node d_sygusOp;
318
  /** weight */
319
  unsigned d_weight;
320
  /** shared selectors for each type
321
   *
322
   * This stores the shared (constructor-agnotic)
323
   * selectors that access the fields of this datatype.
324
   * In the terminology of "DTypes with Shared Selectors",
325
   * this stores:
326
   *   sel_{dtt}^{T1,atos(T1,C,1)}, ...,
327
   *   sel_{dtt}^{Tn,atos(Tn,C,n)}
328
   * where C is this constructor, which has type
329
   * T1 x ... x Tn -> dtt above.
330
   * We store this information for (possibly multiple)
331
   * datatype types dtt, since this constructor may be
332
   * for a parametric datatype, where dtt is an instantiated
333
   * parametric datatype.
334
   */
335
  mutable std::map<TypeNode, std::vector<Node> > d_sharedSelectors;
336
  /** for each type, a cache mapping from shared selectors to
337
   * its argument index for this constructor.
338
   */
339
  mutable std::map<TypeNode, std::map<Node, unsigned> > d_sharedSelectorIndex;
340
  /**  A cache for computeCardinalityInfo. */
341
  mutable std::map<TypeNode, std::pair<CardinalityClass, bool> > d_cardInfo;
342
}; /* class DTypeConstructor */
343
344
/**
345
 * A hash function for DTypeConstructors.  Needed to store them in hash sets
346
 * and hash maps.
347
 */
348
struct DTypeConstructorHashFunction
349
{
350
  size_t operator()(const DTypeConstructor& dtc) const
351
  {
352
    return std::hash<std::string>()(dtc.getName());
353
  }
354
  size_t operator()(const DTypeConstructor* dtc) const
355
  {
356
    return std::hash<std::string>()(dtc->getName());
357
  }
358
}; /* struct DTypeConstructorHashFunction */
359
360
std::ostream& operator<<(std::ostream& os, const DTypeConstructor& ctor);
361
362
}  // namespace cvc5
363
364
#endif