GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/symbol_table.cpp Lines: 194 231 84.0 %
Date: 2021-08-16 Branches: 188 492 38.2 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Tim King, Morgan Deters
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
 * Convenience class for scoping variable and type declarations
14
 * (implementation).
15
 */
16
17
#include "expr/symbol_table.h"
18
19
#include <ostream>
20
#include <string>
21
#include <unordered_map>
22
#include <utility>
23
24
#include "api/cpp/cvc5.h"
25
#include "context/cdhashmap.h"
26
#include "context/cdhashset.h"
27
#include "context/context.h"
28
29
namespace cvc5 {
30
31
using ::cvc5::context::CDHashMap;
32
using ::cvc5::context::CDHashSet;
33
using ::cvc5::context::Context;
34
using ::std::copy;
35
using ::std::endl;
36
using ::std::ostream_iterator;
37
using ::std::pair;
38
using ::std::string;
39
using ::std::vector;
40
41
/** Overloaded type trie.
42
 *
43
 * This data structure stores a trie of expressions with
44
 * the same name, and must be distinguished by their argument types.
45
 * It is context-dependent.
46
 *
47
 * Using the argument allowFunVariants,
48
 * it may either be configured to allow function variants or not,
49
 * where a function variant is function that expects the same
50
 * argument types as another.
51
 *
52
 * For example, the following definitions introduce function
53
 * variants for the symbol f:
54
 *
55
 * 1. (declare-fun f (Int) Int) and
56
 *    (declare-fun f (Int) Bool)
57
 *
58
 * 2. (declare-fun f (Int) Int) and
59
 *    (declare-fun f (Int) Int)
60
 *
61
 * 3. (declare-datatypes ((Tup 0)) ((f (data Int)))) and
62
 *    (declare-fun f (Int) Tup)
63
 *
64
 * 4. (declare-datatypes ((Tup 0)) ((mkTup (f Int)))) and
65
 *    (declare-fun f (Tup) Bool)
66
 *
67
 * If function variants is set to true, we allow function variants
68
 * but not function redefinition. In examples 2 and 3, f is
69
 * declared twice as a symbol of identical argument and range
70
 * types. We never accept these definitions. However, we do
71
 * allow examples 1 and 4 above when allowFunVariants is true.
72
 *
73
 * For 0-argument functions (constants), we always allow
74
 * function variants.  That is, we always accept these examples:
75
 *
76
 * 5.  (declare-fun c () Int)
77
 *     (declare-fun c () Bool)
78
 *
79
 * 6.  (declare-datatypes ((Enum 0)) ((c)))
80
 *     (declare-fun c () Int)
81
 *
82
 * and always reject constant redefinition such as:
83
 *
84
 * 7. (declare-fun c () Int)
85
 *    (declare-fun c () Int)
86
 *
87
 * 8. (declare-datatypes ((Enum 0)) ((c))) and
88
 *    (declare-fun c () Enum)
89
 */
90
class OverloadedTypeTrie {
91
 public:
92
6463
  OverloadedTypeTrie(Context* c, bool allowFunVariants = false)
93
6463
      : d_overloaded_symbols(
94
6463
            new (true) CDHashSet<api::Term, std::hash<api::Term>>(c)),
95
12926
        d_allowFunctionVariants(allowFunVariants)
96
  {
97
6463
  }
98
6463
  ~OverloadedTypeTrie() { d_overloaded_symbols->deleteSelf(); }
99
100
  /** is this function overloaded? */
101
  bool isOverloadedFunction(api::Term fun) const;
102
103
  /** Get overloaded constant for type.
104
   * If possible, it returns a defined symbol with name
105
   * that has type t. Otherwise returns null expression.
106
   */
107
  api::Term getOverloadedConstantForType(const std::string& name,
108
                                         api::Sort t) const;
109
110
  /**
111
   * If possible, returns a defined function for a name
112
   * and a vector of expected argument types. Otherwise returns
113
   * null expression.
114
   */
115
  api::Term getOverloadedFunctionForTypes(
116
      const std::string& name, const std::vector<api::Sort>& argTypes) const;
117
  /** called when obj is bound to name, and prev_bound_obj was already bound to
118
   * name Returns false if the binding is invalid.
119
   */
120
  bool bind(const string& name, api::Term prev_bound_obj, api::Term obj);
121
122
 private:
123
  /** Marks expression obj with name as overloaded.
124
   * Adds relevant information to the type arg trie data structure.
125
   * It returns false if there is already an expression bound to that name
126
   * whose type expects the same arguments as the type of obj but is not
127
   * identical to the type of obj.  For example, if we declare :
128
   *
129
   * (declare-datatypes () ((List (cons (hd Int) (tl List)) (nil))))
130
   * (declare-fun cons (Int List) List)
131
   *
132
   * cons : constructor_type( Int, List, List )
133
   * cons : function_type( Int, List, List )
134
   *
135
   * These are put in the same place in the trie but do not have identical type,
136
   * hence we return false.
137
   */
138
  bool markOverloaded(const string& name, api::Term obj);
139
  /** the null expression */
140
  api::Term d_nullTerm;
141
  // The (context-independent) trie storing that maps expected argument
142
  // vectors to symbols. All expressions stored in d_symbols are only
143
  // interpreted as active if they also appear in the context-dependent
144
  // set d_overloaded_symbols.
145
368
  class TypeArgTrie {
146
   public:
147
    // children of this node
148
    std::map<api::Sort, TypeArgTrie> d_children;
149
    // symbols at this node
150
    std::map<api::Sort, api::Term> d_symbols;
151
  };
152
  /** for each string with operator overloading, this stores the data structure
153
   * above. */
154
  std::unordered_map<std::string, TypeArgTrie> d_overload_type_arg_trie;
155
  /** The set of overloaded symbols. */
156
  CDHashSet<api::Term, std::hash<api::Term>>* d_overloaded_symbols;
157
  /** allow function variants
158
   * This is true if we allow overloading (non-constant) functions that expect
159
   * the same argument types.
160
   */
161
  bool d_allowFunctionVariants;
162
  /** get unique overloaded function
163
  * If tat->d_symbols contains an active overloaded function, it
164
  * returns that function, where that function must be unique
165
  * if reqUnique=true.
166
  * Otherwise, it returns the null expression.
167
  */
168
  api::Term getOverloadedFunctionAt(const TypeArgTrie* tat,
169
                                    bool reqUnique = true) const;
170
};
171
172
3876610
bool OverloadedTypeTrie::isOverloadedFunction(api::Term fun) const
173
{
174
3876610
  return d_overloaded_symbols->find(fun) != d_overloaded_symbols->end();
175
}
176
177
6
api::Term OverloadedTypeTrie::getOverloadedConstantForType(
178
    const std::string& name, api::Sort t) const
179
{
180
  std::unordered_map<std::string, TypeArgTrie>::const_iterator it =
181
6
      d_overload_type_arg_trie.find(name);
182
6
  if (it != d_overload_type_arg_trie.end()) {
183
    std::map<api::Sort, api::Term>::const_iterator its =
184
6
        it->second.d_symbols.find(t);
185
6
    if (its != it->second.d_symbols.end()) {
186
6
      api::Term expr = its->second;
187
      // must be an active symbol
188
6
      if (isOverloadedFunction(expr)) {
189
6
        return expr;
190
      }
191
    }
192
  }
193
  return d_nullTerm;
194
}
195
196
74
api::Term OverloadedTypeTrie::getOverloadedFunctionForTypes(
197
    const std::string& name, const std::vector<api::Sort>& argTypes) const
198
{
199
  std::unordered_map<std::string, TypeArgTrie>::const_iterator it =
200
74
      d_overload_type_arg_trie.find(name);
201
74
  if (it != d_overload_type_arg_trie.end()) {
202
74
    const TypeArgTrie* tat = &it->second;
203
172
    for (unsigned i = 0; i < argTypes.size(); i++) {
204
      std::map<api::Sort, TypeArgTrie>::const_iterator itc =
205
98
          tat->d_children.find(argTypes[i]);
206
98
      if (itc != tat->d_children.end()) {
207
98
        tat = &itc->second;
208
      } else {
209
        Trace("parser-overloading")
210
            << "Could not find overloaded function " << name << std::endl;
211
212
          // no functions match
213
        return d_nullTerm;
214
      }
215
    }
216
    // we ensure that there is *only* one active symbol at this node
217
74
    return getOverloadedFunctionAt(tat);
218
  }
219
  return d_nullTerm;
220
}
221
222
66
bool OverloadedTypeTrie::bind(const string& name,
223
                              api::Term prev_bound_obj,
224
                              api::Term obj)
225
{
226
66
  bool retprev = true;
227
66
  if (!isOverloadedFunction(prev_bound_obj)) {
228
    // mark previous as overloaded
229
54
    retprev = markOverloaded(name, prev_bound_obj);
230
  }
231
  // mark this as overloaded
232
66
  bool retobj = markOverloaded(name, obj);
233
66
  return retprev && retobj;
234
}
235
236
120
bool OverloadedTypeTrie::markOverloaded(const string& name, api::Term obj)
237
{
238
120
  Trace("parser-overloading") << "Overloaded function : " << name;
239
120
  Trace("parser-overloading") << " with type " << obj.getSort() << std::endl;
240
  // get the argument types
241
240
  api::Sort t = obj.getSort();
242
240
  api::Sort rangeType = t;
243
240
  std::vector<api::Sort> argTypes;
244
120
  if (t.isFunction())
245
  {
246
10
    argTypes = t.getFunctionDomainSorts();
247
10
    rangeType = t.getFunctionCodomainSort();
248
  }
249
110
  else if (t.isConstructor())
250
  {
251
38
    argTypes = t.getConstructorDomainSorts();
252
38
    rangeType = t.getConstructorCodomainSort();
253
  }
254
72
  else if (t.isTester())
255
  {
256
32
    argTypes.push_back(t.getTesterDomainSort());
257
32
    rangeType = t.getTesterCodomainSort();
258
  }
259
40
  else if (t.isSelector())
260
  {
261
40
    argTypes.push_back(t.getSelectorDomainSort());
262
40
    rangeType = t.getSelectorCodomainSort();
263
  }
264
  // add to the trie
265
120
  TypeArgTrie* tat = &d_overload_type_arg_trie[name];
266
252
  for (unsigned i = 0; i < argTypes.size(); i++) {
267
132
    tat = &(tat->d_children[argTypes[i]]);
268
  }
269
270
  // check if function variants are allowed here
271
120
  if (d_allowFunctionVariants || argTypes.empty())
272
  {
273
    // they are allowed, check for redefinition
274
    std::map<api::Sort, api::Term>::iterator it =
275
12
        tat->d_symbols.find(rangeType);
276
12
    if (it != tat->d_symbols.end())
277
    {
278
      api::Term prev_obj = it->second;
279
      // if there is already an active function with the same name and expects
280
      // the same argument types and has the same return type, we reject the
281
      // re-declaration here.
282
      if (isOverloadedFunction(prev_obj))
283
      {
284
        return false;
285
      }
286
    }
287
  }
288
  else
289
  {
290
    // they are not allowed, we cannot have any function defined here.
291
216
    api::Term existingFun = getOverloadedFunctionAt(tat, false);
292
108
    if (!existingFun.isNull())
293
    {
294
      return false;
295
    }
296
  }
297
298
  // otherwise, update the symbols
299
120
  d_overloaded_symbols->insert(obj);
300
120
  tat->d_symbols[rangeType] = obj;
301
120
  return true;
302
}
303
304
182
api::Term OverloadedTypeTrie::getOverloadedFunctionAt(
305
    const OverloadedTypeTrie::TypeArgTrie* tat, bool reqUnique) const
306
{
307
364
  api::Term retExpr;
308
74
  for (std::map<api::Sort, api::Term>::const_iterator its =
309
182
           tat->d_symbols.begin();
310
256
       its != tat->d_symbols.end();
311
       ++its)
312
  {
313
148
    api::Term expr = its->second;
314
74
    if (isOverloadedFunction(expr))
315
    {
316
74
      if (retExpr.isNull())
317
      {
318
74
        if (!reqUnique)
319
        {
320
          return expr;
321
        }
322
        else
323
        {
324
74
          retExpr = expr;
325
        }
326
      }
327
      else
328
      {
329
        // multiple functions match
330
        return d_nullTerm;
331
      }
332
    }
333
  }
334
182
  return retExpr;
335
}
336
337
class SymbolTable::Implementation {
338
 public:
339
6463
  Implementation()
340
6463
      : d_context(),
341
        d_exprMap(&d_context),
342
        d_typeMap(&d_context),
343
6463
        d_overload_trie(&d_context)
344
  {
345
    // use an outermost push, to be able to clear definitions not at level zero
346
6463
    d_context.push();
347
6463
  }
348
349
6463
  ~Implementation() { d_context.pop(); }
350
351
  bool bind(const string& name, api::Term obj, bool levelZero, bool doOverload);
352
  void bindType(const string& name, api::Sort t, bool levelZero = false);
353
  void bindType(const string& name,
354
                const vector<api::Sort>& params,
355
                api::Sort t,
356
                bool levelZero = false);
357
  bool isBound(const string& name) const;
358
  bool isBoundType(const string& name) const;
359
  api::Term lookup(const string& name) const;
360
  api::Sort lookupType(const string& name) const;
361
  api::Sort lookupType(const string& name,
362
                       const vector<api::Sort>& params) const;
363
  size_t lookupArity(const string& name);
364
  void popScope();
365
  void pushScope();
366
  size_t getLevel() const;
367
  void reset();
368
  void resetAssertions();
369
  //------------------------ operator overloading
370
  /** implementation of function from header */
371
  bool isOverloadedFunction(api::Term fun) const;
372
373
  /** implementation of function from header */
374
  api::Term getOverloadedConstantForType(const std::string& name,
375
                                         api::Sort t) const;
376
377
  /** implementation of function from header */
378
  api::Term getOverloadedFunctionForTypes(
379
      const std::string& name, const std::vector<api::Sort>& argTypes) const;
380
  //------------------------ end operator overloading
381
 private:
382
  /** The context manager for the scope maps. */
383
  Context d_context;
384
385
  /** A map for expressions. */
386
  CDHashMap<string, api::Term> d_exprMap;
387
388
  /** A map for types. */
389
  using TypeMap = CDHashMap<string, std::pair<vector<api::Sort>, api::Sort>>;
390
  TypeMap d_typeMap;
391
392
  //------------------------ operator overloading
393
  // the null expression
394
  api::Term d_nullTerm;
395
  // overloaded type trie, stores all information regarding overloading
396
  OverloadedTypeTrie d_overload_trie;
397
  /** bind with overloading
398
   * This is called whenever obj is bound to name where overloading symbols is
399
   * allowed. If a symbol is previously bound to that name, it marks both as
400
   * overloaded. Returns false if the binding was invalid.
401
   */
402
  bool bindWithOverloading(const string& name, api::Term obj);
403
  //------------------------ end operator overloading
404
}; /* SymbolTable::Implementation */
405
406
375565
bool SymbolTable::Implementation::bind(const string& name,
407
                                       api::Term obj,
408
                                       bool levelZero,
409
                                       bool doOverload)
410
{
411
375565
  PrettyCheckArgument(!obj.isNull(), obj, "cannot bind to a null api::Term");
412
751130
  Trace("sym-table") << "SymbolTable: bind " << name
413
375565
                     << ", levelZero=" << levelZero
414
375565
                     << ", doOverload=" << doOverload << std::endl;
415
375565
  if (doOverload) {
416
184920
    if (!bindWithOverloading(name, obj)) {
417
      return false;
418
    }
419
  }
420
375565
  if (levelZero) {
421
11010
    d_exprMap.insertAtContextLevelZero(name, obj);
422
  } else {
423
364555
    d_exprMap.insert(name, obj);
424
  }
425
375565
  return true;
426
}
427
428
19384351
bool SymbolTable::Implementation::isBound(const string& name) const {
429
19384351
  return d_exprMap.find(name) != d_exprMap.end();
430
}
431
432
3876464
api::Term SymbolTable::Implementation::lookup(const string& name) const
433
{
434
3876464
  Assert(isBound(name));
435
7752928
  api::Term expr = (*d_exprMap.find(name)).second;
436
3876464
  if (isOverloadedFunction(expr)) {
437
80
    return d_nullTerm;
438
  } else {
439
3876384
    return expr;
440
  }
441
}
442
443
31702
void SymbolTable::Implementation::bindType(const string& name,
444
                                           api::Sort t,
445
                                           bool levelZero)
446
{
447
31702
  if (levelZero) {
448
24508
    d_typeMap.insertAtContextLevelZero(name, make_pair(vector<api::Sort>(), t));
449
  } else {
450
7194
    d_typeMap.insert(name, make_pair(vector<api::Sort>(), t));
451
  }
452
31702
}
453
454
329
void SymbolTable::Implementation::bindType(const string& name,
455
                                           const vector<api::Sort>& params,
456
                                           api::Sort t,
457
                                           bool levelZero)
458
{
459
329
  if (Debug.isOn("sort")) {
460
    Debug("sort") << "bindType(" << name << ", [";
461
    if (params.size() > 0) {
462
      copy(params.begin(),
463
           params.end() - 1,
464
           ostream_iterator<api::Sort>(Debug("sort"), ", "));
465
      Debug("sort") << params.back();
466
    }
467
    Debug("sort") << "], " << t << ")" << endl;
468
  }
469
329
  if (levelZero) {
470
4
    d_typeMap.insertAtContextLevelZero(name, make_pair(params, t));
471
  } else {
472
325
    d_typeMap.insert(name, make_pair(params, t));
473
  }
474
329
}
475
476
638805
bool SymbolTable::Implementation::isBoundType(const string& name) const {
477
638805
  return d_typeMap.find(name) != d_typeMap.end();
478
}
479
480
276480
api::Sort SymbolTable::Implementation::lookupType(const string& name) const
481
{
482
  std::pair<std::vector<api::Sort>, api::Sort> p =
483
552960
      (*d_typeMap.find(name)).second;
484
276480
  PrettyCheckArgument(p.first.size() == 0, name,
485
                      "type constructor arity is wrong: "
486
                      "`%s' requires %u parameters but was provided 0",
487
                      name.c_str(), p.first.size());
488
552960
  return p.second;
489
}
490
491
585
api::Sort SymbolTable::Implementation::lookupType(
492
    const string& name, const vector<api::Sort>& params) const
493
{
494
  std::pair<std::vector<api::Sort>, api::Sort> p =
495
1170
      (*d_typeMap.find(name)).second;
496
585
  PrettyCheckArgument(p.first.size() == params.size(), params,
497
                      "type constructor arity is wrong: "
498
                      "`%s' requires %u parameters but was provided %u",
499
                      name.c_str(), p.first.size(), params.size());
500
585
  if (p.first.size() == 0) {
501
    PrettyCheckArgument(p.second.isUninterpretedSort(), name.c_str());
502
    return p.second;
503
  }
504
585
  if (p.second.isDatatype())
505
  {
506
168
    PrettyCheckArgument(
507
        p.second.isParametricDatatype(), name, "expected parametric datatype");
508
168
    return p.second.instantiate(params);
509
  }
510
417
  bool isSortConstructor = p.second.isSortConstructor();
511
417
  if (Debug.isOn("sort"))
512
  {
513
    Debug("sort") << "instantiating using a sort "
514
                  << (isSortConstructor ? "constructor" : "substitution")
515
                  << std::endl;
516
    Debug("sort") << "have formals [";
517
    copy(p.first.begin(),
518
         p.first.end() - 1,
519
         ostream_iterator<api::Sort>(Debug("sort"), ", "));
520
    Debug("sort") << p.first.back() << "]" << std::endl << "parameters   [";
521
    copy(params.begin(),
522
         params.end() - 1,
523
         ostream_iterator<api::Sort>(Debug("sort"), ", "));
524
    Debug("sort") << params.back() << "]" << endl
525
                  << "type ctor    " << name << std::endl
526
                  << "type is      " << p.second << std::endl;
527
  }
528
  api::Sort instantiation = isSortConstructor
529
                                ? p.second.instantiate(params)
530
834
                                : p.second.substitute(p.first, params);
531
532
417
  Debug("sort") << "instance is  " << instantiation << std::endl;
533
534
417
  return instantiation;
535
}
536
537
6188
size_t SymbolTable::Implementation::lookupArity(const string& name) {
538
  std::pair<std::vector<api::Sort>, api::Sort> p =
539
12376
      (*d_typeMap.find(name)).second;
540
12376
  return p.first.size();
541
}
542
543
103049
void SymbolTable::Implementation::popScope() {
544
  // should not pop beyond level one
545
103049
  if (d_context.getLevel() == 1)
546
  {
547
2
    throw ScopeException();
548
  }
549
103047
  d_context.pop();
550
103047
}
551
552
103598
void SymbolTable::Implementation::pushScope() { d_context.push(); }
553
554
2738
size_t SymbolTable::Implementation::getLevel() const {
555
2738
  return d_context.getLevel();
556
}
557
558
49
void SymbolTable::Implementation::reset() {
559
49
  Trace("sym-table") << "SymbolTable: reset" << std::endl;
560
49
  this->SymbolTable::Implementation::~Implementation();
561
49
  new (this) SymbolTable::Implementation();
562
49
}
563
564
36
void SymbolTable::Implementation::resetAssertions()
565
{
566
36
  Trace("sym-table") << "SymbolTable: resetAssertions" << std::endl;
567
  // pop all contexts
568
120
  while (d_context.getLevel() > 0)
569
  {
570
42
    d_context.pop();
571
  }
572
36
  d_context.push();
573
36
}
574
575
3876464
bool SymbolTable::Implementation::isOverloadedFunction(api::Term fun) const
576
{
577
3876464
  return d_overload_trie.isOverloadedFunction(fun);
578
}
579
580
6
api::Term SymbolTable::Implementation::getOverloadedConstantForType(
581
    const std::string& name, api::Sort t) const
582
{
583
6
  return d_overload_trie.getOverloadedConstantForType(name, t);
584
}
585
586
74
api::Term SymbolTable::Implementation::getOverloadedFunctionForTypes(
587
    const std::string& name, const std::vector<api::Sort>& argTypes) const
588
{
589
74
  return d_overload_trie.getOverloadedFunctionForTypes(name, argTypes);
590
}
591
592
184920
bool SymbolTable::Implementation::bindWithOverloading(const string& name,
593
                                                      api::Term obj)
594
{
595
184920
  CDHashMap<string, api::Term>::const_iterator it = d_exprMap.find(name);
596
184920
  if (it != d_exprMap.end())
597
  {
598
66
    const api::Term& prev_bound_obj = (*it).second;
599
66
    if (prev_bound_obj != obj) {
600
66
      return d_overload_trie.bind(name, prev_bound_obj, obj);
601
    }
602
  }
603
184854
  return true;
604
}
605
606
bool SymbolTable::isOverloadedFunction(api::Term fun) const
607
{
608
  return d_implementation->isOverloadedFunction(fun);
609
}
610
611
6
api::Term SymbolTable::getOverloadedConstantForType(const std::string& name,
612
                                                    api::Sort t) const
613
{
614
6
  return d_implementation->getOverloadedConstantForType(name, t);
615
}
616
617
74
api::Term SymbolTable::getOverloadedFunctionForTypes(
618
    const std::string& name, const std::vector<api::Sort>& argTypes) const
619
{
620
74
  return d_implementation->getOverloadedFunctionForTypes(name, argTypes);
621
}
622
623
6414
SymbolTable::SymbolTable() : d_implementation(new SymbolTable::Implementation())
624
{
625
6414
}
626
627
6414
SymbolTable::~SymbolTable() {}
628
375565
bool SymbolTable::bind(const string& name,
629
                       api::Term obj,
630
                       bool levelZero,
631
                       bool doOverload)
632
{
633
375565
  return d_implementation->bind(name, obj, levelZero, doOverload);
634
}
635
636
31702
void SymbolTable::bindType(const string& name, api::Sort t, bool levelZero)
637
{
638
31702
  d_implementation->bindType(name, t, levelZero);
639
31702
}
640
641
329
void SymbolTable::bindType(const string& name,
642
                           const vector<api::Sort>& params,
643
                           api::Sort t,
644
                           bool levelZero)
645
{
646
329
  d_implementation->bindType(name, params, t, levelZero);
647
329
}
648
649
15507887
bool SymbolTable::isBound(const string& name) const
650
{
651
15507887
  return d_implementation->isBound(name);
652
}
653
638805
bool SymbolTable::isBoundType(const string& name) const
654
{
655
638805
  return d_implementation->isBoundType(name);
656
}
657
3876464
api::Term SymbolTable::lookup(const string& name) const
658
{
659
3876464
  return d_implementation->lookup(name);
660
}
661
276480
api::Sort SymbolTable::lookupType(const string& name) const
662
{
663
276480
  return d_implementation->lookupType(name);
664
}
665
666
585
api::Sort SymbolTable::lookupType(const string& name,
667
                                  const vector<api::Sort>& params) const
668
{
669
585
  return d_implementation->lookupType(name, params);
670
}
671
6188
size_t SymbolTable::lookupArity(const string& name) {
672
6188
  return d_implementation->lookupArity(name);
673
}
674
103049
void SymbolTable::popScope() { d_implementation->popScope(); }
675
103598
void SymbolTable::pushScope() { d_implementation->pushScope(); }
676
2738
size_t SymbolTable::getLevel() const { return d_implementation->getLevel(); }
677
49
void SymbolTable::reset() { d_implementation->reset(); }
678
36
void SymbolTable::resetAssertions() { d_implementation->resetAssertions(); }
679
680
29340
}  // namespace cvc5