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"
18#include "mcrl2/data/function_update.h"
19#include "mcrl2/data/list.h"
34 const function_symbol_vector& constructors=m_specification.constructors(s);
35 if (constructors.empty())
40 for(
const function_symbol& f: constructors)
42 if (is_function_sort(f.sort()))
44 const function_sort& f_sort=atermpp::down_cast<function_sort>(f.sort());
45 const sort_expression_list& l=f_sort.domain();
47 for(
const sort_expression& e: l)
67 if (m_visiting.count(s)>0)
103 for(
const sort_expression& sort: s.domain())
105 if (!is_finite(sort))
150 std::set<sort_expression> sorts_already_seen,
151 const bool toplevel)
const
155 if (sorts_already_seen.count(s)>0)
157 throw mcrl2::runtime_error(
"Sort alias " + pp(s) +
" is defined in terms of itself.");
159 for(
const alias& a: m_user_defined_aliases)
163 sorts_already_seen.insert(s);
164 check_for_alias_loop(a.reference(), sorts_already_seen,
true);
165 sorts_already_seen.erase(s);
174 check_for_alias_loop(container_sort(s).element_sort(),sorts_already_seen,
false);
180 sort_expression_list s_domain(function_sort(s).domain());
181 for(
const sort_expression& sort: s_domain)
183 check_for_alias_loop(sort,sorts_already_seen,
false);
186 check_for_alias_loop(function_sort(s).codomain(),sorts_already_seen,
false);
195 structured_sort_constructor_list constructors=ss.constructors();
196 for(
const structured_sort_constructor& constructor: constructors)
198 structured_sort_constructor_argument_list ssca=constructor.arguments();
199 for(
const structured_sort_constructor_argument& a: ssca)
201 check_for_alias_loop(a.sort(),sorts_already_seen,
false);
215 const std::multimap< sort_expression, sort_expression >& map1,
218 assert(sorts_already_seen.find(e)==sorts_already_seen.end());
226 find_normal_form(fs.codomain(),map1,sorts_already_seen);
227 const sort_expression_list& domain=fs
.domain();
228 sort_expression_list normalised_domain;
229 for(
const sort_expression& s: domain)
231 normalised_domain.push_front(find_normal_form(s,map1,sorts_already_seen));
233 return function_sort(reverse(normalised_domain),normalised_codomain);
239 return container_sort(cs.container_name(),find_normal_form(cs.element_sort(),map1,sorts_already_seen));
247 structured_sort_constructor_list constructors=ss.constructors();
248 structured_sort_constructor_list normalised_constructors;
249 for(
const structured_sort_constructor& constructor: constructors)
251 structured_sort_constructor_argument_list normalised_ssa;
252 for(
const structured_sort_constructor_argument& a: constructor.arguments())
254 normalised_ssa.push_front(structured_sort_constructor_argument(a.name(),
255 find_normal_form(a.sort(),map1,sorts_already_seen)));
258 normalised_constructors.push_front(
259 structured_sort_constructor(
261 reverse(normalised_ssa),
262 constructor.recogniser()));
265 result_sort=structured_sort(reverse(normalised_constructors));
275 const std::multimap< sort_expression, sort_expression >::const_iterator i1=map1.find(result_sort);
279 sorts_already_seen.insert(result_sort);
281 return find_normal_form(i1->second,map1,sorts_already_seen);
296 mCRL2log(mcrl2::log::debug) <<
"Erroneous attempt to insert an untyped sort into the a sort specification\n";
300 if (!m_sorts_in_context.insert(sort).second)
319#ifdef MCRL2_ENABLE_MACHINENUMBERS
320 import_system_defined_sort(sort_machine_word::machine_word());
321 import_system_defined_sort(sort_nat::natnatpair());
329#ifdef MCRL2_ENABLE_MACHINENUMBERS
330 import_system_defined_sort(sort_machine_word::machine_word());
335 const function_sort& fsort=atermpp::down_cast<function_sort>(sort);
336 import_system_defined_sorts(fsort
.domain());
352 sort_expression_list element_sorts;
353 element_sorts.push_front(element_sort);
354 import_system_defined_sort(function_sort(element_sorts,sort_bool::bool_()));
368 sort_expression_list element_sorts ;
369 element_sorts.push_front(element_sort);
370 import_system_defined_sort(function_sort(element_sorts,sort_nat::nat()));
381 function_symbol_vector f(s_sort.constructor_functions(sort));
382 for(
const function_symbol& f: s_sort.constructor_functions(sort))
384 import_system_defined_sort(f.sort());
398 m_normalised_aliases.clear();
404 for(
const alias& a: m_user_defined_aliases)
406 std::set < sort_expression > sorts_already_seen;
409 check_for_alias_loop(a.name(),sorts_already_seen,
true);
411 catch (mcrl2::runtime_error &)
413 mCRL2log(log::debug) <<
"Encountered an alias loop in the alias for " << a.name() <<
". The normalised aliases are not constructed\n";
424 std::multimap< sort_expression, sort_expression > sort_aliases_to_be_investigated;
425 std::multimap< sort_expression, sort_expression > resulting_normalized_sort_aliases;
427 for(
const alias& a: m_user_defined_aliases)
429 if (is_structured_sort(a.reference()))
431 sort_aliases_to_be_investigated.insert(std::pair<sort_expression,sort_expression>(a.reference(),a.name()));
435 resulting_normalized_sort_aliases.insert(std::pair<sort_expression,sort_expression>(a.name(),a.reference()));
440 for(; !sort_aliases_to_be_investigated.empty() ;)
442 const std::multimap< sort_expression, sort_expression >::iterator it=sort_aliases_to_be_investigated.begin();
443 const sort_expression lhs=it->first;
444 const sort_expression rhs=it->second;
445 sort_aliases_to_be_investigated.erase(it);
447 for(
const std::pair<
const sort_expression, sort_expression >& p: resulting_normalized_sort_aliases)
449 const sort_expression s1=data::replace_sort_expressions(lhs,sort_expression_assignment(p.first,p.second),
true);
454 assert(is_basic_sort(rhs));
458 const bool rhs_to_s1 = is_basic_sort(s1) && pp(basic_sort(s1))<=pp(rhs);
459 const sort_expression left_hand_side=(rhs_to_s1?rhs:s1);
460 const sort_expression pre_normal_form=(rhs_to_s1?s1:rhs);
461 assert(is_basic_sort(pre_normal_form));
462 const sort_expression& e1=pre_normal_form;
463 if (e1!=left_hand_side)
465 const sort_expression normalised_lhs=find_normal_form(left_hand_side,resulting_normalized_sort_aliases);
467 if (std::find_if(sort_aliases_to_be_investigated.lower_bound(normalised_lhs),
468 sort_aliases_to_be_investigated.upper_bound(normalised_lhs),
469 [&rhs](
const std::pair<sort_expression,sort_expression>& x){
return x.second==rhs; })
470 == sort_aliases_to_be_investigated.upper_bound(normalised_lhs))
472 sort_aliases_to_be_investigated.insert(
473 std::pair<sort_expression,sort_expression > (normalised_lhs, e1));
479 const sort_expression s2 = data::replace_sort_expressions(p.first,sort_expression_assignment(lhs,rhs),
true);
482 assert(is_basic_sort(p.second));
485 const bool i_second_to_s2 = is_basic_sort(s2) && pp(basic_sort(s2))<=pp(p.second);
486 const sort_expression left_hand_side=(i_second_to_s2?p.second:s2);
487 const sort_expression pre_normal_form=(i_second_to_s2?s2:p.second);
488 assert(is_basic_sort(pre_normal_form));
489 const sort_expression& e2=pre_normal_form;
490 if (e2!=left_hand_side)
492 const sort_expression normalised_lhs=find_normal_form(left_hand_side,resulting_normalized_sort_aliases);
494 if (std::find_if(sort_aliases_to_be_investigated.lower_bound(normalised_lhs),
495 sort_aliases_to_be_investigated.upper_bound(normalised_lhs),
496 [&rhs](
const std::pair<sort_expression,sort_expression>& x){
return x.second==rhs; })
497 == sort_aliases_to_be_investigated.upper_bound(normalised_lhs))
499 sort_aliases_to_be_investigated.insert(
500 std::pair<sort_expression,sort_expression > (normalised_lhs,e2));
507 const sort_expression normalised_lhs = find_normal_form(lhs,resulting_normalized_sort_aliases);
508 const sort_expression normalised_rhs = find_normal_form(rhs,resulting_normalized_sort_aliases);
509 if (normalised_lhs!=normalised_rhs)
511 resulting_normalized_sort_aliases.insert(std::pair<sort_expression,sort_expression >(normalised_lhs,normalised_rhs));
518 for(
const std::pair<
const sort_expression,sort_expression>& p: resulting_normalized_sort_aliases)
520 const sort_expression normalised_rhs = find_normal_form(p.second,resulting_normalized_sort_aliases);
521 m_normalised_aliases[p.first]=normalised_rhs;
523 assert(p.first!=normalised_rhs);
531 std::set < function_symbol >& constructors,
532 std::set < function_symbol >& mappings,
533 std::set < data_equation >& equations,
534 implementation_map& cpp_implemented_functions,
535 const bool skip_equations)
const
540 function_symbol_vector f(sort_bool::bool_generate_constructors_code());
541 constructors.insert(f.begin(), f.end());
542 f = sort_bool::bool_generate_functions_code();
543 mappings.insert(f.begin(), f.end());
544 implementation_map f1 = sort_bool::bool_cpp_implementable_mappings();
545 cpp_implemented_functions.insert(f1.begin(), f1.end());
546 f1 = sort_bool::bool_cpp_implementable_constructors();
547 cpp_implemented_functions.insert(f1.begin(), f1.end());
550 data_equation_vector e(sort_bool::bool_generate_equations_code());
551 equations.insert(e.begin(),e.end());
556 function_symbol_vector f(sort_real::real_generate_constructors_code());
557 constructors.insert(f.begin(),f.end());
558 f = sort_real::real_generate_functions_code();
559 mappings.insert(f.begin(),f.end());
560 implementation_map f1 = sort_int::int_cpp_implementable_mappings();
561 cpp_implemented_functions.insert(f1.begin(), f1.end());
562 f1 = sort_int::int_cpp_implementable_constructors();
563 cpp_implemented_functions.insert(f1.begin(), f1.end());
566 data_equation_vector e(sort_real::real_generate_equations_code());
567 equations.insert(e.begin(),e.end());
572 function_symbol_vector f(sort_int::int_generate_constructors_code());
573 constructors.insert(f.begin(),f.end());
574 f = sort_int::int_generate_functions_code();
575 mappings.insert(f.begin(),f.end());
576 implementation_map f1 = sort_int::int_cpp_implementable_mappings();
577 cpp_implemented_functions.insert(f1.begin(), f1.end());
578 f1 = sort_int::int_cpp_implementable_constructors();
579 cpp_implemented_functions.insert(f1.begin(), f1.end());
582 data_equation_vector e(sort_int::int_generate_equations_code());
583 equations.insert(e.begin(),e.end());
588 function_symbol_vector f(sort_nat::nat_generate_constructors_code());
589 constructors.insert(f.begin(),f.end());
590 f = sort_nat::nat_generate_functions_code();
591 mappings.insert(f.begin(),f.end());
592 implementation_map f1 = sort_nat::nat_cpp_implementable_mappings();
593 cpp_implemented_functions.insert(f1.begin(), f1.end());
594 f1 = sort_nat::nat_cpp_implementable_constructors();
595 cpp_implemented_functions.insert(f1.begin(), f1.end());
598 data_equation_vector e(sort_nat::nat_generate_equations_code());
599 equations.insert(e.begin(),e.end());
604 function_symbol_vector f(sort_pos::pos_generate_constructors_code());
605 constructors.insert(f.begin(),f.end());
606 f = sort_pos::pos_generate_functions_code();
607 mappings.insert(f.begin(),f.end());
608 implementation_map f1 = sort_pos::pos_cpp_implementable_mappings();
609 cpp_implemented_functions.insert(f1.begin(), f1.end());
610 f1 = sort_pos::pos_cpp_implementable_constructors();
611 cpp_implemented_functions.insert(f1.begin(), f1.end());
614 data_equation_vector e(sort_pos::pos_generate_equations_code());
615 equations.insert(e.begin(),e.end());
618#ifdef MCRL2_ENABLE_MACHINENUMBERS
619 else if (sort == sort_machine_word::machine_word())
621 function_symbol_vector f(sort_machine_word::machine_word_generate_constructors_code());
622 constructors.insert(f.begin(),f.end());
623 f = sort_machine_word::machine_word_generate_functions_code();
624 mappings.insert(f.begin(),f.end());
625 implementation_map f1 = sort_machine_word::machine_word_cpp_implementable_mappings();
626 cpp_implemented_functions.insert(f1.begin(), f1.end());
627 f1 = sort_machine_word::machine_word_cpp_implementable_constructors();
628 cpp_implemented_functions.insert(f1.begin(), f1.end());
631 data_equation_vector e(sort_machine_word::machine_word_generate_equations_code());
632 equations.insert(e.begin(),e.end());
642 const function_symbol_vector f = function_update_generate_functions_code(l.front(),t);
643 mappings.insert(f.begin(),f.end());
644 implementation_map f1 = function_update_cpp_implementable_mappings(l.front(),t);
645 cpp_implemented_functions.insert(f1.begin(), f1.end());
646 f1 = function_update_cpp_implementable_constructors();
647 cpp_implemented_functions.insert(f1.begin(), f1.end());
650 data_equation_vector e(function_update_generate_equations_code(l.front(),t));
651 equations.insert(e.begin(),e.end());
660 function_symbol_vector f(sort_list::list_generate_constructors_code(element_sort));
661 constructors.insert(f.begin(),f.end());
662 f = sort_list::list_generate_functions_code(element_sort);
663 mappings.insert(f.begin(),f.end());
664 implementation_map f1 = sort_list::list_cpp_implementable_mappings(element_sort);
665 cpp_implemented_functions.insert(f1.begin(), f1.end());
666 f1 = sort_list::list_cpp_implementable_constructors(element_sort);
667 cpp_implemented_functions.insert(f1.begin(), f1.end());
670 data_equation_vector e(sort_list::list_generate_equations_code(element_sort));
671 equations.insert(e.begin(),e.end());
676 sort_expression_list element_sorts;
677 element_sorts.push_front(element_sort);
678 function_symbol_vector f(sort_set::set_generate_constructors_code(element_sort));
679 constructors.insert(f.begin(),f.end());
680 f = sort_set::set_generate_functions_code(element_sort);
681 mappings.insert(f.begin(),f.end());
682 implementation_map f1 = sort_set::set_cpp_implementable_mappings(element_sort);
683 cpp_implemented_functions.insert(f1.begin(), f1.end());
684 f1 = sort_set::set_cpp_implementable_constructors(element_sort);
685 cpp_implemented_functions.insert(f1.begin(), f1.end());
688 data_equation_vector e(sort_set::set_generate_equations_code(element_sort));
689 equations.insert(e.begin(),e.end());
694 function_symbol_vector f = sort_fset::fset_generate_constructors_code(element_sort);
695 constructors.insert(f.begin(),f.end());
696 f = sort_fset::fset_generate_functions_code(element_sort);
697 mappings.insert(f.begin(),f.end());
698 implementation_map f1 = sort_fset::fset_cpp_implementable_mappings(element_sort);
699 cpp_implemented_functions.insert(f1.begin(), f1.end());
700 f1 = sort_fset::fset_cpp_implementable_constructors(element_sort);
701 cpp_implemented_functions.insert(f1.begin(), f1.end());
704 data_equation_vector e = sort_fset::fset_generate_equations_code(element_sort);
705 equations.insert(e.begin(),e.end());
710 sort_expression_list element_sorts;
711 element_sorts.push_front(element_sort);
712 function_symbol_vector f(sort_bag::bag_generate_constructors_code(element_sort));
713 constructors.insert(f.begin(),f.end());
714 f = sort_bag::bag_generate_functions_code(element_sort);
715 mappings.insert(f.begin(),f.end());
716 implementation_map f1 = sort_bag::bag_cpp_implementable_mappings(element_sort);
717 cpp_implemented_functions.insert(f1.begin(), f1.end());
718 f1 = sort_bag::bag_cpp_implementable_constructors(element_sort);
719 cpp_implemented_functions.insert(f1.begin(), f1.end());
722 data_equation_vector e(sort_bag::bag_generate_equations_code(element_sort));
723 equations.insert(e.begin(),e.end());
728 function_symbol_vector f = sort_fbag::fbag_generate_constructors_code(element_sort);
729 constructors.insert(f.begin(),f.end());
730 f = sort_fbag::fbag_generate_functions_code(element_sort);
731 mappings.insert(f.begin(),f.end());
732 implementation_map f1 = sort_fbag::fbag_cpp_implementable_mappings(element_sort);
733 cpp_implemented_functions.insert(f1.begin(), f1.end());
734 f1 = sort_fbag::fbag_cpp_implementable_constructors(element_sort);
735 cpp_implemented_functions.insert(f1.begin(), f1.end());
738 data_equation_vector e = sort_fbag::fbag_generate_equations_code(element_sort);
739 equations.insert(e.begin(),e.end());
745 insert_mappings_constructors_for_structured_sort(
746 atermpp::down_cast<structured_sort>(sort),
747 constructors, mappings, equations, skip_equations);
749 add_standard_mappings_and_equations(sort, mappings, equations, skip_equations);
760#ifdef MCRL2_ENABLE_MACHINENUMBERS
784 if (!detail::check_data_spec_sorts(constructors(), sorts()))
786 std::clog <<
"data_specification::is_well_typed() failed: not all of the sorts appearing in the constructors "
787 << data::pp(constructors()) <<
" are declared in " << data::pp(sorts()) << std::endl;
792 if (!detail::check_data_spec_sorts(mappings(), sorts()))
794 std::clog <<
"data_specification::is_well_typed() failed: not all of the sorts appearing in the mappings "
795 << data::pp(mappings()) <<
" are declared in " << data::pp(sorts()) << std::endl;
811 assert(
core::
detail::check_rule_DataSpec(term));
815 atermpp::down_cast<atermpp::term_list<atermpp::aterm> >(term[0][0]);
816 const data::function_symbol_list term_constructors=
817 atermpp::down_cast<data::function_symbol_list>(term[1][0]);
818 const data::function_symbol_list term_mappings=
819 atermpp::down_cast<data::function_symbol_list>(term[2][0]);
820 const data::data_equation_list term_equations=
821 atermpp::down_cast<data::data_equation_list>(term[3][0]);
824 for(
const atermpp::aterm& t: term_sorts)
826 if (data::is_alias(t))
828 add_alias(atermpp::down_cast<data::alias>(t));
832 add_sort(atermpp::down_cast<basic_sort>(t));
837 for(
const function_symbol& f: term_constructors)
843 for(
const function_symbol& f: term_mappings)
849 for(
const data_equation& e: term_equations)
856 const alias_vector& aliases,
857 const function_symbol_vector& constructors,
858 const function_symbol_vector& user_defined_mappings,
859 const data_equation_vector& user_defined_equations)
863 for(
const function_symbol& f: constructors)
869 for(
const function_symbol& f: user_defined_mappings)
875 for(
const data_equation& e: user_defined_equations)
A unordered_map class in which aterms can be stored.
basic_sort(const atermpp::aterm &term)
const container_type & container_name() const
const sort_expression & element_sort() const
container_sort(const atermpp::aterm &term)
data_specification(const basic_sort_vector &sorts, const alias_vector &aliases, const function_symbol_vector &constructors, const function_symbol_vector &user_defined_mappings, const data_equation_vector &user_defined_equations)
Constructor from its members.
bool is_well_typed() const
Returns true if.
bool is_certainly_finite(const sort_expression &s) const
Checks whether a sort is certainly finite.
bool is_finite(const container_sort &s)
bool is_finite(const basic_sort &s)
bool is_finite_aux(const sort_expression &s)
bool is_finite(const sort_expression &s)
std::set< sort_expression > m_visiting
bool is_finite(const alias &)
bool is_finite(const function_sort &s)
const data_specification & m_specification
finiteness_helper(const data_specification &specification)
bool is_finite(const structured_sort &s)
\brief Container type for finite sets
fset_container()
\brief Default constructor X3.
const sort_expression & codomain() const
function_sort(const atermpp::aterm &term)
const sort_expression_list & domain() const
\brief Container type for sets
set_container()
\brief Default constructor X3.
sort_expression & operator=(const sort_expression &) noexcept=default
sort_expression(const sort_expression &) noexcept=default
Move semantics.
void add_system_defined_sort(const sort_expression &s)
Adds a sort to this specification, and marks it as system defined.
void add_predefined_basic_sorts()
void sorts_are_not_necessarily_normalised_anymore() const
void reconstruct_m_normalised_aliases() const
void import_system_defined_sort(const sort_expression &sort)
Adds the system defined sorts in a sequence. The second argument is used to check which sorts are add...
structured_sort(const atermpp::aterm &term)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Namespace for system defined sort bag.
bool is_bag(const sort_expression &e)
Recogniser for sort expression Bag(s)
Namespace for system defined sort bool_.
const basic_sort & bool_()
Constructor for sort expression Bool.
Namespace for system defined sort fbag.
container_sort fbag(const sort_expression &s)
Constructor for sort expression FBag(S)
bool is_fbag(const sort_expression &e)
Recogniser for sort expression FBag(s)
Namespace for system defined sort fset.
bool is_fset(const sort_expression &e)
Recogniser for sort expression FSet(s)
container_sort fset(const sort_expression &s)
Constructor for sort expression FSet(S)
Namespace for system defined sort int_.
const basic_sort & int_()
Constructor for sort expression Int.
Namespace for system defined sort list.
bool is_list(const sort_expression &e)
Recogniser for sort expression List(s)
Namespace for system defined sort nat.
const basic_sort & nat()
Constructor for sort expression Nat.
const basic_sort & natpair()
Constructor for sort expression @NatPair.
Namespace for system defined sort pos.
const basic_sort & pos()
Constructor for sort expression Pos.
Namespace for system defined sort real_.
const basic_sort & real_()
Constructor for sort expression Real.
Namespace for system defined sort set_.
bool is_set(const sort_expression &e)
Recogniser for sort expression Set(s)
container_sort set_(const sort_expression &s)
Constructor for sort expression Set(S)
bool is_structured_sort(const atermpp::aterm &x)
Returns true if the term t is a structured sort.
static sort_expression find_normal_form(const sort_expression &e, const std::multimap< sort_expression, sort_expression > &map1, std::set< sort_expression > sorts_already_seen=std::set< sort_expression >())
bool is_untyped_possible_sorts(const atermpp::aterm &x)
Returns true if the term t is an expression for multiple possible sorts.
bool is_untyped_sort(const atermpp::aterm &x)
Returns true if the term t is the unknown sort.
bool is_container_sort(const atermpp::aterm &x)
Returns true if the term t is a container sort.
bool is_basic_sort(const atermpp::aterm &x)
Returns true if the term t is a basic sort.
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.