13#ifndef MCRL2_PROCESS_TYPECHECK_H
14#define MCRL2_PROCESS_TYPECHECK_H
35 std::string msg =
"action";
48 if (std::find(sorts1.
begin(), sorts1.
end(), s) != sorts1.
end())
60 for (
auto i = x.
begin(); i != x.
end(); ++i)
124std::ostream&
operator<<(std::ostream& out,
const std::pair<core::identifier_string, data::sort_expression_list>& x)
126 return out <<
"(" << x.first <<
", " << x.second <<
")";
168 std::set<core::identifier_string> actions;
172 if (!actions.insert(a).second)
174 mCRL2log(
log::warning) <<
"Used action " << a <<
" twice (typechecking " << x <<
")" << std::endl;
179 template <
typename Container>
188 template <
typename T>
199 std::set<data::sort_expression_list> v1(s1.
begin(), s1.
end());
200 std::set<data::sort_expression_list> v2(s2.
begin(), s2.
end());
214 std::map<core::identifier_string, data::data_expression> result;
217 auto i = result.find(a.lhs());
218 if (i != result.end())
222 result[a.lhs()]=a.rhs();
244 std::string msg =
"process";
266 std::set<data::variable> Q_variables;
269 Q_variables.insert(a.lhs());
273 Q_variables.insert(v);
277 if (Q_variables.find(v) == Q_variables.end())
287 mCRL2log(
log::debug) <<
"typechecking a process call with short-hand assignments " << x <<
"" << std::endl;
299 std::map<core::identifier_string, data::variable> formal_parameter_map;
302 formal_parameter_map[v.name()] = v;
306 std::vector<data::assignment> assignments;
312 formal_parameter_map.erase(v.
name());
314 assignments.emplace_back(v, e);
318 throw mcrl2::runtime_error(std::string(e.what()) +
"\nType error occurred while typechecking the process call with short-hand assignments " +
process::pp(x));
329 for (
const auto& [name, var]: formal_parameter_map)
337 throw mcrl2::runtime_error(std::string(e.what()) +
"\nIn implicitly stated assignment " +
pp(var) +
"=" +
pp(var) +
" in process " +
pp(P) +
"(" +
data::pp(assignments) +
")\n");
391 std::set<core::identifier_string> actions;
394 check_not_equal(r.source(), r.target(),
"Renaming action into itself:", x);
398 if (!actions.insert(r.source()).second)
412 std::multiset<core::identifier_string> left_hand_side_actions;
416 assert(!cnames.
empty());
418 if (cnames.
size() == 1)
441 " into action " +
core::pp(c.name()) +
": these have no common type (typechecking " +
process::pp(x) +
")");
447 std::set < core::identifier_string > this_left_hand_sides;
450 if (this_left_hand_sides.count(a)==0 && left_hand_side_actions.find(a) != left_hand_side_actions.end())
456 left_hand_side_actions.insert(a);
457 this_left_hand_sides.insert(a);
467 std::size_t number_of_rhs_in_lhs=0;
470 if (lhs_action==c.name())
472 number_of_rhs_in_lhs++;
475 assert(left_hand_side_actions.count(c.name())>=number_of_rhs_in_lhs);
476 if (left_hand_side_actions.count(c.name())-number_of_rhs_in_lhs>0)
479 " occurs at the left and the right in a communication (typechecking " +
process::pp(x) +
")");
502 mCRL2log(
log::warning) <<
"allowing (multi)action " << A.names() <<
" twice (typechecking " << x <<
")" << std::endl;
544 (*this).apply(operand, x.
operand());
563 (*this).apply(operand, x.
operand());
598 std::vector<process_identifier> result;
601 result.push_back(eqn.identifier());
607 template <
typename VariableContainer,
typename ActionLabelContainer,
typename ProcessIdentifierContainer>
609 const VariableContainer& variables,
610 const ActionLabelContainer& action_labels,
611 const ProcessIdentifierContainer& process_identifiers
690 type_checker(proc_spec);
701template <
typename VariableContainer,
typename ActionLabelContainer,
typename ProcessIdentifierContainer>
703 const VariableContainer& variables = VariableContainer(),
705 const ActionLabelContainer& action_labels = ActionLabelContainer(),
706 const ProcessIdentifierContainer& process_identifiers = ProcessIdentifierContainer(),
711 return type_checker(x, current_equation);
Term containing a string.
size_type size() const
Returns the size of the term_list.
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
const term_list< Term > & tail() const
Returns the tail of the list.
const Term & front() const
Returns the first element of the list.
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
bool empty() const
Returns true if the list's size is 0.
void push_front(const Term &el)
Inserts a new element at the beginning of the current list.
\brief Assignment of a data expression to a variable
void translate_user_notation()
Translate user notation within the equations of the data specification.
data_expression typecheck_data_expression(const data_expression &x, const sort_expression &expected_sort, const detail::variable_context &variable_context)
const data_specification & typechecked_data_specification() const
void add_context_variables(const VariableContainer &variables)
\brief An untyped parameter
const core::identifier_string & name() const
const data_expression_list & arguments() const
\brief Assignment of a data expression to a string
const core::identifier_string & name() const
const sort_expression & sort() const
const core::identifier_string & name() const
\brief A multiset of action names
const data::data_expression_list & arguments() const
const action_label & label() const
\brief The allow operator
const action_name_multiset_list & allow_set() const
const data::data_expression & time_stamp() const
const process_expression & operand() const
\brief The block operator
const core::identifier_string_list & block_set() const
\brief The communication operator
const communication_expression_list & comm_set() const
\brief A communication expression
void add_context_action_labels(const ActionLabelContainer &actions, const data::sort_type_checker &sort_typechecker)
bool is_declared(const core::identifier_string &name) const
data::sorts_list matching_action_sorts(const core::identifier_string &name) const
bool is_declared(const core::identifier_string &name) const
data::sorts_list matching_process_sorts(const core::identifier_string &name, const data::data_expression_list ¶meters) const
process_instance make_process_instance(const core::identifier_string &name, const data::sort_expression_list &formal_parameters, const data::data_expression_list &actual_parameters) const
process_identifier match_untyped_process_instance_assignment(const untyped_process_assignment &x) const
void add_process_identifiers(const ProcessIdentifierContainer &ids, const action_context &action_ctx, const data::sort_type_checker &sort_typechecker)
const core::identifier_string_list & hide_set() const
\brief The if-then-else operator
const process_expression & else_case() const
const process_expression & then_case() const
const data::data_expression & condition() const
\brief The if-then operator
const process_expression & then_case() const
const data::data_expression & condition() const
\brief A process equation
\brief A process expression
\brief A process identifier
const data::variable_list & variables() const
Process specification consisting of a data specification, action labels, a sequence of process equati...
const std::vector< process_equation > & equations() const
Returns the equations of the process specification.
const process_expression & init() const
Returns the initialization of the process specification.
const data::data_specification & data() const
Returns the data specification.
const process::action_label_list & action_labels() const
Returns the action label specification.
const std::set< data::variable > & global_variables() const
Returns the declared free variables of the process specification.
data::data_type_checker m_data_type_checker
process_expression typecheck_process_expression(const data::detail::variable_context &variables, const process_expression &x, const process_identifier *current_equation=nullptr)
detail::action_context m_action_context
data::detail::variable_context m_variable_context
process_type_checker(const data::data_specification &dataspec=data::data_specification())
Default constructor.
void operator()(process_specification &procspec)
Typecheck the process specification procspec.
static std::vector< process_identifier > equation_identifiers(const std::vector< process_equation > &equations)
detail::process_context m_process_context
process_type_checker(const data::data_specification &dataspec, const VariableContainer &variables, const ActionLabelContainer &action_labels, const ProcessIdentifierContainer &process_identifiers)
process_expression operator()(const process_expression &x, const process_identifier *current_equation=nullptr)
Type check a process expression. Throws a mcrl2::runtime_error exception if the expression is not wel...
\brief A rename expression
\brief The rename operator
const rename_expression_list & rename_set() const
\brief The distribution operator
const data::variable_list & variables() const
const data::data_expression & distribution() const
const process_expression & operand() const
const process_expression & operand() const
const data::variable_list & variables() const
\brief An untyped process assginment
const data::untyped_identifier_assignment_list & assignments() const
const core::identifier_string & name() const
Standard exception class for reporting runtime errors.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
add your file description here.
term_list< Term > reverse(const term_list< Term > &l)
Returns the list with the elements in reversed order.
std::string print_arguments(const Container &v)
Prints a comma separated list of the elements of v. If v is empty, the empty string is returned.
std::string pp(const identifier_string &x)
const basic_sort & bool_()
Constructor for sort expression Bool.
const basic_sort & real_()
Constructor for sort expression Real.
std::string pp(const abstraction &x)
bool multi_actions_contains(const core::identifier_string_list &a, const action_name_multiset_list &A)
typecheck_builder make_typecheck_builder(data::data_type_checker &data_typechecker, const data::detail::variable_context &variables, const detail::process_context &process_identifiers, const detail::action_context &action_context, const process_identifier *current_equation=nullptr)
bool equal_multi_actions(core::identifier_string_list a1, core::identifier_string_list a2)
std::tuple< bool, data::data_expression_vector, std::string > match_action_parameters(const data::data_expression_list ¶meters, const data::sort_expression_list &expected_sorts, const data::detail::variable_context &variable_context, data::data_type_checker &typechecker)
std::ostream & operator<<(std::ostream &out, const alphabet_node &x)
void make_allow(atermpp::aterm &t, const ARGUMENTS &... args)
void make_at(atermpp::aterm &t, const ARGUMENTS &... args)
process_expression typecheck_process_expression(const process_expression &x, const VariableContainer &variables=VariableContainer(), const data::data_specification &dataspec=data::data_specification(), const ActionLabelContainer &action_labels=ActionLabelContainer(), const ProcessIdentifierContainer &process_identifiers=ProcessIdentifierContainer(), const process_identifier *current_equation=nullptr)
Typecheck a process expression.
void make_if_then_else(atermpp::aterm &t, const ARGUMENTS &... args)
void make_hide(atermpp::aterm &t, const ARGUMENTS &... args)
action_label_list normalize_sorts(const action_label_list &x, const data::sort_specification &sortspec)
void make_if_then(atermpp::aterm &t, const ARGUMENTS &... args)
void typecheck_process_specification(process_specification &proc_spec)
Type check a parsed mCRL2 process specification. Throws an exception if something went wrong.
void make_block(atermpp::aterm &t, const ARGUMENTS &... args)
action typecheck_action(const core::identifier_string &name, const data::data_expression_list ¶meters, data::data_type_checker &typechecker, const data::detail::variable_context &variable_context, const detail::action_context &action_context)
void make_stochastic_operator(atermpp::aterm &t, const ARGUMENTS &... args)
std::string pp(const action_label &x)
data::sorts_list sorts_list_intersection(const data::sorts_list &sorts1, const data::sorts_list &sorts2)
void make_process_instance_assignment(atermpp::aterm &t, const ARGUMENTS &... args)
void make_comm(atermpp::aterm &t, const ARGUMENTS &... args)
std::ostream & operator<<(std::ostream &out, const action_label &x)
void make_rename(atermpp::aterm &t, const ARGUMENTS &... args)
void make_sum(atermpp::aterm &t, const ARGUMENTS &... args)
bool has_empty_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
Returns true if the sorted ranges [first1, ..., last1) and [first2, ..., last2) have an empty interse...
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
add your file description here.
add your file description here.
void apply(T &result, const process::process_equation &x)
void check_not_empty(const Container &c, const std::string &msg, const process_expression &x)
void check_action_declared(const core::identifier_string &a, const process_expression &x)
action typecheck_action(const core::identifier_string &name, const data::data_expression_list ¶meters)
typecheck_builder(data::data_type_checker &data_typechecker, const data::detail::variable_context &variable_context, const detail::process_context &process_context, const detail::action_context &action_context, const process_identifier *current_equation=nullptr)
void apply(T &result, const untyped_process_assignment &x)
const detail::process_context & m_process_context
void apply(T &result, const process::stochastic_operator &x)
void apply(T &result, const data::untyped_data_parameter &x)
data::data_type_checker & m_data_type_checker
void apply(T &result, const process::hide &x)
process_instance typecheck_process_instance(const core::identifier_string &name, const data::data_expression_list ¶meters)
void apply(T &result, const process::if_then &x)
void check_rename_common_type(const core::identifier_string &a, const core::identifier_string &b, const process_expression &x)
bool is_action_name(const core::identifier_string &name)
void check_actions_declared(const core::identifier_string_list &act_list, const process_expression &x)
bool is_process_name(const core::identifier_string &name)
static std::map< core::identifier_string, data::data_expression > make_assignment_map(const data::untyped_identifier_assignment_list &assignments)
void check_not_equal(const T &first, const T &second, const std::string &msg, const process_expression &x)
void apply(T &result, const process::sum &x)
static bool has_empty_intersection(const data::sorts_list &s1, const data::sorts_list &s2)
void check_assignments(const process_identifier &P, const process_identifier &Q, const std::vector< data::assignment > &assignments, const untyped_process_assignment &x) const
void apply(T &result, const process::allow &x)
data::detail::variable_context m_variable_context
process_expression_builder< typecheck_builder > super
const process_identifier * m_current_equation
void apply(T &result, const process::block &x)
data::sorts_list action_sorts(const core::identifier_string &name)
void apply(T &result, const process::action &x)
void apply(T &result, const process::rename &x)
std::string print_untyped_process_assignment(const untyped_process_assignment &x) const
void apply(T &result, const process::if_then_else &x)
void apply(T &result, const process::at &x)
void apply(T &result, const process::comm &x)
const detail::action_context & m_action_context