@ -406,25 +406,27 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            // Compute the ingredients of the equation system.
  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  maybeStatesAdd  =  maybeStates . template  toAdd < ValueType > ( ) ;  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  submatrix  =  maybeStatesAdd  *  game . getTransitionMatrix ( ) ;  
			
		
	
		
			
				
								storm : : dd : : Bdd < Type >  allStates  =  game . getReachableStates ( ) ;  
			
		
	
		
			
				
								storm : : dd : : Add < Type ,  ValueType >  allStatesAdd  =  allStates . template  toAdd < ValueType > ( ) ;  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  submatrix  =  allStatesAdd  *  game . getTransitionMatrix ( ) ;  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  prob1StatesAsColumn  =  prob1States . template  toAdd < ValueType > ( ) . swapVariables ( game . getRowColumnMetaVariablePairs ( ) ) ;  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  subvector  =  submatrix  *  prob1StatesAsColumn ;  
			
		
	
		
			
				
					            subvector  =  subvector . sumAbstract ( game . getColumnVariables ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            // Cut away all columns targeting non-maybe states.
  
			
		
	
		
			
				
					            submatrix  * =  maybe StatesAdd. swapVariables ( game . getRowColumnMetaVariablePairs ( ) ) ;  
			
		
	
		
			
				
					            submatrix  * =  all StatesAdd. swapVariables ( game . getRowColumnMetaVariablePairs ( ) ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            // Cut the starting vector to the maybe states of this query.
  
			
		
	
		
			
				
					            storm : : dd : : Add < Type ,  ValueType >  startVector ;  
			
		
	
		
			
				
					            if  ( startInfo )  {  
			
		
	
		
			
				
					                startVector  =  startInfo . get ( ) . values  *  maybe StatesAdd;  
			
		
	
		
			
				
					                startVector  =  startInfo . get ( ) . values  *  all StatesAdd;  
			
		
	
		
			
				
					            }  else  {  
			
		
	
		
			
				
					                startVector  =  game . getManager ( ) . template  getAddZero < ValueType > ( ) ;  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            // Create the solver and solve the equation system.
  
			
		
	
		
			
				
					            storm : : utility : : solver : : SymbolicGameSolverFactory < Type ,  ValueType >  solverFactory ;  
			
		
	
		
			
				
					            std : : unique_ptr < storm : : solver : : SymbolicGameSolver < Type ,  ValueType > >  solver  =  solverFactory . create ( submatrix ,  maybe States,  game . getIllegalPlayer1Mask ( ) ,  game . getIllegalPlayer2Mask ( ) ,  game . getRowVariables ( ) ,  game . getColumnVariables ( ) ,  game . getRowColumnMetaVariablePairs ( ) ,  game . getPlayer1Variables ( ) ,  game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					            std : : unique_ptr < storm : : solver : : SymbolicGameSolver < Type ,  ValueType > >  solver  =  solverFactory . create ( submatrix ,  all States,  game . getIllegalPlayer1Mask ( ) ,  game . getIllegalPlayer2Mask ( ) ,  game . getRowVariables ( ) ,  game . getColumnVariables ( ) ,  game . getRowColumnMetaVariablePairs ( ) ,  game . getPlayer1Variables ( ) ,  game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					            solver - > setGeneratePlayersStrategies ( true ) ;  
			
		
	
		
			
				
					            auto  values  =  solver - > solveGame ( player1Direction ,  player2Direction ,  startVector ,  subvector ,  startInfo  ?  boost : : make_optional ( startInfo . get ( ) . player1Strategy )  :  boost : : none ,  startInfo  ?  boost : : make_optional ( startInfo . get ( ) . player2Strategy )  :  boost : : none ) ;  
			
		
	
		
			
				
					            return  MaybeStateResult < Type ,  ValueType > ( values ,  solver - > getPlayer1Strategy ( ) ,  solver - > getPlayer2Strategy ( ) ) ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -532,7 +534,7 @@ namespace storm { 
			
		
	
		
			
				
					                    MaybeStateResult < Type ,  ValueType >  minMaybeStateResult ( game . getManager ( ) . template  getAddZero < ValueType > ( ) ,  game . getManager ( ) . getBddZero ( ) ,  game . getManager ( ) . getBddZero ( ) ) ;  
			
		
	
		
			
				
					                    if  ( ! maybeMin . isZero ( ) )  {  
			
		
	
		
			
				
					                        minMaybeStateResult  =  solveMaybeStates ( player1Direction ,  storm : : OptimizationDirection : : Minimize ,  game ,  maybeMin ,  prob01 . min . second . getPlayer1States ( ) ) ;  
			
		
	
		
			
				
					                        minResult  + =  minMaybeStateResult . values ;  
			
		
	
		
			
				
					                        minResult  =  minMaybeStateResult . values ;  
			
		
	
		
			
				
					                        storm : : dd : : Add < Type ,  ValueType >  initialStateMin  =  initialStatesAdd  *  minResult ;  
			
		
	
		
			
				
					                        // Here we can only require a non-zero count of *at most* one, because the result may actually be 0.
  
			
		
	
		
			
				
					                        STORM_LOG_ASSERT ( initialStateMin . getNonZeroCount ( )  < =  1 ,  " Wrong number of results for initial states. Expected <= 1, but got  "  < <  initialStateMin . getNonZeroCount ( )  < <  " . " ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -552,7 +554,7 @@ namespace storm { 
			
		
	
		
			
				
					                    MaybeStateResult < Type ,  ValueType >  maxMaybeStateResult ( game . getManager ( ) . template  getAddZero < ValueType > ( ) ,  game . getManager ( ) . getBddZero ( ) ,  game . getManager ( ) . getBddZero ( ) ) ;  
			
		
	
		
			
				
					                    if  ( ! maybeMax . isZero ( ) )  {  
			
		
	
		
			
				
					                        maxMaybeStateResult  =  solveMaybeStates ( player1Direction ,  storm : : OptimizationDirection : : Maximize ,  game ,  maybeMax ,  prob01 . max . second . getPlayer1States ( ) ,  boost : : make_optional ( minMaybeStateResult ) ) ;  
			
		
	
		
			
				
					                        maxResult  + =  maxMaybeStateResult . values ;  
			
		
	
		
			
				
					                        maxResult  =  maxMaybeStateResult . values ;  
			
		
	
		
			
				
					                        storm : : dd : : Add < Type ,  ValueType >  initialStateMax  =  ( initialStatesAdd  *  maxResult ) ;  
			
		
	
		
			
				
					                        // Unlike in the min-case, we can require a non-zero count of 1 here, because if the max was in
  
			
		
	
		
			
				
					                        // fact 0, the result would be 0, which would have been detected earlier by the graph algorithms.
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -577,16 +579,29 @@ namespace storm { 
			
		
	
		
			
				
					                    // If we arrived at this point, it means that we have all qualitative and quantitative information
  
			
		
	
		
			
				
					                    // about the game, but we could not yet answer the query. In this case, we need to refine.
  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    // Start by extending the quantitative strategies by the qualitative ones.
  
			
		
	
		
			
				
					                    minMaybeStateResult . player1Strategy  | =  prob01 . min . first . getPlayer1Strategy ( )  | |  prob01 . min . second . getPlayer1Strategy ( ) ;  
			
		
	
		
			
				
					                    // Redirect all player 1 choices of the min strategy to that of the max strategy if this leads to a player 2 state that has the same prob.
  
			
		
	
		
			
				
										// Get all relevant strategies.
  
			
		
	
		
			
				
										storm : : dd : : Bdd < Type >  minPlayer1Strategy  =  minMaybeStateResult . player1Strategy ;  
			
		
	
		
			
				
										storm : : dd : : Bdd < Type >  minPlayer2Strategy  =  minMaybeStateResult . player2Strategy ;  
			
		
	
		
			
				
										storm : : dd : : Bdd < Type >  maxPlayer1Strategy  =  maxMaybeStateResult . player1Strategy ;  
			
		
	
		
			
				
										storm : : dd : : Bdd < Type >  maxPlayer2Strategy  =  maxMaybeStateResult . player2Strategy ;  
			
		
	
		
			
				
										 
			
		
	
		
			
				
										storm : : dd : : Add < Type ,  ValueType >  matrix  =  game . getTransitionMatrix ( ) ;  
			
		
	
		
			
				
										 
			
		
	
		
			
				
										storm : : dd : : Add < Type ,  ValueType >  minValuesForPlayer1UnderMinP1Strategy  =  matrix  *  minPlayer1Strategy . template  toAdd < ValueType > ( )  *  minPlayer2Strategy . template  toAdd < ValueType > ( ) ;  
			
		
	
		
			
				
										storm : : dd : : Add < Type ,  ValueType >  minValuesForPlayer1UnderMaxP1Strategy  =  matrix  *  maxPlayer1Strategy . template  toAdd < ValueType > ( )  *  minPlayer2Strategy . template  toAdd < ValueType > ( ) ;  
			
		
	
		
			
				
										// This BDD has a 1 for every state (s) that can switch the strategy.
  
			
		
	
		
			
				
										storm : : dd : : Bdd < Type >  minIsGreaterOrEqual  =  minValuesForPlayer1UnderMinP1Strategy . greaterOrEqual ( minValuesForPlayer1UnderMaxP1Strategy ) ;  
			
		
	
		
			
				
										 
			
		
	
		
			
				
										minPlayer1Strategy  =  minIsGreaterOrEqual . existsAbstract ( game . getPlayer1Variables ( ) ) . ite ( maxPlayer1Strategy ,  minPlayer1Strategy ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    storm : : dd : : Bdd < Type >  tmp  =  ( prob01 . min . first . getPlayer2Strategy ( ) . existsAbstract ( game . getPlayer2Variables ( ) )  & &  prob01 . min . second . getPlayer2Strategy ( ) . existsAbstract ( game . getPlayer2Variables ( ) ) ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( tmp . isZero ( ) ,  " wth? " ) ;  
			
		
	
		
			
				
					                    tmp  =  prob01 . min . first . getPlayer2Strategy ( ) . existsAbstract ( game . getPlayer2Variables ( ) )  & &  minMaybeStateResult . player2Strategy . existsAbstract ( game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					                    tmp  =  prob01 . min . first . getPlayer2Strategy ( ) . existsAbstract ( game . getPlayer2Variables ( ) )  & &  minP layer2Strategy . existsAbstract ( game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					                    if  ( ! tmp . isZero ( ) )  {  
			
		
	
		
			
				
					                        tmp  =  tmp  & &  prob01 . min . first . getPlayer2Strategy ( ) . exclusiveOr ( minMaybeStateResult . player2Strategy ) . existsAbstract ( game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					                        tmp  =  tmp  & &  prob01 . min . first . getPlayer2Strategy ( ) . exclusiveOr ( minP layer2Strategy ) . existsAbstract ( game . getPlayer2Variables ( ) ) ;  
			
		
	
		
			
				
					                        ( tmp  & &  prob01 . min . first . getPlayer2Strategy ( ) ) . template  toAdd < ValueType > ( ) . exportToDot ( " prob0_strat.dot " ) ;  
			
		
	
		
			
				
					                        ( tmp  & &  minMaybeStateResult . player2Strategy ) . template  toAdd < ValueType > ( ) . exportToDot ( " maybe_strat.dot " ) ;  
			
		
	
		
			
				
					                        ( tmp  & &  minP layer2Strategy ) . template  toAdd < ValueType > ( ) . exportToDot ( " maybe_strat.dot " ) ;  
			
		
	
		
			
				
					                        if  ( ! tmp . isZero ( ) )  {  
			
		
	
		
			
				
					                            storm : : dd : : Add < Type ,  ValueType >  values  =  ( tmp . template  toAdd < ValueType > ( )  *  game . getTransitionMatrix ( )  *  minResult . swapVariables ( game . getRowColumnMetaVariablePairs ( ) ) ) . sumAbstract ( game . getColumnVariables ( ) ) ;  
			
		
	
		
			
				
					                            tmp . template  toAdd < ValueType > ( ) . exportToDot ( " illegal.dot " ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -595,20 +610,20 @@ namespace storm { 
			
		
	
		
			
				
					                        STORM_LOG_ASSERT ( tmp . isZero ( ) ,  " ddduuuudde? " ) ;  
			
		
	
		
			
				
					                    }  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( tmp . isZero ( ) ,  " wth2? " ) ;  
			
		
	
		
			
				
					                    tmp  =  prob01 . min . second . getPlayer2Strategy ( ) . existsAbstract ( game . getPlayer2Variables ( ) )  & &  minMaybeStateResult . player2Strategy ;  
			
		
	
		
			
				
					                    //tmp = prob01.min.second.getPlayer2Strategy().existsAbstract(game.getPlayer2Variables()) && minPlayer2Strategy;
  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    ( minMaybeStateResult . player2Strategy  & &  ( prob01 . min . first . getPlayer2Strategy ( )  | |  prob01 . min . second . getPlayer2Strategy ( ) ) ) . template  toAdd < ValueType > ( ) . exportToDot ( " strat_overlap.dot " ) ;  
			
		
	
		
			
				
					                    minMaybeStateResult . player2Strategy  | =  prob01 . min . first . getPlayer2Strategy ( )  | |  prob01 . min . second . getPlayer2Strategy ( ) ;  
			
		
	
		
			
				
					                    maxMaybeStateResult . player1Strategy  | =  prob01 . max . first . getPlayer1Strategy ( )  | |  prob01 . max . second . getPlayer1Strategy ( ) ;  
			
		
	
		
			
				
					                    maxMaybeStateResult . player2Strategy  | =  prob01 . max . first . getPlayer2Strategy ( )  | |  prob01 . max . second . getPlayer2Strategy ( ) ;  
			
		
	
		
			
				
					                    //(minMaybeStateResult.player2Strategy && (prob01.min.first.getPlayer2Strategy() || prob01.min.second.getPlayer2Strategy())).template toAdd<ValueType>().exportToDot("strat_overlap.dot");
  
			
		
	
		
			
				
					                    //minMaybeStateResult.player2Strategy |= prob01.min.first.getPlayer2Strategy() || prob01.min.second.getPlayer2Strategy();
  
			
		
	
		
			
				
					                    //maxMaybeStateResult.player1Strategy |= prob01.max.first.getPlayer1Strategy() || prob01.max.second.getPlayer1Strategy();
  
			
		
	
		
			
				
					                    //maxMaybeStateResult.player2Strategy |= prob01.max.first.getPlayer2Strategy() || prob01.max.second.getPlayer2Strategy();
  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    // Make sure that all strategies are still valid strategies.
  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( minMaybeStateResult . p layer1Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer1Variables ( ) ) . getMax ( )  < =  1 ,  " Player 1 strategy for min is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( maxMaybeStateResult . p layer1Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer1Variables ( ) ) . getMax ( )  < =  1 ,  " Player 1 strategy for max is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( minMaybeStateResult . p layer2Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer2Variables ( ) ) . getMax ( )  < =  1 ,  " Player 2 strategy for min is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( maxMaybeStateResult . p layer2Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer2Variables ( ) ) . getMax ( )  < =  1 ,  " Player 2 strategy for max is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( minP layer1Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer1Variables ( ) ) . getMax ( )  < =  1 ,  " Player 1 strategy for min is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( maxP layer1Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer1Variables ( ) ) . getMax ( )  < =  1 ,  " Player 1 strategy for max is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( minP layer2Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer2Variables ( ) ) . getMax ( )  < =  1 ,  " Player 2 strategy for min is illegal. " ) ;  
			
		
	
		
			
				
					                    STORM_LOG_ASSERT ( maxP layer2Strategy . template  toAdd < ValueType > ( ) . sumAbstract ( game . getPlayer2Variables ( ) ) . getMax ( )  < =  1 ,  " Player 2 strategy for max is illegal. " ) ;  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    refineAfterQuantitativeCheck ( abstractor ,  game ,  minResult ,  maxResult ,  prob01 ,  std : : make_pair ( minMaybeStateResult . player1Strategy ,  minMaybeStateResult . p layer2Strategy ) ,  std : : make_pair ( maxMaybeStateResult . player1Strategy ,  maxMaybeStateResult . p layer2Strategy ) ,  transitionMatrixBdd ) ;  
			
		
	
		
			
				
					                    refineAfterQuantitativeCheck ( abstractor ,  game ,  minResult ,  maxResult ,  prob01 ,  std : : make_pair ( minPlayer1Strategy ,  minP layer2Strategy ) ,  std : : make_pair ( maxPlayer1Strategy ,  maxP layer2Strategy ) ,  transitionMatrixBdd ) ;  
			
		
	
		
			
				
					                }  
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -633,7 +648,7 @@ namespace storm { 
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            return  std : : make_pair ( prob0 ,  prob1 ) ;  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					          
			
		
	
		
			
				
					
  
			
		
	
		
			
				
					        template < storm : : dd : : DdType  Type ,  typename  ModelType >  
			
		
	
		
			
				
					        storm : : expressions : : Expression  GameBasedMdpModelChecker < Type ,  ModelType > : : getExpression ( storm : : logic : : Formula  const &  formula )  {  
			
		
	
		
			
				
					            STORM_LOG_THROW ( formula . isBooleanLiteralFormula ( )  | |  formula . isAtomicExpressionFormula ( )  | |  formula . isAtomicLabelFormula ( ) ,  storm : : exceptions : : InvalidPropertyException ,  " The target states have to be given as label or an expression. " ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -647,11 +662,11 @@ namespace storm { 
			
		
	
		
			
				
					            }  
			
		
	
		
			
				
					            return  result ;  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					          
			
		
	
		
			
				
					
  
			
		
	
		
			
				
					        template  class  GameBasedMdpModelChecker < storm : : dd : : DdType : : CUDD ,  storm : : models : : symbolic : : Dtmc < storm : : dd : : DdType : : CUDD ,  double > > ;  
			
		
	
		
			
				
					        template  class  GameBasedMdpModelChecker < storm : : dd : : DdType : : CUDD ,  storm : : models : : symbolic : : Mdp < storm : : dd : : DdType : : CUDD ,  double > > ;  
			
		
	
		
			
				
					        template  class  GameBasedMdpModelChecker < storm : : dd : : DdType : : Sylvan ,  storm : : models : : symbolic : : Dtmc < storm : : dd : : DdType : : Sylvan ,  double > > ;  
			
		
	
		
			
				
					        template  class  GameBasedMdpModelChecker < storm : : dd : : DdType : : Sylvan ,  storm : : models : : symbolic : : Mdp < storm : : dd : : DdType : : Sylvan ,  double > > ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					}