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