STORM_LOG_ASSERT(isPivotState||!otherStrategyPair.getPlayer2Strategy().hasDefinedChoice(player2Successor)||strategyPair.getPlayer2Strategy().getChoice(player2Successor)==player2Choice,"Did not expect deviation in player 2 strategy.");
STORM_LOG_ASSERT(player2Grouping[player2Successor]<=player2Choice&&player2Choice<player2Grouping[player2Successor+1],"Illegal choice for player 2.");
STORM_LOG_ASSERT(!maxStrategyPair.getPlayer2Strategy().hasDefinedChoice(minPlayer2Successor)||minStrategyPair.getPlayer2Strategy().getChoice(minPlayer2Successor)==minPlayer2Choice,"Did not expect deviation in player 2 strategy.");
STORM_LOG_ASSERT(player2Grouping[minPlayer2Successor]<=minPlayer2Choice&&minPlayer2Choice<player2Grouping[minPlayer2Successor+1],"Illegal choice for player 2.");
STORM_LOG_ASSERT(!minStrategyPair.getPlayer2Strategy().hasDefinedChoice(maxPlayer2Successor)||minStrategyPair.getPlayer2Strategy().getChoice(maxPlayer2Successor)==maxPlayer2Choice,"Did not expect deviation in player 2 strategy.");
STORM_LOG_ASSERT(player2Grouping[maxPlayer2Successor]<=maxPlayer2Choice&&maxPlayer2Choice<player2Grouping[maxPlayer2Successor+1],"Illegal choice for player 2.");
STORM_LOG_WARN_COND(!model.hasUndefinedConstants(),"Model contains undefined constants. Game-based abstraction can treat such models, but you should make sure that you did not simply forget to define these constants. In particular, it may be necessary to constrain the values of the undefined constants.");
@ -529,6 +529,8 @@ namespace storm {
// Optimization: do not compute both bounds if not necessary (e.g. if bound given and exceeded, etc.)
STORM_LOG_INFO("Abstraction in iteration "<<iteration<<" has "<<game.getNumberOfStates()<<" player 1 states ("<<game.getInitialStates().getNonZeroCount()<<" initial), "<<game.getNumberOfPlayer2States()<<" player 2 states, "<<game.getNumberOfTransitions()<<" transitions, "<<game.getBottomStates().getNonZeroCount()<<" bottom states, "<<abstractor->getNumberOfPredicates()<<" predicate(s), "<<game.getTransitionMatrix().getNodeCount()<<" nodes (transition matrix) (computed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd-abstractionStart).count()<<"ms).");
abstractionWatch.stop();
totalAbstractionWatch.add(abstractionWatch);
STORM_LOG_INFO("Abstraction in iteration "<<iteration<<" has "<<game.getNumberOfStates()<<" player 1 states ("<<game.getInitialStates().getNonZeroCount()<<" initial), "<<game.getNumberOfPlayer2States()<<" player 2 states, "<<game.getNumberOfTransitions()<<" transitions, "<<game.getBottomStates().getNonZeroCount()<<" bottom states, "<<abstractor->getNumberOfPredicates()<<" predicate(s), "<<game.getTransitionMatrix().getNodeCount()<<" nodes (transition matrix) (computed in "<<abstractionWatch.getTimeInMilliseconds()<<"ms).");
// (2) Prepare initial, constraint and target state BDDs for later use.
STORM_LOG_INFO("Qualitative computation completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(qualitativeEnd-qualitativeStart).count()<<"ms.");
qualitativeWatch.stop();
totalSolutionWatch.add(qualitativeWatch);
STORM_LOG_INFO("Qualitative computation completed in "<<qualitativeWatch.getTimeInMilliseconds()<<"ms.");
// (2) compute the states for which we have to determine quantitative information.
STORM_LOG_INFO("Qualitative refinement completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(qualitativeRefinementEnd-qualitativeRefinementStart).count()<<"ms.");
refinementWatch.stop();
totalRefinementWatch.add(refinementWatch);
STORM_LOG_INFO("Qualitative refinement completed in "<<refinementWatch.getTimeInMilliseconds()<<"ms.");
}
// (4) if we arrived at this point and no refinement was made, we need to compute the quantitative solution.
STORM_LOG_INFO("Obtained quantitative bounds ["<<quantitativeResult.min.getInitialStatesRange().first<<", "<<quantitativeResult.max.getInitialStatesRange().second<<"] on the actual value for the initial states in "<<std::chrono::duration_cast<std::chrono::milliseconds>(quantitativeEnd-quantitativeStart).count()<<"ms.");
totalSolutionWatch.add(quantitativeWatch);
STORM_LOG_INFO("Obtained quantitative bounds ["<<quantitativeResult.min.getInitialStatesRange().first<<", "<<quantitativeResult.max.getInitialStatesRange().second<<"] on the actual value for the initial states in "<<quantitativeWatch.getTimeInMilliseconds()<<"ms.");
// (9) Check whether the lower and upper bounds are close enough to terminate with an answer.
STORM_LOG_ASSERT(quantitativeResult.min.getPlayer2Strategy().isZero()||quantitativeResult.min.getPlayer2Strategy().templatetoAdd<ValueType>().sumAbstract(game.getPlayer2Variables()).getMax()<=1,"Player 2 strategy for min is illegal.");
STORM_LOG_ASSERT(quantitativeResult.max.getPlayer2Strategy().isZero()||quantitativeResult.max.getPlayer2Strategy().templatetoAdd<ValueType>().sumAbstract(game.getPlayer2Variables()).getMax()<=1,"Player 2 strategy for max is illegal.");
STORM_LOG_INFO("Quantitative refinement completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(quantitativeRefinementEnd-quantitativeRefinementStart).count()<<"ms.");
refinementWatch.stop();
totalRefinementWatch.add(refinementWatch);
STORM_LOG_INFO("Quantitative refinement completed in "<<refinementWatch.getTimeInMilliseconds()<<"ms.");
}
// Return null to indicate no result has been found yet.
STORM_LOG_ASSERT(targetStates.get(state)||minStrategyPair.getPlayer1Strategy().hasDefinedChoice(state),"Expected lower player 1 choice in state "<<state<<".");
STORM_LOG_ASSERT(targetStates.get(state)||maxStrategyPair.getPlayer1Strategy().hasDefinedChoice(state),"Expected upper player 1 choice in state "<<state<<".");
STORM_LOG_ASSERT(minStrategyPair.getPlayer2Strategy().hasDefinedChoice(lowerPlayer1Choice),"Expected lower player 2 choice for state "<<state<<" (upper player 1 choice "<<lowerPlayer1Choice<<").");
STORM_LOG_ASSERT(maxStrategyPair.getPlayer2Strategy().hasDefinedChoice(upperPlayer1Choice),"Expected upper player 2 choice for state "<<state<<" (upper player 1 choice "<<upperPlayer1Choice<<").");
STORM_LOG_INFO("Translation to explicit representation completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(translationEnd-translationStart).count()<<"ms.");
translationWatch.stop();
totalTranslationWatch.add(translationWatch);
STORM_LOG_INFO("Translation to explicit representation completed in "<<translationWatch.getTimeInMilliseconds()<<"ms.");
STORM_LOG_INFO("Qualitative computation completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(qualitativeEnd-qualitativeStart).count()<<"ms.");
// (2) compute the states for which we have to determine quantitative information.
STORM_LOG_INFO("Qualitative refinement completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(qualitativeRefinementEnd-qualitativeRefinementStart).count()<<"ms.");
refinementWatch.stop();
totalRefinementWatch.add(refinementWatch);
STORM_LOG_INFO("Qualitative refinement completed in "<<refinementWatch.getTimeInMilliseconds()<<"ms.");
STORM_LOG_INFO("Obtained quantitative bounds ["<<quantitativeResult.getMin().getRange(initialStates).first<<", "<<quantitativeResult.getMax().getRange(initialStates).second<<"] on the actual value for the initial states in "<<std::chrono::duration_cast<std::chrono::milliseconds>(quantitativeEnd-quantitativeStart).count()<<"ms.");
STORM_LOG_INFO("Obtained quantitative bounds ["<<quantitativeResult.getMin().getRange(initialStates).first<<", "<<quantitativeResult.getMax().getRange(initialStates).second<<"] on the actual value for the initial states in "<<quantitativeWatch.getTimeInMilliseconds()<<"ms.");
// (9) Check whether the lower and upper bounds are close enough to terminate with an answer.
std::cout<<"state "<<state<<" has values ["<<quantitativeResult.getMin().getValues()[state]<<", "<<quantitativeResult.getMax().getValues()[state]<<"]"<<std::endl;
STORM_LOG_ASSERT(targetStates.get(state)||minStrategyPair.getPlayer1Strategy().hasDefinedChoice(state),"Expected lower player 1 choice in state "<<state<<".");
STORM_LOG_ASSERT(targetStates.get(state)||maxStrategyPair.getPlayer1Strategy().hasDefinedChoice(state),"Expected upper player 1 choice in state "<<state<<".");
STORM_LOG_ASSERT(minStrategyPair.getPlayer2Strategy().hasDefinedChoice(lowerPlayer1Choice),"Expected lower player 2 choice for state "<<state<<" (upper player 1 choice "<<lowerPlayer1Choice<<").");
STORM_LOG_ASSERT(maxStrategyPair.getPlayer2Strategy().hasDefinedChoice(upperPlayer1Choice),"Expected upper player 2 choice for state "<<state<<" (upper player 1 choice "<<upperPlayer1Choice<<").");
std::cout<<"state "<<state<<": "<<sanityValues[state]<<" vs "<<quantitativeResult.getMin().getValues()[state]<<std::endl;
std::cout<<"[min] state is prob0? "<<qualitativeResult.getProb0Min().getStates().get(state)<<", prob1? "<<qualitativeResult.getProb1Min().getStates().get(state)<<std::endl;
STORM_LOG_ASSERT(std::abs(sanityValues[state]-quantitativeResult.getMin().getValues()[state])<1e-6,"Got weird min divergences!");
}
///////// SANITY CHECK: apply upper strategy, obtain DTMC matrix and model check it. the values should
std::cout<<"state "<<state<<": "<<sanityValues[state]<<" vs "<<quantitativeResult.getMax().getValues()[state]<<std::endl;
std::cout<<"[max] state is prob0? "<<qualitativeResult.getProb0Max().getStates().get(state)<<", prob1? "<<qualitativeResult.getProb1Max().getStates().get(state)<<std::endl;
STORM_LOG_ASSERT(std::abs(sanityValues[state]-quantitativeResult.getMax().getValues()[state])<1e-6,"Got weird max divergences!");
// Make sure that all strategies are still valid strategies.
STORM_LOG_ASSERT(minStrategyPair.getNumberOfUndefinedPlayer1States()<=targetStates.getNumberOfSetBits(),"Expected at most "<<targetStates.getNumberOfSetBits()<<" (number of target states) player 1 states with undefined choice but got "<<minStrategyPair.getNumberOfUndefinedPlayer1States()<<".");
STORM_LOG_ASSERT(maxStrategyPair.getNumberOfUndefinedPlayer1States()<=targetStates.getNumberOfSetBits(),"Expected at most "<<targetStates.getNumberOfSetBits()<<" (number of target states) player 1 states with undefined choice but got "<<maxStrategyPair.getNumberOfUndefinedPlayer1States()<<".");
STORM_LOG_INFO("Quantitative refinement completed in "<<std::chrono::duration_cast<std::chrono::milliseconds>(quantitativeRefinementEnd-quantitativeRefinementStart).count()<<"ms.");
refinementWatch.stop();
totalRefinementWatch.add(refinementWatch);
STORM_LOG_INFO("Quantitative refinement completed in "<<refinementWatch.getTimeInMilliseconds()<<"ms.");