1 /********************* */ 2 /*! \file output_channel.h 3 ** \verbatim 4 ** Top contributors (to current version): 5 ** Morgan Deters, Tim King, Liana Hadarean 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 The theory output channel interface 13 ** 14 ** The theory output channel interface. 15 **/ 16 17 #include "cvc4_private.h" 18 19 #ifndef __CVC4__THEORY__OUTPUT_CHANNEL_H 20 #define __CVC4__THEORY__OUTPUT_CHANNEL_H 21 22 #include <memory> 23 24 #include "base/cvc4_assert.h" 25 #include "proof/proof_manager.h" 26 #include "smt/logic_exception.h" 27 #include "theory/interrupted.h" 28 #include "util/proof.h" 29 #include "util/resource_manager.h" 30 31 namespace CVC4 { 32 namespace theory { 33 34 class Theory; 35 36 /** 37 * A LemmaStatus, returned from OutputChannel::lemma(), provides information 38 * about the lemma added. In particular, it contains the T-rewritten lemma 39 * for inspection and the user-level at which the lemma will reside. 40 */ 41 class LemmaStatus { 42 public: LemmaStatus(TNode rewrittenLemma,unsigned level)43 LemmaStatus(TNode rewrittenLemma, unsigned level) 44 : d_rewrittenLemma(rewrittenLemma), d_level(level) {} 45 46 /** Get the T-rewritten form of the lemma. */ getRewrittenLemma()47 TNode getRewrittenLemma() const { return d_rewrittenLemma; } 48 /** 49 * Get the user-level at which the lemma resides. After this user level 50 * is popped, the lemma is un-asserted from the SAT layer. This level 51 * will be 0 if the lemma didn't reach the SAT layer at all. 52 */ getLevel()53 unsigned getLevel() const { return d_level; } 54 private: 55 Node d_rewrittenLemma; 56 unsigned d_level; 57 }; /* class LemmaStatus */ 58 59 /** 60 * Generic "theory output channel" interface. 61 * 62 * All methods can throw unrecoverable CVC4::Exception's unless otherwise 63 * documented. 64 */ 65 class OutputChannel { 66 public: 67 /** Construct an OutputChannel. */ OutputChannel()68 OutputChannel() {} 69 70 /** 71 * Destructs an OutputChannel. This implementation does nothing, 72 * but we need a virtual destructor for safety in case subclasses 73 * have a destructor. 74 */ ~OutputChannel()75 virtual ~OutputChannel() {} 76 77 OutputChannel(const OutputChannel&) = delete; 78 OutputChannel& operator=(const OutputChannel&) = delete; 79 80 /** 81 * With safePoint(), the theory signals that it is at a safe point 82 * and can be interrupted. 83 * 84 * @throws Interrupted if the theory can be safely interrupted. 85 */ safePoint(uint64_t amount)86 virtual void safePoint(uint64_t amount) {} 87 88 /** 89 * Indicate a theory conflict has arisen. 90 * 91 * @param n - a conflict at the current decision level. This should 92 * be an AND-kinded node of literals that are TRUE in the current 93 * assignment and are in conflict (i.e., at least one must be 94 * assigned false), or else a literal by itself (in the case of a 95 * unit conflict) which is assigned TRUE (and T-conflicting) in the 96 * current assignment. 97 * @param pf - a proof of the conflict. This is only non-null if proofs 98 * are enabled. 99 */ 100 virtual void conflict(TNode n, std::unique_ptr<Proof> pf = nullptr) = 0; 101 102 /** 103 * Propagate a theory literal. 104 * 105 * @param n - a theory consequence at the current decision level 106 * @return false if an immediate conflict was encountered 107 */ 108 virtual bool propagate(TNode n) = 0; 109 110 /** 111 * Tell the core that a valid theory lemma at decision level 0 has 112 * been detected. (This requests a split.) 113 * 114 * @param n - a theory lemma valid at decision level 0 115 * @param rule - the proof rule for this lemma 116 * @param removable - whether the lemma can be removed at any point 117 * @param preprocess - whether to apply more aggressive preprocessing 118 * @param sendAtoms - whether to ensure atoms are sent to the theory 119 * @return the "status" of the lemma, including user level at which 120 * the lemma resides; the lemma will be removed when this user level pops 121 */ 122 virtual LemmaStatus lemma(TNode n, ProofRule rule, bool removable = false, 123 bool preprocess = false, 124 bool sendAtoms = false) = 0; 125 126 /** 127 * Variant of the lemma function that does not require providing a proof rule. 128 */ 129 virtual LemmaStatus lemma(TNode n, bool removable = false, 130 bool preprocess = false, bool sendAtoms = false) { 131 return lemma(n, RULE_INVALID, removable, preprocess, sendAtoms); 132 } 133 134 /** 135 * Request a split on a new theory atom. This is equivalent to 136 * calling lemma({OR n (NOT n)}). 137 * 138 * @param n - a theory atom; must be of Boolean type 139 */ split(TNode n)140 LemmaStatus split(TNode n) { return splitLemma(n.orNode(n.notNode())); } 141 142 virtual LemmaStatus splitLemma(TNode n, bool removable = false) = 0; 143 144 /** 145 * If a decision is made on n, it must be in the phase specified. 146 * Note that this is enforced *globally*, i.e., it is completely 147 * context-INdependent. If you ever requirePhase() on a literal, 148 * it is phase-locked forever and ever. If it is to ever have the 149 * other phase as its assignment, it will be because it has been 150 * propagated that way (or it's a unit, at decision level 0). 151 * 152 * @param n - a theory atom with a SAT literal assigned; must have 153 * been pre-registered 154 * @param phase - the phase to decide on n 155 */ 156 virtual void requirePhase(TNode n, bool phase) = 0; 157 158 /** 159 * Notification from a theory that it realizes it is incomplete at 160 * this context level. If SAT is later determined by the 161 * TheoryEngine, it should actually return an UNKNOWN result. 162 */ 163 virtual void setIncomplete() = 0; 164 165 /** 166 * "Spend" a "resource." The meaning is specific to the context in 167 * which the theory is operating, and may even be ignored. The 168 * intended meaning is that if the user has set a limit on the "units 169 * of resource" that can be expended in a search, and that limit is 170 * exceeded, then the search is terminated. Note that the check for 171 * termination occurs in the main search loop, so while theories 172 * should call OutputChannel::spendResource() during particularly 173 * long-running operations, they cannot rely on resource() to break 174 * out of infinite or intractable computations. 175 */ spendResource(unsigned amount)176 virtual void spendResource(unsigned amount) {} 177 178 /** 179 * Handle user attribute. 180 * Associates theory t with the attribute attr. Theory t will be 181 * notified whenever an attribute of name attr is set on a node. 182 * This can happen through, for example, the SMT-LIBv2 language. 183 */ handleUserAttribute(const char * attr,Theory * t)184 virtual void handleUserAttribute(const char* attr, Theory* t) {} 185 186 /** Demands that the search restart from sat search level 0. 187 * Using this leads to non-termination issues. 188 * It is appropriate for prototyping for theories. 189 */ demandRestart()190 virtual void demandRestart() {} 191 192 }; /* class OutputChannel */ 193 194 } // namespace theory 195 } // namespace CVC4 196 197 #endif /* __CVC4__THEORY__OUTPUT_CHANNEL_H */ 198