| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1078,22 +1078,62 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<Type> inputEnabledGuard = this->variables.manager->getBddOne(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Add<Type, ValueType> transitions = this->variables.manager->template getAddOne<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t lowestNondeterminismVariable = actions.front().second.get().getLowestLocalNondeterminismVariable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t highestNondeterminismVariable = actions.front().second.get().getHighestLocalNondeterminismVariable(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                bool hasTransientEdgeAssignments = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& actionIndexPair : actions) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto const& action = actionIndexPair.second.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!action.transientEdgeAssignments.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        hasTransientEdgeAssignments = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                boost::optional<storm::dd::Add<Type, ValueType>> exitRates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (this->model.getModelType() == storm::jani::ModelType::CTMC && hasTransientEdgeAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // For CTMCs, we need to weigh the transient assignments with the exit rates.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    exitRates = this->variables.manager->template getAddOne<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& actionIndexPair : actions) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        auto const& action = actionIndexPair.second.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::set<storm::expressions::Variable> columnVariablesToAbstract; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::set_intersection(action.transitions.getContainedMetaVariables().begin(), action.transitions.getContainedMetaVariables().end(), this->variables.columnMetaVariables.begin(), this->variables.columnMetaVariables.end(), std::inserter(columnVariablesToAbstract, columnVariablesToAbstract.begin())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        auto actionExitRates = action.transitions.sumAbstract(columnVariablesToAbstract); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        exitRates = exitRates.get() * actionExitRates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (!action.transientEdgeAssignments.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            for (auto const& entry : action.transientEdgeAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                auto transientEdgeAssignmentIt = transientEdgeAssignments.find(entry.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (transientEdgeAssignmentIt != transientEdgeAssignments.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    transientEdgeAssignmentIt->second *= entry.second / actionExitRates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    transientEdgeAssignments.emplace(entry.first, entry.second / actionExitRates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } else if (hasTransientEdgeAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // Otherwise, just join the assignments.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& actionIndexPair : actions) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        auto const& action = actionIndexPair.second.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        joinTransientAssignmentMapsInPlace(transientEdgeAssignments, action.transientEdgeAssignments); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<Type> newIllegalFragment = this->variables.manager->getBddZero(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& actionIndexPair : actions) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto componentIndex = actionIndexPair.first; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto const& action = actionIndexPair.second.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (guardDisjunction) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        guardDisjunction.get() |= action.guard; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    lowestNondeterminismVariable = std::min(lowestNondeterminismVariable, action.getLowestLocalNondeterminismVariable()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    highestNondeterminismVariable = std::max(highestNondeterminismVariable, action.getHighestLocalNondeterminismVariable()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    transientEdgeAssignments = joinTransientAssignmentMaps(transientEdgeAssignments, action.transientEdgeAssignments); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (action.isInputEnabled()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // If the action is input-enabled, we add self-loops to all states.
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1153,6 +1193,18 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // such a combined transition.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                illegalFragment &= inputEnabledGuard; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Add<Type, ValueType> transientEdgeAssignmentWeights; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (hasTransientEdgeAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    transientEdgeAssignmentWeights = inputEnabledGuard.template toAdd<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (exitRates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        transientEdgeAssignmentWeights *= exitRates.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto& entry : transientEdgeAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        entry.second *= transientEdgeAssignmentWeights; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return ActionDd(inputEnabledGuard, transitions * nonSynchronizingIdentity, transientEdgeAssignments, std::make_pair(lowestNondeterminismVariable, highestNondeterminismVariable), globalVariableToWritingFragment, illegalFragment); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1223,7 +1275,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<Type, ValueType> nondeterminismEncoding = encodeIndex(actionIndex, highestLocalNondeterminismVariable, numberOfLocalNondeterminismVariables, this->variables); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        transitions += nondeterminismEncoding * action.transitions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        transientEdgeAssignments = joinTransientAssignmentMaps(transientEdgeAssignments, action.transientEdgeAssignments); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        joinTransientAssignmentMapsInPlace(transientEdgeAssignments, action.transientEdgeAssignments, nondeterminismEncoding); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Bdd<Type> nondeterminismEncodingBdd = nondeterminismEncoding.toBdd(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto& entry : action.variableToWritingFragment) { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1319,16 +1371,22 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // If the edge has a rate, we multiply it to the DD.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    bool isMarkovian = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    boost::optional<storm::dd::Add<Type, ValueType>> exitRates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (edge.hasRate()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        transitions *= this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        exitRates = this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        transitions *= exitRates.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        isMarkovian = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // Finally treat the transient assignments.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!this->transientVariables.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &sourceLocationAndGuard] (storm::jani::Assignment const& assignment) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            transientEdgeAssignments[assignment.getExpressionVariable()] = sourceLocationAndGuard * this->variables.rowExpressionAdapter->translateExpression(assignment.getAssignedExpression()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &sourceLocationAndGuard, &exitRates] (storm::jani::Assignment const& assignment) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            auto newTransientEdgeAssignments = sourceLocationAndGuard * this->variables.rowExpressionAdapter->translateExpression(assignment.getAssignedExpression()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            if (exitRates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                newTransientEdgeAssignments *= exitRates.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            transientEdgeAssignments[assignment.getExpressionVariable()] = newTransientEdgeAssignments; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1355,7 +1413,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    guard |= edge.guard; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    transitions += edge.transitions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    variableToWritingFragment = joinVariableWritingFragmentMaps(variableToWritingFragment, edge.variableToWritingFragment); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    transientEdgeAssignments = joinTransientAssignmentMaps(transientEdgeAssignments, edge.transientEdgeAssignments); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    joinTransientAssignmentMapsInPlace(transientEdgeAssignments, edge.transientEdgeAssignments); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Currently, we can only combine the transient edge assignments if there is no overlap of the guards of the edges.
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1426,13 +1484,25 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (resultIt != result.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        resultIt->second += entry.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result[entry.first] = entry.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result.emplace(entry); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            void joinTransientAssignmentMapsInPlace(std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>>& target, std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> const& newTransientAssignments, boost::optional<storm::dd::Add<Type, ValueType>> const& factor = boost::none) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& entry : newTransientAssignments) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto targetIt = target.find(entry.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (targetIt != target.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        targetIt->second += factor ? factor.get() * entry.second : entry.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        target[entry.first] = factor ? factor.get() * entry.second : entry.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ActionDd combineEdgesToActionDeterministic(std::vector<EdgeDd> const& edgeDds) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<Type> allGuards = this->variables.manager->getBddZero(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Add<Type, ValueType> allTransitions = this->variables.manager->template getAddZero<ValueType>(); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1922,9 +1992,15 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template <storm::dd::DdType Type, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<Type, ValueType>> buildRewardModels(ComposerResult<Type, ValueType> const& system, std::vector<storm::expressions::Variable> const& rewardVariables) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<Type, ValueType>> buildRewardModels(storm::dd::Add<Type, ValueType> const& reachableStates, storm::dd::Add<Type, ValueType> const& transitionMatrix, storm::jani::ModelType const& modelType, CompositionVariables<Type, ValueType> const& variables, ComposerResult<Type, ValueType> const& system, std::vector<storm::expressions::Variable> const& rewardVariables) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<Type, ValueType>> result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // For CTMCs, we need to scale the state-action rewards with the total exit rates.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            boost::optional<storm::dd::Add<Type, ValueType>> exitRates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (modelType == storm::jani::ModelType::CTMC || modelType == storm::jani::ModelType::DTMC) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                exitRates = transitionMatrix.sumAbstract(variables.columnMetaVariables); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto const& variable : rewardVariables) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                boost::optional<storm::dd::Add<Type, ValueType>> stateRewards = boost::none; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                boost::optional<storm::dd::Add<Type, ValueType>> stateActionRewards = boost::none; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -1932,12 +2008,15 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto it = system.transientLocationAssignments.find(variable); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (it != system.transientLocationAssignments.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    stateRewards = it->second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    stateRewards = reachableStates * it->second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                it = system.transientEdgeAssignments.find(variable); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (it != system.transientEdgeAssignments.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    stateActionRewards = it->second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    stateActionRewards = reachableStates * it->second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (exitRates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        stateActionRewards.get() = stateActionRewards.get() / exitRates.get(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                result.emplace(variable.getName(), storm::models::symbolic::StandardRewardModel<Type, ValueType>(stateRewards, stateActionRewards, transitionRewards)); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -2045,7 +2124,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            modelComponents.deadlockStates = modelComponents.deadlockStates && !terminalStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Build the reward models.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            modelComponents.rewardModels = buildRewardModels(system, rewardVariables); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            modelComponents.rewardModels = buildRewardModels(reachableStatesAdd, modelComponents.transitionMatrix, preparedModel.getModelType(), variables, system, rewardVariables); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Build the label to expressions mapping.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            modelComponents.labelToExpressionMap = buildLabelExpressions(preparedModel, variables, options); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |