LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory - rewriter.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 208 229 90.8 %
Date: 2026-03-21 10:41:10 Functions: 18 18 100.0 %
Branches: 143 226 63.3 %

           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                 :            :  * The Rewriter class.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/rewriter.h"
      14                 :            : 
      15                 :            : #include "options/theory_options.h"
      16                 :            : #include "proof/conv_proof_generator.h"
      17                 :            : #include "theory/builtin/proof_checker.h"
      18                 :            : #include "theory/evaluator.h"
      19                 :            : #include "theory/quantifiers/extended_rewrite.h"
      20                 :            : #include "theory/rewriter_tables.h"
      21                 :            : #include "theory/theory.h"
      22                 :            : #include "util/resource_manager.h"
      23                 :            : 
      24                 :            : using namespace std;
      25                 :            : 
      26                 :            : namespace cvc5::internal {
      27                 :            : namespace theory {
      28                 :            : 
      29                 :            : // Note that this function is a simplified version of Theory::theoryOf for
      30                 :            : // (type-based) theoryOfMode. We expand and simplify it here for the sake of
      31                 :            : // efficiency.
      32                 :  268713218 : static TheoryId theoryOf(TNode node) {
      33         [ +  + ]:  268713218 :   if (node.getKind() == Kind::EQUAL)
      34                 :            :   {
      35                 :            :     // Equality is owned by the theory that owns the domain
      36                 :   45348597 :     return Theory::theoryOf(node[0].getType());
      37                 :            :   }
      38                 :            :   // Regular nodes are owned by the kind
      39                 :  223364621 :   return kindToTheoryId(node.getKind());
      40                 :            : }
      41                 :            : 
      42                 :            : /**
      43                 :            :  * TheoryEngine::rewrite() keeps a stack of things that are being pre-
      44                 :            :  * and post-rewritten.  Each element of the stack is a
      45                 :            :  * RewriteStackElement.
      46                 :            :  */
      47                 :            : struct RewriteStackElement {
      48                 :            :   /**
      49                 :            :    * Construct a fresh stack element.
      50                 :            :    */
      51                 :   57602935 :   RewriteStackElement(TNode node, TheoryId theoryId)
      52                 :   57602935 :       : d_node(node),
      53                 :   57602935 :         d_original(node),
      54                 :   57602935 :         d_theoryId(theoryId),
      55                 :   57602935 :         d_originalTheoryId(theoryId),
      56                 :   57602935 :         d_nextChild(0),
      57                 :   57602935 :         d_builder(node.getNodeManager())
      58                 :            :   {
      59                 :   57602935 :   }
      60                 :            : 
      61                 :  224159652 :   TheoryId getTheoryId() { return static_cast<TheoryId>(d_theoryId); }
      62                 :            : 
      63                 :   40777684 :   TheoryId getOriginalTheoryId()
      64                 :            :   {
      65                 :   40777684 :     return static_cast<TheoryId>(d_originalTheoryId);
      66                 :            :   }
      67                 :            : 
      68                 :            :   /** The node we're currently rewriting */
      69                 :            :   Node d_node;
      70                 :            :   /** Original node (either the unrewritten node or the node after prerewriting)
      71                 :            :    */
      72                 :            :   Node d_original;
      73                 :            :   /** Id of the theory that's currently rewriting this node */
      74                 :            :   unsigned d_theoryId : 8;
      75                 :            :   /** Id of the original theory that started the rewrite */
      76                 :            :   unsigned d_originalTheoryId : 8;
      77                 :            :   /** Index of the child this node is done rewriting */
      78                 :            :   unsigned d_nextChild : 32;
      79                 :            :   /** Builder for this node */
      80                 :            :   NodeBuilder d_builder;
      81                 :            : };
      82                 :            : 
      83                 :            : 
      84                 :   95029125 : Node Rewriter::rewrite(TNode node) {
      85         [ +  + ]:   95029125 :   if (node.getNumChildren() == 0)
      86                 :            :   {
      87                 :            :     // Nodes with zero children should never change via rewriting. We return
      88                 :            :     // eagerly for the sake of efficiency here.
      89                 :    9092244 :     return node;
      90                 :            :   }
      91                 :   85936881 :   return rewriteTo(theoryOf(node), node);
      92                 :            : }
      93                 :            : 
      94                 :     571046 : Node Rewriter::extendedRewrite(TNode node, bool aggr)
      95                 :            : {
      96                 :     571046 :   quantifiers::ExtendedRewriter er(d_nm, *this, aggr);
      97                 :    1142092 :   return er.extendedRewrite(node);
      98                 :     571046 : }
      99                 :            : 
     100                 :     323530 : TrustNode Rewriter::rewriteWithProof(TNode node,
     101                 :            :                                      bool isExtEq)
     102                 :            : {
     103                 :            :   // must set the proof checker before calling this
     104 [ -  + ][ -  + ]:     323530 :   Assert(d_tpg != nullptr);
                 [ -  - ]
     105         [ +  + ]:     323530 :   if (isExtEq)
     106                 :            :   {
     107                 :            :     // theory rewriter is responsible for rewriting the equality
     108                 :        856 :     TheoryRewriter* tr = d_theoryRewriters[theoryOf(node)];
     109 [ -  + ][ -  + ]:        856 :     Assert(tr != nullptr);
                 [ -  - ]
     110                 :        856 :     return tr->rewriteEqualityExtWithProof(node);
     111                 :            :   }
     112                 :     645348 :   Node ret = rewriteTo(theoryOf(node), node, d_tpg.get());
     113         [ +  - ]:     322674 :   return TrustNode::mkTrustRewrite(node, ret, d_tpg.get());
     114                 :     322674 : }
     115                 :            : 
     116                 :      19134 : void Rewriter::finishInit(Env& env)
     117                 :            : {
     118                 :            :   // if not already initialized with proof support
     119         [ +  - ]:      19134 :   if (d_tpg == nullptr)
     120                 :            :   {
     121         [ +  - ]:      19134 :     Trace("rewriter") << "Rewriter::finishInit" << std::endl;
     122                 :            :     // the rewriter is staticly determinstic, thus use static cache policy
     123                 :            :     // for the term conversion proof generator
     124                 :      38268 :     d_tpg.reset(new TConvProofGenerator(env,
     125                 :            :                                         nullptr,
     126                 :            :                                         TConvPolicy::FIXPOINT,
     127                 :            :                                         TConvCachePolicy::STATIC,
     128                 :      19134 :                                         "Rewriter::TConvProofGenerator"));
     129                 :            :   }
     130                 :      19134 : }
     131                 :            : 
     132                 :       2882 : Node Rewriter::rewriteEqualityExt(TNode node)
     133                 :            : {
     134 [ -  + ][ -  + ]:       2882 :   Assert(node.getKind() == Kind::EQUAL);
                 [ -  - ]
     135                 :            :   // note we don't force caching of this method currently
     136                 :       2882 :   return d_theoryRewriters[theoryOf(node)]->rewriteEqualityExt(node);
     137                 :            : }
     138                 :            : 
     139                 :     703700 : void Rewriter::registerTheoryRewriter(theory::TheoryId tid,
     140                 :            :                                       TheoryRewriter* trew)
     141                 :            : {
     142         [ +  + ]:     703700 :   if (trew == nullptr)
     143                 :            :   {
     144                 :            :     // if nullptr, use the default (null) theory rewriter.
     145                 :         20 :     d_nullTr.emplace_back(
     146                 :         40 :         std::unique_ptr<NoOpTheoryRewriter>(new NoOpTheoryRewriter(d_nm, tid)));
     147                 :         20 :     d_theoryRewriters[tid] = d_nullTr.back().get();
     148                 :            :   }
     149                 :            :   else
     150                 :            :   {
     151                 :     703680 :     d_theoryRewriters[tid] = trew;
     152                 :            :   }
     153                 :     703700 : }
     154                 :            : 
     155                 :    1455001 : TheoryRewriter* Rewriter::getTheoryRewriter(theory::TheoryId theoryId)
     156                 :            : {
     157                 :    1455001 :   return d_theoryRewriters[theoryId];
     158                 :            : }
     159                 :            : 
     160                 :      71960 : Node Rewriter::rewriteViaRule(ProofRewriteRule id, const Node& n)
     161                 :            : {
     162                 :            :   // dispatches to the appropriate theory
     163                 :      71960 :   TheoryId tid = theoryOf(n);
     164                 :      71960 :   TheoryRewriter* tr = getTheoryRewriter(tid);
     165         [ +  - ]:      71960 :   if (tr != nullptr)
     166                 :            :   {
     167                 :      71960 :     return tr->rewriteViaRule(id, n);
     168                 :            :   }
     169                 :          0 :   return Node::null();
     170                 :            : }
     171                 :            : 
     172                 :    1175754 : ProofRewriteRule Rewriter::findRule(const Node& a,
     173                 :            :                                     const Node& b,
     174                 :            :                                     TheoryRewriteCtx ctx)
     175                 :            : {
     176                 :            :   // dispatches to the appropriate theory
     177                 :    1175754 :   TheoryId tid = theoryOf(a);
     178                 :    1175754 :   TheoryRewriter* tr = getTheoryRewriter(tid);
     179         [ +  - ]:    1175754 :   if (tr != nullptr)
     180                 :            :   {
     181                 :    1175754 :     return tr->findRule(a, b, ctx);
     182                 :            :   }
     183                 :          0 :   return ProofRewriteRule::NONE;
     184                 :            : }
     185                 :            : 
     186                 :   88732345 : Node Rewriter::rewriteTo(theory::TheoryId theoryId,
     187                 :            :                          Node node,
     188                 :            :                          TConvProofGenerator* tcpg)
     189                 :            : {
     190                 :            : #ifdef CVC5_ASSERTIONS
     191                 :  177464690 :   bool isEquality = node.getKind() == Kind::EQUAL
     192                 :  110014327 :                     && !node[0].getType().isBoolean()
     193                 :  110014327 :                     && !node[1].getType().isBoolean();
     194                 :            : 
     195         [ +  + ]:   88732345 :   if (d_rewriteStack == nullptr)
     196                 :            :   {
     197                 :      36688 :     d_rewriteStack.reset(new std::unordered_set<Node>());
     198                 :            :   }
     199                 :            : #endif
     200                 :            : 
     201         [ +  - ]:   88732345 :   Trace("rewriter") << "Rewriter::rewriteTo(" << theoryId << "," << node << ")"<< std::endl;
     202                 :            : 
     203                 :            :   // Check if it's been cached already
     204                 :   88732345 :   Node cached = getPostRewriteCache(theoryId, node);
     205 [ +  + ][ +  + ]:   88732345 :   if (!cached.isNull() && (tcpg == nullptr || hasRewrittenWithProofs(node)))
         [ +  + ][ +  + ]
         [ +  + ][ -  - ]
     206                 :            :   {
     207                 :   74769509 :     return cached;
     208                 :            :   }
     209                 :            : 
     210                 :            :   // Put the node on the stack in order to start the "recursive" rewrite
     211                 :   13962836 :   vector<RewriteStackElement> rewriteStack;
     212                 :   13962836 :   rewriteStack.push_back(RewriteStackElement(node, theoryId));
     213                 :            : 
     214                 :            :   // Rewrite until the stack is empty
     215                 :            :   for (;;){
     216         [ +  - ]:  101243034 :     if (d_resourceManager != nullptr)
     217                 :            :     {
     218                 :  101243034 :       d_resourceManager->spendResource(Resource::RewriteStep);
     219                 :            :     }
     220                 :            : 
     221                 :            :     // Get the top of the recursion stack
     222                 :  101243034 :     RewriteStackElement& rewriteStackTop = rewriteStack.back();
     223                 :            : 
     224         [ +  - ]:  202486068 :     Trace("rewriter") << "Rewriter::rewriting: "
     225                 :  101243034 :                       << rewriteStackTop.getTheoryId() << ","
     226                 :  101243034 :                       << rewriteStackTop.d_node << std::endl;
     227                 :            : 
     228                 :            :     // Before rewriting children we need to do a pre-rewrite of the node
     229         [ +  + ]:  101243034 :     if (rewriteStackTop.d_nextChild == 0)
     230                 :            :     {
     231                 :            :       // Check if the pre-rewrite has already been done (it's in the cache)
     232                 :  115205870 :       cached = getPreRewriteCache(rewriteStackTop.getTheoryId(),
     233                 :  115205870 :                                   rewriteStackTop.d_node);
     234                 :  172808805 :       if (cached.isNull()
     235 [ +  + ][ +  + ]:   61067855 :           || (tcpg != nullptr
     236 [ +  + ][ +  + ]:   61067855 :               && !hasRewrittenWithProofs(rewriteStackTop.d_node)))
         [ +  + ][ -  - ]
     237                 :            :       {
     238                 :            :         // Rewrite until fix-point is reached
     239                 :            :         for(;;) {
     240                 :            :           // Perform the pre-rewrite
     241                 :   24772723 :           Kind originalKind = rewriteStackTop.d_node.getKind();
     242                 :            :           RewriteResponse response = preRewrite(
     243                 :   24772723 :               rewriteStackTop.getTheoryId(), rewriteStackTop.d_node, tcpg);
     244                 :            : 
     245                 :            :           // Put the rewritten node to the top of the stack
     246                 :   24772723 :           TNode newNode = response.d_node;
     247         [ +  - ]:   49545446 :           Trace("rewriter-debug") << "Pre-Rewrite: " << rewriteStackTop.d_node
     248                 :   24772723 :                                   << " to " << newNode << std::endl;
     249                 :   24772723 :           TheoryId newTheory = theoryOf(newNode);
     250                 :   24772723 :           rewriteStackTop.d_node = newNode;
     251                 :   24772723 :           rewriteStackTop.d_theoryId = newTheory;
     252 [ -  + ][ -  - ]:   49545446 :           Assert(newNode.getType().isComparableTo(
     253                 :            :               rewriteStackTop.d_node.getType()))
     254                 :   24772723 :               << "Pre-rewriting " << rewriteStackTop.d_node << " to " << newNode
     255                 :          0 :               << " does not preserve type";
     256                 :            :           // In the pre-rewrite, if changing theories, we just call the other
     257                 :            :           // theories pre-rewrite. If the kind of the node was changed, then we
     258                 :            :           // pre-rewrite again.
     259                 :   24772723 :           if ((originalKind == newNode.getKind()
     260         [ +  + ]:   21693065 :                && response.d_status == REWRITE_DONE)
     261 [ +  + ][ +  + ]:   46465788 :               || newNode.getNumChildren() == 0)
                 [ +  + ]
     262                 :            :           {
     263         [ +  - ]:   21345533 :             if (Configuration::isAssertionBuild())
     264                 :            :             {
     265                 :            :               // REWRITE_DONE should imply that no other pre-rewriting can be
     266                 :            :               // done.
     267                 :            :               Node rewrittenAgain =
     268                 :   42691066 :                   preRewrite(newTheory, newNode, nullptr).d_node;
     269                 :   21345533 :               Assert(newNode == rewrittenAgain)
     270 [ -  + ][ -  + ]:   21345533 :                   << "Rewriter returned REWRITE_DONE for " << newNode
                 [ -  - ]
     271                 :          0 :                   << " but it can be rewritten to " << rewrittenAgain;
     272                 :   21345533 :             }
     273                 :   21345533 :             break;
     274                 :            :           }
     275 [ +  + ][ +  + ]:   49545446 :         }
     276                 :            : 
     277                 :            :         // Cache the rewrite
     278                 :   21345533 :         setPreRewriteCache(rewriteStackTop.getOriginalTheoryId(),
     279                 :   21345533 :                            rewriteStackTop.d_original,
     280                 :   21345533 :                            rewriteStackTop.d_node);
     281                 :            :       }
     282                 :            :       // Otherwise we're have already been pre-rewritten (in pre-rewrite cache)
     283                 :            :       else {
     284                 :            :         // Continue with the cached version
     285                 :   36257402 :         rewriteStackTop.d_node = cached;
     286                 :   36257402 :         rewriteStackTop.d_theoryId = theoryOf(cached);
     287                 :            :       }
     288                 :            :     }
     289                 :            : 
     290                 :  101243034 :     rewriteStackTop.d_original = rewriteStackTop.d_node;
     291                 :            :     // Now it's time to rewrite the children, check if this has already been done
     292                 :  202486068 :     cached = getPostRewriteCache(rewriteStackTop.getTheoryId(),
     293                 :  202486068 :                                  rewriteStackTop.d_node);
     294                 :            :     // If not, go through the children
     295                 :  303729102 :     if (cached.isNull()
     296 [ +  + ][ +  + ]:  101243034 :         || (tcpg != nullptr && !hasRewrittenWithProofs(rewriteStackTop.d_node)))
         [ +  + ][ +  + ]
         [ +  + ][ -  - ]
     297                 :            :     {
     298                 :            :       // The child we need to rewrite
     299                 :   63072250 :       unsigned child = rewriteStackTop.d_nextChild++;
     300                 :            : 
     301                 :            :       // To build the rewritten expression we set up the builder
     302         [ +  + ]:   63072250 :       if(child == 0) {
     303         [ +  + ]:   19432151 :         if (rewriteStackTop.d_node.getNumChildren() > 0)
     304                 :            :         {
     305                 :            :           // The children will add themselves to the builder once they're done
     306                 :   18370166 :           rewriteStackTop.d_builder << rewriteStackTop.d_node.getKind();
     307                 :   18370166 :           kind::MetaKind metaKind = rewriteStackTop.d_node.getMetaKind();
     308         [ +  + ]:   18370166 :           if (metaKind == kind::metakind::PARAMETERIZED) {
     309                 :    1272521 :             rewriteStackTop.d_builder << rewriteStackTop.d_node.getOperator();
     310                 :            :           }
     311                 :            :         }
     312                 :            :       }
     313                 :            : 
     314                 :            :       // Process the next child
     315         [ +  + ]:   63072250 :       if (child < rewriteStackTop.d_node.getNumChildren())
     316                 :            :       {
     317                 :            :         // The child node
     318                 :   43640099 :         Node childNode = rewriteStackTop.d_node[child];
     319                 :            :         // Push the rewrite request to the stack (NOTE: rewriteStackTop might be a bad reference now)
     320                 :   43640099 :         rewriteStack.push_back(RewriteStackElement(childNode, theoryOf(childNode)));
     321                 :            :         // Go on with the rewriting
     322                 :   43640099 :         continue;
     323                 :   43640099 :       }
     324                 :            : 
     325                 :            :       // Incorporate the children if necessary
     326         [ +  + ]:   19432151 :       if (rewriteStackTop.d_node.getNumChildren() > 0)
     327                 :            :       {
     328                 :   18370166 :         Node rewritten = rewriteStackTop.d_builder;
     329                 :   18370166 :         rewriteStackTop.d_node = rewritten;
     330                 :   18370166 :         rewriteStackTop.d_theoryId = theoryOf(rewriteStackTop.d_node);
     331                 :   18370166 :       }
     332                 :            : 
     333                 :            :       // Done with all pre-rewriting, so let's do the post rewrite
     334                 :            :       for(;;) {
     335                 :            :         // Do the post-rewrite
     336                 :   19991037 :         Kind originalKind = rewriteStackTop.d_node.getKind();
     337                 :            :         RewriteResponse response = postRewrite(
     338                 :   19991037 :             rewriteStackTop.getTheoryId(), rewriteStackTop.d_node, tcpg);
     339                 :            :         // We continue with the response we got
     340                 :   19991037 :         TNode newNode = response.d_node;
     341         [ +  - ]:   39982074 :         Trace("rewriter-debug") << "Post-Rewrite: " << rewriteStackTop.d_node
     342                 :   19991037 :                                 << " to " << newNode << std::endl;
     343                 :   19991037 :         TheoryId newTheoryId = theoryOf(newNode);
     344 [ -  + ][ -  - ]:   39982074 :         Assert(
     345                 :            :             newNode.getType().isComparableTo(rewriteStackTop.d_node.getType()))
     346                 :   19991037 :             << "Post-rewriting " << rewriteStackTop.d_node << " to " << newNode
     347                 :          0 :             << " does not preserve type";
     348                 :   19991037 :         if (newTheoryId != rewriteStackTop.getTheoryId()
     349 [ +  + ][ +  + ]:   19991037 :             || response.d_status == REWRITE_AGAIN_FULL)
                 [ +  + ]
     350                 :            :         {
     351                 :            :           // In the post rewrite if we've changed theories, we must do a full rewrite
     352 [ -  + ][ -  + ]:    2472790 :           Assert(response.d_node != rewriteStackTop.d_node);
                 [ -  - ]
     353                 :            :           //TODO: this is not thread-safe - should make this assertion dependent on sequential build
     354                 :            : #ifdef CVC5_ASSERTIONS
     355                 :    2472790 :           Assert(d_rewriteStack->find(response.d_node) == d_rewriteStack->end())
     356                 :          0 :               << "Non-terminating rewriting detected for: " << response.d_node;
     357                 :    2472790 :           d_rewriteStack->insert(response.d_node);
     358                 :            : #endif
     359                 :    2472790 :           Node rewritten = rewriteTo(newTheoryId, response.d_node, tcpg);
     360                 :    2472790 :           rewriteStackTop.d_node = rewritten;
     361                 :            : #ifdef CVC5_ASSERTIONS
     362                 :    2472790 :           d_rewriteStack->erase(response.d_node);
     363                 :            : #endif
     364                 :    2472790 :           break;
     365                 :    2472790 :         }
     366                 :   35036494 :         else if ((response.d_status == REWRITE_DONE
     367         [ +  + ]:   17059726 :                   && originalKind == newNode.getKind())
     368 [ +  + ][ +  + ]:   34577973 :                  || newNode.getNumChildren() == 0)
                 [ +  + ]
     369                 :            :         {
     370                 :            : #ifdef CVC5_ASSERTIONS
     371                 :            :           RewriteResponse r2 =
     372                 :   16959361 :               d_theoryRewriters[newTheoryId]->postRewrite(newNode);
     373                 :   16959361 :           Assert(r2.d_node == newNode)
     374 [ -  + ][ -  + ]:   16959361 :               << "Non-idempotent rewriting: " << r2.d_node << " != " << newNode;
                 [ -  - ]
     375                 :            : #endif
     376                 :   16959361 :           rewriteStackTop.d_node = newNode;
     377                 :   16959361 :           break;
     378                 :   16959361 :         }
     379                 :            :         // Check for trivial rewrite loops of size 1 or 2
     380 [ -  + ][ -  + ]:     558886 :         Assert(response.d_node != rewriteStackTop.d_node);
                 [ -  - ]
     381 [ -  + ][ -  + ]:     558886 :         Assert(d_theoryRewriters[rewriteStackTop.getTheoryId()]
                 [ -  - ]
     382                 :            :                    ->postRewrite(response.d_node)
     383                 :            :                    .d_node
     384                 :            :                != rewriteStackTop.d_node);
     385                 :     558886 :         rewriteStackTop.d_node = response.d_node;
     386 [ +  + ][ +  + ]:   39982074 :       }
     387                 :            : 
     388                 :            :       // We're done with the post rewrite, so we add to the cache
     389         [ +  + ]:   19432151 :       if (tcpg != nullptr)
     390                 :            :       {
     391                 :            :         // if proofs are enabled, mark that we've rewritten with proofs
     392                 :    1538318 :         d_tpgNodes.insert(rewriteStackTop.d_original);
     393         [ +  + ]:    1538318 :         if (!cached.isNull())
     394                 :            :         {
     395                 :            :           // We may have gotten a different node, due to non-determinism in
     396                 :            :           // theory rewriters (e.g. quantifiers rewriter which introduces
     397                 :            :           // fresh BOUND_VARIABLE). This can happen if we wrote once without
     398                 :            :           // proofs and then rewrote again with proofs.
     399         [ -  + ]:    1459611 :           if (rewriteStackTop.d_node != cached)
     400                 :            :           {
     401         [ -  - ]:          0 :             Trace("rewriter-proof") << "WARNING: Rewritten forms with and "
     402                 :          0 :                                        "without proofs were not equivalent"
     403                 :          0 :                                     << std::endl;
     404         [ -  - ]:          0 :             Trace("rewriter-proof")
     405                 :          0 :                 << "   original: " << rewriteStackTop.d_original << std::endl;
     406         [ -  - ]:          0 :             Trace("rewriter-proof")
     407                 :          0 :                 << "with proofs: " << rewriteStackTop.d_node << std::endl;
     408         [ -  - ]:          0 :             Trace("rewriter-proof") << " w/o proofs: " << cached << std::endl;
     409                 :          0 :             Node eq = rewriteStackTop.d_node.eqNode(cached);
     410                 :            :             // we make this a post-rewrite, since we are processing a node that
     411                 :            :             // has finished post-rewriting above
     412                 :          0 :             Node trrid = mkTrustId(d_nm, TrustId::REWRITE_NO_ELABORATE);
     413                 :          0 :             tcpg->addRewriteStep(rewriteStackTop.d_node,
     414                 :            :                                  cached,
     415                 :            :                                  ProofRule::TRUST,
     416                 :            :                                  {},
     417                 :            :                                  {trrid, eq},
     418                 :            :                                  false);
     419                 :            :             // don't overwrite the cache, should be the same
     420                 :          0 :             rewriteStackTop.d_node = cached;
     421                 :          0 :           }
     422                 :            :         }
     423                 :            :       }
     424                 :   19432151 :       setPostRewriteCache(rewriteStackTop.getOriginalTheoryId(),
     425                 :   19432151 :                           rewriteStackTop.d_original,
     426                 :   19432151 :                           rewriteStackTop.d_node);
     427                 :            :     }
     428                 :            :     else
     429                 :            :     {
     430                 :            :       // We were already in cache, so just remember it
     431                 :   38170784 :       rewriteStackTop.d_node = cached;
     432                 :   38170784 :       rewriteStackTop.d_theoryId = theoryOf(cached);
     433                 :            :     }
     434                 :            : 
     435                 :            :     // If this is the last node, just return
     436         [ +  + ]:   57602935 :     if (rewriteStack.size() == 1) {
     437 [ +  + ][ +  + ]:   13962836 :       Assert(!isEquality || rewriteStackTop.d_node.getKind() == Kind::EQUAL
         [ +  + ][ +  - ]
         [ -  + ][ -  + ]
                 [ -  - ]
     438                 :            :              || rewriteStackTop.d_node.isConst());
     439 [ -  + ][ -  - ]:   27925672 :       Assert(rewriteStackTop.d_node.getType().isComparableTo(node.getType()))
     440                 :   13962836 :           << "Rewriting " << node << " to " << rewriteStackTop.d_node
     441                 :          0 :           << " does not preserve type";
     442                 :   13962836 :       return rewriteStackTop.d_node;
     443                 :            :     }
     444                 :            : 
     445                 :            :     // We're done with this node, append it to the parent
     446                 :   43640099 :     rewriteStack[rewriteStack.size() - 2].d_builder << rewriteStackTop.d_node;
     447                 :   43640099 :     rewriteStack.pop_back();
     448                 :   87280198 :   }
     449                 :            : 
     450                 :            :   Unreachable();
     451                 :   88732345 : } /* Rewriter::rewriteTo() */
     452                 :            : 
     453                 :   46118256 : RewriteResponse Rewriter::preRewrite(theory::TheoryId theoryId,
     454                 :            :                                      TNode n,
     455                 :            :                                      TConvProofGenerator* tcpg)
     456                 :            : {
     457         [ +  + ]:   46118256 :   if (tcpg != nullptr)
     458                 :            :   {
     459                 :            :     // call the trust rewrite response interface
     460                 :            :     TrustRewriteResponse tresponse =
     461                 :    2170430 :         d_theoryRewriters[theoryId]->preRewriteWithProof(n);
     462                 :            :     // process the trust rewrite response: store the proof step into
     463                 :            :     // tcpg if necessary and then convert to rewrite response.
     464                 :    2170430 :     return processTrustRewriteResponse(theoryId, tresponse, true, tcpg);
     465                 :    2170430 :   }
     466                 :   43947826 :   return d_theoryRewriters[theoryId]->preRewrite(n);
     467                 :            : }
     468                 :            : 
     469                 :   19991037 : RewriteResponse Rewriter::postRewrite(theory::TheoryId theoryId,
     470                 :            :                                       TNode n,
     471                 :            :                                       TConvProofGenerator* tcpg)
     472                 :            : {
     473         [ +  + ]:   19991037 :   if (tcpg != nullptr)
     474                 :            :   {
     475                 :            :     // same as above, for post-rewrite
     476                 :            :     TrustRewriteResponse tresponse =
     477                 :    1594956 :         d_theoryRewriters[theoryId]->postRewriteWithProof(n);
     478                 :    1594956 :     return processTrustRewriteResponse(theoryId, tresponse, false, tcpg);
     479                 :    1594956 :   }
     480                 :   18396081 :   return d_theoryRewriters[theoryId]->postRewrite(n);
     481                 :            : }
     482                 :            : 
     483                 :    3765386 : RewriteResponse Rewriter::processTrustRewriteResponse(
     484                 :            :     theory::TheoryId theoryId,
     485                 :            :     const TrustRewriteResponse& tresponse,
     486                 :            :     bool isPre,
     487                 :            :     TConvProofGenerator* tcpg)
     488                 :            : {
     489 [ -  + ][ -  + ]:    3765386 :   Assert(tcpg != nullptr);
                 [ -  - ]
     490                 :    3765386 :   TrustNode trn = tresponse.d_node;
     491 [ -  + ][ -  + ]:    3765386 :   Assert(trn.getKind() == TrustNodeKind::REWRITE);
                 [ -  - ]
     492                 :    3765386 :   Node proven = trn.getProven();
     493         [ +  + ]:    3765386 :   if (proven[0] != proven[1])
     494                 :            :   {
     495                 :    1038839 :     ProofGenerator* pg = trn.getGenerator();
     496         [ +  - ]:    1038839 :     if (pg == nullptr)
     497                 :            :     {
     498                 :            :       Node tidn =
     499                 :    1038839 :           builtin::BuiltinProofRuleChecker::mkTheoryIdNode(d_nm, theoryId);
     500                 :            :       // add small step trusted rewrite
     501                 :            :       Node rid = mkMethodId(d_nm,
     502                 :            :                             isPre ? MethodId::RW_REWRITE_THEORY_PRE
     503         [ +  + ]:    1038839 :                                   : MethodId::RW_REWRITE_THEORY_POST);
     504 [ +  + ][ -  - ]:    4155356 :       tcpg->addRewriteStep(proven[0],
     505                 :            :                            proven[1],
     506                 :            :                            ProofRule::TRUST_THEORY_REWRITE,
     507                 :            :                            {},
     508                 :            :                            {proven, tidn, rid},
     509                 :            :                            isPre);
     510                 :    1038839 :     }
     511                 :            :     else
     512                 :            :     {
     513                 :            :       // store proven rewrite step
     514                 :          0 :       tcpg->addRewriteStep(proven[0], proven[1], pg, isPre);
     515                 :            :     }
     516                 :            :   }
     517                 :   11296158 :   return RewriteResponse(tresponse.d_status, trn.getNode());
     518                 :    3765386 : }
     519                 :            : 
     520                 :   10291912 : bool Rewriter::hasRewrittenWithProofs(TNode n) const
     521                 :            : {
     522                 :   10291912 :   return d_tpgNodes.find(n) != d_tpgNodes.end();
     523                 :            : }
     524                 :            : 
     525                 :            : }  // namespace theory
     526                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14