LCOV - code coverage report
Current view: top level - lts/include/mcrl2/lts - lts_lts.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 59 103 57.3 %
Date: 2024-04-19 03:43:27 Functions: 23 25 92.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jan Friso Groote
       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             : 
      10             : /** \file lts_lts.h
      11             :  *
      12             :  * \brief This file contains a class that contains labelled transition systems in lts (mcrl2) format.
      13             :  * \details A labelled transition system in lts/mcrl2 format is a transition system
      14             :  * with as state labels vectors of strings, and as transition labels strings.
      15             :  * \author Jan Friso Groote
      16             :  */
      17             : 
      18             : 
      19             : #ifndef MCRL2_LTS_LTS_MCRL2_H
      20             : #define MCRL2_LTS_LTS_MCRL2_H
      21             : 
      22             : #include "mcrl2/lps/parse.h"
      23             : #include "mcrl2/lps/print.h"
      24             : #include "mcrl2/lps/state.h"
      25             : #include "mcrl2/lps/probabilistic_data_expression.h"
      26             : #include "mcrl2/lts/probabilistic_lts.h"
      27             : 
      28             : namespace mcrl2
      29             : {
      30             : namespace lts
      31             : {
      32             : 
      33             : /** \brief This class contains state labels for an labelled transition system in .lts format.
      34             :     \details A state label in .lts format consists of lists of balanced tree of data expressions.
      35             :              These represent sets of state vectors. The reason for the sets is that states can
      36             :              be merged by operations on state spaces, and if so, the sets of labels can easily
      37             :              be joined.
      38             : */
      39             : class state_label_lts : public atermpp::term_list< lps::state >
      40             : {
      41             :   public:
      42             :     typedef atermpp::term_list< lps::state > super;
      43             : 
      44             :     /** \brief Default constructor.
      45             :     */
      46        1750 :     state_label_lts()
      47        1750 :     {}
      48             : 
      49             :     /** \brief Copy constructor. */
      50        1938 :     state_label_lts(const state_label_lts& )=default;
      51             : 
      52             :     /** \brief Copy assignment. */
      53        1296 :     state_label_lts& operator=(const state_label_lts& )=default;
      54             : 
      55             :     /** \brief Construct a single state label out of the elements in a container.
      56             :     */
      57             :     template < class CONTAINER >
      58             :     explicit state_label_lts(const CONTAINER& l)
      59             :     {
      60             :       static_assert(std::is_same<typename CONTAINER::value_type, data::data_expression>::value,"Value type must be a data_expression");
      61             :       this->push_front(lps::state(l.begin(),l.size()));
      62             :     }
      63             : 
      64             :     /** \brief Construct a state label out of a balanced tree of data expressions, representing a state label.
      65             :     */
      66         870 :     explicit state_label_lts(const lps::state& l)
      67         870 :     {
      68         870 :       this->push_front(l);
      69         870 :     }
      70             : 
      71             :     /** \brief Construct a state label out of list of balanced trees of data expressions, representing a state label.
      72             :     */
      73             :     explicit state_label_lts(const super& l)
      74             :       : super(l)
      75             :     {
      76             :     }
      77             : 
      78             :     /** \brief An operator to concatenate two state labels.
      79             :         \details Is optimal whenever |l| is smaller than the left operand, i.e. |l| < |this|.
      80             :      */
      81           0 :     state_label_lts operator+(const state_label_lts& l) const
      82             :     {
      83             :       // The order of the state labels should not matter. For efficiency the elements of l are inserted in front of the aterm_list.
      84           0 :       state_label_lts result(*this);
      85             : 
      86           0 :       for (const lps::state& el : l)
      87             :       {
      88           0 :         result.push_front(el);
      89             :       }
      90             : 
      91           0 :       return result;
      92           0 :     }
      93             : };
      94             : 
      95             : /** \brief Pretty print a state value of this LTS.
      96             :     \details The label is printed as (t1,...,tn) if it consists of a single label.
      97             :              Otherwise the labels are printed with square brackets surrounding it.
      98             :     \param[in] label  The state value to pretty print.
      99             :     \return           The pretty-printed representation of value. */
     100             : 
     101           0 : inline std::string pp(const state_label_lts& label)
     102             : {
     103           0 :   std::string s;
     104           0 :   if (label.size()!=1)
     105             :   {
     106           0 :     s += "[";
     107             :   }
     108           0 :   bool first=true;
     109           0 :   for(const lps::state& l: label)
     110             :   {
     111           0 :     if (!first)
     112             :     {
     113           0 :       s += ", ";
     114             :     }
     115           0 :     first = false;
     116           0 :     s += "(";
     117           0 :     for (lps::state::iterator i=l.begin(); i!=l.end(); ++i)
     118             :     {
     119           0 :       if (i!=l.begin())
     120             :       {
     121           0 :         s += ",";
     122             :       }
     123           0 :       s += data::pp(*i);
     124             :     }
     125           0 :     s += ")";
     126             :   }
     127           0 :   if (label.size()!=1)
     128             :   {
     129           0 :     s += "]";
     130             :   }
     131           0 :   return s;
     132           0 : }
     133             : 
     134             : /** \brief A class containing the values for action labels for the .lts format.
     135             :     \details An action label is a multi_action. */
     136             : class action_label_lts: public mcrl2::lps::multi_action
     137             : {
     138             :   public:
     139             : 
     140             :     /** \brief Default constructor. */
     141        1554 :     action_label_lts()
     142        1554 :     {}
     143             : 
     144             :     /** \brief Copy constructor. */
     145        2963 :     action_label_lts(const action_label_lts& )=default;
     146             : 
     147             :     /** \brief Copy assignment. */
     148        1535 :     action_label_lts& operator=(const action_label_lts& )=default;
     149             : 
     150             :     /** \brief Constructor. */
     151        1034 :     explicit action_label_lts(const mcrl2::lps::multi_action& a)
     152        1034 :      : mcrl2::lps::multi_action(sort_multiactions(a))
     153             :     {
     154        1034 :     }
     155             : 
     156             :     /** \brief Hide the actions with labels in tau_actions.
     157             :         \return Returns whether the hidden action becomes empty, i.e. a tau or hidden action.
     158             :     */
     159             :     void hide_actions(const std::vector<std::string>& tau_actions)
     160             :     {
     161             :       process::action_vector new_multi_action;
     162             :       for (const process::action& a: this->actions()) 
     163             :       {
     164             :         if (std::find(tau_actions.begin(),tau_actions.end(),
     165             :                       std::string(a.label().name()))==tau_actions.end())  // this action must not be hidden.
     166             :         {
     167             :           new_multi_action.push_back(a);
     168             :         }
     169             :       }
     170             :       *this= action_label_lts(lps::multi_action(process::action_list(new_multi_action.begin(), new_multi_action.end()),time()));
     171             :     }
     172             : 
     173             :     /* \brief The action label that represents the internal action.
     174             :     */
     175        2486 :     static const action_label_lts& tau_action()
     176             :     {
     177        2486 :       static action_label_lts tau_action=action_label_lts();
     178        2486 :       return tau_action;
     179             :     }
     180             : 
     181             :   protected:
     182             :     /// A function to sort a multi action to guarantee that multi-actions are compared properly. 
     183        1034 :     static mcrl2::lps::multi_action sort_multiactions(const mcrl2::lps::multi_action& a)
     184             :     {
     185        1034 :       if (a.actions().size()<=1)
     186             :       {
     187        1030 :         return a;
     188             :       }
     189           4 :       std::multiset<process::action> sorted_actions(a.actions().begin(), a.actions().end());
     190           8 :       return  mcrl2::lps::multi_action(process::action_list(sorted_actions.begin(),sorted_actions.end()),a.time());
     191           4 :     }
     192             : };
     193             : 
     194             : /** \brief Print the action label to string. */
     195         508 : inline std::string pp(const action_label_lts& l)
     196             : {
     197        1016 :   return lps::pp(mcrl2::lps::multi_action(l));
     198             : }
     199             : 
     200             : /** \brief Parse a string into an action label.
     201             :     \details The string is typechecked against the data specification and
     202             :              list of declared actions. If parsing or type checking fails, an
     203             :              mcrl2::runtime_error is thrown.
     204             :     \param[in] multi_action_string The string to be parsed.
     205             :     \param[in] data_spec The data specification used for parsing.
     206             :     \param[in] act_decls Action declarations.
     207             :     \return The parsed and type checked multi action. */
     208          12 : inline action_label_lts parse_lts_action(
     209             :   const std::string& multi_action_string,
     210             :   const data::data_specification& data_spec,
     211             :   lps::multi_action_type_checker& typechecker)
     212             : {
     213          12 :   std::string l(multi_action_string);
     214          24 :   lps::multi_action al;
     215             :   // Find an @ symbol in the action, in which case it is timed.
     216          12 :   size_t position_of_at=l.find_first_of('@');
     217          12 :   std::string time_expression_string;
     218          12 :   if (position_of_at!=std::string::npos)
     219             :   {
     220             :     // The at symbol is found. It is a timed action.
     221           0 :     time_expression_string=l.substr(position_of_at+1,l.size());
     222           0 :     l=l.substr(0,position_of_at-1);
     223             :   }
     224             :   try
     225             :   {
     226          12 :     al=lps::parse_multi_action(l, typechecker, data_spec);
     227             :   }
     228           0 :   catch (mcrl2::runtime_error& e)
     229             :   {
     230           0 :     throw mcrl2::runtime_error("Parse error in action label " + multi_action_string + ".\n" + e.what());
     231           0 :   }
     232             : 
     233          12 :   if (time_expression_string.size()>0)
     234             :   {
     235             :     try
     236             :     {
     237           0 :       data::data_expression time=parse_data_expression(time_expression_string,data::variable_list(),data_spec);
     238             :       // Translate the sort of time to a real.
     239           0 :       if (time.sort()==data::sort_pos::pos())
     240             :       {
     241           0 :         time = data::sort_nat::cnat(time);
     242             :       }
     243           0 :       if (time.sort()==data::sort_nat::nat())
     244             :       {
     245           0 :         time = data::sort_int::cint(time);
     246             :       }
     247           0 :       if (time.sort()==data::sort_int::int_())
     248             :       {
     249           0 :         time = data::sort_real::creal(time, data::sort_pos::c1());
     250             :       }
     251           0 :       if (time.sort()!=data::sort_real::real_())
     252             :       {
     253           0 :         throw mcrl2::runtime_error("The time is not of sort Pos, Nat, Int or Real\n");
     254             :       }
     255           0 :       return action_label_lts(lps::multi_action(al.actions(),time));
     256           0 :     }
     257           0 :     catch (mcrl2::runtime_error& e)
     258             :     {
     259           0 :       throw mcrl2::runtime_error("Parse error in the time expression " + multi_action_string + ".\n" + e.what());
     260           0 :     }
     261             :   }
     262          12 :   return action_label_lts(al);
     263          12 : }
     264             : 
     265             : namespace detail
     266             : {
     267             : 
     268             : /** \brief a base class for lts_lts_t and probabilistic_lts_t.
     269             :  */
     270             : class lts_lts_base
     271             : {
     272             :   protected:
     273             :     data::data_specification m_data_spec;
     274             :     data::variable_list m_parameters;
     275             :     process::action_label_list m_action_decls;
     276             : 
     277             :   public:
     278             :     /// \brief Default constructor
     279         188 :     lts_lts_base()
     280         188 :     {}
     281             : 
     282             :     /// \brief Standard equality function;
     283             :     bool operator==(const lts_lts_base& other) const
     284             :     {
     285             :       return m_data_spec==other.m_data_spec &&
     286             :              m_parameters==other.m_parameters &&
     287             :              m_action_decls==other.m_action_decls;
     288             :     }
     289             : 
     290             :     void swap(lts_lts_base& l)
     291             :     {
     292             :       const data::data_specification auxd=m_data_spec;
     293             :       m_data_spec=l.m_data_spec;
     294             :       l.m_data_spec=auxd;
     295             :       m_parameters.swap(l.m_parameters);
     296             :       m_action_decls.swap(l.m_action_decls);
     297             :     }
     298             : 
     299             :     /** \brief Yields the type of this lts, in this case lts_lts. */
     300          58 :     static lts_type type()
     301             :     {
     302          58 :       return lts_lts;
     303             :     }
     304             : 
     305             :     /** \brief Returns the mCRL2 data specification of this LTS.
     306             :     */
     307          76 :     const data::data_specification& data() const
     308             :     {
     309          76 :       return m_data_spec;
     310             :     }
     311             : 
     312             :     /** \brief Return action label declarations stored in this LTS.
     313             :     */
     314          74 :     const process::action_label_list& action_label_declarations() const
     315             :     {
     316          74 :       return m_action_decls;
     317             :     }
     318             : 
     319             :     /** \brief Set the action label information for this LTS.
     320             :      * \param[in] decls  The action labels to be set in this lts.
     321             :     */
     322         186 :     void set_action_label_declarations(const process::action_label_list& decls)
     323             :     {
     324         186 :       m_action_decls=decls;
     325         186 :     }
     326             : 
     327             :     /** \brief Set the mCRL2 data specification of this LTS.
     328             :      * \param[in] spec  The mCRL2 data specification for this LTS.
     329             :     */
     330         186 :     void set_data(const data::data_specification& spec)
     331             :     {
     332         186 :       m_data_spec=spec;
     333         186 :     }
     334             : 
     335             :     /** \brief Return the process parameters stored in this LTS.
     336             :     */
     337         179 :     const data::variable_list& process_parameters() const
     338             :     {
     339         179 :       return m_parameters;
     340             :     }
     341             : 
     342             :     /** \brief Returns the i-th parameter of the state vectors stored in this LTS.
     343             :      * \return The state parameters stored in this LTS.
     344             :     */
     345             :     const data::variable& process_parameter(std::size_t i) const
     346             :     {
     347             :       assert(i<m_parameters.size());
     348             :       data::variable_list::const_iterator j=m_parameters.begin();
     349             :       for(std::size_t c=0; c!=i; ++j, ++c)
     350             :       {}
     351             :       return *j;
     352             :     }
     353             : 
     354             : 
     355             :     /** \brief Set the state parameters for this LTS.
     356             :      * \param[in] params  The state parameters for this lts.
     357             :     */
     358         183 :     void set_process_parameters(const data::variable_list& params)
     359             :     {
     360         183 :       m_parameters=params;
     361         183 :     }
     362             : 
     363             : };
     364             : 
     365             : } // namespace detail
     366             : 
     367             : 
     368             : /** \brief This class contains labelled transition systems in .lts format.
     369             :     \details In this .lts format, an action label is a multi action, and a
     370             :            state label is an expression of the form STATE(t1,...,tn) where
     371             :            ti are data expressions.
     372             : */
     373             : class lts_lts_t : public lts< state_label_lts, action_label_lts, detail::lts_lts_base >
     374             : {
     375             :   public:
     376             :     /** \brief Creates an object containing no information. */
     377         176 :     lts_lts_t() {}
     378             : 
     379             :     /** \brief Load the labelled transition system from file.
     380             :      *  \details If the filename is empty, the result is read from stdout.
     381             :      *  \param[in] filename Name of the file to which this lts is written.
     382             :      */
     383             :     void load(const std::string& filename);
     384             : 
     385             :     /** \brief Save the labelled transition system to file.
     386             :      *  \details If the filename is empty, the result is read from stdin.
     387             :      *  \param[in] filename Name of the file from which this lts is read.
     388             :      */
     389             :     void save(const std::string& filename) const;
     390             : };
     391             : 
     392             : /** \brief This class contains probabilistic labelled transition systems in .lts format.
     393             :     \details In this .lts format, an action label is a multi action, and a
     394             :            state label is an expression of the form STATE(t1,...,tn) where
     395             :            ti are data expressions.
     396             : */
     397             : class probabilistic_lts_lts_t :
     398             :          public probabilistic_lts< state_label_lts,
     399             :                                    action_label_lts,
     400             :                                    probabilistic_state<std::size_t, lps::probabilistic_data_expression>,
     401             :                                    detail::lts_lts_base >
     402             : {
     403             :   public:
     404             :     /** \brief Creates an object containing no information. */
     405          12 :     probabilistic_lts_lts_t() {}
     406             : 
     407             :     /** \brief Load the labelled transition system from file.
     408             :      *  \details If the filename is empty, the result is read from stdout.
     409             :      *  \param[in] filename Name of the file to which this lts is written.
     410             :      */
     411             :     void load(const std::string& filename);
     412             : 
     413             :     /** \brief Save the labelled transition system to file.
     414             :      *  \details If the filename is empty, the result is read from stdin.
     415             :      *  \param[in] filename Name of the file from which this lts is read.
     416             :      */
     417             :     void save(const std::string& filename) const;
     418             : };
     419             : } // namespace lts
     420             : } // namespace mcrl2
     421             : 
     422             : namespace std
     423             : {
     424             : 
     425             : /// \brief specialization of the standard std::hash function for an action_label_string.
     426             : template<>
     427             : struct hash< mcrl2::lts::action_label_lts >
     428             : {
     429        1271 :   std::size_t operator()(const mcrl2::lts::action_label_lts& as) const
     430             :   {
     431             :     hash<mcrl2::lps::multi_action> hasher;
     432        2542 :     return hasher(as);
     433             :   }
     434             : };
     435             : 
     436             : } // namespace std
     437             : 
     438             : 
     439             : #endif

Generated by: LCOV version 1.14