Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Gereon Kremer, Andrew Reynolds, Hans-Joerg Schurr 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2024 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 : : * Implementation of the lazy tree proof generator class. 14 : : */ 15 : : 16 : : #include "proof/lazy_tree_proof_generator.h" 17 : : 18 : : #include <iostream> 19 : : 20 : : #include "base/output.h" 21 : : #include "expr/node.h" 22 : : #include "proof/proof_generator.h" 23 : : #include "proof/proof_node.h" 24 : : #include "proof/proof_node_manager.h" 25 : : #include "smt/env.h" 26 : : 27 : : namespace cvc5::internal { 28 : : 29 : 69 : LazyTreeProofGenerator::LazyTreeProofGenerator(Env& env, 30 : 69 : const std::string& name) 31 : 69 : : EnvObj(env), d_name(name) 32 : : { 33 : 69 : d_stack.emplace_back(&d_proof); 34 : 69 : } 35 : 6779 : void LazyTreeProofGenerator::openChild() 36 : : { 37 [ + - ]: 6779 : Trace("proof-ltpg") << "openChild() start" << std::endl << *this << std::endl; 38 : 6779 : detail::TreeProofNode& pn = getCurrent(); 39 : 6779 : pn.d_children.emplace_back(); 40 : 6779 : d_stack.emplace_back(&pn.d_children.back()); 41 [ + - ]: 6779 : Trace("proof-ltpg") << "openChild() end" << std::endl << *this << std::endl; 42 : 6779 : } 43 : 6822 : void LazyTreeProofGenerator::closeChild() 44 : : { 45 [ + - ]: 13644 : Trace("proof-ltpg") << "closeChild() start" << std::endl 46 : 6822 : << *this << std::endl; 47 [ - + ][ - + ]: 6822 : Assert(getCurrent().d_rule != ProofRule::UNKNOWN); [ - - ] 48 : 6822 : d_stack.pop_back(); 49 [ + - ]: 6822 : Trace("proof-ltpg") << "closeChild() end" << std::endl << *this << std::endl; 50 : 6822 : } 51 : 25747 : detail::TreeProofNode& LazyTreeProofGenerator::getCurrent() 52 : : { 53 [ - + ][ - + ]: 25747 : Assert(!d_stack.empty()) << "Proof construction has already been finished."; [ - - ] 54 : 25747 : return *d_stack.back(); 55 : : } 56 : 6822 : void LazyTreeProofGenerator::setCurrent(size_t objectId, 57 : : ProofRule rule, 58 : : const std::vector<Node>& premise, 59 : : std::vector<Node> args, 60 : : Node proven) 61 : : { 62 : 6822 : detail::TreeProofNode& pn = getCurrent(); 63 : 6822 : pn.d_objectId = objectId; 64 : 6822 : pn.d_rule = rule; 65 : 6822 : pn.d_premise = premise; 66 : 6822 : pn.d_args = args; 67 : 6822 : pn.d_proven = proven; 68 : 6822 : } 69 : : 70 : 4228 : void LazyTreeProofGenerator::setCurrentTrust(size_t objectId, 71 : : TrustId tid, 72 : : const std::vector<Node>& premise, 73 : : std::vector<Node> args, 74 : : Node proven) 75 : : { 76 : 4228 : std::vector<Node> newArgs; 77 : 4228 : newArgs.push_back(mkTrustId(tid)); 78 : 4228 : newArgs.push_back(proven); 79 : 4228 : newArgs.insert(newArgs.end(), args.begin(), args.end()); 80 : 4228 : setCurrent(objectId, ProofRule::TRUST, premise, newArgs, proven); 81 : 4228 : } 82 : 121 : std::shared_ptr<ProofNode> LazyTreeProofGenerator::getProof() const 83 : : { 84 : : // Check cache 85 [ + + ]: 121 : if (d_cached) return d_cached; 86 [ - + ][ - + ]: 41 : Assert(d_stack.empty()) << "Proof construction has not yet been finished."; [ - - ] 87 : 82 : std::vector<std::shared_ptr<ProofNode>> scope; 88 : 41 : d_cached = getProof(scope, d_proof); 89 : 41 : return d_cached; 90 : : } 91 : : 92 : 40 : std::shared_ptr<ProofNode> LazyTreeProofGenerator::getProofFor(Node f) 93 : : { 94 [ - + ][ - + ]: 40 : Assert(hasProofFor(f)); [ - - ] 95 : 40 : return getProof(); 96 : : } 97 : : 98 : 81 : bool LazyTreeProofGenerator::hasProofFor(Node f) 99 : : { 100 : 81 : return f == getProof()->getResult(); 101 : : } 102 : : 103 : 568 : std::shared_ptr<ProofNode> LazyTreeProofGenerator::getProof( 104 : : std::vector<std::shared_ptr<ProofNode>>& scope, 105 : : const detail::TreeProofNode& pn) const 106 : : { 107 : 568 : ProofNodeManager* pnm = d_env.getProofNodeManager(); 108 : : // Store scope size to reset scope afterwards 109 : 568 : std::size_t before = scope.size(); 110 : 568 : std::vector<std::shared_ptr<ProofNode>> children; 111 [ + + ]: 568 : if (pn.d_rule == ProofRule::SCOPE) 112 : : { 113 : : // Extend scope for all but the root node 114 [ + + ]: 280 : if (&pn != &d_proof) 115 : : { 116 [ + + ]: 465 : for (const auto& a : pn.d_args) 117 : : { 118 : 226 : scope.emplace_back(pnm->mkAssume(a)); 119 : : } 120 : : } 121 : : } 122 : : else 123 : : { 124 : : // Initialize the children with the scope 125 : 288 : children = scope; 126 : : } 127 [ + + ]: 1095 : for (auto& c : pn.d_children) 128 : : { 129 : : // Recurse into tree 130 : 527 : children.emplace_back(getProof(scope, c)); 131 : : } 132 [ + + ]: 729 : for (const auto& p : pn.d_premise) 133 : : { 134 : : // Add premises as assumptions 135 : 161 : children.emplace_back(pnm->mkAssume(p)); 136 : : } 137 : : // Reset scope 138 : 568 : scope.resize(before); 139 : 1136 : return pnm->mkNode(pn.d_rule, children, pn.d_args); 140 : : } 141 : : 142 : 0 : void LazyTreeProofGenerator::print(std::ostream& os, 143 : : const std::string& prefix, 144 : : const detail::TreeProofNode& pn) const 145 : : { 146 : 0 : os << prefix << pn.d_rule << " [" << pn.d_objectId << "]: "; 147 : 0 : container_to_stream(os, pn.d_premise); 148 : 0 : os << " ==> " << pn.d_proven << std::endl; 149 [ - - ]: 0 : if (!pn.d_args.empty()) 150 : : { 151 : 0 : os << prefix << ":args "; 152 : 0 : container_to_stream(os, pn.d_args); 153 : 0 : std::cout << std::endl; 154 : : } 155 [ - - ]: 0 : for (const auto& c : pn.d_children) 156 : : { 157 : 0 : print(os, prefix + '\t', c); 158 : : } 159 : 0 : } 160 : : 161 : 0 : std::ostream& operator<<(std::ostream& os, const LazyTreeProofGenerator& ltpg) 162 : : { 163 : 0 : ltpg.print(os, "", ltpg.d_proof); 164 : 0 : return os; 165 : : } 166 : : 167 : : } // namespace cvc5::internal