3#include <unordered_set> 
   23    std::ifstream inputFileStream;
 
   29        std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
 
   31    } 
catch (storm::exceptions::WrongFormatException& e) {
 
   35    } 
catch (std::exception& e) {
 
 
   47    bool hasByteOrderMark = input.size() >= 3 && input[0] == 
'\xEF' && input[1] == 
'\xBB' && input[2] == 
'\xBF';
 
   61        storm::spirit_encoding::space_type space;
 
   62        bool succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit(
"//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
 
   63        STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, 
"Parsing failed in first pass.");
 
   70        grammar.moveToSecondRun();
 
   71        succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit(
"//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
 
   72        STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, 
"Parsing failed in second pass.");
 
   73    } 
catch (qi::expectation_failure<PositionIteratorType> 
const& e) {
 
   75        std::size_t lineNumber = boost::spirit::get_line(e.first);
 
   78        STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException, 
"Parsing error in line " << lineNumber << 
" of file " << filename << 
".");
 
 
   86PrismParserGrammar::PrismParserGrammar(std::string 
const& filename, 
Iterator first, 
bool prismCompatibility)
 
   89      prismCompatibility(prismCompatibility),
 
   92      manager(new 
storm::expressions::ExpressionManager()),
 
   95    boolExpression = (expression_[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isOfBoolType, phoenix::ref(*
this), qi::_val)];
 
   96    boolExpression.name(
"boolean expression");
 
   98    intExpression = (expression_[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isOfIntType, phoenix::ref(*
this), qi::_val)];
 
   99    intExpression.name(
"integer expression");
 
  101    numericalExpression = (expression_[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isOfNumericalType, phoenix::ref(*
this), qi::_val)];
 
  102    numericalExpression.name(
"numerical expression");
 
  105    identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_(
'_')) >> *(qi::alnum | qi::char_(
'_')))]]]
 
  106                               [qi::_pass = phoenix::bind(&PrismParserGrammar::isValidIdentifier, phoenix::ref(*
this), qi::_1)];
 
  107    identifier.name(
"identifier");
 
  110    freshIdentifier = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshIdentifier, phoenix::ref(*
this), qi::_1)];
 
  111    freshIdentifier.name(
"fresh identifier");
 
  113    modelTypeDefinition %= modelType_;
 
  114    modelTypeDefinition.name(
"model type");
 
  118    definedBooleanConstantDefinition =
 
  119        (((qi::lit(
"const") >> qi::lit(
"bool")) > freshIdentifier) >>
 
  120         (qi::lit(
"=") > boolExpression >
 
  121          qi::lit(
";")))[qi::_val = phoenix::bind(&PrismParserGrammar::createDefinedBooleanConstant, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  122    definedBooleanConstantDefinition.name(
"defined boolean constant declaration");
 
  124    definedIntegerConstantDefinition =
 
  125        (((qi::lit(
"const") >> -qi::lit(
"int")) >> freshIdentifier) >>
 
  126         (qi::lit(
"=") > intExpression > qi::lit(
";")))[qi::_val = phoenix::bind(&PrismParserGrammar::createDefinedIntegerConstant, phoenix::ref(*
this), qi::_1,
 
  129    definedIntegerConstantDefinition.name(
"defined integer constant declaration");
 
  131    definedDoubleConstantDefinition =
 
  132        (((qi::lit(
"const") >> qi::lit(
"double")) > freshIdentifier) >>
 
  133         (qi::lit(
"=") > numericalExpression >
 
  134          qi::lit(
";")))[qi::_val = phoenix::bind(&PrismParserGrammar::createDefinedDoubleConstant, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  135    definedDoubleConstantDefinition.name(
"defined double constant declaration");
 
  137    definedConstantDefinition %= (definedBooleanConstantDefinition | definedDoubleConstantDefinition | definedIntegerConstantDefinition);
 
  138    definedConstantDefinition.name(
"defined constant definition");
 
  141    undefinedBooleanConstantDefinition =
 
  142        (((qi::lit(
"const") >> qi::lit(
"bool")) > freshIdentifier) >
 
  143         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createUndefinedBooleanConstant, phoenix::ref(*
this), qi::_1)];
 
  144    undefinedBooleanConstantDefinition.name(
"undefined boolean constant declaration");
 
  146    undefinedIntegerConstantDefinition =
 
  147        (((qi::lit(
"const") >> -qi::lit(
"int")) > freshIdentifier) >
 
  148         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createUndefinedIntegerConstant, phoenix::ref(*
this), qi::_1)];
 
  149    undefinedIntegerConstantDefinition.name(
"undefined integer constant declaration");
 
  151    undefinedDoubleConstantDefinition =
 
  152        (((qi::lit(
"const") >> qi::lit(
"double")) > freshIdentifier) >
 
  153         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createUndefinedDoubleConstant, phoenix::ref(*
this), qi::_1)];
 
  154    undefinedDoubleConstantDefinition.name(
"undefined double constant definition");
 
  156    undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedDoubleConstantDefinition |
 
  157                                   undefinedIntegerConstantDefinition);  
 
  159    undefinedConstantDefinition.name(
"undefined constant definition");
 
  162    formulaDefinitionRhs = (qi::lit(
"=") > qi::as_string[(+(qi::char_ - (qi::lit(
";") | qi::lit(
"endmodule"))))][qi::_val = qi::_1] > qi::lit(
";"));
 
  163    formulaDefinitionRhs.name(
"formula defining expression");
 
  165    formulaDefinition = (qi::lit(
"formula") > freshIdentifier >
 
  166                         formulaDefinitionRhs)[qi::_val = phoenix::bind(&PrismParserGrammar::createFormulaFirstRun, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  167    formulaDefinition.name(
"formula definition");
 
  169    booleanVariableDefinition =
 
  170        (((freshIdentifier > qi::lit(
":")) >> qi::lit(
"bool")) > -((qi::lit(
"init") > boolExpression[qi::_a = qi::_1]) | qi::attr(manager->boolean(
false))) >
 
  171         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createBooleanVariable, phoenix::ref(*
this), qi::_1, qi::_a)];
 
  172    booleanVariableDefinition.name(
"boolean variable definition");
 
  174    boundedIntegerVariableDefinition =
 
  175        (((freshIdentifier > qi::lit(
":")) >> qi::lit(
"[")) > intExpression > qi::lit(
"..") > intExpression > qi::lit(
"]") >
 
  176         -(qi::lit(
"init") > intExpression[qi::_a = qi::_1]) >
 
  177         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createIntegerVariable, phoenix::ref(*
this), qi::_1, qi::_2, qi::_3, qi::_a)];
 
  178    boundedIntegerVariableDefinition.name(
"bounded integer variable definition");
 
  180    unboundedIntegerVariableDefinition = (((freshIdentifier > qi::lit(
":")) >> qi::lit(
"int")) > -(qi::lit(
"init") > intExpression[qi::_a = qi::_1]) >
 
  181                                          qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createIntegerVariable, phoenix::ref(*
this), qi::_1,
 
  183    unboundedIntegerVariableDefinition.name(
"unbounded integer variable definition");
 
  185    integerVariableDefinition = boundedIntegerVariableDefinition | unboundedIntegerVariableDefinition;
 
  186    integerVariableDefinition.name(
"integer variable definition");
 
  188    clockVariableDefinition = (((freshIdentifier > qi::lit(
":")) >> qi::lit(
"clock")) >
 
  189                               qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createClockVariable, phoenix::ref(*
this), qi::_1)];
 
  190    clockVariableDefinition.name(
"clock variable definition");
 
  192    variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)] |
 
  193                          clockVariableDefinition[phoenix::push_back(qi::_r3, qi::_1)]);
 
  194    variableDefinition.name(
"variable declaration");
 
  196    globalVariableDefinition =
 
  200    globalVariableDefinition.name(
"global variable declaration list");
 
  202    stateRewardDefinition = (boolExpression > qi::lit(
":") > numericalExpression >
 
  203                             qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createStateReward, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  204    stateRewardDefinition.name(
"state reward definition");
 
  206    stateActionRewardDefinition =
 
  207        (qi::lit(
"[") > -identifier > qi::lit(
"]") > boolExpression > qi::lit(
":") > numericalExpression >
 
  208         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createStateActionReward, phoenix::ref(*
this), qi::_1, qi::_2, qi::_3, qi::_r1)];
 
  209    stateActionRewardDefinition.name(
"state action reward definition");
 
  211    transitionRewardDefinition =
 
  212        ((qi::lit(
"[") > -identifier[qi::_a = qi::_1] > qi::lit(
"]") > boolExpression[qi::_b = qi::_1]) >>
 
  213         (qi::lit(
"->") > boolExpression[qi::_c = qi::_1] > qi::lit(
":") > numericalExpression[qi::_d = qi::_1] >
 
  214          qi::lit(
";")))[qi::_val = phoenix::bind(&PrismParserGrammar::createTransitionReward, phoenix::ref(*
this), qi::_a, qi::_b, qi::_c, qi::_d, qi::_r1)];
 
  215    transitionRewardDefinition.name(
"transition reward definition");
 
  217    freshRewardModelName = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshRewardModelName, phoenix::ref(*
this), qi::_1)];
 
  218    freshRewardModelName.name(
"fresh reward model name");
 
  220    rewardModelDefinition =
 
  221        (qi::lit(
"rewards") > -(qi::lit(
"\"") > freshRewardModelName[qi::_a = qi::_1] > qi::lit(
"\"")) >
 
  222         +(transitionRewardDefinition(qi::_r1)[phoenix::push_back(qi::_d, qi::_1)] | stateActionRewardDefinition(qi::_r1)[phoenix::push_back(qi::_c, qi::_1)] |
 
  223           stateRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >
 
  224         qi::lit(
"endrewards"))[qi::_val = phoenix::bind(&PrismParserGrammar::createRewardModel, phoenix::ref(*
this), qi::_a, qi::_b, qi::_c, qi::_d)];
 
  225    rewardModelDefinition.name(
"reward model definition");
 
  227    initialStatesConstruct =
 
  228        (qi::lit(
"init") > boolExpression >
 
  229         qi::lit(
"endinit"))[qi::_pass = phoenix::bind(&PrismParserGrammar::addInitialStatesConstruct, phoenix::ref(*
this), qi::_1, qi::_r1)];
 
  230    initialStatesConstruct.name(
"initial construct");
 
  232    observablesConstruct = (qi::lit(
"observables") > (identifier % qi::lit(
",")) >
 
  233                            qi::lit(
"endobservables"))[phoenix::bind(&PrismParserGrammar::createObservablesList, phoenix::ref(*
this), qi::_1)];
 
  234    observablesConstruct.name(
"observables construct");
 
  236    invariantConstruct = (qi::lit(
"invariant") > boolExpression > qi::lit(
"endinvariant"))[qi::_val = qi::_1];
 
  237    invariantConstruct.name(
"invariant construct");
 
  239    knownModuleName = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isKnownModuleName, phoenix::ref(*
this), qi::_1, 
false)];
 
  240    knownModuleName.name(
"existing module name");
 
  242    freshModuleName = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshModuleName, phoenix::ref(*
this), qi::_1)];
 
  243    freshModuleName.name(
"fresh module name");
 
  245    systemCompositionConstruct =
 
  246        (qi::lit(
"system") > parallelComposition >
 
  247         qi::lit(
"endsystem"))[phoenix::bind(&PrismParserGrammar::addSystemCompositionConstruct, phoenix::ref(*
this), qi::_1, qi::_r1)];
 
  248    systemCompositionConstruct.name(
"system composition construct");
 
  250    actionNameList %= identifier[phoenix::insert(qi::_val, qi::_1)] >> *(
"," >> identifier[phoenix::insert(qi::_val, qi::_1)]);
 
  251    actionNameList.name(
"action list");
 
  253    parallelComposition =
 
  254        hidingOrRenamingComposition[qi::_val = qi::_1] >>
 
  255        *((interleavingParallelComposition > hidingOrRenamingComposition)[qi::_val = phoenix::bind(&PrismParserGrammar::createInterleavingParallelComposition,
 
  256                                                                                                   phoenix::ref(*
this), qi::_val, qi::_1)] |
 
  257          (synchronizingParallelComposition > hidingOrRenamingComposition)[qi::_val = phoenix::bind(&PrismParserGrammar::createSynchronizingParallelComposition,
 
  258                                                                                                    phoenix::ref(*
this), qi::_val, qi::_1)] |
 
  259          (restrictedParallelComposition > hidingOrRenamingComposition)[qi::_val = phoenix::bind(&PrismParserGrammar::createRestrictedParallelComposition,
 
  260                                                                                                 phoenix::ref(*
this), qi::_val, qi::_1, qi::_2)]);
 
  261    parallelComposition.name(
"parallel composition");
 
  263    synchronizingParallelComposition = qi::lit(
"||");
 
  264    synchronizingParallelComposition.name(
"synchronizing parallel composition");
 
  266    interleavingParallelComposition = qi::lit(
"|||");
 
  267    interleavingParallelComposition.name(
"interleaving parallel composition");
 
  269    restrictedParallelComposition = qi::lit(
"|[") > actionNameList > qi::lit(
"]|");
 
  270    restrictedParallelComposition.name(
"restricted parallel composition");
 
  272    hidingOrRenamingComposition = hidingComposition | renamingComposition | atomicComposition;
 
  273    hidingOrRenamingComposition.name(
"hiding/renaming composition");
 
  276        (atomicComposition >>
 
  277         (qi::lit(
"/") > (qi::lit(
"{") > actionNameList >
 
  278                          qi::lit(
"}"))))[qi::_val = phoenix::bind(&PrismParserGrammar::createHidingComposition, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  279    hidingComposition.name(
"hiding composition");
 
  282        +(identifier >> (qi::lit(
"<-") >> identifier))[phoenix::insert(qi::_val, phoenix::construct<std::pair<std::string, std::string>>(qi::_1, qi::_2))];
 
  283    actionRenamingList.name(
"action renaming list");
 
  285    renamingComposition =
 
  286        (atomicComposition >>
 
  288          (actionRenamingList > qi::lit(
"}"))))[qi::_val = phoenix::bind(&PrismParserGrammar::createRenamingComposition, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  289    renamingComposition.name(
"renaming composition");
 
  291    atomicComposition = (qi::lit(
"(") > parallelComposition > qi::lit(
")")) | moduleComposition;
 
  292    atomicComposition.name(
"atomic composition");
 
  294    moduleComposition = identifier[qi::_val = phoenix::bind(&PrismParserGrammar::createModuleComposition, phoenix::ref(*
this), qi::_1)];
 
  295    moduleComposition.name(
"module composition");
 
  297    freshLabelName = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshLabelName, phoenix::ref(*
this), qi::_1)];
 
  298    freshLabelName.name(
"fresh label name");
 
  300    labelDefinition = (qi::lit(
"label") > -qi::lit(
"\"") > freshLabelName > -qi::lit(
"\"") > qi::lit(
"=") > boolExpression >
 
  301                       qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createLabel, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  302    labelDefinition.name(
"label definition");
 
  304    freshObservationLabelName =
 
  305        (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshObservationLabelName, phoenix::ref(*
this), qi::_1)];
 
  306    freshObservationLabelName.name(
"fresh observable name");
 
  308    observableDefinition =
 
  309        (qi::lit(
"observable") > -qi::lit(
"\"") > freshObservationLabelName > -qi::lit(
"\"") > qi::lit(
"=") > (intExpression | boolExpression) >
 
  310         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createObservationLabel, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  311    observableDefinition.name(
"observable definition");
 
  313    assignmentDefinition = ((qi::lit(
"(") >> identifier >> qi::lit(
"'")) > qi::lit(
"=") > expression_ >
 
  314                            qi::lit(
")"))[qi::_val = phoenix::bind(&PrismParserGrammar::createAssignment, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  315    assignmentDefinition.name(
"assignment");
 
  317    assignmentDefinitionList =
 
  318        (assignmentDefinition % 
"&")[qi::_val = qi::_1] | (qi::lit(
"true"))[qi::_val = phoenix::construct<std::vector<storm::prism::Assignment>>()];
 
  319    assignmentDefinitionList.name(
"assignment list");
 
  321    likelihoodDefinition =
 
  322        (numericalExpression >
 
  324        (qi::lit(
"[") > numericalExpression > qi::lit(
",") > numericalExpression > qi::lit(
"]") >
 
  325         qi::lit(
":"))[qi::_val = phoenix::construct<typename storm::prism::Update::ExpressionPair>(qi::_1, qi::_2)];
 
  328        (assignmentDefinitionList[qi::_val = phoenix::bind(&PrismParserGrammar::createUpdate, phoenix::ref(*
this),
 
  330         ((likelihoodDefinition >
 
  331           assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismParserGrammar::createUpdate, phoenix::ref(*
this), qi::_1, qi::_2, qi::_r1)]));
 
  332    updateDefinition.name(
"update");
 
  334    updateListDefinition %= +updateDefinition(qi::_r1) % 
"+";
 
  335    updateListDefinition.name(
"update list");
 
  338    commandDefinition = (((qi::lit(
"[") > -identifier > qi::lit(
"]")) | (qi::lit(
"<") > -identifier > qi::lit(
">")[qi::_a = 
true])) >
 
  339                         +(qi::char_ - (qi::lit(
";") | qi::lit(
"endmodule"))) >
 
  340                         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createDummyCommand, phoenix::ref(*
this), qi::_1, qi::_r1)];
 
  341    commandDefinition.name(
"command definition");
 
  345        ((qi::lit(
"module") > freshModuleName > *(variableDefinition(qi::_a, qi::_b, qi::_c))) > -invariantConstruct > (*commandDefinition(qi::_r1)) >
 
  346         qi::lit(
"endmodule"))[qi::_val = phoenix::bind(&PrismParserGrammar::createModule, phoenix::ref(*
this), qi::_1, qi::_a, qi::_b, qi::_c, qi::_2, qi::_3,
 
  348    moduleDefinition.name(
"module definition");
 
  350    freshPlayerName = (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isFreshPlayerName, phoenix::ref(*
this), qi::_1)];
 
  351    freshPlayerName.name(
"fresh player name");
 
  353    playerControlledActionName =
 
  354        ((qi::lit(
"[") > identifier >
 
  355          qi::lit(
"]"))[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isKnownActionName, phoenix::ref(*
this), qi::_1, 
true)];
 
  356    playerControlledActionName.name(
"player controlled action name");
 
  358    playerControlledModuleName =
 
  359        (identifier[qi::_val = qi::_1])[qi::_pass = phoenix::bind(&PrismParserGrammar::isKnownModuleName, phoenix::ref(*
this), qi::_1, 
true)];
 
  360    playerControlledModuleName.name(
"player controlled module name");
 
  363        (qi::lit(
"player") > freshPlayerName[qi::_a = qi::_1] >
 
  364         +((playerControlledActionName[phoenix::push_back(qi::_c, qi::_1)] | playerControlledModuleName[phoenix::push_back(qi::_b, qi::_1)]) % 
',') >
 
  365         qi::lit(
"endplayer"))[qi::_val = phoenix::bind(&PrismParserGrammar::createPlayer, phoenix::ref(*
this), qi::_a, qi::_b, qi::_c)];
 
  366    playerConstruct.name(
"player construct");
 
  370         ((identifier > qi::lit(
"=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string, std::string>>(qi::_1, qi::_2))] % 
",") >
 
  371         qi::lit(
"]"))[qi::_val = phoenix::bind(&PrismParserGrammar::createModuleRenaming, phoenix::ref(*
this), qi::_a)];
 
  372    moduleRenaming.name(
"Module renaming list");
 
  375        (((qi::lit(
"module") > freshModuleName) >> qi::lit(
"=")) > knownModuleName[qi::_a = qi::_1] >
 
  376         (moduleRenaming[qi::_b = qi::_1])[qi::_pass =
 
  377                                               phoenix::bind(&PrismParserGrammar::isValidModuleRenaming, phoenix::ref(*
this), qi::_a, qi::_b, qi::_r1)] >
 
  378         qi::lit(
"endmodule"))[qi::_val = phoenix::bind(&PrismParserGrammar::createRenamedModule, phoenix::ref(*
this), qi::_1, qi::_a, qi::_b, qi::_r1)];
 
  379    renamedModule.name(
"module definition via renaming");
 
  382        (qi::eps[phoenix::bind(&PrismParserGrammar::removeInitialConstruct, phoenix::ref(*
this), phoenix::ref(globalProgramInformation))] >
 
  383         modelTypeDefinition[phoenix::bind(&PrismParserGrammar::setModelType, phoenix::ref(*
this), phoenix::ref(globalProgramInformation), qi::_1)] >
 
  384         -observablesConstruct >
 
  389           globalVariableDefinition(phoenix::ref(globalProgramInformation)) |
 
  390           (renamedModule(phoenix::ref(globalProgramInformation)) | moduleDefinition(phoenix::ref(globalProgramInformation)))[phoenix::push_back(
 
  392           initialStatesConstruct(phoenix::ref(globalProgramInformation)) |
 
  393           rewardModelDefinition(phoenix::ref(globalProgramInformation))[phoenix::push_back(
 
  399           playerConstruct(phoenix::ref(globalProgramInformation))[phoenix::push_back(
 
  401         -(systemCompositionConstruct(phoenix::ref(globalProgramInformation))) >
 
  402         qi::eoi)[qi::_val = phoenix::bind(&PrismParserGrammar::createProgram, phoenix::ref(*
this), phoenix::ref(globalProgramInformation))];
 
  403    start.name(
"probabilistic program");
 
  406    auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
 
  407    qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
 
  408    qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction);
 
  409    qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction);
 
  410    qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction);
 
  411    qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction);
 
  412    qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction);
 
  413    qi::on_success(booleanVariableDefinition, setLocationInfoFunction);
 
  414    qi::on_success(integerVariableDefinition, setLocationInfoFunction);
 
  415    qi::on_success(clockVariableDefinition, setLocationInfoFunction);
 
  416    qi::on_success(moduleDefinition, setLocationInfoFunction);
 
  417    qi::on_success(moduleRenaming, setLocationInfoFunction);
 
  418    qi::on_success(renamedModule, setLocationInfoFunction);
 
  419    qi::on_success(formulaDefinition, setLocationInfoFunction);
 
  420    qi::on_success(rewardModelDefinition, setLocationInfoFunction);
 
  421    qi::on_success(labelDefinition, setLocationInfoFunction);
 
  422    qi::on_success(observableDefinition, setLocationInfoFunction);
 
  423    qi::on_success(commandDefinition, setLocationInfoFunction);
 
  424    qi::on_success(updateDefinition, setLocationInfoFunction);
 
  425    qi::on_success(assignmentDefinition, setLocationInfoFunction);
 
  428    qi::on_error<qi::fail>(start, handler(qi::_1, qi::_2, qi::_3, qi::_4));
 
  431void PrismParserGrammar::moveToSecondRun() {
 
  434    STORM_LOG_THROW(observables.empty(), storm::exceptions::WrongFormatException,
 
  435                    "Some variables marked as observable, but never declared, e.g. " << *observables.begin());
 
  438        (((qi::lit(
"[") > -identifier > qi::lit(
"]")) | (qi::lit(
"<") > -identifier > qi::lit(
">")[qi::_a = 
true])) > *expressionParser > qi::lit(
"->") >
 
  439         updateListDefinition(qi::_r1) >
 
  440         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createCommand, phoenix::ref(*
this), qi::_a, qi::_1, qi::_2, qi::_3, qi::_r1)];
 
  442    auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
 
  443    qi::on_success(commandDefinition, setLocationInfoFunction);
 
  445    formulaDefinition = (qi::lit(
"formula") > identifier > qi::lit(
"=") > *expressionParser >
 
  446                         qi::lit(
";"))[qi::_val = phoenix::bind(&PrismParserGrammar::createFormulaSecondRun, phoenix::ref(*
this), qi::_1, qi::_2)];
 
  447    formulaDefinition.name(
"formula definition");
 
  448    this->secondRun = 
true;
 
  449    this->expressionParser->setIdentifierMapping(&this->identifiers_);
 
  454    createFormulaIdentifiers(this->globalProgramInformation.
formulas);
 
  459void PrismParserGrammar::createFormulaIdentifiers(std::vector<storm::prism::Formula> 
const& formulas) {
 
  460    STORM_LOG_THROW(formulas.size() == this->formulaExpressions.size(), storm::exceptions::UnexpectedException,
 
  461                    "Unexpected number of formulas and formula expressions");
 
  462    this->formulaOrder.clear();
 
  468    bool progress = 
true;
 
  471        for (uint64_t formulaIndex = unprocessed.getNextSetIndex(0); formulaIndex < formulas.size();
 
  472             formulaIndex = unprocessed.getNextSetIndex(formulaIndex + 1)) {
 
  476                unprocessed.set(formulaIndex, 
false);
 
  477                formulaOrder.push_back(formulaIndex);
 
  481                        variable = manager->declareIntegerVariable(formulas[formulaIndex].getName());
 
  483                        variable = manager->declareBooleanVariable(formulas[formulaIndex].getName());
 
  486                                         "Unexpected type for formula expression of formula " << formulas[formulaIndex].getName());
 
  487                        variable = manager->declareRationalVariable(formulas[formulaIndex].getName());
 
  489                    this->identifiers_.add(formulas[formulaIndex].getName(), variable.
getExpression());
 
  490                } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  492                                    "Parsing error in " << this->getFilename() << 
": illegal identifier '" << formulas[formulaIndex].getName() << 
"' at line '" 
  493                                                        << formulas[formulaIndex].getLineNumber());
 
  495                this->expressionParser->setIdentifierMapping(&this->identifiers_);
 
  499    if (!unprocessed.empty()) {
 
  500        for (
auto formulaIndex : unprocessed) {
 
  501            STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Invalid expression for formula '" << formulas[formulaIndex].getName()
 
  502                                                << 
"' at line '" << formulas[formulaIndex].getLineNumber() << 
"':\n\t" << formulaExpressions[formulaIndex]);
 
  504        STORM_LOG_THROW(unprocessed.getNumberOfSetBits() == 1, storm::exceptions::WrongFormatException,
 
  505                        "Unable to parse expressions for " << unprocessed.getNumberOfSetBits() << 
" formulas. This could be due to circular dependencies");
 
  507                        "Unable to parse expression for formula '" << formulas[unprocessed.getNextSetIndex(0)].getName() << 
"'.");
 
  511void PrismParserGrammar::allowDoubleLiterals(
bool flag) {
 
  512    this->expressionParser->setAcceptDoubleLiterals(flag);
 
  515std::string 
const& PrismParserGrammar::getFilename()
 const {
 
  516    return this->filename;
 
  519bool PrismParserGrammar::isValidIdentifier(std::string 
const& identifier) {
 
  520    if (this->keywords_.find(identifier) != 
nullptr) {
 
  526bool PrismParserGrammar::isKnownModuleName(std::string 
const& moduleName, 
bool inSecondRun) {
 
  527    if ((this->secondRun == inSecondRun) && this->globalProgramInformation.
moduleToIndexMap.count(moduleName) == 0) {
 
  528        STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Unknown module '" << moduleName << 
"'.");
 
  534bool PrismParserGrammar::isFreshModuleName(std::string 
const& moduleName) {
 
  535    if (!this->secondRun && this->globalProgramInformation.
moduleToIndexMap.count(moduleName) != 0) {
 
  536        STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Duplicate module name '" << moduleName << 
"'.");
 
  542bool PrismParserGrammar::isKnownActionName(std::string 
const& actionName, 
bool inSecondRun) {
 
  543    if ((this->secondRun == inSecondRun) && this->globalProgramInformation.
actionIndices.count(actionName) == 0) {
 
  544        STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Unknown action label '" << actionName << 
"'.");
 
  550bool PrismParserGrammar::isFreshIdentifier(std::string 
const& identifier) {
 
  551    if (!this->secondRun && this->manager->hasVariable(identifier)) {
 
  552        STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Duplicate identifier '" << identifier << 
"'.");
 
  558bool PrismParserGrammar::isFreshLabelName(std::string 
const& labelName) {
 
  559    if (!this->secondRun) {
 
  560        for (
auto const& existingLabel : this->globalProgramInformation.labels) {
 
  561            if (labelName == existingLabel.getName()) {
 
  562                STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Duplicate label name '" << identifier << 
"'.");
 
  570bool PrismParserGrammar::isFreshObservationLabelName(std::string 
const& labelName) {
 
  571    if (!this->secondRun) {
 
  572        for (
auto const& existingLabel : this->globalProgramInformation.observationLabels) {
 
  573            if (labelName == existingLabel.getName()) {
 
  574                STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Duplicate observable name '" << identifier << 
"'.");
 
  582bool PrismParserGrammar::isFreshRewardModelName(std::string 
const& rewardModelName) {
 
  583    if (!this->secondRun) {
 
  584        for (
auto const& existingRewardModel : this->globalProgramInformation.rewardModels) {
 
  585            if (rewardModelName == existingRewardModel.getName()) {
 
  586                STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": Duplicate reward model name '" << identifier << 
"'.");
 
  594bool PrismParserGrammar::isFreshPlayerName(std::string 
const& playerName) {
 
  611                                                   GlobalProgramInformation& globalProgramInformation) {
 
  612    STORM_LOG_THROW(!globalProgramInformation.hasInitialConstruct, storm::exceptions::WrongFormatException,
 
  613                    "Parsing error in " << this->getFilename() << 
": Program must not define two initial constructs.");
 
  614    if (globalProgramInformation.hasInitialConstruct) {
 
  617    globalProgramInformation.hasInitialConstruct = 
true;
 
  622bool PrismParserGrammar::addSystemCompositionConstruct(std::shared_ptr<storm::prism::Composition> 
const& composition,
 
  623                                                       GlobalProgramInformation& globalProgramInformation) {
 
  630                    "Parsing error in " << this->getFilename() << 
": Program must not set model type multiple times.");
 
  631    globalProgramInformation.modelType = modelType;
 
  634std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createModuleComposition(std::string 
const& moduleName)
 const {
 
  635    return std::make_shared<storm::prism::ModuleComposition>(moduleName);
 
  638std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createRenamingComposition(std::shared_ptr<storm::prism::Composition> 
const& subcomposition,
 
  639                                                                                         std::map<std::string, std::string> 
const& renaming)
 const {
 
  640    return std::make_shared<storm::prism::RenamingComposition>(subcomposition, renaming);
 
  643std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createHidingComposition(std::shared_ptr<storm::prism::Composition> 
const& subcomposition,
 
  644                                                                                       std::set<std::string> 
const& actionsToHide)
 const {
 
  645    return std::make_shared<storm::prism::HidingComposition>(subcomposition, actionsToHide);
 
  648std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createSynchronizingParallelComposition(
 
  649    std::shared_ptr<storm::prism::Composition> 
const& left, std::shared_ptr<storm::prism::Composition> 
const& right)
 const {
 
  650    return std::make_shared<storm::prism::SynchronizingParallelComposition>(left, right);
 
  653std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createInterleavingParallelComposition(
 
  654    std::shared_ptr<storm::prism::Composition> 
const& left, std::shared_ptr<storm::prism::Composition> 
const& right)
 const {
 
  655    return std::make_shared<storm::prism::InterleavingParallelComposition>(left, right);
 
  658std::shared_ptr<storm::prism::Composition> PrismParserGrammar::createRestrictedParallelComposition(
 
  659    std::shared_ptr<storm::prism::Composition> 
const& left, std::set<std::string> 
const& synchronizingActions,
 
  660    std::shared_ptr<storm::prism::Composition> 
const& right)
 const {
 
  661    return std::make_shared<storm::prism::RestrictedParallelComposition>(left, synchronizingActions, right);
 
  664storm::prism::Constant PrismParserGrammar::createUndefinedBooleanConstant(std::string 
const& newConstant)
 const {
 
  665    if (!this->secondRun) {
 
  668            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  669        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  671                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  677storm::prism::Constant PrismParserGrammar::createUndefinedIntegerConstant(std::string 
const& newConstant)
 const {
 
  678    if (!this->secondRun) {
 
  681            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  682        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  684                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  690storm::prism::Constant PrismParserGrammar::createUndefinedDoubleConstant(std::string 
const& newConstant)
 const {
 
  691    if (!this->secondRun) {
 
  694            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  695        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  697                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  704    if (!this->secondRun) {
 
  707            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  708        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  710                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  717    if (!this->secondRun) {
 
  720            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  721        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  723                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  730    if (!this->secondRun) {
 
  733            this->identifiers_.add(newConstant, newVariable.
getExpression());
 
  734        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  736                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << newConstant << 
"'.");
 
  742storm::prism::Formula PrismParserGrammar::createFormulaFirstRun(std::string 
const& formulaName, std::string 
const& expression) {
 
  745    STORM_LOG_ASSERT(!this->secondRun, 
"This constructor should have only been called during the first run.");
 
  746    formulaExpressions.push_back(expression);
 
  752    STORM_LOG_ASSERT(this->secondRun, 
"This constructor should have only been called during the second run.");
 
  765storm::prism::RewardModel PrismParserGrammar::createRewardModel(std::string 
const& rewardModelName, std::vector<storm::prism::StateReward> 
const& stateRewards,
 
  766                                                                std::vector<storm::prism::StateActionReward> 
const& stateActionRewards,
 
  767                                                                std::vector<storm::prism::TransitionReward> 
const& transitionRewards)
 const {
 
  768    return storm::prism::RewardModel(rewardModelName, stateRewards, stateActionRewards, transitionRewards, this->getFilename());
 
  773    if (this->secondRun) {
 
  783                                                                            GlobalProgramInformation& globalProgramInformation)
 const {
 
  784    if (this->secondRun) {
 
  785        std::string realActionName = actionName ? actionName.get() : 
"";
 
  787        auto const& nameIndexPair = globalProgramInformation.actionIndices.find(realActionName);
 
  788        STORM_LOG_THROW(nameIndexPair != globalProgramInformation.actionIndices.end(), storm::exceptions::WrongFormatException,
 
  789                        "Action reward refers to illegal action '" << realActionName << 
"'.");
 
  800                                                                          GlobalProgramInformation& globalProgramInformation)
 const {
 
  801    if (this->secondRun) {
 
  802        std::string realActionName = actionName ? actionName.get() : 
"";
 
  804        auto const& nameIndexPair = globalProgramInformation.actionIndices.find(realActionName);
 
  805        STORM_LOG_THROW(nameIndexPair != globalProgramInformation.actionIndices.end(), storm::exceptions::WrongFormatException,
 
  806                        "Transition reward refers to illegal action '" << realActionName << 
"'.");
 
  808                                              rewardValueExpression, this->getFilename());
 
  819                                                      std::vector<storm::prism::Assignment> 
const& assignments,
 
  820                                                      GlobalProgramInformation& globalProgramInformation)
 const {
 
  821    ++globalProgramInformation.currentUpdateIndex;
 
  822    if (!likelihoodExpressions.first.isInitialized()) {
 
  823        likelihoodExpressions.first = manager->rational(1);
 
  825    return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpressions, assignments, this->getFilename());
 
  828storm::prism::Command PrismParserGrammar::createCommand(
bool markovian, boost::optional<std::string> 
const& actionName,
 
  830                                                        GlobalProgramInformation& globalProgramInformation)
 const {
 
  831    ++globalProgramInformation.currentCommandIndex;
 
  832    std::string realActionName = actionName ? actionName.get() : 
"";
 
  834    uint_fast64_t actionIndex = 0;
 
  837    auto nameIndexPair = globalProgramInformation.actionIndices.find(realActionName);
 
  838    if (nameIndexPair == globalProgramInformation.actionIndices.end()) {
 
  839        std::size_t nextIndex = globalProgramInformation.actionIndices.size();
 
  840        globalProgramInformation.actionIndices.emplace(realActionName, nextIndex);
 
  841        actionIndex = nextIndex;
 
  843        actionIndex = nameIndexPair->second;
 
  845    return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, markovian, actionIndex, realActionName, guardExpression, updates,
 
  846                                 this->getFilename());
 
  849storm::prism::Command PrismParserGrammar::createDummyCommand(boost::optional<std::string> 
const& actionName,
 
  850                                                             GlobalProgramInformation& globalProgramInformation)
 const {
 
  851    STORM_LOG_ASSERT(!this->secondRun, 
"Dummy procedure must not be called in second run.");
 
  852    std::string realActionName = actionName ? actionName.get() : 
"";
 
  855    auto nameIndexPair = globalProgramInformation.actionIndices.find(realActionName);
 
  856    if (nameIndexPair == globalProgramInformation.actionIndices.end()) {
 
  857        std::size_t nextIndex = globalProgramInformation.actionIndices.size();
 
  858        globalProgramInformation.actionIndices.emplace(realActionName, nextIndex);
 
  866    if (!this->secondRun) {
 
  869            this->identifiers_.add(variableName, newVariable.
getExpression());
 
  870        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  872                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << variableName << 
"'.");
 
  875    bool observable = this->observables.count(variableName) > 0;
 
  877        this->observables.erase(variableName);
 
  885    if (!this->secondRun) {
 
  888            this->identifiers_.add(variableName, newVariable.
getExpression());
 
  889        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  891                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << variableName << 
"'.");
 
  894    bool observable = this->observables.count(variableName) > 0;
 
  896        this->observables.erase(variableName);
 
  899    return storm::prism::IntegerVariable(manager->getVariable(variableName), lowerBoundExpression, upperBoundExpression, initialValueExpression, observable,
 
  900                                         this->getFilename());
 
  904    if (!this->secondRun) {
 
  907            this->identifiers_.add(variableName, newVariable.
getExpression());
 
  908        } 
catch (storm::exceptions::InvalidArgumentException 
const& e) {
 
  910                            "Parsing error in " << this->getFilename() << 
": illegal identifier '" << variableName << 
"'.");
 
  913    bool observable = this->observables.count(variableName) > 0;
 
  915        this->observables.erase(variableName);
 
  921void PrismParserGrammar::createObservablesList(std::vector<std::string> 
const& observables) {
 
  922    this->observables.insert(observables.begin(), observables.end());
 
  926storm::prism::Player PrismParserGrammar::createPlayer(std::string 
const& playerName, std::vector<std::string> 
const& moduleNames,
 
  927                                                      std::vector<std::string> 
const& actionNames) {
 
  928    if (this->secondRun) {
 
  929        std::unordered_set<std::string> controlledModules;
 
  930        std::unordered_set<std::string> controlledActions;
 
  931        for (
auto const& moduleName : moduleNames) {
 
  932            auto moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(moduleName);
 
  933            STORM_LOG_ASSERT(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(),
 
  934                             "Parsing error in " << this->getFilename() << 
" for player " << playerName << 
": No module named '" << moduleName << 
"' present.");
 
  935            controlledModules.insert(moduleIndexPair->first);
 
  936            bool moduleNotYetControlled = globalProgramInformation.playerControlledModules.insert(moduleIndexPair->second).second;
 
  937            STORM_LOG_THROW(moduleNotYetControlled, storm::exceptions::WrongFormatException,
 
  938                            "Parsing error in " << this->getFilename() << 
" for player " << playerName << 
": Module '" << moduleName
 
  939                                                << 
"' already controlled by another player.");
 
  941        for (std::string actionName : actionNames) {
 
  942            auto actionIndexPair = globalProgramInformation.actionIndices.find(actionName);
 
  943            STORM_LOG_ASSERT(actionIndexPair != globalProgramInformation.actionIndices.end(),
 
  944                             "Parsing error in " << this->getFilename() << 
" for player " << playerName << 
": No action named '" << actionName << 
"' present.");
 
  945            controlledActions.insert(actionIndexPair->first);
 
  946            bool actionNotYetControlled = globalProgramInformation.playerControlledActions.insert(actionIndexPair->second).second;
 
  947            STORM_LOG_THROW(actionNotYetControlled, storm::exceptions::WrongFormatException,
 
  948                            "Parsing error in " << this->getFilename() << 
" for player " << playerName << 
": Command '" << actionName
 
  949                                                << 
"' already controlled by another player.");
 
  957storm::prism::Module PrismParserGrammar::createModule(std::string 
const& moduleName, std::vector<storm::prism::BooleanVariable> 
const& booleanVariables,
 
  958                                                      std::vector<storm::prism::IntegerVariable> 
const& integerVariables,
 
  959                                                      std::vector<storm::prism::ClockVariable> 
const& clockVariables,
 
  960                                                      boost::optional<storm::expressions::Expression> 
const& invariant,
 
  961                                                      std::vector<storm::prism::Command> 
const& commands,
 
  962                                                      GlobalProgramInformation& globalProgramInformation)
 const {
 
  963    if (!this->secondRun) {
 
  964        globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size();
 
  967    STORM_LOG_ASSERT(!this->secondRun || globalProgramInformation.moduleToIndexMap.count(moduleName) > 0, 
"Module name '" << moduleName << 
"' was not found.");
 
  968    STORM_LOG_ASSERT(!this->secondRun || globalProgramInformation.moduleToIndexMap[moduleName] == globalProgramInformation.modules.size(),
 
  969                     "The index for module '" << moduleName << 
"' does not match the index from the first parsing run.");
 
  971                                invariant.is_initialized() ? invariant.get() : 
storm::expressions::Expression(), commands, this->getFilename());
 
  975                                               GlobalProgramInformation 
const& globalProgramInformation)
 const {
 
  976    if (!this->secondRun) {
 
  977        auto const& renaming = moduleRenaming.
getRenaming();
 
  978        auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
 
  979        if (moduleIndexPair == globalProgramInformation.moduleToIndexMap.end()) {
 
  980            STORM_LOG_ERROR(
"Parsing error in " << this->getFilename() << 
": No module named '" << oldModuleName << 
"' to rename.");
 
  983        storm::prism::Module const& moduleToRename = globalProgramInformation.modules[moduleIndexPair->second];
 
  985        for (
auto const& variable : moduleToRename.getBooleanVariables()) {
 
  986            auto const& renamingPair = renaming.find(variable.
getName());
 
  987            if (renamingPair == renaming.end()) {
 
  988                STORM_LOG_ERROR(
"Parsing error in renaming of module '" << oldModuleName << 
"': Boolean variable '" << variable.
getName()
 
  989                                                                        << 
"' was not renamed.");
 
  993        for (
auto const& variable : moduleToRename.getIntegerVariables()) {
 
  994            auto const& renamingPair = renaming.find(variable.
getName());
 
  995            if (renamingPair == renaming.end()) {
 
  996                STORM_LOG_ERROR(
"Parsing error in renaming of module '" << oldModuleName << 
"': Integer variable '" << variable.
getName()
 
  997                                                                        << 
"' was not renamed.");
 
 1001        for (
auto const& variable : moduleToRename.getClockVariables()) {
 
 1002            auto const& renamingPair = renaming.find(variable.
getName());
 
 1003            if (renamingPair == renaming.end()) {
 
 1004                STORM_LOG_ERROR(
"Parsing error in renaming of module '" << oldModuleName << 
"': Clock variable '" << variable.
getName()
 
 1005                                                                        << 
"' was not renamed.");
 
 1017storm::prism::Module PrismParserGrammar::createRenamedModule(std::string 
const& newModuleName, std::string 
const& oldModuleName,
 
 1019                                                             GlobalProgramInformation& globalProgramInformation)
 const {
 
 1021    auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
 
 1022    STORM_LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException,
 
 1023                    "Parsing error in " << this->getFilename() << 
": No module named '" << oldModuleName << 
"' to rename.");
 
 1024    storm::prism::Module const& moduleToRename = globalProgramInformation.modules[moduleIndexPair->second];
 
 1026                    "Parsing error in " << this->getFilename() << 
": The module '" << newModuleName << 
"' can not be created from module '" << oldModuleName
 
 1027                                        << 
"' through module renaming because '" << oldModuleName << 
"' is also a renamed module. Create '" << newModuleName
 
 1028                                        << 
"' via a renaming from base module '" << moduleToRename.
getBaseModule() << 
"' instead.");
 
 1029    auto const& renaming = moduleRenaming.
getRenaming();
 
 1030    if (!this->secondRun) {
 
 1032        globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size();
 
 1036        for (
auto const& variable : moduleToRename.getBooleanVariables()) {
 
 1037            auto const& renamingPair = renaming.find(variable.
getName());
 
 1038            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1039                            "Parsing error in " << this->getFilename() << 
": Boolean variable '" << variable.
getName() << 
" was not renamed.");
 
 1041            this->identifiers_.add(renamingPair->second, renamedVariable.
getExpression());
 
 1042            if (this->observables.count(renamingPair->second) > 0) {
 
 1043                this->observables.erase(renamingPair->second);
 
 1046        for (
auto const& variable : moduleToRename.getIntegerVariables()) {
 
 1047            auto const& renamingPair = renaming.find(variable.
getName());
 
 1048            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1049                            "Parsing error in " << this->getFilename() << 
": Integer variable '" << variable.
getName() << 
" was not renamed.");
 
 1051            this->identifiers_.add(renamingPair->second, renamedVariable.
getExpression());
 
 1052            if (this->observables.count(renamingPair->second) > 0) {
 
 1053                this->observables.erase(renamingPair->second);
 
 1056        for (
auto const& variable : moduleToRename.getClockVariables()) {
 
 1057            auto const& renamingPair = renaming.find(variable.
getName());
 
 1058            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1059                            "Parsing error in " << this->getFilename() << 
": Clock variable '" << variable.
getName() << 
" was not renamed.");
 
 1061            this->identifiers_.add(renamingPair->second, renamedVariable.
getExpression());
 
 1062            if (this->observables.count(renamingPair->second) > 0) {
 
 1063                this->observables.erase(renamingPair->second);
 
 1067        for (
auto const& command : moduleToRename.getCommands()) {
 
 1068            std::string newActionName = command.getActionName();
 
 1069            auto const& renamingPair = renaming.find(command.getActionName());
 
 1070            if (renamingPair != renaming.end()) {
 
 1071                newActionName = renamingPair->second;
 
 1075            auto nameIndexPair = globalProgramInformation.actionIndices.find(newActionName);
 
 1076            if (nameIndexPair == globalProgramInformation.actionIndices.end()) {
 
 1077                std::size_t nextIndex = globalProgramInformation.actionIndices.size();
 
 1078                globalProgramInformation.actionIndices.emplace(newActionName, nextIndex);
 
 1086        STORM_LOG_ASSERT(globalProgramInformation.moduleToIndexMap.count(newModuleName) > 0, 
"Module name '" << newModuleName << 
"' was not found.");
 
 1087        STORM_LOG_ASSERT(globalProgramInformation.moduleToIndexMap[newModuleName] == globalProgramInformation.modules.size(),
 
 1088                         "The index for module " << newModuleName << 
" does not match the index from the first parsing run.");
 
 1091        std::map<storm::expressions::Variable, storm::expressions::Expression> expressionRenaming;
 
 1092        for (
auto const& namePair : renaming) {
 
 1095            if (substitutedExpression != 
nullptr) {
 
 1096                expressionRenaming.emplace(manager->getVariable(namePair.first), *substitutedExpression);
 
 1101        std::vector<storm::prism::BooleanVariable> booleanVariables;
 
 1102        for (
auto const& variable : moduleToRename.getBooleanVariables()) {
 
 1103            auto const& renamingPair = renaming.find(variable.
getName());
 
 1104            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1105                            "Parsing error in " << this->getFilename() << 
": Boolean variable '" << variable.
getName() << 
" was not renamed.");
 
 1106            bool observable = this->observables.count(renamingPair->second) > 0;
 
 1108                this->observables.erase(renamingPair->second);
 
 1111                manager->getVariable(renamingPair->second),
 
 1112                variable.hasInitialValue() ? variable.getInitialValueExpression().substitute(expressionRenaming) : variable.getInitialValueExpression(),
 
 1113                observable, this->getFilename(), moduleRenaming.getLineNumber()));
 
 1117        std::vector<storm::prism::IntegerVariable> integerVariables;
 
 1118        for (
auto const& variable : moduleToRename.getIntegerVariables()) {
 
 1119            auto const& renamingPair = renaming.find(variable.
getName());
 
 1120            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1121                            "Parsing error in " << this->getFilename() << 
": Integer variable '" << variable.
getName() << 
" was not renamed.");
 
 1122            bool observable = this->observables.count(renamingPair->second) > 0;
 
 1124                this->observables.erase(renamingPair->second);
 
 1127                manager->getVariable(renamingPair->second), variable.getLowerBoundExpression().substitute(expressionRenaming),
 
 1128                variable.getUpperBoundExpression().substitute(expressionRenaming),
 
 1129                variable.hasInitialValue() ? variable.getInitialValueExpression().substitute(expressionRenaming) : variable.getInitialValueExpression(),
 
 1130                observable, this->getFilename(), moduleRenaming.getLineNumber()));
 
 1134        std::vector<storm::prism::ClockVariable> clockVariables;
 
 1135        for (
auto const& variable : moduleToRename.getClockVariables()) {
 
 1136            auto const& renamingPair = renaming.find(variable.
getName());
 
 1137            STORM_LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException,
 
 1138                            "Parsing error in " << this->getFilename() << 
": Clock variable '" << variable.
getName() << 
" was not renamed.");
 
 1139            bool observable = this->observables.count(renamingPair->second) > 0;
 
 1141                this->observables.erase(renamingPair->second);
 
 1143            clockVariables.push_back(
 
 1154        std::vector<storm::prism::Command> commands;
 
 1155        for (
auto const& command : moduleToRename.getCommands()) {
 
 1156            std::vector<storm::prism::Update> updates;
 
 1157            for (
auto const& update : command.getUpdates()) {
 
 1158                std::vector<storm::prism::Assignment> assignments;
 
 1159                for (
auto const& assignment : update.getAssignments()) {
 
 1160                    auto const& renamingPair = renaming.find(assignment.getVariableName());
 
 1161                    if (renamingPair != renaming.end()) {
 
 1162                        assignments.emplace_back(manager->getVariable(renamingPair->second), assignment.getExpression().substitute(expressionRenaming),
 
 1165                        assignments.emplace_back(assignment.getVariable(), assignment.getExpression().substitute(expressionRenaming), this->getFilename(),
 
 1169                if (update.isLikelihoodInterval()) {
 
 1171                        update.getLikelihoodExpressionInterval().first.
substitute(expressionRenaming),
 
 1172                        update.getLikelihoodExpressionInterval().second.
substitute(expressionRenaming)};
 
 1173                    updates.emplace_back(globalProgramInformation.currentUpdateIndex, likelihoodInterval, assignments, this->getFilename(),
 
 1176                    updates.emplace_back(globalProgramInformation.currentUpdateIndex, update.getLikelihoodExpression().substitute(expressionRenaming),
 
 1177                                         assignments, this->getFilename(), moduleRenaming.
getLineNumber());
 
 1179                ++globalProgramInformation.currentUpdateIndex;
 
 1182            std::string newActionName = command.getActionName();
 
 1183            auto const& renamingPair = renaming.find(command.getActionName());
 
 1184            if (renamingPair != renaming.end()) {
 
 1185                newActionName = renamingPair->second;
 
 1188            uint_fast64_t actionIndex = 0;
 
 1189            auto nameIndexPair = globalProgramInformation.actionIndices.find(newActionName);
 
 1190            if (nameIndexPair == globalProgramInformation.actionIndices.end()) {
 
 1191                std::size_t nextIndex = globalProgramInformation.actionIndices.size();
 
 1192                globalProgramInformation.actionIndices.emplace(newActionName, nextIndex);
 
 1193                actionIndex = nextIndex;
 
 1195                actionIndex = nameIndexPair->second;
 
 1198            commands.emplace_back(globalProgramInformation.currentCommandIndex, command.isMarkovian(), actionIndex, newActionName,
 
 1199                                  command.getGuardExpression().substitute(expressionRenaming), updates, this->getFilename(), moduleRenaming.
getLineNumber());
 
 1200            ++globalProgramInformation.currentCommandIndex;
 
 1203        return storm::prism::Module(newModuleName, booleanVariables, integerVariables, clockVariables, invariant, commands, oldModuleName, renaming);
 
 1207storm::prism::Program PrismParserGrammar::createProgram(GlobalProgramInformation 
const& globalProgramInformation)
 const {
 
 1210        STORM_LOG_WARN(
"Program does not specify model type. Implicitly assuming 'mdp'.");
 
 1215    std::vector<storm::prism::Formula> orderedFormulas;
 
 1216    if (this->secondRun) {
 
 1217        orderedFormulas.reserve(globalProgramInformation.formulas.size());
 
 1218        for (uint64_t 
const& i : formulaOrder) {
 
 1219            orderedFormulas.push_back(std::move(globalProgramInformation.formulas[i]));
 
 1224        manager, finalModelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables,
 
 1225        globalProgramInformation.globalIntegerVariables, orderedFormulas, globalProgramInformation.players, globalProgramInformation.modules,
 
 1226        globalProgramInformation.actionIndices, globalProgramInformation.rewardModels, globalProgramInformation.labels,
 
 1227        globalProgramInformation.observationLabels,
 
 1228        secondRun && !globalProgramInformation.hasInitialConstruct ? boost::none : 
boost::make_optional(globalProgramInformation.initialConstruct),
 
 1229        globalProgramInformation.systemCompositionConstruct, prismCompatibility, this->getFilename(), 1, this->secondRun);
 
 1232void PrismParserGrammar::removeInitialConstruct(GlobalProgramInformation& globalProgramInformation)
 const {
 
boost::spirit::line_pos_iterator< BaseIteratorType > PositionIteratorType
 
PositionIteratorType Iterator
 
VariableExpression const & asVariableExpression() const
 
bool hasNumericalType() const
Retrieves whether the expression has a numerical return type, i.e., integer or double.
 
bool hasBooleanType() const
Retrieves whether the expression has a boolean return type.
 
bool hasIntegerType() const
Retrieves whether the expression has an integral return type.
 
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
 
Expression substitute(std::map< Variable, Expression > const &variableToExpressionMap) const
Substitutes all occurrences of the variables according to the given map.
 
bool isInitialized() const
Checks whether the object encapsulates a base-expression.
 
Variable const & getVariable() const
Retrieves the variable associated with this expression.
 
storm::expressions::Expression getExpression() const
Retrieves an expression that represents the variable.
 
std::string const & getName() const
Retrieves the name of the variable.
 
static storm::prism::Program parseFromString(std::string const &input, std::string const &filename, bool prismCompatability=false)
Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM synt...
 
static storm::prism::Program parse(std::string const &filename, bool prismCompatability=false)
Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
 
std::string const & getBaseModule() const
If the module was created via renaming, this method retrieves the name of the module that was used as...
 
storm::expressions::Expression const & getInvariant() const
Returns the specified invariant (only relevant for PTA models)
 
bool isRenamedFromModule() const
Retrieves whether this module was created from another module via renaming.
 
bool hasInvariant() const
Returns true, if an invariant was specified (only relevant for PTA models)
 
std::map< std::string, std::string > const & getRenaming() const
If the module was created via renaming, this method returns the applied renaming of identifiers used ...
 
ModelType
An enum for the different model types.
 
bool hasInitialConstruct() const
Retrieves whether the program specifies an initial construct.
 
std::pair< storm::expressions::Expression, storm::expressions::Expression > ExpressionPair
 
A bit vector that is internally represented as a vector of 64-bit values.
 
#define STORM_LOG_WARN(message)
 
#define STORM_LOG_DEBUG(message)
 
#define STORM_LOG_TRACE(message)
 
#define STORM_LOG_ERROR(message)
 
#define STORM_LOG_ASSERT(cond, message)
 
#define STORM_LOG_THROW(cond, exception, message)
 
void closeFile(std::ofstream &stream)
Close the given file after writing.
 
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.