Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * This file is part of the cvc5 project. 3 : : * 4 : : * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS 5 : : * in the top-level source directory and their institutional affiliations. 6 : : * All rights reserved. See the file COPYING in the top-level source 7 : : * directory for licensing information. 8 : : * **************************************************************************** 9 : : * 10 : : * Proof node utility. 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__PROOF__PROOF_NODE_H 16 : : #define CVC5__PROOF__PROOF_NODE_H 17 : : 18 : : #include <vector> 19 : : 20 : : #include "expr/node.h" 21 : : #include "cvc5/cvc5_proof_rule.h" 22 : : 23 : : namespace cvc5::internal { 24 : : 25 : : class ProofNodeManager; 26 : : class ProofNode; 27 : : 28 : : // Alias for shared pointer to a proof node 29 : : using Pf = std::shared_ptr<ProofNode>; 30 : : 31 : : struct ProofNodeHashFunction 32 : : { 33 : : inline size_t operator()(std::shared_ptr<ProofNode> pfn) const; 34 : : size_t operator()(const ProofNode* pfn) const; 35 : : }; /* struct ProofNodeHashFunction */ 36 : : 37 : : /** A node in a proof 38 : : * 39 : : * A ProofNode represents a single step in a proof. It contains: 40 : : * (1) d_id, an identifier indicating the kind of inference, 41 : : * (2) d_children, the child ProofNode objects indicating its premises, 42 : : * (3) d_args, additional arguments used to determine the conclusion, 43 : : * (4) d_proven, cache of the formula that this ProofNode proves. 44 : : * 45 : : * Overall, a ProofNode and its children form a directed acyclic graph. 46 : : * 47 : : * A ProofNode is partially mutable in that (1), (2) and (3) can be 48 : : * modified. A motivating example of when this is useful is when a ProofNode 49 : : * is established to be a "hole" for something to be proven later. On the other 50 : : * hand, (4) is intended to be immutable. 51 : : * 52 : : * The method setValue is private and can be called by objects that manage 53 : : * ProofNode objects in trusted ways that ensure that the node maintains 54 : : * the invariant above. Furthermore, notice that this class is not responsible 55 : : * for setting d_proven; this is done externally by a ProofNodeManager class. 56 : : * 57 : : * Notice that all fields of ProofNode are stored in ***Skolem form***. Their 58 : : * correctness is checked in ***witness form*** (for details on this 59 : : * terminology, see expr/skolem_manager.h). As a simple example, say a 60 : : * theory solver has a term t, and wants to introduce a unit lemma (= k t) 61 : : * where k is a fresh Skolem variable. It creates this variable via: 62 : : * k = SkolemManager::mkPurifySkolem(t,"k"); 63 : : * A checked ProofNode for the fact (= k t) then may have fields: 64 : : * d_rule := MACRO_SR_PRED_INTRO, 65 : : * d_children := {}, 66 : : * d_args := {(= k t)} 67 : : * d_proven := (= k t). 68 : : * Its justification via the rule MACRO_SR_PRED_INTRO (see documentation 69 : : * in theory/builtin/proof_kinds) is in terms of the witness form of the 70 : : * argument: 71 : : * (= (witness ((z T)) (= z t)) t) 72 : : * which, by that rule's side condition, is such that: 73 : : * Rewriter::rewrite((= (witness ((z T)) (= z t)) t)) = true. 74 : : * Notice that the correctness of the rule is justified here by rewriting 75 : : * the witness form of (= k t). The conversion to/from witness form is 76 : : * managed by ProofRuleChecker::check. 77 : : * 78 : : * An external proof checker is expected to formalize the ProofNode only in 79 : : * terms of *witness* forms. 80 : : * 81 : : * However, the rest of cvc5 sees only the *Skolem* form of arguments and 82 : : * conclusions in ProofNode, since this is what is used throughout cvc5. 83 : : */ 84 : : class ProofNode 85 : : { 86 : : friend class ProofNodeManager; 87 : : 88 : : public: 89 : : ProofNode(ProofRule id, 90 : : const std::vector<std::shared_ptr<ProofNode>>& children, 91 : : const std::vector<Node>& args); 92 : 76417945 : ~ProofNode() {} 93 : : /** get the rule of this proof node */ 94 : : ProofRule getRule() const; 95 : : /** Get children */ 96 : : const std::vector<std::shared_ptr<ProofNode>>& getChildren() const; 97 : : /** Get arguments */ 98 : : const std::vector<Node>& getArguments() const; 99 : : /** get what this node proves, or the null node if this is an invalid proof */ 100 : : Node getResult() const; 101 : : /** 102 : : * Returns true if this is a closed proof (i.e. it has no free assumptions). 103 : : */ 104 : : bool isClosed(); 105 : : /** Print debug on output strem os 106 : : * 107 : : * @param os the stream to print to 108 : : * @param printConclusion Whether to print conclusions 109 : : */ 110 : : void printDebug(std::ostream& os, bool printConclusion = false) const; 111 : : /** 112 : : * Clone this proof node, which creates a deep copy of this proof node and 113 : : * returns it. The dag structure of pn is the same as that in the returned 114 : : * proof node. 115 : : * 116 : : * @return the cloned proof node. 117 : : */ 118 : : std::shared_ptr<ProofNode> clone() const; 119 : : 120 : : private: 121 : : /** 122 : : * Set value, called to overwrite the contents of this ProofNode with the 123 : : * given arguments. 124 : : */ 125 : : void setValue(ProofRule id, 126 : : const std::vector<std::shared_ptr<ProofNode>>& children, 127 : : const std::vector<Node>& args); 128 : : /** The proof rule */ 129 : : ProofRule d_rule; 130 : : /** The children of this proof node */ 131 : : std::vector<std::shared_ptr<ProofNode>> d_children; 132 : : /** arguments of this node */ 133 : : std::vector<Node> d_args; 134 : : /** The cache of the fact that has been proven, modifiable by ProofChecker */ 135 : : Node d_proven; 136 : : /** Was d_proven actually checked, or is it trusted? */ 137 : : bool d_provenChecked; 138 : : }; 139 : : } // namespace cvc5::internal 140 : : 141 : : namespace std { 142 : : template <> 143 : : struct hash<cvc5::internal::ProofNode> 144 : : { 145 : : size_t operator()(const cvc5::internal::ProofNode& node) const; 146 : : }; 147 : : } // namespace std 148 : : 149 : : namespace cvc5::internal { 150 : : 151 : 1992570 : inline size_t ProofNodeHashFunction::operator()( 152 : : std::shared_ptr<ProofNode> pfn) const 153 : : { 154 : 1992570 : return pfn->getResult().getId() + static_cast<unsigned>(pfn->getRule()); 155 : : } 156 : : 157 : : /** 158 : : * Serializes a given proof node to the given stream. 159 : : * 160 : : * @param out the output stream to use 161 : : * @param pn the proof node to output to the stream 162 : : * @return the stream 163 : : */ 164 : : std::ostream& operator<<(std::ostream& out, const ProofNode& pn); 165 : : 166 : : } // namespace cvc5::internal 167 : : 168 : : #endif /* CVC5__PROOF__PROOF_NODE_H */