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 rewrite rule class 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__REWRITER__REWRITE_PROOF_RULE__H 16 : : #define CVC5__REWRITER__REWRITE_PROOF_RULE__H 17 : : 18 : : #include <string> 19 : : #include <vector> 20 : : #include <unordered_set> 21 : : 22 : : #include "expr/nary_match_trie.h" 23 : : #include "expr/node.h" 24 : : #include "rewriter/rewrites.h" 25 : : 26 : : namespace cvc5::internal { 27 : : namespace rewriter { 28 : : 29 : : /** 30 : : * The level for a rewrite, which determines which proof signature they are a 31 : : * part of. 32 : : */ 33 : : enum class Level 34 : : { 35 : : NORMAL, 36 : : EXPERT, 37 : : }; 38 : : 39 : : /** 40 : : * The definition of a (conditional) rewrite rule. An instance of this 41 : : * class is generated for each DSL rule provided in the rewrite files. The 42 : : * interface of this class is used by the proof reconstruction algorithm. 43 : : */ 44 : : class RewriteProofRule 45 : : { 46 : : public: 47 : : RewriteProofRule(); 48 : : /** 49 : : * Initialize this rule. 50 : : * @param id The identifier of this rule 51 : : * @param userFvs The (user-provided) free variable list of the rule. This 52 : : * is used only to track the original names of the arguments to the rule. 53 : : * @param fvs The internal free variable list of the rule. Notice these 54 : : * variables are normalized such that *all* proof rules use the same 55 : : * variables, per type. In detail, the n^th argument left-to-right of a given 56 : : * type T is the same for all rules. This is to facilitate parallel matching. 57 : : * @param cond The conditions of the rule, normalized to fvs. 58 : : * @param conc The conclusion of the rule, which is an equality of the form 59 : : * (= t s), where t is specified as rewriting to s. This equality is 60 : : * normalized to fvs. 61 : : * @param context The term context for the conclusion of the rule. This is 62 : : * non-null for all rules that should be applied to fixed-point. The context 63 : : * is a lambda term that specifies the next position of the term to rewrite. 64 : : * @param _level The level of the rewrite, which determines which proof 65 : : * signature they should be added to (normal or expert). 66 : : */ 67 : : void init(ProofRewriteRule id, 68 : : const std::vector<Node>& userFvs, 69 : : const std::vector<Node>& fvs, 70 : : const std::vector<Node>& cond, 71 : : Node conc, 72 : : Node context, 73 : : Level _level); 74 : : /** get id */ 75 : : ProofRewriteRule getId() const; 76 : : /** get name */ 77 : : const char* getName() const; 78 : : /** Get user variable list */ 79 : : const std::vector<Node>& getUserVarList() const; 80 : : /** Get variable list */ 81 : : const std::vector<Node>& getVarList() const; 82 : : /** The context that the rule is applied in */ 83 : 16399 : Node getContext() const { return d_context; } 84 : : /** 85 : : * Get path to context variable, for example if 86 : : * d_context is (lambda x (f a (g x b))), then d_pathToCtx = [1,0]. 87 : : */ 88 : 1417 : const std::vector<size_t> getPathToContextVar() const { return d_pathToCtx; } 89 : : /** Does this rule have conditions? */ 90 : : bool hasConditions() const; 91 : : /** Get (declared) conditions */ 92 : : const std::vector<Node>& getConditions() const; 93 : : /** 94 : : * Get the conditions of the rule under the substitution { vs -> ss }. 95 : : */ 96 : : bool getObligations(const std::vector<Node>& vs, 97 : : const std::vector<Node>& ss, 98 : : std::vector<Node>& vcs) const; 99 : : /** 100 : : * Check match, return true if h matches the head of this rule; notifies 101 : : * the match notify object ntm. 102 : : * 103 : : * Note this method is not run as the main matching algorithm for rewrite 104 : : * proof reconstruction, which considers all rules in parallel. This method 105 : : * can be used for debugging matches of h against the head of this rule. 106 : : */ 107 : : void getMatches(Node h, expr::NotifyMatch* ntm) const; 108 : : /** 109 : : * Get (uninstantiated) conclusion of the rule. 110 : : * @param includeContext If we should include the context of this rule (if 111 : : * the RARE rule is given a "context" as described in the constructor). 112 : : * @return The (uninstantiated) conclusion of the rule. 113 : : */ 114 : : Node getConclusion(bool includeContext = false) const; 115 : : /** 116 : : * Get conclusion of the rule for the substituted terms ss for the variables 117 : : * v = getVarList() of this rule. 118 : : * 119 : : * @param ss The terms to substitute in this rule. Each ss[i] is the same sort 120 : : * as v[i] if v[i] is not a list variable, or is an SEXPR if v[i] is a list 121 : : * variable, 122 : : * @return the substituted conclusion of the rule. 123 : : */ 124 : : Node getConclusionFor(const std::vector<Node>& ss) const; 125 : : /** 126 : : * Get conclusion of the rule for the substituted terms ss. 127 : : * Additionally computes the "witness term" for each variable in the rule 128 : : * which gives the corresponding term. 129 : : * In particular, for each v[i] where v = getVarList(), 130 : : * witnessTerms[i] is either: 131 : : * (UNDEFINED_KIND, {t}), specifying that v -> t, 132 : : * (k, {t1...tn}), specifying that v -> (<k> t1 ... tn). 133 : : * Note that we don't construct (<k> t1 ... tn) since it may be illegal to 134 : : * do so if e.g. k=or, and n=1 due to restrictions on the arity of Kinds. 135 : : * 136 : : * @param ss The terms to substitute in this rule. Each ss[i] is the same sort 137 : : * as v[i] if v[i] is not a list variable, or is an SEXPR if v[i] is a list 138 : : * variable, 139 : : * @param witnessTerms The computed witness terms for each variable of this 140 : : * rule. 141 : : * @return the substituted conclusion of the rule. 142 : : */ 143 : : Node getConclusionFor( 144 : : const std::vector<Node>& ss, 145 : : std::vector<std::pair<Kind, std::vector<Node>>>& witnessTerms) const; 146 : : /** 147 : : * @return the list of applications of Kind::TYPE_OF that appear in the 148 : : * conclusion or a premise. These require special handling by the 149 : : * printer. 150 : : */ 151 : : std::vector<Node> getExplicitTypeOfList() const; 152 : : /** 153 : : * Is variable explicit? An explicit variable is one that does not occur 154 : : * in a condition and thus its value must be specified in a proof 155 : : * in languages that allow for implicit/unspecified hole arguments, 156 : : * e.g. LFSC. 157 : : */ 158 : : bool isExplicitVar(Node v) const; 159 : : /** 160 : : * Get list context. This returns the parent kind of the list variable v. 161 : : * For example, for 162 : : * (define-rule bool-or-true ((xs Bool :list) (ys Bool :list)) 163 : : * (or xs true ys) true) 164 : : * The variable xs has list context `OR`. 165 : : * 166 : : * If v is in an ambiguous context, an exception will have been thrown 167 : : * in the constructor of this class. 168 : : * 169 : : * This method returns UNDEFINED_KIND if there is no list context for v, 170 : : * e.g. if v is not a list variable. 171 : : */ 172 : : Kind getListContext(Node v) const; 173 : : /** Was this rule marked as being applied to fixed point? */ 174 : : bool isFixedPoint() const; 175 : : /** 176 : : * Get condition definitions given an application vs -> ss of this rule. 177 : : * This is used to handle variables that do not occur in the left hand side 178 : : * of rewrite rules and are defined in conditions of this rule. 179 : : * @param vs The matched variables of this rule. 180 : : * @param ss The terms to substitute in this rule for each vs. 181 : : * @param dvs The variables for which a definition can now be inferred. 182 : : * @param dss The terms that each dvs are defined as, for each dvs. 183 : : */ 184 : : void getConditionalDefinitions(const std::vector<Node>& vs, 185 : : const std::vector<Node>& ss, 186 : : std::vector<Node>& dvs, 187 : : std::vector<Node>& dss) const; 188 : : /** Get the signature level for the rewrite rule */ 189 : : Level getSignatureLevel() const; 190 : : 191 : : private: 192 : : /** The id of the rule */ 193 : : ProofRewriteRule d_id; 194 : : /** The conditions of the rule */ 195 : : std::vector<Node> d_cond; 196 : : /** The conclusion of the rule (an equality) */ 197 : : Node d_conc; 198 : : /** Is the rule applied in some fixed point context? */ 199 : : Node d_context; 200 : : /** The level */ 201 : : Level d_level; 202 : : /** the ordered list of free variables, provided by the user */ 203 : : std::vector<Node> d_userFvs; 204 : : /** the ordered list of free variables */ 205 : : std::vector<Node> d_fvs; 206 : : /** number of free variables */ 207 : : size_t d_numFv; 208 : : /** 209 : : * The free variables that do not occur in the conditions. These cannot be 210 : : * "holes" in a proof. 211 : : */ 212 : : std::unordered_set<Node> d_noOccVars; 213 : : /** Maps variables to the term they are defined to be */ 214 : : std::map<Node, Node> d_condDefinedVars; 215 : : /** The context for list variables (see expr::getListVarContext). */ 216 : : std::map<Node, Node> d_listVarCtx; 217 : : /** The match trie (for fixed point matching) */ 218 : : expr::NaryMatchTrie d_mt; 219 : : /** Path to context variable */ 220 : : std::vector<size_t> d_pathToCtx; 221 : : }; 222 : : 223 : : } // namespace rewriter 224 : : } // namespace cvc5::internal 225 : : 226 : : #endif /* CVC5__REWRITER__REWRITE_PROOF_RULE__H */