LCOV - code coverage report
Current view: top level - data/source - data_specification.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 434 459 94.6 %
Date: 2024-04-19 03:43:27 Functions: 18 20 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jeroen Keiren, Jeroen van der Wulp, Jan Friso Groote
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : 
      10             : #include "mcrl2/core/load_aterm.h"
      11             : #include "mcrl2/data/data_specification.h"
      12             : #include "mcrl2/data/detail/data_utility.h"
      13             : #include "mcrl2/data/detail/io.h"
      14             : #include "mcrl2/data/replace.h"
      15             : #include "mcrl2/data/substitutions/sort_expression_assignment.h"
      16             : 
      17             : // Predefined datatypes
      18             : #include "mcrl2/data/function_update.h"
      19             : #include "mcrl2/data/list.h"
      20             : 
      21             : namespace mcrl2
      22             : {
      23             : namespace data
      24             : {
      25             : 
      26             : class finiteness_helper
      27             : {
      28             :   protected:
      29             : 
      30             :     const data_specification& m_specification;
      31             :     std::set< sort_expression > m_visiting;
      32             : 
      33        1991 :     bool is_finite_aux(const sort_expression& s)
      34             :     {
      35        1991 :       const function_symbol_vector& constructors=m_specification.constructors(s);
      36        1991 :       if (constructors.empty())
      37             :       {
      38           7 :         return false;
      39             :       }
      40             : 
      41        5196 :       for(const function_symbol& f: constructors)
      42             :       {
      43        3969 :         if (is_function_sort(f.sort()))
      44             :         {
      45         763 :           const function_sort& f_sort=atermpp::down_cast<function_sort>(f.sort());
      46         763 :           const sort_expression_list& l=f_sort.domain();
      47             : 
      48        1158 :           for(const sort_expression& e: l)
      49             :           {
      50        1152 :             if (!is_finite(e))
      51             :             {
      52         757 :               return false;
      53             :             }
      54             :           }
      55             :         }
      56             :       }
      57        1227 :       return true;
      58             :     }
      59             : 
      60             :   public:
      61             : 
      62        1169 :     finiteness_helper(const data_specification& specification) : m_specification(specification)
      63        1169 :     { }
      64             : 
      65        2518 :     bool is_finite(const sort_expression& s)
      66             :     {
      67        2518 :       assert(s==normalize_sorts(s,m_specification));
      68        2518 :       if (m_visiting.count(s)>0)
      69             :       {
      70         396 :         return false;
      71             :       }
      72             : 
      73        2122 :       m_visiting.insert(s);
      74             : 
      75        2122 :       bool result=false;
      76        2122 :       if (is_basic_sort(s))
      77             :       {
      78        1991 :         result=is_finite(basic_sort(s));
      79             :       }
      80         131 :       else if (is_container_sort(s))
      81             :       {
      82          51 :         result=is_finite(container_sort(s));
      83             :       }
      84          80 :       else if (is_function_sort(s))
      85             :       {
      86          80 :         result=is_finite(function_sort(s));
      87             :       }
      88           0 :       else if (is_structured_sort(s))
      89             :       {
      90           0 :         result=is_finite(structured_sort(s));
      91             :       }
      92             : 
      93        2122 :       m_visiting.erase(s);
      94        2122 :       return result;
      95             :     }
      96             : 
      97        1991 :     bool is_finite(const basic_sort& s)
      98             :     {
      99        1991 :       return is_finite_aux(s);
     100             :     }
     101             : 
     102          80 :     bool is_finite(const function_sort& s)
     103             :     {
     104         182 :       for(const sort_expression& sort: s.domain())
     105             :       {
     106         105 :         if (!is_finite(sort))
     107             :         {
     108           3 :           return false;
     109             :         }
     110             :       }
     111             : 
     112          77 :       return is_finite(s.codomain());
     113             :     }
     114             : 
     115          51 :     bool is_finite(const container_sort& s)
     116             :     {
     117          51 :       return (s.container_name() == set_container()) ? is_finite(s.element_sort()) : false;
     118             :     }
     119             : 
     120             :     bool is_finite(const alias&)
     121             :     {
     122             :       assert(0);
     123             :       return false;
     124             :     }
     125             : 
     126           0 :     bool is_finite(const structured_sort& s)
     127             :     {
     128           0 :       return is_finite_aux(s);
     129             :     }
     130             : };
     131             : 
     132             : /// \brief Checks whether a sort is certainly finite.
     133             : ///
     134             : /// \param[in] s A sort expression
     135             : /// \return true if s can be determined to be finite,
     136             : ///      false otherwise.
     137        1169 : bool data_specification::is_certainly_finite(const sort_expression& s) const
     138             : {
     139        1169 :   const bool result=finiteness_helper(*this).is_finite(s);
     140        1169 :   return result;
     141             : }
     142             : 
     143             : 
     144             : // The function below checks whether there is an alias loop, e.g. aliases
     145             : // of the form A=B; B=A; or more complex A=B->C; B=Set(D); D=List(A); Loops
     146             : // through structured sorts are allowed. If a loop is detected, an exception
     147             : // is thrown.
     148       10081 : void sort_specification::check_for_alias_loop(
     149             :   const sort_expression& s,
     150             :   std::set<sort_expression> sorts_already_seen,
     151             :   const bool toplevel) const
     152             : {
     153       10081 :   if (is_basic_sort(s))
     154             :   {
     155        5516 :     if (sorts_already_seen.count(s)>0)
     156             :     {
     157           6 :       throw mcrl2::runtime_error("Sort alias " + pp(s) + " is defined in terms of itself.");
     158             :     }
     159       11572 :     for(const alias& a: m_user_defined_aliases)
     160             :     {
     161       10934 :       if (a.name() == s)
     162             :       {
     163        4872 :         sorts_already_seen.insert(s);
     164        4881 :         check_for_alias_loop(a.reference(), sorts_already_seen, true);
     165        4863 :         sorts_already_seen.erase(s);
     166        4863 :         return;
     167             :       }
     168             :     }
     169         638 :     return;
     170             :   }
     171             : 
     172        4565 :   if (is_container_sort(s))
     173             :   {
     174         405 :     check_for_alias_loop(container_sort(s).element_sort(),sorts_already_seen,false);
     175         399 :     return;
     176             :   }
     177             : 
     178        4164 :   if (is_function_sort(s))
     179             :   {
     180         152 :     sort_expression_list s_domain(function_sort(s).domain());
     181         303 :     for(const sort_expression& sort: s_domain)
     182             :     {
     183         153 :       check_for_alias_loop(sort,sorts_already_seen,false);
     184             :     }
     185             : 
     186         153 :     check_for_alias_loop(function_sort(s).codomain(),sorts_already_seen,false);
     187         150 :     return;
     188         152 :   }
     189             : 
     190             :   // A sort declaration with a struct on toplevel can be recursive. Otherwise a
     191             :   // check needs to be made.
     192        4012 :   if (is_structured_sort(s) && !toplevel)
     193             :   {
     194           5 :     const structured_sort ss(s);
     195           5 :     structured_sort_constructor_list constructors=ss.constructors();
     196          11 :     for(const structured_sort_constructor& constructor: constructors)
     197             :     {
     198           8 :       structured_sort_constructor_argument_list ssca=constructor.arguments();
     199          11 :       for(const structured_sort_constructor_argument& a: ssca)
     200             :       {
     201           7 :         check_for_alias_loop(a.sort(),sorts_already_seen,false);
     202             :       }
     203           8 :     }
     204           7 :   }
     205             : 
     206             : }
     207             : 
     208             : 
     209             : // This function returns the normal form of e, under the the map map1.
     210             : // This normal form is obtained by repeatedly applying map1, until this
     211             : // is not possible anymore. It is assumed that this procedure terminates. There is
     212             : // no check for loops.
     213       17202 : static sort_expression find_normal_form(
     214             :   const sort_expression& e,
     215             :   const std::multimap< sort_expression, sort_expression >& map1,
     216             :   std::set < sort_expression > sorts_already_seen = std::set < sort_expression >())
     217             : {
     218       17202 :   assert(sorts_already_seen.find(e)==sorts_already_seen.end()); // e has not been seen already.
     219       17202 :   assert(!is_untyped_sort(e));
     220       17202 :   assert(!is_untyped_possible_sorts(e));
     221             : 
     222       17202 :   if (is_function_sort(e))
     223             :   {
     224         239 :     const function_sort fs(e);
     225             :     const sort_expression normalised_codomain=
     226         239 :       find_normal_form(fs.codomain(),map1,sorts_already_seen);
     227         239 :     const sort_expression_list& domain=fs.domain();
     228         239 :     sort_expression_list normalised_domain;
     229         478 :     for(const sort_expression& s: domain)
     230             :     {
     231         239 :       normalised_domain.push_front(find_normal_form(s,map1,sorts_already_seen));
     232             :     }
     233         239 :     return function_sort(reverse(normalised_domain),normalised_codomain);
     234         239 :   }
     235             : 
     236       16963 :   if (is_container_sort(e))
     237             :   {
     238         558 :     const container_sort cs(e);
     239         558 :     return container_sort(cs.container_name(),find_normal_form(cs.element_sort(),map1,sorts_already_seen));
     240         558 :   }
     241             : 
     242       16405 :   sort_expression result_sort;
     243             : 
     244       16405 :   if (is_structured_sort(e))
     245             :   {
     246        3785 :     const structured_sort ss(e);
     247        3785 :     structured_sort_constructor_list constructors=ss.constructors();
     248        3785 :     structured_sort_constructor_list normalised_constructors;
     249       11175 :     for(const structured_sort_constructor& constructor: constructors)
     250             :     {
     251        7390 :       structured_sort_constructor_argument_list normalised_ssa;
     252       10792 :       for(const structured_sort_constructor_argument& a: constructor.arguments())
     253             :       {
     254        3402 :         normalised_ssa.push_front(structured_sort_constructor_argument(a.name(),
     255        6804 :                                       find_normal_form(a.sort(),map1,sorts_already_seen)));
     256             :       }
     257             : 
     258        7390 :       normalised_constructors.push_front(
     259       14780 :                                 structured_sort_constructor(
     260        7390 :                                   constructor.name(),
     261       14780 :                                   reverse(normalised_ssa),
     262        7390 :                                   constructor.recogniser()));
     263             : 
     264        7390 :     }
     265        3785 :     result_sort=structured_sort(reverse(normalised_constructors));
     266        3785 :   }
     267             : 
     268       16405 :   if (is_basic_sort(e))
     269             :   {
     270       12620 :     result_sort=e;
     271             :   }
     272             : 
     273             : 
     274       16405 :   assert(is_basic_sort(result_sort) || is_structured_sort(result_sort));
     275       16405 :   const std::multimap< sort_expression, sort_expression >::const_iterator i1=map1.find(result_sort);
     276       16405 :   if (i1!=map1.end()) // found
     277             :   {
     278             : #ifndef NDEBUG
     279         772 :     sorts_already_seen.insert(result_sort);
     280             : #endif
     281         772 :     return find_normal_form(i1->second,map1,sorts_already_seen);
     282             :   }
     283       15633 :   return result_sort;
     284       16405 : }
     285             : 
     286       30852 : void sort_specification::add_predefined_basic_sorts()
     287             : {
     288       30852 :     add_system_defined_sort(sort_bool::bool_());
     289       30852 :     add_system_defined_sort(sort_pos::pos());
     290       30852 : }
     291             : 
     292      142070 : void sort_specification::import_system_defined_sort(const sort_expression& sort)
     293             : {
     294      142070 :   if (is_untyped_sort(sort) || is_untyped_possible_sorts(sort))
     295             :   {
     296         102 :     mCRL2log(mcrl2::log::debug) << "Erroneous attempt to insert an untyped sort into the a sort specification\n";
     297         102 :     return;
     298             :   }
     299             :   // Add an element, and stop if it was already added.
     300      141968 :   if (!m_sorts_in_context.insert(sort).second)
     301             :   {
     302       60405 :     return;
     303             :   }
     304             : 
     305       81563 :   sorts_are_not_necessarily_normalised_anymore();
     306             :   // add the sorts on which this sorts depends.
     307       81563 :   if (sort == sort_real::real_())
     308             :   {
     309             :     // Int is required as the rewrite rules of Real rely on it.
     310         973 :     import_system_defined_sort(sort_int::int_());
     311             :   }
     312       80590 :   else if (sort == sort_int::int_())
     313             :   {
     314             :     // See above, Int requires Nat.
     315        1029 :     import_system_defined_sort(sort_nat::nat());
     316             :   }
     317       79561 :   else if (sort == sort_nat::nat())
     318             :   {
     319             :     // Nat requires NatPair.
     320        1996 :     import_system_defined_sort(sort_nat::natpair());
     321             :   }
     322       77565 :   else if (is_function_sort(sort))
     323             :   {
     324        9286 :     const function_sort& fsort=atermpp::down_cast<function_sort>(sort);
     325        9286 :     import_system_defined_sorts(fsort.domain());
     326        9286 :     import_system_defined_sort(fsort.codomain());
     327             :   }
     328       68279 :   else if (is_container_sort(sort))
     329             :   {
     330         717 :     const sort_expression element_sort(container_sort(sort).element_sort());
     331             :     // Import the element sort (which may be a complex sort also).
     332         717 :     import_system_defined_sort(element_sort);
     333         717 :     if (sort_list::is_list(sort))
     334             :     {
     335         348 :       import_system_defined_sort(sort_nat::nat()); // Required for lists.
     336             :     }
     337         369 :     else if (sort_set::is_set(sort))
     338             :     {
     339         141 :       import_system_defined_sort(sort_fset::fset(element_sort));
     340             :       // Import the functions from element_sort->Bool.
     341         141 :       sort_expression_list element_sorts;
     342         141 :       element_sorts.push_front(element_sort);
     343         141 :       import_system_defined_sort(function_sort(element_sorts,sort_bool::bool_()));
     344         141 :     }
     345         228 :     else if (sort_fset::is_fset(sort))
     346             :     {
     347             :     }
     348          63 :     else if (sort_bag::is_bag(sort))
     349             :     {
     350             :       // Add the sorts Nat and set_(element_sort) to the specification.
     351          22 :       import_system_defined_sort(sort_nat::nat()); // Required for bags.
     352          22 :       import_system_defined_sort(sort_set::set_(element_sort));
     353          22 :       import_system_defined_sort(sort_fbag::fbag(element_sort));
     354             :       
     355             :       // Add the function sort element_sort->Nat to the specification
     356          22 :       sort_expression_list element_sorts ;
     357          22 :       element_sorts.push_front(element_sort);
     358          22 :       import_system_defined_sort(function_sort(element_sorts,sort_nat::nat()));
     359          22 :     }
     360          41 :     else if (sort_fbag::is_fbag(sort))
     361             :     {
     362          41 :       import_system_defined_sort(sort_nat::nat()); // Required for bags.
     363             :     }
     364         717 :   }
     365       67562 :   else if (is_structured_sort(sort))
     366             :   {
     367        1629 :     structured_sort s_sort(sort);
     368        1629 :     function_symbol_vector f(s_sort.constructor_functions(sort));
     369        4899 :     for(const function_symbol& f: s_sort.constructor_functions(sort))
     370             :     {
     371        3270 :       import_system_defined_sort(f.sort());
     372        1629 :     }
     373        1629 :   }
     374             : }
     375             : 
     376             : // The function below recalculates m_normalised_aliases, such that
     377             : // it forms a confluent terminating rewriting system using which
     378             : // sorts can be normalised.
     379             : // This algorithm is described in the document: algorithm-for-sort-equivalence.tex in
     380             : // the developers library of the mCRL2 toolset.
     381       11400 : void sort_specification::reconstruct_m_normalised_aliases() const
     382             : {
     383             :   // First reset the normalised aliases and the mappings and constructors that have been
     384             :   // inherited to basic sort aliases during a previous round of sort normalisation.
     385       11400 :   m_normalised_aliases.clear();
     386             : 
     387             :   // This is the first step of the algorithm.
     388             :   // Check for loops in the aliases. The type checker should already have done this,
     389             :   // but we check it again here. If there is a loop m_normalised_aliases will not be
     390             :   // built.
     391       15894 :     for(const alias& a: m_user_defined_aliases)
     392             :     {
     393        4500 :       std::set < sort_expression > sorts_already_seen; // Empty set.
     394             :     try
     395             :     {
     396        4506 :       check_for_alias_loop(a.name(),sorts_already_seen,true);
     397             :     }
     398           6 :     catch (mcrl2::runtime_error &)
     399             :     {
     400           6 :       mCRL2log(log::debug) << "Encountered an alias loop in the alias for " << a.name() <<". The normalised aliases are not constructed\n";
     401           6 :       return;
     402           6 :     }
     403        4500 :   }
     404             : 
     405             :   // This is the second step of the algorithm.
     406             :   // Copy m_normalised_aliases. All aliases are stored from left to right,
     407             :   // except structured sorts, which are stored from right to left. The reason is
     408             :   // that structured sorts can be recursive, and therefore, they cannot be
     409             :   // rewritten from left to right, as this can cause sorts to be infinitely rewritten.
     410             : 
     411       11394 :   std::multimap< sort_expression, sort_expression > sort_aliases_to_be_investigated;
     412       11394 :   std::multimap< sort_expression, sort_expression > resulting_normalized_sort_aliases;
     413             : 
     414       15888 :   for(const alias& a: m_user_defined_aliases)
     415             :   {
     416        4494 :     if (is_structured_sort(a.reference()))
     417             :     {
     418        3707 :       sort_aliases_to_be_investigated.insert(std::pair<sort_expression,sort_expression>(a.reference(),a.name()));
     419             :     }
     420             :     else
     421             :     {
     422         787 :       resulting_normalized_sort_aliases.insert(std::pair<sort_expression,sort_expression>(a.name(),a.reference()));
     423             :     }
     424             :   }
     425             : 
     426             :   // Apply Knuth-Bendix completion to the rules in m_normalised_aliases.
     427       15115 :   for(; !sort_aliases_to_be_investigated.empty() ;)
     428             :   {
     429        3721 :     const std::multimap< sort_expression, sort_expression >::iterator it=sort_aliases_to_be_investigated.begin();
     430        3721 :     const sort_expression lhs=it->first;
     431        3721 :     const sort_expression rhs=it->second;
     432        3721 :     sort_aliases_to_be_investigated.erase(it);
     433             : 
     434        7239 :     for(const std::pair<const sort_expression, sort_expression >& p: resulting_normalized_sort_aliases)
     435             :     {
     436        3518 :       const sort_expression s1=data::replace_sort_expressions(lhs,sort_expression_assignment(p.first,p.second), true);
     437             : 
     438        3518 :       if (s1!=lhs)
     439             :       {
     440             :         // There is a conflict between the two sort rewrite rules.
     441          69 :         assert(is_basic_sort(rhs));
     442             :         // Choose the normal form on the basis of a lexicographical ordering. This guarantees
     443             :         // uniqueness of normal forms over different tools. Ordering on addresses (as used previously)
     444             :         // proved to be unstable over different tools.
     445          69 :         const bool rhs_to_s1 = is_basic_sort(s1) && pp(basic_sort(s1))<=pp(rhs);
     446          69 :         const sort_expression left_hand_side=(rhs_to_s1?rhs:s1);
     447          69 :         const sort_expression pre_normal_form=(rhs_to_s1?s1:rhs);
     448          69 :         assert(is_basic_sort(pre_normal_form));
     449          69 :         const sort_expression& e1=pre_normal_form;
     450          69 :         if (e1!=left_hand_side)
     451             :         {
     452          56 :           const sort_expression normalised_lhs=find_normal_form(left_hand_side,resulting_normalized_sort_aliases);
     453             :           // Check whether the inserted sort rewrite rule is already in sort_aliases_to_be_investigated.
     454          56 :           if (std::find_if(sort_aliases_to_be_investigated.lower_bound(normalised_lhs),
     455             :                         sort_aliases_to_be_investigated.upper_bound(normalised_lhs),
     456          42 :                         [&rhs](const std::pair<sort_expression,sort_expression>& x){ return x.second==rhs; })
     457         112 :                    == sort_aliases_to_be_investigated.upper_bound(normalised_lhs)) // Not found.
     458             :           {
     459          14 :             sort_aliases_to_be_investigated.insert(
     460          28 :                   std::pair<sort_expression,sort_expression > (normalised_lhs, e1));
     461             :           }
     462          56 :         }
     463          69 :       }
     464             :       else
     465             :       {
     466        3449 :         const sort_expression s2 = data::replace_sort_expressions(p.first,sort_expression_assignment(lhs,rhs), true);
     467        3449 :         if (s2!=p.first)
     468             :         {
     469           0 :           assert(is_basic_sort(p.second));
     470             :           // Choose the normal form on the basis of a lexicographical ordering. This guarantees
     471             :           // uniqueness of normal forms over different tools.
     472           0 :           const bool i_second_to_s2 = is_basic_sort(s2) && pp(basic_sort(s2))<=pp(p.second);
     473           0 :           const sort_expression left_hand_side=(i_second_to_s2?p.second:s2);
     474           0 :           const sort_expression pre_normal_form=(i_second_to_s2?s2:p.second);
     475           0 :           assert(is_basic_sort(pre_normal_form));
     476           0 :           const sort_expression& e2=pre_normal_form;
     477           0 :           if (e2!=left_hand_side)
     478             :           {
     479           0 :             const sort_expression normalised_lhs=find_normal_form(left_hand_side,resulting_normalized_sort_aliases);
     480             :             // Check whether the inserted sort rewrite rule is already in sort_aliases_to_be_investigated.
     481           0 :             if (std::find_if(sort_aliases_to_be_investigated.lower_bound(normalised_lhs),
     482             :                           sort_aliases_to_be_investigated.upper_bound(normalised_lhs),
     483           0 :                           [&rhs](const std::pair<sort_expression,sort_expression>& x){ return x.second==rhs; })
     484           0 :                      == sort_aliases_to_be_investigated.upper_bound(normalised_lhs)) // Not found.
     485             :             {
     486           0 :               sort_aliases_to_be_investigated.insert(
     487           0 :                     std::pair<sort_expression,sort_expression > (normalised_lhs,e2));
     488             :             }
     489           0 :           }
     490           0 :         }
     491        3449 :       }
     492        3518 :     }
     493        3721 :     assert(lhs!=rhs);
     494        3721 :     const sort_expression normalised_lhs = find_normal_form(lhs,resulting_normalized_sort_aliases);
     495        3721 :     const sort_expression normalised_rhs = find_normal_form(rhs,resulting_normalized_sort_aliases);
     496        3721 :     if (normalised_lhs!=normalised_rhs)
     497             :     {
     498        3707 :       resulting_normalized_sort_aliases.insert(std::pair<sort_expression,sort_expression >(normalised_lhs,normalised_rhs));
     499             :     }
     500        3721 :   }
     501             :   // Copy resulting_normalized_sort_aliases into m_normalised_aliases, i.e. from multimap to map.
     502             :   // If there are rules with equal left hand side, only one is arbitrarily chosen. Rewrite the
     503             :   // right hand side to normal form.
     504             : 
     505       15888 :   for(const std::pair<const sort_expression,sort_expression>& p: resulting_normalized_sort_aliases)
     506             :   {
     507        4494 :     const sort_expression normalised_rhs = find_normal_form(p.second,resulting_normalized_sort_aliases);
     508        4494 :     m_normalised_aliases[p.first]=normalised_rhs;
     509             : 
     510        4494 :     assert(p.first!=normalised_rhs);
     511        4494 :   }
     512       11394 : }
     513             : 
     514             : ///\brief Adds the system defined sorts to the sets with constructors, mappings, and equations for
     515             : //        a given sort. If the boolean skip_equations is true, no equations are added.
     516       72141 : void data_specification::find_associated_system_defined_data_types_for_a_sort(
     517             :                    const sort_expression& sort,
     518             :                    std::set < function_symbol >& constructors,
     519             :                    std::set < function_symbol >& mappings,
     520             :                    std::set < data_equation >& equations,
     521             :                    implementation_map& cpp_implemented_functions,
     522             :                    const bool skip_equations) const
     523             : {
     524             :   // add sorts, constructors, mappings and equations
     525       72141 :   if (sort == sort_bool::bool_())
     526             :   {
     527       10405 :     function_symbol_vector f(sort_bool::bool_generate_constructors_code());
     528       10405 :     constructors.insert(f.begin(), f.end());
     529       10405 :     f = sort_bool::bool_generate_functions_code();
     530       10405 :     mappings.insert(f.begin(), f.end());
     531       10405 :     implementation_map f1 = sort_bool::bool_cpp_implementable_mappings();
     532       10405 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     533       10405 :     f1 = sort_bool::bool_cpp_implementable_constructors();
     534       10405 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     535       10405 :     if (!skip_equations)
     536             :     {
     537       10404 :       data_equation_vector e(sort_bool::bool_generate_equations_code());
     538       10404 :       equations.insert(e.begin(),e.end());
     539       10404 :     }
     540       10405 :   }
     541       61736 :   else if (sort == sort_real::real_())
     542             :   {
     543        5431 :     function_symbol_vector f(sort_real::real_generate_constructors_code());
     544        5431 :     constructors.insert(f.begin(),f.end());
     545        5431 :     f = sort_real::real_generate_functions_code();
     546        5431 :     mappings.insert(f.begin(),f.end());
     547        5431 :     implementation_map f1 = sort_int::int_cpp_implementable_mappings();
     548        5431 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     549        5431 :     f1 = sort_int::int_cpp_implementable_constructors();
     550        5431 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     551        5431 :     if (!skip_equations)
     552             :     {
     553        5430 :       data_equation_vector e(sort_real::real_generate_equations_code());
     554        5430 :       equations.insert(e.begin(),e.end());
     555        5430 :     }
     556        5431 :   }
     557       56305 :   else if (sort == sort_int::int_())
     558             :   {
     559        5483 :     function_symbol_vector f(sort_int::int_generate_constructors_code());
     560        5483 :     constructors.insert(f.begin(),f.end());
     561        5483 :     f = sort_int::int_generate_functions_code();
     562        5483 :     mappings.insert(f.begin(),f.end());
     563        5483 :     implementation_map f1 = sort_int::int_cpp_implementable_mappings();
     564        5483 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     565        5483 :     f1 = sort_int::int_cpp_implementable_constructors();
     566        5483 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     567        5483 :     if (!skip_equations)
     568             :     {
     569        5482 :       data_equation_vector e(sort_int::int_generate_equations_code());
     570        5482 :       equations.insert(e.begin(),e.end());
     571        5482 :     }
     572        5483 :   }
     573       50822 :   else if (sort == sort_nat::nat())
     574             :   {
     575        6296 :     function_symbol_vector f(sort_nat::nat_generate_constructors_code());
     576        6296 :     constructors.insert(f.begin(),f.end());
     577        6296 :     f = sort_nat::nat_generate_functions_code();
     578        6296 :     mappings.insert(f.begin(),f.end());
     579        6296 :     implementation_map f1 = sort_nat::nat_cpp_implementable_mappings();
     580        6296 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     581        6296 :     f1 = sort_nat::nat_cpp_implementable_constructors();
     582        6296 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     583        6296 :     if (!skip_equations)
     584             :     {
     585        6295 :       data_equation_vector e(sort_nat::nat_generate_equations_code());
     586        6295 :       equations.insert(e.begin(),e.end());
     587        6295 :     }
     588        6296 :   }
     589       44526 :   else if (sort == sort_pos::pos())
     590             :   {
     591       10484 :     function_symbol_vector f(sort_pos::pos_generate_constructors_code());
     592       10484 :     constructors.insert(f.begin(),f.end());
     593       10484 :     f = sort_pos::pos_generate_functions_code();
     594       10484 :     mappings.insert(f.begin(),f.end());
     595       10484 :     implementation_map f1 = sort_pos::pos_cpp_implementable_mappings();
     596       10484 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     597       10484 :     f1 = sort_pos::pos_cpp_implementable_constructors();
     598       10484 :     cpp_implemented_functions.insert(f1.begin(), f1.end());
     599       10484 :     if (!skip_equations)
     600             :     {
     601       10483 :       data_equation_vector e(sort_pos::pos_generate_equations_code());
     602       10483 :       equations.insert(e.begin(),e.end());
     603       10483 :     }
     604       10484 :   }
     605       34042 :   else if (is_function_sort(sort))
     606             :   {
     607       18479 :     const sort_expression& t=function_sort(sort).codomain();
     608       18479 :     const sort_expression_list& l=function_sort(sort).domain();
     609       18479 :     if (l.size()==1)
     610             :     {
     611        6992 :       const function_symbol_vector f = function_update_generate_functions_code(l.front(),t);
     612        6992 :       mappings.insert(f.begin(),f.end());
     613        6992 :       implementation_map f1 = function_update_cpp_implementable_mappings(l.front(),t);
     614        6992 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     615        6992 :       f1 = function_update_cpp_implementable_constructors();
     616        6992 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     617        6992 :       if (!skip_equations)
     618             :       {
     619        6992 :         data_equation_vector e(function_update_generate_equations_code(l.front(),t));
     620        6992 :         equations.insert(e.begin(),e.end());
     621        6992 :       }
     622        6992 :     }
     623             :   }
     624       15563 :   else if (is_container_sort(sort))
     625             :   {
     626        1833 :     sort_expression element_sort(container_sort(sort).element_sort());
     627        1833 :     if (sort_list::is_list(sort))
     628             :     {
     629        1078 :       function_symbol_vector f(sort_list::list_generate_constructors_code(element_sort));
     630        1078 :       constructors.insert(f.begin(),f.end());
     631        1078 :       f = sort_list::list_generate_functions_code(element_sort);
     632        1078 :       mappings.insert(f.begin(),f.end());
     633        1078 :       implementation_map f1 = sort_list::list_cpp_implementable_mappings(element_sort);
     634        1078 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     635        1078 :       f1 = sort_list::list_cpp_implementable_constructors(element_sort);
     636        1078 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     637        1078 :       if (!skip_equations)
     638             :       {
     639        1077 :         data_equation_vector e(sort_list::list_generate_equations_code(element_sort));
     640        1077 :         equations.insert(e.begin(),e.end());
     641        1077 :       }
     642        1078 :     }
     643         755 :     else if (sort_set::is_set(sort))
     644             :     {
     645         283 :       sort_expression_list element_sorts;
     646         283 :       element_sorts.push_front(element_sort);
     647         283 :       function_symbol_vector f(sort_set::set_generate_constructors_code(element_sort));
     648         283 :       constructors.insert(f.begin(),f.end());
     649         283 :       f = sort_set::set_generate_functions_code(element_sort);
     650         283 :       mappings.insert(f.begin(),f.end());
     651         283 :       implementation_map f1 = sort_set::set_cpp_implementable_mappings(element_sort);
     652         283 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     653         283 :       f1 = sort_set::set_cpp_implementable_constructors(element_sort);
     654         283 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     655         283 :       if (!skip_equations)
     656             :       {
     657         282 :         data_equation_vector e(sort_set::set_generate_equations_code(element_sort));
     658         282 :         equations.insert(e.begin(),e.end());
     659         282 :       }
     660         283 :     }
     661         472 :     else if (sort_fset::is_fset(sort))
     662             :     {
     663         332 :       function_symbol_vector f = sort_fset::fset_generate_constructors_code(element_sort);
     664         332 :       constructors.insert(f.begin(),f.end());
     665         332 :       f = sort_fset::fset_generate_functions_code(element_sort);
     666         332 :       mappings.insert(f.begin(),f.end());
     667         332 :       implementation_map f1 = sort_fset::fset_cpp_implementable_mappings(element_sort);
     668         332 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     669         332 :       f1 = sort_fset::fset_cpp_implementable_constructors(element_sort);
     670         332 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     671         332 :       if (!skip_equations)
     672             :       {
     673         331 :         data_equation_vector e = sort_fset::fset_generate_equations_code(element_sort);
     674         331 :         equations.insert(e.begin(),e.end());
     675         331 :       }
     676         332 :     }
     677         140 :     else if (sort_bag::is_bag(sort))
     678             :     {
     679          68 :       sort_expression_list element_sorts;
     680          68 :       element_sorts.push_front(element_sort);
     681          68 :       function_symbol_vector f(sort_bag::bag_generate_constructors_code(element_sort));
     682          68 :       constructors.insert(f.begin(),f.end());
     683          68 :       f = sort_bag::bag_generate_functions_code(element_sort);
     684          68 :       mappings.insert(f.begin(),f.end());
     685          68 :       implementation_map f1 = sort_bag::bag_cpp_implementable_mappings(element_sort);
     686          68 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     687          68 :       f1 = sort_bag::bag_cpp_implementable_constructors(element_sort);
     688          68 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     689          68 :       if (!skip_equations)
     690             :       {
     691          67 :         data_equation_vector e(sort_bag::bag_generate_equations_code(element_sort));
     692          67 :         equations.insert(e.begin(),e.end());
     693          67 :       }
     694          68 :     }
     695          72 :     else if (sort_fbag::is_fbag(sort))
     696             :     {
     697          72 :       function_symbol_vector f = sort_fbag::fbag_generate_constructors_code(element_sort);
     698          72 :       constructors.insert(f.begin(),f.end());
     699          72 :       f = sort_fbag::fbag_generate_functions_code(element_sort);
     700          72 :       mappings.insert(f.begin(),f.end());
     701          72 :       implementation_map f1 = sort_fbag::fbag_cpp_implementable_mappings(element_sort);
     702          72 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     703          72 :       f1 = sort_fbag::fbag_cpp_implementable_constructors(element_sort);
     704          72 :       cpp_implemented_functions.insert(f1.begin(), f1.end());
     705          72 :       if (!skip_equations)
     706             :       {
     707          71 :         data_equation_vector e = sort_fbag::fbag_generate_equations_code(element_sort);
     708          71 :         equations.insert(e.begin(),e.end());
     709          71 :       }
     710          72 :     }
     711        1833 :   }
     712       13730 :   else if (is_structured_sort(sort))
     713             :   {
     714        3496 :     insert_mappings_constructors_for_structured_sort(
     715             :                     atermpp::down_cast<structured_sort>(sort),
     716             :                     constructors, mappings, equations, skip_equations);
     717             :   }
     718       72141 :   add_standard_mappings_and_equations(sort, mappings, equations, skip_equations);
     719       72141 : }
     720             : 
     721           1 : void data_specification::get_system_defined_sorts_constructors_and_mappings(
     722             :             std::set < sort_expression >& sorts,
     723             :             std::set < function_symbol >& constructors,
     724             :             std::set <function_symbol >& mappings) const
     725             : {
     726           1 :   implementation_map cpp_implemented_functions;
     727             : 
     728           1 :   sorts.insert(sort_bool::bool_());
     729           1 :   sorts.insert(sort_pos::pos());
     730           1 :   sorts.insert(sort_nat::nat());
     731           1 :   sorts.insert(sort_int::int_());
     732           1 :   sorts.insert(sort_real::real_());
     733           1 :   sorts.insert(sort_list::list(sort_pos::pos()));
     734           1 :   sorts.insert(sort_fset::fset(sort_pos::pos()));
     735           1 :   sorts.insert(sort_set::set_(sort_pos::pos()));
     736           1 :   sorts.insert(sort_fbag::fbag(sort_pos::pos()));
     737           1 :   sorts.insert(sort_bag::bag(sort_pos::pos()));
     738             : 
     739           1 :   std::set < data_equation > dummy_equations;
     740          11 :   for(const sort_expression& s: sorts)
     741             :   {
     742          10 :     find_associated_system_defined_data_types_for_a_sort(s, constructors, mappings, dummy_equations, cpp_implemented_functions, true);
     743             :   }
     744           1 :   assert(dummy_equations.size()==0);
     745           1 : }
     746             : 
     747         994 : bool data_specification::is_well_typed() const
     748             : {
     749             :   // check 1)
     750         994 :   if (!detail::check_data_spec_sorts(constructors(), sorts()))
     751             :   {
     752             :     std::clog << "data_specification::is_well_typed() failed: not all of the sorts appearing in the constructors "
     753           0 :               << data::pp(constructors()) << " are declared in " << data::pp(sorts()) << std::endl;
     754           0 :     return false;
     755             :   }
     756             : 
     757             :   // check 2)
     758         994 :   if (!detail::check_data_spec_sorts(mappings(), sorts()))
     759             :   {
     760             :     std::clog << "data_specification::is_well_typed() failed: not all of the sorts appearing in the mappings "
     761           0 :               << data::pp(mappings()) << " are declared in " << data::pp(sorts()) << std::endl;
     762           0 :     return false;
     763             :   }
     764             : 
     765         994 :   return true;
     766             : }
     767             : 
     768             : /// There are two types of representations of ATerms:
     769             : ///  - the bare specification that does not contain constructor, mappings
     770             : ///    and equations for system defined sorts
     771             : ///  - specification that includes all system defined information (legacy)
     772             : /// The last type must eventually disappear but is unfortunately still in
     773             : /// use in a substantial amount of source code.
     774             : /// Note, all sorts with name prefix \@legacy_ are eliminated
     775           3 : void data_specification::build_from_aterm(const atermpp::aterm_appl& term)
     776             : {
     777           3 :   assert(core::detail::check_rule_DataSpec(term));
     778             : 
     779             :   // Note backwards compatibility measure: alias is no longer a sort_expression
     780             :   const atermpp::term_list<atermpp::aterm_appl> term_sorts=
     781           3 :                  atermpp::down_cast<atermpp::term_list<atermpp::aterm_appl> >(atermpp::down_cast<atermpp::aterm_appl>(term[0])[0]);
     782             :   const data::function_symbol_list term_constructors=
     783           3 :                  atermpp::down_cast<data::function_symbol_list>(atermpp::down_cast<atermpp::aterm_appl>(term[1])[0]);
     784             :   const data::function_symbol_list term_mappings=
     785           3 :                  atermpp::down_cast<data::function_symbol_list>(atermpp::down_cast<atermpp::aterm_appl>(term[2])[0]);
     786             :   const data::data_equation_list term_equations=
     787           3 :                  atermpp::down_cast<data::data_equation_list>(atermpp::down_cast<atermpp::aterm_appl>(term[3])[0]);
     788             : 
     789             :   // Store the sorts and aliases.
     790           9 :   for(const atermpp::aterm_appl& t: term_sorts)
     791             :   {
     792           6 :     if (data::is_alias(t)) // Compatibility with legacy code
     793             :     {
     794           5 :       add_alias(atermpp::down_cast<data::alias>(t));
     795             :     }
     796             :     else
     797             :     {
     798           1 :       add_sort(atermpp::down_cast<basic_sort>(t));
     799             :     }
     800             :   }
     801             : 
     802             :   // Store the constructors.
     803           4 :   for(const function_symbol& f: term_constructors)
     804             :   {
     805           1 :     add_constructor(f);
     806             :   }
     807             : 
     808             :   // Store the mappings.
     809           4 :   for(const function_symbol& f: term_mappings)
     810             :   {
     811           1 :     add_mapping(f);
     812             :   }
     813             : 
     814             :   // Store the equations.
     815           3 :   for(const data_equation& e: term_equations)
     816             :   {
     817           0 :     add_equation(e);
     818             :   }
     819           3 : }
     820             : 
     821          72 : data_specification::data_specification(const basic_sort_vector& sorts,
     822             :   const alias_vector& aliases,
     823             :   const function_symbol_vector& constructors,
     824             :   const function_symbol_vector& user_defined_mappings,
     825          72 :   const data_equation_vector& user_defined_equations)
     826          72 :   : sort_specification(sorts, aliases)
     827             : {
     828             :   // Store the constructors.
     829          72 :   for(const function_symbol& f: constructors)
     830             :   {
     831           0 :     add_constructor(f);
     832             :   }
     833             : 
     834             :   // Store the mappings.
     835          93 :   for(const function_symbol& f: user_defined_mappings)
     836             :   {
     837          21 :     add_mapping(f);
     838             :   }
     839             : 
     840             :   // Store the equations.
     841          89 :   for(const data_equation& e: user_defined_equations)
     842             :   {
     843          17 :     add_equation(e);
     844             :   }
     845             : 
     846          72 :   assert(is_well_typed());
     847          72 : }
     848             : 
     849             : } // namespace data
     850             : } // namespace mcrl2

Generated by: LCOV version 1.14