1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Haniel Barbosa, 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 |
|
* [[ Add one-line brief description here ]] |
14 |
|
* |
15 |
|
* [[ Add lengthier description here ]] |
16 |
|
* \todo document this file |
17 |
|
*/ |
18 |
|
#include "prop/theory_proxy.h" |
19 |
|
|
20 |
|
#include "context/context.h" |
21 |
|
#include "decision/decision_engine.h" |
22 |
|
#include "options/decision_options.h" |
23 |
|
#include "options/smt_options.h" |
24 |
|
#include "prop/cnf_stream.h" |
25 |
|
#include "prop/prop_engine.h" |
26 |
|
#include "prop/skolem_def_manager.h" |
27 |
|
#include "smt/smt_statistics_registry.h" |
28 |
|
#include "theory/rewriter.h" |
29 |
|
#include "theory/theory_engine.h" |
30 |
|
#include "util/statistics_stats.h" |
31 |
|
|
32 |
|
namespace cvc5 { |
33 |
|
namespace prop { |
34 |
|
|
35 |
9908 |
TheoryProxy::TheoryProxy(PropEngine* propEngine, |
36 |
|
TheoryEngine* theoryEngine, |
37 |
|
decision::DecisionEngine* decisionEngine, |
38 |
|
SkolemDefManager* skdm, |
39 |
|
context::Context* context, |
40 |
|
context::UserContext* userContext, |
41 |
9908 |
ProofNodeManager* pnm) |
42 |
|
: d_propEngine(propEngine), |
43 |
|
d_cnfStream(nullptr), |
44 |
|
d_decisionEngine(decisionEngine), |
45 |
|
d_theoryEngine(theoryEngine), |
46 |
|
d_queue(context), |
47 |
|
d_tpp(*theoryEngine, userContext, pnm), |
48 |
9908 |
d_skdm(skdm) |
49 |
|
{ |
50 |
9908 |
} |
51 |
|
|
52 |
19816 |
TheoryProxy::~TheoryProxy() { |
53 |
|
/* nothing to do for now */ |
54 |
19816 |
} |
55 |
|
|
56 |
9908 |
void TheoryProxy::finishInit(CnfStream* cnfStream) { d_cnfStream = cnfStream; } |
57 |
|
|
58 |
465359 |
void TheoryProxy::notifyAssertion(Node a, TNode skolem) |
59 |
|
{ |
60 |
465359 |
if (skolem.isNull()) |
61 |
|
{ |
62 |
435461 |
d_decisionEngine->addAssertion(a); |
63 |
|
} |
64 |
|
else |
65 |
|
{ |
66 |
29898 |
d_skdm->notifySkolemDefinition(skolem, a); |
67 |
29898 |
d_decisionEngine->addSkolemDefinition(a, skolem); |
68 |
|
} |
69 |
465359 |
} |
70 |
|
|
71 |
431472 |
void TheoryProxy::variableNotify(SatVariable var) { |
72 |
431472 |
d_theoryEngine->preRegister(getNode(SatLiteral(var))); |
73 |
431472 |
} |
74 |
|
|
75 |
15553885 |
void TheoryProxy::theoryCheck(theory::Theory::Effort effort) { |
76 |
27126451 |
while (!d_queue.empty()) { |
77 |
23145132 |
TNode assertion = d_queue.front(); |
78 |
11572566 |
d_queue.pop(); |
79 |
11572566 |
d_theoryEngine->assertFact(assertion); |
80 |
11572566 |
d_decisionEngine->notifyAsserted(assertion); |
81 |
|
} |
82 |
3981319 |
d_theoryEngine->check(effort); |
83 |
3981305 |
} |
84 |
|
|
85 |
3981305 |
void TheoryProxy::theoryPropagate(std::vector<SatLiteral>& output) { |
86 |
|
// Get the propagated literals |
87 |
7962610 |
std::vector<TNode> outputNodes; |
88 |
3981305 |
d_theoryEngine->getPropagatedLiterals(outputNodes); |
89 |
10245905 |
for (unsigned i = 0, i_end = outputNodes.size(); i < i_end; ++ i) { |
90 |
6264600 |
Debug("prop-explain") << "theoryPropagate() => " << outputNodes[i] << std::endl; |
91 |
6264600 |
output.push_back(d_cnfStream->getLiteral(outputNodes[i])); |
92 |
|
} |
93 |
3981305 |
} |
94 |
|
|
95 |
109993 |
void TheoryProxy::explainPropagation(SatLiteral l, SatClause& explanation) { |
96 |
219986 |
TNode lNode = d_cnfStream->getNode(l); |
97 |
109993 |
Debug("prop-explain") << "explainPropagation(" << lNode << ")" << std::endl; |
98 |
|
|
99 |
219986 |
TrustNode tte = d_theoryEngine->getExplanation(lNode); |
100 |
219986 |
Node theoryExplanation = tte.getNode(); |
101 |
219986 |
if (options::produceProofs() |
102 |
109993 |
&& options::unsatCoresMode() != options::UnsatCoresMode::ASSUMPTIONS) |
103 |
|
{ |
104 |
18235 |
Assert(options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF |
105 |
|
|| tte.getGenerator()); |
106 |
18235 |
d_propEngine->getProofCnfStream()->convertPropagation(tte); |
107 |
|
} |
108 |
219986 |
Debug("prop-explain") << "explainPropagation() => " << theoryExplanation |
109 |
109993 |
<< std::endl; |
110 |
109993 |
explanation.push_back(l); |
111 |
109993 |
if (theoryExplanation.getKind() == kind::AND) |
112 |
|
{ |
113 |
885613 |
for (const Node& n : theoryExplanation) |
114 |
|
{ |
115 |
780809 |
explanation.push_back(~d_cnfStream->getLiteral(n)); |
116 |
|
} |
117 |
|
} |
118 |
|
else |
119 |
|
{ |
120 |
5189 |
explanation.push_back(~d_cnfStream->getLiteral(theoryExplanation)); |
121 |
|
} |
122 |
109993 |
if (Trace.isOn("sat-proof")) |
123 |
|
{ |
124 |
|
std::stringstream ss; |
125 |
|
ss << "TheoryProxy::explainPropagation: clause for lit is "; |
126 |
|
for (unsigned i = 0, size = explanation.size(); i < size; ++i) |
127 |
|
{ |
128 |
|
ss << explanation[i] << " [" << d_cnfStream->getNode(explanation[i]) |
129 |
|
<< "] "; |
130 |
|
} |
131 |
|
Trace("sat-proof") << ss.str() << "\n"; |
132 |
|
} |
133 |
109993 |
} |
134 |
|
|
135 |
16703481 |
void TheoryProxy::enqueueTheoryLiteral(const SatLiteral& l) { |
136 |
33406962 |
Node literalNode = d_cnfStream->getNode(l); |
137 |
16703481 |
Debug("prop") << "enqueueing theory literal " << l << " " << literalNode << std::endl; |
138 |
16703481 |
Assert(!literalNode.isNull()); |
139 |
16703481 |
d_queue.push(literalNode); |
140 |
16703481 |
} |
141 |
|
|
142 |
2688509 |
SatLiteral TheoryProxy::getNextTheoryDecisionRequest() { |
143 |
5377016 |
TNode n = d_theoryEngine->getNextDecisionRequest(); |
144 |
5377014 |
return n.isNull() ? undefSatLiteral : d_cnfStream->getLiteral(n); |
145 |
|
} |
146 |
|
|
147 |
2628152 |
SatLiteral TheoryProxy::getNextDecisionEngineRequest(bool &stopSearch) { |
148 |
2628152 |
Assert(d_decisionEngine != NULL); |
149 |
2628152 |
Assert(stopSearch != true); |
150 |
2628152 |
SatLiteral ret = d_decisionEngine->getNext(stopSearch); |
151 |
2628152 |
if(stopSearch) { |
152 |
50392 |
Trace("decision") << " *** Decision Engine stopped search *** " << std::endl; |
153 |
|
} |
154 |
2628152 |
return ret; |
155 |
|
} |
156 |
|
|
157 |
21485 |
bool TheoryProxy::theoryNeedCheck() const { |
158 |
21485 |
return d_theoryEngine->needCheck(); |
159 |
|
} |
160 |
|
|
161 |
431472 |
TNode TheoryProxy::getNode(SatLiteral lit) { |
162 |
431472 |
return d_cnfStream->getNode(lit); |
163 |
|
} |
164 |
|
|
165 |
2738 |
void TheoryProxy::notifyRestart() { |
166 |
2738 |
d_propEngine->spendResource(Resource::RestartStep); |
167 |
2738 |
d_theoryEngine->notifyRestart(); |
168 |
2738 |
} |
169 |
|
|
170 |
3276071 |
void TheoryProxy::spendResource(Resource r) |
171 |
|
{ |
172 |
3276071 |
d_theoryEngine->spendResource(r); |
173 |
3276071 |
} |
174 |
|
|
175 |
4628417 |
bool TheoryProxy::isDecisionRelevant(SatVariable var) { return true; } |
176 |
|
|
177 |
64183 |
bool TheoryProxy::isDecisionEngineDone() { |
178 |
64183 |
return d_decisionEngine->isDone(); |
179 |
|
} |
180 |
|
|
181 |
1428725 |
SatValue TheoryProxy::getDecisionPolarity(SatVariable var) { |
182 |
1428725 |
return SAT_VALUE_UNKNOWN; |
183 |
|
} |
184 |
|
|
185 |
1249 |
CnfStream* TheoryProxy::getCnfStream() { return d_cnfStream; } |
186 |
|
|
187 |
445043 |
TrustNode TheoryProxy::preprocessLemma(TrustNode trn, |
188 |
|
std::vector<TrustNode>& newLemmas, |
189 |
|
std::vector<Node>& newSkolems) |
190 |
|
{ |
191 |
445043 |
return d_tpp.preprocessLemma(trn, newLemmas, newSkolems); |
192 |
|
} |
193 |
|
|
194 |
303342 |
TrustNode TheoryProxy::preprocess(TNode node, |
195 |
|
std::vector<TrustNode>& newLemmas, |
196 |
|
std::vector<Node>& newSkolems) |
197 |
|
{ |
198 |
303342 |
return d_tpp.preprocess(node, newLemmas, newSkolems); |
199 |
|
} |
200 |
|
|
201 |
4 |
TrustNode TheoryProxy::removeItes(TNode node, |
202 |
|
std::vector<TrustNode>& newLemmas, |
203 |
|
std::vector<Node>& newSkolems) |
204 |
|
{ |
205 |
4 |
RemoveTermFormulas& rtf = d_tpp.getRemoveTermFormulas(); |
206 |
4 |
return rtf.run(node, newLemmas, newSkolems, true); |
207 |
|
} |
208 |
|
|
209 |
2734 |
void TheoryProxy::getSkolems(TNode node, |
210 |
|
std::vector<Node>& skAsserts, |
211 |
|
std::vector<Node>& sks) |
212 |
|
{ |
213 |
5468 |
std::unordered_set<Node> skolems; |
214 |
2734 |
d_skdm->getSkolems(node, skolems); |
215 |
5142 |
for (const Node& k : skolems) |
216 |
|
{ |
217 |
2408 |
sks.push_back(k); |
218 |
2408 |
skAsserts.push_back(d_skdm->getDefinitionForSkolem(k)); |
219 |
|
} |
220 |
2734 |
} |
221 |
|
|
222 |
612621 |
void TheoryProxy::preRegister(Node n) { d_theoryEngine->preRegister(n); } |
223 |
|
|
224 |
|
} // namespace prop |
225 |
29286 |
} // namespace cvc5 |