diff --git a/src/storm/builder/DdPrismModelBuilder.cpp b/src/storm/builder/DdPrismModelBuilder.cpp index 0075f91f5..3a5b6e23e 100644 --- a/src/storm/builder/DdPrismModelBuilder.cpp +++ b/src/storm/builder/DdPrismModelBuilder.cpp @@ -1103,7 +1103,16 @@ namespace storm { } template - storm::models::symbolic::StandardRewardModel DdPrismModelBuilder::createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix, boost::optional> stateActionDd) { + std::unordered_map> DdPrismModelBuilder::createRewardModelDecisionDiagrams(std::vector> const& selectedRewardModels, SystemResult& system, GenerationInformation& generationInfo, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix) { + std::unordered_map> rewardModels; + for (auto const& rewardModel : selectedRewardModels) { + rewardModels.emplace(rewardModel.get().getName(), createRewardModelDecisionDiagrams(generationInfo, rewardModel.get(), globalModule, reachableStatesAdd, transitionMatrix, system.stateActionDd)); + } + return rewardModels; + } + + template + storm::models::symbolic::StandardRewardModel DdPrismModelBuilder::createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix, boost::optional>& stateActionDd) { // Start by creating the state reward vector. boost::optional> stateRewards; @@ -1141,15 +1150,16 @@ namespace storm { } ActionDecisionDiagram const& actionDd = stateActionReward.isLabeled() ? globalModule.synchronizingActionToDecisionDiagramMap.at(stateActionReward.getActionIndex()) : globalModule.independentAction; states *= actionDd.guardDd * reachableStatesAdd; - storm::dd::Add stateActionRewardDd = synchronization * (reachableStatesAdd * states * rewards); + storm::dd::Add stateActionRewardDd = synchronization * states * rewards; // If we are building the state-action rewards for an MDP, we need to make sure that the encoding // of the nondeterminism is present in the reward vector, so we ne need to multiply it with the // legal state-actions. if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - // FIXME: get synchronization encoding differently. - // stateActionRewardDd *= stateActionDd; - stateActionRewardDd *= transitionMatrix.notZero().existsAbstract(generationInfo.columnMetaVariables).template toAdd(); + if (!stateActionDd) { + stateActionDd = transitionMatrix.notZero().existsAbstract(generationInfo.columnMetaVariables).template toAdd(); + } + stateActionRewardDd *= stateActionDd.get(); } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { // For CTMCs, we need to multiply the entries with the exit rate of the corresponding action. stateActionRewardDd *= actionDd.transitionsDd.sumAbstract(generationInfo.columnMetaVariables); @@ -1165,7 +1175,10 @@ namespace storm { // Scale state-action rewards for DTMCs and CTMCs. if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - // stateActionRewards.get() /= stateActionDd; + if (!stateActionDd) { + stateActionDd = transitionMatrix.sumAbstract(generationInfo.columnMetaVariables); + } + stateActionRewards.get() /= stateActionDd.get(); } } @@ -1381,10 +1394,7 @@ namespace storm { selectedRewardModels.push_back(program.getRewardModel(0)); } - std::unordered_map> rewardModels; - for (auto const& rewardModel : selectedRewardModels) { - rewardModels.emplace(rewardModel.get().getName(), createRewardModelDecisionDiagrams(generationInfo, rewardModel.get(), globalModule, reachableStatesAdd, transitionMatrix, system.stateActionDd)); - } + std::unordered_map> rewardModels = createRewardModelDecisionDiagrams(selectedRewardModels, system, generationInfo, globalModule, reachableStatesAdd, transitionMatrix); // Build the labels that can be accessed as a shortcut. std::map labelToExpressionMapping; @@ -1395,7 +1405,7 @@ namespace storm { if (program.getModelType() == storm::prism::Program::ModelType::DTMC) { return std::shared_ptr>(new storm::models::symbolic::Dtmc(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); } else if (program.getModelType() == storm::prism::Program::ModelType::CTMC) { - return std::shared_ptr>(new storm::models::symbolic::Ctmc(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); + return std::shared_ptr>(new storm::models::symbolic::Ctmc(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, system.stateActionDd, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { return std::shared_ptr>(new storm::models::symbolic::Mdp(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, rewardModels)); } else { diff --git a/src/storm/builder/DdPrismModelBuilder.h b/src/storm/builder/DdPrismModelBuilder.h index 701a2ecdc..7abbe08b0 100644 --- a/src/storm/builder/DdPrismModelBuilder.h +++ b/src/storm/builder/DdPrismModelBuilder.h @@ -230,7 +230,9 @@ namespace storm { static storm::dd::Add createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module); - static storm::models::symbolic::StandardRewardModel createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix, boost::optional> stateActionDd); + static std::unordered_map> createRewardModelDecisionDiagrams(std::vector> const& selectedRewardModels, SystemResult& system, GenerationInformation& generationInfo, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix); + + static storm::models::symbolic::StandardRewardModel createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add const& reachableStatesAdd, storm::dd::Add const& transitionMatrix, boost::optional>& stateActionDd); static SystemResult createSystemDecisionDiagram(GenerationInformation& generationInfo); diff --git a/src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp b/src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp index 7a55f0c8a..0f37d1b45 100644 --- a/src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp +++ b/src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp @@ -32,6 +32,8 @@ namespace storm { namespace builder { namespace jit { + static const std::string JIT_VARIABLE_EXTENSION = "_jit_"; + #ifdef LINUX static const std::string DYLIB_EXTENSION = ".so"; #endif @@ -924,19 +926,19 @@ namespace storm { if (hasLocationRewards) { cpptempl::data_map locationReward; - locationReward["variable"] = variable.getName(); + locationReward["variable"] = variable.getName() + JIT_VARIABLE_EXTENSION; locationRewards.push_back(locationReward); } if (hasEdgeRewards) { cpptempl::data_map edgeReward; - edgeReward["variable"] = variable.getName(); + edgeReward["variable"] = variable.getName() + JIT_VARIABLE_EXTENSION; edgeReward["index"] = asString(rewardModelIndex); edgeRewards.push_back(edgeReward); } if (hasDestinationRewards) { cpptempl::data_map destinationReward; destinationReward["index"] = asString(rewardModelIndex); - destinationReward["variable"] = variable.getName(); + destinationReward["variable"] = variable.getName() + JIT_VARIABLE_EXTENSION; destinationRewards.push_back(destinationReward); } ++rewardModelIndex; @@ -1578,7 +1580,7 @@ namespace storm { template std::string const& ExplicitJitJaniModelBuilder::registerVariable(storm::expressions::Variable const& variable, bool transient) { // Since the variable name might be illegal as a C++ identifier, we need to prepare it a bit. - variableToName[variable] = variable.getName() + "_jit_"; + variableToName[variable] = variable.getName() + JIT_VARIABLE_EXTENSION; if (transient) { transientVariables.insert(variable); variablePrefixes[variable] = "transientIn."; diff --git a/src/storm/builder/jit/StateBehaviour.cpp b/src/storm/builder/jit/StateBehaviour.cpp index a14261e1f..40cf06895 100644 --- a/src/storm/builder/jit/StateBehaviour.cpp +++ b/src/storm/builder/jit/StateBehaviour.cpp @@ -73,13 +73,14 @@ namespace storm { if (modelType == storm::jani::ModelType::CTMC) { for (auto const& choice : choices) { ValueType massOfChoice = storm::utility::zero(); - for (auto const& entry : choices.front().getDistribution()) { + for (auto const& entry : choice.getDistribution()) { massOfChoice += entry.getValue(); } - + totalExitRate += massOfChoice; + auto outIt = newRewards.begin(); for (auto const& reward : choice.getRewards()) { - *outIt += reward * massOfChoice / totalExitRate; + *outIt += reward * massOfChoice; ++outIt; } } @@ -87,12 +88,16 @@ namespace storm { for (auto const& choice : choices) { auto outIt = newRewards.begin(); for (auto const& reward : choice.getRewards()) { - *outIt += reward / totalExitRate; + *outIt += reward; ++outIt; } } } + for (auto& entry : newRewards) { + entry /= totalExitRate; + } + choices.front().setRewards(std::move(newRewards)); } diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index c7fe2497c..b5a3d420b 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -467,6 +467,9 @@ namespace storm { // If the new state was already found as a successor state, update the probability // and otherwise insert it. auto probability = stateProbabilityPair.second * this->evaluator->asRational(destination.getProbability()); + if (edge.hasRate()) { + probability *= this->evaluator->asRational(edge.getRate()); + } if (probability != storm::utility::zero()) { auto targetStateIt = newTargetStates->find(newTargetState); if (targetStateIt != newTargetStates->end()) { diff --git a/src/storm/logic/FragmentSpecification.cpp b/src/storm/logic/FragmentSpecification.cpp index 0790c48a6..0d4771552 100644 --- a/src/storm/logic/FragmentSpecification.cpp +++ b/src/storm/logic/FragmentSpecification.cpp @@ -325,7 +325,6 @@ namespace storm { return *this; } - bool FragmentSpecification::areTotalRewardFormulasAllowed() const { return totalRewardFormula; } diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp index c528d4e12..4d6e9407f 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -49,7 +49,7 @@ namespace storm { template::SupportsExponential, int>::type> bool SparseCtmcCslModelChecker::canHandleImplementation(CheckTask const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isInFragment(storm::logic::prctl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true)); + return formula.isInFragment(storm::logic::prctl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true)); } template diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 15cbe2c64..02d3c5133 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -496,12 +496,6 @@ namespace storm { solver->solveEquations(bsccEquationSystemSolution, bsccEquationSystemRightSide); } -// std::vector tmp(probabilityMatrix.getRowCount(), storm::utility::zero()); -// probabilityMatrix.multiplyVectorWithMatrix(bsccEquationSystemSolution, tmp); -// for (uint64_t i = 0; i < tmp.size(); ++i) { -// std::cout << tmp[i] << " vs. " << bsccEquationSystemSolution[i] << std::endl; -// } - // If exit rates were given, we need to 'fix' the results to also account for the timing behaviour. if (exitRateVector != nullptr) { std::vector bsccTotalValue(bsccDecomposition.size(), zero); @@ -513,11 +507,7 @@ namespace storm { bsccEquationSystemSolution[indexInStatesInBsccs[*stateIter]] = (bsccEquationSystemSolution[indexInStatesInBsccs[*stateIter]] * (one / (*exitRateVector)[*stateIter])) / bsccTotalValue[stateToBsccIndexMap[indexInStatesInBsccs[*stateIter]]]; } } - -// for (auto const& val : bsccEquationSystemSolution) { -// std::cout << "val: " << val << std::endl; -// } - + // Calculate LRA Value for each BSCC from steady state distribution in BSCCs. for (uint_fast64_t bsccIndex = 0; bsccIndex < bsccDecomposition.size(); ++bsccIndex) { storm::storage::StronglyConnectedComponent const& bscc = bsccDecomposition[bsccIndex]; diff --git a/src/storm/models/sparse/StandardRewardModel.cpp b/src/storm/models/sparse/StandardRewardModel.cpp index 1866be5d2..59dfee941 100644 --- a/src/storm/models/sparse/StandardRewardModel.cpp +++ b/src/storm/models/sparse/StandardRewardModel.cpp @@ -165,11 +165,6 @@ namespace storm { template template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const { - if (this->hasStateActionRewards()) { - for (auto const& e : this->getStateActionRewardVector()) { - std::cout << "e " << e << std::endl; - } - } std::vector result = this->hasTransitionRewards() ? transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()) : (this->hasStateActionRewards() ? this->getStateActionRewardVector() : std::vector(transitionMatrix.getRowCount())); if (this->hasStateActionRewards() && this->hasTransitionRewards()) { storm::utility::vector::addVectors(result, this->getStateActionRewardVector(), result); diff --git a/src/storm/models/symbolic/Ctmc.cpp b/src/storm/models/symbolic/Ctmc.cpp index e3dd2e724..410e247b5 100644 --- a/src/storm/models/symbolic/Ctmc.cpp +++ b/src/storm/models/symbolic/Ctmc.cpp @@ -24,12 +24,33 @@ namespace storm { std::map labelToExpressionMap, std::unordered_map const& rewardModels) : DeterministicModel(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) { - exitRates = this->getTransitionMatrix().sumAbstract(this->getColumnVariables()); + // Intentionally left empty. } - + + template + Ctmc::Ctmc(std::shared_ptr> manager, + storm::dd::Bdd reachableStates, + storm::dd::Bdd initialStates, + storm::dd::Bdd deadlockStates, + storm::dd::Add transitionMatrix, + boost::optional> exitRateVector, + std::set const& rowVariables, + std::shared_ptr> rowExpressionAdapter, + std::set const& columnVariables, + std::shared_ptr> columnExpressionAdapter, + std::vector> const& rowColumnMetaVariablePairs, + std::map labelToExpressionMap, + std::unordered_map const& rewardModels) + : DeterministicModel(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels), exitRates(exitRateVector) { + // Intentionally left empty. + } + template storm::dd::Add const& Ctmc::getExitRateVector() const { - return exitRates; + if (!exitRates) { + exitRates = this->getTransitionMatrix().sumAbstract(this->getColumnVariables()); + } + return exitRates.get(); } // Explicitly instantiate the template class. diff --git a/src/storm/models/symbolic/Ctmc.h b/src/storm/models/symbolic/Ctmc.h index 8701ed148..c0c4054a3 100644 --- a/src/storm/models/symbolic/Ctmc.h +++ b/src/storm/models/symbolic/Ctmc.h @@ -54,7 +54,40 @@ namespace storm { std::vector> const& rowColumnMetaVariablePairs, std::map labelToExpressionMap = std::map(), std::unordered_map const& rewardModels = std::unordered_map()); - + + /*! + * Constructs a model from the given data. + * + * @param manager The manager responsible for the decision diagrams. + * @param reachableStates A DD representing the reachable states. + * @param initialStates A DD representing the initial states of the model. + * @param deadlockStates A DD representing the deadlock states of the model. + * @param transitionMatrix The matrix representing the transitions in the model. + * @param exitRateVector The vector specifying the exit rates for the states. + * @param rowVariables The set of row meta variables used in the DDs. + * @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row + * meta variables. + * @param columVariables The set of column meta variables used in the DDs. + * @param columnExpressionAdapter An object that can be used to translate expressions in terms of the + * column meta variables. + * @param rowColumnMetaVariablePairs All pairs of row/column meta variables. + * @param labelToExpressionMap A mapping from label names to their defining expressions. + * @param rewardModels The reward models associated with the model. + */ + Ctmc(std::shared_ptr> manager, + storm::dd::Bdd reachableStates, + storm::dd::Bdd initialStates, + storm::dd::Bdd deadlockStates, + storm::dd::Add transitionMatrix, + boost::optional> exitRateVector, + std::set const& rowVariables, + std::shared_ptr> rowExpressionAdapter, + std::set const& columnVariables, + std::shared_ptr> columnExpressionAdapter, + std::vector> const& rowColumnMetaVariablePairs, + std::map labelToExpressionMap = std::map(), + std::unordered_map const& rewardModels = std::unordered_map()); + /*! * Retrieves the exit rate vector of the CTMC. * @@ -63,7 +96,7 @@ namespace storm { storm::dd::Add const& getExitRateVector() const; private: - storm::dd::Add exitRates; + mutable boost::optional> exitRates; }; } // namespace symbolic diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index 18ff5b247..43bbb670b 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -32,6 +32,14 @@ namespace storm { } FormulaParser::FormulaParser(storm::prism::Program const& program) : manager(program.getManager().getSharedPointer()), grammar(new FormulaParserGrammar(manager)) { + this->addFormulasAsIdentifiers(program); + } + + FormulaParser::FormulaParser(storm::prism::Program& program) : manager(program.getManager().getSharedPointer()), grammar(new FormulaParserGrammar(manager)) { + this->addFormulasAsIdentifiers(program); + } + + void FormulaParser::addFormulasAsIdentifiers(storm::prism::Program const& program) { // Make the formulas of the program available to the parser. for (auto const& formula : program.getFormulas()) { this->addIdentifierExpression(formula.getName(), formula.getExpression()); diff --git a/src/storm/parser/FormulaParser.h b/src/storm/parser/FormulaParser.h index c9aa5c5f3..d9c06fa92 100644 --- a/src/storm/parser/FormulaParser.h +++ b/src/storm/parser/FormulaParser.h @@ -29,6 +29,7 @@ namespace storm { explicit FormulaParser(std::shared_ptr const& manager); explicit FormulaParser(std::shared_ptr const& manager); explicit FormulaParser(storm::prism::Program const& program); + explicit FormulaParser(storm::prism::Program& program); FormulaParser(FormulaParser const& other); FormulaParser& operator=(FormulaParser const& other); @@ -67,6 +68,8 @@ namespace storm { void addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression); private: + void addFormulasAsIdentifiers(storm::prism::Program const& program); + // The manager used to parse expressions. std::shared_ptr manager; diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index fe46e8ca5..e0326dd09 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -213,7 +213,7 @@ namespace storm { } boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { - stream << expression.getValue(); + stream << "(" << expression.getValue() << ")"; return boost::any(); } } diff --git a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp index 4ff7db433..8a3643842 100644 --- a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp +++ b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp @@ -78,8 +78,13 @@ namespace storm { } template - boost::any ToRationalNumberVisitor::visit(UnaryNumericalFunctionExpression const&, boost::any const& ) { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational number."); + boost::any ToRationalNumberVisitor::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) { + RationalNumberType operandAsRationalNumber = boost::any_cast(expression.getOperand()->accept(*this, data)); + switch (expression.getOperatorType()) { + case UnaryNumericalFunctionExpression::OperatorType::Minus: return -operandAsRationalNumber; + case UnaryNumericalFunctionExpression::OperatorType::Floor: return storm::utility::floor(operandAsRationalNumber); + case UnaryNumericalFunctionExpression::OperatorType::Ceil: return storm::utility::ceil(operandAsRationalNumber); + } } template diff --git a/src/storm/storage/prism/ToJaniConverter.cpp b/src/storm/storage/prism/ToJaniConverter.cpp index a544c9d83..963683b19 100644 --- a/src/storm/storage/prism/ToJaniConverter.cpp +++ b/src/storm/storage/prism/ToJaniConverter.cpp @@ -141,6 +141,7 @@ namespace storm { // Now create the separate JANI automata from the modules of the PRISM program. While doing so, we use the // previously built mapping to make variables global that are read by more than one module. + std::set firstModules; bool firstModule = true; for (auto const& module : program.getModules()) { // Keep track of the action indices contained in this module. @@ -179,7 +180,7 @@ namespace storm { uint64_t onlyLocationIndex = automaton.addLocation(storm::jani::Location("l")); automaton.addInitialLocation(onlyLocationIndex); - // If we are translating the first module, we need to add the transient assignments to the location. + // If we are translating the first module that has the action, we need to add the transient assignments to the location. if (firstModule) { storm::jani::Location& onlyLocation = automaton.getLocation(onlyLocationIndex); for (auto const& assignment : transientLocationAssignments) { @@ -189,7 +190,7 @@ namespace storm { for (auto const& command : module.getCommands()) { std::shared_ptr templateEdge = automaton.createTemplateEdge(command.getGuardExpression()); - actionIndicesOfModule.insert(command.getActionIndex()); + actionIndicesOfModule.insert(janiModel.getActionIndex(command.getActionName())); boost::optional rateExpression; if (program.getModelType() == Program::ModelType::CTMC || program.getModelType() == Program::ModelType::CTMDP || (program.getModelType() == Program::ModelType::MA && command.isMarkovian())) { @@ -226,7 +227,6 @@ namespace storm { for (auto const& assignment : transientEdgeAssignmentsToAdd->second) { templateEdge->addTransientAssignment(assignment); } - transientEdgeAssignments.erase(transientEdgeAssignmentsToAdd); } // Create the edge object. diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index d5cf20a46..66805146b 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -195,6 +195,16 @@ namespace storm { return std::fabs(number); } + template + ValueType floor(ValueType const& number) { + return std::floor(number); + } + + template + ValueType ceil(ValueType const& number) { + return std::ceil(number); + } + template<> std::pair minmax(std::vector const&) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Minimum/maximum for rational functions is not defined."); @@ -376,7 +386,17 @@ namespace storm { RationalNumber abs(storm::RationalNumber const& number) { return carl::abs(number); } - + + template<> + RationalNumber floor(storm::RationalNumber const& number) { + return carl::floor(number); + } + + template<> + RationalNumber ceil(storm::RationalNumber const& number) { + return carl::ceil(number); + } + template<> RationalNumber pow(RationalNumber const& value, uint_fast64_t exponent) { return carl::pow(value, exponent); @@ -502,15 +522,13 @@ namespace storm { template std::pair minmax(std::map const&); template double minimum(std::map const&); template double maximum(std::map const&); - + +#ifdef STORM_HAVE_CARL + // Instantiations for rational number. template std::pair minmax(std::map const&); template storm::RationalNumber minimum(std::map const&); template storm::RationalNumber maximum(std::map const&); - template storm::RationalFunction minimum(std::map const&); - template storm::RationalFunction maximum(std::map const&); -#ifdef STORM_HAVE_CARL - // Instantiations for rational number. template bool isOne(storm::RationalNumber const& value); template bool isZero(storm::RationalNumber const& value); template bool isConstant(storm::RationalNumber const& value); @@ -526,8 +544,9 @@ namespace storm { RationalNumber convertNumber(std::string const& number); template storm::RationalNumber sqrt(storm::RationalNumber const& number); - template storm::RationalNumber abs(storm::RationalNumber const& number); + template storm::RationalNumber floor(storm::RationalNumber const& number); + template storm::RationalNumber ceil(storm::RationalNumber const& number); template storm::RationalNumber pow(storm::RationalNumber const& value, uint_fast64_t exponent); @@ -561,6 +580,9 @@ namespace storm { template Interval one(); template Interval zero(); + + template storm::RationalFunction minimum(std::map const&); + template storm::RationalFunction maximum(std::map const&); template storm::storage::MatrixEntry simplify(storm::storage::MatrixEntry matrixEntry); template storm::storage::MatrixEntry& simplify(storm::storage::MatrixEntry& matrixEntry); diff --git a/src/storm/utility/constants.h b/src/storm/utility/constants.h index e8bd62de0..26259d98b 100644 --- a/src/storm/utility/constants.h +++ b/src/storm/utility/constants.h @@ -85,7 +85,13 @@ namespace storm { template ValueType abs(ValueType const& number); - + + template + ValueType floor(ValueType const& number); + + template + ValueType ceil(ValueType const& number); + template bool isInteger(ValueType const& number);