GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/datatypes/inference_manager.cpp Lines: 69 69 100.0 %
Date: 2021-11-05 Branches: 141 256 55.1 %

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
15271
InferenceManager::InferenceManager(Env& env, Theory& t, TheoryState& state)
34
    : InferenceManagerBuffered(env, t, state, "theory::datatypes::"),
35
15271
      d_ipc(isProofEnabled()
36
5372
                ? new InferProofCons(context(), env.getProofNodeManager())
37
                : nullptr),
38
15271
      d_lemPg(isProofEnabled()
39
5372
                  ? new EagerProofGenerator(env.getProofNodeManager(),
40
5372
                                            userContext(),
41
5372
                                            "datatypes::lemPg")
42
61929
                  : nullptr)
43
{
44
15271
  d_false = NodeManager::currentNM()->mkConst(false);
45
15271
}
46
47
15266
InferenceManager::~InferenceManager()
48
{
49
15266
}
50
51
534986
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
534986
  if (forceLemma || DatatypesInference::mustCommunicateFact(conc, exp))
60
  {
61
20163
    d_pendingLem.emplace_back(new DatatypesInference(this, conc, exp, id));
62
  }
63
  else
64
  {
65
514823
    d_pendingFact.emplace_back(new DatatypesInference(this, conc, exp, id));
66
  }
67
534986
}
68
69
6365517
void InferenceManager::process()
70
{
71
  // if we are in conflict, immediately reset and clear pending
72
6365517
  if (d_theoryState.isInConflict())
73
  {
74
18745
    reset();
75
18745
    clearPending();
76
18745
    return;
77
  }
78
  // process pending lemmas, used infrequently, only for definitional lemmas
79
6346772
  doPendingLemmas();
80
  // now process the pending facts
81
6346772
  doPendingFacts();
82
}
83
84
1709
void InferenceManager::sendDtLemma(Node lem, InferenceId id, LemmaProperty p)
85
{
86
1709
  if (isProofEnabled())
87
  {
88
164
    TrustNode trn = processDtLemma(lem, Node::null(), id);
89
82
    trustedLemma(trn, id);
90
82
    return;
91
  }
92
  // otherwise send as a normal lemma directly
93
1627
  lemma(lem, id, p);
94
}
95
96
4027
void InferenceManager::sendDtConflict(const std::vector<Node>& conf, InferenceId id)
97
{
98
4027
  if (isProofEnabled())
99
  {
100
378
    Node exp = NodeManager::currentNM()->mkAnd(conf);
101
189
    prepareDtInference(d_false, exp, id, d_ipc.get());
102
  }
103
4027
  conflictExp(id, conf, d_ipc.get());
104
4027
}
105
106
20110
TrustNode InferenceManager::processDtLemma(Node conc, Node exp, InferenceId id)
107
{
108
  // set up a proof constructor
109
40220
  std::shared_ptr<InferProofCons> ipcl;
110
20110
  if (isProofEnabled())
111
  {
112
1004
    ipcl =
113
2008
        std::make_shared<InferProofCons>(nullptr, d_env.getProofNodeManager());
114
  }
115
20110
  conc = prepareDtInference(conc, exp, id, ipcl.get());
116
  // send it as a lemma
117
40220
  Node lem;
118
20110
  if (!exp.isNull() && !exp.isConst())
119
  {
120
19317
    lem = NodeManager::currentNM()->mkNode(kind::IMPLIES, exp, conc);
121
  }
122
  else
123
  {
124
793
    lem = conc;
125
  }
126
20110
  if (isProofEnabled())
127
  {
128
    // store its proof
129
2008
    std::shared_ptr<ProofNode> pbody = ipcl->getProofFor(conc);
130
2008
    std::shared_ptr<ProofNode> pn = pbody;
131
1004
    if (!exp.isNull() && !exp.isConst())
132
    {
133
1584
      std::vector<Node> expv;
134
792
      expv.push_back(exp);
135
792
      pn = d_env.getProofNodeManager()->mkScope(pbody, expv);
136
    }
137
1004
    d_lemPg->setProofFor(lem, pn);
138
  }
139
40220
  return TrustNode::mkTrustLemma(lem, d_lemPg.get());
140
}
141
142
510691
Node InferenceManager::processDtFact(Node conc,
143
                                     Node exp,
144
                                     InferenceId id,
145
                                     ProofGenerator*& pg)
146
{
147
510691
  pg = d_ipc.get();
148
510691
  return prepareDtInference(conc, exp, id, d_ipc.get());
149
}
150
151
530990
Node InferenceManager::prepareDtInference(Node conc,
152
                                          Node exp,
153
                                          InferenceId id,
154
                                          InferProofCons* ipc)
155
{
156
1061980
  Trace("dt-lemma-debug") << "prepareDtInference : " << conc << " via " << exp
157
530990
                          << " by " << id << std::endl;
158
530990
  if (conc.getKind() == EQUAL && conc[0].getType().isBoolean())
159
  {
160
    // must turn (= conc false) into (not conc)
161
508
    conc = rewrite(conc);
162
  }
163
530990
  if (isProofEnabled())
164
  {
165
11847
    Assert(ipc != nullptr);
166
    // If proofs are enabled, notify the proof constructor.
167
    // Notice that we have to reconstruct a datatypes inference here. This is
168
    // because the inference in the pending vector may be destroyed as we are
169
    // processing this inference, if we triggered to backtrack based on the
170
    // call below, since it is a unique pointer.
171
    std::shared_ptr<DatatypesInference> di =
172
23694
        std::make_shared<DatatypesInference>(this, conc, exp, id);
173
11847
    ipc->notifyFact(di);
174
  }
175
530990
  return conc;
176
}
177
178
}  // namespace datatypes
179
}  // namespace theory
180
31125
}  // namespace cvc5