LCOV - code coverage report
Current view: top level - pbes/include/mcrl2/pbes - normalize.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 70 78 89.7 %
Date: 2024-04-26 03:18:02 Functions: 13 15 86.7 %
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/normalize.h
      10             : /// \brief Normalization of pbes expressions.
      11             : 
      12             : #ifndef MCRL2_PBES_NORMALIZE_H
      13             : #define MCRL2_PBES_NORMALIZE_H
      14             : 
      15             : #include "mcrl2/data/consistency.h"
      16             : #include "mcrl2/pbes/builder.h"
      17             : #include "mcrl2/pbes/traverser.h"
      18             : 
      19             : namespace mcrl2
      20             : {
      21             : 
      22             : namespace pbes_system
      23             : {
      24             : 
      25             : /// \cond INTERNAL_DOCS
      26             : // \brief Visitor for checking if a pbes expression is normalized.
      27             : struct is_normalized_traverser: public pbes_expression_traverser<is_normalized_traverser>
      28             : {
      29             :   typedef pbes_expression_traverser<is_normalized_traverser> super;
      30             :   using super::enter;
      31             :   using super::leave;
      32             :   using super::apply;
      33             : 
      34             :   bool result;
      35             : 
      36         137 :   is_normalized_traverser()
      37         137 :     : result(true)
      38         137 :   {}
      39             : 
      40             :   /// \brief Visit not node
      41           0 :   void enter(const not_& /* x */)
      42             :   {
      43           0 :     result = false;
      44           0 :   }
      45             : 
      46             :   /// \brief Visit imp node
      47           0 :   void enter(const imp& /* x */)
      48             :   {
      49           0 :     result = false;
      50           0 :   }
      51             : };
      52             : /// \endcond
      53             : 
      54             : /// \cond INTERNAL_DOCS
      55             : // \brief Visitor for checking if a pbes expression is normalized.
      56             : struct normalize_builder: public pbes_expression_builder<normalize_builder>
      57             : {
      58             :   typedef pbes_expression_builder<normalize_builder> super;
      59             :   using super::apply;
      60             : 
      61             :   bool negated;
      62             : 
      63         436 :   normalize_builder()
      64         436 :     : negated(false)
      65         436 :   {}
      66             : 
      67             :   template <class T>
      68        2532 :   void apply(T& result, const data::data_expression& x)
      69             :   {
      70        2532 :     result = negated ? data::not_(x) : x;
      71        2532 :   }
      72             : 
      73             :   template <class T>
      74         139 :   void apply(T& result, const not_& x)
      75             :   {
      76         139 :     negated = !negated;
      77         139 :     super::apply(result, x.operand());
      78         139 :     negated = !negated;
      79         139 :   }
      80             : 
      81             :   template <class T>
      82        1850 :   void apply(T& result, const and_& x)
      83             :   {
      84        1850 :     pbes_expression left;
      85        1850 :     super::apply(left, x.left());
      86        1850 :     pbes_expression right;
      87        1850 :     super::apply(right, x.right());
      88        1850 :     if (negated)
      89             :     {
      90          46 :       make_or_(result, left, right);
      91             :     }
      92             :     else
      93             :     {
      94        1804 :       make_and_(result, left, right);
      95             :     }
      96        1850 :   }
      97             : 
      98             :   template <class T>
      99        1067 :   void apply(T& result, const or_& x)
     100             :   {
     101        1067 :     pbes_expression left;
     102        1067 :     super::apply(left, x.left());
     103        1067 :     pbes_expression right;
     104        1067 :     super::apply(right, x.right());
     105        1067 :     if (negated)
     106             :     {
     107          36 :       make_and_(result, left, right);
     108             :     }
     109             :     else
     110             :     {
     111        1031 :       make_or_(result, left, right);
     112             :     }
     113        1067 :   }
     114             : 
     115             :   template <class T>
     116         586 :   void apply(T& result, const imp& x)
     117             :   {
     118         586 :     negated = !negated;
     119         586 :     pbes_expression left;
     120         586 :     super::apply(left, x.left());
     121         586 :     negated = !negated;
     122         586 :     pbes_expression right;
     123         586 :     super::apply(right, x.right());
     124         586 :     if (negated)
     125             :     {
     126           8 :       make_and_(result, left, right);
     127             :     }
     128             :     else
     129             :     {
     130         578 :       make_or_(result, left, right);
     131             :     }
     132         586 :   }
     133             : 
     134             :   template <class T>
     135         390 :   void apply(T& result, const forall& x)
     136             :   {
     137         390 :     pbes_expression body;
     138         390 :     super::apply(body, x.body());
     139         390 :     result = negated ? make_exists_(x.variables(), body) : make_forall_(x.variables(), body);
     140         390 :   }
     141             : 
     142             :   template <class T>
     143         438 :   void apply(T& result, const exists& x)
     144             :   {
     145         438 :     pbes_expression body;
     146         438 :     super::apply(body, x.body());
     147         438 :     result = negated ? make_forall_(x.variables(), body) : make_exists_(x.variables(), body);
     148         438 :   }
     149             : 
     150             :   template <class T>
     151        1948 :   void apply(T& result, const propositional_variable_instantiation& x)
     152             :   {
     153        1948 :     if (negated)
     154             :     {
     155           0 :       throw mcrl2::runtime_error(std::string("normalize error: illegal argument ") + pp(x));
     156             :     }
     157        1948 :     result = x;
     158        1948 :   }
     159             : };
     160             : /// \endcond
     161             : 
     162             : /// \brief Checks if a pbes expression is normalized
     163             : /// \param x A PBES expression
     164             : /// \return True if the pbes expression is normalized
     165             : template <typename T>
     166         137 : bool is_normalized(const T& x)
     167             : {
     168         137 :   is_normalized_traverser f;
     169         137 :   f.apply(x);
     170         137 :   return f.result;
     171             : }
     172             : 
     173             : /// \brief The function normalize brings (embedded) pbes expressions into positive normal form,
     174             : /// i.e. a formula without any occurrences of ! or =>.
     175             : /// \param x an object containing pbes expressions
     176             : template <typename T>
     177         428 : void normalize(T& x,
     178             :                typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value>::type* = nullptr
     179             :               )
     180             : {
     181         428 :   normalize_builder f;
     182         428 :   f.update(x);
     183         428 : }
     184             : 
     185             : /// \brief The function normalize brings (embedded) pbes expressions into positive normal form,
     186             : /// i.e. a formula without any occurrences of ! or =>.
     187             : /// \param x an object containing pbes expressions
     188             : template <typename T>
     189           8 : T normalize(const T& x,
     190             :             typename std::enable_if< std::is_base_of< atermpp::aterm, T >::value>::type* = nullptr
     191             :            )
     192             : {
     193           8 :   T result;
     194           8 :   normalize_builder f;
     195           8 :   f.apply(result, x);
     196          16 :   return result;
     197           0 : }
     198             : 
     199             : } // namespace pbes_system
     200             : 
     201             : } // namespace mcrl2
     202             : 
     203             : #endif // MCRL2_PBES_NORMALIZE_H

Generated by: LCOV version 1.14