LCOV - code coverage report
Current view: top level - lts/include/mcrl2/lts/detail - liblts_ready_sim.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 89 100 89.0 %
Date: 2024-04-21 03:44:01 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /// Author(s): # Carlos Gregorio-Rodriguez, Luis LLana, Rafael Martinez-Torres.
       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 liblts_ready_sim.h
      10             : /// \brief Header file for the ready-simulation preorder algorithm
      11             : 
      12             : #ifndef MCRL2_LTS_LIBLTS_READY_SIM_H
      13             : #define MCRL2_LTS_LIBLTS_READY_SIM_H
      14             : 
      15             : #include "mcrl2/lts/detail/liblts_sim.h"
      16             : 
      17             : 
      18             : namespace mcrl2
      19             : {
      20             : namespace lts
      21             : {
      22             : namespace detail
      23             : {
      24             : 
      25             : template <class LTS_TYPE>
      26             :   class ready_sim_partitioner : public sim_partitioner<LTS_TYPE>
      27             : {
      28             :  public:
      29          16 :   ready_sim_partitioner(LTS_TYPE& l) : sim_partitioner<LTS_TYPE>(l)
      30             :   {
      31          16 :     exists2 = new hash_table2(1000);
      32          16 :     forall2 = new hash_table2(1000);
      33          16 :   };
      34             : 
      35             :     /**
      36             :      * Computes the ready-simulation equivalence
      37             :      * classes and preorder relations of the LTS
      38             :      */  
      39             :   virtual void partitioning_algorithm();
      40             :     /** Destroys this partitioner. */
      41             :   ~ready_sim_partitioner();
      42             :  private :
      43             :   // Non inherited data members...
      44             :   hash_table2* exists2;
      45             :   hash_table2* forall2;  
      46             : 
      47             :   // Non inherited methods...
      48             :     /**
      49             :      * Drives the partition pair <Universal,Id>
      50             :      * into appropriate ready partition-pair
      51             :      * for furhter input into GCPP.
      52             :      * \pre : true
      53             :      */          
      54             :   void ready2sim_reduction();
      55             : 
      56             :   /**
      57             :    * Splits Universal partition
      58             :    * into classes alpha where either
      59             :    * { N } A<-l- alpha or
      60             :    * not { N } <-l- alpha
      61             :    * for some L
      62             :    * \pre : initialise_datastructures called.
      63             :    */
      64             :   void refinei() ;
      65             : 
      66             :   /*
      67             :    * Induce P on Pi, then
      68             :    * drops those pairs (alpha, beta)
      69             :    * such that
      70             :    *  {N} E<-l- Beta and not {N} A<-l- Alpha
      71             :    * \pre : refinei  called 
      72             :    */
      73             :   void updatei();
      74             : 
      75             : 
      76             :   // Non inherited auxiliary methods...
      77             :   std::string print_structure(hash_table2* struc);  
      78             :   
      79             :   // Inherited data members...
      80             :   using sim_partitioner<LTS_TYPE>::aut;
      81             :   using sim_partitioner<LTS_TYPE>::s_Pi;
      82             :   using sim_partitioner<LTS_TYPE>::s_Sigma;  
      83             :   using sim_partitioner<LTS_TYPE>::block_Pi;
      84             :   using sim_partitioner<LTS_TYPE>::children;
      85             :   using sim_partitioner<LTS_TYPE>::parent;
      86             :   using sim_partitioner<LTS_TYPE>::Q;
      87             :   using sim_partitioner<LTS_TYPE>::P;  
      88             :   using sim_partitioner<LTS_TYPE>::contents_t;
      89             :   using sim_partitioner<LTS_TYPE>::contents_u;
      90             :   using sim_partitioner<LTS_TYPE>::touched_blocks;  
      91             :   using sim_partitioner<LTS_TYPE>::block_touched;
      92             :   using sim_partitioner<LTS_TYPE>::state_buckets;
      93             : 
      94             :   // Inherited methods
      95             :   using sim_partitioner<LTS_TYPE>::induce_P_on_Pi;
      96             :   using sim_partitioner<LTS_TYPE>::initialise_Sigma;    
      97             :   using sim_partitioner<LTS_TYPE>::initialise_datastructures;  
      98             :   using sim_partitioner<LTS_TYPE>::partitioning_algorithmG;
      99             :   using sim_partitioner<LTS_TYPE>::touch;
     100             :   using sim_partitioner<LTS_TYPE>::untouch;
     101             : 
     102             :   // Auxiliary inherited methods
     103             :   using sim_partitioner<LTS_TYPE>::print_relation;
     104             :   using sim_partitioner<LTS_TYPE>::print_Sigma_P;
     105             :   using sim_partitioner<LTS_TYPE>::print_Pi_Q;
     106             : 
     107             : };
     108             : 
     109             : 
     110             : /* Pre : true */
     111             : template <class LTS_TYPE>
     112          16 : void ready_sim_partitioner<LTS_TYPE>::ready2sim_reduction()
     113             : {
     114          16 :   initialise_datastructures();
     115          16 :   refinei();
     116          16 :   updatei();
     117          16 :   s_Sigma = s_Pi; // <== Key!!
     118          16 :   P.swap(Q);      // <== Key!!
     119          16 :   mCRL2log(log::debug) << "--------------------- READY PRE-REDUCTION-------------------------" << std::endl;
     120          16 :   mCRL2log(log::debug) << "  prereduction; number of blocks: " << s_Sigma << std::endl;
     121          16 : }
     122             : 
     123             : /* ----------------- PARTITIONING ALGORITHM ------------------------- */
     124             : /* Pre : true */
     125             : template <class LTS_TYPE>
     126          16 : void ready_sim_partitioner<LTS_TYPE>::partitioning_algorithm()
     127             : {
     128             :   // ready_sim problem amounts to GCPP previous reduction
     129          16 :   ready2sim_reduction();
     130          16 :   partitioning_algorithmG();
     131          16 : }
     132             : 
     133             : /* ----------------- REFINE ----------------------------------------- */
     134             : 
     135             : /* PRE: s_Sigma = s_Pi = 1 */
     136             : template <class LTS_TYPE>
     137          16 : void ready_sim_partitioner<LTS_TYPE>::refinei()
     138             : {
     139             :   using namespace mcrl2::core;  
     140             :   /* Initialise the parent and children functions */
     141          16 :   std::vector<std::size_t> v;
     142          16 :   children.clear();
     143          16 :   children.assign(s_Pi,v);
     144          16 :   parent.clear();
     145          16 :   parent.assign(s_Pi,UNIVERSAL_PART);
     146             :   std::size_t alpha;
     147          32 :   for (alpha = 0; alpha < s_Pi; ++alpha)
     148             :   {
     149          16 :     children[alpha].push_back(alpha);
     150          16 :     parent[alpha] = alpha;
     151             :   }
     152             : 
     153          16 :   if (mCRL2logEnabled(log::debug))
     154             :   {
     155           0 :     mCRL2log(log::debug) << "---------------- Refinei ---------------------------------------" << std::endl;
     156           0 :     mCRL2log(log::debug) << print_Sigma_P();
     157             :   }
     158             : 
     159             :   /* Some local variables */
     160          16 :   std::vector<std::size_t>::iterator alphai, last;
     161             :   std::size_t l;  
     162             : 
     163             :   /* The main loop */  
     164          80 :   for (l = 0; l < aut.num_action_labels(); ++l)
     165             :   {
     166          64 :     mCRL2log(log::debug) << "---------------------------------------------------" << std::endl;
     167          64 :     mCRL2log(log::debug) << "Label = \"" << mcrl2::lts::pp(aut.action_label(l)) << "\"" << std::endl;
     168             : 
     169          64 :     touched_blocks.clear();
     170          64 :     initialise_Sigma(UNIVERSAL_PART,l);  // Interested on {N} E<-l- alpha
     171             :     
     172             :     /* iterate over all alpha such that {N} E<-l- alpha  */
     173          64 :     last = touched_blocks.end();
     174         125 :     for (alphai = touched_blocks.begin(); alphai != last; ++alphai)
     175             :       {
     176          61 :         alpha = *alphai;
     177             :         /* if {N} A<-l- alpha then alpha cannot be split */
     178          61 :         if (contents_u[alpha] != LIST_END)
     179             :           {
     180             :             /* split alpha; new block will be s_Pi */
     181          58 :             children[parent[alpha]].push_back(s_Pi);  
     182          58 :             parent.push_back(parent[alpha]);
     183          58 :             block_touched.push_back(false);
     184          58 :             contents_t.push_back(LIST_END);
     185             :               
     186             :             /* assign the untouched contents of alpha to s_Pi */
     187          58 :             contents_u.push_back(contents_u[alpha]);
     188          58 :             contents_u[alpha] = LIST_END;
     189             :               
     190             :             /* update the block information for the moved states */
     191         389 :             for (ptrdiff_t i = contents_u[s_Pi]; i != LIST_END;
     192         331 :                  i = state_buckets[i].next)
     193             :               {
     194         331 :                 block_Pi[i] = s_Pi;
     195             :               }
     196          58 :             ++s_Pi;
     197             :           }
     198          61 :         untouch(alpha); 
     199             :       }
     200             :   }
     201          16 : }
     202             : 
     203             :  
     204             : /* ----------------- UPDATEI ----------------------------------------- */
     205             : template <class LTS_TYPE>
     206          16 : void ready_sim_partitioner<LTS_TYPE>::updatei()
     207             : {
     208             :   using namespace mcrl2::core;
     209          16 :   mCRL2log(log::debug) << "---------------  Updatei ---------------------------------------" << std::endl;
     210             :   
     211             :   std::size_t l,alpha,gamma;
     212          16 :   std::vector<std::size_t>::iterator alphai, last;
     213             : 
     214          16 :   induce_P_on_Pi(); 
     215             : 
     216          16 :   exists2->clear();
     217          16 :   forall2->clear();
     218             : 
     219          80 :   for (l = 0; l < aut.num_action_labels(); ++l)
     220             :   {
     221         128 :     for (gamma = 0; gamma < s_Sigma; ++gamma) 
     222             :     {
     223          64 :       touched_blocks.clear();
     224          64 :       initialise_Sigma(gamma,l); 
     225          64 :       last = touched_blocks.end(); 
     226         138 :       for (alphai = touched_blocks.begin(); alphai != last; ++alphai)
     227             :       {
     228          74 :         alpha = *alphai;
     229          74 :         exists2->add(alpha,l); 
     230          74 :         if (contents_u[alpha] == LIST_END)
     231             :           {
     232          74 :             forall2->add(alpha,l);
     233             :           }
     234          74 :         untouch(alpha);
     235             :       }
     236             :     }
     237             :   }
     238             : 
     239          16 :   mCRL2log(log::debug) << "------ Before Filter ------\nExists2: ";
     240          16 :   mCRL2log(log::debug) << print_structure(exists2);
     241          16 :   mCRL2log(log::debug) << "\nForall2: ";
     242          16 :   mCRL2log(log::debug) << print_structure(forall2);
     243          16 :   mCRL2log(log::debug) << "\nReady Preorder: ";
     244          16 :   mCRL2log(log::debug) << print_relation(s_Pi,Q);  
     245             : 
     246             :   std::size_t beta;
     247             : 
     248             :   /* Apply the filtering to discard non "ready-init" pairs,
     249             :    * in Q[alpha][beta], i.e.,  when
     250             :    * {N} E<-l- Beta and not {N} A<-l- Alpha
     251             :    */
     252          80 :   for (l = 0; l < aut.num_action_labels(); ++l)
     253             :   {
     254         360 :     for (beta = 0; beta < s_Pi; ++beta) 
     255             :     {
     256         296 :       if (exists2->find(beta,l)) 
     257             :         {
     258         420 :           for (alpha = 0; alpha < s_Pi; ++alpha)
     259         346 :           if (Q[alpha][beta] && !forall2->find(alpha,l))
     260         191 :             Q[alpha][beta] = false ;
     261             :         }
     262             :     }
     263             :   };
     264             : 
     265          16 :   mCRL2log(log::debug) << "-----  After Filter ------\nExists2: ";
     266          16 :   mCRL2log(log::debug) << print_structure(exists2);
     267          16 :   mCRL2log(log::debug) << "\nForall2: ";
     268          16 :   mCRL2log(log::debug) << print_structure(forall2);
     269          16 :   mCRL2log(log::debug) << "\nReady Preorder: ";
     270          16 :   mCRL2log(log::debug) << print_relation(s_Pi,Q);  
     271          16 : }
     272             : 
     273             : template <class LTS_TYPE>
     274           0 : std::string ready_sim_partitioner<LTS_TYPE>::print_structure(hash_table2* struc)
     275             : {
     276             :   using namespace mcrl2::core;
     277           0 :   std::stringstream result;
     278           0 :   result << "{";
     279           0 :   hash_table2_iterator i(struc);
     280           0 :   for (; !i.is_end(); ++i)
     281             :   {
     282           0 :     result << "(" << i.get_x() << "," << mcrl2::lts::pp(aut.action_label(i.get_y()))<< "),";
     283             :   }
     284           0 :   result << "}";
     285           0 :   return result.str();  
     286           0 : }
     287             : 
     288             : template <class LTS_TYPE>
     289          16 : ready_sim_partitioner<LTS_TYPE>::~ready_sim_partitioner()
     290             : {
     291          16 :   delete exists2;
     292          16 :   delete forall2;
     293          32 : }
     294             : 
     295             :  
     296             : } // namespace detail
     297             : } // namespace lts
     298             : } // namespacemcrl2
     299             : #endif

Generated by: LCOV version 1.14