21 std::set<storm::expressions::Variable>
const& givenVariablesToMakeGlobal, std::string suffix) {
22 labelRenaming.clear();
23 rewardModelRenaming.clear();
24 formulaToFunctionCallMap.clear();
63 std::map<storm::expressions::Variable, bool> variablesToMakeGlobal;
64 for (
auto const& var : givenVariablesToMakeGlobal) {
65 variablesToMakeGlobal.emplace(var,
true);
70 std::set<storm::expressions::Variable> renamedVariables;
71 for (
auto const& module : program.
getModules()) {
72 if (module.isRenamedFromModule()) {
73 for (
auto const& renaimingPair : module.getRenaming()) {
74 if (manager->hasVariable(renaimingPair.first)) {
75 renamedVariables.insert(manager->getVariable(renaimingPair.first));
77 if (manager->hasVariable(renaimingPair.second)) {
78 renamedVariables.insert(manager->getVariable(renaimingPair.second));
90 std::set<storm::expressions::Variable> variablesInFormula, placeholdersInFormula;
91 for (
auto const& var : formula.getExpression().getVariables()) {
93 auto functionCallIt = formulaToFunctionCallMap.find(var);
94 if (functionCallIt == formulaToFunctionCallMap.end()) {
95 if (renamedVariables.count(var) > 0) {
96 variablesInFormula.insert(var);
98 variablesToMakeGlobal.emplace(var,
true);
103 for (
auto const& innerFunctionArg : innerFunctionCall.
getArguments()) {
104 auto const& argVar = innerFunctionArg->asVariableExpression().getVariable();
105 if (renamedVariables.count(argVar) > 0) {
106 variablesInFormula.insert(argVar);
108 variablesToMakeGlobal.emplace(argVar,
true);
111 placeholdersInFormula.insert(var);
116 std::map<storm::expressions::Variable, storm::expressions::Expression> functionBodySubstitution;
117 std::vector<storm::expressions::Variable> functionParameters;
118 std::vector<std::shared_ptr<storm::expressions::BaseExpression const>> functionArguments;
119 for (
auto const& var : variablesInFormula) {
120 functionArguments.push_back(var.getExpression().getBaseExpressionPointer());
121 functionParameters.push_back(manager->declareVariable(formula.getName() +
"__param__" + var.getName() + suffix, var.getType()));
122 functionBodySubstitution[var] = functionParameters.back().getExpression();
124 for (
auto const& formulaVar : placeholdersInFormula) {
125 functionBodySubstitution[formulaVar] =
132 auto functionCallExpression =
133 std::make_shared<storm::expressions::FunctionCallExpression>(*manager, formula.getType(), formula.getName(), functionArguments);
134 formulaToFunctionCallMap[formula.getExpressionVariable()] = functionCallExpression->toExpression();
140 std::map<storm::expressions::Variable, std::reference_wrapper<storm::jani::Variable const>> variableToVariableMap;
144 if (variable.hasLowerBoundExpression() || variable.hasUpperBoundExpression()) {
147 false, variable.getLowerBoundExpression(), variable.getUpperBoundExpression()));
148 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
152 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
158 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
162 for (
auto const& action : program.
getActions()) {
164 if (!action.empty()) {
171 std::map<storm::expressions::Variable, std::set<uint_fast64_t>> variablesToAccessingModuleIndices;
176 std::set<storm::expressions::Variable> variables =
module.getAllExpressionVariables();
178 command.getGuardExpression().getBaseExpression().gatherVariables(variables);
179 for (
auto const& update : command.getUpdates()) {
180 update.getLikelihoodExpression().gatherVariables(variables);
181 for (
auto const& assignment : update.getAssignments()) {
182 assignment.getExpression().getBaseExpression().gatherVariables(variables);
183 variables.insert(assignment.getVariable());
189 std::map<storm::expressions::Variable, storm::expressions::Expression> renamedFormulaToFunctionCallMap;
194 for (
auto const& variable : variables) {
196 if (formulaToFunctionCallMap.count(variable) > 0) {
197 std::set<storm::expressions::Variable> variablesInFunctionCall;
199 variablesInFunctionCall = renamedFormulaToFunctionCallMap[variable].getVariables();
201 variablesInFunctionCall = formulaToFunctionCallMap[variable].getVariables();
203 for (
auto const& funVar : variablesInFunctionCall) {
204 variablesToAccessingModuleIndices[funVar].insert(index);
207 variablesToAccessingModuleIndices[variable].insert(index);
213 for (
auto const& varMods : variablesToAccessingModuleIndices) {
214 assert(!varMods.second.empty());
215 auto varIt = variablesToMakeGlobal.find(varMods.first);
217 if (varIt == variablesToMakeGlobal.end()) {
218 variablesToMakeGlobal.emplace(varMods.first, allVariablesGlobal || (varMods.second.size() > 1));
220 varIt->second = varIt->second || allVariablesGlobal || (varMods.second.size() > 1);
225 std::vector<storm::jani::Assignment> transientLocationAssignments;
226 for (
auto const& label : program.
getLabels()) {
227 bool renameLabel = manager->hasVariable(label.getName()) || program.
hasRewardModel(label.getName());
228 std::string finalLabelName = renameLabel ?
"label_" + label.getName() + suffix : label.getName();
230 STORM_LOG_INFO(
"Label '" << label.getName() <<
"' was renamed to '" << finalLabelName
231 <<
"' in PRISM-to-JANI conversion, as another variable with that name already exists.");
232 labelRenaming[label.getName()] = finalLabelName;
234 auto newExpressionVariable = manager->declareBooleanVariable(finalLabelName);
237 transientLocationAssignments.emplace_back(
storm::jani::LValue(newTransientVariable), label.getStatePredicateExpression());
240 std::set<storm::expressions::Variable> variables = label.getStatePredicateExpression().getVariables();
241 for (
auto const& variable : variables) {
242 if (formulaToFunctionCallMap.count(variable) > 0) {
243 for (
auto const& funVar : formulaToFunctionCallMap[variable].getVariables()) {
244 variablesToMakeGlobal[funVar] =
true;
247 variablesToMakeGlobal[variable] =
true;
257 for (
auto const& variable : variables) {
258 if (formulaToFunctionCallMap.count(variable) > 0) {
259 for (
auto const& funVar : formulaToFunctionCallMap[variable].getVariables()) {
260 variablesToMakeGlobal[funVar] =
true;
263 variablesToMakeGlobal[variable] =
true;
272 std::map<uint_fast64_t, std::vector<storm::jani::Assignment>> transientEdgeAssignments;
273 bool hasStateRewards =
false;
275 std::string finalRewardModelName;
276 if (rewardModel.getName().empty()) {
277 finalRewardModelName =
"default_reward_model";
279 if (manager->hasVariable(rewardModel.getName())) {
281 finalRewardModelName =
"rewardmodel_" + rewardModel.getName() + suffix;
282 STORM_LOG_INFO(
"Rewardmodel '" << rewardModel.getName() <<
"' was renamed to '" << finalRewardModelName
283 <<
"' in PRISM-to-JANI conversion, as another variable with that name already exists.");
284 rewardModelRenaming[rewardModel.getName()] = finalRewardModelName;
286 finalRewardModelName = rewardModel.getName();
290 auto newExpressionVariable = manager->declareRationalVariable(finalRewardModelName);
294 if (rewardModel.hasStateRewards()) {
295 hasStateRewards =
true;
297 for (
auto const& stateReward : rewardModel.getStateRewards()) {
299 stateReward.getStatePredicateExpression().
isTrue()
300 ? stateReward.getRewardValueExpression()
301 :
storm::expressions::ite(stateReward.getStatePredicateExpression(), stateReward.getRewardValueExpression(), manager->rational(0));
303 transientLocationExpression = transientLocationExpression + rewardTerm;
305 transientLocationExpression = rewardTerm;
308 transientLocationAssignments.emplace_back(
storm::jani::LValue(newTransientVariable), transientLocationExpression);
310 std::set<storm::expressions::Variable> variables = transientLocationExpression.
getVariables();
311 for (
auto const& variable : variables) {
312 if (formulaToFunctionCallMap.count(variable) > 0) {
313 for (
auto const& funVar : formulaToFunctionCallMap[variable].getVariables()) {
314 variablesToMakeGlobal[funVar] =
true;
317 variablesToMakeGlobal[variable] =
true;
322 std::map<uint_fast64_t, storm::expressions::Expression> actionIndexToExpression;
323 for (
auto const& actionReward : rewardModel.getStateActionRewards()) {
325 actionReward.getStatePredicateExpression().
isTrue()
326 ? actionReward.getRewardValueExpression()
327 :
storm::expressions::ite(actionReward.getStatePredicateExpression(), actionReward.getRewardValueExpression(), manager->rational(0));
328 auto it = actionIndexToExpression.find(janiModel.
getActionIndex(actionReward.getActionName()));
329 if (it != actionIndexToExpression.end()) {
330 it->second = it->second + rewardTerm;
332 actionIndexToExpression[janiModel.
getActionIndex(actionReward.getActionName())] = rewardTerm;
336 for (
auto const& entry : actionIndexToExpression) {
337 auto it = transientEdgeAssignments.find(entry.first);
338 if (it != transientEdgeAssignments.end()) {
342 transientEdgeAssignments.emplace(entry.first, assignments);
345 std::set<storm::expressions::Variable> variables = entry.second.getVariables();
346 for (
auto const& variable : variables) {
347 variablesToMakeGlobal[variable] =
true;
350 STORM_LOG_THROW(!rewardModel.hasTransitionRewards(), storm::exceptions::NotImplementedException,
351 "Transition reward translation currently not implemented.");
354 storm::exceptions::NotImplementedException,
"Cannot translate reward models from PRISM to JANI that specify a custom system composition.");
362 std::set<uint64_t> firstModules;
363 bool firstModule =
true;
364 for (
auto const& module : program.
getModules()) {
366 std::set<uint_fast64_t> actionIndicesOfModule;
368 storm::jani::Automaton automaton(module.getName(), manager->declareIntegerVariable(
"_loc_prism2jani_" + module.getName() +
"_" + suffix));
369 for (
auto const& variable : module.getIntegerVariables()) {
370 auto findRes = variablesToMakeGlobal.find(variable.getExpressionVariable());
371 if (findRes != variablesToMakeGlobal.end()) {
372 bool makeVarGlobal = findRes->second;
373 if (variable.hasLowerBoundExpression() || variable.hasUpperBoundExpression()) {
375 variable.getName(), variable.getExpressionVariable(), variable.getInitialValueExpression(),
false, variable.getLowerBoundExpression(),
376 variable.getUpperBoundExpression());
379 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
382 variable.getInitialValueExpression(),
false);
385 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
388 STORM_LOG_INFO(
"Variable " << variable.getName() <<
" is declared but never used.");
391 for (
auto const& variable : module.getBooleanVariables()) {
393 variable.getName(), variable.getExpressionVariable(),
394 variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none,
false);
395 auto findRes = variablesToMakeGlobal.find(variable.getExpressionVariable());
396 if (findRes != variablesToMakeGlobal.end()) {
397 bool makeVarGlobal = findRes->second;
400 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
402 STORM_LOG_INFO(
"Variable " << variable.getName() <<
" is declared but never used.");
405 for (
auto const& variable : module.getClockVariables()) {
407 variable.getName(), variable.getExpressionVariable(),
408 variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none,
false);
409 auto findRes = variablesToMakeGlobal.find(variable.getExpressionVariable());
410 if (findRes != variablesToMakeGlobal.end()) {
411 bool makeVarGlobal = findRes->second;
414 variableToVariableMap.emplace(variable.getExpressionVariable(), createdVariable);
416 STORM_LOG_INFO(
"Variable " << variable.getName() <<
" is declared but never used.");
426 if (module.hasInvariant()) {
435 for (
auto const& assignment : transientLocationAssignments) {
440 for (
auto const& command : module.getCommands()) {
441 std::shared_ptr<storm::jani::TemplateEdge> templateEdge = std::make_shared<storm::jani::TemplateEdge>(command.getGuardExpression());
443 actionIndicesOfModule.insert(janiModel.
getActionIndex(command.getActionName()));
445 boost::optional<storm::expressions::Expression> rateExpression;
448 for (
auto const& update : command.getUpdates()) {
449 if (rateExpression) {
450 rateExpression = rateExpression.get() + update.getLikelihoodExpression();
452 rateExpression = update.getLikelihoodExpression();
457 std::vector<std::pair<uint64_t, storm::expressions::Expression>> destinationLocationsAndProbabilities;
458 for (
auto const& update : command.getUpdates()) {
459 std::vector<storm::jani::Assignment> assignments;
460 for (
auto const& assignment : update.getAssignments()) {
461 assignments.push_back(
465 if (rateExpression) {
466 destinationLocationsAndProbabilities.emplace_back(onlyLocationIndex, update.getLikelihoodExpression() / rateExpression.get());
468 destinationLocationsAndProbabilities.emplace_back(onlyLocationIndex, update.getLikelihoodExpression());
477 auto transientEdgeAssignmentsToAdd = transientEdgeAssignments.find(janiModel.
getActionIndex(command.getActionName()));
478 if (transientEdgeAssignmentsToAdd != transientEdgeAssignments.end()) {
479 for (
auto const& assignment : transientEdgeAssignmentsToAdd->second) {
480 templateEdge->addTransientAssignment(assignment);
486 if (command.getActionName().empty()) {
488 destinationLocationsAndProbabilities);
491 destinationLocationsAndProbabilities);
502 for (
auto actionIndex : actionIndicesOfModule) {
508 auto it = transientEdgeAssignments.find(actionIndex);
509 if (it != transientEdgeAssignments.end()) {
510 transientEdgeAssignments.erase(it);
518 automaton.
substitute(renamedFormulaToFunctionCallMap,
false);
536 janiModel.
substitute(formulaToFunctionCallMap,
false);