LCOV - code coverage report
Current view: top level - pbes/test - pbesinst_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 82 90 91.1 %
Date: 2024-04-21 03:44:01 Functions: 14 14 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 pbesinst_test.cpp
      10             : /// \brief Add your file description here.
      11             : 
      12             : #define BOOST_TEST_MODULE pbesinst_test
      13             : #include <boost/test/included/unit_test.hpp>
      14             : 
      15             : #include "mcrl2/lps/detail/test_input.h"
      16             : #include "mcrl2/modal_formula/detail/test_input.h"
      17             : #include "mcrl2/modal_formula/parse.h"
      18             : #include "mcrl2/pbes/is_bes.h"
      19             : #include "mcrl2/pbes/lps2pbes.h"
      20             : #include "mcrl2/pbes/pbesinst_finite_algorithm.h"
      21             : #include "mcrl2/pbes/pbesinst_symbolic.h"
      22             : #include "mcrl2/pbes/rewriter.h"
      23             : #include "mcrl2/pbes/txt2pbes.h"
      24             : 
      25             : using namespace mcrl2;
      26             : using namespace mcrl2::pbes_system;
      27             : 
      28             : inline
      29           7 : pbes pbesinst_lazy(const pbes& p)
      30             : {
      31           7 :   pbes q = p;
      32           7 :   pbesinst_algorithm algorithm(q.data());
      33           7 :   algorithm.run(q);
      34          14 :   return algorithm.get_result();
      35           7 : }
      36             : 
      37             : inline
      38           9 : pbes pbesinst_finite(const pbes& p)
      39             : {
      40           9 :   pbes q = p;
      41           9 :   pbesinst_finite_algorithm algorithm(data::jitty);
      42           9 :   algorithm.run(q);
      43          18 :   return q;
      44           9 : }
      45             : 
      46             : std::string test1 =
      47             :   "pbes                                                                              \n"
      48             :   "                                                                                  \n"
      49             :   "nu X(b:Bool, n:Nat) = (val(b) => X(!b, n)) && (val(!b) => X(!b, n+1));            \n"
      50             :   "                                                                                  \n"
      51             :   "init X(true,0);                                                                   \n"
      52             :   ;
      53             : 
      54             : std::string test2 =
      55             :   "pbes                                                                              \n"
      56             :   "                                                                                  \n"
      57             :   "nu X(b:Bool, n:Nat) = forall c:Bool. X(c,n);                                      \n"
      58             :   "                                                                                  \n"
      59             :   "init X(true,0);                                                                   \n"
      60             :   ;
      61             : 
      62             : std::string test3 =
      63             :   "pbes                                                                              \n"
      64             :   "                                                                                  \n"
      65             :   "nu X(b:Bool, n:Nat) = exists c:Bool. X(c,n+1);                                    \n"
      66             :   "                                                                                  \n"
      67             :   "init X(true,0);                                                                   \n"
      68             :   ;
      69             : 
      70             : std::string test4 =
      71             :   "pbes                                                                              \n"
      72             :   "                                                                                  \n"
      73             :   "nu X(b:Bool, n:Nat) = val(b && n < 10) => X(!b,n+1);                              \n"
      74             :   "                                                                                  \n"
      75             :   "init X(true,0);                                                                   \n"
      76             :   ;
      77             : 
      78             : std::string test5 =
      79             :   "sort D = struct d1 | d2;                                                          \n"
      80             :   "                                                                                  \n"
      81             :   "pbes                                                                              \n"
      82             :   "                                                                                  \n"
      83             :   "nu X(d:D, n:Nat) = val(d == d1 && n < 10) => X(d2,n+1);                           \n"
      84             :   "                                                                                  \n"
      85             :   "init X(d1,0);                                                                     \n"
      86             :   ;
      87             : 
      88             : std::string test6 =
      89             :   "pbes                                                                              \n"
      90             :   "nu X(b:Bool) = forall c:Bool. X(if (c,!c,c));                                     \n"
      91             :   "                                                                                  \n"
      92             :   "init X(true);                                                                     \n"
      93             :   ;
      94             : 
      95             : std::string test7 =
      96             :   "sort Enum2 = struct e1_5 | e0_5;                                                  \n"
      97             :   "                                                                                  \n"
      98             :   "map                                                                               \n"
      99             :   "                                                                                  \n"
     100             :   "     C5_fun2: Enum2 # Enum2 # Enum2  -> Enum2;                                    \n"
     101             :   "     C5_fun1: Enum2 # Nat # Nat  -> Nat;                                          \n"
     102             :   "                                                                                  \n"
     103             :   "var  y23,y22,y21,x5,y14,y13,y12,y11,y10,x2,e3,e2,e1: Enum2;                       \n"
     104             :   "     y20,y19,y18,x4,y9,y8,y7,y6,y5,x1: Nat;                                       \n"
     105             :   "     y17,y16,y15,x3,y4,y3,y2,y1,y,x: Bool;                                        \n"
     106             :   "eqn                                                                               \n"
     107             :   "     C5_fun2(e0_5, y14, y13)  =  y14;                                             \n"
     108             :   "     C5_fun2(e1_5, y14, y13)  =  y13;                                             \n"
     109             :   "     C5_fun2(e3, x2, x2)  =  x2;                                                  \n"
     110             :   "     C5_fun1(e0_5,  y6, y5)  =  y5;                                               \n"
     111             :   "     C5_fun1(e1_5,  y6, y5)  =  y6;                                               \n"
     112             :   "     C5_fun1(e2,  x1, x1)  =  x1;                                                 \n"
     113             :   "                                                                                  \n"
     114             :   "pbes nu X(s3_P: Enum2,  n_P: Nat) =                                               \n"
     115             :   "                                                                                  \n"
     116             :   "(forall e: Enum2.  X(C5_fun2(e, e, e1_5), C5_fun1(e, 0, n_P))                     \n"
     117             :   "                                                                                  \n"
     118             :   ")                                                                                 \n"
     119             :   "                                                                                  \n"
     120             :   "                                                                                  \n"
     121             :   ";                                                                                 \n"
     122             :   "                                                                                  \n"
     123             :   "init X(e1_5,  0);                                                                 \n"
     124             :   ;
     125             : 
     126             : std::string test8 =
     127             :   "pbes                                                                              \n"
     128             :   "                                                                                  \n"
     129             :   "nu X(b:Bool) = val(b) && Y(!b);                                                   \n"
     130             :   "                                                                                  \n"
     131             :   "mu Y(c:Bool) = forall d:Bool. X(d && c) || Y(d);                                  \n"
     132             :   "                                                                                  \n"
     133             :   "init X(true);                                                                     \n"
     134             :   ;
     135             : 
     136             : // This pbes triggered a garbage collection problem, that has been solved.
     137             : std::string random1 =
     138             :   "pbes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \n"
     139             :   "nu X0(c:Bool, n:Nat) = (forall n:Nat.((val(n < 3)) && (((val(n < 3)) || (exists m:Nat.((val(m < 3)) || (X3(m + 1, m > 0))))) && ((forall m:Nat.((val(m < 3)) && (!X2(m + 1, 1)))) => ((val(c)) || (val(n < 3))))))) || ((val(false)) || (X0(false, n + 1)));                                                                                                                                                                                                                                                \n"
     140             :   "nu X1(b:Bool) = (!(!(forall k:Nat.((val(k < 3)) && ((forall k:Nat.((val(k < 3)) && ((X2(1, k + 1)) && (val(false))))) || ((X4(k > 0, k + 1)) && (X1(k > 1)))))))) && (!(forall m:Nat.((val(m < 3)) && (((val(m < 2)) && (val(m > 0))) && (val(true))))));                                                                                                                                                                                                                                                   \n"
     141             :   "mu X2(m:Nat, n:Nat) = (((val(m < 2)) && (X4(m == n, n + 1))) || ((val(false)) || ((val(true)) => (X0(n == m, 0))))) || (forall k:Nat.((val(k < 3)) && (exists m:Nat.((val(m < 3)) || ((val(n < 2)) && (X2(m + 1, m + 1)))))));                                                                                                                                                                                                                                                                              \n"
     142             :   "nu X3(n:Nat, c:Bool) = ((forall k:Nat.((val(k < 3)) && (!((forall m:Nat.((val(m < 3)) && (val(n > 0)))) => (val(c)))))) && ((X3(0, n < 3)) && (exists m:Nat.((val(m < 3)) || ((!(exists n:Nat.((val(n < 3)) || (val(m < 2))))) && (X2(n + 1, m + 1))))))) || ((!(!X1(n > 0))) || (val(false)));                                                                                                                                                                                                             \n"
     143             :   "nu X4(c:Bool, n:Nat) = (((exists m:Nat.((val(m < 3)) || (val(m > 0)))) && ((!(!X0(n < 3, 0))) || (!((val(n > 0)) => (!X2(0, 0)))))) => (forall k:Nat.((val(k < 3)) && (!(forall n:Nat.((val(n < 3)) && (val(n < 2)))))))) => (!(forall m:Nat.((val(m < 3)) && ((val(c)) && (forall m:Nat.((val(m < 3)) && (!X3(n + 1, false))))))));                                                                                                                                                                        \n"
     144             :   "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \n"
     145             :   "init X0(true, 0);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \n"
     146             :   ;
     147             : 
     148             : // This pbes triggered a garbage collection problem, that has been solved.
     149             : std::string random2 =
     150             :   "pbes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \n"
     151             :   "mu X0(m:Nat, b:Bool) = (X0(m + 1, m > 0)) && (((forall m:Nat.((val(m < 3)) && (forall k:Nat.((val(k < 3)) && (!((val(k > 1)) && (val(false)))))))) && (exists n:Nat.((val(n < 3)) || (!(!(val(n > 1))))))) || (exists n:Nat.((val(n < 3)) || (forall n:Nat.((val(n < 3)) && (exists n:Nat.((val(n < 3)) || (((forall m:Nat.((val(m < 3)) && (val(m == n)))) => (X3(0, n > 1))) && (!(!X2(n == m)))))))))));                                                                                                 \n"
     152             :   "mu X1(c:Bool, b:Bool) = (((!X1(c, true)) || ((!X2(b)) || (val(b)))) && (forall k:Nat.((val(k < 3)) && (((val(c)) => (X4(c, 1))) => (val(true)))))) => (val(true));                                                                                                                                                                                                                                                                                                                                          \n"
     153             :   "nu X2(b:Bool) = (!(!(((exists m:Nat.((val(m < 3)) || (val(m < 3)))) => ((X0(1, true)) => (!(val(false))))) && ((!((!X1(b, true)) && (!X3(0, false)))) => (val(false)))))) => (exists m:Nat.((val(m < 3)) || (forall k:Nat.((val(k < 3)) && (exists n:Nat.((val(n < 3)) || (forall n:Nat.((val(n < 3)) && (exists n:Nat.((val(n < 3)) || (forall n:Nat.((val(n < 3)) && (val(false))))))))))))));                                                                                                            \n"
     154             :   "mu X3(m:Nat, c:Bool) = (exists m:Nat.((val(m < 3)) || ((!(val(c))) && (forall k:Nat.((val(k < 3)) && (exists m:Nat.((val(m < 3)) || (forall k:Nat.((val(k < 3)) && (val(false))))))))))) || (exists m:Nat.((val(m < 3)) || (exists n:Nat.((val(n < 3)) || ((!((exists k:Nat.((val(k < 3)) || (!X4(false, k + 1)))) && ((!X1(m > 0, n < 2)) || ((val(n > 0)) || (val(c)))))) && (exists k:Nat.((val(k < 3)) || (exists n:Nat.((val(n < 3)) || (exists k:Nat.((val(k < 3)) || (X3(k + 1, k == n))))))))))))); \n"
     155             :   "nu X4(b:Bool, n:Nat) = (exists m:Nat.((val(m < 3)) || ((val(b)) || ((val(n > 1)) && ((X1(m > 1, n == m)) || (val(m > 0))))))) && ((exists k:Nat.((val(k < 3)) || (!(!((!X3(1, n > 0)) && (!(val(k == n)))))))) => (forall n:Nat.((val(n < 3)) && (exists k:Nat.((val(k < 3)) || (!(!(X4(n > 1, 0)))))))));                                                                                                                                                                                                  \n"
     156             :   "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            \n"
     157             :   "init X0(0, true);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           \n"
     158             :   ;
     159             : 
     160             : // This pbes triggered an error with pbesinst finite
     161             : std::string random3 =
     162             :   "pbes                                                                                                                                                                                                                                                                                                                                                              \n"
     163             :   "mu X0(n:Nat, c:Bool) = ((!(((val(n < 2)) && (!X1)) && (exists k:Nat.((val(k < 3)) || (val(c)))))) && (((forall n:Nat.((val(n < 3)) && (!X4(n > 1)))) || (!(val(n > 1)))) => (val(true)))) && (exists n:Nat.((val(n < 3)) || (exists k:Nat.((val(k < 3)) || (forall m:Nat.((val(m < 3)) && (X0(k + 1, n < 3))))))));                                               \n"
     164             :   "mu X1 = (((!((val(true)) => (X2))) => (!(!(!(!X1))))) && (((val(false)) || (X3(1))) && (forall n:Nat.((val(n < 3)) && (val(true)))))) || (forall k:Nat.((val(k < 3)) && (!(forall k:Nat.((val(k < 3)) && (exists m:Nat.((val(m < 3)) || (val(k < 2)))))))));                                                                                                      \n"
     165             :   "mu X2 = ((exists k:Nat.((val(k < 3)) || (exists k:Nat.((val(k < 3)) || (exists m:Nat.((val(m < 3)) || ((val(m == k)) => (X1)))))))) => (((val(true)) => (!X2)) || (exists k:Nat.((val(k < 3)) || (val(false)))))) => (!((val(false)) => (!(X3(0)))));                                                                                                             \n"
     166             :   "mu X3(n:Nat) = ((exists n:Nat.((val(n < 3)) || (exists n:Nat.((val(n < 3)) || (forall n:Nat.((val(n < 3)) && (val(false)))))))) && (forall m:Nat.((val(m < 3)) && (((forall m:Nat.((val(m < 3)) && (exists m:Nat.((val(m < 3)) || (exists m:Nat.((val(m < 3)) || (!(val(n > 0))))))))) && ((!X4(m > 1)) || (!X2))) || (val(n < 2)))))) => ((val(n < 2)) => (X1)); \n"
     167             :   "nu X4(b:Bool) = ((val(true)) => ((forall m:Nat.((val(m < 3)) && (val(false)))) => ((X1) || ((!X3(0)) => (forall n:Nat.((val(n < 3)) && (val(n > 1)))))))) && (forall m:Nat.((val(m < 3)) && (forall n:Nat.((val(n < 3)) && ((X2) && (val(false)))))));                                                                                                            \n"
     168             :   "                                                                                                                                                                                                                                                                                                                                                                  \n"
     169             :   "init X0(0, true);                                                                                                                                                                                                                                                                                                                                                 \n"
     170             :   ;
     171             : 
     172           9 : void test_pbes(const std::string& pbes_spec, bool test_finite, bool test_lazy)
     173             : {
     174           9 :   pbes p = txt2pbes(pbes_spec);
     175           9 :   std::cout << "------------------------------\n" << pbes_system::pp(p) << std::endl;
     176           9 :   if (!p.is_closed())
     177             :   {
     178           0 :     std::cout << "ERROR: the pbes is not closed!" << std::endl;
     179           0 :     return;
     180             :   }
     181             : 
     182           9 :   if (test_finite)
     183             :   {
     184           8 :     std::cout << "FINITE" << std::endl;
     185             :     try
     186             :     {
     187             :       using namespace pbes_system;
     188           8 :       pbes q1 = ::pbesinst_finite(p);
     189           8 :       std::cout << pbes_system::pp(q1) << std::endl;
     190           8 :     }
     191           0 :     catch (mcrl2::runtime_error& e)
     192             :     {
     193           0 :       std::cout << "pbesinst failed: " << e.what() << std::endl;
     194           0 :     }
     195             :   }
     196             : 
     197           9 :   if (test_lazy)
     198             :   {
     199           7 :     std::cout << "LAZY" << std::endl;
     200             :     try
     201             :     {
     202             :       using namespace pbes_system;
     203           7 :       pbes q1 = pbesinst_lazy(p);
     204           7 :       std::cout << pbes_system::pp(q1) << std::endl;
     205           7 :     }
     206           0 :     catch (mcrl2::runtime_error& e)
     207             :     {
     208           0 :       std::cout << "pbesinst failed: " << e.what() << std::endl;
     209           0 :     }
     210             :   }
     211           9 : }
     212             : 
     213           2 : BOOST_AUTO_TEST_CASE(test_pbesinst)
     214             : {
     215           1 :   test_pbes(test1, true, false);
     216           1 :   test_pbes(test2, true, true);
     217           1 :   test_pbes(test3, true, false);
     218           1 :   test_pbes(test4, true, true);
     219           1 :   test_pbes(test5, true, true);
     220           1 :   test_pbes(test6, true, true);
     221           1 :   test_pbes(test7, true, true);
     222           1 :   test_pbes(test8, true, true);
     223           1 :   test_pbes(random3, false, true);
     224           1 : }
     225             : 
     226           2 : BOOST_AUTO_TEST_CASE(test_pbesinst_finite)
     227             : {
     228           1 :   pbes p = txt2pbes(random3);
     229           1 :   pbes q = pbesinst_finite(p);
     230           1 :   std::cerr << pbes_system::pp(q) << std::endl;
     231             : 
     232             :   std::string text =
     233             :     "sort D = struct d1 | d2;                                        \n"
     234             :     "                                                                \n"
     235             :     "pbes                                                            \n"
     236             :     "                                                                \n"
     237             :     "nu X(d:D) = (val(d == d1) && X(d2)) || (val(d == d2) && X(d1)); \n"
     238             :     "                                                                \n"
     239           1 :     "init X(d1);                                                     \n"
     240             :     ;
     241           1 :   pbes p1 = txt2pbes(text);
     242           1 :   pbesinst_finite_algorithm algorithm(data::jitty);
     243           2 :   pbesinst_variable_map variable_map = mcrl2::pbes_system::detail::parse_pbes_parameter_map(p1, "X(*:D)");
     244           1 :   algorithm.run(p1, variable_map);
     245           1 : }
     246             : 
     247           2 : BOOST_AUTO_TEST_CASE(test_abp_no_deadlock)
     248             : {
     249           2 :   lps::specification spec=remove_stochastic_operators(lps::linearise(lps::detail::ABP_SPECIFICATION()));
     250           1 :   state_formulas::state_formula formula = state_formulas::parse_state_formula(lps::detail::NO_DEADLOCK(), spec, false);
     251           1 :   bool timed = false;
     252           1 :   pbes p = lps2pbes(spec, formula, timed);
     253           1 :   data::rewriter::strategy rewriter_strategy = data::jitty;
     254           1 :   bool print_equations = true;
     255           1 :   pbes_system::pbesinst_algorithm algorithm(p.data(), rewriter_strategy, print_equations);
     256           1 :   algorithm.run(p);
     257           1 :   pbes q = algorithm.get_result();
     258           1 :   std::cout << "--- ABP ---" << std::endl;
     259           1 :   std::cout << pbes_system::pp(q) << std::endl;
     260           1 :   BOOST_CHECK(is_bes(q));
     261           1 : }
     262             : 
     263             : // Example supplied by Tim Willemse, 23-05-2011
     264           2 : BOOST_AUTO_TEST_CASE(test_functions)
     265             : {
     266             :   std::string text =
     267             :     "sort D = struct one | two;           \n"
     268             :     "                                     \n"
     269             :     "map  f: D -> D;                      \n"
     270             :     "                                     \n"
     271             :     "eqn  f  =  lambda x: D. one;         \n"
     272             :     "                                     \n"
     273             :     "pbes nu X(d: D, g: D -> D) =         \n"
     274             :     "       forall e: D. X(e, g[e -> e]); \n"
     275             :     "                                     \n"
     276           1 :     "init X(one, f);                      \n"
     277             :     ;
     278           1 :   pbes p = txt2pbes(text);
     279           1 :   data::rewriter::strategy rewrite_strategy = data::jitty;
     280           1 :   pbesinst_finite_algorithm algorithm(rewrite_strategy);
     281           2 :   mcrl2::pbes_system::detail::pbes_parameter_map parameter_map = mcrl2::pbes_system::detail::parse_pbes_parameter_map(p, "X(*:D)");
     282           1 :   algorithm.run(p, parameter_map);
     283           1 : }
     284             : 
     285           4 : void test_pbesinst_symbolic(const std::string& text)
     286             : {
     287           4 :   pbes p;
     288           4 :   p = txt2pbes(text);
     289           4 :   pbesinst_symbolic_algorithm algorithm(p);
     290           4 :   algorithm.run();
     291           4 : }
     292             : 
     293           2 : BOOST_AUTO_TEST_CASE(test_pbesinst_symbolic1)
     294             : {
     295           1 :   test_pbesinst_symbolic(test2);
     296           1 :   test_pbesinst_symbolic(test4);
     297           1 :   test_pbesinst_symbolic(test5);
     298           1 :   test_pbesinst_symbolic(test6);
     299           1 : }
     300             : 
     301             : #ifdef MCRL2_EXTENDED_TESTS
     302             : BOOST_AUTO_TEST_CASE(test_pbesinst_slow)
     303             : {
     304             :   test_pbes(random1, false, true);
     305             :   test_pbes(random2, false, true);
     306             : }
     307             : 
     308             : // Note: this test takes a lot of time!
     309             : BOOST_AUTO_TEST_CASE(test_cabp)
     310             : {
     311             :     std::string CABP_SPECIFICATION =
     312             :             "% This file contains the cabp protocol as described in section 3.5 of         \n"
     313             :             "% S. Mauw and G.J. Veltink, editors, Algebraic Specification of Communication \n"
     314             :             "% Protocols, Cambridge tracts in theoretical computer science 36, Cambridge   \n"
     315             :             "% University Press, Cambridge 1993.                                           \n"
     316             :             "%                                                                             \n"
     317             :             "% With two data elements, the generated transition system has 464 states.     \n"
     318             :             "%                                                                             \n"
     319             :             "% It is interesting to see the clustering of this statespace in ltsgraph.     \n"
     320             :             "% The statespace after branching bisimulation contains 3 states and is        \n"
     321             :             "% exactly the same as the reduced statespace of the alternating bit protocol. \n"
     322             :             "%                                                                             \n"
     323             :             "% Note that it is interesting to compare the differences of the alternating   \n"
     324             :             "% bit protocol (abp), concurrent alternating bit protocol (cabp), one bit     \n"
     325             :             "% sliding window protocol (onebit) and the alternating bit protocol with      \n"
     326             :             "% independent acknowledgements (par), regarding the implementation, the       \n"
     327             :             "% the number of states and the external behaviour.                            \n"
     328             :             "                                                                              \n"
     329             :             "%-------------------------------  DATA  ----------------------------------    \n"
     330             :             "                                                                              \n"
     331             :             "sort DATA = struct d1 | d2;                                                   \n"
     332             :             "                                                                              \n"
     333             :             "%-------------------------------  error  ----------------------------------   \n"
     334             :             "                                                                              \n"
     335             :             "sort  error = struct ce | ae;                                                 \n"
     336             :             "                                                                              \n"
     337             :             "%-------------------------------  bit ------------------------------------    \n"
     338             :             "                                                                              \n"
     339             :             "sort  bit = struct bit0 | bit1;                                               \n"
     340             :             "                                                                              \n"
     341             :             "map   invert:bit -> bit;                                                      \n"
     342             :             "eqn   invert(bit1)=bit0;                                                      \n"
     343             :             "      invert(bit0)=bit1;                                                      \n"
     344             :             "                                                                              \n"
     345             :             "%-------------------------------  Frame ----------------------------------    \n"
     346             :             "                                                                              \n"
     347             :             "sort Frame = struct frame(getd : DATA, getb: bit);                            \n"
     348             :             "                                                                              \n"
     349             :             "%------------------------------  ACK   -----------------------------------    \n"
     350             :             "                                                                              \n"
     351             :             "sort ACK = struct ac;                                                         \n"
     352             :             "                                                                              \n"
     353             :             "%------------------------------  act   -----------------------------------    \n"
     354             :             "                                                                              \n"
     355             :             "act   r1,s2 : DATA;                                                           \n"
     356             :             "      c3,r3,s3,c4,r4,s4 : Frame;                                              \n"
     357             :             "      c4,r4,s4,c7,r7,s7 : error;                                              \n"
     358             :             "      c5,r5,s5,c8,r8,s8 : ACK;                                                \n"
     359             :             "      c6,r6,s6,c7,r7,s7 : bit;                                                \n"
     360             :             "      skip;                                                                   \n"
     361             :             "                                                                              \n"
     362             :             "%------------------------------  proc  -----------------------------------    \n"
     363             :             "                                                                              \n"
     364             :             "                                                                              \n"
     365             :             "proc  S = RM(bit0);                                                           \n"
     366             :             "      RM(b:bit) = sum d:DATA.r1(d).SF(frame(d,b));                            \n"
     367             :             "      SF(f:Frame) = s3(f).SF(f) + r8(ac).RM(invert(getb(f)));                 \n"
     368             :             "                                                                              \n"
     369             :             "      K  = sum f:Frame.r3(f).K(f);                                            \n"
     370             :             "      K(f:Frame) = (skip.s4(f)+skip.s4(ce)+skip).K;                           \n"
     371             :             "                                                                              \n"
     372             :             "      R = RF(bit0);                                                           \n"
     373             :             "      RF(b:bit) = sum d:DATA.r4(frame(d,b)).s2(d).s5(ac).RF(invert(b))        \n"
     374             :             "                     + sum d:DATA. r4(frame(d,invert(b))).RF(b)               \n"
     375             :             "                     + r4(ce).RF(b);                                          \n"
     376             :             "                                                                              \n"
     377             :             "      AS = AS(bit1);                                                          \n"
     378             :             "      AS(b:bit) = r5(ac).AS(invert(b)) + s6(b).AS(b);                         \n"
     379             :             "                                                                              \n"
     380             :             "      L = sum b:bit.r6(b) . L(b);                                             \n"
     381             :             "      L(b:bit) = ( skip.s7(b) + skip.s7(ae) + skip ).L;                       \n"
     382             :             "                                                                              \n"
     383             :             "      AR = AR(bit0);                                                          \n"
     384             :             "      AR(b:bit) = ( r7(ae) + r7(invert(b))) . AR(b)                           \n"
     385             :             "                   + r7(b).s8(ac).AR(invert(b));                              \n"
     386             :             "                                                                              \n"
     387             :             "init                                                                          \n"
     388             :             "   hide({c3,c4,c5,c6,c7,c8,skip},                                             \n"
     389             :             "     allow({c3,c4,c5,c6,c7,c8,skip,r1,s2},                                    \n"
     390             :             "       comm({r3|s3->c3, r4|s4->c4, r5|s5->c5, r6|s6->c6,                      \n"
     391             :             "                r7|s7->c7, r8|s8->c8},                                        \n"
     392             :             "               S || K || R || AS || L || AR )));                              \n"
     393             :     ;
     394             : 
     395             :     std::string INFINITELY_OFTEN_SEND = "nu X. mu Y. (<r1(d1)>X || <!r1(d1)>Y)";
     396             : 
     397             :     // create a pbes p
     398             :     lps::specification spec = remove_stochastic_operators(lps::linearise(CABP_SPECIFICATION));
     399             :     state_formulas::state_formula formula = state_formulas::parse_state_formula(INFINITELY_OFTEN_SEND, spec, false);
     400             :     bool timed = false;
     401             :     pbes p = lps2pbes(spec, formula, timed);
     402             :     pbes_system::detail::instantiate_global_variables(p);
     403             : 
     404             :     std::string expr = "(exists d_RM_00: DATA. (val(d_RM_00 == d1) && val(s31_RM == 1)) && X(2, bit0, frame(d_RM_00, b_RM), s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1)) || (((((((((((exists d_RM_00: DATA. (val(!(d_RM_00 == d1)) && val(s31_RM == 1)) && Y(2, bit0, frame(d_RM_00, b_RM), s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1)) || (exists e4_RF1_00: Bool, d4_RF1_00: DATA. val((s32_K == 3 && s33_RF1 == 1) && if(e4_RF1_00, frame(d4_RF1_00, invert(b_RF1)), frame(d4_RF1_00, b_RF1)) == f_K) && Y(s31_RM, b_RM, f_RM, 1, frame(d1, bit0), if(e4_RF1_00, 1, 2), if(e4_RF1_00, d1, d4_RF1_00), b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1))) || val(s32_K == 4 && s33_RF1 == 1) && Y(s31_RM, b_RM, f_RM, 1, frame(d1, bit0), 1, d1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1)) || val(s33_RF1 == 2) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, 3, d1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1)) || val(s35_L == 1) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, 2, b_AS1, s36_AR1, b_AR1)) || (exists e5_L_00: Enum3. val(C3_fun2(e5_L_00, true, true, true) && s35_L == 2) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, C3_fun(e5_L_00, 1, 3, 4), C3_fun3(e5_L_00, bit0, b_L, bit0), s36_AR1, b_AR1))) || val(s35_L == 4 && s36_AR1 == 1) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, 1, bit0, 1, b_AR1)) || (exists e7_AR1_00: Bool. val((s35_L == 3 && s36_AR1 == 1) && if(e7_AR1_00, b_AR1, invert(b_AR1)) == b_L) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, 1, bit0, if(e7_AR1_00, 2, 1), b_AR1))) || val(s33_RF1 == 3) && Y(s31_RM, b_RM, f_RM, s32_K, f_K, 1, d1, invert(b_RF1), invert(b_AS1), s35_L, b_L, s36_AR1, b_AR1)) || (exists e_K_00: Enum3. val(C3_fun2(e_K_00, true, true, true) && s32_K == 2) && Y(s31_RM, b_RM, f_RM, C3_fun(e_K_00, 1, 3, 4), C3_fun1(e_K_00, frame(d1, bit0), f_K, frame(d1, bit0)), s33_RF1, d_RF1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1))) || val(s31_RM == 2 && s32_K == 1) && Y(2, bit0, f_RM, 2, f_RM, s33_RF1, d_RF1, b_RF1, b_AS1, s35_L, b_L, s36_AR1, b_AR1)) || val(s31_RM == 2 && s36_AR1 == 2) && Y(1, invert(getb(f_RM)), frame(d1, bit0), s32_K, f_K, s33_RF1, d_RF1, b_RF1, b_AS1, s35_L, b_L, 1, invert(b_AR1))";
     405             :     std::string subst = "s31_RM:Pos := 2; b_RM:bit := bit0; f_RM:Frame := frame(d2, bit0); s32_K:Pos := 3; f_K:Frame := frame(d2, bit0); s33_RF1:Pos := 1; d_RF1:DATA := d1; b_RF1:bit := bit0; b_AS1:bit := bit1; s35_L:Pos := 1; b_L:bit := bit0; s36_AR1:Pos := 1; b_AR1:bit := bit0";
     406             : 
     407             :     data::mutable_map_substitution<> sigma;
     408             :     pbes_expression t = parse_pbes_expression(expr, subst, p, sigma);
     409             :     pbesinst_algorithm algorithm(p.data());
     410             :     enumerate_quantifiers_rewriter& R = algorithm.rewriter();
     411             :     data::mutable_indexed_substitution<> sigma1;
     412             :     for (const auto& i: sigma)
     413             :     {
     414             :         sigma1[i.first] = i.second;
     415             :     }
     416             :     pbes_expression z = R(t, sigma1);
     417             : }
     418             : 
     419             : // Note: this test takes a lot of time!
     420             : BOOST_AUTO_TEST_CASE(test_balancing_plat)
     421             : {
     422             :     using namespace pbes_system;
     423             : 
     424             :     const std::string BALANCE_PLAT_SPECIFICATION =
     425             :             " % Specification of balancing coins to determine the single coin with                 \n"
     426             :             " % different weight.                                                                  \n"
     427             :             "                                                                                      \n"
     428             :             " % C: Total number of coins                                                           \n"
     429             :             " map  C: Nat;                                                                         \n"
     430             :             " eqn  C = 12;                                                                         \n"
     431             :             "                                                                                      \n"
     432             :             " % Every coin can be in one of four categories: NHL, NH, NL, and N,                   \n"
     433             :             " % where:                                                                             \n"
     434             :             " % N: possibly normal weight                                                          \n"
     435             :             " % H: possibly heavy weight                                                           \n"
     436             :             " % L: possibly light weight                                                           \n"
     437             :             " % We count the number of coins in every category, but we do not count                \n"
     438             :             " % the number of coins in N explicitly, because:                                      \n"
     439             :             " %   |N| = C - ( |NHL| + |NH| + |NL| )                                                \n"
     440             :             "                                                                                      \n"
     441             :             " map                                                                                  \n"
     442             :             "      lexleq: Nat # Nat # Nat # Nat # Nat # Nat -> Bool;                              \n"
     443             :             "      is_better: Nat # Nat # Nat # Nat # Nat # Nat -> Bool;                           \n"
     444             :             "      is_useful: Nat # Nat # Nat # Nat # Nat # Nat # Nat # Nat # Nat -> Bool;         \n"
     445             :             "      is_possible: Nat # Nat # Nat # Nat # Nat # Nat # Nat # Nat # Nat -> Bool;       \n"
     446             :             "                                                                                      \n"
     447             :             " var  d1,d2,d3,e1,e2,e3,f1,f2,f3: Nat;                                                \n"
     448             :             "                                                                                      \n"
     449             :             " eqn                                                                                  \n"
     450             :             "      % lexicographical ordening on distributions; this is needed to                  \n"
     451             :             "      % eliminate half of the possibilities for balancing: only consider              \n"
     452             :             "      % X vs. Y and not Y vs. X, if X <= Y.                                           \n"
     453             :             "      lexleq(d1,d2,d3,e1,e2,e3) =                                                     \n"
     454             :             "          d1<e1 || (d1==e1 && d2<e2) || (d1==e1 && d2==e2 && d3<=e3);                 \n"
     455             :             "                                                                                      \n"
     456             :             "      % determines whether a distribution d is 'better than' a                        \n"
     457             :             "      % distribution e, in the sense that in d we have more certainty (or             \n"
     458             :             "      % less uncertainty) about a larger number of coins                              \n"
     459             :             "      is_better(d1,d2,d3,e1,e2,e3) = d1+d2+d3 < e1+e2+e3 || d1 < e1;                  \n"
     460             :             "                                                                                      \n"
     461             :             "      % determines whether weighing e against f is useful in situation d:             \n"
     462             :             "      % all possible outcomes should be an improvement                                \n"
     463             :             "      is_useful(d1,d2,d3,e1,e2,e3,f1,f2,f3) =                                         \n"
     464             :             "        is_better(Int2Nat(d1-e1-f1),Int2Nat(d2-e2-f2),Int2Nat(d3-e3-f3),d1,d2,d3) &&  \n"
     465             :             "        is_better(0,e1+e2,f1+f3,d1,d2,d3) &&                                          \n"
     466             :             "        is_better(0,f1+f2,e1+e3,d1,d2,d3);                                            \n"
     467             :             "                                                                                      \n"
     468             :             "      % determines whether weighing e against f is possible in situation              \n"
     469             :             "      % d:                                                                            \n"
     470             :             "      % - for every category X: X(e) + X(f) <= X(d)                                   \n"
     471             :             "      % - if total(e) < total(f) then N 'normal' coins are added to e                 \n"
     472             :             "      %   such that N = total(f) - total(e), so N 'normal' coins must                 \n"
     473             :             "      %   be available in situation d, i.e. N <= C - total(d).                        \n"
     474             :             "      % - analogously if total(e) > total(f).                                         \n"
     475             :             "      is_possible(d1,d2,d3,e1,e2,e3,f1,f2,f3) =                                       \n"
     476             :             "        e1+f1 <= d1 && e2+f2 <= d2 && e3+f3 <= d3 &&                                  \n"
     477             :             "        ( e1+e2+e3 == f1+f2+f3 ||                                                     \n"
     478             :             "          (e1+e2+e3 < f1+f2+f3 && f1+f2+f3 - e1-e2-e3 <= C - d1-d2-d3) ||             \n"
     479             :             "          (f1+f2+f3 < e1+e2+e3 && e1+e2+e3 - f1-f2-f3 <= C - d1-d2-d3)                \n"
     480             :             "        );                                                                            \n"
     481             :             "                                                                                      \n"
     482             :             " act  weigh, equal, greater, smaller: Nat # Nat # Nat # Nat # Nat # Nat;              \n"
     483             :             "      done;                                                                           \n"
     484             :             "                                                                                      \n"
     485             :             " proc BalancingAct(NHL,NH,NL:Nat) =                                                   \n"
     486             :             "      % we're done if |NHL| + |NH| + |NL| == 1                                        \n"
     487             :             "        (NHL+NH+NL == 1) -> done . BalancingAct(NHL,NH,NL)                            \n"
     488             :             "                                                                                      \n"
     489             :             "      + (NHL+NH+NL >  1) ->                                                           \n"
     490             :             "          (                                                                           \n"
     491             :             "            sum nhl_l,nh_l,nl_l:Nat, nhl_r,nh_r,nl_r:Nat .                            \n"
     492             :             "                                                                                      \n"
     493             :             "            (lexleq(nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) &&                               \n"
     494             :             "            is_possible(NHL,NH,NL,nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) &&                 \n"
     495             :             "            is_useful(NHL,NH,NL,nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r)) ->                  \n"
     496             :             "                                                                                      \n"
     497             :             "              weigh(nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) .                                \n"
     498             :             "              (                                                                       \n"
     499             :             "              % left and right have equal weight                                      \n"
     500             :             "              ((NHL-nhl_l-nhl_r + NH-nh_l-nh_r + NL-nl_l-nl_r > 0) ->                 \n"
     501             :             "                equal(nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) .                              \n"
     502             :             "                  BalancingAct(Int2Nat(NHL-nhl_l-nhl_r),                              \n"
     503             :             "                               Int2Nat(NH-nh_l-nh_r),                                 \n"
     504             :             "                               Int2Nat(NL-nl_l-nl_r)))                                \n"
     505             :             "              +                                                                       \n"
     506             :             "              % left is heavier than right                                            \n"
     507             :             "              ((nhl_l+nh_l + nhl_r+nl_r > 0) ->                                       \n"
     508             :             "                greater(nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) .                            \n"
     509             :             "                  BalancingAct(0,nhl_l+nh_l,nhl_r+nl_r))                              \n"
     510             :             "              +                                                                       \n"
     511             :             "              % left is lighter than right                                            \n"
     512             :             "              ((nhl_r+nh_r + nhl_l+nl_l > 0) ->                                       \n"
     513             :             "                smaller(nhl_l,nh_l,nl_l,nhl_r,nh_r,nl_r) .                            \n"
     514             :             "                  BalancingAct(0,nhl_r+nh_r,nhl_l+nl_l))                              \n"
     515             :             "              )                                                                       \n"
     516             :             "          );                                                                          \n"
     517             :             "                                                                                      \n"
     518             :             " init BalancingAct(C,0,0);                                                            \n"
     519             :     ;
     520             : 
     521             :     lps::specification spec = remove_stochastic_operators(lps::linearise(BALANCE_PLAT_SPECIFICATION));
     522             :     state_formulas::state_formula formula = state_formulas::parse_state_formula(lps::detail::NO_DEADLOCK(), spec, false);
     523             :     bool timed = false;
     524             :     pbes p = lps2pbes(spec, formula, timed);
     525             :     pbes_system::pbesinst_algorithm algorithm(p.data());
     526             :     algorithm.run(p);
     527             :     pbes q = algorithm.get_result();
     528             : }
     529             : #endif // MCRL2_EXTENDED_TESTS

Generated by: LCOV version 1.14