@ -4,6 +4,8 @@ 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				# include  "src/storage/StronglyConnectedComponentDecomposition.h" 
  
				 
				 
				# include  "src/storage/StronglyConnectedComponentDecomposition.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "src/utility/graph.h" 
  
				 
				 
				# include  "src/utility/graph.h" 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "src/utility/vector.h" 
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				# include  "src/exceptions/InvalidStateException.h" 
  
			
		 
		
	
		
			
				 
				 
				# include  "src/exceptions/ExceptionMacros.h" 
  
				 
				 
				# include  "src/exceptions/ExceptionMacros.h" 
  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				namespace  storm  {  
				 
				 
				namespace  storm  {  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -30,41 +32,35 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                // Determine the set of states that is reachable from the initial state without jumping over a target state.
  
				 
				 
				                // Determine the set of states that is reachable from the initial state without jumping over a target state.
  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : BitVector  reachableStates  =  storm : : utility : : graph : : getReachableStates ( dtmc . getTransitionMatrix ( ) ,  dtmc . getInitialStates ( ) ,  maybeStates ,  statesWithProbability1 ) ;  
				 
				 
				                storm : : storage : : BitVector  reachableStates  =  storm : : utility : : graph : : getReachableStates ( dtmc . getTransitionMatrix ( ) ,  dtmc . getInitialStates ( ) ,  maybeStates ,  statesWithProbability1 ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Subtract from the maybe states the set of states that is not reachable.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                // Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state) .
  
			
		 
		
	
		
			
				 
				 
				                maybeStates  & =  reachableStates ;  
				 
				 
				                maybeStates  & =  reachableStates ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Otherwise, we build the submatrix that only has the transitions of the maybe states.
  
				 
				 
				                // Otherwise, we build the submatrix that only has the transitions of the maybe states.
  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  submatrix  =  dtmc . getTransitionMatrix ( ) . getSubmatrix ( false ,  maybeStates ,  maybeStates ) ;  
				 
				 
				                storm : : storage : : SparseMatrix < ValueType >  submatrix  =  dtmc . getTransitionMatrix ( ) . getSubmatrix ( false ,  maybeStates ,  maybeStates ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Then, we convert the reduced matrix to a more flexible format to be able to perform state elimination more easily.
  
				 
				 
				                // Then, we convert the reduced matrix to a more flexible format to be able to perform state elimination more easily.
  
			
		 
		
	
		
			
				 
				 
				                FlexibleSparseMatrix < ValueType >  flexibleMatrix  =  getFlexibleSparseMatrix ( dtmc . getTransitionMatrix ( ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                FlexibleSparseMatrix < ValueType >  flexibleMatrix  =  getFlexibleSparseMatrix ( submatrix ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Create a vector for the probabilities to go to a state with probability 1 in one step.
  
				 
				 
				                // Create a vector for the probabilities to go to a state with probability 1 in one step.
  
			
		 
		
	
		
			
				 
				 
				                std : : vector < ValueType >  oneStepProbabilities  =  dtmc . getTransitionMatrix ( ) . getConstrainedRowSumVector ( maybeStates ,  statesWithProbability1 ) ;  
				 
				 
				                std : : vector < ValueType >  oneStepProbabilities  =  dtmc . getTransitionMatrix ( ) . getConstrainedRowSumVector ( maybeStates ,  statesWithProbability1 ) ;  
			
		 
		
	
		
			
				 
				 
				                for  ( uint_fast64_t  i  =  0 ;  i  <  oneStepProbabilities . size ( ) ;  + + i )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  i  < <  "  ->  "  < <  oneStepProbabilities [ i ]  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Then, we recursively treat all SCCs.
  
				 
				 
				                // Then, we recursively treat all SCCs.
  
			
		 
		
	
		
			
				 
				 
				                treatScc ( dtmc ,  flexibleMatrix ,  oneStepProbabilities ,  dtmc . getInitialStates ( )  %  maybeStates ,  storm : : storage : : BitVector ( maybeStates . getNumberOfSetBits ( ) ,  true ) ,  submatrix ,  submatrix . transpose ( ) ,  false ,  0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                FlexibleSparseMatrix < ValueType >  backwardTransitions  =  getFlexibleSparseMatrix ( submatrix . transpose ( ) ,  true ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                treatScc ( dtmc ,  flexibleMatrix ,  oneStepProbabilities ,  dtmc . getInitialStates ( )  %  maybeStates ,  storm : : storage : : BitVector ( maybeStates . getNumberOfSetBits ( ) ,  true ) ,  submatrix ,  backwardTransitions ,  false ,  0 ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Now, we return the value for the only initial state.
  
				 
				 
				                // Now, we return the value for the only initial state.
  
			
		 
		
	
		
			
				 
				 
				                return  oneStepProbabilities [ initialStateIndex ] ;  
				 
				 
				                return  oneStepProbabilities [ initialStateIndex ] ;  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            void  SparseSccModelChecker < ValueType > : : treatScc ( storm : : models : : Dtmc < ValueType >  const &  dtmc ,  FlexibleSparseMatrix < ValueType > &  matrix ,  std : : vector < ValueType > &  oneStepProbabilities ,  storm : : storage : : BitVector  const &  entryStates ,  storm : : storage : : BitVector  const &  scc ,  storm : : storage : : SparseMatrix < ValueType >  const &  forwardTransitions ,  storm : : storage : : SparseMatrix < ValueType >  const &  backwardTransitions ,  bool  eliminateEntryStates ,  uint_fast64_t  level )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                std : : cout  < <  " treating SCC  "  < <  scc  < <  "  at level  "  < <  level  < <   "  (entry:  "  < <  entryStates  < <  " ) "  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                if  ( level  < =  2 )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " 1 "  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            void  SparseSccModelChecker < ValueType > : : treatScc ( storm : : models : : Dtmc < ValueType >  const &  dtmc ,  FlexibleSparseMatrix < ValueType > &  matrix ,  std : : vector < ValueType > &  oneStepProbabilities ,  storm : : storage : : BitVector  const &  entryStates ,  storm : : storage : : BitVector  const &  scc ,  storm : : storage : : SparseMatrix < ValueType >  const &  forwardTransitions ,  FlexibleSparseMatrix < ValueType > &  backwardTransitions ,  bool  eliminateEntryStates ,  uint_fast64_t  level )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( level  < =  3 )  {  
			
		 
		
	
		
			
				 
				 
				                    // Here, we further decompose the SCC into sub-SCCs.
  
				 
				 
				                    // Here, we further decompose the SCC into sub-SCCs.
  
			
		 
		
	
		
			
				 
				 
				                    storm : : storage : : StronglyConnectedComponentDecomposition < ValueType >  decomposition ( forwardTransitions ,  scc  &  ~ entryStates ,  true ,  false ) ;  
				 
				 
				                    storm : : storage : : StronglyConnectedComponentDecomposition < ValueType >  decomposition ( forwardTransitions ,  scc  &  ~ entryStates ,  true ,  false ) ;  
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  decomposition  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                    // To eliminate the remaining one-state SCCs, we need to keep track of them.
  
				 
				 
				                    // To eliminate the remaining one-state SCCs, we need to keep track of them.
  
			
		 
		
	
		
			
				 
				 
				                    storm : : storage : : BitVector  remainingStates ( scc ) ;  
				 
				 
				                    storm : : storage : : BitVector  remainingStates ( scc ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " 1 "  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    // And then recursively treat all sub-SCCs.
  
				 
				 
				                    // And then recursively treat all sub-SCCs.
  
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  const &  newScc  :  decomposition )  {  
				 
				 
				                    for  ( auto  const &  newScc  :  decomposition )  {  
			
		 
		
	
		
			
				 
				 
				                        // If the SCC consists of just one state, we do not explore it recursively, but rather eliminate
  
				 
				 
				                        // If the SCC consists of just one state, we do not explore it recursively, but rather eliminate
  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -91,8 +87,6 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                        treatScc ( dtmc ,  matrix ,  oneStepProbabilities ,  entryStates ,  newSccAsBitVector ,  forwardTransitions ,  backwardTransitions ,  true ,  level  +  1 ) ;  
				 
				 
				                        treatScc ( dtmc ,  matrix ,  oneStepProbabilities ,  entryStates ,  newSccAsBitVector ,  forwardTransitions ,  backwardTransitions ,  true ,  level  +  1 ) ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " 1 "  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    // If we are not supposed to eliminate the entry states, we need to take them out of the set of
  
				 
				 
				                    // If we are not supposed to eliminate the entry states, we need to take them out of the set of
  
			
		 
		
	
		
			
				 
				 
				                    // remaining states.
  
				 
				 
				                    // remaining states.
  
			
		 
		
	
		
			
				 
				 
				                    if  ( ! eliminateEntryStates )  {  
				 
				 
				                    if  ( ! eliminateEntryStates )  {  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -122,13 +116,16 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            void  SparseSccModelChecker < ValueType > : : eliminateState ( FlexibleSparseMatrix < ValueType > &  matrix ,  std : : vector < ValueType > &  oneStepProbabilities ,  uint_fast64_t  state ,  storm : : storage : : SparseMatrix < ValueType >  const  &  backwardTransitions )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            void  SparseSccModelChecker < ValueType > : : eliminateState ( FlexibleSparseMatrix < ValueType > &  matrix ,  std : : vector < ValueType > &  oneStepProbabilities ,  uint_fast64_t  state ,  Flexible SparseMatrix< ValueType > &  backwardTransitions )  {  
			
		 
		
	
		
			
				 
				 
				                ValueType  loopProbability  =  storm : : utility : : constantZero < ValueType > ( ) ;  
				 
				 
				                ValueType  loopProbability  =  storm : : utility : : constantZero < ValueType > ( ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Start by finding loop probability.
  
				 
				 
				                // Start by finding loop probability.
  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  entry  :  matrix . getRow ( state ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                typename  FlexibleSparseMatrix < ValueType > : : row_type &  currentStateSuccessors  =  matrix . getRow ( state ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                for  ( auto  const &  entry  :  currentStateSuccessors )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( entry . getColumn ( )  > =  state )  {  
			
		 
		
	
		
			
				 
				 
				                        if  ( entry . getColumn ( )  = =  state )  {  
				 
				 
				                        if  ( entry . getColumn ( )  = =  state )  {  
			
		 
		
	
		
			
				 
				 
				                            loopProbability  =  entry . getValue ( ) ;  
				 
				 
				                            loopProbability  =  entry . getValue ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                        break ;  
				 
				 
				                        break ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -140,49 +137,128 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                oneStepProbabilities [ state ]  * =  loopProbability ;  
				 
				 
				                oneStepProbabilities [ state ]  * =  loopProbability ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                // Now connect the predecessors of the state to eliminate with its successors.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                std : : size_t  newEntries  =  matrix . getRow ( state ) . size ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  predecessorEntry  :  backwardTransitions . getRow ( state ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    // First, add all entries of the successor to the list of outgoing transitions of the predecessor.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type  row  =  matrix . getRow ( predecessorEntry . getColumn ( ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  multiplyElement  =  std : : find_if ( row . begin ( ) ,  row . end ( ) ,  [ = ] ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  = =  state ;  } ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                // Now connect the predecessors of the state being eliminated with its successors.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                typename  FlexibleSparseMatrix < ValueType > : : row_type &  currentStatePredecessors  =  backwardTransitions . getRow ( state ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                for  ( auto  const &  predecessorEntry  :  currentStatePredecessors )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    uint_fast64_t  predecessor  =  predecessorEntry . getColumn ( ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    ValueType  multiplyFactor  =  storm : : utility : : constantOne < ValueType > ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    if  ( multiplyElement  ! =  row . end ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        // Remove the transition to the state that is to be eliminated.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        multiplyElement - > setValue ( 0 ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        multiplyFactor  =  multiplyElement - > getValue ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Skip the state itself as one of its predecessors.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( predecessor  = =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        continue ;  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    // Now scale all the entries in the current row and insert them in the transitions of the predecessor.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    row . reserve ( row . size ( )  +  newEntries ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : for_each ( matrix . getRow ( state ) . begin ( ) ,  matrix . getRow ( state ) . end ( ) ,  [ & ]  ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  row . emplace_back ( a . getColumn ( ) ,  multiplyFactor  *  a . getValue ( ) ) ;  } ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // First, find the probability with which the predecessor can move to the current state, because
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // the other probabilities need to be scaled with this factor.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type &  predecessorForwardTransitions  =  matrix . getRow ( predecessor ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  multiplyElement  =  std : : find_if ( predecessorForwardTransitions . begin ( ) ,  predecessorForwardTransitions . end ( ) ,  [ & ] ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  = =  state ;  } ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    // Then sort the vector according to their column indices.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : sort ( row . begin ( ) ,  row . end ( ) ,  [ ] ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a ,  storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  b ) {  return  a . getColumn ( )  <  b . getColumn ( ) ;  } ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Make sure we have found the probability and set it to zero.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    LOG_THROW ( multiplyElement  ! =  predecessorForwardTransitions . end ( ) ,  storm : : exceptions : : InvalidStateException ,  " No probability for successor found. " ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    ValueType  multiplyFactor  =  multiplyElement - > getValue ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    multiplyElement - > setValue ( 0 ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    // Now we can eliminate entries with the same column by simple addition.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  rowIt  =  row . begin ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  it  =  row . begin ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  rowIte  =  row . end ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    for  ( + + it ;  it  ! =  rowIte ;  + + it )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        if  ( it - > getValue ( )  = =  storm : : utility : : constantZero < ValueType > ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // At this point, we need to update the (forward) transitions of the predecessor.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  first1  =  predecessorForwardTransitions . begin ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  last1  =  predecessorForwardTransitions . end ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  first2  =  currentStateSuccessors . begin ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  last2  =  currentStateSuccessors . end ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type  newSuccessors ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    newSuccessors . reserve ( ( last1  -  first1 )  +  ( last2  -  first2 ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    std : : insert_iterator < typename  FlexibleSparseMatrix < ValueType > : : row_type >  result ( newSuccessors ,  newSuccessors . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Now we merge the two successor lists. (Code taken from std::set_union and modified to suit our needs).
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( ;  first1  ! =  last1 ;  + + result )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        // Skip the transitions to the state that is currently being eliminated.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first1 - > getColumn ( )  = =  state  | |  ( first2  ! =  last2  & &  first2 - > getColumn ( )  = =  state ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( first1 - > getColumn ( )  = =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                + + first1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( first2  ! =  last2  & &  first2 - > getColumn ( )  = =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                + + first2 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				                            continue ;  
				 
				 
				                            continue ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                         
				 
				 
				                         
			
		 
		
	
		
			
				 
				 
				                        if  ( it - > getColumn ( )  = =  rowIt - > getColumn ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            rowIt - > setValue ( rowIt - > getValue ( )  +  it - > getValue ( ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first2  = =  last2 )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            std : : copy_if ( first1 ,  last1 ,  result ,  [ & ]  ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  ! =  state ;  }  ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            break ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first2 - > getColumn ( )  <  first1 - > getColumn ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            * result  =  * first2  *  multiplyFactor ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first2 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  else  if  ( first1 - > getColumn ( )  <  first2 - > getColumn ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            * result  =  * first1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            * result  =  storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type > ( first1 - > getColumn ( ) ,  first1 - > getValue ( )  +  multiplyFactor  *  first2 - > getValue ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first2 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( ;  first2  ! =  last2 ;  + + first2 )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first2 - > getColumn ( )  ! =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            * result  =  * first2  *  multiplyFactor ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Now move the new transitions in place.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    predecessorForwardTransitions  =  std : : move ( newSuccessors ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Add the probabilities to go to a target state in just one step.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    oneStepProbabilities [ predecessor ]  + =  multiplyFactor  *  oneStepProbabilities [ state ] ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                // Finally, we need to add the predecessor to the set of predecessors of every successor.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                for  ( auto  const &  successorEntry  :  currentStateSuccessors )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type &  successorBackwardTransitions  =  backwardTransitions . getRow ( successorEntry . getColumn ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Delete the current state as a predecessor of the successor state.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : const_iterator  elimIt  =  std : : find_if ( successorBackwardTransitions . begin ( ) ,  successorBackwardTransitions . end ( ) ,  [ & ] ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  = =  state ;  } ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( elimIt  ! =  successorBackwardTransitions . end ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        successorBackwardTransitions . erase ( elimIt ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  first1  =  successorBackwardTransitions . begin ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  last1  =  successorBackwardTransitions . end ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  first2  =  currentStatePredecessors . begin ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type : : iterator  last2  =  currentStatePredecessors . end ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    typename  FlexibleSparseMatrix < ValueType > : : row_type  newPredecessors ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    newPredecessors . reserve ( ( last1  -  first1 )  +  ( last2  -  first2 ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    std : : insert_iterator < typename  FlexibleSparseMatrix < ValueType > : : row_type >  result ( newPredecessors ,  newPredecessors . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( ;  first1  ! =  last1 ;  + + result )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first2  = =  last2 )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            std : : copy_if ( first1 ,  last1 ,  result ,  [ & ]  ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  ! =  state ;  } ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            break ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( first2 - > getColumn ( )  <  first1 - > getColumn ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( first2 - > getColumn ( )  ! =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                * result  =  * first2 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first2 ;  
			
		 
		
	
		
			
				 
				 
				                        }  else  {  
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				                            + + rowIt ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            * rowIt  =  * it ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( first1 - > getColumn ( )  ! =  state )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                * result  =  * first1 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            if  ( first1 - > getColumn ( )  = =  first2 - > getColumn ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                + + first2 ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            + + first1 ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    std : : copy_if ( first2 ,  last2 ,  result ,  [ & ]  ( storm : : storage : : MatrixEntry < typename  FlexibleSparseMatrix < ValueType > : : index_type ,  typename  FlexibleSparseMatrix < ValueType > : : value_type >  const &  a )  {  return  a . getColumn ( )  ! =  state ;  } ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    // Finally, add the probabilities to go to a target state in just one step.
  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " prior:  "  < <  oneStepProbabilities [ predecessorEntry . getColumn ( ) ]  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    oneStepProbabilities [ predecessorEntry . getColumn ( ) ]  + =  oneStepProbabilities [ state ] ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " updating one step prob of  "  < <  predecessorEntry . getColumn ( )  < <  "  to  "  < <  oneStepProbabilities [ predecessorEntry . getColumn ( ) ]  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    // Now move the new predecessors in place.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    successorBackwardTransitions  =  std : : move ( newPredecessors ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                // Clear the eliminated row to reduce memory consumption.
  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                currentStateSuccessors . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                currentStateSuccessors . shrink_to_fit ( ) ;  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -201,7 +277,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				            template < typename  ValueType >  
				 
				 
				            template < typename  ValueType >  
			
		 
		
	
		
			
				 
				 
				            FlexibleSparseMatrix < ValueType >  SparseSccModelChecker < ValueType > : : getFlexibleSparseMatrix ( storm : : storage : : SparseMatrix < ValueType >  const &  matrix )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            FlexibleSparseMatrix < ValueType >  SparseSccModelChecker < ValueType > : : getFlexibleSparseMatrix ( storm : : storage : : SparseMatrix < ValueType >  const &  matrix ,  bool  setAllValuesToOne )  {  
			
		 
		
	
		
			
				 
				 
				                FlexibleSparseMatrix < ValueType >  flexibleMatrix ( matrix . getRowCount ( ) ) ;  
				 
				 
				                FlexibleSparseMatrix < ValueType >  flexibleMatrix ( matrix . getRowCount ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                for  ( typename  FlexibleSparseMatrix < ValueType > : : index_type  rowIndex  =  0 ;  rowIndex  <  matrix . getRowCount ( ) ;  + + rowIndex )  {  
				 
				 
				                for  ( typename  FlexibleSparseMatrix < ValueType > : : index_type  rowIndex  =  0 ;  rowIndex  <  matrix . getRowCount ( ) ;  + + rowIndex )  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -209,9 +285,13 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                    flexibleMatrix . reserveInRow ( rowIndex ,  row . getNumberOfEntries ( ) ) ;  
				 
				 
				                    flexibleMatrix . reserveInRow ( rowIndex ,  row . getNumberOfEntries ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  const &  element  :  row )  {  
				 
				 
				                    for  ( auto  const &  element  :  row )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( setAllValuesToOne )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            flexibleMatrix . getRow ( rowIndex ) . emplace_back ( element . getColumn ( ) ,  storm : : utility : : constantOne < ValueType > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				                            flexibleMatrix . getRow ( rowIndex ) . emplace_back ( element ) ;  
				 
				 
				                            flexibleMatrix . getRow ( rowIndex ) . emplace_back ( element ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                return  flexibleMatrix ;  
				 
				 
				                return  flexibleMatrix ;  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }