LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/builtin - proof_checker.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 273 310 88.1 %
Date: 2026-06-12 10:33:39 Functions: 11 12 91.7 %
Branches: 232 460 50.4 %

           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/builtin/proof_checker.h"
      14                 :            : 
      15                 :            : #include "expr/aci_norm.h"
      16                 :            : #include "expr/node_algorithm.h"
      17                 :            : #include "expr/skolem_manager.h"
      18                 :            : #include "rewriter/rewrite_db.h"
      19                 :            : #include "rewriter/rewrite_db_term_process.h"
      20                 :            : #include "rewriter/rewrite_proof_rule.h"
      21                 :            : #include "smt/env.h"
      22                 :            : #include "smt/term_formula_removal.h"
      23                 :            : #include "theory/evaluator.h"
      24                 :            : #include "theory/quantifiers/extended_rewrite.h"
      25                 :            : #include "theory/rewriter.h"
      26                 :            : #include "theory/substitutions.h"
      27                 :            : #include "theory/theory.h"
      28                 :            : #include "util/rational.h"
      29                 :            : 
      30                 :            : using namespace cvc5::internal::kind;
      31                 :            : 
      32                 :            : namespace cvc5::internal {
      33                 :            : namespace theory {
      34                 :            : namespace builtin {
      35                 :            : 
      36                 :      51214 : BuiltinProofRuleChecker::BuiltinProofRuleChecker(NodeManager* nm,
      37                 :            :                                                  Rewriter* r,
      38                 :      51214 :                                                  Env& env)
      39                 :      51214 :     : ProofRuleChecker(nm), d_rewriter(r), d_env(env), d_rdb(nullptr)
      40                 :            : {
      41                 :      51214 : }
      42                 :            : 
      43                 :      19964 : void BuiltinProofRuleChecker::registerTo(ProofChecker* pc)
      44                 :            : {
      45                 :      19964 :   pc->registerChecker(ProofRule::ASSUME, this);
      46                 :      19964 :   pc->registerChecker(ProofRule::SCOPE, this);
      47                 :      19964 :   pc->registerChecker(ProofRule::SUBS, this);
      48                 :      19964 :   pc->registerChecker(ProofRule::EVALUATE, this);
      49                 :      19964 :   pc->registerChecker(ProofRule::DISTINCT_VALUES, this);
      50                 :      19964 :   pc->registerChecker(ProofRule::ACI_NORM, this);
      51                 :      19964 :   pc->registerChecker(ProofRule::ABSORB, this);
      52                 :      19964 :   pc->registerChecker(ProofRule::ITE_EQ, this);
      53                 :      19964 :   pc->registerChecker(ProofRule::ENCODE_EQ_INTRO, this);
      54                 :      19964 :   pc->registerChecker(ProofRule::DSL_REWRITE, this);
      55                 :      19964 :   pc->registerChecker(ProofRule::THEORY_REWRITE, this);
      56                 :            :   // rules depending on the rewriter
      57                 :      19964 :   pc->registerTrustedChecker(ProofRule::MACRO_REWRITE, this, 4);
      58                 :      19964 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_EQ_INTRO, this, 4);
      59                 :      19964 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_INTRO, this, 4);
      60                 :      19964 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_ELIM, this, 4);
      61                 :      19964 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_TRANSFORM, this, 4);
      62                 :      19964 :   pc->registerTrustedChecker(ProofRule::TRUST_THEORY_REWRITE, this, 4);
      63                 :            :   // trusted rules
      64                 :      19964 :   pc->registerTrustedChecker(ProofRule::TRUST, this, 1);
      65                 :            :   // external proof rules
      66                 :      19964 :   pc->registerChecker(ProofRule::LFSC_RULE, this);
      67                 :      19964 :   pc->registerChecker(ProofRule::ALETHE_RULE, this);
      68                 :            : 
      69                 :      19964 :   d_rdb = pc->getRewriteDatabase();
      70                 :      19964 : }
      71                 :            : 
      72                 :     278405 : Node BuiltinProofRuleChecker::applySubstitutionRewrite(
      73                 :            :     Node n,
      74                 :            :     const std::vector<Node>& exp,
      75                 :            :     MethodId ids,
      76                 :            :     MethodId ida,
      77                 :            :     MethodId idr)
      78                 :            : {
      79                 :     278405 :   Node nks = applySubstitution(n, exp, ids, ida);
      80         [ +  + ]:     278405 :   if (nks.isNull())
      81                 :            :   {
      82                 :         40 :     return nks;
      83                 :            :   }
      84                 :     278365 :   return d_env.rewriteViaMethod(nks, idr);
      85                 :     278405 : }
      86                 :            : 
      87                 :    4937580 : bool BuiltinProofRuleChecker::getSubstitutionForLit(Node exp,
      88                 :            :                                                     TNode& var,
      89                 :            :                                                     TNode& subs,
      90                 :            :                                                     MethodId ids)
      91                 :            : {
      92                 :    4937580 :   NodeManager* nm = exp.getNodeManager();
      93         [ +  + ]:    4937580 :   if (ids == MethodId::SB_DEFAULT)
      94                 :            :   {
      95         [ +  + ]:    4936789 :     if (exp.getKind() != Kind::EQUAL)
      96                 :            :     {
      97                 :         40 :       return false;
      98                 :            :     }
      99                 :    4936749 :     var = exp[0];
     100                 :    4936749 :     subs = exp[1];
     101                 :            :   }
     102         [ +  + ]:        791 :   else if (ids == MethodId::SB_LITERAL)
     103                 :            :   {
     104                 :         24 :     bool polarity = exp.getKind() != Kind::NOT;
     105         [ +  - ]:         24 :     var = polarity ? exp : exp[0];
     106                 :         24 :     subs = nm->mkConst(polarity);
     107                 :            :   }
     108         [ +  - ]:        767 :   else if (ids == MethodId::SB_FORMULA)
     109                 :            :   {
     110                 :        767 :     var = exp;
     111                 :        767 :     subs = nm->mkConst(true);
     112                 :            :   }
     113                 :            :   else
     114                 :            :   {
     115                 :          0 :     DebugUnhandled() << "BuiltinProofRuleChecker::applySubstitution: no "
     116                 :          0 :                         "substitution for "
     117                 :          0 :                      << ids << std::endl;
     118                 :            :     return false;
     119                 :            :   }
     120                 :    4937540 :   return true;
     121                 :            : }
     122                 :            : 
     123                 :      91943 : bool BuiltinProofRuleChecker::getSubstitutionFor(Node exp,
     124                 :            :                                                  std::vector<TNode>& vars,
     125                 :            :                                                  std::vector<TNode>& subs,
     126                 :            :                                                  std::vector<TNode>& from,
     127                 :            :                                                  MethodId ids)
     128                 :            : {
     129                 :      91943 :   TNode v;
     130                 :      91943 :   TNode s;
     131 [ +  + ][ +  - ]:      91943 :   if (exp.getKind() == Kind::AND && ids == MethodId::SB_DEFAULT)
                 [ +  + ]
     132                 :            :   {
     133         [ +  + ]:    4921389 :     for (const Node& ec : exp)
     134                 :            :     {
     135                 :            :       // non-recursive, do not use nested AND
     136         [ -  + ]:    4883513 :       if (!getSubstitutionForLit(ec, v, s, ids))
     137                 :            :       {
     138                 :          0 :         return false;
     139                 :            :       }
     140                 :    4883513 :       vars.push_back(v);
     141                 :    4883513 :       subs.push_back(s);
     142                 :    4883513 :       from.push_back(ec);
     143         [ +  - ]:    4883513 :     }
     144                 :      37876 :     return true;
     145                 :            :   }
     146                 :      54067 :   bool ret = getSubstitutionForLit(exp, v, s, ids);
     147                 :      54067 :   vars.push_back(v);
     148                 :      54067 :   subs.push_back(s);
     149                 :      54067 :   from.push_back(exp);
     150                 :      54067 :   return ret;
     151                 :      91943 : }
     152                 :            : 
     153                 :          0 : Node BuiltinProofRuleChecker::applySubstitution(Node n,
     154                 :            :                                                 Node exp,
     155                 :            :                                                 MethodId ids,
     156                 :            :                                                 MethodId ida)
     157                 :            : {
     158                 :          0 :   std::vector<Node> expv{exp};
     159                 :          0 :   return applySubstitution(n, expv, ids, ida);
     160                 :          0 : }
     161                 :            : 
     162                 :     321401 : Node BuiltinProofRuleChecker::applySubstitution(Node n,
     163                 :            :                                                 const std::vector<Node>& exp,
     164                 :            :                                                 MethodId ids,
     165                 :            :                                                 MethodId ida)
     166                 :            : {
     167                 :     321401 :   std::vector<TNode> vars;
     168                 :     321401 :   std::vector<TNode> subs;
     169                 :     321401 :   std::vector<TNode> from;
     170         [ +  + ]:     394700 :   for (size_t i = 0, nexp = exp.size(); i < nexp; i++)
     171                 :            :   {
     172         [ -  + ]:      73339 :     if (exp[i].isNull())
     173                 :            :     {
     174                 :          0 :       return Node::null();
     175                 :            :     }
     176         [ +  + ]:      73339 :     if (!getSubstitutionFor(exp[i], vars, subs, from, ids))
     177                 :            :     {
     178                 :         40 :       return Node::null();
     179                 :            :     }
     180                 :            :   }
     181         [ -  + ]:     321361 :   if (ida == MethodId::SBA_SIMUL)
     182                 :            :   {
     183                 :            :     // simply apply the simultaneous substitution now
     184                 :          0 :     return n.substitute(vars.begin(), vars.end(), subs.begin(), subs.end());
     185                 :            :   }
     186         [ +  + ]:     321361 :   else if (ida == MethodId::SBA_FIXPOINT)
     187                 :            :   {
     188                 :      54831 :     SubstitutionMap sm;
     189         [ +  + ]:    3880393 :     for (size_t i = 0, nvars = vars.size(); i < nvars; i++)
     190                 :            :     {
     191                 :    3825562 :       sm.addSubstitution(vars[i], subs[i]);
     192                 :            :     }
     193                 :      54831 :     Node ns = sm.apply(n);
     194                 :      54831 :     return ns;
     195                 :      54831 :   }
     196 [ -  + ][ -  + ]:     266530 :   Assert(ida == MethodId::SBA_SEQUENTIAL);
                 [ -  - ]
     197                 :            :   // we prefer n traversals of the term to n^2/2 traversals of range terms
     198                 :     266530 :   Node ns = n;
     199         [ +  + ]:     304609 :   for (size_t i = 0, nvars = vars.size(); i < nvars; i++)
     200                 :            :   {
     201                 :      38079 :     TNode v = vars[(nvars - 1) - i];
     202                 :      38079 :     TNode s = subs[(nvars - 1) - i];
     203                 :      38079 :     ns = ns.substitute(v, s);
     204                 :      38079 :   }
     205                 :     266530 :   return ns;
     206                 :     321401 : }
     207                 :            : 
     208                 :    2643178 : Node BuiltinProofRuleChecker::checkInternal(ProofRule id,
     209                 :            :                                             const std::vector<Node>& children,
     210                 :            :                                             const std::vector<Node>& args)
     211                 :            : {
     212                 :    2643178 :   NodeManager* nm = nodeManager();
     213                 :            :   // compute what was proven
     214         [ +  + ]:    2643178 :   if (id == ProofRule::ASSUME)
     215                 :            :   {
     216 [ -  + ][ -  + ]:      65090 :     Assert(children.empty());
                 [ -  - ]
     217 [ -  + ][ -  + ]:      65090 :     Assert(args.size() == 1);
                 [ -  - ]
     218 [ -  + ][ -  + ]:      65090 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     219                 :      65090 :     return args[0];
     220                 :            :   }
     221         [ +  + ]:    2578088 :   else if (id == ProofRule::SCOPE)
     222                 :            :   {
     223 [ -  + ][ -  + ]:     760411 :     Assert(children.size() == 1);
                 [ -  - ]
     224         [ +  + ]:     760411 :     if (args.empty())
     225                 :            :     {
     226                 :            :       // no antecedant
     227                 :       5943 :       return children[0];
     228                 :            :     }
     229                 :     754468 :     Node ant = nm->mkAnd(args);
     230                 :            :     // if the conclusion is false, its the negated antencedant only
     231 [ +  + ][ +  + ]:     754468 :     if (children[0].isConst() && !children[0].getConst<bool>())
                 [ +  + ]
     232                 :            :     {
     233                 :     610172 :       return ant.notNode();
     234                 :            :     }
     235                 :     144296 :     return nm->mkNode(Kind::IMPLIES, ant, children[0]);
     236                 :     754468 :   }
     237         [ +  + ]:    1817677 :   else if (id == ProofRule::SUBS)
     238                 :            :   {
     239 [ -  + ][ -  + ]:         80 :     Assert(children.size() > 0);
                 [ -  - ]
     240 [ +  - ][ +  - ]:         80 :     Assert(1 <= args.size() && args.size() <= 3) << "Args: " << args;
         [ -  + ][ -  + ]
                 [ -  - ]
     241                 :         80 :     MethodId ids = MethodId::SB_DEFAULT;
     242 [ -  + ][ -  - ]:         80 :     if (args.size() >= 2 && !getMethodId(args[1], ids))
         [ -  + ][ -  + ]
                 [ -  - ]
     243                 :            :     {
     244                 :          0 :       return Node::null();
     245                 :            :     }
     246                 :         80 :     MethodId ida = MethodId::SBA_SEQUENTIAL;
     247 [ -  + ][ -  - ]:         80 :     if (args.size() >= 3 && !getMethodId(args[2], ida))
         [ -  + ][ -  + ]
                 [ -  - ]
     248                 :            :     {
     249                 :          0 :       return Node::null();
     250                 :            :     }
     251                 :         80 :     std::vector<Node> exp;
     252         [ +  + ]:        432 :     for (size_t i = 0, nchild = children.size(); i < nchild; i++)
     253                 :            :     {
     254                 :        352 :       exp.push_back(children[i]);
     255                 :            :     }
     256                 :         80 :     Node res = applySubstitution(args[0], exp, ids, ida);
     257         [ -  + ]:         80 :     if (res.isNull())
     258                 :            :     {
     259                 :          0 :       return Node::null();
     260                 :            :     }
     261                 :         80 :     return args[0].eqNode(res);
     262                 :         80 :   }
     263         [ +  + ]:    1817597 :   else if (id == ProofRule::MACRO_REWRITE)
     264                 :            :   {
     265 [ -  + ][ -  + ]:       2034 :     Assert(children.empty());
                 [ -  - ]
     266 [ +  - ][ +  - ]:       2034 :     Assert(1 <= args.size() && args.size() <= 2);
         [ -  + ][ -  + ]
                 [ -  - ]
     267                 :       2034 :     MethodId idr = MethodId::RW_REWRITE;
     268 [ -  + ][ -  - ]:       2034 :     if (args.size() == 2 && !getMethodId(args[1], idr))
         [ -  + ][ -  + ]
                 [ -  - ]
     269                 :            :     {
     270                 :          0 :       return Node::null();
     271                 :            :     }
     272                 :       2034 :     Node res = d_env.rewriteViaMethod(args[0], idr);
     273         [ -  + ]:       2034 :     if (res.isNull())
     274                 :            :     {
     275                 :          0 :       return Node::null();
     276                 :            :     }
     277                 :       2034 :     return args[0].eqNode(res);
     278                 :       2034 :   }
     279         [ +  + ]:    1815563 :   else if (id == ProofRule::EVALUATE)
     280                 :            :   {
     281 [ -  + ][ -  + ]:     718176 :     Assert(children.empty());
                 [ -  - ]
     282 [ -  + ][ -  + ]:     718176 :     Assert(args.size() == 1);
                 [ -  - ]
     283                 :     718176 :     Node res = d_env.rewriteViaMethod(args[0], MethodId::RW_EVALUATE);
     284         [ +  + ]:     718176 :     if (res.isNull())
     285                 :            :     {
     286                 :     529227 :       return Node::null();
     287                 :            :     }
     288                 :     188949 :     return args[0].eqNode(res);
     289                 :     718176 :   }
     290         [ +  + ]:    1097387 :   else if (id == ProofRule::DISTINCT_VALUES)
     291                 :            :   {
     292 [ -  + ][ -  + ]:         44 :     Assert(children.empty());
                 [ -  - ]
     293 [ -  + ][ -  + ]:         44 :     Assert(args.size() == 2);
                 [ -  - ]
     294 [ -  + ][ -  + ]:        132 :     AssertEqual(args[0].getType(), args[1].getType());
                 [ -  - ]
     295 [ +  - ][ +  - ]:         44 :     if (!args[0].isConst() || !args[1].isConst() || args[0] == args[1])
         [ -  + ][ -  + ]
     296                 :            :     {
     297                 :          0 :       return Node::null();
     298                 :            :     }
     299                 :            :     // note we don't check for illegal (non-first-class) types here
     300                 :         88 :     return args[0].eqNode(args[1]).notNode();
     301                 :            :   }
     302         [ +  + ]:    1097343 :   else if (id == ProofRule::ACI_NORM)
     303                 :            :   {
     304 [ -  + ][ -  + ]:      28375 :     Assert(children.empty());
                 [ -  - ]
     305 [ -  + ][ -  + ]:      28375 :     Assert(args.size() == 1);
                 [ -  - ]
     306         [ -  + ]:      28375 :     if (args[0].getKind() != Kind::EQUAL)
     307                 :            :     {
     308                 :          0 :       return Node::null();
     309                 :            :     }
     310         [ -  + ]:      28375 :     if (!expr::isACINorm(args[0][0], args[0][1]))
     311                 :            :     {
     312                 :          0 :       return Node::null();
     313                 :            :     }
     314                 :      28375 :     return args[0];
     315                 :            :   }
     316         [ +  + ]:    1068968 :   else if (id == ProofRule::ABSORB)
     317                 :            :   {
     318 [ -  + ][ -  + ]:       4951 :     Assert(children.empty());
                 [ -  - ]
     319 [ -  + ][ -  + ]:       4951 :     Assert(args.size() == 1);
                 [ -  - ]
     320         [ -  + ]:       4951 :     if (args[0].getKind() != Kind::EQUAL)
     321                 :            :     {
     322                 :          0 :       return Node::null();
     323                 :            :     }
     324                 :       9902 :     if (expr::getZeroElement(nm, args[0][0].getKind(), args[0][0].getType())
     325         [ -  + ]:      14853 :         != args[0][1])
     326                 :            :     {
     327                 :          0 :       return Node::null();
     328                 :            :     }
     329         [ -  + ]:       4951 :     if (!expr::isAbsorb(args[0][0], args[0][1]))
     330                 :            :     {
     331                 :          0 :       return Node::null();
     332                 :            :     }
     333                 :       4951 :     return args[0];
     334                 :            :   }
     335         [ +  + ]:    1064017 :   else if (id == ProofRule::MACRO_SR_EQ_INTRO)
     336                 :            :   {
     337 [ +  - ][ +  - ]:      35343 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  + ]
                 [ -  - ]
     338                 :            :     MethodId ids, ida, idr;
     339         [ -  + ]:      35343 :     if (!getMethodIds(args, ids, ida, idr, 1))
     340                 :            :     {
     341                 :          0 :       return Node::null();
     342                 :            :     }
     343                 :      35343 :     Node res = applySubstitutionRewrite(args[0], children, ids, ida, idr);
     344         [ -  + ]:      35343 :     if (res.isNull())
     345                 :            :     {
     346                 :          0 :       return Node::null();
     347                 :            :     }
     348                 :      35343 :     return args[0].eqNode(res);
     349                 :      35343 :   }
     350         [ +  + ]:    1028674 :   else if (id == ProofRule::MACRO_SR_PRED_INTRO)
     351                 :            :   {
     352         [ +  - ]:      90550 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     353                 :      45275 :                              << args[0] << std::endl;
     354 [ +  - ][ +  - ]:      45275 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  + ]
                 [ -  - ]
     355                 :            :     MethodId ids, ida, idr;
     356         [ -  + ]:      45275 :     if (!getMethodIds(args, ids, ida, idr, 1))
     357                 :            :     {
     358                 :          0 :       return Node::null();
     359                 :            :     }
     360                 :      45275 :     Node res = applySubstitutionRewrite(args[0], children, ids, ida, idr);
     361         [ -  + ]:      45275 :     if (res.isNull())
     362                 :            :     {
     363                 :          0 :       return Node::null();
     364                 :            :     }
     365         [ +  - ]:      45275 :     Trace("builtin-pfcheck") << "Result is " << res << std::endl;
     366         [ +  - ]:      90550 :     Trace("builtin-pfcheck")
     367                 :      45275 :         << "Witness form is " << SkolemManager::getOriginalForm(res)
     368                 :      45275 :         << std::endl;
     369                 :            :     // **** NOTE: can rewrite the witness form here. This enables certain lemmas
     370                 :            :     // to be provable, e.g. (= k t) where k is a purification Skolem for t.
     371                 :      45275 :     res = d_rewriter->rewrite(SkolemManager::getOriginalForm(res));
     372 [ +  + ][ +  + ]:      45275 :     if (!res.isConst() || !res.getConst<bool>())
                 [ +  + ]
     373                 :            :     {
     374         [ +  - ]:      37760 :       Trace("builtin-pfcheck")
     375                 :      18880 :           << "Failed to rewrite to true, res=" << res << std::endl;
     376                 :      18880 :       return Node::null();
     377                 :            :     }
     378         [ +  - ]:      26395 :     Trace("builtin-pfcheck") << "...success" << std::endl;
     379                 :      26395 :     return args[0];
     380                 :      45275 :   }
     381         [ +  + ]:     983399 :   else if (id == ProofRule::MACRO_SR_PRED_ELIM)
     382                 :            :   {
     383         [ +  - ]:      12002 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     384                 :       6001 :                              << args.size() << std::endl;
     385 [ -  + ][ -  + ]:       6001 :     Assert(children.size() >= 1);
                 [ -  - ]
     386 [ -  + ][ -  + ]:       6001 :     Assert(args.size() <= 3);
                 [ -  - ]
     387                 :       6001 :     std::vector<Node> exp;
     388                 :       6001 :     exp.insert(exp.end(), children.begin() + 1, children.end());
     389                 :            :     MethodId ids, ida, idr;
     390         [ -  + ]:       6001 :     if (!getMethodIds(args, ids, ida, idr, 0))
     391                 :            :     {
     392                 :          0 :       return Node::null();
     393                 :            :     }
     394                 :       6001 :     Node res1 = applySubstitutionRewrite(children[0], exp, ids, ida, idr);
     395         [ +  - ]:       6001 :     Trace("builtin-pfcheck") << "Returned " << res1 << std::endl;
     396                 :       6001 :     return res1;
     397                 :       6001 :   }
     398         [ +  + ]:     977398 :   else if (id == ProofRule::MACRO_SR_PRED_TRANSFORM)
     399                 :            :   {
     400         [ +  - ]:     191786 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     401                 :      95893 :                              << args.size() << std::endl;
     402 [ -  + ][ -  + ]:      95893 :     Assert(children.size() >= 1);
                 [ -  - ]
     403 [ +  - ][ +  - ]:      95893 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  + ]
                 [ -  - ]
     404 [ -  + ][ -  + ]:      95893 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     405                 :            :     MethodId ids, ida, idr;
     406         [ -  + ]:      95893 :     if (!getMethodIds(args, ids, ida, idr, 1))
     407                 :            :     {
     408                 :          0 :       return Node::null();
     409                 :            :     }
     410                 :      95893 :     std::vector<Node> exp;
     411                 :      95893 :     exp.insert(exp.end(), children.begin() + 1, children.end());
     412                 :      95893 :     Node res1 = applySubstitutionRewrite(children[0], exp, ids, ida, idr);
     413                 :      95893 :     Node res2 = applySubstitutionRewrite(args[0], exp, ids, ida, idr);
     414 [ +  + ][ -  + ]:      95893 :     if (res1.isNull() || res2.isNull())
                 [ +  + ]
     415                 :            :     {
     416                 :         16 :       return Node::null();
     417                 :            :     }
     418                 :            :     // if not already equal, do rewriting
     419         [ +  + ]:      95877 :     if (res1 != res2)
     420                 :            :     {
     421         [ +  - ]:       7236 :       Trace("builtin-pfcheck-debug")
     422                 :          0 :           << "Failed to show " << res1 << " == " << res2
     423                 :       3618 :           << ", resort to original forms..." << std::endl;
     424                 :            :       // can rewrite the witness forms
     425                 :       3618 :       res1 = d_rewriter->rewrite(SkolemManager::getOriginalForm(res1));
     426                 :       3618 :       res2 = d_rewriter->rewrite(SkolemManager::getOriginalForm(res2));
     427 [ +  - ][ +  + ]:       3618 :       if (res1.isNull() || res1 != res2)
                 [ +  + ]
     428                 :            :       {
     429         [ +  - ]:       1219 :         Trace("builtin-pfcheck") << "Failed to match results" << std::endl;
     430         [ +  - ]:       1219 :         Trace("builtin-pfcheck-debug") << res1 << " vs " << res2 << std::endl;
     431                 :       1219 :         return Node::null();
     432                 :            :       }
     433                 :            :     }
     434                 :      94658 :     return args[0];
     435                 :      95893 :   }
     436         [ +  + ]:     881505 :   else if (id == ProofRule::ITE_EQ)
     437                 :            :   {
     438 [ -  + ][ -  + ]:       5339 :     Assert(children.empty());
                 [ -  - ]
     439 [ -  + ][ -  + ]:       5339 :     Assert(args.size() == 1);
                 [ -  - ]
     440                 :       5339 :     return RemoveTermFormulas::getAxiomFor(args[0]);
     441                 :            :   }
     442         [ +  + ]:     876166 :   else if (id == ProofRule::TRUST)
     443                 :            :   {
     444 [ -  + ][ -  + ]:      69902 :     Assert(args.size() >= 2);
                 [ -  - ]
     445                 :      69902 :     return args[1];
     446                 :            :   }
     447         [ +  + ]:     806264 :   else if (id == ProofRule::TRUST_THEORY_REWRITE)
     448                 :            :   {
     449                 :            :     // "trusted" rules
     450 [ -  + ][ -  + ]:     597969 :     Assert(!args.empty());
                 [ -  - ]
     451 [ -  + ][ -  + ]:     597969 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     452                 :     597969 :     return args[0];
     453                 :            :   }
     454 [ +  + ][ -  + ]:     208295 :   else if (id == ProofRule::LFSC_RULE || id == ProofRule::ALETHE_RULE)
     455                 :            :   {
     456 [ -  + ][ -  + ]:      43155 :     Assert(args.size() > 1);
                 [ -  - ]
     457 [ -  + ][ -  + ]:      43155 :     Assert(args[0].getType().isInteger());
                 [ -  - ]
     458                 :      43155 :     return args[1];
     459                 :            :   }
     460         [ +  + ]:     165140 :   else if (id == ProofRule::ENCODE_EQ_INTRO)
     461                 :            :   {
     462 [ -  + ][ -  + ]:       3370 :     Assert(children.empty());
                 [ -  - ]
     463 [ -  + ][ -  + ]:       3370 :     Assert(args.size() == 1);
                 [ -  - ]
     464                 :       3370 :     Node ac = getEncodeEqIntro(nodeManager(), args[0]);
     465                 :       3370 :     return args[0].eqNode(ac);
     466                 :       3370 :   }
     467         [ +  + ]:     161770 :   else if (id == ProofRule::DSL_REWRITE)
     468                 :            :   {
     469                 :            :     // consult rewrite db, apply args[1]...args[n] as a substitution
     470                 :            :     // to variable list and prove equality between LHS and RHS.
     471 [ -  + ][ -  + ]:      93235 :     Assert(d_rdb != nullptr);
                 [ -  - ]
     472                 :            :     ProofRewriteRule di;
     473         [ -  + ]:      93235 :     if (!rewriter::getRewriteRule(args[0], di))
     474                 :            :     {
     475                 :          0 :       return Node::null();
     476                 :            :     }
     477                 :      93235 :     const rewriter::RewriteProofRule& rpr = d_rdb->getRule(di);
     478                 :      93235 :     const std::vector<Node>& varList = rpr.getVarList();
     479                 :      93235 :     const std::vector<Node>& conds = rpr.getConditions();
     480                 :      93235 :     std::vector<Node> subs(args.begin() + 1, args.end());
     481         [ -  + ]:      93235 :     if (varList.size() != subs.size())
     482                 :            :     {
     483                 :          0 :       return Node::null();
     484                 :            :     }
     485                 :            :     // check whether child proof match
     486         [ -  + ]:      93235 :     if (conds.size() != children.size())
     487                 :            :     {
     488                 :          0 :       return Node::null();
     489                 :            :     }
     490         [ +  + ]:      97385 :     for (size_t i = 0, nchildren = children.size(); i < nchildren; i++)
     491                 :            :     {
     492                 :       4150 :       Node scond = expr::narySubstitute(conds[i], varList, subs);
     493         [ -  + ]:       4150 :       if (scond != children[i])
     494                 :            :       {
     495                 :          0 :         return Node::null();
     496                 :            :       }
     497         [ +  - ]:       4150 :     }
     498                 :      93235 :     return rpr.getConclusionFor(subs);
     499                 :      93235 :   }
     500         [ +  - ]:      68535 :   else if (id == ProofRule::THEORY_REWRITE)
     501                 :            :   {
     502 [ -  + ][ -  + ]:      68535 :     Assert(args.size() == 2);
                 [ -  - ]
     503                 :            :     ProofRewriteRule di;
     504         [ -  + ]:      68535 :     if (!rewriter::getRewriteRule(args[0], di))
     505                 :            :     {
     506                 :          0 :       return Node::null();
     507                 :            :     }
     508         [ -  + ]:      68535 :     if (args[1].getKind() != Kind::EQUAL)
     509                 :            :     {
     510                 :          0 :       return Node::null();
     511                 :            :     }
     512                 :      68535 :     Node rhs = d_rewriter->rewriteViaRule(di, args[1][0]);
     513 [ +  - ][ -  + ]:      68535 :     if (rhs.isNull() || rhs != args[1][1])
         [ +  - ][ -  + ]
                 [ -  - ]
     514                 :            :     {
     515                 :          0 :       return Node::null();
     516                 :            :     }
     517                 :      68535 :     return args[1];
     518                 :      68535 :   }
     519                 :            :   // no rule
     520                 :          0 :   return Node::null();
     521                 :            : }
     522                 :            : 
     523                 :       3450 : Node BuiltinProofRuleChecker::getEncodeEqIntro(NodeManager* nm, const Node& n)
     524                 :            : {
     525                 :       3450 :   rewriter::RewriteDbNodeConverter rconv(nm);
     526                 :            :   // run a single (small) step conversion
     527                 :       6900 :   return rconv.postConvert(n);
     528                 :       3450 : }
     529                 :            : 
     530                 :     504149 : bool BuiltinProofRuleChecker::getTheoryId(TNode n, TheoryId& tid)
     531                 :            : {
     532                 :            :   uint32_t i;
     533         [ -  + ]:     504149 :   if (!getUInt32(n, i))
     534                 :            :   {
     535                 :          0 :     return false;
     536                 :            :   }
     537                 :     504149 :   tid = static_cast<TheoryId>(i);
     538                 :     504149 :   return true;
     539                 :            : }
     540                 :            : 
     541                 :    1119103 : Node BuiltinProofRuleChecker::mkTheoryIdNode(NodeManager* nm, TheoryId tid)
     542                 :            : {
     543                 :    2238206 :   return nm->mkConstInt(Rational(static_cast<uint32_t>(tid)));
     544                 :            : }
     545                 :            : 
     546                 :            : }  // namespace builtin
     547                 :            : }  // namespace theory
     548                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14