GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/datatypes/inference_manager.cpp Lines: 65 65 100.0 %
Date: 2021-09-16 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
9942
InferenceManager::InferenceManager(Env& env,
34
                                   Theory& t,
35
                                   TheoryState& state,
36
9942
                                   ProofNodeManager* pnm)
37
    : InferenceManagerBuffered(env, t, state, pnm, "theory::datatypes::"),
38
      d_pnm(pnm),
39
1243
      d_ipc(pnm == nullptr ? nullptr : new InferProofCons(context(), pnm)),
40
      d_lemPg(pnm == nullptr ? nullptr
41
                             : new EagerProofGenerator(
42
11185
                                 pnm, userContext(), "datatypes::lemPg"))
43
{
44
9942
  d_false = NodeManager::currentNM()->mkConst(false);
45
9942
}
46
47
9939
InferenceManager::~InferenceManager()
48
{
49
9939
}
50
51
348200
void InferenceManager::addPendingInference(Node conc,
52
                                           InferenceId id,
53
                                           Node exp,
54
                                           bool forceLemma)
55
{
56
  // if we are forcing the inference to be processed as a lemma, or if the
57
  // inference must be sent as a lemma based on the policy in
58
  // mustCommunicateFact.
59
348200
  if (forceLemma || DatatypesInference::mustCommunicateFact(conc, exp))
60
  {
61
18761
    d_pendingLem.emplace_back(new DatatypesInference(this, conc, exp, id));
62
  }
63
  else
64
  {
65
329439
    d_pendingFact.emplace_back(new DatatypesInference(this, conc, exp, id));
66
  }
67
348200
}
68
69
3379873
void InferenceManager::process()
70
{
71
  // if we are in conflict, immediately reset and clear pending
72
3379873
  if (d_theoryState.isInConflict())
73
  {
74
14549
    reset();
75
14549
    clearPending();
76
14549
    return;
77
  }
78
  // process pending lemmas, used infrequently, only for definitional lemmas
79
3365324
  doPendingLemmas();
80
  // now process the pending facts
81
3365324
  doPendingFacts();
82
}
83
84
1305
void InferenceManager::sendDtLemma(Node lem, InferenceId id, LemmaProperty p)
85
{
86
1305
  if (isProofEnabled())
87
  {
88
172
    TrustNode trn = processDtLemma(lem, Node::null(), id);
89
86
    trustedLemma(trn, id);
90
86
    return;
91
  }
92
  // otherwise send as a normal lemma directly
93
1219
  lemma(lem, id, p);
94
}
95
96
2948
void InferenceManager::sendDtConflict(const std::vector<Node>& conf, InferenceId id)
97
{
98
2948
  if (isProofEnabled())
99
  {
100
378
    Node exp = NodeManager::currentNM()->mkAnd(conf);
101
189
    prepareDtInference(d_false, exp, id, d_ipc.get());
102
  }
103
2948
  conflictExp(id, conf, d_ipc.get());
104
2948
}
105
106
386230
bool InferenceManager::isProofEnabled() const { return d_ipc != nullptr; }
107
108
18734
TrustNode InferenceManager::processDtLemma(Node conc, Node exp, InferenceId id)
109
{
110
  // set up a proof constructor
111
37468
  std::shared_ptr<InferProofCons> ipcl;
112
18734
  if (isProofEnabled())
113
  {
114
984
    ipcl = std::make_shared<InferProofCons>(nullptr, d_pnm);
115
  }
116
18734
  conc = prepareDtInference(conc, exp, id, ipcl.get());
117
  // send it as a lemma
118
37468
  Node lem;
119
18734
  if (!exp.isNull() && !exp.isConst())
120
  {
121
17975
    lem = NodeManager::currentNM()->mkNode(kind::IMPLIES, exp, conc);
122
  }
123
  else
124
  {
125
759
    lem = conc;
126
  }
127
18734
  if (isProofEnabled())
128
  {
129
    // store its proof
130
1968
    std::shared_ptr<ProofNode> pbody = ipcl->getProofFor(conc);
131
1968
    std::shared_ptr<ProofNode> pn = pbody;
132
984
    if (!exp.isNull() && !exp.isConst())
133
    {
134
1556
      std::vector<Node> expv;
135
778
      expv.push_back(exp);
136
778
      pn = d_pnm->mkScope(pbody, expv);
137
    }
138
984
    d_lemPg->setProofFor(lem, pn);
139
  }
140
37468
  return TrustNode::mkTrustLemma(lem, d_lemPg.get());
141
}
142
143
325586
Node InferenceManager::processDtFact(Node conc,
144
                                     Node exp,
145
                                     InferenceId id,
146
                                     ProofGenerator*& pg)
147
{
148
325586
  pg = d_ipc.get();
149
325586
  return prepareDtInference(conc, exp, id, d_ipc.get());
150
}
151
152
344509
Node InferenceManager::prepareDtInference(Node conc,
153
                                          Node exp,
154
                                          InferenceId id,
155
                                          InferProofCons* ipc)
156
{
157
689018
  Trace("dt-lemma-debug") << "prepareDtInference : " << conc << " via " << exp
158
344509
                          << " by " << id << std::endl;
159
344509
  if (conc.getKind() == EQUAL && conc[0].getType().isBoolean())
160
  {
161
    // must turn (= conc false) into (not conc)
162
508
    conc = Rewriter::rewrite(conc);
163
  }
164
344509
  if (isProofEnabled())
165
  {
166
11881
    Assert(ipc != nullptr);
167
    // If proofs are enabled, notify the proof constructor.
168
    // Notice that we have to reconstruct a datatypes inference here. This is
169
    // because the inference in the pending vector may be destroyed as we are
170
    // processing this inference, if we triggered to backtrack based on the
171
    // call below, since it is a unique pointer.
172
    std::shared_ptr<DatatypesInference> di =
173
23762
        std::make_shared<DatatypesInference>(this, conc, exp, id);
174
11881
    ipc->notifyFact(di);
175
  }
176
344509
  return conc;
177
}
178
179
}  // namespace datatypes
180
}  // namespace theory
181
29577
}  // namespace cvc5