LCOV - code coverage report
Current view: top level - pbes/include/mcrl2/pbes/detail - stategraph_global_algorithm.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 0 89 0.0 %
Date: 2024-04-19 03:43:27 Functions: 0 7 0.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/pbes/detail/stategraph_global_algorithm.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_ALGORITHM_H
      13             : #define MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_ALGORITHM_H
      14             : 
      15             : #include "mcrl2/data/substitutions/sequence_sequence_substitution.h"
      16             : #include "mcrl2/pbes/algorithms.h"
      17             : #include "mcrl2/pbes/detail/stategraph_algorithm.h"
      18             : #include "mcrl2/pbes/detail/stategraph_global_graph.h"
      19             : 
      20             : namespace mcrl2 {
      21             : 
      22             : namespace pbes_system {
      23             : 
      24             : namespace detail {
      25             : 
      26             : /// \brief Algorithm class for the global variant of the stategraph algorithm
      27             : class stategraph_global_algorithm: public stategraph_algorithm
      28             : {
      29             :   public:
      30             :     typedef stategraph_algorithm super;
      31             : 
      32             :   protected:
      33             :     // the control flow graph
      34             :     global_control_flow_graph m_control_flow_graph;
      35             : 
      36             :     // eq_X is the equation corresponding to u = (X, e)
      37             :     // eq_Y is the equation corresponding to Yf
      38           0 :     bool enabled_edge(const global_control_flow_graph_vertex& u, const stategraph_equation& eq_X, const predicate_variable& Yf)
      39             :     {
      40           0 :       auto const& e = u.values();
      41           0 :       auto const& cfp_X = eq_X.control_flow_parameter_indices();
      42           0 :       for (std::size_t k = 0; k < cfp_X.size(); k++)
      43             :       {
      44           0 :         auto q = Yf.source(cfp_X[k]);
      45           0 :         if (q != data::undefined_data_expression() && q != nth_element(e, k))
      46             :         {
      47           0 :           return false;
      48             :         }
      49           0 :       }
      50           0 :       return true;
      51             :     }
      52             : 
      53             :     // Returns k such that cfp[k] == l. Throws an exception if no such k exists.
      54           0 :     std::size_t unproject(const predicate_variable& Yf, const std::vector<std::size_t>& cfp, std::size_t l) const
      55             :     {
      56           0 :       mCRL2log(log::trace) << "stategraph_global_algorithm::unproject: cfp = " << core::detail::print_list(cfp) << " l = " << l << std::endl;
      57           0 :       for (std::size_t k = 0; k < cfp.size(); k++)
      58             :       {
      59           0 :         if (Yf.copy(cfp[k]) == l)
      60             :         {
      61           0 :           return k;
      62             :         }
      63             :       }
      64           0 :       throw mcrl2::runtime_error("no index found in stategraph_global_algorithm::unproject");
      65             :     }
      66             : 
      67           0 :     const global_control_flow_graph_vertex& compute_vertex(global_control_flow_graph& G, const global_control_flow_graph_vertex& u, const stategraph_equation& eq_X, const predicate_variable& Yf, const stategraph_equation& eq_Y)
      68             :     {
      69           0 :       data::data_expression_vector f;
      70           0 :       auto const& X = u.name();
      71           0 :       auto const& e = u.values();
      72           0 :       auto const& cfp_X = eq_X.control_flow_parameter_indices();
      73           0 :       auto const& cfp_Y = eq_Y.control_flow_parameter_indices();
      74             : 
      75           0 :       mCRL2log(log::trace) << "compute_vertex u = (X, e) = (" << X << ", " << core::detail::print_list(e) << "), Y(f) = " << Yf << std::endl;
      76           0 :       mCRL2log(log::trace) << "cfp_X = " << core::detail::print_list(cfp_X) << std::endl;
      77           0 :       mCRL2log(log::trace) << "cfp_Y = " << core::detail::print_list(cfp_Y) << std::endl;
      78             : 
      79           0 :       for (std::size_t l = 0; l < cfp_Y.size(); l++)
      80             :       {
      81           0 :         auto q = Yf.target(cfp_Y[l]);
      82           0 :         if (q != data::undefined_data_expression())
      83             :         {
      84           0 :           mCRL2log(log::trace) << "q = " << q << std::endl;
      85           0 :           f.push_back(q);
      86             :         }
      87             :         else
      88             :         {
      89           0 :           mCRL2log(log::trace) << "q = undefined" << std::endl;
      90             :           // Compute k such that (X, k) and (Y, l) are related. This implies copy(X, i, cfp_X[k]) == cfp_Y[l].
      91             :           //                                                                 Yf.copy[cfp_X[k]] = cfp_Y[l]
      92           0 :           auto p = cfp_Y[l];
      93           0 :           mCRL2log(log::trace) << "Yf = " << Yf << "\n" << Yf.print() << " l = " << l << " Yf.copy(" << l << ") = " << p << std::endl;
      94           0 :           assert(p != data::undefined_index());
      95           0 :           std::size_t k = unproject(Yf, cfp_X, p);
      96           0 :           assert(k < e.size());
      97           0 :           f.push_back(nth_element(e, k));
      98             :         }
      99           0 :       }
     100           0 :       return G.insert_vertex(global_control_flow_graph_vertex(Yf.variable().name(), data::data_expression_list(f.begin(), f.end())));
     101           0 :     }
     102             : 
     103           0 :     void compute_significant_variables()
     104             :     {
     105           0 :       pbes_system::simplify_data_rewriter<data::rewriter> pbesr(m_datar);
     106           0 :       for (const auto& u : m_control_flow_graph)
     107             :       {
     108           0 :         auto const& X = u.name();
     109           0 :         auto const& eq_X = *find_equation(m_pbes, X);
     110           0 :         auto const& d = eq_X.control_flow_parameters();
     111           0 :         auto const& e = u.values();
     112           0 :         assert(d.size() == e.size());
     113           0 :         data::sequence_sequence_substitution<data::variable_vector, data::data_expression_list> sigma(d, e);
     114           0 :         u.set_significant_variables(pbes_system::algorithms::significant_variables(pbesr(eq_X.formula(), sigma)));
     115             :       }
     116           0 :     }
     117             : 
     118           0 :     void compute_global_control_flow_graph()
     119             :     {
     120             :       using utilities::detail::contains;
     121             :       using utilities::detail::pick_element;
     122             : 
     123           0 :       mCRL2log(log::debug) << "=== compute control flow graph ===" << std::endl;
     124           0 :       std::set<const global_control_flow_graph_vertex*> todo;
     125           0 :       std::set<const global_control_flow_graph_vertex*> done;
     126             : 
     127             :       // initialize todo
     128           0 :       auto const& Xinit = m_pbes.initial_state();
     129           0 :       auto const& eq_Xinit = *find_equation(m_pbes, Xinit.name());
     130           0 :       auto einit = eq_Xinit.project(Xinit.parameters());
     131           0 :       auto const& w = m_control_flow_graph.insert_vertex(global_control_flow_graph_vertex(Xinit.name(), einit));
     132           0 :       todo.insert(&w);
     133             : 
     134           0 :       while (!todo.empty())
     135             :       {
     136             :         // u = (X, e)
     137           0 :         auto const& u = *pick_element(todo);
     138           0 :         auto const& X = u.name();
     139           0 :         auto const& eq_X = *find_equation(m_pbes, X);
     140           0 :         auto const& predvars = eq_X.predicate_variables();
     141             : 
     142           0 :         mCRL2log(log::trace) << "choose todo element " << u << std::endl;
     143             : 
     144           0 :         for (std::size_t i = 0; i < predvars.size(); i++)
     145             :         {
     146           0 :           auto const& Yf = predvars[i];
     147           0 :           auto const& Y = Yf.variable().name();
     148           0 :           auto const& eq_Y = *find_equation(m_pbes, Y);
     149           0 :           if (enabled_edge(u, eq_X, Yf))
     150             :           {
     151           0 :             const global_control_flow_graph_vertex& v = compute_vertex(m_control_flow_graph, u, eq_X, Yf, eq_Y);
     152           0 :             m_control_flow_graph.insert_edge(u, i, v);
     153           0 :             if (!contains(done, &v))
     154             :             {
     155           0 :               mCRL2log(log::trace) << "insert todo element " << v << std::endl;
     156           0 :               todo.insert(&v);
     157           0 :               done.insert(&v);
     158             :             }
     159             :           }
     160             :         }
     161             :       }
     162           0 :       m_control_flow_graph.compute_index();
     163           0 :       compute_significant_variables();
     164           0 :       mCRL2log(log::debug) << "--- global control flow graph ---\n" << m_control_flow_graph << std::endl;
     165           0 :     }
     166             : 
     167             :   public:
     168           0 :     stategraph_global_algorithm(const pbes& p, const pbesstategraph_options& options)
     169           0 :       : stategraph_algorithm(p, options)
     170           0 :     { }
     171             : 
     172             :     /// \brief Computes the control flow graph
     173           0 :     void run() override
     174             :     {
     175           0 :       super::run();
     176           0 :       start_timer("compute_global_control_flow_graph");
     177           0 :       compute_global_control_flow_graph();
     178           0 :       finish_timer("compute_global_control_flow_graph");
     179           0 :     }
     180             : 
     181             :     const global_control_flow_graph& global_graph() const
     182             :     {
     183             :       return m_control_flow_graph;
     184             :     }
     185             : };
     186             : 
     187             : } // namespace detail
     188             : 
     189             : } // namespace pbes_system
     190             : 
     191             : } // namespace mcrl2
     192             : 
     193             : #endif // MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_ALGORITHM_H

Generated by: LCOV version 1.14