@ -269,26 +269,42 @@ namespace storm { 
		
	
		
			
				            template < typename  ParametricSparseModelType ,  typename  ConstantType >             template < typename  ParametricSparseModelType ,  typename  ConstantType >  
		
	
		
			
				            ConstantType   ApproximationModel < ParametricSparseModelType ,  ConstantType > : : computeInitialStateValue ( ParameterRegion < ParametricType >  const &  region ,  bool  computeLowerBounds )  {             ConstantType   ApproximationModel < ParametricSparseModelType ,  ConstantType > : : computeInitialStateValue ( ParameterRegion < ParametricType >  const &  region ,  bool  computeLowerBounds )  {  
		
	
		
			
				                instantiate ( region ,  computeLowerBounds ) ;                 instantiate ( region ,  computeLowerBounds ) ;  
		
	
		
			
				                std : : vector < std : : size_t >  policy ;  
		
	
		
			
				                invokeSolver ( computeLowerBounds ,  policy ) ;  
		
	
		
			
				                std : : shared_ptr < Policy >  policy ;  
		
	
		
			
				                if ( computeLowerBounds  & &  ! this - > minimizingPolicies . empty ( ) ) {  
		
	
		
			
				                    policy  =  std : : make_shared < Policy > ( * * ( this - > minimizingPolicies . begin ( ) ) ) ;  //we need a fresh policy, initialized with the values of the old one
  
		
	
		
			
				                }  else  if ( ! computeLowerBounds  & &  ! this - > maximizingPolicies . empty ( ) ) {  
		
	
		
			
				                    policy  =  std : : make_shared < Policy > ( * * ( this - > maximizingPolicies . begin ( ) ) ) ;  //we need a fresh policy, initialized with the values of the old one
  
		
	
		
			
				                }  else  {  
		
	
		
			
				                    policy  =  std : : make_shared < Policy > ( this - > matrixData . matrix . getRowGroupCount ( ) ) ;  
		
	
		
			
				                }  
		
	
		
			
				                invokeSolver ( computeLowerBounds ,  * policy ) ;  
		
	
		
			
				                if ( computeLowerBounds ) {  
		
	
		
			
				                    this - > minimizingPolicies . insert ( policy ) ;  
		
	
		
			
				                    std : : cout  < <  minimizingPolicies . size ( )  < <  std : : endl ;  
		
	
		
			
				                }  else  {  
		
	
		
			
				                    this - > maximizingPolicies . insert ( policy ) ;  
		
	
		
			
				                    std : : cout  < <  maximizingPolicies . size ( )  < <  std : : endl ;  
		
	
		
			
				                }  
		
	
		
			
				                                 
		
	
		
			
				                //TODO: policy for games.
                 //TODO: policy for games.
  
		
	
		
			
				                //TODO: do this only when necessary.
  
		
	
		
			
				                //TODO: (maybe) when a few parameters are mapped to another value, build a "nicer" scheduler and check whether it induces values that are more optimal.
                 //TODO: (maybe) when a few parameters are mapped to another value, build a "nicer" scheduler and check whether it induces values that are more optimal.
  
		
	
		
			
				                if ( policy . empty ( ) )  return  this - > eqSysResult [ this - > eqSysInitIndex ] ;  
		
	
		
			
				                if ( policy - > empty ( ) )  return  this - > eqSysResult [ this - > eqSysInitIndex ] ;  
		
	
		
			
				                //Get the set of parameters which are (according to the policy) always mapped to the same region boundary.
                 //Get the set of parameters which are (according to the policy) always mapped to the same region boundary.
  
		
	
		
			
				                //First, collect all (relevant) parameters, i.e., the ones that are set to the lower or upper boundary.
                 //First, collect all (relevant) parameters, i.e., the ones that are set to the lower or upper boundary.
  
		
	
		
			
				                std : : map < VariableType ,  RegionBoundary >  fixedVariables ;                 std : : map < VariableType ,  RegionBoundary >  fixedVariables ;  
		
	
		
			
				                std : : map < VariableType ,  std : : pair < std : : size_t ,  std : : size_t > >  VarCount ;  
		
	
		
			
				                std : : size_t  substitutionCount  = 0 ;  
		
	
		
			
				                for ( auto  const &  substitution  :  this - > funcSubData . substitutions ) {                 for ( auto  const &  substitution  :  this - > funcSubData . substitutions ) {  
		
	
		
			
				                    for (  auto  const &  sub  :  substitution ) {                     for (  auto  const &  sub  :  substitution ) {  
		
	
		
			
				                        if ( sub . second ! =  RegionBoundary : : UNSPECIFIED ) {                         if ( sub . second ! =  RegionBoundary : : UNSPECIFIED ) {  
		
	
		
			
				                            fixedVariables . insert ( typename  std : : map < VariableType ,  RegionBoundary > : : value_type ( sub . first ,  RegionBoundary : : UNSPECIFIED ) ) ;                             fixedVariables . insert ( typename  std : : map < VariableType ,  RegionBoundary > : : value_type ( sub . first ,  RegionBoundary : : UNSPECIFIED ) ) ;  
		
	
		
			
				                            VarCount . insert ( typename  std : : map < VariableType ,  std : : pair < std : : size_t ,  std : : size_t > > : : value_type ( sub . first ,  std : : pair < std : : size_t ,  std : : size_t > ( 0 , 0 ) ) ) ;  
		
	
		
			
				                        }                         }  
		
	
		
			
				                    }                     }  
		
	
		
			
				                }                 }  
		
	
		
			
				                //Now erase the parameters that are mapped to different boundaries.
                 //Now erase the parameters that are mapped to different boundaries.
  
		
	
		
			
				                for ( std : : size_t  rowGroup = 0 ;  rowGroup < this - > matrixData . matrix . getRowGroupCount ( ) ;  + + rowGroup ) {                 for ( std : : size_t  rowGroup = 0 ;  rowGroup < this - > matrixData . matrix . getRowGroupCount ( ) ;  + + rowGroup ) {  
		
	
		
			
				                    std : : size_t  row  =  this - > matrixData . matrix . getRowGroupIndices ( ) [ rowGroup ]  +  policy [ rowGroup ] ;  
		
	
		
			
				                    std : : size_t  row  =  this - > matrixData . matrix . getRowGroupIndices ( ) [ rowGroup ]  +  ( * policy ) [ rowGroup ] ;  
		
	
		
			
				                    for ( std : : pair < VariableType ,  RegionBoundary >  const &  sub  :  this - > funcSubData . substitutions [ this - > matrixData . rowSubstitutions [ row ] ] ) {                     for ( std : : pair < VariableType ,  RegionBoundary >  const &  sub  :  this - > funcSubData . substitutions [ this - > matrixData . rowSubstitutions [ row ] ] ) {  
		
	
		
			
				                        auto  fixedVarIt  =  fixedVariables . find ( sub . first ) ;                         auto  fixedVarIt  =  fixedVariables . find ( sub . first ) ;  
		
	
		
			
				                        if ( fixedVarIt  ! =  fixedVariables . end ( )  & &  fixedVarIt - > second  ! =  sub . second ) {                         if ( fixedVarIt  ! =  fixedVariables . end ( )  & &  fixedVarIt - > second  ! =  sub . second ) {  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -299,15 +315,29 @@ namespace storm { 
		
	
		
			
				                                fixedVariables . erase ( fixedVarIt ) ;                                 fixedVariables . erase ( fixedVarIt ) ;  
		
	
		
			
				                            }                             }  
		
	
		
			
				                        }                         }  
		
	
		
			
				                        auto  varcountIt  =  VarCount . find ( sub . first ) ;  
		
	
		
			
				                        if ( sub . second = = RegionBoundary : : LOWER ) {  
		
	
		
			
				                            + + ( varcountIt - > second . first ) ;  
		
	
		
			
				                        }  else  if  ( sub . second = = RegionBoundary : : UPPER ) {  
		
	
		
			
				                            + + ( varcountIt - > second . second ) ;  
		
	
		
			
				                        }  
		
	
		
			
				                        + + substitutionCount ;  
		
	
		
			
				                    }                     }  
		
	
		
			
				                    if  ( fixedVariables . empty ( ) ) {                     if  ( fixedVariables . empty ( ) ) {  
		
	
		
			
				                        break ;  
		
	
		
			
				                       // break;
  
		
	
		
			
				                    }  
		
	
		
			
				                }  
		
	
		
			
				       //         std::cout << "Used Approximation" << std::endl;
  
		
	
		
			
				                for  ( auto  const &  varcount  :  VarCount ) {  
		
	
		
			
				                    if ( varcount . second . first  >  0  & &  varcount . second . second  >  0 ) {  
		
	
		
			
				              //          std::cout << "  Variable " << varcount.first << " has been set to lower " << varcount.second.first << " times and to upper " << varcount.second.second << " times. (total: " << substitutionCount << ")" << std::endl;
  
		
	
		
			
				                    }                     }  
		
	
		
			
				                }                 }  
		
	
		
			
				                for  ( auto  const &  fixVar  :  fixedVariables ) {                 for  ( auto  const &  fixVar  :  fixedVariables ) {  
		
	
		
			
				                    //std::cout << "APPROXMODEL: variable " << fixVar.first << " is always mapped to " << fixVar.second << std::endl;
  
		
	
		
			
				                    //std::cout << "   APPROXMODEL: variable " << fixVar.first << " is always mapped to " << fixVar.second << std::endl;
  
		
	
		
			
				                }                 }  
		
	
		
			
				                                         
		
	
		
			
				        //        std::cout << "    Result is " << this->eqSysResult[this->eqSysInitIndex] << std::endl;
  
		
	
		
			
				                return  this - > eqSysResult [ this - > eqSysInitIndex ] ;                 return  this - > eqSysResult [ this - > eqSysInitIndex ] ;  
		
	
		
			
				            }             }  
		
	
		
			
				                         
		
	
	
		
			
				
					
						
							 
					
					
						
							 
					
					
				 
				@ -342,17 +372,17 @@ namespace storm { 
		
	
		
			
				                    auto &  result  =  functionResult . second ;                     auto &  result  =  functionResult . second ;  
		
	
		
			
				                    result  =  computeLowerBounds  ?  storm : : utility : : infinity < ConstantType > ( )  :  storm : : utility : : zero < ConstantType > ( ) ;                     result  =  computeLowerBounds  ?  storm : : utility : : infinity < ConstantType > ( )  :  storm : : utility : : zero < ConstantType > ( ) ;  
		
	
		
			
				                     //Iterate over the different combinations of lower and upper bounds and update the min and max values
                      //Iterate over the different combinations of lower and upper bounds and update the min and max values
  
		
	
		
			
				                    auto  const &  vertices = region . getVerticesOfRegion ( unspecifiedParameters [ funcSub . getSubstitution ( ) ] ) ;  
		
	
		
			
				                    auto  const &  vertices = region . getVerticesOfRegion ( unspecifiedParameters [ funcSub . second ] ) ;  
		
	
		
			
				                    for ( auto  const &  vertex  :  vertices ) {                     for ( auto  const &  vertex  :  vertices ) {  
		
	
		
			
				                        //extend the substitution
                         //extend the substitution
  
		
	
		
			
				                        for ( auto  const &  vertexSub  :  vertex ) {                         for ( auto  const &  vertexSub  :  vertex ) {  
		
	
		
			
				                            instantiatedSubs [ funcSub . getSubstitution ( ) ] [ vertexSub . first ] = vertexSub . second ;  
		
	
		
			
				                            instantiatedSubs [ funcSub . second ] [ vertexSub . first ] = vertexSub . second ;  
		
	
		
			
				                        }                         }  
		
	
		
			
				                        //evaluate the function
                         //evaluate the function
  
		
	
		
			
				                        ConstantType  currValue  =  storm : : utility : : region : : convertNumber < ConstantType > (                         ConstantType  currValue  =  storm : : utility : : region : : convertNumber < ConstantType > (  
		
	
		
			
				                                storm : : utility : : region : : evaluateFunction (                                 storm : : utility : : region : : evaluateFunction (  
		
	
		
			
				                                    funcSub . getFunction ( ) ,  
		
	
		
			
				                                    instantiatedSubs [ funcSub . getSubstitution ( ) ]  
		
	
		
			
				                                    funcSub . first ,  
		
	
		
			
				                                    instantiatedSubs [ funcSub . second ]  
		
	
		
			
				                                    )                                     )  
		
	
		
			
				                                ) ;                                 ) ;  
		
	
		
			
				                        result  =  computeLowerBounds  ?  std : : min ( result ,  currValue )  :  std : : max ( result ,  currValue ) ;                         result  =  computeLowerBounds  ?  std : : min ( result ,  currValue )  :  std : : max ( result ,  currValue ) ;  
		
	
	
		
			
				
					
					
					
						
							 
					
				 
				@ -370,16 +400,16 @@ namespace storm { 
		
	
		
			
				                         
		
	
		
			
				                                                 
		
	
		
			
				            template < >             template < >  
		
	
		
			
				            void  ApproximationModel < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > ,  double > : : invokeSolver ( bool  computeLowerBounds ,  std : : vector < std : : size_t > &  policy ) {  
		
	
		
			
				            void  ApproximationModel < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > ,  double > : : invokeSolver ( bool  computeLowerBounds ,  Policy &  policy ) {  
		
	
		
			
				                storm : : solver : : SolveGoal  goal ( computeLowerBounds ) ;                 storm : : solver : : SolveGoal  goal ( computeLowerBounds ) ;  
		
	
		
			
				                std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < double > >  solver  =  storm : : solver : : configureMinMaxLinearEquationSolver ( goal ,  storm : : utility : : solver : : MinMaxLinearEquationSolverFactory < double > ( ) ,  this - > matrixData . matrix ) ;                 std : : unique_ptr < storm : : solver : : MinMaxLinearEquationSolver < double > >  solver  =  storm : : solver : : configureMinMaxLinearEquationSolver ( goal ,  storm : : utility : : solver : : MinMaxLinearEquationSolverFactory < double > ( ) ,  this - > matrixData . matrix ) ;  
		
	
		
			
				                solver - > setPolicyTracking ( ) ;                 solver - > setPolicyTracking ( ) ;  
		
	
		
			
				                solver - > solveEquationSystem ( this - > eqSysResult ,  this - > vectorData . vector ) ;  
		
	
		
			
				                solver - > solveEquationSystem ( goal . direction ( ) ,  this - > eqSysResult ,  this - > vectorData . vector ,  nullptr ,  nullptr ,  & policy ) ;  
		
	
		
			
				                policy  =  solver - > getPolicy ( ) ;                 policy  =  solver - > getPolicy ( ) ;  
		
	
		
			
				            }             }  
		
	
		
			
				                         
		
	
		
			
				            template < >             template < >  
		
	
		
			
				            void  ApproximationModel < storm : : models : : sparse : : Mdp < storm : : RationalFunction > ,  double > : : invokeSolver ( bool  computeLowerBounds ,  std : : vector < std : : size_t > &  policy ) {  
		
	
		
			
				            void  ApproximationModel < storm : : models : : sparse : : Mdp < storm : : RationalFunction > ,  double > : : invokeSolver ( bool  computeLowerBounds ,  Policy &  policy ) {  
		
	
		
			
				                storm : : solver : : SolveGoal  player2Goal ( computeLowerBounds ) ;                 storm : : solver : : SolveGoal  player2Goal ( computeLowerBounds ) ;  
		
	
		
			
				                std : : unique_ptr < storm : : solver : : GameSolver < double > >  solver  =  storm : : utility : : solver : : GameSolverFactory < double > ( ) . create ( this - > player1Matrix ,  this - > matrixData . matrix ) ;                 std : : unique_ptr < storm : : solver : : GameSolver < double > >  solver  =  storm : : utility : : solver : : GameSolverFactory < double > ( ) . create ( this - > player1Matrix ,  this - > matrixData . matrix ) ;  
		
	
		
			
				                solver - > solveGame ( this - > player1Goal . direction ( ) ,  player2Goal . direction ( ) ,  this - > eqSysResult ,  this - > vectorData . vector ) ;                 solver - > solveGame ( this - > player1Goal . direction ( ) ,  player2Goal . direction ( ) ,  this - > eqSysResult ,  this - > vectorData . vector ) ;