@ -40,6 +40,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				            struct  RelevancyInformation  {  
				 
				 
				            struct  RelevancyInformation  {  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : BitVector  relevantStates ;  
				 
				 
				                storm : : storage : : BitVector  relevantStates ;  
			
		 
		
	
		
			
				 
				 
				                std : : set < uint_fast64_t >  relevantLabels ;  
				 
				 
				                std : : set < uint_fast64_t >  relevantLabels ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : set < uint_fast64_t >  knownLabels ;  
			
		 
		
	
		
			
				 
				 
				                std : : unordered_map < uint_fast64_t ,  std : : list < uint_fast64_t > >  relevantChoicesForRelevantStates ;  
				 
				 
				                std : : unordered_map < uint_fast64_t ,  std : : list < uint_fast64_t > >  relevantChoicesForRelevantStates ;  
			
		 
		
	
		
			
				 
				 
				            } ;  
				 
				 
				            } ;  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -47,6 +48,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                std : : vector < z3 : : expr >  labelVariables ;  
				 
				 
				                std : : vector < z3 : : expr >  labelVariables ;  
			
		 
		
	
		
			
				 
				 
				                std : : vector < z3 : : expr >  originalAuxiliaryVariables ;  
				 
				 
				                std : : vector < z3 : : expr >  originalAuxiliaryVariables ;  
			
		 
		
	
		
			
				 
				 
				                std : : vector < z3 : : expr >  auxiliaryVariables ;  
				 
				 
				                std : : vector < z3 : : expr >  auxiliaryVariables ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : vector < z3 : : expr >  adderVariables ;  
			
		 
		
	
		
			
				 
				 
				                std : : map < uint_fast64_t ,  uint_fast64_t >  labelToIndexMap ;  
				 
				 
				                std : : map < uint_fast64_t ,  uint_fast64_t >  labelToIndexMap ;  
			
		 
		
	
		
			
				 
				 
				            } ;  
				 
				 
				            } ;  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -63,6 +65,9 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                / /  Create  result .  
				 
				 
				                / /  Create  result .  
			
		 
		
	
		
			
				 
				 
				                RelevancyInformation  relevancyInformation ;  
				 
				 
				                RelevancyInformation  relevancyInformation ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  Compute  the  set  of  labels  that  are  known  to  be  taken  in  any  case .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                relevancyInformation . knownLabels  =  storm : : utility : : counterexamples : : getGuaranteedLabelSet ( labeledMdp ,  psiStates ,  relevancyInformation . relevantLabels ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Compute  all  relevant  states ,  i . e .  states  for  which  there  exists  a  scheduler  that  has  a  non - zero  
				 
				 
				                / /  Compute  all  relevant  states ,  i . e .  states  for  which  there  exists  a  scheduler  that  has  a  non - zero  
			
		 
		
	
		
			
				 
				 
				                / /  probabilitiy  of  satisfying  phi  until  psi .  
				 
				 
				                / /  probabilitiy  of  satisfying  phi  until  psi .  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < bool >  backwardTransitions  =  labeledMdp . getBackwardTransitions ( ) ;  
				 
				 
				                storm : : storage : : SparseMatrix < bool >  backwardTransitions  =  labeledMdp . getBackwardTransitions ( ) ;  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -89,7 +94,10 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                            / /  If  there  is  a  relevant  successor ,  we  need  to  add  the  labels  of  the  current  choice .  
				 
				 
				                            / /  If  there  is  a  relevant  successor ,  we  need  to  add  the  labels  of  the  current  choice .  
			
		 
		
	
		
			
				 
				 
				                            if  ( relevancyInformation . relevantStates . get ( * successorIt )  | |  psiStates . get ( * successorIt ) )  {  
				 
				 
				                            if  ( relevancyInformation . relevantStates . get ( * successorIt )  | |  psiStates . get ( * successorIt ) )  {  
			
		 
		
	
		
			
				 
				 
				                                for  ( auto  const &  label  :  choiceLabeling [ row ] )  {  
				 
				 
				                                for  ( auto  const &  label  :  choiceLabeling [ row ] )  {  
			
		 
		
	
		
			
				 
				 
				                                    relevancyInformation . relevantLabels . insert ( label ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    / /  Only  insert  the  label  if  it ' s  not  already  known .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    if  ( relevancyInformation . knownLabels . find ( label )  = =  relevancyInformation . knownLabels . end ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                        relevancyInformation . relevantLabels . insert ( label ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                    }  
			
		 
		
	
		
			
				 
				 
				                                }  
				 
				 
				                                }  
			
		 
		
	
		
			
				 
				 
				                                if  ( ! currentChoiceRelevant )  {  
				 
				 
				                                if  ( ! currentChoiceRelevant )  {  
			
		 
		
	
		
			
				 
				 
				                                    currentChoiceRelevant  =  true ;  
				 
				 
				                                    currentChoiceRelevant  =  true ;  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -100,7 +108,8 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                LOG4CPLUS_DEBUG ( logger ,  " Found  "  < <  relevancyInformation . relevantLabels . size ( )  < <  "  relevant labels. " ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                LOG4CPLUS_DEBUG ( logger ,  " Found  "  < <  relevancyInformation . relevantLabels . size ( )  < <  "  relevant and  "  < <  relevancyInformation . knownLabels . size ( )  < <  "  known labels. " ) ;  
			
		 
		
	
		
			
				 
				 
				                return  relevancyInformation ;  
				 
				 
				                return  relevancyInformation ;  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -248,27 +257,48 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                std : : vector < z3 : : expr >  formulae ;  
				 
				 
				                std : : vector < z3 : : expr >  formulae ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Start  by  asserting  that  we  take  at  least  one  initial  label .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                for  ( auto  label  :  initialLabels )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  Start  by  asserting  that  we  take  at  least  one  initial  label .  We  may  do  so  only  if  there  is  no  initial  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  label  that  is  already  known .  Otherwise  this  condition  would  be  too  strong .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : set < uint_fast64_t >  intersection ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : set_intersection ( initialLabels . begin ( ) ,  initialLabels . end ( ) ,  relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ,  std : : inserter ( intersection ,  intersection . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( intersection . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( auto  label  :  initialLabels )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    assertDisjunction ( context ,  solver ,  formulae ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    formulae . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    / /  If  the  intersection  was  non - empty ,  we  clear  the  set  so  we  can  re - use  it  later .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    intersection . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                assertDisjunction ( context ,  solver ,  formulae ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                formulae . clear ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Also  assert  that  we  take  at  least  one  target  label .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                for  ( auto  label  :  targetLabels )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  Likewise ,  if  no  target  label  is  known ,  we  may  assert  that  there  is  at  least  one .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : set_intersection ( targetLabels . begin ( ) ,  targetLabels . end ( ) ,  relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ,  std : : inserter ( intersection ,  intersection . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( intersection . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    for  ( auto  label  :  targetLabels )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    assertDisjunction ( context ,  solver ,  formulae ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    / /  If  the  intersection  was  non - empty ,  we  clear  the  set  so  we  can  re - use  it  later .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    intersection . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                assertDisjunction ( context ,  solver ,  formulae ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Now  assert  that  for  each  non - target  label ,  we  take  a  following  label .  
				 
				 
				                / /  Now  assert  that  for  each  non - target  label ,  we  take  a  following  label .  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  labelSetPair  :  followingLabels )  {  
				 
				 
				                for  ( auto  const &  labelSetPair  :  followingLabels )  {  
			
		 
		
	
		
			
				 
				 
				                    formulae . clear ( ) ;  
				 
				 
				                    formulae . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				                    if  ( targetLabels . find ( labelSetPair . first )  = =  targetLabels . end ( ) )  {  
				 
				 
				                    if  ( targetLabels . find ( labelSetPair . first )  = =  targetLabels . end ( ) )  {  
			
		 
		
	
		
			
				 
				 
				                        formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelSetPair . first ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  followingLabel  :  labelSetPair . second )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( followingLabel ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        / /  Also ,  if  there  is  a  known  label  that  may  follow  the  current  label ,  we  don ' t  need  to  assert  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        / /  anything  here .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        std : : set_intersection ( labelSetPair . second . begin ( ) ,  labelSetPair . second . end ( ) ,  relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ,  std : : inserter ( intersection ,  intersection . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        if  ( intersection . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelSetPair . first ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            for  ( auto  followingLabel  :  labelSetPair . second )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                                formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( followingLabel ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            / /  If  the  intersection  was  non - empty ,  we  clear  the  set  so  we  can  re - use  it  later .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            intersection . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                    if  ( formulae . size ( )  >  0 )  {  
				 
				 
				                    if  ( formulae . size ( )  >  0 )  {  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -276,28 +306,28 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  FIXME :  This  is  currently  disabled  because  it  derives  less  information  than  the  following  backward  cuts .  
			
		 
		
	
		
			
				 
				 
				                / /  Consequently ,  assert  that  for  each  non - initial  label ,  we  take  preceding  command .  
				 
				 
				                / /  Consequently ,  assert  that  for  each  non - initial  label ,  we  take  preceding  command .  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  labelSetPair  :  precedingLabels )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    formulae . clear ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    if  ( initialLabels . find ( labelSetPair . first )  = =  initialLabels . end ( ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelSetPair . first ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        for  ( auto  followingLabel  :  labelSetPair . second )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                            formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( followingLabel ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    if  ( formulae . size ( )  >  0 )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        assertDisjunction ( context ,  solver ,  formulae ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  Also ,  we  can  assert  that  all  labels  that  are  encountered  along  all  paths  from  an  initial  to  a  target  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  state  are  taken .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                formulae . clear ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                std : : set < uint_fast64_t >  knownLabels  =  storm : : utility : : counterexamples : : getGuaranteedLabelSet ( labeledMdp ,  psiStates ,  relevancyInformation . relevantLabels ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                for  ( auto  label  :  knownLabels )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                assertConjunction ( context ,  solver ,  formulae ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                 for  ( auto  const &  labelSetPair  :  precedingLabels )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     formulae . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     if  ( initialLabels . find ( labelSetPair . first )  = =  initialLabels . end ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         / /  Also ,  if  there  is  a  known  label  that  may  follow  the  current  label ,  we  don ' t  need  to  assert  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         / /  anything  here .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         std : : set_intersection ( labelSetPair . second . begin ( ) ,  labelSetPair . second . end ( ) ,  relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ,  std : : inserter ( intersection ,  intersection . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         if  ( intersection . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelSetPair . first ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             for  ( auto  followingLabel  :  labelSetPair . second )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                                 formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( followingLabel ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             / /  If  the  intersection  was  non - empty ,  we  clear  the  set  so  we  can  re - use  it  later .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             intersection . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     if  ( formulae . size ( )  >  0 )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         assertDisjunction ( context ,  solver ,  formulae ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                 }  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				            /*!  
				 
				 
				            /*!  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -309,19 +339,8 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				             *  @ param  solver  The  solver  to  use  for  the  satisfiability  evaluation .  
				 
				 
				             *  @ param  solver  The  solver  to  use  for  the  satisfiability  evaluation .  
			
		 
		
	
		
			
				 
				 
				             */  
				 
				 
				             */  
			
		 
		
	
		
			
				 
				 
				            static  void  assertSymbolicCuts ( storm : : ir : : Program  const &  program ,  storm : : models : : Mdp < T >  const &  labeledMdp ,  VariableInformation  const &  variableInformation ,  RelevancyInformation  const &  relevancyInformation ,  z3 : : context &  context ,  z3 : : solver &  solver )  {  
				 
				 
				            static  void  assertSymbolicCuts ( storm : : ir : : Program  const &  program ,  storm : : models : : Mdp < T >  const &  labeledMdp ,  VariableInformation  const &  variableInformation ,  RelevancyInformation  const &  relevancyInformation ,  z3 : : context &  context ,  z3 : : solver &  solver )  {  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  Initially ,  we  look  for  synchronisation  implications .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                 for  ( uint_fast64_t  moduleIndex  =  0 ;  moduleIndex  <  program . getNumberOfModules ( ) ;  + + moduleIndex )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                     storm : : ir : : Module  const &  module  =  program . getModule ( moduleIndex ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                      
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                     for  ( uint_fast64_t  commandIndex  =  0 ;  commandIndex  <  module . getNumberOfCommands ( ) ;  + + commandIndex )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                         storm : : ir : : Command  const &  command  =  module . getCommand ( commandIndex ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                   
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                         / /  If  the  command  is  unlabeled ,  there  are  no  synchronisation  cuts  to  apply .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                         if  ( command . getActionName ( )  = =  " " )  continue ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                     }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				/ /                 }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  FIXME :  Include  synchronisation  cuts .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  FIXME :  Fix  backward  cuts  in  the  presence  of  synchronizing  actions .  
			
		 
		
	
		
			
				 
				 
				                std : : map < uint_fast64_t ,  std : : set < uint_fast64_t > >  precedingLabels ;  
				 
				 
				                std : : map < uint_fast64_t ,  std : : set < uint_fast64_t > >  precedingLabels ;  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                / /  Get  some  data  from  the  MDP  for  convenient  access .  
				 
				 
				                / /  Get  some  data  from  the  MDP  for  convenient  access .  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -329,6 +348,7 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                std : : vector < std : : set < uint_fast64_t > >  const &  choiceLabeling  =  labeledMdp . getChoiceLabeling ( ) ;  
				 
				 
				                std : : vector < std : : set < uint_fast64_t > >  const &  choiceLabeling  =  labeledMdp . getChoiceLabeling ( ) ;  
			
		 
		
	
		
			
				 
				 
				                storm : : storage : : SparseMatrix < bool >  backwardTransitions  =  labeledMdp . getBackwardTransitions ( ) ;  
				 
				 
				                storm : : storage : : SparseMatrix < bool >  backwardTransitions  =  labeledMdp . getBackwardTransitions ( ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  Compute  the  set  of  labels  that  may  precede  a  given  action .  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  currentState  :  relevancyInformation . relevantStates )  {  
				 
				 
				                for  ( auto  currentState  :  relevancyInformation . relevantStates )  {  
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  currentChoice  :  relevancyInformation . relevantChoicesForRelevantStates . at ( currentState ) )  {  
				 
				 
				                    for  ( auto  currentChoice  :  relevancyInformation . relevantChoicesForRelevantStates . at ( currentState ) )  {  
			
		 
		
	
		
			
				 
				 
				                        / /  Iterate  over  predecessors  and  add  all  choices  that  target  the  current  state  to  the  preceding  
				 
				 
				                        / /  Iterate  over  predecessors  and  add  all  choices  that  target  the  current  state  to  the  preceding  
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -470,17 +490,26 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                std : : vector < z3 : : expr >  formulae ;  
				 
				 
				                std : : vector < z3 : : expr >  formulae ;  
			
		 
		
	
		
			
				 
				 
				                for  ( auto  const &  labelImplicationsPair  :  backwardImplications )  {  
				 
				 
				                for  ( auto  const &  labelImplicationsPair  :  backwardImplications )  {  
			
		 
		
	
		
			
				 
				 
				                    formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelImplicationsPair . first ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    / /  We  only  need  to  make  this  an  implication  if  the  label  is  not  already  known .  If  it  is  known ,  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    / /  we  can  directly  assert  the  disjunction  of  the  implications .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( relevancyInformation . knownLabels . find ( labelImplicationsPair . first )  = =  relevancyInformation . knownLabels . end ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        formulae . push_back ( ! variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( labelImplicationsPair . first ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    std : : set < uint_fast64_t >  actualImplications ;  
				 
				 
				                    std : : set < uint_fast64_t >  actualImplications ;  
			
		 
		
	
		
			
				 
				 
				                    std : : set_intersection ( labelImplicationsPair . second . begin ( ) ,  labelImplicationsPair . second . end ( ) ,  precedingLabels . at ( labelImplicationsPair . first ) . begin ( ) ,  precedingLabels . at ( labelImplicationsPair . first ) . end ( ) ,  std : : inserter ( actualImplications ,  actualImplications . begin ( ) ) ) ;  
				 
				 
				                    std : : set_intersection ( labelImplicationsPair . second . begin ( ) ,  labelImplicationsPair . second . end ( ) ,  precedingLabels . at ( labelImplicationsPair . first ) . begin ( ) ,  precedingLabels . at ( labelImplicationsPair . first ) . end ( ) ,  std : : inserter ( actualImplications ,  actualImplications . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  label  :  actualImplications )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    / /  We  should  assert  the  implications  if  they  are  not  already  known  to  be  true  anyway .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    std : : set < uint_fast64_t >  knownImplications ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    std : : set_intersection ( actualImplications . begin ( ) ,  actualImplications . end ( ) ,  relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ,  std : : inserter ( knownImplications ,  knownImplications . begin ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    if  ( knownImplications . empty ( ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        for  ( auto  label  :  actualImplications )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                            formulae . push_back ( variableInformation . labelVariables . at ( variableInformation . labelToIndexMap . at ( label ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        }  
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    assertDisjunction ( context ,  solver ,  formulae ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    formulae . clear ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        assertDisjunction ( context ,  solver ,  formulae ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        formulae . clear ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
	
		
			
				
					
						
							 
						 
					
					
						
							 
						 
					
					
				 
				@ -742,17 +771,25 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				             *  @ param  variableInformation  A  structure  with  information  about  the  variables  for  the  labels .  
				 
				 
				             *  @ param  variableInformation  A  structure  with  information  about  the  variables  for  the  labels .  
			
		 
		
	
		
			
				 
				 
				             *  @ return  The  smallest  set  of  labels  such  that  the  constraint  system  of  the  solver  is  still  satisfiable .  
				 
				 
				             *  @ return  The  smallest  set  of  labels  such  that  the  constraint  system  of  the  solver  is  still  satisfiable .  
			
		 
		
	
		
			
				 
				 
				             */  
				 
				 
				             */  
			
		 
		
	
		
			
				 
				 
				            static  std : : set < uint_fast64_t >  findSmallestCommandSet ( z3 : : context &  context ,  z3 : : solver &  solver ,  VariableInformation &  variableInformation ,  std : : vector < z3 : : expr > &  softConstraints ,  uint_fast64_t &  nextFreeVariableIndex )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  Copy  the  original  auxiliary  variables  and  soft  constraints  so  the  procedure  can  modify  the  copies .  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  std : : vector < z3 : : expr >  auxiliaryVariables ( variableInformation . auxiliaryVariables ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  std : : vector < z3 : : expr >  tmpSoftConstraints ( softConstraints ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                / /  solver . push ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                for  ( uint_fast64_t  i  =  0 ;  ;  + + i )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    if  ( fuMalikMaxsatStep ( context ,  solver ,  variableInformation . auxiliaryVariables ,  softConstraints ,  nextFreeVariableIndex ) )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        break ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            static  std : : set < uint_fast64_t >  findSmallestCommandSet ( z3 : : context &  context ,  z3 : : solver &  solver ,  VariableInformation &  variableInformation ,  std : : vector < z3 : : expr > &  softConstraints ,  uint_fast64_t  knownBound ,  uint_fast64_t &  nextFreeVariableIndex ,  bool  useFuMalik  =  false )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( useFuMalik )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    while  ( ! fuMalikMaxsatStep ( context ,  solver ,  variableInformation . auxiliaryVariables ,  softConstraints ,  nextFreeVariableIndex ) )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                        / /  Intentionally  left  empty .  
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     for  ( uint_fast64_t  currentBound  =  knownBound ;  currentBound  >  0 ;  + + currentBound )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         solver . push ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         assertAtMostK ( context ,  solver ,  variableInformation . adderVariables ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                          
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         if  ( solver . check ( )  = =  z3 : : unsat )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             / /  If  the  system  has  become  unsat ,  we  need  to  retract  the  last  constraint .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             solver . pop ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         }  else  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             / /  If  the  system  is  still  satisfiable  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                             z3 : : model  model  =  solver . get_model ( ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                         }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				/ /                     }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    throw  storm : : exceptions : : InvalidStateException ( )  < <  " Error! " ;  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Now  we  are  ready  to  construct  the  label  set  from  the  model  of  the  solver .  
				 
				 
				                / /  Now  we  are  ready  to  construct  the  label  set  from  the  model  of  the  solver .  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -774,14 +811,24 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				                    }  
			
		 
		
	
		
			
				 
				 
				                }  
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                                 
				 
				 
				                                 
			
		 
		
	
		
			
				 
				 
				                / /  solver . pop ( ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                return  result ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            static  std : : vector < z3 : : expr >  assertAdder ( z3 : : context &  context ,  z3 : : solver &  solver ,  VariableInformation  const &  variableInformation )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : vector < z3 : : expr >  result ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : vector < z3 : : expr >  adderVariables  =  createCounterCircuit ( context ,  variableInformation . originalAuxiliaryVariables ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                for  ( uint_fast64_t  i  =  0 ;  i  <  adderVariables . size ( ) ;  + + i )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    result . push_back ( context . bool_const ( " " ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    solver . add ( implies ( adderVariables [ i ] ,  result . back ( ) ) ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                return  result ;  
				 
				 
				                return  result ;  
			
		 
		
	
		
			
				 
				 
				            }  
				 
				 
				            }  
			
		 
		
	
		
			
				 
				 
				# endif  
				 
				 
				# endif  
			
		 
		
	
		
			
				 
				 
				             
				 
				 
				             
			
		 
		
	
		
			
				 
				 
				        public :  
				 
				 
				        public :  
			
		 
		
	
		
			
				 
				 
				            static  std : : set < uint_fast64_t >  getMinimalCommandSet ( storm : : ir : : Program  program ,  std : : string  const &  constantDefinitionString ,  storm : : models : : Mdp < T >  const &  labeledMdp ,  storm : : storage : : BitVector  const &  phiStates ,  storm : : storage : : BitVector  const &  psiStates ,  double  probabilityThreshold ,  bool  checkThresholdFeasible  =  false )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				            static  std : : set < uint_fast64_t >  getMinimalCommandSet ( storm : : ir : : Program  program ,  std : : string  const &  constantDefinitionString ,  storm : : models : : Mdp < T >  const &  labeledMdp ,  storm : : storage : : BitVector  const &  phiStates ,  storm : : storage : : BitVector  const &  psiStates ,  double  probabilityThreshold ,  bool  checkThresholdFeasible  =  false ,  bool  useFuMalik  =  true )  {  
			
		 
		
	
		
			
				 
				 
				# ifdef STORM_HAVE_Z3  
				 
				 
				# ifdef STORM_HAVE_Z3  
			
		 
		
	
		
			
				 
				 
				                storm : : utility : : ir : : defineUndefinedConstants ( program ,  constantDefinitionString ) ;  
				 
				 
				                storm : : utility : : ir : : defineUndefinedConstants ( program ,  constantDefinitionString ) ;  
			
		 
		
	
		
			
				 
				 
				
 
				 
				 
				
 
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -807,6 +854,11 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                / /  ( 5 )  Build  the  initial  constraint  system .  
				 
				 
				                / /  ( 5 )  Build  the  initial  constraint  system .  
			
		 
		
	
		
			
				 
				 
				                assertInitialConstraints ( program ,  labeledMdp ,  psiStates ,  context ,  solver ,  variableInformation ,  relevancyInformation ) ;  
				 
				 
				                assertInitialConstraints ( program ,  labeledMdp ,  psiStates ,  context ,  solver ,  variableInformation ,  relevancyInformation ) ;  
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                / /  ( 6 )  If  we  are  supposed  to  use  the  counter - circuit  method ,  we  need  to  assert  the  adder  circuit .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                if  ( ! useFuMalik )  {  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    variableInformation . adderVariables  =  assertAdder ( context ,  solver ,  variableInformation ) ;  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                }  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  ( 6 )  Add  constraints  that  cut  off  a  lot  of  suboptimal  solutions .  
				 
				 
				                / /  ( 6 )  Add  constraints  that  cut  off  a  lot  of  suboptimal  solutions .  
			
		 
		
	
		
			
				 
				 
				                assertExplicitCuts ( labeledMdp ,  psiStates ,  variableInformation ,  relevancyInformation ,  context ,  solver ) ;  
				 
				 
				                assertExplicitCuts ( labeledMdp ,  psiStates ,  variableInformation ,  relevancyInformation ,  context ,  solver ) ;  
			
		 
		
	
		
			
				 
				 
				                assertSymbolicCuts ( program ,  labeledMdp ,  variableInformation ,  relevancyInformation ,  context ,  solver ) ;  
				 
				 
				                assertSymbolicCuts ( program ,  labeledMdp ,  variableInformation ,  relevancyInformation ,  context ,  solver ) ;  
			
		 
		
	
	
		
			
				
					
					
					
						
							 
						 
					
				 
				@ -828,21 +880,17 @@ namespace storm { 
			
		 
		
	
		
			
				 
				 
				                 
				 
				 
				                 
			
		 
		
	
		
			
				 
				 
				                / /  Keep  track  of  the  command  set  we  used  to  achieve  the  current  probability  as  well  as  the  probability  
				 
				 
				                / /  Keep  track  of  the  command  set  we  used  to  achieve  the  current  probability  as  well  as  the  probability  
			
		 
		
	
		
			
				 
				 
				                / /  itself .  
				 
				 
				                / /  itself .  
			
		 
		
	
		
			
				 
				 
				                std : : set < uint_fast64_t >  commandSet ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                std : : set < uint_fast64_t >  commandSet ( relevancyInformation . relevantLabels ) ;  
			
		 
		
	
		
			
				 
				 
				                double  maximalReachabilityProbability  =  0 ;  
				 
				 
				                double  maximalReachabilityProbability  =  0 ;  
			
		 
		
	
		
			
				 
				 
				                bool  done  =  false ;  
				 
				 
				                bool  done  =  false ;  
			
		 
		
	
		
			
				 
				 
				                uint_fast64_t  iterations  =  0 ;  
				 
				 
				                uint_fast64_t  iterations  =  0 ;  
			
		 
		
	
		
			
				 
				 
				                do  {  
				 
				 
				                do  {  
			
		 
		
	
		
			
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Computing minimal command set. " ) ;  
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Computing minimal command set. " ) ;  
			
		 
		
	
		
			
				 
				 
				                    commandSet  =  findSmallestCommandSet ( context ,  solver ,  variableInformation ,  softConstraints ,  nextFreeVariableIndex ) ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    commandSet  =  findSmallestCommandSet ( context ,  solver ,  variableInformation ,  softConstraints ,  commandSet . size ( ) ,  nextFreeVariableIndex ,  useFuMalik ) ;  
			
		 
		
	
		
			
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Computed minimal command set of size  "  < <  commandSet . size ( )  < <  " . " ) ;  
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Computed minimal command set of size  "  < <  commandSet . size ( )  < <  " . " ) ;  
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  " solution:  "  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    for  ( auto  label  :  commandSet )  {  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                        std : : cout  < <  label  < <  " ,  " ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    }  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                    std : : cout  < <  std : : endl ;  
				 
				 
				 
			
		 
		
	
		
			
				 
				 
				                     
				 
				 
				                     
			
		 
		
	
		
			
				 
				 
				                    / /  Restrict  the  given  MDP  to  the  current  set  of  labels  and  compute  the  reachability  probability .  
				 
				 
				                    / /  Restrict  the  given  MDP  to  the  current  set  of  labels  and  compute  the  reachability  probability .  
			
		 
		
	
		
			
				 
				 
				 
				 
				 
				                    commandSet . insert ( relevancyInformation . knownLabels . begin ( ) ,  relevancyInformation . knownLabels . end ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                    storm : : models : : Mdp < T >  subMdp  =  labeledMdp . restrictChoiceLabels ( commandSet ) ;  
				 
				 
				                    storm : : models : : Mdp < T >  subMdp  =  labeledMdp . restrictChoiceLabels ( commandSet ) ;  
			
		 
		
	
		
			
				 
				 
				                    storm : : modelchecker : : prctl : : SparseMdpPrctlModelChecker < T >  modelchecker ( subMdp ,  new  storm : : solver : : GmmxxNondeterministicLinearEquationSolver < T > ( ) ) ;  
				 
				 
				                    storm : : modelchecker : : prctl : : SparseMdpPrctlModelChecker < T >  modelchecker ( subMdp ,  new  storm : : solver : : GmmxxNondeterministicLinearEquationSolver < T > ( ) ) ;  
			
		 
		
	
		
			
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Invoking model checker. " ) ;  
				 
				 
				                    LOG4CPLUS_DEBUG ( logger ,  " Invoking model checker. " ) ;