LCOV - code coverage report
Current view: top level - pbes/include/mcrl2/pbes/detail - parity_game_output.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 27 29 93.1 %
Date: 2024-04-21 03:44:01 Functions: 2 2 100.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/parity_game_output.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #include "mcrl2/pbes/parity_game_generator.h"
      13             : #include <boost/algorithm/string/join.hpp>
      14             : 
      15             : #ifndef MCRL2_PBES_DETAIL_PARITY_GAME_OUTPUT_H
      16             : #define MCRL2_PBES_DETAIL_PARITY_GAME_OUTPUT_H
      17             : 
      18             : namespace mcrl2
      19             : {
      20             : 
      21             : namespace pbes_system
      22             : {
      23             : 
      24             : namespace detail
      25             : {
      26             : 
      27             : /// A class that generates python code for a parity game, such
      28             : /// that it can be solved with a parity game solver written in
      29             : /// python.
      30             : class parity_game_output: public parity_game_generator
      31             : {
      32             :   protected:
      33             :     /// The vertices of the parity game graph.
      34             :     std::set<std::size_t> V;
      35             : 
      36             :     /// The edges of the parity game graph.
      37             :     std::set<std::pair<std::size_t, std::size_t> > E;
      38             : 
      39             :     /// The vertex priorities of the parity game graph.
      40             :     std::map<std::size_t, std::size_t> priorities;
      41             : 
      42             :     /// The even vertices of the parity game graph.
      43             :     std::set<std::size_t> even_vertices;
      44             : 
      45             :     /// The odd vertices of the parity game graph.
      46             :     std::set<std::size_t> odd_vertices;
      47             : 
      48             :     /// \brief Returns the quoted name of the vertex, for example "X1"
      49             :     /// \param i A positive integer
      50             :     /// \return The quoted name of the vertex, for example "X1"
      51             :     std::string vertex(std::size_t i) const
      52             :     {
      53             :       return "\"X" + utilities::number2string(i+1) + "\"";
      54             :     }
      55             : 
      56             :     /// \brief Returns a tuple representing an edge, for example ("X1", "X2")
      57             :     /// \param e An edge
      58             :     /// \return A tuple representing an edge, for example ("X1", "X2")
      59             :     std::string edge(std::pair<std::size_t, std::size_t> e) const
      60             :     {
      61             :       return "(" + vertex(e.first) + ", " + vertex(e.second) + ")";
      62             :     }
      63             : 
      64             :     /// \brief Returns a string representing a priority, for example "X1":0
      65             :     /// \param p A pair of integers
      66             :     /// \return A string representing a priority, for example "X1":0
      67             :     std::string priority(std::pair<std::size_t, std::size_t> p) const
      68             :     {
      69             :       return vertex(p.first) + ":" + utilities::number2string(p.second);
      70             :     }
      71             : 
      72             :     /// \brief Applies a function to the elements of a container
      73             :     /// \param c A container
      74             :     /// \param f A function
      75             :     /// \return The transformed container
      76             :     template <typename Container, typename Function>
      77             :     std::vector<std::string> apply(const Container& c, const Function& f) const
      78             :     {
      79             :       std::vector<std::string> result;
      80             :       for (auto i = c.begin(); i != c.end(); ++i)
      81             :       {
      82             :         result.push_back(f(*i));
      83             :       }
      84             :       return result;
      85             :     }
      86             : 
      87             :     /// \brief Prints the elements of a container with a separator between them
      88             :     /// \param c A container
      89             :     /// \param sep A string
      90             :     /// \return The joined elements
      91             :     template <typename Container>
      92             :     std::string join(const Container& c, const std::string& sep) const
      93             :     {
      94             :       std::ostringstream out;
      95             :       for (auto i = c.begin(); i != c.end(); ++i)
      96             :       {
      97             :         out << (i == c.begin() ? "" : sep) << *i;
      98             :       }
      99             :       return out.str();
     100             :     }
     101             : 
     102             :     /// \brief Wraps a sequence of strings in a Python set.
     103             :     /// \param elements A vector of strings
     104             :     /// \return The Python set representation
     105             :     std::string python_set(const std::vector<std::string>& elements) const
     106             :     {
     107             :       return "set([" + join(elements, ", ") +  "])";
     108             :     }
     109             : 
     110             :     /// \brief Prints the todo list
     111             :     /// \param name A string
     112             :     /// \param todo A todo list
     113             :     void print_set(const std::string& name, const std::set<std::size_t>& todo) const
     114             :     {
     115             :       mCRL2log(log::verbose) << name << " = {";
     116             :       for (auto i = todo.begin(); i != todo.end(); ++i)
     117             :       {
     118             :         mCRL2log(log::verbose) << (i == todo.begin() ? "" : ", ") << *i;
     119             :       }
     120             :       mCRL2log(log::verbose) << "}" << std::endl;
     121             :     }
     122             : 
     123             :   public:
     124          12 :     explicit parity_game_output(pbes& p, bool min_parity_game = true)
     125          12 :       : parity_game_generator(p, true, min_parity_game)
     126          12 :     {}
     127             : 
     128             :     // Example:
     129             :     // set(["X1", "X2", "X3", "X4", "X5"])
     130             :     // set([("X1", "X2"), ("X2", "X1"), ("X2", "X3"), ("X3", "X4"), ("X3", "X5"), ("X4", "X1"), ("X5", "X3"), ("X5", "X1")])
     131             :     // {"X1":0, "X2":1, "X3":2, "X4":1, "X5":3}
     132             :     // set(["X3", "X4"])
     133             :     // set(["X1", "X2", "X5"])
     134             :     //
     135             :     // Line 1: set of vertices
     136             :     // Line 2: set of edges
     137             :     // Line 3: dictionary of priorities
     138             :     // Line 4: set of vertices for player even
     139             :     // Line 5: set of vertices for player oneven
     140             :     /// \brief Returns a representation of the parity game in python format.
     141             :     /// This code is used as input for a python parity game solver.
     142             :     /// \return A representation of the parity game in python format.
     143             :     std::string python_graph()
     144             :     {
     145             :       std::string result;
     146             :       result = result + python_set(apply(V, [&](std::size_t i) { return vertex(i); })) + "\n";
     147             :       result = result + python_set(apply(E, [&](std::pair<std::size_t, std::size_t> e) { return edge(e); })) + "\n";
     148             :       result = result + "{" + join(apply(priorities, [&](std::pair<std::size_t, std::size_t> p) { return priority(p); }), ", ") + "}\n";
     149             :       result = result + python_set(apply(even_vertices, [&](std::size_t i) { return vertex(i); })) + "\n";
     150             :       result = result + python_set(apply(odd_vertices, [&](std::size_t i) { return vertex(i); }));
     151             :       return result;
     152             :     }
     153             : 
     154             :     /// \brief Returns a representation of the parity game in Alpaga format.
     155             :     /// \return A representation of the parity game in Alpaga format.
     156             :     std::string pgsolver_graph()
     157             :     {
     158             :       std::vector<std::string> lines(V.size());
     159             :       for (std::size_t k: V)
     160             :       {
     161             :         lines[k] = std::to_string(k) + " " + utilities::number2string(priorities[k]) + " " + (odd_vertices.find(k) == odd_vertices.end() ? "0 " : "1 ");
     162             :       }
     163             :       for (const auto& i: E)
     164             :       {
     165             :         std::size_t k = i.first;
     166             :         std::size_t m = i.second;
     167             :         std::string& line = lines[k];
     168             :         line += ((line[line.size()-1] == ' ' ? "" : ", ") + utilities::number2string(m));
     169             :       }
     170             :       return join(lines, ";\n") + ";";
     171             :     }
     172             : 
     173             :     /// \brief Generates the parity game graph
     174          12 :     void run()
     175             :     {
     176          12 :       std::set<std::size_t> todo = get_initial_values();
     177          12 :       std::set<std::size_t> done;
     178         135 :       while (!todo.empty())
     179             :       {
     180             :         // handle vertex i
     181         123 :         std::size_t i = *todo.begin();
     182         123 :         todo.erase(i);
     183         123 :         done.insert(i);
     184         123 :         V.insert(i);
     185         123 :         std::size_t p = get_priority(i);
     186         123 :         priorities[i] = p;
     187         123 :         std::set<std::size_t> dep_i = get_dependencies(i);
     188         123 :         switch (get_operation(i))
     189             :         {
     190          36 :           case PGAME_AND:
     191          36 :             odd_vertices.insert(i);
     192          36 :             break;
     193          87 :           case PGAME_OR:
     194          87 :             even_vertices.insert(i);
     195          87 :             break;
     196           0 :           default:
     197           0 :             assert(false);
     198             :         }
     199             : 
     200         272 :         for (std::size_t j: dep_i)
     201             :         {
     202             :           // handle edge (i, *j)
     203         149 :           E.insert(std::make_pair(i, j));
     204         149 :           if (done.find(j) == done.end())
     205             :           {
     206          92 :             todo.insert(j);
     207             :           }
     208             :         }
     209         123 :       }
     210          12 :     }
     211             : };
     212             : 
     213             : } // namespace detail
     214             : 
     215             : } // namespace pbes_system
     216             : 
     217             : } // namespace mcrl2
     218             : 
     219             : #endif // MCRL2_PBES_DETAIL_PARITY_GAME_OUTPUT_H

Generated by: LCOV version 1.14