1254 std::set<storm::expressions::Variable> all;
1255 std::set<storm::expressions::Variable> allGlobals;
1256 std::set<storm::expressions::Variable> globalVariables;
1257 std::set<storm::expressions::Variable> constants;
1260 if (constant.isDefined()) {
1261 std::set<storm::expressions::Variable> containedVariables = constant.getExpression().getVariables();
1262 std::set<storm::expressions::Variable> illegalVariables;
1263 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1264 std::inserter(illegalVariables, illegalVariables.begin()));
1265 bool isValid = illegalVariables.empty();
1268 std::vector<std::string> illegalVariableNames;
1269 for (
auto const& var : illegalVariables) {
1270 illegalVariableNames.push_back(var.getName());
1273 "Error in " << constant.getFilename() <<
", line " << constant.getLineNumber()
1274 <<
": defining expression refers to unknown identifiers: " << boost::algorithm::join(illegalVariableNames,
",")
1280 constants.insert(constant.getExpressionVariable());
1281 all.insert(constant.getExpressionVariable());
1282 allGlobals.insert(constant.getExpressionVariable());
1286 std::set<storm::expressions::Variable> variables;
1288 if (variable.hasInitialValue()) {
1290 "Error for " << variable.getName() <<
" (" << variable.getFilename() <<
", line " << variable.getLineNumber()
1291 <<
"): illegal to specify initial value if an initial construct is present.");
1294 std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
1295 std::set<storm::expressions::Variable> illegalVariables;
1296 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1297 std::inserter(illegalVariables, illegalVariables.begin()));
1298 bool isValid = illegalVariables.empty();
1301 std::vector<std::string> illegalVariableNames;
1302 for (
auto const& var : illegalVariables) {
1303 illegalVariableNames.push_back(var.getName());
1306 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1307 <<
": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1313 variables.insert(variable.getExpressionVariable());
1314 all.insert(variable.getExpressionVariable());
1315 allGlobals.insert(variable.getExpressionVariable());
1316 globalVariables.insert(variable.getExpressionVariable());
1320 if (variable.hasLowerBoundExpression()) {
1321 std::set<storm::expressions::Variable> containedVariables = variable.getLowerBoundExpression().getVariables();
1322 std::set<storm::expressions::Variable> illegalVariables;
1323 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1324 std::inserter(illegalVariables, illegalVariables.begin()));
1325 bool isValid = illegalVariables.empty();
1328 std::vector<std::string> illegalVariableNames;
1329 for (
auto const& var : illegalVariables) {
1330 illegalVariableNames.push_back(var.getName());
1333 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1334 <<
": lower bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1339 if (variable.hasUpperBoundExpression()) {
1340 std::set<storm::expressions::Variable> containedVariables = variable.getUpperBoundExpression().getVariables();
1341 std::set<storm::expressions::Variable> illegalVariables;
1342 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1343 std::inserter(illegalVariables, illegalVariables.begin()));
1344 bool isValid = illegalVariables.empty();
1346 std::vector<std::string> illegalVariableNames;
1347 for (
auto const& var : illegalVariables) {
1348 illegalVariableNames.push_back(var.getName());
1351 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1352 <<
": upper bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1357 if (variable.hasInitialValue()) {
1359 "Error for " << variable.getName() <<
" (" << variable.getFilename() <<
", line " << variable.getLineNumber()
1360 <<
"): illegal to specify initial value if an initial construct is present.");
1363 std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
1364 std::set<storm::expressions::Variable> illegalVariables;
1365 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1366 std::inserter(illegalVariables, illegalVariables.begin()));
1367 bool isValid = illegalVariables.empty();
1369 std::vector<std::string> illegalVariableNames;
1370 for (
auto const& var : illegalVariables) {
1371 illegalVariableNames.push_back(var.getName());
1374 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1375 <<
": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1381 variables.insert(variable.getExpressionVariable());
1382 all.insert(variable.getExpressionVariable());
1383 allGlobals.insert(variable.getExpressionVariable());
1384 globalVariables.insert(variable.getExpressionVariable());
1388 for (
auto const& module : this->
getModules()) {
1389 for (
auto const& variable : module.getBooleanVariables()) {
1390 if (variable.hasInitialValue()) {
1392 "Error for " << module.getName() <<
"." << variable.getName() <<
" (" << variable.getFilename() <<
", line "
1393 << variable.getLineNumber() <<
"): illegal to specify initial value if an initial construct is present.");
1396 std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
1397 std::set<storm::expressions::Variable> illegalVariables;
1398 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1399 std::inserter(illegalVariables, illegalVariables.begin()));
1400 bool isValid = illegalVariables.empty();
1402 std::vector<std::string> illegalVariableNames;
1403 for (
auto const& var : illegalVariables) {
1404 illegalVariableNames.push_back(var.getName());
1407 isValid, storm::exceptions::WrongFormatException,
1408 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1409 <<
": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1414 variables.insert(variable.getExpressionVariable());
1415 all.insert(variable.getExpressionVariable());
1417 for (
auto const& variable : module.getIntegerVariables()) {
1419 if (variable.hasLowerBoundExpression()) {
1420 std::set<storm::expressions::Variable> containedVariables = variable.getLowerBoundExpression().getVariables();
1421 std::set<storm::expressions::Variable> illegalVariables;
1422 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1423 std::inserter(illegalVariables, illegalVariables.begin()));
1424 bool isValid = illegalVariables.empty();
1426 std::vector<std::string> illegalVariableNames;
1427 for (
auto const& var : illegalVariables) {
1428 illegalVariableNames.push_back(var.getName());
1431 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1432 <<
": lower bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1437 if (variable.hasUpperBoundExpression()) {
1438 std::set<storm::expressions::Variable> containedVariables = variable.getUpperBoundExpression().getVariables();
1439 std::set<storm::expressions::Variable> illegalVariables;
1441 illegalVariables.clear();
1442 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1443 std::inserter(illegalVariables, illegalVariables.begin()));
1444 bool isValid = illegalVariables.empty();
1446 std::vector<std::string> illegalVariableNames;
1447 for (
auto const& var : illegalVariables) {
1448 illegalVariableNames.push_back(var.getName());
1451 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1452 <<
": upper bound expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",")
1457 if (variable.hasInitialValue()) {
1459 "Error for " << module.getName() <<
"." << variable.getName() <<
" (" << variable.getFilename() <<
", line "
1460 << variable.getLineNumber() <<
"): illegal to specify initial value if an initial construct is present.");
1463 std::set<storm::expressions::Variable> containedVariables = variable.getInitialValueExpression().getVariables();
1464 std::set<storm::expressions::Variable> illegalVariables;
1465 illegalVariables.clear();
1466 std::set_difference(containedVariables.begin(), containedVariables.end(), constants.begin(), constants.end(),
1467 std::inserter(illegalVariables, illegalVariables.begin()));
1468 bool isValid = illegalVariables.empty();
1470 std::vector<std::string> illegalVariableNames;
1471 for (
auto const& var : illegalVariables) {
1472 illegalVariableNames.push_back(var.getName());
1475 isValid, storm::exceptions::WrongFormatException,
1476 "Error in " << variable.getFilename() <<
", line " << variable.getLineNumber()
1477 <<
": initial value expression refers to unknown constants: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1482 variables.insert(variable.getExpressionVariable());
1483 all.insert(variable.getExpressionVariable());
1486 for (
auto const& variable : module.getClockVariables()) {
1488 variables.insert(variable.getExpressionVariable());
1489 all.insert(variable.getExpressionVariable());
1494 std::set<storm::expressions::Variable> variablesAndConstants;
1495 std::set_union(variables.begin(), variables.end(), constants.begin(), constants.end(), std::inserter(variablesAndConstants, variablesAndConstants.begin()));
1499 std::set<storm::expressions::Variable> containedVariables = formula.getExpression().getVariables();
1500 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1502 "Error in " << formula.getFilename() <<
", line " << formula.getLineNumber() <<
": expression '" << formula.getExpression()
1503 <<
"'of formula '" << formula.getName() <<
"' refers to unknown identifiers.");
1504 if (formula.hasExpressionVariable()) {
1505 all.insert(formula.getExpressionVariable());
1506 variablesAndConstants.insert(formula.getExpressionVariable());
1511 bool hasProbabilisticCommand =
false;
1512 bool hasMarkovianCommand =
false;
1513 bool hasLabeledMarkovianCommand =
false;
1514 std::map<std::pair<storm::expressions::Variable, uint64_t>, std::pair<uint64_t, std::string>> writtenGlobalVariables;
1515 for (
auto const& module : this->
getModules()) {
1516 std::set<storm::expressions::Variable> legalVariables = globalVariables;
1517 for (
auto const& variable : module.getBooleanVariables()) {
1518 legalVariables.insert(variable.getExpressionVariable());
1520 for (
auto const& variable : module.getIntegerVariables()) {
1521 legalVariables.insert(variable.getExpressionVariable());
1523 for (
auto const& variable : module.getClockVariables()) {
1524 legalVariables.insert(variable.getExpressionVariable());
1527 if (module.hasInvariant()) {
1528 std::set<storm::expressions::Variable> containedVariables =
module.getInvariant().getVariables();
1529 std::set<storm::expressions::Variable> illegalVariables;
1530 std::set_difference(containedVariables.begin(), containedVariables.end(), variablesAndConstants.begin(), variablesAndConstants.end(),
1531 std::inserter(illegalVariables, illegalVariables.begin()));
1532 bool isValid = illegalVariables.empty();
1534 std::vector<std::string> illegalVariableNames;
1535 for (
auto const& var : illegalVariables) {
1536 illegalVariableNames.push_back(var.getName());
1539 "Error in " << module.getFilename() <<
", line " << module.getLineNumber() <<
": invariant " << module.getInvariant()
1540 <<
" refers to unknown identifiers: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1542 STORM_LOG_THROW(module.getInvariant().hasBooleanType(), storm::exceptions::WrongFormatException,
1543 "Error in " << module.getFilename() <<
", line " << module.getLineNumber() <<
": invariant " << module.getInvariant()
1544 <<
" must evaluate to type 'bool'.");
1547 for (
auto& command : module.getCommands()) {
1549 std::set<storm::expressions::Variable> containedVariables = command.getGuardExpression().getVariables();
1550 std::set<storm::expressions::Variable> illegalVariables;
1551 std::set_difference(containedVariables.begin(), containedVariables.end(), variablesAndConstants.begin(), variablesAndConstants.end(),
1552 std::inserter(illegalVariables, illegalVariables.begin()));
1553 bool isValid = illegalVariables.empty();
1555 std::vector<std::string> illegalVariableNames;
1556 for (
auto const& var : illegalVariables) {
1557 illegalVariableNames.push_back(var.getName());
1560 "Error in " << command.getFilename() <<
", line " << command.getLineNumber() <<
": guard " << command.getGuardExpression()
1561 <<
" refers to unknown identifiers: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1564 command.getGuardExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1565 "Error in " << command.getFilename() <<
", line " << command.getLineNumber() <<
": expression for guard must evaluate to type 'bool'.");
1568 if (command.isMarkovian()) {
1569 hasMarkovianCommand =
true;
1571 hasProbabilisticCommand =
true;
1576 if (command.isMarkovian() && command.isLabeled()) {
1577 hasLabeledMarkovianCommand =
true;
1581 for (
auto const& update : command.getUpdates()) {
1582 containedVariables.clear();
1583 if (update.isLikelihoodInterval()) {
1584 update.getLikelihoodExpressionInterval().first.gatherVariables(containedVariables);
1585 update.getLikelihoodExpressionInterval().second.gatherVariables(containedVariables);
1587 update.getLikelihoodExpression().gatherVariables(containedVariables);
1589 illegalVariables.clear();
1590 std::set_difference(containedVariables.begin(), containedVariables.end(), variablesAndConstants.begin(), variablesAndConstants.end(),
1591 std::inserter(illegalVariables, illegalVariables.begin()));
1592 isValid = illegalVariables.empty();
1594 std::vector<std::string> illegalVariableNames;
1595 for (
auto const& var : illegalVariables) {
1596 illegalVariableNames.push_back(var.getName());
1599 isValid, storm::exceptions::WrongFormatException,
1600 "Error in " << command.getFilename() <<
", line " << command.getLineNumber()
1601 <<
": likelihood expression refers to unknown identifiers: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1605 std::set<storm::expressions::Variable> alreadyAssignedVariables;
1606 for (
auto const& assignment : update.getAssignments()) {
1609 if (legalVariables.find(assignedVariable) == legalVariables.end()) {
1610 if (all.find(assignedVariable) != all.end()) {
1612 "Error in " << command.getFilename() <<
", line " << command.getLineNumber()
1613 <<
": assignment illegally refers to variable '" << assignment.getVariableName() <<
"'.");
1616 "Error in " << command.getFilename() <<
", line " << command.getLineNumber()
1617 <<
": assignment refers to unknown variable '" << assignment.getVariableName() <<
"'.");
1620 STORM_LOG_THROW(alreadyAssignedVariables.find(assignedVariable) == alreadyAssignedVariables.end(), storm::exceptions::WrongFormatException,
1621 "Error in " << command.getFilename() <<
", line " << command.getLineNumber() <<
": duplicate assignment to variable '"
1622 << assignment.getVariableName() <<
"'.");
1624 (assignedVariable.
getType().
isRationalType() && assignment.getExpression().getType().isNumericalType()),
1625 storm::exceptions::WrongFormatException,
1626 "Error in " << command.getFilename() <<
", line " << command.getLineNumber() <<
": illegally assigning a value of type '"
1627 << assignment.getExpression().getType() <<
"' to variable '" << assignment.getVariableName() <<
"' of type '"
1628 << assignedVariable.
getType() <<
"'.");
1630 if (command.isLabeled() && globalVariables.find(assignedVariable) != globalVariables.end()) {
1631 std::pair<storm::expressions::Variable, uint64_t> variableActionIndexPair(assignedVariable, command.getActionIndex());
1632 std::pair<uint64_t, std::string> lineModuleNamePair(command.getLineNumber(), module.getName());
1633 auto insertionResult = writtenGlobalVariables.emplace(variableActionIndexPair, lineModuleNamePair);
1635 insertionResult.second || insertionResult.first->second.second == module.getName(), storm::exceptions::WrongFormatException,
1636 "Error in " << command.getFilename() <<
", line " << command.getLineNumber() <<
": Syncronizing command with action label '"
1637 << command.getActionName() <<
"' illegally assigns a value to global variable '" << assignedVariable.
getName()
1638 <<
"'. Previous assignment to the variable at line " << insertionResult.first->second.first <<
" in module '"
1639 << insertionResult.first->second.second <<
"'.");
1642 containedVariables = assignment.getExpression().getVariables();
1643 illegalVariables.clear();
1644 std::set_difference(containedVariables.begin(), containedVariables.end(), variablesAndConstants.begin(), variablesAndConstants.end(),
1645 std::inserter(illegalVariables, illegalVariables.begin()));
1646 isValid = illegalVariables.empty();
1648 std::vector<std::string> illegalVariableNames;
1649 for (
auto const& var : illegalVariables) {
1650 illegalVariableNames.push_back(var.getName());
1653 isValid, storm::exceptions::WrongFormatException,
1654 "Error in " << command.getFilename() <<
", line " << command.getLineNumber()
1655 <<
": assigned expression refers to unknown identifiers: " << boost::algorithm::join(illegalVariableNames,
",") <<
".");
1659 alreadyAssignedVariables.insert(assignedVariable);
1665 if (hasLabeledMarkovianCommand) {
1666 if (prismCompatibility) {
1668 false,
"The model uses synchronizing Markovian commands. This may lead to unexpected verification results, because of unclear semantics.");
1671 "The model uses synchronizing Markovian commands. This may lead to unexpected verification results, because of unclear semantics.");
1676 STORM_LOG_THROW(!hasMarkovianCommand, storm::exceptions::WrongFormatException,
"Discrete-time model must not have Markovian commands.");
1678 STORM_LOG_THROW(!hasProbabilisticCommand, storm::exceptions::WrongFormatException,
1679 "The input model is a CTMC, but uses probabilistic commands like they are used in PRISM. Please use Markovian commands instead or turn "
1680 "on the PRISM compatibility mode using the flag '-pc'.");
1685 for (
auto const& stateReward : rewardModel.getStateRewards()) {
1686 std::set<storm::expressions::Variable> containedVariables = stateReward.getStatePredicateExpression().getVariables();
1687 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1689 "Error in " << stateReward.getFilename() <<
", line " << stateReward.getLineNumber()
1690 <<
": state reward expression refers to unknown identifiers.");
1692 stateReward.getStatePredicateExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1693 "Error in " << stateReward.getFilename() <<
", line " << stateReward.getLineNumber() <<
": state predicate must evaluate to type 'bool'.");
1695 containedVariables = stateReward.getRewardValueExpression().getVariables();
1696 isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1698 "Error in " << stateReward.getFilename() <<
", line " << stateReward.getLineNumber()
1699 <<
": state reward value expression refers to unknown identifiers.");
1700 STORM_LOG_THROW(stateReward.getRewardValueExpression().hasNumericalType(), storm::exceptions::WrongFormatException,
1701 "Error in " << stateReward.getFilename() <<
", line " << stateReward.getLineNumber()
1702 <<
": reward value expression must evaluate to numerical type.");
1705 for (
auto const& stateActionReward : rewardModel.getStateActionRewards()) {
1706 std::set<storm::expressions::Variable> containedVariables = stateActionReward.getStatePredicateExpression().getVariables();
1707 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1709 "Error in " << stateActionReward.getFilename() <<
", line " << stateActionReward.getLineNumber()
1710 <<
": state reward expression refers to unknown identifiers.");
1711 STORM_LOG_THROW(stateActionReward.getStatePredicateExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1712 "Error in " << stateActionReward.getFilename() <<
", line " << stateActionReward.getLineNumber()
1713 <<
": state predicate must evaluate to type 'bool'.");
1715 containedVariables = stateActionReward.getRewardValueExpression().getVariables();
1716 isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1718 "Error in " << stateActionReward.getFilename() <<
", line " << stateActionReward.getLineNumber()
1719 <<
": state reward value expression refers to unknown identifiers.");
1720 STORM_LOG_THROW(stateActionReward.getRewardValueExpression().hasNumericalType(), storm::exceptions::WrongFormatException,
1721 "Error in " << stateActionReward.getFilename() <<
", line " << stateActionReward.getLineNumber()
1722 <<
": reward value expression must evaluate to numerical type.");
1725 for (
auto const& transitionReward : rewardModel.getTransitionRewards()) {
1726 std::set<storm::expressions::Variable> containedVariables = transitionReward.getSourceStatePredicateExpression().getVariables();
1727 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1729 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1730 <<
": state reward expression refers to unknown identifiers.");
1731 STORM_LOG_THROW(transitionReward.getSourceStatePredicateExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1732 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1733 <<
": state predicate must evaluate to type 'bool'.");
1735 containedVariables = transitionReward.getTargetStatePredicateExpression().getVariables();
1736 isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1738 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1739 <<
": state reward expression refers to unknown identifiers.");
1740 STORM_LOG_THROW(transitionReward.getTargetStatePredicateExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1741 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1742 <<
": state predicate must evaluate to type 'bool'.");
1744 containedVariables = transitionReward.getRewardValueExpression().getVariables();
1745 isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1747 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1748 <<
": state reward value expression refers to unknown identifiers.");
1749 STORM_LOG_THROW(transitionReward.getRewardValueExpression().hasNumericalType(), storm::exceptions::WrongFormatException,
1750 "Error in " << transitionReward.getFilename() <<
", line " << transitionReward.getLineNumber()
1751 <<
": reward value expression must evaluate to numerical type.");
1757 std::set<storm::expressions::Variable> containedIdentifiers = this->getInitialConstruct().getInitialStatesExpression().getVariables();
1758 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedIdentifiers.begin(), containedIdentifiers.end());
1760 "Error in " << this->getInitialConstruct().
getFilename() <<
", line " << this->getInitialConstruct().
getLineNumber()
1761 <<
": initial construct refers to unknown identifiers.");
1765 if (systemCompositionConstruct) {
1767 checker.
check(systemCompositionConstruct.get().getSystemComposition());
1771 for (
auto const& label : this->
getLabels()) {
1772 std::set<storm::expressions::Variable> containedVariables = label.getStatePredicateExpression().getVariables();
1773 bool isValid = std::includes(variablesAndConstants.begin(), variablesAndConstants.end(), containedVariables.begin(), containedVariables.end());
1775 "Error in " << label.getFilename() <<
", line " << label.getLineNumber() <<
": label expression refers to unknown identifiers.");
1776 STORM_LOG_THROW(label.getStatePredicateExpression().hasBooleanType(), storm::exceptions::WrongFormatException,
1777 "Error in " << label.getFilename() <<
", line " << label.getLineNumber() <<
": label predicate must evaluate to type 'bool'.");
1781 for (
auto const& player : this->
getPlayers()) {
1783 for (
auto const& controlledAction : player.getActions()) {
1785 "Error in " << player.getFilename() <<
", line " << player.getLineNumber() <<
": The player controlled action " << controlledAction
1786 <<
" is not available.");
1788 for (
auto const& controlledModule : player.getModules()) {
1790 "Error in " << player.getFilename() <<
", line " << player.getLineNumber() <<
": The player controlled module " << controlledModule
1791 <<
" is not available.");
1797 std::set<std::pair<std::string, std::string>> globalBVarsWrittenToByCommand;
1798 std::set<std::pair<std::string, std::string>> globalIVarsWrittenToByCommand;
1799 for (
auto const& module : this->
getModules()) {
1800 std::set<std::pair<std::string, std::string>> globalBVarsWrittenToByCommandInThisModule;
1801 std::set<std::pair<std::string, std::string>> globalIVarsWrittenToByCommandInThisModule;
1802 for (
auto const& command : module.getCommands()) {
1803 if (!command.isLabeled()) {
1806 for (
auto const& update : command.getUpdates()) {
1807 for (
auto const& assignment : update.getAssignments()) {
1809 globalBVarsWrittenToByCommandInThisModule.insert({assignment.getVariable().getName(), command.getActionName()});
1811 globalIVarsWrittenToByCommandInThisModule.insert({assignment.getVariable().getName(), command.getActionName()});
1816 for (
auto const& entry : globalIVarsWrittenToByCommandInThisModule) {
1817 STORM_LOG_THROW(globalIVarsWrittenToByCommand.find(entry) == globalIVarsWrittenToByCommand.end(), storm::exceptions::WrongFormatException,
1818 "Error in " << module.getFilename() <<
", line " << module.getLineNumber()
1819 <<
": assignment of (possibly) synchronizing command with label '" << entry.second
1820 <<
"' writes to global variable '" << entry.first <<
"'.");
1822 for (
auto const& entry : globalBVarsWrittenToByCommandInThisModule) {
1823 STORM_LOG_THROW(globalBVarsWrittenToByCommand.find(entry) == globalBVarsWrittenToByCommand.end(), storm::exceptions::WrongFormatException,
1824 "Error in " << module.getFilename() <<
", line " << module.getLineNumber()
1825 <<
": assignment of (possibly) synchronizing command with label '" << entry.second
1826 <<
"' writes to global variable '" << entry.first <<
"'.");
1987 "Unable to flatten modules for model of type '" << this->
getModelType() <<
"'.");
1992 std::unique_ptr<storm::solver::SmtSolver>
solver = smtSolverFactory->create(*manager);
1995 std::stringstream newModuleName;
1996 std::vector<storm::prism::BooleanVariable> allBooleanVariables;
1997 std::vector<storm::prism::IntegerVariable> allIntegerVariables;
1998 std::vector<storm::prism::ClockVariable> allClockVariables;
1999 std::vector<storm::prism::Command> newCommands;
2000 uint_fast64_t nextCommandIndex = 0;
2001 uint_fast64_t nextUpdateIndex = 0;
2005 if (constant.isDefined()) {
2006 if (constant.getType().isBooleanType()) {
2009 solver->add(constant.getExpressionVariable() == constant.getExpression());
2016 solver->add(variable.getRangeExpression());
2021 allBooleanVariables.insert(allBooleanVariables.end(), this->getGlobalBooleanVariables().begin(), this->getGlobalBooleanVariables().end());
2022 allIntegerVariables.insert(allIntegerVariables.end(), this->getGlobalIntegerVariables().begin(), this->getGlobalIntegerVariables().end());
2027 for (
auto const& module : this->
getModules()) {
2028 newModuleName << module.getName() <<
"_";
2029 allBooleanVariables.insert(allBooleanVariables.end(), module.getBooleanVariables().begin(), module.getBooleanVariables().end());
2030 allIntegerVariables.insert(allIntegerVariables.end(), module.getIntegerVariables().begin(), module.getIntegerVariables().end());
2031 allClockVariables.insert(allClockVariables.end(), module.getClockVariables().begin(), module.getClockVariables().end());
2033 for (
auto const& variable : module.getIntegerVariables()) {
2034 solver->add(variable.getRangeExpression());
2037 if (module.hasInvariant()) {
2038 newInvariant = newInvariant.
isInitialized() ? (newInvariant && module.getInvariant()) :
module.getInvariant();
2043 for (
auto const& command : module.getCommands()) {
2044 if (!command.isLabeled()) {
2045 std::vector<storm::prism::Update> updates;
2046 updates.reserve(command.getUpdates().size());
2048 for (
auto const& update : command.getUpdates()) {
2050 storm::prism::Update(nextUpdateIndex, update.getLikelihoodExpression(), update.getAssignments(), update.getFilename(), 0));
2054 newCommands.push_back(
storm::prism::Command(nextCommandIndex, command.isMarkovian(), actionToIndexMap.find(
"")->second,
"",
2055 command.getGuardExpression(), updates, command.getFilename(), 0));
2068 bool noCombinationsForAction =
false;
2071 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>> possibleCommands;
2073 for (
auto const& module : this->
getModules()) {
2075 if (!module.hasActionIndex(actionIndex)) {
2079 std::set<uint_fast64_t>
const& commandIndices =
module.getCommandIndicesByActionIndex(actionIndex);
2083 if (commandIndices.empty()) {
2084 noCombinationsForAction =
true;
2089 possibleCommands.push_back(std::vector<std::reference_wrapper<storm::prism::Command const>>());
2092 for (
auto const& commandIndex : commandIndices) {
2093 possibleCommands.back().push_back(module.getCommand(commandIndex));
2099 if (!noCombinationsForAction) {
2104 std::vector<std::vector<storm::expressions::Variable>> commandVariables(possibleCommands.size());
2105 std::vector<storm::expressions::Variable> allCommandVariables;
2106 for (uint_fast64_t outerIndex = 0; outerIndex < possibleCommands.size(); ++outerIndex) {
2108 for (uint_fast64_t innerIndex = 0; innerIndex < possibleCommands[outerIndex].size(); ++innerIndex) {
2109 commandVariables[outerIndex].push_back(manager->declareFreshBooleanVariable());
2110 allCommandVariables.push_back(commandVariables[outerIndex].back());
2111 solver->add(implies(commandVariables[outerIndex].back(), possibleCommands[outerIndex][innerIndex].get().getGuardExpression()));
2115 for (
auto const& commandVariable : commandVariables[outerIndex]) {
2116 atLeastOneCommandFromModule = atLeastOneCommandFromModule || commandVariable;
2118 solver->add(atLeastOneCommandFromModule);
2127 std::vector<std::vector<std::reference_wrapper<Command const>>> chosenCommands(possibleCommands.size());
2129 for (uint_fast64_t outerIndex = 0; outerIndex < commandVariables.size(); ++outerIndex) {
2130 for (uint_fast64_t innerIndex = 0; innerIndex < commandVariables[outerIndex].size(); ++innerIndex) {
2131 if (modelReference.
getBooleanValue(commandVariables[outerIndex][innerIndex])) {
2132 chosenCommands[outerIndex].push_back(possibleCommands[outerIndex][innerIndex]);
2139 std::vector<std::vector<std::reference_wrapper<Command const>>::const_iterator> iterators;
2140 for (
auto const& element : chosenCommands) {
2141 iterators.push_back(element.begin());
2144 bool movedAtLeastOneIterator =
false;
2145 std::vector<std::reference_wrapper<Command const>> commandCombination(chosenCommands.size(), chosenCommands.front().front());
2146 std::vector<uint_fast64_t> commandCombinationIndices(iterators.size());
2148 for (uint_fast64_t index = 0; index < iterators.size(); ++index) {
2149 commandCombination[index] = *iterators[index];
2150 commandCombinationIndices[index] = commandCombination[index].get().getGlobalIndex();
2154 auto seenIt = seenCommandCombinations.find(commandCombinationIndices);
2155 if (seenIt == seenCommandCombinations.end()) {
2156 newCommands.push_back(synchronizeCommands(nextCommandIndex, actionIndex, nextUpdateIndex, indexToActionMap.find(actionIndex)->second,
2157 commandCombination));
2158 seenCommandCombinations.insert(commandCombinationIndices);
2162 nextUpdateIndex += newCommands.back().getNumberOfUpdates();
2165 movedAtLeastOneIterator =
false;
2166 for (uint_fast64_t index = 0; index < iterators.size(); ++index) {
2168 if (iterators[index] != chosenCommands[index].cend()) {
2169 movedAtLeastOneIterator =
true;
2172 iterators[index] = chosenCommands[index].cbegin();
2175 }
while (movedAtLeastOneIterator);
2185 storm::prism::Module singleModule(newModuleName.str(), allBooleanVariables, allIntegerVariables, allClockVariables, newInvariant, newCommands,
2186 this->getFilename(), 0);
2189 std::vector<storm::prism::IntegerVariable>(), this->
getFormulas(), this->
getPlayers(), {singleModule}, actionToIndexMap,