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 |
106911 |
InferenceManagerBuffered::InferenceManagerBuffered(Env& env, |
28 |
|
Theory& t, |
29 |
|
TheoryState& state, |
30 |
|
const std::string& statsName, |
31 |
106911 |
bool cacheLemmas) |
32 |
|
: TheoryInferenceManager(env, t, state, statsName, cacheLemmas), |
33 |
106911 |
d_processingPendingLemmas(false) |
34 |
|
{ |
35 |
106911 |
} |
36 |
|
|
37 |
3969467 |
bool InferenceManagerBuffered::hasPending() const |
38 |
|
{ |
39 |
3969467 |
return hasPendingFact() || hasPendingLemma(); |
40 |
|
} |
41 |
|
|
42 |
4802451 |
bool InferenceManagerBuffered::hasPendingFact() const |
43 |
|
{ |
44 |
4802451 |
return !d_pendingFact.empty(); |
45 |
|
} |
46 |
|
|
47 |
4930050 |
bool InferenceManagerBuffered::hasPendingLemma() const |
48 |
|
{ |
49 |
4930050 |
return !d_pendingLem.empty(); |
50 |
|
} |
51 |
|
|
52 |
160243 |
bool InferenceManagerBuffered::addPendingLemma(Node lem, |
53 |
|
InferenceId id, |
54 |
|
LemmaProperty p, |
55 |
|
ProofGenerator* pg, |
56 |
|
bool checkCache) |
57 |
|
{ |
58 |
160243 |
if (checkCache) |
59 |
|
{ |
60 |
|
// check if it is unique up to rewriting |
61 |
264224 |
Node lemr = rewrite(lem); |
62 |
160243 |
if (hasCachedLemma(lemr, p)) |
63 |
|
{ |
64 |
56262 |
return false; |
65 |
|
} |
66 |
|
} |
67 |
|
// make the simple theory lemma |
68 |
103981 |
d_pendingLem.emplace_back(new SimpleTheoryLemma(id, lem, p, pg)); |
69 |
103981 |
return true; |
70 |
|
} |
71 |
|
|
72 |
25793 |
void InferenceManagerBuffered::addPendingLemma( |
73 |
|
std::unique_ptr<TheoryInference> lemma) |
74 |
|
{ |
75 |
25793 |
d_pendingLem.emplace_back(std::move(lemma)); |
76 |
25793 |
} |
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 |
38199 |
void InferenceManagerBuffered::addPendingFact( |
89 |
|
std::unique_ptr<TheoryInference> fact) |
90 |
|
{ |
91 |
38199 |
d_pendingFact.emplace_back(std::move(fact)); |
92 |
38199 |
} |
93 |
|
|
94 |
4850 |
void InferenceManagerBuffered::addPendingPhaseRequirement(Node lit, bool pol) |
95 |
|
{ |
96 |
|
// it is the responsibility of the caller to ensure lit is rewritten |
97 |
4850 |
d_pendingReqPhase[lit] = pol; |
98 |
4850 |
} |
99 |
|
|
100 |
6595487 |
void InferenceManagerBuffered::doPendingFacts() |
101 |
|
{ |
102 |
6595487 |
size_t i = 0; |
103 |
7702405 |
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 |
553459 |
assertInternalFactTheoryInference(d_pendingFact[i].get()); |
108 |
553459 |
i++; |
109 |
|
} |
110 |
6595487 |
d_pendingFact.clear(); |
111 |
6595487 |
} |
112 |
|
|
113 |
6459472 |
void InferenceManagerBuffered::doPendingLemmas() |
114 |
|
{ |
115 |
6459472 |
if (d_processingPendingLemmas) |
116 |
|
{ |
117 |
|
// already processing |
118 |
12715 |
return; |
119 |
|
} |
120 |
6446757 |
d_processingPendingLemmas = true; |
121 |
6446757 |
size_t i = 0; |
122 |
6765027 |
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 |
159136 |
lemmaTheoryInference(d_pendingLem[i].get()); |
127 |
159135 |
i++; |
128 |
|
} |
129 |
6446756 |
d_pendingLem.clear(); |
130 |
6446756 |
d_processingPendingLemmas = false; |
131 |
|
} |
132 |
|
|
133 |
275523 |
void InferenceManagerBuffered::doPendingPhaseRequirements() |
134 |
|
{ |
135 |
|
// process the pending require phase calls |
136 |
280372 |
for (const std::pair<const Node, bool>& prp : d_pendingReqPhase) |
137 |
|
{ |
138 |
4849 |
requirePhase(prp.first, prp.second); |
139 |
|
} |
140 |
275523 |
d_pendingReqPhase.clear(); |
141 |
275523 |
} |
142 |
1586076 |
void InferenceManagerBuffered::clearPending() |
143 |
|
{ |
144 |
1586076 |
d_pendingFact.clear(); |
145 |
1586076 |
d_pendingLem.clear(); |
146 |
1586076 |
d_pendingReqPhase.clear(); |
147 |
1586076 |
} |
148 |
1690 |
void InferenceManagerBuffered::clearPendingFacts() { d_pendingFact.clear(); } |
149 |
26925 |
void InferenceManagerBuffered::clearPendingLemmas() { d_pendingLem.clear(); } |
150 |
2824 |
void InferenceManagerBuffered::clearPendingPhaseRequirements() |
151 |
|
{ |
152 |
2824 |
d_pendingReqPhase.clear(); |
153 |
2824 |
} |
154 |
|
|
155 |
359115 |
std::size_t InferenceManagerBuffered::numPendingLemmas() const |
156 |
|
{ |
157 |
359115 |
return d_pendingLem.size(); |
158 |
|
} |
159 |
|
std::size_t InferenceManagerBuffered::numPendingFacts() const |
160 |
|
{ |
161 |
|
return d_pendingFact.size(); |
162 |
|
} |
163 |
|
|
164 |
163673 |
void InferenceManagerBuffered::lemmaTheoryInference(TheoryInference* lem) |
165 |
|
{ |
166 |
|
// process this lemma |
167 |
163673 |
LemmaProperty p = LemmaProperty::NONE; |
168 |
327346 |
TrustNode tlem = lem->processLemma(p); |
169 |
163673 |
Assert(!tlem.isNull()); |
170 |
|
// send the lemma |
171 |
163673 |
trustedLemma(tlem, lem->getId(), p); |
172 |
163672 |
} |
173 |
|
|
174 |
553459 |
void InferenceManagerBuffered::assertInternalFactTheoryInference( |
175 |
|
TheoryInference* fact) |
176 |
|
{ |
177 |
|
// process this fact |
178 |
1106918 |
std::vector<Node> exp; |
179 |
553459 |
ProofGenerator* pg = nullptr; |
180 |
1106918 |
Node lit = fact->processFact(exp, pg); |
181 |
553459 |
Assert(!lit.isNull()); |
182 |
553459 |
bool pol = lit.getKind() != NOT; |
183 |
1106918 |
TNode atom = pol ? lit : lit[0]; |
184 |
|
// no double negation or conjunctive conclusions |
185 |
553459 |
Assert(atom.getKind() != NOT && atom.getKind() != AND); |
186 |
|
// assert the internal fact |
187 |
553459 |
assertInternalFact(atom, pol, fact->getId(), exp, pg); |
188 |
553459 |
} |
189 |
|
|
190 |
1553566 |
void InferenceManagerBuffered::notifyInConflict() |
191 |
|
{ |
192 |
1553566 |
d_theoryState.notifyInConflict(); |
193 |
|
// also clear the pending facts, which will be stale after backtracking |
194 |
1553566 |
clearPending(); |
195 |
1553566 |
} |
196 |
|
|
197 |
|
} // namespace theory |
198 |
31137 |
} // namespace cvc5 |