ae5de49e9a6069e9b8e5f1cec8d8d435067c485c
1 /******************************************************************************
2 * Top contributors (to current version):
3 * Andrew Reynolds, Haniel Barbosa, Diego Della Rocca de Camargos
5 * This file is part of the cvc5 project.
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 * ****************************************************************************
13 * The proof manager of the SMT engine.
16 #include "smt/proof_manager.h"
18 #include "options/base_options.h"
19 #include "options/main_options.h"
20 #include "options/proof_options.h"
21 #include "options/smt_options.h"
22 #include "proof/dot/dot_printer.h"
23 #include "proof/proof_checker.h"
24 #include "proof/proof_node_algorithm.h"
25 #include "proof/proof_node_manager.h"
26 #include "smt/assertions.h"
28 #include "smt/preprocess_proof_generator.h"
29 #include "smt/proof_post_processor.h"
34 PfManager::PfManager(Env
& env
, SmtEngine
* smte
)
36 d_pchecker(new ProofChecker(
37 d_env
.getOptions().proof
.proofCheck
== options::ProofCheckMode::EAGER
,
38 d_env
.getOptions().proof
.proofPedantic
)),
39 d_pnm(new ProofNodeManager(d_pchecker
.get())),
40 d_pppg(new PreprocessProofGenerator(
41 d_pnm
.get(), env
.getUserContext(), "smt::PreprocessProofGenerator")),
42 d_pfpp(new ProofPostproccess(
46 // by default the post-processor will update all assumptions, which
47 // can lead to SCOPE subproofs of the form
54 // ------------- SCOPE [B1, B2]
57 // where A is an available assumption from outside the scope (note
58 // that B1 was an assumption of this SCOPE subproof but since it could
59 // be inferred from A, it was updated). This shape is problematic for
60 // the veriT reconstruction, so we disable the update of scoped
61 // assumptions (which would disable the update of B1 in this case).
62 options::proofFormatMode() != options::ProofFormatMode::VERIT
)),
65 // add rules to eliminate here
66 if (options::proofGranularityMode() != options::ProofGranularityMode::OFF
)
68 d_pfpp
->setEliminateRule(PfRule::MACRO_SR_EQ_INTRO
);
69 d_pfpp
->setEliminateRule(PfRule::MACRO_SR_PRED_INTRO
);
70 d_pfpp
->setEliminateRule(PfRule::MACRO_SR_PRED_ELIM
);
71 d_pfpp
->setEliminateRule(PfRule::MACRO_SR_PRED_TRANSFORM
);
72 d_pfpp
->setEliminateRule(PfRule::MACRO_RESOLUTION_TRUST
);
73 d_pfpp
->setEliminateRule(PfRule::MACRO_RESOLUTION
);
74 d_pfpp
->setEliminateRule(PfRule::MACRO_ARITH_SCALE_SUM_UB
);
75 if (options::proofGranularityMode()
76 != options::ProofGranularityMode::REWRITE
)
78 d_pfpp
->setEliminateRule(PfRule::SUBS
);
79 d_pfpp
->setEliminateRule(PfRule::REWRITE
);
80 if (options::proofGranularityMode()
81 != options::ProofGranularityMode::THEORY_REWRITE
)
83 // this eliminates theory rewriting steps with finer-grained DSL rules
84 d_pfpp
->setEliminateRule(PfRule::THEORY_REWRITE
);
87 // theory-specific lazy proof reconstruction
88 d_pfpp
->setEliminateRule(PfRule::STRING_INFERENCE
);
89 d_pfpp
->setEliminateRule(PfRule::BV_BITBLAST
);
91 d_false
= NodeManager::currentNM()->mkConst(false);
94 PfManager::~PfManager() {}
96 void PfManager::setFinalProof(std::shared_ptr
<ProofNode
> pfn
, Assertions
& as
)
98 // Note this assumes that setFinalProof is only called once per unsat
99 // response. This method would need to cache its result otherwise.
100 Trace("smt-proof") << "SmtEngine::setFinalProof(): get proof body...\n";
102 if (Trace
.isOn("smt-proof-debug"))
104 Trace("smt-proof-debug")
105 << "SmtEngine::setFinalProof(): Proof node for false:\n";
106 Trace("smt-proof-debug") << *pfn
.get() << std::endl
;
107 Trace("smt-proof-debug") << "=====" << std::endl
;
110 std::vector
<Node
> assertions
;
111 getAssertions(as
, assertions
);
113 if (Trace
.isOn("smt-proof"))
115 Trace("smt-proof") << "SmtEngine::setFinalProof(): get free assumptions..."
117 std::vector
<Node
> fassumps
;
118 expr::getFreeAssumptions(pfn
.get(), fassumps
);
120 << "SmtEngine::setFinalProof(): initial free assumptions are:\n";
121 for (const Node
& a
: fassumps
)
123 Trace("smt-proof") << "- " << a
<< std::endl
;
126 Trace("smt-proof") << "SmtEngine::setFinalProof(): assertions are:\n";
127 for (const Node
& n
: assertions
)
129 Trace("smt-proof") << "- " << n
<< std::endl
;
131 Trace("smt-proof") << "=====" << std::endl
;
134 Trace("smt-proof") << "SmtEngine::setFinalProof(): postprocess...\n";
135 Assert(d_pfpp
!= nullptr);
136 d_pfpp
->process(pfn
);
138 Trace("smt-proof") << "SmtEngine::setFinalProof(): make scope...\n";
140 // Now make the final scope, which ensures that the only open leaves of the
141 // proof are the assertions.
142 d_finalProof
= d_pnm
->mkScope(pfn
, assertions
);
143 Trace("smt-proof") << "SmtEngine::setFinalProof(): finished.\n";
146 void PfManager::printProof(std::ostream
& out
,
147 std::shared_ptr
<ProofNode
> pfn
,
150 Trace("smt-proof") << "PfManager::printProof: start" << std::endl
;
151 std::shared_ptr
<ProofNode
> fp
= getFinalProof(pfn
, as
);
152 // if we are in incremental mode, we don't want to invalidate the proof
153 // nodes in fp, since these may be reused in further check-sat calls
154 if (options::incrementalSolving()
155 && options::proofFormatMode() != options::ProofFormatMode::NONE
)
157 fp
= d_pnm
->clone(fp
);
159 // TODO (proj #37) according to the proof format, post process the proof node
160 // TODO (proj #37) according to the proof format, print the proof node
162 if (options::proofFormatMode() == options::ProofFormatMode::DOT
)
164 proof::DotPrinter dotPrinter
;
165 dotPrinter
.print(out
, fp
.get());
167 else if (options::proofFormatMode() == options::ProofFormatMode::TPTP
)
169 out
<< "% SZS output start Proof for " << d_env
.getOptions().driver
.filename
<< std::endl
;
170 // TODO (proj #37) print in TPTP compliant format
171 out
<< *fp
<< std::endl
;
172 out
<< "% SZS output end Proof for " << d_env
.getOptions().driver
.filename
<< std::endl
;
181 void PfManager::checkProof(std::shared_ptr
<ProofNode
> pfn
, Assertions
& as
)
183 Trace("smt-proof") << "PfManager::checkProof: start" << std::endl
;
184 std::shared_ptr
<ProofNode
> fp
= getFinalProof(pfn
, as
);
185 Trace("smt-proof-debug") << "PfManager::checkProof: returned " << *fp
.get()
189 ProofChecker
* PfManager::getProofChecker() const { return d_pchecker
.get(); }
191 ProofNodeManager
* PfManager::getProofNodeManager() const { return d_pnm
.get(); }
193 smt::PreprocessProofGenerator
* PfManager::getPreprocessProofGenerator() const
198 std::shared_ptr
<ProofNode
> PfManager::getFinalProof(
199 std::shared_ptr
<ProofNode
> pfn
, Assertions
& as
)
201 setFinalProof(pfn
, as
);
202 Assert(d_finalProof
);
206 void PfManager::getAssertions(Assertions
& as
,
207 std::vector
<Node
>& assertions
)
209 context::CDList
<Node
>* al
= as
.getAssertionList();
210 Assert(al
!= nullptr);
211 for (context::CDList
<Node
>::const_iterator i
= al
->begin(); i
!= al
->end();
214 assertions
.push_back(*i
);