LCOV - code coverage report
Current view: top level - modal_formula/include/mcrl2/modal_formula - state_formula_rename.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 61 66 92.4 %
Date: 2024-04-26 03:18:02 Functions: 21 25 84.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/modal_formula/state_formula_rename.h
      10             : /// \brief Add your file description here.
      11             : 
      12             : #ifndef MCRL2_MODAL_FORMULA_STATE_FORMULA_RENAME_H
      13             : #define MCRL2_MODAL_FORMULA_STATE_FORMULA_RENAME_H
      14             : 
      15             : #include "mcrl2/modal_formula/replace.h"
      16             : 
      17             : namespace mcrl2
      18             : {
      19             : 
      20             : namespace state_formulas
      21             : {
      22             : 
      23             : /// Visitor that renames predicate variables using the specified identifier generator.
      24             : /// \post In the generated formula, all predicate variables have different names.
      25             : template <typename IdentifierGenerator>
      26             : struct state_formula_predicate_variable_rename_builder: public state_formulas::state_formula_builder<state_formula_predicate_variable_rename_builder<IdentifierGenerator> >
      27             : {
      28             :   typedef state_formulas::state_formula_builder<state_formula_predicate_variable_rename_builder<IdentifierGenerator> > super;
      29             :   using super::enter;
      30             :   using super::leave;
      31             :   using super::update;
      32             :   using super::apply;
      33             : 
      34             :   /// \brief An identifier generator
      35             :   IdentifierGenerator& generator;
      36             : 
      37             :   /// \brief A stack of replacements. It may contain pairs with identical values.
      38             :   std::deque<std::pair<core::identifier_string, core::identifier_string> > replacements;
      39             : 
      40             :   /// \brief Constructor
      41             :   /// \param generator A generator for fresh identifiers
      42         144 :   state_formula_predicate_variable_rename_builder(IdentifierGenerator& generator)
      43         144 :     : generator(generator)
      44         144 :   {}
      45             : 
      46             :   /// \brief Generates a new name for n, and adds a replacement to the replacement stack.
      47             :   /// \param n A
      48             :   /// \return The new name.
      49         120 :   core::identifier_string push(const core::identifier_string& n)
      50             :   {
      51         120 :     core::identifier_string new_name = generator(n);
      52         120 :     replacements.push_front(std::make_pair(n, new_name));
      53         120 :     return new_name;
      54           0 :   }
      55             : 
      56             :   /// \brief Removes the last added replacement.
      57         120 :   void pop()
      58             :   {
      59         120 :     replacements.pop_front();
      60         120 :   }
      61             : 
      62             :   /// \brief Visit var node.
      63             :   /// \param x A variable.
      64             :   /// \return The result of visiting the node
      65             :   template <class T>
      66         111 :   void apply(T& result, const variable& x)
      67             :   {
      68         111 :     core::identifier_string new_name = x.name();
      69         125 :     for (std::deque<std::pair<core::identifier_string, core::identifier_string> >::iterator i = replacements.begin(); i != replacements.end(); ++i)
      70             :     {
      71         125 :       if (i->first == x.name())
      72             :       {
      73         111 :         new_name = i->second;
      74         111 :         break;
      75             :       }
      76             :     }
      77         111 :     result = variable(new_name, x.arguments());
      78         111 :   }
      79             : 
      80             :   /// \brief Visit mu node.
      81             :   /// \param x The mu state variable.
      82             :   /// \return The result of visiting the node
      83             :   template <class T>
      84          69 :   void apply(T& result, const mu& x)
      85             :   {
      86          69 :     core::identifier_string new_name = push(x.name());
      87          69 :     state_formula new_formula;
      88          69 :     apply(new_formula, x.operand());
      89          69 :     pop();
      90          69 :     make_mu(result, new_name, x.assignments(), new_formula);
      91          69 :   }
      92             : 
      93             :   /// \brief Visit nu node.
      94             :   /// \param x The visited nu node.
      95             :   /// \return The result of visiting the node
      96             :   template <class T>
      97          51 :   void apply(T& result, const nu& x)
      98             :   {
      99          51 :     core::identifier_string new_name = push(x.name());
     100          51 :     state_formula new_formula;
     101          51 :     apply(new_formula, x.operand());
     102          51 :     pop();
     103          51 :     make_nu(result, new_name, x.assignments(), new_formula);
     104          51 :   }
     105             : };
     106             : 
     107             : /// \brief Utility function for creating a state_formula_predicate_variable_rename_builder.
     108             : /// \param generator A generator for fresh identifiers
     109             : /// \return a state_formula_predicate_variable_rename_builder
     110             : template <typename IdentifierGenerator>
     111         144 : state_formula_predicate_variable_rename_builder<IdentifierGenerator> make_state_formula_predicate_variable_rename_builder(IdentifierGenerator& generator)
     112             : {
     113         144 :   return state_formula_predicate_variable_rename_builder<IdentifierGenerator>(generator);
     114             : }
     115             : 
     116             : /// \brief Renames predicate variables of the formula f using the specified identifier generator.
     117             : /// \post predicate variables within the same scope have different names
     118             : /// \param f A modal formula
     119             : /// \param generator A generator for fresh identifiers
     120             : /// \return The rename result
     121             : template <typename IdentifierGenerator>
     122         144 : state_formula rename_predicate_variables(const state_formula& f, IdentifierGenerator& generator)
     123             : {
     124         144 :   state_formula result;
     125         144 :   make_state_formula_predicate_variable_rename_builder(generator).apply(result, f);
     126         144 :   return result;
     127           0 : }
     128             : 
     129             : /// Visitor that renames variables using the specified identifier generator. Also bound variables are renamed!
     130             : struct state_formula_variable_rename_builder: public state_formulas::sort_expression_builder<state_formula_variable_rename_builder>
     131             : {
     132             :   typedef state_formulas::sort_expression_builder<state_formula_variable_rename_builder> super;
     133             : 
     134             :   using super::enter;
     135             :   using super::leave;
     136             :   using super::update;
     137             :   using super::apply;
     138             : 
     139             :   /// \brief The set of identifiers that may not be used as a variable name.
     140             :   const std::set<core::identifier_string>& forbidden_identifiers;
     141             : 
     142             :   std::map<core::identifier_string, core::identifier_string> generated_identifiers;
     143             : 
     144             :   utilities::number_postfix_generator generator;
     145             : 
     146          86 :   core::identifier_string create_name(const core::identifier_string& x)
     147             :   {
     148          86 :     std::map<core::identifier_string, core::identifier_string>::iterator i = generated_identifiers.find(x);
     149          86 :     if (i != generated_identifiers.end())
     150             :     {
     151          54 :       return i->second;
     152             :     }
     153          32 :     std::string name = generator(std::string(x));
     154          32 :     generated_identifiers[x] = core::identifier_string(name);
     155          32 :     return core::identifier_string(name);
     156          32 :   }
     157             : 
     158             :   /// \brief Constructor
     159         142 :   state_formula_variable_rename_builder(const std::set<core::identifier_string>& forbidden_identifiers_)
     160         142 :     : forbidden_identifiers(forbidden_identifiers_)
     161             :   {
     162       10218 :     for (const core::identifier_string& id: forbidden_identifiers)
     163             :     {
     164       10076 :       generator.add_identifier(std::string(id));
     165             :     }
     166         142 :   }
     167             : 
     168             :   // do not traverse sorts
     169             :   template <class T>
     170         256 :   void apply(T& result, const data::sort_expression& x)
     171             :   {
     172         256 :     result = x;
     173         256 :   }
     174             : 
     175             :   template <class T>
     176          86 :   void apply(T& result, const data::variable& x)
     177             :   {
     178             :     using utilities::detail::contains;
     179          86 :     if (!contains(forbidden_identifiers, x.name()))
     180             :     {
     181           0 :       result = x;
     182           0 :       return;
     183             :     }
     184          86 :     data::make_variable(result, create_name(x.name()), x.sort());
     185             :   }
     186             : };
     187             : 
     188             : /// \brief Renames all data variables in the formula f such that the forbidden identifiers are not used.
     189             : /// \param f A modal formula.
     190             : /// \param forbidden_identifiers Set of identifiers strings, which are renamed. 
     191             : /// \return The rename result.
     192             : inline
     193         142 : state_formula rename_variables(const state_formula& f, const std::set<core::identifier_string>& forbidden_identifiers)
     194             : {
     195         142 :   state_formula result;
     196         142 :   state_formula_variable_rename_builder(forbidden_identifiers).apply(result, f);
     197         142 :   return result;
     198           0 : }
     199             : 
     200             : } // namespace state_formulas
     201             : 
     202             : } // namespace mcrl2
     203             : 
     204             : #endif // MCRL2_MODAL_FORMULA_STATE_FORMULA_RENAME_H

Generated by: LCOV version 1.14