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-04-02 10:40:46 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                 :      50907 : BoolProofRuleChecker::BoolProofRuleChecker(NodeManager* nm)
      22                 :      50907 :     : ProofRuleChecker(nm)
      23                 :            : {
      24                 :      50907 : }
      25                 :            : 
      26                 :      19673 : void BoolProofRuleChecker::registerTo(ProofChecker* pc)
      27                 :            : {
      28                 :      19673 :   pc->registerChecker(ProofRule::SPLIT, this);
      29                 :      19673 :   pc->registerChecker(ProofRule::RESOLUTION, this);
      30                 :      19673 :   pc->registerChecker(ProofRule::CHAIN_RESOLUTION, this);
      31                 :      19673 :   pc->registerChecker(ProofRule::CHAIN_M_RESOLUTION, this);
      32                 :      19673 :   pc->registerChecker(ProofRule::FACTORING, this);
      33                 :      19673 :   pc->registerChecker(ProofRule::REORDERING, this);
      34                 :      19673 :   pc->registerChecker(ProofRule::EQ_RESOLVE, this);
      35                 :      19673 :   pc->registerChecker(ProofRule::MODUS_PONENS, this);
      36                 :      19673 :   pc->registerChecker(ProofRule::NOT_NOT_ELIM, this);
      37                 :      19673 :   pc->registerChecker(ProofRule::CONTRA, this);
      38                 :      19673 :   pc->registerChecker(ProofRule::AND_ELIM, this);
      39                 :      19673 :   pc->registerChecker(ProofRule::AND_INTRO, this);
      40                 :      19673 :   pc->registerChecker(ProofRule::NOT_OR_ELIM, this);
      41                 :      19673 :   pc->registerChecker(ProofRule::IMPLIES_ELIM, this);
      42                 :      19673 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM1, this);
      43                 :      19673 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM2, this);
      44                 :      19673 :   pc->registerChecker(ProofRule::EQUIV_ELIM1, this);
      45                 :      19673 :   pc->registerChecker(ProofRule::EQUIV_ELIM2, this);
      46                 :      19673 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM1, this);
      47                 :      19673 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM2, this);
      48                 :      19673 :   pc->registerChecker(ProofRule::XOR_ELIM1, this);
      49                 :      19673 :   pc->registerChecker(ProofRule::XOR_ELIM2, this);
      50                 :      19673 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM1, this);
      51                 :      19673 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM2, this);
      52                 :      19673 :   pc->registerChecker(ProofRule::ITE_ELIM1, this);
      53                 :      19673 :   pc->registerChecker(ProofRule::ITE_ELIM2, this);
      54                 :      19673 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM1, this);
      55                 :      19673 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM2, this);
      56                 :      19673 :   pc->registerChecker(ProofRule::NOT_AND, this);
      57                 :      19673 :   pc->registerChecker(ProofRule::CNF_AND_POS, this);
      58                 :      19673 :   pc->registerChecker(ProofRule::CNF_AND_NEG, this);
      59                 :      19673 :   pc->registerChecker(ProofRule::CNF_OR_POS, this);
      60                 :      19673 :   pc->registerChecker(ProofRule::CNF_OR_NEG, this);
      61                 :      19673 :   pc->registerChecker(ProofRule::CNF_IMPLIES_POS, this);
      62                 :      19673 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG1, this);
      63                 :      19673 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG2, this);
      64                 :      19673 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS1, this);
      65                 :      19673 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS2, this);
      66                 :      19673 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG1, this);
      67                 :      19673 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG2, this);
      68                 :      19673 :   pc->registerChecker(ProofRule::CNF_XOR_POS1, this);
      69                 :      19673 :   pc->registerChecker(ProofRule::CNF_XOR_POS2, this);
      70                 :      19673 :   pc->registerChecker(ProofRule::CNF_XOR_NEG1, this);
      71                 :      19673 :   pc->registerChecker(ProofRule::CNF_XOR_NEG2, this);
      72                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_POS1, this);
      73                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_POS2, this);
      74                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_POS3, this);
      75                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_NEG1, this);
      76                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_NEG2, this);
      77                 :      19673 :   pc->registerChecker(ProofRule::CNF_ITE_NEG3, this);
      78                 :      19673 :   pc->registerTrustedChecker(ProofRule::SAT_REFUTATION, this, 1);
      79                 :      19673 :   pc->registerTrustedChecker(ProofRule::DRAT_REFUTATION, this, 1);
      80                 :      19673 :   pc->registerTrustedChecker(ProofRule::SAT_EXTERNAL_PROVE, this, 1);
      81                 :      19673 : }
      82                 :            : 
      83                 :    5002558 : Node BoolProofRuleChecker::checkInternal(ProofRule id,
      84                 :            :                                          const std::vector<Node>& children,
      85                 :            :                                          const std::vector<Node>& args)
      86                 :            : {
      87         [ +  + ]:    5002558 :   if (id == ProofRule::RESOLUTION)
      88                 :            :   {
      89 [ -  + ][ -  + ]:     946890 :     Assert(children.size() == 2);
                 [ -  - ]
      90 [ -  + ][ -  + ]:     946890 :     Assert(args.size() == 2);
                 [ -  - ]
      91                 :     946890 :     NodeManager* nm = nodeManager();
      92                 :     946890 :     std::vector<Node> disjuncts;
      93         [ +  + ]:    4734450 :     Node pivots[2];
      94         [ +  + ]:     946890 :     if (args[0] == nm->mkConst(true))
      95                 :            :     {
      96                 :     515725 :       pivots[0] = args[1];
      97                 :     515725 :       pivots[1] = args[1].notNode();
      98                 :            :     }
      99                 :            :     else
     100                 :            :     {
     101 [ -  + ][ -  + ]:     431165 :       Assert(args[0] == nm->mkConst(false));
                 [ -  - ]
     102                 :     431165 :       pivots[0] = args[1].notNode();
     103                 :     431165 :       pivots[1] = args[1];
     104                 :            :     }
     105         [ +  + ]:    2840670 :     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                 :    1893780 :       std::vector<Node> lits;
     111 [ +  + ][ +  + ]:    1893780 :       if (children[i].getKind() == Kind::OR && pivots[i] != children[i])
                 [ +  + ]
     112                 :            :       {
     113                 :    1583608 :         lits.insert(lits.end(), children[i].begin(), children[i].end());
     114                 :            :       }
     115                 :            :       else
     116                 :            :       {
     117                 :     310172 :         lits.push_back(children[i]);
     118                 :            :       }
     119         [ +  + ]:   21671870 :       for (unsigned j = 0, size = lits.size(); j < size; ++j)
     120                 :            :       {
     121         [ +  + ]:   19778090 :         if (pivots[i] != lits[j])
     122                 :            :         {
     123                 :   17884310 :           disjuncts.push_back(lits[j]);
     124                 :            :         }
     125                 :            :         else
     126                 :            :         {
     127                 :            :           // just eliminate first occurrence
     128                 :    1893780 :           pivots[i] = Node::null();
     129                 :            :         }
     130                 :            :       }
     131                 :    1893780 :     }
     132                 :    1893780 :     return disjuncts.empty()       ? nm->mkConst(false)
     133                 :    1044698 :            : disjuncts.size() == 1 ? disjuncts[0]
     134 [ +  + ][ +  + ]:    1991588 :                                    : nm->mkNode(Kind::OR, disjuncts);
     135 [ +  + ][ -  - ]:    3787560 :   }
     136         [ +  + ]:    4055668 :   if (id == ProofRule::FACTORING)
     137                 :            :   {
     138 [ -  + ][ -  + ]:     349556 :     Assert(children.size() == 1);
                 [ -  - ]
     139 [ -  + ][ -  + ]:     349556 :     Assert(args.empty());
                 [ -  - ]
     140         [ -  + ]:     349556 :     if (children[0].getKind() != Kind::OR)
     141                 :            :     {
     142                 :          0 :       return Node::null();
     143                 :            :     }
     144                 :            :     // remove duplicates while keeping the order of children
     145                 :     349556 :     std::unordered_set<TNode> clauseSet;
     146                 :     349556 :     std::vector<Node> disjuncts;
     147                 :     349556 :     unsigned size = children[0].getNumChildren();
     148         [ +  + ]:    9076067 :     for (unsigned i = 0; i < size; ++i)
     149                 :            :     {
     150         [ +  + ]:    8726511 :       if (clauseSet.count(children[0][i]))
     151                 :            :       {
     152                 :    2699214 :         continue;
     153                 :            :       }
     154                 :    6027297 :       disjuncts.push_back(children[0][i]);
     155                 :    6027297 :       clauseSet.insert(children[0][i]);
     156                 :            :     }
     157         [ -  + ]:     349556 :     if (disjuncts.size() == size)
     158                 :            :     {
     159                 :          0 :       return Node::null();
     160                 :            :     }
     161                 :     349556 :     NodeManager* nm = nodeManager();
     162                 :     349556 :     return nm->mkOr(disjuncts);
     163                 :     349556 :   }
     164         [ +  + ]:    3706112 :   if (id == ProofRule::REORDERING)
     165                 :            :   {
     166 [ -  + ][ -  + ]:    1254624 :     Assert(children.size() == 1);
                 [ -  - ]
     167 [ -  + ][ -  + ]:    1254624 :     Assert(args.size() == 1);
                 [ -  - ]
     168                 :    1254624 :     std::unordered_set<Node> clauseSet1, clauseSet2;
     169         [ +  - ]:    1254624 :     if (children[0].getKind() == Kind::OR)
     170                 :            :     {
     171                 :    1254624 :       clauseSet1.insert(children[0].begin(), children[0].end());
     172                 :            :     }
     173                 :            :     else
     174                 :            :     {
     175                 :          0 :       clauseSet1.insert(children[0]);
     176                 :            :     }
     177         [ +  - ]:    1254624 :     if (args[0].getKind() == Kind::OR)
     178                 :            :     {
     179                 :    1254624 :       clauseSet2.insert(args[0].begin(), args[0].end());
     180                 :            :     }
     181                 :            :     else
     182                 :            :     {
     183                 :          0 :       clauseSet2.insert(args[0]);
     184                 :            :     }
     185         [ -  + ]:    1254624 :     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                 :    1254624 :     return args[0];
     192                 :    1254624 :   }
     193         [ +  + ]:    2451488 :   if (id == ProofRule::CHAIN_RESOLUTION)
     194                 :            :   {
     195 [ -  + ][ -  + ]:     361920 :     Assert(children.size() > 1);
                 [ -  - ]
     196 [ -  + ][ -  + ]:     361920 :     Assert(args.size() == 2);
                 [ -  - ]
     197 [ -  + ][ -  + ]:     361920 :     Assert(args[0].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     198 [ -  + ][ -  + ]:     361920 :     Assert(args[1].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     199         [ +  - ]:     361920 :     Trace("bool-pfcheck") << "chain_res:\n" << push;
     200                 :     361920 :     NodeManager* nm = nodeManager();
     201                 :     361920 :     Node trueNode = nm->mkConst(true);
     202                 :     361920 :     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                 :     361920 :     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                 :     361920 :     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                 :     361920 :     Node pols = args[0];
     225                 :     361920 :     Node lits = args[1];
     226                 :     361920 :     if (children[0].getKind() != Kind::OR
     227                 :     723577 :         || (pols[0] == trueNode && children[0] == lits[0])
     228                 :    1085497 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
     229                 :            :     {
     230                 :        263 :       lhsClause.push_back(children[0]);
     231                 :            :     }
     232                 :            :     else
     233                 :            :     {
     234                 :     361657 :       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         [ +  + ]:    3347162 :     for (size_t i = 0, argsSize = pols.getNumChildren(); i < argsSize; i++)
     239                 :            :     {
     240                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     241         [ +  + ]:    2985242 :       if (pols[i] == trueNode)
     242                 :            :       {
     243                 :    1147989 :         lhsElim = lits[i];
     244                 :    1147989 :         rhsElim = lits[i].notNode();
     245                 :            :       }
     246                 :            :       else
     247                 :            :       {
     248 [ -  + ][ -  + ]:    1837253 :         Assert(pols[i] == falseNode);
                 [ -  - ]
     249                 :    1837253 :         lhsElim = lits[i].notNode();
     250                 :    1837253 :         rhsElim = lits[i];
     251                 :            :       }
     252                 :            :       // The index of the child corresponding to the current rhs clause
     253                 :    2985242 :       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                 :    2985242 :       if (children[childIndex].getKind() != Kind::OR
     257 [ +  + ][ +  + ]:    2985242 :           || children[childIndex] == rhsElim)
                 [ +  + ]
     258                 :            :       {
     259                 :    1548092 :         rhsClause.push_back(children[childIndex]);
     260                 :            :       }
     261                 :            :       else
     262                 :            :       {
     263                 :    1437150 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     264                 :            :       }
     265         [ +  - ]:    2985242 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     266         [ +  - ]:    2985242 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     267         [ +  - ]:    2985242 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     268         [ +  - ]:    2985242 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     269         [ +  - ]:    2985242 :       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                 :    2985242 :       auto itlhs = std::find(lhsClause.begin(), lhsClause.end(), lhsElim);
     275 [ -  + ][ -  + ]:    2985242 :       AlwaysAssert(itlhs != lhsClause.end());
                 [ -  - ]
     276                 :    2985242 :       lhsClause.erase(itlhs);
     277         [ +  - ]:    2985242 :       Trace("bool-pfcheck") << "\t.. after lhsClause: " << lhsClause << "\n";
     278                 :    2985242 :       auto itrhs = std::find(rhsClause.begin(), rhsClause.end(), rhsElim);
     279 [ -  + ][ -  + ]:    2985242 :       AlwaysAssert(itrhs != rhsClause.end());
                 [ -  - ]
     280                 :    2985242 :       lhsClause.insert(lhsClause.end(), rhsClause.begin(), itrhs);
     281                 :    2985242 :       lhsClause.insert(lhsClause.end(), itrhs + 1, rhsClause.end());
     282         [ -  + ]:    2985242 :       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                 :    2985242 :       rhsClause.clear();
     291                 :            :     }
     292         [ +  - ]:     723840 :     Trace("bool-pfcheck") << "\n resulting clause: " << lhsClause << "\n"
     293                 :     361920 :                           << pop;
     294                 :     361920 :     return nm->mkOr(lhsClause);
     295                 :     361920 :   }
     296         [ +  + ]:    2089568 :   if (id == ProofRule::CHAIN_M_RESOLUTION)
     297                 :            :   {
     298 [ -  + ][ -  + ]:     307203 :     Assert(children.size() > 1);
                 [ -  - ]
     299         [ +  - ]:     307203 :     Trace("bool-pfcheck") << "macro_res: " << args[0] << "\n" << push;
     300                 :     307203 :     NodeManager* nm = nodeManager();
     301                 :     307203 :     Node trueNode = nm->mkConst(true);
     302                 :     307203 :     Node falseNode = nm->mkConst(false);
     303                 :     307203 :     std::vector<Node> lhsClause, rhsClause;
     304                 :     307203 :     Node lhsElim, rhsElim;
     305                 :     307203 :     std::vector<Node> pols, lits;
     306 [ -  + ][ -  + ]:     307203 :     Assert(args.size() == 3);
                 [ -  - ]
     307                 :     307203 :     pols.insert(pols.end(), args[1].begin(), args[1].end());
     308                 :     307203 :     lits.insert(lits.end(), args[2].begin(), args[2].end());
     309         [ -  + ]:     307203 :     if (pols.size() != lits.size())
     310                 :            :     {
     311                 :          0 :       return Node::null();
     312                 :            :     }
     313                 :     307203 :     if (children[0].getKind() != Kind::OR
     314 [ +  + ][ +  - ]:     306984 :         || (pols[0] == trueNode && children[0] == lits[0])
     315 [ +  + ][ +  + ]:     921390 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
         [ -  + ][ +  + ]
         [ +  + ][ -  - ]
     316                 :            :     {
     317                 :        219 :       lhsClause.push_back(children[0]);
     318                 :            :     }
     319                 :            :     else
     320                 :            :     {
     321                 :     306984 :       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         [ +  + ]:    5605794 :     for (size_t i = 0, argsSize = pols.size(); i < argsSize; i++)
     326                 :            :     {
     327                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     328         [ +  + ]:    5298591 :       if (pols[i] == trueNode)
     329                 :            :       {
     330                 :    3199026 :         lhsElim = lits[i];
     331                 :    3199026 :         rhsElim = lits[i].notNode();
     332                 :            :       }
     333                 :            :       else
     334                 :            :       {
     335 [ -  + ][ -  + ]:    2099565 :         Assert(pols[i] == falseNode);
                 [ -  - ]
     336                 :    2099565 :         lhsElim = lits[i].notNode();
     337                 :    2099565 :         rhsElim = lits[i];
     338                 :            :       }
     339                 :            :       // The index of the child corresponding to the current rhs clause
     340                 :    5298591 :       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                 :    5298591 :       if (children[childIndex].getKind() != Kind::OR
     344 [ +  + ][ +  + ]:    5298591 :           || children[childIndex] == rhsElim)
                 [ +  + ]
     345                 :            :       {
     346                 :     679992 :         rhsClause.push_back(children[childIndex]);
     347                 :            :       }
     348                 :            :       else
     349                 :            :       {
     350                 :    4618599 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     351                 :            :       }
     352         [ +  - ]:    5298591 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     353         [ +  - ]:    5298591 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     354         [ +  - ]:    5298591 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     355         [ +  - ]:    5298591 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     356         [ +  - ]:    5298591 :       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                 :    5298591 :       lhsClause.erase(std::remove(lhsClause.begin(), lhsClause.end(), lhsElim),
     370                 :    5298591 :                       lhsClause.end());
     371         [ +  + ]:   24319717 :       for (const Node& l : rhsClause)
     372                 :            :       {
     373                 :            :         // only add if literal does not occur in elimination set
     374         [ +  + ]:   19021126 :         if (rhsElim != l)
     375                 :            :         {
     376                 :   13722535 :           lhsClause.push_back(l);
     377                 :            :         }
     378                 :            :       }
     379                 :    5298591 :       rhsClause.clear();
     380                 :            :     }
     381                 :            : 
     382         [ +  - ]:     307203 :     Trace("bool-pfcheck") << "clause: " << lhsClause << "\n";
     383                 :            :     // check that set representation is the same as of the given conclusion
     384                 :     307203 :     std::unordered_set<Node> clauseComputed{lhsClause.begin(), lhsClause.end()};
     385         [ +  - ]:     307203 :     Trace("bool-pfcheck") << "clauseSet: " << clauseComputed << "\n" << pop;
     386         [ +  + ]:     307203 :     if (clauseComputed.empty())
     387                 :            :     {
     388                 :            :       // conclusion differ
     389         [ -  + ]:       1893 :       if (args[0] != falseNode)
     390                 :            :       {
     391                 :          0 :         return Node::null();
     392                 :            :       }
     393                 :       1893 :       return args[0];
     394                 :            :     }
     395         [ +  + ]:     305310 :     if (clauseComputed.size() == 1)
     396                 :            :     {
     397                 :            :       // conclusion differ
     398         [ -  + ]:      87870 :       if (args[0] != *clauseComputed.begin())
     399                 :            :       {
     400                 :          0 :         return Node::null();
     401                 :            :       }
     402                 :      87870 :       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         [ -  + ]:     217440 :     if (args[0].getKind() != Kind::OR)
     407                 :            :     {
     408                 :          0 :       return Node::null();
     409                 :            :     }
     410                 :     217440 :     std::unordered_set<Node> clauseGiven{args[0].begin(), args[0].end()};
     411         [ +  - ]:     217440 :     return clauseComputed == clauseGiven ? args[0] : Node::null();
     412                 :     307203 :   }
     413         [ +  + ]:    1782365 :   if (id == ProofRule::SPLIT)
     414                 :            :   {
     415 [ -  + ][ -  + ]:      39007 :     Assert(children.empty());
                 [ -  - ]
     416 [ -  + ][ -  + ]:      39007 :     Assert(args.size() == 1);
                 [ -  - ]
     417                 :      39007 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0].notNode());
     418                 :            :   }
     419         [ +  + ]:    1743358 :   if (id == ProofRule::CONTRA)
     420                 :            :   {
     421 [ -  + ][ -  + ]:      68136 :     Assert(children.size() == 2);
                 [ -  - ]
     422 [ +  - ][ +  - ]:      68136 :     if (children[1].getKind() == Kind::NOT && children[0] == children[1][0])
         [ +  - ][ +  - ]
                 [ -  - ]
     423                 :            :     {
     424                 :     136272 :       return nodeManager()->mkConst(false);
     425                 :            :     }
     426                 :          0 :     return Node::null();
     427                 :            :   }
     428         [ +  + ]:    1675222 :   if (id == ProofRule::EQ_RESOLVE)
     429                 :            :   {
     430 [ -  + ][ -  + ]:     423648 :     Assert(children.size() == 2);
                 [ -  - ]
     431 [ -  + ][ -  + ]:     423648 :     Assert(args.empty());
                 [ -  - ]
     432 [ +  - ][ -  + ]:     423648 :     if (children[1].getKind() != Kind::EQUAL || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     433                 :            :     {
     434                 :          0 :       return Node::null();
     435                 :            :     }
     436                 :     423648 :     return children[1][1];
     437                 :            :   }
     438         [ +  + ]:    1251574 :   if (id == ProofRule::MODUS_PONENS)
     439                 :            :   {
     440 [ -  + ][ -  + ]:     237683 :     Assert(children.size() == 2);
                 [ -  - ]
     441 [ -  + ][ -  + ]:     237683 :     Assert(args.empty());
                 [ -  - ]
     442 [ +  - ][ -  + ]:     237683 :     if (children[1].getKind() != Kind::IMPLIES || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     443                 :            :     {
     444                 :          0 :       return Node::null();
     445                 :            :     }
     446                 :     237683 :     return children[1][1];
     447                 :            :   }
     448         [ +  + ]:    1013891 :   if (id == ProofRule::NOT_NOT_ELIM)
     449                 :            :   {
     450 [ -  + ][ -  + ]:       5663 :     Assert(children.size() == 1);
                 [ -  - ]
     451 [ -  + ][ -  + ]:       5663 :     Assert(args.empty());
                 [ -  - ]
     452                 :       5663 :     if (children[0].getKind() != Kind::NOT
     453 [ +  - ][ -  + ]:      11326 :         || children[0][0].getKind() != Kind::NOT)
         [ +  - ][ -  + ]
                 [ -  - ]
     454                 :            :     {
     455                 :          0 :       return Node::null();
     456                 :            :     }
     457                 :       5663 :     return children[0][0][0];
     458                 :            :   }
     459                 :            :   // natural deduction rules
     460         [ +  + ]:    1008228 :   if (id == ProofRule::AND_ELIM)
     461                 :            :   {
     462 [ -  + ][ -  + ]:     190867 :     Assert(children.size() == 1);
                 [ -  - ]
     463 [ -  + ][ -  + ]:     190867 :     Assert(args.size() == 1);
                 [ -  - ]
     464                 :            :     uint32_t i;
     465 [ +  - ][ -  + ]:     190867 :     if (children[0].getKind() != Kind::AND || !getUInt32(args[0], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     466                 :            :     {
     467                 :          0 :       return Node::null();
     468                 :            :     }
     469         [ -  + ]:     190867 :     if (i >= children[0].getNumChildren())
     470                 :            :     {
     471                 :          0 :       return Node::null();
     472                 :            :     }
     473                 :     190867 :     return children[0][i];
     474                 :            :   }
     475         [ +  + ]:     817361 :   if (id == ProofRule::AND_INTRO)
     476                 :            :   {
     477 [ -  + ][ -  + ]:     259108 :     Assert(children.size() >= 1);
                 [ -  - ]
     478                 :     259108 :     return children.size() == 1 ? children[0]
     479         [ -  + ]:     259108 :                                 : nodeManager()->mkNode(Kind::AND, children);
     480                 :            :   }
     481         [ +  + ]:     558253 :   if (id == ProofRule::NOT_OR_ELIM)
     482                 :            :   {
     483 [ -  + ][ -  + ]:       7363 :     Assert(children.size() == 1);
                 [ -  - ]
     484 [ -  + ][ -  + ]:       7363 :     Assert(args.size() == 1);
                 [ -  - ]
     485                 :            :     uint32_t i;
     486                 :       7363 :     if (children[0].getKind() != Kind::NOT
     487                 :      14726 :         || children[0][0].getKind() != Kind::OR || !getUInt32(args[0], i))
     488                 :            :     {
     489                 :          0 :       return Node::null();
     490                 :            :     }
     491         [ -  + ]:       7363 :     if (i >= children[0][0].getNumChildren())
     492                 :            :     {
     493                 :          0 :       return Node::null();
     494                 :            :     }
     495                 :       7363 :     return children[0][0][i].notNode();
     496                 :            :   }
     497         [ +  + ]:     550890 :   if (id == ProofRule::IMPLIES_ELIM)
     498                 :            :   {
     499 [ -  + ][ -  + ]:      65606 :     Assert(children.size() == 1);
                 [ -  - ]
     500 [ -  + ][ -  + ]:      65606 :     Assert(args.empty());
                 [ -  - ]
     501         [ -  + ]:      65606 :     if (children[0].getKind() != Kind::IMPLIES)
     502                 :            :     {
     503                 :          0 :       return Node::null();
     504                 :            :     }
     505                 :      65606 :     return nodeManager()->mkNode(
     506                 :      65606 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     507                 :            :   }
     508         [ +  + ]:     485284 :   if (id == ProofRule::NOT_IMPLIES_ELIM1)
     509                 :            :   {
     510 [ -  + ][ -  + ]:       4069 :     Assert(children.size() == 1);
                 [ -  - ]
     511 [ -  + ][ -  + ]:       4069 :     Assert(args.empty());
                 [ -  - ]
     512                 :       4069 :     if (children[0].getKind() != Kind::NOT
     513 [ +  - ][ -  + ]:       8138 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     514                 :            :     {
     515                 :          0 :       return Node::null();
     516                 :            :     }
     517                 :       4069 :     return children[0][0][0];
     518                 :            :   }
     519         [ +  + ]:     481215 :   if (id == ProofRule::NOT_IMPLIES_ELIM2)
     520                 :            :   {
     521 [ -  + ][ -  + ]:       1879 :     Assert(children.size() == 1);
                 [ -  - ]
     522 [ -  + ][ -  + ]:       1879 :     Assert(args.empty());
                 [ -  - ]
     523                 :       1879 :     if (children[0].getKind() != Kind::NOT
     524 [ +  - ][ -  + ]:       3758 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     525                 :            :     {
     526                 :          0 :       return Node::null();
     527                 :            :     }
     528                 :       1879 :     return children[0][0][1].notNode();
     529                 :            :   }
     530         [ +  + ]:     479336 :   if (id == ProofRule::EQUIV_ELIM1)
     531                 :            :   {
     532 [ -  + ][ -  + ]:      33931 :     Assert(children.size() == 1);
                 [ -  - ]
     533 [ -  + ][ -  + ]:      33931 :     Assert(args.empty());
                 [ -  - ]
     534         [ -  + ]:      33931 :     if (children[0].getKind() != Kind::EQUAL)
     535                 :            :     {
     536                 :          0 :       return Node::null();
     537                 :            :     }
     538                 :      33931 :     return nodeManager()->mkNode(
     539                 :      33931 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     540                 :            :   }
     541         [ +  + ]:     445405 :   if (id == ProofRule::EQUIV_ELIM2)
     542                 :            :   {
     543 [ -  + ][ -  + ]:      15348 :     Assert(children.size() == 1);
                 [ -  - ]
     544 [ -  + ][ -  + ]:      15348 :     Assert(args.empty());
                 [ -  - ]
     545         [ -  + ]:      15348 :     if (children[0].getKind() != Kind::EQUAL)
     546                 :            :     {
     547                 :          0 :       return Node::null();
     548                 :            :     }
     549                 :      15348 :     return nodeManager()->mkNode(
     550                 :      15348 :         Kind::OR, children[0][0], children[0][1].notNode());
     551                 :            :   }
     552         [ +  + ]:     430057 :   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         [ +  + ]:     429416 :   if (id == ProofRule::NOT_EQUIV_ELIM2)
     565                 :            :   {
     566 [ -  + ][ -  + ]:        404 :     Assert(children.size() == 1);
                 [ -  - ]
     567 [ -  + ][ -  + ]:        404 :     Assert(args.empty());
                 [ -  - ]
     568                 :        404 :     if (children[0].getKind() != Kind::NOT
     569 [ +  - ][ -  + ]:        808 :         || children[0][0].getKind() != Kind::EQUAL)
         [ +  - ][ -  + ]
                 [ -  - ]
     570                 :            :     {
     571                 :          0 :       return Node::null();
     572                 :            :     }
     573                 :        404 :     return nodeManager()->mkNode(
     574                 :        404 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1].notNode());
     575                 :            :   }
     576         [ +  + ]:     429012 :   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         [ +  + ]:     428928 :   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         [ +  + ]:     428826 :   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         [ +  + ]:     428763 :   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         [ +  + ]:     428692 :   if (id == ProofRule::ITE_ELIM1)
     622                 :            :   {
     623 [ -  + ][ -  + ]:       5379 :     Assert(children.size() == 1);
                 [ -  - ]
     624 [ -  + ][ -  + ]:       5379 :     Assert(args.empty());
                 [ -  - ]
     625         [ -  + ]:       5379 :     if (children[0].getKind() != Kind::ITE)
     626                 :            :     {
     627                 :          0 :       return Node::null();
     628                 :            :     }
     629                 :       5379 :     return nodeManager()->mkNode(
     630                 :       5379 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     631                 :            :   }
     632         [ +  + ]:     423313 :   if (id == ProofRule::ITE_ELIM2)
     633                 :            :   {
     634 [ -  + ][ -  + ]:      13413 :     Assert(children.size() == 1);
                 [ -  - ]
     635 [ -  + ][ -  + ]:      13413 :     Assert(args.empty());
                 [ -  - ]
     636         [ -  + ]:      13413 :     if (children[0].getKind() != Kind::ITE)
     637                 :            :     {
     638                 :          0 :       return Node::null();
     639                 :            :     }
     640                 :      13413 :     return nodeManager()->mkNode(Kind::OR, children[0][0], children[0][2]);
     641                 :            :   }
     642         [ +  + ]:     409900 :   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         [ +  + ]:     409876 :   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         [ +  + ]:     409824 :   if (id == ProofRule::NOT_AND)
     668                 :            :   {
     669 [ -  + ][ -  + ]:     187079 :     Assert(children.size() == 1);
                 [ -  - ]
     670 [ -  + ][ -  + ]:     187079 :     Assert(args.empty());
                 [ -  - ]
     671                 :     187079 :     if (children[0].getKind() != Kind::NOT
     672 [ +  - ][ -  + ]:     374158 :         || children[0][0].getKind() != Kind::AND)
         [ +  - ][ -  + ]
                 [ -  - ]
     673                 :            :     {
     674                 :          0 :       return Node::null();
     675                 :            :     }
     676                 :     187079 :     std::vector<Node> disjuncts;
     677         [ +  + ]:     935888 :     for (std::size_t i = 0, size = children[0][0].getNumChildren(); i < size;
     678                 :            :          ++i)
     679                 :            :     {
     680                 :     748809 :       disjuncts.push_back(children[0][0][i].notNode());
     681                 :            :     }
     682                 :     187079 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     683                 :     187079 :   }
     684                 :            :   // valid clauses rules for Tseitin CNF transformation
     685         [ +  + ]:     222745 :   if (id == ProofRule::CNF_AND_POS)
     686                 :            :   {
     687 [ -  + ][ -  + ]:      70474 :     Assert(children.empty());
                 [ -  - ]
     688 [ -  + ][ -  + ]:      70474 :     Assert(args.size() == 2);
                 [ -  - ]
     689                 :            :     uint32_t i;
     690 [ +  - ][ -  + ]:      70474 :     if (args[0].getKind() != Kind::AND || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     691                 :            :     {
     692                 :          0 :       return Node::null();
     693                 :            :     }
     694         [ -  + ]:      70474 :     if (i >= args[0].getNumChildren())
     695                 :            :     {
     696                 :          0 :       return Node::null();
     697                 :            :     }
     698                 :      70474 :     return nodeManager()->mkNode(Kind::OR, args[0].notNode(), args[0][i]);
     699                 :            :   }
     700         [ +  + ]:     152271 :   if (id == ProofRule::CNF_AND_NEG)
     701                 :            :   {
     702 [ -  + ][ -  + ]:      56722 :     Assert(children.empty());
                 [ -  - ]
     703 [ -  + ][ -  + ]:      56722 :     Assert(args.size() == 1);
                 [ -  - ]
     704         [ -  + ]:      56722 :     if (args[0].getKind() != Kind::AND)
     705                 :            :     {
     706                 :          0 :       return Node::null();
     707                 :            :     }
     708                 :     170166 :     std::vector<Node> disjuncts{args[0]};
     709         [ +  + ]:     408731 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     710                 :            :     {
     711                 :     352009 :       disjuncts.push_back(args[0][i].notNode());
     712                 :            :     }
     713                 :      56722 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     714                 :      56722 :   }
     715         [ +  + ]:      95549 :   if (id == ProofRule::CNF_OR_POS)
     716                 :            :   {
     717 [ -  + ][ -  + ]:      15543 :     Assert(children.empty());
                 [ -  - ]
     718 [ -  + ][ -  + ]:      15543 :     Assert(args.size() == 1);
                 [ -  - ]
     719         [ -  + ]:      15543 :     if (args[0].getKind() != Kind::OR)
     720                 :            :     {
     721                 :          0 :       return Node::null();
     722                 :            :     }
     723                 :      46629 :     std::vector<Node> disjuncts{args[0].notNode()};
     724         [ +  + ]:    1132757 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     725                 :            :     {
     726                 :    1117214 :       disjuncts.push_back(args[0][i]);
     727                 :            :     }
     728                 :      15543 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     729                 :      15543 :   }
     730         [ +  + ]:      80006 :   if (id == ProofRule::CNF_OR_NEG)
     731                 :            :   {
     732 [ -  + ][ -  + ]:      42988 :     Assert(children.empty());
                 [ -  - ]
     733 [ -  + ][ -  + ]:      42988 :     Assert(args.size() == 2);
                 [ -  - ]
     734                 :            :     uint32_t i;
     735 [ +  - ][ -  + ]:      42988 :     if (args[0].getKind() != Kind::OR || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     736                 :            :     {
     737                 :          0 :       return Node::null();
     738                 :            :     }
     739         [ -  + ]:      42988 :     if (i >= args[0].getNumChildren())
     740                 :            :     {
     741                 :          0 :       return Node::null();
     742                 :            :     }
     743                 :      42988 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0][i].notNode());
     744                 :            :   }
     745         [ +  + ]:      37018 :   if (id == ProofRule::CNF_IMPLIES_POS)
     746                 :            :   {
     747 [ -  + ][ -  + ]:       2610 :     Assert(children.empty());
                 [ -  - ]
     748 [ -  + ][ -  + ]:       2610 :     Assert(args.size() == 1);
                 [ -  - ]
     749         [ -  + ]:       2610 :     if (args[0].getKind() != Kind::IMPLIES)
     750                 :            :     {
     751                 :          0 :       return Node::null();
     752                 :            :     }
     753                 :            :     std::vector<Node> disjuncts{
     754                 :      15660 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     755                 :       2610 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     756                 :       2610 :   }
     757         [ +  + ]:      34408 :   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         [ +  + ]:      33987 :   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         [ +  + ]:      31853 :   if (id == ProofRule::CNF_EQUIV_POS1)
     780                 :            :   {
     781 [ -  + ][ -  + ]:       2322 :     Assert(children.empty());
                 [ -  - ]
     782 [ -  + ][ -  + ]:       2322 :     Assert(args.size() == 1);
                 [ -  - ]
     783         [ -  + ]:       2322 :     if (args[0].getKind() != Kind::EQUAL)
     784                 :            :     {
     785                 :          0 :       return Node::null();
     786                 :            :     }
     787                 :            :     std::vector<Node> disjuncts{
     788                 :      13932 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     789                 :       2322 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     790                 :       2322 :   }
     791         [ +  + ]:      29531 :   if (id == ProofRule::CNF_EQUIV_POS2)
     792                 :            :   {
     793 [ -  + ][ -  + ]:       2245 :     Assert(children.empty());
                 [ -  - ]
     794 [ -  + ][ -  + ]:       2245 :     Assert(args.size() == 1);
                 [ -  - ]
     795         [ -  + ]:       2245 :     if (args[0].getKind() != Kind::EQUAL)
     796                 :            :     {
     797                 :          0 :       return Node::null();
     798                 :            :     }
     799                 :            :     std::vector<Node> disjuncts{
     800                 :      13470 :         args[0].notNode(), args[0][0], args[0][1].notNode()};
     801                 :       2245 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     802                 :       2245 :   }
     803         [ +  + ]:      27286 :   if (id == ProofRule::CNF_EQUIV_NEG1)
     804                 :            :   {
     805 [ -  + ][ -  + ]:       2321 :     Assert(children.empty());
                 [ -  - ]
     806 [ -  + ][ -  + ]:       2321 :     Assert(args.size() == 1);
                 [ -  - ]
     807         [ -  + ]:       2321 :     if (args[0].getKind() != Kind::EQUAL)
     808                 :            :     {
     809                 :          0 :       return Node::null();
     810                 :            :     }
     811                 :      11605 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1]};
     812                 :       2321 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     813                 :       2321 :   }
     814         [ +  + ]:      24965 :   if (id == ProofRule::CNF_EQUIV_NEG2)
     815                 :            :   {
     816 [ -  + ][ -  + ]:       4459 :     Assert(children.empty());
                 [ -  - ]
     817 [ -  + ][ -  + ]:       4459 :     Assert(args.size() == 1);
                 [ -  - ]
     818         [ -  + ]:       4459 :     if (args[0].getKind() != Kind::EQUAL)
     819                 :            :     {
     820                 :          0 :       return Node::null();
     821                 :            :     }
     822                 :            :     std::vector<Node> disjuncts{
     823                 :      26754 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     824                 :       4459 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     825                 :       4459 :   }
     826         [ +  + ]:      20506 :   if (id == ProofRule::CNF_XOR_POS1)
     827                 :            :   {
     828 [ -  + ][ -  + ]:       2765 :     Assert(children.empty());
                 [ -  - ]
     829 [ -  + ][ -  + ]:       2765 :     Assert(args.size() == 1);
                 [ -  - ]
     830         [ -  + ]:       2765 :     if (args[0].getKind() != Kind::XOR)
     831                 :            :     {
     832                 :          0 :       return Node::null();
     833                 :            :     }
     834                 :      13825 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][1]};
     835                 :       2765 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     836                 :       2765 :   }
     837         [ +  + ]:      17741 :   if (id == ProofRule::CNF_XOR_POS2)
     838                 :            :   {
     839 [ -  + ][ -  + ]:       1550 :     Assert(children.empty());
                 [ -  - ]
     840 [ -  + ][ -  + ]:       1550 :     Assert(args.size() == 1);
                 [ -  - ]
     841         [ -  + ]:       1550 :     if (args[0].getKind() != Kind::XOR)
     842                 :            :     {
     843                 :          0 :       return Node::null();
     844                 :            :     }
     845                 :            :     std::vector<Node> disjuncts{
     846                 :       9300 :         args[0].notNode(), args[0][0].notNode(), args[0][1].notNode()};
     847                 :       1550 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     848                 :       1550 :   }
     849         [ +  + ]:      16191 :   if (id == ProofRule::CNF_XOR_NEG1)
     850                 :            :   {
     851 [ -  + ][ -  + ]:       1974 :     Assert(children.empty());
                 [ -  - ]
     852 [ -  + ][ -  + ]:       1974 :     Assert(args.size() == 1);
                 [ -  - ]
     853         [ -  + ]:       1974 :     if (args[0].getKind() != Kind::XOR)
     854                 :            :     {
     855                 :          0 :       return Node::null();
     856                 :            :     }
     857                 :      11844 :     std::vector<Node> disjuncts{args[0], args[0][0].notNode(), args[0][1]};
     858                 :       1974 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     859                 :       1974 :   }
     860         [ +  + ]:      14217 :   if (id == ProofRule::CNF_XOR_NEG2)
     861                 :            :   {
     862 [ -  + ][ -  + ]:       1716 :     Assert(children.empty());
                 [ -  - ]
     863 [ -  + ][ -  + ]:       1716 :     Assert(args.size() == 1);
                 [ -  - ]
     864         [ -  + ]:       1716 :     if (args[0].getKind() != Kind::XOR)
     865                 :            :     {
     866                 :          0 :       return Node::null();
     867                 :            :     }
     868                 :      10296 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1].notNode()};
     869                 :       1716 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     870                 :       1716 :   }
     871         [ +  + ]:      12501 :   if (id == ProofRule::CNF_ITE_POS1)
     872                 :            :   {
     873 [ -  + ][ -  + ]:       2218 :     Assert(children.empty());
                 [ -  - ]
     874 [ -  + ][ -  + ]:       2218 :     Assert(args.size() == 1);
                 [ -  - ]
     875         [ -  + ]:       2218 :     if (args[0].getKind() != Kind::ITE)
     876                 :            :     {
     877                 :          0 :       return Node::null();
     878                 :            :     }
     879                 :            :     std::vector<Node> disjuncts{
     880                 :      13308 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     881                 :       2218 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     882                 :       2218 :   }
     883         [ +  + ]:      10283 :   if (id == ProofRule::CNF_ITE_POS2)
     884                 :            :   {
     885 [ -  + ][ -  + ]:       2017 :     Assert(children.empty());
                 [ -  - ]
     886 [ -  + ][ -  + ]:       2017 :     Assert(args.size() == 1);
                 [ -  - ]
     887         [ -  + ]:       2017 :     if (args[0].getKind() != Kind::ITE)
     888                 :            :     {
     889                 :          0 :       return Node::null();
     890                 :            :     }
     891                 :      10085 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][2]};
     892                 :       2017 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     893                 :       2017 :   }
     894         [ +  + ]:       8266 :   if (id == ProofRule::CNF_ITE_POS3)
     895                 :            :   {
     896 [ -  + ][ -  + ]:       2435 :     Assert(children.empty());
                 [ -  - ]
     897 [ -  + ][ -  + ]:       2435 :     Assert(args.size() == 1);
                 [ -  - ]
     898         [ -  + ]:       2435 :     if (args[0].getKind() != Kind::ITE)
     899                 :            :     {
     900                 :          0 :       return Node::null();
     901                 :            :     }
     902                 :      12175 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][1], args[0][2]};
     903                 :       2435 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     904                 :       2435 :   }
     905         [ +  + ]:       5831 :   if (id == ProofRule::CNF_ITE_NEG1)
     906                 :            :   {
     907 [ -  + ][ -  + ]:       3006 :     Assert(children.empty());
                 [ -  - ]
     908 [ -  + ][ -  + ]:       3006 :     Assert(args.size() == 1);
                 [ -  - ]
     909         [ -  + ]:       3006 :     if (args[0].getKind() != Kind::ITE)
     910                 :            :     {
     911                 :          0 :       return Node::null();
     912                 :            :     }
     913                 :            :     std::vector<Node> disjuncts{
     914                 :      18036 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     915                 :       3006 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     916                 :       3006 :   }
     917         [ +  + ]:       2825 :   if (id == ProofRule::CNF_ITE_NEG2)
     918                 :            :   {
     919 [ -  + ][ -  + ]:       1357 :     Assert(children.empty());
                 [ -  - ]
     920 [ -  + ][ -  + ]:       1357 :     Assert(args.size() == 1);
                 [ -  - ]
     921         [ -  + ]:       1357 :     if (args[0].getKind() != Kind::ITE)
     922                 :            :     {
     923                 :          0 :       return Node::null();
     924                 :            :     }
     925                 :       8142 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][2].notNode()};
     926                 :       1357 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     927                 :       1357 :   }
     928         [ +  + ]:       1468 :   if (id == ProofRule::CNF_ITE_NEG3)
     929                 :            :   {
     930 [ -  + ][ -  + ]:       1293 :     Assert(children.empty());
                 [ -  - ]
     931 [ -  + ][ -  + ]:       1293 :     Assert(args.size() == 1);
                 [ -  - ]
     932         [ -  + ]:       1293 :     if (args[0].getKind() != Kind::ITE)
     933                 :            :     {
     934                 :          0 :       return Node::null();
     935                 :            :     }
     936                 :            :     std::vector<Node> disjuncts{
     937                 :       7758 :         args[0], args[0][1].notNode(), args[0][2].notNode()};
     938                 :       1293 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     939                 :       1293 :   }
     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