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: 428 543 78.8 %
Date: 2024-11-17 12:40:58 Functions: 3 3 100.0 %
Branches: 464 1078 43.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Haniel Barbosa, Hans-Joerg Schurr, Aina Niemetz
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Implementation of equality proof checker.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/booleans/proof_checker.h"
      17                 :            : #include "expr/skolem_manager.h"
      18                 :            : #include "theory/rewriter.h"
      19                 :            : 
      20                 :            : namespace cvc5::internal {
      21                 :            : namespace theory {
      22                 :            : namespace booleans {
      23                 :            : 
      24                 :      49837 : BoolProofRuleChecker::BoolProofRuleChecker(NodeManager* nm)
      25                 :      49837 :     : ProofRuleChecker(nm)
      26                 :            : {
      27                 :      49837 : }
      28                 :            : 
      29                 :      19203 : void BoolProofRuleChecker::registerTo(ProofChecker* pc)
      30                 :            : {
      31                 :      19203 :   pc->registerChecker(ProofRule::SPLIT, this);
      32                 :      19203 :   pc->registerChecker(ProofRule::RESOLUTION, this);
      33                 :      19203 :   pc->registerChecker(ProofRule::CHAIN_RESOLUTION, this);
      34                 :      19203 :   pc->registerTrustedChecker(ProofRule::MACRO_RESOLUTION_TRUST, this, 3);
      35                 :      19203 :   pc->registerChecker(ProofRule::MACRO_RESOLUTION, this);
      36                 :      19203 :   pc->registerChecker(ProofRule::FACTORING, this);
      37                 :      19203 :   pc->registerChecker(ProofRule::REORDERING, this);
      38                 :      19203 :   pc->registerChecker(ProofRule::EQ_RESOLVE, this);
      39                 :      19203 :   pc->registerChecker(ProofRule::MODUS_PONENS, this);
      40                 :      19203 :   pc->registerChecker(ProofRule::NOT_NOT_ELIM, this);
      41                 :      19203 :   pc->registerChecker(ProofRule::CONTRA, this);
      42                 :      19203 :   pc->registerChecker(ProofRule::AND_ELIM, this);
      43                 :      19203 :   pc->registerChecker(ProofRule::AND_INTRO, this);
      44                 :      19203 :   pc->registerChecker(ProofRule::NOT_OR_ELIM, this);
      45                 :      19203 :   pc->registerChecker(ProofRule::IMPLIES_ELIM, this);
      46                 :      19203 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM1, this);
      47                 :      19203 :   pc->registerChecker(ProofRule::NOT_IMPLIES_ELIM2, this);
      48                 :      19203 :   pc->registerChecker(ProofRule::EQUIV_ELIM1, this);
      49                 :      19203 :   pc->registerChecker(ProofRule::EQUIV_ELIM2, this);
      50                 :      19203 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM1, this);
      51                 :      19203 :   pc->registerChecker(ProofRule::NOT_EQUIV_ELIM2, this);
      52                 :      19203 :   pc->registerChecker(ProofRule::XOR_ELIM1, this);
      53                 :      19203 :   pc->registerChecker(ProofRule::XOR_ELIM2, this);
      54                 :      19203 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM1, this);
      55                 :      19203 :   pc->registerChecker(ProofRule::NOT_XOR_ELIM2, this);
      56                 :      19203 :   pc->registerChecker(ProofRule::ITE_ELIM1, this);
      57                 :      19203 :   pc->registerChecker(ProofRule::ITE_ELIM2, this);
      58                 :      19203 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM1, this);
      59                 :      19203 :   pc->registerChecker(ProofRule::NOT_ITE_ELIM2, this);
      60                 :      19203 :   pc->registerChecker(ProofRule::NOT_AND, this);
      61                 :      19203 :   pc->registerChecker(ProofRule::CNF_AND_POS, this);
      62                 :      19203 :   pc->registerChecker(ProofRule::CNF_AND_NEG, this);
      63                 :      19203 :   pc->registerChecker(ProofRule::CNF_OR_POS, this);
      64                 :      19203 :   pc->registerChecker(ProofRule::CNF_OR_NEG, this);
      65                 :      19203 :   pc->registerChecker(ProofRule::CNF_IMPLIES_POS, this);
      66                 :      19203 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG1, this);
      67                 :      19203 :   pc->registerChecker(ProofRule::CNF_IMPLIES_NEG2, this);
      68                 :      19203 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS1, this);
      69                 :      19203 :   pc->registerChecker(ProofRule::CNF_EQUIV_POS2, this);
      70                 :      19203 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG1, this);
      71                 :      19203 :   pc->registerChecker(ProofRule::CNF_EQUIV_NEG2, this);
      72                 :      19203 :   pc->registerChecker(ProofRule::CNF_XOR_POS1, this);
      73                 :      19203 :   pc->registerChecker(ProofRule::CNF_XOR_POS2, this);
      74                 :      19203 :   pc->registerChecker(ProofRule::CNF_XOR_NEG1, this);
      75                 :      19203 :   pc->registerChecker(ProofRule::CNF_XOR_NEG2, this);
      76                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_POS1, this);
      77                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_POS2, this);
      78                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_POS3, this);
      79                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_NEG1, this);
      80                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_NEG2, this);
      81                 :      19203 :   pc->registerChecker(ProofRule::CNF_ITE_NEG3, this);
      82                 :      19203 :   pc->registerTrustedChecker(ProofRule::SAT_REFUTATION, this, 1);
      83                 :      19203 :   pc->registerTrustedChecker(ProofRule::DRAT_REFUTATION, this, 1);
      84                 :      19203 :   pc->registerTrustedChecker(ProofRule::SAT_EXTERNAL_PROVE, this, 1);
      85                 :      19203 : }
      86                 :            : 
      87                 :    8967660 : Node BoolProofRuleChecker::checkInternal(ProofRule id,
      88                 :            :                                          const std::vector<Node>& children,
      89                 :            :                                          const std::vector<Node>& args)
      90                 :            : {
      91         [ +  + ]:    8967660 :   if (id == ProofRule::RESOLUTION)
      92                 :            :   {
      93 [ -  + ][ -  + ]:     770158 :     Assert(children.size() == 2);
                 [ -  - ]
      94 [ -  + ][ -  + ]:     770158 :     Assert(args.size() == 2);
                 [ -  - ]
      95                 :     770158 :     NodeManager* nm = nodeManager();
      96                 :    1540320 :     std::vector<Node> disjuncts;
      97 [ +  + ][ +  + ]:    4620950 :     Node pivots[2];
                 [ -  - ]
      98         [ +  + ]:     770158 :     if (args[0] == nm->mkConst(true))
      99                 :            :     {
     100                 :     405103 :       pivots[0] = args[1];
     101                 :     405103 :       pivots[1] = args[1].notNode();
     102                 :            :     }
     103                 :            :     else
     104                 :            :     {
     105 [ -  + ][ -  + ]:     365055 :       Assert(args[0] == nm->mkConst(false));
                 [ -  - ]
     106                 :     365055 :       pivots[0] = args[1].notNode();
     107                 :     365055 :       pivots[1] = args[1];
     108                 :            :     }
     109         [ +  + ]:    2310470 :     for (unsigned i = 0; i < 2; ++i)
     110                 :            :     {
     111                 :            :       // determine whether the clause is a singleton for effects of resolution,
     112                 :            :       // which is the case if it's not an OR node or it is an OR node but it is
     113                 :            :       // equal to the pivot
     114                 :    3080630 :       std::vector<Node> lits;
     115 [ +  + ][ +  + ]:    1540320 :       if (children[i].getKind() == Kind::OR && pivots[i] != children[i])
                 [ +  + ]
     116                 :            :       {
     117                 :    1258880 :         lits.insert(lits.end(), children[i].begin(), children[i].end());
     118                 :            :       }
     119                 :            :       else
     120                 :            :       {
     121                 :     281441 :         lits.push_back(children[i]);
     122                 :            :       }
     123         [ +  + ]:   15083600 :       for (unsigned j = 0, size = lits.size(); j < size; ++j)
     124                 :            :       {
     125         [ +  + ]:   13543300 :         if (pivots[i] != lits[j])
     126                 :            :         {
     127                 :   12003000 :           disjuncts.push_back(lits[j]);
     128                 :            :         }
     129                 :            :         else
     130                 :            :         {
     131                 :            :           // just eliminate first occurrence
     132                 :    1540320 :           pivots[i] = Node::null();
     133                 :            :         }
     134                 :            :       }
     135                 :            :     }
     136                 :    1540320 :     return disjuncts.empty()       ? nm->mkConst(false)
     137                 :     860999 :            : disjuncts.size() == 1 ? disjuncts[0]
     138 [ +  + ][ +  + ]:    1631160 :                                    : nm->mkNode(Kind::OR, disjuncts);
     139                 :            :   }
     140         [ +  + ]:    8197500 :   if (id == ProofRule::FACTORING)
     141                 :            :   {
     142 [ -  + ][ -  + ]:    1639300 :     Assert(children.size() == 1);
                 [ -  - ]
     143 [ -  + ][ -  + ]:    1639300 :     Assert(args.empty());
                 [ -  - ]
     144         [ -  + ]:    1639300 :     if (children[0].getKind() != Kind::OR)
     145                 :            :     {
     146                 :          0 :       return Node::null();
     147                 :            :     }
     148                 :            :     // remove duplicates while keeping the order of children
     149                 :    3278600 :     std::unordered_set<TNode> clauseSet;
     150                 :    3278600 :     std::vector<Node> disjuncts;
     151                 :    1639300 :     unsigned size = children[0].getNumChildren();
     152         [ +  + ]:   56350600 :     for (unsigned i = 0; i < size; ++i)
     153                 :            :     {
     154         [ +  + ]:   54711300 :       if (clauseSet.count(children[0][i]))
     155                 :            :       {
     156                 :   10908200 :         continue;
     157                 :            :       }
     158                 :   43803100 :       disjuncts.push_back(children[0][i]);
     159                 :   43803100 :       clauseSet.insert(children[0][i]);
     160                 :            :     }
     161         [ -  + ]:    1639300 :     if (disjuncts.size() == size)
     162                 :            :     {
     163                 :          0 :       return Node::null();
     164                 :            :     }
     165                 :    1639300 :     NodeManager* nm = nodeManager();
     166                 :    1639300 :     return nm->mkOr(disjuncts);
     167                 :            :   }
     168         [ +  + ]:    6558200 :   if (id == ProofRule::REORDERING)
     169                 :            :   {
     170 [ -  + ][ -  + ]:    2341460 :     Assert(children.size() == 1);
                 [ -  - ]
     171 [ -  + ][ -  + ]:    2341460 :     Assert(args.size() == 1);
                 [ -  - ]
     172                 :    4682920 :     std::unordered_set<Node> clauseSet1, clauseSet2;
     173         [ +  - ]:    2341460 :     if (children[0].getKind() == Kind::OR)
     174                 :            :     {
     175                 :    2341460 :       clauseSet1.insert(children[0].begin(), children[0].end());
     176                 :            :     }
     177                 :            :     else
     178                 :            :     {
     179                 :          0 :       clauseSet1.insert(children[0]);
     180                 :            :     }
     181         [ +  - ]:    2341460 :     if (args[0].getKind() == Kind::OR)
     182                 :            :     {
     183                 :    2341460 :       clauseSet2.insert(args[0].begin(), args[0].end());
     184                 :            :     }
     185                 :            :     else
     186                 :            :     {
     187                 :          0 :       clauseSet2.insert(args[0]);
     188                 :            :     }
     189         [ -  + ]:    2341460 :     if (clauseSet1 != clauseSet2)
     190                 :            :     {
     191         [ -  - ]:          0 :       Trace("bool-pfcheck") << id << ": clause set1: " << clauseSet1 << "\n"
     192                 :          0 :                             << id << ": clause set2: " << clauseSet2 << "\n";
     193                 :          0 :       return Node::null();
     194                 :            :     }
     195                 :    2341460 :     return args[0];
     196                 :            :   }
     197         [ +  + ]:    4216750 :   if (id == ProofRule::CHAIN_RESOLUTION)
     198                 :            :   {
     199 [ -  + ][ -  + ]:    1865000 :     Assert(children.size() > 1);
                 [ -  - ]
     200 [ -  + ][ -  + ]:    1865000 :     Assert(args.size() == 2);
                 [ -  - ]
     201 [ -  + ][ -  + ]:    1865000 :     Assert(args[0].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     202 [ -  + ][ -  + ]:    1865000 :     Assert(args[1].getNumChildren() == (children.size() - 1));
                 [ -  - ]
     203         [ +  - ]:    1865000 :     Trace("bool-pfcheck") << "chain_res:\n" << push;
     204                 :    1865000 :     NodeManager* nm = nodeManager();
     205                 :    3730000 :     Node trueNode = nm->mkConst(true);
     206                 :    3730000 :     Node falseNode = nm->mkConst(false);
     207                 :            :     // The lhs and rhs clauses in a binary resolution step, respectively. Since
     208                 :            :     // children correspond to the premises in the resolution chain, the first
     209                 :            :     // lhs clause is the first premise, the first rhs clause is the second
     210                 :            :     // premise. Each subsequent lhs clause will be the result of the previous
     211                 :            :     // binary resolution step in the chain, while each subsequent rhs clause
     212                 :            :     // will be respectively the second, third etc premises.
     213                 :    3730000 :     std::vector<Node> lhsClause, rhsClause;
     214                 :            :     // The pivots to be eliminated to the lhs clause and rhs clause in a binary
     215                 :            :     // resolution step, respectively
     216                 :    3730000 :     Node lhsElim, rhsElim;
     217                 :            :     // Get lhsClause of first resolution.
     218                 :            :     //
     219                 :            :     // Since a Node cannot hold an OR with a single child we need to
     220                 :            :     // disambiguate singleton clauses that are OR nodes from non-singleton
     221                 :            :     // clauses (i.e. unit clauses in the SAT solver).
     222                 :            :     //
     223                 :            :     // If the child is not an OR, it is a singleton clause and we take the
     224                 :            :     // child itself as the clause. Otherwise the child can only be a singleton
     225                 :            :     // clause if the child itself is used as a resolution literal, i.e. if the
     226                 :            :     // first child equal to the first pivot (which is args[1][0] or
     227                 :            :     // args[1][0].notNode() depending on the polarity).
     228                 :    3730000 :     Node pols = args[0];
     229                 :    3730000 :     Node lits = args[1];
     230                 :    1865000 :     if (children[0].getKind() != Kind::OR
     231                 :    3729030 :         || (pols[0] == trueNode && children[0] == lits[0])
     232                 :    5594030 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
     233                 :            :     {
     234                 :        972 :       lhsClause.push_back(children[0]);
     235                 :            :     }
     236                 :            :     else
     237                 :            :     {
     238                 :    1864030 :       lhsClause.insert(lhsClause.end(), children[0].begin(), children[0].end());
     239                 :            :     }
     240                 :            :     // Traverse the links, which amounts to for each pair of args removing a
     241                 :            :     // literal from the lhs and a literal from the lhs.
     242         [ +  + ]:   13813800 :     for (size_t i = 0, argsSize = pols.getNumChildren(); i < argsSize; i++)
     243                 :            :     {
     244                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     245         [ +  + ]:   11948800 :       if (pols[i] == trueNode)
     246                 :            :       {
     247                 :    6301420 :         lhsElim = lits[i];
     248                 :    6301420 :         rhsElim = lits[i].notNode();
     249                 :            :       }
     250                 :            :       else
     251                 :            :       {
     252 [ -  + ][ -  + ]:    5647420 :         Assert(pols[i] == falseNode);
                 [ -  - ]
     253                 :    5647420 :         lhsElim = lits[i].notNode();
     254                 :    5647420 :         rhsElim = lits[i];
     255                 :            :       }
     256                 :            :       // The index of the child corresponding to the current rhs clause
     257                 :   11948800 :       size_t childIndex = i + 1;
     258                 :            :       // Get rhs clause. It's a singleton if not an OR node or if equal to
     259                 :            :       // rhsElim
     260                 :   11948800 :       if (children[childIndex].getKind() != Kind::OR
     261 [ +  + ][ +  + ]:   11948800 :           || children[childIndex] == rhsElim)
                 [ +  + ]
     262                 :            :       {
     263                 :    3069040 :         rhsClause.push_back(children[childIndex]);
     264                 :            :       }
     265                 :            :       else
     266                 :            :       {
     267                 :    8879800 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     268                 :            :       }
     269         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     270         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     271         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     272         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     273         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << "\t\t - rhsElim: " << rhsElim << "\n";
     274                 :            :       // Compute the resulting clause, which will be the next lhsClause, as
     275                 :            :       // follows:
     276                 :            :       //   - remove lhsElim from lhsClause
     277                 :            :       //   - remove rhsElim from rhsClause and add the lits to lhsClause
     278                 :   11948800 :       auto itlhs = std::find(lhsClause.begin(), lhsClause.end(), lhsElim);
     279 [ -  + ][ -  + ]:   11948800 :       AlwaysAssert(itlhs != lhsClause.end());
                 [ -  - ]
     280                 :   11948800 :       lhsClause.erase(itlhs);
     281         [ +  - ]:   11948800 :       Trace("bool-pfcheck") << "\t.. after lhsClause: " << lhsClause << "\n";
     282                 :   11948800 :       auto itrhs = std::find(rhsClause.begin(), rhsClause.end(), rhsElim);
     283 [ -  + ][ -  + ]:   11948800 :       AlwaysAssert(itrhs != rhsClause.end());
                 [ -  - ]
     284                 :   11948800 :       lhsClause.insert(lhsClause.end(), rhsClause.begin(), itrhs);
     285                 :   11948800 :       lhsClause.insert(lhsClause.end(), itrhs + 1, rhsClause.end());
     286         [ -  + ]:   11948800 :       if (TraceIsOn("bool-pfcheck"))
     287                 :            :       {
     288                 :          0 :         std::vector<Node> updatedRhsClause{rhsClause.begin(), itrhs};
     289                 :            :         updatedRhsClause.insert(
     290                 :          0 :             updatedRhsClause.end(), itrhs + 1, rhsClause.end());
     291         [ -  - ]:          0 :         Trace("bool-pfcheck")
     292                 :          0 :             << "\t.. after rhsClause: " << updatedRhsClause << "\n";
     293                 :            :       }
     294                 :   11948800 :       rhsClause.clear();
     295                 :            :     }
     296         [ +  - ]:    3730000 :     Trace("bool-pfcheck") << "\n resulting clause: " << lhsClause << "\n"
     297                 :    1865000 :                           << pop;
     298                 :    1865000 :     return nm->mkOr(lhsClause);
     299                 :            :   }
     300         [ +  + ]:    2351740 :   if (id == ProofRule::MACRO_RESOLUTION_TRUST)
     301                 :            :   {
     302 [ -  + ][ -  + ]:     209769 :     Assert(children.size() > 1);
                 [ -  - ]
     303 [ -  + ][ -  + ]:     209769 :     Assert(args.size() == 2 * (children.size() - 1) + 1);
                 [ -  - ]
     304                 :     209769 :     return args[0];
     305                 :            :   }
     306         [ -  + ]:    2141980 :   if (id == ProofRule::MACRO_RESOLUTION)
     307                 :            :   {
     308                 :          0 :     Assert(children.size() > 1);
     309                 :          0 :     Assert(args.size() == 2 * (children.size() - 1) + 1);
     310         [ -  - ]:          0 :     Trace("bool-pfcheck") << "macro_res: " << args[0] << "\n" << push;
     311                 :          0 :     NodeManager* nm = nodeManager();
     312                 :          0 :     Node trueNode = nm->mkConst(true);
     313                 :          0 :     Node falseNode = nm->mkConst(false);
     314                 :          0 :     std::vector<Node> lhsClause, rhsClause;
     315                 :          0 :     Node lhsElim, rhsElim;
     316                 :          0 :     std::vector<Node> pols, lits;
     317         [ -  - ]:          0 :     for (size_t i = 1, nargs = args.size(); i < nargs; i = i + 2)
     318                 :            :     {
     319                 :          0 :       pols.push_back(args[i]);
     320                 :          0 :       lits.push_back(args[i + 1]);
     321                 :            :     }
     322                 :            : 
     323                 :          0 :     if (children[0].getKind() != Kind::OR
     324                 :          0 :         || (pols[0] == trueNode && children[0] == lits[0])
     325                 :          0 :         || (pols[0] == falseNode && children[0] == lits[0].notNode()))
     326                 :            :     {
     327                 :          0 :       lhsClause.push_back(children[0]);
     328                 :            :     }
     329                 :            :     else
     330                 :            :     {
     331                 :          0 :       lhsClause.insert(lhsClause.end(), children[0].begin(), children[0].end());
     332                 :            :     }
     333                 :            :     // Traverse the links, which amounts to for each pair of args removing a
     334                 :            :     // literal from the lhs and a literal from the lhs.
     335         [ -  - ]:          0 :     for (size_t i = 0, argsSize = pols.size(); i < argsSize; i++)
     336                 :            :     {
     337                 :            :       // Polarity determines how the pivot occurs in lhs and rhs
     338         [ -  - ]:          0 :       if (pols[i] == trueNode)
     339                 :            :       {
     340                 :          0 :         lhsElim = lits[i];
     341                 :          0 :         rhsElim = lits[i].notNode();
     342                 :            :       }
     343                 :            :       else
     344                 :            :       {
     345                 :          0 :         Assert(pols[i] == falseNode);
     346                 :          0 :         lhsElim = lits[i].notNode();
     347                 :          0 :         rhsElim = lits[i];
     348                 :            :       }
     349                 :            :       // The index of the child corresponding to the current rhs clause
     350                 :          0 :       size_t childIndex = i + 1;
     351                 :            :       // Get rhs clause. It's a singleton if not an OR node or if equal to
     352                 :            :       // rhsElim
     353                 :          0 :       if (children[childIndex].getKind() != Kind::OR
     354                 :          0 :           || children[childIndex] == rhsElim)
     355                 :            :       {
     356                 :          0 :         rhsClause.push_back(children[childIndex]);
     357                 :            :       }
     358                 :            :       else
     359                 :            :       {
     360                 :          0 :         rhsClause = {children[childIndex].begin(), children[childIndex].end()};
     361                 :            :       }
     362         [ -  - ]:          0 :       Trace("bool-pfcheck") << i << "-th res link:\n";
     363         [ -  - ]:          0 :       Trace("bool-pfcheck") << "\t - lhsClause: " << lhsClause << "\n";
     364         [ -  - ]:          0 :       Trace("bool-pfcheck") << "\t\t - lhsElim: " << lhsElim << "\n";
     365         [ -  - ]:          0 :       Trace("bool-pfcheck") << "\t - rhsClause: " << rhsClause << "\n";
     366         [ -  - ]:          0 :       Trace("bool-pfcheck") << "\t\t - rhsElim: " << rhsElim << "\n";
     367                 :            :       // Compute the resulting clause, which will be the next lhsClause, as
     368                 :            :       // follows:
     369                 :            :       //   - remove all lhsElim from lhsClause
     370                 :            :       //   - remove all rhsElim from rhsClause and add the lits to lhsClause
     371                 :            :       //
     372                 :            :       // Note that to remove the elements from lhsClaus we use the
     373                 :            :       // "erase-remove" idiom in C++: the std::remove call shuffles the elements
     374                 :            :       // different from lhsElim to the beginning of the container, returning an
     375                 :            :       // iterator to the beginning of the "rest" of the container (with
     376                 :            :       // occurrences of lhsElim). Then the call to erase removes the range from
     377                 :            :       // there to the end. Once C++ 20 is allowed in the cvc5 code base, this
     378                 :            :       // could be done with a single call to std::erase.
     379                 :          0 :       lhsClause.erase(std::remove(lhsClause.begin(), lhsClause.end(), lhsElim),
     380                 :          0 :                       lhsClause.end());
     381         [ -  - ]:          0 :       for (const Node& l : rhsClause)
     382                 :            :       {
     383                 :            :         // only add if literal does not occur in elimination set
     384         [ -  - ]:          0 :         if (rhsElim != l)
     385                 :            :         {
     386                 :          0 :           lhsClause.push_back(l);
     387                 :            :         }
     388                 :            :       }
     389                 :          0 :       rhsClause.clear();
     390                 :            :     }
     391                 :            : 
     392         [ -  - ]:          0 :     Trace("bool-pfcheck") << "clause: " << lhsClause << "\n";
     393                 :            :     // check that set representation is the same as of the given conclusion
     394                 :          0 :     std::unordered_set<Node> clauseComputed{lhsClause.begin(), lhsClause.end()};
     395         [ -  - ]:          0 :     Trace("bool-pfcheck") << "clauseSet: " << clauseComputed << "\n" << pop;
     396         [ -  - ]:          0 :     if (clauseComputed.empty())
     397                 :            :     {
     398                 :            :       // conclusion differ
     399         [ -  - ]:          0 :       if (args[0] != falseNode)
     400                 :            :       {
     401                 :          0 :         return Node::null();
     402                 :            :       }
     403                 :          0 :       return args[0];
     404                 :            :     }
     405         [ -  - ]:          0 :     if (clauseComputed.size() == 1)
     406                 :            :     {
     407                 :            :       // conclusion differ
     408         [ -  - ]:          0 :       if (args[0] != *clauseComputed.begin())
     409                 :            :       {
     410                 :          0 :         return Node::null();
     411                 :            :       }
     412                 :          0 :       return args[0];
     413                 :            :     }
     414                 :            :     // At this point, should amount to them differing only on order or in
     415                 :            :     // repetitions. So the original result can't be a singleton clause.
     416         [ -  - ]:          0 :     if (args[0].getKind() != Kind::OR)
     417                 :            :     {
     418                 :          0 :       return Node::null();
     419                 :            :     }
     420                 :          0 :     std::unordered_set<Node> clauseGiven{args[0].begin(), args[0].end()};
     421         [ -  - ]:          0 :     return clauseComputed == clauseGiven ? args[0] : Node::null();
     422                 :            :   }
     423         [ +  + ]:    2141980 :   if (id == ProofRule::SPLIT)
     424                 :            :   {
     425 [ -  + ][ -  + ]:      49814 :     Assert(children.empty());
                 [ -  - ]
     426 [ -  + ][ -  + ]:      49814 :     Assert(args.size() == 1);
                 [ -  - ]
     427                 :      49814 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0].notNode());
     428                 :            :   }
     429         [ +  + ]:    2092160 :   if (id == ProofRule::CONTRA)
     430                 :            :   {
     431 [ -  + ][ -  + ]:     100501 :     Assert(children.size() == 2);
                 [ -  - ]
     432 [ +  - ][ +  - ]:     100501 :     if (children[1].getKind() == Kind::NOT && children[0] == children[1][0])
         [ +  - ][ +  - ]
                 [ -  - ]
     433                 :            :     {
     434                 :     201002 :       return nodeManager()->mkConst(false);
     435                 :            :     }
     436                 :          0 :     return Node::null();
     437                 :            :   }
     438         [ +  + ]:    1991660 :   if (id == ProofRule::EQ_RESOLVE)
     439                 :            :   {
     440 [ -  + ][ -  + ]:     465041 :     Assert(children.size() == 2);
                 [ -  - ]
     441 [ -  + ][ -  + ]:     465041 :     Assert(args.empty());
                 [ -  - ]
     442 [ +  - ][ -  + ]:     465041 :     if (children[1].getKind() != Kind::EQUAL || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     443                 :            :     {
     444                 :          0 :       return Node::null();
     445                 :            :     }
     446                 :     465041 :     return children[1][1];
     447                 :            :   }
     448         [ +  + ]:    1526620 :   if (id == ProofRule::MODUS_PONENS)
     449                 :            :   {
     450 [ -  + ][ -  + ]:     210188 :     Assert(children.size() == 2);
                 [ -  - ]
     451 [ -  + ][ -  + ]:     210188 :     Assert(args.empty());
                 [ -  - ]
     452 [ +  - ][ -  + ]:     210188 :     if (children[1].getKind() != Kind::IMPLIES || children[0] != children[1][0])
         [ +  - ][ -  + ]
                 [ -  - ]
     453                 :            :     {
     454                 :          0 :       return Node::null();
     455                 :            :     }
     456                 :     210188 :     return children[1][1];
     457                 :            :   }
     458         [ +  + ]:    1316430 :   if (id == ProofRule::NOT_NOT_ELIM)
     459                 :            :   {
     460 [ -  + ][ -  + ]:       7580 :     Assert(children.size() == 1);
                 [ -  - ]
     461 [ -  + ][ -  + ]:       7580 :     Assert(args.empty());
                 [ -  - ]
     462                 :       7580 :     if (children[0].getKind() != Kind::NOT
     463 [ +  - ][ -  + ]:      15160 :         || children[0][0].getKind() != Kind::NOT)
         [ +  - ][ -  + ]
                 [ -  - ]
     464                 :            :     {
     465                 :          0 :       return Node::null();
     466                 :            :     }
     467                 :       7580 :     return children[0][0][0];
     468                 :            :   }
     469                 :            :   // natural deduction rules
     470         [ +  + ]:    1308850 :   if (id == ProofRule::AND_ELIM)
     471                 :            :   {
     472 [ -  + ][ -  + ]:     350788 :     Assert(children.size() == 1);
                 [ -  - ]
     473 [ -  + ][ -  + ]:     350788 :     Assert(args.size() == 1);
                 [ -  - ]
     474                 :            :     uint32_t i;
     475 [ +  - ][ -  + ]:     350788 :     if (children[0].getKind() != Kind::AND || !getUInt32(args[0], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     476                 :            :     {
     477                 :          0 :       return Node::null();
     478                 :            :     }
     479         [ -  + ]:     350788 :     if (i >= children[0].getNumChildren())
     480                 :            :     {
     481                 :          0 :       return Node::null();
     482                 :            :     }
     483                 :     350788 :     return children[0][i];
     484                 :            :   }
     485         [ +  + ]:     958064 :   if (id == ProofRule::AND_INTRO)
     486                 :            :   {
     487 [ -  + ][ -  + ]:     264815 :     Assert(children.size() >= 1);
                 [ -  - ]
     488                 :     264815 :     return children.size() == 1 ? children[0]
     489         [ -  + ]:     264815 :                                 : nodeManager()->mkNode(Kind::AND, children);
     490                 :            :   }
     491         [ +  + ]:     693249 :   if (id == ProofRule::NOT_OR_ELIM)
     492                 :            :   {
     493 [ -  + ][ -  + ]:       8930 :     Assert(children.size() == 1);
                 [ -  - ]
     494 [ -  + ][ -  + ]:       8930 :     Assert(args.size() == 1);
                 [ -  - ]
     495                 :            :     uint32_t i;
     496                 :       8930 :     if (children[0].getKind() != Kind::NOT
     497                 :      17860 :         || children[0][0].getKind() != Kind::OR || !getUInt32(args[0], i))
     498                 :            :     {
     499                 :          0 :       return Node::null();
     500                 :            :     }
     501         [ -  + ]:       8930 :     if (i >= children[0][0].getNumChildren())
     502                 :            :     {
     503                 :          0 :       return Node::null();
     504                 :            :     }
     505                 :       8930 :     return children[0][0][i].notNode();
     506                 :            :   }
     507         [ +  + ]:     684319 :   if (id == ProofRule::IMPLIES_ELIM)
     508                 :            :   {
     509 [ -  + ][ -  + ]:      84013 :     Assert(children.size() == 1);
                 [ -  - ]
     510 [ -  + ][ -  + ]:      84013 :     Assert(args.empty());
                 [ -  - ]
     511         [ -  + ]:      84013 :     if (children[0].getKind() != Kind::IMPLIES)
     512                 :            :     {
     513                 :          0 :       return Node::null();
     514                 :            :     }
     515                 :            :     return nodeManager()->mkNode(
     516                 :      84013 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     517                 :            :   }
     518         [ +  + ]:     600306 :   if (id == ProofRule::NOT_IMPLIES_ELIM1)
     519                 :            :   {
     520 [ -  + ][ -  + ]:       4534 :     Assert(children.size() == 1);
                 [ -  - ]
     521 [ -  + ][ -  + ]:       4534 :     Assert(args.empty());
                 [ -  - ]
     522                 :       4534 :     if (children[0].getKind() != Kind::NOT
     523 [ +  - ][ -  + ]:       9068 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     524                 :            :     {
     525                 :          0 :       return Node::null();
     526                 :            :     }
     527                 :       4534 :     return children[0][0][0];
     528                 :            :   }
     529         [ +  + ]:     595772 :   if (id == ProofRule::NOT_IMPLIES_ELIM2)
     530                 :            :   {
     531 [ -  + ][ -  + ]:       2371 :     Assert(children.size() == 1);
                 [ -  - ]
     532 [ -  + ][ -  + ]:       2371 :     Assert(args.empty());
                 [ -  - ]
     533                 :       2371 :     if (children[0].getKind() != Kind::NOT
     534 [ +  - ][ -  + ]:       4742 :         || children[0][0].getKind() != Kind::IMPLIES)
         [ +  - ][ -  + ]
                 [ -  - ]
     535                 :            :     {
     536                 :          0 :       return Node::null();
     537                 :            :     }
     538                 :       2371 :     return children[0][0][1].notNode();
     539                 :            :   }
     540         [ +  + ]:     593401 :   if (id == ProofRule::EQUIV_ELIM1)
     541                 :            :   {
     542 [ -  + ][ -  + ]:      35640 :     Assert(children.size() == 1);
                 [ -  - ]
     543 [ -  + ][ -  + ]:      35640 :     Assert(args.empty());
                 [ -  - ]
     544         [ -  + ]:      35640 :     if (children[0].getKind() != Kind::EQUAL)
     545                 :            :     {
     546                 :          0 :       return Node::null();
     547                 :            :     }
     548                 :            :     return nodeManager()->mkNode(
     549                 :      35640 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     550                 :            :   }
     551         [ +  + ]:     557761 :   if (id == ProofRule::EQUIV_ELIM2)
     552                 :            :   {
     553 [ -  + ][ -  + ]:      20583 :     Assert(children.size() == 1);
                 [ -  - ]
     554 [ -  + ][ -  + ]:      20583 :     Assert(args.empty());
                 [ -  - ]
     555         [ -  + ]:      20583 :     if (children[0].getKind() != Kind::EQUAL)
     556                 :            :     {
     557                 :          0 :       return Node::null();
     558                 :            :     }
     559                 :            :     return nodeManager()->mkNode(
     560                 :      20583 :         Kind::OR, children[0][0], children[0][1].notNode());
     561                 :            :   }
     562         [ +  + ]:     537178 :   if (id == ProofRule::NOT_EQUIV_ELIM1)
     563                 :            :   {
     564 [ -  + ][ -  + ]:        994 :     Assert(children.size() == 1);
                 [ -  - ]
     565 [ -  + ][ -  + ]:        994 :     Assert(args.empty());
                 [ -  - ]
     566                 :        994 :     if (children[0].getKind() != Kind::NOT
     567 [ +  - ][ -  + ]:       1988 :         || children[0][0].getKind() != Kind::EQUAL)
         [ +  - ][ -  + ]
                 [ -  - ]
     568                 :            :     {
     569                 :          0 :       return Node::null();
     570                 :            :     }
     571                 :            :     return nodeManager()->mkNode(
     572                 :        994 :         Kind::OR, children[0][0][0], children[0][0][1]);
     573                 :            :   }
     574         [ +  + ]:     536184 :   if (id == ProofRule::NOT_EQUIV_ELIM2)
     575                 :            :   {
     576 [ -  + ][ -  + ]:        569 :     Assert(children.size() == 1);
                 [ -  - ]
     577 [ -  + ][ -  + ]:        569 :     Assert(args.empty());
                 [ -  - ]
     578                 :        569 :     if (children[0].getKind() != Kind::NOT
     579 [ +  - ][ -  + ]:       1138 :         || children[0][0].getKind() != Kind::EQUAL)
         [ +  - ][ -  + ]
                 [ -  - ]
     580                 :            :     {
     581                 :          0 :       return Node::null();
     582                 :            :     }
     583                 :            :     return nodeManager()->mkNode(
     584                 :        569 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1].notNode());
     585                 :            :   }
     586         [ +  + ]:     535615 :   if (id == ProofRule::XOR_ELIM1)
     587                 :            :   {
     588 [ -  + ][ -  + ]:        106 :     Assert(children.size() == 1);
                 [ -  - ]
     589 [ -  + ][ -  + ]:        106 :     Assert(args.empty());
                 [ -  - ]
     590         [ -  + ]:        106 :     if (children[0].getKind() != Kind::XOR)
     591                 :            :     {
     592                 :          0 :       return Node::null();
     593                 :            :     }
     594                 :        106 :     return nodeManager()->mkNode(Kind::OR, children[0][0], children[0][1]);
     595                 :            :   }
     596         [ +  + ]:     535509 :   if (id == ProofRule::XOR_ELIM2)
     597                 :            :   {
     598 [ -  + ][ -  + ]:        131 :     Assert(children.size() == 1);
                 [ -  - ]
     599 [ -  + ][ -  + ]:        131 :     Assert(args.empty());
                 [ -  - ]
     600         [ -  + ]:        131 :     if (children[0].getKind() != Kind::XOR)
     601                 :            :     {
     602                 :          0 :       return Node::null();
     603                 :            :     }
     604                 :            :     return nodeManager()->mkNode(
     605                 :        131 :         Kind::OR, children[0][0].notNode(), children[0][1].notNode());
     606                 :            :   }
     607         [ +  + ]:     535378 :   if (id == ProofRule::NOT_XOR_ELIM1)
     608                 :            :   {
     609 [ -  + ][ -  + ]:         74 :     Assert(children.size() == 1);
                 [ -  - ]
     610 [ -  + ][ -  + ]:         74 :     Assert(args.empty());
                 [ -  - ]
     611                 :         74 :     if (children[0].getKind() != Kind::NOT
     612 [ +  - ][ -  + ]:        148 :         || children[0][0].getKind() != Kind::XOR)
         [ +  - ][ -  + ]
                 [ -  - ]
     613                 :            :     {
     614                 :          0 :       return Node::null();
     615                 :            :     }
     616                 :            :     return nodeManager()->mkNode(
     617                 :         74 :         Kind::OR, children[0][0][0], children[0][0][1].notNode());
     618                 :            :   }
     619         [ +  + ]:     535304 :   if (id == ProofRule::NOT_XOR_ELIM2)
     620                 :            :   {
     621 [ -  + ][ -  + ]:         76 :     Assert(children.size() == 1);
                 [ -  - ]
     622 [ -  + ][ -  + ]:         76 :     Assert(args.empty());
                 [ -  - ]
     623                 :         76 :     if (children[0].getKind() != Kind::NOT
     624 [ +  - ][ -  + ]:        152 :         || children[0][0].getKind() != Kind::XOR)
         [ +  - ][ -  + ]
                 [ -  - ]
     625                 :            :     {
     626                 :          0 :       return Node::null();
     627                 :            :     }
     628                 :            :     return nodeManager()->mkNode(
     629                 :         76 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1]);
     630                 :            :   }
     631         [ +  + ]:     535228 :   if (id == ProofRule::ITE_ELIM1)
     632                 :            :   {
     633 [ -  + ][ -  + ]:       9437 :     Assert(children.size() == 1);
                 [ -  - ]
     634 [ -  + ][ -  + ]:       9437 :     Assert(args.empty());
                 [ -  - ]
     635         [ -  + ]:       9437 :     if (children[0].getKind() != Kind::ITE)
     636                 :            :     {
     637                 :          0 :       return Node::null();
     638                 :            :     }
     639                 :            :     return nodeManager()->mkNode(
     640                 :       9437 :         Kind::OR, children[0][0].notNode(), children[0][1]);
     641                 :            :   }
     642         [ +  + ]:     525791 :   if (id == ProofRule::ITE_ELIM2)
     643                 :            :   {
     644 [ -  + ][ -  + ]:      22498 :     Assert(children.size() == 1);
                 [ -  - ]
     645 [ -  + ][ -  + ]:      22498 :     Assert(args.empty());
                 [ -  - ]
     646         [ -  + ]:      22498 :     if (children[0].getKind() != Kind::ITE)
     647                 :            :     {
     648                 :          0 :       return Node::null();
     649                 :            :     }
     650                 :      22498 :     return nodeManager()->mkNode(Kind::OR, children[0][0], children[0][2]);
     651                 :            :   }
     652         [ +  + ]:     503293 :   if (id == ProofRule::NOT_ITE_ELIM1)
     653                 :            :   {
     654 [ -  + ][ -  + ]:         30 :     Assert(children.size() == 1);
                 [ -  - ]
     655 [ -  + ][ -  + ]:         30 :     Assert(args.empty());
                 [ -  - ]
     656                 :         30 :     if (children[0].getKind() != Kind::NOT
     657 [ +  - ][ -  + ]:         60 :         || children[0][0].getKind() != Kind::ITE)
         [ +  - ][ -  + ]
                 [ -  - ]
     658                 :            :     {
     659                 :          0 :       return Node::null();
     660                 :            :     }
     661                 :            :     return nodeManager()->mkNode(
     662                 :         30 :         Kind::OR, children[0][0][0].notNode(), children[0][0][1].notNode());
     663                 :            :   }
     664         [ +  + ]:     503263 :   if (id == ProofRule::NOT_ITE_ELIM2)
     665                 :            :   {
     666 [ -  + ][ -  + ]:         58 :     Assert(children.size() == 1);
                 [ -  - ]
     667 [ -  + ][ -  + ]:         58 :     Assert(args.empty());
                 [ -  - ]
     668                 :         58 :     if (children[0].getKind() != Kind::NOT
     669 [ +  - ][ -  + ]:        116 :         || children[0][0].getKind() != Kind::ITE)
         [ +  - ][ -  + ]
                 [ -  - ]
     670                 :            :     {
     671                 :          0 :       return Node::null();
     672                 :            :     }
     673                 :            :     return nodeManager()->mkNode(
     674                 :         58 :         Kind::OR, children[0][0][0], children[0][0][2].notNode());
     675                 :            :   }
     676                 :            :   // De Morgan
     677         [ +  + ]:     503205 :   if (id == ProofRule::NOT_AND)
     678                 :            :   {
     679 [ -  + ][ -  + ]:     203434 :     Assert(children.size() == 1);
                 [ -  - ]
     680 [ -  + ][ -  + ]:     203434 :     Assert(args.empty());
                 [ -  - ]
     681                 :     203434 :     if (children[0].getKind() != Kind::NOT
     682 [ +  - ][ -  + ]:     406868 :         || children[0][0].getKind() != Kind::AND)
         [ +  - ][ -  + ]
                 [ -  - ]
     683                 :            :     {
     684                 :          0 :       return Node::null();
     685                 :            :     }
     686                 :     406868 :     std::vector<Node> disjuncts;
     687         [ +  + ]:    1039220 :     for (std::size_t i = 0, size = children[0][0].getNumChildren(); i < size;
     688                 :            :          ++i)
     689                 :            :     {
     690                 :     835788 :       disjuncts.push_back(children[0][0][i].notNode());
     691                 :            :     }
     692                 :     203434 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     693                 :            :   }
     694                 :            :   // valid clauses rules for Tseitin CNF transformation
     695         [ +  + ]:     299771 :   if (id == ProofRule::CNF_AND_POS)
     696                 :            :   {
     697 [ -  + ][ -  + ]:      68566 :     Assert(children.empty());
                 [ -  - ]
     698 [ -  + ][ -  + ]:      68566 :     Assert(args.size() == 2);
                 [ -  - ]
     699                 :            :     uint32_t i;
     700 [ +  - ][ -  + ]:      68566 :     if (args[0].getKind() != Kind::AND || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     701                 :            :     {
     702                 :          0 :       return Node::null();
     703                 :            :     }
     704         [ -  + ]:      68566 :     if (i >= args[0].getNumChildren())
     705                 :            :     {
     706                 :          0 :       return Node::null();
     707                 :            :     }
     708                 :      68566 :     return nodeManager()->mkNode(Kind::OR, args[0].notNode(), args[0][i]);
     709                 :            :   }
     710         [ +  + ]:     231205 :   if (id == ProofRule::CNF_AND_NEG)
     711                 :            :   {
     712 [ -  + ][ -  + ]:      80540 :     Assert(children.empty());
                 [ -  - ]
     713 [ -  + ][ -  + ]:      80540 :     Assert(args.size() == 1);
                 [ -  - ]
     714         [ -  + ]:      80540 :     if (args[0].getKind() != Kind::AND)
     715                 :            :     {
     716                 :          0 :       return Node::null();
     717                 :            :     }
     718                 :     322160 :     std::vector<Node> disjuncts{args[0]};
     719         [ +  + ]:     484675 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     720                 :            :     {
     721                 :     404135 :       disjuncts.push_back(args[0][i].notNode());
     722                 :            :     }
     723                 :      80540 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     724                 :            :   }
     725         [ +  + ]:     150665 :   if (id == ProofRule::CNF_OR_POS)
     726                 :            :   {
     727 [ -  + ][ -  + ]:      18396 :     Assert(children.empty());
                 [ -  - ]
     728 [ -  + ][ -  + ]:      18396 :     Assert(args.size() == 1);
                 [ -  - ]
     729         [ -  + ]:      18396 :     if (args[0].getKind() != Kind::OR)
     730                 :            :     {
     731                 :          0 :       return Node::null();
     732                 :            :     }
     733                 :      73584 :     std::vector<Node> disjuncts{args[0].notNode()};
     734         [ +  + ]:    1305020 :     for (unsigned i = 0, size = args[0].getNumChildren(); i < size; ++i)
     735                 :            :     {
     736                 :    1286630 :       disjuncts.push_back(args[0][i]);
     737                 :            :     }
     738                 :      18396 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     739                 :            :   }
     740         [ +  + ]:     132269 :   if (id == ProofRule::CNF_OR_NEG)
     741                 :            :   {
     742 [ -  + ][ -  + ]:      69638 :     Assert(children.empty());
                 [ -  - ]
     743 [ -  + ][ -  + ]:      69638 :     Assert(args.size() == 2);
                 [ -  - ]
     744                 :            :     uint32_t i;
     745 [ +  - ][ -  + ]:      69638 :     if (args[0].getKind() != Kind::OR || !getUInt32(args[1], i))
         [ +  - ][ -  + ]
                 [ -  - ]
     746                 :            :     {
     747                 :          0 :       return Node::null();
     748                 :            :     }
     749         [ -  + ]:      69638 :     if (i >= args[0].getNumChildren())
     750                 :            :     {
     751                 :          0 :       return Node::null();
     752                 :            :     }
     753                 :      69638 :     return nodeManager()->mkNode(Kind::OR, args[0], args[0][i].notNode());
     754                 :            :   }
     755         [ +  + ]:      62631 :   if (id == ProofRule::CNF_IMPLIES_POS)
     756                 :            :   {
     757 [ -  + ][ -  + ]:       3059 :     Assert(children.empty());
                 [ -  - ]
     758 [ -  + ][ -  + ]:       3059 :     Assert(args.size() == 1);
                 [ -  - ]
     759         [ -  + ]:       3059 :     if (args[0].getKind() != Kind::IMPLIES)
     760                 :            :     {
     761                 :          0 :       return Node::null();
     762                 :            :     }
     763                 :            :     std::vector<Node> disjuncts{
     764                 :      21413 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     765                 :       3059 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     766                 :            :   }
     767         [ +  + ]:      59572 :   if (id == ProofRule::CNF_IMPLIES_NEG1)
     768                 :            :   {
     769 [ -  + ][ -  + ]:        628 :     Assert(children.empty());
                 [ -  - ]
     770 [ -  + ][ -  + ]:        628 :     Assert(args.size() == 1);
                 [ -  - ]
     771         [ -  + ]:        628 :     if (args[0].getKind() != Kind::IMPLIES)
     772                 :            :     {
     773                 :          0 :       return Node::null();
     774                 :            :     }
     775                 :       3140 :     std::vector<Node> disjuncts{args[0], args[0][0]};
     776                 :        628 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     777                 :            :   }
     778         [ +  + ]:      58944 :   if (id == ProofRule::CNF_IMPLIES_NEG2)
     779                 :            :   {
     780 [ -  + ][ -  + ]:       3434 :     Assert(children.empty());
                 [ -  - ]
     781 [ -  + ][ -  + ]:       3434 :     Assert(args.size() == 1);
                 [ -  - ]
     782         [ -  + ]:       3434 :     if (args[0].getKind() != Kind::IMPLIES)
     783                 :            :     {
     784                 :          0 :       return Node::null();
     785                 :            :     }
     786                 :      20604 :     std::vector<Node> disjuncts{args[0], args[0][1].notNode()};
     787                 :       3434 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     788                 :            :   }
     789         [ +  + ]:      55510 :   if (id == ProofRule::CNF_EQUIV_POS1)
     790                 :            :   {
     791 [ -  + ][ -  + ]:       8272 :     Assert(children.empty());
                 [ -  - ]
     792 [ -  + ][ -  + ]:       8272 :     Assert(args.size() == 1);
                 [ -  - ]
     793         [ -  + ]:       8272 :     if (args[0].getKind() != Kind::EQUAL)
     794                 :            :     {
     795                 :          0 :       return Node::null();
     796                 :            :     }
     797                 :            :     std::vector<Node> disjuncts{
     798                 :      57904 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     799                 :       8272 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     800                 :            :   }
     801         [ +  + ]:      47238 :   if (id == ProofRule::CNF_EQUIV_POS2)
     802                 :            :   {
     803 [ -  + ][ -  + ]:       8300 :     Assert(children.empty());
                 [ -  - ]
     804 [ -  + ][ -  + ]:       8300 :     Assert(args.size() == 1);
                 [ -  - ]
     805         [ -  + ]:       8300 :     if (args[0].getKind() != Kind::EQUAL)
     806                 :            :     {
     807                 :          0 :       return Node::null();
     808                 :            :     }
     809                 :            :     std::vector<Node> disjuncts{
     810                 :      58100 :         args[0].notNode(), args[0][0], args[0][1].notNode()};
     811                 :       8300 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     812                 :            :   }
     813         [ +  + ]:      38938 :   if (id == ProofRule::CNF_EQUIV_NEG1)
     814                 :            :   {
     815 [ -  + ][ -  + ]:       4760 :     Assert(children.empty());
                 [ -  - ]
     816 [ -  + ][ -  + ]:       4760 :     Assert(args.size() == 1);
                 [ -  - ]
     817         [ -  + ]:       4760 :     if (args[0].getKind() != Kind::EQUAL)
     818                 :            :     {
     819                 :          0 :       return Node::null();
     820                 :            :     }
     821                 :      28560 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1]};
     822                 :       4760 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     823                 :            :   }
     824         [ +  + ]:      34178 :   if (id == ProofRule::CNF_EQUIV_NEG2)
     825                 :            :   {
     826 [ -  + ][ -  + ]:      11850 :     Assert(children.empty());
                 [ -  - ]
     827 [ -  + ][ -  + ]:      11850 :     Assert(args.size() == 1);
                 [ -  - ]
     828         [ -  + ]:      11850 :     if (args[0].getKind() != Kind::EQUAL)
     829                 :            :     {
     830                 :          0 :       return Node::null();
     831                 :            :     }
     832                 :            :     std::vector<Node> disjuncts{
     833                 :      82950 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     834                 :      11850 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     835                 :            :   }
     836         [ +  + ]:      22328 :   if (id == ProofRule::CNF_XOR_POS1)
     837                 :            :   {
     838 [ -  + ][ -  + ]:       4275 :     Assert(children.empty());
                 [ -  - ]
     839 [ -  + ][ -  + ]:       4275 :     Assert(args.size() == 1);
                 [ -  - ]
     840         [ -  + ]:       4275 :     if (args[0].getKind() != Kind::XOR)
     841                 :            :     {
     842                 :          0 :       return Node::null();
     843                 :            :     }
     844                 :      25650 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][1]};
     845                 :       4275 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     846                 :            :   }
     847         [ +  + ]:      18053 :   if (id == ProofRule::CNF_XOR_POS2)
     848                 :            :   {
     849 [ -  + ][ -  + ]:       1780 :     Assert(children.empty());
                 [ -  - ]
     850 [ -  + ][ -  + ]:       1780 :     Assert(args.size() == 1);
                 [ -  - ]
     851         [ -  + ]:       1780 :     if (args[0].getKind() != Kind::XOR)
     852                 :            :     {
     853                 :          0 :       return Node::null();
     854                 :            :     }
     855                 :            :     std::vector<Node> disjuncts{
     856                 :      12460 :         args[0].notNode(), args[0][0].notNode(), args[0][1].notNode()};
     857                 :       1780 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     858                 :            :   }
     859         [ +  + ]:      16273 :   if (id == ProofRule::CNF_XOR_NEG1)
     860                 :            :   {
     861 [ -  + ][ -  + ]:       1680 :     Assert(children.empty());
                 [ -  - ]
     862 [ -  + ][ -  + ]:       1680 :     Assert(args.size() == 1);
                 [ -  - ]
     863         [ -  + ]:       1680 :     if (args[0].getKind() != Kind::XOR)
     864                 :            :     {
     865                 :          0 :       return Node::null();
     866                 :            :     }
     867                 :      11760 :     std::vector<Node> disjuncts{args[0], args[0][0].notNode(), args[0][1]};
     868                 :       1680 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     869                 :            :   }
     870         [ +  + ]:      14593 :   if (id == ProofRule::CNF_XOR_NEG2)
     871                 :            :   {
     872 [ -  + ][ -  + ]:       1766 :     Assert(children.empty());
                 [ -  - ]
     873 [ -  + ][ -  + ]:       1766 :     Assert(args.size() == 1);
                 [ -  - ]
     874         [ -  + ]:       1766 :     if (args[0].getKind() != Kind::XOR)
     875                 :            :     {
     876                 :          0 :       return Node::null();
     877                 :            :     }
     878                 :      12362 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][1].notNode()};
     879                 :       1766 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     880                 :            :   }
     881         [ +  + ]:      12827 :   if (id == ProofRule::CNF_ITE_POS1)
     882                 :            :   {
     883 [ -  + ][ -  + ]:       1524 :     Assert(children.empty());
                 [ -  - ]
     884 [ -  + ][ -  + ]:       1524 :     Assert(args.size() == 1);
                 [ -  - ]
     885         [ -  + ]:       1524 :     if (args[0].getKind() != Kind::ITE)
     886                 :            :     {
     887                 :          0 :       return Node::null();
     888                 :            :     }
     889                 :            :     std::vector<Node> disjuncts{
     890                 :      10668 :         args[0].notNode(), args[0][0].notNode(), args[0][1]};
     891                 :       1524 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     892                 :            :   }
     893         [ +  + ]:      11303 :   if (id == ProofRule::CNF_ITE_POS2)
     894                 :            :   {
     895 [ -  + ][ -  + ]:       1651 :     Assert(children.empty());
                 [ -  - ]
     896 [ -  + ][ -  + ]:       1651 :     Assert(args.size() == 1);
                 [ -  - ]
     897         [ -  + ]:       1651 :     if (args[0].getKind() != Kind::ITE)
     898                 :            :     {
     899                 :          0 :       return Node::null();
     900                 :            :     }
     901                 :       9906 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][0], args[0][2]};
     902                 :       1651 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     903                 :            :   }
     904         [ +  + ]:       9652 :   if (id == ProofRule::CNF_ITE_POS3)
     905                 :            :   {
     906 [ -  + ][ -  + ]:       1571 :     Assert(children.empty());
                 [ -  - ]
     907 [ -  + ][ -  + ]:       1571 :     Assert(args.size() == 1);
                 [ -  - ]
     908         [ -  + ]:       1571 :     if (args[0].getKind() != Kind::ITE)
     909                 :            :     {
     910                 :          0 :       return Node::null();
     911                 :            :     }
     912                 :       9426 :     std::vector<Node> disjuncts{args[0].notNode(), args[0][1], args[0][2]};
     913                 :       1571 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     914                 :            :   }
     915         [ +  + ]:       8081 :   if (id == ProofRule::CNF_ITE_NEG1)
     916                 :            :   {
     917 [ -  + ][ -  + ]:       5662 :     Assert(children.empty());
                 [ -  - ]
     918 [ -  + ][ -  + ]:       5662 :     Assert(args.size() == 1);
                 [ -  - ]
     919         [ -  + ]:       5662 :     if (args[0].getKind() != Kind::ITE)
     920                 :            :     {
     921                 :          0 :       return Node::null();
     922                 :            :     }
     923                 :            :     std::vector<Node> disjuncts{
     924                 :      39634 :         args[0], args[0][0].notNode(), args[0][1].notNode()};
     925                 :       5662 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     926                 :            :   }
     927         [ +  + ]:       2419 :   if (id == ProofRule::CNF_ITE_NEG2)
     928                 :            :   {
     929 [ -  + ][ -  + ]:       1096 :     Assert(children.empty());
                 [ -  - ]
     930 [ -  + ][ -  + ]:       1096 :     Assert(args.size() == 1);
                 [ -  - ]
     931         [ -  + ]:       1096 :     if (args[0].getKind() != Kind::ITE)
     932                 :            :     {
     933                 :          0 :       return Node::null();
     934                 :            :     }
     935                 :       7672 :     std::vector<Node> disjuncts{args[0], args[0][0], args[0][2].notNode()};
     936                 :       1096 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     937                 :            :   }
     938         [ +  + ]:       1323 :   if (id == ProofRule::CNF_ITE_NEG3)
     939                 :            :   {
     940 [ -  + ][ -  + ]:       1255 :     Assert(children.empty());
                 [ -  - ]
     941 [ -  + ][ -  + ]:       1255 :     Assert(args.size() == 1);
                 [ -  - ]
     942         [ -  + ]:       1255 :     if (args[0].getKind() != Kind::ITE)
     943                 :            :     {
     944                 :          0 :       return Node::null();
     945                 :            :     }
     946                 :            :     std::vector<Node> disjuncts{
     947                 :       8785 :         args[0], args[0][1].notNode(), args[0][2].notNode()};
     948                 :       1255 :     return nodeManager()->mkNode(Kind::OR, disjuncts);
     949                 :            :   }
     950 [ -  + ][ -  - ]:         68 :   if (id == ProofRule::SAT_REFUTATION || id == ProofRule::DRAT_REFUTATION
     951         [ -  - ]:          0 :       || id == ProofRule::SAT_EXTERNAL_PROVE)
     952                 :            :   {
     953 [ -  + ][ -  - ]:         68 :     Assert(args.size()
         [ -  + ][ -  + ]
                 [ -  - ]
     954                 :            :            == (id == ProofRule::SAT_REFUTATION
     955                 :            :                    ? 0
     956                 :            :                    : (id == ProofRule::SAT_EXTERNAL_PROVE ? 1 : 2)));
     957                 :        136 :     return nodeManager()->mkConst(false);
     958                 :            :   }
     959                 :            :   // no rule
     960                 :          0 :   return Node::null();
     961                 :            : }
     962                 :            : 
     963                 :            : }  // namespace booleans
     964                 :            : }  // namespace theory
     965                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14