@ -7,6 +7,8 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/utility/DirectEncodingExporter.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/models/ModelType.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm/transformer/NonMarkovianChainTransformer.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm-dft/builder/ExplicitDFTModelBuilder.h" 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "storm-dft/storage/dft/DFTIsomorphism.h" 
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -17,7 +19,13 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    namespace  modelchecker  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  DFTModelChecker < ValueType > : : check ( storm : : storage : : DFT < ValueType >  const &  origDft ,  std : : vector < std : : shared_ptr < const  storm : : logic : : Formula > >  const &  properties ,  bool  symred ,  bool  allowModularisation ,  std : : set < size_t >  const &  relevantEvents ,  bool  allowDCForRelevantEvents ,  double  approximationError ,  storm : : builder : : ApproximationHeuristic  approximationHeuristic )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DFTModelChecker < ValueType > : : check ( storm : : storage : : DFT < ValueType >  const  & origDft ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                          std : : vector < std : : shared_ptr < const  storm : : logic : : Formula > >  const  & properties ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                          bool  symred ,  bool  allowModularisation ,  std : : set < size_t >  const  & relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                          bool  allowDCForRelevantEvents ,  double  approximationError ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                          storm : : builder : : ApproximationHeuristic  approximationHeuristic ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                          bool  eliminateChains ,  bool  ignoreLabeling )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            totalTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            dft_results  results ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -30,21 +38,32 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // TODO: distinguish for all properties, not only for first one
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( properties [ 0 ] - > isTimeOperatorFormula ( )  & &  allowModularisation )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Use parallel composition as modularisation approach for expected time
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model  =  buildModelViaComposition ( dft ,  properties ,  symred ,  true ,  relevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model  =  buildModelViaComposition ( dft ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                          properties ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                          symred ,  true ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                          relevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Model checking
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < ValueType >  resultsValue  =  checkModel ( model ,  properties ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( ValueType  result  :  resultsValue )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    results . push_back ( result ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                results  =  checkHelper ( dft ,  properties ,  symred ,  allowModularisation ,  relevantEvents ,  allowDCForRelevantEvents ,  approximationError ,  approximationHeuristic ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                results  =  checkHelper ( dft ,  properties ,  symred ,  allowModularisation ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                      allowDCForRelevantEvents ,  approximationError ,  approximationHeuristic ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                      eliminateChains ,  ignoreLabeling ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            totalTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  results ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  DFTModelChecker < ValueType > : : checkHelper ( storm : : storage : : DFT < ValueType >  const &  dft ,  property_vector  const &  properties ,  bool  symred ,  bool  allowModularisation ,  std : : set < size_t >  const &  relevantEvents ,  bool  allowDCForRelevantEvents ,  double  approximationError ,  storm : : builder : : ApproximationHeuristic  approximationHeuristic )   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DFTModelChecker < ValueType > : : checkHelper ( storm : : storage : : DFT < ValueType >  const  & dft ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                property_vector  const  & properties ,  bool  symred ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                bool  allowModularisation ,  std : : set < size_t >  const  & relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                bool  allowDCForRelevantEvents ,  double  approximationError ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                storm : : builder : : ApproximationHeuristic  approximationHeuristic ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                bool  eliminateChains ,  bool  ignoreLabeling )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Check helper called " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : storage : : DFT < ValueType > >  dfts ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  invResults  =  false ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -52,7 +71,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            size_t  nrM  =  0 ;  // K out of M
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Try modularisation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( allowModularisation )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if   ( allowModularisation )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                switch  ( dft . topLevelType ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    case  storm : : storage : : DFTElementType : : AND :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " top modularisation called AND " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -73,9 +92,10 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " top modularisation called VOT " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        dfts  =  dft . topModularisation ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Modularisation into  "  < <  dfts . size ( )  < <  "  submodules. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        nrK  =  std : : static_pointer_cast < storm : : storage : : DFTVot < ValueType >  const > ( dft . getTopLevelGate ( ) ) - > threshold ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        nrK  =  std : : static_pointer_cast < storm : : storage : : DFTVot < ValueType >  const > (  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                dft . getTopLevelGate ( ) ) - > threshold ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        nrM  =  dfts . size ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if ( nrK  < =  nrM / 2 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if   ( nrK  < =  nrM   /   2 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            nrK  - =  1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            invResults  =  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -87,7 +107,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Perform modularisation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( dfts . size ( )  >  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if   ( dfts . size ( )  >  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " Recursive CHECK Call " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // TODO: compute simultaneously
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                dft_results  results ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -97,39 +117,42 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        // Recursively call model checking
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        std : : vector < ValueType >  res ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( auto  const  ft  :  dfts )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for   ( auto  const  ft  :  dfts )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            // TODO: allow approximation in modularisation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            dft_results  ftResults  =  checkHelper ( ft ,  { property } ,  symred ,  true ,  relevantEvents ,  allowDCForRelevantEvents ,  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            dft_results  ftResults  =  checkHelper ( ft ,  { property } ,  symred ,  true ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                allowDCForRelevantEvents ,  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_ASSERT ( ftResults . size ( )  = =  1 ,  " Wrong number of results " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            res . push_back ( boost : : get < ValueType > ( ftResults [ 0 ] ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        // Combine modularisation results
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Combining all results... K= "  < <  nrK  < <  " ; M= "  < <  nrM  < <  " ; invResults= "  < <  ( invResults ? " On " : " Off " ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " Combining all results... K= "  < <  nrK  < <  " ; M= "  < <  nrM  < <  " ; invResults= "  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                      < <  ( invResults  ?  " On "  :  " Off " ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        ValueType  result  =  storm : : utility : : zero < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        int  limK  =  invResults  ?  - 1  :  nrM + 1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        int  limK  =  invResults  ?  - 1  :  nrM   +   1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        int  chK  =  invResults  ?  - 1  :  1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        // WARNING: there is a bug for computing permutations with more than 32 elements
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_THROW ( res . size ( )  <  32 ,  storm : : exceptions : : NotSupportedException ,  " Permutations work only for < 32 elements " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for ( int  cK  =  nrK ;  cK  ! =  limK ;  cK  + =  chK  )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_THROW ( res . size ( )  <  32 ,  storm : : exceptions : : NotSupportedException ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                        " Permutations work only for < 32 elements " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        for  ( int  cK  =  nrK ;  cK  ! =  limK ;  cK  + =  chK )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            STORM_LOG_ASSERT ( cK  > =  0 ,  " ck negative. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            size_t  permutation  =  smallestIntWithNBitsSet ( static_cast < size_t > ( cK ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            do  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                STORM_LOG_TRACE ( " Permutation= " < < permutation ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                STORM_LOG_TRACE ( " Permutation= "   < <   permutation ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                ValueType  permResult  =  storm : : utility : : one < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                for ( size_t  i  =  0 ;  i  <  res . size ( ) ;  + + i )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    if ( permutation  &  ( 1  < <  i ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                for   ( size_t  i  =  0 ;  i  <  res . size ( ) ;  + + i )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    if   ( permutation  &  ( 1  < <  i ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                        permResult  * =  res [ i ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                        permResult  * =  storm : : utility : : one < ValueType > ( )  -  res [ i ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                STORM_LOG_TRACE ( " Result for permutation: " < < permResult ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                STORM_LOG_TRACE ( " Result for permutation: "   < <   permResult ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                permutation  =  nextBitPermutation ( permutation ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                result  + =  permResult ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  while ( permutation  <  ( 1  < <  nrM )  & &  permutation  ! =  0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            }  while   ( permutation  <  ( 1  < <  nrM )  & &  permutation  ! =  0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if ( invResults )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        if   ( invResults )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            result  =  storm : : utility : : one < ValueType > ( )  -  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        results . push_back ( result ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -138,19 +161,25 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  results ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // No modularisation was possible
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  checkDFT ( dft ,  properties ,  symred ,  relevantEvents ,  allowDCForRelevantEvents ,  approximationError ,  approximationHeuristic ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  checkDFT ( dft ,  properties ,  symred ,  relevantEvents ,  allowDCForRelevantEvents ,  approximationError ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                approximationHeuristic ,  eliminateChains ,  ignoreLabeling ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : shared_ptr < storm : : models : : sparse : : Ctmc < ValueType > >  DFTModelChecker < ValueType > : : buildModelViaComposition ( storm : : storage : : DFT < ValueType >  const &  dft ,  property_vector  const &  properties ,  bool  symred ,  bool  allowModularisation ,  std : : set < size_t >  const &  relevantEvents ,  bool  allowDCForRelevantEvents )   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : shared_ptr < storm : : models : : sparse : : Ctmc < ValueType > >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DFTModelChecker < ValueType > : : buildModelViaComposition ( storm : : storage : : DFT < ValueType >  const  & dft ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                             property_vector  const  & properties ,  bool  symred ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                             bool  allowModularisation ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                             std : : set < size_t >  const  & relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                             bool  allowDCForRelevantEvents )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // TODO: use approximation?
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_TRACE ( " Build model via composition " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : vector < storm : : storage : : DFT < ValueType > >  dfts ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  isAnd  =  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Try modularisation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( allowModularisation )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if   ( allowModularisation )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                switch  ( dft . topLevelType ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    case  storm : : storage : : DFTElementType : : AND :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_TRACE ( " top modularisation called AND " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -174,7 +203,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Perform modularisation via parallel composition
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( dfts . size ( )  >  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if   ( dfts . size ( )  >  1 )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_TRACE ( " Recursive CHECK Call " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  firstTime  =  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Ctmc < ValueType > >  composedModel ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -185,7 +214,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Find symmetries
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : map < size_t ,  std : : vector < std : : vector < size_t > > >  emptySymmetry ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : DFTIndependentSymmetries  symmetries ( emptySymmetry ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if   ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        auto  colouring  =  ft . colourDFT ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        symmetries  =  ft . findSymmetries ( colouring ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        STORM_LOG_DEBUG ( " Found  "  < <  symmetries . groups . size ( )  < <  "  symmetries. " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -194,29 +223,37 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Build a single CTMC
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_DEBUG ( " Building Model... " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( ft ,  symmetries ,  relevantEvents ,  allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( ft ,  symmetries ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                               allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    builder . buildModel ( 0 ,  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model  =  builder . getModel ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    explorationTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_THROW ( model - > isOfType ( storm : : models : : ModelType : : Ctmc ) ,  storm : : exceptions : : NotSupportedException ,  " Parallel composition only applicable for CTMCs " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_THROW ( model - > isOfType ( storm : : models : : ModelType : : Ctmc ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    storm : : exceptions : : NotSupportedException ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    " Parallel composition only applicable for CTMCs " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    std : : shared_ptr < storm : : models : : sparse : : Ctmc < ValueType > >  ctmc  =  model - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Apply bisimulation to new CTMC
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bisimulationTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ctmc  =   storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > ( ctmc ,  properties ,  storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    ctmc  =  storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > (  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            ctmc ,  properties ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bisimulationTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( firstTime )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        composedModel  =  ctmc ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        firstTime  =  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        composedModel  =  storm : : builder : : ParallelCompositionBuilder < ValueType > : : compose ( composedModel ,  ctmc ,  isAnd ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        composedModel  =  storm : : builder : : ParallelCompositionBuilder < ValueType > : : compose ( composedModel ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                       ctmc ,  isAnd ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Apply bisimulation to parallel composition
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bisimulationTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    composedModel  =  storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > ( composedModel ,  properties ,  storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    composedModel  =  storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > (  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            composedModel ,  properties ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    bisimulationTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_DEBUG ( " No. states (Composed):  "  < <  composedModel - > getNumberOfStates ( ) ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -236,7 +273,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Find symmetries
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : map < size_t ,  std : : vector < std : : vector < size_t > > >  emptySymmetry ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : DFTIndependentSymmetries  symmetries ( emptySymmetry ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if   ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  colouring  =  dft . colourDFT ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    symmetries  =  dft . findSymmetries ( colouring ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_DEBUG ( " Found  "  < <  symmetries . groups . size ( )  < <  "  symmetries. " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -245,24 +282,33 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Build a single CTMC
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Building Model... " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                           allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                builder . buildModel ( 0 ,  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model  =  builder . getModel ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //model->printModelInformationToStream(std::cout);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                explorationTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_THROW ( model - > isOfType ( storm : : models : : ModelType : : Ctmc ) ,  storm : : exceptions : : NotSupportedException ,  " Parallel composition only applicable for CTMCs " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_THROW ( model - > isOfType ( storm : : models : : ModelType : : Ctmc ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                storm : : exceptions : : NotSupportedException ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                " Parallel composition only applicable for CTMCs " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  model - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  DFTModelChecker < ValueType > : : checkDFT ( storm : : storage : : DFT < ValueType >  const &  dft ,  property_vector  const &  properties ,  bool  symred ,  std : : set < size_t >  const &  relevantEvents ,  bool  allowDCForRelevantEvents ,  double  approximationError ,  storm : : builder : : ApproximationHeuristic  approximationHeuristic )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  DFTModelChecker < ValueType > : : dft_results  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DFTModelChecker < ValueType > : : checkDFT ( storm : : storage : : DFT < ValueType >  const  & dft ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                             property_vector  const  & properties ,  bool  symred ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                             std : : set < size_t >  const  & relevantEvents ,  bool  allowDCForRelevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                             double  approximationError ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                             storm : : builder : : ApproximationHeuristic  approximationHeuristic ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                             bool  eliminateChains ,  bool  ignoreLabeling )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            explorationTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Find symmetries
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : map < size_t ,  std : : vector < std : : vector < size_t > > >  emptySymmetry ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : DFTIndependentSymmetries  symmetries ( emptySymmetry ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if   ( symred )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  colouring  =  dft . colourDFT ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                symmetries  =  dft . findSymmetries ( colouring ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Found  "  < <  symmetries . groups . size ( )  < <  "  symmetries. " ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -273,10 +319,12 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Comparator for checking the error of the approximation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : utility : : ConstantsComparator < ValueType >  comparator ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Build approximate Markov Automata for lower and upper bound
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                approximation_result  approxResult  =  std : : make_pair ( storm : : utility : : zero < ValueType > ( ) ,  storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                approximation_result  approxResult  =  std : : make_pair ( storm : : utility : : zero < ValueType > ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                   storm : : utility : : zero < ValueType > ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : vector < ValueType >  newResult ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                           allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // TODO: compute approximation for all properties simultaneously?
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < const  storm : : logic : : Formula >  property  =  properties [ 0 ] ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -285,7 +333,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bool  probabilityFormula  =  property - > isProbabilityOperatorFormula ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_ASSERT ( ( property - > isTimeOperatorFormula ( )  & &  ! probabilityFormula )  | |  ( ! property - > isTimeOperatorFormula ( )  & &  probabilityFormula ) ,  " Probability formula not initialized correctly " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_ASSERT ( ( property - > isTimeOperatorFormula ( )  & &  ! probabilityFormula )  | |  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                 ( ! property - > isTimeOperatorFormula ( )  & &  probabilityFormula ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                 " Probability formula not initialized correctly " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                size_t  iteration  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                do  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Iteratively build finer models
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -310,7 +360,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Check lower bounds
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    newResult  =  checkModel ( model ,  { property } ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( newResult . size ( )  = =  1 ,  " Wrong size for result vector. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( iteration  = =  0  | |  ! comparator . isLess ( newResult [ 0 ] ,  approxResult . first ) ,  " New under-approximation  "  < <  newResult [ 0 ]  < <  "  is smaller than old result  "  < <  approxResult . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( iteration  = =  0  | |  ! comparator . isLess ( newResult [ 0 ] ,  approxResult . first ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     " New under-approximation  "  < <  newResult [ 0 ]  < <  "  is smaller than old result  "  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                < <  approxResult . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    approxResult . first  =  newResult [ 0 ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Build model for upper bound
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -321,17 +373,27 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    // Check upper bound
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    newResult  =  checkModel ( model ,  { property } ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( newResult . size ( )  = =  1 ,  " Wrong size for result vector. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( iteration  = =  0  | |  ! comparator . isLess ( approxResult . second ,  newResult [ 0 ] ) ,  " New over-approximation  "  < <  newResult [ 0 ]  < <  "  is greater than old result  "  < <  approxResult . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( iteration  = =  0  | |  ! comparator . isLess ( approxResult . second ,  newResult [ 0 ] ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     " New over-approximation  "  < <  newResult [ 0 ]  < <  "  is greater than old result  "  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                               < <  approxResult . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    approxResult . second  =  newResult [ 0 ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    + + iteration ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( comparator . isLess ( approxResult . first ,  approxResult . second )  | |  comparator . isEqual ( approxResult . first ,  approxResult . second ) ,  " Under-approximation  "  < <  approxResult . first  < <  "  is greater than over-approximation  "  < <  approxResult . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_ASSERT ( comparator . isLess ( approxResult . first ,  approxResult . second )  | |  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     comparator . isEqual ( approxResult . first ,  approxResult . second ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     " Under-approximation  "  < <  approxResult . first  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                            < <  "  is greater than over-approximation  "  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                            < <  approxResult . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    //STORM_LOG_INFO("Result after iteration " << iteration << ": (" << std::setprecision(10) << approxResult.first << ", " << approxResult.second << ")");
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    totalTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    printTimings ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    totalTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_THROW ( ! storm : : utility : : isInfinity < ValueType > ( approxResult . first )  & &  ! storm : : utility : : isInfinity < ValueType > ( approxResult . second ) ,  storm : : exceptions : : NotSupportedException ,  " Approximation does not work if result might be infinity. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  while  ( ! isApproximationSufficient ( approxResult . first ,  approxResult . second ,  approximationError ,  probabilityFormula ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    STORM_LOG_THROW ( ! storm : : utility : : isInfinity < ValueType > ( approxResult . first )  & &  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    ! storm : : utility : : isInfinity < ValueType > ( approxResult . second ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    storm : : exceptions : : NotSupportedException ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    " Approximation does not work if result might be infinity. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  while  ( ! isApproximationSufficient ( approxResult . first ,  approxResult . second ,  approximationError ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                    probabilityFormula ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //STORM_LOG_INFO("Finished approximation after " << iteration << " iteration" << (iteration > 1 ? "s." : "."));
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                dft_results  results ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -341,9 +403,15 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Build a single Markov Automaton
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                auto  ioSettings  =  storm : : settings : : getModule < storm : : settings : : modules : : IOSettings > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Building Model... " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : builder : : ExplicitDFTModelBuilder < ValueType >  builder ( dft ,  symmetries ,  relevantEvents ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                           allowDCForRelevantEvents ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                builder . buildModel ( 0 ,  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  model  =  builder . getModel ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                if  ( eliminateChains  & &  model - > isOfType ( storm : : models : : ModelType : : MarkovAutomaton ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  ma  =  std : : static_pointer_cast < storm : : models : : sparse : : MarkovAutomaton < ValueType > > ( model ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    model  =  storm : : transformer : : NonMarkovianChainTransformer < ValueType > : : eliminateNonmarkovianStates ( ma ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                                     ! ignoreLabeling ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                explorationTimer . stop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Print model information
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -376,12 +444,17 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < ValueType >  DFTModelChecker < ValueType > : : checkModel ( std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > > &  model ,  property_vector  const &  properties )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        std : : vector < ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DFTModelChecker < ValueType > : : checkModel ( std : : shared_ptr < storm : : models : : sparse : : Model < ValueType > >  & model ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                               property_vector  const  & properties )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Bisimulation
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( model - > isOfType ( storm : : models : : ModelType : : Ctmc )  & &  storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) . isBisimulationSet ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( model - > isOfType ( storm : : models : : ModelType : : Ctmc )  & &  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) . isBisimulationSet ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bisimulationTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " Bisimulation... " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                model  =   storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > ( model - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ,  properties ,  storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                model  =  storm : : api : : performDeterministicSparseBisimulationMinimization < storm : : models : : sparse : : Ctmc < ValueType > > (  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        model - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ,  properties ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : storage : : BisimulationType : : Weak ) - > template  as < storm : : models : : sparse : : Ctmc < ValueType > > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " No. states (Bisimulation):  "  < <  model - > getNumberOfStates ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_DEBUG ( " No. transitions (Bisimulation):  "  < <  model - > getNumberOfTransitions ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                bisimulationTimer . stop ( ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -398,7 +471,9 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                singleModelCheckingTimer . reset ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                singleModelCheckingTimer . start ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                //STORM_PRINT_AND_LOG("Model checking property " << *property << " ..." << std::endl);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : unique_ptr < storm : : modelchecker : : CheckResult >  result ( storm : : api : : verifyWithSparseEngine < ValueType > ( model ,  storm : : api : : createTask < ValueType > ( property ,  true ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : unique_ptr < storm : : modelchecker : : CheckResult >  result (  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        storm : : api : : verifyWithSparseEngine < ValueType > ( model ,  storm : : api : : createTask < ValueType > ( property ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                                                               true ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                STORM_LOG_ASSERT ( result ,  " Result does not exist. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                result - > filter ( storm : : modelchecker : : ExplicitQualitativeCheckResult ( model - > getInitialStates ( ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                ValueType  resultValue  =  result - > asExplicitQuantitativeCheckResult < ValueType > ( ) . getValueMap ( ) . begin ( ) - > second ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -413,13 +488,15 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  DFTModelChecker < ValueType > : : isApproximationSufficient ( ValueType   ,  ValueType   ,  double   ,  bool   )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  DFTModelChecker < ValueType > : : isApproximationSufficient ( ValueType ,  ValueType ,  double ,  bool )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( false ,  storm : : exceptions : : NotImplementedException ,  " Approximation works only for double. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  DFTModelChecker < double > : : isApproximationSufficient ( double  lowerBound ,  double  upperBound ,  double  approximationError ,  bool  relative )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( ! std : : isnan ( lowerBound )  & &  ! std : : isnan ( upperBound ) ,  storm : : exceptions : : NotSupportedException ,  " Approximation does not work if result is NaN. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  DFTModelChecker < double > : : isApproximationSufficient ( double  lowerBound ,  double  upperBound ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                                double  approximationError ,  bool  relative )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( ! std : : isnan ( lowerBound )  & &  ! std : : isnan ( upperBound ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                            storm : : exceptions : : NotSupportedException ,  " Approximation does not work if result is NaN. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( relative )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  upperBound  -  lowerBound  < =  approximationError ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  else  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -428,17 +505,17 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  DFTModelChecker < ValueType > : : printTimings ( std : : ostream &   os )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  DFTModelChecker < ValueType > : : printTimings ( std : : ostream   & os )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Times: "  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Exploration: \t "  < <  explorationTimer  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Building: \t "  < <  buildingTimer  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Bisimulation: \t "  < <  bisimulationTimer < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Bisimulation: \t "  < <  bisimulationTimer   < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Modelchecking: \t "  < <  modelCheckingTimer  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Total: \t \t "  < <  totalTimer  < <  std : : endl ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  DFTModelChecker < ValueType > : : printResults ( dft_results  const &   results ,  std : : ostream &   os )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  DFTModelChecker < ValueType > : : printResults ( dft_results  const   & results ,  std : : ostream   & os )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  first  =  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            os  < <  " Result: [ " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  result  :  results )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -453,10 +530,14 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  class  DFTModelChecker < double > ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        class  DFTModelChecker < double > ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# ifdef STORM_HAVE_CARL 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  class  DFTModelChecker < storm : : RationalFunction > ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        class  DFTModelChecker < storm : : RationalFunction > ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif 
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}