GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/proof_manager.cpp Lines: 69 90 76.7 %
Date: 2021-08-01 Branches: 100 328 30.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Haniel Barbosa, Diego Della Rocca de Camargos
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
 * The proof manager of the SMT engine.
14
 */
15
16
#include "smt/proof_manager.h"
17
18
#include "options/base_options.h"
19
#include "options/proof_options.h"
20
#include "options/smt_options.h"
21
#include "proof/dot/dot_printer.h"
22
#include "proof/proof_checker.h"
23
#include "proof/proof_node_algorithm.h"
24
#include "proof/proof_node_manager.h"
25
#include "smt/assertions.h"
26
#include "smt/preprocess_proof_generator.h"
27
#include "smt/proof_post_processor.h"
28
29
namespace cvc5 {
30
namespace smt {
31
32
3756
PfManager::PfManager(context::UserContext* u, SmtEngine* smte)
33
7512
    : d_pchecker(new ProofChecker(options::proofPedantic())),
34
3756
      d_pnm(new ProofNodeManager(d_pchecker.get())),
35
      d_pppg(new PreprocessProofGenerator(
36
7512
          d_pnm.get(), u, "smt::PreprocessProofGenerator")),
37
      d_pfpp(new ProofPostproccess(
38
3756
          d_pnm.get(),
39
          smte,
40
3756
          d_pppg.get(),
41
          // by default the post-processor will update all assumptions, which
42
          // can lead to SCOPE subproofs of the form
43
          //   A
44
          //  ...
45
          //   B1    B2
46
          //  ...   ...
47
          // ------------
48
          //      C
49
          // ------------- SCOPE [B1, B2]
50
          // B1 ^ B2 => C
51
          //
52
          // where A is an available assumption from outside the scope (note
53
          // that B1 was an assumption of this SCOPE subproof but since it could
54
          // be inferred from A, it was updated). This shape is problematic for
55
          // the veriT reconstruction, so we disable the update of scoped
56
          // assumptions (which would disable the update of B1 in this case).
57
7513
          options::proofFormatMode() != options::ProofFormatMode::VERIT)),
58
22536
      d_finalProof(nullptr)
59
{
60
  // add rules to eliminate here
61
9858
  if (options::proofGranularityMode() != options::ProofGranularityMode::OFF)
62
  {
63
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_SR_EQ_INTRO);
64
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_SR_PRED_INTRO);
65
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_SR_PRED_ELIM);
66
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_SR_PRED_TRANSFORM);
67
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_RESOLUTION_TRUST);
68
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_RESOLUTION);
69
1173
    d_pfpp->setEliminateRule(PfRule::MACRO_ARITH_SCALE_SUM_UB);
70
2346
    if (options::proofGranularityMode()
71
1173
        != options::ProofGranularityMode::REWRITE)
72
    {
73
1173
      d_pfpp->setEliminateRule(PfRule::SUBS);
74
1173
      d_pfpp->setEliminateRule(PfRule::REWRITE);
75
2346
      if (options::proofGranularityMode()
76
1173
          != options::ProofGranularityMode::THEORY_REWRITE)
77
      {
78
        // this eliminates theory rewriting steps with finer-grained DSL rules
79
        d_pfpp->setEliminateRule(PfRule::THEORY_REWRITE);
80
      }
81
    }
82
1173
    d_pfpp->setEliminateRule(PfRule::BV_BITBLAST);
83
  }
84
3756
  d_false = NodeManager::currentNM()->mkConst(false);
