LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/booleans - proof_checker.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 512 578 88.6 %
Date: 2026-02-26 11:40:56 Functions: 3 3 100.0 %
Branches: 508 1104 46.0 %

           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                 :            :  * Implementation of equality proof checker.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/booleans/proof_checker.h"
      14                 :            : #include "expr/skolem_manager.h"
      15                 :            : #include "theory/rewriter.h"
      16                 :            : 
      17                 :            : namespace cvc5::internal {
      18                 :            : namespace theory {
      19                 :            : namespace booleans {
      20                 :            : 
      21                 :      49917 : BoolProofRuleChecker::BoolProofRuleChecker(NodeManager* nm)
      22                 :      49917 :     : ProofRuleChecker(nm)
      23                 :            : {
      24                 :      49917 : }
      25                 :            : 
      26                 :      18895 : void BoolProofRuleChecker::registerTo(ProofChecker* pc)
      27                 :            : {
      28                 :      18895 :   pc->registerChecker(ProofRule::SPLIT, this);
      29                 :      18895 :   pc->registerChecker(ProofRule::RESOLUTION, this);
      30                 :      18895 :   pc->registerChecker(ProofRule::CHAIN_RESOLUTION, this);
      31                 :      18895 :   pc->registerChecker(ProofRule::CHAIN_M_RESOLUTION, this);
      32                 :      18895 :   pc->registerChecker(ProofRule::FACTORING, this);
      33                 :      18895 :   pc->registerChecker(ProofRule::REORDERING, this);
      34                 :      18895 :   pc->registerChecker(ProofRule::EQ_RESOLVE, this);
      35                 :      18895 :   pc->registerChecker(ProofRule::MODUS_PONENS, this);
      36                 :      18895 :   pc->registerChecker(ProofRule::NOT_NOT_ELIM, this);
      37                 :      18895 :   pc->registerChecker(ProofRule::CONTRA, this);
      38                 :      18895 :   pc->registerChecker(ProofRule::AND_ELIM, this);
      39                 :      18895 :   pc->registerChecker(ProofRule::AND_INTRO, this);
      40                 :      18895 :   pc->registerChecker(ProofRule::NOT_OR_ELIM, this);
      41                 :      18895 :   pc->registerChecker(ProofRule::IMPLIES_ELIM, this);
      42                 :      18895 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM1, this);
      43                 :      18895 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM2, this);
      44                 :      18895 :   pc->registerChecker(ProofRule::EQUIV_ELIM1, this);
      45                 :      18895 :   pc->registerChecker(ProofRule::EQUIV_ELIM2, this);
      46                 :      18895 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM1, this);
      47                 :      18895 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM2, this);
      48                 :      18895 :   pc->registerChecker(ProofRule::XOR_ELIM1, this);
      49                 :      18895 :   pc->registerChecker(ProofRule::XOR_ELIM2, this);
      50                 :      18895 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM1, this);
      51                 :      18895 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM2, this);
      52                 :      18895 :   pc->registerChecker(ProofRule::ITE_ELIM1, this);
      53                 :      18895 :   pc->registerChecker(ProofRule::ITE_ELIM2, this);
      54                 :      18895 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM1, this);
      55                 :      18895 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM2, this);
      56                 :      18895 :   pc->registerChecker(ProofRule::NOT_AND, this);
      57                 :      18895 :   pc->registerChecker(ProofRule::CNF_AND_POS, this);
      58                 :      18895 :   pc->registerChecker(ProofRule::CNF_AND_NEG, this);
      59                 :      18895 :   pc->registerChecker(ProofRule::CNF_OR_POS, this);
      60                 :      18895 :   pc->registerChecker(ProofRule::CNF_OR_NEG, this);
      61                 :      18895 :   pc->registerChecker(ProofRule::CNF_IMPLIES_POS, this);
      62                 :      18895 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG1, this);
      63                 :      18895 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG2, this);
      64                 :      18895 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS1, this);
      65                 :      18895 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS2, this);
      66                 :      18895 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG1, this);
      67                 :      18895 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG2, this);
      68                 :      18895 :   pc->registerChecker(ProofRule::CNF_XOR_POS1, this);
      69                 :      18895 :   pc->registerChecker(ProofRule::CNF_XOR_POS2, this);
      70                 :      18895 :   pc->registerChecker(ProofRule::CNF_XOR_NEG1, this);
      71                 :      18895 :   pc->registerChecker(ProofRule::CNF_XOR_NEG2, this);
      72                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_POS1, this);
      73                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_POS2, this);
      74                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_POS3, this);
      75                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_NEG1, this);
      76                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_NEG2, this);
      77                 :      18895 :   pc->registerChecker(ProofRule::CNF_ITE_NEG3, this);
      78                 :      18895 :   pc->registerTrustedChecker(ProofRule::SAT_REFUTATION, this, 1);
      79                 :      18895 :   pc->registerTrustedChecker(ProofRule::DRAT_REFUTATION, this, 1);
      80                 :      18895 :   pc->registerTrustedChecker(ProofRule::SAT_EXTERNAL_PROVE, this, 1);
      81                 :      18895 : }
      82                 :            : 
      83                 :    4465809 : Node BoolProofRuleChecker::checkInternal(ProofRule id,
      84                 :            :                                          const std::vector<Node>& children,
      85                 :            :                                          const std::vector<Node>& args)
      86                 :            : {
      87         [ +  + ]:    4465809 :   if (id == ProofRule::RESOLUTION)
      88                 :            :   {
      89 [ -  + ][ -  + ]:     770383 :     Assert(children.size() == 2);
                 [ -  - ]
      90 [ -  + ][ -  + ]:     770383 :     Assert(args.size() == 2);
                 [ -  - ]
      91                 :     770383 :     NodeManager* nm = nodeManager();
      92                 :     770383 :     std::vector<Node> disjuncts;
      93         [ +  + ]:    3851915 :     Node pivots[2];
      94         [ +  + ]:     770383 :     if (args[0] == nm->mkConst(true))
      95                 :            :     {
      96                 :     394019 :       pivots[0] = args[1];
      97                 :     394019 :       pivots[1] = args[1].notNode();
      98                 :            :     }
      99                 :            :     else
     100                 :            :     {
     101 [ -  + ][ -  + ]:     376364 :       Assert(args[0] == nm->mkConst(false));
                 [ -  - ]
     102                 :     376364 :       pivots[0] = args[1].notNode();
     103                 :     376364 :       pivots[1] = args[1];
     104                 :            :     }
     105         [ +  + ]:    2311149 :     for (unsigned i = 0; i < 2; ++i)
     106                 :            :     {
     107                 :            :       // determine whether the clause is a singleton for effects of resolution,
     108                 :            :       // which is the case if it's not an OR node or it is an OR node but it is
     109                 :            :       // equal to the pivot
     110                 :    1540766 :       std::vector<Node> lits;
     111 [ +  + ][ +  + ]:    1540766 :       if (children[i].getKind() == Kind::OR && pivots[i] != children[i])
                 [ +  + ]
     112                 :            :       {
     113                 :    1244128 :         lits.insert(lits.end(), children[i].begin(), children[i].end());
     114                 :            :       }
     115                 :            :       else
     116                 :            :       {
     117                 :     296638 :         lits.push_back(children[i]);
     118                 :            :       }
     119         [ +  + ]:   15066389 :       for (unsigned j = 0, size = lits.size(); j < size; ++j)
     120                 :            :       {
     121         [ +  + ]:   13525623 :         if (pivots[i] != lits[j])
     122                 :            :         {
     123                 :   11984857 :           disjuncts.push_back(lits[j]);
     124                 :            :         }
     125                 :            :         else
     126                 :            :         {
     127                 :            :           // just eliminate first occurrence
     128                 :    1540766 :           pivots[i] = Node::null();
     129                 :            :         }
     130                 :            :       }
     131                 :    1540766 :     }
     132                 :    1540766 :     return disjuncts.empty()       ? nm->mkConst(false)
     133                 :     862311 :            : disjuncts.size() == 1 ? disjuncts[0]
     134 [ +  + ][ +  + ]:    1632694 :                                    : nm->mkNode(Kind::OR, disjuncts);
     135 [ +  + ][ -  - ]:    3081532 :   }
     136         [ +  + ]:    3695426 :   if (id == ProofRule::FACTORING)
     137                 :            :   {
     138 [ -  + ][ -  + ]:     313398 :     Assert(children.size() == 1);
                 [ -  - ]
     139 [ -  + ][ -  + ]:     313398 :     Assert(args.empty());
                 [ -  - ]
     140         [ -  + ]:     313398 :     if (children[0].getKind() != Kind::OR)
     141                 :            :     {
     142                 :          0 :       return Node::null();
     143                 :            :     }
     144                 :            :     // remove duplicates while keeping the order of children
     145                 :     313398 :     std::unordered_set<TNode> clauseSet;
     146                 :     313398 :     std::vector<Node> disjuncts;
     147                 :     313398 :     unsigned size = children[0].getNumChildren();
     148         [ +  + ]:    8038359 :     for (unsigned i = 0; i < size; ++i)
     149                 :            :     {
     150         [ +  + ]:    7724961 :       if (clauseSet.count(children[0][i]))
     151                 :            :       {
     152                 :    2541992 :         continue;
     153                 :            :       }
     154                 :    5182969 :       disjuncts.push_back(children[0][i]);
     155                 :    5182969 :       clauseSet.insert(children[0][i]);
     156                 :            :     }
     157         [ -  + ]:     313398 :     if (disjuncts.size() == size)
     158                 :            :     {
     159                 :          0 :       return Node::null();
     160                 :            :     }
     161                 :     313398 :     NodeManager* nm = nodeManager();
     162                 :     313398 :     return nm->mkOr(disjuncts);
     163                 :     313398 :   }
     164         [ +  + ]:    3382028 :   if (id == ProofRule::REORDERING)
     165                 :            :   {
     166 [ -  + ][ -  + ]:    1032085 :     Assert(children.size() == 1);
                 [ -  - ]
     167 [ -  + ][ -  + ]:    1032085 :     Assert(args.size() == 1);
                 [ -  - ]
     168                 :    1032085 :     std::unordered_set<Node> clauseSet1, clauseSet2;
     169         [ +  - ]:    1032085 :     if (children[0].getKind() == Kind::OR)
     170                 :            :     {
     171                 :    1032085 :       clauseSet1.insert(children[0].begin(), children[0].end());
     172                 :            :     }
     173                 :            :     else
     174                 :            :     {
     175                 :          0 :       clauseSet1.insert(children[0]);
     176                 :            :     }
     177         [ +  - ]:    1032085 :     if (args[0].getKind() == Kind::OR)
     178                 :            :     {
     179                 :    1032085 :       clauseSet2.insert(args[0].begin(), args[0].end());
     180                 :            :     }
     181                 :            :     else
     182                 :            :     {
     183                 :          0 :       clauseSet2.insert(args[0]);
     184                 :            :     }
     185         [ -  + ]:    1032085 :     if (clauseSet1 != clauseSet2)
     186                 :            :     {
     187         [ -  - ]:          0 :       Trace("bool-pfcheck") << id << ": clause set1: " << clauseSet1 << "\n"
     188                 :          0 :                             << id << ": clause set2: " << clauseSet2 << "\n";
     189                 :          0 :       return Node::null();
     190                 :            :     }
     191                 :    1032085 :     return args[0];
     192                 :    1032085 :   }
     193         [ +  + ]:    2349943 :   if (id == ProofRule::CHAIN_RESOLUTION)
     194                 :            :   {
     195 [ -  + ][ -  + ]:     334806 :     Assert(children.size() > 1);
                 [ -  - ]
     196 [ -  + ][ -  + ]:     334806 :     Assert(args.size() == 2);
                 [ -  - ]
     197 [ -  + ][ -  + ]:     334806 :     Assert(args[0].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     198 [ -  + ][ -  + ]:     334806 :     Assert(args[1].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     199         [ +  - ]:     334806 :     Trace("bool-pfcheck") << "chain_res:\n" << push;
     200                 :     334806 :     NodeManager* nm = nodeManager();
     201                 :     334806 :     Node trueNode = nm->mkConst(true);
     202                 :     334806 :     Node falseNode = nm->mkConst(false);
     203                 :            :     // The lhs and rhs clauses in a binary resolution step, respectively. Since
     204                 :            :     // children correspond to the premises in the resolution chain, the first
     205                 :            :     // lhs clause is the first premise, the first rhs clause is the second
     206                 :            :     // premise. Each subsequent lhs clause will be the result of the previous
     207                 :            :     // binary resolution step in the chain, while each subsequent rhs clause
     208                 :            :     // will be respectively the second, third etc premises.
     209                 :     334806 :     std::vector<Node> lhsClause, rhsClause;
     210                 :            :     // The pivots to be eliminated to the lhs clause and rhs clause in a binary
     211                 :            :     // resolution step, respectively
     212                 :     334806 :     Node lhsElim, rhsElim;
     213                 :            :     // Get lhsClause of first resolution.
     214                 :            :     //
     215                 :            :     // Since a Node cannot hold an OR with a single child we need to
     216                 :            :     // disambiguate singleton clauses that are OR nodes from non-singleton
     217                 :            :     // clauses (i.e. unit clauses in the SAT solver).
     218                 :            :     //
     219                 :            :     // If the child is not an OR, it is a singleton clause and we take the
     220                 :            :     // child itself as the clause. Otherwise the child can only be a singleton
     221                 :            :     // clause if the child itself is used as a resolution literal, i.e. if the
     222                 :            :     // first child equal to the first pivot (which is args[1][0] or
     223                 :            :     // args[1][0].notNode() depending on the polarity).
     224                 :     334806 :     Node pols = args[0];
     225                 :     334806 :     Node lits = args[1];
     226                 :     334806 :     if (children[0].getKind() != Kind::OR
     227                 :     669349 :         || (pols[0] == trueNode && children[0] == lits[0])
     228                 :    1004155 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
     229                 :            :     {
     230                 :        263 :       lhsClause.push_back(children[0]);
     231                 :            :     }
     232                 :            :     else
     233                 :            :     {
     234                 :     334543 :       lhsClause.insert(lhsClause.end(), children[0].begin(), children[0].end());
     235                 :            :     }
     236                 :            :     // Traverse the links, which amounts to for each pair of args removing a
     237                 :            :     // literal from the lhs and a literal from the lhs.
     238         [ +  + ]:    3042264 :     for (size_t i = 0, argsSize = pols.getNumChildren(); i < argsSize; i++)
     239                 :            :     {
     240                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     241         [ +  + ]:    2707458 :       if (pols[i] == trueNode)
     242                 :            :       {
     243                 :     955839 :         lhsElim = lits[i];
     244                 :     955839 :         rhsElim = lits[i].notNode();
     245                 :            :       }
     246                 :            :       else
     247                 :            :       {
     248 [ -  + ][ -  + ]:    1751619 :         Assert(pols[i] == falseNode);
                 [ -  - ]
     249                 :    1751619 :         lhsElim = lits[i].notNode();
     250                 :    1751619 :         rhsElim = lits[i];
     251                 :            :       }
     252                 :            :       // The index of the child corresponding to the current rhs clause
     253                 :    2707458 :       size_t childIndex = i + 1;
     254                 :            :       // Get rhs clause. It's a singleton if not an OR node or if equal to
     255                 :            :       // rhsElim
     256                 :    2707458 :       if (children[childIndex].getKind() != Kind::OR
     257 [ +  + ][ +  + ]:    2707458 :           || children[childIndex] == rhsElim)
                 [ +  + ]
     258                 :            :       {
     259                 :    1531444 :         rhsClause.push_back(children[childIndex]);
     260                 :            :       }
     261                 :            :       else
     262                 :            :       {
     263                 :    1176014 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     264                 :            :       }
     265         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     266         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     267         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     268         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     269         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << "\t\t - rhsElim: " << rhsElim << "\n";
     270                 :            :       // Compute the resulting clause, which will be the next lhsClause, as
     271                 :            :       // follows:
     272                 :            :       //   - remove lhsElim from lhsClause
     273                 :            :       //   - remove rhsElim from rhsClause and add the lits to lhsClause
     274                 :    2707458 :       auto itlhs = std::find(lhsClause.begin(), lhsClause.end(), lhsElim);
     275 [ -  + ][ -  + ]:    2707458 :       AlwaysAssert(itlhs != lhsClause.end());
                 [ -  - ]
     276                 :    2707458 :       lhsClause.erase(itlhs);
     277         [ +  - ]:    2707458 :       Trace("bool-pfcheck") << "\t.. after lhsClause: " << lhsClause << "\n";
     278                 :    2707458 :       auto itrhs = std::find(rhsClause.begin(), rhsClause.end(), rhsElim);
     279 [ -  + ][ -  + ]:    2707458 :       AlwaysAssert(itrhs != rhsClause.end());
                 [ -  - ]
     280                 :    2707458 :       lhsClause.insert(lhsClause.end(), rhsClause.begin(), itrhs);
     281                 :    2707458 :       lhsClause.insert(lhsClause.end(), itrhs + 1, rhsClause.end());
     282         [ -  + ]:    2707458 :       if (TraceIsOn("bool-pfcheck"))
     283                 :            :       {
     284                 :          0 :         std::vector<Node> updatedRhsClause{rhsClause.begin(), itrhs};
     285                 :          0 :         updatedRhsClause.insert(
     286                 :          0 :             updatedRhsClause.end(), itrhs + 1, rhsClause.end());
     287         [ -  - ]:          0 :         Trace("bool-pfcheck")
     288                 :          0 :             << "\t.. after rhsClause: " << updatedRhsClause << "\n";
     289                 :          0 :       }
     290                 :    2707458 :       rhsClause.clear();
     291                 :            :     }
     292         [ +  - ]:     669612 :     Trace("bool-pfcheck") << "\n resulting clause: " << lhsClause << "\n"
     293                 :     334806 :                           << pop;
     294                 :     334806 :     return nm->mkOr(lhsClause);
     295                 :     334806 :   }
     296         [ +  + ]:    2015137 :   if (id == ProofRule::CHAIN_M_RESOLUTION)
     297                 :            :   {
     298 [ -  + ][ -  + ]:     304602 :     Assert(children.size() > 1);
                 [ -  - ]
     299         [ +  - ]:     304602 :     Trace("bool-pfcheck") << "macro_res: " << args[0] << "\n" << push;
     300                 :     304602 :     NodeManager* nm = nodeManager();
     301                 :     304602 :     Node trueNode = nm->mkConst(true);
     302                 :     304602 :     Node falseNode = nm->mkConst(false);
     303                 :     304602 :     std::vector<Node> lhsClause, rhsClause;
     304                 :     304602 :     Node lhsElim, rhsElim;
     305                 :     304602 :     std::vector<Node> pols, lits;
     306 [ -  + ][ -  + ]:     304602 :     Assert(args.size() == 3);
                 [ -  - ]
     307                 :     304602 :     pols.insert(pols.end(), args[1].begin(), args[1].end());
     308                 :     304602 :     lits.insert(lits.end(), args[2].begin(), args[2].end());
     309         [ -  + ]:     304602 :     if (pols.size() != lits.size())
     310                 :            :     {
     311                 :          0 :       return Node::null();
     312                 :            :     }
     313                 :     304602 :     if (children[0].getKind() != Kind::OR
     314 [ +  + ][ +  - ]:     304383 :         || (pols[0] == trueNode && children[0] == lits[0])
     315 [ +  + ][ +  + ]:     913587 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
         [ -  + ][ +  + ]
         [ +  + ][ -  - ]
     316                 :            :     {
     317                 :        219 :       lhsClause.push_back(children[0]);
     318                 :            :     }
     319                 :            :     else
     320                 :            :     {
     321                 :     304383 :       lhsClause.insert(lhsClause.end(), children[0].begin(), children[0].end());
     322                 :            :     }
     323                 :            :     // Traverse the links, which amounts to for each pair of args removing a
     324                 :            :     // literal from the lhs and a literal from the lhs.
     325         [ +  + ]:    5772659 :     for (size_t i = 0, argsSize = pols.size(); i < argsSize; i++)
     326                 :            :     {
     327                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     328         [ +  + ]:    5468057 :       if (pols[i] == trueNode)
     329                 :            :       {
     330                 :    3320245 :         lhsElim = lits[i];
     331                 :    3320245 :         rhsElim = lits[i].notNode();
     332                 :            :       }
     333                 :            :       else
     334                 :            :       {
     335 [ -  + ][ -  + ]:    2147812 :         Assert(pols[i] == falseNode);
                 [ -  - ]
     336                 :    2147812 :         lhsElim = lits[i].notNode();
     337                 :    2147812 :         rhsElim = lits[i];
     338                 :            :       }
     339                 :            :       // The index of the child corresponding to the current rhs clause
     340                 :    5468057 :       size_t childIndex = i + 1;
     341                 :            :       // Get rhs clause. It's a singleton if not an OR node or if equal to
     342                 :            :       // rhsElim
     343                 :    5468057 :       if (children[childIndex].getKind() != Kind::OR
     344 [ +  + ][ +  + ]:    5468057 :           || children[childIndex] == rhsElim)
                 [ +  + ]
     345                 :            :       {
     346                 :     675100 :         rhsClause.push_back(children[childIndex]);
     347                 :            :       }
     348                 :            :       else
     349                 :            :       {
     350                 :    4792957 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     351                 :            :       }
     352         [ +  - ]:    5468057 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     353         [ +  - ]:    5468057 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     354         [ +  - ]:    5468057 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     355         [ +  - ]:    5468057 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     356         [ +  - ]:    5468057 :       Trace("bool-pfcheck") << "\t\t - rhsElim: " << rhsElim << "\n";
     357                 :            :       // Compute the resulting clause, which will be the next lhsClause, as
     358                 :            :       // follows:
     359                 :            :       //   - remove all lhsElim from lhsClause
     360                 :            :       //   - remove all rhsElim from rhsClause and add the lits to lhsClause
     361                 :            :       //
     362                 :            :       // Note that to remove the elements from lhsClaus we use the
     363                 :            :       // "erase-remove" idiom in C++: the std::remove call shuffles the elements
     364                 :            :       // different from lhsElim to the beginning of the container, returning an
     365                 :            :       // iterator to the beginning of the "rest" of the container (with
     366                 :            :       // occurrences of lhsElim). Then the call to erase removes the range from
     367                 :            :       // there to the end. Once C++ 20 is allowed in the cvc5 code base, this
     368                 :            :       // could be done with a single call to std::erase.
     369                 :    5468057 :       lhsClause.erase(std::remove(lhsClause.begin(), lhsClause.end(), lhsElim),
     370                 :    5468057 :                       lhsClause.end());
     371         [ +  + ]:   24949943 :       for (const Node& l : rhsClause)
     372                 :            :       {
     373                 :            :         // only add if literal does not occur in elimination set
     374         [ +  + ]:   19481886 :         if (rhsElim != l)
     375                 :            :         {
     376                 :   14013829 :           lhsClause.push_back(l);
     377                 :            :         }
     378                 :            :       }
     379                 :    5468057 :       rhsClause.clear();
     380                 :            :     }
     381                 :            : 
     382         [ +  - ]:     304602 :     Trace("bool-pfcheck") << "clause: " << lhsClause << "\n";
     383                 :            :     // check that set representation is the same as of the given conclusion
     384                 :     304602 :     std::unordered_set<Node> clauseComputed{lhsClause.begin(), lhsClause.end()};
     385         [ +  - ]:     304602 :     Trace("bool-pfcheck") << "clauseSet: " << clauseComputed << "\n" << pop;
     386         [ +  + ]:     304602 :     if (clauseComputed.empty())
     387                 :            :     {
     388                 :            :       // conclusion differ
     389         [ -  + ]:       1876 :       if (args[0] != falseNode)
     390                 :            :       {
     391                 :          0 :         return Node::null();
     392                 :            :       }
     393                 :       1876 :       return args[0];
     394                 :            :     }
     395         [ +  + ]:     302726 :     if (clauseComputed.size() == 1)
     396                 :            :     {
     397                 :            :       // conclusion differ
     398         [ -  + ]:      86042 :       if (args[0] != *clauseComputed.begin())
     399                 :            :       {
     400                 :          0 :         return Node::null();
     401                 :            :       }
     402                 :      86042 :       return args[0];
     403                 :            :     }
     404                 :            :     // At this point, should amount to them differing only on order or in
     405                 :            :     // repetitions. So the original result can't be a singleton clause.
     406         [ -  + ]:     216684 :     if (args[0].getKind() != Kind::OR)
     407                 :            :     {
     408                 :          0 :       return Node::null();
     409                 :            :     }
     410                 :     216684 :     std::unordered_set<Node> clauseGiven{args[0].begin(), args[0].end()};
     411         [ +  - ]:     216684 :     return clauseComputed == clauseGiven ? args[0] : Node::null();
     412                 :     304602 :   }
     413         [ +  + ]:    1710535 :   if (id == ProofRule::SPLIT)
     414                 :            :   {
     415 [ -  + ][ -  + ]:      38952 :     Assert(children.empty());
                 [ -  - ]
     416 [ -  + ][ -  + ]:      38952 :     Assert(args.size() == 1);
                 [ -  - ]
     417                 :      38952 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0].notNode());
     418                 :            :   }
     419         [ +  + ]:    1671583 :   if (id == ProofRule::CONTRA)
     420                 :            :   {
     421 [ -  + ][ -  + ]:      66555 :     Assert(children.size() == 2);
                 [ -  - ]
     422 [ +  - ][ +  - ]:      66555 :     if (children[1].getKind() == Kind::NOT && children[0] == children[1][0])
         [ +  - ][ +  - ]
                 [ -  - ]
     423                 :            :     {
     424                 :     133110 :       return nodeManager()->mkConst(false);
     425                 :            :     }
     426                 :          0 :     return Node::null();
     427                 :            :   }
     428         [ +  + ]:    1605028 :   if (id == ProofRule::EQ_RESOLVE)
     429                 :            :   {
     430 [ -  + ][ -  + ]:     417385 :     Assert(children.size() == 2);
                 [ -  - ]
     431 [ -  + ][ -  + ]:     417385 :     Assert(args.empty());
                 [ -  - ]
     432 [ +  - ][ -  + ]:     417385 :     if (children[1].getKind() != Kind::EQUAL || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     433                 :            :     {
     434                 :          0 :       return Node::null();
     435                 :            :     }
     436                 :     417385 :     return children[1][1];
     437                 :            :   }
     438         [ +  + ]:    1187643 :   if (id == ProofRule::MODUS_PONENS)
     439                 :            :   {
     440 [ -  + ][ -  + ]:     233163 :     Assert(children.size() == 2);
                 [ -  - ]
     441 [ -  + ][ -  + ]:     233163 :     Assert(args.empty());
                 [ -  - ]
     442 [ +  - ][ -  + ]:     233163 :     if (children[1].getKind() != Kind::IMPLIES || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     443                 :            :     {
     444                 :          0 :       return Node::null();
     445                 :            :     }
     446                 :     233163 :     return children[1][1];
     447                 :            :   }
     448         [ +  + ]:     954480 :   if (id == ProofRule::NOT_NOT_ELIM)
     449                 :            :   {
     450 [ -  + ][ -  + ]:       5630 :     Assert(children.size() == 1);
                 [ -  - ]
     451 [ -  + ][ -  + ]:       5630 :     Assert(args.empty());
                 [ -  - ]
     452                 :       5630 :     if (children[0].getKind() != Kind::NOT
     453 [ +  - ][ -  + ]:      11260 :         || children[0][0].getKind() != Kind::NOT)
         [ +  - ][ -  + ]
                 [ -  - ]
     454                 :            :     {
     455                 :          0 :       return Node::null();
     456                 :            :     }
     457                 :       5630 :     return children[0][0][0];
     458                 :            :   }
     459                 :            :   // natural deduction rules
     460         [ +  + ]:     948850 :   if (id == ProofRule::AND_ELIM)
     461                 :            :   {
     462 [ -  + ][ -  + ]:     189531 :     Assert(children.size() == 1);
                 [ -  - ]
     463 [ -  + ][ -  + ]:     189531 :     Assert(args.size() == 1);
                 [ -  - ]
     464                 :            :     uint32_t i;
     465 [ +  - ][ -  + ]:     189531 :     if (children[0].getKind() != Kind::AND || !getUInt32(args[0], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     466                 :            :     {
     467                 :          0 :       return Node::null();
     468                 :            :     }
     469         [ -  + ]:     189531 :     if (i >= children[0].getNumChildren())
     470                 :            :     {
     471                 :          0 :       return Node::null();
     472                 :            :     }
     473                 :     189531 :     return children[0][i];
     474                 :            :   }
     475         [ +  + ]:     759319 :   if (id == ProofRule::AND_INTRO)
     476                 :            :   {
     477 [ -  + ][ -  + ]:     254467 :     Assert(children.size() >= 1);
                 [ -  - ]
     478                 :     254467 :     return children.size() == 1 ? children[0]
     479         [ -  + ]:     254467 :                                 : nodeManager()->mkNode(Kind::AND, children);
     480                 :            :   }
     481         [ +  + ]:     504852 :   if (id == ProofRule::NOT_OR_ELIM)
     482                 :            :   {
     483 [ -  + ][ -  + ]:       7338 :     Assert(children.size() == 1);
                 [ -  - ]
     484 [ -  + ][ -  + ]:       7338 :     Assert(args.size() == 1);
                 [ -  - ]
     485                 :            :     uint32_t i;
     486                 :       7338 :     if (children[0].getKind() != Kind::NOT
     487                 :      14676 :         || children[0][0].getKind() != Kind::OR || !getUInt32(args[0], i))
     488                 :            :     {
     489                 :          0 :       return Node::null();
     490                 :            :     }
     491         [ -  + ]:       7338 :     if (i >= children[0][0].getNumChildren())
     492                 :            :     {
     493                 :          0 :       return Node::null();
     494                 :            :     }
     495                 :       7338 :     return children[0][0][i].notNode();
     496                 :            :   }
     497         [ +  + ]:     497514 :   if (id == ProofRule::IMPLIES_ELIM)
     498                 :            :   {
     499 [ -  + ][ -  + ]:      64695 :     Assert(children.size() == 1);
                 [ -  - ]
     500 [ -  + ][ -  + ]:      64695 :     Assert(args.empty());
                 [ -  - ]
     501         [ -  + ]:      64695 :     if (children[0].getKind() != Kind::IMPLIES)
     502                 :            :     {
     503                 :          0 :       return Node::null();
     504                 :            :     }
     505                 :      64695 :     return nodeManager()->mkNode(
     506                 :      64695 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     507                 :            :   }
     508         [ +  + ]:     432819 :   if (id == ProofRule::NOT_IMPLIES_ELIM1)
     509                 :            :   {
     510 [ -  + ][ -  + ]:       4041 :     Assert(children.size() == 1);
                 [ -  - ]
     511 [ -  + ][ -  + ]:       4041 :     Assert(args.empty());
                 [ -  - ]
     512                 :       4041 :     if (children[0].getKind() != Kind::NOT
     513 [ +  - ][ -  + ]:       8082 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     514                 :            :     {
     515                 :          0 :       return Node::null();
     516                 :            :     }
     517                 :       4041 :     return children[0][0][0];
     518                 :            :   }
     519         [ +  + ]:     428778 :   if (id == ProofRule::NOT_IMPLIES_ELIM2)
     520                 :            :   {
     521 [ -  + ][ -  + ]:       1853 :     Assert(children.size() == 1);
                 [ -  - ]
     522 [ -  + ][ -  + ]:       1853 :     Assert(args.empty());
                 [ -  - ]
     523                 :       1853 :     if (children[0].getKind() != Kind::NOT
     524 [ +  - ][ -  + ]:       3706 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     525                 :            :     {
     526                 :          0 :       return Node::null();
     527                 :            :     }
     528                 :       1853 :     return children[0][0][1].notNode();
     529                 :            :   }
     530         [ +  + ]:     426925 :   if (id == ProofRule::EQUIV_ELIM1)
     531                 :            :   {
     532 [ -  + ][ -  + ]:      16330 :     Assert(children.size() == 1);
                 [ -  - ]
     533 [ -  + ][ -  + ]:      16330 :     Assert(args.empty());
                 [ -  - ]
     534         [ -  + ]:      16330 :     if (children[0].getKind() != Kind::EQUAL)
     535                 :            :     {
     536                 :          0 :       return Node::null();
     537                 :            :     }
     538                 :      16330 :     return nodeManager()->mkNode(
     539                 :      16330 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     540                 :            :   }
     541         [ +  + ]:     410595 :   if (id == ProofRule::EQUIV_ELIM2)
     542                 :            :   {
     543 [ -  + ][ -  + ]:       9476 :     Assert(children.size() == 1);
                 [ -  - ]
     544 [ -  + ][ -  + ]:       9476 :     Assert(args.empty());
                 [ -  - ]
     545         [ -  + ]:       9476 :     if (children[0].getKind() != Kind::EQUAL)
     546                 :            :     {
     547                 :          0 :       return Node::null();
     548                 :            :     }
     549                 :       9476 :     return nodeManager()->mkNode(
     550                 :       9476 :         Kind::OR, children[0][0], children[0][1].notNode());
     551                 :            :   }
     552         [ +  + ]:     401119 :   if (id == ProofRule::NOT_EQUIV_ELIM1)
     553                 :            :   {
     554 [ -  + ][ -  + ]:        641 :     Assert(children.size() == 1);
                 [ -  - ]
     555 [ -  + ][ -  + ]:        641 :     Assert(args.empty());
                 [ -  - ]
     556                 :        641 :     if (children[0].getKind() != Kind::NOT
     557 [ +  - ][ -  + ]:       1282 :         || children[0][0].getKind() != Kind::EQUAL)
         [ +  - ][ -  + ]
                 [ -  - ]
     558                 :            :     {
     559                 :          0 :       return Node::null();
     560                 :            :     }
     561                 :        641 :     return nodeManager()->mkNode(
     562                 :        641 :         Kind::OR, children[0][0][0], children[0][0][1]);
     563                 :            :   }
     564         [ +  + ]:     400478 :   if (id == ProofRule::NOT_EQUIV_ELIM2)
     565                 :            :   {
     566 [ -  + ][ -  + ]:        402 :     Assert(children.size() == 1);
                 [ -  - ]
     567 [ -  + ][ -  + ]:        402 :     Assert(args.empty());
                 [ -  - ]
     568                 :        402 :     if (children[0].getKind() != Kind::NOT
     569 [ +  - ][ -  + ]:        804 :         || children[0][0].getKind() != Kind::EQUAL)
         [ +  - ][ -  + ]
                 [ -  - ]
     570                 :            :     {
     571                 :          0 :       return Node::null();
     572                 :            :     }
     573                 :        402 :     return nodeManager()->mkNode(
     574                 :        402 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1].notNode());
     575                 :            :   }
     576         [ +  + ]:     400076 :   if (id == ProofRule::XOR_ELIM1)
     577                 :            :   {
     578 [ -  + ][ -  + ]:         84 :     Assert(children.size() == 1);
                 [ -  - ]
     579 [ -  + ][ -  + ]:         84 :     Assert(args.empty());
                 [ -  - ]
     580         [ -  + ]:         84 :     if (children[0].getKind() != Kind::XOR)
     581                 :            :     {
     582                 :          0 :       return Node::null();
     583                 :            :     }
     584                 :         84 :     return nodeManager()->mkNode(Kind::OR, children[0][0], children[0][1]);
     585                 :            :   }
     586         [ +  + ]:     399992 :   if (id == ProofRule::XOR_ELIM2)
     587                 :            :   {
     588 [ -  + ][ -  + ]:        102 :     Assert(children.size() == 1);
                 [ -  - ]
     589 [ -  + ][ -  + ]:        102 :     Assert(args.empty());
                 [ -  - ]
     590         [ -  + ]:        102 :     if (children[0].getKind() != Kind::XOR)
     591                 :            :     {
     592                 :          0 :       return Node::null();
     593                 :            :     }
     594                 :        102 :     return nodeManager()->mkNode(
     595                 :        102 :         Kind::OR, children[0][0].notNode(), children[0][1].notNode());
     596                 :            :   }
     597         [ +  + ]:     399890 :   if (id == ProofRule::NOT_XOR_ELIM1)
     598                 :            :   {
     599 [ -  + ][ -  + ]:         63 :     Assert(children.size() == 1);
                 [ -  - ]
     600 [ -  + ][ -  + ]:         63 :     Assert(args.empty());
                 [ -  - ]
     601                 :         63 :     if (children[0].getKind() != Kind::NOT
     602 [ +  - ][ -  + ]:        126 :         || children[0][0].getKind() != Kind::XOR)
         [ +  - ][ -  + ]
                 [ -  - ]
     603                 :            :     {
     604                 :          0 :       return Node::null();
     605                 :            :     }
     606                 :         63 :     return nodeManager()->mkNode(
     607                 :         63 :         Kind::OR, children[0][0][0], children[0][0][1].notNode());
     608                 :            :   }
     609         [ +  + ]:     399827 :   if (id == ProofRule::NOT_XOR_ELIM2)
     610                 :            :   {
     611 [ -  + ][ -  + ]:         71 :     Assert(children.size() == 1);
                 [ -  - ]
     612 [ -  + ][ -  + ]:         71 :     Assert(args.empty());
                 [ -  - ]
     613                 :         71 :     if (children[0].getKind() != Kind::NOT
     614 [ +  - ][ -  + ]:        142 :         || children[0][0].getKind() != Kind::XOR)
         [ +  - ][ -  + ]
                 [ -  - ]
     615                 :            :     {
     616                 :          0 :       return Node::null();
     617                 :            :     }
     618                 :         71 :     return nodeManager()->mkNode(
     619                 :         71 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1]);
     620                 :            :   }
     621         [ +  + ]:     399756 :   if (id == ProofRule::ITE_ELIM1)
     622                 :            :   {
     623 [ -  + ][ -  + ]:       4912 :     Assert(children.size() == 1);
                 [ -  - ]
     624 [ -  + ][ -  + ]:       4912 :     Assert(args.empty());
                 [ -  - ]
     625         [ -  + ]:       4912 :     if (children[0].getKind() != Kind::ITE)
     626                 :            :     {
     627                 :          0 :       return Node::null();
     628                 :            :     }
     629                 :       4912 :     return nodeManager()->mkNode(
     630                 :       4912 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     631                 :            :   }
     632         [ +  + ]:     394844 :   if (id == ProofRule::ITE_ELIM2)
     633                 :            :   {
     634 [ -  + ][ -  + ]:      12232 :     Assert(children.size() == 1);
                 [ -  - ]
     635 [ -  + ][ -  + ]:      12232 :     Assert(args.empty());
                 [ -  - ]
     636         [ -  + ]:      12232 :     if (children[0].getKind() != Kind::ITE)
     637                 :            :     {
     638                 :          0 :       return Node::null();
     639                 :            :     }
     640                 :      12232 :     return nodeManager()->mkNode(Kind::OR, children[0][0], children[0][2]);
     641                 :            :   }
     642         [ +  + ]:     382612 :   if (id == ProofRule::NOT_ITE_ELIM1)
     643                 :            :   {
     644 [ -  + ][ -  + ]:         24 :     Assert(children.size() == 1);
                 [ -  - ]
     645 [ -  + ][ -  + ]:         24 :     Assert(args.empty());
                 [ -  - ]
     646                 :         24 :     if (children[0].getKind() != Kind::NOT
     647 [ +  - ][ -  + ]:         48 :         || children[0][0].getKind() != Kind::ITE)
         [ +  - ][ -  + ]
                 [ -  - ]
     648                 :            :     {
     649                 :          0 :       return Node::null();
     650                 :            :     }
     651                 :         24 :     return nodeManager()->mkNode(
     652                 :         24 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1].notNode());
     653                 :            :   }
     654         [ +  + ]:     382588 :   if (id == ProofRule::NOT_ITE_ELIM2)
     655                 :            :   {
     656 [ -  + ][ -  + ]:         52 :     Assert(children.size() == 1);
                 [ -  - ]
     657 [ -  + ][ -  + ]:         52 :     Assert(args.empty());
                 [ -  - ]
     658                 :         52 :     if (children[0].getKind() != Kind::NOT
     659 [ +  - ][ -  + ]:        104 :         || children[0][0].getKind() != Kind::ITE)
         [ +  - ][ -  + ]
                 [ -  - ]
     660                 :            :     {
     661                 :          0 :       return Node::null();
     662                 :            :     }
     663                 :         52 :     return nodeManager()->mkNode(
     664                 :         52 :         Kind::OR, children[0][0][0], children[0][0][2].notNode());
     665                 :            :   }
     666                 :            :   // De Morgan
     667         [ +  + ]:     382536 :   if (id == ProofRule::NOT_AND)
     668                 :            :   {
     669 [ -  + ][ -  + ]:     185007 :     Assert(children.size() == 1);
                 [ -  - ]
     670 [ -  + ][ -  + ]:     185007 :     Assert(args.empty());
                 [ -  - ]
     671                 :     185007 :     if (children[0].getKind() != Kind::NOT
     672 [ +  - ][ -  + ]:     370014 :         || children[0][0].getKind() != Kind::AND)
         [ +  - ][ -  + ]
                 [ -  - ]
     673                 :            :     {
     674                 :          0 :       return Node::null();
     675                 :            :     }
     676                 :     185007 :     std::vector<Node> disjuncts;
     677         [ +  + ]:     924643 :     for (std::size_t i = 0, size = children[0][0].getNumChildren(); i < size;
     678                 :            :          ++i)
     679                 :            :     {
     680                 :     739636 :       disjuncts.push_back(children[0][0][i].notNode());
     681                 :            :     }
     682                 :     185007 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     683                 :     185007 :   }
     684                 :            :   // valid clauses rules for Tseitin CNF transformation
     685         [ +  + ]:     197529 :   if (id == ProofRule::CNF_AND_POS)
     686                 :            :   {
     687 [ -  + ][ -  + ]:      67802 :     Assert(children.empty());
                 [ -  - ]
     688 [ -  + ][ -  + ]:      67802 :     Assert(args.size() == 2);
                 [ -  - ]
     689                 :            :     uint32_t i;
     690 [ +  - ][ -  + ]:      67802 :     if (args[0].getKind() != Kind::AND || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     691                 :            :     {
     692                 :          0 :       return Node::null();
     693                 :            :     }
     694         [ -  + ]:      67802 :     if (i >= args[0].getNumChildren())
     695                 :            :     {
     696                 :          0 :       return Node::null();
     697                 :            :     }
     698                 :      67802 :     return nodeManager()->mkNode(Kind::OR, args[0].notNode(), args[0][i]);
     699                 :            :   }
     700         [ +  + ]:     129727 :   if (id == ProofRule::CNF_AND_NEG)
     701                 :            :   {
     702 [ -  + ][ -  + ]:      50408 :     Assert(children.empty());
                 [ -  - ]
     703 [ -  + ][ -  + ]:      50408 :     Assert(args.size() == 1);
                 [ -  - ]
     704         [ -  + ]:      50408 :     if (args[0].getKind() != Kind::AND)
     705                 :            :     {
     706                 :          0 :       return Node::null();
     707                 :            :     }
     708                 :     151224 :     std::vector<Node> disjuncts{args[0]};
     709         [ +  + ]:     385817 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     710                 :            :     {
     711                 :     335409 :       disjuncts.push_back(args[0][i].notNode());
     712                 :            :     }
     713                 :      50408 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     714                 :      50408 :   }
     715         [ +  + ]:      79319 :   if (id == ProofRule::CNF_OR_POS)
     716                 :            :   {
     717 [ -  + ][ -  + ]:      14602 :     Assert(children.empty());
                 [ -  - ]
     718 [ -  + ][ -  + ]:      14602 :     Assert(args.size() == 1);
                 [ -  - ]
     719         [ -  + ]:      14602 :     if (args[0].getKind() != Kind::OR)
     720                 :            :     {
     721                 :          0 :       return Node::null();
     722                 :            :     }
     723                 :      43806 :     std::vector<Node> disjuncts{args[0].notNode()};
     724         [ +  + ]:    1129910 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     725                 :            :     {
     726                 :    1115308 :       disjuncts.push_back(args[0][i]);
     727                 :            :     }
     728                 :      14602 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     729                 :      14602 :   }
     730         [ +  + ]:      64717 :   if (id == ProofRule::CNF_OR_NEG)
     731                 :            :   {
     732 [ -  + ][ -  + ]:      32236 :     Assert(children.empty());
                 [ -  - ]
     733 [ -  + ][ -  + ]:      32236 :     Assert(args.size() == 2);
                 [ -  - ]
     734                 :            :     uint32_t i;
     735 [ +  - ][ -  + ]:      32236 :     if (args[0].getKind() != Kind::OR || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     736                 :            :     {
     737                 :          0 :       return Node::null();
     738                 :            :     }
     739         [ -  + ]:      32236 :     if (i >= args[0].getNumChildren())
     740                 :            :     {
     741                 :          0 :       return Node::null();
     742                 :            :     }
     743                 :      32236 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0][i].notNode());
     744                 :            :   }
     745         [ +  + ]:      32481 :   if (id == ProofRule::CNF_IMPLIES_POS)
     746                 :            :   {
     747 [ -  + ][ -  + ]:       2574 :     Assert(children.empty());
                 [ -  - ]
     748 [ -  + ][ -  + ]:       2574 :     Assert(args.size() == 1);
                 [ -  - ]
     749         [ -  + ]:       2574 :     if (args[0].getKind() != Kind::IMPLIES)
     750                 :            :     {
     751                 :          0 :       return Node::null();
     752                 :            :     }
     753                 :            :     std::vector<Node> disjuncts{
     754                 :      15444 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     755                 :       2574 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     756                 :       2574 :   }
     757         [ +  + ]:      29907 :   if (id == ProofRule::CNF_IMPLIES_NEG1)
     758                 :            :   {
     759 [ -  + ][ -  + ]:        421 :     Assert(children.empty());
                 [ -  - ]
     760 [ -  + ][ -  + ]:        421 :     Assert(args.size() == 1);
                 [ -  - ]
     761         [ -  + ]:        421 :     if (args[0].getKind() != Kind::IMPLIES)
     762                 :            :     {
     763                 :          0 :       return Node::null();
     764                 :            :     }
     765                 :       1684 :     std::vector<Node> disjuncts{args[0], args[0][0]};
     766                 :        421 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     767                 :        421 :   }
     768         [ +  + ]:      29486 :   if (id == ProofRule::CNF_IMPLIES_NEG2)
     769                 :            :   {
     770 [ -  + ][ -  + ]:       2134 :     Assert(children.empty());
                 [ -  - ]
     771 [ -  + ][ -  + ]:       2134 :     Assert(args.size() == 1);
                 [ -  - ]
     772         [ -  + ]:       2134 :     if (args[0].getKind() != Kind::IMPLIES)
     773                 :            :     {
     774                 :          0 :       return Node::null();
     775                 :            :     }
     776                 :      10670 :     std::vector<Node> disjuncts{args[0], args[0][1].notNode()};
     777                 :       2134 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     778                 :       2134 :   }
     779         [ +  + ]:      27352 :   if (id == ProofRule::CNF_EQUIV_POS1)
     780                 :            :   {
     781 [ -  + ][ -  + ]:       2154 :     Assert(children.empty());
                 [ -  - ]
     782 [ -  + ][ -  + ]:       2154 :     Assert(args.size() == 1);
                 [ -  - ]
     783         [ -  + ]:       2154 :     if (args[0].getKind() != Kind::EQUAL)
     784                 :            :     {
     785                 :          0 :       return Node::null();
     786                 :            :     }
     787                 :            :     std::vector<Node> disjuncts{
     788                 :      12924 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     789                 :       2154 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     790                 :       2154 :   }
     791         [ +  + ]:      25198 :   if (id == ProofRule::CNF_EQUIV_POS2)
     792                 :            :   {
     793 [ -  + ][ -  + ]:       2119 :     Assert(children.empty());
                 [ -  - ]
     794 [ -  + ][ -  + ]:       2119 :     Assert(args.size() == 1);
                 [ -  - ]
     795         [ -  + ]:       2119 :     if (args[0].getKind() != Kind::EQUAL)
     796                 :            :     {
     797                 :          0 :       return Node::null();
     798                 :            :     }
     799                 :            :     std::vector<Node> disjuncts{
     800                 :      12714 :         args[0].notNode(), args[0][0], args[0][1].notNode()};
     801                 :       2119 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     802                 :       2119 :   }
     803         [ +  + ]:      23079 :   if (id == ProofRule::CNF_EQUIV_NEG1)
     804                 :            :   {
     805 [ -  + ][ -  + ]:       2059 :     Assert(children.empty());
                 [ -  - ]
     806 [ -  + ][ -  + ]:       2059 :     Assert(args.size() == 1);
                 [ -  - ]
     807         [ -  + ]:       2059 :     if (args[0].getKind() != Kind::EQUAL)
     808                 :            :     {
     809                 :          0 :       return Node::null();
     810                 :            :     }
     811                 :      10295 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1]};
     812                 :       2059 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     813                 :       2059 :   }
     814         [ +  + ]:      21020 :   if (id == ProofRule::CNF_EQUIV_NEG2)
     815                 :            :   {
     816 [ -  + ][ -  + ]:       3074 :     Assert(children.empty());
                 [ -  - ]
     817 [ -  + ][ -  + ]:       3074 :     Assert(args.size() == 1);
                 [ -  - ]
     818         [ -  + ]:       3074 :     if (args[0].getKind() != Kind::EQUAL)
     819                 :            :     {
     820                 :          0 :       return Node::null();
     821                 :            :     }
     822                 :            :     std::vector<Node> disjuncts{
     823                 :      18444 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     824                 :       3074 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     825                 :       3074 :   }
     826         [ +  + ]:      17946 :   if (id == ProofRule::CNF_XOR_POS1)
     827                 :            :   {
     828 [ -  + ][ -  + ]:       2222 :     Assert(children.empty());
                 [ -  - ]
     829 [ -  + ][ -  + ]:       2222 :     Assert(args.size() == 1);
                 [ -  - ]
     830         [ -  + ]:       2222 :     if (args[0].getKind() != Kind::XOR)
     831                 :            :     {
     832                 :          0 :       return Node::null();
     833                 :            :     }
     834                 :      11110 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][1]};
     835                 :       2222 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     836                 :       2222 :   }
     837         [ +  + ]:      15724 :   if (id == ProofRule::CNF_XOR_POS2)
     838                 :            :   {
     839 [ -  + ][ -  + ]:       1164 :     Assert(children.empty());
                 [ -  - ]
     840 [ -  + ][ -  + ]:       1164 :     Assert(args.size() == 1);
                 [ -  - ]
     841         [ -  + ]:       1164 :     if (args[0].getKind() != Kind::XOR)
     842                 :            :     {
     843                 :          0 :       return Node::null();
     844                 :            :     }
     845                 :            :     std::vector<Node> disjuncts{
     846                 :       6984 :         args[0].notNode(), args[0][0].notNode(), args[0][1].notNode()};
     847                 :       1164 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     848                 :       1164 :   }
     849         [ +  + ]:      14560 :   if (id == ProofRule::CNF_XOR_NEG1)
     850                 :            :   {
     851 [ -  + ][ -  + ]:       1194 :     Assert(children.empty());
                 [ -  - ]
     852 [ -  + ][ -  + ]:       1194 :     Assert(args.size() == 1);
                 [ -  - ]
     853         [ -  + ]:       1194 :     if (args[0].getKind() != Kind::XOR)
     854                 :            :     {
     855                 :          0 :       return Node::null();
     856                 :            :     }
     857                 :       7164 :     std::vector<Node> disjuncts{args[0], args[0][0].notNode(), args[0][1]};
     858                 :       1194 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     859                 :       1194 :   }
     860         [ +  + ]:      13366 :   if (id == ProofRule::CNF_XOR_NEG2)
     861                 :            :   {
     862 [ -  + ][ -  + ]:       1218 :     Assert(children.empty());
                 [ -  - ]
     863 [ -  + ][ -  + ]:       1218 :     Assert(args.size() == 1);
                 [ -  - ]
     864         [ -  + ]:       1218 :     if (args[0].getKind() != Kind::XOR)
     865                 :            :     {
     866                 :          0 :       return Node::null();
     867                 :            :     }
     868                 :       7308 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1].notNode()};
     869                 :       1218 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     870                 :       1218 :   }
     871         [ +  + ]:      12148 :   if (id == ProofRule::CNF_ITE_POS1)
     872                 :            :   {
     873 [ -  + ][ -  + ]:       2127 :     Assert(children.empty());
                 [ -  - ]
     874 [ -  + ][ -  + ]:       2127 :     Assert(args.size() == 1);
                 [ -  - ]
     875         [ -  + ]:       2127 :     if (args[0].getKind() != Kind::ITE)
     876                 :            :     {
     877                 :          0 :       return Node::null();
     878                 :            :     }
     879                 :            :     std::vector<Node> disjuncts{
     880                 :      12762 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     881                 :       2127 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     882                 :       2127 :   }
     883         [ +  + ]:      10021 :   if (id == ProofRule::CNF_ITE_POS2)
     884                 :            :   {
     885 [ -  + ][ -  + ]:       2025 :     Assert(children.empty());
                 [ -  - ]
     886 [ -  + ][ -  + ]:       2025 :     Assert(args.size() == 1);
                 [ -  - ]
     887         [ -  + ]:       2025 :     if (args[0].getKind() != Kind::ITE)
     888                 :            :     {
     889                 :          0 :       return Node::null();
     890                 :            :     }
     891                 :      10125 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][2]};
     892                 :       2025 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     893                 :       2025 :   }
     894         [ +  + ]:       7996 :   if (id == ProofRule::CNF_ITE_POS3)
     895                 :            :   {
     896 [ -  + ][ -  + ]:       2042 :     Assert(children.empty());
                 [ -  - ]
     897 [ -  + ][ -  + ]:       2042 :     Assert(args.size() == 1);
                 [ -  - ]
     898         [ -  + ]:       2042 :     if (args[0].getKind() != Kind::ITE)
     899                 :            :     {
     900                 :          0 :       return Node::null();
     901                 :            :     }
     902                 :      10210 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][1], args[0][2]};
     903                 :       2042 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     904                 :       2042 :   }
     905         [ +  + ]:       5954 :   if (id == ProofRule::CNF_ITE_NEG1)
     906                 :            :   {
     907 [ -  + ][ -  + ]:       3048 :     Assert(children.empty());
                 [ -  - ]
     908 [ -  + ][ -  + ]:       3048 :     Assert(args.size() == 1);
                 [ -  - ]
     909         [ -  + ]:       3048 :     if (args[0].getKind() != Kind::ITE)
     910                 :            :     {
     911                 :          0 :       return Node::null();
     912                 :            :     }
     913                 :            :     std::vector<Node> disjuncts{
     914                 :      18288 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     915                 :       3048 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     916                 :       3048 :   }
     917         [ +  + ]:       2906 :   if (id == ProofRule::CNF_ITE_NEG2)
     918                 :            :   {
     919 [ -  + ][ -  + ]:       1378 :     Assert(children.empty());
                 [ -  - ]
     920 [ -  + ][ -  + ]:       1378 :     Assert(args.size() == 1);
                 [ -  - ]
     921         [ -  + ]:       1378 :     if (args[0].getKind() != Kind::ITE)
     922                 :            :     {
     923                 :          0 :       return Node::null();
     924                 :            :     }
     925                 :       8268 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][2].notNode()};
     926                 :       1378 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     927                 :       1378 :   }
     928         [ +  + ]:       1528 :   if (id == ProofRule::CNF_ITE_NEG3)
     929                 :            :   {
     930 [ -  + ][ -  + ]:       1353 :     Assert(children.empty());
                 [ -  - ]
     931 [ -  + ][ -  + ]:       1353 :     Assert(args.size() == 1);
                 [ -  - ]
     932         [ -  + ]:       1353 :     if (args[0].getKind() != Kind::ITE)
     933                 :            :     {
     934                 :          0 :       return Node::null();
     935                 :            :     }
     936                 :            :     std::vector<Node> disjuncts{
     937                 :       8118 :         args[0], args[0][1].notNode(), args[0][2].notNode()};
     938                 :       1353 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     939                 :       1353 :   }
     940 [ -  + ][ -  - ]:        175 :   if (id == ProofRule::SAT_REFUTATION || id == ProofRule::DRAT_REFUTATION
     941         [ -  - ]:          0 :       || id == ProofRule::SAT_EXTERNAL_PROVE)
     942                 :            :   {
     943 [ -  + ][ -  - ]:        175 :     Assert(args.size()
         [ -  + ][ -  + ]
                 [ -  - ]
     944                 :            :            == (id == ProofRule::SAT_REFUTATION
     945                 :            :                    ? 0
     946                 :            :                    : (id == ProofRule::SAT_EXTERNAL_PROVE ? 1 : 2)));
     947                 :        350 :     return nodeManager()->mkConst(false);
     948                 :            :   }
     949                 :            :   // no rule
     950                 :          0 :   return Node::null();
     951                 :            : }
     952                 :            : 
     953                 :            : }  // namespace booleans
     954                 :            : }  // namespace theory
     955                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14