LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/smt - proof_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 207 258 80.2 %
Date: 2026-07-22 10:35:40 Functions: 14 17 82.4 %
Branches: 100 184 54.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                 :            :  * The proof manager of the SMT engine.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "smt/proof_manager.h"
      14                 :            : 
      15                 :            : #include "expr/subtype_elim_node_converter.h"
      16                 :            : #include "options/base_options.h"
      17                 :            : #include "options/main_options.h"
      18                 :            : #include "options/smt_options.h"
      19                 :            : #include "proof/alethe/alethe_node_converter.h"
      20                 :            : #include "proof/alethe/alethe_post_processor.h"
      21                 :            : #include "proof/alethe/alethe_printer.h"
      22                 :            : #include "proof/dot/dot_printer.h"
      23                 :            : #include "proof/eo/eo_printer.h"
      24                 :            : #include "proof/lfsc/lfsc_post_processor.h"
      25                 :            : #include "proof/lfsc/lfsc_printer.h"
      26                 :            : #include "proof/proof_checker.h"
      27                 :            : #include "proof/proof_node_algorithm.h"
      28                 :            : #include "proof/proof_node_manager.h"
      29                 :            : #include "rewriter/rewrite_db.h"
      30                 :            : #include "smt/assertions.h"
      31                 :            : #include "smt/difficulty_post_processor.h"
      32                 :            : #include "smt/env.h"
      33                 :            : #include "smt/preprocess_proof_generator.h"
      34                 :            : #include "smt/proof_logger.h"
      35                 :            : #include "smt/proof_post_processor.h"
      36                 :            : #include "smt/smt_solver.h"
      37                 :            : 
      38                 :            : using namespace cvc5::internal::rewriter;
      39                 :            : namespace cvc5::internal {
      40                 :            : namespace smt {
      41                 :            : 
      42                 :      15170 : PfManager::PfManager(Env& env)
      43                 :            :     : EnvObj(env),
      44                 :      15170 :       d_rewriteDb(nullptr),
      45                 :      15170 :       d_pchecker(nullptr),
      46                 :      15170 :       d_pnm(nullptr),
      47                 :      15170 :       d_pfpp(nullptr),
      48                 :      15170 :       d_pppg(nullptr),
      49                 :      15170 :       d_finalCb(env),
      50                 :      45510 :       d_finalizer(env, d_finalCb)
      51                 :            : {
      52                 :            :   // construct the rewrite db only if DSL rewrites are enabled
      53                 :      15170 :   if (options().proof.proofGranularityMode
      54                 :            :           == options::ProofGranularityMode::DSL_REWRITE
      55 [ +  + ][ -  + ]:      15170 :       || options().proof.proofGranularityMode
                 [ +  + ]
      56                 :            :              == options::ProofGranularityMode::DSL_REWRITE_STRICT)
      57                 :            :   {
      58                 :       6764 :     d_rewriteDb.reset(new RewriteDb(nodeManager()));
      59                 :            :     // maybe output rare rules?
      60                 :       6764 :     bool isNormalOut = isOutputOn(OutputTag::RARE_DB);
      61                 :       6764 :     bool isExpertOut = isOutputOn(OutputTag::RARE_DB_EXPERT);
      62 [ +  - ][ -  + ]:       6764 :     if (isNormalOut || isExpertOut)
      63                 :            :     {
      64         [ -  - ]:          0 :       if (options().proof.proofFormatMode != options::ProofFormatMode::CPC)
      65                 :            :       {
      66         [ -  - ]:          0 :         Warning()
      67                 :            :             << "WARNING: Assuming --proof-format=cpc when printing the RARE "
      68                 :          0 :                "database with -o rare-db(-expert)"
      69                 :          0 :             << std::endl;
      70                 :            :       }
      71                 :          0 :       proof::EoNodeConverter atp(nodeManager());
      72                 :          0 :       proof::EoPrinter eop(d_env, atp, d_rewriteDb.get());
      73                 :            :       const std::map<ProofRewriteRule, RewriteProofRule>& rules =
      74                 :          0 :           d_rewriteDb->getAllRules();
      75         [ -  - ]:          0 :       for (const std::pair<const ProofRewriteRule, RewriteProofRule>& r : rules)
      76                 :            :       {
      77                 :            :         // only output if the signature level is what we want
      78                 :          0 :         Level l = r.second.getSignatureLevel();
      79 [ -  - ][ -  - ]:          0 :         if (l == Level::NORMAL && isNormalOut)
      80                 :            :         {
      81                 :          0 :           std::ostream& os = output(OutputTag::RARE_DB);
      82                 :          0 :           eop.printDslRule(os, r.first);
      83                 :          0 :         }
      84 [ -  - ][ -  - ]:          0 :         else if (l == Level::EXPERT && isExpertOut)
      85                 :            :         {
      86                 :          0 :           std::ostream& os = output(OutputTag::RARE_DB_EXPERT);
      87                 :          0 :           eop.printDslRule(os, r.first);
      88                 :            :         }
      89                 :            :       }
      90                 :          0 :     }
      91                 :            :   }
      92                 :            : 
      93                 :            :   // enable the proof checker and the proof node manager
      94                 :      15170 :   d_pchecker.reset(
      95                 :      15170 :       new ProofChecker(statisticsRegistry(),
      96                 :      15170 :                        options().proof.proofCheck,
      97                 :      15170 :                        static_cast<uint32_t>(options().proof.proofPedantic),
      98                 :      15170 :                        d_rewriteDb.get()));
      99                 :      30340 :   d_pnm.reset(new ProofNodeManager(env.getNodeManager(),
     100                 :      15170 :                                    env.getOptions(),
     101                 :      15170 :                                    env.getRewriter(),
     102                 :      15170 :                                    d_pchecker.get()));
     103                 :            :   // Now, initialize the proof postprocessor with the environment.
     104                 :            :   // By default the post-processor will update all assumptions, which
     105                 :            :   // can lead to SCOPE subproofs of the form
     106                 :            :   //   A
     107                 :            :   //  ...
     108                 :            :   //   B1    B2
     109                 :            :   //  ...   ...
     110                 :            :   // ------------
     111                 :            :   //      C
     112                 :            :   // ------------- SCOPE [B1, B2]
     113                 :            :   // B1 ^ B2 => C
     114                 :            :   //
     115                 :            :   // where A is an available assumption from outside the scope (note
     116                 :            :   // that B1 was an assumption of this SCOPE subproof but since it could
     117                 :            :   // be inferred from A, it was updated). This shape is problematic for
     118                 :            :   // the Alethe reconstruction, so we disable the update of scoped
     119                 :            :   // assumptions (which would disable the update of B1 in this case).
     120                 :      15170 :   d_pfpp = std::make_unique<ProofPostprocess>(
     121                 :            :       env,
     122                 :      15170 :       d_rewriteDb.get(),
     123                 :      30340 :       options().proof.proofFormatMode != options::ProofFormatMode::ALETHE);
     124                 :            : 
     125                 :            :   // add rules to eliminate here
     126                 :      15170 :   if (options().proof.proofGranularityMode
     127         [ +  + ]:      15170 :       != options::ProofGranularityMode::MACRO)
     128                 :            :   {
     129                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_SR_EQ_INTRO);
     130                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_SR_PRED_INTRO);
     131                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_SR_PRED_ELIM);
     132                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_SR_PRED_TRANSFORM);
     133                 :            :     // Alethe does not require chain multiset resolution to be expanded,
     134                 :            :     // LFSC requires it to be expanded.
     135                 :       8700 :     if ((options().proof.proofFormatMode != options::ProofFormatMode::ALETHE
     136         [ +  - ]:       6810 :          && !options().proof.proofChainMRes)
     137 [ +  + ][ +  + ]:      15510 :         || options().proof.proofFormatMode == options::ProofFormatMode::LFSC)
                 [ +  + ]
     138                 :            :     {
     139                 :       1930 :       d_pfpp->setEliminateRule(ProofRule::CHAIN_M_RESOLUTION);
     140                 :            :     }
     141                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_ARITH_SCALE_SUM_UB);
     142                 :       8700 :     if (options().proof.proofGranularityMode
     143         [ +  - ]:       8700 :         != options::ProofGranularityMode::REWRITE)
     144                 :            :     {
     145                 :       8700 :       d_pfpp->setEliminateRule(ProofRule::SUBS);
     146                 :       8700 :       d_pfpp->setEliminateRule(ProofRule::MACRO_REWRITE);
     147                 :            :       // if in a DSL rewrite mode
     148                 :       8700 :       if (options().proof.proofGranularityMode
     149         [ +  + ]:       8700 :           != options::ProofGranularityMode::THEORY_REWRITE)
     150                 :            :       {
     151                 :            :         // this eliminates theory rewriting steps with finer-grained DSL rules
     152                 :       6764 :         d_pfpp->setEliminateAllTrustedRules();
     153                 :            :       }
     154                 :            :     }
     155                 :            :     // theory-specific lazy proof reconstruction
     156                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_STRING_INFERENCE);
     157                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::MACRO_BV_BITBLAST);
     158                 :            :     // we only try to eliminate TRUST if not macro level
     159                 :       8700 :     d_pfpp->setEliminateRule(ProofRule::TRUST);
     160                 :            :   }
     161                 :      15170 :   d_false = nodeManager()->mkConst(false);
     162                 :            : 
     163                 :      15170 :   d_pppg = std::make_unique<PreprocessProofGenerator>(
     164                 :      15170 :       d_env, userContext(), "smt::PreprocessProofGenerator");
     165                 :      15170 : }
     166                 :            : 
     167                 :      30339 : PfManager::~PfManager() {}
     168                 :            : 
     169                 :            : // TODO: Remove in favor of `std::erase_if` with C++ 20+ (see cvc5-wishues#137).
     170                 :            : template <class T, class Alloc, class Pred>
     171                 :      10588 : constexpr typename std::vector<T, Alloc>::size_type erase_if(
     172                 :            :     std::vector<T, Alloc>& c, Pred pred)
     173                 :            : {
     174                 :            :   typename std::vector<T, Alloc>::iterator it =
     175                 :      10588 :       std::remove_if(c.begin(), c.end(), pred);
     176                 :      10588 :   typename std::vector<T, Alloc>::size_type r = std::distance(it, c.end());
     177                 :      10588 :   c.erase(it, c.end());
     178                 :      10588 :   return r;
     179                 :            : }
     180                 :            : 
     181                 :          0 : void PfManager::startProofLogging(std::ostream& out, Assertions& as)
     182                 :            : {
     183                 :            :   // by default, CPC proof logger
     184                 :          0 :   d_plog.reset(new ProofLoggerCpc(d_env, out, this, as));
     185                 :          0 : }
     186                 :            : 
     187                 :      11330 : std::shared_ptr<ProofNode> PfManager::connectProofToAssertions(
     188                 :            :     std::shared_ptr<ProofNode> pfn, Assertions& as, ProofScopeMode scopeMode)
     189                 :            : {
     190                 :            :   // Note this assumes that connectProofToAssertions is only called once per
     191                 :            :   // unsat response. This method would need to cache its result otherwise.
     192         [ +  - ]:      22660 :   Trace("smt-proof")
     193                 :      11330 :       << "SolverEngine::connectProofToAssertions(): get proof body...\n";
     194                 :            : 
     195         [ -  + ]:      11330 :   if (TraceIsOn("smt-proof-debug"))
     196                 :            :   {
     197         [ -  - ]:          0 :     Trace("smt-proof-debug")
     198                 :          0 :         << "SolverEngine::connectProofToAssertions(): Proof node for false:\n";
     199         [ -  - ]:          0 :     Trace("smt-proof-debug") << *pfn.get() << std::endl;
     200         [ -  - ]:          0 :     Trace("smt-proof-debug") << "=====" << std::endl;
     201                 :            :   }
     202                 :      11330 :   std::vector<Node> assertions;
     203                 :      11330 :   getAssertions(as, assertions);
     204                 :            : 
     205         [ -  + ]:      11330 :   if (TraceIsOn("smt-proof"))
     206                 :            :   {
     207         [ -  - ]:          0 :     Trace("smt-proof")
     208                 :          0 :         << "SolverEngine::connectProofToAssertions(): get free assumptions..."
     209                 :          0 :         << std::endl;
     210                 :          0 :     std::vector<Node> fassumps;
     211                 :          0 :     expr::getFreeAssumptions(pfn.get(), fassumps);
     212         [ -  - ]:          0 :     Trace("smt-proof") << "SolverEngine::connectProofToAssertions(): initial "
     213                 :          0 :                           "free assumptions are:\n";
     214         [ -  - ]:          0 :     for (const Node& a : fassumps)
     215                 :            :     {
     216         [ -  - ]:          0 :       Trace("smt-proof") << "- " << a << std::endl;
     217                 :            :     }
     218                 :            : 
     219         [ -  - ]:          0 :     Trace("smt-proof")
     220                 :          0 :         << "SolverEngine::connectProofToAssertions(): assertions are:\n";
     221         [ -  - ]:          0 :     for (const Node& n : assertions)
     222                 :            :     {
     223         [ -  - ]:          0 :       Trace("smt-proof") << "- " << n << std::endl;
     224                 :            :     }
     225         [ -  - ]:          0 :     Trace("smt-proof") << "=====" << std::endl;
     226                 :          0 :   }
     227                 :            : 
     228         [ +  - ]:      22660 :   Trace("smt-proof")
     229                 :      11330 :       << "SolverEngine::connectProofToAssertions(): postprocess...\n";
     230 [ -  + ][ -  + ]:      11330 :   Assert(d_pfpp != nullptr);
                 [ -  - ]
     231                 :            :   // Note that in incremental mode, we cannot set assertions here, as it
     232                 :            :   // permits the postprocessor to merge subproofs at a higher user context
     233                 :            :   // level into proofs that are used in a lower user context level.
     234         [ +  + ]:      11330 :   if (!options().base.incrementalSolving)
     235                 :            :   {
     236                 :      10230 :     d_pfpp->setAssertions(assertions, false);
     237                 :            :   }
     238         [ +  - ]:      11330 :   d_pfpp->process(pfn, d_pppg.get());
     239                 :            : 
     240 [ +  + ][ +  - ]:      11330 :   switch (scopeMode)
     241                 :            :   {
     242                 :         36 :     case ProofScopeMode::NONE:
     243                 :            :     {
     244                 :         36 :       return pfn;
     245                 :            :     }
     246                 :            :     // Now make the final scope(s), which ensure(s) that the only open leaves
     247                 :            :     // of the proof are the assertions (and definitions). If we are pruning
     248                 :            :     // the input, we will try to minimize the used assertions (and definitions).
     249                 :       6000 :     case ProofScopeMode::UNIFIED:
     250                 :            :     {
     251         [ +  - ]:      12000 :       Trace("smt-proof") << "SolverEngine::connectProofToAssertions(): make "
     252                 :       6000 :                             "unified scope...\n";
     253                 :            :       return d_pnm->mkScope(
     254                 :       6000 :           pfn, assertions, true, options().proof.proofPruneInput);
     255                 :            :     }
     256                 :       5294 :     case ProofScopeMode::DEFINITIONS_AND_ASSERTIONS:
     257                 :            :     {
     258         [ +  - ]:      10588 :       Trace("smt-proof")
     259                 :       5294 :           << "SolverEngine::connectProofToAssertions(): make split scope...\n";
     260                 :            :       // To support proof pruning for nested scopes, we need to:
     261                 :            :       // 1. Minimize assertions of closed unified scope.
     262                 :       5294 :       std::vector<Node> unifiedAssertions;
     263                 :       5294 :       getAssertions(as, unifiedAssertions);
     264                 :            :       Pf pf = d_pnm->mkScope(
     265                 :      10588 :           pfn, unifiedAssertions, true, options().proof.proofPruneInput);
     266                 :            :       // if this is violated, there is unsoundness since we have shown
     267                 :            :       // false that does not depend on the input.
     268 [ -  + ][ -  + ]:       5294 :       AlwaysAssert(pf->getRule() == ProofRule::SCOPE);
                 [ -  - ]
     269                 :            :       // 2. Extract minimum unified assertions from the scope node.
     270                 :       5294 :       std::unordered_set<Node> minUnifiedAssertions;
     271                 :       5294 :       minUnifiedAssertions.insert(pf->getArguments().cbegin(),
     272                 :       5294 :                                   pf->getArguments().cend());
     273                 :            :       // 3. Split those assertions into minimized definitions and assertions.
     274                 :       5294 :       std::vector<Node> minDefinitions;
     275                 :       5294 :       std::vector<Node> minAssertions;
     276                 :       5294 :       getDefinitionsAndAssertions(as, minDefinitions, minAssertions);
     277                 :      98668 :       std::function<bool(Node)> predicate = [&minUnifiedAssertions](Node n) {
     278                 :      49334 :         return minUnifiedAssertions.find(n) == minUnifiedAssertions.cend();
     279                 :       5294 :       };
     280                 :       5294 :       erase_if(minDefinitions, predicate);
     281                 :       5294 :       erase_if(minAssertions, predicate);
     282                 :            :       // 4. Extract proof from unified scope and encapsulate it with split
     283                 :            :       // scopes introducing minimized definitions and assertions.
     284                 :       5294 :       return d_pnm->mkNode(
     285                 :            :           ProofRule::SCOPE,
     286                 :            :           {d_pnm->mkNode(ProofRule::SCOPE, pf->getChildren(), minAssertions)},
     287                 :      10588 :           minDefinitions);
     288                 :       5294 :     }
     289                 :          0 :     default: Unreachable();
     290                 :            :   }
     291                 :      11330 : }
     292                 :            : 
     293                 :       2505 : void PfManager::checkFinalProof(std::shared_ptr<ProofNode> pfn)
     294                 :            : {
     295                 :            :   // take stats and check pedantic
     296                 :       2505 :   d_finalCb.initializeUpdate();
     297                 :       2505 :   d_finalizer.process(pfn);
     298                 :            : 
     299                 :       2505 :   std::stringstream serr;
     300                 :       2505 :   bool wasPedanticFailure = d_finalCb.wasPedanticFailure(serr);
     301         [ -  + ]:       2505 :   if (wasPedanticFailure)
     302                 :            :   {
     303                 :          0 :     AlwaysAssert(!wasPedanticFailure)
     304                 :          0 :         << "ProofPostprocess::process: pedantic failure:" << std::endl
     305                 :          0 :         << serr.str();
     306                 :            :   }
     307                 :       2505 : }
     308                 :            : 
     309                 :       5319 : void PfManager::printProof(std::ostream& out,
     310                 :            :                            std::shared_ptr<ProofNode> fp,
     311                 :            :                            options::ProofFormatMode mode,
     312                 :            :                            ProofScopeMode scopeMode,
     313                 :            :                            const std::map<Node, std::string>& assertionNames)
     314                 :            : {
     315         [ +  - ]:       5319 :   Trace("smt-proof") << "PfManager::printProof: start " << mode << std::endl;
     316                 :            :   // We don't want to invalidate the proof nodes in fp, since these may be
     317                 :            :   // reused in further check-sat calls, or they may be used again if the
     318                 :            :   // user asks for the proof again (in non-incremental mode). We don't need to
     319                 :            :   // clone if the printing below does not modify the proof, which is the case
     320                 :            :   // for proof formats Eunoia and NONE.
     321         [ +  + ]:       5319 :   if (mode != options::ProofFormatMode::CPC
     322         [ +  + ]:       3527 :       && mode != options::ProofFormatMode::NONE)
     323                 :            :   {
     324                 :       3483 :     fp = fp->clone();
     325                 :            :   }
     326                 :            : 
     327                 :            :   // according to the proof format, post process and print the proof node
     328         [ -  + ]:       5319 :   if (mode == options::ProofFormatMode::DOT)
     329                 :            :   {
     330                 :          0 :     proof::DotPrinter dotPrinter(d_env);
     331                 :          0 :     dotPrinter.print(out, fp.get());
     332                 :          0 :   }
     333         [ +  + ]:       5319 :   else if (mode == options::ProofFormatMode::CPC)
     334                 :            :   {
     335                 :       1792 :     proof::EoNodeConverter atp(nodeManager());
     336                 :       1792 :     proof::EoPrinter eop(d_env, atp, d_rewriteDb.get());
     337                 :       1792 :     eop.print(out, fp, scopeMode);
     338                 :       1792 :   }
     339         [ +  + ]:       3527 :   else if (mode == options::ProofFormatMode::ALETHE)
     340                 :            :   {
     341                 :       1734 :     options::ProofCheckMode oldMode = options().proof.proofCheck;
     342                 :       1734 :     d_pnm->getChecker()->setProofCheckMode(options::ProofCheckMode::NONE);
     343                 :            :     proof::AletheNodeConverter anc(nodeManager(),
     344                 :       3468 :                                    options().proof.proofAletheDefineSkolems,
     345                 :       1734 :                                    options().proof.proofAletheTesting);
     346                 :       1734 :     proof::AletheProofPostprocess vpfpp(d_env, anc);
     347         [ +  + ]:       1734 :     if (vpfpp.process(fp))
     348                 :            :     {
     349                 :        476 :       proof::AletheProofPrinter vpp(d_env, anc);
     350                 :        476 :       vpp.print(out, fp, assertionNames);
     351                 :        476 :     }
     352                 :            :     else
     353                 :            :     {
     354                 :       1258 :       out << "(error " << vpfpp.getError() << ")";
     355                 :            :     }
     356                 :       1734 :     d_pnm->getChecker()->setProofCheckMode(oldMode);
     357                 :       1734 :   }
     358         [ +  + ]:       1793 :   else if (mode == options::ProofFormatMode::LFSC)
     359                 :            :   {
     360 [ -  + ][ -  + ]:       1749 :     Assert(fp->getRule() == ProofRule::SCOPE);
                 [ -  - ]
     361                 :       1749 :     proof::LfscNodeConverter ltp(nodeManager());
     362                 :       1749 :     proof::LfscProofPostprocess lpp(d_env, ltp);
     363                 :       1749 :     lpp.process(fp);
     364                 :       1749 :     proof::LfscPrinter lp(d_env, ltp, d_rewriteDb.get());
     365                 :       1749 :     lp.print(out, fp.get());
     366                 :       1749 :   }
     367                 :            :   else
     368                 :            :   {
     369                 :            :     // otherwise, print using default printer
     370                 :            :     // we call the printing method explicitly because we may want to print the
     371                 :            :     // final proof node with conclusions
     372                 :         44 :     fp->printDebug(out, options().proof.proofPrintConclusion);
     373                 :            :   }
     374                 :       5319 : }
     375                 :            : 
     376                 :         19 : void PfManager::translateDifficultyMap(std::map<Node, Node>& dmap,
     377                 :            :                                        Assertions& as)
     378                 :            : {
     379         [ +  - ]:         19 :   Trace("difficulty-proc") << "Translate difficulty start" << std::endl;
     380         [ +  - ]:         19 :   Trace("difficulty") << "PfManager::translateDifficultyMap" << std::endl;
     381         [ +  + ]:         19 :   if (dmap.empty())
     382                 :            :   {
     383                 :          6 :     return;
     384                 :            :   }
     385                 :         15 :   std::map<Node, Node> dmapp;
     386         [ +  - ]:         15 :   Trace("difficulty-proc") << "Get ppAsserts" << std::endl;
     387                 :         15 :   std::vector<Node> ppAsserts;
     388                 :         15 :   SubtypeElimNodeConverter senc(nodeManager());
     389         [ +  + ]:         54 :   for (const std::pair<const Node, Node>& ppa : dmap)
     390                 :            :   {
     391                 :         39 :     Node assertion = ppa.first;
     392                 :            :     // proof may eliminate mixed arithmetic from the assertion
     393         [ +  - ]:         39 :     if (options().proof.proofElimSubtypes)
     394                 :            :     {
     395                 :         39 :       assertion = senc.convert(ppa.first);
     396                 :            :     }
     397                 :         39 :     dmapp[assertion] = ppa.second;
     398         [ +  - ]:         78 :     Trace("difficulty") << "  preprocess difficulty: " << assertion << " for "
     399                 :         39 :                         << ppa.first << std::endl;
     400                 :            :     // The difficulty manager should only report difficulty for preprocessed
     401                 :            :     // assertions, or we will get an open proof below. This is ensured
     402                 :            :     // internally by the difficuly manager.
     403                 :         39 :     ppAsserts.push_back(ppa.first);
     404                 :         39 :   }
     405                 :         15 :   dmap.clear();
     406         [ +  - ]:         15 :   Trace("difficulty-proc") << "Make SAT refutation" << std::endl;
     407                 :            :   // assume a SAT refutation from all input assertions that were marked
     408                 :            :   // as having a difficulty
     409                 :         30 :   CDProof cdp(d_env);
     410                 :         15 :   Node fnode = nodeManager()->mkConst(false);
     411                 :         15 :   cdp.addStep(fnode, ProofRule::SAT_REFUTATION, ppAsserts, {});
     412                 :         15 :   std::shared_ptr<ProofNode> pf = cdp.getProofFor(fnode);
     413         [ +  - ]:         15 :   Trace("difficulty-proc") << "Get final proof" << std::endl;
     414                 :         15 :   std::shared_ptr<ProofNode> fpf = connectProofToAssertions(pf, as);
     415         [ +  - ]:         15 :   Trace("difficulty-debug") << "Final proof is " << *fpf.get() << std::endl;
     416                 :            :   // We are typically a SCOPE here, although if we are not, then the proofs
     417                 :            :   // have no free assumptions. If this is the case, then the only difficulty
     418                 :            :   // was incremented on auxiliary lemmas added during preprocessing. Since
     419                 :            :   // there are no dependencies, then the difficulty map is empty.
     420         [ +  + ]:         15 :   if (fpf->getRule() != ProofRule::SCOPE)
     421                 :            :   {
     422                 :          2 :     return;
     423                 :            :   }
     424                 :         13 :   fpf = fpf->getChildren()[0];
     425                 :            :   // analyze proof
     426 [ -  + ][ -  + ]:         13 :   Assert(fpf->getRule() == ProofRule::SAT_REFUTATION);
                 [ -  - ]
     427                 :         13 :   const std::vector<std::shared_ptr<ProofNode>>& children = fpf->getChildren();
     428                 :         13 :   DifficultyPostprocessCallback dpc;
     429                 :         13 :   ProofNodeUpdater dpnu(d_env, dpc);
     430         [ +  - ]:         13 :   Trace("difficulty-proc") << "Compute accumulated difficulty" << std::endl;
     431                 :            :   // For each child of SAT_REFUTATION, we increment the difficulty on all
     432                 :            :   // "source" free assumptions (see DifficultyPostprocessCallback) by the
     433                 :            :   // difficulty of the preprocessed assertion.
     434         [ +  + ]:         50 :   for (const std::shared_ptr<ProofNode>& c : children)
     435                 :            :   {
     436                 :         37 :     Node res = c->getResult();
     437                 :         37 :     Assert(dmapp.find(res) != dmapp.end())
     438                 :          0 :         << "Could not find assumption " << res;
     439         [ +  - ]:         37 :     Trace("difficulty-debug") << "  process: " << res << std::endl;
     440         [ +  - ]:         37 :     Trace("difficulty-debug") << "  .dvalue: " << dmapp[res] << std::endl;
     441         [ +  - ]:         37 :     Trace("difficulty-debug") << "  ..proof: " << *c.get() << std::endl;
     442         [ -  + ]:         37 :     if (!dpc.setCurrentDifficulty(dmapp[res]))
     443                 :            :     {
     444                 :          0 :       continue;
     445                 :            :     }
     446                 :         37 :     dpnu.process(c);
     447         [ +  - ]:         37 :   }
     448                 :            :   // get the accumulated difficulty map from the callback
     449                 :         13 :   dpc.getDifficultyMap(nodeManager(), dmap);
     450         [ +  - ]:         13 :   Trace("difficulty-proc") << "Translate difficulty end" << std::endl;
     451 [ +  + ][ +  + ]:         27 : }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     452                 :            : 
     453                 :          0 : ProofChecker* PfManager::getProofChecker() const { return d_pchecker.get(); }
     454                 :            : 
     455                 :      15182 : ProofNodeManager* PfManager::getProofNodeManager() const { return d_pnm.get(); }
     456                 :            : 
     457                 :      21199 : ProofLogger* PfManager::getProofLogger() const { return d_plog.get(); }
     458                 :            : 
     459                 :          0 : rewriter::RewriteDb* PfManager::getRewriteDatabase() const
     460                 :            : {
     461                 :          0 :   return d_rewriteDb.get();
     462                 :            : }
     463                 :            : 
     464                 :      15185 : PreprocessProofGenerator* PfManager::getPreprocessProofGenerator() const
     465                 :            : {
     466                 :      15185 :   return d_pppg.get();
     467                 :            : }
     468                 :            : 
     469                 :      16624 : void PfManager::getAssertions(Assertions& as, std::vector<Node>& assertions)
     470                 :            : {
     471                 :            :   // note that the assertion list is always available
     472                 :      16624 :   const context::CDList<Node>& al = as.getAssertionList();
     473         [ +  + ]:     159711 :   for (const Node& a : al)
     474                 :            :   {
     475                 :     143087 :     assertions.push_back(a);
     476                 :            :   }
     477                 :      16624 : }
     478                 :            : 
     479                 :       5294 : void PfManager::getDefinitionsAndAssertions(Assertions& as,
     480                 :            :                                             std::vector<Node>& definitions,
     481                 :            :                                             std::vector<Node>& assertions)
     482                 :            : {
     483                 :       5294 :   const context::CDList<Node>& defs = as.getAssertionListDefinitions();
     484         [ +  + ]:       6964 :   for (const Node& d : defs)
     485                 :            :   {
     486                 :            :     // Keep treating (mutually) recursive functions as declarations +
     487                 :            :     // assertions.
     488         [ +  - ]:       1670 :     if (d.getKind() == Kind::EQUAL)
     489                 :            :     {
     490                 :       1670 :       definitions.push_back(d);
     491                 :            :     }
     492                 :            :   }
     493                 :       5294 :   const context::CDList<Node>& asserts = as.getAssertionList();
     494         [ +  + ]:      54628 :   for (const Node& a : asserts)
     495                 :            :   {
     496                 :      49334 :     if (std::find(definitions.cbegin(), definitions.cend(), a)
     497         [ +  + ]:      98668 :         == definitions.cend())
     498                 :            :     {
     499                 :      47664 :       assertions.push_back(a);
     500                 :            :     }
     501                 :            :   }
     502                 :       5294 : }
     503                 :            : 
     504                 :            : }  // namespace smt
     505                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14