85
3756
}
86
87
3756
PfManager::~PfManager() {}
88
89
2792
void PfManager::setFinalProof(std::shared_ptr<ProofNode> pfn, Assertions& as)
90
{
91
  // Note this assumes that setFinalProof is only called once per unsat
92
  // response. This method would need to cache its result otherwise.
93
2792
  Trace("smt-proof") << "SmtEngine::setFinalProof(): get proof body...\n";
94
95
2792
  if (Trace.isOn("smt-proof-debug"))
96
  {
97
    Trace("smt-proof-debug")
98
        << "SmtEngine::setFinalProof(): Proof node for false:\n";
99
    Trace("smt-proof-debug") << *pfn.get() << std::endl;
100
    Trace("smt-proof-debug") << "=====" << std::endl;
101
  }
102
103
5584
  std::vector<Node> assertions;
104
2792
  getAssertions(as, assertions);
105
106
2792
  if (Trace.isOn("smt-proof"))
107
  {
108
    Trace("smt-proof") << "SmtEngine::setFinalProof(): get free assumptions..."
109
                       << std::endl;
110
    std::vector<Node> fassumps;
111
    expr::getFreeAssumptions(pfn.get(), fassumps);
112
    Trace("smt-proof")
113
        << "SmtEngine::setFinalProof(): initial free assumptions are:\n";
114
    for (const Node& a : fassumps)
115
    {
116
      Trace("smt-proof") << "- " << a << std::endl;
117
    }
118
119
    Trace("smt-proof") << "SmtEngine::setFinalProof(): assertions are:\n";
120
    for (const Node& n : assertions)
121
    {
122
      Trace("smt-proof") << "- " << n << std::endl;
123
    }
124
    Trace("smt-proof") << "=====" << std::endl;
125
  }
126
127
2792
  Trace("smt-proof") << "SmtEngine::setFinalProof(): postprocess...\n";
128
2792
  Assert(d_pfpp != nullptr);
129
2792
  d_pfpp->process(pfn);
130
131
2792
  Trace("smt-proof") << "SmtEngine::setFinalProof(): make scope...\n";
132
133
  // Now make the final scope, which ensures that the only open leaves of the
134
  // proof are the assertions.
135
2792
  d_finalProof = d_pnm->mkScope(pfn, assertions);
136
2792
  Trace("smt-proof") << "SmtEngine::setFinalProof(): finished.\n";
137
2792
}
138
139
1
void PfManager::printProof(std::ostream& out,
140
                           std::shared_ptr<ProofNode> pfn,
141
                           Assertions& as)
142
{
143
1
  Trace("smt-proof") << "PfManager::printProof: start" << std::endl;
144
2
  std::shared_ptr<ProofNode> fp = getFinalProof(pfn, as);
145
  // if we are in incremental mode, we don't want to invalidate the proof
146
  // nodes in fp, since these may be reused in further check-sat calls
147
2
  if (options::incrementalSolving()
148
1
      && options::proofFormatMode() != options::ProofFormatMode::NONE)
149
  {
150
    fp = d_pnm->clone(fp);
151
  }
152
  // TODO (proj #37) according to the proof format, post process the proof node
153
  // TODO (proj #37) according to the proof format, print the proof node
154
155
1
  if (options::proofFormatMode() == options::ProofFormatMode::DOT)
156
  {
157
    proof::DotPrinter dotPrinter;
158
    dotPrinter.print(out, fp.get());
159
  }
160
  else
161
  {
162
1
    out << "(proof\n";
163
1
    out << *fp;
164
1
    out << "\n)\n";
165
  }
166
1
}
167
1365
void PfManager::checkProof(std::shared_ptr<ProofNode> pfn, Assertions& as)
168
{
169
1365
  Trace("smt-proof") << "PfManager::checkProof: start" << std::endl;
170
2730
  std::shared_ptr<ProofNode> fp = getFinalProof(pfn, as);
171
2730
  Trace("smt-proof-debug") << "PfManager::checkProof: returned " << *fp.get()
172
1365
                           << std::endl;
173
1365
}
174
175
ProofChecker* PfManager::getProofChecker() const { return d_pchecker.get(); }
176
177
3756
ProofNodeManager* PfManager::getProofNodeManager() const { return d_pnm.get(); }
178
179
3756
smt::PreprocessProofGenerator* PfManager::getPreprocessProofGenerator() const
180
{
181
3756
  return d_pppg.get();
182
}
183
184
2792
std::shared_ptr<ProofNode> PfManager::getFinalProof(
185
    std::shared_ptr<ProofNode> pfn, Assertions& as)
186
{
187
2792
  setFinalProof(pfn, as);
188
2792
  Assert(d_finalProof);
189
2792
  return d_finalProof;
190
}
191
192
2792
void PfManager::getAssertions(Assertions& as,
193
                              std::vector<Node>& assertions)
194
{
195
2792
  context::CDList<Node>* al = as.getAssertionList();
196
2792
  Assert(al != nullptr);
197
37751
  for (context::CDList<Node>::const_iterator i = al->begin(); i != al->end();
198
       ++i)
199
  {
200
34959
    assertions.push_back(*i);
201
  }
202
2792
}
203
204
}  // namespace smt
205
42895
}  // namespace cvc5