| 
					
					
						
							
						
					
					
				 | 
				@ -578,27 +578,40 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<OptimizationDirection> const& optimalityType) { | 
				 | 
				 | 
				        std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<OptimizationDirection> const& optimalityType) { | 
			
		
		
	
		
			
				 | 
				 | 
				            // Retrieve the appropriate bitvectors by model checking the subformulas.
 | 
				 | 
				 | 
				            // Retrieve the appropriate bitvectors by model checking the subformulas.
 | 
			
		
		
	
		
			
				 | 
				 | 
				            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); | 
				 | 
				 | 
				            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::storage::BitVector phiStates(this->getModel().getNumberOfStates(), true); | 
				 | 
				 | 
				            storm::storage::BitVector targetStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::storage::BitVector const& psiStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); | 
				 | 
				 | 
				            storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); | 
			
		
		
	
		
		
	
		
		
	
		
			
				 | 
				 | 
				             | 
				 | 
				 | 
				             | 
			
		
		
	
		
			
				 | 
				 | 
				            // Do some sanity checks to establish some required properties.
 | 
				 | 
				 | 
				            // Do some sanity checks to establish some required properties.
 | 
			
		
		
	
		
			
				 | 
				 | 
				            RewardModelType const& rewardModel = this->getModel().getRewardModel(rewardModelName ? rewardModelName.get() : ""); | 
				 | 
				 | 
				            RewardModelType const& rewardModel = this->getModel().getRewardModel(rewardModelName ? rewardModelName.get() : ""); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::vector<ValueType> stateRewardValues = rewardModel.getTotalRewardVector(trueStates.getNumberOfSetBits(), this->getModel().getTransitionMatrix(), trueStates); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::IllegalArgumentException, "Input model does not have a reward model."); | 
				 | 
				 | 
				            STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::IllegalArgumentException, "Input model does not have a reward model."); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::vector<ValueType> result = computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), targetStates, stateRewardValues, this->computeResultsForInitialStatesOnly, qualitative, optimalityType); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            // Then, compute the subset of states that has a reachability reward less than infinity.
 | 
				 | 
				 | 
				            // Construct check result
 | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); | 
				 | 
				 | 
				            std::unique_ptr<CheckResult> checkResult(new ExplicitQuantitativeCheckResult<ValueType>(result)); | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(this->getModel().getBackwardTransitions(), trueStates, psiStates); | 
				 | 
				 | 
				            return checkResult; | 
			
		
		
	
		
		
	
		
		
	
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        template<typename SparseDtmcModelType> | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        std::vector<typename SparseDtmcModelType::ValueType> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& targetStates, std::vector<ValueType> const& stateRewardValues, bool computeForInitialStatesOnly, bool qualitative, boost::optional<OptimizationDirection> const& optimalityType) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            uint_fast64_t numberOfStates = probabilityMatrix.getRowCount(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				             | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            // Compute the subset of states that has a reachability reward less than infinity.
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::storage::BitVector trueStates(numberOfStates, true); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, targetStates); | 
			
		
		
	
		
			
				 | 
				 | 
				            infinityStates.complement(); | 
				 | 
				 | 
				            infinityStates.complement(); | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::storage::BitVector maybeStates = ~psiStates & ~infinityStates; | 
				 | 
				 | 
				            storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates; | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				             | 
				 | 
				 | 
				             | 
			
		
		
	
		
			
				 | 
				 | 
				            // Determine whether we need to perform some further computation.
 | 
				 | 
				 | 
				            // Determine whether we need to perform some further computation.
 | 
			
		
		
	
		
			
				 | 
				 | 
				            bool furtherComputationNeeded = true; | 
				 | 
				 | 
				            bool furtherComputationNeeded = true; | 
			
		
		
	
		
			
				 | 
				 | 
				            if (computeResultsForInitialStatesOnly) { | 
				 | 
				 | 
				            if (computeForInitialStatesOnly) { | 
			
		
		
	
		
			
				 | 
				 | 
				                if (this->getModel().getInitialStates().isSubsetOf(infinityStates)) { | 
				 | 
				 | 
				                if (initialStates.isSubsetOf(infinityStates)) { | 
			
		
		
	
		
		
	
		
		
	
		
			
				 | 
				 | 
				                    STORM_LOG_DEBUG("The reward of all initial states was found in a preprocessing step."); | 
				 | 
				 | 
				                    STORM_LOG_DEBUG("The reward of all initial states was found in a preprocessing step."); | 
			
		
		
	
		
			
				 | 
				 | 
				                    furtherComputationNeeded = false; | 
				 | 
				 | 
				                    furtherComputationNeeded = false; | 
			
		
		
	
		
			
				 | 
				 | 
				                } | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				                if (this->getModel().getInitialStates().isSubsetOf(psiStates)) { | 
				 | 
				 | 
				                if (initialStates.isSubsetOf(targetStates)) { | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				                    STORM_LOG_DEBUG("The reward of all initial states was found in a preprocessing step."); | 
				 | 
				 | 
				                    STORM_LOG_DEBUG("The reward of all initial states was found in a preprocessing step."); | 
			
		
		
	
		
			
				 | 
				 | 
				                    furtherComputationNeeded = false; | 
				 | 
				 | 
				                    furtherComputationNeeded = false; | 
			
		
		
	
		
			
				 | 
				 | 
				                } | 
				 | 
				 | 
				                } | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -608,40 +621,37 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				            if (furtherComputationNeeded) { | 
				 | 
				 | 
				            if (furtherComputationNeeded) { | 
			
		
		
	
		
			
				 | 
				 | 
				                // If we compute the results for the initial states only, we can cut off all maybe state that are not
 | 
				 | 
				 | 
				                // If we compute the results for the initial states only, we can cut off all maybe state that are not
 | 
			
		
		
	
		
			
				 | 
				 | 
				                // reachable from them.
 | 
				 | 
				 | 
				                // reachable from them.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                if (computeResultsForInitialStatesOnly) { | 
				 | 
				 | 
				                if (computeForInitialStatesOnly) { | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				                    // Determine the set of states that is reachable from the initial state without jumping over a target state.
 | 
				 | 
				 | 
				                    // Determine the set of states that is reachable from the initial state without jumping over a target state.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    storm::storage::BitVector reachableStates = storm::utility::graph::getReachableStates(this->getModel().getTransitionMatrix(), this->getModel().getInitialStates(), maybeStates, psiStates); | 
				 | 
				 | 
				                    storm::storage::BitVector reachableStates = storm::utility::graph::getReachableStates(probabilityMatrix, initialStates, maybeStates, targetStates); | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				                     | 
				 | 
				 | 
				                     | 
			
		
		
	
		
			
				 | 
				 | 
				                    // Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state).
 | 
				 | 
				 | 
				                    // Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state).
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    maybeStates &= reachableStates; | 
				 | 
				 | 
				                    maybeStates &= reachableStates; | 
			
		
		
	
		
			
				 | 
				 | 
				                } | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				                 | 
				 | 
				 | 
				                 | 
			
		
		
	
		
			
				 | 
				 | 
				                // Determine the set of initial states of the sub-model.
 | 
				 | 
				 | 
				                // Determine the set of initial states of the sub-model.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                storm::storage::BitVector newInitialStates = this->getModel().getInitialStates() % maybeStates; | 
				 | 
				 | 
				                storm::storage::BitVector newInitialStates = initialStates % maybeStates; | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                // We then build the submatrix that only has the transitions of the maybe states.
 | 
				 | 
				 | 
				                // We then build the submatrix that only has the transitions of the maybe states.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                storm::storage::SparseMatrix<ValueType> submatrix = this->getModel().getTransitionMatrix().getSubmatrix(false, maybeStates, maybeStates); | 
				 | 
				 | 
				                storm::storage::SparseMatrix<ValueType> submatrix = probabilityMatrix.getSubmatrix(false, maybeStates, maybeStates); | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				                storm::storage::SparseMatrix<ValueType> submatrixTransposed = submatrix.transpose(); | 
				 | 
				 | 
				                storm::storage::SparseMatrix<ValueType> submatrixTransposed = submatrix.transpose(); | 
			
		
		
	
		
			
				 | 
				 | 
				                 | 
				 | 
				 | 
				                 | 
			
		
		
	
		
			
				 | 
				 | 
				                // Project the state reward vector to all maybe-states.
 | 
				 | 
				 | 
				                // Project the state reward vector to all maybe-states.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                std::vector<ValueType> stateRewardValues = rewardModel.getTotalRewardVector(maybeStates.getNumberOfSetBits(), this->getModel().getTransitionMatrix(), maybeStates); | 
				 | 
				 | 
				                std::vector<ValueType> rewardValues = storm::utility::vector::filterVector(stateRewardValues, maybeStates); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				                storm::storage::BitVector phiStates(numberOfStates, true); | 
			
		
		
	
		
			
				 | 
				 | 
				                std::vector<ValueType> subresult = computeReachabilityValues(submatrix, stateRewardValues, submatrixTransposed, newInitialStates, computeResultsForInitialStatesOnly, phiStates, psiStates, this->getModel().getTransitionMatrix().getConstrainedRowSumVector(maybeStates, psiStates)); | 
				 | 
				 | 
				                std::vector<ValueType> subresult = computeReachabilityValues(submatrix, rewardValues, submatrixTransposed, newInitialStates, computeForInitialStatesOnly, phiStates, targetStates, probabilityMatrix.getConstrainedRowSumVector(maybeStates, targetStates)); | 
			
		
		
	
		
		
	
		
		
	
		
		
	
		
			
				 | 
				 | 
				                storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, subresult); | 
				 | 
				 | 
				                storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, subresult); | 
			
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				             | 
				 | 
				 | 
				             | 
			
		
		
	
		
			
				 | 
				 | 
				            // Construct full result.
 | 
				 | 
				 | 
				            // Construct full result.
 | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::utility::vector::setVectorValues<ValueType>(result, infinityStates, storm::utility::infinity<ValueType>()); | 
				 | 
				 | 
				            storm::utility::vector::setVectorValues<ValueType>(result, infinityStates, storm::utility::infinity<ValueType>()); | 
			
		
		
	
		
			
				 | 
				 | 
				            storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::zero<ValueType>()); | 
				 | 
				 | 
				            storm::utility::vector::setVectorValues<ValueType>(result, targetStates, storm::utility::zero<ValueType>()); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				            if (computeForInitialStatesOnly) { | 
			
		
		
	
		
			
				 | 
				 | 
				            // Construct check result based on whether we have computed values for all states or just the initial states.
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            std::unique_ptr<CheckResult> checkResult(new ExplicitQuantitativeCheckResult<ValueType>(result)); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            if (computeResultsForInitialStatesOnly) { | 
				 | 
				 | 
				 | 
			
		
		
	
		
		
	
		
		
	
		
			
				 | 
				 | 
				                // If we computed the results for the initial (and inf) states only, we need to filter the result to
 | 
				 | 
				 | 
				                // If we computed the results for the initial (and inf) states only, we need to filter the result to
 | 
			
		
		
	
		
			
				 | 
				 | 
				                // only communicate these results.
 | 
				 | 
				 | 
				                // only communicate these results.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                checkResult->filter(ExplicitQualitativeCheckResult(~maybeStates | this->getModel().getInitialStates())); | 
				 | 
				 | 
				                result = storm::utility::vector::filterVector(result, ~maybeStates | initialStates); | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				            return checkResult; | 
				 | 
				 | 
				            return result; | 
			
		
		
	
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				         | 
				 | 
				 | 
				         | 
			
		
		
	
		
			
				 | 
				 | 
				        template<typename SparseDtmcModelType> | 
				 | 
				 | 
				        template<typename SparseDtmcModelType> | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
					
				 | 
				
  | 
			
		
		
	
										
									
								
							 
xxxxxxxxxx