GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/theory.cpp Lines: 272 320 85.0 %
Date: 2021-11-05 Branches: 551 1119 49.2 %

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
198565
Theory::Theory(TheoryId id,
63
               Env& env,
64
               OutputChannel& out,
65
               Valuation valuation,
66
198565
               std::string name)
67
    : EnvObj(env),
68
      d_instanceName(name),
69
397130
      d_checkTime(statisticsRegistry().registerTimer(getStatsPrefix(id) + name
70
397130
                                                     + "checkTime")),
71
198565
      d_computeCareGraphTime(statisticsRegistry().registerTimer(
72
397130
          getStatsPrefix(id) + name + "computeCareGraphTime")),
73
198565
      d_sharedTerms(d_env.getContext()),
74
      d_out(&out),
75
      d_valuation(valuation),
76
      d_equalityEngine(nullptr),
77
      d_allocEqualityEngine(nullptr),
78
      d_theoryState(nullptr),
79
      d_inferManager(nullptr),
80
      d_quantEngine(nullptr),
81
198565
      d_pnm(d_env.isTheoryProofProducing() ? d_env.getProofNodeManager()
82
                                           : nullptr),
83
      d_id(id),
84
198565
      d_facts(d_env.getContext()),
85
198565
      d_factsHead(d_env.getContext(), 0),
86
198565
      d_sharedTermsIndex(d_env.getContext(), 0),
87
1787085
      d_careGraph(nullptr)
88
{
89
198565
}
90
91
198500
Theory::~Theory() {
92
198500
}
93
94
30542
bool Theory::needsEqualityEngine(EeSetupInfo& esi)
95
{
96
  // by default, this theory does not use an (official) equality engine
97
30542
  return false;
98
}
99
100
198523
void Theory::setEqualityEngine(eq::EqualityEngine* ee)
101
{
102
  // set the equality engine pointer
103
198523
  d_equalityEngine = ee;
104
198523
  if (d_theoryState != nullptr)
105
  {
106
183252
    d_theoryState->setEqualityEngine(ee);
107
  }
108
198523
  if (d_inferManager != nullptr)
109
  {
110
183252
    d_inferManager->setEqualityEngine(ee);
111
  }
112
198523
}
113
114
198523
void Theory::setQuantifiersEngine(QuantifiersEngine* qe)
115
{
116
  // quantifiers engine may be null if not in quantified logic
117
198523
  d_quantEngine = qe;
118
198523
}
119
120
198523
void Theory::setDecisionManager(DecisionManager* dm)
121
{
122
198523
  Assert(dm != nullptr);
123
198523
  if (d_inferManager != nullptr)
124
  {
125
183252
    d_inferManager->setDecisionManager(dm);
126
  }
127
198523
}
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 =
136
        std::make_unique<eq::EqualityEngine>(d_env,
137
                                             context(),
138
                                             *esi.d_notify,
139
                                             esi.d_name,
140
                                             esi.d_constantsAreTriggers);
141
    // use it as the official equality engine
142
    setEqualityEngine(d_allocEqualityEngine.get());
143
  }
144
  finishInit();
