@ -390,7 +390,7 @@ namespace storm { 
		
	
		
			
				            storm : : dd : : Bdd < Type >  lowerChoice1  =  ( lowerChoice  & &  minPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;             storm : : dd : : Bdd < Type >  lowerChoice1  =  ( lowerChoice  & &  minPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;  
		
	
		
			
				            storm : : dd : : Bdd < Type >  lowerChoice2  =  ( lowerChoice  & &  maxPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;             storm : : dd : : Bdd < Type >  lowerChoice2  =  ( lowerChoice  & &  maxPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;  
		
	
		
			
				                         
		
	
		
			
				            bool  lowerChoicesDifferent  =  ! lowerChoice1 . exclusiveOr ( lowerChoice2 ) . isZero ( ) ;  
		
	
		
			
				            bool  lowerChoicesDifferent  =  ! lowerChoice1 . exclusiveOr ( lowerChoice2 ) . isZero ( )  & &  ! lowerChoice1 . isZero ( )  & &  ! lowerChoice2 . isZero ( )  ;  
		
	
		
			
				            if  ( lowerChoicesDifferent )  {             if  ( lowerChoicesDifferent )  {  
		
	
		
			
				                STORM_LOG_TRACE ( " Deriving predicate based on lower choice. " ) ;                 STORM_LOG_TRACE ( " Deriving predicate based on lower choice. " ) ;  
		
	
		
			
				                predicates  =  derivePredicatesFromDifferingChoices ( ( pivotState  & &  minPlayer1Strategy ) . existsAbstract ( game . getRowVariables ( ) ) ,  lowerChoice1 ,  lowerChoice2 ) ;                 predicates  =  derivePredicatesFromDifferingChoices ( ( pivotState  & &  minPlayer1Strategy ) . existsAbstract ( game . getRowVariables ( ) ) ,  lowerChoice1 ,  lowerChoice2 ) ;  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -405,7 +405,7 @@ namespace storm { 
		
	
		
			
				                storm : : dd : : Bdd < Type >  upperChoice1  =  ( upperChoice  & &  minPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;                 storm : : dd : : Bdd < Type >  upperChoice1  =  ( upperChoice  & &  minPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;  
		
	
		
			
				                storm : : dd : : Bdd < Type >  upperChoice2  =  ( upperChoice  & &  maxPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;                 storm : : dd : : Bdd < Type >  upperChoice2  =  ( upperChoice  & &  maxPlayer2Strategy ) . existsAbstract ( variablesToAbstract ) ;  
		
	
		
			
				                                 
		
	
		
			
				                bool  upperChoicesDifferent  =  ! upperChoice1 . exclusiveOr ( upperChoice2 ) . isZero ( ) ;  
		
	
		
			
				                bool  upperChoicesDifferent  =  ! upperChoice1 . exclusiveOr ( upperChoice2 ) . isZero ( )  & &  ! upperChoice1 . isZero ( )  & &  ! upperChoice2 . isZero ( )  ;  
		
	
		
			
				                if  ( upperChoicesDifferent )  {                 if  ( upperChoicesDifferent )  {  
		
	
		
			
				                    STORM_LOG_TRACE ( " Deriving predicate based on upper choice. " ) ;                     STORM_LOG_TRACE ( " Deriving predicate based on upper choice. " ) ;  
		
	
		
			
				                    additionalPredicates  =  derivePredicatesFromDifferingChoices ( ( pivotState  & &  maxPlayer1Strategy ) . existsAbstract ( game . getRowVariables ( ) ) ,  upperChoice1 ,  upperChoice2 ) ;                     additionalPredicates  =  derivePredicatesFromDifferingChoices ( ( pivotState  & &  maxPlayer1Strategy ) . existsAbstract ( game . getRowVariables ( ) ) ,  upperChoice1 ,  upperChoice2 ) ;  
		
	
	
		
			
				
					
						
							 
					
					
						
							 
					
					
				 
				@ -476,12 +476,26 @@ namespace storm { 
		
	
		
			
				                                 
		
	
		
			
				                // Retrieve the variable updates that the predecessor needs to perform to get to the current state.
                 // Retrieve the variable updates that the predecessor needs to perform to get to the current state.
  
		
	
		
			
				                auto  variableUpdates  =  abstractor . get ( ) . getVariableUpdates ( std : : get < 1 > ( decodedPredecessor ) ,  std : : get < 2 > ( decodedPredecessor ) ) ;                 auto  variableUpdates  =  abstractor . get ( ) . getVariableUpdates ( std : : get < 1 > ( decodedPredecessor ) ,  std : : get < 2 > ( decodedPredecessor ) ) ;  
		
	
		
			
				                for  ( auto  const &  update  :  variableUpdates )  {  
		
	
		
			
				                    storm : : expressions : : Variable  newVariable  =  oldToNewVariables . at ( update . first ) ;  
		
	
		
			
				                    if  ( update . second . hasBooleanType ( ) )  {  
		
	
		
			
				                        predicates . back ( ) . push_back ( storm : : expressions : : iff ( lastSubstitution . at ( oldToNewVariables . at ( update . first ) ) ,  update . second . changeManager ( expressionManager ) . substitute ( substitution ) ) ) ;  
		
	
		
			
				                for  ( auto  const &  oldNewVariablePair  :  oldToNewVariables )  {  
		
	
		
			
				                    storm : : expressions : : Variable  const &  newVariable  =  oldNewVariablePair . second ;  
		
	
		
			
				
 
		
	
		
			
				                    // If the variable was set, use its update expression.
  
		
	
		
			
				                    auto  updateIt  =  variableUpdates . find ( oldNewVariablePair . first ) ;  
		
	
		
			
				                    if  ( updateIt  ! =  variableUpdates . end ( ) )  {  
		
	
		
			
				                        auto  const &  update  =  * updateIt ;  
		
	
		
			
				
 
		
	
		
			
				                        if  ( update . second . hasBooleanType ( ) )  {  
		
	
		
			
				                            predicates . back ( ) . push_back ( storm : : expressions : : iff ( lastSubstitution . at ( newVariable ) ,  update . second . changeManager ( expressionManager ) . substitute ( substitution ) ) ) ;  
		
	
		
			
				                        }  else  {  
		
	
		
			
				                            predicates . back ( ) . push_back ( lastSubstitution . at ( newVariable )  = =  update . second . changeManager ( expressionManager ) . substitute ( substitution ) ) ;  
		
	
		
			
				                        }  
		
	
		
			
				                    }  else  {                     }  else  {  
		
	
		
			
				                        predicates . back ( ) . push_back ( lastSubstitution . at ( oldToNewVariables . at ( update . first ) )  = =  update . second . changeManager ( expressionManager ) . substitute ( substitution ) ) ;  
		
	
		
			
				                        // Otherwise, make sure that the new variable maintains the old value.
  
		
	
		
			
				                        if  ( newVariable . hasBooleanType ( ) )  {  
		
	
		
			
				                            predicates . back ( ) . push_back ( storm : : expressions : : iff ( lastSubstitution . at ( newVariable ) ,  substitution . at ( newVariable ) ) ) ;  
		
	
		
			
				                        }  else  {  
		
	
		
			
				                            predicates . back ( ) . push_back ( lastSubstitution . at ( newVariable )  = =  substitution . at ( newVariable ) ) ;  
		
	
		
			
				                        }  
		
	
		
			
				                    }                     }  
		
	
		
			
				                }                 }  
		
	
		
			
				                                 
		
	
	
		
			
				
					
						
							 
					
					
						
							 
					
					
				 
				@ -581,6 +595,7 @@ namespace storm { 
		
	
		
			
				                         
		
	
		
			
				            // Redirect all player 1 choices of the min strategy to that of the max strategy if this leads to a player 2
             // Redirect all player 1 choices of the min strategy to that of the max strategy if this leads to a player 2
  
		
	
		
			
				            // state that is also a prob 0 state.
             // state that is also a prob 0 state.
  
		
	
		
			
				            auto  oldMinPlayer1Strategy  =  minPlayer1Strategy ;  
		
	
		
			
				            minPlayer1Strategy  =  ( maxPlayer1Strategy  & &  qualitativeResult . prob0Min . getPlayer2States ( ) ) . existsAbstract ( game . getPlayer1Variables ( ) ) . ite ( maxPlayer1Strategy ,  minPlayer1Strategy ) ;             minPlayer1Strategy  =  ( maxPlayer1Strategy  & &  qualitativeResult . prob0Min . getPlayer2States ( ) ) . existsAbstract ( game . getPlayer1Variables ( ) ) . ite ( maxPlayer1Strategy ,  minPlayer1Strategy ) ;  
		
	
		
			
				                         
		
	
		
			
				            // Compute all reached pivot states.
             // Compute all reached pivot states.
  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -597,7 +612,49 @@ namespace storm { 
		
	
		
			
				                         
		
	
		
			
				            // Now that we have the pivot state candidates, we need to pick one.
             // Now that we have the pivot state candidates, we need to pick one.
  
		
	
		
			
				            PivotStateResult < Type ,  ValueType >  pivotStateResult  =  pickPivotState < Type ,  ValueType > ( pivotSelectionHeuristic ,  game ,  pivotStateCandidatesResult ,  qualitativeResult ,  boost : : none ) ;             PivotStateResult < Type ,  ValueType >  pivotStateResult  =  pickPivotState < Type ,  ValueType > ( pivotSelectionHeuristic ,  game ,  pivotStateCandidatesResult ,  qualitativeResult ,  boost : : none ) ;  
		
	
		
			
				             
		
	
		
			
				
 
		
	
		
			
				//            // SANITY CHECK TO MAKE SURE OUR STRATEGIES ARE NOT BROKEN.
  
		
	
		
			
				//            // FIXME.
  
		
	
		
			
				//            auto min1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && minPlayer1Strategy;
  
		
	
		
			
				//            STORM_LOG_ASSERT(!min1ChoiceInPivot.isZero(), "wth?");
  
		
	
		
			
				//            bool min1ChoiceInPivotIsProb0Min = !(min1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool min1ChoiceInPivotIsProb0Max = !(min1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool min1ChoiceInPivotIsProb1Min = !(min1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool min1ChoiceInPivotIsProb1Max = !(min1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero();
  
		
	
		
			
				//            std::cout << "after redirection (min)" << std::endl;
  
		
	
		
			
				//            std::cout << "min choice is prob0 in min? " << min1ChoiceInPivotIsProb0Min << ", max? " << min1ChoiceInPivotIsProb0Max << std::endl;
  
		
	
		
			
				//            std::cout << "min choice is prob1 in min? " << min1ChoiceInPivotIsProb1Min << ", max? " << min1ChoiceInPivotIsProb1Max << std::endl;
  
		
	
		
			
				//            std::cout << "min" << std::endl;
  
		
	
		
			
				//            for (auto const& e : (min1ChoiceInPivot && minPlayer2Strategy).template toAdd<ValueType>()) {
  
		
	
		
			
				//                std::cout << e.first << " -> " << e.second << std::endl;
  
		
	
		
			
				//            }
  
		
	
		
			
				//            std::cout << "max" << std::endl;
  
		
	
		
			
				//            for (auto const& e : (min1ChoiceInPivot && maxPlayer2Strategy).template toAdd<ValueType>()) {
  
		
	
		
			
				//                std::cout << e.first << " -> " << e.second << std::endl;
  
		
	
		
			
				//            }
  
		
	
		
			
				//            bool different = (min1ChoiceInPivot && minPlayer2Strategy) != (min1ChoiceInPivot && maxPlayer2Strategy);
  
		
	
		
			
				//            std::cout << "min/max choice of player 2 is different? " << different << std::endl;
  
		
	
		
			
				//            bool min1MinPlayer2Choice = !(min1ChoiceInPivot && minPlayer2Strategy).isZero();
  
		
	
		
			
				//            bool min1MaxPlayer2Choice = !(min1ChoiceInPivot && maxPlayer2Strategy).isZero();
  
		
	
		
			
				//            std::cout << "max/min choice there? " << min1MinPlayer2Choice << std::endl;
  
		
	
		
			
				//            std::cout << "max/max choice there? " << min1MaxPlayer2Choice << std::endl;
  
		
	
		
			
				//
  
		
	
		
			
				//            auto max1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && maxPlayer1Strategy;
  
		
	
		
			
				//            STORM_LOG_ASSERT(!max1ChoiceInPivot.isZero(), "wth?");
  
		
	
		
			
				//            bool max1ChoiceInPivotIsProb0Min = !(max1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool max1ChoiceInPivotIsProb0Max = !(max1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool max1ChoiceInPivotIsProb1Min = !(max1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero();
  
		
	
		
			
				//            bool max1ChoiceInPivotIsProb1Max = !(max1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero();
  
		
	
		
			
				//            std::cout << "after redirection (max)" << std::endl;
  
		
	
		
			
				//            std::cout << "max choice is prob0 in min? " << max1ChoiceInPivotIsProb0Min << ", max? " << max1ChoiceInPivotIsProb0Max << std::endl;
  
		
	
		
			
				//            std::cout << "max choice is prob1 in min? " << max1ChoiceInPivotIsProb1Min << ", max? " << max1ChoiceInPivotIsProb1Max << std::endl;
  
		
	
		
			
				//            different = (max1ChoiceInPivot && minPlayer2Strategy) != (max1ChoiceInPivot && maxPlayer2Strategy);
  
		
	
		
			
				//            std::cout << "min/max choice of player 2 is different? " << different << std::endl;
  
		
	
		
			
				//            bool max1MinPlayer2Choice = !(max1ChoiceInPivot && minPlayer2Strategy).isZero();
  
		
	
		
			
				//            bool max1MaxPlayer2Choice = !(max1ChoiceInPivot && maxPlayer2Strategy).isZero();
  
		
	
		
			
				//            std::cout << "max/min choice there? " << max1MinPlayer2Choice << std::endl;
  
		
	
		
			
				//            std::cout << "max/max choice there? " << max1MaxPlayer2Choice << std::endl;
  
		
	
		
			
				
 
		
	
		
			
				            boost : : optional < RefinementPredicates >  predicates ;             boost : : optional < RefinementPredicates >  predicates ;  
		
	
		
			
				            if  ( useInterpolation )  {             if  ( useInterpolation )  {  
		
	
		
			
				                predicates  =  derivePredicatesFromInterpolation ( game ,  pivotStateResult ,  minPlayer1Strategy ,  minPlayer2Strategy ,  maxPlayer1Strategy ,  maxPlayer2Strategy ) ;                 predicates  =  derivePredicatesFromInterpolation ( game ,  pivotStateResult ,  minPlayer1Strategy ,  minPlayer2Strategy ,  maxPlayer1Strategy ,  maxPlayer2Strategy ) ;