32 #include <boost/tuple/tuple.hpp> 47 using namespace Constants;
130 return expr.
getType().isProbability();
151 for(uint32_t i = 0; i < expr.
getSize(); ++i)
153 if (!expr[i].getType().isFormula())
164 for(
size_t i = 0; i < expr.
getSize(); ++i)
195 for(
size_t i = 0; i < expr.
getSize(); ++i)
254 for (
size_t i = 0; i < type.
size(); i++)
281 for (uint32_t i = 0; i < parameters.
getSize(); i++)
283 type_t type = parameters[i].getType();
303 hasStrictInvariant(
false), hasClockRates(
false),
308 bool hasStrictInvariant, hasClockRates;
309 size_t countCostRates;
314 void RateDecomposer::decompose(
expression_t expr,
bool inforall)
322 hasStrictInvariant =
true;
326 invariant = invariant.empty()
329 AND, invariant, expr,
336 decompose(expr[0], inforall);
337 decompose(expr[1], inforall);
342 assert((expr[0].getType().getKind() ==
RATE)
343 ^ (expr[1].getType().getKind() ==
RATE));
345 if (expr[0].getType().getKind() ==
RATE)
363 hasClockRates =
true;
366 invariant = invariant.
empty()
369 AND, invariant, expr,
381 decompose(expr[1],
true);
382 invariant = invariant.empty()
385 AND, invariant, expr,
395 : system{_system}, refinementWarnings{refinement}
397 system->
accept(compileTimeComputableValues);
403 void TypeChecker::handleWarning(
const T& expr,
const std::string& msg)
409 void TypeChecker::handleError(
const T& expr,
const std::string& msg)
428 handleWarning(expr,
"$Expression_does_not_have_any_effect");
432 checkIgnoredValue(expr[1]);
436 bool TypeChecker::isCompileTimeComputable(
expression_t expr)
const 449 for (set<symbol_t>::iterator i = reads.begin(); i != reads.end(); i++)
452 (!i->getType().isFunction()
453 && !compileTimeComputableValues.
contains(*i)))
501 handleError(type,
"$Prefix_urgent_only_allowed_for_locations_and_channels");
509 handleError(type,
"$Prefix_broadcast_only_allowed_for_channels");
517 handleError(type,
"$Prefix_committed_only_allowed_for_locations");
525 handleError(type,
"$Prefix_hybrid_only_allowed_for_clocks");
533 handleError(type,
"$Prefix_const_not_allowed_for_clocks");
535 checkType(type[0],
true, inStruct);
541 handleError(type,
"$Prefix_meta_not_allowed_for_clocks");
543 checkType(type[0],
true, inStruct);
551 handleError(type,
"$Reference_to_this_type_not_allowed");
559 handleError(type,
"$Range_over_this_type_not_allowed");
566 handleError(l,
"$Integer_expected");
568 if (!isCompileTimeComputable(l))
570 handleError(l,
"$Must_be_computable_at_compile_time");
577 handleError(u,
"$Integer_expected");
579 if (!isCompileTimeComputable(u))
581 handleError(u,
"$Must_be_computable_at_compile_time");
590 handleError(type,
"$Invalid_array_size");
600 for (
size_t i = 0; i < type.
size(); i++)
602 checkType(type.
getSub(i),
true,
true);
609 handleError(type,
"$This_type_cannot_be_declared_inside_a_struct");
618 handleError(type,
"$This_type_cannot_be_declared_const_or_meta");
626 std::list<chan_priority_t>::const_iterator i;
627 for (i = list.begin(); i != list.end(); i++)
638 channel = channel.
getSub();
642 handleError(expr,
"$Channel_expected");
648 if (!isCompileTimeComputable(expr[1]))
650 handleError(expr[1],
"$Must_be_computable_at_compile_time");
652 else if (i->head.changesAnyVariable())
654 handleError(expr[1],
"$Index_must_be_side-effect_free");
660 chan_priority_t::tail_t::const_iterator j;
661 for (j = i->tail.begin(); j != i->tail.end(); ++j)
672 channel = channel.
getSub();
676 handleError(expr,
"$Channel_expected");
682 if (!isCompileTimeComputable(expr[1]))
684 handleError(expr[1],
"$Must_be_computable_at_compile_time");
686 else if (j->second.changesAnyVariable())
688 handleError(expr[1],
"$Index_must_be_side-effect_free");
703 handleError(e,
"$Clock_expected");
707 handleError(e,
"$Index_must_be_side-effect_free");
716 for(vector<expression_t>::iterator i = iodecl.
param.begin();
717 i != iodecl.
param.end(); ++i)
724 handleError(e,
"$Integer_expected");
726 else if (!isCompileTimeComputable(e))
728 handleError(e,
"$Must_be_computable_at_compile_time");
732 handleError(e,
"$Index_must_be_side-effect_free");
743 else if (!iodecl.
csp.empty())
750 if (!iodecl.
csp.empty())
764 handleError(iodecl.
csp.front(),
"$CSP_and_IO_synchronisations_cannot_be_mixed");
769 for(list<expression_t>::iterator i = iodecl.
inputs.begin();
770 i != iodecl.
inputs.end(); ++i)
774 type_t channel = i->getType();
780 channel = channel.
getSub();
784 handleError(expr,
"$Channel_expected");
790 if (!isCompileTimeComputable(expr[1]))
792 handleError(expr[1],
"$Must_be_computable_at_compile_time");
794 else if (i->changesAnyVariable())
796 handleError(expr[1],
"$Index_must_be_side-effect_free");
803 for(list<expression_t>::iterator i = iodecl.
outputs.begin();
804 i != iodecl.
outputs.end(); ++i)
808 type_t channel = i->getType();
814 channel = channel.
getSub();
818 handleError(expr,
"$Channel_expected");
824 if (!isCompileTimeComputable(expr[1]))
826 handleError(expr[1],
"$Must_be_computable_at_compile_time");
828 else if (i->changesAnyVariable())
830 handleError(expr[1],
"$Index_must_be_side-effect_free");
840 for (
size_t i = 0; i < process.
unbound; i++)
849 handleError(type,
"$Free_process_parameters_must_be_a_bounded_integer_or_a_scalar");
858 handleError(type,
"$Free_process_parameters_must_not_be_used_directly_or_indirectly_in_an_array_declaration_or_select_expression");
870 handleError (variable.
expr,
"Dynamic constructions cannot be used as initialisers");
874 if (!isCompileTimeComputable(variable.
expr))
876 handleError(variable.
expr,
"$Must_be_computable_at_compile_time");
880 handleError(variable.
expr,
"$Initialiser_must_be_side-effect_free");
899 std::string s =
"$Expression_of_type ";
901 s +=
" $cannot_be_used_as_an_invariant";
906 handleError(state.
invariant,
"$Invariant_must_be_side-effect_free");
910 RateDecomposer decomposer;
913 state.
costRate = decomposer.costRate;
914 if (decomposer.countCostRates > 1)
916 handleError(state.
invariant,
"$Only_one_cost_rate_is_allowed");
918 if (decomposer.hasClockRates)
922 if (decomposer.hasStrictInvariant)
926 handleWarning(state.
invariant,
"$Strict_invariant");
952 for (
size_t i = 0; i < select.
getSize(); i++)
954 checkType(select[i].getType());
958 bool strictBound =
false;
965 std::string s =
"$Expression_of_type ";
967 s +=
" $cannot_be_used_as_a_guard";
968 handleError(edge.
guard, s);
972 handleError(edge.
guard,
"$Guard_must_be_side-effect_free");
997 handleError(edge.
sync.
get(0),
"$Channel_expected");
1001 handleError(edge.
sync,
1002 "$Synchronisation_must_be_side-effect_free");
1006 bool hasClockGuard =
1008 bool isUrgent = channel.
is(
URGENT);
1012 if (isUrgent && hasClockGuard)
1015 handleWarning(edge.
sync,
1016 "$Clock_guards_are_not_allowed_on_urgent_edges");
1018 else if (receivesBroadcast && hasClockGuard)
1030 if (edge.
dst == NULL)
1032 handleWarning(edge.
sync,
1033 "SMC requires input edges to be deterministic");
1039 handleWarning(edge.
sync,
1040 "$It_may_be_needed_to_add_a_guard_involving_the_target_invariant");
1051 if (isUrgent && strictBound)
1053 handleWarning(edge.
guard,
1054 "$Strict_bounds_on_urgent_edges_may_not_make_sense");
1081 handleError(edge.
sync,
"$Assumed_IO_but_found_CSP_synchronization");
1091 handleError(edge.
sync,
"$Assumed_CSP_but_found_IO_synchronization");
1103 if (refinementWarnings)
1109 handleWarning(edge.
sync,
1110 "$Outputs_should_be_uncontrollable_for_refinement_checking");
1117 handleWarning(edge.
sync,
1118 "$Inputs_should_be_controllable_for_refinement_checking");
1123 handleWarning(edge.
sync,
1124 "$CSP_synchronisations_are_incompatible_with_refinement_checking");
1131 checkAssignmentExpression(edge.
assign);
1135 if (!edge.prob.empty())
1139 if (!isProbability(edge.prob))
1141 std::string s =
"$Expression_of_type ";
1142 s += edge.prob.getType().
toString();
1143 s +=
" $cannot_be_used_as_a_probability";
1144 handleError(edge.prob, s);
1146 else if (edge.prob.changesAnyVariable())
1148 handleError(edge.prob,
"$Probability_must_be_side-effect_free");
1169 handleError(message.
label.
get(0),
"$Channel_expected");
1173 handleError(message.
label,
1174 "$Message_must_be_side-effect_free");
1187 std::string s =
"$Expression_of_type ";
1189 s +=
" $cannot_be_used_as_a_condition";
1190 handleError(condition.
label, s);
1194 handleError(condition.
label,
"$Condition_must_be_side-effect_free");
1203 checkAssignmentExpression(update.
label);
1214 handleError(progress.
guard,
1215 "$Progress_guard_must_evaluate_to_a_boolean");
1221 "$Progress_measure_must_evaluate_to_a_value");
1228 for(
size_t i = 0; i < n; ++i)
1233 std::list<ganttmap_t>::const_iterator first, end = gc.
mapping.end();
1234 for(first = gc.
mapping.begin(); first != end; ++first)
1236 n = (*first).parameters.getSize();
1237 for(
size_t i = 0; i < n; ++i)
1239 checkType((*first).parameters[i].getType());
1246 handleError(p,
"$Boolean_expected");
1253 handleError(m,
"$Integer_expected");
1265 for (
size_t i = 0; i < type.
size(); i++)
1285 handleError(argument,
"$Argument_must_be_side-effect_free");
1296 bool computable = isCompileTimeComputable(argument);
1298 if ((!ref && !computable)
1299 || (ref && !constant && !isUniqueReference(argument))
1300 || (ref && constant && !computable))
1302 handleError(argument,
"$Incompatible_argument");
1306 checkParameterCompatible(parameter.
getType(), argument);
1340 for (uint32_t i = 0; i < expr.
getSize(); i++)
1352 for (uint32_t i = 0; i < expr.
getSize(); i++)
1366 handleError(expr,
"$Property_must_be_side-effect_free");
1371 handleError(expr,
"$Property_must_be_a_valid_formula");
1404 for (uint32_t i = 0; i < expr.
getSize(); i++)
1409 handleError(expr[i],
"$Nesting_of_path_quantifiers_is_not_allowed");
1418 checkObservationConstraints(expr);
1422 handleError(expr,
"MITL inside forall or exists in non-MITL property");
1444 bool TypeChecker::checkAssignmentExpression(
expression_t expr)
1453 handleError(expr,
"$Invalid_assignment_expression");
1459 checkIgnoredValue(expr);
1466 bool TypeChecker::checkConditionalExpressionInFunction(
expression_t expr)
1470 handleError(expr,
"$Boolean_expected");
1477 void TypeChecker::checkObservationConstraints(
expression_t expr)
1479 for(
size_t i = 0; i < expr.
getSize(); ++i)
1481 checkObservationConstraints(expr[i]);
1484 bool invalid =
false;
1509 handleError(expr,
"$Clock_lower_bound_must_be_weak_and_upper_bound_strict");
1525 handleError(expr,
"$Clock_differences_are_not_supported");
1542 for (
size_t i = 0; i < type.
size(); i++)
1573 checkType(return_type);
1576 handleError(return_type,
"$Invalid_return_type");
1603 for (list<variable_t>::iterator i = vars.begin(); i != vars.end(); i++)
1609 for (
size_t i = 0; i < parameters; i++)
1623 checkAssignmentExpression(stat->
expr);
1631 handleError(stat->
expr,
"$Assertion_must_be_side-effect_free");
1638 checkAssignmentExpression(stat->
init);
1642 checkConditionalExpressionInFunction(stat->
cond);
1645 checkAssignmentExpression(stat->
step);
1659 handleError(type,
"$Scalar_set_or_integer_expected");
1663 handleError(type,
"$Range_expected");
1673 checkConditionalExpressionInFunction(stat->
cond);
1682 checkConditionalExpressionInFunction(stat->
cond);
1693 for (uint32_t i = 0; i < frame.
getSize(); ++i)
1709 handleError(var->
expr,
"$Initialiser_must_be_side-effect_free");
1721 for (
auto* blockstatement : *stat)
1722 blockstatement->accept(
this);
1730 checkConditionalExpressionInFunction(stat->
cond);
1749 type_t return_type =
function->uid.getType()[0];
1750 checkParameterCompatible(return_type, stat->
value);
1814 bool ref = paramType.
is(
REF);
1816 bool lvalue = isModifiableLValue(arg);
1820 if (ref && !constant && !lvalue)
1829 else if (ref && lvalue)
1831 return areEquivalent(argType, paramType);
1835 return areAssignmentCompatible(paramType, argType);
1844 if (!isParameterCompatible(paramType, arg))
1846 handleError(arg,
"$Incompatible_argument");
1861 if (areAssignmentCompatible(type, init.
getType(),
true))
1869 for (uint32_t i = 0; i < init.
getType().
size(); i++)
1874 init[i],
"$Field_name_not_allowed_in_array_initialiser");
1876 result[i] = checkInitialiser(subtype, init[i]);
1887 int32_t current = 0;
1888 for (uint32_t i = 0; i < init.
getType().
size(); i++, current++)
1896 handleError(init[i],
"$Unknown_field");
1903 handleError(init[i],
"$Too_many_elements_in_initialiser");
1907 if (!result[current].empty())
1909 handleError(init[i],
"$Multiple_initialisers_for_field");
1913 result[current] = checkInitialiser(type.
getSub(current), init[i]);
1917 for (
size_t i = 0; i < result.size(); i++)
1919 if (result[i].empty())
1921 handleError(init,
"$Incomplete_initialiser");
1929 handleError(init,
"$Invalid_initialiser");
1939 bool TypeChecker::areInlineIfCompatible(
type_t t1,
type_t t2)
const 1947 return areEquivalent(t1, t2);
1956 bool TypeChecker::areEquivalent(
type_t a,
type_t b)
const 1983 for (
size_t i = 0; i < aSize; i++)
2030 bool TypeChecker::areAssignmentCompatible(
type_t lvalue,
type_t rvalue,
bool init)
const 2043 return areEquivalent(lvalue, rvalue);
2059 bool TypeChecker::areEqCompatible(
type_t t1,
type_t t2)
const 2071 return areEquivalent(t1, t2);
2086 for(uint32_t j = 0; j < expr.
getSize(); ++j)
2120 for (uint32_t i = 0; i < expr.
getSize(); i++)
2136 type_t type, arg1, arg2, arg3;
2168 handleError (expr,
"A sum can only be made over integer, double, invariant or guard expressions.");
2298 handleError(expr,
"Appears as an attempt to spawn a non-dynamic template");
2302 handleError(expr,
"Wrong number of arguments");
2315 handleError (expr,
"Template is only declared - not defined");
2329 handleError (expr,
"Not a dynamic template");
2339 handleError (expr,
"Exit can only be used in templates declared as dynamic");
2359 else if (areEqCompatible(expr[0].getType(), expr[1].getType()))
2363 else if ((expr[0].getType().is(
RATE) &&
2366 expr[1].getType().is(
RATE)))
2377 if (areEqCompatible(expr[0].getType(), expr[1].getType()))
2478 if (!areAssignmentCompatible(expr[0].getType(), expr[1].getType()))
2480 handleError(expr,
"$Incompatible_types");
2483 else if (!isModifiableLValue(expr[0]))
2485 handleError(expr[0],
"$Left_hand_side_value_expected");
2494 handleError(expr,
"$Increment_operator_can_only_be_used_for_integers_and_cost_variables");
2496 else if (!isModifiableLValue(expr[0]))
2498 handleError(expr[0],
"$Left_hand_side_value_expected");
2514 handleError(expr,
"$Non-integer_types_must_use_regular_assignment_operator");
2517 else if (!isModifiableLValue(expr[0]))
2519 handleError(expr[0],
"$Left_hand_side_value_expected");
2529 if (!isModifiableLValue(expr[0]))
2531 handleError(expr[0],
"$Left_hand_side_value_expected");
2536 handleError(expr,
"$Integer_expected");
2546 handleError(expr[2],
"$Number_expected");
2565 handleError(expr[1],
"$Number_expected");
2604 handleError(expr[0],
"$Number_expected");
2613 handleError(expr[1],
"$Integer_expected");
2618 handleError(expr[0],
"$Number_expected");
2628 handleError(expr[0],
"$Integer_expected");
2638 handleError(expr[0],
"$Number_expected");
2652 handleError(expr[0],
"$Number_expected");
2661 handleError(expr,
"$First_argument_of_inline_if_must_be_an_integer");
2664 if (!areInlineIfCompatible(expr[1].getType(), expr[2].getType()))
2666 handleError(expr,
"$Incompatible_arguments_to_inline_if");
2675 handleError(expr[0],
"$Incompatible_type_for_comma_expression");
2680 handleError(expr[1],
"$Incompatible_type_for_comma_expression");
2683 checkIgnoredValue(expr[0]);
2693 size_t parameters = type.
size() - 1;
2694 for (uint32_t i = 0; i < parameters; i++)
2696 type_t parameter = type[i + 1];
2698 result &= checkParameterCompatible(parameter, argument);
2711 handleError(expr[0],
"$Array_expected");
2726 handleError(expr[1],
"$Incompatible_type");
2732 handleError(expr[1],
"$Incompatible_type");
2738 checkType(expr[0].getSymbol().getType());
2762 handleError(expr[1],
"$Boolean_expected");
2765 if (expr[1].changesAnyVariable())
2767 handleError(expr[1],
"$Expression_must_be_side-effect_free");
2772 checkType(expr[0].getSymbol().getType());
2784 handleError(expr[1],
"$Boolean_expected");
2787 if (expr[1].changesAnyVariable())
2789 handleError(expr[1],
"$Expression_must_be_side-effect_free");
2794 checkType(expr[0].getSymbol().getType());
2806 handleError(expr[1],
"$Number_expected");
2809 if (expr[1].changesAnyVariable())
2811 handleError(expr[1],
"$Expression_must_be_side-effect_free");
2843 handleError(expr[0],
"$Composition_of_processes_expected");
2848 handleError(expr[1],
"$List_of_channels_expected");
2866 handleError(e1,
"$Composition_of_processes_expected");
2871 handleError(e2,
"$Composition_of_processes_expected");
2885 handleError(expr[0],
"$Process_expression_expected");
2890 handleError(expr[1],
"$Process_expression_expected");
2903 handleError(expr[0],
"$Process_expression_expected");
2908 handleError(expr[1],
"$Property_must_be_a_valid_formula");
2922 handleError(expr[0],
"$Process_expression_expected");
2931 for(uint32_t i = 0; i < expr.
getSize(); ++i)
2935 handleError(expr[i],
"$Process_expression_expected");
2950 handleError(expr[0],
"$Process_expression_expected");
2955 handleError(expr[0],
"$Process_expression_expected");
2984 ok &= checkNrOfRuns(expr[0]);
2985 if (ok && expr[0].getValue() <= 0)
2987 handleError(expr[0],
"$Invalid_run_count");
2990 ok &= checkBoundTypeOrBoundedExpr(expr[1]);
2991 ok &= checkBound(expr[2]);
2999 ok &= checkPredicate(expr[nb]);
3000 ok &= checkNrOfRuns(expr[nb+1]);
3004 for (
int i = 3; i < nb; ++i)
3005 if (!checkMonitoredExpr(expr[i]))
3016 handleError(expr[0],
"$Boolean_expected");
3019 if (expr[1].getKind() ==
LIST)
3021 for(uint32_t i = 0; i < expr[1].
getSize(); ++i)
3025 if (expr[1][i].changesAnyVariable())
3027 handleError(expr[1][i],
"$Expression_must_be_side-effect_free");
3031 else if (!
isClock(expr[1][i]))
3033 handleError(expr[1][i],
"$Type_error");
3054 ok &= checkBoundTypeOrBoundedExpr(expr[0]);
3055 ok &= checkBound(expr[1]);
3069 ok &= checkNrOfRuns(expr[0]);
3070 if (ok && expr[0].getValue() > 0)
3072 handleError(expr[0],
"Explicit number of runs is not supported here");
3075 ok &= checkBoundTypeOrBoundedExpr(expr[1]);
3076 ok &= checkBound(expr[2]);
3077 ok &= checkPredicate(expr[3]);
3078 ok &= checkProbBound(expr[4]);
3083 handleError(expr,
"Bug: wrong number of arguments");
3093 ok &= checkNrOfRuns(expr[0]);
3094 ok &= checkBoundTypeOrBoundedExpr(expr[1]);
3095 ok &= checkBound(expr[2]);
3096 ok &= checkPredicate(expr[3]);
3097 ok &= checkUntilCond(expr.
getKind(), expr[4]);
3102 handleError(expr,
"Bug: wrong number of arguments");
3112 ok &= checkBoundTypeOrBoundedExpr(expr[0]);
3113 ok &= checkBound(expr[1]);
3114 ok &= checkPathQuant(expr[2]);
3115 ok &= checkPredicate(expr[3]);
3117 ok &= checkBoundTypeOrBoundedExpr(expr[4]);
3118 ok &= checkBound(expr[5]);
3119 ok &= checkPathQuant(expr[6]);
3120 ok &= checkPredicate(expr[7]);
3125 handleError(expr,
"Bug: wrong number of arguments");
3134 ok &= checkNrOfRuns(expr[0]);
3135 ok &= checkBoundTypeOrBoundedExpr(expr[1]);
3136 ok &= checkBound(expr[2]);
3137 ok &= checkAggregationOp(expr[3]);
3138 ok &= checkMonitoredExpr(expr[4]);
3143 handleError(expr,
"Bug: wrong number of arguments");
3154 handleError(expr,
"$Type_error");
3167 bool TypeChecker::isModifiableLValue(
expression_t expr)
const 3180 if (expr[0].getType().isProcess())
3185 return isModifiableLValue(expr[0]);
3188 return isModifiableLValue(expr[0]);
3206 return isModifiableLValue(expr[1]) && isModifiableLValue(expr[2])
3207 && areEquivalent(expr[1].getType(), expr[2].getType());
3210 return isModifiableLValue(expr[1]);
3246 return isLValue(expr[0]);
3249 return isLValue(expr[1]) && isLValue(expr[2])
3250 && areEquivalent(expr[1].getType(), expr[2].getType());
3253 return isLValue(expr[1]);
3269 bool TypeChecker::isUniqueReference(
expression_t expr)
const 3277 return isUniqueReference(expr[0]);
3280 return isUniqueReference(expr[0])
3281 && isCompileTimeComputable(expr[1]);
3296 return isUniqueReference(expr[0]);
3302 return isUniqueReference(expr[1]);
3327 parseXTA(buffer, &builder, newxta);
3407 return checkParameterCompatible(param,arg);
3412 std::list<expression_t> l;
3419 handleError(it,
"Dynamic constructs are only allowed on edges!");
3424 bool TypeChecker::checkNrOfRuns(
const expression_t& runs)
3426 if (!isCompileTimeComputable(runs))
3428 handleError(runs,
"$Must_be_computable_at_compile_time");
3433 handleError(runs,
"$Integer_expected");
3439 bool TypeChecker::checkBoundTypeOrBoundedExpr(
const expression_t& boundTypeOrExpr)
3443 handleError(boundTypeOrExpr,
"$Clock_expected");
3449 bool TypeChecker::checkBound(
const expression_t& bound)
3451 if (!isCompileTimeComputable(bound))
3453 handleError(bound,
"$Must_be_computable_at_compile_time");
3458 handleError(bound,
"$Integer_expected");
3464 bool TypeChecker::checkPredicate(
const expression_t& predicate)
3468 handleError(predicate,
"$Boolean_expected");
3473 handleError(predicate,
"$Property_must_be_side-effect_free");
3479 bool TypeChecker::checkProbBound(
const expression_t& probBound)
3483 handleError(probBound,
"Floating point number expected as probability bound");
3494 handleError(untilCond,
"$Boolean_expected");
3500 handleError(untilCond,
"Must be false");
3506 bool TypeChecker::checkMonitoredExpr(
const expression_t& expr)
3512 handleError(expr,
"$Integer_or_clock_expected");
3517 handleError(expr,
"$Property_must_be_side-effect_free");
3523 bool TypeChecker::checkPathQuant(
const expression_t& expr)
3527 handleError(expr,
"Bug: bad path quantifier");
3533 bool TypeChecker::checkAggregationOp(
const expression_t& expr)
3537 handleError(expr,
"Bug: bad aggregation operator expression");
3542 handleError(expr,
"Bug: bad aggregation operator value");
symbol_t uid
The symbol of the variables.
void recordStrictInvariant()
Record that the system has some strict invariant.
static bool hasStrictLowerBound(expression_t expr)
bool isRange() const
Shortcut for is(RANGE).
static bool isClock(expression_t expr)
Constants::kind_t getKind() const
Returns the kind of the expression.
Partial instance of a template.
static bool isFormula(expression_t expr)
bool isClock() const
Shortcut for is(CLOCK).
void recordStopWatch()
Record that the system stops a clock.
static bool isInvariant(expression_t expr)
std::list< variable_t > variables
Local variables.
void visitUpdate(update_t &) override
static bool isCost(expression_t expr)
std::list< ganttmap_t > mapping
expression_t label
The label.
static bool isIntegral(expression_t expr)
int32_t parseXMLFile(const char *file, TimedAutomataSystem *system, bool newxta)
bool unknown() const
Returns true if this is null-type or of kind UNKNOWN.
bool empty() const
Returns true if this is an empty expression.
static bool hasMITLInQuantifiedSub(expression_t expr)
static int channelCapability(type_t type)
Returns a value indicating the capabilities of a channel.
std::set< symbol_t > restricted
Restricted variables.
bool isVoid() const
Shortcut for is(VOID_TYPE).
bool isIntegral() const
Returns true if this is a boolean or integer.
void visitProgressMeasure(progress_t &) override
virtual void visitInstanceLine(instanceLine_t &)
uint32_t getSize() const
Returns the number of symbols in this frame.
int32_t visitEmptyStatement(EmptyStatement *stat) override
std::set< symbol_t > changes
Variables changed by this function.
virtual void visitProperty(expression_t)
bool control
Controllable (true/false)
void visitInstance(instance_t &) override
void visitGanttChart(gantt_t &) override
bool isInvariant() const
Returns true if this is an invariant, boolean or integer.
bool checkExpression(expression_t)
Type check an expression.
Information about a location.
bool isInteger() const
Shortcut for is(INT).
expression_t label
The label.
expression_t guard
The guard.
static expression_t createNary(Constants::kind_t, const std::vector< expression_t > &, position_t=position_t(), type_t=type_t())
Create an n-ary expression.
void visitIODecl(iodecl_t &) override
A visitor which type checks the system it visits.
static bool isDouble(expression_t expr)
expression_t getAfterUpdate()
expression_t sync
The synchronisation.
This class constructs a TimedAutomataSystem.
void setSyncUsed(sync_use_t s)
void addError(position_t, const std::string &msg, const std::string &ctx="")
std::list< expression_t > outputs
int32_t visitReturnStatement(ReturnStatement *stat) override
void addWarning(position_t, const std::string &msg, const std::string &ctx="")
static bool validReturnType(type_t type)
frame_t parameters
The parameters.
static bool isConstantDouble(expression_t expr)
static type_t createPrimitive(Constants::kind_t, position_t=position_t())
Create a primitive type.
virtual void visitUpdate(update_t &)
static bool isListOfFormulas(expression_t expr)
static bool isInvariantWR(expression_t expr)
Returns true iff type is a valid invariant.
void visitCondition(condition_t &) override
Information about an edge.
expression_t exponentialRate
Statement class for the iterator loop-construction.
static vector< string > variables
std::vector< expression_t > param
bool isArray() const
Shortcut for is(ARRAY).
Information about an update.
std::string toString() const
Generates string representation of the type.
virtual void visitFunction(function_t &)
ExpressionFragments & getExpressions()
virtual void visitVariable(variable_t &)
expression_t assign
The assignment.
std::pair< expression_t, expression_t > getRange() const
Returns the range of a RANGE type.
static bool hasStrictUpperBound(expression_t expr)
bool visitTemplateBefore(template_t &) override
state_t * dst
Pointer to destination location.
static bool isDiff(expression_t expr)
std::set< symbol_t > depends
Variables the function depends on.
Partial implementation of the builder interface: The ExpressionBuilder implements all expression rela...
void visitVariable(variable_t &) override
std::list< expression_t > inputs
Information about an instance line.
bool checkDynamicExpressions(Statement *stat)
const std::string & getLabel(uint32_t) const
Returns the i'th label.
virtual void visitMessage(message_t &)
virtual void visitInstance(instance_t &)
expression_t & get(uint32_t)
Returns the ith subexpression.
expression_t label
The label.
bool isFormula() const
Returns true if this is a formula, constraint, guard, invariant, boolean or integer.
expression_t invariant
The invariant.
const position_t & getPosition() const
Returns the position of this expression.
bool isConstant() const
Returns true if and only if all elements of the type are constant.
bool isConstraint() const
Returns true if this is a constraint, guard, invariant, boolean or integer.
static bool isBound(expression_t expr)
bool checkSpawnParameterCompatible(type_t param, expression_t arg)
template_t * getDynamicTemplate(const std::string &name)
void recordStrictLowerBoundOnControllableEdges()
Record that the system has guards on controllable edges with strict lower bounds. ...
int32_t visitAssertStatement(AssertStatement *stat) override
bool parseXTA(FILE *file, TimedAutomataSystem *system, bool newxta)
Base type for variables, clocks, etc.
type_t stripArray() const
Removes any leading prefixes, RANGE, REF, LABEL and ARRAY types and returns the result.
type_t getSub() const
Returns the element type of an array.
virtual void visitHybridClock(expression_t)
static string symbol(const char *str)
Extracts the alpha-numerical symbol used for variable/type identifiers.
int32_t visitIfStatement(IfStatement *stat) override
static bool isGameProperty(expression_t expr)
bool isDiff() const
Shortcut for is(DIFF).
static bool isVoid(expression_t expr)
static bool isGuard(expression_t expr)
static bool isInteger(expression_t expr)
int32_t visitBlockStatement(BlockStatement *stat) override
void visitMessage(message_t &) override
TypeChecker(TimedAutomataSystem *system, bool refinement=false)
int32_t visitExprStatement(ExprStatement *stat) override
void visitEdge(edge_t &) override
bool isNonConstant() const
Returns true if and only if all elements of the type are not constant.
static bool isProcessID(expression_t expr)
void setUrgentTransition()
void clockGuardRecvBroadcast()
virtual void visitEdge(edge_t &)
int32_t visitDoWhileStatement(DoWhileStatement *stat) override
int32_t accept(StatementVisitor *visitor) override
static bool isConstraint(expression_t expr)
expression_t expr
The initialiser.
void visitState(state_t &) override
std::map< symbol_t, expression_t > mapping
The arguments.
type_t getType() const
Returns the type of this symbol.
std::list< expression_t > csp
bool isGuard() const
Returns true if this is a guard, invariant, boolean or integer.
bool isBoolean() const
Shortcut for is(BOOL).
int32_t visitIterationStatement(IterationStatement *stat) override
size_t size() const
Returns the number of children.
symbol_t uid
The symbol of the function.
int32_t visitForStatement(ForStatement *stat) override
frame_t select
Frame for non-deterministic select.
void visitInstance(instance_t &) override
Information about a message.
int32_t findIndexOf(const std::string &) const
Returns the index of the record or process field with the given label.
std::string getRecordLabel(size_t i) const
Returns the label of the 'th field of a record.
void visitFunction(function_t &) override
BlockStatement * body
Pointer to the block.
void accept(SystemVisitor &)
A reference to an expression.
static bool initialisable(type_t type)
void visitSystemAfter(TimedAutomataSystem *) override
bool hasDynamicSub() const
Information about a function.
type_t getArraySize() const
Returns the size of an array (this is itself a type).
static bool isDoubleValue(expression_t expr)
void visitProcess(instance_t &) override
type_t getType() const
Returns the type of the expression.
int32_t parseXMLBuffer(const char *buffer, TimedAutomataSystem *system, bool newxta)
void * getData()
Returns the user data of this symbol.
virtual int32_t accept(StatementVisitor *visitor)=0
static bool isNumber(expression_t expr)
void visitTemplateAfter(template_t &) override
frame_t parameters
The select parameters.
bool contains(symbol_t) const
int32_t getValue() const
Returns the value field of this expression.
int32_t visitWhileStatement(WhileStatement *stat) override
void visitInstanceLine(instanceLine_t &) override
size_t getSize() const
Returns the number of subexpression.
expression_t getBeforeUpdate()
static bool isAssignable(type_t type)
Returns true if values of this type can be assigned.
bool is(Constants::kind_t kind) const
Returns true if the type has kind kind or if type is a prefix, RANGE or REF type and the getChild()...
bool isLocation() const
Shortcut for is(LOCATION).
static bool isSameScalarType(type_t t1, type_t t2)
Returns true if two scalar types are name-equivalent.
void visitVariable(variable_t &) override
static expression_t createConstant(int32_t, position_t=position_t())
Create a CONSTANT expression.
void setType(type_t)
Sets the type of the expression.
bool isScalar() const
Shortcut for is(SCALAR).
Constants::synchronisation_t getSync() const
Returns the synchronisation type of SYNC operations.
static expression_t createBinary(Constants::kind_t, expression_t, expression_t, position_t=position_t(), type_t=type_t())
Create a binary expression.
expression_t parseExpression(const char *str, TimedAutomataSystem *system, bool newxtr)
void collectPossibleReads(std::set< symbol_t > &, bool collectRandom=false) const
const std::list< chan_priority_t > & getChanPriorities() const
static bool checkIDList(expression_t expr, kind_t kind)
virtual void visitState(state_t &)
bool isDouble() const
Shortcut for is(DOUBLE).
expression_t costRate
Rate expression.
Information about a condition.
static bool hasSpawnOrExit(expression_t expr)
bool isRecord() const
Shortcut for is(RECORD).
Constants::kind_t getKind() const
Returns the kind of type object.
bool isChannel() const
Shortcut for is(CHANNEL).
static bool isConstantInteger(expression_t expr)
std::string toString() const
virtual void visitCondition(condition_t &)
size_t getRecordSize() const
Returns the number of fields of a record.
bool changesAnyVariable() const
True if this expression can change any variable at all.