LCOV - code coverage report
Current view: top level - lps/test - action_rename_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 127 127 100.0 %
Date: 2024-04-26 03:18:02 Functions: 23 23 100.0 %
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 action_rename_test.cpp
      10             : /// \brief Action rename test.
      11             : 
      12             : #define BOOST_TEST_MODULE action_rename_test
      13             : #include "mcrl2/lps/linearise.h"
      14             : #include "mcrl2/lps/parse.h"
      15             : #include "mcrl2/lps/remove.h"
      16             : #include "mcrl2/lps/rewrite.h"
      17             : #include <boost/test/included/unit_test.hpp>
      18             : 
      19             : using namespace mcrl2;
      20             : using lps::stochastic_specification;
      21             : using lps::action_rename_specification;
      22             : using lps::action_summand;
      23             : using lps::action_summand_vector;
      24             : using lps::deadlock_summand;
      25             : 
      26           1 : void test1()
      27             : {
      28             :   // Check a renaming when more than one renaming rule
      29             :   // for one action is present.
      30             :   const std::string SPEC =
      31             :     "act a:Nat;                               \n"
      32             :     "proc P(n:Nat) = sum m: Nat. a(m). P(m);  \n"
      33           1 :     "init P(0);                               \n";
      34             : 
      35             :   const std::string AR_SPEC =
      36             :     "act b,c:Nat;\n"
      37             :     "var n:Nat;\n"
      38             :     "rename \n"
      39             :     "  (n>4)  -> a(n) => b(n); \n"
      40           1 :     "  (n<22) -> a(n) => c(n); \n";
      41             : 
      42           1 :   stochastic_specification spec=lps::linearise(SPEC);
      43           1 :   std::istringstream ar_spec_stream(AR_SPEC);
      44           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
      45           2 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
      46           1 :   BOOST_CHECK(check_well_typedness(new_spec));
      47           1 :   BOOST_CHECK(new_spec.process().summand_count()==3);
      48           1 : }
      49             : 
      50           1 : void test2()
      51             : {
      52             :   // Check whether new declarations in the rename file
      53             :   // are read properly. Check for renamings of more than one action.
      54             :   const std::string SPEC =
      55             :     "act a,b:Nat;                             \n"
      56             :     "proc P(n:Nat) = sum m: Nat. a(m). P(m);  \n"
      57           1 :     "init P(0);                               \n";
      58             : 
      59             :   const std::string AR_SPEC =
      60             :     "map f:Nat->Nat; \n"
      61             :     "var n':Nat; \n"
      62             :     "eqn f(n')=3; \n"
      63             :     "act c:Nat; \n"
      64             :     "var n:Nat; \n"
      65             :     "rename \n"
      66             :     "  (f(n)>23) -> a(n) => b(n); \n"
      67           1 :     "  b(n) => c(n); \n";
      68             : 
      69           1 :   stochastic_specification spec=lps::linearise(SPEC);
      70           1 :   std::istringstream ar_spec_stream(AR_SPEC);
      71           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
      72           2 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
      73           1 :   BOOST_CHECK(check_well_typedness(new_spec));
      74           1 :   BOOST_CHECK(new_spec.process().summand_count()==2);
      75           1 : }
      76             : 
      77           1 : void test3()
      78             : {
      79             :   // Check whether constants in an action_rename file are properly translated.
      80             :   const std::string SPEC =
      81             :     "act a,b:Nat;                             \n"
      82             :     "proc P(n:Nat) = a(1). P(n)+b(1).P(1);  \n"
      83           1 :     "init P(0);                               \n";
      84             : 
      85             :   const std::string AR_SPEC =
      86             :     "rename \n"
      87           1 :     "  a(1) => delta; \n";
      88             : 
      89           1 :   stochastic_specification spec=lps::linearise(SPEC);
      90           1 :   std::istringstream ar_spec_stream(AR_SPEC);
      91           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
      92           1 :   data::rewriter R (spec.data(), mcrl2::data::rewriter::strategy());
      93           1 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
      94           1 :   lps::rewrite(new_spec, R);
      95           1 :   lps::remove_trivial_summands(new_spec);
      96           1 :   BOOST_CHECK(check_well_typedness(new_spec));
      97           1 :   BOOST_CHECK(new_spec.process().summand_count()==2);
      98           1 : }
      99             : 
     100           1 : void test4()
     101             : {
     102             :   const std::string SPEC =
     103             :     "sort D = struct d1 | d2;\n"
     104             :     "     E = D;\n"
     105             :     "\n"
     106             :     "act a : E;\n"
     107             :     "\n"
     108             :     "proc P(d:D) = a(d) . P(d1);\n"
     109             :     "\n"
     110           1 :     "init P(d2);\n";
     111             : 
     112             :   const std::string AR_SPEC =
     113             :     "var e : E;\n"
     114             :     "rename\n"
     115           1 :     "(e==d1) -> a(e) => tau;\n";
     116             : 
     117           1 :   stochastic_specification spec=lps::linearise(SPEC);
     118           1 :   std::istringstream ar_spec_stream(AR_SPEC);
     119           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
     120           1 :   data::rewriter R (spec.data(), mcrl2::data::rewriter::strategy());
     121           1 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
     122           1 :   lps::rewrite(new_spec, R);
     123           1 :   lps::remove_trivial_summands(new_spec);
     124           1 :   BOOST_CHECK(check_well_typedness(new_spec));
     125           1 :   BOOST_CHECK(new_spec.process().summand_count()==2);
     126           1 : }
     127             : 
     128           1 : void test5() // Test whether partial renaming to delta is going well. See bug report #1009.
     129             : {
     130             :   const std::string SPEC =
     131             :     "sort Command = struct com1 | com2;\n"
     132             :     "sort State = struct st1 | st2;\n"
     133             :     "\n"
     134             :     "proc Parent(id: Nat, children: List(Nat)) =\n"
     135             :     "  sum child: Nat, command: Command . (child in children) -> sc(id, child, command) . Parent()\n"
     136             :     "+ sum child: Nat, state: State . (child in children) -> rs(child, id, state) . Parent();\n"
     137             :     "\n"
     138             :     "proc Child(id: Nat, parent: Nat) =\n"
     139             :     "  sum command: Command . rc(parent, id, command) . Child()\n"
     140             :     "+ sum state: State . ss(id, parent, state) . Child();\n"
     141             :     "\n"
     142             :     "act sc, rc, cc: Nat # Nat # Command;\n"
     143             :     "    rs, ss, cs: Nat # Nat # State;\n"
     144             :     "\n"
     145             :     "act none;\n"
     146             :     "\n"
     147             :     "init\n"
     148             :     "  allow({cc, cs, sc, rs},\n"
     149             :     "  comm({sc|rc -> cc, rs|ss->cs},\n"
     150             :     "    Parent(0, [1, 2]) ||\n"
     151             :     "    Child(1, 0) ||\n"
     152             :     "    Child(2, 0)\n"
     153           1 :     "  ));\n";
     154             : 
     155             : 
     156             :   const std::string AR_SPEC =
     157             :     "var c: Command;\n"
     158             :     "    s: State;\n"
     159             :     "rename\n"
     160             :     "  sc(0, 1, c) => delta;\n"
     161           1 :     "  rs(1, 0, s) => delta;\n";
     162             : 
     163             : 
     164           1 :   stochastic_specification spec=lps::linearise(SPEC);
     165           1 :   std::istringstream ar_spec_stream(AR_SPEC);
     166           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
     167           1 :   data::rewriter R (spec.data(), mcrl2::data::rewriter::strategy());
     168           1 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
     169           1 :   lps::rewrite(new_spec, R);
     170           1 :   lps::remove_trivial_summands(new_spec);
     171           1 :   BOOST_CHECK(check_well_typedness(new_spec));
     172           1 :   BOOST_CHECK(new_spec.process().summand_count()==8);
     173           1 : }
     174             : 
     175             : // Check whether renaming with a regular expression works well
     176           1 : static void test_regex1()
     177             : {
     178             :   const std::string SPEC =
     179             :   "act a_out, b_out, cout, ab_out, ac_out;\n"
     180           1 :   "init a_out|ab_out . b_out . cout . delta;";
     181             : 
     182           1 :   stochastic_specification spec = lps::linearise(SPEC);
     183             :   // This should rename a_out and ac_out, leaving the rest
     184           2 :   stochastic_specification new_spec = action_rename(std::regex("^([^b]*)_out"), "out_$1", spec);
     185             : 
     186           1 :   BOOST_CHECK(check_well_typedness(new_spec));
     187           1 :   BOOST_CHECK(std::string(new_spec.action_labels().front().name()) == "out_a");
     188           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().front().name()) == "b_out");
     189           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().tail().front().name()) == "cout");
     190           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().tail().tail().front().name()) == "ab_out");
     191           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().tail().tail().tail().front().name()) == "out_ac");
     192             : 
     193           4 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     194             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "out_a|ab_out"; }));
     195           3 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     196             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "b_out"; }));
     197           2 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     198             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "cout"; }));
     199           1 : }
     200             : 
     201             : // Check whether renaming some actions to delta works
     202           1 : void test_regex2()
     203             : {
     204             :   const std::string SPEC =
     205             :   "act a_out, b_out, cout, ab_out, ac_out;\n"
     206           1 :   "init a_out|ab_out . b_out . cout . delta;";
     207             : 
     208           1 :   stochastic_specification spec = lps::linearise(SPEC);
     209             :   // This should rename a_out, leaving the rest
     210           2 :   stochastic_specification new_spec = action_rename(std::regex("^a_out"), "delta", spec);
     211             : 
     212           1 :   BOOST_CHECK(std::string(new_spec.action_labels().front().name()) == "b_out");
     213           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().front().name()) == "cout");
     214           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().tail().front().name()) == "ab_out");
     215             : 
     216           3 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     217             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "b_out"; }));
     218           2 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     219             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "cout"; }));
     220             : 
     221           1 :   BOOST_CHECK(new_spec.process().deadlock_summands().size() == 2);
     222           1 :   auto find_result = std::find_if(spec.process().action_summands().begin(), spec.process().action_summands().end(),
     223           3 :     [](const action_summand& as){ return lps::pp(as.multi_action()) == "a_out|ab_out"; });
     224           1 :   BOOST_CHECK(find_result != spec.process().action_summands().end());
     225           1 :   if(find_result != spec.process().action_summands().end())
     226             :   {
     227           3 :     BOOST_CHECK(std::any_of(new_spec.process().deadlock_summands().begin(), new_spec.process().deadlock_summands().end(),
     228             :                                 [&find_result](const deadlock_summand& ds){ return ds.condition() == find_result->condition(); }));
     229             :   }
     230           1 : }
     231             : 
     232             : // Check whether renaming some actions to tau works
     233           1 : void test_regex3()
     234             : {
     235             :   const std::string SPEC =
     236             :   "act a_out, b_out, cout, ab_out, ac_out;\n"
     237           1 :   "init a_out|ab_out . b_out . cout . delta;";
     238             : 
     239           1 :   stochastic_specification spec = lps::linearise(SPEC);
     240             :   // This should rename a_out and cout, leaving the rest
     241           2 :   stochastic_specification new_spec = action_rename(std::regex("^(a_out|cout)$"), "tau", spec);
     242             : 
     243           1 :   BOOST_CHECK(std::string(new_spec.action_labels().front().name()) == "b_out");
     244           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().front().name()) == "ab_out");
     245           1 :   BOOST_CHECK(std::string(new_spec.action_labels().tail().tail().front().name()) == "ac_out");
     246             : 
     247           4 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     248             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "ab_out"; }));
     249           3 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     250             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "b_out"; }));
     251           2 :   BOOST_CHECK(std::any_of(new_spec.process().action_summands().begin(), new_spec.process().action_summands().end(),
     252             :                               [](const action_summand& as){ return lps::pp(as.multi_action()) == "tau"; }));
     253           1 : }
     254             : 
     255             : // Check whether the list of actions contains no duplicates after renaming multiple actions
     256             : // to one action.
     257           1 : void test_regex4()
     258             : {
     259             :   const std::string SPEC =
     260             :   "act a_out, b_out;\n"
     261           1 :   "init a_out . b_out . delta;";
     262             : 
     263           1 :   stochastic_specification spec = lps::linearise(SPEC);
     264             :   // This should rename both actions to 'out'
     265           2 :   stochastic_specification new_spec = action_rename(std::regex("^(a|b)_out$"), "out", spec);
     266             : 
     267           1 :   BOOST_CHECK(new_spec.action_labels().size() == 1);
     268           1 :   BOOST_CHECK(std::string(new_spec.action_labels().front().name()) == "out");
     269           1 : }
     270             : 
     271           2 : BOOST_AUTO_TEST_CASE(multiple_action_declarations)
     272             : {
     273             :   const std::string SPEC =
     274             :      "act a1,a2;\n"
     275             :      "proc P = a1.a2.P;\n"
     276           1 :      "init P;\n";
     277             : 
     278             :   const std::string RENAME_SPEC =
     279             :     "act b1;\n"
     280             :     "rename a1 => b1;\n"
     281             :     "act b2;\n"
     282           1 :     "rename a2 => b2;\n";
     283             : 
     284           1 :   stochastic_specification spec = lps::linearise(SPEC);
     285           1 :   std::istringstream ar_spec_stream(RENAME_SPEC);
     286           1 :   action_rename_specification ar_spec = parse_action_rename_specification(ar_spec_stream, spec);
     287           2 :   stochastic_specification new_spec = action_rename(ar_spec,spec,data::rewriter(),false);
     288             : 
     289           1 :   BOOST_CHECK(new_spec.action_labels().size() == 4);
     290           1 : }
     291             : 
     292           2 : BOOST_AUTO_TEST_CASE(test_main)
     293             : {
     294           1 :   test1();
     295           1 :   test2();
     296           1 :   test3();
     297           1 :   test4();
     298           1 :   test5();
     299             : 
     300           1 :   test_regex1();
     301           1 :   test_regex2();
     302           1 :   test_regex3();
     303           1 :   test_regex4();
     304           1 : }

Generated by: LCOV version 1.14