50 this->initializeSpecialStates();
53 this->evaluator = std::make_unique<storm::expressions::ExpressionEvaluator<BaseValueType>>(program.
getManager());
56 for (
auto const& rewardModel : this->program.getRewardModels()) {
57 rewardModels.push_back(rewardModel);
61 for (
auto const& rewardModelName : this->options.getRewardModelNames()) {
63 rewardModels.push_back(this->program.
getRewardModel(rewardModelName));
65 STORM_LOG_THROW(rewardModelName.empty(), storm::exceptions::InvalidArgumentException,
66 "Cannot build unknown reward model '" << rewardModelName <<
"'.");
68 "Reference to standard reward model is ambiguous.");
74 if (rewardModels.empty() && !this->options.getRewardModelNames().empty()) {
80 for (
auto const& rewardModel : rewardModels) {
81 hasStateActionRewards |= rewardModel.get().hasStateActionRewards();
86 for (
auto const& expressionOrLabelAndBool : this->options.getTerminalStates()) {
87 if (expressionOrLabelAndBool.first.isExpression()) {
88 this->terminalStates.push_back(std::make_pair(expressionOrLabelAndBool.first.getExpression(), expressionOrLabelAndBool.second));
90 if (program.
hasLabel(expressionOrLabelAndBool.first.getLabel())) {
91 this->terminalStates.push_back(
92 std::make_pair(this->program.
getLabelExpression(expressionOrLabelAndBool.first.getLabel()), expressionOrLabelAndBool.second));
95 STORM_LOG_THROW(this->isSpecialLabel(expressionOrLabelAndBool.first.getLabel()), storm::exceptions::InvalidArgumentException,
96 "Terminal states refer to illegal label '" << expressionOrLabelAndBool.first.getLabel() <<
"'.");
108template<
typename ValueType,
typename StateType>
114template<
typename ValueType,
typename StateType>
117#ifdef STORM_HAVE_CARL
122 std::vector<std::reference_wrapper<storm::prism::Constant const>> undefinedConstants = program.
getUndefinedConstants();
123 std::stringstream stream;
124 bool printComma =
false;
125 for (
auto const& constant : undefinedConstants) {
131 stream << constant.get().getName() <<
" (" << constant.get().getType() <<
")";
134 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"Program still contains these undefined constants: " + stream.str());
136#ifdef STORM_HAVE_CARL
140 "The program contains undefined constants that appear in some places other than update probabilities and reward value expressions, "
141 "which is not admitted. Undefined constants are: "
147template<
typename ValueType,
typename StateType>
163 STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException,
"Invalid model type.");
167template<
typename ValueType,
typename StateType>
172template<
typename ValueType,
typename StateType>
177template<
typename ValueType,
typename StateType>
182template<
typename ValueType,
typename StateType>
184 std::vector<StateType> initialStateIndices;
189 std::vector<std::vector<uint64_t>> allValues;
190 for (
auto const& intVar : this->variableInformation.integerVariables) {
191 STORM_LOG_ASSERT(intVar.lowerBound <= intVar.upperBound,
"Expecting variable with non-empty set of possible values.");
193 allValues.push_back(storm::utility::vector::buildVectorForRange<uint64_t>(
static_cast<uint64_t
>(0), intVar.upperBound + 1 - intVar.lowerBound));
195 uint64_t intEndIndex = allValues.size();
197 allValues.resize(allValues.size() + this->variableInformation.booleanVariables.size(),
198 std::vector<uint64_t>({static_cast<uint64_t>(0), static_cast<uint64_t>(1)}));
200 std::vector<std::vector<uint64_t>::const_iterator> its;
201 std::vector<std::vector<uint64_t>::const_iterator> ites;
202 for (
auto const& valVec : allValues) {
203 its.push_back(valVec.cbegin());
204 ites.push_back(valVec.cend());
208 CompressedState initialState(this->variableInformation.getTotalBitOffset(
true));
211 [
this, &initialState, &intEndIndex](uint64_t index, uint64_t value) {
213 if (index < intEndIndex) {
215 auto const& intVar = this->variableInformation.integerVariables[index];
216 initialState.
setFromInt(intVar.bitOffset, intVar.bitWidth, value);
219 STORM_LOG_ASSERT(index - intEndIndex < this->variableInformation.booleanVariables.size(),
"Unexpected index");
220 auto const& boolVar = this->variableInformation.booleanVariables[index - intEndIndex];
222 initialState.
set(boolVar.bitOffset,
static_cast<bool>(value));
225 [&stateToIdCallback, &initialStateIndices, &initialState]() {
227 StateType
id = stateToIdCallback(initialState);
228 initialStateIndices.push_back(
id);
231 STORM_LOG_DEBUG(
"Enumerated " << initialStateIndices.size() <<
" initial states using brute force enumeration.");
235 std::unique_ptr<storm::solver::SmtSolver> solver = factory.
create(program.
getManager());
238 for (
auto const& expression : rangeExpressions) {
239 solver->add(expression);
246 CompressedState initialState(this->variableInformation.getTotalBitOffset(
true));
251 std::shared_ptr<storm::solver::SmtSolver::ModelReference> model = solver->getModel();
252 for (
auto const& booleanVariable : this->variableInformation.booleanVariables) {
253 bool variableValue = model->getBooleanValue(booleanVariable.variable);
255 blockingExpression = blockingExpression.
isInitialized() ? blockingExpression || localBlockingExpression : localBlockingExpression;
256 initialState.
set(booleanVariable.bitOffset, variableValue);
258 for (
auto const& integerVariable : this->variableInformation.integerVariables) {
259 int_fast64_t variableValue = model->getIntegerValue(integerVariable.variable);
261 blockingExpression = blockingExpression.
isInitialized() ? blockingExpression || localBlockingExpression : localBlockingExpression;
262 initialState.
setFromInt(integerVariable.bitOffset, integerVariable.bitWidth,
263 static_cast<uint_fast64_t
>(variableValue - integerVariable.lowerBound));
267 StateType
id = stateToIdCallback(initialState);
268 initialStateIndices.push_back(
id);
274 solver->add(blockingExpression);
277 STORM_LOG_DEBUG(
"Enumerated " << initialStateIndices.size() <<
" initial states using SMT solving.");
280 return initialStateIndices;
283template<
typename ValueType,
typename StateType>
290 for (
auto const& rewardModel : rewardModels) {
291 ValueType stateRewardValue = storm::utility::zero<ValueType>();
292 if (rewardModel.get().hasStateRewards()) {
293 for (
auto const& stateReward : rewardModel.get().getStateRewards()) {
294 if (this->evaluator->asBool(stateReward.getStatePredicateExpression())) {
295 stateRewardValue += ValueType(this->evaluator->asRational(stateReward.getRewardValueExpression()));
303 if (!this->terminalStates.empty()) {
304 for (
auto const& expressionBool : this->terminalStates) {
305 if (this->evaluator->asBool(expressionBool.first) == expressionBool.second) {
306 if (!isPartiallyObservable()) {
312 std::vector<Choice<ValueType>> allChoices = getSelfLoopsForAllActions(*this->state, stateToIdCallback);
313 if (allChoices.size() != 0) {
314 for (
auto& choice : allChoices) {
318 this->postprocess(result);
329 std::vector<Choice<ValueType>> allChoices;
330 if (this->getOptions().isApplyMaximalProgressAssumptionSet()) {
332 allChoices = getAsynchronousChoices(*this->state, stateToIdCallback, CommandFilter::Probabilistic);
333 addSynchronousChoices(allChoices, *this->state, stateToIdCallback, CommandFilter::Probabilistic);
334 if (allChoices.empty()) {
336 allChoices = getAsynchronousChoices(*this->state, stateToIdCallback, CommandFilter::Markovian);
337 addSynchronousChoices(allChoices, *this->state, stateToIdCallback, CommandFilter::Markovian);
340 allChoices = getAsynchronousChoices(*this->state, stateToIdCallback);
341 addSynchronousChoices(allChoices, *this->state, stateToIdCallback);
346 if (allChoices.empty()) {
351 if (this->isDeterministicModel() && allChoices.size() > 1) {
355 this->overlappingGuardStates->push_back(stateToIdCallback(*this->state));
360 ValueType
const totalNumberOfChoices = storm::utility::convertNumber<ValueType, uint64_t>(allChoices.size());
361 ValueType totalExitRate = this->isDiscreteTimeModel() ? totalNumberOfChoices : storm::utility::zero<ValueType>();
364 for (
auto const& choice : allChoices) {
365 for (
auto const& stateProbabilityPair : choice) {
366 if (this->isDiscreteTimeModel()) {
367 globalChoice.
addProbability(stateProbabilityPair.first, stateProbabilityPair.second / totalNumberOfChoices);
369 globalChoice.
addProbability(stateProbabilityPair.first, stateProbabilityPair.second);
373 if (hasStateActionRewards && !this->isDiscreteTimeModel()) {
374 totalExitRate += choice.getTotalMass();
378 globalChoice.
addLabels(choice.getLabels());
387 for (
auto const& rewardModel : rewardModels) {
388 ValueType stateActionRewardValue = storm::utility::zero<ValueType>();
389 if (rewardModel.get().hasStateActionRewards()) {
390 for (
auto const& stateActionReward : rewardModel.get().getStateActionRewards()) {
391 for (
auto const& choice : allChoices) {
392 if (stateActionReward.getActionIndex() == choice.getActionIndex() &&
393 this->evaluator->asBool(stateActionReward.getStatePredicateExpression())) {
394 stateActionRewardValue +=
395 ValueType(this->evaluator->asRational(stateActionReward.getRewardValueExpression())) * choice.getTotalMass();
400 if (hasStateActionRewards) {
401 globalChoice.
addReward(stateActionRewardValue / totalExitRate);
407 allChoices.push_back(std::move(globalChoice));
412 auto choiceIt = allChoices.begin();
414 "State '" << this->stateToString(*this->state)
415 <<
"' features a choice without player index.");
418 "State '" << this->stateToString(*this->state)
419 <<
"' features a choice with invalid player index.");
420 for (++choiceIt; choiceIt != allChoices.end(); ++choiceIt) {
422 "State '" << this->stateToString(*this->state)
423 <<
"' features a choice without player index.");
425 "State '" << this->stateToString(*this->state)
426 <<
"' features a choice with invalid player index.");
427 STORM_LOG_THROW(statePlayerIndex == choiceIt->getPlayerIndex(), storm::exceptions::WrongFormatException,
428 "The player for state '" << this->stateToString(*this->state) <<
"' is not unique. At least one choice is owned by player '"
429 << statePlayerIndex <<
"' while another is owned by player '" << choiceIt->getPlayerIndex() <<
"'.");
434 for (
auto& choice : allChoices) {
438 this->postprocess(result);
443template<
typename ValueType,
typename StateType>
445 return this->evaluator->asBool(expr);
448template<
typename ValueType,
typename StateType>
461 auto boolIt = this->variableInformation.booleanVariables.begin();
462 for (; assignmentIt != assignmentIte && assignmentIt->getExpression().hasBooleanType(); ++assignmentIt) {
463 while (assignmentIt->getVariable() != boolIt->variable) {
466 newState.set(boolIt->bitOffset, this->evaluator->asBool(assignmentIt->getExpression()));
470 auto integerIt = this->variableInformation.integerVariables.begin();
471 for (; assignmentIt != assignmentIte && assignmentIt->getExpression().hasIntegerType(); ++assignmentIt) {
472 while (assignmentIt->getVariable() != integerIt->variable) {
475 int_fast64_t assignedValue = this->evaluator->asInt(assignmentIt->getExpression());
477 if (assignedValue < integerIt->lowerBound || assignedValue > integerIt->upperBound) {
478 return this->outOfBoundsState;
480 }
else if (integerIt->forceOutOfBoundsCheck || this->options.isExplorationChecksSet()) {
481 STORM_LOG_THROW(assignedValue >= integerIt->lowerBound, storm::exceptions::WrongFormatException,
482 "The update " << update <<
" leads to an out-of-bounds value (" << assignedValue <<
") for the variable '"
483 << assignmentIt->getVariableName() <<
"'.");
484 STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException,
485 "The update " << update <<
" leads to an out-of-bounds value (" << assignedValue <<
") for the variable '"
486 << assignmentIt->getVariableName() <<
"'.");
488 newState.setFromInt(integerIt->bitOffset, integerIt->bitWidth, assignedValue - integerIt->lowerBound);
489 STORM_LOG_ASSERT(
static_cast<int_fast64_t
>(newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth)) + integerIt->lowerBound == assignedValue,
490 "Writing to the bit vector bucket failed (read " << newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth) <<
" but wrote "
491 << assignedValue <<
").");
495 STORM_LOG_ASSERT(assignmentIt == assignmentIte,
"Not all assignments were consumed.");
511template<
typename ValueType,
typename StateType>
512boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>>
520 std::vector<ActiveCommandData> activeCommands;
525 if (!module.hasActionIndex(actionIndex)) {
529 std::set<uint_fast64_t>
const& commandIndices =
module.getCommandIndicesByActionIndex(actionIndex);
533 if (commandIndices.empty()) {
538 bool hasOneEnabledCommand =
false;
539 for (
auto commandIndexIt = commandIndices.begin(), commandIndexIte = commandIndices.end(); commandIndexIt != commandIndexIte; ++commandIndexIt) {
541 if (!isCommandPotentiallySynchronizing(command)) {
544 if (commandFilter != CommandFilter::All) {
545 STORM_LOG_ASSERT(commandFilter == CommandFilter::Markovian || commandFilter == CommandFilter::Probabilistic,
"Unexpected command filter.");
546 if ((commandFilter == CommandFilter::Markovian) != command.
isMarkovian()) {
552 hasOneEnabledCommand =
true;
553 activeCommands.emplace_back(&module, &commandIndices, commandIndexIt);
558 if (!hasOneEnabledCommand) {
564 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>> result;
567 for (
auto const& activeCommand : activeCommands) {
568 std::vector<std::reference_wrapper<storm::prism::Command const>> commands;
570 auto commandIndexIt = activeCommand.currentCommandIndexIt;
572 commands.push_back(activeCommand.modulePtr->getCommand(*commandIndexIt));
575 auto commandIndexIte = activeCommand.commandIndicesPtr->end();
576 for (++commandIndexIt; commandIndexIt != commandIndexIte; ++commandIndexIt) {
578 if (commandFilter != CommandFilter::All) {
579 STORM_LOG_ASSERT(commandFilter == CommandFilter::Markovian || commandFilter == CommandFilter::Probabilistic,
"Unexpected command filter.");
580 if ((commandFilter == CommandFilter::Markovian) != command.
isMarkovian()) {
585 commands.push_back(command);
589 result.push_back(std::move(commands));
596template<
typename ValueType,
typename BaseValueType>
598 if constexpr (storm::IsIntervalType<ValueType>) {
602 return ValueType(lower, carl::BoundType::WEAK, upper, carl::BoundType::WEAK);
613template<
typename ValueType,
typename StateType>
614std::vector<Choice<ValueType>> PrismNextStateGenerator<ValueType, StateType>::getAsynchronousChoices(
CompressedState const& state,
615 StateToIdCallback stateToIdCallback,
616 CommandFilter
const& commandFilter) {
617 std::vector<Choice<ValueType>> result;
624 for (uint_fast64_t j = 0; j <
module.getNumberOfCommands(); ++j) {
628 if (isCommandPotentiallySynchronizing(command))
631 if (commandFilter != CommandFilter::All) {
632 STORM_LOG_ASSERT(commandFilter == CommandFilter::Markovian || commandFilter == CommandFilter::Probabilistic,
"Unexpected command filter.");
633 if ((commandFilter == CommandFilter::Markovian) != command.
isMarkovian()) {
637 if (this->actionMask !=
nullptr) {
649 Choice<ValueType>& choice = result.back();
654 choice.addOriginData(boost::any(std::move(commandIndex)));
658 ValueType probabilitySum = storm::utility::zero<ValueType>();
662 ValueType probability = evaluateLikelihoodExpression<ValueType>(update, *this->evaluator);
663 if (probability != storm::utility::zero<ValueType>()) {
666 StateType stateIndex = stateToIdCallback(applyUpdate(state, update));
669 choice.addProbability(stateIndex, probability);
671 if constexpr (!std::is_same_v<ValueType, storm::RationalFunction>) {
672 STORM_LOG_THROW(probability > storm::utility::zero<ValueType>(), storm::exceptions::WrongFormatException,
673 "Probability expression in update '" << update <<
" evaluates to negative value " << probability <<
".");
675 storm::exceptions::WrongFormatException,
676 "Probability expression in update '" << update <<
" evaluates to value " << probability <<
" >1.");
678 probabilitySum += probability;
684 for (
auto const& rewardModel : rewardModels) {
685 ValueType stateActionRewardValue = storm::utility::zero<ValueType>();
686 if (rewardModel.get().hasStateActionRewards()) {
687 for (
auto const& stateActionReward : rewardModel.get().getStateActionRewards()) {
688 if (stateActionReward.getActionIndex() == choice.getActionIndex() &&
689 this->evaluator->asBool(stateActionReward.getStatePredicateExpression())) {
690 stateActionRewardValue +=
ValueType(this->evaluator->asRational(stateActionReward.getRewardValueExpression()));
694 choice.addReward(stateActionRewardValue);
704 auto const playerOfModule = moduleIndexToPlayerIndexMap.at(i);
706 "Module " << module.getName() <<
" is not owned by any player but has at least one enabled, unlabeled command.");
707 choice.setPlayerIndex(playerOfModule);
710 auto const playerOfAction = actionIndexToPlayerIndexMap.at(command.
getActionIndex());
713 choice.setPlayerIndex(playerOfAction);
720 storm::exceptions::WrongFormatException,
721 "Probabilities do not sum to one for command '" << command <<
"' (actually sum to " << probabilitySum <<
").");
729template<
typename ValueType,
typename StateType>
730std::vector<Choice<ValueType>> PrismNextStateGenerator<ValueType, StateType>::getSelfLoopsForAllActions(
CompressedState const& state,
731 StateToIdCallback stateToIdCallback,
732 CommandFilter
const& commandFilter) {
733 std::vector<Choice<ValueType>> result;
741 for (uint_fast64_t j = 0; j <
module.getNumberOfCommands(); ++j) {
745 if (isCommandPotentiallySynchronizing(command))
748 if (this->actionMask !=
nullptr) {
760 Choice<ValueType>& choice = result.back();
765 choice.addOriginData(boost::any(std::move(commandIndex)));
767 choice.addProbability(stateToIdCallback(*this->state), storm::utility::one<ValueType>());
770 for (
auto const& rewardModel : rewardModels) {
771 ValueType stateActionRewardValue = storm::utility::zero<ValueType>();
772 if (rewardModel.get().hasStateActionRewards()) {
773 for (
auto const& stateActionReward : rewardModel.get().getStateActionRewards()) {
774 if (stateActionReward.getActionIndex() == choice.getActionIndex() &&
775 this->evaluator->asBool(stateActionReward.getStatePredicateExpression())) {
776 stateActionRewardValue +=
ValueType(this->evaluator->asRational(stateActionReward.getRewardValueExpression()));
780 choice.addReward(stateActionRewardValue);
790 for (uint_fast64_t actionIndex : program.getSynchronizingActionIndices()) {
791 if (this->actionMask !=
nullptr) {
792 if (!this->actionMask->query(*
this, actionIndex)) {
796 boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> optionalActiveCommandLists =
797 getActiveCommandsByActionIndex(actionIndex, commandFilter);
800 if (optionalActiveCommandLists) {
801 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>
const& activeCommandList = optionalActiveCommandLists.get();
802 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>::const_iterator> iteratorList(activeCommandList.size());
805 for (
size_t i = 0;
i < activeCommandList.size(); ++
i) {
806 iteratorList[
i] = activeCommandList[
i].cbegin();
815 result.push_back(Choice<ValueType>(actionIndex));
818 Choice<ValueType>& choice = result.back();
825 CommandSet commandIndices;
826 for (uint_fast64_t i = 0;
i < iteratorList.size(); ++
i) {
827 commandIndices.insert(iteratorList[i]->get().getGlobalIndex());
829 choice.addOriginData(boost::any(std::move(commandIndices)));
831 choice.addProbability(stateToIdCallback(*this->state), storm::utility::one<ValueType>());
834 for (
auto const& rewardModel : rewardModels) {
835 ValueType stateActionRewardValue = storm::utility::zero<ValueType>();
836 if (rewardModel.get().hasStateActionRewards()) {
837 for (
auto const& stateActionReward : rewardModel.get().getStateActionRewards()) {
838 if (stateActionReward.getActionIndex() == choice.getActionIndex() &&
839 this->evaluator->asBool(stateActionReward.getStatePredicateExpression())) {
840 stateActionRewardValue +=
ValueType(this->evaluator->asRational(stateActionReward.getRewardValueExpression()));
844 choice.addReward(stateActionRewardValue);
848 bool movedIterator =
false;
849 for (int_fast64_t j = iteratorList.size() - 1; !movedIterator && j >= 0; --j) {
851 if (iteratorList[j] != activeCommandList[j].end()) {
852 movedIterator =
true;
855 iteratorList[j] = activeCommandList[j].begin();
859 done = !movedIterator;
867template<
typename ValueType,
typename StateType>
868void PrismNextStateGenerator<ValueType, StateType>::generateSynchronizedDistribution(
870 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>::const_iterator>
const& iteratorList,
872 if (storm::utility::isZero<ValueType>(probability)) {
876 if (position >= iteratorList.size()) {
877 StateType
id = stateToIdCallback(state);
878 distribution.
add(
id, std::move(probability));
883 ValueType updateProbability = evaluateLikelihoodExpression<ValueType>(update, *this->evaluator);
884 if constexpr (!std::is_same_v<ValueType, storm::RationalFunction>) {
886 STORM_LOG_THROW(updateProbability >= storm::utility::zero<ValueType>(), storm::exceptions::WrongFormatException,
887 "Probability expression in update '" << update <<
" evaluates to negative value " << updateProbability <<
".");
889 storm::exceptions::WrongFormatException,
890 "Probability expression in update '" << update <<
" evaluates to value " << updateProbability <<
" >1.");
893 updateProbability *= probability;
894 generateSynchronizedDistribution(applyUpdate(state, update), updateProbability, position + 1, iteratorList, distribution, stateToIdCallback);
899template<
typename ValueType,
typename StateType>
900void PrismNextStateGenerator<ValueType, StateType>::addSynchronousChoices(std::vector<Choice<ValueType>>& choices,
CompressedState const& state,
901 StateToIdCallback stateToIdCallback, CommandFilter
const& commandFilter) {
902 for (uint_fast64_t actionIndex : program.getSynchronizingActionIndices()) {
903 if (this->actionMask !=
nullptr) {
904 if (!this->actionMask->query(*
this, actionIndex)) {
908 boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> optionalActiveCommandLists =
909 getActiveCommandsByActionIndex(actionIndex, commandFilter);
912 if (optionalActiveCommandLists) {
913 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>
const& activeCommandList = optionalActiveCommandLists.get();
914 std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>::const_iterator> iteratorList(activeCommandList.size());
917 for (
size_t i = 0;
i < activeCommandList.size(); ++
i) {
918 iteratorList[
i] = activeCommandList[
i].cbegin();
926 distribution.
clear();
927 generateSynchronizedDistribution(state, storm::utility::one<ValueType>(), 0, iteratorList, distribution, stateToIdCallback);
933 choices.push_back(Choice<ValueType>(actionIndex));
936 Choice<ValueType>& choice = choices.back();
942 <<
" is not owned by any player but has at least one enabled, unlabeled (synchronized) command.");
943 choice.setPlayerIndex(playerOfAction);
951 CommandSet commandIndices;
952 for (uint_fast64_t i = 0;
i < iteratorList.size(); ++
i) {
953 commandIndices.insert(iteratorList[i]->get().getGlobalIndex());
955 choice.addOriginData(boost::any(std::move(commandIndices)));
959 ValueType probabilitySum = storm::utility::zero<ValueType>();
960 choice.reserve(std::distance(distribution.
begin(), distribution.
end()));
961 for (
auto const& stateProbability : distribution) {
962 choice.addProbability(stateProbability.getState(), stateProbability.getValue());
964 probabilitySum += stateProbability.getValue();
971 storm::exceptions::WrongFormatException,
972 "Sum of update probabilities do not some to one for some command (actually sum to " << probabilitySum <<
").");
976 for (
auto const& rewardModel : rewardModels) {
977 ValueType stateActionRewardValue = storm::utility::zero<ValueType>();
978 if (rewardModel.get().hasStateActionRewards()) {
979 for (
auto const& stateActionReward : rewardModel.get().getStateActionRewards()) {
980 if (stateActionReward.getActionIndex() == choice.getActionIndex() &&
981 this->evaluator->asBool(stateActionReward.getStatePredicateExpression())) {
982 stateActionRewardValue +=
ValueType(this->evaluator->asRational(stateActionReward.getRewardValueExpression()));
986 choice.addReward(stateActionRewardValue);
990 bool movedIterator =
false;
991 for (int_fast64_t j = iteratorList.size() - 1; !movedIterator && j >= 0; --j) {
993 if (iteratorList[j] != activeCommandList[j].end()) {
994 movedIterator =
true;
997 iteratorList[j] = activeCommandList[j].begin();
1001 done = !movedIterator;
1007template<
typename ValueType,
typename StateType>
1012template<
typename ValueType,
typename StateType>
1014 std::vector<StateType>
const& initialStateIndices,
1015 std::vector<StateType>
const& deadlockStateIndices,
1016 std::vector<StateType>
const& unexploredStateIndices) {
1018 std::vector<std::pair<std::string, storm::expressions::Expression>> labels;
1020 for (
auto const& label : program.
getLabels()) {
1021 labels.push_back(std::make_pair(label.getName(), label.getStatePredicateExpression()));
1024 for (
auto const& labelName : this->options.
getLabelNames()) {
1028 STORM_LOG_THROW(this->isSpecialLabel(labelName), storm::exceptions::InvalidArgumentException,
1029 "Cannot build labeling for unknown label '" << labelName <<
"'.");
1037template<
typename ValueType,
typename StateType>
1047 result.setFromInt(64 * i, 64, this->evaluator->asInt(program.
getObservationLabels()[i].getStatePredicateExpression()));
1052template<
typename ValueType,
typename StateType>
1059template<
typename ValueType,
typename StateType>
1061 return rewardModels.size();
1064template<
typename ValueType,
typename StateType>
1071template<
typename ValueType,
typename StateType>
1073 std::vector<boost::any>& dataForChoiceOrigins)
const {
1074 if (!this->getOptions().isBuildChoiceOriginsSet()) {
1078 std::vector<uint_fast64_t> identifiers;
1079 identifiers.reserve(dataForChoiceOrigins.size());
1081 std::map<CommandSet, uint_fast64_t> commandSetToIdentifierMap;
1084 commandSetToIdentifierMap.insert(std::make_pair(
CommandSet(), 0));
1085 uint_fast64_t currentIdentifier = 1;
1086 for (boost::any& originData : dataForChoiceOrigins) {
1087 STORM_LOG_ASSERT(originData.empty() || boost::any_cast<CommandSet>(&originData) !=
nullptr,
1088 "Origin data has unexpected type: " << originData.type().name() <<
".");
1090 CommandSet currentCommandSet = originData.empty() ?
CommandSet() : boost::any_cast<CommandSet>(std::move(originData));
1091 auto insertionRes = commandSetToIdentifierMap.insert(std::make_pair(std::move(currentCommandSet), currentIdentifier));
1092 identifiers.push_back(insertionRes.first->second);
1093 if (insertionRes.second) {
1094 ++currentIdentifier;
1098 std::vector<CommandSet> identifierToCommandSetMapping(currentIdentifier);
1099 for (
auto const& setIdPair : commandSetToIdentifierMap) {
1100 identifierToCommandSetMapping[setIdPair.second] = setIdPair.first;
1103 return std::make_shared<storm::storage::sparse::PrismChoiceOrigins>(std::make_shared<storm::prism::Program>(program), std::move(identifiers),
1104 std::move(identifierToCommandSetMapping));