|  |  | @ -134,16 +134,25 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             template<typename ValueType> | 
			
		
	
		
			
				
					|  |  |  |             std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { | 
			
		
	
		
			
				
					|  |  |  |             MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 // Create the vector with which to multiply and initialize it correctly.
 | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); | 
			
		
	
		
			
				
					|  |  |  |                 storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); | 
			
		
	
		
			
				
					|  |  |  |                  | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType> choiceValues = std::vector<ValueType>(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); | 
			
		
	
		
			
				
					|  |  |  |                 storm::storage::BitVector allStates = storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); | 
			
		
	
		
			
				
					|  |  |  |                 multiplier->multiplyAndReduce(env, dir, result, nullptr, result); | 
			
		
	
		
			
				
					|  |  |  |                  | 
			
		
	
		
			
				
					|  |  |  |                 return result; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if(goal.isShieldingTask()) { | 
			
		
	
		
			
				
					|  |  |  |                     multiplier->multiply(env, result, nullptr, choiceValues); | 
			
		
	
		
			
				
					|  |  |  |                     multiplier->reduce(env, goal.direction(), choiceValues, transitionMatrix.getRowGroupIndices(), result, nullptr); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 else { | 
			
		
	
		
			
				
					|  |  |  |                     multiplier->multiplyAndReduce(env, dir, result, nullptr, result); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(allStates), nullptr, std::move(choiceValues)); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             template<typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | @ -608,6 +617,10 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                  | 
			
		
	
		
			
				
					|  |  |  |                 // Check if the values of the maybe states are relevant for the SolveGoal
 | 
			
		
	
		
			
				
					|  |  |  |                 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(qualitativeStateSets.maybeStates); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 // create multiplier and execute the calculation for 1 additional step
 | 
			
		
	
		
			
				
					|  |  |  |                 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType> choiceValues = std::vector<ValueType>(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); | 
			
		
	
		
			
				
					|  |  |  |                  | 
			
		
	
		
			
				
					|  |  |  |                 // Check whether we need to compute exact probabilities for some states.
 | 
			
		
	
		
			
				
					|  |  |  |                 if (qualitative || maybeStatesNotRelevant) { | 
			
		
	
	
		
			
				
					|  |  | @ -632,10 +645,10 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                             // Otherwise, we compute the standard equations.
 | 
			
		
	
		
			
				
					|  |  |  |                             computeFixedPointSystemUntilProbabilities(goal, transitionMatrix, qualitativeStateSets, submatrix, b); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                          | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         // Now compute the results for the maybe states.
 | 
			
		
	
		
			
				
					|  |  |  |                         MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation); | 
			
		
	
		
			
				
					|  |  |  |                          | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         // If we eliminated end components, we need to extract the result differently.
 | 
			
		
	
		
			
				
					|  |  |  |                         if (ecInformation && ecInformation.get().getEliminatedEndComponents()) { | 
			
		
	
		
			
				
					|  |  |  |                             ecInformation.get().setValues(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues()); | 
			
		
	
	
		
			
				
					|  |  | @ -649,6 +662,10 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                                 extractSchedulerChoices(*scheduler, resultForMaybeStates.getScheduler(), qualitativeStateSets.maybeStates); | 
			
		
	
		
			
				
					|  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                         if (goal.isShieldingTask()) { | 
			
		
	
		
			
				
					|  |  |  |                             multiplier->multiply(env, result, &b, choiceValues); | 
			
		
	
		
			
				
					|  |  |  |                             multiplier->reduce(env, goal.direction(), choiceValues, transitionMatrix.getRowGroupIndices(), result, nullptr); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -664,7 +681,7 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 // Return result.
 | 
			
		
	
		
			
				
					|  |  |  |                 return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(scheduler)); | 
			
		
	
		
			
				
					|  |  |  |                 return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(qualitativeStateSets.maybeStates), std::move(scheduler), std::move(choiceValues)); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             template<typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | @ -1173,7 +1190,11 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(scheduler)); | 
			
		
	
		
			
				
					|  |  |  |                 //TODO: keep nullvector for choiceValues in computeReachabilityRewardsHelper? - nullptr causes ERROR
 | 
			
		
	
		
			
				
					|  |  |  |                 //std::vector<ValueType> choiceValues = std::vector<ValueType>(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
 | 
			
		
	
		
			
				
					|  |  |  |                 std::vector<ValueType> choiceValues = std::vector<ValueType>(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(qualitativeStateSets.maybeStates), std::move(scheduler), std::move(choiceValues)); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             template<typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | 
 |