145
}
146
147
198797561
TheoryId Theory::theoryOf(options::TheoryOfMode mode, TNode node)
148
{
149
198797561
  TheoryId tid = THEORY_BUILTIN;
150
198797561
  switch(mode) {
151
117542453
    case options::TheoryOfMode::THEORY_OF_TYPE_BASED:
152
      // Constants, variables, 0-ary constructors
153
117542453
      if (node.isVar())
154
      {
155
5273704
        if (node.getKind() == kind::BOOLEAN_TERM_VARIABLE)
156
        {
157
230911
          tid = THEORY_UF;
158
        }
159
        else
160
        {
161
5042793
          tid = Theory::theoryOf(node.getType());
162
        }
163
      }
164
112268749
      else if (node.getKind() == kind::EQUAL)
165
      {
166
        // Equality is owned by the theory that owns the domain
167
8343062
        tid = Theory::theoryOf(node[0].getType());
168
      }
169
      else
170
      {
171
        // Regular nodes are owned by the kind. Notice that constants are a
172
        // special case here, where the theory of the kind of a constant
173
        // always coincides with the type of that constant.
174
103925687
        tid = kindToTheoryId(node.getKind());
175
      }
176
117542453
      break;
177
81255108
    case options::TheoryOfMode::THEORY_OF_TERM_BASED:
178
      // Variables
179
81255108
      if (node.isVar())
180
      {
181
5759867
        if (Theory::theoryOf(node.getType()) != theory::THEORY_BOOL)
182
        {
183
          // We treat the variables as uninterpreted
184
5749105
          tid = s_uninterpretedSortOwner;
185
        }
186
        else
187
        {
188
10762
          if (node.getKind() == kind::BOOLEAN_TERM_VARIABLE)
189
          {
190
            // Boolean vars go to UF
191
5586
            tid = THEORY_UF;
192
          }
193
          else
194
          {
195
            // Except for the Boolean ones
196
5176
            tid = THEORY_BOOL;
197
          }
198
        }
199
      }
200
75495241
      else if (node.getKind() == kind::EQUAL)
201
      {  // Equality
202
        // If one of them is an ITE, it's irelevant, since they will get
203
        // replaced out anyhow
204
6404383
        if (node[0].getKind() == kind::ITE)
205
        {
206
5793
          tid = Theory::theoryOf(node[0].getType());
207
        }
208
6398590
        else if (node[1].getKind() == kind::ITE)
209
        {
210
9755
          tid = Theory::theoryOf(node[1].getType());
211
        }
212
        else
213
        {
214
12777670
          TNode l = node[0];
215
12777670
          TNode r = node[1];
216
12777670
          TypeNode ltype = l.getType();
217
12777670
          TypeNode rtype = r.getType();
218
          // If the types are different, we must assign based on type due
219
          // to handling subtypes (limited to arithmetic). Also, if we are
220
          // a Boolean equality, we must assign THEORY_BOOL.
221
6388835
          if (ltype != rtype || ltype.isBoolean())
222
          {
223
72526
            tid = Theory::theoryOf(ltype);
224
          }
225
          else
226
          {
227
            // If both sides belong to the same theory the choice is easy
228
6316309
            TheoryId T1 = Theory::theoryOf(l);
229
6316309
            TheoryId T2 = Theory::theoryOf(r);
230
6316309
            if (T1 == T2)
231
            {
232
2873510
              tid = T1;
233
            }
234
            else
235
            {
236
3442799
              TheoryId T3 = Theory::theoryOf(ltype);
237
              // This is a case of
238
              // * x*y = f(z) -> UF
239
              // * x = c      -> UF
240
              // * f(x) = read(a, y) -> either UF or ARRAY
241
              // at least one of the theories has to be parametric, i.e. theory
242
              // of the type is different from the theory of the term
243
3442799
              if (T1 == T3)
244
              {
245
52654
                tid = T2;
246
              }
247
3390145
              else if (T2 == T3)
248
              {
249
3262921
                tid = T1;
250
              }
251
              else
252
              {
253
                // If both are parametric, we take the smaller one (arbitrary)
254
127224
                tid = T1 < T2 ? T1 : T2;
255
              }
256
            }
257
          }
258
        }
259
      }
260
      else
261
      {
262
        // Regular nodes are owned by the kind, which includes constants as a
263
        // special case.
264
69090858
        tid = kindToTheoryId(node.getKind());
265
      }
266
81255108
    break;
267
  default:
268
    Unreachable();
269
  }
270
198797561
  Trace("theory::internal") << "theoryOf(" << mode << ", " << node << ") -> " << tid << std::endl;
271
198797561
  return tid;
272
}
273
274
1370791
void Theory::notifySharedTerm(TNode n)
275
{
276
  // do nothing
277
1370791
}
278
279
2780570
void Theory::notifyInConflict()
280
{
281
2780570
  if (d_inferManager != nullptr)
282
  {
283
2566680
    d_inferManager->notifyInConflict();
284
  }
285
2780570
}
286
287
8715
void Theory::computeCareGraph() {
288
8715
  Debug("sharing") << "Theory::computeCareGraph<" << getId() << ">()" << endl;
289
9757
  for (unsigned i = 0; i < d_sharedTerms.size(); ++ i) {
290
2084
    TNode a = d_sharedTerms[i];
291
2084
    TypeNode aType = a.getType();
292
15256
    for (unsigned j = i + 1; j < d_sharedTerms.size(); ++ j) {
293
25694
      TNode b = d_sharedTerms[j];
294
14214
      if (b.getType() != aType) {
295
        // We don't care about the terms of different types
296
2734
        continue;
297
      }
298
11480
      switch (d_valuation.getEqualityStatus(a, b)) {
299
10448
      case EQUALITY_TRUE_AND_PROPAGATED:
300
      case EQUALITY_FALSE_AND_PROPAGATED:
301
        // If we know about it, we should have propagated it, so we can skip
302
10448
        break;
303
1032
      default:
304
        // Let's split on it
305
1032
        addCarePair(a, b);
306
1032
        break;
307
      }
308
    }
309
  }
310
8715
}
311
312
void Theory::printFacts(std::ostream& os) const {
313
  unsigned i, n = d_facts.size();
314
  for(i = 0; i < n; i++){
315
    const Assertion& a_i = d_facts[i];
316
    Node assertion  = a_i;
317
    os << d_id << '[' << i << ']' << " " << assertion << endl;
318
  }
319
}
320
321
void Theory::debugPrintFacts() const{
322
  DebugChannel.getStream() << "Theory::debugPrintFacts()" << endl;
323
  printFacts(DebugChannel.getStream());
324
}
325
326
19414
bool Theory::isLegalElimination(TNode x, TNode val)
327
{
328
19414
  Assert(x.isVar());
329
38828
  if (x.getKind() == kind::BOOLEAN_TERM_VARIABLE
330
19414
      || val.getKind() == kind::BOOLEAN_TERM_VARIABLE)
331
  {
332
    return false;
333
  }
334
19414
  if (expr::hasSubterm(val, x))
335
  {
336
5257
    return false;
337
  }
338
14157
  if (!val.getType().isSubtypeOf(x.getType()))
339
  {
340
    return false;
341
  }
342
14157
  if (!options().smt.produceModels && !logicInfo().isQuantified())
343
  {
344
    // Don't care about the model and logic is not quantified, we can eliminate.
345
2972
    return true;
346
  }
347
  // If models are enabled, then it depends on whether the term contains any
348
  // unevaluable operators like FORALL, SINE, etc. Having such operators makes
349
  // model construction contain non-constant values for variables, which is
350
  // not ideal from a user perspective.
351
  // We also insist on this check since the term to eliminate should never
352
  // contain quantifiers, or else variable shadowing issues may arise.
353
  // there should be a model object
354
11185
  TheoryModel* tm = d_valuation.getModel();
355
11185
  Assert(tm != nullptr);
356
11185
  return tm->isLegalElimination(x, val);
357
}
358
359
79927
std::unordered_set<TNode> Theory::currentlySharedTerms() const
360
{
361
79927
  std::unordered_set<TNode> currentlyShared;
362
2796241
  for (shared_terms_iterator i = shared_terms_begin(),
363
79927
           i_end = shared_terms_end(); i != i_end; ++i) {
364
2716314
    currentlyShared.insert (*i);
365
  }
366
79927
  return currentlyShared;
367
}
368
369
107878
bool Theory::collectModelInfo(TheoryModel* m, const std::set<Node>& termSet)
370
{
371
  // if we are using an equality engine, assert it to the model
372
107878
  if (d_equalityEngine != nullptr && !termSet.empty())
373
  {
374
92690
    Trace("model-builder") << "Assert Equality engine for " << d_id
375
46345
                           << std::endl;
376
46345
    if (!m->assertEqualityEngine(d_equalityEngine, &termSet))
377
    {
378
      return false;
379
    }
380
  }
381
107878
  Trace("model-builder") << "Collect Model values for " << d_id << std::endl;
382
  // now, collect theory-specific value assigments
383
107878
  return collectModelValues(m, termSet);
384
}
385
386
101990
void Theory::computeRelevantTerms(std::set<Node>& termSet)
387
{
388
  // by default, there are no additional relevant terms
389
101990
}
390
391
212254
void Theory::collectAssertedTerms(std::set<Node>& termSet,
392
                                  bool includeShared) const
