LCOV - code coverage report
Current view: top level - data/test - data_specification_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 429 458 93.7 %
Date: 2024-04-21 03:44:01 Functions: 31 33 93.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jeroen Keiren, 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 data_specification_test.cpp
      10             : /// \brief Basic regression test for data specifications.
      11             : 
      12             : #define BOOST_TEST_MODULE data_specification_test
      13             : #include <boost/test/included/unit_test.hpp>
      14             : 
      15             : #include "mcrl2/data/data_io.h"
      16             : #include "mcrl2/data/merge_data_specifications.h"
      17             : #include "mcrl2/data/parse.h"
      18             : #include "mcrl2/data/print.h"
      19             : 
      20             : using namespace mcrl2;
      21             : using namespace mcrl2::data;
      22             : 
      23             : template <typename Container1, typename Container2>
      24             : bool equal_content(Container1 const& c1, Container2 const& c2)
      25             : {
      26             :   std::set<typename Container1::value_type> s1(c1.begin(), c1.end());
      27             :   std::set<typename Container2::value_type> s2(c2.begin(), c2.end());
      28             : 
      29             :   if (s1 != s2)
      30             :   {
      31             :     std::clog << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl
      32             :                       << "Detailed comparison:" << std::endl;
      33             :     std::clog << data::pp(c1) << std::endl;
      34             :     std::clog << data::pp(c2) << std::endl;
      35             :   }
      36             :   return s1 == s2;
      37             : }
      38             : 
      39          15 : bool detailed_compare_for_equality(data_specification const& left, data_specification const& right)
      40             : {
      41          15 :   std::set<sort_expression> left_sorts(left.sorts().begin(), left.sorts().end());
      42          15 :   std::set<sort_expression> right_sorts(right.sorts().begin(), right.sorts().end());
      43          15 :   BOOST_CHECK(left_sorts == right_sorts);
      44             : 
      45          15 :   std::set<data::function_symbol> left_constructors(left.constructors().begin(), left.constructors().end());
      46          15 :   std::set<data::function_symbol> right_constructors(right.constructors().begin(), right.constructors().end());
      47          15 :   BOOST_CHECK(left_constructors == right_constructors);
      48             : 
      49          15 :   std::set<data::function_symbol> left_mappings(left.mappings().begin(), left.mappings().end());
      50          15 :   std::set<data::function_symbol> right_mappings(right.mappings().begin(), right.mappings().end());
      51          15 :   BOOST_CHECK(left_mappings == right_mappings);
      52             : 
      53          15 :   BOOST_CHECK(left.equations() == right.equations());
      54             : 
      55          15 :   if (/*(left_aliases != right_aliases)*/
      56          15 :        (left_sorts != right_sorts)
      57          15 :       || (left_constructors != right_constructors)
      58          15 :       || (left_mappings != right_mappings)
      59          30 :       || (left.equations() != right.equations()))
      60             :   {
      61           0 :     std::clog << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl
      62           0 :                   << "Specification detailed comparison:" << std::endl;
      63             : 
      64             :   /*
      65             :     if (left_aliases != right_aliases)
      66             :     {
      67             :       std::clog << "Aliases (left)  " << data::pp(left.aliases()) << std::endl;
      68             :       std::clog << "Aliases (right)  " << data::pp(right.aliases()) << std::endl;
      69             :     }*/
      70           0 :     if (left_sorts != right_sorts)
      71             :     {
      72           0 :       std::clog << "Sorts (left)  " << data::pp(left.sorts()) << std::endl;
      73           0 :       std::clog << "Sorts (right) " << data::pp(right.sorts()) << std::endl;
      74             :     }
      75           0 :     if (left_constructors != right_constructors)
      76             :     {
      77           0 :       std::clog << "Constructors (left)  " << data::pp(left.constructors()) << std::endl;
      78           0 :       std::clog << "Constructors (right) " << data::pp(right.constructors()) << std::endl;
      79             :     }
      80           0 :     if (left_mappings != right_mappings)
      81             :     {
      82           0 :       std::clog << "Mappings (left)  " << data::pp(left.mappings()) << std::endl;
      83           0 :       std::clog << "Mappings (right) " << data::pp(right.mappings()) << std::endl;
      84             :     }
      85           0 :     if (left.equations() != right.equations())
      86             :     {
      87           0 :       std::clog << "Equations (left)  " << data::pp(left.equations()) << std::endl;
      88           0 :       std::clog << "Equations (right) " << data::pp(right.equations()) << std::endl;
      89             :     }
      90             : 
      91           0 :     std::clog << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
      92             : 
      93           0 :     return false;
      94             :   }
      95          15 :   return true;
      96          15 : }
      97             : 
      98          15 : bool compare_for_equality(data_specification const& left, data_specification const& right)
      99             : {
     100          15 :   return detailed_compare_for_equality(left, right);
     101             : }
     102             : 
     103           1 : void test_sorts()
     104             : {
     105           1 :   std::clog << "test_sorts" << std::endl;
     106             : 
     107           2 :   basic_sort s("S");
     108           2 :   basic_sort s0("S0");
     109           2 :   alias s1(s,basic_sort("S1"));
     110             : 
     111           1 :   std::vector< sort_expression > sl;
     112           1 :   sl.push_back(basic_sort("S1"));
     113           1 :   sl.push_back(s0);
     114             : 
     115           1 :   data_specification spec;
     116           1 :   spec.add_sort(s);
     117           1 :   spec.add_sort(s0);
     118           1 :   spec.add_alias(s1);
     119           1 :   data_specification spec1;
     120           1 :   spec1.add_alias(s1);
     121           1 :   spec1.add_sort(s0);
     122           1 :   spec1.add_sort(s);
     123             : 
     124             :   //BOOST_CHECK(equal_content(sl, spec.user_defined_sorts()));
     125             :   //BOOST_CHECK(equal_content(sl, spec1.user_defined_sorts()));
     126           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     127             : 
     128           2 :   basic_sort s2("S2");
     129           3 :   sort_expression_vector s2l {s2};
     130           1 :   spec.add_context_sort(s2);
     131           1 :   spec1.add_context_sorts(s2l);
     132           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     133             : 
     134           2 :   std::for_each(s2l.begin(), s2l.end(), [&spec](const sort_expression& s){ spec.remove_sort(s); });
     135           1 :   spec1.remove_sort(s2);
     136           1 :   compare_for_equality(spec, spec1);
     137           1 : }
     138             : 
     139           0 : void test_aliases()
     140             : {
     141           0 :   std::clog << "test_aliases" << std::endl;
     142             : 
     143           0 :   basic_sort s("S");
     144           0 :   basic_sort t("T");
     145           0 :   alias      s1(basic_sort("S1"), s);
     146           0 :   alias      s2(basic_sort("S2"), s);
     147             : 
     148           0 :   data_specification spec;
     149             : 
     150             :   // BOOST_CHECK(spec.aliases().size()) == 0);
     151             : 
     152           0 :   std::set<basic_sort> sorts = { s, t };
     153           0 :   std::for_each(sorts.begin(), sorts.end(), [&spec](const basic_sort& s){ spec.add_sort(s); });
     154             : 
     155             :   /* std::set< sort_expression > aliases;
     156             :   aliases.insert(s1);
     157             :   aliases.insert(s2);
     158             :   spec.add_aliases(aliases);
     159             : 
     160             :   BOOST_CHECK(spec.aliases(s).size()) == 2);
     161             :   BOOST_CHECK(spec.aliases(t).size()) == 0);
     162             :   BOOST_CHECK(spec.aliases(s) == aliases); */
     163           0 : }
     164             : 
     165           1 : void test_constructors()
     166             : {
     167           1 :   std::clog << "test_constructors" << std::endl;
     168             : 
     169           2 :   basic_sort s("S");
     170           2 :   basic_sort s0("S0");
     171           3 :   function_sort s0s(sort_expression_list({s0}),s);
     172           2 :   data::function_symbol f("f", s);
     173           2 :   data::function_symbol g("g", s0s);
     174           2 :   data::function_symbol h("h", s0);
     175           4 :   function_symbol_vector fgl {f,g};
     176           3 :   function_symbol_vector hl {h};
     177           5 :   function_symbol_vector fghl {f,g,h};
     178             : 
     179           1 :   data_specification spec;
     180           1 :   spec.add_sort(s);
     181           1 :   spec.add_sort(s0);
     182             : 
     183           1 :   spec.add_constructor(f);
     184           1 :   spec.add_constructor(g);
     185           1 :   spec.add_constructor(h);
     186             : 
     187           1 :   data_specification spec1(spec);
     188           4 :   std::for_each(fghl.begin(), fghl.end(), [&spec1](const function_symbol& f){ spec1.add_constructor(f); });
     189             : 
     190           1 :   function_symbol_vector constructors(spec.constructors());
     191           1 :   BOOST_CHECK(spec.constructors(s) == fgl);
     192           1 :   BOOST_CHECK(constructors.size() == 7); // f,g,h, true, false.
     193           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), f) != constructors.end());
     194           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), g) != constructors.end());
     195           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), h) != constructors.end());
     196             : 
     197           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     198           1 :   BOOST_CHECK(spec.constructors() == spec1.constructors());
     199           1 :   BOOST_CHECK(spec.constructors(s) == fgl);
     200           1 :   BOOST_CHECK(spec.constructors(s0) == hl);
     201           1 :   BOOST_CHECK(spec1.constructors(s) == fgl);
     202           1 :   BOOST_CHECK(spec1.constructors(s0) == hl);
     203           1 :   spec.add_constructor(data::function_symbol("i", s0));
     204           2 :   data::function_symbol i("i", s0);
     205           1 :   spec.remove_constructor(i);
     206           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     207             : 
     208           1 :   spec.add_constructor(i);
     209           3 :   function_symbol_vector il {i};
     210           2 :   std::for_each(il.begin(), il.end(), [&spec1](const function_symbol& f){ spec1.add_constructor(f); });
     211             : 
     212           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     213             : 
     214           1 :   spec.remove_constructor(i);
     215           2 :   std::for_each(il.begin(), il.end(), [&spec1](const function_symbol& f){ spec1.remove_constructor(f); });
     216             :   
     217           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     218           1 : }
     219             : 
     220           1 : void test_functions()
     221             : {
     222           1 :   std::clog << "test_functions" << std::endl;
     223             : 
     224           2 :   basic_sort s("S");
     225           2 :   basic_sort s0("S0");
     226           3 :   function_sort s0s(sort_expression_list({s0}), s);
     227           2 :   data::function_symbol f("f", s);
     228           2 :   data::function_symbol g("g", s0s);
     229           2 :   data::function_symbol h("h", s0);
     230             : 
     231           4 :   function_symbol_vector fgl {f,g};
     232           3 :   function_symbol_vector hl {h};
     233           5 :   function_symbol_vector fghl {f,g,h};
     234             : 
     235           1 :   data_specification spec;
     236           1 :   spec.add_sort(s);
     237           1 :   spec.add_sort(s0);
     238           1 :   spec.add_mapping(f);
     239           1 :   spec.add_mapping(g);
     240           1 :   spec.add_mapping(h);
     241             : 
     242           1 :   data_specification spec1(spec);
     243           4 :   std::for_each(fghl.begin(), fghl.end(), [&spec1](const function_symbol& f){ spec1.add_mapping(f); } );
     244             : 
     245           1 : std::cerr << "#mappings " << spec.mappings().size() << "\n";
     246           1 :   BOOST_CHECK(spec.mappings().size() == 54);
     247             : 
     248           1 :   function_symbol_vector mappings(spec.mappings());
     249           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), f) != mappings.end());
     250           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), g) != mappings.end());
     251           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), h) != mappings.end());
     252             : 
     253           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     254           1 :   BOOST_CHECK(spec.mappings(s).size() == 3);
     255           1 :   BOOST_CHECK(std::find(spec.mappings(s).begin(), spec.mappings(s).end(), f) != spec.mappings(s).end());
     256           1 :   BOOST_CHECK(std::find(spec.mappings(s).begin(), spec.mappings(s).end(), g) != spec.mappings(s).end());
     257           1 :   BOOST_CHECK(std::find(spec.mappings(s0).begin(), spec.mappings(s0).end(), h) != spec.mappings(s0).end());
     258           1 :   BOOST_CHECK(spec1.mappings(s).size() == 3);
     259           1 :   BOOST_CHECK(std::find(spec1.mappings(s).begin(), spec1.mappings(s).end(), f) != spec1.mappings(s).end());
     260           1 :   BOOST_CHECK(std::find(spec1.mappings(s).begin(), spec1.mappings(s).end(), g) != spec1.mappings(s).end());
     261           1 :   BOOST_CHECK(std::find(spec1.mappings(s0).begin(), spec1.mappings(s0).end(), h) != spec1.mappings(s0).end());
     262             : 
     263           2 :   data::function_symbol i("i", s0);
     264           1 :   spec.add_mapping(i);
     265           3 :   function_symbol_vector il {i}; 
     266           2 :   std::for_each(il.begin(), il.end(), [&spec1](const function_symbol& f){ spec1.add_mapping(f); }); 
     267           1 :   compare_for_equality(spec, spec1);
     268             : 
     269           2 :   std::for_each(il.begin(), il.end(), [&spec](const function_symbol& f){ spec.remove_mapping(f); });
     270           1 :   spec1.remove_mapping(i);
     271           1 :   compare_for_equality(spec, spec1);
     272           1 : }
     273             : 
     274           1 : void test_equations()
     275             : {
     276           1 :   std::clog << "test_equations" << std::endl;
     277           2 :   basic_sort s("S");
     278           2 :   basic_sort s0("S0");
     279           3 :   function_sort s0s(sort_expression_list({s0}), s);
     280           2 :   data::function_symbol f("f", s0s);
     281           2 :   variable x("x", s0);
     282           3 :   data_expression_vector xel {x};
     283           1 :   application fx(f, xel.begin(), xel.end());
     284           3 :   variable_vector xl {x};
     285           1 :   data_equation fxx(xl, x, fx, x);
     286             : 
     287           1 :   data_specification spec;
     288           1 :   data_specification spec1;
     289           1 :   spec.add_sort(s);
     290           1 :   spec.add_sort(s0);
     291             : 
     292           1 :   spec1 = spec;
     293           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     294           1 :   spec.add_equation(fxx);
     295           3 :   data_equation_vector fxxl {fxx};
     296           2 :   std::for_each(fxxl.begin(), fxxl.end(), [&spec1](const data_equation& eqn){ spec1.add_equation(eqn); }); 
     297             : 
     298           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     299             : 
     300           1 :   data_equation fxf(xl, x, fx, f);
     301           3 :   data_equation_vector fxfl {fxf};
     302           1 :   spec.add_equation(fxf);
     303           2 :   std::for_each(fxfl.begin(), fxfl.end(), [&spec1](const data_equation& eqn){ spec1.add_equation(eqn); }); 
     304             : 
     305           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     306             : 
     307           1 :   data_equation_vector result = find_equations(spec, f);
     308           1 :   BOOST_CHECK(result.size() == 2);
     309           1 :   BOOST_CHECK(std::find(result.begin(), result.end(), fxf) != result.end());
     310           1 :   BOOST_CHECK(std::find(result.begin(), result.end(), fxx) != result.end());
     311           2 :   std::for_each(fxfl.begin(), fxfl.end(), [&spec](const data_equation& eqn){ spec.remove_equation(eqn); }); 
     312           1 :   spec1.remove_equation(fxf);
     313           1 :   BOOST_CHECK(compare_for_equality(spec, spec1));
     314           1 : }
     315             : 
     316           1 : void test_is_certainly_finite()
     317             : {
     318           1 :   std::clog << "test_is_certainly_finite" << std::endl;
     319           2 :   basic_sort s("S");
     320           2 :   basic_sort s0("S0");
     321           3 :   function_sort s0s0(sort_expression_list({s0}), s0);
     322           2 :   data::function_symbol f("f", s);
     323           2 :   data::function_symbol g("g", s0s0);
     324           2 :   variable x("x", s0);
     325           1 :   application gx(g, x);
     326           1 :   data_specification spec;
     327           1 :   spec.add_sort(s);
     328           1 :   spec.add_sort(s0);
     329           1 :   spec.add_constructor(f);
     330           1 :   spec.add_constructor(g);
     331             : 
     332           1 :   BOOST_CHECK(spec.is_certainly_finite(s));
     333           1 :   BOOST_CHECK(!spec.is_certainly_finite(s0));
     334             : 
     335           1 :   spec.add_context_sort(sort_real::real_());
     336           1 :   BOOST_CHECK(spec.is_certainly_finite(sort_bool::bool_()));
     337           1 :   BOOST_CHECK(!spec.is_certainly_finite(sort_pos::pos()));
     338           1 :   BOOST_CHECK(!spec.is_certainly_finite(sort_nat::nat()));
     339           1 :   BOOST_CHECK(!spec.is_certainly_finite(sort_int::int_()));
     340           1 :   BOOST_CHECK(!spec.is_certainly_finite(sort_real::real_()));
     341             : 
     342           2 :   basic_sort s1("S1");
     343           2 :   basic_sort s2("S2");
     344           1 :   spec.add_constructor(data::function_symbol("h", make_function_sort_(s1, s2)));
     345           1 :   spec.add_constructor(data::function_symbol("i", make_function_sort_(s2, s1)));
     346             : 
     347           1 :   spec.add_alias(alias(basic_sort("a"), s));
     348           1 :   spec.add_alias(alias(basic_sort("a0"), s0));
     349           1 :   spec.add_alias(alias(basic_sort("a1"), s1));
     350             : 
     351           1 :   BOOST_CHECK(spec.is_certainly_finite(normalize_sorts(basic_sort("a"),spec)));
     352           1 :   BOOST_CHECK(!spec.is_certainly_finite(normalize_sorts(basic_sort("a0"),spec)));
     353           1 :   BOOST_CHECK(!spec.is_certainly_finite(normalize_sorts(basic_sort("a1"),spec)));
     354             : 
     355             :   using namespace sort_list;
     356             : 
     357           1 :   BOOST_CHECK(!spec.is_certainly_finite(list(s)));
     358           1 :   BOOST_CHECK(!spec.is_certainly_finite(list(s0)));
     359             : 
     360             :   using namespace sort_set;
     361             : 
     362           1 :   BOOST_CHECK(spec.is_certainly_finite(set_(s)));
     363           1 :   BOOST_CHECK(!spec.is_certainly_finite(set_(s0)));
     364           1 :   BOOST_CHECK(!spec.is_certainly_finite(normalize_sorts(set_(s0),spec)));
     365             : 
     366             :   using namespace sort_bag;
     367             : 
     368           1 :   BOOST_CHECK(!spec.is_certainly_finite(bag(s)));
     369           1 :   BOOST_CHECK(!spec.is_certainly_finite(bag(s0)));
     370           1 :   BOOST_CHECK(spec.is_certainly_finite(make_function_sort_(s,s)));
     371           1 :   BOOST_CHECK(!spec.is_certainly_finite(make_function_sort_(s,s0)));
     372           1 :   BOOST_CHECK(!spec.is_certainly_finite(make_function_sort_(s0,s)));
     373             : 
     374             :   // structured sort
     375             :   /* This test should be reconsidered, as it does not work in this way.
     376             :  *   Having a test for structured sort is good.
     377             : 
     378             :   std::vector< data::structured_sort_constructor_argument > arguments;
     379             : 
     380             :   arguments.push_back(data::structured_sort_constructor_argument(s));
     381             :   arguments.push_back(data::structured_sort_constructor_argument(s0));
     382             :   arguments.push_back(data::structured_sort_constructor_argument(s1));
     383             : 
     384             :   std::vector< data::structured_sort_constructor > constructors;
     385             :   constructors.push_back(data::structured_sort_constructor("a", structured_sort_constructor_argument_list(arguments.begin(), arguments.begin() + 1)));
     386             :   constructors.push_back(data::structured_sort_constructor("b", structured_sort_constructor_argument_list(arguments.begin() + 1, arguments.begin() + 2)));
     387             :   constructors.push_back(data::structured_sort_constructor("b", structured_sort_constructor_argument_list(arguments.begin() + 2, arguments.begin() + 3)));
     388             : 
     389             :   structured_sort struct1(structured_sort_constructor_list(constructors.begin(), constructors.begin() + 1));
     390             :   structured_sort struct2(structured_sort_constructor_list(constructors.begin() + 1, constructors.begin() + 2));
     391             :   structured_sort struct3(structured_sort_constructor_list(constructors.begin() + 2, constructors.begin() + 3));
     392             :   structured_sort struct4(structured_sort_constructor_list(constructors.begin() + 0, constructors.begin() + 3));
     393             :   spec.add_sort(struct1);   add_sort does not work on complex sorts, since 2/6/2015.
     394             :   spec.add_sort(struct2);
     395             :   spec.add_sort(struct3);
     396             :   spec.add_sort(struct4);
     397             :   BOOST_CHECK(spec.is_certainly_finite(struct1));
     398             :   BOOST_CHECK(!spec.is_certainly_finite(struct2));
     399             :   BOOST_CHECK(!spec.is_certainly_finite(struct3));
     400             :   BOOST_CHECK(!spec.is_certainly_finite(struct4)); */
     401           1 : }
     402             : 
     403           1 : void test_constructor()
     404             : {
     405           1 :   std::clog << "test_constructor" << std::endl;
     406             :   std::string SPEC =
     407             :     "sort                      \n"
     408             :     "  D     = struct d1 | d2; \n"
     409             :     "  Error = struct e;       \n"
     410           1 :     "                          \n"
     411             :     ;
     412           1 :   data_specification data = parse_data_specification(SPEC);
     413           1 :   atermpp::aterm_appl a = data::detail::data_specification_to_aterm(data);
     414           1 :   data_specification spec1(a);
     415           1 : }
     416             : 
     417             : template < typename Container, typename Expression >
     418           1 : bool search(Container const& container, Expression const& expression)
     419             : {
     420           1 :   return std::find(container.begin(), container.end(), expression) != container.end();
     421             : }
     422             : 
     423           3 : bool search_alias(const alias_vector& v, const sort_expression& s)
     424             : {
     425           6 :   for(const alias& a: v)
     426             :   {
     427           6 :     if(a.name() == s)
     428             :     {
     429           3 :       return true;
     430             :     }
     431             :   }
     432           0 :   return false;
     433             : }
     434             : 
     435           1 : void test_system_defined()
     436             : {
     437           1 :   std::clog << "test_system_defined" << std::endl;
     438             : 
     439           1 :   data_specification specification;
     440             : 
     441           1 :   BOOST_CHECK(!specification.constructors(sort_bool::bool_()).empty());
     442             : 
     443           2 :   specification = parse_data_specification(
     444             :                     "sort S;"
     445           1 :                     "map f: Set(S);");
     446             : 
     447           1 :   BOOST_CHECK(search(specification.sorts(), sort_set::set_(basic_sort("S"))));
     448             :   // BOOST_CHECK(search(specification.sorts(), sort_fset::fset(basic_sort("S")))); MUST BE CHECKED ALSO?
     449             : 
     450           2 :   specification = parse_data_specification(
     451             :                     "sort D = Set(Nat);"
     452             :                     "sort E = D;"
     453           1 :                     "sort F = E;");
     454           1 :   BOOST_CHECK(specification.constructors(::sort_set::set_(sort_nat::nat())) == specification.constructors(basic_sort("D")));
     455           1 :   BOOST_CHECK(specification.constructors(normalize_sorts(basic_sort("D"),specification)) ==
     456             :               specification.constructors(normalize_sorts(basic_sort("E"),specification)));
     457           1 :   BOOST_CHECK(specification.mappings(normalize_sorts(basic_sort("D"),specification)) ==
     458             :               specification.mappings(normalize_sorts(basic_sort("E"),specification)));
     459           1 :   BOOST_CHECK(specification.constructors(normalize_sorts(basic_sort("D"),specification)) ==
     460             :               specification.constructors(normalize_sorts(basic_sort("F"),specification)));
     461             : 
     462           1 :   data_specification copy = specification;
     463             : 
     464             :   // A data specification that is constructed using data_specification_to_aterm is assumed not
     465             :   // not be type checked. This must be indicated explicitly.
     466           2 :   data_specification specification1=data_specification(data::detail::data_specification_to_aterm(copy));
     467           1 :   BOOST_CHECK(compare_for_equality(specification1,specification));
     468             : 
     469           2 :   specification = parse_data_specification(
     470             :                     "sort D = struct d(getBool : Bool)?is_d;"
     471             :                     "sort E = D;"
     472           1 :                     "sort F = E;");
     473             : 
     474           1 :   alias_vector aliases(specification.user_defined_aliases());
     475           1 :   BOOST_CHECK(search_alias(aliases, basic_sort("D")));
     476           1 :   BOOST_CHECK(search_alias(aliases, basic_sort("E")));
     477           1 :   BOOST_CHECK(search_alias(aliases, basic_sort("F")));
     478           1 :   BOOST_CHECK(specification.constructors(basic_sort("D")).size() == 1);
     479             : 
     480           1 :   BOOST_CHECK(specification.constructors(basic_sort("D")) == specification.constructors(basic_sort("E")));
     481           1 :   BOOST_CHECK(specification.mappings(basic_sort("D")) == specification.mappings(basic_sort("E")));
     482           1 :   BOOST_CHECK(specification.constructors(basic_sort("D")) == specification.constructors(basic_sort("F")));
     483             : 
     484             :   /* copy = specification;
     485             :   specification1=data_specification(data::detail::data_specification_to_aterm(copy));
     486             :   specification1.declare_data_specification_to_be_type_checked();
     487             :   BOOST_CHECK(compare_for_equality(specification1, specification)); */
     488             : 
     489             :   // Check for the non presence of function sort
     490           1 :   BOOST_CHECK(specification.mappings(make_function_sort_(basic_sort("D"), sort_bool::bool_())).empty());
     491             : 
     492           1 :   specification.add_mapping(data::function_symbol("f", make_function_sort_(sort_bool::bool_(), sort_bool::bool_(), sort_nat::nat())));
     493             : 
     494           1 :   BOOST_CHECK(!specification.mappings(make_function_sort_(sort_bool::bool_(), sort_bool::bool_(), sort_nat::nat())).empty());
     495             : 
     496             :   // Manually structured sort
     497           1 :   std::vector< data::structured_sort_constructor_argument > arguments;
     498             : 
     499             :   // sort that references itself by a name
     500           1 :   arguments.push_back(data::structured_sort_constructor_argument(basic_sort("Q")));
     501             : 
     502           1 :   std::vector< data::structured_sort_constructor > constructors;
     503           1 :   constructors.push_back(data::structured_sort_constructor("q",structured_sort_constructor_argument_list(arguments.begin(), arguments.begin() + 1)));
     504             : 
     505           1 :   specification.add_alias(alias(basic_sort("Q"), data::structured_sort(constructors)));
     506           1 : }
     507             : 
     508           1 : void test_utility_functionality()
     509             : {
     510           1 :   data_specification spec;
     511             : 
     512           2 :   basic_sort s("S");
     513           2 :   basic_sort s0("S0");
     514           2 :   basic_sort a("a");
     515           3 :   function_sort s0s(sort_expression_list({s0}), s);
     516           2 :   data::function_symbol f("f", s);
     517             : 
     518           2 :   data::function_symbol g("g", s0s);
     519           2 :   data::function_symbol h("h", s0);
     520             : 
     521             :   {
     522           1 :     const std::set<sort_expression>& sorts(spec.sorts());
     523           1 :     BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s0) == sorts.end());
     524           1 :     BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s) == sorts.end());
     525           1 :     function_symbol_vector constructors(spec.constructors());
     526           1 :     BOOST_CHECK(std::find(constructors.begin(), constructors.end(), f) == constructors.end());
     527           1 :     function_symbol_vector mappings(spec.mappings());
     528           1 :     BOOST_CHECK(std::find(mappings.begin(), mappings.end(), f) == mappings.end());
     529           1 :     BOOST_CHECK(std::find(mappings.begin(), mappings.end(), g) == mappings.end());
     530           1 :   }
     531             : 
     532           1 :   spec.add_sort(s0);
     533           1 :   spec.add_constructor(f);
     534           1 :   spec.add_mapping(g);
     535             : 
     536             :   {
     537           1 :     const std::set<sort_expression>& sorts(spec.sorts());
     538           1 :     BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s0) != sorts.end());
     539           1 :     BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s) != sorts.end()); // Automatically added!
     540           1 :     function_symbol_vector constructors(spec.constructors());
     541           1 :     BOOST_CHECK(std::find(constructors.begin(), constructors.end(), f) != constructors.end());
     542           1 :     function_symbol_vector mappings(spec.mappings());
     543           1 :     BOOST_CHECK(std::find(mappings.begin(), mappings.end(), f) == mappings.end());
     544           1 :     BOOST_CHECK(std::find(mappings.begin(), mappings.end(), g) != mappings.end());
     545           1 :     BOOST_CHECK(std::find(mappings.begin(), mappings.end(), h) == mappings.end());
     546           1 :   }
     547           1 :   spec.add_mapping(h);
     548             : 
     549           1 :   spec.add_sort(s);
     550           1 :   spec.add_alias(alias(basic_sort("a"),s));
     551             : 
     552           1 :   const std::set<sort_expression> sorts(spec.sorts());
     553           1 :   function_symbol_vector constructors(spec.constructors());
     554           1 :   function_symbol_vector mappings(spec.mappings());
     555             : 
     556             : 
     557           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s0) != sorts.end());
     558           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), normalize_sorts(a,spec)) != sorts.end());
     559           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), s) != sorts.end());
     560             : 
     561           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), f) == mappings.end());
     562           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), f) != constructors.end());
     563             : 
     564           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), g) == constructors.end());
     565           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), g) != mappings.end());
     566           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), g) == constructors.end());
     567           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), h) == constructors.end());
     568           1 :   BOOST_CHECK(std::find(mappings.begin(), mappings.end(), h) != mappings.end());
     569           1 :   BOOST_CHECK(spec.constructors(a) == spec.constructors(s));
     570           1 :   BOOST_CHECK(spec.mappings(a) == spec.mappings(s));
     571           1 : }
     572             : 
     573           1 : void test_normalisation()
     574             : {
     575             :   using namespace mcrl2::data;
     576             :   using namespace mcrl2::data::sort_list;
     577             :   using namespace mcrl2::data::sort_set;
     578             :   using namespace mcrl2::data::sort_bag;
     579             : 
     580           1 :   data_specification specification;
     581             : 
     582           2 :   basic_sort A("A");
     583             : 
     584           1 :   specification.add_sort(A);
     585             : 
     586           2 :   basic_sort L("L");
     587           2 :   basic_sort S("S");
     588           2 :   basic_sort B("B");
     589             : 
     590           1 :   specification.add_alias(alias(L, list(A)));
     591           1 :   specification.add_alias(alias(S, set_(A)));
     592           1 :   specification.add_alias(alias(B, bag(A)));
     593           1 :   BOOST_CHECK(normalize_sorts(L,specification) == normalize_sorts(list(A),specification));
     594           1 :   BOOST_CHECK(normalize_sorts(list(L),specification) == normalize_sorts(list(list(A)),specification));
     595           1 :   BOOST_CHECK(normalize_sorts(S,specification) == normalize_sorts(set_(A),specification));
     596           1 :   BOOST_CHECK(normalize_sorts(list(S),specification) == normalize_sorts(list(set_(A)),specification));
     597           1 :   BOOST_CHECK(normalize_sorts(B,specification) == normalize_sorts(bag(A),specification));
     598           1 :   BOOST_CHECK(normalize_sorts(list(B),specification) == normalize_sorts(list(bag(A)),specification));
     599             : 
     600           2 :   specification = parse_data_specification(
     601             :                     "sort A = struct a(B);"
     602           1 :                     "sort B = struct b(A)|c;");
     603             : 
     604           1 :   std::vector< structured_sort_constructor_argument > arguments;
     605             : 
     606           1 :   arguments.push_back(structured_sort_constructor_argument(basic_sort("B")));
     607           1 :   arguments.push_back(structured_sort_constructor_argument(basic_sort("A")));
     608             : 
     609           1 :   std::vector< structured_sort_constructor > constructors;
     610             : 
     611           1 :   constructors.push_back(structured_sort_constructor("a", structured_sort_constructor_argument_list(arguments.begin(), arguments.begin() + 1)));
     612           1 :   constructors.push_back(structured_sort_constructor("b", structured_sort_constructor_argument_list(arguments.begin() + 1, arguments.end())));
     613           1 :   constructors.push_back(structured_sort_constructor("c"));
     614             : 
     615           1 :   structured_sort sA(data::structured_sort(structured_sort_constructor_list(constructors.begin(), constructors.begin() + 1)));
     616           1 :   structured_sort sB(data::structured_sort(structured_sort_constructor_list(constructors.begin() + 1, constructors.end())));
     617             : 
     618           1 :   const std::set<sort_expression> sorts(specification.sorts());
     619           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), normalize_sorts(sA,specification)) != sorts.end());
     620           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), normalize_sorts(sB,specification)) != sorts.end());
     621             : 
     622           1 :   BOOST_CHECK(normalize_sorts(sA,specification) == normalize_sorts(normalize_sorts(sA,specification),specification));
     623           1 :   BOOST_CHECK(normalize_sorts(sB,specification) == normalize_sorts(normalize_sorts(sB,specification),specification));
     624             : 
     625             :   // Check whether the sort expression struct f(struct f(A)|g) |g normalises to A
     626             :   // in the context of the specification sort A = struct f(A) | g;
     627           2 :   specification = parse_data_specification(
     628           1 :                     "sort A = struct f(A) | g;");
     629             : 
     630           1 :   std::vector< structured_sort_constructor_argument > arguments1;
     631           1 :   arguments1.push_back(structured_sort_constructor_argument(basic_sort("A")));
     632             : 
     633           1 :   std::vector< structured_sort_constructor > constructors1;
     634           1 :   constructors1.push_back(structured_sort_constructor("f", arguments1));
     635           1 :   constructors1.push_back(structured_sort_constructor("g"));
     636             : 
     637           1 :   sort_expression s1=structured_sort(constructors1); // s1 has the shape struct f(A)|g
     638           1 :   std::vector< structured_sort_constructor_argument > arguments2;
     639           1 :   arguments2.push_back(structured_sort_constructor_argument(s1));
     640             : 
     641           1 :   std::vector< structured_sort_constructor > constructors2;
     642           1 :   constructors2.push_back(structured_sort_constructor("f", arguments2));
     643           1 :   constructors2.push_back(structured_sort_constructor("g"));
     644             : 
     645           2 :   sort_expression s2=structured_sort(constructors2); // s2 has the shape f(struct f(A)|g) |g
     646           1 :   BOOST_CHECK(normalize_sorts(s2,specification)==basic_sort("A"));
     647           1 : }
     648             : 
     649           1 : void test_copy()
     650             : {
     651           1 :   std::clog << "test_copy" << std::endl;
     652             : 
     653             :   data_specification specification = parse_data_specification(
     654             :                                        "sort D = struct d(bla : Bool)?is_d;"
     655             :                                        "sort A = S;"
     656             :                                        "sort S;"
     657           2 :                                        "map f: Set(S);");
     658             : 
     659           1 :   function_symbol_vector constructors(specification.constructors());
     660           1 :   BOOST_CHECK(std::find(constructors.begin(), constructors.end(), sort_bool::true_()) != constructors.end());
     661             : 
     662           1 :   data_specification other;
     663           1 :   other = specification;
     664             : 
     665           1 :   BOOST_CHECK(other == specification);
     666             : 
     667           1 :   specification = data_specification();
     668             : 
     669             : 
     670           1 :   BOOST_CHECK(normalize_sorts(basic_sort("A"),other) == normalize_sorts(basic_sort("S"),other));
     671             : 
     672           1 :   const std::set<sort_expression> sorts(specification.sorts());
     673           1 :   BOOST_CHECK(std::find(sorts.begin(), sorts.end(), basic_sort("A")) == sorts.end());
     674           1 : }
     675             : 
     676           1 : void test_specification()
     677             : {
     678           2 :   data_specification spec = parse_data_specification("sort D = struct d1|d2;");
     679           1 :   BOOST_CHECK(spec.constructors(basic_sort("D")).size() == 2);
     680           1 : }
     681             : 
     682           1 : void test_bke()
     683             : {
     684           1 :   std::cout << "test_bke" << std::endl;
     685             : 
     686             :   std::string BKE =
     687             :     "% This model is translated from the mCRL model used for analysing the Bilateral                \n"
     688             :     "% Key Exchange (BKE) protocol. The analysis is described in a paper with the                   \n"
     689             :     "% name 'Analysing the BKE-security protocol with muCRL', by Jan Friso Groote,                  \n"
     690             :     "% Sjouke Mauw and Alexander Serebrenik.                                                        \n"
     691             :     "%                                                                                              \n"
     692             :     "% The translation of the existing mCRL model into this mCRL2 model has been                    \n"
     693             :     "% performed manually.  The purpose was making use of the additional language                   \n"
     694             :     "% features of mCRL2 with respect to mCRL.                                                      \n"
     695             :     "%                                                                                              \n"
     696             :     "% The behaviour of this model should be bisimular with the original mcrl model                 \n"
     697             :     "% after renaming actions. Though this is not verified for all system                           \n"
     698             :     "% configurations below.                                                                        \n"
     699             :     "%                                                                                              \n"
     700             :     "% Eindhoven, June 11, 2008, Jeroen van der Wulp                                                \n"
     701             :     "                                                                                               \n"
     702             :     "% Agents. There are exactly three agents - A, B, E An order E < A < B is                       \n"
     703             :     "% imposed on agents to reduce the size of the state space.                                     \n"
     704             :     "sort Agent = struct A | B | E;                                                                 \n"
     705             :     "map  less : Agent # Agent -> Bool;                                                             \n"
     706             :     "var  a: Agent;                                                                                 \n"
     707             :     "eqn  less(A,a) = (a == B);                                                                     \n"
     708             :     "     less(B,a) = false;                                                                        \n"
     709             :     "     less(E,a) = (a != E);                                                                     \n"
     710             :     "                                                                                               \n"
     711             :     "sort Address = struct address(agent : Agent);                                                  \n"
     712             :     "map  bad_address : Address;                                                                    \n"
     713             :     "                                                                                               \n"
     714             :     "% A nonce is a random, unpredictable value which is used to make the                           \n"
     715             :     "% exchanged messages unique and thus helps to counter replay attacks.                          \n"
     716             :     "sort Nonce = struct nonce(value : Nat);                                                        \n"
     717             :     "                                                                                               \n"
     718             :     "% There are two kinds of keys used in the protocol: symmetric and                              \n"
     719             :     "% asymmetric ones (functional keys).                                                           \n"
     720             :     "% Symmetric keys have form K(n) where n is a natural number.                                   \n"
     721             :     "sort SymmetricKey = struct symmetric_key(value : Nat);                                         \n"
     722             :     "                                                                                               \n"
     723             :     "% Sort for representing asymmetric keys                                                        \n"
     724             :     "sort AsymmetricKey = struct public_key(Agent)?is_public |                                      \n"
     725             :     "                            secret_key(Agent)?is_secret |                                      \n"
     726             :     "                            hash(value : Nonce)?is_hash;                                       \n"
     727             :     "map  has_complementary_key: AsymmetricKey -> Bool;                                             \n"
     728             :     "     complementary_key    : AsymmetricKey -> AsymmetricKey;                                    \n"
     729             :     "var  a : Agent;                                                                                \n"
     730             :     "     n : Nonce;                                                                                \n"
     731             :     "eqn  has_complementary_key(public_key(a)) = true;                                              \n"
     732             :     "     has_complementary_key(secret_key(a)) = true;                                              \n"
     733             :     "     has_complementary_key(hash(n)) = false;                                                   \n"
     734             :     "     complementary_key(public_key(a)) = secret_key(a);                                         \n"
     735             :     "     complementary_key(secret_key(a)) = public_key(a);                                         \n"
     736             :     "                                                                                               \n"
     737             :     "sort Key = struct key(SymmetricKey)?is_symmetric | key(AsymmetricKey)?is_asymmetric;           \n"
     738             :     "map  has_complementary_key: Key -> Bool;                                                       \n"
     739             :     "     complementary_key : Key -> Key; % gets the complementary key if key is asymmetric         \n"
     740             :     "var  a,a1   : Agent;                                                                           \n"
     741             :     "     n,n1   : Nat;                                                                             \n"
     742             :     "     k,k1   : Key;                                                                             \n"
     743             :     "     ak,ak1 : AsymmetricKey;                                                                   \n"
     744             :     "eqn                                                                                            \n"
     745             :     "     % gets the complementary key if key is asymmetric                                         \n"
     746             :     "     complementary_key(key(ak)) = key(complementary_key(ak));                                  \n"
     747             :     "     has_complementary_key(key(ak)) = has_complementary_key(ak);                               \n"
     748             :     "                                                                                               \n"
     749             :     "sort Message = struct                                                                          \n"
     750             :     "        encrypt(Nonce, Address, AsymmetricKey)?is_message_1 |                                  \n"
     751             :     "        encrypt(AsymmetricKey, Nonce, SymmetricKey, AsymmetricKey)?is_message_2 |              \n"
     752             :     "        encrypt(AsymmetricKey, SymmetricKey)?is_message_3;                                     \n"
     753             :     "map  valid_message_1 : Message # AsymmetricKey -> Bool;                                        \n"
     754             :     "     valid_message_2 : Message # AsymmetricKey -> Bool;                                        \n"
     755             :     "     valid_message_3 : Message # SymmetricKey  -> Bool;                                        \n"
     756             :     "     used_key : Message -> Key;                  % key used to encrypt                         \n"
     757             :     "var  sk, sk1 : SymmetricKey;                                                                   \n"
     758             :     "     ak, ak1, ak2 : AsymmetricKey;                                                             \n"
     759             :     "     n, n1  : Nonce;                                                                           \n"
     760             :     "     m, m1   : Message;                                                                        \n"
     761             :     "     a, a1   : Address;                                                                        \n"
     762             :     "eqn  used_key(encrypt(n,a,ak)) = key(ak);                                                      \n"
     763             :     "     used_key(encrypt(ak,n1,sk,ak1)) = key(ak1);                                               \n"
     764             :     "     used_key(encrypt(ak,sk)) = key(sk);                                                       \n"
     765             :     "     valid_message_1(m, ak) = is_message_1(m) && (used_key(m) == key(ak));                     \n"
     766             :     "     valid_message_2(m, ak) = is_message_2(m) && (used_key(m) == key(ak));                     \n"
     767             :     "     valid_message_3(m, sk) = is_message_3(m) && (used_key(m) == key(sk));                     \n"
     768             :     "                                                                                               \n"
     769             :     "% Type for message sets; currently cannot use Set() because set iteration is not possible      \n"
     770             :     "sort MessageSet = List(Message);                                                               \n"
     771             :     "map  insert                : Message # MessageSet -> MessageSet;                               \n"
     772             :     "     select_crypted_by     : Key # MessageSet -> MessageSet;                                   \n"
     773             :     "     select_not_crypted_by : Key # MessageSet -> MessageSet;                                   \n"
     774             :     "     select                : (Message -> Bool) # MessageSet -> MessageSet;                     \n"
     775             :     "var  k,k1 : Key;                                                                               \n"
     776             :     "     m,m1 : Message;                                                                           \n"
     777             :     "     ms   : MessageSet;                                                                        \n"
     778             :     "     c    : Message -> Bool;                                                                   \n"
     779             :     "eqn                                                                                            \n"
     780             :     "     % inserts a message m, if it is not in the list                                           \n"
     781             :     "     insert(m,[]) = [m];                                                                       \n"
     782             :     "     m < m1  -> insert(m,m1|>ms) = m|>m1|>ms;                                                  \n"
     783             :     "     m == m1 -> insert(m,m1|>ms) = m1|>ms;                                                     \n"
     784             :     "     m1 < m  -> insert(m,m1|>ms) = m1|>insert(m,ms);                                           \n"
     785             :     "                                                                                               \n"
     786             :     "     % the set (as ordered list) of messages in m that are signed by sk                        \n"
     787             :     "     select_crypted_by(k,ms) = select(lambda x : Message.k == used_key(x),ms);                 \n"
     788             :     "     select_not_crypted_by(k,ms) = select(lambda x : Message.k != used_key(x),ms);             \n"
     789             :     "                                                                                               \n"
     790             :     "     select(c,[]) = [];                                                                        \n"
     791             :     "     select(c,m|>ms) = if(c(m),m|>r,r) whr r = select(c, ms) end;                              \n"
     792             :     "                                                                                               \n"
     793             :     "% The eavesdropper's knowledge consists of:                                                    \n"
     794             :     "%  * a list of addresses                                                                       \n"
     795             :     "%  * a list of nonces                                                                          \n"
     796             :     "%  * a list of keys (both symmetric and asymmetric)                                            \n"
     797             :     "%  * a list of messages of which the key is not known                                          \n"
     798             :     "sort Knowledge = struct                                                                        \n"
     799             :     "        knowledge(addresses : Set(Address),                                                    \n"
     800             :     "                  nonces : Set(Nonce),                                                         \n"
     801             :     "                  keys : Set(Key),                                                             \n"
     802             :     "                  messages : MessageSet);                                                      \n"
     803             :     "map  update_knowledge : Message # Knowledge -> Knowledge;                                      \n"
     804             :     "     propagate : MessageSet # Knowledge -> Knowledge;                                          \n"
     805             :     "     propagate : Key # Knowledge -> Knowledge;                                                 \n"
     806             :     "     add_key : Key # Knowledge -> Knowledge;                                                   \n"
     807             :     "     add_nonce : Nonce # Knowledge -> Knowledge;                                               \n"
     808             :     "     add_address : Address # Knowledge -> Knowledge;                                           \n"
     809             :     "var  m  : Message;                                                                             \n"
     810             :     "     as : Set(Address);                                                                        \n"
     811             :     "     ns : Set(Nonce);                                                                          \n"
     812             :     "     ks : Set(Key);                                                                            \n"
     813             :     "     ms : MessageSet;                                                                          \n"
     814             :     "     k  : Knowledge;                                                                           \n"
     815             :     "     sk : SymmetricKey;                                                                        \n"
     816             :     "     ak,hk : AsymmetricKey;                                                                    \n"
     817             :     "     ck : Key;                                                                                 \n"
     818             :     "     n, n1 : Nonce;                                                                            \n"
     819             :     "     a  : Address;                                                                             \n"
     820             :     "eqn                                                                                            \n"
     821             :     "     % adds keys to knowledge that are part of known messages encrypted with a new key         \n"
     822             :     "     has_complementary_key(ak) && complementary_key(key(ak)) in keys(k) ->                     \n"
     823             :     "         update_knowledge(encrypt(n,a,ak),k) =                                                 \n"
     824             :     "                propagate(key(ak), add_key(key(ak),                                            \n"
     825             :     "                        add_address(a, add_nonce(n, k))));                                     \n"
     826             :     "     has_complementary_key(ak) && complementary_key(key(ak)) in keys(k) ->                     \n"
     827             :     "         update_knowledge(encrypt(hk,n1,sk,ak),k) =                                            \n"
     828             :     "                propagate(key(sk), propagate(key(ak),                                          \n"
     829             :     "                      add_key(key(sk),add_key(key(ak),k))));                                   \n"
     830             :     "     key(sk) in keys(k) ->                                                                     \n"
     831             :     "         update_knowledge(encrypt(ak,sk),k) =                                                  \n"
     832             :     "                propagate(key(ak), add_key(key(ak),k));                                        \n"
     833             :     "                                                                                               \n"
     834             :     "     % adds a message that cannot be decrypted with any known key                              \n"
     835             :     "     ((is_symmetric(ck) && !(ck in keys(k))) ||                                                \n"
     836             :     "       (is_asymmetric(ck) && !(has_complementary_key(ck) &&                                    \n"
     837             :     "                (complementary_key(ck) in keys(k))))) whr ck = used_key(m) end ->              \n"
     838             :     "         update_knowledge(m,k) =                                                               \n"
     839             :     "                knowledge(addresses(k),nonces(k),keys(k),insert(m,messages(k)));               \n"
     840             :     "                                                                                               \n"
     841             :     "     % adds a key to knowledge                                                                 \n"
     842             :     "     add_key(ck,knowledge(as,ns,ks,ms)) = knowledge(as,ns,ks + {ck},ms);                       \n"
     843             :     "     add_nonce(n,knowledge(as,ns,ks,ms)) = knowledge(as,ns + {n},ks,ms);                       \n"
     844             :     "     add_address(a,knowledge(as,ns,ks,ms)) = knowledge(as + {a},ns,ks,ms);                     \n"
     845             :     "                                                                                               \n"
     846             :     "     % adds keys to knowledge that are part of messages encrypted with a key k                 \n"
     847             :     "     propagate([],k) = k;                                                                      \n"
     848             :     "     propagate(m|>ms,k) = propagate(ms, update_knowledge(m, k));                               \n"
     849             :     "     propagate(ck,knowledge(as,ns,ks,ms)) =                                                    \n"
     850             :     "        propagate(select_crypted_by(ck,ms),                                                    \n"
     851           1 :     "                knowledge(as,ns,ks,select_not_crypted_by(ck,ms)));                             \n"
     852             :     ;
     853             : 
     854           1 :   data_specification data_spec = parse_data_specification(BKE);
     855           1 :   const alias_vector& aliases = data_spec.user_defined_aliases();
     856          10 :   for (const alias& a: aliases)
     857             :   {
     858           9 :     std::cout << "alias " << a << std::endl;
     859           9 :     const sort_expression& s = a.reference();
     860           9 :     if (is_structured_sort(s))
     861             :     {
     862          23 :       for (const structured_sort_constructor& constructor: structured_sort(s).constructors())
     863             :       {
     864          36 :         for (const structured_sort_constructor_argument& argument: constructor.arguments())
     865             :         {
     866          21 :           std::cout << "argument: " << argument << " " << argument << std::endl;
     867          21 :           const atermpp::aterm_appl& name = argument.name();
     868          21 :           if (name != core::empty_identifier_string())
     869             :           {
     870           8 :             std::cout << "name = " << name << std::endl;
     871             :           }
     872             :         }
     873             :       }
     874             :     }
     875             :   }
     876           1 : }
     877             : 
     878           1 : void test_abuse_of_tail()
     879             : {
     880           1 :   std::cout << "Test abuse of tail\n";
     881             :   const std::string spec_string =
     882             :     "map tail:Nat#List(Bool) -> List(Bool);\n"
     883             :     "var vs: List(Bool);\n"
     884             :     "n: Nat;\n"
     885           1 :     "eqn tail(n, vs) = if(n==0, vs, tail(Int2Nat(n-1),vs));\n";
     886             :   try
     887             :   {
     888           1 :     data_specification data_spec=parse_data_specification(spec_string);
     889           0 :     BOOST_CHECK(false); // Typechecking is supposed to fail; one cannot get here.
     890           0 :   }
     891           1 :   catch (mcrl2::runtime_error &e)
     892             :   {
     893             :     // It is expected that a runtime error is thrown.
     894           1 :   }
     895           1 : }
     896             : 
     897           1 : void test_merge_data_specifications()
     898             : {
     899             :   std::string DATASPEC =
     900             :     "sort D;\n"
     901           1 :     "cons s: D;"
     902             :   ;
     903           1 :   data_specification dataspec1 = parse_data_specification(DATASPEC);
     904           1 :   data_specification dataspec2 = parse_data_specification(DATASPEC);
     905           1 :   data_specification dataspec3 = merge_data_specifications(dataspec1, dataspec2);
     906           1 :   BOOST_CHECK(dataspec1 == dataspec3);
     907           1 : }
     908             : 
     909           1 : void test_standard_sorts_mappings_functions()
     910             : {
     911           1 :    std::set < sort_expression > sorts;
     912           1 :    std::set < function_symbol > constructors;
     913           1 :    std::set <function_symbol > mappings;
     914             : 
     915           1 :    data_specification spec;
     916           1 :    spec.get_system_defined_sorts_constructors_and_mappings(sorts, constructors, mappings);
     917             : 
     918           1 :    BOOST_CHECK(sorts.size()==10);
     919           1 :    BOOST_CHECK(constructors.size()==17);
     920           1 :    BOOST_CHECK(mappings.size()==225);
     921           1 : }
     922             : 
     923           2 : BOOST_AUTO_TEST_CASE(test_main)
     924             : {
     925           1 :   test_bke();
     926             : 
     927           1 :   test_sorts();
     928             : 
     929           1 :   test_constructors();
     930             : 
     931           1 :   test_functions();
     932             : 
     933           1 :   test_equations();
     934             : 
     935           1 :   test_is_certainly_finite();
     936             : 
     937           1 :   test_constructor();
     938             : 
     939           1 :   test_system_defined();
     940             : 
     941           1 :   test_utility_functionality();
     942             : 
     943           1 :   test_normalisation();
     944             : 
     945           1 :   test_copy();
     946             : 
     947           1 :   test_specification();
     948             : 
     949           1 :   test_abuse_of_tail();
     950             : 
     951           1 :   test_merge_data_specifications();
     952             : 
     953           1 :   test_standard_sorts_mappings_functions();
     954           1 : }
     955             : 
     956             : 

Generated by: LCOV version 1.14