GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/prop/theory_proxy.cpp Lines: 108 114 94.7 %
Date: 2021-11-07 Branches: 140 338 41.4 %

Line Exec Source
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/env.h"
28
#include "smt/smt_statistics_registry.h"
29
#include "theory/rewriter.h"
30
#include "theory/theory_engine.h"
31
#include "util/statistics_stats.h"
32
33
namespace cvc5 {
34
namespace prop {
35
36
15340
TheoryProxy::TheoryProxy(PropEngine* propEngine,
37
                         TheoryEngine* theoryEngine,
38
                         decision::DecisionEngine* decisionEngine,
39
                         SkolemDefManager* skdm,
40
15340
                         Env& env)
41
    : d_propEngine(propEngine),
42
      d_cnfStream(nullptr),
43
      d_decisionEngine(decisionEngine),
44
15340
      d_dmNeedsActiveDefs(d_decisionEngine->needsActiveSkolemDefs()),
45
      d_theoryEngine(theoryEngine),
46
      d_queue(env.getContext()),
47
      d_tpp(env, *theoryEngine),
48
      d_skdm(skdm),
49
30680
      d_env(env)
50
{
51
15340
}
52
53
30670
TheoryProxy::~TheoryProxy() {
54
  /* nothing to do for now */
55
30670
}
56
57
15340
void TheoryProxy::finishInit(CnfStream* cnfStream) { d_cnfStream = cnfStream; }
58
59
20560
void TheoryProxy::presolve()
60
{
61
20560
  d_decisionEngine->presolve();
62
20560
  d_theoryEngine->presolve();
63
20560
}
64
65
512165
void TheoryProxy::notifyAssertion(Node a, TNode skolem, bool isLemma)
66
{
67
512165
  if (skolem.isNull())
68
  {
69
482409
    d_decisionEngine->addAssertion(a, isLemma);
70
  }
71
  else
72
  {
73
29756
    d_skdm->notifySkolemDefinition(skolem, a);
74
29756
    d_decisionEngine->addSkolemDefinition(a, skolem, isLemma);
75
  }
76
512165
}
77
78
513795
void TheoryProxy::variableNotify(SatVariable var) {
79
513795
  d_theoryEngine->preRegister(getNode(SatLiteral(var)));
80
513795
}
81
82
21077427
void TheoryProxy::theoryCheck(theory::Theory::Effort effort) {
83
36926729
  while (!d_queue.empty()) {
84
31698604
    TNode assertion = d_queue.front();
85
15849302
    d_queue.pop();
86
    // now, assert to theory engine
87
15849302
    d_theoryEngine->assertFact(assertion);
88
15849302
    if (d_dmNeedsActiveDefs)
89
    {
90
7431374
      Assert(d_skdm != nullptr);
91
14862748
      Trace("sat-rlv-assert")
92
7431374
          << "Assert to theory engine: " << assertion << std::endl;
93
      // Assertion makes all skolems in assertion active,
94
      // which triggers their definitions to becoming active.
95
14862748
      std::vector<TNode> activeSkolemDefs;
96
7431374
      d_skdm->notifyAsserted(assertion, activeSkolemDefs, true);
97
      // notify the decision engine of the skolem definitions that have become
98
      // active due to the assertion.
99
7431374
      d_decisionEngine->notifyActiveSkolemDefs(activeSkolemDefs);
100
    }
101
  }
102
5228125
  d_theoryEngine->check(effort);
103
5228106
}
104
105
5228106
void TheoryProxy::theoryPropagate(std::vector<SatLiteral>& output) {
106
  // Get the propagated literals
107
10456212
  std::vector<TNode> outputNodes;
108
5228106
  d_theoryEngine->getPropagatedLiterals(outputNodes);
109
15203624
  for (unsigned i = 0, i_end = outputNodes.size(); i < i_end; ++ i) {
110
9975518
    Debug("prop-explain") << "theoryPropagate() => " << outputNodes[i] << std::endl;
111
9975518
    output.push_back(d_cnfStream->getLiteral(outputNodes[i]));
112
  }
113
5228106
}
114
115
120613
void TheoryProxy::explainPropagation(SatLiteral l, SatClause& explanation) {
116
241226
  TNode lNode = d_cnfStream->getNode(l);
117
120613
  Debug("prop-explain") << "explainPropagation(" << lNode << ")" << std::endl;
118
119
241226
  TrustNode tte = d_theoryEngine->getExplanation(lNode);
120
241226
  Node theoryExplanation = tte.getNode();
121
120613
  if (d_env.isSatProofProducing())
122
  {
123
15234
    Assert(options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF
124
           || tte.getGenerator());
125
15234
    d_propEngine->getProofCnfStream()->convertPropagation(tte);
126
  }
127
241226
  Debug("prop-explain") << "explainPropagation() => " << theoryExplanation
128
120613
                        << std::endl;
129
120613
  explanation.push_back(l);
130
120613
  if (theoryExplanation.getKind() == kind::AND)
131
  {
132
897047
    for (const Node& n : theoryExplanation)
133
    {
134
783189
      explanation.push_back(~d_cnfStream->getLiteral(n));
135
    }
136
  }
137
  else
138
  {
139
6755
    explanation.push_back(~d_cnfStream->getLiteral(theoryExplanation));
140
  }
141
120613
  if (Trace.isOn("sat-proof"))
142
  {
143
    std::stringstream ss;
144
    ss << "TheoryProxy::explainPropagation: clause for lit is ";
145
    for (unsigned i = 0, size = explanation.size(); i < size; ++i)
146
    {
147
      ss << explanation[i] << " [" << d_cnfStream->getNode(explanation[i])
148
         << "] ";
149
    }
150
    Trace("sat-proof") << ss.str() << "\n";
151
  }
152
120613
}
153
154
21139295
void TheoryProxy::enqueueTheoryLiteral(const SatLiteral& l) {
155
42278590
  Node literalNode = d_cnfStream->getNode(l);
156
21139295
  Debug("prop") << "enqueueing theory literal " << l << " " << literalNode << std::endl;
157
21139295
  Assert(!literalNode.isNull());
158
21139295
  d_queue.push(literalNode);
159
21139295
}
160
161
3530070
SatLiteral TheoryProxy::getNextTheoryDecisionRequest() {
162
7060136
  TNode n = d_theoryEngine->getNextDecisionRequest();
163
7060132
  return n.isNull() ? undefSatLiteral : d_cnfStream->getLiteral(n);
164
}
165
166
3454001
SatLiteral TheoryProxy::getNextDecisionEngineRequest(bool &stopSearch) {
167
3454001
  Assert(d_decisionEngine != NULL);
168
3454001
  Assert(stopSearch != true);
169
3454001
  SatLiteral ret = d_decisionEngine->getNext(stopSearch);
170
3454001
  if(stopSearch) {
171
57002
    Trace("decision") << "  ***  Decision Engine stopped search *** " << std::endl;
172
  }
173
3454001
  return ret;
174
}
175
176
19102
bool TheoryProxy::theoryNeedCheck() const {
177
19102
  return d_theoryEngine->needCheck();
178
}
179
180
513795
TNode TheoryProxy::getNode(SatLiteral lit) {
181
513795
  return d_cnfStream->getNode(lit);
182
}
183
184
2701
void TheoryProxy::notifyRestart() {
185
2701
  d_propEngine->spendResource(Resource::RestartStep);
186
2701
  d_theoryEngine->notifyRestart();
187
2701
}
188
189
4169329
void TheoryProxy::spendResource(Resource r)
190
{
191
4169329
  d_theoryEngine->spendResource(r);
192
4169329
}
193
194
6790280
bool TheoryProxy::isDecisionRelevant(SatVariable var) { return true; }
195
196
73604
bool TheoryProxy::isDecisionEngineDone() {
197
73604
  return d_decisionEngine->isDone();
198
}
199
200
2076491
SatValue TheoryProxy::getDecisionPolarity(SatVariable var) {
201
2076491
  return SAT_VALUE_UNKNOWN;
202
}
203
204
5381
CnfStream* TheoryProxy::getCnfStream() { return d_cnfStream; }
205
206
518401
TrustNode TheoryProxy::preprocessLemma(
207
    TrustNode trn, std::vector<theory::SkolemLemma>& newLemmas)
208
{
209
518401
  return d_tpp.preprocessLemma(trn, newLemmas);
210
}
211
212
348820
TrustNode TheoryProxy::preprocess(TNode node,
213
                                  std::vector<theory::SkolemLemma>& newLemmas)
214
{
215
348820
  return d_tpp.preprocess(node, newLemmas);
216
}
217
218
2
TrustNode TheoryProxy::removeItes(TNode node,
219
                                  std::vector<theory::SkolemLemma>& newLemmas)
220
{
221
2
  RemoveTermFormulas& rtf = d_tpp.getRemoveTermFormulas();
222
2
  return rtf.run(node, newLemmas, true);
223
}
224
225
3677
void TheoryProxy::getSkolems(TNode node,
226
                             std::vector<Node>& skAsserts,
227
                             std::vector<Node>& sks)
228
{
229
7354
  std::unordered_set<Node> skolems;
230
3677
  d_skdm->getSkolems(node, skolems);
231
6200
  for (const Node& k : skolems)
232
  {
233
2523
    sks.push_back(k);
234
2523
    skAsserts.push_back(d_skdm->getDefinitionForSkolem(k));
235
  }
236
3677
}
237
238
705064
void TheoryProxy::preRegister(Node n) { d_theoryEngine->preRegister(n); }
239
240
}  // namespace prop
241
31137
}  // namespace cvc5