| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -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) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Retrieve the appropriate bitvectors by model checking the subformulas.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector phiStates(this->getModel().getNumberOfStates(), true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector const& psiStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector targetStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Do some sanity checks to establish some required properties.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            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."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> result = computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), targetStates, stateRewardValues, this->computeResultsForInitialStatesOnly, qualitative, optimalityType); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Construct check result
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::unique_ptr<CheckResult> checkResult(new ExplicitQuantitativeCheckResult<ValueType>(result)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            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(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Then, compute the subset of states that has a reachability reward less than infinity.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(this->getModel().getBackwardTransitions(), trueStates, psiStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 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(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector maybeStates = ~psiStates & ~infinityStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Determine whether we need to perform some further computation.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            bool furtherComputationNeeded = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (computeResultsForInitialStatesOnly) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (this->getModel().getInitialStates().isSubsetOf(infinityStates)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (computeForInitialStatesOnly) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (initialStates.isSubsetOf(infinityStates)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_DEBUG("The reward of all initial states was found in a preprocessing step."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    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."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    furtherComputationNeeded = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -608,40 +621,37 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (furtherComputationNeeded) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // If we compute the results for the initial states only, we can cut off all maybe state that are not
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 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.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    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).
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    maybeStates &= reachableStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 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.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                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(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Project the state reward vector to all maybe-states.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<ValueType> stateRewardValues = rewardModel.getTotalRewardVector(maybeStates.getNumberOfSetBits(), this->getModel().getTransitionMatrix(), maybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<ValueType> subresult = computeReachabilityValues(submatrix, stateRewardValues, submatrixTransposed, newInitialStates, computeResultsForInitialStatesOnly, phiStates, psiStates, this->getModel().getTransitionMatrix().getConstrainedRowSumVector(maybeStates, psiStates)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<ValueType> rewardValues = storm::utility::vector::filterVector(stateRewardValues, maybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::storage::BitVector phiStates(numberOfStates, true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<ValueType> subresult = computeReachabilityValues(submatrix, rewardValues, submatrixTransposed, newInitialStates, computeForInitialStatesOnly, phiStates, targetStates, probabilityMatrix.getConstrainedRowSumVector(maybeStates, targetStates)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, subresult); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Construct full result.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::utility::vector::setVectorValues<ValueType>(result, infinityStates, storm::utility::infinity<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 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) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::utility::vector::setVectorValues<ValueType>(result, targetStates, storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (computeForInitialStatesOnly) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // If we computed the results for the initial (and inf) states only, we need to filter the result to
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // 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> | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |