12#ifndef MCRL2_MODAL_FORMULA_TYPECHECK_H
13#define MCRL2_MODAL_FORMULA_TYPECHECK_H
15#include "mcrl2/lps/typecheck.h"
16#include "mcrl2/modal_formula/detail/state_variable_context.h"
17#include "mcrl2/modal_formula/is_monotonous.h"
18#include "mcrl2/modal_formula/normalize_sorts.h"
49 return process::typecheck_action(name, parameters, m_data_type_checker, m_variable_context, m_action_context);
55 result = m_data_type_checker.typecheck_data_expression(x, data::sort_bool::bool_(), m_variable_context);
61 data::
data_expression new_time = m_data_type_checker.typecheck_data_expression(x.time_stamp(), data::sort_real::real_(), m_variable_context);
69 if (x.actions().size() == 1)
74 result = data::typecheck_untyped_data_parameter(m_data_type_checker, y.name(), y.arguments(), data::sort_bool::bool_(), m_variable_context);
84 for (
const data::untyped_data_parameter& a: x.actions())
86 new_arguments.push_front(typecheck_action(a.name(), a.arguments()));
88 new_arguments = atermpp::reverse(new_arguments);
89 result = action_formulas::multi_action(new_arguments);
97 auto m_variable_context_copy = m_variable_context;
98 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
101 m_variable_context = m_variable_context_copy;
115 auto m_variable_context_copy = m_variable_context;
116 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
119 m_variable_context = m_variable_context_copy;
144 const VariableContainer& variables,
145 const ActionLabelContainer& actions
150 variable_context.add_context_variables(variables, data_typechecker);
152 action_context.add_context_action_labels(actions, data_typechecker);
162 return typecheck_action_formula(x, lpsspec.data(), lpsspec.global_variables(), lpsspec.action_labels());
272 if (x
.name() == core::identifier_string(
"."))
283 if (x
.name() == core::identifier_string(
"."))
285 result =
seq(left
, right
);
289 result =
alt(left
, right
);
317 const VariableContainer& variables,
318 const ActionLabelContainer& actions
323 variable_context.add_context_variables(variables, data_typechecker);
325 action_context.add_context_action_labels(actions, data_typechecker);
335 return typecheck_regular_formula(x, lpsspec.data(), lpsspec.global_variables(), lpsspec.action_labels());
361 const bool formula_is_quantitative
377 result = m_data_type_checker.typecheck_data_expression(x, data::sort_real::real_(), m_variable_context);
383 result = m_data_type_checker.typecheck_data_expression(x, data::sort_bool::bool_(), m_variable_context);
387 throw mcrl2::
runtime_error(
"Fail to type data expression as bool or real: " +
pp(x
) +
".\n" +
395 result = m_data_type_checker.typecheck_data_expression(x, data::sort_bool::bool_(), m_variable_context);
404 throw mcrl2::
runtime_error(
"Forall is not allowed to capture values in a quantitative modal formula " +
state_formulas::pp(x
) +
". Use inf for infimum instead. ");
410 auto m_variable_context_copy = m_variable_context;
411 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
414 m_variable_context = m_variable_context_copy;
429 throw mcrl2::
runtime_error(
"Exists is not allowed to capture values in a quantitative modal formula " +
state_formulas::pp(x
) +
". Use sup for supremum instead. ");
435 auto m_variable_context_copy = m_variable_context;
436 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
439 m_variable_context = m_variable_context_copy;
460 auto m_variable_context_copy = m_variable_context;
461 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
464 m_variable_context = m_variable_context_copy;
485 auto m_variable_context_copy = m_variable_context;
486 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
489 m_variable_context = m_variable_context_copy;
510 auto m_variable_context_copy = m_variable_context;
511 m_variable_context.add_context_variables(x.variables(), m_data_type_checker);
514 m_variable_context = m_variable_context_copy;
528 regular_formulas::detail::make_typecheck_builder(m_data_type_checker, m_variable_context, m_action_context).apply(formula, x.formula());
531 make_may(result, formula, operand);
538 regular_formulas::detail::make_typecheck_builder(m_data_type_checker, m_variable_context, m_action_context).apply(formula, x.formula());
541 make_must(result, formula, operand);
547 data::
data_expression new_time = m_data_type_checker.typecheck_data_expression(x.time_stamp(), data::sort_real::real_(), m_variable_context);
548 make_delay_timed(result, new_time);
554 data::
data_expression new_time = m_data_type_checker.typecheck_data_expression(x.time_stamp(), data::sort_real::real_(), m_variable_context);
555 make_yaled_timed(result, new_time);
560 data::
sort_expression_list expected_sorts = m_state_variable_context.matching_state_variable_sorts(name, arguments);
562 auto q1 = expected_sorts.begin();
563 auto q2 = arguments.begin();
564 for (; q1 != expected_sorts.end(); ++q1, ++q2)
566 new_arguments.push_front(m_data_type_checker.typecheck_data_expression(*q2, *q1, m_variable_context));
568 new_arguments = atermpp::reverse(new_arguments);
569 return state_formulas::variable(name, new_arguments);
586 std::vector<data::variable> result;
587 for (
const data::assignment& a: x)
589 result.push_back(a.lhs());
591 return data::variable_list(result.begin(), result.end());
594 template <
typename MuNuFormula>
597 data::
assignment_list new_assignments = m_data_type_checker.typecheck_assignment_list(x.assignments(), m_variable_context);
600 auto m_variable_context_copy = m_variable_context;
602 m_variable_context.add_context_variables(x_variables, m_data_type_checker);
605 auto m_state_variable_context_copy = m_state_variable_context;
606 m_state_variable_context.add_state_variable(x.name(), x_variables, m_data_type_checker);
610 (*
this).apply(new_operand, x.operand());
613 m_variable_context = m_variable_context_copy;
614 m_state_variable_context = m_state_variable_context_copy;
618 return mu(x.name(), new_assignments, new_operand);
622 return nu(x.name(), new_assignments, new_operand);
629 result = apply_mu_nu(x,
false);
635 result = apply_mu_nu(x,
true);
648 make_not_(result, result);
662 make_minus(result, result);
678 make_plus(result, result, rhs);
691 data::
data_expression constant = m_data_type_checker.typecheck_data_expression(
static_cast<const_multiply>(x).left(), data::sort_real::real_(), m_variable_context);
694 make_const_multiply(result, constant, rhs);
709 data::
data_expression constant = m_data_type_checker.typecheck_data_expression(
static_cast<const_multiply_alt>(x).right(), data::sort_real::real_(), m_variable_context);
710 make_const_multiply_alt(result, lhs, constant);
721 const bool formula_is_quantitative
724 return typecheck_builder(data_typechecker
, variable_context
, action_context
, state_variable_context
, formula_is_quantitative
);
740
741
742
743
746 const bool formula_is_quantitative,
747 const ActionLabelContainer& action_labels = ActionLabelContainer(),
748 const VariableContainer& variables = VariableContainer()
753 m_variable_context.add_context_variables(variables, m_data_type_checker);
754 m_action_context.add_context_action_labels(action_labels, m_data_type_checker);
769 detail::make_typecheck_builder(m_data_type_checker, m_variable_context, m_action_context, m_state_variable_context, m_formula_is_quantitative).
770 apply(result, state_formulas::normalize_sorts(x, m_data_type_checker.typechecked_data_specification()));
776
777
778
779
780
781
782
783template <
typename VariableContainer,
typename ActionLabelContainer>
785 const bool formula_is_quantitative,
787 const ActionLabelContainer& action_labels = ActionLabelContainer(),
788 const VariableContainer& variables = VariableContainer()
803
804
805
806
807
808
812 const bool formula_is_quantitative
815 return typecheck_state_formula(x, formula_is_quantitative, lpsspec.data(), lpsspec.action_labels(), lpsspec.global_variables());
828 state_formula_type_checker type_checker(dataspec, formula_is_quantitative, formspec.action_labels(), std::vector<data::variable>());
aterm_string(const aterm_string &t) noexcept=default
aterm()
Default constructor.
bool operator==(const unprotected_aterm_core &t) const
Comparison operator.
const sort_expression & element_sort() const
sort_expression sort() const
Returns the sort of the data expression.
void translate_user_notation()
Translate user notation within the equations of the data specification.
data_equation_vector & user_defined_equations()
data_specification()
Default constructor. Generate a data specification that contains only booleans and positive numbers.
const data_specification operator()() const
Yields a type checked data specification, provided typechecking was successful. If not successful an ...
void operator()(data_equation_vector &eqns)
Yields a type checked equation list, and sets the types in the equations right. If not successful an ...
data_type_checker(const data_specification &data_spec)
make a data type checker. Throws a mcrl2::runtime_error exception if the data_specification is not we...
const data_specification & typechecked_data_specification() const
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief An untyped parameter
const core::identifier_string & name() const
const data_expression_list & arguments() const
logger(const log_level_t l)
Default constructor.
Linear process specification.
Linear process specification.
stochastic_specification(const specification &other)
Constructor. This constructor is explicit as implicit conversions of this kind is a source of bugs.
\brief An untyped multi action or data application
Standard exception class for reporting runtime errors.
Identifier generator that generates names consisting of a prefix followed by a number....
D_ParserTables parser_tables_mcrl2
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
The main namespace for the aterm++ library.
void syntax_error_fn(struct D_Parser *ap)
Custom syntax error function that prints both the line number and the column.
D_ParseNode * ambiguity_fn(struct D_Parser *, int n, struct D_ParseNode **v)
Function for resolving parser ambiguities.
void warn_left_merge_merge(const parse_node &)
Prints a warning for each occurrence of 'x ||_ y || z' in the parse tree.
atermpp::aterm_string identifier_string
String type of the LPS library. Identifier strings are represented internally as ATerms.
void warn_and_or(const parse_node &)
Prints a warning for each occurrence of 'x && y || z' in the parse tree.
Namespace for system defined sort bag.
bool is_union_application(const atermpp::aterm &e)
Recogniser for application of +.
application union_(const sort_expression &s, const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
Namespace for system defined sort bool_.
const basic_sort & bool_()
Constructor for sort expression Bool.
application not_(const data_expression &arg0)
Application of function symbol !.
Namespace for system defined sort fbag.
application union_(const sort_expression &s, const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
bool is_union_application(const atermpp::aterm &e)
Recogniser for application of +.
Namespace for system defined sort fset.
application union_(const sort_expression &s, const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
bool is_union_application(const atermpp::aterm &e)
Recogniser for application of +.
Namespace for system defined sort int_.
application plus(const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
bool is_int(const sort_expression &e)
Recogniser for sort expression Int.
Namespace for system defined sort list.
application element_at(const sort_expression &s, const data_expression &arg0, const data_expression &arg1)
Application of function symbol ..
Namespace for system defined sort nat.
bool is_nat(const sort_expression &e)
Recogniser for sort expression Nat.
application plus(const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
Namespace for system defined sort pos.
bool is_pos(const sort_expression &e)
Recogniser for sort expression Pos.
application plus(const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
Namespace for system defined sort real_.
application negate(const data_expression &arg0)
Application of function symbol -.
bool is_real(const sort_expression &e)
Recogniser for sort expression Real.
application plus(const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
Namespace for system defined sort set_.
bool is_union_application(const atermpp::aterm &e)
Recogniser for application of +.
application union_(const sort_expression &s, const data_expression &arg0, const data_expression &arg1)
Application of function symbol +.
Namespace for all data library functionality.
bool is_data_expression(const atermpp::aterm &x)
Test for a data_expression expression.
data_specification merge_data_specifications(const data_specification &dataspec1, const data_specification &dataspec2)
Merges two data specifications. Throws an exception if conflicts are detected.
atermpp::term_list< sort_expression > sort_expression_list
\brief list of sort_expressions
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
bool is_untyped_data_parameter(const atermpp::aterm &x)
atermpp::term_list< variable > variable_list
\brief list of variables
atermpp::term_list< assignment > assignment_list
\brief list of assignments
std::string pp(const data::data_expression &x)
The main namespace for the LPS library.
specification remove_stochastic_operators(const stochastic_specification &spec)
Converts a stochastic specification to a specification. Throws an exception if non-empty distribution...
The main namespace for the Process library.
atermpp::term_list< action_label > action_label_list
\brief list of action_labels
atermpp::term_list< action > action_list
\brief list of actions
bool is_untyped_multi_action(const atermpp::aterm &x)
std::string read_text(std::istream &in)
Read text from a stream.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
expression builder that visits all sub expressions
Wrapper for D_Parser and its corresponding D_ParserTables.
parse_node parse(const std::string &text, unsigned int start_symbol_index=0, bool partial_parses=false)
Parses a string. N.B. The user is responsible for destruction of the returned value by calling destro...
parser(D_ParserTables &tables, D_AmbiguityFn ambiguity_fn=nullptr, D_SyntaxErrorFn syntax_error_fn=nullptr, std::size_t max_error_message_count=1)
unsigned int start_symbol_index(const std::string &name) const
expression traverser that visits all sub expressions
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const