@ -23,8 +23,7 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					namespace  storm  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    namespace  modelchecker  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        SparseMdpLearningModelChecker < ValueType > : : SparseMdpLearningModelChecker ( storm : : prism : : Program  const &  program ,  boost : : optional < std : : map < storm : : expressions : : Variable ,  storm : : expressions : : Expression > >  const &  constantDefinitions )  :  program ( storm : : utility : : prism : : preprocessProgram < ValueType > ( program ,  constantDefinitions ) ) ,  variableInformation ( this - > program ) ,  //randomGenerator(std::chrono::system_clock::now().time_since_epoch().count()),
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        comparator ( 1e-9 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        SparseMdpLearningModelChecker < ValueType > : : SparseMdpLearningModelChecker ( storm : : prism : : Program  const &  program ,  boost : : optional < std : : map < storm : : expressions : : Variable ,  storm : : expressions : : Expression > >  const &  constantDefinitions )  :  program ( storm : : utility : : prism : : preprocessProgram < ValueType > ( program ,  constantDefinitions ) ) ,  variableInformation ( this - > program ) ,  randomGenerator ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) . count ( ) ) ,  comparator ( )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Intentionally left empty.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -120,7 +119,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Value of initial state is in [ "  < <  bounds . getLowerBoundForState ( initialStateIndex ,  explorationInformation )  < <  " ,  "  < <  bounds . getUpperBoundForState ( initialStateIndex ,  explorationInformation )  < <  " ]. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                ValueType  difference  =  bounds . getDifferenceOfStateBounds ( initialStateIndex ,  explorationInformation ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Difference after iteration  "  < <  stats . iterations  < <  "  is  "  < <  difference  < <  " . " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                convergenceCriterionMet  =  difference  <  1e-6 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                convergenceCriterionMet  =  comparator . isZero ( difference ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                + + stats . iterations ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -128,8 +127,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( storm : : settings : : generalSettings ( ) . isShowStatisticsSet ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  std : : endl  < <  " Learning summary ------------------------- "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  " Discovered states:  "  < <  explorationInformation . getNumberOfDiscoveredStates ( )  < <  "  ( "  < <  stats . numberOfExploredStates  < <  "  explored,  "  < <  explorationInformation . getNumberOfUnexploredStates ( )  < <  "  unexplored,  "  < <  stats . numberOfTargetStates  < <  "  target) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  " Sampling iteration s:  "  < <  stats . iterations  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  " Sampled path s:  "  < <  stats . iterations  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  " Maximal path length:  "  < <  stats . maxPathLength  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : cout  < <  " EC detections:  "  < <  stats . ecDetections  < <  "  ( "  < <  stats . failedEcDetections  < <  "  failed,  "  < <  stats . totalNumberOfEcDetected  < <  "  EC(s) detected) "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  std : : make_tuple ( initialStateIndex ,  bounds . getLowerBoundForState ( initialStateIndex ,  explorationInformation ) ,  bounds . getUpperBoundForState ( initialStateIndex ,  explorationInformation ) ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -180,13 +180,16 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // If the current path length exceeds the threshold and the model is a nondeterministic one, we
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // perform an EC detection.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( stack . size ( )  >  stats . pathLengthUntilEndComponentDetection  & &  ! program . isDeterministicModel ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        detectEndComponents ( stack ,  explorationInformation ,  bounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( stack . size ( )  >  explorationInformation . getPathLengthUntilEndComponentDetection ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        bool  success  =  detectEndComponents ( stack ,  explorationInformation ,  bounds ,  stat s ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        // Abort the current search.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Aborting the search after EC detection. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        stack . clear ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        // Only if the detection found an EC, we abort the search.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( success )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            // Abort the current search.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_TRACE ( " Aborting the search after succesful EC detection. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            stack . clear ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            break ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -296,31 +299,17 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Determine the values of all available actions.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < std : : pair < ActionType ,  ValueType > >  actionValues ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            StateType  rowGroup  =  explorationInformation . getRowGroup ( currentStateId ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            auto  choicesInEcIt  =  explorationInformation . stateToLeavingActionsOfEndComponent . find ( currentStateId ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Check for cases in which we do not need to perform more work.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( choicesInEcIt  = =  explorationInformation . stateToLeavingActionsOfEndComponent . end ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( explorationInformation . onlyOneActionAvailable ( rowGroup ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  explorationInformation . getStartRowOfGroup ( rowGroup ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( choicesInEcIt - > second - > size ( )  = =  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  * choicesInEcIt - > second - > begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( explorationInformation . onlyOneActionAvailable ( rowGroup ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  explorationInformation . getStartRowOfGroup ( rowGroup ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If there are more choices to consider, start by gathering the values of relevant actions.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( choicesInEcIt  ! =  explorationInformation . stateToLeavingActionsOfEndComponent . end ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " Sampling from actions leaving the previously detected EC. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  row  :  * choicesInEcIt - > second )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    actionValues . push_back ( std : : make_pair ( row ,  bounds . getBoundForAction ( explorationInformation . optimizationDirection ,  row ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " Sampling from actions leaving the state. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( uint32_t  row  =  explorationInformation . getStartRowOfGroup ( rowGroup ) ;  row  <  explorationInformation . getStartRowOfGroup ( rowGroup  +  1 ) ;  + + row )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    actionValues . push_back ( std : : make_pair ( row ,  bounds . getBoundForAction ( explorationInformation . optimizationDirection ,  row ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Sampling from actions leaving the state. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( uint32_t  row  =  explorationInformation . getStartRowOfGroup ( rowGroup ) ;  row  <  explorationInformation . getStartRowOfGroup ( rowGroup  +  1 ) ;  + + row )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                actionValues . push_back ( std : : make_pair ( row ,  bounds . getBoundForAction ( explorationInformation . optimizationDirection ,  row ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_ASSERT ( ! actionValues . empty ( ) ,  " Values for actions must not be empty. " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -356,8 +345,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  SparseMdpLearningModelChecker < ValueType > : : detectEndComponents ( StateActionStack  const &  stack ,  ExplorationInformation &  explorationInformation ,  BoundValues &  bounds )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Starting EC detection. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  SparseMdpLearningModelChecker < ValueType > : : detectEndComponents ( StateActionStack  const &  stack ,  ExplorationInformation &  explorationInformation ,  BoundValues &  bounds ,  Statistics &  stats )  const  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Starting  "  < <  ( explorationInformation . useLocalECDetection ( )  ?  " local "  :  " global " )  < <  " EC detection. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            + + stats . ecDetections ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Outline:
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // 1. construct a sparse transition matrix of the relevant part of the state space.
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -428,19 +418,29 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : MaximalEndComponentDecomposition < ValueType >  mecDecomposition ( relevantStatesMatrix ,  relevantStatesMatrix . transpose ( true ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Successfully computed MEC decomposition. Found  "  < <  ( mecDecomposition . size ( )  >  1  ?  ( mecDecomposition . size ( )  -  1 )  :  0 )  < <  "  MEC(s). " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // 3. Analyze the MEC decomposition.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  const &  mec  :  mecDecomposition )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Ignore the (expected) MEC of the sink state.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( mec . containsState ( sink ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    continue ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If the decomposition contains only the MEC consisting of the sink state, we count it as 'failed'.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( mecDecomposition . size ( )  < =  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                + + stats . failedEcDetections ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					//                explorationInformation.increasePathLengthUntilEndComponentDetection();
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                stats . totalNumberOfEcDetected  + =  mecDecomposition . size ( )  -  1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( explorationInformation . maximize ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    analyzeMecForMaximalProbabilities ( mec ,  relevantStates ,  relevantStatesMatrix ,  explorationInformation ,  bounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    analyzeMecForMinimalProbabilities ( mec ,  relevantStates ,  relevantStatesMatrix ,  explorationInformation ,  bounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // 3. Analyze the MEC decomposition.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  mec  :  mecDecomposition )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Ignore the (expected) MEC of the sink state.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( mec . containsState ( sink ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        continue ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( explorationInformation . maximize ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        analyzeMecForMaximalProbabilities ( mec ,  relevantStates ,  relevantStatesMatrix ,  explorationInformation ,  bounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        analyzeMecForMinimalProbabilities ( mec ,  relevantStates ,  relevantStatesMatrix ,  explorationInformation ,  bounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -453,7 +453,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  containsTargetState  =  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Now we record all choices leaving the EC.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            ActionSetPointer  leavingChoices  =  std : : make_shared < ActionSet > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < ActionType >  leavingActions ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  const &  stateAndChoices  :  mec )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Compute the state of the original model that corresponds to the current state.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                StateType  originalState  =  relevantStates [ stateAndChoices . first ] ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -473,18 +473,16 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Current (local) choice iterated is  "  < <  ( action  -  explorationInformation . getStartRowOfGroup ( originalRowGroup ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if  ( action  -  explorationInformation . getStartRowOfGroup ( originalRowGroup )  ! =  * includedChoicesIt  -  relevantStatesMatrix . getRowGroupIndices ( ) [ stateAndChoices . first ] )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_TRACE ( " Choice leaves the EC. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            leavingChoices - > insert  ( action ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            leavingActions . push_back  ( action ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_TRACE ( " Choice stays in the EC. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            + + includedChoicesIt ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Choice leaves the EC, because there is no more choice staying in the EC. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        leavingChoices - > insert  ( action ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        leavingActions . push_back  ( action ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                explorationInformation . stateToLeavingActionsOfEndComponent [ originalState ]  =  leavingChoices ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If one of the states of the EC is a target state, all states in the EC have probability 1.
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -498,7 +496,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bounds . setLowerBoundForState ( originalState ,  explorationInformation ,  storm : : utility : : one < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    explorationInformation . addTerminalState ( originalState ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  if  ( leavingChoices - >  empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  if  ( leavingActions .  empty ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " MEC's leaving choices are empty. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // If there is no choice leaving the EC, but it contains no target state, all states have probability 0.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  stateAndChoices  :  mec )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -509,6 +507,32 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bounds . setUpperBoundForState ( originalState ,  explorationInformation ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    explorationInformation . addTerminalState ( originalState ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // In this case, no target state is contained in the MEC, but there are actions leaving the MEC. To
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // prevent the simulation getting stuck in this MEC again, we replace all states in the MEC by a new
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // state whose outgoing actions are the ones leaving the MEC. We do this, by assigning all states in the
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // MEC to a new row group, which will then hold all the outgoing choices.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Remap all contained states to the new row group.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                StateType  nextRowGroup  =  explorationInformation . getNextRowGroup ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  stateAndChoices  :  mec )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    explorationInformation . assignStateToRowGroup ( stateAndChoices . first ,  nextRowGroup ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bounds . initializeBoundsForNextState ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Add to the new row group all leaving actions of contained states and set the appropriate bounds for
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // the actions and the new state.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : pair < ValueType ,  ValueType >  stateBounds  =  getLowestBounds ( explorationInformation . optimizationDirection ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  action  :  leavingActions )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    explorationInformation . matrix . emplace_back ( std : : move ( explorationInformation . matrix [ action ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : pair < ValueType ,  ValueType >  const &  actionBounds  =  bounds . getBoundsForAction ( action ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bounds . initializeBoundsForNextAction ( actionBounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    stateBounds  =  combineBounds ( explorationInformation . optimizationDirection ,  stateBounds ,  actionBounds ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Terminate the row group of the newly introduced state.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                explorationInformation . rowGroupIndices . push_back ( explorationInformation . matrix . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }