LCOV - code coverage report
Current view: top level - lps/include/mcrl2/lps - suminst.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 76 85 89.4 %
Date: 2024-04-19 03:43:27 Functions: 11 21 52.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jeroen Keiren
       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 suminst.h
      10             : /// \brief Instantiate summation variables.
      11             : 
      12             : #ifndef MCRL2_LPS_SUMINST_H
      13             : #define MCRL2_LPS_SUMINST_H
      14             : 
      15             : #include "mcrl2/atermpp/set_operations.h"
      16             : 
      17             : #include "mcrl2/data/enumerator.h"
      18             : 
      19             : #include "mcrl2/lps/detail/lps_algorithm.h"
      20             : 
      21             : namespace mcrl2
      22             : {
      23             : namespace lps
      24             : {
      25             : 
      26             : /// \brief Return a set with all finite sorts in data specification s.
      27             : inline
      28           5 : std::set<data::sort_expression> finite_sorts(const data::data_specification& s)
      29             : {
      30           5 :   const std::set<data::sort_expression>& sorts = s.sorts();
      31           5 :   std::set<data::sort_expression> result;
      32             : 
      33          44 :   for(const data::sort_expression& sort : sorts)
      34             :   {
      35          39 :     if(s.is_certainly_finite(sort))
      36             :     {
      37          11 :       result.insert(sort);
      38             :     }
      39             :   }
      40           5 :   return result;
      41           0 : }
      42             : 
      43             : template<typename DataRewriter, typename Specification>
      44             : class suminst_algorithm: public detail::lps_algorithm<Specification>
      45             : {
      46             :   typedef detail::lps_algorithm<Specification> super;
      47             :   typedef data::enumerator_list_element_with_substitution<> enumerator_element;
      48             :   typedef typename Specification::process_type process_type;
      49             :   typedef typename process_type::action_summand_type action_summand_type;
      50             :   typedef std::vector<action_summand_type> action_summand_vector_type;
      51             :   using super::m_spec;
      52             : 
      53             :   protected:
      54             :     /// Sorts to be instantiated
      55             :     std::set<data::sort_expression> m_sorts;
      56             : 
      57             :     /// Only instantiate tau summands
      58             :     bool m_tau_summands_only;
      59             : 
      60             :     /// Rewriter
      61             :     DataRewriter m_rewriter;
      62             :     data::enumerator_algorithm<> m_enumerator;
      63             :     data::enumerator_identifier_generator m_id_generator;
      64             : 
      65             :     /// Statistiscs for verbose output
      66             :     std::size_t m_processed;
      67             :     std::size_t m_deleted;
      68             :     std::size_t m_added;
      69             : 
      70             :     template <typename SummandType, typename Container>
      71           9 :     std::size_t instantiate_summand(const SummandType& s, Container& result)
      72             :     {
      73             :       using namespace data;
      74           9 :       std::size_t nr_summands = 0; // Counter for the number of new summands, used for verbose output
      75           9 :       std::deque< variable > variables; // The variables we need to consider in instantiating
      76             : 
      77             :       // partition such that variables with finite sort precede those that do not
      78          25 :       for (const variable& v: s.summation_variables())
      79             :       {
      80           7 :         if(m_sorts.find(v.sort()) != m_sorts.end())
      81             :         {
      82           6 :           if (m_spec.data().is_certainly_finite(v.sort()))
      83             :           {
      84           5 :             variables.push_front(v);
      85             :           }
      86             :           else
      87             :           {
      88           1 :             variables.push_back(v);
      89             :           }
      90             :         }
      91             :       }
      92             : 
      93           9 :       if (variables.empty())
      94             :       {
      95             :         // Nothing to be done, return original summand
      96           3 :         result.push_back(s);
      97           3 :         nr_summands = 1;
      98             :       }
      99             :       else
     100             :       {
     101             :         // List of variables with the instantiated variables removed (can be done upfront, which is more efficient,
     102             :         // because we only need to calculate it once.
     103           6 :         const variable_list vl(variables.begin(),variables.end());
     104           6 :         variable_list new_summation_variables = term_list_difference(s.summation_variables(), vl);
     105             : 
     106             :         try
     107             :         {
     108           6 :           mCRL2log(log::debug) << "enumerating variables " << vl << " in condition: " << data::pp(s.condition()) << std::endl;
     109           6 :           data::mutable_indexed_substitution<> local_sigma;
     110           6 :           m_enumerator.enumerate(enumerator_element(vl, s.condition()),
     111             :                                  local_sigma,
     112          98 :                                  [&](const enumerator_element& p)
     113             :                                  {
     114          14 :                                    mutable_indexed_substitution<> sigma;
     115          14 :                                    p.add_assignments(vl, sigma, m_rewriter);
     116          14 :                                    mCRL2log(log::debug) << "substitutions: " << sigma << std::endl;
     117          14 :                                    SummandType t(s);
     118          14 :                                    t.summation_variables() = new_summation_variables;
     119          14 :                                    lps::rewrite(t, m_rewriter, sigma);
     120          14 :                                    result.push_back(t);
     121          14 :                                    ++nr_summands;
     122          14 :                                    return false;
     123          14 :                                  },
     124             :                                  sort_bool::is_false_function_symbol
     125             :           );
     126           6 :         }
     127           0 :         catch (mcrl2::runtime_error const& e)
     128             :         {
     129             :           // If an error occurs in enumerating, remove all summands that
     130             :           // have been added to result thus far, and re-add the original.
     131             :           // This prevents problems e.g. in case of a sort without constructors.
     132           0 :           mCRL2log(log::debug) << "An error occurred in enumeration, removing already added summands, and keeping the original" << std::endl;
     133           0 :           mCRL2log(log::debug) << e.what() << std::endl;
     134             : 
     135           0 :           result.resize(result.size() - nr_summands);
     136           0 :           result.push_back(s);
     137           0 :           nr_summands = 1;
     138             :         }
     139           6 :       }
     140           9 :       return nr_summands;
     141           9 :     }
     142             : 
     143           8 :     bool must_instantiate(const action_summand_type& summand)
     144             :     {
     145           8 :       return !m_tau_summands_only || summand.is_tau();
     146             :     }
     147             : 
     148           2 :     bool must_instantiate(const deadlock_summand& )
     149             :     {
     150           2 :       return !m_tau_summands_only;
     151             :     }
     152             : 
     153             :     template <typename SummandListType, typename Container>
     154          12 :     void run(const SummandListType& list, Container& result)
     155             :     {
     156          22 :       for (typename SummandListType::const_iterator i = list.begin(); i != list.end(); ++i)
     157             :       {
     158          10 :         if (must_instantiate(*i))
     159             :         {
     160           9 :           std::size_t newsummands = instantiate_summand(*i, result);
     161           9 :           if (newsummands > 0)
     162             :           {
     163           9 :             m_added += newsummands - 1;
     164             :           }
     165             :           else
     166             :           {
     167           0 :             ++m_deleted;
     168             :           }
     169             :         }
     170             :         else
     171             :         {
     172           1 :           result.push_back(*i);
     173             :         }
     174          10 :         ++m_processed;
     175          10 :         mCRL2log(log::status) << "Replaced " << m_processed << " summands by " << (m_processed + m_added - m_deleted)
     176           0 :                               << " summands (" << m_deleted << " were deleted)" << std::endl;
     177             :       }
     178          12 :     }
     179             : 
     180             :   public:
     181           6 :     suminst_algorithm(Specification& spec,
     182             :                       DataRewriter& r,
     183             :                       std::set<data::sort_expression> sorts = std::set<data::sort_expression>(),
     184             :                       bool tau_summands_only = false)
     185             :       : detail::lps_algorithm<Specification>(spec),
     186           6 :         m_sorts(sorts),
     187           6 :         m_tau_summands_only(tau_summands_only),
     188           6 :         m_rewriter(r),
     189           6 :         m_enumerator(r, spec.data(), r, m_id_generator, false),
     190           6 :         m_processed(0),
     191           6 :         m_deleted(0),
     192          12 :         m_added(0)
     193             :     {
     194           6 :       if(sorts.empty())
     195             :       {
     196           4 :         mCRL2log(log::info) << "an empty set of sorts to be unfolded was provided; defaulting to all finite sorts" << std::endl;
     197           4 :         m_sorts = finite_sorts(spec.data());
     198             :       }
     199           6 :     }
     200             : 
     201           6 :     void run()
     202             :     {
     203           6 :       action_summand_vector_type action_summands;
     204           6 :       deadlock_summand_vector deadlock_summands;
     205           6 :       m_added = 0;
     206           6 :       m_deleted = 0;
     207           6 :       m_processed = 0;
     208           6 :       run(m_spec.process().action_summands(), action_summands);
     209           6 :       run(m_spec.process().deadlock_summands(), deadlock_summands);
     210           6 :       m_spec.process().action_summands().swap(action_summands);
     211           6 :       m_spec.process().deadlock_summands().swap(deadlock_summands);
     212           6 :       mCRL2log(log::status) << std::endl;
     213           6 :     }
     214             : 
     215             : }; // suminst_algorithm
     216             : 
     217             : } // namespace lps
     218             : } // namespace mcrl2
     219             : 
     220             : #endif // MCRL2_LPS_SUMINST_H
     221             : 

Generated by: LCOV version 1.14