393
{
394
  // Collect all terms appearing in assertions
395
212254
  context::CDList<Assertion>::const_iterator assert_it = facts_begin(),
396
212254
                                             assert_it_end = facts_end();
397
26059284
  for (; assert_it != assert_it_end; ++assert_it)
398
  {
399
12923515
    collectTerms(*assert_it, termSet);
400
  }
401
402
212254
  if (includeShared)
403
  {
404
    // Add terms that are shared terms
405
212254
    context::CDList<TNode>::const_iterator shared_it = shared_terms_begin(),
406
212254
                                           shared_it_end = shared_terms_end();
407
8426030
    for (; shared_it != shared_it_end; ++shared_it)
408
    {
409
4106888
      collectTerms(*shared_it, termSet);
410
    }
411
  }
412
212254
}
413
414
17030403
void Theory::collectTerms(TNode n, std::set<Node>& termSet) const
415
{
416
  const std::set<Kind>& irrKinds =
417
17030403
      d_theoryState->getModel()->getIrrelevantKinds();
418
34060806
  std::vector<TNode> visit;
419
34060806
  TNode cur;
420
17030403
  visit.push_back(n);
421
40562443
  do
422
  {
423
57592846
    cur = visit.back();
424
57592846
    visit.pop_back();
425
57592846
    if (termSet.find(cur) != termSet.end())
426
    {
427
      // already visited
428
30079529
      continue;
429
    }
430
27513317
    Kind k = cur.getKind();
431
    // only add to term set if a relevant kind
432
27513317
    if (irrKinds.find(k) == irrKinds.end())
433
    {
434
13846958
      termSet.insert(cur);
435
    }
436
    // traverse owned terms, don't go under quantifiers
437
76728648
    if ((k == kind::NOT || k == kind::EQUAL || Theory::theoryOf(cur) == d_id)
438
79762617
        && !cur.isClosure())
439
    {
440
24700613
      visit.insert(visit.end(), cur.begin(), cur.end());
441
    }
442
57592846
  } while (!visit.empty());
443
17030403
}
444
445
7043
bool Theory::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
446
{
447
7043
  return true;
448
}
449
450
48355
Theory::PPAssertStatus Theory::ppAssert(TrustNode tin,
451
                                        TrustSubstitutionMap& outSubstitutions)
