GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/datatypes/inference_manager.cpp Lines: 49 65 75.4 %
Date: 2021-09-29 Branches: 100 244 41.0 %

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
6271
InferenceManager::InferenceManager(Env& env,
34
                                   Theory& t,
35
                                   TheoryState& state,
36
6271
                                   ProofNodeManager* pnm)
37
    : InferenceManagerBuffered(env, t, state, pnm, "theory::datatypes::"),
38
      d_pnm(pnm),
39
60
      d_ipc(pnm == nullptr ? nullptr : new InferProofCons(context(), pnm)),
40
      d_lemPg(pnm == nullptr ? nullptr
41
                             : new EagerProofGenerator(
42
6331
                                 pnm, userContext(), "datatypes::lemPg"))
43
{
44
6271
  d_false = NodeManager::currentNM()->mkConst(false);
45
6271
}
46
47
6268
InferenceManager::~InferenceManager()
48
{
49
6268
}
50
51
261140
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
261140
  if (forceLemma || DatatypesInference::mustCommunicateFact(conc, exp))
60
  {
61
2769
    d_pendingLem.emplace_back(new DatatypesInference(this, conc, exp, id));
62
  }
63
  else
64
  {
65
258371
    d_pendingFact.emplace_back(new DatatypesInference(this, conc, exp, id));
66
  }
67
261140
}
68
69
2914198
void InferenceManager::process()
70
{
71
  // if we are in conflict, immediately reset and clear pending
72
2914198
  if (d_theoryState.isInConflict())
73
  {
74
11112
    reset();
75
11112
    clearPending();
76
11112
    return;
77
  }
78
  // process pending lemmas, used infrequently, only for definitional lemmas
79
2903086
  doPendingLemmas();
80
  // now process the pending facts
81
2903086
  doPendingFacts();
82
}
83
84
1051
void InferenceManager::sendDtLemma(Node lem, InferenceId id, LemmaProperty p)
85
{
86
1051
  if (isProofEnabled())
87
  {
88
    TrustNode trn = processDtLemma(lem, Node::null(), id);
89
    trustedLemma(trn, id);
90
    return;
91
  }
92
  // otherwise send as a normal lemma directly
93
1051
  lemma(lem, id, p);
94
}
95
96
2139
void InferenceManager::sendDtConflict(const std::vector<Node>& conf, InferenceId id)
97
{
98
2139
  if (isProofEnabled())
99
  {
100
    Node exp = NodeManager::currentNM()->mkAnd(conf);
101
    prepareDtInference(d_false, exp, id, d_ipc.get());
102
  }
103
2139
  conflictExp(id, conf, d_ipc.get());
104
2139
}
105
106
267822
bool InferenceManager::isProofEnabled() const { return d_ipc != nullptr; }
107
108
2703
TrustNode InferenceManager::processDtLemma(Node conc, Node exp, InferenceId id)
109
{
110
  // set up a proof constructor
111
5406
  std::shared_ptr<InferProofCons> ipcl;
112
2703
  if (isProofEnabled())
113
  {
114
    ipcl = std::make_shared<InferProofCons>(nullptr, d_pnm);
115
  }
116
2703
  conc = prepareDtInference(conc, exp, id, ipcl.get());
117
  // send it as a lemma
118
5406
  Node lem;
119
2703
  if (!exp.isNull() && !exp.isConst())
120
  {
121
2428
    lem = NodeManager::currentNM()->mkNode(kind::IMPLIES, exp, conc);
122
  }
123
  else
124
  {
125
275
    lem = conc;
126
  }
127
2703
  if (isProofEnabled())
128
  {
129
    // store its proof
130
    std::shared_ptr<ProofNode> pbody = ipcl->getProofFor(conc);
131
    std::shared_ptr<ProofNode> pn = pbody;
132
    if (!exp.isNull() && !exp.isConst())
133
    {
134
      std::vector<Node> expv;
135
      expv.push_back(exp);
136
      pn = d_pnm->mkScope(pbody, expv);
137
    }
138
    d_lemPg->setProofFor(lem, pn);
139
  }
140
5406
  return TrustNode::mkTrustLemma(lem, d_lemPg.get());
141
}
142
143
256523
Node InferenceManager::processDtFact(Node conc,
144
                                     Node exp,
145
                                     InferenceId id,
146
                                     ProofGenerator*& pg)
147
{
148
256523
  pg = d_ipc.get();
149
256523
  return prepareDtInference(conc, exp, id, d_ipc.get());
150
}
151
152
259226
Node InferenceManager::prepareDtInference(Node conc,
153
                                          Node exp,
154
                                          InferenceId id,
155
                                          InferProofCons* ipc)
156
{
157
518452
  Trace("dt-lemma-debug") << "prepareDtInference : " << conc << " via " << exp
158
259226
                          << " by " << id << std::endl;
159
259226
  if (conc.getKind() == EQUAL && conc[0].getType().isBoolean())
160
  {
161
    // must turn (= conc false) into (not conc)
162
307
    conc = Rewriter::rewrite(conc);
163
  }
164
259226
  if (isProofEnabled())
165
  {
166
    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
        std::make_shared<DatatypesInference>(this, conc, exp, id);
174
    ipc->notifyFact(di);
175
  }
176
259226
  return conc;
177
}
178
179
}  // namespace datatypes
180
}  // namespace theory
181
22746
}  // namespace cvc5