1 /********************* */ 2 /*! \file inst_match_trie.h 3 ** \verbatim 4 ** Top contributors (to current version): 5 ** Andrew Reynolds, Morgan Deters, Tim King 6 ** This file is part of the CVC4 project. 7 ** Copyright (c) 2009-2019 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.\endverbatim 11 ** 12 ** \brief inst match class 13 **/ 14 15 #include "cvc4_private.h" 16 17 #ifndef __CVC4__THEORY__QUANTIFIERS__INST_MATCH_TRIE_H 18 #define __CVC4__THEORY__QUANTIFIERS__INST_MATCH_TRIE_H 19 20 #include <map> 21 22 #include "context/cdlist.h" 23 #include "context/cdo.h" 24 #include "expr/node.h" 25 #include "theory/quantifiers/inst_match.h" 26 27 namespace CVC4 { 28 namespace theory { 29 30 class QuantifiersEngine; 31 class EqualityQuery; 32 33 namespace inst { 34 35 /** trie for InstMatch objects 36 * 37 * This class is used for storing instantiations of a quantified formula q. 38 * It is a trie data structure for which entries can be added and removed. 39 * This class has interfaces for adding instantiations that are either 40 * represented by std::vectors or InstMatch objects (see inst_match.h). 41 */ 42 class InstMatchTrie 43 { 44 public: 45 /** index ordering */ 46 class ImtIndexOrder 47 { 48 public: 49 std::vector<unsigned> d_order; 50 }; 51 52 public: InstMatchTrie()53 InstMatchTrie() {} ~InstMatchTrie()54 ~InstMatchTrie() {} 55 /** exists inst match 56 * 57 * This method considers the entry given by m, starting at the given index. 58 * The domain of m is the bound variables of quantified formula q. 59 * It returns true if (the suffix) of m exists in this trie. 60 * If modEq is true, we check for duplication modulo equality the current 61 * equalities in the active equality engine of qe. 62 */ 63 bool existsInstMatch(QuantifiersEngine* qe, 64 Node q, 65 InstMatch& m, 66 bool modEq = false, 67 ImtIndexOrder* imtio = NULL, 68 unsigned index = 0) 69 { 70 return !addInstMatch(qe, q, m, modEq, imtio, true, index); 71 } 72 /** exists inst match, vector version */ 73 bool existsInstMatch(QuantifiersEngine* qe, 74 Node q, 75 std::vector<Node>& m, 76 bool modEq = false, 77 ImtIndexOrder* imtio = NULL, 78 unsigned index = 0) 79 { 80 return !addInstMatch(qe, q, m, modEq, imtio, true, index); 81 } 82 /** add inst match 83 * 84 * This method adds (the suffix of) m starting at the given index to this 85 * trie, and returns true if and only if m did not already occur in this trie. 86 * The domain of m is the bound variables of quantified formula q. 87 * If modEq is true, we check for duplication modulo equality the current 88 * equalities in the active equality engine of qe. 89 */ 90 bool addInstMatch(QuantifiersEngine* qe, 91 Node q, 92 InstMatch& m, 93 bool modEq = false, 94 ImtIndexOrder* imtio = NULL, 95 bool onlyExist = false, 96 unsigned index = 0) 97 { 98 return addInstMatch(qe, q, m.d_vals, modEq, imtio, onlyExist, index); 99 } 100 /** add inst match, vector version */ 101 bool addInstMatch(QuantifiersEngine* qe, 102 Node f, 103 std::vector<Node>& m, 104 bool modEq = false, 105 ImtIndexOrder* imtio = NULL, 106 bool onlyExist = false, 107 unsigned index = 0); 108 /** remove inst match 109 * 110 * This removes (the suffix of) m starting at the given index from this trie. 111 * It returns true if and only if this entry existed in this trie. 112 * The domain of m is the bound variables of quantified formula q. 113 */ 114 bool removeInstMatch(Node f, 115 std::vector<Node>& m, 116 ImtIndexOrder* imtio = NULL, 117 unsigned index = 0); 118 /** record instantiation lemma 119 * 120 * This records that the instantiation lemma lem corresponds to the entry 121 * given by (the suffix of) m starting at the given index. 122 */ 123 bool recordInstLemma(Node q, 124 std::vector<Node>& m, 125 Node lem, 126 ImtIndexOrder* imtio = NULL, 127 unsigned index = 0); 128 129 /** get instantiations 130 * 131 * This gets the set of instantiation lemmas that were recorded in this trie 132 * via calls to recordInstLemma. If useActive is true, we only add 133 * instantiations that occur in active. 134 */ getInstantiations(std::vector<Node> & insts,Node q,QuantifiersEngine * qe,bool useActive,std::vector<Node> & active)135 void getInstantiations(std::vector<Node>& insts, 136 Node q, 137 QuantifiersEngine* qe, 138 bool useActive, 139 std::vector<Node>& active) 140 { 141 std::vector<Node> terms; 142 getInstantiations(insts, q, terms, qe, useActive, active); 143 } 144 /** get explanation for inst lemmas 145 * 146 * This gets the explanation for the instantiation lemmas in lems for 147 * quantified formula q, for which this trie stores instantiation matches for. 148 * For each instantiation lemma lem recording in this trie via calls to 149 * recordInstLemma, we map lem to q in map quant, and lem to its corresponding 150 * vector of terms in tvec. 151 */ getExplanationForInstLemmas(Node q,const std::vector<Node> & lems,std::map<Node,Node> & quant,std::map<Node,std::vector<Node>> & tvec)152 void getExplanationForInstLemmas( 153 Node q, 154 const std::vector<Node>& lems, 155 std::map<Node, Node>& quant, 156 std::map<Node, std::vector<Node> >& tvec) const 157 { 158 std::vector<Node> terms; 159 getExplanationForInstLemmas(q, terms, lems, quant, tvec); 160 } 161 162 /** clear the data of this class */ clear()163 void clear() { d_data.clear(); } 164 /** print this class */ print(std::ostream & out,Node q,bool & firstTime,bool useActive,std::vector<Node> & active)165 void print(std::ostream& out, 166 Node q, 167 bool& firstTime, 168 bool useActive, 169 std::vector<Node>& active) const 170 { 171 std::vector<TNode> terms; 172 print(out, q, terms, firstTime, useActive, active); 173 } 174 /** the data */ 175 std::map<Node, InstMatchTrie> d_data; 176 177 private: 178 /** helper for print 179 * terms accumulates the path we are on in the trie. 180 */ 181 void print(std::ostream& out, 182 Node q, 183 std::vector<TNode>& terms, 184 bool& firstTime, 185 bool useActive, 186 std::vector<Node>& active) const; 187 /** helper for get instantiations 188 * terms accumulates the path we are on in the trie. 189 */ 190 void getInstantiations(std::vector<Node>& insts, 191 Node q, 192 std::vector<Node>& terms, 193 QuantifiersEngine* qe, 194 bool useActive, 195 std::vector<Node>& active) const; 196 /** helper for get explantaion for inst lemmas 197 * terms accumulates the path we are on in the trie. 198 */ 199 void getExplanationForInstLemmas( 200 Node q, 201 std::vector<Node>& terms, 202 const std::vector<Node>& lems, 203 std::map<Node, Node>& quant, 204 std::map<Node, std::vector<Node> >& tvec) const; 205 /** set instantiation lemma at this node in the trie */ setInstLemma(Node n)206 void setInstLemma(Node n) 207 { 208 d_data.clear(); 209 d_data[n].clear(); 210 } 211 /** does this node of the trie store an instantiation lemma? */ hasInstLemma()212 bool hasInstLemma() const { return !d_data.empty(); } 213 /** get the instantiation lemma stored in this node of the trie */ getInstLemma()214 Node getInstLemma() const { return d_data.begin()->first; } 215 }; 216 217 /** trie for InstMatch objects 218 * 219 * This is a context-dependent version of the above class. 220 */ 221 class CDInstMatchTrie 222 { 223 public: CDInstMatchTrie(context::Context * c)224 CDInstMatchTrie(context::Context* c) : d_valid(c, false) {} 225 ~CDInstMatchTrie(); 226 227 /** exists inst match 228 * 229 * This method considers the entry given by m, starting at the given index. 230 * The domain of m is the bound variables of quantified formula q. 231 * It returns true if (the suffix) of m exists in this trie. 232 * If modEq is true, we check for duplication modulo equality the current 233 * equalities in the active equality engine of qe. 234 * It additionally takes a context c, for which the entry is valid in. 235 */ 236 bool existsInstMatch(QuantifiersEngine* qe, 237 Node q, 238 InstMatch& m, 239 context::Context* c, 240 bool modEq = false, 241 unsigned index = 0) 242 { 243 return !addInstMatch(qe, q, m, c, modEq, index, true); 244 } 245 /** exists inst match, vector version */ 246 bool existsInstMatch(QuantifiersEngine* qe, 247 Node q, 248 std::vector<Node>& m, 249 context::Context* c, 250 bool modEq = false, 251 unsigned index = 0) 252 { 253 return !addInstMatch(qe, q, m, c, modEq, index, true); 254 } 255 /** add inst match 256 * 257 * This method adds (the suffix of) m starting at the given index to this 258 * trie, and returns true if and only if m did not already occur in this trie. 259 * The domain of m is the bound variables of quantified formula q. 260 * If modEq is true, we check for duplication modulo equality the current 261 * equalities in the active equality engine of qe. 262 * It additionally takes a context c, for which the entry is valid in. 263 */ 264 bool addInstMatch(QuantifiersEngine* qe, 265 Node q, 266 InstMatch& m, 267 context::Context* c, 268 bool modEq = false, 269 unsigned index = 0, 270 bool onlyExist = false) 271 { 272 return addInstMatch(qe, q, m.d_vals, c, modEq, index, onlyExist); 273 } 274 /** add inst match, vector version */ 275 bool addInstMatch(QuantifiersEngine* qe, 276 Node q, 277 std::vector<Node>& m, 278 context::Context* c, 279 bool modEq = false, 280 unsigned index = 0, 281 bool onlyExist = false); 282 /** remove inst match 283 * 284 * This removes (the suffix of) m starting at the given index from this trie. 285 * It returns true if and only if this entry existed in this trie. 286 * The domain of m is the bound variables of quantified formula q. 287 */ 288 bool removeInstMatch(Node q, std::vector<Node>& m, unsigned index = 0); 289 /** record instantiation lemma 290 * 291 * This records that the instantiation lemma lem corresponds to the entry 292 * given by (the suffix of) m starting at the given index. 293 */ 294 bool recordInstLemma(Node q, 295 std::vector<Node>& m, 296 Node lem, 297 unsigned index = 0); 298 299 /** get instantiations 300 * 301 * This gets the set of instantiation lemmas that were recorded in this class 302 * via calls to recordInstLemma. If useActive is true, we only add 303 * instantiations that occur in active. 304 */ getInstantiations(std::vector<Node> & insts,Node q,QuantifiersEngine * qe,bool useActive,std::vector<Node> & active)305 void getInstantiations(std::vector<Node>& insts, 306 Node q, 307 QuantifiersEngine* qe, 308 bool useActive, 309 std::vector<Node>& active) 310 { 311 std::vector<Node> terms; 312 getInstantiations(insts, q, terms, qe, useActive, active); 313 } 314 /** get explanation for inst lemmas 315 * 316 * This gets the explanation for the instantiation lemmas in lems for 317 * quantified formula q, for which this trie stores instantiation matches for. 318 * For each instantiation lemma lem recording in this trie via calls to 319 * recordInstLemma, we map lem to q in map quant, and lem to its corresponding 320 * vector of terms in tvec. 321 */ getExplanationForInstLemmas(Node q,const std::vector<Node> & lems,std::map<Node,Node> & quant,std::map<Node,std::vector<Node>> & tvec)322 void getExplanationForInstLemmas( 323 Node q, 324 const std::vector<Node>& lems, 325 std::map<Node, Node>& quant, 326 std::map<Node, std::vector<Node> >& tvec) const 327 { 328 std::vector<Node> terms; 329 getExplanationForInstLemmas(q, terms, lems, quant, tvec); 330 } 331 332 /** print this class */ print(std::ostream & out,Node q,bool & firstTime,bool useActive,std::vector<Node> & active)333 void print(std::ostream& out, 334 Node q, 335 bool& firstTime, 336 bool useActive, 337 std::vector<Node>& active) const 338 { 339 std::vector<TNode> terms; 340 print(out, q, terms, firstTime, useActive, active); 341 } 342 343 private: 344 /** the data */ 345 std::map<Node, CDInstMatchTrie*> d_data; 346 /** is valid */ 347 context::CDO<bool> d_valid; 348 /** helper for print 349 * terms accumulates the path we are on in the trie. 350 */ 351 void print(std::ostream& out, 352 Node q, 353 std::vector<TNode>& terms, 354 bool& firstTime, 355 bool useActive, 356 std::vector<Node>& active) const; 357 /** helper for get instantiations 358 * terms accumulates the path we are on in the trie. 359 */ 360 void getInstantiations(std::vector<Node>& insts, 361 Node q, 362 std::vector<Node>& terms, 363 QuantifiersEngine* qe, 364 bool useActive, 365 std::vector<Node>& active) const; 366 /** helper for get explanation for inst lemma 367 * terms accumulates the path we are on in the trie. 368 */ 369 void getExplanationForInstLemmas( 370 Node q, 371 std::vector<Node>& terms, 372 const std::vector<Node>& lems, 373 std::map<Node, Node>& quant, 374 std::map<Node, std::vector<Node> >& tvec) const; 375 /** set instantiation lemma at this node in the trie */ setInstLemma(Node n)376 void setInstLemma(Node n) 377 { 378 d_data.clear(); 379 d_data[n] = NULL; 380 } 381 /** does this node of the trie store an instantiation lemma? */ hasInstLemma()382 bool hasInstLemma() const { return !d_data.empty(); } 383 /** get the instantiation lemma stored in this node of the trie */ getInstLemma()384 Node getInstLemma() const { return d_data.begin()->first; } 385 }; 386 387 /** inst match trie ordered 388 * 389 * This is an ordered version of the context-independent instantiation match 390 * trie. It stores a variable order and a base InstMatchTrie. 391 */ 392 class InstMatchTrieOrdered 393 { 394 public: InstMatchTrieOrdered(InstMatchTrie::ImtIndexOrder * imtio)395 InstMatchTrieOrdered(InstMatchTrie::ImtIndexOrder* imtio) : d_imtio(imtio) {} ~InstMatchTrieOrdered()396 ~InstMatchTrieOrdered() {} 397 /** get the ordering */ getOrdering()398 InstMatchTrie::ImtIndexOrder* getOrdering() { return d_imtio; } 399 /** get the trie data */ getTrie()400 InstMatchTrie* getTrie() { return &d_imt; } 401 /** add match m for quantified formula q 402 * 403 * This method returns true if the match m was not previously added to this 404 * class. If modEq is true, we consider duplicates modulo the current 405 * equalities stored in the active equality engine of quantifiers engine. 406 */ 407 bool addInstMatch(QuantifiersEngine* qe, 408 Node q, 409 InstMatch& m, 410 bool modEq = false) 411 { 412 return d_imt.addInstMatch(qe, q, m, modEq, d_imtio); 413 } 414 /** returns true if this trie contains m 415 * 416 * This method returns true if the match m exists in this 417 * class. If modEq is true, we consider duplicates modulo the current 418 * equalities stored in the active equality engine of quantifiers engine. 419 */ 420 bool existsInstMatch(QuantifiersEngine* qe, 421 Node q, 422 InstMatch& m, 423 bool modEq = false) 424 { 425 return d_imt.existsInstMatch(qe, q, m, modEq, d_imtio); 426 } 427 428 private: 429 /** the ordering */ 430 InstMatchTrie::ImtIndexOrder* d_imtio; 431 /** the data of this class */ 432 InstMatchTrie d_imt; 433 }; 434 435 } /* CVC4::theory::inst namespace */ 436 } /* CVC4::theory namespace */ 437 } /* CVC4 namespace */ 438 439 #endif /* __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H */ 440