Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Gereon Kremer, Andres Noetzli 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 : : * A buffered inference manager. 14 : : */ 15 : : 16 : : #include "cvc5_private.h" 17 : : 18 : : #ifndef CVC5__THEORY__INFERENCE_MANAGER_BUFFERED_H 19 : : #define CVC5__THEORY__INFERENCE_MANAGER_BUFFERED_H 20 : : 21 : : #include "expr/node.h" 22 : : #include "theory/theory_inference.h" 23 : : #include "theory/theory_inference_manager.h" 24 : : 25 : : namespace cvc5::internal { 26 : : namespace theory { 27 : : 28 : : /** 29 : : * The buffered inference manager. This class implements standard methods 30 : : * for buffering facts, lemmas and phase requirements. 31 : : */ 32 : : class InferenceManagerBuffered : public TheoryInferenceManager 33 : : { 34 : : public: 35 : : InferenceManagerBuffered(Env& env, 36 : : Theory& t, 37 : : TheoryState& state, 38 : : const std::string& statsName, 39 : : bool cacheLemmas = true); 40 : 342916 : virtual ~InferenceManagerBuffered() {} 41 : : /** 42 : : * Do we have a pending fact or lemma? 43 : : */ 44 : : bool hasPending() const; 45 : : /** 46 : : * Do we have a pending fact to add as an internal fact to the equality 47 : : * engine? 48 : : */ 49 : : bool hasPendingFact() const; 50 : : /** Do we have a pending lemma to send on the output channel? */ 51 : : bool hasPendingLemma() const; 52 : : /** 53 : : * Add pending lemma lem with property p, with proof generator pg. If 54 : : * non-null, pg must be able to provide a proof for lem for the remainder 55 : : * of the user context. Pending lemmas are sent to the output channel using 56 : : * doPendingLemmas. 57 : : * 58 : : * @param lem The lemma to send 59 : : * @param id The identifier of the inference 60 : : * @param p The property of the lemma 61 : : * @param pg The proof generator which can provide a proof for lem 62 : : * @param checkCache Whether we want to check that the lemma is already in 63 : : * the cache. 64 : : * @return true if the lemma was added to the list of pending lemmas and 65 : : * false if the lemma is already cached. 66 : : */ 67 : : bool addPendingLemma(Node lem, 68 : : InferenceId id, 69 : : LemmaProperty p = LemmaProperty::NONE, 70 : : ProofGenerator* pg = nullptr, 71 : : bool checkCache = true); 72 : : /** 73 : : * Add pending lemma, where lemma can be a (derived) class of the 74 : : * theory inference base class. 75 : : */ 76 : : void addPendingLemma(std::unique_ptr<TheoryInference> lemma); 77 : : /** 78 : : * Add pending fact, which adds a fact on the pending fact queue. It must 79 : : * be the case that: 80 : : * (1) exp => conc is valid, 81 : : * (2) exp is a literal (or conjunction of literals) that holds in the 82 : : * equality engine of the theory. 83 : : * 84 : : * Pending facts are sent to the equality engine of this class using 85 : : * doPendingFacts. 86 : : * @param conc The conclustion 87 : : * @param id The identifier of the inference 88 : : * @param exp The explanation in the equality engine of the theory 89 : : * @param pg The proof generator which can provide a proof for conc 90 : : */ 91 : : void addPendingFact(Node conc, InferenceId id, Node exp, ProofGenerator* pg = nullptr); 92 : : /** 93 : : * Add pending fact, where fact can be a (derived) class of the 94 : : * theory inference base class. 95 : : */ 96 : : void addPendingFact(std::unique_ptr<TheoryInference> fact); 97 : : /** Add pending phase requirement 98 : : * 99 : : * This method is called to indicate this class should send a phase 100 : : * requirement request to the output channel for literal lit to be 101 : : * decided with polarity pol. The literal lit should be a SAT literal 102 : : * by the time that doPendingPhaseRequirements is called. Typically, 103 : : * lit is a literal that is a subformula of a pending lemma that is processed 104 : : * prior to sending the phase requirement. 105 : : */ 106 : : void addPendingPhaseRequirement(Node lit, bool pol); 107 : : /** Do pending facts 108 : : * 109 : : * This method asserts pending facts (d_pendingFact) with explanations 110 : : * to the equality engine of the theory via calls 111 : : * to assertInternalFact. 112 : : * 113 : : * It terminates early if a conflict is encountered, for instance, by 114 : : * equality reasoning within the equality engine. 115 : : * 116 : : * Regardless of whether a conflict is encountered, the vector d_pendingFact 117 : : * is cleared after this call. 118 : : */ 119 : : void doPendingFacts(); 120 : : /** Do pending lemmas 121 : : * 122 : : * This method send all pending lemmas (d_pendingLem) on the output 123 : : * channel of the theory. 124 : : * 125 : : * Unlike doPendingFacts, this function will not terminate early if a conflict 126 : : * has already been encountered by the theory. The vector d_pendingLem is 127 : : * cleared after this call. 128 : : */ 129 : : void doPendingLemmas(); 130 : : /** 131 : : * Do pending phase requirements. Calls the output channel for all pending 132 : : * phase requirements and clears d_pendingReqPhase. 133 : : */ 134 : : void doPendingPhaseRequirements(); 135 : : /** Clear pending facts, lemmas, and phase requirements without processing */ 136 : : void clearPending(); 137 : : /** Clear pending facts, without processing */ 138 : : void clearPendingFacts(); 139 : : /** Clear pending lemmas, without processing */ 140 : : void clearPendingLemmas(); 141 : : /** Clear pending phase requirements, without processing */ 142 : : void clearPendingPhaseRequirements(); 143 : : 144 : : /** Returns the number of pending lemmas. */ 145 : : std::size_t numPendingLemmas() const; 146 : : /** Returns the number of pending facts. */ 147 : : std::size_t numPendingFacts() const; 148 : : 149 : : /** 150 : : * Send the given theory inference as a lemma on the output channel of this 151 : : * inference manager. This calls TheoryInferenceManager::trustedLemma based 152 : : * on the provided theory inference, and returns true if the lemma was 153 : : * successfully sent. 154 : : */ 155 : : bool lemmaTheoryInference(TheoryInference* lem); 156 : : /** 157 : : * Add the given theory inference as an internal fact. This calls 158 : : * TheoryInferenceManager::assertInternalFact based on the provided theory 159 : : * inference. 160 : : */ 161 : : void assertInternalFactTheoryInference(TheoryInference* fact); 162 : : 163 : : /** 164 : : * Notify this inference manager that a conflict was sent in this SAT context. 165 : : * This method is called via TheoryEngine when a conflict is sent. This 166 : : * method will clear all pending facts, lemmas, and phase requirements, as 167 : : * these will be stale after the solver backtracks. 168 : : */ 169 : : void notifyInConflict() override; 170 : : 171 : : protected: 172 : : /** A set of pending inferences to be processed as lemmas */ 173 : : std::vector<std::unique_ptr<TheoryInference>> d_pendingLem; 174 : : /** A set of pending inferences to be processed as facts */ 175 : : std::vector<std::unique_ptr<TheoryInference>> d_pendingFact; 176 : : /** A map from literals to their pending phase requirement */ 177 : : std::map<Node, bool> d_pendingReqPhase; 178 : : /** 179 : : * Whether we are currently processing pending lemmas. This flag ensures 180 : : * that we do not call pending lemmas recursively, which may lead to 181 : : * segfaults. 182 : : */ 183 : : bool d_processingPendingLemmas; 184 : : }; 185 : : 186 : : } // namespace theory 187 : : } // namespace cvc5::internal 188 : : 189 : : #endif