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: 213 262 81.3 %
Date: 2024-11-17 12:40:58 Functions: 9 10 90.0 %
Branches: 179 356 50.3 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Hans-Joerg Schurr, Hanna Lachnitt
       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/builtin/proof_checker.h"
      17                 :            : 
      18                 :            : #include "expr/nary_term_util.h"
      19                 :            : #include "expr/skolem_manager.h"
      20                 :            : #include "rewriter/rewrite_db.h"
      21                 :            : #include "rewriter/rewrite_db_term_process.h"
      22                 :            : #include "rewriter/rewrite_proof_rule.h"
      23                 :            : #include "smt/env.h"
      24                 :            : #include "smt/term_formula_removal.h"
      25                 :            : #include "theory/evaluator.h"
      26                 :            : #include "theory/quantifiers/extended_rewrite.h"
      27                 :            : #include "theory/rewriter.h"
      28                 :            : #include "theory/substitutions.h"
      29                 :            : #include "theory/theory.h"
      30                 :            : #include "util/rational.h"
      31                 :            : 
      32                 :            : using namespace cvc5::internal::kind;
      33                 :            : 
      34                 :            : namespace cvc5::internal {
      35                 :            : namespace theory {
      36                 :            : namespace builtin {
      37                 :            : 
      38                 :      49838 : BuiltinProofRuleChecker::BuiltinProofRuleChecker(NodeManager* nm,
      39                 :            :                                                  Rewriter* r,
      40                 :      49838 :                                                  Env& env)
      41                 :      49838 :     : ProofRuleChecker(nm), d_rewriter(r), d_env(env), d_rdb(nullptr)
      42                 :            : {
      43                 :      49838 : }
      44                 :            : 
      45                 :      19204 : void BuiltinProofRuleChecker::registerTo(ProofChecker* pc)
      46                 :            : {
      47                 :      19204 :   pc->registerChecker(ProofRule::ASSUME, this);
      48                 :      19204 :   pc->registerChecker(ProofRule::SCOPE, this);
      49                 :      19204 :   pc->registerChecker(ProofRule::SUBS, this);
      50                 :      19204 :   pc->registerChecker(ProofRule::EVALUATE, this);
      51                 :      19204 :   pc->registerChecker(ProofRule::ACI_NORM, this);
      52                 :      19204 :   pc->registerChecker(ProofRule::ITE_EQ, this);
      53                 :      19204 :   pc->registerChecker(ProofRule::ENCODE_EQ_INTRO, this);
      54                 :      19204 :   pc->registerChecker(ProofRule::DSL_REWRITE, this);
      55                 :      19204 :   pc->registerChecker(ProofRule::THEORY_REWRITE, this);
      56                 :            :   // rules depending on the rewriter
      57                 :      19204 :   pc->registerTrustedChecker(ProofRule::MACRO_REWRITE, this, 4);
      58                 :      19204 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_EQ_INTRO, this, 4);
      59                 :      19204 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_INTRO, this, 4);
      60                 :      19204 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_ELIM, this, 4);
      61                 :      19204 :   pc->registerTrustedChecker(ProofRule::MACRO_SR_PRED_TRANSFORM, this, 4);
      62                 :      19204 :   pc->registerTrustedChecker(ProofRule::TRUST_THEORY_REWRITE, this, 4);
      63                 :            :   // trusted rules
      64                 :      19204 :   pc->registerTrustedChecker(ProofRule::TRUST, this, 1);
      65                 :            :   // external proof rules
      66                 :      19204 :   pc->registerChecker(ProofRule::LFSC_RULE, this);
      67                 :      19204 :   pc->registerChecker(ProofRule::ALETHE_RULE, this);
      68                 :            : 
      69                 :      19204 :   d_rdb = pc->getRewriteDatabase();
      70                 :      19204 : }
      71                 :            : 
      72                 :    2513550 : Node BuiltinProofRuleChecker::applySubstitutionRewrite(
      73                 :            :     Node n,
      74                 :            :     const std::vector<Node>& exp,
      75                 :            :     MethodId ids,
      76                 :            :     MethodId ida,
      77                 :            :     MethodId idr)
      78                 :            : {
      79                 :    2513550 :   Node nks = applySubstitution(n, exp, ids, ida);
      80                 :    5027100 :   return d_env.rewriteViaMethod(nks, idr);
      81                 :            : }
      82                 :            : 
      83                 :    8907560 : bool BuiltinProofRuleChecker::getSubstitutionForLit(Node exp,
      84                 :            :                                                     TNode& var,
      85                 :            :                                                     TNode& subs,
      86                 :            :                                                     MethodId ids)
      87                 :            : {
      88         [ +  + ]:    8907560 :   if (ids == MethodId::SB_DEFAULT)
      89                 :            :   {
      90         [ -  + ]:    8906660 :     if (exp.getKind() != Kind::EQUAL)
      91                 :            :     {
      92                 :          0 :       return false;
      93                 :            :     }
      94                 :    8906660 :     var = exp[0];
      95                 :    8906660 :     subs = exp[1];
      96                 :            :   }
      97         [ -  + ]:        896 :   else if (ids == MethodId::SB_LITERAL)
      98                 :            :   {
      99                 :          0 :     bool polarity = exp.getKind() != Kind::NOT;
     100         [ -  - ]:          0 :     var = polarity ? exp : exp[0];
     101                 :          0 :     subs = NodeManager::currentNM()->mkConst(polarity);
     102                 :            :   }
     103         [ +  - ]:        896 :   else if (ids == MethodId::SB_FORMULA)
     104                 :            :   {
     105                 :        896 :     var = exp;
     106                 :        896 :     subs = NodeManager::currentNM()->mkConst(true);
     107                 :            :   }
     108                 :            :   else
     109                 :            :   {
     110                 :          0 :     Assert(false) << "BuiltinProofRuleChecker::applySubstitution: no "
     111                 :          0 :                      "substitution for "
     112                 :          0 :                   << ids << std::endl;
     113                 :            :     return false;
     114                 :            :   }
     115                 :    8907560 :   return true;
     116                 :            : }
     117                 :            : 
     118                 :     150039 : bool BuiltinProofRuleChecker::getSubstitutionFor(Node exp,
     119                 :            :                                                  std::vector<TNode>& vars,
     120                 :            :                                                  std::vector<TNode>& subs,
     121                 :            :                                                  std::vector<TNode>& from,
     122                 :            :                                                  MethodId ids)
     123                 :            : {
     124                 :     300078 :   TNode v;
     125                 :     300078 :   TNode s;
     126 [ +  + ][ +  - ]:     150039 :   if (exp.getKind() == Kind::AND && ids == MethodId::SB_DEFAULT)
                 [ +  + ]
     127                 :            :   {
     128         [ +  + ]:    8903560 :     for (const Node& ec : exp)
     129                 :            :     {
     130                 :            :       // non-recursive, do not use nested AND
     131         [ -  + ]:    8830540 :       if (!getSubstitutionForLit(ec, v, s, ids))
     132                 :            :       {
     133                 :          0 :         return false;
     134                 :            :       }
     135                 :    8830540 :       vars.push_back(v);
     136                 :    8830540 :       subs.push_back(s);
     137                 :    8830540 :       from.push_back(ec);
     138                 :            :     }
     139                 :      73022 :     return true;
     140                 :            :   }
     141                 :      77017 :   bool ret = getSubstitutionForLit(exp, v, s, ids);
     142                 :      77017 :   vars.push_back(v);
     143                 :      77017 :   subs.push_back(s);
     144                 :      77017 :   from.push_back(exp);
     145                 :      77017 :   return ret;
     146                 :            : }
     147                 :            : 
     148                 :          0 : Node BuiltinProofRuleChecker::applySubstitution(Node n,
     149                 :            :                                                 Node exp,
     150                 :            :                                                 MethodId ids,
     151                 :            :                                                 MethodId ida)
     152                 :            : {
     153                 :          0 :   std::vector<Node> expv{exp};
     154                 :          0 :   return applySubstitution(n, expv, ids, ida);
     155                 :            : }
     156                 :            : 
     157                 :    2580150 : Node BuiltinProofRuleChecker::applySubstitution(Node n,
     158                 :            :                                                 const std::vector<Node>& exp,
     159                 :            :                                                 MethodId ids,
     160                 :            :                                                 MethodId ida)
     161                 :            : {
     162                 :    5160290 :   std::vector<TNode> vars;
     163                 :    5160290 :   std::vector<TNode> subs;
     164                 :    5160290 :   std::vector<TNode> from;
     165         [ +  + ]:    2695360 :   for (size_t i = 0, nexp = exp.size(); i < nexp; i++)
     166                 :            :   {
     167         [ -  + ]:     115211 :     if (exp[i].isNull())
     168                 :            :     {
     169                 :          0 :       return Node::null();
     170                 :            :     }
     171         [ -  + ]:     115211 :     if (!getSubstitutionFor(exp[i], vars, subs, from, ids))
     172                 :            :     {
     173                 :          0 :       return Node::null();
     174                 :            :     }
     175                 :            :   }
     176         [ -  + ]:    2580150 :   if (ida == MethodId::SBA_SIMUL)
     177                 :            :   {
     178                 :            :     // simply apply the simultaneous substitution now
     179                 :          0 :     return n.substitute(vars.begin(), vars.end(), subs.begin(), subs.end());
     180                 :            :   }
     181         [ +  + ]:    2580150 :   else if (ida == MethodId::SBA_FIXPOINT)
     182                 :            :   {
     183                 :     185814 :     SubstitutionMap sm;
     184         [ +  + ]:    6829770 :     for (size_t i = 0, nvars = vars.size(); i < nvars; i++)
     185                 :            :     {
     186                 :    6736870 :       sm.addSubstitution(vars[i], subs[i]);
     187                 :            :     }
     188                 :     185814 :     Node ns = sm.apply(n);
     189                 :      92907 :     return ns;
     190                 :            :   }
     191 [ -  + ][ -  + ]:    2487240 :   Assert(ida == MethodId::SBA_SEQUENTIAL);
                 [ -  - ]
     192                 :            :   // we prefer n traversals of the term to n^2/2 traversals of range terms
     193                 :    4974480 :   Node ns = n;
     194         [ +  + ]:    2540810 :   for (size_t i = 0, nvars = vars.size(); i < nvars; i++)
     195                 :            :   {
     196                 :     107140 :     TNode v = vars[(nvars - 1) - i];
     197                 :      53570 :     TNode s = subs[(nvars - 1) - i];
     198                 :      53570 :     ns = ns.substitute(v, s);
     199                 :            :   }
     200                 :    2487240 :   return ns;
     201                 :            : }
     202                 :            : 
     203                 :    3513390 : Node BuiltinProofRuleChecker::checkInternal(ProofRule id,
     204                 :            :                                             const std::vector<Node>& children,
     205                 :            :                                             const std::vector<Node>& args)
     206                 :            : {
     207                 :    3513390 :   NodeManager* nm = nodeManager();
     208                 :            :   // compute what was proven
     209         [ +  + ]:    3513390 :   if (id == ProofRule::ASSUME)
     210                 :            :   {
     211 [ -  + ][ -  + ]:          6 :     Assert(children.empty());
                 [ -  - ]
     212 [ -  + ][ -  + ]:          6 :     Assert(args.size() == 1);
                 [ -  - ]
     213 [ -  + ][ -  + ]:          6 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     214                 :          6 :     return args[0];
     215                 :            :   }
     216         [ +  + ]:    3513380 :   else if (id == ProofRule::SCOPE)
     217                 :            :   {
     218 [ -  + ][ -  + ]:     816084 :     Assert(children.size() == 1);
                 [ -  - ]
     219         [ +  + ]:     816084 :     if (args.empty())
     220                 :            :     {
     221                 :            :       // no antecedant
     222                 :       4989 :       return children[0];
     223                 :            :     }
     224                 :    1622190 :     Node ant = nm->mkAnd(args);
     225                 :            :     // if the conclusion is false, its the negated antencedant only
     226 [ +  + ][ +  + ]:     811095 :     if (children[0].isConst() && !children[0].getConst<bool>())
                 [ +  + ]
     227                 :            :     {
     228                 :     652944 :       return ant.notNode();
     229                 :            :     }
     230                 :     158151 :     return nm->mkNode(Kind::IMPLIES, ant, children[0]);
     231                 :            :   }
     232         [ -  + ]:    2697300 :   else if (id == ProofRule::SUBS)
     233                 :            :   {
     234                 :          0 :     Assert(children.size() > 0);
     235                 :          0 :     Assert(1 <= args.size() && args.size() <= 3) << "Args: " << args;
     236                 :          0 :     MethodId ids = MethodId::SB_DEFAULT;
     237                 :          0 :     if (args.size() >= 2 && !getMethodId(args[1], ids))
     238                 :            :     {
     239                 :          0 :       return Node::null();
     240                 :            :     }
     241                 :          0 :     MethodId ida = MethodId::SBA_SEQUENTIAL;
     242                 :          0 :     if (args.size() >= 3 && !getMethodId(args[2], ida))
     243                 :            :     {
     244                 :          0 :       return Node::null();
     245                 :            :     }
     246                 :          0 :     std::vector<Node> exp;
     247         [ -  - ]:          0 :     for (size_t i = 0, nchild = children.size(); i < nchild; i++)
     248                 :            :     {
     249                 :          0 :       exp.push_back(children[i]);
     250                 :            :     }
     251                 :          0 :     Node res = applySubstitution(args[0], exp, ids, ida);
     252         [ -  - ]:          0 :     if (res.isNull())
     253                 :            :     {
     254                 :          0 :       return Node::null();
     255                 :            :     }
     256                 :          0 :     return args[0].eqNode(res);
     257                 :            :   }
     258         [ +  + ]:    2697300 :   else if (id == ProofRule::MACRO_REWRITE)
     259                 :            :   {
     260 [ -  + ][ -  + ]:        743 :     Assert(children.empty());
                 [ -  - ]
     261 [ +  - ][ +  - ]:       1486 :     Assert(1 <= args.size() && args.size() <= 2);
         [ -  + ][ -  - ]
     262                 :        743 :     MethodId idr = MethodId::RW_REWRITE;
     263 [ -  + ][ -  - ]:        743 :     if (args.size() == 2 && !getMethodId(args[1], idr))
         [ -  + ][ -  + ]
                 [ -  - ]
     264                 :            :     {
     265                 :          0 :       return Node::null();
     266                 :            :     }
     267                 :       1486 :     Node res = d_env.rewriteViaMethod(args[0], idr);
     268         [ -  + ]:        743 :     if (res.isNull())
     269                 :            :     {
     270                 :          0 :       return Node::null();
     271                 :            :     }
     272                 :        743 :     return args[0].eqNode(res);
     273                 :            :   }
     274         [ +  + ]:    2696560 :   else if (id == ProofRule::EVALUATE)
     275                 :            :   {
     276 [ -  + ][ -  + ]:     443971 :     Assert(children.empty());
                 [ -  - ]
     277 [ -  + ][ -  + ]:     443971 :     Assert(args.size() == 1);
                 [ -  - ]
     278                 :     887942 :     Node res = d_env.rewriteViaMethod(args[0], MethodId::RW_EVALUATE);
     279         [ +  + ]:     443971 :     if (res.isNull())
     280                 :            :     {
     281                 :     291413 :       return Node::null();
     282                 :            :     }
     283                 :     152558 :     return args[0].eqNode(res);
     284                 :            :   }
     285         [ +  + ]:    2252580 :   else if (id == ProofRule::ACI_NORM)
     286                 :            :   {
     287 [ -  + ][ -  + ]:      17674 :     Assert(children.empty());
                 [ -  - ]
     288 [ -  + ][ -  + ]:      17674 :     Assert(args.size() == 1);
                 [ -  - ]
     289         [ -  + ]:      17674 :     if (args[0].getKind() != Kind::EQUAL)
     290                 :            :     {
     291                 :          0 :       return Node::null();
     292                 :            :     }
     293         [ -  + ]:      17674 :     if (!expr::isACINorm(args[0][0], args[0][1]))
     294                 :            :     {
     295                 :          0 :       return Node::null();
     296                 :            :     }
     297                 :      17674 :     return args[0];
     298                 :            :   }
     299         [ +  + ]:    2234910 :   else if (id == ProofRule::MACRO_SR_EQ_INTRO)
     300                 :            :   {
     301 [ +  - ][ +  - ]:     110024 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  - ]
     302                 :            :     MethodId ids, ida, idr;
     303         [ -  + ]:      55012 :     if (!getMethodIds(args, ids, ida, idr, 1))
     304                 :            :     {
     305                 :          0 :       return Node::null();
     306                 :            :     }
     307                 :     110024 :     Node res = applySubstitutionRewrite(args[0], children, ids, ida, idr);
     308         [ -  + ]:      55012 :     if (res.isNull())
     309                 :            :     {
     310                 :          0 :       return Node::null();
     311                 :            :     }
     312                 :      55012 :     return args[0].eqNode(res);
     313                 :            :   }
     314         [ +  + ]:    2179900 :   else if (id == ProofRule::MACRO_SR_PRED_INTRO)
     315                 :            :   {
     316         [ +  - ]:      88530 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     317                 :      44265 :                              << args[0] << std::endl;
     318 [ +  - ][ +  - ]:      88530 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  - ]
     319                 :            :     MethodId ids, ida, idr;
     320         [ -  + ]:      44265 :     if (!getMethodIds(args, ids, ida, idr, 1))
     321                 :            :     {
     322                 :          0 :       return Node::null();
     323                 :            :     }
     324                 :      88530 :     Node res = applySubstitutionRewrite(args[0], children, ids, ida, idr);
     325         [ -  + ]:      44265 :     if (res.isNull())
     326                 :            :     {
     327                 :          0 :       return Node::null();
     328                 :            :     }
     329         [ +  - ]:      44265 :     Trace("builtin-pfcheck") << "Result is " << res << std::endl;
     330         [ +  - ]:      88530 :     Trace("builtin-pfcheck") << "Witness form is "
     331                 :      44265 :                              << SkolemManager::getOriginalForm(res) << std::endl;
     332                 :            :     // **** NOTE: can rewrite the witness form here. This enables certain lemmas
     333                 :            :     // to be provable, e.g. (= k t) where k is a purification Skolem for t.
     334                 :      44265 :     res = d_rewriter->rewrite(SkolemManager::getOriginalForm(res));
     335 [ +  + ][ +  + ]:      44265 :     if (!res.isConst() || !res.getConst<bool>())
                 [ +  + ]
     336                 :            :     {
     337         [ +  - ]:      41758 :       Trace("builtin-pfcheck")
     338                 :      20879 :           << "Failed to rewrite to true, res=" << res << std::endl;
     339                 :      20879 :       return Node::null();
     340                 :            :     }
     341         [ +  - ]:      23386 :     Trace("builtin-pfcheck") << "...success" << std::endl;
     342                 :      23386 :     return args[0];
     343                 :            :   }
     344         [ +  + ]:    2135630 :   else if (id == ProofRule::MACRO_SR_PRED_ELIM)
     345                 :            :   {
     346         [ +  - ]:      10222 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     347                 :       5111 :                              << args.size() << std::endl;
     348 [ -  + ][ -  + ]:       5111 :     Assert(children.size() >= 1);
                 [ -  - ]
     349 [ -  + ][ -  + ]:       5111 :     Assert(args.size() <= 3);
                 [ -  - ]
     350                 :      10222 :     std::vector<Node> exp;
     351                 :       5111 :     exp.insert(exp.end(), children.begin() + 1, children.end());
     352                 :            :     MethodId ids, ida, idr;
     353         [ -  + ]:       5111 :     if (!getMethodIds(args, ids, ida, idr, 0))
     354                 :            :     {
     355                 :          0 :       return Node::null();
     356                 :            :     }
     357                 :      10222 :     Node res1 = applySubstitutionRewrite(children[0], exp, ids, ida, idr);
     358         [ +  - ]:       5111 :     Trace("builtin-pfcheck") << "Returned " << res1 << std::endl;
     359                 :       5111 :     return res1;
     360                 :            :   }
     361         [ +  + ]:    2130520 :   else if (id == ProofRule::MACRO_SR_PRED_TRANSFORM)
     362                 :            :   {
     363         [ +  - ]:    2409160 :     Trace("builtin-pfcheck") << "Check " << id << " " << children.size() << " "
     364                 :    1204580 :                              << args.size() << std::endl;
     365 [ -  + ][ -  + ]:    1204580 :     Assert(children.size() >= 1);
                 [ -  - ]
     366 [ +  - ][ +  - ]:    2409160 :     Assert(1 <= args.size() && args.size() <= 4);
         [ -  + ][ -  - ]
     367 [ -  + ][ -  + ]:    1204580 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     368                 :            :     MethodId ids, ida, idr;
     369         [ -  + ]:    1204580 :     if (!getMethodIds(args, ids, ida, idr, 1))
     370                 :            :     {
     371                 :          0 :       return Node::null();
     372                 :            :     }
     373                 :    2409160 :     std::vector<Node> exp;
     374                 :    1204580 :     exp.insert(exp.end(), children.begin() + 1, children.end());
     375                 :    2409160 :     Node res1 = applySubstitutionRewrite(children[0], exp, ids, ida, idr);
     376                 :    2409160 :     Node res2 = applySubstitutionRewrite(args[0], exp, ids, ida, idr);
     377                 :            :     // if not already equal, do rewriting
     378         [ +  + ]:    1204580 :     if (res1 != res2)
     379                 :            :     {
     380         [ +  - ]:      14128 :       Trace("builtin-pfcheck-debug")
     381                 :          0 :           << "Failed to show " << res1 << " == " << res2
     382                 :       7064 :           << ", resort to original forms..." << std::endl;
     383                 :            :       // can rewrite the witness forms
     384                 :       7064 :       res1 = d_rewriter->rewrite(SkolemManager::getOriginalForm(res1));
     385                 :       7064 :       res2 = d_rewriter->rewrite(SkolemManager::getOriginalForm(res2));
     386 [ +  + ][ +  + ]:       7064 :       if (res1.isNull() || res1 != res2)
                 [ +  + ]
     387                 :            :       {
     388         [ +  - ]:       1113 :         Trace("builtin-pfcheck") << "Failed to match results" << std::endl;
     389         [ +  - ]:       1113 :         Trace("builtin-pfcheck-debug") << res1 << " vs " << res2 << std::endl;
     390                 :       1113 :         return Node::null();
     391                 :            :       }
     392                 :            :     }
     393                 :    1203470 :     return args[0];
     394                 :            :   }
     395         [ +  + ]:     925943 :   else if (id == ProofRule::ITE_EQ)
     396                 :            :   {
     397 [ -  + ][ -  + ]:       7786 :     Assert(children.empty());
                 [ -  - ]
     398 [ -  + ][ -  + ]:       7786 :     Assert(args.size() == 1);
                 [ -  - ]
     399                 :       7786 :     return RemoveTermFormulas::getAxiomFor(args[0]);
     400                 :            :   }
     401         [ +  + ]:     918157 :   else if (id == ProofRule::TRUST)
     402                 :            :   {
     403 [ -  + ][ -  + ]:      51542 :     Assert(args.size() >= 2);
                 [ -  - ]
     404                 :      51542 :     return args[1];
     405                 :            :   }
     406         [ +  + ]:     866615 :   else if (id == ProofRule::TRUST_THEORY_REWRITE)
     407                 :            :   {
     408                 :            :     // "trusted" rules
     409 [ -  + ][ -  + ]:     706156 :     Assert(!args.empty());
                 [ -  - ]
     410 [ -  + ][ -  + ]:     706156 :     Assert(args[0].getType().isBoolean());
                 [ -  - ]
     411                 :     706156 :     return args[0];
     412                 :            :   }
     413 [ +  + ][ -  + ]:     160459 :   else if (id == ProofRule::LFSC_RULE || id == ProofRule::ALETHE_RULE)
     414                 :            :   {
     415 [ -  + ][ -  + ]:      49522 :     Assert(args.size() > 1);
                 [ -  - ]
     416 [ -  + ][ -  + ]:      49522 :     Assert(args[0].getType().isInteger());
                 [ -  - ]
     417                 :      49522 :     return args[1];
     418                 :            :   }
     419         [ +  + ]:     110937 :   else if (id == ProofRule::ENCODE_EQ_INTRO)
     420                 :            :   {
     421 [ -  + ][ -  + ]:       6212 :     Assert(children.empty());
                 [ -  - ]
     422 [ -  + ][ -  + ]:       6212 :     Assert(args.size() == 1);
                 [ -  - ]
     423                 :      12424 :     rewriter::RewriteDbNodeConverter rconv(nodeManager());
     424                 :            :     // run a single (small) step conversion
     425                 :      12424 :     Node ac = rconv.postConvert(args[0]);
     426                 :       6212 :     return args[0].eqNode(ac);
     427                 :            :   }
     428         [ +  + ]:     104725 :   else if (id == ProofRule::DSL_REWRITE)
     429                 :            :   {
     430                 :            :     // consult rewrite db, apply args[1]...args[n] as a substitution
     431                 :            :     // to variable list and prove equality between LHS and RHS.
     432 [ -  + ][ -  + ]:      95384 :     Assert(d_rdb != nullptr);
                 [ -  - ]
     433                 :            :     ProofRewriteRule di;
     434         [ -  + ]:      95384 :     if (!rewriter::getRewriteRule(args[0], di))
     435                 :            :     {
     436                 :          0 :       return Node::null();
     437                 :            :     }
     438                 :      95384 :     const rewriter::RewriteProofRule& rpr = d_rdb->getRule(di);
     439                 :      95384 :     const std::vector<Node>& varList = rpr.getVarList();
     440                 :      95384 :     const std::vector<Node>& conds = rpr.getConditions();
     441                 :     190768 :     std::vector<Node> subs(args.begin() + 1, args.end());
     442         [ -  + ]:      95384 :     if (varList.size() != subs.size())
     443                 :            :     {
     444                 :          0 :       return Node::null();
     445                 :            :     }
     446                 :            :     // check whether child proof match
     447         [ -  + ]:      95384 :     if (conds.size() != children.size())
     448                 :            :     {
     449                 :          0 :       return Node::null();
     450                 :            :     }
     451         [ +  + ]:      97713 :     for (size_t i = 0, nchildren = children.size(); i < nchildren; i++)
     452                 :            :     {
     453                 :       2329 :       Node scond = expr::narySubstitute(conds[i], varList, subs);
     454         [ -  + ]:       2329 :       if (scond != children[i])
     455                 :            :       {
     456                 :          0 :         return Node::null();
     457                 :            :       }
     458                 :            :     }
     459                 :      95384 :     return rpr.getConclusionFor(subs);
     460                 :            :   }
     461         [ +  - ]:       9341 :   else if (id == ProofRule::THEORY_REWRITE)
     462                 :            :   {
     463 [ -  + ][ -  + ]:       9341 :     Assert(args.size() == 2);
                 [ -  - ]
     464                 :            :     ProofRewriteRule di;
     465         [ -  + ]:       9341 :     if (!rewriter::getRewriteRule(args[0], di))
     466                 :            :     {
     467                 :          0 :       return Node::null();
     468                 :            :     }
     469         [ -  + ]:       9341 :     if (args[1].getKind() != Kind::EQUAL)
     470                 :            :     {
     471                 :          0 :       return Node::null();
     472                 :            :     }
     473                 :      18682 :     Node rhs = d_rewriter->rewriteViaRule(di, args[1][0]);
     474 [ +  - ][ -  + ]:       9341 :     if (rhs.isNull() || rhs != args[1][1])
         [ +  - ][ -  + ]
                 [ -  - ]
     475                 :            :     {
     476                 :          0 :       return Node::null();
     477                 :            :     }
     478                 :       9341 :     return args[1];
     479                 :            :   }
     480                 :            :   // no rule
     481                 :          0 :   return Node::null();
     482                 :            : }
     483                 :            : 
     484                 :     779018 : bool BuiltinProofRuleChecker::getTheoryId(TNode n, TheoryId& tid)
     485                 :            : {
     486                 :            :   uint32_t i;
     487         [ -  + ]:     779018 :   if (!getUInt32(n, i))
     488                 :            :   {
     489                 :          0 :     return false;
     490                 :            :   }
     491                 :     779018 :   tid = static_cast<TheoryId>(i);
     492                 :     779018 :   return true;
     493                 :            : }
     494                 :            : 
     495                 :    1337930 : Node BuiltinProofRuleChecker::mkTheoryIdNode(TheoryId tid)
     496                 :            : {
     497                 :            :   return NodeManager::currentNM()->mkConstInt(
     498                 :    2675870 :       Rational(static_cast<uint32_t>(tid)));
     499                 :            : }
     500                 :            : 
     501                 :            : }  // namespace builtin
     502                 :            : }  // namespace theory
     503                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14