Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Aina Niemetz, Mathias Preiner 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 : : * Difficulty manager. 14 : : */ 15 : : 16 : : #include "theory/difficulty_manager.h" 17 : : 18 : : #include "expr/node_algorithm.h" 19 : : #include "options/smt_options.h" 20 : : #include "smt/env.h" 21 : : #include "theory/relevance_manager.h" 22 : : #include "theory/theory_model.h" 23 : : #include "util/rational.h" 24 : : 25 : : using namespace cvc5::internal::kind; 26 : : 27 : : namespace cvc5::internal { 28 : : namespace theory { 29 : : 30 : 408 : DifficultyManager::DifficultyManager(Env& env, 31 : : RelevanceManager* rlv, 32 : 408 : Valuation val) 33 : : : EnvObj(env), 34 : : d_rlv(rlv), 35 : 816 : d_input(userContext()), 36 : 816 : d_lemma(userContext()), 37 : : d_val(val), 38 : 408 : d_dfmap(userContext()) 39 : : { 40 : 408 : } 41 : : 42 : 405 : void DifficultyManager::notifyInputAssertions( 43 : : const std::vector<Node>& assertions) 44 : : { 45 [ + + ]: 1147 : for (const Node& a : assertions) 46 : : { 47 : 742 : d_input.insert(a); 48 : : } 49 : 405 : } 50 : : 51 : 395 : void DifficultyManager::getDifficultyMap(std::map<Node, Node>& dmap, 52 : : bool includeLemmas) 53 : : { 54 : 395 : NodeManager* nm = nodeManager(); 55 [ + + ]: 825 : for (const std::pair<const Node, uint64_t> p : d_dfmap) 56 : : { 57 [ + - ]: 430 : if (!includeLemmas) 58 : : { 59 [ + + ]: 430 : if (d_input.find(p.first) == d_input.end()) 60 : : { 61 : 15 : continue; 62 : : } 63 : : } 64 : 415 : dmap[p.first] = nm->mkConstInt(Rational(p.second)); 65 : : } 66 : 395 : } 67 : : 68 : 0 : uint64_t DifficultyManager::getCurrentDifficulty(const Node& n) const 69 : : { 70 : 0 : NodeUIntMap::const_iterator it = d_dfmap.find(n); 71 [ - - ]: 0 : if (it != d_dfmap.end()) 72 : : { 73 : 0 : return it->second; 74 : : } 75 : 0 : return 0; 76 : : } 77 : : 78 : 615 : void DifficultyManager::notifyLemma(Node n, bool inFullEffortCheck) 79 : : { 80 : 615 : d_lemma.insert(n); 81 : : // compute if we should consider the lemma 82 : 615 : bool considerLemma = false; 83 : 615 : if (options().smt.difficultyMode 84 [ + + ]: 615 : == options::DifficultyMode::LEMMA_LITERAL_ALL) 85 : : { 86 : 433 : considerLemma = true; 87 : : } 88 : 182 : else if (options().smt.difficultyMode 89 [ - + ]: 182 : == options::DifficultyMode::LEMMA_LITERAL) 90 : : { 91 : 0 : considerLemma = inFullEffortCheck; 92 : : } 93 [ + + ]: 615 : if (!considerLemma) 94 : : { 95 : 182 : return; 96 : : } 97 [ + - ]: 433 : Trace("diff-man") << "notifyLemma: " << n << std::endl; 98 : 433 : Kind nk = n.getKind(); 99 : : // for lemma (or a_1 ... a_n), if a_i is a literal that is not true in the 100 : : // valuation, then we increment the difficulty of that assertion 101 : 866 : std::vector<Node> litsToCheck; 102 [ + + ]: 433 : if (nk == Kind::OR) 103 : : { 104 : 84 : litsToCheck.insert(litsToCheck.end(), n.begin(), n.end()); 105 : : } 106 [ + + ]: 349 : else if (nk == Kind::IMPLIES) 107 : : { 108 : 115 : litsToCheck.push_back(n[0].negate()); 109 : 115 : litsToCheck.push_back(n[1]); 110 : : } 111 : : else 112 : : { 113 : 234 : litsToCheck.push_back(n); 114 : : } 115 : 433 : size_t index = 0; 116 [ + + ]: 2494 : while (index < litsToCheck.size()) 117 : : { 118 : 2061 : Node nc = litsToCheck[index]; 119 : 2061 : index++; 120 [ + + ]: 2061 : if (expr::isBooleanConnective(nc)) 121 : : { 122 : 1056 : litsToCheck.insert(litsToCheck.end(), nc.begin(), nc.end()); 123 : 1056 : continue; 124 : : } 125 : 2010 : TNode exp = d_rlv->getExplanationForRelevant(nc); 126 [ + - ]: 2010 : Trace("diff-man-debug") 127 : 1005 : << "Check literal: " << nc << ", has reason = " << (!exp.isNull()) 128 : 1005 : << std::endl; 129 : : // could be input assertion or lemma 130 [ + + ]: 1005 : if (!exp.isNull()) 131 : : { 132 : 537 : incrementDifficulty(exp); 133 : : } 134 : : } 135 : : } 136 : : 137 : 300 : bool DifficultyManager::needsCandidateModel() const 138 : : { 139 : 300 : return options().smt.difficultyMode == options::DifficultyMode::MODEL_CHECK; 140 : : } 141 : : 142 : 33 : void DifficultyManager::notifyCandidateModel(TheoryModel* m) 143 : : { 144 [ - + ][ - + ]: 33 : Assert(needsCandidateModel()); [ - - ] 145 [ + - ]: 66 : Trace("diff-man") << "DifficultyManager::notifyCandidateModel, #input=" 146 : 33 : << d_input.size() << " #lemma=" << d_lemma.size() 147 : 33 : << std::endl; 148 [ + + ]: 99 : for (size_t i = 0; i < 2; i++) 149 : : { 150 [ + + ]: 66 : NodeSet& ns = i == 0 ? d_input : d_lemma; 151 [ + + ]: 1117 : for (const Node& a : ns) 152 : : { 153 : : // check if each input is satisfied 154 : 1051 : Node av = m->getValue(a); 155 [ + + ][ + + ]: 1051 : if (av.isConst() && av.getConst<bool>()) [ + + ] 156 : : { 157 : 967 : continue; 158 : : } 159 [ + - ]: 84 : Trace("diff-man") << " not true: " << a << std::endl; 160 : : // not satisfied, increment counter 161 : 84 : incrementDifficulty(a); 162 : : } 163 : : } 164 [ + - ]: 33 : Trace("diff-man") << std::endl; 165 : 33 : } 166 : 621 : void DifficultyManager::incrementDifficulty(TNode a, uint64_t amount) 167 : : { 168 [ - + ][ - + ]: 621 : Assert(a.getType().isBoolean()); [ - - ] 169 [ + - ]: 1242 : Trace("diff-man") << "incrementDifficulty: " << a << " +" << amount 170 : 621 : << std::endl; 171 : 621 : d_dfmap[a] = d_dfmap[a] + amount; 172 : 621 : } 173 : : 174 : : } // namespace theory 175 : : } // namespace cvc5::internal