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 : : * Preregister policy 11 : : */ 12 : : 13 : : #include "prop/theory_preregistrar.h" 14 : : 15 : : #include "options/prop_options.h" 16 : : #include "prop/cnf_stream.h" 17 : : #include "prop/prop_engine.h" 18 : : #include "prop/sat_solver.h" 19 : : #include "theory/theory_engine.h" 20 : : 21 : : namespace cvc5::internal { 22 : : namespace prop { 23 : : 24 : : /* -------------------------------------------------------------------------- */ 25 : : 26 : : /** 27 : : * The context notify object for the theory preregistrar. Clears the 28 : : * reregistration cache on user context pop. 29 : : */ 30 : : class TheoryPreregistrarNotify : public context::ContextNotifyObj 31 : : { 32 : : public: 33 : 52004 : TheoryPreregistrarNotify(Env& env, TheoryPreregistrar& prr) 34 : 52004 : : context::ContextNotifyObj(env.getUserContext(), false), d_prr(prr) 35 : : { 36 : 52004 : } 37 : : 38 : : protected: 39 : 59869 : void contextNotifyPop() override { d_prr.d_sat_literals.clear(); } 40 : : 41 : : private: 42 : : /** The associated theory preregistrar. */ 43 : : TheoryPreregistrar& d_prr; 44 : : }; 45 : : 46 : : /* -------------------------------------------------------------------------- */ 47 : : 48 : 52004 : TheoryPreregistrar::TheoryPreregistrar(Env& env, 49 : : TheoryEngine* te, 50 : : CVC5_UNUSED CDCLTSatSolver* ss, 51 : 52004 : CVC5_UNUSED CnfStream* cs) 52 : : : EnvObj(env), 53 : 52004 : d_theoryEngine(te), 54 : 52004 : d_notify(new TheoryPreregistrarNotify(env, *this)) 55 : : { 56 : 52004 : } 57 : : 58 : 103312 : TheoryPreregistrar::~TheoryPreregistrar() {} 59 : : 60 : 52004 : bool TheoryPreregistrar::needsActiveSkolemDefs() const { return false; } 61 : : 62 : 11189776 : void TheoryPreregistrar::check() {} 63 : : 64 : 1306132 : void TheoryPreregistrar::addAssertion(CVC5_UNUSED TNode n, 65 : : CVC5_UNUSED TNode skolem, 66 : : CVC5_UNUSED bool isLemma) 67 : : { 68 : 1306132 : } 69 : : 70 : 817197 : void TheoryPreregistrar::notifyActiveSkolemDefs( 71 : : CVC5_UNUSED std::vector<TNode>& defs) 72 : : { 73 : 817197 : } 74 : : 75 : 1292428 : void TheoryPreregistrar::notifySatLiteral(TNode n) 76 : : { 77 : : // if eager policy, send immediately 78 [ + + ]: 1292428 : if (options().prop.preRegisterMode == options::PreRegisterMode::EAGER) 79 : : { 80 [ + - ]: 1292028 : Trace("prereg") << "preregister (eager): " << n << std::endl; 81 : 1292044 : d_theoryEngine->preRegister(n); 82 : : // cache for registration 83 : 1292012 : d_sat_literals.emplace_back(n, d_env.getContext()->getLevel()); 84 : : } 85 : 1292412 : } 86 : : 87 : 1023221 : void TheoryPreregistrar::notifyBacktrack() 88 : : { 89 : 1023221 : uint32_t level = d_env.getContext()->getLevel(); 90 [ + + ]: 1948853 : for (size_t i = 0, n = d_sat_literals.size(); i < n; ++i) 91 : : { 92 : : // We reregister SAT literals from newest to oldest. Changing this order 93 : : // potentially has an impact on performance (quantified instances). 94 : 1945260 : auto& [node, node_level] = d_sat_literals[n - i - 1]; 95 : : 96 [ + + ]: 1945260 : if (node_level <= level) 97 : : { 98 : 1019628 : break; 99 : : } 100 : : 101 : : // Update SAT context level the reregistered SAT literal has been 102 : : // registered at. This is necessary to not reregister literals that 103 : : // are already registered. 104 : 925632 : node_level = level; 105 : : // Reregister all sat literals that have originally been preregistered 106 : : // at a higher level than the current SAT context level. These literals 107 : : // are popped from the SAT context on backtrack but remain in the SAT 108 : : // solver, and thus must be reregistered. 109 [ + - ]: 925632 : Trace("prereg") << "reregister: " << node << std::endl; 110 : : // Note: This call potentially adds to d_sat_literals, which we are 111 : : // currently iterating over. This is not an issue, though, since 112 : : // a) we access it by index and b) any literals added through this 113 : : // call obviously will have node_level == level and don't have to 114 : : // be reregistered. We have to reregister all literals with 115 : : // node_level > level that are located inbetween the currently 116 : : // registered ones and previously registered ones with 117 : : // node_level <= level, which is guaranteed by continuing iteration 118 : : // from the back until the break point while reregistering literals. 119 : 925632 : d_theoryEngine->preRegister(node); 120 : : } 121 : 1023221 : } 122 : : 123 : 28393095 : bool TheoryPreregistrar::notifyAsserted(TNode n) 124 : : { 125 : : // if eager, we've already preregistered it 126 [ + + ]: 28393095 : if (options().prop.preRegisterMode == options::PreRegisterMode::EAGER) 127 : : { 128 : 28392095 : return true; 129 : : } 130 : : // otherwise, we always ensure it is preregistered now, which does nothing 131 : : // if it is already preregistered 132 [ + + ]: 1000 : TNode natom = n.getKind() == Kind::NOT ? n[0] : n; 133 [ + - ]: 1000 : Trace("prereg") << "preregister (lazy): " << natom << std::endl; 134 : 1000 : d_theoryEngine->preRegister(natom); 135 : 1000 : return true; 136 : 1000 : } 137 : : 138 : 0 : void TheoryPreregistrar::preRegisterToTheory( 139 : : const std::vector<TNode>& toPreregister) 140 : : { 141 [ - - ]: 0 : for (TNode n : toPreregister) 142 : : { 143 [ - - ]: 0 : Trace("prereg") << "preregister: " << n << std::endl; 144 : 0 : d_theoryEngine->preRegister(n); 145 : 0 : } 146 : 0 : } 147 : : 148 : : } // namespace prop 149 : : } // namespace cvc5::internal