GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/term_database.cpp Lines: 285 378 75.4 %
Date: 2021-11-07 Branches: 578 1556 37.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner, 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
 * Implementation of term database class.
14
 */
15
16
#include "theory/quantifiers/term_database.h"
17
18
#include "expr/skolem_manager.h"
19
#include "options/base_options.h"
20
#include "options/quantifiers_options.h"
21
#include "options/smt_options.h"
22
#include "options/theory_options.h"
23
#include "options/uf_options.h"
24
#include "theory/quantifiers/ematching/trigger_term_info.h"
25
#include "theory/quantifiers/quantifiers_attributes.h"
26
#include "theory/quantifiers/quantifiers_inference_manager.h"
27
#include "theory/quantifiers/quantifiers_registry.h"
28
#include "theory/quantifiers/quantifiers_state.h"
29
#include "theory/quantifiers/term_util.h"
30
#include "theory/rewriter.h"
31
#include "theory/uf/equality_engine.h"
32
33
using namespace cvc5::kind;
34
using namespace cvc5::context;
35
36
namespace cvc5 {
37
namespace theory {
38
namespace quantifiers {
39
40
15273
TermDb::TermDb(Env& env, QuantifiersState& qs, QuantifiersRegistry& qr)
41
    : QuantifiersUtil(env),
42
      d_qstate(qs),
43
      d_qim(nullptr),
44
      d_qreg(qr),
45
      d_termsContext(),
46
15273
      d_termsContextUse(options::termDbCd() ? context() : &d_termsContext),
47
      d_processed(d_termsContextUse),
48
      d_typeMap(d_termsContextUse),
49
      d_ops(d_termsContextUse),
50
      d_opMap(d_termsContextUse),
51
30546
      d_inactive_map(context())
52
{
53
15273
  d_consistent_ee = true;
54
15273
  d_true = NodeManager::currentNM()->mkConst(true);
55
15273
  d_false = NodeManager::currentNM()->mkConst(false);
56
15273
  if (!options::termDbCd())
57
  {
58
    // when not maintaining terms in a context-dependent manner, we clear during
59
    // each presolve, which requires maintaining a single outermost level
60
    d_termsContext.push();
61
  }
62
15273
}
63
64
30300
TermDb::~TermDb(){
65
66
30300
}
67
68
15273
void TermDb::finishInit(QuantifiersInferenceManager* qim) { d_qim = qim; }
69
70
26099
void TermDb::registerQuantifier( Node q ) {
71
26099
  Assert(q[0].getNumChildren() == d_qreg.getNumInstantiationConstants(q));
72
87502
  for (size_t i = 0, nvars = q[0].getNumChildren(); i < nvars; i++)
73
  {
74
122806
    Node ic = d_qreg.getInstantiationConstant(q, i);
75
61403
    setTermInactive( ic );
76
  }
77
26099
}
78
79
1022
size_t TermDb::getNumOperators() const { return d_ops.size(); }
80
81
2212
Node TermDb::getOperator(size_t i) const
82
{
83
2212
  Assert(i < d_ops.size());
84
2212
  return d_ops[i];
85
}
86
87
/** ground terms */
88
516093
size_t TermDb::getNumGroundTerms(Node f) const
89
{
90
516093
  NodeDbListMap::const_iterator it = d_opMap.find(f);
91
516093
  if (it != d_opMap.end())
92
  {
93
498544
    return it->second->d_list.size();
94
  }
95
17549
  return 0;
96
}
97
98
3036110
Node TermDb::getGroundTerm(Node f, size_t i) const
99
{
100
3036110
  NodeDbListMap::const_iterator it = d_opMap.find(f);
101
3036110
  if (it != d_opMap.end())
102
  {
103
3036110
    Assert(i < it->second->d_list.size());
104
3036110
    return it->second->d_list[i];
105
  }
106
  Assert(false);
107
  return Node::null();
108
}
109
110
426
size_t TermDb::getNumTypeGroundTerms(TypeNode tn) const
111
{
112
426
  TypeNodeDbListMap::const_iterator it = d_typeMap.find(tn);
113
426
  if (it != d_typeMap.end())
114
  {
115
416
    return it->second->d_list.size();
116
  }
117
10
  return 0;
118
}
119
120
21929
Node TermDb::getTypeGroundTerm(TypeNode tn, size_t i) const
121
{
122
21929
  TypeNodeDbListMap::const_iterator it = d_typeMap.find(tn);
123
21929
  if (it != d_typeMap.end())
124
  {
125
21929
    Assert(i < it->second->d_list.size());
126
21929
    return it->second->d_list[i];
127
  }
128
  Assert(false);
129
  return Node::null();
130
}
131
132
2637
Node TermDb::getOrMakeTypeGroundTerm(TypeNode tn, bool reqVar)
133
{
134
2637
  TypeNodeDbListMap::const_iterator it = d_typeMap.find(tn);
135
2637
  if (it != d_typeMap.end())
136
  {
137
651
    Assert(!it->second->d_list.empty());
138
651
    if (!reqVar)
139
    {
140
323
      return it->second->d_list[0];
141
    }
142
525
    for (const Node& v : it->second->d_list)
143
    {
144
468
      if (v.isVar())
145
      {
146
271
        return v;
147
      }
148
    }
149
  }
150
2043
  return getOrMakeTypeFreshVariable(tn);
151
}
152
153
2043
Node TermDb::getOrMakeTypeFreshVariable(TypeNode tn)
154
{
155
2043
  std::unordered_map<TypeNode, Node>::iterator it = d_type_fv.find(tn);
156
2043
  if (it == d_type_fv.end())
157
  {
158
255
    SkolemManager* sm = NodeManager::currentNM()->getSkolemManager();
159
510
    std::stringstream ss;
160
255
    ss << language::SetLanguage(options::outputLanguage());
161
255
    ss << "e_" << tn;
162
510
    Node k = sm->mkDummySkolem(ss.str(), tn, "is a termDb fresh variable");
163
510
    Trace("mkVar") << "TermDb:: Make variable " << k << " : " << tn
164
255
                   << std::endl;
165
255
    if (options::instMaxLevel() != -1)
166
    {
167
      QuantAttributes::setInstantiationLevelAttr(k, 0);
168
    }
169
255
    d_type_fv[tn] = k;
170
255
    return k;
171
  }
172
1788
  return it->second;
173
}
174
175
5378520
Node TermDb::getMatchOperator( Node n ) {
176
5378520
  Kind k = n.getKind();
177
  //datatype operators may be parametric, always assume they are
178
5378520
  if (k == SELECT || k == STORE || k == UNION || k == INTERSECTION
179
5279172
      || k == SUBSET || k == SETMINUS || k == MEMBER || k == SINGLETON
180
5245736
      || k == APPLY_SELECTOR_TOTAL || k == APPLY_SELECTOR || k == APPLY_TESTER
181
5093792
      || k == SEP_PTO || k == HO_APPLY || k == SEQ_NTH || k == STRING_LENGTH)
182
  {
183
    //since it is parametric, use a particular one as op
184
680310
    TypeNode tn = n[0].getType();
185
680310
    Node op = n.getOperator();
186
340155
    std::map< Node, std::map< TypeNode, Node > >::iterator ito = d_par_op_map.find( op );
187
340155
    if( ito!=d_par_op_map.end() ){
188
328045
      std::map< TypeNode, Node >::iterator it = ito->second.find( tn );
189
328045
      if( it!=ito->second.end() ){
190
327306
        return it->second;
191
      }
192
    }
193
12849
    Trace("par-op") << "Parametric operator : " << k << ", " << n.getOperator() << ", " << tn << " : " << n << std::endl;
194
12849
    d_par_op_map[op][tn] = n;
195
12849
    return n;
196
  }
197
5038365
  else if (inst::TriggerTermInfo::isAtomicTriggerKind(k))
198
  {
199
4730741
    return n.getOperator();
200
  }else{
201
307624
    return Node::null();
202
  }
203
}
204
205
3099227
void TermDb::addTerm(Node n)
206
{
207
3099227
  if (d_processed.find(n) != d_processed.end())
208
  {
209
1835147
    return;
210
  }
211
1264080
  d_processed.insert(n);
212
1264080
  if (!TermUtil::hasInstConstAttr(n))
213
  {
214
1224572
    Trace("term-db-debug") << "register term : " << n << std::endl;
215
1224572
    DbList* dlt = getOrMkDbListForType(n.getType());
216
1224572
    dlt->d_list.push_back(n);
217
    // if this is an atomic trigger, consider adding it
218
1224572
    if (inst::TriggerTermInfo::isAtomicTrigger(n))
219
    {
220
497916
      Trace("term-db") << "register term in db " << n << std::endl;
221
222
995832
      Node op = getMatchOperator(n);
223
497916
      Trace("term-db-debug") << "  match operator is : " << op << std::endl;
224
497916
      DbList* dlo = getOrMkDbListForOp(op);
225
497916
      dlo->d_list.push_back(n);
226
      // If we are higher-order, we may need to register more terms.
227
497916
      addTermInternal(n);
228
    }
229
  }
230
  else
231
  {
232
39508
    setTermInactive(n);
233
  }
234
1264080
  if (!n.isClosure())
235
  {
236
3274016
    for (const Node& nc : n)
237
    {
238
2009958
      addTerm(nc);
239
    }
240
  }
241
}
242
243
1224572
DbList* TermDb::getOrMkDbListForType(TypeNode tn)
244
{
245
1224572
  TypeNodeDbListMap::iterator it = d_typeMap.find(tn);
246
1224572
  if (it != d_typeMap.end())
247
  {
248
1196467
    return it->second.get();
249
  }
250
56210
  std::shared_ptr<DbList> dl = std::make_shared<DbList>(d_termsContextUse);
251
28105
  d_typeMap.insert(tn, dl);
252
28105
  return dl.get();
253
}
254
255
558277
DbList* TermDb::getOrMkDbListForOp(TNode op)
256
{
257
558277
  NodeDbListMap::iterator it = d_opMap.find(op);
258
558277
  if (it != d_opMap.end())
259
  {
260
404773
    return it->second.get();
261
  }
262
307008
  std::shared_ptr<DbList> dl = std::make_shared<DbList>(d_termsContextUse);
263
153504
  d_opMap.insert(op, dl);
264
153504
  Assert(op.getKind() != BOUND_VARIABLE);
265
153504
  d_ops.push_back(op);
266
153504
  return dl.get();
267
}
268
269
636905
void TermDb::computeArgReps( TNode n ) {
270
636905
  if (d_arg_reps.find(n) == d_arg_reps.end())
271
  {
272
377495
    eq::EqualityEngine* ee = d_qstate.getEqualityEngine();
273
1185135
    for (const TNode& nc : n)
274
    {
275
1615280
      TNode r = ee->hasTerm(nc) ? ee->getRepresentative(nc) : nc;
276
807640
      d_arg_reps[n].push_back( r );
277
    }
278
  }
279
636905
}
280
281
1895920
void TermDb::computeUfEqcTerms( TNode f ) {
282
1895920
  Assert(f == getOperatorRepresentative(f));
283
1895920
  if (d_func_map_eqc_trie.find(f) != d_func_map_eqc_trie.end())
284
  {
285
1848961
    return;
286
  }
287
46959
  d_func_map_eqc_trie[f].clear();
288
  // get the matchable operators in the equivalence class of f
289
93918
  std::vector<TNode> ops;
290
46959
  getOperatorsFor(f, ops);
291
46959
  eq::EqualityEngine* ee = d_qstate.getEqualityEngine();
292
94015
  for (TNode ff : ops)
293
  {
294
47056
    DbList* dbl = getOrMkDbListForOp(ff);
295
370187
    for (const Node& n : dbl->d_list)
296
    {
297
323131
      if (hasTermCurrent(n) && isTermActive(n))
298
      {
299
302637
        computeArgReps(n);
300
605274
        TNode r = ee->hasTerm(n) ? ee->getRepresentative(n) : TNode(n);
301
302637
        d_func_map_eqc_trie[f].d_data[r].addTerm(n, d_arg_reps[n]);
302
      }
303
    }
304
  }
305
}
306
307
3770341
void TermDb::computeUfTerms( TNode f ) {
308
3770341
  if (d_op_nonred_count.find(f) != d_op_nonred_count.end())
309
  {
310
    // already computed
311
7457267
    return;
312
  }
313
41713
  Assert(f == getOperatorRepresentative(f));
314
41713
  d_op_nonred_count[f] = 0;
315
  // get the matchable operators in the equivalence class of f
316
83415
  std::vector<TNode> ops;
317
41713
  getOperatorsFor(f, ops);
318
41713
  Trace("term-db-debug") << "computeUfTerms for " << f << std::endl;
319
41713
  unsigned congruentCount = 0;
320
41713
  unsigned nonCongruentCount = 0;
321
41713
  unsigned alreadyCongruentCount = 0;
322
41713
  unsigned relevantCount = 0;
323
41713
  NodeManager* nm = NodeManager::currentNM();
324
78382
  for (TNode ff : ops)
325
  {
326
41799
    NodeDbListMap::iterator it = d_opMap.find(ff);
327
41799
    if (it == d_opMap.end())
328
    {
329
      // no terms for this operator
330
5119
      continue;
331
    }
332
36680
    Trace("term-db-debug") << "Adding terms for operator " << ff << std::endl;
333
391095
    for (const Node& n : it->second->d_list)
334
    {
335
      // to be added to term index, term must be relevant, and exist in EE
336
354426
      if (!hasTermCurrent(n) || !d_qstate.hasTerm(n))
337
      {
338
        Trace("term-db-debug") << n << " is not relevant." << std::endl;
339
95867
        continue;
340
      }
341
342
354426
      relevantCount++;
343
374584
      if (!isTermActive(n))
344
      {
345
20158
        Trace("term-db-debug") << n << " is already redundant." << std::endl;
346
20158
        alreadyCongruentCount++;
347
20158
        continue;
348
      }
349
350
334268
      computeArgReps(n);
351
334268
      Trace("term-db-debug") << "Adding term " << n << " with arg reps : ";
352
1048731
      for (unsigned i = 0, size = d_arg_reps[n].size(); i < size; i++)
353
      {
354
714463
        Trace("term-db-debug") << d_arg_reps[n][i] << " ";
355
2857852
        if (std::find(d_func_map_rel_dom[f][i].begin(),
356
1428926
                      d_func_map_rel_dom[f][i].end(),
357
2857852
                      d_arg_reps[n][i])
358
2143389
            == d_func_map_rel_dom[f][i].end())
359
        {
360
248924
          d_func_map_rel_dom[f][i].push_back(d_arg_reps[n][i]);
361
        }
362
      }
363
334268
      Trace("term-db-debug") << std::endl;
364
334268
      Assert(d_qstate.hasTerm(n));
365
668536
      Trace("term-db-debug")
366
334268
          << "  and value : " << d_qstate.getRepresentative(n) << std::endl;
367
592816
      Node at = d_func_map_trie[f].addOrGetTerm(n, d_arg_reps[n]);
368
334268
      Assert(d_qstate.hasTerm(at));
369
334268
      Trace("term-db-debug2") << "...add term returned " << at << std::endl;
370
409977
      if (at != n && d_qstate.areEqual(at, n))
371
      {
372
75709
        setTermInactive(n);
373
75709
        Trace("term-db-debug") << n << " is redundant." << std::endl;
374
75709
        congruentCount++;
375
75709
        continue;
376
      }
377
517107
      std::vector<Node> lits;
378
258559
      if (checkCongruentDisequal(at, n, lits))
379
      {
380
11
        Assert(at.getNumChildren() == n.getNumChildren());
381
41
        for (size_t k = 0, size = at.getNumChildren(); k < size; k++)
382
        {
383
30
          if (at[k] != n[k])
384
          {
385
18
            lits.push_back(nm->mkNode(EQUAL, at[k], n[k]).negate());
386
          }
387
        }
388
22
        Node lem = nm->mkOr(lits);
389
11
        if (Trace.isOn("term-db-lemma"))
390
        {
391
          Trace("term-db-lemma") << "Disequal congruent terms : " << at << " "
392
                                 << n << "!!!!" << std::endl;
393
          if (!d_qstate.getValuation().needCheck())
394
          {
395
            Trace("term-db-lemma")
396
                << "  all theories passed with no lemmas." << std::endl;
397
            // we should be a full effort check, prior to theory combination
398
          }
399
          Trace("term-db-lemma") << "  add lemma : " << lem << std::endl;
400
        }
401
11
        d_qim->addPendingLemma(lem, InferenceId::QUANTIFIERS_TDB_DEQ_CONG);
402
11
        d_qstate.notifyInConflict();
403
11
        d_consistent_ee = false;
404
11
        return;
405
      }
406
258548
      nonCongruentCount++;
407
258548
      d_op_nonred_count[f]++;
408
    }
409
36669
    if (Trace.isOn("tdb"))
410
    {
411
      Trace("tdb") << "Term db size [" << f << "] : " << nonCongruentCount
412
                   << " / ";
413
      Trace("tdb") << (nonCongruentCount + congruentCount) << " / "
414
                   << (nonCongruentCount + congruentCount
415
                       + alreadyCongruentCount)
416
                   << " / ";
417
      Trace("tdb") << relevantCount << " / " << it->second->d_list.size()
418
                   << std::endl;
419
    }
420
  }
421
}
422
423
6676137
Node TermDb::getOperatorRepresentative(TNode op) const { return op; }
424
425
236985
bool TermDb::checkCongruentDisequal(TNode a, TNode b, std::vector<Node>& exp)
426
{
427
236985
  if (d_qstate.areDisequal(a, b))
428
  {
429
11
    exp.push_back(a.eqNode(b));
430
11
    return true;
431
  }
432
236974
  return false;
433
}
434
435
2221328
bool TermDb::inRelevantDomain( TNode f, unsigned i, TNode r ) {
436
  // notice if we are not higher-order, getOperatorRepresentative is a no-op
437
2221328
  f = getOperatorRepresentative(f);
438
2221328
  computeUfTerms( f );
439
2221328
  Assert(!d_qstate.getEqualityEngine()->hasTerm(r)
440
         || d_qstate.getEqualityEngine()->getRepresentative(r) == r);
441
2221328
  std::map< Node, std::map< unsigned, std::vector< Node > > >::iterator it = d_func_map_rel_dom.find( f );
442
2221328
  if( it != d_func_map_rel_dom.end() ){
443
2197271
    std::map< unsigned, std::vector< Node > >::iterator it2 = it->second.find( i );
444
2197271
    if( it2!=it->second.end() ){
445
2197271
      return std::find( it2->second.begin(), it2->second.end(), r )!=it2->second.end();
446
    }else{
447
      return false;
448
    }
449
  }else{
450
24057
    return false;
451
  }
452
}
453
454
4201600
bool TermDb::isTermActive( Node n ) {
455
4201600
  return d_inactive_map.find( n )==d_inactive_map.end();
456
  //return !n.getAttribute(NoMatchAttribute());
457
}
458
459
176620
void TermDb::setTermInactive( Node n ) {
460
176620
  d_inactive_map[n] = true;
461
  //Trace("term-db-debug2") << "set no match attribute" << std::endl;
462
  //NoMatchAttribute nma;
463
  //n.setAttribute(nma,true);
464
176620
}
465
466
4475010
bool TermDb::hasTermCurrent( Node n, bool useMode ) {
467
4475010
  if( !useMode ){
468
    return d_has_map.find( n )!=d_has_map.end();
469
  }
470
  //some assertions are not sent to EE
471
4475010
  if (options::termDbMode() == options::TermDbMode::ALL)
472
  {
473
4475010
    return true;
474
  }
475
  else if (options::termDbMode() == options::TermDbMode::RELEVANT)
476
  {
477
    return d_has_map.find( n )!=d_has_map.end();
478
  }
479
  Assert(false) << "TermDb::hasTermCurrent: Unknown termDbMode : " << options::termDbMode();
480
  return false;
481
}
482
483
1158
bool TermDb::isTermEligibleForInstantiation(TNode n, TNode f)
484
{
485
1158
  if( options::instMaxLevel()!=-1 ){
486
970
    if( n.hasAttribute(InstLevelAttribute()) ){
487
      int64_t fml =
488
970
          f.isNull() ? -1 : d_qreg.getQuantAttributes().getQuantInstLevel(f);
489
970
      unsigned ml = fml>=0 ? fml : options::instMaxLevel();
490
491
970
      if( n.getAttribute(InstLevelAttribute())>ml ){
492
        Trace("inst-add-debug") << "Term " << n << " has instantiation level " << n.getAttribute(InstLevelAttribute());
493
        Trace("inst-add-debug") << ", which is more than maximum allowed level " << ml << " for this quantified formula." << std::endl;
494
        return false;
495
      }
496
    }else{
497
      if( options::instLevelInputOnly() ){
498
        Trace("inst-add-debug") << "Term " << n << " does not have an instantiation level." << std::endl;
499
        return false;
500
      }
501
    }
502
  }
503
  // it cannot have instantiation constants, which originate from
504
  // counterexample-guided instantiation strategies.
505
1158
  return !TermUtil::hasInstConstAttr(n);
506
}
507
508
188
Node TermDb::getEligibleTermInEqc( TNode r ) {
509
188
  if( isTermEligibleForInstantiation( r, TNode::null() ) ){
510
188
    return r;
511
  }else{
512
    std::map< Node, Node >::iterator it = d_term_elig_eqc.find( r );
513
    if( it==d_term_elig_eqc.end() ){
514
      Node h;
515
      eq::EqualityEngine* ee = d_qstate.getEqualityEngine();
516
      eq::EqClassIterator eqc_i = eq::EqClassIterator(r, ee);
517
      while (!eqc_i.isFinished())
518
      {
519
        TNode n = (*eqc_i);
520
        ++eqc_i;
521
        if (isTermEligibleForInstantiation(n, TNode::null()))
522
        {
523
          h = n;
524
          break;
525
        }
526
      }
527
      d_term_elig_eqc[r] = h;
528
      return h;
529
    }else{
530
      return it->second;
531
    }
532
  }
533
}
534
535
34025
bool TermDb::resetInternal(Theory::Effort e)
536
{
537
  // do nothing
538
34025
  return true;
539
}
540
541
34025
bool TermDb::finishResetInternal(Theory::Effort e)
542
{
543
  // do nothing
544
34025
  return true;
545
}
546
547
467145
void TermDb::addTermInternal(Node n)
548
{
549
  // do nothing
550
467145
}
551
552
85946
void TermDb::getOperatorsFor(TNode f, std::vector<TNode>& ops)
553
{
554
85946
  ops.push_back(f);
555
85946
}
556
557
void TermDb::setHasTerm( Node n ) {
558
  Trace("term-db-debug2") << "hasTerm : " << n  << std::endl;
559
  if( d_has_map.find( n )==d_has_map.end() ){
560
    d_has_map[n] = true;
561
    for( unsigned i=0; i<n.getNumChildren(); i++ ){
562
      setHasTerm( n[i] );
563
    }
564
  }
565
}
566
567
13467
void TermDb::presolve() {
568
13467
  if (options::incrementalSolving() && !options::termDbCd())
569
  {
570
    d_termsContext.pop();
571
    d_termsContext.push();
572
  }
573
13467
}
574
575
34975
bool TermDb::reset( Theory::Effort effort ){
576
34975
  d_op_nonred_count.clear();
577
34975
  d_arg_reps.clear();
578
34975
  d_func_map_trie.clear();
579
34975
  d_func_map_eqc_trie.clear();
580
34975
  d_func_map_rel_dom.clear();
581
34975
  d_consistent_ee = true;
582
583
34975
  eq::EqualityEngine* ee = d_qstate.getEqualityEngine();
584
585
34975
  Assert(ee->consistent());
586
  // if higher-order, add equalities for the purification terms now
587
34975
  if (!resetInternal(effort))
588
  {
589
    return false;
590
  }
591
592
  //compute has map
593
34975
  if (options::termDbMode() == options::TermDbMode::RELEVANT)
594
  {
595
    d_has_map.clear();
596
    d_term_elig_eqc.clear();
597
    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
598
    while( !eqcs_i.isFinished() ){
599
      TNode r = (*eqcs_i);
600
      bool addedFirst = false;
601
      Node first;
602
      //TODO: ignoring singleton eqc isn't enough, need to ensure eqc are relevant
603
      eq::EqClassIterator eqc_i = eq::EqClassIterator(r, ee);
604
      while( !eqc_i.isFinished() ){
605
        TNode n = (*eqc_i);
606
        if( first.isNull() ){
607
          first = n;
608
        }else{
609
          if( !addedFirst ){
610
            addedFirst = true;
611
            setHasTerm( first );
612
          }
613
          setHasTerm( n );
614
        }
615
        ++eqc_i;
616
      }
617
      ++eqcs_i;
618
    }
619
    const LogicInfo& logicInfo = d_qstate.getLogicInfo();
620
    for (TheoryId theoryId = THEORY_FIRST; theoryId < THEORY_LAST; ++theoryId)
621
    {
622
      if (!logicInfo.isTheoryEnabled(theoryId))
623
      {
624
        continue;
625
      }
626
      for (context::CDList<Assertion>::const_iterator
627
               it = d_qstate.factsBegin(theoryId),
628
               it_end = d_qstate.factsEnd(theoryId);
629
           it != it_end;
630
           ++it)
631
      {
632
        setHasTerm((*it).d_assertion);
633
      }
634
    }
635
  }
636
  // finish reset
637
34975
  return finishResetInternal(effort);
638
}
639
640
22018
TNodeTrie* TermDb::getTermArgTrie(Node f)
641
{
642
22018
  f = getOperatorRepresentative(f);
643
22018
  computeUfTerms( f );
644
22018
  std::map<Node, TNodeTrie>::iterator itut = d_func_map_trie.find(f);
645
22018
  if( itut!=d_func_map_trie.end() ){
646
13963
    return &itut->second;
647
  }else{
648
8055
    return NULL;
649
  }
650
}
651
652
1895920
TNodeTrie* TermDb::getTermArgTrie(Node eqc, Node f)
653
{
654
1895920
  f = getOperatorRepresentative(f);
655
1895920
  computeUfEqcTerms( f );
656
1895920
  std::map<Node, TNodeTrie>::iterator itut = d_func_map_eqc_trie.find(f);
657
1895920
  if( itut==d_func_map_eqc_trie.end() ){
658
    return NULL;
659
  }else{
660
1895920
    if( eqc.isNull() ){
661
986298
      return &itut->second;
662
    }else{
663
      std::map<TNode, TNodeTrie>::iterator itute =
664
909622
          itut->second.d_data.find(eqc);
665
909622
      if( itute!=itut->second.d_data.end() ){
666
544691
        return &itute->second;
667
      }else{
668
364931
        return NULL;
669
      }
670
    }
671
  }
672
}
673
674
TNode TermDb::getCongruentTerm( Node f, Node n ) {
675
  f = getOperatorRepresentative(f);
676
  computeUfTerms( f );
677
  std::map<Node, TNodeTrie>::iterator itut = d_func_map_trie.find(f);
678
  if( itut!=d_func_map_trie.end() ){
679
    computeArgReps( n );
680
    return itut->second.existsTerm( d_arg_reps[n] );
681
  }else{
682
    return TNode::null();
683
  }
684
}
685
686
1526995
TNode TermDb::getCongruentTerm( Node f, std::vector< TNode >& args ) {
687
1526995
  f = getOperatorRepresentative(f);
688
1526995
  computeUfTerms( f );
689
1526995
  return d_func_map_trie[f].existsTerm( args );
690
}
691
692
}  // namespace quantifiers
693
}  // namespace theory
694
31137
}  // namespace cvc5