GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/inference_manager_buffered.cpp Lines: 81 87 93.1 %
Date: 2021-09-17 Branches: 55 152 36.2 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Gereon Kremer, Aina Niemetz
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * A buffered inference manager.
14
 */
15
16
#include "theory/inference_manager_buffered.h"
17
18
#include "theory/rewriter.h"
19
#include "theory/theory.h"
20
#include "theory/theory_state.h"
21
22
using namespace cvc5::kind;
23
24
namespace cvc5 {
25
namespace theory {
26
27
69594
InferenceManagerBuffered::InferenceManagerBuffered(Env& env,
28
                                                   Theory& t,
29
                                                   TheoryState& state,
30
                                                   ProofNodeManager* pnm,
31
                                                   const std::string& statsName,
32
69594
                                                   bool cacheLemmas)
33
    : TheoryInferenceManager(env, t, state, pnm, statsName, cacheLemmas),
34
69594
      d_processingPendingLemmas(false)
35
{
36
69594
}
37
38
3900927
bool InferenceManagerBuffered::hasPending() const
39
{
40
3900927
  return hasPendingFact() || hasPendingLemma();
41
}
42
43
4692325
bool InferenceManagerBuffered::hasPendingFact() const
44
{
45
4692325
  return !d_pendingFact.empty();
46
}
47
48
4798911
bool InferenceManagerBuffered::hasPendingLemma() const
49
{
50
4798911
  return !d_pendingLem.empty();
51
}
52
53
116335
bool InferenceManagerBuffered::addPendingLemma(Node lem,
54
                                               InferenceId id,
55
                                               LemmaProperty p,
56
                                               ProofGenerator* pg,
57
                                               bool checkCache)
58
{
59
116335
  if (checkCache)
60
  {
61
    // check if it is unique up to rewriting
62
197338
    Node lemr = Rewriter::rewrite(lem);
63
116335
    if (hasCachedLemma(lemr, p))
64
    {
65
35332
      return false;
66
    }
67
  }
68
  // make the simple theory lemma
69
81003
  d_pendingLem.emplace_back(new SimpleTheoryLemma(id, lem, p, pg));
70
81003
  return true;
71
}
72
73
25576
void InferenceManagerBuffered::addPendingLemma(
74
    std::unique_ptr<TheoryInference> lemma)
75
{
76
25576
  d_pendingLem.emplace_back(std::move(lemma));
77
25576
}
78
79
void InferenceManagerBuffered::addPendingFact(Node conc,
80
                                              InferenceId id,
81
                                              Node exp,
82
                                              ProofGenerator* pg)
83
{
84
  // make a simple theory internal fact
85
  Assert(conc.getKind() != AND && conc.getKind() != OR);
86
  d_pendingFact.emplace_back(new SimpleTheoryInternalFact(id, conc, exp, pg));
87
}
88
89
38599
void InferenceManagerBuffered::addPendingFact(
90
    std::unique_ptr<TheoryInference> fact)
91
{
92
38599
  d_pendingFact.emplace_back(std::move(fact));
93
38599
}
94
95
4533
void InferenceManagerBuffered::addPendingPhaseRequirement(Node lit, bool pol)
96
{
97
  // it is the responsibility of the caller to ensure lit is rewritten
98
4533
  d_pendingReqPhase[lit] = pol;
99
4533
}
100
101
3908355
void InferenceManagerBuffered::doPendingFacts()
102
{
103
3908355
  size_t i = 0;
104
4634789
  while (!d_theoryState.isInConflict() && i < d_pendingFact.size())
105
  {
106
    // assert the internal fact, which notice may enqueue more pending facts in
107
    // this loop, or result in a conflict.
108
363217
    assertInternalFactTheoryInference(d_pendingFact[i].get());
109
363217
    i++;
110
  }
111
3908355
  d_pendingFact.clear();
112
3908355
}
113
114
3709808
void InferenceManagerBuffered::doPendingLemmas()
115
{
116
3709808
  if (d_processingPendingLemmas)
117
  {
118
    // already processing
119
11859
    return;
120
  }
121
3697949
  d_processingPendingLemmas = true;
122
3697949
  size_t i = 0;
123
3964829
  while (i < d_pendingLem.size())
124
  {
125
    // process this lemma, which notice may enqueue more pending lemmas in this
126
    // loop, or clear the lemmas.
127
133441
    lemmaTheoryInference(d_pendingLem[i].get());
128
133440
    i++;
129
  }
130
3697948
  d_pendingLem.clear();
131
3697948
  d_processingPendingLemmas = false;
132
}
133
134
231668
void InferenceManagerBuffered::doPendingPhaseRequirements()
135
{
136
  // process the pending require phase calls
137
236199
  for (const std::pair<const Node, bool>& prp : d_pendingReqPhase)
138
  {
139
4531
    requirePhase(prp.first, prp.second);
140
  }
141
231668
  d_pendingReqPhase.clear();
142
231668
}
143
1469107
void InferenceManagerBuffered::clearPending()
144
{
145
1469107
  d_pendingFact.clear();
146
1469107
  d_pendingLem.clear();
147
1469107
  d_pendingReqPhase.clear();
148
1469107
}
149
1290
void InferenceManagerBuffered::clearPendingFacts() { d_pendingFact.clear(); }
150
23481
void InferenceManagerBuffered::clearPendingLemmas() { d_pendingLem.clear(); }
151
2906
void InferenceManagerBuffered::clearPendingPhaseRequirements()
152
{
153
2906
  d_pendingReqPhase.clear();
154
2906
}
155
156
289183
std::size_t InferenceManagerBuffered::numPendingLemmas() const
157
{
158
289183
  return d_pendingLem.size();
159
}
160
std::size_t InferenceManagerBuffered::numPendingFacts() const
161
{
162
  return d_pendingFact.size();
163
}
164
165
136324
void InferenceManagerBuffered::lemmaTheoryInference(TheoryInference* lem)
166
{
167
  // process this lemma
168
136324
  LemmaProperty p = LemmaProperty::NONE;
169
272648
  TrustNode tlem = lem->processLemma(p);
170
136324
  Assert(!tlem.isNull());
171
  // send the lemma
172
136324
  trustedLemma(tlem, lem->getId(), p);
173
136323
}
174
175
363217
void InferenceManagerBuffered::assertInternalFactTheoryInference(
176
    TheoryInference* fact)
177
{
178
  // process this fact
179
726434
  std::vector<Node> exp;
180
363217
  ProofGenerator* pg = nullptr;
181
726434
  Node lit = fact->processFact(exp, pg);
182
363217
  Assert(!lit.isNull());
183
363217
  bool pol = lit.getKind() != NOT;
184
726434
  TNode atom = pol ? lit : lit[0];
185
  // no double negation or conjunctive conclusions
186
363217
  Assert(atom.getKind() != NOT && atom.getKind() != AND);
187
  // assert the internal fact
188
363217
  assertInternalFact(atom, pol, fact->getId(), exp, pg);
189
363217
}
190
191
1446347
void InferenceManagerBuffered::notifyInConflict()
192
{
193
1446347
  d_theoryState.notifyInConflict();
194
  // also clear the pending facts, which will be stale after backtracking
195
1446347
  clearPending();
196
1446347
}
197
198
}  // namespace theory
199
29577
}  // namespace cvc5