452
{
453
96710
  TNode in = tin.getNode();
454
48355
  if (in.getKind() == kind::EQUAL)
455
  {
456
    // (and (= x t) phi) can be replaced by phi[x/t] if
457
    // 1) x is a variable
458
    // 2) x is not in the term t
459
    // 3) x : T and t : S, then S <: T
460
84008
    if (in[0].isVar() && isLegalElimination(in[0], in[1])
461
78887
        && in[0].getKind() != kind::BOOLEAN_TERM_VARIABLE)
462
    {
463
11288
      outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
464
11288
      return PP_ASSERT_STATUS_SOLVED;
465
    }
466
33985
    if (in[1].isVar() && isLegalElimination(in[1], in[0])
467
33985
        && in[1].getKind() != kind::BOOLEAN_TERM_VARIABLE)
468
    {
469
250
      outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
470
250
      return PP_ASSERT_STATUS_SOLVED;
471
    }
472
10995
    if (in[0].isConst() && in[1].isConst())
473
    {
474
      if (in[0] != in[1])
475
      {
476
        return PP_ASSERT_STATUS_CONFLICT;
477
      }
478
    }
479
  }
480
75522
  else if (in.getKind() == kind::NOT && in[0].getKind() == kind::EQUAL
481
75070
           && in[0][0].getType().isBoolean())
482
  {
483
210
    TNode eq = in[0];
484
208
    if (eq[0].isVar())
485
    {
486
412
      Node res = eq[0].eqNode(eq[1].notNode());
487
412
      TrustNode tn = TrustNode::mkTrustRewrite(in, res, nullptr);
488
206
      return ppAssert(tn, outSubstitutions);
489
    }
490
2
    else if (eq[1].isVar())
491
    {
492
      Node res = eq[1].eqNode(eq[0].notNode());
493
      TrustNode tn = TrustNode::mkTrustRewrite(in, res, nullptr);
494
      return ppAssert(tn, outSubstitutions);
495
    }
496
  }
497
498
36611
  return PP_ASSERT_STATUS_UNSOLVED;
499
}
500
501
std::pair<bool, Node> Theory::entailmentCheck(TNode lit)
502
{
503
  return make_pair(false, Node::null());
504
}
505
506
43072
void Theory::addCarePair(TNode t1, TNode t2) {
507
43072
  if (d_careGraph) {
508
43072
    d_careGraph->insert(CarePair(t1, t2, d_id));
509
  }
510
43072
}
511
512
96190
void Theory::getCareGraph(CareGraph* careGraph) {
513
96190
  Assert(careGraph != NULL);
514
515
96190
  Trace("sharing") << "Theory<" << getId() << ">::getCareGraph()" << std::endl;
516
192380
  TimerStat::CodeTimer computeCareGraphTime(d_computeCareGraphTime);
517
96190
  d_careGraph = careGraph;
518
96190
  computeCareGraph();
519
96190
  d_careGraph = NULL;
520
96190
}
521
522
bool Theory::proofsEnabled() const
523
{
524
  return d_env.getProofNodeManager() != nullptr;
525
}
526
527
20155
EqualityStatus Theory::getEqualityStatus(TNode a, TNode b)
528
{
529
  // if not using an equality engine, then by default we don't know the status
530
20155
  if (d_equalityEngine == nullptr)
531
  {
532
5776
    return EQUALITY_UNKNOWN;
533
  }
534
14379
  Trace("sharing") << "Theory<" << getId() << ">::getEqualityStatus(" << a << ", " << b << ")" << std::endl;
535
14379
  Assert(d_equalityEngine->hasTerm(a) && d_equalityEngine->hasTerm(b));
536
537
  // Check for equality (simplest)
538
14379
  if (d_equalityEngine->areEqual(a, b))
539
  {
540
    // The terms are implied to be equal
541
7214
    return EQUALITY_TRUE;
542
  }
543
544
  // Check for disequality
545
7165
  if (d_equalityEngine->areDisequal(a, b, false))
546
  {
547
    // The terms are implied to be dis-equal
548
2378
    return EQUALITY_FALSE;
549
  }
550
551
  // All other terms are unknown, which is conservative. A theory may override
552
  // this method if it knows more information.
553
4787
  return EQUALITY_UNKNOWN;
554
}
555
556
22135953
void Theory::check(Effort level)
557
{
558
  // see if we are already done (as an optimization)
559
22135953
  if (done() && level < EFFORT_FULL)
560
  {
561
30593422
    return;
562
  }
563
6839242
  Assert(d_theoryState!=nullptr);
564
  // standard calls for resource, stats
565
6839242
  d_out->spendResource(Resource::TheoryCheckStep);
566
13678484
  TimerStat::CodeTimer checkTimer(d_checkTime);
567
13678484
  Trace("theory-check") << "Theory::preCheck " << level << " " << d_id
568
6839242
                        << std::endl;
569
  // pre-check at level
570
6839242
  if (preCheck(level))
571
  {
572
    // check aborted for a theory-specific reason
573
    return;
574
  }
575
6839242
  Assert(d_theoryState != nullptr);
576
6839242
  Trace("theory-check") << "Theory::process fact queue " << d_id << std::endl;
577
  // process the pending fact queue
578
44733114
  while (!done() && !d_theoryState->isInConflict())
579
  {
580
    // Get the next assertion from the fact queue
581
30395757
    Assertion assertion = get();
582
30395757
    TNode fact = assertion.d_assertion;
583
37893878
    Trace("theory-check") << "Theory::preNotifyFact " << fact << " " << d_id
584
18946939
                          << std::endl;
585
18946939
    bool polarity = fact.getKind() != kind::NOT;
586
30395757
    TNode atom = polarity ? fact : fact[0];
587
    // call the pre-notify method
588
18946939
    if (preNotifyFact(atom, polarity, fact, assertion.d_isPreregistered, false))
589
    {
590
      // handled in theory-specific way that doesn't involve equality engine
591
7498121
      continue;
592
    }
593
22897636
    Trace("theory-check") << "Theory::assert " << fact << " " << d_id
594
11448818
                          << std::endl;
595
    // Theories that don't have an equality engine should always return true
596
    // for preNotifyFact
597
11448818
    Assert(d_equalityEngine != nullptr);
598
    // assert to the equality engine
599
11448818
    if (atom.getKind() == kind::EQUAL)
600
    {
601
7853281
      d_equalityEngine->assertEquality(atom, polarity, fact);
602
    }
603
    else
604
    {
605
3595540
      d_equalityEngine->assertPredicate(atom, polarity, fact);
606
    }
607
22897630
    Trace("theory-check") << "Theory::notifyFact " << fact << " " << d_id
608
11448815
                          << std::endl;
609
    // notify the theory of the new fact, which is not internal
610
11448815
    notifyFact(atom, polarity, fact, false);
611
  }
612
6839239
  Trace("theory-check") << "Theory::postCheck " << d_id << std::endl;
613
  // post-check at level
614
6839239
  postCheck(level);
615
6839238
  Trace("theory-check") << "Theory::finish check " << d_id << std::endl;
616
}
617
618
2199757
bool Theory::preCheck(Effort level) { return false; }
619
620
2
void Theory::postCheck(Effort level) {}
621
622
8032975
bool Theory::preNotifyFact(
623
    TNode atom, bool polarity, TNode fact, bool isPrereg, bool isInternal)
