LCOV - code coverage report
Current view: top level - lts/include/mcrl2/lts/detail - counter_example.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 10 62 16.1 %
Date: 2024-04-26 03:18:02 Functions: 5 14 35.7 %
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             : /// \file lts/detail/liblts_liblts_counter_example.h
      10             : /// \details This file contains a class in which counter examples 
      11             : ///          for divergence preserving failures refinement can 
      12             : ///          be constructed. A counterexample is a trace from 
      13             : ///          the root. The data structure to construct such a 
      14             : ///          trace is a tree pointing to the root where each branch
      15             : ///          is labelled with an action. By walking from a leaf to
      16             : ///          the root the desired counterexample can be constructed.
      17             : 
      18             : #ifndef _LIBLTS_COUNTER_EXAMPLE_H
      19             : #define _LIBLTS_COUNTER_EXAMPLE_H
      20             : 
      21             : #include "mcrl2/lts/lts_lts.h"
      22             : #include "mcrl2/lts/trace.h"
      23             : 
      24             : 
      25             : namespace mcrl2
      26             : {
      27             : namespace lts
      28             : {
      29             : 
      30             : namespace detail
      31             : {
      32             : 
      33             : 
      34             : /// \brief A simple class storing the index of a label and an index
      35             : //         to the counterexample three in the direction of the root.
      36             : class action_index_pair
      37             : {
      38             :   protected:
      39             :     std::size_t m_label_index;
      40             :     std::size_t m_previous_entry_index;
      41             : 
      42             :   public:
      43           0 :     action_index_pair(std::size_t label_index, std::size_t previous_entry_index)
      44           0 :      : m_label_index(label_index), 
      45           0 :        m_previous_entry_index(previous_entry_index)
      46           0 :     {}
      47             : 
      48           0 :     std::size_t label_index() const
      49             :     {
      50           0 :       return m_label_index;
      51             :     }
      52             : 
      53           0 :     std::size_t previous_entry_index() const
      54             :     {
      55           0 :       return m_previous_entry_index;
      56             :     }
      57             : };
      58             : 
      59             : /// \brief A class that can be used to store counterexample trees and 
      60             : //         from which a counterexample trace can be extracted.
      61             : class counter_example_constructor
      62             : {
      63             :   public:
      64             :     typedef std::size_t index_type;
      65             : 
      66             :   protected:
      67             :     // The backward three is stored in a deque. 
      68             :     // The root has entry std::size_t(-1).
      69             : 
      70             :     static const index_type m_root_index=-1;
      71             :     std::deque< action_index_pair > m_backward_tree;
      72             :     const std::string m_name;
      73             :     const std::string m_counter_example_file;
      74             :     const bool m_structured_output;
      75             :   
      76             :   public:
      77             :     /// \brief Constructor
      78             :     //  \param name The name of the model that the counter example is for
      79             :     //  \param counter_example_file The name of the file to save the counter example to
      80             :     //  \param structured_output Whether the counterexample should be printed to std:cout
      81             :     //  \detail If structured_output=true, the counter example is not saved to file.
      82             :     //          If counter_example_file="", the name of the counter example file name is derived from name (the parameter)
      83           0 :     counter_example_constructor(const std::string& name, const std::string& counter_example_file, bool structured_output)
      84           0 :      : m_name(name)
      85           0 :      , m_counter_example_file(counter_example_file)
      86           0 :      , m_structured_output(structured_output)
      87           0 :     {}
      88             : 
      89             :     /// \brief Return the index of the root.
      90           0 :     static index_type root_index() 
      91             :     {
      92           0 :       return m_root_index;
      93             :     }
      94             : 
      95             :     /// \brief This function stores a label to the counterexample tree.
      96             :     //  \param label_index The label index is the label as used in transitions.
      97             :     //  \param previous_entry The index of the counterexample trace to which
      98             :     //                        this action label must be attached.
      99             :     //  \ret It returns a new index which can be used to extend the counterexample.
     100           0 :     index_type add_transition(std::size_t label_index, index_type previous_entry)
     101             :     {
     102           0 :       m_backward_tree.emplace_back(label_index, previous_entry);
     103           0 :       return m_backward_tree.size()-1;
     104             :     }
     105             : 
     106             :     /* A trace to index is saved, followed by a list of actions in extra_actions. */
     107             :     template < class LTS_TYPE >
     108           0 :     void save_counter_example(index_type index, const LTS_TYPE& l, const std::vector<size_t>& extra_actions=std::vector<size_t>()) const
     109             :     {
     110             :       // We first store the label indices in reverse order in a stack.
     111           0 :       std::stack< index_type > reversed_label_indices;
     112           0 :       for(index_type current_index=index; 
     113           0 :           current_index!=m_root_index; 
     114           0 :           current_index=m_backward_tree[current_index].previous_entry_index())
     115             :       {
     116           0 :         reversed_label_indices.push(m_backward_tree[current_index].label_index());
     117             :       }
     118             : 
     119           0 :       trace result;
     120           0 :       while (!reversed_label_indices.empty())
     121             :       {
     122           0 :         result.add_action(mcrl2::lps::multi_action(mcrl2::process::action(
     123           0 :                                 mcrl2::process::action_label(
     124           0 :                                        core::identifier_string(mcrl2::lts::pp(l.action_label(reversed_label_indices.top()))),
     125           0 :                                        mcrl2::data::sort_expression_list()),
     126           0 :                                 mcrl2::data::data_expression_list())));
     127           0 :         reversed_label_indices.pop();
     128             :       }
     129             : 
     130             :       /* Add the actions in extra actions. */
     131           0 :       for(const size_t& a: extra_actions)
     132             :       {
     133           0 :         result.add_action(mcrl2::lps::multi_action(mcrl2::process::action(
     134           0 :                                 mcrl2::process::action_label(
     135           0 :                                        core::identifier_string(mcrl2::lts::pp(l.action_label(a))),
     136           0 :                                        mcrl2::data::sort_expression_list()),
     137           0 :                                 mcrl2::data::data_expression_list())));
     138             :       }
     139           0 :       if (m_structured_output)
     140             :       {
     141           0 :         std::cout << m_name << ": ";
     142           0 :         result.save("", mcrl2::lts::trace::tfLine);   // Write to stdout.
     143             :       }
     144             :       else
     145             :       {
     146           0 :         std::string filename = m_name + ".trc";
     147           0 :         if (!m_counter_example_file.empty())
     148             :         {
     149           0 :           filename = m_counter_example_file;
     150             :         }
     151           0 :         mCRL2log(log::verbose) << "Saved trace to file " + filename + "\n";
     152           0 :         result.save(filename);
     153           0 :       }
     154           0 :     }
     155             : 
     156             :     /// \brief This function indicates that this is not a dummy counterexample class and that a serious counterexample is required.
     157           0 :     bool is_dummy() const
     158             :     {
     159           0 :       return false;
     160             :     }
     161             : 
     162             :     /// \brief Returns whether this counter-example is printed in a machine-readable way to stdout
     163             :     /// If false is returned, the counter-example is written to a file.
     164           0 :     bool is_structured() const
     165             :     {
     166           0 :       return m_structured_output;
     167             :     }
     168             : };
     169             : 
     170             : 
     171             : /// \brief A class that can be used to construct counter examples if no
     172             : //         counter example is desired. Its index_type is empty.
     173             : class dummy_counter_example_constructor
     174             : {
     175             :   public:
     176             :     typedef dummy_counter_example_constructor index_type;  // This yields an empty type.
     177             : 
     178          48 :     static index_type root_index()
     179             :     {
     180          48 :       return dummy_counter_example_constructor();  // This returns nothing. 
     181             :     }
     182             : 
     183         188 :     index_type add_transition(std::size_t /* label_index*/, index_type /* previous_entry*/)
     184             :     {
     185             :       // This dummy counter example generator intentionally does nothing.
     186         188 :       return *this;
     187             :     }
     188             :  
     189             :     template < class LTS_TYPE >
     190          21 :     void save_counter_example(index_type /* index */, const LTS_TYPE& /*l*/, const std::vector<size_t>& /* extra_actions */ =std::vector<size_t>()) const
     191             :     {
     192             :       // This dummy counter example generator intentionally does not save anything.
     193          21 :     }
     194             : 
     195             :     /// \brief This function indicates that this is a dummy counterexample class and that no counterexample is required.
     196         215 :     bool is_dummy() const
     197             :     {
     198         215 :       return true;
     199             :     }
     200             : 
     201             :     /// \brief Returns whether this counter-example is printed in a machine-readable way to stdout
     202             :     /// If false is returned, the counter-example is written to a file.
     203         103 :     bool is_structured() const
     204             :     {
     205         103 :       return false;
     206             :     }
     207             : };
     208             : 
     209             : } // namespace detail
     210             : } // namespace lts
     211             : } // namespace mcrl2
     212             : 
     213             : #endif // _LIBLTS_COUNTER_EXAMPLE_H

Generated by: LCOV version 1.14