LCOV - code coverage report
Current view: top level - process/test - replace_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 83 97 85.6 %
Date: 2024-04-21 03:44:01 Functions: 12 13 92.3 %
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 replace_test.cpp
      10             : /// \brief Regression test for replace functions
      11             : 
      12             : #define BOOST_TEST_MODULE replace_test
      13             : #include <boost/test/included/unit_test.hpp>
      14             : 
      15             : #include "mcrl2/data/substitutions/mutable_map_substitution.h"
      16             : #include "mcrl2/process/parse.h"
      17             : #include "mcrl2/process/replace.h"
      18             : 
      19             : using namespace mcrl2;
      20             : using namespace mcrl2::process;
      21             : 
      22           1 : void check_result(const std::string& expression, const std::string& result, const std::string& expected_result, const std::string& title)
      23             : {
      24           1 :   if (result != expected_result)
      25             :   {
      26           0 :     std::cout << "--- failure in " << title << " ---" << std::endl;
      27           0 :     std::cout << "expression      = " << expression << std::endl;
      28           0 :     BOOST_CHECK_EQUAL(result, expected_result);
      29             :   }
      30           1 : }
      31             : 
      32             : inline
      33          24 : data::variable make_bool(const std::string& s)
      34             : {
      35          24 :   return data::variable(s, data::sort_bool::bool_());
      36             : }
      37             : 
      38             : inline
      39           1 : std::vector<data::variable> variable_context()
      40             : {
      41           1 :   std::vector<data::variable> result;
      42           1 :   result.push_back(make_bool("k"));
      43           1 :   result.push_back(make_bool("m"));
      44           1 :   result.push_back(make_bool("n"));
      45           1 :   result.push_back(make_bool("v"));
      46           1 :   result.push_back(make_bool("w"));
      47           1 :   result.push_back(make_bool("x"));
      48           1 :   result.push_back(make_bool("y"));
      49           1 :   result.push_back(make_bool("z"));
      50           1 :   result.push_back(make_bool("k1"));
      51           1 :   result.push_back(make_bool("m1"));
      52           1 :   result.push_back(make_bool("n1"));
      53           1 :   result.push_back(make_bool("v1"));
      54           1 :   result.push_back(make_bool("w1"));
      55           1 :   result.push_back(make_bool("x1"));
      56           1 :   result.push_back(make_bool("y1"));
      57           1 :   result.push_back(make_bool("z1"));
      58           1 :   result.push_back(make_bool("k2"));
      59           1 :   result.push_back(make_bool("m2"));
      60           1 :   result.push_back(make_bool("n2"));
      61           1 :   result.push_back(make_bool("v2"));
      62           1 :   result.push_back(make_bool("w2"));
      63           1 :   result.push_back(make_bool("x2"));
      64           1 :   result.push_back(make_bool("y2"));
      65           1 :   result.push_back(make_bool("z2"));
      66           1 :   return result;
      67           0 : }
      68             : 
      69             : inline
      70           1 : process_expression parse_expression(const std::string& text)
      71             : {
      72             :   std::string DATA_DECL =
      73             :     "glob k, m, n, k1, m1, n1, k2, m2, n2: Bool;\n"
      74           1 :     "act a, b, c: Bool;                         \n"
      75             :     ;
      76           1 :   std::string PROC_DECL = "proc P(n: Nat); proc Q(n: Nat); proc R(n: Nat); proc S(n: Nat);\n";
      77           2 :   return process::parse_process_expression(text, DATA_DECL, PROC_DECL);
      78           1 : }
      79             : 
      80             : /// \brief Parses a string of the form "b: Bool := v, c: Bool := !w", and adds
      81             : inline
      82           1 : data::mutable_map_substitution<> parse_substitution(const std::string& text, const std::vector<data::variable>& variables = variable_context())
      83             : {
      84           1 :   data::mutable_map_substitution<> sigma;
      85           2 :   std::vector<std::string> substitutions = utilities::split(text, ";");
      86           2 :   for (auto & substitution : substitutions)
      87             :   {
      88           2 :     std::vector<std::string> words = utilities::regex_split(substitution, ":=");
      89           1 :     if (words.size() != 2)
      90             :     {
      91           0 :       continue;
      92             :     }
      93           1 :     data::variable v = data::parse_variable(words[0]);
      94           1 :     data::data_expression e = data::parse_data_expression(words[1], variables);
      95           1 :     sigma[v] = e;
      96           1 :   }
      97           2 :   return sigma;
      98           1 : }
      99             : 
     100             : // Returns the free variables in the right hand side of sigma.
     101           0 : std::set<data::variable> sigma_variables(const data::mutable_map_substitution<>& sigma)
     102             : {
     103           0 :   std::set<data::variable> result;
     104           0 :   for (const auto & i : sigma)
     105             :   {
     106           0 :     std::set<data::variable> V = data::find_free_variables(i.second);
     107           0 :     V.erase(i.first);
     108           0 :     result.insert(V.begin(), V.end());
     109           0 :   }
     110           0 :   return result;
     111           0 : }
     112             : 
     113           1 : void test_replace_variables_capture_avoiding(const std::string& x_text, const std::string& sigma_text, const std::string& expected_result)
     114             : {
     115           1 :   process_expression x = parse_expression(x_text);
     116           1 :   data::mutable_map_substitution<> sigma = parse_substitution(sigma_text);
     117           1 :   std::string result = process::pp(process::replace_variables_capture_avoiding(x, sigma));
     118           1 :   check_result(x_text + " sigma = " + sigma_text, result, expected_result, "replace_variables_capture_avoiding");
     119           1 : }
     120             : 
     121           2 : BOOST_AUTO_TEST_CASE(replace_variables_capture_avoiding_test)
     122             : {
     123           1 :   test_replace_variables_capture_avoiding("sum n: Bool. a(n) . sum k: Bool. a(k) . a(m)", "m: Bool := n", "sum n1: Bool. a(n1) . (sum k1: Bool. a(k1) . a(n))");
     124           1 : }
     125             : 
     126           2 : BOOST_AUTO_TEST_CASE(process_instance_assignment_test)
     127             : {
     128             :   std::string text =
     129             :     "proc P(b: Bool, c: Bool) = P(c = true); \n"
     130             :     "                                        \n"
     131           1 :     "init P(true, true);                     \n"
     132             :     ;
     133             : 
     134           1 :   process_specification p = parse_process_specification(text);
     135           1 :   data::mutable_map_substitution<> sigma;
     136           2 :   data::variable b("b", data::sort_bool::bool_());
     137           2 :   data::variable c("c", data::sort_bool::bool_());
     138           1 :   sigma[c] = data::sort_bool::false_();
     139             : 
     140           1 :   process_expression x = p.equations().front().expression();
     141           1 :   process_expression x1 = process::replace_variables_capture_avoiding(x, sigma);
     142           1 :   std::cerr << process::pp(x1) << std::endl;
     143           1 :   BOOST_CHECK(process::pp(x1) == "P(c = true)");
     144             : 
     145           1 :   sigma[b] = data::sort_bool::false_();
     146           1 :   process_expression x2 = process::replace_variables_capture_avoiding(x, sigma);
     147           1 :   std::cerr << process::pp(x2) << std::endl;
     148           1 :   BOOST_CHECK(process::pp(x2) == "P(b = false, c = true)");
     149           1 : }
     150             : 
     151           2 : BOOST_AUTO_TEST_CASE(replace_process_identifiers_test)
     152             : {
     153             :   std::string text =
     154             :     "proc P(b: Bool, c: Bool) = P(c = true) . P(false, false); \n"
     155             :     "proc Q(b: Bool, c: Bool) = P(c = true);                   \n"
     156             :     "proc R(b: Bool, c: Bool) = Q(c = true) . Q(false, false); \n"
     157             :     "                                                          \n"
     158           1 :     "init P(true, true);                                       \n"
     159             :     ;
     160             : 
     161           1 :   process_specification p = parse_process_specification(text);
     162           1 :   process_equation eqP = p.equations()[0];
     163           1 :   process_equation eqQ = p.equations()[1];
     164           1 :   process_equation eqR = p.equations()[2];
     165             : 
     166           2 :   process_expression rhs = replace_process_identifiers(eqP.expression(), process_identifier_assignment(eqP.identifier(), eqQ.identifier()));
     167           1 :   BOOST_CHECK(rhs == eqR.expression());
     168           1 : }

Generated by: LCOV version 1.14