diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2021-08-04 14:19:51 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-04 19:19:51 +0000 |
commit | e29a86f380354371dee1e5032034a2fe5edfee16 (patch) | |
tree | 0f076b97e4f150f3165275e733b4dc2c87253172 /src/smt | |
parent | 7f14a11349dae074b4f307488d0289e2fd7043e9 (diff) |
Add optional debug information for dumping instantiations (#6950)
This complete the implementation of dump-instantiations-debug.
With this option, we can print the source of instantiations. For example:
$ cvc5 regress1/quantifiers/dump-inst-proof.smt2 --dump-instantiations-debug --produce-proofs
unsat
(instantiations (forall ((x Int)) (or (P x) (Q x)))
(! ( 2 ) :source QUANTIFIERS_INST_E_MATCHING_SIMPLE ((not (= (P x) true))))
)
(instantiations (forall ((x Int)) (or (not (S x)) (not (Q x))))
(! ( 2 ) :source QUANTIFIERS_INST_E_MATCHING_SIMPLE ((not (= (S x) false))))
)
Diffstat (limited to 'src/smt')
-rw-r--r-- | src/smt/proof_post_processor.cpp | 19 | ||||
-rw-r--r-- | src/smt/proof_post_processor.h | 6 | ||||
-rw-r--r-- | src/smt/smt_engine.cpp | 67 | ||||
-rw-r--r-- | src/smt/smt_engine.h | 3 | ||||
-rw-r--r-- | src/smt/unsat_core_manager.cpp | 28 | ||||
-rw-r--r-- | src/smt/unsat_core_manager.h | 7 |
6 files changed, 95 insertions, 35 deletions
diff --git a/src/smt/proof_post_processor.cpp b/src/smt/proof_post_processor.cpp index ad9a8f844..66f9fde7c 100644 --- a/src/smt/proof_post_processor.cpp +++ b/src/smt/proof_post_processor.cpp @@ -1182,7 +1182,10 @@ bool ProofPostprocessCallback::addToTransChildren(Node eq, ProofPostprocessFinalCallback::ProofPostprocessFinalCallback( ProofNodeManager* pnm) : d_ruleCount(smtStatisticsRegistry().registerHistogram<PfRule>( - "finalProof::ruleCount")), + "finalProof::ruleCount")), + d_instRuleIds( + smtStatisticsRegistry().registerHistogram<theory::InferenceId>( + "finalProof::instRuleId")), d_totalRuleCount( smtStatisticsRegistry().registerInt("finalProof::totalRuleCount")), d_minPedanticLevel( @@ -1227,6 +1230,20 @@ bool ProofPostprocessFinalCallback::shouldUpdate(std::shared_ptr<ProofNode> pn, // record stats for the rule d_ruleCount << r; ++d_totalRuleCount; + // take stats on the instantiations in the proof + if (r == PfRule::INSTANTIATE) + { + Node q = pn->getChildren()[0]->getResult(); + const std::vector<Node>& args = pn->getArguments(); + if (args.size() > q[0].getNumChildren()) + { + InferenceId id; + if (getInferenceId(args[q[0].getNumChildren()], id)) + { + d_instRuleIds << id; + } + } + } return false; } diff --git a/src/smt/proof_post_processor.h b/src/smt/proof_post_processor.h index f9e93fa91..056f77695 100644 --- a/src/smt/proof_post_processor.h +++ b/src/smt/proof_post_processor.h @@ -24,6 +24,7 @@ #include "proof/proof_node_updater.h" #include "smt/witness_form.h" +#include "theory/inference_id.h" #include "util/statistics_stats.h" namespace cvc5 { @@ -256,6 +257,11 @@ class ProofPostprocessFinalCallback : public ProofNodeUpdaterCallback private: /** Counts number of postprocessed proof nodes for each kind of proof rule */ HistogramStat<PfRule> d_ruleCount; + /** + * Counts number of postprocessed proof nodes of rule INSTANTIATE that were + * marked with the given inference id. + */ + HistogramStat<theory::InferenceId> d_instRuleIds; /** Total number of postprocessed rule applications */ IntStat d_totalRuleCount; /** The minimum pedantic level of any rule encountered */ diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 55f3d1c5f..5f3920929 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -1561,7 +1561,7 @@ UnsatCore SmtEngine::getUnsatCore() { } void SmtEngine::getRelevantInstantiationTermVectors( - std::map<Node, std::vector<std::vector<Node>>>& insts) + std::map<Node, InstantiationList>& insts, bool getDebugInfo) { Assert(d_state->getMode() == SmtMode::UNSAT); // generate with new proofs @@ -1570,7 +1570,7 @@ void SmtEngine::getRelevantInstantiationTermVectors( Assert(pe->getProof() != nullptr); std::shared_ptr<ProofNode> pfn = d_pfManager->getFinalProof(pe->getProof(), *d_asserts); - d_ucManager->getRelevantInstantiations(pfn, insts); + d_ucManager->getRelevantInstantiations(pfn, insts, getDebugInfo); } std::string SmtEngine::getProof() @@ -1635,11 +1635,36 @@ void SmtEngine::printInstantiations( std::ostream& out ) { } // Second, extract and print the instantiations - std::map<Node, std::vector<std::vector<Node>>> insts; - getInstantiationTermVectors(insts); - for (const std::pair<const Node, std::vector<std::vector<Node>>>& i : insts) + std::map<Node, InstantiationList> rinsts; + if (d_env->getOptions().smt.produceProofs + && (!d_env->getOptions().smt.unsatCores + || d_env->getOptions().smt.unsatCoresMode + == options::UnsatCoresMode::FULL_PROOF) + && getSmtMode() == SmtMode::UNSAT) { - if (i.second.empty()) + // minimize instantiations based on proof manager + getRelevantInstantiationTermVectors(rinsts, + options::dumpInstantiationsDebug()); + } + else + { + std::map<Node, std::vector<std::vector<Node>>> insts; + getInstantiationTermVectors(insts); + for (const std::pair<const Node, std::vector<std::vector<Node>>>& i : insts) + { + // convert to instantiation list + Node q = i.first; + InstantiationList& ilq = rinsts[q]; + ilq.initialize(q); + for (const std::vector<Node>& ii : i.second) + { + ilq.d_inst.push_back(InstantiationVec(ii)); + } + } + } + for (std::pair<const Node, InstantiationList>& i : rinsts) + { + if (i.second.d_inst.empty()) { // no instantiations, skip continue; @@ -1653,22 +1678,23 @@ void SmtEngine::printInstantiations( std::ostream& out ) { // must have a name if (d_env->getOptions().printer.printInstMode == options::PrintInstMode::NUM) { - out << "(num-instantiations " << name << " " << i.second.size() << ")" - << std::endl; + out << "(num-instantiations " << name << " " << i.second.d_inst.size() + << ")" << std::endl; } else { + // take the name + i.second.d_quant = name; Assert(d_env->getOptions().printer.printInstMode == options::PrintInstMode::LIST); - InstantiationList ilist(name, i.second); - out << ilist; + out << i.second; } printed = true; } // if we did not print anything, we indicate this if (!printed) { - out << "No instantiations" << std::endl; + out << "none" << std::endl; } if (d_env->getOptions().printer.instFormatMode == options::InstFormatMode::SZS) { @@ -1681,21 +1707,10 @@ void SmtEngine::getInstantiationTermVectors( { SmtScope smts(this); finishInit(); - if (d_env->getOptions().smt.produceProofs - && (!d_env->getOptions().smt.unsatCores - || d_env->getOptions().smt.unsatCoresMode == options::UnsatCoresMode::FULL_PROOF) - && getSmtMode() == SmtMode::UNSAT) - { - // minimize instantiations based on proof manager - getRelevantInstantiationTermVectors(insts); - } - else - { - QuantifiersEngine* qe = - getAvailableQuantifiersEngine("getInstantiationTermVectors"); - // otherwise, just get the list of all instantiations - qe->getInstantiationTermVectors(insts); - } + QuantifiersEngine* qe = + getAvailableQuantifiersEngine("getInstantiationTermVectors"); + // get the list of all instantiations + qe->getInstantiationTermVectors(insts); } bool SmtEngine::getSynthSolutions(std::map<Node, Node>& solMap) diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index 68b1caad0..d00fa0c76 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -46,6 +46,7 @@ class LogicRequest; class StatisticsRegistry; class Printer; class ResourceManager; +struct InstantiationList; /* -------------------------------------------------------------------------- */ @@ -673,7 +674,7 @@ class CVC5_EXPORT SmtEngine * refutation. */ void getRelevantInstantiationTermVectors( - std::map<Node, std::vector<std::vector<Node>>>& insts); + std::map<Node, InstantiationList>& insts, bool getDebugInfo = false); /** * Get instantiation term vectors, which maps each instantiated quantified * formula to the list of instantiations for that quantified formula. This diff --git a/src/smt/unsat_core_manager.cpp b/src/smt/unsat_core_manager.cpp index 22304f9e8..01025e505 100644 --- a/src/smt/unsat_core_manager.cpp +++ b/src/smt/unsat_core_manager.cpp @@ -56,12 +56,13 @@ void UnsatCoreManager::getUnsatCore(std::shared_ptr<ProofNode> pfn, void UnsatCoreManager::getRelevantInstantiations( std::shared_ptr<ProofNode> pfn, - std::map<Node, std::vector<std::vector<Node>>>& insts) + std::map<Node, InstantiationList>& insts, + bool getDebugInfo) { std::unordered_map<ProofNode*, bool> visited; std::unordered_map<ProofNode*, bool>::iterator it; std::vector<std::shared_ptr<ProofNode>> visit; - + std::map<Node, InstantiationList>::iterator itq; std::shared_ptr<ProofNode> cur; visit.push_back(pfn); do @@ -82,8 +83,27 @@ void UnsatCoreManager::getRelevantInstantiations( Node q = cs[0]->getResult(); // the instantiation is a prefix of the arguments up to the number of // variables - insts[q].push_back( - {instTerms.begin(), instTerms.begin() + q[0].getNumChildren()}); + itq = insts.find(q); + if (itq == insts.end()) + { + insts[q].initialize(q); + itq = insts.find(q); + } + itq->second.d_inst.push_back(InstantiationVec( + {instTerms.begin(), instTerms.begin() + q[0].getNumChildren()})); + if (getDebugInfo) + { + std::vector<Node> extraArgs(instTerms.begin() + q[0].getNumChildren(), + instTerms.end()); + if (extraArgs.size() >= 1) + { + getInferenceId(extraArgs[0], itq->second.d_inst.back().d_id); + } + if (extraArgs.size() >= 2) + { + itq->second.d_inst.back().d_pfArg = extraArgs[1]; + } + } } for (const std::shared_ptr<ProofNode>& cp : cs) { diff --git a/src/smt/unsat_core_manager.h b/src/smt/unsat_core_manager.h index e064b83a7..eb71c67ca 100644 --- a/src/smt/unsat_core_manager.h +++ b/src/smt/unsat_core_manager.h @@ -21,6 +21,7 @@ #include "context/cdlist.h" #include "expr/node.h" #include "proof/proof_node.h" +#include "theory/quantifiers/instantiation_list.h" namespace cvc5 { @@ -61,9 +62,9 @@ class UnsatCoreManager * matrix with each row corresponding to the terms with which the respective * quantified formula is instiated. */ - void getRelevantInstantiations( - std::shared_ptr<ProofNode> pfn, - std::map<Node, std::vector<std::vector<Node>>>& insts); + void getRelevantInstantiations(std::shared_ptr<ProofNode> pfn, + std::map<Node, InstantiationList>& insts, + bool getDebugInfo = false); }; /* class UnsatCoreManager */ |