Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Alex Ozdemir, Tim King, Andrew Reynolds 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2025 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 : : * Congruence manager, the interface to the equality engine from the 14 : : * linear arithmetic solver 15 : : */ 16 : : 17 : : #include "cvc5_private.h" 18 : : 19 : : #pragma once 20 : : 21 : : #include "context/cdhashmap.h" 22 : : #include "context/cdlist.h" 23 : : #include "context/cdmaybe.h" 24 : : #include "context/cdtrail_queue.h" 25 : : #include "proof/trust_node.h" 26 : : #include "smt/env_obj.h" 27 : : #include "theory/arith/arith_utilities.h" 28 : : #include "theory/arith/linear/arithvar.h" 29 : : #include "theory/arith/linear/arithvar_node_map.h" 30 : : #include "theory/arith/linear/callbacks.h" 31 : : #include "theory/arith/linear/constraint_forward.h" 32 : : #include "theory/uf/equality_engine_notify.h" 33 : : #include "util/dense_map.h" 34 : : #include "util/statistics_stats.h" 35 : : 36 : : namespace cvc5::internal { 37 : : 38 : : class ProofNodeManager; 39 : : class EagerProofGenerator; 40 : : 41 : : namespace theory { 42 : : 43 : : namespace eq { 44 : : class ProofEqEngine; 45 : : class EqualityEngine; 46 : : } 47 : : 48 : : namespace arith::linear { 49 : : 50 : : class ArithVariables; 51 : : 52 : : class ArithCongruenceManager : protected EnvObj 53 : : { 54 : : public: 55 : : ArithCongruenceManager(Env& env, 56 : : ConstraintDatabase&, 57 : : SetupLiteralCallBack, 58 : : const ArithVariables&, 59 : : RaiseEqualityEngineConflict raiseConflict); 60 : : ~ArithCongruenceManager(); 61 : : 62 : : //--------------------------------- initialization 63 : : /** 64 : : * Finish initialize. This class is instructed by TheoryArithPrivate to use 65 : : * the equality engine ee. 66 : : */ 67 : : void finishInit(eq::EqualityEngine* ee); 68 : : //--------------------------------- end initialization 69 : : 70 : : /** 71 : : * Return the trust node for the explanation of literal. The returned 72 : : * trust node is generated by the proof equality engine of this class. 73 : : */ 74 : : TrustNode explain(TNode literal); 75 : : 76 : : void addWatchedPair(ArithVar s, TNode x, TNode y); 77 : : 78 : 12773200 : bool isWatchedVariable(ArithVar s) const 79 : : { 80 : 12773200 : return d_watchedVariables.isMember(s); 81 : : } 82 : : 83 : : /** Assert an equality. */ 84 : : void watchedVariableIsZero(ConstraintCP eq); 85 : : 86 : : /** Assert a conjunction from lb and ub. */ 87 : : void watchedVariableIsZero(ConstraintCP lb, ConstraintCP ub); 88 : : 89 : : /** Assert that the value cannot be zero. */ 90 : : void watchedVariableCannotBeZero(ConstraintCP c); 91 : : 92 : : /** Assert that the value cannot be zero. */ 93 : : void watchedVariableCannotBeZero(ConstraintCP c, ConstraintCP d); 94 : : 95 : : /** Assert that the value is congruent to a constant. */ 96 : : void equalsConstant(ConstraintCP eq); 97 : : void equalsConstant(ConstraintCP lb, ConstraintCP ub); 98 : : 99 : : bool inConflict() const; 100 : : 101 : : bool hasMorePropagations() const; 102 : : 103 : : const Node getNextPropagation(); 104 : : 105 : : bool canExplain(TNode n) const; 106 : : 107 : : /** 108 : : * Propagate. Called when the equality engine has inferred literal x. 109 : : */ 110 : : bool propagate(TNode x); 111 : : 112 : : private: 113 : : context::CDRaised d_inConflict; 114 : : RaiseEqualityEngineConflict d_raiseConflict; 115 : : 116 : : /** 117 : : * The set of ArithVars equivalent to a pair of terms. 118 : : * If this is 0 or cannot be 0, this can be signalled. 119 : : * The pair of terms for the congruence is stored in watched equalities. 120 : : */ 121 : : DenseSet d_watchedVariables; 122 : : /** d_watchedVariables |-> (= x y) */ 123 : : ArithVarToNodeMap d_watchedEqualities; 124 : : 125 : : context::CDList<Node> d_keepAlive; 126 : : 127 : : /** Store the propagations. */ 128 : : context::CDTrailQueue<Node> d_propagatations; 129 : : 130 : : /* This maps the node a theory engine will request on an explain call to 131 : : * to its corresponding PropUnit. 132 : : * This is node is potentially both the propagation or 133 : : * rewrite(propagation). 134 : : */ 135 : : using ExplainMap = context::CDHashMap<Node, size_t>; 136 : : ExplainMap d_explanationMap; 137 : : 138 : : ConstraintDatabase& d_constraintDatabase; 139 : : SetupLiteralCallBack d_setupLiteral; 140 : : 141 : : const ArithVariables& d_avariables; 142 : : 143 : : /** The equality engine being used by this class */ 144 : : eq::EqualityEngine* d_ee; 145 : : /** proof manager */ 146 : : ProofNodeManager* d_pnm; 147 : : /** A proof generator for storing proofs of facts that are asserted to the EQ 148 : : * engine. Note that these proofs **are not closed**; they may contain 149 : : * literals from the explanation of their fact as unclosed assumptions. 150 : : * This makes these proofs SAT-context depdent. 151 : : * 152 : : * This is why this generator is separate from the TheoryArithPrivate 153 : : * generator, which stores closed proofs. 154 : : */ 155 : : std::unique_ptr<EagerProofGenerator> d_pfGenEe; 156 : : /** A proof generator for TrustNodes sent to TheoryArithPrivate. 157 : : * 158 : : * When TheoryArithPrivate requests an explanation from 159 : : * ArithCongruenceManager, it can request a TrustNode for that explanation. 160 : : * This proof generator is the one used in that TrustNode: it stores the 161 : : * (closed) proofs of implications proved by the 162 : : * ArithCongruenceManager/EqualityEngine. 163 : : * 164 : : * It is insufficient to just use the ProofGenerator from the ProofEqEngine, 165 : : * since sometimes the ArithCongruenceManager needs to add some 166 : : * arith-specific reasoning to extend the proof (e.g. rewriting the result 167 : : * into a normal form). 168 : : * */ 169 : : std::unique_ptr<EagerProofGenerator> d_pfGenExplain; 170 : : 171 : : /** Pointer to the proof equality engine of TheoryArith */ 172 : : theory::eq::ProofEqEngine* d_pfee; 173 : : 174 : : /** Raise a conflict node `conflict` to the theory of arithmetic. 175 : : * 176 : : * When proofs are enabled, a (closed) proof of the conflict should be 177 : : * provided. 178 : : */ 179 : : void raiseConflict(Node conflict, std::shared_ptr<ProofNode> pf = nullptr); 180 : : /** 181 : : * Are proofs enabled? This is true if a non-null proof manager was provided 182 : : * to the constructor of this class. 183 : : */ 184 : : bool isProofEnabled() const; 185 : : 186 : : Node externalToInternal(TNode n) const; 187 : : 188 : : void pushBack(TNode n); 189 : : 190 : : void pushBack(TNode n, TNode r); 191 : : 192 : : void pushBack(TNode n, TNode r, TNode w); 193 : : 194 : : /** Assert this literal to the eq engine. Common functionality for 195 : : * * assertionToEqualityEngine(..) 196 : : * * equalsConstant(c) 197 : : * * equalsConstant(lb, ub) 198 : : * If proof is off, then just asserts. 199 : : */ 200 : : void assertLitToEqualityEngine(Node lit, 201 : : TNode reason, 202 : : std::shared_ptr<ProofNode> pf); 203 : : /** This sends a shared term to the uninterpreted equality engine. */ 204 : : void assertionToEqualityEngine(bool eq, 205 : : ArithVar s, 206 : : TNode reason, 207 : : std::shared_ptr<ProofNode> pf); 208 : : 209 : : /** Check for proof for this or a symmetric fact 210 : : * 211 : : * The proof submitted to this method are stored in `d_pfGenEe`, and should 212 : : * have closure properties consistent with the documentation for that member. 213 : : * 214 : : * @returns whether this or a symmetric fact has a proof. 215 : : */ 216 : : bool hasProofFor(TNode f) const; 217 : : /** 218 : : * Sets the proof for this fact and the symmetric one. 219 : : * 220 : : * The proof submitted to this method are stored in `d_pfGenEe`, and should 221 : : * have closure properties consistent with the documentation for that member. 222 : : * */ 223 : : void setProofFor(TNode f, std::shared_ptr<ProofNode> pf) const; 224 : : 225 : : /** Dequeues the delay queue and asserts these equalities.*/ 226 : : void enableSharedTerms(); 227 : : void dequeueLiterals(); 228 : : 229 : : /** 230 : : * Determine an explaination for `internal`. That is a conjunction of theory 231 : : * literals which imply `internal`. 232 : : * 233 : : * The TrustNode here is a trusted propagation. 234 : : */ 235 : : TrustNode explainInternal(TNode internal); 236 : : 237 : : class Statistics { 238 : : public: 239 : : IntStat d_watchedVariables; 240 : : IntStat d_watchedVariableIsZero; 241 : : IntStat d_watchedVariableIsNotZero; 242 : : 243 : : IntStat d_equalsConstantCalls; 244 : : 245 : : IntStat d_propagations; 246 : : IntStat d_propagateConstraints; 247 : : IntStat d_conflicts; 248 : : 249 : : Statistics(StatisticsRegistry& sr); 250 : : } d_statistics; 251 : : 252 : : }; /* class ArithCongruenceManager */ 253 : : 254 : : } // namespace arith 255 : : } // namespace theory 256 : : } // namespace cvc5::internal