LCOV - code coverage report
Current view: top level - pbes/include/mcrl2/pbes/detail - bqnf_visitor.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 118 229 51.5 %
Date: 2024-04-26 03:18:02 Functions: 16 21 76.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Gijs Kant
       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/bqnf_visitor.h
      10             : /// \brief Visitor class for PBESs in Bounded Quantifier Normal Form (BQNF):
      11             : /// BQNF :== forall d: D . b => BQNF  |  exists d: D . b && BQNF  |  CONJ
      12             : /// CONJ :== And_{k: K} f_k && And_{i: I} forall v: D_I . g_i => DISJ^i
      13             : /// DISJ^i :== Or_{l: L_i} f_{il} || Or_{j: J_i} exists w: D_{ij} . g_{ij} && X_{ij}(e_{ij})
      14             : ///
      15             : /// DEPRECATED
      16             : #ifndef MCRL2_PBES_DETAIL_BQNF_VISITOR_H
      17             : #define MCRL2_PBES_DETAIL_BQNF_VISITOR_H
      18             : 
      19             : #include "mcrl2/pbes/pbes_functions.h"
      20             : 
      21             : namespace mcrl2 {
      22             : 
      23             : namespace pbes_system {
      24             : 
      25             : namespace detail {
      26             : 
      27             : /// \brief The current indent level. Used for debug output.
      28             : static int indent_count = 0;
      29             : /// \brief Increases the current indent level.
      30          26 : static void inc_indent()
      31             : {
      32          26 :   indent_count++;
      33          26 : }
      34             : /// \brief Decreases the current indent level.
      35          26 : static void dec_indent()
      36             : {
      37          26 :   indent_count--;
      38          26 : }
      39             : 
      40             : /// \brief Indents according to the current indent level.
      41           0 : static void indent()
      42             : {
      43           0 :   for(int i=0;i<indent_count;i++)
      44             :   {
      45           0 :     std::clog << "  ";
      46             :   }
      47           0 : }
      48             : 
      49             : /// \brief A visitor class for PBES equations in BQNF. There is a visit_<node>
      50             : /// function for each type of node. By default these functions do nothing, but check
      51             : /// that the PBES equations are indeed in BQNF, so they
      52             : /// must be overridden in order to add behaviour.
      53             : struct bqnf_visitor
      54             : {
      55             :   /// \brief flag that indicates if debug output should be printed.
      56             :   bool debug;
      57             : 
      58             :   /// \brief Returns a string representation of the type of the root node of the expression.
      59             :   /// \param e a PBES expression
      60             :   /// \return a string representation of the type of the root node of the expression.
      61           0 :   static std::string print_brief(const pbes_expression& e)
      62             :   {
      63           0 :     if (is_propositional_variable_instantiation(e)) {
      64           0 :       return std::string("PropVar ") + std::string(atermpp::down_cast<propositional_variable_instantiation>(e).name());
      65           0 :     } else if (is_simple_expression(e)) {
      66           0 :       return "SimpleExpr";
      67           0 :     } else if (is_and(e)) {
      68           0 :       return "And";
      69           0 :     } else if (is_or(e)) {
      70           0 :       return "Or";
      71           0 :     } else if (is_imp(e)) {
      72           0 :       return "Imp";
      73           0 :     } else if (is_forall(e)) {
      74           0 :       return std::string("ForAll(")+core::pp(atermpp::down_cast<forall>(e).variables())+std::string(")");
      75           0 :     } else if (is_exists(e)) {
      76           0 :       return std::string("Exists(")+core::pp(atermpp::down_cast<exists>(e).variables())+std::string(")");
      77             :     } else {
      78           0 :       return "Unknown type";
      79             :     }
      80             :   }
      81             : 
      82             :   /// \brief Determines if an expression if of the form
      83             :   /// phi /\ psi where phi is a simple expression
      84             :   /// and psi is an arbitrary expression.
      85             :   /// \param e an expression
      86             :   /// \return true if e is of the form phi /\ psi.
      87             :   static bool is_inner_and(const pbes_expression& e)
      88             :   {
      89             :     bool result = true;
      90             :     if (!(is_propositional_variable_instantiation(e) || is_simple_expression(e))) {
      91             :       if (is_and(e)) {
      92             :         pbes_expression l = pbes_system::accessors::left(e);
      93             :         pbes_expression r = pbes_system::accessors::right(e);
      94             :         if (is_simple_expression(l)) {
      95             :           result = is_inner_and(r);
      96             :         } else {
      97             :           result = false;
      98             :         }
      99             :       } else {
     100             :         result = false;
     101             :       }
     102             :     }
     103             :     return result;
     104             :   }
     105             : 
     106             :   /// \brief Determines if an expression if of the form
     107             :   /// phi => psi or of the form phi \/  psi where phi is a simple expression
     108             :   /// and psi is an arbitrary expression.
     109             :   /// \param e an expression
     110             :   /// \return true if e is of the form phi => psi or phi \/ psi.
     111             :   static bool is_inner_implies(const pbes_expression& e)
     112             :   {
     113             :     bool result = true;
     114             :     if (!(is_propositional_variable_instantiation(e) || is_simple_expression(e))) {
     115             :       if (is_or(e) || is_imp(e)) {
     116             :         pbes_expression l = pbes_system::accessors::left(e);
     117             :         pbes_expression r = pbes_system::accessors::right(e);
     118             :         if (is_simple_expression(l)) {
     119             :           result = is_inner_implies(r);
     120             :         } else {
     121             :           result = false;
     122             :         }
     123             :       } else {
     124             :         result = false;
     125             :       }
     126             :     }
     127             :     return result;
     128             :   }
     129             : 
     130             :   /// \brief Destructor.
     131           3 :   virtual ~bqnf_visitor()
     132           3 :   { }
     133             : 
     134             :   /// \brief Constructor.
     135           2 :   bqnf_visitor():
     136           2 :     debug(false)
     137           2 :   { }
     138             : 
     139             :   /// \brief Visits a simple expression.
     140             :   /// An expression is simple if it does not contain propositional variables.
     141             :   /// \param sigma fixpoint symbol (unused in this class)
     142             :   /// \param var propositional variable (unused in this class)
     143             :   /// \param e a PBES expression
     144             :   /// \return true if the expression e is a simple expression.
     145           2 :   virtual bool visit_simple_expression(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     146             :   {
     147           2 :     bool result = true;
     148           2 :     if (is_data(e) || is_true(e) || is_false(e)) {
     149           2 :       result = true;
     150           0 :     } else if (is_not(e)) {
     151           0 :       pbes_expression n = pbes_system::accessors::arg(e);
     152           0 :       result &= visit_simple_expression(sigma, var, n);
     153           0 :     } else if (is_and(e) || is_or(e) || is_imp(e)) {
     154           0 :       pbes_expression l = pbes_system::accessors::left(e);
     155           0 :       pbes_expression r = pbes_system::accessors::right(e);
     156           0 :       result &= visit_simple_expression(sigma, var, l);
     157           0 :       result &= visit_simple_expression(sigma, var, r);
     158           0 :     } else if (is_forall(e) || is_exists(e)) {
     159           0 :       pbes_expression a = pbes_system::accessors::arg(e);
     160           0 :       result &= visit_simple_expression(sigma, var, a);
     161           0 :     } else if (is_propositional_variable_instantiation(e)) {
     162           0 :       if (debug) {
     163           0 :         indent(); std::clog << "Not a simple expression!" << std::endl;
     164             :       } else {
     165           0 :         throw(std::runtime_error("Not a simple expression!"));
     166             :       }
     167             :     } else {
     168           0 :       throw(std::runtime_error("Unknown type of expression!"));
     169             :     }
     170           2 :     if (debug) {
     171           0 :       indent(); std::clog << "visit_simple_expression: " << pp(e) << ": " << (result?"true":"false") << std::endl;
     172             :     }
     173           2 :     return result;
     174             :   }
     175             : 
     176             :   /// \brief Visits a propositional variable expression.
     177             :   /// \param sigma fixpoint symbol (unused in this class)
     178             :   /// \param var propositional variable (unused in this class)
     179             :   /// \param e PBES expression
     180             :   /// \return true if the expression is a propositional variable or a simple expression.
     181           3 :   virtual bool visit_propositional_variable(const fixpoint_symbol& /*sigma*/, const propositional_variable& /*var*/, const pbes_expression& e)
     182             :   {
     183           3 :     inc_indent();
     184           3 :     bool result = true;
     185           3 :     if (is_propositional_variable_instantiation(e) || is_simple_expression(e)) {
     186             :       // std::clog << pp(e) << std::endl;
     187             :     } else {
     188           0 :       result = false;
     189           0 :       if (debug) {
     190           0 :         indent(); std::clog << "Not a propositional variable or simple expression:" << core::pp(e) << std::endl;
     191             :       } else {
     192           0 :         throw(std::runtime_error("Not a propositional variable or simple expression!"));
     193             :       }
     194             :     }
     195           3 :     if (debug) {
     196           0 :       indent(); std::clog << "  visit_propositional_variable: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     197             :     }
     198           3 :     dec_indent();
     199           3 :     return result;
     200             :   }
     201             : 
     202             :   /// \brief Visits a conjunctive expression within an inner existential quantifier expression.
     203             :   /// \param sigma fixpoint symbol (unused in this class)
     204             :   /// \param var propositional variable (unused in this class)
     205             :   /// \param e a PBES expression
     206             :   /// \return true if the expression e conforms to BQNF.
     207           3 :   virtual bool visit_inner_and(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     208             :   {
     209           3 :     inc_indent();
     210           3 :     bool result = true;
     211           3 :     if (is_and(e)) {
     212           0 :       pbes_expression l = pbes_system::accessors::left(e);
     213           0 :       pbes_expression r = pbes_system::accessors::right(e);
     214           0 :       if (is_simple_expression(l)) {
     215           0 :         result &= visit_simple_expression(sigma, var, l);
     216             :         // std::clog << pp(l) << " /\\ " << std::endl;
     217           0 :         result &= visit_inner_and(sigma, var, r);
     218             :       } else {
     219           0 :         result &= visit_propositional_variable(sigma, var, e);
     220             :       }
     221           0 :     } else {
     222           3 :       result &= visit_propositional_variable(sigma, var, e);
     223             :     }
     224           3 :     if (debug) {
     225           0 :       indent(); std::clog << "  visit_inner_and: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     226             :     }
     227           3 :     dec_indent();
     228           3 :     return result;
     229             :   }
     230             : 
     231             :   /// \brief Visits a bounded existential quantifier expression within a disjunctive expression.
     232             :   /// \param sigma fixpoint symbol (unused in this class)
     233             :   /// \param var propositional variable (unused in this class)
     234             :   /// \param e a PBES expression
     235             :   /// \return true if the expression e conforms to BQNF.
     236           3 :   virtual bool visit_inner_bounded_exists(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     237             :   {
     238           3 :     inc_indent();
     239           3 :     pbes_expression qexpr = e;
     240           3 :     data::variable_list qvars;
     241           3 :     while (is_exists(qexpr)) {
     242           0 :       qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
     243           0 :       qexpr = pbes_system::accessors::arg(qexpr);
     244             :     }
     245           3 :     bool result = visit_inner_and(sigma, var, qexpr);
     246           3 :     if (debug) {
     247           0 :       indent(); std::clog << "visit_inner_bounded_exists: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     248             :     }
     249           3 :     dec_indent();
     250           3 :     return result;
     251           3 :   }
     252             : 
     253             :   /// \brief Visits a disjunctive expression.
     254             :   /// \param sigma fixpoint symbol (unused in this class)
     255             :   /// \param var propositional variable (unused in this class)
     256             :   /// \param e a PBES expression
     257             :   /// \return true if the expression e conforms to BQNF.
     258           3 :   virtual bool visit_or(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     259             :   {
     260           3 :     inc_indent();
     261           3 :     bool result = true;
     262           3 :     if (is_or(e) || is_imp(e)) {
     263           0 :       pbes_expression l = pbes_system::accessors::left(e);
     264           0 :       pbes_expression r = pbes_system::accessors::right(e);
     265           0 :       result &= visit_or(sigma, var, l);
     266           0 :       result &= visit_or(sigma, var, r);
     267           0 :     } else {
     268           3 :       result &= visit_inner_bounded_exists(sigma, var, e);
     269             :     }
     270           3 :     if (debug) {
     271           0 :       indent(); std::clog << "visit_or: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     272             :     }
     273           3 :     dec_indent();
     274           3 :     return result;
     275             :   }
     276             : 
     277             :   /// \brief Visits a bounded universal quantifier expression within a conjunctive expression.
     278             :   /// \param sigma fixpoint symbol (unused in this class)
     279             :   /// \param var propositional variable (unused in this class)
     280             :   /// \param e a PBES expression
     281             :   /// \return true if the expression e conforms to BQNF.
     282           3 :   virtual bool visit_inner_bounded_forall(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     283             :   {
     284           3 :     inc_indent();
     285           3 :     pbes_expression qexpr = e;
     286           3 :     data::variable_list qvars;
     287           3 :     while (is_forall(qexpr)) {
     288           0 :       qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
     289           0 :       qexpr = pbes_system::accessors::arg(qexpr);
     290             :     }
     291           3 :     bool result = true;
     292           3 :     if (is_or(qexpr) || is_imp(qexpr)) {
     293           2 :       pbes_expression l = pbes_system::accessors::left(qexpr);
     294           2 :       pbes_expression r = pbes_system::accessors::right(qexpr);
     295           2 :       if (is_simple_expression(l)) {
     296           2 :         result &= visit_simple_expression(sigma, var, l);
     297             :         // std::clog << pp(l) << (is_or(qexpr) ? " \\/ " : " => ") << std::endl;
     298           2 :         result &= visit_or(sigma, var, r);
     299             :       } else {
     300           0 :         result &= visit_or(sigma, var, qexpr);
     301             :       }
     302           2 :     } else {
     303           1 :       result &= visit_or(sigma, var, qexpr);
     304             :     }
     305           3 :     if (debug) {
     306           0 :       indent(); std::clog << "visit_inner_bounded_forall: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     307             :     }
     308           3 :     dec_indent();
     309           3 :     return result;
     310           3 :   }
     311             : 
     312             :   /// \brief Visits a conjunctive expression.
     313             :   /// \param sigma fixpoint symbol (unused in this class)
     314             :   /// \param var propositional variable (unused in this class)
     315             :   /// \param e a PBES expression
     316             :   /// \return true if the expression e conforms to BQNF.
     317           4 :   virtual bool visit_and(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     318             :   {
     319           4 :     inc_indent();
     320           4 :     bool result = true;
     321           4 :     if (is_and(e)) {
     322           1 :       pbes_expression l = pbes_system::accessors::left(e);
     323           1 :       pbes_expression r = pbes_system::accessors::right(e);
     324           1 :       result &= visit_and(sigma, var, l);
     325             :       // std::clog << " /\\ " << std::endl;
     326           1 :       result &= visit_and(sigma, var, r);
     327           1 :     } else {
     328           3 :       result &= visit_inner_bounded_forall(sigma, var, e);
     329             :     }
     330           4 :     if (debug) {
     331           0 :       indent(); std::clog << "visit_and: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     332             :     }
     333           4 :     dec_indent();
     334           4 :     return result;
     335             :   }
     336             : 
     337             :   /// \brief Visits a bounded universal quantifier expression.
     338             :   /// \param sigma fixpoint symbol (unused in this class)
     339             :   /// \param var propositional variable (unused in this class)
     340             :   /// \param e a PBES expression
     341             :   /// \return true if the expression e conforms to BQNF.
     342           1 :   virtual bool visit_bounded_forall(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     343             :   {
     344           1 :     inc_indent();
     345           1 :     assert(is_forall(e));
     346           1 :     pbes_expression qexpr = e;
     347           1 :     data::variable_list qvars;
     348           2 :     while (is_forall(qexpr)) {
     349           1 :       qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
     350           1 :       qexpr = pbes_system::accessors::arg(qexpr);
     351             :     }
     352             :     //std::clog << "  Bounded forall: " << pp(qvars) << " . " << std::endl;
     353           1 :     bool result = true;
     354           1 :     if (is_or(qexpr) || is_imp(qexpr)) {
     355           0 :       pbes_expression l = pbes_system::accessors::left(qexpr);
     356           0 :       pbes_expression r = pbes_system::accessors::right(qexpr);
     357           0 :       if (is_simple_expression(l)) {
     358           0 :         result &= visit_simple_expression(sigma, var, l);
     359             :         // std::clog << pp(l) << (is_or(qexpr) ? " \\/ " : " => ") << std::endl;
     360           0 :         result &= visit_bqnf_expression(sigma, var, r);
     361             :       } else {
     362           0 :         result &= visit_bqnf_expression(sigma, var, qexpr);
     363             :       }
     364           0 :     } else {
     365           1 :       result &= visit_bqnf_expression(sigma, var, qexpr);
     366             :     }
     367           1 :     if (debug) {
     368           0 :       indent(); std::clog << "visit_bounded_forall: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     369             :     }
     370           1 :     dec_indent();
     371           1 :     return result;
     372           1 :   }
     373             : 
     374             :   /// \brief Visits a bounded existential quantifier expression.
     375             :   /// \param sigma fixpoint symbol (unused in this class)
     376             :   /// \param var propositional variable (unused in this class)
     377             :   /// \param e a PBES expression
     378             :   /// \return true if the expression e conforms to BQNF.
     379           0 :   virtual bool visit_bounded_exists(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     380             :   {
     381           0 :     inc_indent();
     382           0 :     assert(is_exists(e));
     383           0 :     pbes_expression qexpr = e;
     384           0 :     data::variable_list qvars;
     385           0 :     while (is_exists(qexpr)) {
     386           0 :       qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
     387           0 :       qexpr = pbes_system::accessors::arg(qexpr);
     388             :     }
     389           0 :     bool result = true;
     390           0 :     if (is_and(qexpr)) {
     391           0 :       pbes_expression l = pbes_system::accessors::left(qexpr);
     392           0 :       pbes_expression r = pbes_system::accessors::right(qexpr);
     393           0 :       if (is_simple_expression(l)) {
     394           0 :         result &= visit_simple_expression(sigma, var, l);
     395           0 :         result &= visit_bqnf_expression(sigma, var, r);
     396             :       } else {
     397           0 :         result &= visit_bqnf_expression(sigma, var, qexpr);
     398             :       }
     399           0 :     } else {
     400           0 :       result &= visit_bqnf_expression(sigma, var, qexpr);
     401             :     }
     402           0 :     if (debug) {
     403           0 :       indent(); std::clog << "visit_bounded_exists: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     404             :     }
     405           0 :     dec_indent();
     406           0 :     return result;
     407           0 :   }
     408             : 
     409             :   /// \brief Visits a bounded quantifier expression.
     410             :   /// \param sigma fixpoint symbol (unused in this class)
     411             :   /// \param var propositional variable (unused in this class)
     412             :   /// \param e a PBES expression
     413             :   /// \return true if the expression e conforms to BQNF.
     414           1 :   virtual bool visit_bounded_quantifier(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     415             :   {
     416           1 :     inc_indent();
     417           1 :     bool result = true;
     418           1 :     if (is_forall(e)) {
     419           1 :       result &= visit_bounded_forall(sigma, var, e);
     420           0 :     } else if (is_exists(e)) {
     421           0 :       result &= visit_bounded_exists(sigma, var, e);
     422             :     } else {
     423             :       // should not be possible
     424           0 :       throw(std::runtime_error("Not a quantifier expression!"));
     425             :     }
     426           1 :     if (debug) {
     427           0 :       indent(); std::clog << "visit_bounded_quantifier: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     428             :     }
     429           1 :     dec_indent();
     430           1 :     return result;
     431             :   }
     432             : 
     433             :   /// \brief Visits a BQNF expression.
     434             :   /// \param sigma fixpoint symbol (unused in this class)
     435             :   /// \param var propositional variable (unused in this class)
     436             :   /// \param e a PBES expression
     437             :   /// \return true if the expression e is in BQNF.
     438           5 :   virtual bool visit_bqnf_expression(const fixpoint_symbol& sigma, const propositional_variable& var, const pbes_expression& e)
     439             :   {
     440           5 :     inc_indent();
     441           5 :     bool result = true;
     442           5 :     if (is_simple_expression(e)) {
     443           2 :       result = true;
     444           3 :     } else if (is_forall(e) || is_exists(e)) {
     445           1 :       result &= visit_bounded_quantifier(sigma, var, e);
     446             :     } else {
     447           2 :       result &= visit_and(sigma, var, e);
     448             :     }
     449           5 :     if (debug) {
     450           0 :       indent(); std::clog << "visit_bqnf_expression: " << print_brief(e) << ": " << (result?"true":"false") << std::endl;
     451             :     }
     452           5 :     dec_indent();
     453           5 :     return result;
     454             :   }
     455             : 
     456             :   /// \brief Visits a BQNF expression.
     457             :   /// In the current BQNF visitor sigma and var parameters are added for use in bqnf2ppg_rewriter.
     458             :   /// This functions adds dummy values for sigma and var.
     459             :   /// \param e a PBES expression
     460             :   /// \return true if the expression e is in BQNF.
     461           4 :   virtual bool visit_bqnf_expression(const pbes_expression& e)
     462             :   {
     463           4 :     bool result = visit_bqnf_expression(fixpoint_symbol::nu(), propositional_variable(core::identifier_string("X"), data::variable_list()), e);
     464           4 :     return result;
     465             :   }
     466             : 
     467             :   /// \brief Visits a BQNF equation.
     468             :   /// \param eqn a PBES equation
     469             :   /// \return true if the right hand side of the equation is in BQNF.
     470           0 :   virtual bool visit_bqnf_equation(const pbes_equation& eqn)
     471             :   {
     472           0 :     if (debug) std::clog << "visit_bqnf_equation." << std::endl;
     473           0 :     const fixpoint_symbol& sigma = eqn.symbol();
     474           0 :     const propositional_variable& var = eqn.variable();
     475           0 :     const pbes_expression& e = eqn.formula();
     476           0 :     bool result = visit_bqnf_expression(sigma, var, e);
     477           0 :     if (debug) std::clog << "visit_bqnf_equation: equation " << var.name() << " is " << (result ? "" : "NOT ") << "in BQNF." << std::endl;
     478           0 :     return result;
     479             :   }
     480             : 
     481             :   /// \brief Visits a BQNF equation in debug mode.
     482             :   /// \param eqn a PBES equation
     483             :   /// \return true if the right hand side of the equation is in BQNF.
     484           0 :   virtual bool visit_bqnf_equation_debug(const pbes_equation& eqn)
     485             :   {
     486           0 :     debug = true;
     487           0 :     return visit_bqnf_equation(eqn);
     488             :   }
     489             : 
     490             : };
     491             : 
     492             : } // namespace detail
     493             : 
     494             : } // namespace pbes_system
     495             : 
     496             : } // namespace mcrl2
     497             : 
     498             : #endif // MCRL2_PBES_DETAIL_BQNF_VISITOR_H

Generated by: LCOV version 1.14