@ -475,6 +475,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        DeterministicModelBisimulationDecomposition < ValueType > : : DeterministicModelBisimulationDecomposition ( storm : : models : : Dtmc < ValueType >  const &  dtmc ,  bool  weak ,  bool  buildQuotient )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            STORM_LOG_THROW ( ! dtmc . hasStateRewards ( )  & &  ! dtmc . hasTransitionRewards ( ) ,  storm : : exceptions : : IllegalFunctionCallException ,  " Bisimulation is currently only supported for models without reward structures. " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            computeBisimulationEquivalenceClasses ( dtmc ,  weak ,  buildQuotient ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -492,7 +493,7 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // (c) the new reward structures.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Prepare a matrix builder for (a).
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrixBuilder < ValueType >  builder ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : storage : : SparseMatrixBuilder < ValueType >  builder ( this - > size ( ) ,  this - > size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Prepare the new state labeling for (b).
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            storm : : models : : AtomicPropositionsLabeling  newLabeling ( this - > size ( ) ,  dtmc . getStateLabeling ( ) . getNumberOfAtomicPropositions ( ) ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -509,7 +510,22 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Pick one representative state. It doesn't matter which state it is, because they all behave equally.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                storm : : storage : : sparse : : state_type  representativeState  =  * block . begin ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Add the outgoing transitions
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Compute the outgoing transitions of the block.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                std : : map < storm : : storage : : sparse : : state_type ,  ValueType >  blockProbability ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  entry  :  dtmc . getTransitionMatrix ( ) . getRow ( representativeState ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    storm : : storage : : sparse : : state_type  targetBlock  =  partition . getBlock ( entry . getColumn ( ) ) . getId ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    auto  probIterator  =  blockProbability . find ( targetBlock ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    if  ( probIterator  ! =  blockProbability . end ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        probIterator - > second  + =  entry . getValue ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  else  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                        blockProbability [ targetBlock ]  =  entry . getValue ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Now add them to the actual matrix.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  probabilityEntry  :  blockProbability )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    builder . addNextValue ( blockIndex ,  probabilityEntry . first ,  probabilityEntry . second ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                // Add all atomic propositions to the equivalence class that the representative state satisfies.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                for  ( auto  const &  ap  :  atomicPropositions )  {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -525,7 +541,11 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                newLabeling . addAtomicPropositionToState ( " init " ,  initialBlock . getId ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > quotient  =  nullptr ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // FIXME:
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If reward structures are allowed, the quotient structures need to be built here.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Finally construct the quotient model.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > quotient  =  std : : shared_ptr < storm : : models : : AbstractDeterministicModel < ValueType > > ( new  storm : : models : : Dtmc < ValueType > ( builder . build ( ) ,  std : : move ( newLabeling ) ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template < typename  ValueType >  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -555,16 +575,16 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                splitterQueue . pop_front ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If we are required to build the quotient model, do so now.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( buildQuotient )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > buildQuotient ( dtmc ,  partition ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // Now move the states from the internal partition into their final place in the decomposition. We do so in
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // a way that maintains the block IDs as indices.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            this - > blocks . resize ( partition . size ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            for  ( auto  const &  block  :  partition . getBlocks ( ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > blocks [ block . getId ( ) ]  =  block_type ( partition . getBeginOfStates ( block ) ,  partition . getEndOfStates ( block ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > blocks [ block . getId ( ) ]  =  block_type ( partition . getBeginOfStates ( block ) ,  partition . getEndOfStates ( block ) ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            // If we are required to build the quotient model, do so now.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( buildQuotient )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                this - > buildQuotient ( dtmc ,  partition ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : chrono : : high_resolution_clock : : duration  totalTime  =  std : : chrono : : high_resolution_clock : : now ( )  -  totalStart ;