GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/datatypes/inference_manager.cpp Lines: 65 65 100.0 %
Date: 2021-08-14 Branches: 135 244 55.3 %

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
 * Datatypes inference manager.
14
 */
15
16
#include "theory/datatypes/inference_manager.h"
17
18
#include "expr/dtype.h"
19
#include "options/datatypes_options.h"
20
#include "proof/eager_proof_generator.h"
21
#include "smt/smt_statistics_registry.h"
22
#include "theory/rewriter.h"
23
#include "theory/theory.h"
24
#include "theory/theory_state.h"
25
#include "theory/trust_substitutions.h"
26
27
using namespace cvc5::kind;
28
29
namespace cvc5 {
30
namespace theory {
31
namespace datatypes {
32
33
9853
InferenceManager::InferenceManager(Theory& t,
34
                                   TheoryState& state,
35
9853
                                   ProofNodeManager* pnm)
36
    : InferenceManagerBuffered(t, state, pnm, "theory::datatypes::"),
37
      d_pnm(pnm),
38
      d_ipc(pnm == nullptr ? nullptr
39
1245
                           : new InferProofCons(state.getSatContext(), pnm)),
40
      d_lemPg(pnm == nullptr
41
                  ? nullptr
42
                  : new EagerProofGenerator(
43
11098
                      pnm, state.getUserContext(), "datatypes::lemPg"))
44
{
45
9853
  d_false = NodeManager::currentNM()->mkConst(false);
46
9853
}
47
48
9853
InferenceManager::~InferenceManager()
49
{
50
9853
}
51
52
320049
void InferenceManager::addPendingInference(Node conc,
53
                                           InferenceId id,
54
                                           Node exp,
55
                                           bool forceLemma)
56
{
57
  // if we are forcing the inference to be processed as a lemma, or if the
58
  // inference must be sent as a lemma based on the policy in
59
  // mustCommunicateFact.
60
320049
  if (forceLemma || DatatypesInference::mustCommunicateFact(conc, exp))
61
  {
62
25339
    d_pendingLem.emplace_back(new DatatypesInference(this, conc, exp, id));
63
  }
64
  else
65
  {
66
294710
    d_pendingFact.emplace_back(new DatatypesInference(this, conc, exp, id));
67
  }
68
320049
}
69
70
2714197
void InferenceManager::process()
71
{
72
  // if we are in conflict, immediately reset and clear pending
73
2714197
  if (d_theoryState.isInConflict())
74
  {
75
11589
    reset();
76
11589
    clearPending();
77
11589
    return;
78
  }
79
  // process pending lemmas, used infrequently, only for definitional lemmas
80
2702608
  doPendingLemmas();
81
  // now process the pending facts
82
2702608
  doPendingFacts();
83
}
84
85
1293
void InferenceManager::sendDtLemma(Node lem, InferenceId id, LemmaProperty p)
86
{
87
1293
  if (isProofEnabled())
88
  {
89
190
    TrustNode trn = processDtLemma(lem, Node::null(), id);
90
95
    trustedLemma(trn, id);
91
95
    return;
92
  }
93
  // otherwise send as a normal lemma directly
94
1198
  lemma(lem, id, p);
95
}
96
97
2562
void InferenceManager::sendDtConflict(const std::vector<Node>& conf, InferenceId id)
98
{
99
2562
  if (isProofEnabled())
100
  {
101
444
    Node exp = NodeManager::currentNM()->mkAnd(conf);
102
222
    prepareDtInference(d_false, exp, id, d_ipc.get());
103
  }
104
2562
  conflictExp(id, conf, d_ipc.get());
105
2562
}
106
107
369721
bool InferenceManager::isProofEnabled() const { return d_ipc != nullptr; }
108
109
24948
TrustNode InferenceManager::processDtLemma(Node conc, Node exp, InferenceId id)
110
{
111
  // set up a proof constructor
112
49896
  std::shared_ptr<InferProofCons> ipcl;
113
24948
  if (isProofEnabled())
114
  {
115
1206
    ipcl = std::make_shared<InferProofCons>(nullptr, d_pnm);
116
  }
117
24948
  conc = prepareDtInference(conc, exp, id, ipcl.get());
118
  // send it as a lemma
119
49896
  Node lem;
120
24948
  if (!exp.isNull() && !exp.isConst())
121
  {
122
24094
    lem = NodeManager::currentNM()->mkNode(kind::IMPLIES, exp, conc);
123
  }
124
  else
125
  {
126
854
    lem = conc;
127
  }
128
24948
  if (isProofEnabled())
129
  {
130
    // store its proof
131
2412
    std::shared_ptr<ProofNode> pbody = ipcl->getProofFor(conc);
132
2412
    std::shared_ptr<ProofNode> pn = pbody;
133
1206
    if (!exp.isNull() && !exp.isConst())
134
    {
135
1910
      std::vector<Node> expv;
136
955
      expv.push_back(exp);
137
955
      pn = d_pnm->mkScope(pbody, expv);
138
    }
139
1206
    d_lemPg->setProofFor(lem, pn);
140
  }
141
49896
  return TrustNode::mkTrustLemma(lem, d_lemPg.get());
142
}
143
144
290800
Node InferenceManager::processDtFact(Node conc,
145
                                     Node exp,
146
                                     InferenceId id,
147
                                     ProofGenerator*& pg)
148
{
149
290800
  pg = d_ipc.get();
150
290800
  return prepareDtInference(conc, exp, id, d_ipc.get());
151
}
152
153
315970
Node InferenceManager::prepareDtInference(Node conc,
154
                                          Node exp,
155
                                          InferenceId id,
156
                                          InferProofCons* ipc)
157
{
158
631940
  Trace("dt-lemma-debug") << "prepareDtInference : " << conc << " via " << exp
159
315970
                          << " by " << id << std::endl;
160
315970
  if (conc.getKind() == EQUAL && conc[0].getType().isBoolean())
161
  {
162
    // must turn (= conc false) into (not conc)
163
630
    conc = Rewriter::rewrite(conc);
164
  }
165
315970
  if (isProofEnabled())
166
  {
167
13870
    Assert(ipc != nullptr);
168
    // If proofs are enabled, notify the proof constructor.
169
    // Notice that we have to reconstruct a datatypes inference here. This is
170
    // because the inference in the pending vector may be destroyed as we are
171
    // processing this inference, if we triggered to backtrack based on the
172
    // call below, since it is a unique pointer.
173
    std::shared_ptr<DatatypesInference> di =
174
27740
        std::make_shared<DatatypesInference>(this, conc, exp, id);
175
13870
    ipc->notifyFact(di);
176
  }
177
315970
  return conc;
178
}
179
180
}  // namespace datatypes
181
}  // namespace theory
182
29340
}  // namespace cvc5