| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -48,18 +48,26 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Initialize the maximal end component list to be the full state space.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::list<StateBlock> endComponentStateSets; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            endComponentStateSets.emplace_back(0, model.getNumberOfStates()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector statesToCheck(model.getNumberOfStates()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                StronglyConnectedComponentDecomposition<ValueType> sccs(model, true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (std::list<StateBlock>::const_iterator mecIterator = endComponentStateSets.begin(); mecIterator != endComponentStateSets.end();) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                StateBlock const& mec = *mecIterator; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Keep track of whether the MEC changed during this iteration.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                bool mecChanged = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Get an SCC decomposition of the current MEC candidate.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                StronglyConnectedComponentDecomposition<ValueType> sccs(model, mec, true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                mecChanged |= sccs.size() > 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Check for each of the SCCs whether there is at least one action for each state that does not leave the SCC.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto& scc : sccs) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::storage::BitVector statesToCheck(model.getNumberOfStates(), scc.begin(), scc.end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    statesToCheck.set(scc.begin(), scc.end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    while (!statesToCheck.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        storm::storage::BitVector statesToRemove(model.getNumberOfStates()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto state : scc) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto state : statesToCheck) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            bool keepStateInMEC = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -84,16 +92,65 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Now erase the states that have no option to stay inside the MEC with all successors.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        mecChanged |= !statesToRemove.empty(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<uint_fast64_t> statesToRemoveList = statesToRemove.getSetIndicesList(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        scc.erase(storm::storage::VectorSet<uint_fast64_t>(statesToRemoveList.begin(), statesToRemoveList.end())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        // Now check which states should be reconsidered, because successors of them were removed.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        statesToCheck.clear(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto state : statesToRemove) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            for (typename storm::storage::SparseMatrix<ValueType>::ConstIndexIterator predIt = backwardTransitions.constColumnIteratorBegin(state), predIte = backwardTransitions.constColumnIteratorEnd(state); predIt != predIte; ++predIt) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (scc.contains(*predIt)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    statesToCheck.set(*predIt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // If the MEC changed, we delete it from the list of MECs and append the possible new MEC candidates to the list instead.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (mecChanged) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::list<StateBlock>::const_iterator eraseIterator(mecIterator); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (StateBlock& scc : sccs) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        endComponentStateSets.push_back(std::move(scc)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        ++mecIterator; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    endComponentStateSets.erase(eraseIterator); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // Otherwise, we proceed with the next MEC candidate.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ++mecIterator; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } // end of loop over all MEC candidates
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Now that we computed the underlying state sets of the MECs, we need to properly identify the choices contained in the MEC.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            this->blocks.reserve(endComponentStateSets.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto const& mecStateSet : endComponentStateSets) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                MaximalEndComponent newMec; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto state : mecStateSet) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::vector<uint_fast64_t> containedChoices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        bool choiceContained = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (typename storm::storage::SparseMatrix<ValueType>::ConstIndexIterator successorIt = transitionMatrix.constColumnIteratorBegin(choice), successorIte = transitionMatrix.constColumnIteratorEnd(choice); successorIt != successorIte; ++successorIt) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            if (!mecStateSet.contains(*successorIt)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                choiceContained = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (choiceContained) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            containedChoices.push_back(choice); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    newMec.addState(state, std::move(containedChoices)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                this->blocks.emplace_back(std::move(newMec)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } while (true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            LOG4CPLUS_INFO(logger, "Computed MEC decomposition of size " << this->size() << "."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template class MaximalEndComponentDecomposition<double>; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
				 | 
				
					
  |