LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory - difficulty_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 79 85 92.9 %
Date: 2026-03-11 10:41:32 Functions: 7 8 87.5 %
Branches: 52 70 74.3 %

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

Generated by: LCOV version 1.14