LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/preprocessing/passes - nl_ext_purify.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 56 69.6 %
Date: 2024-09-09 12:04:23 Functions: 3 3 100.0 %
Branches: 30 50 60.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Haniel Barbosa, Andrew Reynolds, Mathias Preiner
       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                 :            :  * The NlExtPurify preprocessing pass.
      14                 :            :  *
      15                 :            :  * Purifies non-linear terms.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "preprocessing/passes/nl_ext_purify.h"
      19                 :            : 
      20                 :            : #include "expr/skolem_manager.h"
      21                 :            : #include "preprocessing/assertion_pipeline.h"
      22                 :            : #include "theory/rewriter.h"
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : namespace preprocessing {
      26                 :            : namespace passes {
      27                 :            : 
      28                 :            : using namespace std;
      29                 :            : using namespace cvc5::internal::theory;
      30                 :            : 
      31                 :       2944 : Node NlExtPurify::purifyNlTerms(TNode n,
      32                 :            :                                 NodeMap& cache,
      33                 :            :                                 NodeMap& bcache,
      34                 :            :                                 std::vector<Node>& var_eq,
      35                 :            :                                 bool beneathMult)
      36                 :            : {
      37                 :       2944 :   NodeManager* nm = nodeManager();
      38                 :       2944 :   SkolemManager* sm = nm->getSkolemManager();
      39         [ +  + ]:       2944 :   if (beneathMult)
      40                 :            :   {
      41                 :       2294 :     NodeMap::iterator find = bcache.find(n);
      42         [ +  + ]:       2294 :     if (find != bcache.end())
      43                 :            :     {
      44                 :       2170 :       return (*find).second;
      45                 :            :     }
      46                 :            :   }
      47                 :            :   else
      48                 :            :   {
      49                 :        650 :     NodeMap::iterator find = cache.find(n);
      50         [ +  + ]:        650 :     if (find != cache.end())
      51                 :            :     {
      52                 :        462 :       return (*find).second;
      53                 :            :     }
      54                 :            :   }
      55         [ -  + ]:        312 :   if (n.isClosure())
      56                 :            :   {
      57                 :            :     // don't traverse quantified formulas
      58                 :          0 :     return n;
      59                 :            :   }
      60                 :        624 :   Node ret = n;
      61         [ +  + ]:        312 :   if (n.getNumChildren() > 0)
      62                 :            :   {
      63 [ +  + ][ +  - ]:        238 :     if (beneathMult && (n.getKind() == Kind::ADD || n.getKind() == Kind::SUB))
         [ -  + ][ -  + ]
      64                 :            :     {
      65                 :            :       // don't do it if it rewrites to a constant
      66                 :          0 :       Node nr = rewrite(n);
      67         [ -  - ]:          0 :       if (nr.isConst())
      68                 :            :       {
      69                 :            :         // return the rewritten constant
      70                 :          0 :         ret = nr;
      71                 :            :       }
      72                 :            :       else
      73                 :            :       {
      74                 :            :         // new variable
      75                 :          0 :         ret = sm->mkDummySkolem("__purifyNl_var",
      76                 :          0 :                                 n.getType(),
      77                 :          0 :                                 "Variable introduced in purifyNl pass");
      78                 :          0 :         Node np = purifyNlTerms(n, cache, bcache, var_eq, false);
      79                 :          0 :         var_eq.push_back(np.eqNode(ret));
      80         [ -  - ]:          0 :         Trace("nl-ext-purify") << "Purify : " << ret << " -> " << np
      81                 :          0 :                                << std::endl;
      82                 :            :       }
      83                 :            :     }
      84                 :            :     else
      85                 :            :     {
      86 [ +  + ][ +  + ]:        238 :       bool beneathMultNew = beneathMult || n.getKind() == Kind::MULT;
      87                 :        238 :       bool childChanged = false;
      88                 :        476 :       std::vector<Node> children;
      89         [ +  + ]:       2832 :       for (unsigned i = 0, size = n.getNumChildren(); i < size; ++i)
      90                 :            :       {
      91                 :       5188 :         Node nc = purifyNlTerms(n[i], cache, bcache, var_eq, beneathMultNew);
      92 [ +  - ][ -  + ]:       2594 :         childChanged = childChanged || nc != n[i];
         [ +  - ][ -  - ]
      93                 :       2594 :         children.push_back(nc);
      94                 :            :       }
      95         [ -  + ]:        238 :       if (childChanged)
      96                 :            :       {
      97                 :          0 :         ret = nm->mkNode(n.getKind(), children);
      98                 :            :       }
      99                 :            :     }
     100                 :            :   }
     101         [ +  + ]:        312 :   if (beneathMult)
     102                 :            :   {
     103                 :        124 :     bcache[n] = ret;
     104                 :            :   }
     105                 :            :   else
     106                 :            :   {
     107                 :        188 :     cache[n] = ret;
     108                 :            :   }
     109                 :        312 :   return ret;
     110                 :            : }
     111                 :            : 
     112                 :      48195 : NlExtPurify::NlExtPurify(PreprocessingPassContext* preprocContext)
     113                 :      48195 :     : PreprocessingPass(preprocContext, "nl-ext-purify"){};
     114                 :            : 
     115                 :         10 : PreprocessingPassResult NlExtPurify::applyInternal(
     116                 :            :     AssertionPipeline* assertionsToPreprocess)
     117                 :            : {
     118                 :         20 :   unordered_map<Node, Node> cache;
     119                 :         20 :   unordered_map<Node, Node> bcache;
     120                 :         10 :   std::vector<Node> var_eq;
     121                 :         10 :   unsigned size = assertionsToPreprocess->size();
     122         [ +  + ]:        360 :   for (unsigned i = 0; i < size; ++i)
     123                 :            :   {
     124                 :        700 :     Node a = (*assertionsToPreprocess)[i];
     125                 :        700 :     Node ap = purifyNlTerms(a, cache, bcache, var_eq);
     126         [ -  + ]:        350 :     if (a != ap)
     127                 :            :     {
     128                 :          0 :       assertionsToPreprocess->replace(i, ap);
     129         [ -  - ]:          0 :       Trace("nl-ext-purify")
     130                 :          0 :           << "Purify : " << a << " -> " << (*assertionsToPreprocess)[i] << "\n";
     131                 :            :     }
     132                 :            :   }
     133         [ -  + ]:         10 :   if (!var_eq.empty())
     134                 :            :   {
     135         [ -  - ]:          0 :     for (const Node& ve : var_eq)
     136                 :            :     {
     137                 :          0 :       assertionsToPreprocess->push_back(ve);
     138                 :            :     }
     139                 :            :   }
     140                 :         20 :   return PreprocessingPassResult::NO_CONFLICT;
     141                 :            : }
     142                 :            : 
     143                 :            : 
     144                 :            : }  // namespace passes
     145                 :            : }  // namespace preprocessing
     146                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14