624
{
625
8032975
  return false;
626
}
627
628
10437
void Theory::notifyFact(TNode atom, bool polarity, TNode fact, bool isInternal)
629
{
630
10437
}
631
632
33032
void Theory::preRegisterTerm(TNode node) {}
633
634
2470265
void Theory::addSharedTerm(TNode n)
635
{
636
4940530
  Debug("sharing") << "Theory::addSharedTerm<" << getId() << ">(" << n << ")"
637
2470265
                   << std::endl;
638
4940530
  Debug("theory::assertions")
639
2470265
      << "Theory::addSharedTerm<" << getId() << ">(" << n << ")" << std::endl;
640
2470265
  d_sharedTerms.push_back(n);
641
  // now call theory-specific method notifySharedTerm
642
2470265
  notifySharedTerm(n);
643
  // if we have an equality engine, add the trigger term
644
2470265
  if (d_equalityEngine != nullptr)
645
  {
646
2464641
    d_equalityEngine->addTriggerTerm(n, d_id);
647
  }
648
2470265
}
649
650
401420
eq::EqualityEngine* Theory::getEqualityEngine()
651
{
652
  // get the assigned equality engine, which is a pointer stored in this class
653
401420
  return d_equalityEngine;
654
}
655
656
370
bool Theory::usesCentralEqualityEngine() const
657
{
658
370
  return usesCentralEqualityEngine(d_id);
659
}
660
661
39553264
bool Theory::usesCentralEqualityEngine(TheoryId id)
662
{
663
39553264
  if (id == THEORY_BUILTIN)
664
  {
665
14262376
    return true;
666
  }
667
25290888
  if (options::eeMode() == options::EqEngineMode::DISTRIBUTED)
668
  {
669
25274138
    return false;
670
  }
671
16750
  if (id == THEORY_ARITH)
672
  {
673
    // conditional on whether we are using the equality solver
674
74
    return options::arithEqSolver();
675
  }
676
15742
  return id == THEORY_UF || id == THEORY_DATATYPES || id == THEORY_BAGS
677
9646
         || id == THEORY_FP || id == THEORY_SETS || id == THEORY_STRINGS
678
25766
         || id == THEORY_SEP || id == THEORY_ARRAYS || id == THEORY_BV;
679
}
680
681
45684582
bool Theory::expUsingCentralEqualityEngine(TheoryId id)
682
{
683
45684582
  return id != THEORY_ARITH && usesCentralEqualityEngine(id);
684
}
685
686
18946939
theory::Assertion Theory::get()
687
{
688
18946939
  Assert(!done()) << "Theory::get() called with assertion queue empty!";
689
690
  // Get the assertion
691
18946939
  Assertion fact = d_facts[d_factsHead];
692
18946939
  d_factsHead = d_factsHead + 1;
693
694
37893878
  Trace("theory") << "Theory::get() => " << fact << " ("
695
18946939
                  << d_facts.size() - d_factsHead << " left)" << std::endl;
696
697
18946939
  return fact;
698
}
699
700
}  // namespace theory
701
31125
}  // namespace cvc5