LCOV - code coverage report
Current view: top level - data/include/mcrl2/data - rewriter.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 50 59 84.7 %
Date: 2024-04-19 03:43:27 Functions: 17 22 77.3 %
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/rewriter.h
      10             : /// \brief The class rewriter.
      11             : 
      12             : #ifndef MCRL2_DATA_REWRITER_H
      13             : #define MCRL2_DATA_REWRITER_H
      14             : 
      15             : #include "mcrl2/atermpp/detail/aterm_configuration.h"
      16             : #include "mcrl2/data/detail/rewrite.h"
      17             : #include "mcrl2/data/expression_traits.h"
      18             : 
      19             : namespace mcrl2
      20             : {
      21             : 
      22             : namespace data
      23             : {
      24             : 
      25             : /// \brief Rewriter class for the mCRL2 Library. It only works for terms of type data_expression
      26             : /// and data_expression_with_variables.
      27             : template < typename Term >
      28             : class basic_rewriter
      29             : {
      30             :   public:
      31             :     /// \brief The type for the substitution that is used internally.
      32             :     typedef data::mutable_indexed_substitution<> substitution_type;
      33             : 
      34             :   protected:
      35             :     /// \brief The wrapped Rewriter.
      36             :     std::shared_ptr<detail::Rewriter> m_rewriter;
      37             : 
      38             :   public:
      39             : 
      40             :     /// \brief The type for expressions manipulated by the rewriter.
      41             :     typedef Term term_type;
      42             : 
      43             :     /// \brief The rewrite strategies of the rewriter.
      44             :     typedef rewrite_strategy strategy;
      45             : 
      46             :   protected:
      47             : 
      48             :     /// \brief Constructor.
      49             :     /// \param[in] r A rewriter
      50           0 :     explicit basic_rewriter(const std::shared_ptr<detail::Rewriter>& r) :
      51           0 :       m_rewriter(r)
      52           0 :     {}
      53             : 
      54             :     /// \brief Copy Constructor
      55        6651 :     basic_rewriter(const basic_rewriter& other)=default;
      56             : 
      57             :     /// \brief Assignment operator
      58          25 :     basic_rewriter& operator=(const basic_rewriter& other)=default;
      59             : 
      60             :     /// \brief Constructor.
      61             :     /// \param[in] d A data specification
      62             :     /// \param[in] s A rewriter strategy.
      63        1751 :     explicit basic_rewriter(const data_specification& d, const strategy s = jitty) :
      64        1751 :       m_rewriter(detail::createRewriter(d, used_data_equation_selector(d), static_cast< rewrite_strategy >(s)))
      65        1751 :     { }
      66             : 
      67             :     /// \brief Constructor.
      68          50 :     basic_rewriter(const data_specification& d, const used_data_equation_selector& equation_selector, const strategy s = jitty) :
      69          50 :       m_rewriter(detail::createRewriter(d, equation_selector, static_cast< rewrite_strategy >(s)))
      70          50 :     {}
      71             : 
      72             : };
      73             : 
      74             : /// \brief Rewriter that operates on data expressions.
      75             : //
      76             : /// \attention As long as normalisation of sorts remains necessary, the data
      77             : /// specification object used for construction *must* exist during the
      78             : /// lifetime of the rewriter object.
      79             : 
      80             : class rewriter: public basic_rewriter<data_expression>
      81             : {
      82             :   protected:
      83             :     // cache the empty substitution, since it is expensive to construct
      84       88648 :     static substitution_type& empty_substitution()
      85             :     {
      86             : #ifdef MCRL2_ENABLE_MULTITHREADING 
      87             :       static_assert(mcrl2::utilities::detail::GlobalThreadSafe);
      88       88648 :       thread_local substitution_type result;
      89             : #else
      90             :       static_assert(!mcrl2::utilities::detail::GlobalThreadSafe);
      91             :       static substitution_type result;
      92             : #endif
      93       88648 :       assert(result.empty());    // This static substitution should always become empty again after use.
      94       88648 :       return result;
      95             :     }
      96             : 
      97             :     /// \brief Default specification used if no specification is specified at construction
      98          12 :     static const data_specification& default_specification()
      99             :     {
     100          12 :       static data_specification specification;
     101          12 :       return specification;
     102             :     }
     103             : 
     104             :     /// \brief Constructor for internal use.
     105             :     /// \param[in] r A rewriter
     106           0 :     explicit rewriter(const std::shared_ptr<detail::Rewriter>& r) :
     107           0 :       basic_rewriter(r)
     108           0 :     {}
     109             : 
     110             : #ifdef MCRL2_COUNT_DATA_REWRITE_CALLS
     111             :     mutable std::size_t rewrite_calls = 0;
     112             : #endif
     113             : 
     114             :   public:
     115             :     typedef basic_rewriter<data_expression>::substitution_type substitution_type;
     116             : 
     117             :     /// \brief Constructor.
     118             :     /// \param[in] r a rewriter.
     119        6651 :     rewriter(const rewriter& r) = default;
     120             : 
     121             :     /// \brief Constructor.
     122             :     /// \param[in] d A data specification
     123             :     /// \param[in] s A rewriter strategy.
     124        1751 :     explicit rewriter(const data_specification& d = rewriter::default_specification(), const strategy s = jitty) :
     125        1751 :       basic_rewriter<data_expression>(d, s)
     126        1751 :     { }
     127             : 
     128             :     /// \brief Constructor.
     129             :     /// \param[in] d A data specification
     130             :     /// \param[in] selector A component that selects the equations that are converted to rewrite rules
     131             :     /// \param[in] s A rewriter strategy.
     132             :     template < typename EquationSelector >
     133          50 :     rewriter(const data_specification& d, const EquationSelector& selector, const strategy s = jitty) :
     134          50 :       basic_rewriter<data_expression>(d, selector, s)
     135             :     {
     136          50 :     }
     137             : 
     138             :     /// \brief Create a clone of the rewriter in which the underlying rewriter is copied, and not passed as a shared pointer. 
     139             :     /// \details This is useful when the rewriter is used in different parallel processes. One rewriter can only be used sequentially. 
     140             :     /// \return A rewriter, with a copy of the underlying jitty, jittyc or jittyp rewriting engine. 
     141           0 :     rewriter clone()
     142             :     {
     143           0 :       return rewriter(m_rewriter->clone());
     144             :     }
     145             : 
     146             :     /// \brief Initialises this rewriter with thread dependent information. 
     147             :     /// \details This function sets a pointer to the m_busy_flag and m_forbidden_flag of this.
     148             :     ///          process, such that rewriter can access these faster than via the general thread.
     149             :     ///          local mechanism. It is expected that this is not needed when compilers become.
     150             :     ///          faster, and should be removed in due time. 
     151         347 :     void thread_initialise()
     152             :     {
     153         347 :       m_rewriter->thread_initialise();
     154         347 :     }
     155             : 
     156             :     /// \brief Rewrites a data expression.
     157             :     /// \param[in] d A data expression.
     158             :     /// \return The normal form of d.
     159       88648 :     data_expression operator()(const data_expression& d) const
     160             :     {
     161       88648 :       return (*this)(d, empty_substitution());
     162             :     }
     163             : 
     164             :     /// \brief Rewrites the data expression d, and on the fly applies a substitution function.
     165             :     /// to data variables.
     166             :     /// \param[in] d A data expression.
     167             :     /// \param[in] sigma A substitution function.
     168             :     /// \return The normal form of the term.
     169             :     template <typename SubstitutionFunction>
     170       16526 :     data_expression operator()(const data_expression& d, const SubstitutionFunction& sigma) const
     171             :     {
     172       16526 :       substitution_type sigma_with_iterator;
     173       16526 :       std::set<variable> free_variables = data::find_free_variables(d);
     174       31288 :       for(const variable& free_variable: free_variables)
     175             :       {
     176       14762 :         sigma_with_iterator[free_variable] = sigma(free_variable);
     177             :       }
     178       33052 :       return (*this)(d, sigma_with_iterator);
     179       16526 :     }
     180             : 
     181             :     /// \brief Rewrites the data expression d, and on the fly applies a substitution function.
     182             :     /// to data variables.
     183             :     /// \param[out] result The normal form of the term is placed in result.
     184             :     /// \param[in] d A data expression.
     185             :     /// \param[in] sigma A substitution function.
     186             :     template <typename SubstitutionFunction>
     187          16 :     void operator()(data_expression& result, const data_expression& d, const SubstitutionFunction& sigma) const
     188             :     {
     189          16 :       substitution_type sigma_with_iterator;
     190          16 :       std::set<variable> free_variables = data::find_free_variables(d);
     191          29 :       for(const variable& free_variable: free_variables)
     192             :       {
     193          13 :         sigma_with_iterator[free_variable] = sigma(free_variable);
     194             :       }
     195          16 :       (*this)(result, d, sigma_with_iterator);
     196          16 :     }
     197             : 
     198             :     /// \brief Rewrites the data expression d, and on the fly applies a substitution function
     199             :     /// to data variables.
     200             :     /// \param[in] d A data expression.
     201             :     /// \param[in] sigma A substitution function.
     202             :     /// \return The normal form of the term.
     203             :     //  Added bij JFG, to avoid the use of find_free_variables in the function operator() with
     204             :     //  an arbitrary SubstitionFunction, as this is prohibitively costly.
     205      109026 :     data_expression operator()(const data_expression& d, substitution_type& sigma) const
     206             :     {
     207      109026 :       data_expression result;
     208      109026 :       (*this)(result, d, sigma);
     209      109026 :       return result;
     210           0 :     }
     211             : 
     212             :     /// \brief Rewrites the data expression d, and on the fly applies a substitution function
     213             :     /// to data variables.
     214             :     /// \param[out] result The normal form of the term is put in resul is put in result
     215             :     /// \param[in] d A data expression.
     216             :     /// \param[in] sigma A substitutionA. function
     217             :     //  Added bij JFG, to avoid the use of find_free_variables in the function operator() with
     218             :     //  an arbitrary SubstitionFunction, as this is prohibitively costly.
     219      269912 :     void operator()(data_expression& result, const data_expression& d, substitution_type& sigma) const
     220             :     {
     221             : #ifdef MCRL2_COUNT_DATA_REWRITE_CALLS
     222             :       rewrite_calls++;
     223             : #endif
     224             : #ifdef MCRL2_PRINT_REWRITE_STEPS
     225             :       mCRL2log(log::debug) << "REWRITE " << d << "\n";
     226             : #endif
     227      269912 :       m_rewriter->rewrite(result,d,sigma);
     228             : #ifdef MCRL2_PRINT_REWRITE_STEPS
     229             :       mCRL2log(log::debug) << " ------------> " << result << std::endl;
     230             : #endif
     231      269912 :     }
     232             : 
     233        8452 :     ~rewriter()
     234             :     {
     235             : #ifdef MCRL2_COUNT_DATA_REWRITE_CALLS
     236             :       std::cout << "number of data rewrite calls: " << rewrite_calls << std::endl;
     237             : #endif
     238        8452 :     }
     239             : };
     240             : 
     241             : } // namespace data
     242             : 
     243             : } // namespace mcrl2
     244             : 
     245             : #endif // MCRL2_DATA_REWRITER_H

Generated by: LCOV version 1.14