80 using RewardValueType = RewardModelType::ValueType;
83 bool hasTransitionRewards =
false;
84 for (
auto const& rewardModelName : relevantRewardModelNames) {
85 auto const& rewardModel = originalModel->getRewardModel(rewardModelName);
86 if (rewardModel.hasTransitionRewards()) {
87 hasTransitionRewards =
true;
91 if (!hasTransitionRewards) {
92 return {originalModel->template as<storm::models::sparse::Model<ValueType, RewardModelType>>(),
99 std::vector<std::vector<detail::MultiRewardVector<RewardValueType>>> incomingRewards(originalModel->getNumberOfStates());
100 auto const& transitions = originalModel->getTransitionMatrix();
101 for (uint64_t row = 0; row < transitions.getRowCount(); ++row) {
109 std::vector<uint64_t> originalToNewIndex;
110 uint64_t numStates = 0;
111 for (
auto const& incomingRewardVectors : incomingRewards) {
112 numStates += incomingRewardVectors.size();
113 originalToNewIndex.push_back(numStates);
118 uint64_t
const numIntermediateStates = numStates - originalModel->getNumberOfStates();
119 bool const useGroups = !transitions.hasTrivialRowGrouping();
121 transitions.getEntryCount() + numIntermediateStates,
true, useGroups,
122 useGroups ? numStates : 0ull);
123 std::vector<std::vector<RewardValueType>> newActionRewards(relevantRewardModelNames.size(),
124 std::vector<RewardValueType>(transitions.getRowCount() + numIntermediateStates));
125 uint64_t currNewRow = 0;
126 for (uint64_t currOrigState = 0; currOrigState < originalModel->getNumberOfStates(); ++currOrigState) {
127 uint64_t
const currNewState = originalToNewIndex[currOrigState];
129 for (
auto const& incomingRewardVector : incomingRewards[currOrigState]) {
134 auto newRewIt = newActionRewards.begin();
135 for (
auto const& rew : incomingRewardVector) {
136 (*newRewIt)[currNewRow] = rew;
145 for (
auto origRowIndex : transitions.getRowGroupIndices(currOrigState)) {
148 [&newTransitionsBuilder, &originalToNewIndex, &incomingRewards, &currNewRow](uint64_t column, ValueType prob,
150 if (std::all_of(rewards.begin(), rewards.end(), [](RewardValueType
const& r) { return storm::utility::isZero(r); })) {
152 newTransitionsBuilder.
addNextValue(currNewRow, originalToNewIndex[column], prob);
155 auto incomingRewardsIt = std::find(incomingRewards[column].begin(), incomingRewards[column].end(), rewards);
156 STORM_LOG_ASSERT(incomingRewardsIt != incomingRewards[column].end(),
"Invalid incoming rewards.");
157 uint64_t
const intermediateStateIndex =
158 originalToNewIndex[column] - incomingRewards[column].size() + std::distance(incomingRewards[column].begin(), incomingRewardsIt);
159 newTransitionsBuilder.
addNextValue(currNewRow, intermediateStateIndex, prob);
168 for (
auto const& l : originalModel->getStateLabeling().getLabels()) {
170 for (
auto origIndex : originalModel->getStateLabeling().getStates(l)) {
177 uint64_t rewardIndex = 0;
178 for (
auto const& rewardModelName : relevantRewardModelNames) {
179 auto& newActionRewardVector = newActionRewards[rewardIndex++];
180 auto const& oldRewardModel = originalModel->getRewardModel(rewardModelName);
181 for (uint64_t oldState = 0; oldState < originalModel->getNumberOfStates(); ++oldState) {
182 uint64_t
const oldStartRow = transitions.getRowGroupIndices()[oldState];
183 uint64_t
const newState = originalToNewIndex[oldState];
184 uint64_t
const newStartRow = useGroups ? components.
transitionMatrix.getRowGroupIndices()[newState] : newState;
185 uint64_t
const numRowsInGroup = useGroups ? transitions.getRowGroupSize(oldState) : 1ull;
186 for (uint64_t groupOffset = 0; groupOffset < numRowsInGroup; ++groupOffset) {
187 auto& rewValue = newActionRewardVector[newStartRow + groupOffset];
188 if (originalModel->isDiscreteTimeModel() && oldRewardModel.hasStateRewards()) {
189 rewValue += oldRewardModel.getStateReward(oldState);
191 if (oldRewardModel.hasStateActionRewards()) {
192 rewValue += oldRewardModel.getStateActionReward(oldStartRow + groupOffset);
196 std::optional<std::vector<typename RewardModelType::ValueType>> newStateRewards;
197 if (!originalModel->isDiscreteTimeModel() && oldRewardModel.hasStateRewards()) {
199 for (uint64_t origState = 0; origState < originalModel->getNumberOfStates(); ++origState) {
200 uint64_t
const newState = originalToNewIndex[origState];
201 newStateRewards.value()[newState] = oldRewardModel.getStateReward(origState);
204 RewardModelType newRewardModel(std::move(newStateRewards), std::move(newActionRewardVector));
205 components.
rewardModels.emplace(rewardModelName, std::move(newRewardModel));
208 STORM_LOG_WARN_COND(!originalModel->hasChoiceLabeling(),
"Choice labellings will be dropped as the transformation is currently not implemented.");
209 STORM_LOG_WARN_COND(!originalModel->hasStateValuations(),
"State valuations will be dropped as the transformation is currently not implemented.");
210 STORM_LOG_WARN_COND(!originalModel->hasChoiceOrigins(),
"Choice origins will be dropped as the transformation is currently not implemented.");
214 auto const& ma = *originalModel->template as<storm::models::sparse::MarkovAutomaton<ValueType>>();
217 for (uint64_t origState = 0; origState < originalModel->getNumberOfStates(); ++origState) {
218 uint64_t
const newState = originalToNewIndex[origState];
219 if (ma.isMarkovianState(origState)) {
221 components.
exitRates->at(newState) = ma.getExitRate(origState);
229 storm::exceptions::UnexpectedException,
"Unhandled model type.");