GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/inference_manager_buffered.cpp Lines: 81 87 93.1 %
Date: 2021-08-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
68950
InferenceManagerBuffered::InferenceManagerBuffered(Theory& t,
28
                                                   TheoryState& state,
29
                                                   ProofNodeManager* pnm,
30
                                                   const std::string& statsName,
31
68950
                                                   bool cacheLemmas)
32
    : TheoryInferenceManager(t, state, pnm, statsName, cacheLemmas),
33
68950
      d_processingPendingLemmas(false)
34
{
35
68950
}
36
37
3209278
bool InferenceManagerBuffered::hasPending() const
38
{
39
3209278
  return hasPendingFact() || hasPendingLemma();
40
}
41
42
3925821
bool InferenceManagerBuffered::hasPendingFact() const
43
{
44
3925821
  return !d_pendingFact.empty();
45
}
46
47
4031116
bool InferenceManagerBuffered::hasPendingLemma() const
48
{
49
4031116
  return !d_pendingLem.empty();
50
}
51
52
113130
bool InferenceManagerBuffered::addPendingLemma(Node lem,
53
                                               InferenceId id,
54
                                               LemmaProperty p,
55
                                               ProofGenerator* pg,
56
                                               bool checkCache)
57
{
58
113130
  if (checkCache)
59
  {
60
    // check if it is unique up to rewriting
61
191592
    Node lemr = Rewriter::rewrite(lem);
62
113130
    if (hasCachedLemma(lemr, p))
63
    {
64
34668
      return false;
65
    }
66
  }
67
  // make the simple theory lemma
68
78462
  d_pendingLem.emplace_back(new SimpleTheoryLemma(id, lem, p, pg));
69
78462
  return true;
70
}
71
72
21651
void InferenceManagerBuffered::addPendingLemma(
73
    std::unique_ptr<TheoryInference> lemma)
74
{
75
21651
  d_pendingLem.emplace_back(std::move(lemma));
76
21651
}
77
78
void InferenceManagerBuffered::addPendingFact(Node conc,
79
                                              InferenceId id,
80
                                              Node exp,
81
                                              ProofGenerator* pg)
82
{
83
  // make a simple theory internal fact
84
  Assert(conc.getKind() != AND && conc.getKind() != OR);
85
  d_pendingFact.emplace_back(new SimpleTheoryInternalFact(id, conc, exp, pg));
86
}
87
88
30206
void InferenceManagerBuffered::addPendingFact(
89
    std::unique_ptr<TheoryInference> fact)
90
{
91
30206
  d_pendingFact.emplace_back(std::move(fact));
92
30206
}
93
94
4201
void InferenceManagerBuffered::addPendingPhaseRequirement(Node lit, bool pol)
95
{
96
  // it is the responsibility of the caller to ensure lit is rewritten
97
4201
  d_pendingReqPhase[lit] = pol;
98
4201
}
99
100
3217332
void InferenceManagerBuffered::doPendingFacts()
101
{
102
3217332
  size_t i = 0;
103
3861048
  while (!d_theoryState.isInConflict() && i < d_pendingFact.size())
104
  {
105
    // assert the internal fact, which notice may enqueue more pending facts in
106
    // this loop, or result in a conflict.
107
321858
    assertInternalFactTheoryInference(d_pendingFact[i].get());
108
321858
    i++;
109
  }
110
3217332
  d_pendingFact.clear();
111
3217332
}
112
113
3070640
void InferenceManagerBuffered::doPendingLemmas()
114
{
115
3070640
  if (d_processingPendingLemmas)
116
  {
117
    // already processing
118
12731
    return;
119
  }
120
3057909
  d_processingPendingLemmas = true;
121
3057909
  size_t i = 0;
122
3323815
  while (i < d_pendingLem.size())
123
  {
124
    // process this lemma, which notice may enqueue more pending lemmas in this
125
    // loop, or clear the lemmas.
126
132954
    lemmaTheoryInference(d_pendingLem[i].get());
127
132953
    i++;
128
  }
129
3057908
  d_pendingLem.clear();
130
3057908
  d_processingPendingLemmas = false;
131
}
132
133
229150
void InferenceManagerBuffered::doPendingPhaseRequirements()
134
{
135
  // process the pending require phase calls
136
233350
  for (const std::pair<const Node, bool>& prp : d_pendingReqPhase)
137
  {
138
4200
    requirePhase(prp.first, prp.second);
139
  }
140
229150
  d_pendingReqPhase.clear();
141
229150
}
142
1335393
void InferenceManagerBuffered::clearPending()
143
{
144
1335393
  d_pendingFact.clear();
145
1335393
  d_pendingLem.clear();
146
1335393
  d_pendingReqPhase.clear();
147
1335393
}
148
1250
void InferenceManagerBuffered::clearPendingFacts() { d_pendingFact.clear(); }
149
22611
void InferenceManagerBuffered::clearPendingLemmas() { d_pendingLem.clear(); }
150
2464
void InferenceManagerBuffered::clearPendingPhaseRequirements()
151
{
152
2464
  d_pendingReqPhase.clear();
153
2464
}
154
155
289371
std::size_t InferenceManagerBuffered::numPendingLemmas() const
156
{
157
289371
  return d_pendingLem.size();
158
}
159
std::size_t InferenceManagerBuffered::numPendingFacts() const
160
{
161
  return d_pendingFact.size();
162
}
163
164
135837
void InferenceManagerBuffered::lemmaTheoryInference(TheoryInference* lem)
165
{
166
  // process this lemma
167
135837
  LemmaProperty p = LemmaProperty::NONE;
168
271674
  TrustNode tlem = lem->processLemma(p);
169
135837
  Assert(!tlem.isNull());
170
  // send the lemma
171
135837
  trustedLemma(tlem, lem->getId(), p);
172
135836
}
173
174
321858
void InferenceManagerBuffered::assertInternalFactTheoryInference(
175
    TheoryInference* fact)
176
{
177
  // process this fact
178
643716
  std::vector<Node> exp;
179
321858
  ProofGenerator* pg = nullptr;
180
643716
  Node lit = fact->processFact(exp, pg);
181
321858
  Assert(!lit.isNull());
182
321858
  bool pol = lit.getKind() != NOT;
183
643716
  TNode atom = pol ? lit : lit[0];
184
  // no double negation or conjunctive conclusions
185
321858
  Assert(atom.getKind() != NOT && atom.getKind() != AND);
186
  // assert the internal fact
187
321858
  assertInternalFact(atom, pol, fact->getId(), exp, pg);
188
321858
}
189
190
1315685
void InferenceManagerBuffered::notifyInConflict()
191
{
192
1315685
  d_theoryState.notifyInConflict();
193
  // also clear the pending facts, which will be stale after backtracking
194
1315685
  clearPending();
195
1315685
}
196
197
}  // namespace theory
198
29337
}  // namespace cvc5