LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/prop - prop_proof_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 166 220 75.5 %
Date: 2024-12-14 12:43:28 Functions: 16 19 84.2 %
Branches: 68 140 48.6 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Haniel Barbosa, Andrew Reynolds, Aina Niemetz
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 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                 :            :  * Implementation of the proof manager for the PropPfManager.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "prop/prop_proof_manager.h"
      17                 :            : 
      18                 :            : #include "expr/skolem_manager.h"
      19                 :            : #include "options/base_options.h"
      20                 :            : #include "options/main_options.h"
      21                 :            : #include "printer/printer.h"
      22                 :            : #include "proof/proof_ensure_closed.h"
      23                 :            : #include "proof/proof_node_algorithm.h"
      24                 :            : #include "proof/theory_proof_step_buffer.h"
      25                 :            : #include "prop/cnf_stream.h"
      26                 :            : #include "prop/minisat/sat_proof_manager.h"
      27                 :            : #include "prop/prop_proof_manager.h"
      28                 :            : #include "prop/sat_solver.h"
      29                 :            : #include "prop/sat_solver_factory.h"
      30                 :            : #include "smt/env.h"
      31                 :            : #include "smt/logic_exception.h"
      32                 :            : #include "util/resource_manager.h"
      33                 :            : #include "util/string.h"
      34                 :            : 
      35                 :            : namespace cvc5::internal {
      36                 :            : namespace prop {
      37                 :            : 
      38                 :      10845 : PropPfManager::PropPfManager(Env& env,
      39                 :            :                              CDCLTSatSolver* satSolver,
      40                 :            :                              CnfStream& cnf,
      41                 :      10845 :                              const context::CDList<Node>& assumptions)
      42                 :            :     : EnvObj(env),
      43                 :      21690 :       d_propProofs(userContext()),
      44                 :            :       // Since the ProofCnfStream performs no equality reasoning, there is no
      45                 :            :       // need to automatically add symmetry steps. Note that it is *safer* to
      46                 :            :       // forbid this, since adding symmetry steps when proof nodes are being
      47                 :            :       // updated may inadvertently generate cyclic proofs.
      48                 :            :       //
      49                 :            :       // This can happen for example if the proof cnf stream has a generator for
      50                 :            :       // (= a b), whose proof depends on symmetry applied to (= b a). It does
      51                 :            :       // not have a generator for (= b a). However if asked for a proof of the
      52                 :            :       // fact (= b a) (after having expanded the proof of (= a b)), since it has
      53                 :            :       // no generator for (= b a), a proof (= b a) can be generated via symmetry
      54                 :            :       // on the proof of (= a b). As a result, the assumption (= b a) would be
      55                 :            :       // assigned a proof with assumption (= b a). This breaks the invariant of
      56                 :            :       // the proof node manager of no cyclic proofs if the ASSUMPTION proof node
      57                 :            :       // of both the assumption (= b a) we are asking the proof for and the
      58                 :            :       // assumption (= b a) in the proof of (= a b) are the same.
      59                 :            :       d_proof(
      60                 :      10845 :           env, nullptr, userContext(), "ProofCnfStream::LazyCDProof", false),
      61                 :      10845 :       d_pfpp(new ProofPostprocess(env, &d_proof)),
      62                 :            :       d_pfCnfStream(env, cnf, this),
      63                 :            :       d_satSolver(satSolver),
      64                 :      21690 :       d_assertions(userContext()),
      65                 :            :       d_cnfStream(cnf),
      66                 :            :       d_assumptions(assumptions),
      67                 :      21690 :       d_inputClauses(userContext()),
      68                 :      21690 :       d_lemmaClauses(userContext()),
      69                 :            :       d_trackLemmaClauseIds(false),
      70                 :      21690 :       d_lemmaClauseIds(userContext()),
      71                 :      21690 :       d_lemmaClauseTimestamp(userContext()),
      72                 :            :       d_currLemmaId(theory::InferenceId::NONE),
      73                 :            :       d_satPm(nullptr),
      74                 :      21690 :       d_uclIds(statisticsRegistry().registerHistogram<theory::InferenceId>(
      75                 :      10845 :           "ppm::unsatCoreLemmaIds")),
      76                 :      10845 :       d_uclSize(statisticsRegistry().registerInt("ppm::unsatCoreLemmaSize")),
      77                 :      43380 :       d_numUcl(statisticsRegistry().registerInt("ppm::unsatCoreLemmaCalls"))
      78                 :            : {
      79                 :            :   // Add trivial assumption. This is so that we can check that the prop engine's
      80                 :            :   // proof is closed, as the SAT solver's refutation proof may use True as an
      81                 :            :   // assumption even when True is not given as an assumption. An example is when
      82                 :            :   // a propagated literal has an empty explanation (i.e., it is a valid
      83                 :            :   // literal), which leads to adding True as its explanation, since for creating
      84                 :            :   // a learned clause we need at least two literals.
      85                 :      10845 :   d_assertions.push_back(nodeManager()->mkConst(true));
      86                 :      10845 :   d_trackLemmaClauseIds = isOutputOn(OutputTag::UNSAT_CORE_LEMMAS);
      87                 :      10845 : }
      88                 :            : 
      89                 :     146909 : void PropPfManager::ensureLiteral(TNode n) { d_pfCnfStream.ensureLiteral(n); }
      90                 :            : 
      91                 :     583830 : void PropPfManager::convertAndAssert(theory::InferenceId id,
      92                 :            :                                      TNode node,
      93                 :            :                                      bool negated,
      94                 :            :                                      bool removable,
      95                 :            :                                      bool input,
      96                 :            :                                      ProofGenerator* pg)
      97                 :            : {
      98                 :     583830 :   d_currLemmaId = id;
      99                 :     583830 :   d_pfCnfStream.convertAndAssert(node, negated, removable, input, pg);
     100                 :     583830 :   d_currLemmaId = theory::InferenceId::NONE;
     101                 :            :   // if input, register the assertion in the proof manager
     102         [ +  + ]:     583830 :   if (input)
     103                 :            :   {
     104                 :     219228 :     d_assertions.push_back(node);
     105                 :            :   }
     106                 :     583830 : }
     107                 :            : 
     108                 :          0 : void PropPfManager::registerAssertion(Node assertion)
     109                 :            : {
     110                 :          0 :   d_assertions.push_back(assertion);
     111                 :          0 : }
     112                 :            : 
     113                 :         14 : void PropPfManager::checkProof(const context::CDList<Node>& assertions)
     114                 :            : {
     115         [ +  - ]:         28 :   Trace("sat-proof") << "PropPfManager::checkProof: Checking if resolution "
     116                 :         14 :                         "proof of false is closed\n";
     117                 :         28 :   std::shared_ptr<ProofNode> conflictProof = getProof(false);
     118 [ -  + ][ -  + ]:         14 :   Assert(conflictProof);
                 [ -  - ]
     119                 :            :   // connect it with CNF proof
     120                 :         14 :   d_pfpp->process(conflictProof);
     121                 :            :   // add given assertions d_assertions
     122         [ +  + ]:         38 :   for (const Node& assertion : assertions)
     123                 :            :   {
     124                 :         24 :     d_assertions.push_back(assertion);
     125                 :            :   }
     126                 :         28 :   std::vector<Node> avec{d_assertions.begin(), d_assertions.end()};
     127                 :         14 :   pfnEnsureClosedWrt(options(),
     128                 :            :                      conflictProof.get(),
     129                 :            :                      avec,
     130                 :            :                      "sat-proof",
     131                 :            :                      "PropPfManager::checkProof");
     132                 :         14 : }
     133                 :            : 
     134                 :        400 : std::vector<Node> PropPfManager::getUnsatCoreLemmas()
     135                 :            : {
     136                 :        400 :   std::vector<Node> usedLemmas;
     137                 :        800 :   std::vector<Node> allLemmas = getLemmaClauses();
     138                 :            :   // compute the unsat core clauses, as below
     139                 :        800 :   std::vector<Node> ucc = getUnsatCoreClauses();
     140         [ +  - ]:        800 :   Trace("prop-pf") << "Compute unsat core lemmas from " << ucc.size()
     141                 :        400 :                    << " clauses (of " << allLemmas.size() << " lemmas)"
     142                 :        400 :                    << std::endl;
     143         [ +  - ]:        400 :   Trace("prop-pf") << "lemmas: " << allLemmas << std::endl;
     144         [ +  - ]:        400 :   Trace("prop-pf") << "uc: " << ucc << std::endl;
     145                 :            :   // filter to only those corresponding to lemmas
     146         [ +  + ]:        603 :   for (const Node& lemma : allLemmas)
     147                 :            :   {
     148         [ +  - ]:        203 :     if (std::find(ucc.begin(), ucc.end(), lemma) != ucc.end())
     149                 :            :     {
     150                 :        203 :       usedLemmas.push_back(lemma);
     151                 :            :     }
     152                 :            :   }
     153         [ -  + ]:        400 :   if (d_trackLemmaClauseIds)
     154                 :            :   {
     155                 :          0 :     ++d_numUcl;
     156                 :            :     uint64_t timestamp;
     157         [ -  - ]:          0 :     for (const Node& lemma : usedLemmas)
     158                 :            :     {
     159                 :          0 :       d_uclIds << getInferenceIdFor(lemma, timestamp);
     160                 :          0 :       ++d_uclSize;
     161                 :            :     }
     162                 :            :   }
     163                 :        800 :   return usedLemmas;
     164                 :            : }
     165                 :            : 
     166                 :          0 : theory::InferenceId PropPfManager::getInferenceIdFor(const Node& lem,
     167                 :            :                                                      uint64_t& timestamp) const
     168                 :            : {
     169                 :            :   context::CDHashMap<Node, theory::InferenceId>::const_iterator it =
     170                 :          0 :       d_lemmaClauseIds.find(lem);
     171         [ -  - ]:          0 :   if (it != d_lemmaClauseIds.end())
     172                 :            :   {
     173                 :            :     context::CDHashMap<Node, uint64_t>::const_iterator itt =
     174                 :          0 :         d_lemmaClauseTimestamp.find(lem);
     175         [ -  - ]:          0 :     if (itt != d_lemmaClauseTimestamp.end())
     176                 :            :     {
     177                 :          0 :       timestamp = itt->second;
     178                 :            :     }
     179                 :          0 :     return it->second;
     180                 :            :   }
     181                 :          0 :   return theory::InferenceId::NONE;
     182                 :            : }
     183                 :        400 : std::vector<Node> PropPfManager::getUnsatCoreClauses()
     184                 :            : {
     185                 :        400 :   std::vector<Node> uc;
     186                 :            :   // if it has a proof
     187                 :        800 :   std::shared_ptr<ProofNode> satPf = d_satSolver->getProof();
     188                 :            :   // Note that we currently assume that the proof is the standard way of
     189                 :            :   // communicating the unsat core of theory lemmas. If no proofs are
     190                 :            :   // available, then a trust step (e.g. SAT_REFUTATION) with free assumptions
     191                 :            :   // F1 ... Fn can be used to indicate that F1 ... Fn is the unsat core
     192         [ -  + ]:        400 :   if (satPf == nullptr)
     193                 :            :   {
     194                 :          0 :     std::stringstream ss;
     195                 :            :     ss << "ERROR: cannot get unsat core clauses when SAT solver is not proof "
     196                 :          0 :           "producing.";
     197                 :          0 :     throw LogicException(ss.str());
     198                 :            :   }
     199                 :            :   // then, get the proof *without* connecting the CNF
     200                 :        400 :   expr::getFreeAssumptions(satPf.get(), uc);
     201                 :        800 :   return uc;
     202                 :            : }
     203                 :            : 
     204                 :          8 : std::vector<std::shared_ptr<ProofNode>> PropPfManager::getProofLeaves(
     205                 :            :     modes::ProofComponent pc)
     206                 :            : {
     207         [ +  - ]:         16 :   Trace("sat-proof") << "PropPfManager::getProofLeaves: Getting " << pc
     208                 :          8 :                      << " component proofs\n";
     209                 :         16 :   std::vector<Node> fassumps;
     210 [ +  + ][ -  + ]:          8 :   Assert(pc == modes::ProofComponent::THEORY_LEMMAS
         [ -  + ][ -  - ]
     211                 :            :          || pc == modes::ProofComponent::PREPROCESS);
     212                 :            :   std::vector<std::shared_ptr<ProofNode>> pfs =
     213                 :          8 :       pc == modes::ProofComponent::THEORY_LEMMAS ? getLemmaClausesProofs()
     214         [ +  + ]:         16 :                                                  : getInputClausesProofs();
     215                 :         16 :   std::shared_ptr<ProofNode> satPf = getProof(false);
     216                 :         16 :   std::vector<Node> satLeaves;
     217                 :          8 :   expr::getFreeAssumptions(satPf.get(), satLeaves);
     218                 :          8 :   std::vector<std::shared_ptr<ProofNode>> usedPfs;
     219         [ +  + ]:         44 :   for (const std::shared_ptr<ProofNode>& pf : pfs)
     220                 :            :   {
     221                 :         72 :     Node proven = pf->getResult();
     222         [ +  + ]:         36 :     if (std::find(satLeaves.begin(), satLeaves.end(), proven) != satLeaves.end())
     223                 :            :     {
     224                 :         16 :       usedPfs.push_back(pf);
     225                 :            :     }
     226                 :            :   }
     227                 :         16 :   return usedPfs;
     228                 :            : }
     229                 :            : 
     230                 :      10047 : std::shared_ptr<ProofNode> PropPfManager::getProof(bool connectCnf)
     231                 :            : {
     232                 :      10047 :   auto it = d_propProofs.find(connectCnf);
     233         [ +  + ]:      10047 :   if (it != d_propProofs.end())
     234                 :            :   {
     235                 :        645 :     return it->second;
     236                 :            :   }
     237                 :            :   // retrieve the SAT solver's refutation proof
     238         [ +  - ]:       9402 :   Trace("sat-proof") << "PropPfManager::getProof: Getting proof of false\n";
     239                 :            : 
     240                 :            :   // get the proof based on the proof mode
     241                 :       9402 :   options::PropProofMode pmode = options().proof.propProofMode;
     242                 :       9402 :   std::shared_ptr<ProofNode> conflictProof;
     243                 :            :   // take proof from SAT solver as is
     244                 :       9402 :   conflictProof = d_satSolver->getProof();
     245                 :            : 
     246 [ -  + ][ -  + ]:       9402 :   Assert(conflictProof);
                 [ -  - ]
     247         [ -  + ]:       9402 :   if (TraceIsOn("sat-proof"))
     248                 :            :   {
     249                 :          0 :     std::vector<Node> fassumps;
     250                 :          0 :     expr::getFreeAssumptions(conflictProof.get(), fassumps);
     251         [ -  - ]:          0 :     Trace("sat-proof")
     252                 :          0 :         << "PropPfManager::getProof: initial free assumptions are:\n";
     253         [ -  - ]:          0 :     for (const Node& a : fassumps)
     254                 :            :     {
     255         [ -  - ]:          0 :       Trace("sat-proof") << "- " << a << "\n";
     256                 :            :     }
     257         [ -  - ]:          0 :     Trace("sat-proof-debug")
     258                 :          0 :         << "PropPfManager::getProof: proof is " << *conflictProof.get() << "\n";
     259         [ -  - ]:          0 :     Trace("sat-proof")
     260                 :          0 :         << "PropPfManager::getProof: Connecting with CNF proof\n";
     261                 :            :   }
     262         [ +  + ]:       9402 :   if (!connectCnf)
     263                 :            :   {
     264                 :        395 :     d_propProofs[connectCnf] = conflictProof;
     265                 :        395 :     return conflictProof;
     266                 :            :   }
     267                 :            :   // Must clone if we are using the original proof, since we don't want to
     268                 :            :   // modify the original SAT proof. Note that other propProofMode settings
     269                 :            :   // may also require cloning here.
     270         [ +  - ]:       9007 :   if (pmode == options::PropProofMode::PROOF)
     271                 :            :   {
     272                 :       9007 :     conflictProof = conflictProof->clone();
     273                 :            :   }
     274                 :            :   // connect it with CNF proof
     275                 :       9007 :   d_pfpp->process(conflictProof);
     276         [ -  + ]:       9007 :   if (TraceIsOn("sat-proof"))
     277                 :            :   {
     278                 :          0 :     std::vector<Node> fassumps;
     279                 :          0 :     expr::getFreeAssumptions(conflictProof.get(), fassumps);
     280         [ -  - ]:          0 :     Trace("sat-proof")
     281                 :          0 :         << "PropPfManager::getProof: new free assumptions are:\n";
     282         [ -  - ]:          0 :     for (const Node& a : fassumps)
     283                 :            :     {
     284         [ -  - ]:          0 :       Trace("sat-proof") << "- " << a << "\n";
     285                 :            :     }
     286         [ -  - ]:          0 :     Trace("sat-proof") << "PropPfManager::getProof: assertions are:\n";
     287         [ -  - ]:          0 :     for (const Node& a : d_assertions)
     288                 :            :     {
     289         [ -  - ]:          0 :       Trace("sat-proof") << "- " << a << "\n";
     290                 :            :     }
     291         [ -  - ]:          0 :     Trace("sat-proof-debug")
     292                 :          0 :         << "PropPfManager::getProof: proof is " << *conflictProof.get() << "\n";
     293                 :            :   }
     294                 :       9007 :   d_propProofs[connectCnf] = conflictProof;
     295                 :       9007 :   return conflictProof;
     296                 :            : }
     297                 :            : 
     298                 :    3195930 : Node PropPfManager::normalizeAndRegister(TNode clauseNode,
     299                 :            :                                          bool input,
     300                 :            :                                          bool doNormalize)
     301                 :            : {
     302                 :    3195930 :   Node normClauseNode = clauseNode;
     303         [ +  + ]:    3195930 :   if (doNormalize)
     304                 :            :   {
     305                 :    6044980 :     TheoryProofStepBuffer psb;
     306                 :    3022490 :     normClauseNode = psb.factorReorderElimDoubleNeg(clauseNode);
     307                 :    3022490 :     const std::vector<std::pair<Node, ProofStep>>& steps = psb.getSteps();
     308         [ +  + ]:   15087600 :     for (const std::pair<Node, ProofStep>& step : steps)
     309                 :            :     {
     310                 :   12065100 :       d_proof.addStep(step.first, step.second);
     311                 :            :     }
     312                 :            :   }
     313                 :    3195930 :   if (TraceIsOn("cnf") && normClauseNode != clauseNode)
     314                 :            :   {
     315         [ -  - ]:          0 :     Trace("cnf") << push
     316                 :          0 :                  << "ProofCnfStream::normalizeAndRegister: steps to normalized "
     317                 :          0 :                  << normClauseNode << "\n"
     318                 :          0 :                  << pop;
     319                 :            :   }
     320         [ +  - ]:    6391860 :   Trace("cnf-input") << "New clause: " << normClauseNode << " " << input
     321                 :    3195930 :                      << std::endl;
     322         [ +  + ]:    3195930 :   if (input)
     323                 :            :   {
     324                 :     519321 :     d_inputClauses.insert(normClauseNode);
     325                 :            :   }
     326                 :            :   else
     327                 :            :   {
     328                 :    2676610 :     d_lemmaClauses.insert(normClauseNode);
     329         [ -  + ]:    2676610 :     if (d_trackLemmaClauseIds)
     330                 :            :     {
     331                 :          0 :       d_lemmaClauseIds[normClauseNode] = d_currLemmaId;
     332                 :          0 :       uint64_t currTimestamp = d_env.getResourceManager()->getResource(
     333                 :          0 :           Resource::TheoryFullCheckStep);
     334                 :          0 :       d_lemmaClauseTimestamp[normClauseNode] = currTimestamp;
     335                 :            :     }
     336                 :            :   }
     337         [ +  - ]:    3195930 :   if (d_satPm)
     338                 :            :   {
     339                 :    6391860 :     d_satPm->registerSatAssumptions({normClauseNode});
     340                 :            :   }
     341                 :    3195930 :   return normClauseNode;
     342                 :            : }
     343                 :            : 
     344                 :     272628 : LazyCDProof* PropPfManager::getCnfProof() { return &d_proof; }
     345                 :            : 
     346                 :          0 : std::vector<Node> PropPfManager::getInputClauses()
     347                 :            : {
     348                 :          0 :   std::vector<Node> cls;
     349         [ -  - ]:          0 :   for (const Node& c : d_inputClauses)
     350                 :            :   {
     351                 :          0 :     cls.push_back(c);
     352                 :            :   }
     353                 :          0 :   return cls;
     354                 :            : }
     355                 :            : 
     356                 :        400 : std::vector<Node> PropPfManager::getLemmaClauses()
     357                 :            : {
     358                 :        400 :   std::vector<Node> cls;
     359         [ +  + ]:        603 :   for (const Node& c : d_lemmaClauses)
     360                 :            :   {
     361                 :        203 :     cls.push_back(c);
     362                 :            :   }
     363                 :        400 :   return cls;
     364                 :            : }
     365                 :            : 
     366                 :          4 : std::vector<std::shared_ptr<ProofNode>> PropPfManager::getInputClausesProofs()
     367                 :            : {
     368                 :          4 :   std::vector<std::shared_ptr<ProofNode>> pfs;
     369         [ +  + ]:         40 :   for (const Node& a : d_inputClauses)
     370                 :            :   {
     371                 :         36 :     pfs.push_back(d_proof.getProofFor(a));
     372                 :            :   }
     373                 :          4 :   return pfs;
     374                 :            : }
     375                 :            : 
     376                 :          4 : std::vector<std::shared_ptr<ProofNode>> PropPfManager::getLemmaClausesProofs()
     377                 :            : {
     378                 :          4 :   std::vector<std::shared_ptr<ProofNode>> pfs;
     379         [ -  + ]:          4 :   for (const Node& a : d_lemmaClauses)
     380                 :            :   {
     381                 :          0 :     pfs.push_back(d_proof.getProofFor(a));
     382                 :            :   }
     383                 :          4 :   return pfs;
     384                 :            : }
     385                 :            : 
     386                 :      79837 : void PropPfManager::notifyExplainedPropagation(TrustNode trn)
     387                 :            : {
     388                 :     159674 :   Node proven = trn.getProven();
     389                 :            :   // If we are not producing proofs in the theory engine there is no need to
     390                 :            :   // keep track in d_proof of the clausification. We still need however to let
     391                 :            :   // the SAT proof manager know that this clause is an assumption.
     392                 :      79837 :   bool proofLogging = trn.getGenerator() != nullptr;
     393         [ +  - ]:     159674 :   Trace("cnf")
     394                 :          0 :       << "PropPfManager::notifyExplainedPropagation: proven explanation"
     395                 :      79837 :       << proven << ", proofLogging=" << proofLogging << "\n";
     396         [ +  + ]:      79837 :   if (proofLogging)
     397                 :            :   {
     398 [ -  + ][ -  + ]:      79834 :     Assert(trn.getGenerator()->getProofFor(proven)->isClosed());
                 [ -  - ]
     399         [ +  - ]:     159668 :     Trace("cnf-steps") << proven << " by explainPropagation "
     400 [ -  + ][ -  - ]:      79834 :                        << trn.identifyGenerator() << std::endl;
     401                 :      79834 :     d_proof.addLazyStep(proven,
     402                 :            :                         trn.getGenerator(),
     403                 :            :                         TrustId::NONE,
     404                 :            :                         true,
     405                 :            :                         "PropPfManager::notifyExplainedPropagation");
     406                 :            :   }
     407                 :            :   // since the propagation is added directly to the SAT solver via theoryProxy,
     408                 :            :   // do the transformation of the lemma E1 ^ ... ^ En => P into CNF here
     409                 :      79837 :   NodeManager* nm = nodeManager();
     410                 :     159674 :   Node clauseImpliesElim;
     411         [ +  + ]:      79837 :   if (proofLogging)
     412                 :            :   {
     413                 :      79834 :     clauseImpliesElim = nm->mkNode(Kind::OR, proven[0].notNode(), proven[1]);
     414         [ +  - ]:     159668 :     Trace("cnf") << "PropPfManager::notifyExplainedPropagation: adding "
     415                 :      79834 :                  << ProofRule::IMPLIES_ELIM << " rule to conclude "
     416                 :      79834 :                  << clauseImpliesElim << "\n";
     417                 :     159668 :     d_proof.addStep(clauseImpliesElim, ProofRule::IMPLIES_ELIM, {proven}, {});
     418                 :            :   }
     419                 :     159674 :   Node clauseExp;
     420                 :            :   // need to eliminate AND
     421         [ +  + ]:      79837 :   if (proven[0].getKind() == Kind::AND)
     422                 :            :   {
     423                 :     300676 :     std::vector<Node> disjunctsAndNeg{proven[0]};
     424                 :     150338 :     std::vector<Node> disjunctsRes;
     425         [ +  + ]:     660429 :     for (unsigned i = 0, size = proven[0].getNumChildren(); i < size; ++i)
     426                 :            :     {
     427                 :     585260 :       disjunctsAndNeg.push_back(proven[0][i].notNode());
     428                 :     585260 :       disjunctsRes.push_back(proven[0][i].notNode());
     429                 :            :     }
     430                 :      75169 :     disjunctsRes.push_back(proven[1]);
     431                 :      75169 :     clauseExp = nm->mkNode(Kind::OR, disjunctsRes);
     432         [ +  + ]:      75169 :     if (proofLogging)
     433                 :            :     {
     434                 :            :       // add proof steps to convert into clause
     435                 :      75166 :       Node clauseAndNeg = nm->mkNode(Kind::OR, disjunctsAndNeg);
     436                 :     150332 :       d_proof.addStep(clauseAndNeg, ProofRule::CNF_AND_NEG, {}, {proven[0]});
     437                 :     375830 :       d_proof.addStep(clauseExp,
     438                 :            :                       ProofRule::RESOLUTION,
     439                 :            :                       {clauseAndNeg, clauseImpliesElim},
     440                 :     450996 :                       {nm->mkConst(true), proven[0]});
     441                 :            :     }
     442                 :            :   }
     443                 :            :   else
     444                 :            :   {
     445                 :       4668 :     clauseExp = nm->mkNode(Kind::OR, proven[0].notNode(), proven[1]);
     446                 :            :   }
     447                 :      79837 :   d_currPropagationProcessed = normalizeAndRegister(clauseExp, false);
     448                 :            :   // If we are not logging the clausification, we need to add the clause, as *it
     449                 :            :   // will be saved in the SAT solver* (i.e., as clauseExp), as closed step in
     450                 :            :   // the d_proof, so that there are no non-input assumptions.
     451         [ +  + ]:      79837 :   if (!proofLogging)
     452                 :            :   {
     453                 :          3 :     d_proof.addTrustedStep(clauseExp, TrustId::THEORY_LEMMA, {}, {});
     454                 :            :   }
     455                 :      79837 : }
     456                 :            : 
     457                 :        153 : Node PropPfManager::getLastExplainedPropagation() const
     458                 :            : {
     459                 :        153 :   return d_currPropagationProcessed;
     460                 :            : }
     461                 :            : 
     462                 :        153 : void PropPfManager::resetLastExplainedPropagation()
     463                 :            : {
     464                 :        153 :   d_currPropagationProcessed = Node::null();
     465                 :        153 : }
     466                 :            : 
     467                 :            : }  // namespace prop
     468                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14