@ -334,50 +334,75 @@ namespace storm { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								// Start by decomposing the MDP into its MECs.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : MaximalEndComponentDecomposition < double >  mecDecomposition ( this - > getModelAs < storm : : models : : AbstractNondeterministicModel < ValueType > >  ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : MaximalEndComponentDecomposition < double >  mecDecomposition ( this - > getModel ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								// Get some data members for convenience.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								typename  storm : : storage : : SparseMatrix < ValueType >  const &  transitionMatrix  =  this - > getModel ( ) . getTransitionMatrix ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								ValueType  one  =  storm : : utility : : one < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								ValueType  zero  =  storm : : utility : : zero < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								// First we check which states are in MECs. We use this later to speed up reachability analysis
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : BitVector  statesNotInMecs ( numOfStates ,  true ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//first calculate LRA for the Maximal End Components.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : BitVector  statesInMecs ( numOfStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : vector < uint_fast64_t >  stateToMecIndexMap ( transitionMatrix . getColumnCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : vector < ValueType >  mecLra ( mecDecomposition . size ( ) ,  zero ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								for  ( uint_fast64_t  currentMecIndex  =  0 ;  currentMecIndex  <  mecDecomposition . size ( ) ;  + + currentMecIndex )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									storm : : storage : : MaximalEndComponent  const &  mec  =  mecDecomposition [ currentMecIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									mecLra [ currentMecIndex ]  =  computeLraForMaximalEndComponent ( minimize ,  transitionMatrix ,  psiStates ,  mec ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									// Gather information for later use.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									for  ( auto  const &  stateChoicesPair  :  mec )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										statesInMecs . set ( stateChoicesPair . first ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										statesInMecs . set ( stateChoicesPair . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										stateToMecIndexMap [ stateChoicesPair . first ]  =  currentMecIndex ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								// Prepare result vector.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : vector < ValueType >  result ( numOfStates ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//FIXME: This doesn't work for MDP. Simple counterexample, an MPD with precisely two MECs, both with LRA of 1. Max Reach Prob for both is 1 from the initial state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//       Then this approach would yield an LRA value of 2 for the initial state, which is incorrect.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								////now we calculate the long run average for each MEC in isolation and compute the weighted contribution of the MEC to the LRA value of all states
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//for (uint_fast64_t currentMecIndex = 0; currentMecIndex < mecDecomposition.size(); ++currentMecIndex) {
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	storm::storage::MaximalEndComponent const& mec = mecDecomposition[currentMecIndex];
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	storm::storage::BitVector statesInThisMec(numOfStates);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	for (auto const& state : bscc) {
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//		statesInThisMec.set(state);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	}
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	// Compute the LRA value for the current MEC.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	lraValuesForEndComponents.push_back(this->computeLraForMaximalEndComponent(minimize, transitionMatrix, psiStates, mec));
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//calculate LRA for states not in MECs as expected reachability rewards
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//we add an auxiliary target state, every state in any MEC has a choice to move to that state with prob 1.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//This transitions have the LRA of the MEC as reward.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//The expected reward corresponds to sum of LRAs in MEC weighted by the reachability probability of the MEC
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : unique_ptr < storm : : solver : : LinearEquationSolver < ValueType > >  solver  =  storm : : utility : : solver : : getLinearEquationSolver < ValueType > ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//we now build the submatrix of the transition matrix of the system with the auxiliary state, that only contains the states from
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//the original state, i.e. all "maybe-states"
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : SparseMatrixBuilder < ValueType >  rewardEquationSystemMatrixBuilder ( transitionMatrix . getRowCount ( )  +  statesInMecs . getNumberOfSetBits ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									transitionMatrix . getColumnCount ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									transitionMatrix . getEntryCount ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									true ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									true ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									transitionMatrix . getRowGroupCount ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : vector < ValueType >  rewardRightSide ( transitionMatrix . getRowCount ( )  +  statesInMecs . getNumberOfSetBits ( ) ,  zero ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								uint_fast64_t  rowIndex  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								uint_fast64_t  oldRowIndex  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								for  ( uint_fast64_t  rowGroupIndex  =  0 ;  rowGroupIndex  <  transitionMatrix . getRowGroupCount ( ) ;  + + rowGroupIndex )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									rewardEquationSystemMatrixBuilder . newRowGroup ( rowIndex ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									for  ( uint_fast64_t  i  =  0 ;  i  <  transitionMatrix . getRowGroupSize ( rowGroupIndex ) ;  + + i )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										for  ( auto  entry  :  transitionMatrix . getRow ( oldRowIndex ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
											//copy over values from transition matrix of the actual system
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
											rewardEquationSystemMatrixBuilder . addNextValue ( rowIndex ,  entry . getColumn ( ) ,  entry . getValue ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										+ + oldRowIndex ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										+ + rowIndex ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									+ + rowGroupIndex ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									if  ( statesInMecs . get ( rowGroupIndex ) )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										//add the choice where we go to the auxiliary state, which is a row with all zeros in the submatrix we build
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										+ + rowIndex ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										//put the transition-reward on the right side
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										rewardRightSide [ rowIndex ]  =  mecLra [ rowGroupIndex ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	//the LRA value of a MEC contributes to the LRA value of a state with the probability of reaching that MEC from that state
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	//thus we add Min/MaxProb(Eventually statesInThisBscc) * lraForThisBscc to the result vector
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								storm : : storage : : SparseMatrix < ValueType >  rewardEquationSystemMatrix  =  rewardEquationSystemMatrixBuilder . build ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								rewardEquationSystemMatrix . convertToEquationSystem ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	//the reachability probabilities will be zero in other MECs, thus we can set the left operand of the until formula to statesNotInMecs as an optimization
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	std::vector<ValueType> reachProbThisBscc = this->computeUntilProbabilitiesHelper(minimize, statesNotInMecs, statesInThisMec, false);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								std : : vector < ValueType >  result ( rewardEquationSystemMatrix . getColumnCount ( ) ,  one ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	storm::utility::vector::scaleVectorInPlace<ValueType>(reachProbThisBscc, lraForThisBscc);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//	storm::utility::vector::addVectorsInPlace<ValueType>(result, reachProbThisBscc);
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								//}
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								solver - > solveEquationSystem ( rewardEquationSystemMatrix ,  result ,  rewardRightSide ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return  result ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}