LCOV - code coverage report
Current view: top level - data/include/mcrl2/data/rewriters - if_rewriter.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 0 94 0.0 %
Date: 2024-04-26 03:18:02 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Wieger Wesselink
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : /// \file mcrl2/data/rewriters/if_rewriter.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_DATA_REWRITERS_IF_REWRITER_H
      13             : #define MCRL2_DATA_REWRITERS_IF_REWRITER_H
      14             : 
      15             : #include "mcrl2/data/rewriter.h"
      16             : #include "mcrl2/data/builder.h"
      17             : #include "mcrl2/data/consistency.h"
      18             : #include "mcrl2/data/standard.h"
      19             : 
      20             : namespace mcrl2 {
      21             : 
      22             : namespace data {
      23             : 
      24             : namespace detail {
      25             : 
      26             : // Returns f(x0, ..., x_i-1, y, x_i+1, ..., xn)
      27             : inline
      28           0 : application replace_argument(const application& x, std::size_t i, const data_expression& y)
      29             : {
      30           0 :   std::size_t j = 0;
      31           0 :   return application(x.head(), x.begin(), x.end(), [&](const data_expression& x_i) { return (j++ == i+1) ? y : x_i; });
      32             : }
      33             : 
      34             : inline
      35           0 : data_expression push_if_outside(const application& x)
      36             : {
      37           0 :   for (std::size_t i = 0; i < x.size(); i++)
      38             :   {
      39           0 :     if (is_if_application(x[i]))
      40             :     {
      41           0 :       const auto& x_i = atermpp::down_cast<application>(x[i]);
      42           0 :       const data_expression& b = x_i[0];
      43           0 :       const data_expression& t1 = x_i[1];
      44           0 :       const data_expression& t2 = x_i[2];
      45           0 :       return if_(b, push_if_outside(replace_argument(x, i, t1)), push_if_outside(replace_argument(x, i, t2)));
      46             :     }
      47             :   }
      48           0 :   return x;
      49             : }
      50             : 
      51             : template <typename Derived>
      52             : struct if_rewrite_builder: public data_expression_builder<Derived>
      53             : {
      54             :   typedef data_expression_builder<Derived> super;
      55             : 
      56             :   using super::apply;
      57             : 
      58           0 :   bool is_simple(const data_expression& x) const
      59             :   {
      60           0 :     return !is_and(x) && !is_or(x) && !is_imp(x) && !is_not(x) && !is_true(x) && !is_false(x);
      61             :   }
      62             : 
      63           0 :   data_expression apply_if(const data_expression& b, const data_expression& t1, const data_expression& t2)
      64             :   {
      65           0 :     if (is_true(b))
      66             :     {
      67           0 :       return t1;
      68             :     }
      69           0 :     else if (is_false(b))
      70             :     {
      71           0 :       return t2;
      72             :     }
      73           0 :     else if (is_and(b))
      74             :     {
      75           0 :       const data_expression& b1 = binary_left1(b);
      76           0 :       const data_expression& b2 = binary_right1(b);
      77           0 :       return if_(b1, if_(b2, t1, t2), t2);
      78             :     }
      79           0 :     else if (is_or(b))
      80             :     {
      81           0 :       const data_expression& b1 = binary_left1(b);
      82           0 :       const data_expression& b2 = binary_right1(b);
      83           0 :       return if_(b1, t1, if_(b2, t1, t2));
      84             :     }
      85           0 :     else if (is_imp(b))
      86             :     {
      87           0 :       const data_expression& b1 = binary_left1(b);
      88           0 :       const data_expression& b2 = binary_right1(b);
      89           0 :       return if_(b1, if_(b2, t1, t2), t1);
      90             :     }
      91           0 :     else if (is_not(b))
      92             :     {
      93           0 :       const data_expression& b1 = unary_operand1(b);
      94           0 :       return if_(b1, t2, t1);
      95             :     }
      96             :     else
      97             :     {
      98           0 :       assert(is_simple(b));
      99           0 :       if (t1 == t2)
     100             :       {
     101           0 :         return t1;
     102             :       }
     103           0 :       else if (is_if_application(t1))
     104             :       {
     105           0 :         const application& t1_ = atermpp::down_cast<application>(t1);
     106           0 :         const data_expression& c = t1_[0];
     107           0 :         const data_expression& u1 = t1_[1];
     108           0 :         const data_expression& u2 = t1_[2];
     109           0 :         if (b == c)
     110             :         {
     111           0 :           return apply_if(b, u1, t2);
     112             :         }
     113           0 :         else if (b > c) // use the aterm pointer comparison
     114             :         {
     115           0 :           assert(is_simple(c));
     116           0 :           return apply_if(c, apply_if(b, u1, t2), apply_if(b, u2, t2));
     117             :         }
     118             :         else
     119             :         {
     120           0 :           return if_(b, t1, t2);
     121             :         }
     122             :       }
     123           0 :       else if (is_if_application(t2))
     124             :       {
     125           0 :         const application& t2_ = atermpp::down_cast<application>(t2);
     126           0 :         const data_expression& c = t2_[0];
     127           0 :         const data_expression& u1 = t2_[1];
     128           0 :         const data_expression& u2 = t2_[2];
     129           0 :         if (b == c)
     130             :         {
     131           0 :           return apply_if(b, t1, u2);
     132             :         }
     133           0 :         else if (b > c) // use the aterm pointer comparison
     134             :         {
     135           0 :           assert(is_simple(c));
     136           0 :           return apply_if(c, apply_if(b, t1, u1), apply_if(b, t1, u2));
     137             :         }
     138             :         else
     139             :         {
     140           0 :           return if_(b, t1, t2);
     141             :         }
     142             :       }
     143             :       else
     144             :       {
     145           0 :         return if_(b, t1, t2);
     146             :       }
     147             :     }
     148             :   }
     149             : 
     150             :   template <class T>
     151           0 :   void apply(T& result, const application& x)
     152             :   {
     153           0 :     if (is_if_application(x))
     154             :     {
     155           0 :       data_expression b;
     156           0 :       super::apply(b, x[0]);
     157           0 :       data_expression t1;
     158           0 :       super::apply(t1, x[1]);
     159           0 :       data_expression t2;
     160           0 :       super::apply(t2, x[2]);
     161           0 :       result = apply_if(b, t1, t2);
     162           0 :     }
     163             :     else
     164             :     {
     165           0 :       super::apply(result, x);
     166           0 :       result = push_if_outside(atermpp::down_cast<application>(result));
     167             :     }
     168           0 :   }
     169             : };
     170             : 
     171             : struct if_rewrite_with_rewriter_builder: public if_rewrite_builder<if_rewrite_with_rewriter_builder>
     172             : {
     173             :   typedef if_rewrite_builder<if_rewrite_with_rewriter_builder> super;
     174             :   using super::apply;
     175             :   using super::apply_if;
     176             : 
     177             :   data::rewriter& rewr;
     178             : 
     179           0 :   explicit if_rewrite_with_rewriter_builder(data::rewriter& rewr_) : rewr(rewr_)
     180           0 :   {}
     181             : 
     182             :   template <class T>
     183           0 :   void apply(T& result, const application& x)
     184             :   {
     185           0 :     if (is_if_application(x))
     186             :     {
     187           0 :       data_expression b; 
     188           0 :       super::apply(b, x[0]);
     189           0 :       data_expression t1;
     190           0 :       super::apply(t1, x[1]);
     191           0 :       data_expression t2;
     192           0 :       super::apply(t2, x[2]);
     193           0 :       result = apply_if(b, t1, t2);
     194           0 :     }
     195             :     else
     196             :     {
     197           0 :       super::apply(result, x);
     198           0 :       result = push_if_outside(atermpp::down_cast<application>(result));
     199             :     }
     200           0 :     result = rewr(result);
     201           0 :   }
     202             : };
     203             : 
     204             : } // namespace detail
     205             : 
     206             : struct if_rewriter
     207             : {
     208             :   using argument_type = data_expression;
     209             :   using result_type = data_expression;
     210             : 
     211           0 :   data_expression operator()(const data_expression& x) const
     212             :   {
     213           0 :     data_expression result;
     214           0 :     core::make_apply_builder<detail::if_rewrite_builder>().apply(result, x);
     215           0 :     return result;
     216           0 :   }
     217             : };
     218             : 
     219             : template <typename T>
     220             : void if_rewrite(T& x, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value>::type* = 0)
     221             : {
     222             :   core::make_update_apply_builder<data::data_expression_builder>(if_rewriter()).update(x);
     223             : }
     224             : 
     225             : template <typename T>
     226             : T if_rewrite(const T& x, typename std::enable_if< std::is_base_of< atermpp::aterm, T >::value>::type* = 0)
     227             : {
     228             :   T result;
     229             :   core::make_update_apply_builder<data::data_expression_builder>(if_rewriter()).apply(result, x);
     230             :   return result;
     231             : }
     232             : 
     233             : } // namespace data
     234             : 
     235             : } // namespace mcrl2
     236             : 
     237             : #endif // MCRL2_DATA_REWRITERS_IF_REWRITER_H

Generated by: LCOV version 1.14