@ -226,7 +226,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            template < storm : : dd : : DdType  DdType ,  typename  ValueType >  
				 
				 
				            template < storm : : dd : : DdType  DdType ,  typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            class  InternalSparseQuotientExtractorBase  {  
				 
				 
				            class  InternalSparseQuotientExtractorBase  {  
			
		 
		
	
		
			
				 
				 
				            public :  
				 
				 
				            public :  
			
		 
		
	
		
			
				 
				 
				                InternalSparseQuotientExtractorBase ( storm : : models : : symbolic : : Model < DdType ,  ValueType >  const &  model ,  Partition < DdType ,  Value Type>  const &  partition ,  storm : : dd : : Bdd < DdType >  const &  representatives )  :  manager ( model . getManager ( ) ) ,  isNondeterministic ( false ) ,  partition ( partition ) ,  representatives ( representatives ) ,  matrixEntriesCreated ( false )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                InternalSparseQuotientExtractorBase ( storm : : models : : symbolic : : Model < DdType ,  ValueType >  const &  model ,  storm : : dd : : Bdd < Dd Type>  const &  partitionBdd  ,  storm : : dd : : Bdd < DdType >  const &  representatives ,  uint64_t  numberOfBlocks )  :  manager ( model . getManager ( ) ) ,  isNondeterministic ( false ) ,  partitionBdd  ( partitionBdd ) ,  numberOfBlocks ( numberOfBlocks  ) ,  representatives ( representatives ) ,  matrixEntriesCreated ( false )  {  
			
		 
		
	
		
			
				 
				 
				                    // Create cubes.
  
				 
				 
				                    // Create cubes.
  
			
		 
		
	
		
			
				 
				 
				                    rowVariablesCube  =  manager . getBddOne ( ) ;  
				 
				 
				                    rowVariablesCube  =  manager . getBddOne ( ) ;  
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  const &  variable  :  model . getRowVariables ( ) )  {  
				 
				 
				                    for  ( auto  const &  variable  :  model . getRowVariables ( ) )  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -251,6 +251,8 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                    if  ( this - > isNondeterministic )  {  
				 
				 
				                    if  ( this - > isNondeterministic )  {  
			
		 
		
	
		
			
				 
				 
				                        this - > nondeterminismOdd  =  ( model . getQualitativeTransitionMatrix ( ) . existsAbstract ( model . getColumnVariables ( ) )  & &  this - > representatives ) . createOdd ( ) ;  
				 
				 
				                        this - > nondeterminismOdd  =  ( model . getQualitativeTransitionMatrix ( ) . existsAbstract ( model . getColumnVariables ( ) )  & &  this - > representatives ) . createOdd ( ) ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    STORM_LOG_TRACE ( " Partition has  "  < <  partitionBdd . existsAbstract ( model . getRowVariables ( ) ) . getNonZeroCount ( )  < <  "  states in  "  < <  this - > numberOfBlocks  < <  "  blocks. " ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Odd  const &  getOdd ( )  const  {  
				 
				 
				                storm : : dd : : Odd  const &  getOdd ( )  const  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -274,7 +276,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    uint64_t  rowCounter  =  0 ;  
				 
				 
				                    uint64_t  rowCounter  =  0 ;  
			
		 
		
	
		
			
				 
				 
				                    uint64_t  lastState  =  this - > isNondeterministic  ?  rowToState [ rowPermutation . front ( ) ]  :  0 ;  
				 
				 
				                    uint64_t  lastState  =  this - > isNondeterministic  ?  rowToState [ rowPermutation . front ( ) ]  :  0 ;  
			
		 
		
	
		
			
				 
				 
				                    storm : : storage : : SparseMatrixBuilder < ValueType >  builder ( matrixEntries . size ( ) ,  partition . getNumberOfBlocks ( ) ,  0 ,  true ,  this - > isNondeterministic ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    storm : : storage : : SparseMatrixBuilder < ValueType >  builder ( matrixEntries . size ( ) ,  this - > numberOfBlocks ,  0 ,  true ,  this - > isNondeterministic ) ;  
			
		 
		
	
		
			
				 
				 
				                    if  ( this - > isNondeterministic )  {  
				 
				 
				                    if  ( this - > isNondeterministic )  {  
			
		 
		
	
		
			
				 
				 
				                        builder . newRowGroup ( 0 ) ;  
				 
				 
				                        builder . newRowGroup ( 0 ) ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -337,7 +339,8 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Bdd < DdType >  nondeterminismVariablesCube ;  
				 
				 
				                storm : : dd : : Bdd < DdType >  nondeterminismVariablesCube ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Information about the state partition.
  
				 
				 
				                // Information about the state partition.
  
			
		 
		
	
		
			
				 
				 
				                Partition < DdType ,  ValueType >  partition ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                storm : : dd : : Bdd < DdType >  partitionBdd ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                uint64_t  numberOfBlocks ;  
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Bdd < DdType >  representatives ;  
				 
				 
				                storm : : dd : : Bdd < DdType >  representatives ;  
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Odd  odd ;  
				 
				 
				                storm : : dd : : Odd  odd ;  
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Odd  nondeterminismOdd ;  
				 
				 
				                storm : : dd : : Odd  nondeterminismOdd ;  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -355,28 +358,25 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            class  InternalSparseQuotientExtractor < storm : : dd : : DdType : : CUDD ,  ValueType >  :  public  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : CUDD ,  ValueType >  {  
				 
				 
				            class  InternalSparseQuotientExtractor < storm : : dd : : DdType : : CUDD ,  ValueType >  :  public  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : CUDD ,  ValueType >  {  
			
		 
		
	
		
			
				 
				 
				            public :  
				 
				 
				            public :  
			
		 
		
	
		
			
				 
				 
				                InternalSparseQuotientExtractor ( storm : : models : : symbolic : : Model < storm : : dd : : DdType : : CUDD ,  ValueType >  const &  model ,  Partition < storm : : dd : : DdType : : CUDD ,  ValueType >  const &  partition ,  storm : : dd : : Bdd < storm : : dd : : DdType : : CUDD >  const &  representatives )  :  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : CUDD ,  ValueType > ( model ,  partition ,  representatives ) ,  ddman ( this - > manager . getInternalDdManager ( ) . getCuddManager ( ) . getManager ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_ASSERT ( this - > partition . storedAsAdd ( ) ,  " Expected partition to be stored as an ADD. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                InternalSparseQuotientExtractor ( storm : : models : : symbolic : : Model < storm : : dd : : DdType : : CUDD ,  ValueType >  const &  model ,  storm : : dd : : Bdd < storm : : dd : : DdType : : CUDD >  const &  partitionBdd ,  storm : : dd : : Bdd < storm : : dd : : DdType : : CUDD >  const &  representatives ,  uint64_t  numberOfBlocks )  :  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : CUDD ,  ValueType > ( model ,  partitionBdd ,  representatives ,  numberOfBlocks ) ,  ddman ( this - > manager . getInternalDdManager ( ) . getCuddManager ( ) . getManager ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                    this - > createBlockToOffsetMapping ( ) ;  
				 
				 
				                    this - > createBlockToOffsetMapping ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  extractTransitionMatrix ( storm : : dd : : Add < storm : : dd : : DdType : : CUDD ,  ValueType >  const &  transitionMatrix )  {  
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  extractTransitionMatrix ( storm : : dd : : Add < storm : : dd : : DdType : : CUDD ,  ValueType >  const &  transitionMatrix )  {  
			
		 
		
	
		
			
				 
				 
				                    // Create the number of rows necessary for the matrix.
  
				 
				 
				                    // Create the number of rows necessary for the matrix.
  
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_TRACE ( " Partition has  "  < <  this - > partition . getNumberOfStates ( )  < <  "  states in  "  < <  this - > partition . getNumberOfBlocks ( )  < <  "  blocks. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    this - > createMatrixEntryStorage ( ) ;  
				 
				 
				                    this - > createMatrixEntryStorage ( ) ;  
			
		 
		
	
		
			
				 
				 
				                    extractTransitionMatrixRec ( transitionMatrix . getInternalAdd ( ) . getCuddDdNode ( ) ,  this - > isNondeterministic  ?  this - > nondeterminismOdd  :  this - > odd ,  0 ,  this - > partition . asAdd ( ) . getInternalA dd( ) . getCuddDdNode ( ) ,  this - > representatives . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > allSourceVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > nondeterminismVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > isNondeterministic  ?  & this - > odd  :  nullptr ,  0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    extractTransitionMatrixRec ( transitionMatrix . getInternalAdd ( ) . getCuddDdNode ( ) ,  this - > isNondeterministic  ?  this - > nondeterminismOdd  :  this - > odd ,  0 ,  this - > partitionBdd . getInternalB dd ( ) . getCuddDdNode ( ) ,  this - > representatives . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > allSourceVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > nondeterminismVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > isNondeterministic  ?  & this - > odd  :  nullptr ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				                    return  this - > createMatrixFromEntries ( ) ;  
				 
				 
				                    return  this - > createMatrixFromEntries ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				            private :  
				 
				 
				            private :  
			
		 
		
	
		
			
				 
				 
				                void  createBlockToOffsetMapping ( )  {  
				 
				 
				                void  createBlockToOffsetMapping ( )  {  
			
		 
		
	
		
			
				 
				 
				                    this - > createBlockToOffsetMappingRec ( this - > partition . asAdd ( ) . getInternalA dd( ) . getCuddDdNode ( ) ,  this - > representatives . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > rowVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > odd ,  0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_ASSERT ( blockToOffset . size ( )  = =  this - > partitio n. getN umberOfBlocks( ) ,  " Mismatching block-to-offset mapping:  "  < <  blockToOffset . size ( )  < <  "  vs.  "  < <  this - > partitio n. getN umberOfBlocks( )   < <  " . " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    this - > createBlockToOffsetMappingRec ( this - > partitionBdd . getInternalB dd ( ) . getCuddDdNode ( ) ,  this - > representatives . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > rowVariablesCube . getInternalBdd ( ) . getCuddDdNode ( ) ,  this - > odd ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    STORM_LOG_ASSERT ( blockToOffset . size ( )  = =  this - > numberOfBlocks ,  " Mismatching block-to-offset mapping:  "  < <  blockToOffset . size ( )  < <  "  vs.  "  < <  this - > numberOfBlocks  < <  " . " ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                void  createBlockToOffsetMappingRec ( DdNodePtr  partitionNode ,  DdNodePtr  representativesNode ,  DdNodePtr  variables ,  storm : : dd : : Odd  const &  odd ,  uint64_t  offset )  {  
				 
				 
				                void  createBlockToOffsetMappingRec ( DdNodePtr  partitionNode ,  DdNodePtr  representativesNode ,  DdNodePtr  variables ,  storm : : dd : : Odd  const &  odd ,  uint64_t  offset )  {  
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_ASSERT ( partitionNode  ! =  Cudd_ReadZero ( ddman )  | |  representativesNode  = =  Cudd_ReadLogicZero ( ddman ) ,  " Expected representative to be zero if the partition is zero. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    STORM_LOG_ASSERT ( partitionNode  ! =  Cudd_ReadLogic Zero ( ddman )  | |  representativesNode  = =  Cudd_ReadLogicZero ( ddman ) ,  " Expected representative to be zero if the partition is zero. " ) ;  
			
		 
		
	
		
			
				 
				 
				                    if  ( representativesNode  = =  Cudd_ReadLogicZero ( ddman ) )  {  
				 
				 
				                    if  ( representativesNode  = =  Cudd_ReadLogicZero ( ddman ) )  {  
			
		 
		
	
		
			
				 
				 
				                        return ;  
				 
				 
				                        return ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -389,9 +389,14 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        STORM_LOG_ASSERT ( ! odd . isTerminalNode ( ) ,  " Expected non-terminal node. " ) ;  
				 
				 
				                        STORM_LOG_ASSERT ( ! odd . isTerminalNode ( ) ,  " Expected non-terminal node. " ) ;  
			
		 
		
	
		
			
				 
				 
				                        DdNodePtr  partitionT ;  
				 
				 
				                        DdNodePtr  partitionT ;  
			
		 
		
	
		
			
				 
				 
				                        DdNodePtr  partitionE ;  
				 
				 
				                        DdNodePtr  partitionE ;  
			
		 
		
	
		
			
				 
				 
				                        if  ( Cudd_NodeReadIndex ( partitionNode )  = =  Cudd_NodeReadIndex ( variables )  +  1  )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( Cudd_NodeReadIndex ( partitionNode )  = =  Cudd_NodeReadIndex ( variables ) )  {  
			
		 
		
	
		
			
				 
				 
				                            partitionT  =  Cudd_T ( partitionNode ) ;  
				 
				 
				                            partitionT  =  Cudd_T ( partitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				                            partitionE  =  Cudd_E ( partitionNode ) ;  
				 
				 
				                            partitionE  =  Cudd_E ( partitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( Cudd_IsComplement ( partitionNode ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                partitionE  =  Cudd_Not ( partitionE ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                partitionT  =  Cudd_Not ( partitionT ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				                        }  else  {  
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				                            partitionT  =  partitionE  =  partitionNode ;  
				 
				 
				                            partitionT  =  partitionE  =  partitionNode ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -401,15 +406,15 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        if  ( Cudd_NodeReadIndex ( representativesNode )  = =  Cudd_NodeReadIndex ( variables ) )  {  
				 
				 
				                        if  ( Cudd_NodeReadIndex ( representativesNode )  = =  Cudd_NodeReadIndex ( variables ) )  {  
			
		 
		
	
		
			
				 
				 
				                            representativesT  =  Cudd_T ( representativesNode ) ;  
				 
				 
				                            representativesT  =  Cudd_T ( representativesNode ) ;  
			
		 
		
	
		
			
				 
				 
				                            representativesE  =  Cudd_E ( representativesNode ) ;  
				 
				 
				                            representativesE  =  Cudd_E ( representativesNode ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( Cudd_IsComplement ( representativesNode ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                representativesE  =  Cudd_Not ( representativesE ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                representativesT  =  Cudd_Not ( representativesT ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				                        }  else  {  
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				                            representativesT  =  representativesE  =  representativesNode ;  
				 
				 
				                            representativesT  =  representativesE  =  representativesNode ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                         
				 
				 
				                         
			
		 
		
	
		
			
				 
				 
				                        if  ( representativesT  ! =  representativesE  & &  Cudd_IsComplement ( representativesNode ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            representativesE  =  Cudd_Not ( representativesE ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            representativesT  =  Cudd_Not ( representativesT ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                         
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        createBlockToOffsetMappingRec ( partitionE ,  representativesE ,  Cudd_T ( variables ) ,  odd . getElseSuccessor ( ) ,  offset ) ;  
				 
				 
				                        createBlockToOffsetMappingRec ( partitionE ,  representativesE ,  Cudd_T ( variables ) ,  odd . getElseSuccessor ( ) ,  offset ) ;  
			
		 
		
	
		
			
				 
				 
				                        createBlockToOffsetMappingRec ( partitionT ,  representativesT ,  Cudd_T ( variables ) ,  odd . getThenSuccessor ( ) ,  offset  +  odd . getElseOffset ( ) ) ;  
				 
				 
				                        createBlockToOffsetMappingRec ( partitionT ,  representativesT ,  Cudd_T ( variables ) ,  odd . getThenSuccessor ( ) ,  offset  +  odd . getElseOffset ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -487,10 +492,15 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                             
				 
				 
				                             
			
		 
		
	
		
			
				 
				 
				                            DdNodePtr  targetT ;  
				 
				 
				                            DdNodePtr  targetT ;  
			
		 
		
	
		
			
				 
				 
				                            DdNodePtr  targetE ;  
				 
				 
				                            DdNodePtr  targetE ;  
			
		 
		
	
		
			
				 
				 
				                            if  ( Cudd_NodeReadIndex ( targetPartitionNode )  = =  Cudd_NodeReadIndex ( variables )  +  1  )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( Cudd_NodeReadIndex ( targetPartitionNode )  = =  Cudd_NodeReadIndex ( variables ) )  {  
			
		 
		
	
		
			
				 
				 
				                                // Node was not skipped in target partition.
  
				 
				 
				                                // Node was not skipped in target partition.
  
			
		 
		
	
		
			
				 
				 
				                                targetT  =  Cudd_T ( targetPartitionNode ) ;  
				 
				 
				                                targetT  =  Cudd_T ( targetPartitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				                                targetE  =  Cudd_E ( targetPartitionNode ) ;  
				 
				 
				                                targetE  =  Cudd_E ( targetPartitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                if  ( Cudd_IsComplement ( targetPartitionNode ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    targetT  =  Cudd_Not ( targetT ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    targetE  =  Cudd_Not ( targetE ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                }  
			
		 
		
	
		
			
				 
				 
				                            }  else  {  
				 
				 
				                            }  else  {  
			
		 
		
	
		
			
				 
				 
				                                // Node was skipped in target partition.
  
				 
				 
				                                // Node was skipped in target partition.
  
			
		 
		
	
		
			
				 
				 
				                                targetT  =  targetE  =  targetPartitionNode ;  
				 
				 
				                                targetT  =  targetE  =  targetPartitionNode ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -529,23 +539,21 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            class  InternalSparseQuotientExtractor < storm : : dd : : DdType : : Sylvan ,  ValueType >  :  public  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : Sylvan ,  ValueType >  {  
				 
				 
				            class  InternalSparseQuotientExtractor < storm : : dd : : DdType : : Sylvan ,  ValueType >  :  public  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : Sylvan ,  ValueType >  {  
			
		 
		
	
		
			
				 
				 
				            public :  
				 
				 
				            public :  
			
		 
		
	
		
			
				 
				 
				                InternalSparseQuotientExtractor ( storm : : models : : symbolic : : Model < storm : : dd : : DdType : : Sylvan ,  ValueType >  const &  model ,  Partition < storm : : dd : : DdType : : Sylvan ,  ValueType >  const &  partition ,  storm : : dd : : Bdd < storm : : dd : : DdType : : Sylvan >  const &  representatives )  :  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : Sylvan ,  ValueType > ( model ,  partition ,  representatives )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_ASSERT ( partition . storedAsBdd ( ) ,  " Expected partition stored as BDD. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                InternalSparseQuotientExtractor ( storm : : models : : symbolic : : Model < storm : : dd : : DdType : : Sylvan ,  ValueType >  const &  model ,  storm : : dd : : Bdd < storm : : dd : : DdType : : Sylvan >  const &  partitionBdd ,  storm : : dd : : Bdd < storm : : dd : : DdType : : Sylvan >  const &  representatives ,  uint64_t  numberOfBlocks )  :  InternalSparseQuotientExtractorBase < storm : : dd : : DdType : : Sylvan ,  ValueType > ( model ,  partitionBdd ,  representatives ,  numberOfBlocks )  {  
			
		 
		
	
		
			
				 
				 
				                    this - > createBlockToOffsetMapping ( ) ;  
				 
				 
				                    this - > createBlockToOffsetMapping ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  extractTransitionMatrix ( storm : : dd : : Add < storm : : dd : : DdType : : Sylvan ,  ValueType >  const &  transitionMatrix )  {  
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  extractTransitionMatrix ( storm : : dd : : Add < storm : : dd : : DdType : : Sylvan ,  ValueType >  const &  transitionMatrix )  {  
			
		 
		
	
		
			
				 
				 
				                    // Create the number of rows necessary for the matrix.
  
				 
				 
				                    // Create the number of rows necessary for the matrix.
  
			
		 
		
	
		
			
				 
				 
				                    this - > createMatrixEntryStorage ( ) ;  
				 
				 
				                    this - > createMatrixEntryStorage ( ) ;  
			
		 
		
	
		
			
				 
				 
				                    extractTransitionMatrixRec ( transitionMatrix . getInternalAdd ( ) . getSylvanMtbdd ( ) . GetMTBDD ( ) ,  this - > isNondeterministic  ?  this - > nondeterminismOdd  :  this - > odd ,  0 ,  this - > partition . as Bdd( ) . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > representatives . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > allSourceVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > nondeterminismVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > isNondeterministic  ?  & this - > odd  :  nullptr ,  0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    extractTransitionMatrixRec ( transitionMatrix . getInternalAdd ( ) . getSylvanMtbdd ( ) . GetMTBDD ( ) ,  this - > isNondeterministic  ?  this - > nondeterminismOdd  :  this - > odd ,  0 ,  this - > partitionBdd . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > representatives . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > allSourceVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > nondeterminismVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > isNondeterministic  ?  & this - > odd  :  nullptr ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				                    return  this - > createMatrixFromEntries ( ) ;  
				 
				 
				                    return  this - > createMatrixFromEntries ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				            private :  
				 
				 
				            private :  
			
		 
		
	
		
			
				 
				 
				                void  createBlockToOffsetMapping ( )  {  
				 
				 
				                void  createBlockToOffsetMapping ( )  {  
			
		 
		
	
		
			
				 
				 
				                    this - > createBlockToOffsetMappingRec ( this - > partition . as Bdd( ) . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > representatives . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > rowVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > odd ,  0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    STORM_LOG_ASSERT ( blockToOffset . size ( )  = =  this - > partitio n. getN umberOfBlocks( ) ,  " Mismatching block-to-offset mapping:  "  < <  blockToOffset . size ( )  < <  "  vs.  "  < <  this - > partitio n. getN umberOfBlocks( )   < <  " . " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    this - > createBlockToOffsetMappingRec ( this - > partitionBdd . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > representatives . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > rowVariablesCube . getInternalBdd ( ) . getSylvanBdd ( ) . GetBDD ( ) ,  this - > odd ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    STORM_LOG_ASSERT ( blockToOffset . size ( )  = =  this - > numberOfBlocks ,  " Mismatching block-to-offset mapping:  "  < <  blockToOffset . size ( )  < <  "  vs.  "  < <  this - > numberOfBlocks  < <  " . " ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                void  createBlockToOffsetMappingRec ( BDD  partitionNode ,  BDD  representativesNode ,  BDD  variables ,  storm : : dd : : Odd  const &  odd ,  uint64_t  offset )  {  
				 
				 
				                void  createBlockToOffsetMappingRec ( BDD  partitionNode ,  BDD  representativesNode ,  BDD  variables ,  storm : : dd : : Odd  const &  odd ,  uint64_t  offset )  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -562,7 +570,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        STORM_LOG_ASSERT ( ! odd . isTerminalNode ( ) ,  " Expected non-terminal node. " ) ;  
				 
				 
				                        STORM_LOG_ASSERT ( ! odd . isTerminalNode ( ) ,  " Expected non-terminal node. " ) ;  
			
		 
		
	
		
			
				 
				 
				                        BDD  partitionT ;  
				 
				 
				                        BDD  partitionT ;  
			
		 
		
	
		
			
				 
				 
				                        BDD  partitionE ;  
				 
				 
				                        BDD  partitionE ;  
			
		 
		
	
		
			
				 
				 
				                        if  ( sylvan_var ( partitionNode )  = =  sylvan_var ( variables )  +  1  )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( sylvan_var ( partitionNode )  = =  sylvan_var ( variables ) )  {  
			
		 
		
	
		
			
				 
				 
				                            partitionT  =  sylvan_high ( partitionNode ) ;  
				 
				 
				                            partitionT  =  sylvan_high ( partitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				                            partitionE  =  sylvan_low ( partitionNode ) ;  
				 
				 
				                            partitionE  =  sylvan_low ( partitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  else  {  
				 
				 
				                        }  else  {  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -655,7 +663,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                             
				 
				 
				                             
			
		 
		
	
		
			
				 
				 
				                            BDD  targetT ;  
				 
				 
				                            BDD  targetT ;  
			
		 
		
	
		
			
				 
				 
				                            BDD  targetE ;  
				 
				 
				                            BDD  targetE ;  
			
		 
		
	
		
			
				 
				 
				                            if  ( sylvan_var ( targetPartitionNode )  = =  sylvan_var ( variables )  +  1  )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( sylvan_var ( targetPartitionNode )  = =  sylvan_var ( variables ) )  {  
			
		 
		
	
		
			
				 
				 
				                                // Node was not skipped in target partition.
  
				 
				 
				                                // Node was not skipped in target partition.
  
			
		 
		
	
		
			
				 
				 
				                                targetT  =  sylvan_high ( targetPartitionNode ) ;  
				 
				 
				                                targetT  =  sylvan_high ( targetPartitionNode ) ;  
			
		 
		
	
		
			
				 
				 
				                                targetE  =  sylvan_low ( targetPartitionNode ) ;  
				 
				 
				                                targetE  =  sylvan_low ( targetPartitionNode ) ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -720,10 +728,9 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                auto  start  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
				 
				 
				                auto  start  =  std : : chrono : : high_resolution_clock : : now ( ) ;  
			
		 
		
	
		
			
				 
				 
				                auto  representatives  =  InternalRepresentativeComputer < DdType > ( partitionAsBdd ,  model . getRowVariables ( ) ) . getRepresentatives ( ) ;  
				 
				 
				                auto  representatives  =  InternalRepresentativeComputer < DdType > ( partitionAsBdd ,  model . getRowVariables ( ) ) . getRepresentatives ( ) ;  
			
		 
		
	
		
			
				 
				 
				                representatives . template  toAdd < ValueType > ( ) . exportToDot ( " repr.dot " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                STORM_LOG_ASSERT ( representatives . getNonZeroCount ( )  = =  partition . getNumberOfBlocks ( ) ,  " Representatives size does not match that of the partition:  "  < <  representatives . getNonZeroCount ( )  < <  "  vs.  "  < <  partition . getNumberOfBlocks ( )  < <  " . " ) ;  
				 
				 
				                STORM_LOG_ASSERT ( representatives . getNonZeroCount ( )  = =  partition . getNumberOfBlocks ( ) ,  " Representatives size does not match that of the partition:  "  < <  representatives . getNonZeroCount ( )  < <  "  vs.  "  < <  partition . getNumberOfBlocks ( )  < <  " . " ) ;  
			
		 
		
	
		
			
				 
				 
				                STORM_LOG_ASSERT ( ( representatives  & &  partitionAsBdd ) . existsAbstract ( model . getRowVariables ( ) )  = =  partitionAsBdd . existsAbstract ( model . getRowVariables ( ) ) ,  " Representatives do not cover all blocks. " ) ;  
				 
				 
				                STORM_LOG_ASSERT ( ( representatives  & &  partitionAsBdd ) . existsAbstract ( model . getRowVariables ( ) )  = =  partitionAsBdd . existsAbstract ( model . getRowVariables ( ) ) ,  " Representatives do not cover all blocks. " ) ;  
			
		 
		
	
		
			
				 
				 
				                InternalSparseQuotientExtractor < DdType ,  ValueType >  sparseExtractor ( model ,  partition ,  representatives ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                InternalSparseQuotientExtractor < DdType ,  ValueType >  sparseExtractor ( model ,  partitionAsBdd  ,  representatives ,  partition . getNumberOfBlocks ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                storm : : dd : : Odd  const &  odd  =  sparseExtractor . getOdd ( ) ;  
				 
				 
				                storm : : dd : : Odd  const &  odd  =  sparseExtractor . getOdd ( ) ;  
			
		 
		
	
		
			
				 
				 
				                STORM_LOG_ASSERT ( odd . getTotalOffset ( )  = =  representatives . getNonZeroCount ( ) ,  " Mismatching ODD. " ) ;  
				 
				 
				                STORM_LOG_ASSERT ( odd . getTotalOffset ( )  = =  representatives . getNonZeroCount ( ) ,  " Mismatching ODD. " ) ;  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  quotientTransitionMatrix  =  sparseExtractor . extractTransitionMatrix ( model . getTransitionMatrix ( ) ) ;  
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  quotientTransitionMatrix  =  sparseExtractor . extractTransitionMatrix ( model . getTransitionMatrix ( ) ) ;