LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/rewriter - rewrite_db.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 72 90 80.0 %
Date: 2026-03-30 10:41:07 Functions: 6 9 66.7 %
Branches: 45 84 53.6 %

           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                 :            :  * Rewrite database
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "rewriter/rewrite_db.h"
      14                 :            : 
      15                 :            : #include "expr/node_algorithm.h"
      16                 :            : #include "rewriter/rewrite_db_term_process.h"
      17                 :            : #include "rewriter/rewrites.h"
      18                 :            : 
      19                 :            : using namespace cvc5::internal::kind;
      20                 :            : 
      21                 :            : namespace cvc5::internal {
      22                 :            : namespace rewriter {
      23                 :            : 
      24                 :    8921755 : uint32_t IsListTypeClassCallback::getTypeClass(TNode v)
      25                 :            : {
      26         [ +  + ]:    8921755 :   return expr::isListVar(v) ? 1 : 0;
      27                 :            : }
      28                 :            : 
      29                 :       6943 : RewriteDb::RewriteDb(NodeManager* nm) : d_canonCb(), d_canon(&d_canonCb)
      30                 :            : {
      31                 :       6943 :   d_true = nm->mkConst(true);
      32                 :       6943 :   d_false = nm->mkConst(false);
      33                 :       6943 :   rewriter::addRules(nm, *this);
      34                 :            : 
      35         [ -  + ]:       6943 :   if (TraceIsOn("rewrite-db"))
      36                 :            :   {
      37         [ -  - ]:          0 :     Trace("rewrite-db") << "Rewrite database:" << std::endl;
      38         [ -  - ]:          0 :     Trace("rewrite-db") << "START" << std::endl;
      39                 :          0 :     Trace("rewrite-db") << d_mt.debugPrint();
      40         [ -  - ]:          0 :     Trace("rewrite-db") << "END" << std::endl;
      41                 :            :   }
      42                 :       6943 : }
      43                 :            : 
      44                 :    3041034 : void RewriteDb::addRule(ProofRewriteRule id,
      45                 :            :                         const std::vector<Node> fvs,
      46                 :            :                         Node a,
      47                 :            :                         Node b,
      48                 :            :                         Node cond,
      49                 :            :                         Node context,
      50                 :            :                         Level _level)
      51                 :            : {
      52                 :    3041034 :   NodeManager* nm = a.getNodeManager();
      53                 :    3041034 :   std::vector<Node> fvsf = fvs;
      54                 :    3041034 :   std::vector<Node> condsn;
      55                 :    3041034 :   Node eq = a.eqNode(b);
      56                 :            :   // we canonize left-to-right, hence we should traverse in the opposite
      57                 :            :   // order, since we index based on conclusion, we make a dummy node here
      58                 :    3041034 :   std::vector<Node> tmpArgs;
      59                 :    3041034 :   tmpArgs.push_back(eq);
      60                 :    3041034 :   tmpArgs.push_back(cond);
      61         [ +  + ]:    3041034 :   if (!context.isNull())
      62                 :            :   {
      63                 :     118031 :     tmpArgs.push_back(context);
      64                 :            :   }
      65                 :    3041034 :   Node tmp = nm->mkNode(Kind::SEXPR, tmpArgs);
      66                 :            : 
      67                 :            :   // must canonize
      68         [ +  - ]:    6082068 :   Trace("rewrite-db") << "Add rule " << id << ": " << cond << " => " << a
      69                 :    3041034 :                       << " == " << b << std::endl;
      70 [ -  + ][ -  + ]:    3041034 :   Assert(a.getType().isComparableTo(b.getType()));
                 [ -  - ]
      71                 :    3041034 :   Node ctmp = d_canon.getCanonicalTerm(tmp, false, false);
      72         [ +  + ]:    3041034 :   if (!context.isNull())
      73                 :            :   {
      74                 :     118031 :     context = ctmp[2];
      75                 :            :   }
      76                 :            : 
      77                 :    3041034 :   Node condC = ctmp[1];
      78                 :    3041034 :   std::vector<Node> conds;
      79         [ +  + ]:    3041034 :   if (condC.getKind() == Kind::AND)
      80                 :            :   {
      81         [ +  + ]:    2291190 :     for (const Node& c : condC)
      82                 :            :     {
      83                 :            :       // should flatten in proof inference listing
      84 [ -  + ][ -  + ]:    1666320 :       Assert(c.getKind() != Kind::AND);
                 [ -  - ]
      85                 :    1666320 :       conds.push_back(c);
      86                 :    1666320 :     }
      87                 :            :   }
      88         [ +  + ]:    2416164 :   else if (!condC.isConst())
      89                 :            :   {
      90                 :     777616 :     conds.push_back(condC);
      91                 :            :   }
      92         [ -  + ]:    1638548 :   else if (!condC.getConst<bool>())
      93                 :            :   {
      94                 :            :     // skip those with false condition
      95                 :          0 :     return;
      96                 :            :   }
      97                 :            :   // make as expected matching: top symbol of all conditions is equality
      98                 :            :   // this means (not p) becomes (= p false), p becomes (= p true)
      99         [ +  + ]:    5484970 :   for (size_t i = 0, nconds = conds.size(); i < nconds; i++)
     100                 :            :   {
     101         [ +  + ]:    2443936 :     if (conds[i].getKind() == Kind::NOT)
     102                 :            :     {
     103                 :     333264 :       conds[i] = conds[i][0].eqNode(d_false);
     104                 :            :     }
     105         [ +  + ]:    2110672 :     else if (conds[i].getKind() != Kind::EQUAL)
     106                 :            :     {
     107                 :     708186 :       conds[i] = conds[i].eqNode(d_true);
     108                 :            :     }
     109                 :            :   }
     110                 :            :   // register side conditions?
     111                 :            : 
     112                 :    3041034 :   Node eqC = ctmp[0];
     113 [ -  + ][ -  + ]:    3041034 :   Assert(eqC.getKind() == Kind::EQUAL);
                 [ -  - ]
     114                 :            : 
     115                 :            :   // add to discrimination tree
     116         [ +  - ]:    3041034 :   Trace("proof-db-debug") << "Add (canonical) rule " << eqC << std::endl;
     117                 :    3041034 :   d_mt.addTerm(eqC[0]);
     118                 :            : 
     119                 :            :   // match to get canonical variables
     120                 :    3041034 :   std::unordered_map<Node, Node> msubs;
     121         [ -  + ]:    3041034 :   if (!expr::match(eq, eqC, msubs))
     122                 :            :   {
     123                 :          0 :     DebugUnhandled();
     124                 :            :   }
     125                 :    3041034 :   std::unordered_map<Node, Node>::iterator its;
     126                 :    3041034 :   std::vector<Node> ofvs;
     127                 :    3041034 :   std::vector<Node> cfvs;
     128         [ +  + ]:   11844758 :   for (const Node& v : fvsf)
     129                 :            :   {
     130                 :    8803724 :     its = msubs.find(v);
     131         [ +  - ]:    8803724 :     if (its != msubs.end())
     132                 :            :     {
     133                 :    8803724 :       ofvs.push_back(v);
     134                 :    8803724 :       cfvs.push_back(its->second);
     135         [ +  + ]:    8803724 :       if (expr::isListVar(v))
     136                 :            :       {
     137                 :            :         // mark the canonical variable as a list variable as well
     138                 :    1062279 :         expr::markListVar(its->second);
     139                 :            :       }
     140                 :            :     }
     141                 :            :     else
     142                 :            :     {
     143                 :          0 :       Unhandled() << "In DSL rule " << id << ", variable " << v
     144                 :          0 :                   << " is unused, dropping it" << std::endl;
     145                 :            :     }
     146                 :            :     // remember the free variables
     147                 :    8803724 :     d_allFv.insert(v);
     148                 :            :   }
     149                 :            : 
     150                 :            :   // initialize rule
     151                 :    3041034 :   d_rewDbRule[id].init(id, ofvs, cfvs, conds, eqC, context, _level);
     152                 :    3041034 :   d_concToRules[eqC].push_back(id);
     153                 :    3041034 :   d_headToRules[eqC[0]].push_back(id);
     154 [ +  - ][ +  - ]:    3041034 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     155                 :            : 
     156                 :     891077 : void RewriteDb::getMatches(const Node& eq, expr::NotifyMatch* ntm)
     157                 :            : {
     158                 :     891077 :   d_mt.getMatches(eq, ntm);
     159                 :     891077 : }
     160                 :            : 
     161                 :    1995643 : const RewriteProofRule& RewriteDb::getRule(ProofRewriteRule id) const
     162                 :            : {
     163                 :            :   std::map<ProofRewriteRule, RewriteProofRule>::const_iterator it =
     164                 :    1995643 :       d_rewDbRule.find(id);
     165 [ -  + ][ -  + ]:    1995643 :   Assert(it != d_rewDbRule.end());
                 [ -  - ]
     166                 :    1995643 :   return it->second;
     167                 :            : }
     168                 :            : 
     169                 :          0 : const std::vector<ProofRewriteRule>& RewriteDb::getRuleIdsForConclusion(
     170                 :            :     const Node& eq) const
     171                 :            : {
     172                 :            :   std::map<Node, std::vector<ProofRewriteRule> >::const_iterator it =
     173                 :          0 :       d_concToRules.find(eq);
     174         [ -  - ]:          0 :   if (it != d_concToRules.end())
     175                 :            :   {
     176                 :          0 :     return it->second;
     177                 :            :   }
     178                 :          0 :   return d_emptyVec;
     179                 :            : }
     180                 :            : 
     181                 :    1046284 : const std::vector<ProofRewriteRule>& RewriteDb::getRuleIdsForHead(
     182                 :            :     const Node& eq) const
     183                 :            : {
     184                 :            :   std::map<Node, std::vector<ProofRewriteRule> >::const_iterator it =
     185                 :    1046284 :       d_headToRules.find(eq);
     186         [ +  - ]:    1046284 :   if (it != d_headToRules.end())
     187                 :            :   {
     188                 :    1046284 :     return it->second;
     189                 :            :   }
     190                 :          0 :   return d_emptyVec;
     191                 :            : }
     192                 :          0 : const std::unordered_set<Node>& RewriteDb::getAllFreeVariables() const
     193                 :            : {
     194                 :          0 :   return d_allFv;
     195                 :            : }
     196                 :            : 
     197                 :          0 : const std::map<ProofRewriteRule, RewriteProofRule>& RewriteDb::getAllRules()
     198                 :            :     const
     199                 :            : {
     200                 :          0 :   return d_rewDbRule;
     201                 :            : }
     202                 :            : 
     203                 :            : }  // namespace rewriter
     204                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14