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 : : * A class for augmenting model-based instantiations via fast sygus enumeration. 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__THEORY__QUANTIFIERS__MBQI_ENUM_H 16 : : #define CVC5__THEORY__QUANTIFIERS__MBQI_ENUM_H 17 : : 18 : : #include <map> 19 : : #include <unordered_map> 20 : : #include <unordered_set> 21 : : 22 : : #include "expr/sygus_term_enumerator.h" 23 : : #include "smt/env_obj.h" 24 : : #include "theory/inference_id.h" 25 : : #include "theory/quantifiers/sygus/sygus_enumerator.h" 26 : : 27 : : namespace cvc5::internal { 28 : : namespace theory { 29 : : namespace quantifiers { 30 : : 31 : : class InstStrategyMbqi; 32 : : 33 : : /** 34 : : * Maintains a sygus enumeration for a single quantified variable in our 35 : : * strategy. 36 : : */ 37 : : class MVarInfo 38 : : { 39 : : public: 40 : : /** 41 : : * Initialize this class for variable v of quantified formula q. 42 : : * 43 : : * @param env Reference to the environment. 44 : : * @param q The quantified formula. 45 : : * @param v The variable from q we are enumerating terms for. 46 : : * @param etrules A list of terms which to consider terminals in the grammar 47 : : * we enumerate. These terms may be of any sort. 48 : : */ 49 : : void initialize(Env& env, 50 : : const Node& q, 51 : : const Node& v, 52 : : const std::vector<Node>& etrules); 53 : : /** 54 : : * Get the i^th term in the enumeration maintained by this class. Will 55 : : * continue the sygus enumeration if i is greater than the number of terms 56 : : * enumerated so far. 57 : : */ 58 : : Node getEnumeratedTerm(NodeManager* nm, size_t i); 59 : : 60 : : /** 61 : : * Get the auxiliary lemmas introduced while enumerating terms 62 : : */ 63 : : std::vector<std::pair<Node, InferenceId>> getEnumeratedLemmas(const Node& t); 64 : : 65 : : private: 66 : : /** The underlying sygus enumerator utility */ 67 : : std::unique_ptr<SygusTermEnumerator> d_senum; 68 : : /** 69 : : * Converts enumerated terms by eliminating witness terms, replacing each 70 : : * with an internal choice function symbol and recording the corresponding 71 : : * justification lemma. 72 : : */ 73 : : class ChoiceElimNodeConverter : public NodeConverter 74 : : { 75 : : public: 76 : : ChoiceElimNodeConverter(NodeManager* nm); 77 : : Node postConvert(Node n) override; 78 : : std::vector<std::pair<Node, InferenceId>> getEnumeratedLemmas( 79 : : const Node& t); 80 : : /** Maps introduced choice symbols to their justification lemmas. */ 81 : : std::map<Node, Node> d_lemmas; 82 : : /** Visited cache used while collecting symbols from terms. */ 83 : : std::unordered_set<TNode> d_visited; 84 : : }; 85 : : /** Converter used for witness/choice elimination. */ 86 : : std::unique_ptr<ChoiceElimNodeConverter> d_cenc; 87 : : /** Callback used to post-process and filter enumerated terms. */ 88 : : std::unique_ptr<SygusTermEnumeratorCallback> d_senumCb; 89 : : /** A cache of all enumerated terms so far */ 90 : : std::vector<Node> d_enum; 91 : : /** 92 : : * If we are enumerating function values, this is a BOUND_VAR_LIST node. 93 : : * The terms we enumerate are t_1, ..., which are transformed to 94 : : * (lambda <var_list> t_1) ... for this variable list. 95 : : */ 96 : : Node d_lamVars; 97 : : }; 98 : : 99 : : /** 100 : : * Maintains information about a quantified formula in our strategy, including 101 : : * which variables are processed/unprocessed, and the sygus enumeration for 102 : : * each of them (in MVarInfo). 103 : : */ 104 : : class MQuantInfo 105 : : { 106 : : public: 107 : : /** 108 : : * Intialize the instantiation strategy for quantified formula q. 109 : : * 110 : : * @param env Reference to the environment. 111 : : * @param parent Reference to the parent instantiation strategy. 112 : : * @param q The quantified formula. 113 : : */ 114 : : void initialize(Env& env, InstStrategyMbqi& parent, const Node& q); 115 : : /** Get indices of variables to instantiate */ 116 : : std::vector<size_t> getInstIndices(); 117 : : /** Get indices of variables not to instantiate */ 118 : : std::vector<size_t> getNoInstIndices(); 119 : : /** Get variable info for the index^th variable of the quantified formula */ 120 : : MVarInfo& getVarInfo(size_t index); 121 : : 122 : : private: 123 : : /** The quantified formula */ 124 : : Node d_quant; 125 : : /** A list of variable informations for each of the variables of q */ 126 : : std::vector<MVarInfo> d_vinfo; 127 : : /** The indices of variables we are enumerating */ 128 : : std::vector<size_t> d_indices; 129 : : /** The indices of variables we are not enumerating */ 130 : : std::vector<size_t> d_nindices; 131 : : }; 132 : : 133 : : /** 134 : : * MbqiEnum, which postprocesses an instantiation from MBQI based on 135 : : * sygus enumeration. 136 : : */ 137 : : class MbqiEnum : protected EnvObj 138 : : { 139 : : public: 140 : : MbqiEnum(Env& env, InstStrategyMbqi& parent); 141 : 2196 : ~MbqiEnum() {} 142 : : 143 : : /** 144 : : * Updates mvs to the desired instantiation of q. Returns true if successful. 145 : : * 146 : : * In detail, this method maintains the invariant that 147 : : * query[ mvs / vars ] is satisfiable. 148 : : * This is initially guaranteed since mvs is a model for vars in query 149 : : * due to MBQI. This method iterates over the variables vars[i] and replaces 150 : : * mvs[i] with the first term in the SyGuS enumeration such that the updated 151 : : * mvs still satisfies the query. Checking whether the invariant holds is 152 : : * confirmed via a subsolver call for each replacement. 153 : : * 154 : : * @param q The quantified formula to instantiate. 155 : : * @param query The query that was made to a subsolver for MBQI. 156 : : * @param vars The input variables that were used in the query, which 157 : : * correspond 1-to-1 with the variables of the quantified formula. 158 : : * @param mvs The model values of vars found in the subsolver for MBQI. 159 : : * @param mvFreshVar Maps model values to variables, for the purposes 160 : : * of representing term models for uninterpreted sorts. 161 : : * @param auxLemmas Other lemmas to add. 162 : : * @return true if we successfully modified the instantiation. 163 : : */ 164 : : bool constructInstantiation( 165 : : const Node& q, 166 : : const Node& query, 167 : : const std::vector<Node>& vars, 168 : : std::vector<Node>& mvs, 169 : : const std::map<Node, Node>& mvFreshVar, 170 : : std::vector<std::pair<Node, InferenceId>>& auxLemmas); 171 : : 172 : : private: 173 : : /** 174 : : * @return The information for quantified formula q. 175 : : */ 176 : : MQuantInfo& getOrMkQuantInfo(const Node& q); 177 : : /** Map from quantified formulas to information above */ 178 : : std::map<Node, MQuantInfo> d_qinfo; 179 : : /** Reference to the parent instantiation strategy */ 180 : : InstStrategyMbqi& d_parent; 181 : : /** The options for subsolver calls */ 182 : : Options d_subOptions; 183 : : }; 184 : : 185 : : } // namespace quantifiers 186 : : } // namespace theory 187 : : } // namespace cvc5::internal 188 : : 189 : : #endif /* CVC5__THEORY__QUANTIFIERS__MBQI_ENUM_H */