GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/theory.cpp Lines: 265 312 84.9 %
Date: 2021-09-07 Branches: 537 1083 49.6 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Tim King, Dejan Jovanovic
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
 * Base for theory interface.
14
 */
15
16
#include "theory/theory.h"
17
18
#include <iostream>
19
#include <sstream>
20
#include <string>
21
#include <vector>
22
23
#include "base/check.h"
24
#include "expr/node_algorithm.h"
25
#include "options/arith_options.h"
26
#include "options/smt_options.h"
27
#include "options/theory_options.h"
28
#include "smt/smt_statistics_registry.h"
29
#include "theory/ee_setup_info.h"
30
#include "theory/ext_theory.h"
31
#include "theory/output_channel.h"
32
#include "theory/quantifiers_engine.h"
33
#include "theory/substitutions.h"
34
#include "theory/theory_inference_manager.h"
35
#include "theory/theory_model.h"
36
#include "theory/theory_rewriter.h"
37
#include "theory/theory_state.h"
38
#include "theory/trust_substitutions.h"
39
40
using namespace std;
41
42
namespace cvc5 {
43
namespace theory {
44
45
/** Default value for the uninterpreted sorts is the UF theory */
46
TheoryId Theory::s_uninterpretedSortOwner = THEORY_UF;
47
48
std::ostream& operator<<(std::ostream& os, Theory::Effort level){
49
  switch(level){
50
  case Theory::EFFORT_STANDARD:
51
    os << "EFFORT_STANDARD"; break;
52
  case Theory::EFFORT_FULL:
53
    os << "EFFORT_FULL"; break;
54
  case Theory::EFFORT_LAST_CALL:
55
    os << "EFFORT_LAST_CALL"; break;
56
  default:
57
      Unreachable();
58
  }
59
  return os;
60
}/* ostream& operator<<(ostream&, Theory::Effort) */
61
62
129080
Theory::Theory(TheoryId id,
63
               Env& env,
64
               OutputChannel& out,
65
               Valuation valuation,
66
129080
               std::string name)
67
    : EnvObj(env),
68
      d_id(id),
69
129080
      d_facts(d_env.getContext()),
70
129080
      d_factsHead(d_env.getContext(), 0),
71
129080
      d_sharedTermsIndex(d_env.getContext(), 0),
72
      d_careGraph(nullptr),
73
      d_instanceName(name),
74
258160
      d_checkTime(smtStatisticsRegistry().registerTimer(getStatsPrefix(id)
75
258160
                                                        + name + "checkTime")),
76
129080
      d_computeCareGraphTime(smtStatisticsRegistry().registerTimer(
77
258160
          getStatsPrefix(id) + name + "computeCareGraphTime")),
78
129080
      d_sharedTerms(d_env.getContext()),
79
      d_out(&out),
80
      d_valuation(valuation),
81
      d_equalityEngine(nullptr),
82
      d_allocEqualityEngine(nullptr),
83
      d_theoryState(nullptr),
84
      d_inferManager(nullptr),
85
      d_quantEngine(nullptr),
86
129080
      d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager()
87
1161720
                                           : nullptr)
88
{
89
129080
}
90
91
129041
Theory::~Theory() {
92
129041
}
93
94
19852
bool Theory::needsEqualityEngine(EeSetupInfo& esi)
95
{
96
  // by default, this theory does not use an (official) equality engine
97
19852
  return false;
98
}
99
100
129038
void Theory::setEqualityEngine(eq::EqualityEngine* ee)
101
{
102
  // set the equality engine pointer
103
129038
  d_equalityEngine = ee;
104
129038
  if (d_theoryState != nullptr)
105
  {
106
119112
    d_theoryState->setEqualityEngine(ee);
107
  }
108
129038
  if (d_inferManager != nullptr)
109
  {
110
119112
    d_inferManager->setEqualityEngine(ee);
111
  }
112
129038
}
113
114
129038
void Theory::setQuantifiersEngine(QuantifiersEngine* qe)
115
{
116
  // quantifiers engine may be null if not in quantified logic
117
129038
  d_quantEngine = qe;
118
129038
}
119
120
129038
void Theory::setDecisionManager(DecisionManager* dm)
121
{
122
129038
  Assert(dm != nullptr);
123
129038
  if (d_inferManager != nullptr)
124
  {
125
119112
    d_inferManager->setDecisionManager(dm);
126
  }
127
129038
}
128
129
void Theory::finishInitStandalone()
130
{
131
  EeSetupInfo esi;
132
  if (needsEqualityEngine(esi))
133
  {
134
    // always associated with the same SAT context as the theory
135
    d_allocEqualityEngine.reset(
136
        new eq::EqualityEngine(*esi.d_notify,
137
                               getSatContext(),
138
                               esi.d_name,
139
                               esi.d_constantsAreTriggers));
140
    // use it as the official equality engine
141
    setEqualityEngine(d_allocEqualityEngine.get());
142
  }
143
  finishInit();
144
}
145
146
191549411
TheoryId Theory::theoryOf(options::TheoryOfMode mode, TNode node)
147
{
148
191549411
  TheoryId tid = THEORY_BUILTIN;
149
191549411
  switch(mode) {
150
128057073
    case options::TheoryOfMode::THEORY_OF_TYPE_BASED:
151
      // Constants, variables, 0-ary constructors
152
128057073
      if (node.isVar())
153
      {
154
4918203
        if (node.getKind() == kind::BOOLEAN_TERM_VARIABLE)
155
        {
156
228182
          tid = THEORY_UF;
157
        }
158
        else
159
        {
160
4690021
          tid = Theory::theoryOf(node.getType());
161
        }
162
      }
163
123138870
      else if (node.getKind() == kind::EQUAL)
164
      {
165
        // Equality is owned by the theory that owns the domain
166
7598267
        tid = Theory::theoryOf(node[0].getType());
167
      }
168
      else
169
      {
170
        // Regular nodes are owned by the kind. Notice that constants are a
171
        // special case here, where the theory of the kind of a constant
172
        // always coincides with the type of that constant.
173
115540603
        tid = kindToTheoryId(node.getKind());
174
      }
175
128057073
      break;
176
63492338
    case options::TheoryOfMode::THEORY_OF_TERM_BASED:
177
      // Variables
178
63492338
      if (node.isVar())
179
      {
180
5415674
        if (Theory::theoryOf(node.getType()) != theory::THEORY_BOOL)
181
        {
182
          // We treat the variables as uninterpreted
183
5404477
          tid = s_uninterpretedSortOwner;
184
        }
185
        else
186
        {
187
11197
          if (node.getKind() == kind::BOOLEAN_TERM_VARIABLE)
188
          {
189
            // Boolean vars go to UF
190
6724
            tid = THEORY_UF;
191
          }
192
          else
193
          {
194
            // Except for the Boolean ones
195
4473
            tid = THEORY_BOOL;
196
          }
197
        }
198
      }
199
58076664
      else if (node.getKind() == kind::EQUAL)
200
      {  // Equality
201
        // If one of them is an ITE, it's irelevant, since they will get
202
        // replaced out anyhow
203
5031885
        if (node[0].getKind() == kind::ITE)
204
        {
205
5135
          tid = Theory::theoryOf(node[0].getType());
206
        }
207
5026750
        else if (node[1].getKind() == kind::ITE)
208
        {
209
10674
          tid = Theory::theoryOf(node[1].getType());
210
        }
211
        else
212
        {
213
10032152
          TNode l = node[0];
214
10032152
          TNode r = node[1];
215
10032152
          TypeNode ltype = l.getType();
216
10032152
          TypeNode rtype = r.getType();
217
          // If the types are different, we must assign based on type due
218
          // to handling subtypes (limited to arithmetic). Also, if we are
219
          // a Boolean equality, we must assign THEORY_BOOL.
220
5016076
          if (ltype != rtype || ltype.isBoolean())
221
          {
222
65195
            tid = Theory::theoryOf(ltype);
223
          }
224
          else
225
          {
226
            // If both sides belong to the same theory the choice is easy
227
4950881
            TheoryId T1 = Theory::theoryOf(l);
228
4950881
            TheoryId T2 = Theory::theoryOf(r);
229
4950881
            if (T1 == T2)
230
            {
231
2827172
              tid = T1;
232
            }
233
            else
234
            {
235
2123709
              TheoryId T3 = Theory::theoryOf(ltype);
236
              // This is a case of
237
              // * x*y = f(z) -> UF
238
              // * x = c      -> UF
239
              // * f(x) = read(a, y) -> either UF or ARRAY
240
              // at least one of the theories has to be parametric, i.e. theory
241
              // of the type is different from the theory of the term
242
2123709
              if (T1 == T3)
243
              {
244
47808
                tid = T2;
245
              }
246
2075901
              else if (T2 == T3)
247
              {
248
2027241
                tid = T1;
249
              }
250
              else
251
              {
252
                // If both are parametric, we take the smaller one (arbitrary)
253
48660
                tid = T1 < T2 ? T1 : T2;
254
              }
255
            }
256
          }
257
        }
258
      }
259
      else
260
      {
261
        // Regular nodes are owned by the kind, which includes constants as a
262
        // special case.
263
53044779
        tid = kindToTheoryId(node.getKind());
264
      }
265
63492338
    break;
266
  default:
267
    Unreachable();
268
  }
269
191549411
  Trace("theory::internal") << "theoryOf(" << mode << ", " << node << ") -> " << tid << std::endl;
270
191549411
  return tid;
271
}
272
273
1018671
void Theory::notifySharedTerm(TNode n)
274
{
275
  // do nothing
276
1018671
}
277
278
2605655
void Theory::notifyInConflict()
279
{
280
2605655
  if (d_inferManager != nullptr)
281
  {
282
2405220
    d_inferManager->notifyInConflict();
283
  }
284
2605655
}
285
286
6529
void Theory::computeCareGraph() {
287
6529
  Debug("sharing") << "Theory::computeCareGraph<" << getId() << ">()" << endl;
288
7057
  for (unsigned i = 0; i < d_sharedTerms.size(); ++ i) {
289
1056
    TNode a = d_sharedTerms[i];
290
1056
    TypeNode aType = a.getType();
291
5094
    for (unsigned j = i + 1; j < d_sharedTerms.size(); ++ j) {
292
8676
      TNode b = d_sharedTerms[j];
293
4566
      if (b.getType() != aType) {
294
        // We don't care about the terms of different types
295
456
        continue;
296
      }
297
4110
      switch (d_valuation.getEqualityStatus(a, b)) {
298
3304
      case EQUALITY_TRUE_AND_PROPAGATED:
299
      case EQUALITY_FALSE_AND_PROPAGATED:
300
        // If we know about it, we should have propagated it, so we can skip
301
3304
        break;
302
806
      default:
303
        // Let's split on it
304
806
        addCarePair(a, b);
305
806
        break;
306
      }
307
    }
308
  }
309
6529
}
310
311
void Theory::printFacts(std::ostream& os) const {
312
  unsigned i, n = d_facts.size();
313
  for(i = 0; i < n; i++){
314
    const Assertion& a_i = d_facts[i];
315
    Node assertion  = a_i;
316
    os << d_id << '[' << i << ']' << " " << assertion << endl;
317
  }
318
}
319
320
void Theory::debugPrintFacts() const{
321
  DebugChannel.getStream() << "Theory::debugPrintFacts()" << endl;
322
  printFacts(DebugChannel.getStream());
323
}
324
325
17838
bool Theory::isLegalElimination(TNode x, TNode val)
326
{
327
17838
  Assert(x.isVar());
328
35676
  if (x.getKind() == kind::BOOLEAN_TERM_VARIABLE
329
17838
      || val.getKind() == kind::BOOLEAN_TERM_VARIABLE)
330
  {
331
    return false;
332
  }
333
17838
  if (expr::hasSubterm(val, x))
334
  {
335
4757
    return false;
336
  }
337
13081
  if (!val.getType().isSubtypeOf(x.getType()))
338
  {
339
    return false;
340
  }
341
13081
  if (!options::produceModels() && !logicInfo().isQuantified())
342
  {
343
    // Don't care about the model and logic is not quantified, we can eliminate.
344
2949
    return true;
345
  }
346
  // If models are enabled, then it depends on whether the term contains any
347
  // unevaluable operators like FORALL, SINE, etc. Having such operators makes
348
  // model construction contain non-constant values for variables, which is
349
  // not ideal from a user perspective.
350
  // We also insist on this check since the term to eliminate should never
351
  // contain quantifiers, or else variable shadowing issues may arise.
352
  // there should be a model object
353
10132
  TheoryModel* tm = d_valuation.getModel();
354
10132
  Assert(tm != nullptr);
355
10132
  return tm->isLegalElimination(x, val);
356
}
357
358
42935
std::unordered_set<TNode> Theory::currentlySharedTerms() const
359
{
360
42935
  std::unordered_set<TNode> currentlyShared;
361
1081376
  for (shared_terms_iterator i = shared_terms_begin(),
362
42935
           i_end = shared_terms_end(); i != i_end; ++i) {
363
1038441
    currentlyShared.insert (*i);
364
  }
365
42935
  return currentlyShared;
366
}
367
368
70143
bool Theory::collectModelInfo(TheoryModel* m, const std::set<Node>& termSet)
369
{
370
  // if we are using an equality engine, assert it to the model
371
70143
  if (d_equalityEngine != nullptr && !termSet.empty())
372
  {
373
57326
    Trace("model-builder") << "Assert Equality engine for " << d_id
374
28663
                           << std::endl;
375
28663
    if (!m->assertEqualityEngine(d_equalityEngine, &termSet))
376
    {
377
      return false;
378
    }
379
  }
380
70143
  Trace("model-builder") << "Collect Model values for " << d_id << std::endl;
381
  // now, collect theory-specific value assigments
382
70143
  return collectModelValues(m, termSet);
383
}
384
385
66947
void Theory::computeRelevantTerms(std::set<Node>& termSet)
386
{
387
  // by default, there are no additional relevant terms
388
66947
}
389
390
124768
void Theory::collectAssertedTerms(std::set<Node>& termSet,
391
                                  bool includeShared) const
392
{
393
  // Collect all terms appearing in assertions
394
124768
  context::CDList<Assertion>::const_iterator assert_it = facts_begin(),
395
124768
                                             assert_it_end = facts_end();
396
10978354
  for (; assert_it != assert_it_end; ++assert_it)
397
  {
398
5426793
    collectTerms(*assert_it, termSet);
399
  }
400
401
124768
  if (includeShared)
402
  {
403
    // Add terms that are shared terms
404
124768
    context::CDList<TNode>::const_iterator shared_it = shared_terms_begin(),
405
124768
                                           shared_it_end = shared_terms_end();
406
3185112
    for (; shared_it != shared_it_end; ++shared_it)
407
    {
408
1530172
      collectTerms(*shared_it, termSet);
409
    }
410
  }
411
124768
}
412
413
6956965
void Theory::collectTerms(TNode n, std::set<Node>& termSet) const
414
{
415
  const std::set<Kind>& irrKinds =
416
6956965
      d_theoryState->getModel()->getIrrelevantKinds();
417
13913930
  std::vector<TNode> visit;
418
13913930
  TNode cur;
419
6956965
  visit.push_back(n);
420
17252653
  do
421
  {
422
24209618
    cur = visit.back();
423
24209618
    visit.pop_back();
424
24209618
    if (termSet.find(cur) != termSet.end())
425
    {
426
      // already visited
427
12593876
      continue;
428
    }
429
11615742
    Kind k = cur.getKind();
430
    // only add to term set if a relevant kind
431
11615742
    if (irrKinds.find(k) == irrKinds.end())
432
    {
433
5982453
      termSet.insert(cur);
434
    }
435
    // traverse owned terms, don't go under quantifiers
436
32597444
    if ((k == kind::NOT || k == kind::EQUAL || Theory::theoryOf(cur) == d_id)
437
33758618
        && !cur.isClosure())
438
    {
439
10497378
      visit.insert(visit.end(), cur.begin(), cur.end());
440
    }
441
24209618
  } while (!visit.empty());
442
6956965
}
443
444
4926
bool Theory::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
445
{
446
4926
  return true;
447
}
448
449
46405
Theory::PPAssertStatus Theory::ppAssert(TrustNode tin,
450
                                        TrustSubstitutionMap& outSubstitutions)
451
{
452
92810
  TNode in = tin.getNode();
453
46405
  if (in.getKind() == kind::EQUAL)
454
  {
455
    // (and (= x t) phi) can be replaced by phi[x/t] if
456
    // 1) x is a variable
457
    // 2) x is not in the term t
458
    // 3) x : T and t : S, then S <: T
459
77902
    if (in[0].isVar() && isLegalElimination(in[0], in[1])
460
73275
        && in[0].getKind() != kind::BOOLEAN_TERM_VARIABLE)
461
    {
462
10335
      outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
463
10335
      return PP_ASSERT_STATUS_SOLVED;
464
    }
465
32182
    if (in[1].isVar() && isLegalElimination(in[1], in[0])
466
32182
        && in[1].getKind() != kind::BOOLEAN_TERM_VARIABLE)
467
    {
468
247
      outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
469
247
      return PP_ASSERT_STATUS_SOLVED;
470
    }
471
10398
    if (in[0].isConst() && in[1].isConst())
472
    {
473
      if (in[0] != in[1])
474
      {
475
        return PP_ASSERT_STATUS_CONFLICT;
476
      }
477
    }
478
  }
479
74384
  else if (in.getKind() == kind::NOT && in[0].getKind() == kind::EQUAL
480
73956
           && in[0][0].getType().isBoolean())
481
  {
482
41
    TNode eq = in[0];
483
39
    if (eq[0].isVar())
484
    {
485
74
      Node res = eq[0].eqNode(eq[1].notNode());
486
74
      TrustNode tn = TrustNode::mkTrustRewrite(in, res, nullptr);
487
37
      return ppAssert(tn, outSubstitutions);
488
    }
489
2
    else if (eq[1].isVar())
490
    {
491
      Node res = eq[1].eqNode(eq[0].notNode());
492
      TrustNode tn = TrustNode::mkTrustRewrite(in, res, nullptr);
493
      return ppAssert(tn, outSubstitutions);
494
    }
495
  }
496
497
35786
  return PP_ASSERT_STATUS_UNSOLVED;
498
}
499
500
std::pair<bool, Node> Theory::entailmentCheck(TNode lit)
501
{
502
  return make_pair(false, Node::null());
503
}
504
505
52974
void Theory::addCarePair(TNode t1, TNode t2) {
506
52974
  if (d_careGraph) {
507
52974
    d_careGraph->insert(CarePair(t1, t2, d_id));
508
  }
509
52974
}
510
511
70564
void Theory::getCareGraph(CareGraph* careGraph) {
512
70564
  Assert(careGraph != NULL);
513
514
70564
  Trace("sharing") << "Theory<" << getId() << ">::getCareGraph()" << std::endl;
515
141128
  TimerStat::CodeTimer computeCareGraphTime(d_computeCareGraphTime);
516
70564
  d_careGraph = careGraph;
517
70564
  computeCareGraph();
518
70564
  d_careGraph = NULL;
519
70564
}
520
521
bool Theory::proofsEnabled() const
522
{
523
  return d_env.getProofNodeManager() != nullptr;
524
}
525
526
20129
EqualityStatus Theory::getEqualityStatus(TNode a, TNode b)
527
{
528
  // if not using an equality engine, then by default we don't know the status
529
20129
  if (d_equalityEngine == nullptr)
530
  {
531
5768
    return EQUALITY_UNKNOWN;
532
  }
533
14361
  Trace("sharing") << "Theory<" << getId() << ">::getEqualityStatus(" << a << ", " << b << ")" << std::endl;
534
14361
  Assert(d_equalityEngine->hasTerm(a) && d_equalityEngine->hasTerm(b));
535
536
  // Check for equality (simplest)
537
14361
  if (d_equalityEngine->areEqual(a, b))
538
  {
539
    // The terms are implied to be equal
540
7253
    return EQUALITY_TRUE;
541
  }
542
543
  // Check for disequality
544
7108
  if (d_equalityEngine->areDisequal(a, b, false))
545
  {
546
    // The terms are implied to be dis-equal
547
2572
    return EQUALITY_FALSE;
548
  }
549
550
  // All other terms are unknown, which is conservative. A theory may override
551
  // this method if it knows more information.
552
4536
  return EQUALITY_UNKNOWN;
553
}
554
555
14588378
void Theory::check(Effort level)
556
{
557
  // see if we are already done (as an optimization)
558
14588378
  if (done() && level < EFFORT_FULL)
559
  {
560
18657284
    return;
561
  }
562
5259736
  Assert(d_theoryState!=nullptr);
563
  // standard calls for resource, stats
564
5259736
  d_out->spendResource(Resource::TheoryCheckStep);
565
10519472
  TimerStat::CodeTimer checkTimer(d_checkTime);
566
10519472
  Trace("theory-check") << "Theory::preCheck " << level << " " << d_id
567
5259736
                        << std::endl;
568
  // pre-check at level
569
5259736
  if (preCheck(level))
570
  {
571
    // check aborted for a theory-specific reason
572
    return;
573
  }
574
5259736
  Assert(d_theoryState != nullptr);
575
5259736
  Trace("theory-check") << "Theory::process fact queue " << d_id << std::endl;
576
  // process the pending fact queue
577
35148866
  while (!done() && !d_theoryState->isInConflict())
578
  {
579
    // Get the next assertion from the fact queue
580
23902079
    Assertion assertion = get();
581
23902079
    TNode fact = assertion.d_assertion;
582
29889136
    Trace("theory-check") << "Theory::preNotifyFact " << fact << " " << d_id
583
14944568
                          << std::endl;
584
14944568
    bool polarity = fact.getKind() != kind::NOT;
585
23902079
    TNode atom = polarity ? fact : fact[0];
586
    // call the pre-notify method
587
14944568
    if (preNotifyFact(atom, polarity, fact, assertion.d_isPreregistered, false))
588
    {
589
      // handled in theory-specific way that doesn't involve equality engine
590
5987057
      continue;
591
    }
592
17915022
    Trace("theory-check") << "Theory::assert " << fact << " " << d_id
593
8957511
                          << std::endl;
594
    // Theories that don't have an equality engine should always return true
595
    // for preNotifyFact
596
8957511
    Assert(d_equalityEngine != nullptr);
597
    // assert to the equality engine
598
8957511
    if (atom.getKind() == kind::EQUAL)
599
    {
600
6590652
      d_equalityEngine->assertEquality(atom, polarity, fact);
601
    }
602
    else
603
    {
604
2366862
      d_equalityEngine->assertPredicate(atom, polarity, fact);
605
    }
606
17915016
    Trace("theory-check") << "Theory::notifyFact " << fact << " " << d_id
607
8957508
                          << std::endl;
608
    // notify the theory of the new fact, which is not internal
609
8957508
    notifyFact(atom, polarity, fact, false);
610
  }
611
5259733
  Trace("theory-check") << "Theory::postCheck " << d_id << std::endl;
612
  // post-check at level
613
5259733
  postCheck(level);
614
5259732
  Trace("theory-check") << "Theory::finish check " << d_id << std::endl;
615
}
616
617
2064676
bool Theory::preCheck(Effort level) { return false; }
618
619
2
void Theory::postCheck(Effort level) {}
620
621
5321922
bool Theory::preNotifyFact(
622
    TNode atom, bool polarity, TNode fact, bool isPrereg, bool isInternal)
623
{
624
5321922
  return false;
625
}
626
627
6814
void Theory::notifyFact(TNode atom, bool polarity, TNode fact, bool isInternal)
628
{
629
6814
}
630
631
22286
void Theory::preRegisterTerm(TNode node) {}
632
633
1895708
void Theory::addSharedTerm(TNode n)
634
{
635
3791416
  Debug("sharing") << "Theory::addSharedTerm<" << getId() << ">(" << n << ")"
636
1895708
                   << std::endl;
637
3791416
  Debug("theory::assertions")
638
1895708
      << "Theory::addSharedTerm<" << getId() << ">(" << n << ")" << std::endl;
639
1895708
  d_sharedTerms.push_back(n);
640
  // now call theory-specific method notifySharedTerm
641
1895708
  notifySharedTerm(n);
642
  // if we have an equality engine, add the trigger term
643
1895708
  if (d_equalityEngine != nullptr)
644
  {
645
1890207
    d_equalityEngine->addTriggerTerm(n, d_id);
646
  }
647
1895708
}
648
649
372957
eq::EqualityEngine* Theory::getEqualityEngine()
650
{
651
  // get the assigned equality engine, which is a pointer stored in this class
652
372957
  return d_equalityEngine;
653
}
654
655
350
bool Theory::usesCentralEqualityEngine() const
656
{
657
350
  return usesCentralEqualityEngine(d_id);
658
}
659
660
28808205
bool Theory::usesCentralEqualityEngine(TheoryId id)
661
{
662
28808205
  if (id == THEORY_BUILTIN)
663
  {
664
11116941
    return true;
665
  }
666
17691264
  if (options::eeMode() == options::EqEngineMode::DISTRIBUTED)
667
  {
668
17673554
    return false;
669
  }
670
17710
  if (id == THEORY_ARITH)
671
  {
672
    // conditional on whether we are using the equality solver
673
70
    return options::arithEqSolver();
674
  }
675
16662
  return id == THEORY_UF || id == THEORY_DATATYPES || id == THEORY_BAGS
676
10048
         || id == THEORY_FP || id == THEORY_SETS || id == THEORY_STRINGS
677
27112
         || id == THEORY_SEP || id == THEORY_ARRAYS || id == THEORY_BV;
678
}
679
680
33356520
bool Theory::expUsingCentralEqualityEngine(TheoryId id)
681
{
682
33356520
  return id != THEORY_ARITH && usesCentralEqualityEngine(id);
683
}
684
685
}  // namespace theory
686
29502
}  // namespace cvc5