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 : : * dynamic quantifiers splitting 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__THEORY__QUANT_SPLIT_H 16 : : #define CVC5__THEORY__QUANT_SPLIT_H 17 : : 18 : : #include "context/cdhashmap.h" 19 : : #include "context/cdo.h" 20 : : #include "smt/env_obj.h" 21 : : #include "theory/quantifiers/quant_module.h" 22 : : 23 : : namespace cvc5::internal { 24 : : namespace theory { 25 : : 26 : : class QuantifiersEngine; 27 : : 28 : : namespace quantifiers { 29 : : 30 : : class QuantDSplitProofGenerator; 31 : : 32 : : /** Quantifiers dynamic splitting 33 : : * 34 : : * This module identifies quantified formulas that should be "split", e.g. 35 : : * based on datatype constructor case splitting. 36 : : * 37 : : * An example of a quantified formula that we may split is the following. Let: 38 : : * optionPair := mkPair( U, U ) | none 39 : : * where U is an uninterpreted sort. The quantified formula: 40 : : * forall x : optionPair. P( x ) 41 : : * may be "split" via the lemma: 42 : : * forall x : optionPair. P( x ) <=> 43 : : * ( forall xy : U. P( mkPair( x, y ) ) OR P( none ) ) 44 : : * 45 : : * Notice that such splitting may lead to exponential behavior, say if we 46 : : * quantify over 32 variables of type optionPair above gives 2^32 disjuncts. 47 : : * This class is used to compute this splitting dynamically, by splitting 48 : : * one variable per quantified formula at a time. 49 : : */ 50 : : class QuantDSplit : public QuantifiersModule 51 : : { 52 : : using NodeSet = context::CDHashSet<Node>; 53 : : using NodeIntMap = context::CDHashMap<Node, size_t>; 54 : : 55 : : public: 56 : : QuantDSplit(Env& env, 57 : : QuantifiersState& qs, 58 : : QuantifiersInferenceManager& qim, 59 : : QuantifiersRegistry& qr, 60 : : TermRegistry& tr); 61 : : /** determine whether this quantified formula will be reduced */ 62 : : void checkOwnership(Node q) override; 63 : : /* whether this module needs to check this round */ 64 : : bool needsCheck(Theory::Effort e) override; 65 : : /* Call during quantifier engine's check */ 66 : : void check(Theory::Effort e, QEffort quant_e) override; 67 : : /** check complete for */ 68 : : bool checkCompleteFor(Node q) override; 69 : : /** Identify this module (for debugging, dynamic configuration, etc..) */ 70 : 0 : std::string identify() const override { return "QuantDSplit"; } 71 : : /** 72 : : * Split the index^th variable of quantified formula q based on its possible 73 : : * constructors. This variable should have datatype type. This method is 74 : : * used for ProofRewriteRule::QUANT_DT_SPLIT. 75 : : */ 76 : : static Node split(NodeManager* nm, const Node& q, size_t index); 77 : : /** 78 : : * Get proof for q = split(nm, q, index). 79 : : */ 80 : : static std::shared_ptr<ProofNode> getQuantDtSplitProof(Env& env, 81 : : const Node& q, 82 : : size_t index); 83 : : 84 : : private: 85 : : /** list of relevant quantifiers asserted in the current context */ 86 : : NodeIntMap d_quant_to_reduce; 87 : : /** whether we have instantiated quantified formulas */ 88 : : NodeSet d_added_split; 89 : : /** Proof generator */ 90 : : std::shared_ptr<QuantDSplitProofGenerator> d_pfgen; 91 : : }; 92 : : 93 : : } // namespace quantifiers 94 : : } // namespace theory 95 : : } // namespace cvc5::internal 96 : : 97 : : #endif