LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/prop - zero_level_learner.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 215 238 90.3 %
Date: 2026-09-12 10:08:15 Functions: 17 17 100.0 %
Branches: 136 186 73.1 %

           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                 :            :  * Learner for literals asserted at level zero.
      11                 :            :  */
      12                 :            : #include "prop/zero_level_learner.h"
      13                 :            : 
      14                 :            : #include "context/context.h"
      15                 :            : #include "expr/node_algorithm.h"
      16                 :            : #include "expr/skolem_manager.h"
      17                 :            : #include "options/base_options.h"
      18                 :            : #include "options/prop_options.h"
      19                 :            : #include "options/smt_options.h"
      20                 :            : #include "smt/env.h"
      21                 :            : #include "theory/theory_engine.h"
      22                 :            : #include "theory/trust_substitutions.h"
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : namespace prop {
      26                 :            : 
      27                 :         33 : ZeroLevelLearner::ZeroLevelLearner(Env& env, TheoryEngine* theoryEngine)
      28                 :            :     : EnvObj(env),
      29                 :         33 :       d_theoryEngine(theoryEngine),
      30                 :         33 :       d_levelZeroAsserts(userContext()),
      31                 :         33 :       d_ldb(userContext()),
      32                 :         33 :       d_nonZeroAssert(context(), false),
      33                 :         33 :       d_ppnAtoms(userContext()),
      34                 :         33 :       d_ppnTerms(userContext()),
      35                 :         33 :       d_ppnSyms(userContext()),
      36                 :         33 :       d_assertNoLearnCount(0),
      37                 :         66 :       d_tsmap(env, userContext(), "ZllSimplificationMap")
      38                 :            : {
      39                 :            :   // get the learned types
      40                 :         33 :   options::DeepRestartMode lmode = options().smt.deepRestartMode;
      41         [ +  + ]:         33 :   if (lmode != options::DeepRestartMode::NONE)
      42                 :            :   {
      43                 :         15 :     d_learnedTypes.insert(modes::LearnedLitType::INPUT);
      44         [ -  + ]:         15 :     if (lmode == options::DeepRestartMode::ALL)
      45                 :            :     {
      46                 :          0 :       d_learnedTypes.insert(modes::LearnedLitType::INTERNAL);
      47                 :          0 :       d_learnedTypes.insert(modes::LearnedLitType::SOLVABLE);
      48                 :          0 :       d_learnedTypes.insert(modes::LearnedLitType::CONSTANT_PROP);
      49                 :            :     }
      50         [ -  + ]:         15 :     else if (lmode == options::DeepRestartMode::INPUT_AND_SOLVABLE)
      51                 :            :     {
      52                 :          0 :       d_learnedTypes.insert(modes::LearnedLitType::SOLVABLE);
      53                 :            :     }
      54         [ +  + ]:         15 :     else if (lmode == options::DeepRestartMode::INPUT_AND_PROP)
      55                 :            :     {
      56                 :          2 :       d_learnedTypes.insert(modes::LearnedLitType::SOLVABLE);
      57                 :          2 :       d_learnedTypes.insert(modes::LearnedLitType::CONSTANT_PROP);
      58                 :            :     }
      59                 :            :   }
      60                 :         33 :   d_trackSimplifications = true;
      61                 :         33 : }
      62                 :            : 
      63                 :         66 : ZeroLevelLearner::~ZeroLevelLearner() {}
      64                 :            : 
      65                 :        131 : void ZeroLevelLearner::getAtoms(TNode a,
      66                 :            :                                 std::unordered_set<TNode>& visited,
      67                 :            :                                 std::unordered_set<Node>& atoms)
      68                 :            : {
      69                 :        131 :   std::vector<TNode> visit;
      70                 :        131 :   TNode cur;
      71                 :        131 :   visit.push_back(a);
      72                 :            :   do
      73                 :            :   {
      74                 :        289 :     cur = visit.back();
      75                 :        289 :     visit.pop_back();
      76         [ +  + ]:        289 :     if (visited.find(cur) == visited.end())
      77                 :            :     {
      78                 :        187 :       visited.insert(cur);
      79         [ +  + ]:        187 :       if (expr::isBooleanConnective(cur))
      80                 :            :       {
      81                 :         82 :         visit.insert(visit.end(), cur.begin(), cur.end());
      82                 :         82 :         continue;
      83                 :            :       }
      84                 :        105 :       atoms.insert(cur);
      85                 :            :     }
      86         [ +  + ]:        289 :   } while (!visit.empty());
      87                 :        131 : }
      88                 :            : 
      89                 :          6 : void ZeroLevelLearner::notifyTopLevelSubstitution(const Node& lhs,
      90                 :            :                                                   const Node& rhs)
      91                 :            : {
      92                 :            :   // process as a preprocess solved learned literal.
      93                 :          6 :   Node eq = lhs.eqNode(rhs);
      94                 :          6 :   processLearnedLiteral(eq, modes::LearnedLitType::PREPROCESS_SOLVED);
      95                 :          6 : }
      96                 :            : 
      97                 :         32 : void ZeroLevelLearner::notifyInputFormulas(const std::vector<Node>& assertions)
      98                 :            : {
      99                 :         32 :   std::unordered_set<TNode> visited;
     100                 :         32 :   std::unordered_set<TNode> visitedWithinAtom;
     101                 :         32 :   std::unordered_set<Node> inputSymbols;
     102                 :            :   // We consider top level literals of assertions, including those occurring
     103                 :            :   // as children of AND to be the preprocessed learned literals only, and not
     104                 :            :   // the literals tracked by the preprocessor
     105                 :            :   // (Preprocessor::getLearnedLiterals). This means that a learned literal from
     106                 :            :   // e.g. circuit propagation that is not trivially a top level assertion will
     107                 :            :   // be considered an ordinary learned literal.
     108                 :            :   // Note that d_pplAtoms and d_ppnAtoms are disjoint
     109                 :         32 :   std::vector<Node> toProcess = assertions;
     110                 :         32 :   size_t index = 0;
     111         [ +  + ]:        163 :   while (index < toProcess.size())
     112                 :            :   {
     113                 :        131 :     TNode lit = toProcess[index];
     114                 :        131 :     index++;
     115         [ -  + ]:        131 :     if (lit.getKind() == Kind::AND)
     116                 :            :     {
     117                 :          0 :       toProcess.insert(toProcess.end(), lit.begin(), lit.end());
     118                 :          0 :       continue;
     119                 :            :     }
     120         [ +  + ]:        131 :     TNode atom = lit.getKind() == Kind::NOT ? lit[0] : lit;
     121         [ +  + ]:        131 :     if (expr::isBooleanConnective(atom))
     122                 :            :     {
     123                 :         46 :       continue;
     124                 :            :     }
     125                 :            :     // we mark that we visited this
     126                 :         85 :     visited.insert(atom);
     127                 :            :     // ignore the true node
     128 [ +  + ][ +  + ]:         85 :     if (!lit.isConst() || !lit.getConst<bool>())
                 [ +  + ]
     129                 :            :     {
     130                 :            :       // output learned literals from preprocessing
     131         [ +  - ]:         44 :       if (d_trackSimplifications)
     132                 :            :       {
     133                 :         44 :         computeLearnedLiteralType(lit);
     134                 :            :       }
     135                 :         44 :       processLearnedLiteral(lit, modes::LearnedLitType::PREPROCESS);
     136                 :            :       // also get its symbols
     137                 :         44 :       expr::getSymbols(atom, inputSymbols, visitedWithinAtom);
     138                 :            :     }
     139                 :            :     // remember we've seen it
     140                 :         85 :     d_levelZeroAsserts.insert(lit);
     141 [ +  + ][ +  + ]:        177 :   }
     142                 :            :   // Compute the set of literals in the preprocessed assertions
     143                 :         32 :   std::unordered_set<Node> inputAtoms;
     144         [ +  + ]:        163 :   for (const Node& a : assertions)
     145                 :            :   {
     146                 :        131 :     getAtoms(a, visited, inputAtoms);
     147                 :            :   }
     148         [ +  + ]:        137 :   for (const Node& a : inputAtoms)
     149                 :            :   {
     150                 :        105 :     d_ppnAtoms.insert(a);
     151                 :            :     // also get its symbols
     152                 :        105 :     expr::getSymbols(a, inputSymbols, visitedWithinAtom);
     153                 :            :   }
     154         [ +  + ]:        504 :   for (const TNode& t : visitedWithinAtom)
     155                 :            :   {
     156                 :        472 :     d_ppnTerms.insert(t);
     157                 :            :   }
     158         [ +  + ]:        132 :   for (const Node& s : inputSymbols)
     159                 :            :   {
     160                 :        100 :     d_ppnSyms.insert(s);
     161                 :            :   }
     162                 :            : 
     163         [ +  - ]:         32 :   Trace("level-zero") << "Preprocess status:" << std::endl;
     164         [ +  - ]:         64 :   Trace("level-zero") << "#Non-learned lits = " << d_ppnAtoms.size()
     165                 :         32 :                       << std::endl;
     166         [ +  - ]:         32 :   Trace("level-zero") << "#Symbols = " << d_ppnSyms.size() << std::endl;
     167         [ +  - ]:         32 :   Trace("level-zero") << "#Subterms = " << d_ppnTerms.size() << std::endl;
     168         [ +  - ]:         64 :   Trace("level-zero") << "#Current top level subs = "
     169                 :         32 :                       << d_env.getTopLevelSubstitutions().get().size()
     170                 :         32 :                       << std::endl;
     171 [ +  - ][ -  + ]:         32 :   Trace("level-zero") << d_ldb.toStringDebug();
                 [ -  - ]
     172                 :            :   // the threshold is by default d_ppnAtoms.size()*3.0, which means we restart
     173                 :            :   // if we have learned any literals, and the number of assertions since the
     174                 :            :   // last learned literal is equal to the total number of literals in the
     175                 :            :   // input problem times 3, i.e. each literal has been asserted on average 3
     176                 :            :   // times.
     177                 :         32 :   d_deepRestartThreshold = static_cast<size_t>(
     178                 :         32 :       static_cast<double>(d_ppnAtoms.size()) * options().smt.deepRestartFactor);
     179         [ +  - ]:         64 :   Trace("level-zero") << "Restart threshold is " << d_deepRestartThreshold
     180                 :         32 :                       << std::endl;
     181                 :         32 : }
     182                 :            : 
     183                 :        404 : bool ZeroLevelLearner::notifyAsserted(TNode assertion, int32_t alevel)
     184                 :            : {
     185                 :            :   // check if at level zero
     186         [ +  + ]:        404 :   if (d_nonZeroAssert.get())
     187                 :            :   {
     188                 :            :     // already not at level zero, skip
     189                 :        224 :     d_assertNoLearnCount++;
     190                 :            :   }
     191         [ +  + ]:        180 :   else if (alevel != 0)
     192                 :            :   {
     193         [ +  - ]:         28 :     Trace("level-zero-dec") << "First non-zero: " << assertion << std::endl;
     194                 :         28 :     d_nonZeroAssert = true;
     195                 :         28 :     d_assertNoLearnCount++;
     196                 :            :   }
     197         [ +  + ]:        152 :   else if (d_levelZeroAsserts.find(assertion) == d_levelZeroAsserts.end())
     198                 :            :   {
     199                 :            :     // remember we've processed this
     200                 :        117 :     d_levelZeroAsserts.insert(assertion);
     201                 :            :     // process what we should do with the learned literal
     202                 :        117 :     modes::LearnedLitType ltype = computeLearnedLiteralType(assertion);
     203                 :        117 :     processLearnedLiteral(assertion, ltype);
     204                 :        117 :     return true;
     205                 :            :   }
     206                 :            :   // request a deep restart?
     207         [ +  + ]:        287 :   if (options().smt.deepRestartMode != options::DeepRestartMode::NONE)
     208                 :            :   {
     209         [ +  + ]:        193 :     if (hasLearnedLiteralForRestart() > 0)
     210                 :            :     {
     211                 :            :       // if non-empty and non-learned atoms have been asserted beyond the
     212                 :            :       // threshold
     213         [ +  + ]:        128 :       if (d_assertNoLearnCount > d_deepRestartThreshold)
     214                 :            :       {
     215         [ +  - ]:         14 :         Trace("level-zero") << "DEEP RESTART after " << d_assertNoLearnCount
     216                 :          7 :                             << " asserts." << std::endl;
     217                 :          7 :         return false;
     218                 :            :       }
     219                 :            :     }
     220                 :            :   }
     221         [ -  + ]:        280 :   if (TraceIsOn("level-zero-debug"))
     222                 :            :   {
     223 [ -  - ][ -  - ]:          0 :     if (d_assertNoLearnCount > 0 && d_deepRestartThreshold > 0
     224         [ -  - ]:          0 :         && d_assertNoLearnCount % d_deepRestartThreshold == 0)
     225                 :            :     {
     226         [ -  - ]:          0 :       Trace("level-zero-debug")
     227                 :          0 :           << "#asserts without learning = " << d_assertNoLearnCount << " ("
     228                 :          0 :           << (d_assertNoLearnCount / d_deepRestartThreshold) << "x)"
     229                 :          0 :           << std::endl;
     230                 :            :     }
     231                 :            :   }
     232                 :        280 :   return true;
     233                 :            : }
     234                 :            : 
     235                 :        161 : modes::LearnedLitType ZeroLevelLearner::computeLearnedLiteralType(
     236                 :            :     const Node& input)
     237                 :            : {
     238                 :            :   // literal was learned, determine its type
     239                 :            :   // compute whether internal prior to substitution
     240         [ +  + ]:        161 :   TNode aatom = input.getKind() == Kind::NOT ? input[0] : input;
     241                 :        161 :   bool internal = d_ppnAtoms.find(aatom) == d_ppnAtoms.end();
     242                 :            :   // apply substitutions now
     243                 :        161 :   Node lit = d_tsmap.apply(input, d_env.getRewriter());
     244                 :        161 :   modes::LearnedLitType ltype =
     245         [ +  + ]:        161 :       internal ? modes::LearnedLitType::INTERNAL : modes::LearnedLitType::INPUT;
     246                 :            :   // we don't try to solve for literals that simplify to constants
     247 [ +  + ][ +  - ]:        161 :   if ((internal || d_trackSimplifications) && !lit.isConst())
         [ +  + ][ +  + ]
     248                 :            :   {
     249                 :        133 :     Subs ss;
     250                 :        133 :     bool processed = false;
     251         [ +  + ]:        133 :     if (getSolved(lit, ss))
     252                 :            :     {
     253                 :            :       // if we solved for any variable from input, we are SOLVABLE.
     254         [ +  + ]:         86 :       for (size_t i = 0, nvars = ss.d_vars.size(); i < nvars; i++)
     255                 :            :       {
     256                 :         43 :         Node v = ss.d_vars[i];
     257         [ +  + ]:         43 :         if (d_ppnSyms.find(v) != d_ppnSyms.end())
     258                 :            :         {
     259         [ +  - ]:         31 :           Trace("level-zero-assert") << "...solvable due to " << v << std::endl;
     260         [ +  + ]:         31 :           if (ltype == modes::LearnedLitType::INTERNAL)
     261                 :            :           {
     262                 :          1 :             ltype = modes::LearnedLitType::SOLVABLE;
     263                 :            :           }
     264                 :            :         }
     265         [ +  - ]:         43 :         if (d_trackSimplifications)
     266                 :            :         {
     267                 :         43 :           bool addSubs = true;
     268         [ +  - ]:         43 :           switch (options().theory.lemmaInprocessSubsMode)
     269                 :            :           {
     270                 :         43 :             case options::LemmaInprocessSubsMode::SIMPLE:
     271                 :         43 :               addSubs = ss.d_subs[i].getNumChildren() == 0;
     272                 :         43 :               break;
     273                 :          0 :             default: break;
     274                 :            :           }
     275         [ +  + ]:         43 :           if (addSubs)
     276                 :            :           {
     277                 :         23 :             processed = true;
     278         [ +  - ]:         46 :             Trace("lemma-inprocess-subs")
     279                 :         23 :                 << "Add subs: " << v << " -> " << ss.d_subs[i] << std::endl;
     280                 :         23 :             addSimplification(v, ss.d_subs[i]);
     281                 :            :           }
     282                 :            :         }
     283                 :         43 :       }
     284                 :            :     }
     285 [ +  - ][ +  + ]:        133 :     if ((d_trackSimplifications && !processed)
     286         [ +  - ]:         23 :         || ltype != modes::LearnedLitType::SOLVABLE)
     287                 :            :     {
     288                 :            :       // maybe a constant prop?
     289         [ +  + ]:        133 :       if (lit.getKind() == Kind::EQUAL)
     290                 :            :       {
     291         [ +  + ]:        115 :         for (size_t i = 0; i < 2; i++)
     292                 :            :         {
     293                 :            :           // Only consider substitutions whose RHS are constants.
     294                 :            :           // A more general policy could consider lit[i].getNumChildren()==0.
     295         [ +  + ]:         88 :           if (lit[i].isConst())
     296                 :            :           {
     297                 :         60 :             if (ltype == modes::LearnedLitType::INTERNAL
     298 [ +  + ][ +  + ]:         30 :                 && d_ppnTerms.find(lit[1 - i]) != d_ppnTerms.end())
         [ +  + ][ +  + ]
                 [ -  - ]
     299                 :            :             {
     300                 :          2 :               ltype = modes::LearnedLitType::CONSTANT_PROP;
     301                 :            :             }
     302 [ +  - ][ +  + ]:         30 :             if (d_trackSimplifications && !processed)
     303                 :            :             {
     304         [ +  - ]:         30 :               Trace("lemma-inprocess-subs")
     305                 :         15 :                   << "Add cp: " << lit[1 - i] << " -> " << lit[i] << std::endl;
     306                 :         15 :               addSimplification(lit[1 - i], lit[i]);
     307                 :         15 :               processed = true;
     308                 :            :             }
     309                 :         30 :             break;
     310                 :            :           }
     311         [ +  + ]:         58 :           else if ((d_trackSimplifications && !processed)
     312                 :        116 :                    && expr::hasSubterm(lit[1 - i], lit[i]))
     313                 :            :           {
     314                 :          0 :             Trace("lemma-inprocess-subs") << "Add cp subterm: " << lit[1 - i]
     315                 :          0 :                                           << " -> " << lit[i] << std::endl;
     316                 :          0 :             addSimplification(lit[1 - i], lit[i]);
     317                 :          0 :             processed = true;
     318                 :          0 :             break;
     319                 :            :           }
     320                 :            :         }
     321                 :            :       }
     322         [ +  + ]:        133 :       if (!processed)
     323                 :            :       {
     324         [ +  - ]:        190 :         Trace("lemma-inprocess-subs-n")
     325                 :         95 :             << "Unused unit learned: " << lit << std::endl;
     326                 :            :       }
     327                 :            :     }
     328                 :        133 :   }
     329         [ +  - ]:        322 :   Trace("level-zero-assert")
     330                 :        161 :       << "Level zero assert: " << lit << ", type=" << ltype << std::endl;
     331                 :        161 :   return ltype;
     332                 :        161 : }
     333                 :            : 
     334                 :          5 : theory::TrustSubstitutionMap& ZeroLevelLearner::getSimplifications()
     335                 :            : {
     336 [ -  + ][ -  + ]:          5 :   Assert(d_trackSimplifications);
                 [ -  - ]
     337                 :          5 :   return d_tsmap;
     338                 :            : }
     339                 :            : 
     340                 :         38 : void ZeroLevelLearner::addSimplification(const Node& t, const Node& s)
     341                 :            : {
     342                 :            :   // in rare cases we may already have a substitution for v, e.g.
     343                 :            :   // if x -> 0, (f y) ---> a, and we learn (f (+ x y)) = b, we
     344                 :            :   // would substitute+rewrite to get (f y) --> b despite already
     345                 :            :   // having a substitution for (f y). We could avoid this by applying
     346                 :            :   // substitution+rewriting until fixed point at the beginning of
     347                 :            :   // computeLearnedLiteralType, but this may be expensive.
     348         [ +  + ]:         38 :   if (!d_tsmap.get().hasSubstitution(t))
     349                 :            :   {
     350                 :         36 :     d_tsmap.addSubstitution(t, s);
     351                 :            :   }
     352                 :         38 : }
     353                 :            : 
     354                 :        167 : void ZeroLevelLearner::processLearnedLiteral(const Node& lit,
     355                 :            :                                              modes::LearnedLitType ltype)
     356                 :            : {
     357                 :            :   // add to the database
     358                 :        167 :   d_ldb.addLearnedLiteral(lit, ltype);
     359                 :            :   // reset the counter for deep restart if the literal was learnable
     360         [ +  + ]:        167 :   if (isLearnable(ltype))
     361                 :            :   {
     362                 :         25 :     d_assertNoLearnCount = 0;
     363                 :            :   }
     364                 :            :   // print to stream
     365         [ +  + ]:        167 :   if (isOutputOn(OutputTag::LEARNED_LITS))
     366                 :            :   {
     367                 :            :     // get the original form so that internally generated variables
     368                 :            :     // are mapped back to their original form
     369                 :          6 :     output(OutputTag::LEARNED_LITS)
     370                 :          6 :         << "(learned-lit " << SkolemManager::getOriginalForm(lit);
     371                 :          6 :     std::stringstream tss;
     372                 :          6 :     tss << ltype;
     373                 :          6 :     std::string ltstr = tss.str();
     374                 :          6 :     std::transform(
     375                 :         40 :         ltstr.begin(), ltstr.end(), ltstr.begin(), [](unsigned char c) {
     376                 :         40 :           return std::tolower(c);
     377                 :            :         });
     378                 :          6 :     output(OutputTag::LEARNED_LITS) << " :" << ltstr;
     379                 :          6 :     output(OutputTag::LEARNED_LITS) << ")" << std::endl;
     380                 :          6 :   }
     381                 :        167 : }
     382                 :            : 
     383                 :         29 : std::vector<Node> ZeroLevelLearner::getLearnedZeroLevelLiterals(
     384                 :            :     modes::LearnedLitType ltype) const
     385                 :            : {
     386                 :         29 :   std::vector<Node> ret = d_ldb.getLearnedLiterals(ltype);
     387         [ -  + ]:         29 :   if (TraceIsOn("level-zero"))
     388                 :            :   {
     389         [ -  - ]:          0 :     if (!ret.empty())
     390                 :            :     {
     391         [ -  - ]:          0 :       Trace("level-zero") << "...learned #literals (" << ltype
     392                 :          0 :                           << ") = " << ret.size() << std::endl;
     393                 :            :     }
     394                 :            :   }
     395                 :         29 :   return ret;
     396                 :          0 : }
     397                 :            : 
     398                 :          7 : std::vector<Node> ZeroLevelLearner::getLearnedZeroLevelLiteralsForRestart()
     399                 :            :     const
     400                 :            : {
     401                 :          7 :   std::vector<Node> ret;
     402         [ +  + ]:         16 :   for (modes::LearnedLitType ltype : d_learnedTypes)
     403                 :            :   {
     404                 :          9 :     std::vector<Node> rett = getLearnedZeroLevelLiterals(ltype);
     405                 :          9 :     ret.insert(ret.end(), rett.begin(), rett.end());
     406                 :          9 :   }
     407                 :          7 :   return ret;
     408                 :          0 : }
     409                 :            : 
     410                 :        193 : bool ZeroLevelLearner::hasLearnedLiteralForRestart() const
     411                 :            : {
     412         [ +  + ]:        269 :   for (modes::LearnedLitType ltype : d_learnedTypes)
     413                 :            :   {
     414         [ +  + ]:        204 :     if (d_ldb.getNumLearnedLiterals(ltype) > 0)
     415                 :            :     {
     416                 :        128 :       return true;
     417                 :            :     }
     418                 :            :   }
     419                 :         65 :   return false;
     420                 :            : }
     421                 :            : 
     422                 :        167 : bool ZeroLevelLearner::isLearnable(modes::LearnedLitType ltype) const
     423                 :            : {
     424                 :        167 :   return d_learnedTypes.find(ltype) != d_learnedTypes.end();
     425                 :            : }
     426                 :            : 
     427                 :        133 : bool ZeroLevelLearner::getSolved(const Node& lit, Subs& subs)
     428                 :            : {
     429                 :        133 :   context::Context dummyContext;
     430                 :        266 :   theory::TrustSubstitutionMap subsOut(d_env, &dummyContext);
     431                 :        133 :   TrustNode tlit = TrustNode::mkTrustLemma(lit);
     432                 :        133 :   bool status = d_theoryEngine->solve(tlit, subsOut);
     433         [ +  + ]:        133 :   if (status)
     434                 :            :   {
     435         [ +  - ]:         43 :     Trace("level-zero-debug") << lit << " is solvable" << std::endl;
     436                 :            :     // extract the substitution
     437                 :         43 :     std::unordered_map<Node, Node> ss = subsOut.get().getSubstitutions();
     438         [ +  + ]:         86 :     for (const std::pair<const Node, Node>& s : ss)
     439                 :            :     {
     440                 :         43 :       subs.add(s.first, s.second);
     441         [ +  - ]:         86 :       Trace("level-zero-debug")
     442                 :         43 :           << "  subs: " << s.first << " -> " << s.second << std::endl;
     443                 :            :     }
     444                 :         43 :     return true;
     445                 :         43 :   }
     446         [ +  - ]:         90 :   Trace("level-zero-debug") << lit << " is not solvable" << std::endl;
     447                 :         90 :   return false;
     448                 :        133 : }
     449                 :            : 
     450                 :            : }  // namespace prop
     451                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14