| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -26,7 +26,8 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        namespace helper { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<uint64_t> computeValidInitialScheduler(uint64_t numberOfMaybeStates, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& b) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<uint64_t> computeValidInitialSchedulerForUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& b) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t numberOfMaybeStates = transitionMatrix.getRowGroupCount(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<uint64_t> result(numberOfMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::storage::BitVector targetStates(numberOfMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -106,7 +107,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, std::move(rowGroupSizes), model.getNondeterminismVariables(), odd, odd); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Create the solution vector.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Check for requirements of the solver.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(storm::solver::MinMaxLinearEquationSolverSystemType::UntilProbabilities, dir); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -114,7 +115,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (!requirements.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                STORM_LOG_DEBUG("Computing valid scheduler hint, because the solver requires it."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                initialScheduler = computeValidInitialScheduler<ValueType>(x.size(), explicitRepresentation.first, explicitRepresentation.second); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                initialScheduler = computeValidInitialSchedulerForUntilProbabilities<ValueType>(explicitRepresentation.first, explicitRepresentation.second); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                requirements.set(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler, false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -250,6 +251,69 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector computeTargetStatesForReachabilityRewardsFromExplicitRepresentation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::storage::BitVector targetStates(transitionMatrix.getRowGroupCount()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // A state is a target state if its row group is empty.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (uint64_t rowGroup = 0; rowGroup < transitionMatrix.getRowGroupCount(); ++rowGroup) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (transitionMatrix.getRowGroupIndices()[rowGroup] == transitionMatrix.getRowGroupIndices()[rowGroup + 1]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        targetStates.set(rowGroup); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return targetStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<uint64_t> computeValidInitialSchedulerForReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& properMaybeStates, storm::storage::BitVector const& targetStates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t numberOfMaybeStates = transitionMatrix.getRowGroupCount(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<uint64_t> result(numberOfMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::storage::Scheduler<ValueType> validScheduler(numberOfMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::storage::SparseMatrix<ValueType> backwardTransitions = transitionMatrix.transpose(true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::utility::graph::computeSchedulerProb1E(storm::storage::BitVector(numberOfMaybeStates, true), transitionMatrix, backwardTransitions, properMaybeStates, targetStates, validScheduler); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (uint64_t state = 0; state < numberOfMaybeStates; ++state) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!targetStates.get(state)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result[state] = validScheduler.getChoice(state).getDeterministicChoice(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            void eliminateTargetStatesFromExplicitRepresentation(std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>& explicitRepresentation, std::vector<uint64_t>& scheduler, storm::storage::BitVector const& properMaybeStates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Treat the matrix first.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                explicitRepresentation.first = explicitRepresentation.first.getSubmatrix(true, properMaybeStates, properMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Now eliminate the superfluous entries from the rhs vector and the scheduler.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t position = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto state : properMaybeStates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    explicitRepresentation.second[position] = explicitRepresentation.second[state]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    scheduler[position] = scheduler[state]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    position++; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t numberOfProperMaybeStates = properMaybeStates.getNumberOfSetBits(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                explicitRepresentation.second.resize(numberOfProperMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                explicitRepresentation.second.shrink_to_fit(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                scheduler.resize(numberOfProperMaybeStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                scheduler.shrink_to_fit(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<ValueType> insertTargetStateValuesIntoExplicitRepresentation(std::vector<ValueType> const& x, storm::storage::BitVector const& properMaybeStates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<ValueType> expandedResult(properMaybeStates.size(), storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t position = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto state : properMaybeStates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    expandedResult[state] = x[position]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    position++; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template<storm::dd::DdType DdType, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -266,7 +330,8 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    infinityStates = storm::utility::graph::performProb1A(model, transitionMatrixBdd, targetStates, storm::utility::graph::performProbGreater0A(model, transitionMatrixBdd, model.getReachableStates(), targetStates)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                infinityStates = !infinityStates && model.getReachableStates(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<DdType> maybeStates = (!targetStates && !infinityStates) && model.getReachableStates(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<DdType> maybeStatesWithTargetStates = !infinityStates && model.getReachableStates(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<DdType> maybeStates = !targetStates && maybeStatesWithTargetStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                STORM_LOG_INFO("Found " << infinityStates.getNonZeroCount() << " 'infinity' states."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                STORM_LOG_INFO("Found " << targetStates.getNonZeroCount() << " 'target' states."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                STORM_LOG_INFO("Found " << maybeStates.getNonZeroCount() << " 'maybe' states."); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -279,51 +344,85 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // If there are maybe states, we need to solve an equation system.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!maybeStates.isZero()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Check for requirements of the solver this early so we can adapt the maybe states accordingly.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(storm::solver::MinMaxLinearEquationSolverSystemType::ReachabilityRewards); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        bool requireInitialScheduler = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (!requirements.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                STORM_LOG_DEBUG("Computing valid scheduler hint, because the solver requires it."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                requireInitialScheduler = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                requirements.set(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler, false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Compute the set of maybe states that we are required to keep in the translation to explicit.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Bdd<DdType> requiredMaybeStates = requireInitialScheduler ? maybeStatesWithTargetStates : maybeStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Create the ODD for the translation between symbolic and explicit storage.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Odd odd = maybeStates.createOdd(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Odd odd = requiredMaybeStates.createOdd(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Create the matrix and the vector for the equation system.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // non-maybe states in the matrix.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Start by getting rid of
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // (a) transitions from non-maybe states, and
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // (b) the choices in the transition matrix that lead to a state that is neither a maybe state
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // nor a target state ('infinity choices').
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, ValueType> choiceFilterAdd = (transitionMatrixBdd && maybeStatesWithTargetStates.renameVariables(model.getRowVariables(), model.getColumnVariables())).existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd * choiceFilterAdd; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Then compute the reward vector to use in the computation.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, submatrix, model.getColumnVariables()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (!rewardModel.hasStateActionRewards() && !rewardModel.hasTransitionRewards()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            // If the reward model neither has state-action nor transition rewards, we need to multiply
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            // it with the legal nondetermism encodings in each state.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            subvector *= transitionMatrixBdd.existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            subvector *= choiceFilterAdd; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Since we are cutting away target and infinity states, we need to account for this by giving
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // choices the value infinity that have some successor contained in the infinity states.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Bdd<DdType> choicesWithInfinitySuccessor = (maybeStates && transitionMatrixBdd && infinityStates.swapVariables(model.getRowColumnMetaVariablePairs())).existsAbstract(model.getColumnVariables()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        subvector = choicesWithInfinitySuccessor.ite(model.getManager().template getInfinity<ValueType>(), subvector); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Before cutting the non-maybe columns, we need to compute the sizes of the row groups.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::dd::Add<DdType, uint_fast64_t> stateActionAdd = submatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<uint_fast64_t>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<uint_fast64_t> rowGroupSizes = stateActionAdd.sumAbstract(model.getNondeterminismVariables()).toVector(odd); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Finally cut away all columns targeting non-maybe states.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Create the solution vector.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Finally cut away all columns targeting non-maybe states (or non-(maybe or target) states, respectively).
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        submatrix *= requireInitialScheduler ? maybeStatesWithTargetStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>() : maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Translate the symbolic matrix/vector to their explicit representations.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, std::move(rowGroupSizes), model.getNondeterminismVariables(), odd, odd); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Check for requirements of the solver.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(storm::solver::MinMaxLinearEquationSolverSystemType::ReachabilityRewards); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Compute a valid initial scheduler if necessary.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        boost::optional<std::vector<uint64_t>> initialScheduler; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        boost::optional<storm::storage::BitVector> properMaybeStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (requireInitialScheduler) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            // Compute a valid initial scheduler.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            storm::storage::BitVector targetStates = computeTargetStatesForReachabilityRewardsFromExplicitRepresentation(explicitRepresentation.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            properMaybeStates = ~targetStates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            initialScheduler = computeValidInitialSchedulerForReachabilityRewards<ValueType>(explicitRepresentation.first, properMaybeStates.get(), targetStates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            // Since we needed the transitions to target states to be translated as well for the computation
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            // of the scheduler, we have to get rid of them now.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            eliminateTargetStatesFromExplicitRepresentation(explicitRepresentation, initialScheduler.get(), properMaybeStates.get()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Now solve the resulting equation system.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(std::move(explicitRepresentation.first)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Move the scheduler to the solver.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (initialScheduler) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            solver->setInitialScheduler(std::move(initialScheduler.get())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Create the solution vector.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        solver->setRequirementsChecked(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        solver->solveEquations(dir, x, explicitRepresentation.second); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // If we included the target states in the ODD, we need to expand the result from the solver.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (requireInitialScheduler) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            x = insertTargetStateValuesIntoExplicitRepresentation(x, properMaybeStates.get()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Return a hybrid check result that stores the numerical values explicitly.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getReachableStates() && !maybeStates, infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()), maybeStates, odd, x)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } else { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |