LCOV - code coverage report
Current view: top level - process/test - process_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 70 72 97.2 %
Date: 2024-04-21 03:44:01 Functions: 8 8 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 process_test.cpp
      10             : /// \brief Add your file description here.
      11             : 
      12             : #define BOOST_TEST_MODULE process_test
      13             : #include <boost/test/included/unit_test.hpp>
      14             : 
      15             : #include "mcrl2/process/balance_nesting_depth.h"
      16             : #include "mcrl2/process/is_guarded.h"
      17             : #include "mcrl2/process/is_linear.h"
      18             : #include "mcrl2/process/parse.h"
      19             : 
      20             : using namespace mcrl2;
      21             : using namespace mcrl2::process;
      22             : 
      23             : const std::string SPEC1 =
      24             :   "act a;                  \n"
      25             :   "proc X = a;             \n"
      26             :   "init X;                 \n"
      27             :   ;
      28             : 
      29             : const std::string SPEC2 =
      30             :   "act a;                  \n"
      31             :   "proc X(i: Nat) = a.X(i);\n"
      32             :   "init X(2);              \n"
      33             :   ;
      34             : 
      35             : const std::string ABS_SPEC_LINEARIZED =
      36             :   "sort D = struct d1 | d2;                                                                                                     \n"
      37             :   "     Error = struct e;                                                                                                       \n"
      38             :   "                                                                                                                             \n"
      39             :   "act  r1,s4: D;                                                                                                               \n"
      40             :   "     s2,r2,c2,s3,r3,c3: D # Bool;                                                                                            \n"
      41             :   "     s3,r3,c3: Error;                                                                                                        \n"
      42             :   "     s5,r5,c5,s6,r6,c6: Bool;                                                                                                \n"
      43             :   "     s6,r6,c6: Error;                                                                                                        \n"
      44             :   "     i;                                                                                                                      \n"
      45             :   "                                                                                                                             \n"
      46             :   "proc P(s31_S: Pos, d_S: D, b_S: Bool, s32_K: Pos, d_K: D, b_K: Bool, s33_L: Pos, b_L: Bool, s34_R: Pos, d_R: D, b_R: Bool) = \n"
      47             :   "       sum e1_S: Bool.                                                                                                       \n"
      48             :   "         ((s31_S == 3 && s33_L == 3) && if(e1_S, !b_S, b_S) == b_L) ->                                                       \n"
      49             :   "         c6(if(e1_S, !b_S, b_S)) .                                                                                           \n"
      50             :   "         P(if(e1_S, 2, 1), if(e1_S, d_S, d2), if(e1_S, b_S, !b_S), s32_K, d_K, b_K, 1, false, s34_R, d_R, b_R)               \n"
      51             :   "     + (s31_S == 3 && s33_L == 4) ->                                                                                         \n"
      52             :   "         c6(e) .                                                                                                             \n"
      53             :   "         P(2, d_S, b_S, s32_K, d_K, b_K, 1, false, s34_R, d_R, b_R)                                                          \n"
      54             :   "     + (s31_S == 2 && s32_K == 1) ->                                                                                         \n"
      55             :   "         c2(d_S, b_S) .                                                                                                      \n"
      56             :   "         P(3, d_S, b_S, 2, d_S, b_S, s33_L, b_L, s34_R, d_R, b_R)                                                            \n"
      57             :   "     + sum e2_K: Bool.                                                                                                       \n"
      58             :   "         (s32_K == 2) ->                                                                                                     \n"
      59             :   "         i .                                                                                                                 \n"
      60             :   "         P(s31_S, d_S, b_S, if(e2_K, 4, 3), if(e2_K, d2, d_K), if(e2_K, false, b_K), s33_L, b_L, s34_R, d_R, b_R)            \n"
      61             :   "     + sum e4_R: Bool.                                                                                                       \n"
      62             :   "         (s33_L == 1 && if(e4_R, s34_R == 4, s34_R == 3)) ->                                                                 \n"
      63             :   "         c5(if(e4_R, !b_R, b_R)) .                                                                                           \n"
      64             :   "         P(s31_S, d_S, b_S, s32_K, d_K, b_K, 2, if(e4_R, !b_R, b_R), 1, d2, if(e4_R, b_R, !b_R))                             \n"
      65             :   "     + (s34_R == 2) ->                                                                                                       \n"
      66             :   "         s4(d_R) .                                                                                                           \n"
      67             :   "         P(s31_S, d_S, b_S, s32_K, d_K, b_K, s33_L, b_L, 3, d2, b_R)                                                         \n"
      68             :   "     + sum e3_L: Bool.                                                                                                       \n"
      69             :   "         (s33_L == 2) ->                                                                                                     \n"
      70             :   "         i .                                                                                                                 \n"
      71             :   "         P(s31_S, d_S, b_S, s32_K, d_K, b_K, if(e3_L, 4, 3), if(e3_L, false, b_L), s34_R, d_R, b_R)                          \n"
      72             :   "     + (s32_K == 4 && s34_R == 1) ->                                                                                         \n"
      73             :   "         c3(e) .                                                                                                             \n"
      74             :   "         P(s31_S, d_S, b_S, 1, d2, false, s33_L, b_L, 4, d2, b_R)                                                            \n"
      75             :   "     + sum e5_R: Bool.                                                                                                       \n"
      76             :   "         ((s32_K == 3 && s34_R == 1) && if(e5_R, b_R, !b_R) == b_K) ->                                                       \n"
      77             :   "         c3(d_K, if(e5_R, b_R, !b_R)) .                                                                                      \n"
      78             :   "         P(s31_S, d_S, b_S, 1, d2, false, s33_L, b_L, if(e5_R, 2, 4), if(e5_R, d_K, d2), b_R)                                \n"
      79             :   "     + sum d3_S: D.                                                                                                          \n"
      80             :   "         (s31_S == 1) ->                                                                                                     \n"
      81             :   "         r1(d3_S) .                                                                                                          \n"
      82             :   "         P(2, d3_S, b_S, s32_K, d_K, b_K, s33_L, b_L, s34_R, d_R, b_R)                                                       \n"
      83             :   "     + true ->                                                                                                               \n"
      84             :   "         delta;                                                                                                              \n"
      85             :   "                                                                                                                             \n"
      86             :   "init P(1, d2, true, 1, d2, false, 1, false, 1, d2, true);                                                                    \n"
      87             :   ;
      88             : 
      89             : // CASE?? specifications were borrowed from sumelm_test.
      90             : 
      91             : std::string CASE1 =
      92             :   "sort S = struct s1 | s2;\n"
      93             :   "map f : S -> Bool;\n"
      94             :   "act a : S # Bool;\n"
      95             :   "proc P = sum c : S, b : Bool . (b == f(c) && c == s2) -> a(c, b) . P;\n"
      96             :   "init P;\n"
      97             :   ;
      98             : 
      99             : std::string CASE2 =
     100             :   "act a,b;\n"
     101             :   "proc P(s3_P: Pos) = sum y_P: Int. (s3_P == 1) -> a . P(2)\n"
     102             :   "                  + (s3_P == 2) -> b . P(1);\n"
     103             :   "init P(1);\n"
     104             :   ;
     105             : 
     106             : std::string CASE3 =
     107             :   "act a;\n"
     108             :   "proc P = sum y:Int . (4 == y) -> a . P;\n"
     109             :   "init P;\n"
     110             :   ;
     111             : 
     112             : std::string CASE4 =
     113             :   "act a;\n"
     114             :   "proc P = sum y:Int . (y == 4) -> a . P;\n"
     115             :   "init P;\n"
     116             :   ;
     117             : 
     118             : std::string CASE5 =
     119             :   "act a,b:Int;\n"
     120             :   "proc P = sum y:Int . (y == 4) -> a(y)@y . b(y*2)@(y+1) . P;\n"
     121             :   "init P;\n"
     122             :   ;
     123             : 
     124             : std::string CASE6 =
     125             :   "act a;\n"
     126             :   "proc P = sum y:Int . (y == y + 1) -> a . P;\n"
     127             :   "init P;\n"
     128             :   ;
     129             : 
     130             : std::string CASE7 =
     131             :   "sort D = struct d1 | d2 | d3;\n"
     132             :   "map g : D -> D;\n"
     133             :   "act a;\n"
     134             :   "proc P(c:D) = sum d:D . sum e:D . sum f:D . (d == e && e == g(e) && e == f) -> a . P(d);\n"
     135             :   "init P(d1);\n"
     136             :   ;
     137             : 
     138             : std::string CASE8 =
     139             :   "sort D = struct d1 | d2 | d3;\n"
     140             :   "act a;\n"
     141             :   "proc P(c:D) = sum d:D . sum e:D . sum f:D . (d == e && d == f) -> a . P(d);\n"
     142             :   "init P(d1);\n"
     143             :   ;
     144             : 
     145             : std::string CASE9 =
     146             :   "proc P = sum y:Bool . y -> delta;\n"
     147             :   "init P;\n"
     148             :   ;
     149             : 
     150             : std::string CASE10 =
     151             :   "act a:Nat;\n"
     152             :   "proc P(n0: Nat) = sum n: Nat. (n == n0 && n == 1) -> a(n0) . P(n);\n"
     153             :   "init P(0);\n"
     154             :   ;
     155             : 
     156             : // provided by Jeroen Keiren
     157             : std::string CASE11 =
     158             :   "act  a,b: Int;                       \n"
     159             :   "glob dc,dc0: Int;                    \n"
     160             :   "proc P(s3_P: Pos, y_P: Int) =        \n"
     161             :   "       sum y0_P: Int.                \n"
     162             :   "         (s3_P == 1 && y0_P == 4) -> \n"
     163             :   "         a(y0_P) @ y0_P .            \n"
     164             :   "         P(s3_P = 2, y_P = y0_P)     \n"
     165             :   "     + (s3_P == 2) ->                \n"
     166             :   "         b(y_P * 2) @ (y_P + 1) .    \n"
     167             :   "         P(s3_P = 1, y_P = dc0);     \n"
     168             :   "init P(1, dc);                       \n"
     169             :   ;
     170             : 
     171             : // test case containing a global variable
     172             : std::string CASE12 =
     173             :   " act a: Nat ;                      \n"
     174             :   " glob  v: Nat ;                    \n"
     175             :   " proc P(i, j: Nat) =               \n"
     176             :   "        (i == j) -> a(i) . P(1, 1) \n"
     177             :   "        ;                          \n"
     178             :   "                                   \n"
     179             :   " init P(i = 1, j = v) ;            \n"
     180             :   ;
     181             : 
     182             : // this process is considered to be NOT linear
     183             : std::string CASE13a =
     184             :   "proc X = tau; \n"
     185             :   "              \n"
     186             :   "init delta;   \n"
     187             :   ;
     188             : 
     189             : // this process is considered to be NOT linear
     190             : std::string CASE13b =
     191             :   "proc X = delta; \n"
     192             :   "                \n"
     193             :   "init X;         \n"
     194             :   ;
     195             : 
     196             : // this process is considered to be NOT linear
     197             : std::string CASE14 =
     198             :   "act a;        \n"
     199             :   "              \n"
     200             :   "proc X = tau; \n"
     201             :   "              \n"
     202             :   "init a;       \n"
     203             :   ;
     204             : 
     205             : // This process is considered linear, although it cannot be directly represented as an LPS.
     206             : const std::string CASE15 =
     207             :   "proc P = tau; \n"
     208             :   "              \n"
     209             :   "init P;       \n"
     210             :   ;
     211             : 
     212          16 : void test_linear(const std::string& text, bool result = true)
     213             : {
     214          16 :   process_specification p = parse_process_specification(text);
     215          16 :   if (is_linear(p) != result)
     216             :   {
     217           0 :     std::cerr << "--- Failed linearity test ---" << std::endl;
     218           0 :     std::cerr << text << std::endl;
     219             :   }
     220          16 :   bool verbose = true;
     221          16 :   BOOST_CHECK(is_linear(p, verbose) == result);
     222          16 : }
     223             : 
     224             : // Test case supplied by Frank Stappers. A segmentation fault is reported on Suse 64 bit.
     225           1 : void test_data_spec()
     226             : {
     227           2 :   process_specification spec = parse_process_specification("sort  X; init tau;");
     228           1 :   data::pp(spec.data());
     229           1 : }
     230             : 
     231           1 : void test_guarded()
     232             : {
     233             :   std::string PROCSPEC =
     234             :     "act a;                  \n"
     235             :     "proc P(n: Nat) = Q(n);  \n"
     236             :     "proc Q(n: Nat) = a.P(n);\n"
     237             :     "proc R(n: Nat) = S(n);  \n"
     238             :     "proc S(n: Nat) = R(n);  \n"
     239           1 :     "init P(2);              \n"
     240             :     ;
     241             : 
     242           1 :   std::string DATA_DECL = "act a;\n";
     243           1 :   std::string PROC_DECL = "proc P(n: Nat); proc Q(n: Nat); proc R(n: Nat); proc S(n: Nat);\n";
     244             :   process_specification procspec =
     245           1 :       parse_process_specification(PROCSPEC);
     246           1 :   process_expression x;
     247             : 
     248           1 :   x = parse_process_expression("delta", DATA_DECL, PROC_DECL);
     249           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     250             : 
     251           1 :   x = parse_process_expression("tau", DATA_DECL, PROC_DECL);
     252           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     253             : 
     254           1 :   x = parse_process_expression("a", DATA_DECL, PROC_DECL);
     255           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     256             : 
     257           1 :   x = parse_process_expression("P(0)", DATA_DECL, PROC_DECL);
     258           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     259             : 
     260           1 :   x = parse_process_expression("a.P(0) + P(1)", DATA_DECL, PROC_DECL);
     261           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     262             : 
     263           1 :   x = parse_process_expression("a.P(0) || P(1)", DATA_DECL, PROC_DECL);
     264           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     265             : 
     266           1 :   x = parse_process_expression("a.P(0) . P(1)", DATA_DECL, PROC_DECL);
     267           1 :   BOOST_CHECK(is_guarded(x, procspec.equations()));
     268             : 
     269           1 :   x = parse_process_expression("R(0)", DATA_DECL, PROC_DECL);
     270           1 :   BOOST_CHECK(!is_guarded(x, procspec.equations()));
     271           1 : }
     272             : 
     273           2 : BOOST_AUTO_TEST_CASE(balance_summands_test)
     274             : {
     275           1 :   std::function<std::size_t(process_expression)> nesting_depth;
     276         802 :   nesting_depth = [&nesting_depth](const process_expression& x) -> std::size_t
     277             :   {
     278         402 :     if (is_choice(x))
     279             :     {
     280         200 :       const auto& x_ = atermpp::down_cast<choice>(x);
     281         200 :       return std::max(nesting_depth(x_.left()), nesting_depth(x_.right())) + 1;
     282             :     }
     283         202 :     return 0;
     284           1 :   };
     285             : 
     286           1 :   process_expression x = delta();
     287         101 :   for (int i = 0; i < 100; i++)
     288             :   {
     289         100 :     x = choice(x, delta());
     290             :   }
     291           1 :   auto depth1 = nesting_depth(x);
     292           1 :   x = balance_summands(x);
     293           1 :   auto depth2 = nesting_depth(x);
     294           1 :   BOOST_CHECK_EQUAL(depth1, 100);
     295           1 :   BOOST_CHECK_EQUAL(depth2, 7);
     296           1 : }
     297             : 
     298           2 : BOOST_AUTO_TEST_CASE(test_main)
     299             : {
     300           1 :   test_linear(CASE1);
     301           1 :   test_linear(CASE2);
     302           1 :   test_linear(CASE3);
     303           1 :   test_linear(CASE4);
     304           1 :   test_linear(CASE5, false);
     305           1 :   test_linear(CASE6);
     306           1 :   test_linear(CASE7);
     307           1 :   test_linear(CASE8);
     308           1 :   test_linear(CASE9);
     309           1 :   test_linear(CASE10);
     310           1 :   test_linear(CASE11);
     311           1 :   test_linear(CASE12);
     312           1 :   test_linear(CASE13a, false);
     313           1 :   test_linear(CASE13b);
     314           1 :   test_linear(CASE14, false);
     315           1 :   test_linear(CASE15);
     316             : 
     317           1 :   test_data_spec();
     318             : 
     319           1 :   test_guarded();
     320           1 : }

Generated by: LCOV version 1.14