35template<
typename ModelType>
37 :
storm::
modelchecker::AbstractModelChecker<ModelType>(), checkTask(nullptr), precision(options.precision) {
42template<
typename ModelType>
47template<
typename ModelType>
53 return formula.
isInFragment(fragment) && checkTask.isOnlyInitialStatesRelevantSet();
56template<
typename ModelType>
61template<
typename ModelType>
64 this->
setCheckTask(checkTask.template substituteFormula<storm::logic::Formula>(checkTask.getFormula()));
68template<
typename ModelType>
72 "Reachability rewards are not supported by this abstraction-refinement model checker.");
73 this->
setCheckTask(checkTask.template substituteFormula<storm::logic::Formula>(checkTask.getFormula()));
77template<
typename ModelType>
80 this->
setCheckTask(checkTask.template substituteFormula<storm::logic::Formula>(checkTask.getFormula()));
84template<
typename ModelType>
86 this->checkTask = std::make_unique<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>>(checkTask);
89template<
typename ModelType>
95template<
typename ModelType>
97 return reuseQualitativeResults;
100template<
typename ModelType>
102 return reuseQuantitativeResults;
105template<
typename ModelType>
107 STORM_LOG_THROW(checkTask->isOnlyInitialStatesRelevantSet(), storm::exceptions::InvalidPropertyException,
108 "The abstraction-refinement model checkers can only compute the result for the initial states.");
113 uint64_t iterations = 0;
114 std::unique_ptr<storm::modelchecker::CheckResult> result;
115 auto start = std::chrono::high_resolution_clock::now();
120 auto abstractionStart = std::chrono::high_resolution_clock::now();
121 std::shared_ptr<storm::models::Model<ValueType>> abstractModel = this->
getAbstractModel();
122 auto abstractionEnd = std::chrono::high_resolution_clock::now();
123 STORM_LOG_TRACE(
"Model in iteration " << iterations <<
" has " << abstractModel->getNumberOfStates() <<
" states and "
124 << abstractModel->getNumberOfTransitions() <<
" transitions (retrieved in "
125 << std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd - abstractionStart).count() <<
"ms).");
128 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>> bounds =
132 if (bounds.first || bounds.second) {
136 if (bounds.first && bounds.second) {
140 auto refinementStart = std::chrono::high_resolution_clock::now();
142 auto refinementEnd = std::chrono::high_resolution_clock::now();
143 STORM_LOG_TRACE(
"Refinement in iteration " << iterations <<
" completed in "
144 << std::chrono::duration_cast<std::chrono::milliseconds>(refinementEnd - refinementStart).count()
148 auto end = std::chrono::high_resolution_clock::now();
150 << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
"ms.");
155template<
typename ModelType>
156std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
160 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>> result;
163 std::pair<std::unique_ptr<storm::gbar::abstraction::StateSet>, std::unique_ptr<storm::gbar::abstraction::StateSet>> constraintAndTargetStates =
167 lastQualitativeResults =
computeQualitativeResult(env, abstractModel, *constraintAndTargetStates.first, *constraintAndTargetStates.second);
178 STORM_LOG_TRACE(
"" << (doSkipQuantitativeSolution ?
"Skipping" :
"Not skipping") <<
" quantitative solution.");
181 if (!doSkipQuantitativeSolution) {
183 computeQuantitativeResult(env, abstractModel, *constraintAndTargetStates.first, *constraintAndTargetStates.second, *lastQualitativeResults);
184 STORM_LOG_ASSERT(lastBounds.first && lastBounds.second,
"Expected both bounds.");
186 result = std::make_pair(lastBounds.first->clone(), lastBounds.second->clone());
191 result.second =
nullptr;
193 result.first =
nullptr;
200template<
typename ModelType>
204 if (checkTask->isBoundSet()) {
206 ValueType threshold = checkTask->getBoundThreshold();
240template<
typename ModelType>
242 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>& bounds) {
243 STORM_LOG_THROW(bounds.first->isSymbolicQuantitativeCheckResult() && bounds.second->isSymbolicQuantitativeCheckResult(),
244 storm::exceptions::NotSupportedException,
"Expected symbolic bounds.");
247 bounds.second->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>());
250template<
typename ModelType>
261 std::pair<ValueType, ValueType> bounds;
262 bounds.first = (lowerBounds.
getValueVector() * maxDiffRepresentative.template toAdd<ValueType>()).getMax();
263 bounds.second = (upperBounds.
getValueVector() * maxDiffRepresentative.template toAdd<ValueType>()).getMax();
265 STORM_LOG_TRACE(
"Largest interval over initial is [" << bounds.first <<
", " << bounds.second <<
"], difference " << (bounds.second - bounds.first)
270template<
typename ModelType>
273 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>& bounds) {
279template<
typename ModelType>
282 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>& bounds) {
284 bounds.first->filter(initialStateFilter);
285 bounds.second->filter(initialStateFilter);
288template<
typename ModelType>
297template<
typename ModelType>
301 bool isRewardFormula =
303 if (isRewardFormula) {
320template<
typename ModelType>
321std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
333template<
typename ModelType>
334std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
341 storm::exceptions::NotSupportedException,
"Abstract model type is not supported.");
351 constraintStates, targetStates, qualitativeResults);
355template<
typename ModelType>
356std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
361 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>> result;
364 bool isRewardFormula =
366 if (isRewardFormula) {
374 startValues = maybe.
ite(lastBounds.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
375 abstractModel.
getManager().template getAddZero<ValueType>());
377 startValues = abstractModel.
getManager().template getAddZero<ValueType>();
380 if (isRewardFormula) {
386 result.first = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.
getReachableStates(), values);
387 result.second = result.first->clone();
392 result.first = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.
getReachableStates(), values);
393 result.second = result.first->clone();
399template<
typename ModelType>
400std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
405 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>> result;
409 bool isRewardFormula =
411 if (isRewardFormula) {
421 minStartValues = maybeMin.
ite(lastBounds.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
422 abstractModel.
getManager().template getAddZero<ValueType>());
424 minStartValues = abstractModel.
getManager().template getAddZero<ValueType>();
428 if (isRewardFormula) {
430 env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel,
435 if (abstractionPlayer == 0) {
436 result.second = result.first->clone();
442 maybeMax.
ite(result.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
443 abstractModel.
getManager().template getAddZero<ValueType>()));
447 env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel,
450 if (abstractionPlayer == 0) {
451 result.second = result.first->clone();
454 env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.
getTransitionMatrix(), maybeMax,
456 maybeMax.
ite(result.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
457 abstractModel.
getManager().template getAddZero<ValueType>()));
464template<
typename ModelType>
465std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
470 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>> result;
474 bool isRewardFormula =
476 if (!isRewardFormula) {
483 minStartValues = maybeMin.
ite(lastBounds.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
484 abstractModel.
getManager().template getAddZero<ValueType>());
486 minStartValues = abstractModel.
getManager().template getAddZero<ValueType>();
489 if (isRewardFormula) {
490 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Reward properties are not supported for abstract stochastic games.");
493 env, abstractModel, this->
getAbstractionPlayer() == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(),
494 this->getAbstractionPlayer() == 2 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), maybeMin,
495 qualitativeResults.
getProb1Min().getStates(), minStartValues);
497 env, abstractModel, this->
getAbstractionPlayer() == 1 ? storm::OptimizationDirection::Maximize : checkTask->getOptimizationDirection(),
498 this->getAbstractionPlayer() == 2 ? storm::OptimizationDirection::Maximize : checkTask->getOptimizationDirection(), maybeMin,
500 maybeMax.
ite(result.first->asSymbolicQuantitativeCheckResult<
DdType,
ValueType>().getValueVector(),
501 abstractModel.
getManager().template getAddZero<ValueType>()));
507template<
typename ModelType>
512 STORM_LOG_TRACE(
"Performing quantative solution step. Player 1: " << player1Direction <<
", player 2: " << player2Direction <<
".");
530 std::unique_ptr<storm::solver::SymbolicGameSolver<DdType, ValueType>>
solver =
534 auto values =
solver->solveGame(env, player1Direction, player2Direction, startVector, subvector);
536 return std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.
getReachableStates(),
537 prob1States.template toAdd<ValueType>() + values);
540template<
typename ModelType>
550template<
typename ModelType>
556 storm::exceptions::NotSupportedException,
"Expected discrete-time abstract model.");
564 constraintStates, targetStates);
568template<
typename ModelType>
573 std::unique_ptr<storm::gbar::abstraction::SymbolicQualitativeMdpResultMinMax<DdType>> result =
574 std::make_unique<storm::gbar::abstraction::SymbolicQualitativeMdpResultMinMax<DdType>>();
576 auto start = std::chrono::high_resolution_clock::now();
577 bool isRewardFormula =
580 if (isRewardFormula) {
588 auto end = std::chrono::high_resolution_clock::now();
590 auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
591 STORM_LOG_DEBUG(
"Computed qualitative solution in " << timeInMilliseconds <<
"ms.");
596template<
typename ModelType>
601 std::unique_ptr<storm::gbar::abstraction::SymbolicQualitativeMdpResultMinMax<DdType>> result =
602 std::make_unique<storm::gbar::abstraction::SymbolicQualitativeMdpResultMinMax<DdType>>();
604 auto start = std::chrono::high_resolution_clock::now();
605 bool isRewardFormula =
610 if (isRewardFormula) {
611 bool computedMin =
false;
612 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Minimize) {
614 abstractModel, transitionMatrixBdd, constraintStates.
getStates(), targetStates.
getStates(),
615 lastQualitativeResults ? lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Min().getStates()
622 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Maximize) {
624 abstractModel, transitionMatrixBdd, targetStates.
getStates(),
628 result->prob1Min = result->prob1Max;
631 result->prob1Max = result->prob1Min;
635 bool computedMax =
false;
636 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Maximize) {
640 abstractModel, transitionMatrixBdd, constraintStates.
getStates(), targetStates.
getStates(),
641 lastQualitativeResults ? lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Min().getStates()
648 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Minimize) {
650 abstractModel, transitionMatrixBdd,
651 lastQualitativeResults ? lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Min().getStates()
660 result->prob0Max = result->prob0Min;
661 result->prob1Max = result->prob1Min;
664 result->prob0Min = result->prob0Max;
665 result->prob1Min = result->prob1Max;
669 if (isRewardFormula) {
670 bool computedMin =
false;
671 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Minimize) {
673 abstractModel, transitionMatrixBdd, constraintStates.
getStates(), targetStates.
getStates(),
679 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Maximize) {
681 abstractModel, transitionMatrixBdd, targetStates.
getStates(),
685 result->prob1Min = result->prob1Max;
688 result->prob1Max = result->prob1Min;
691 bool computedMin =
false;
692 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Minimize) {
700 if (abstractionPlayer == 1 || checkTask->getOptimizationDirection() == storm::OptimizationDirection::Maximize) {
706 result->prob0Min = result->prob0Max;
707 result->prob1Min = result->prob1Max;
710 result->prob0Max = result->prob0Min;
711 result->prob1Max = result->prob1Min;
715 auto end = std::chrono::high_resolution_clock::now();
717 auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
718 if (isRewardFormula) {
719 STORM_LOG_TRACE(
"Min: " << result->getProb1Min().getStates().getNonZeroCount() <<
" states with probability 1.");
720 STORM_LOG_TRACE(
"Max: " << result->getProb1Max().getStates().getNonZeroCount() <<
" states with probability 1.");
722 STORM_LOG_TRACE(
"Min: " << result->getProb0Min().getStates().getNonZeroCount() <<
" states with probability 0, "
723 << result->getProb1Min().getStates().getNonZeroCount() <<
" states with probability 1.");
724 STORM_LOG_TRACE(
"Max: " << result->getProb0Max().getStates().getNonZeroCount() <<
" states with probability 0, "
725 << result->getProb1Max().getStates().getNonZeroCount() <<
" states with probability 1.");
727 STORM_LOG_DEBUG(
"Computed qualitative solution in " << timeInMilliseconds <<
"ms.");
732template<
typename ModelType>
737 std::unique_ptr<storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax<DdType>> result;
751 auto start = std::chrono::high_resolution_clock::now();
754 modelNondeterminismDirection, requiresSchedulers);
756 result = std::make_unique<storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax<DdType>>();
759 abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
760 abstractionPlayer == 2 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
761 requiresSchedulers, requiresSchedulers);
763 abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
764 abstractionPlayer == 2 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
765 requiresSchedulers, requiresSchedulers);
767 abstractionPlayer == 1 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
768 abstractionPlayer == 2 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
769 requiresSchedulers, requiresSchedulers);
771 abstractionPlayer == 1 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
772 abstractionPlayer == 2 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
773 requiresSchedulers, requiresSchedulers);
777 if (abstractionPlayer == 1) {
778 STORM_LOG_TRACE(
"[" << storm::OptimizationDirection::Minimize <<
", " << modelNondeterminismDirection <<
"]: "
779 << result->prob0Min.player1States.getNonZeroCount() <<
" 'no', " << result->prob1Min.player1States.getNonZeroCount() <<
" 'yes'.");
780 STORM_LOG_TRACE(
"[" << storm::OptimizationDirection::Maximize <<
", " << modelNondeterminismDirection <<
"]: "
781 << result->prob0Max.player1States.getNonZeroCount() <<
" 'no', " << result->prob1Max.player1States.getNonZeroCount() <<
" 'yes'.");
783 STORM_LOG_TRACE(
"[" << modelNondeterminismDirection <<
", " << storm::OptimizationDirection::Minimize <<
"]: "
784 << result->prob0Min.player1States.getNonZeroCount() <<
" 'no', " << result->prob1Min.player1States.getNonZeroCount() <<
" 'yes'.");
785 STORM_LOG_TRACE(
"[" << modelNondeterminismDirection <<
", " << storm::OptimizationDirection::Maximize <<
"]: "
786 << result->prob0Max.player1States.getNonZeroCount() <<
" 'no', " << result->prob1Max.player1States.getNonZeroCount() <<
" 'yes'.");
789 auto end = std::chrono::high_resolution_clock::now();
791 auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
792 STORM_LOG_DEBUG(
"Computed qualitative solution in " << timeInMilliseconds <<
"ms.");
797template<
typename ModelType>
798std::unique_ptr<storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax<AbstractAbstractionRefinementModelChecker<ModelType>::DdType>>
803 std::unique_ptr<storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax<DdType>> result =
804 std::make_unique<storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax<DdType>>();
807 if (modelNondeterminismDirection == storm::OptimizationDirection::Minimize) {
810 storm::OptimizationDirection::Minimize, storm::OptimizationDirection::Minimize,
811 requiresSchedulers, requiresSchedulers);
816 abstractModel, transitionMatrixBdd,
817 lastQualitativeResults ? lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Min().getStates() : targetStates.
getStates(),
822 storm::OptimizationDirection::Minimize, storm::OptimizationDirection::Minimize,
823 requiresSchedulers, requiresSchedulers, boost::make_optional(prob1MinMinMdp));
827 abstractionPlayer == 1 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
828 abstractionPlayer == 2 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
829 requiresSchedulers, requiresSchedulers);
835 abstractModel, transitionMatrixBdd, constraintStates.
getStates(), targetStates.
getStates(),
836 abstractionPlayer == 1 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection,
837 abstractionPlayer == 2 ? storm::OptimizationDirection::Maximize : modelNondeterminismDirection, requiresSchedulers, requiresSchedulers,
838 lastQualitativeResults ? lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Max().getStates()
843 storm::OptimizationDirection::Maximize, storm::OptimizationDirection::Maximize,
844 requiresSchedulers, requiresSchedulers);
849 candidates &= lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>().getProb1Max().getStates();
856 storm::OptimizationDirection::Maximize, storm::OptimizationDirection::Maximize,
857 requiresSchedulers, requiresSchedulers, boost::make_optional(prob1MaxMaxMdp));
861 abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
862 abstractionPlayer == 2 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
863 requiresSchedulers, requiresSchedulers);
867 abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
868 abstractionPlayer == 2 ? storm::OptimizationDirection::Minimize : modelNondeterminismDirection,
869 requiresSchedulers, requiresSchedulers, boost::make_optional(prob1MaxMaxMdp));
875template<
typename ModelType>
883template<
typename ModelType>
886 std::unique_ptr<storm::modelchecker::CheckResult> result;
888 auto const& symbolicQualitativeResultMinMax = lastQualitativeResults->asSymbolicQualitativeResultMinMax<
DdType>();
890 bool isRewardFormula =
892 if (isRewardFormula) {
896 result = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
899 abstractModel.
getManager().template getAddZero<ValueType>()));
908 result = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
911 result = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
915 result = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
917 (abstractModel.
getInitialStates() && symbolicQualitativeResultMinMax.getProb0Min().getStates())
918 .
ite(abstractModel.
getManager().template getConstant<ValueType>(0.5), abstractModel.
getManager().template getAddZero<ValueType>()));
921 result = std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
923 (abstractModel.
getInitialStates() && symbolicQualitativeResultMinMax.getProb1Max().getStates())
924 .
ite(abstractModel.
getManager().template getConstant<ValueType>(0.5), abstractModel.
getManager().template getAddZero<ValueType>()) +
925 symbolicQualitativeResultMinMax.getProb1Max().getStates().template toAdd<ValueType>());
938template<
typename ModelType>
941 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>& bounds) {
942 std::unique_ptr<storm::modelchecker::CheckResult> result;
944 if (bounds.first ==
nullptr || bounds.second ==
nullptr) {
945 STORM_LOG_ASSERT(bounds.first || bounds.second,
"Expected at least one bound.");
948 return std::move(bounds.first);
950 return std::move(bounds.second);
966template<
typename ModelType>
968 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
const& bounds) {
969 STORM_LOG_ASSERT(bounds.first->isSymbolicQuantitativeCheckResult(),
"Expected symbolic quantitative check result.");
972 STORM_LOG_ASSERT(bounds.second->isSymbolicQuantitativeCheckResult(),
"Expected symbolic quantitative check result.");
979template<
typename ModelType>
981 std::pair<std::unique_ptr<storm::modelchecker::CheckResult>, std::unique_ptr<storm::modelchecker::CheckResult>>
const& bounds) {
982 STORM_LOG_ASSERT(bounds.first->isSymbolicQuantitativeCheckResult(),
"Expected symbolic quantitative check result.");
985 STORM_LOG_ASSERT(bounds.second->isSymbolicQuantitativeCheckResult(),
"Expected symbolic quantitative check result.");
989 return std::make_unique<storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>>(
Add< LibraryType, ValueType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the ADD.
ValueType getMax() const
Retrieves the highest function value of any encoding.
Add< LibraryType, ValueType > sumAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Sum-abstracts from the given meta variables.
Bdd< LibraryType > toBdd() const
Converts the ADD to a BDD by mapping all values unequal to zero to 1.
bool equalModuloPrecision(Add< LibraryType, ValueType > const &other, ValueType const &precision, bool relative=true) const
Checks whether the current and the given ADD represent the same function modulo some given precision.
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Bdd< LibraryType > maxAbstractRepresentative(std::set< storm::expressions::Variable > const &metaVariables) const
Similar to maxAbstract, but does not abstract from the variables but rather picks a valuation of each...
virtual uint_fast64_t getNonZeroCount() const override
Retrieves the number of encodings that are mapped to a non-zero value.
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
Bdd< LibraryType > ite(Bdd< LibraryType > const &thenBdd, Bdd< LibraryType > const &elseBdd) const
Performs an if-then-else with the given operands, i.e.
std::set< storm::expressions::Variable > const & getContainedMetaVariables() const
Retrieves the set of all meta variables contained in the DD.
DdManager< LibraryType > & getDdManager() const
Retrieves the manager that is responsible for this DD.
SymbolicQualitativeResultMinMax< Type > const & asSymbolicQualitativeResultMinMax() const
SymbolicStateSet< Type > const & asSymbolicStateSet() const
SymbolicQualitativeResult< Type > const & getProb0Min() const
SymbolicQualitativeResult< Type > const & getProb0Max() const
SymbolicQualitativeResult< Type > const & getProb1Max() const
SymbolicQualitativeResult< Type > const & getProb1Min() const
storm::dd::Bdd< Type > const & getStates() const
virtual std::shared_ptr< storm::models::Model< ValueType > > getAbstractModel()=0
Retrieves the abstract model.
std::unique_ptr< storm::gbar::abstraction::SymbolicQualitativeGameResultMinMax< DdType > > computeQualitativeResultReuse(storm::models::symbolic::StochasticTwoPlayerGame< DdType, ValueType > const &abstractModel, storm::dd::Bdd< DdType > const &transitionMatrixBdd, storm::gbar::abstraction::SymbolicStateSet< DdType > const &constraintStates, storm::gbar::abstraction::SymbolicStateSet< DdType > const &targetStates, uint64_t abstractionPlayer, storm::OptimizationDirection const &modelNondeterminismDirection, bool requiresSchedulers)
std::unique_ptr< storm::modelchecker::CheckResult > getAverageOfBounds(std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > const &bounds)
Retrieves the average of the two bounds.
virtual ~AbstractAbstractionRefinementModelChecker()
ModelType::ValueType ValueType
bool checkForResultAfterQuantitativeCheck(storm::models::Model< ValueType > const &abstractModel, bool lowerBounds, storm::modelchecker::QuantitativeCheckResult< ValueType > const &result)
std::unique_ptr< storm::modelchecker::CheckResult > performAbstractionRefinement(Environment const &env)
-----— Methods used to implement the abstraction refinement procedure.
std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > computeQuantitativeResult(Environment const &env, storm::models::Model< ValueType > const &abstractModel, storm::gbar::abstraction::StateSet const &constraintStates, storm::gbar::abstraction::StateSet const &targetStates, storm::gbar::abstraction::QualitativeResultMinMax const &qualitativeResults)
virtual void refineAbstractModel()=0
Refines the abstract model so that the next iteration obtains bounds that are at least as precise as ...
static const storm::dd::DdType DdType
storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const & getCheckTask() const
std::unique_ptr< storm::gbar::abstraction::QualitativeResultMinMax > computeQualitativeResult(Environment const &env, storm::models::Model< ValueType > const &abstractModel, storm::gbar::abstraction::StateSet const &constraintStates, storm::gbar::abstraction::StateSet const &targetStates)
Solves the current check task qualitatively, i.e. computes all states with probability 0/1.
void setCheckTask(storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &checkTask)
Methods to set/get the check task that is currently handled.
virtual bool requiresSchedulerSynthesis() const =0
Retrieves whether schedulers need to be computed.
virtual std::string const & getName() const =0
Retrieves the name of the underlying method.
void printBoundsInformation(std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > &bounds)
virtual void initializeAbstractionRefinement()=0
Called before the abstraction refinement loop to give the implementation a time to set up auxiliary d...
virtual bool supportsReachabilityRewards() const
-----— Methods that need to be overwritten/defined by implementations in subclasses.
std::unique_ptr< storm::modelchecker::CheckResult > checkForResultAfterQualitativeCheck(storm::models::Model< ValueType > const &abstractModel)
virtual std::unique_ptr< storm::modelchecker::CheckResult > computeReachabilityProbabilities(Environment const &env, storm::modelchecker::CheckTask< storm::logic::EventuallyFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< storm::modelchecker::CheckResult > computeUntilProbabilities(Environment const &env, storm::modelchecker::CheckTask< storm::logic::UntilFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< storm::modelchecker::CheckResult > computeReachabilityRewards(Environment const &env, storm::modelchecker::CheckTask< storm::logic::EventuallyFormula, ValueType > const &checkTask) override
bool skipQuantitativeSolution(storm::models::Model< ValueType > const &abstractModel, storm::gbar::abstraction::QualitativeResultMinMax const &qualitativeResults)
virtual std::pair< std::unique_ptr< storm::gbar::abstraction::StateSet >, std::unique_ptr< storm::gbar::abstraction::StateSet > > getConstraintAndTargetStates(storm::models::Model< ValueType > const &abstractModel)=0
Retrieves the state sets corresponding to the constraint and target states.
std::unique_ptr< storm::modelchecker::CheckResult > computeReachabilityProbabilitiesHelper(Environment const &env, storm::models::symbolic::StochasticTwoPlayerGame< DdType, ValueType > const &abstractModel, storm::OptimizationDirection const &player1Direction, storm::OptimizationDirection const &player2Direction, storm::dd::Bdd< DdType > const &maybeStates, storm::dd::Bdd< DdType > const &prob1States, storm::dd::Add< DdType, ValueType > const &startValues)
virtual uint64_t getAbstractionPlayer() const =0
Retrieves the index of the abstraction player.
std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > computeBounds(Environment const &env, storm::models::Model< ValueType > const &abstractModel)
Computes lower and upper bounds on the abstract model and returns the bounds for the initial states.
void filterInitialStates(storm::models::Model< ValueType > const &abstractModel, std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > &bounds)
bool getReuseQuantitativeResults() const
std::unique_ptr< storm::modelchecker::CheckResult > tryToObtainResultFromBounds(storm::models::Model< ValueType > const &model, std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > &bounds)
Tries to obtain the results from the bounds.
bool getReuseQualitativeResults() const
Methods that retrieve which results shall be reused.
bool boundsAreSufficientlyClose(std::pair< std::unique_ptr< storm::modelchecker::CheckResult >, std::unique_ptr< storm::modelchecker::CheckResult > > const &bounds)
Checks whether the provided bounds are sufficiently close to terminate.
virtual bool canHandle(storm::modelchecker::CheckTask< storm::logic::Formula > const &checkTask) const override
Overridden methods from super class.
AbstractAbstractionRefinementModelChecker(abstraction::AbstractionOptions const &options=abstraction::AbstractionOptions())
Constructs a model checker for the given model.
FragmentSpecification & setReachabilityRewardFormulasAllowed(bool newValue)
FragmentSpecification & setRewardOperatorsAllowed(bool newValue)
SymbolicQuantitativeCheckResult< Type, ValueType > & asSymbolicQuantitativeCheckResult()
virtual ExtendedValueType getMax() const =0
virtual ExtendedValueType getMin() const =0
storm::dd::Add< Type, ValueType > const & getValueVector() const
storm::dd::Bdd< Type > const & getStates() const
storm::dd::Bdd< Type > const & getReachableStates() const
static storm::dd::Add< DdType, ValueType > computeUntilProbabilities(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static storm::dd::Add< DdType, ValueType > computeReachabilityRewards(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, storm::dd::Bdd< DdType > const &targetStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static std::unique_ptr< CheckResult > computeUntilProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static std::unique_ptr< CheckResult > computeReachabilityRewards(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, storm::dd::Bdd< DdType > const &targetStates, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
virtual bool isSymbolicModel() const
Checks whether the model is a symbolic model.
virtual void printModelInformationToStream(std::ostream &out) const =0
Prints information about the model to the specified stream.
bool isOfType(storm::models::ModelType const &modelType) const
Checks whether the model is of the given type.
This class represents a discrete-time Markov chain.
This class represents a discrete-time Markov decision process.
Base class for all symbolic models.
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
storm::dd::Bdd< Type > const & getInitialStates() const
Retrieves the initial states of the model.
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
This class represents a discrete-time stochastic two-player game.
std::set< storm::expressions::Variable > const & getPlayer1Variables() const
Retrieeves the set of meta variables used to encode the nondeterministic choices of player 1.
std::set< storm::expressions::Variable > const & getPlayer2Variables() const
Retrieeves the set of meta variables used to encode the nondeterministic choices of player 2.
storm::dd::Bdd< Type > getIllegalPlayer1Mask() const
Retrieves a BDD characterizing all illegal player 1 choice encodings in the model.
storm::dd::Bdd< Type > getIllegalPlayer2Mask() const
Retrieves a BDD characterizing all illegal player 2 choice encodings in the model.
virtual std::unique_ptr< storm::solver::SymbolicGameSolver< Type, ValueType > > create(storm::dd::Add< Type, ValueType > const &A, storm::dd::Bdd< Type > const &allRows, storm::dd::Bdd< Type > const &illegalPlayer1Mask, storm::dd::Bdd< Type > const &illegalPlayer2Mask, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables, std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &rowColumnMetaVariablePairs, std::set< storm::expressions::Variable > const &player1Variables, std::set< storm::expressions::Variable > const &player2Variables) const
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::unique_ptr< storm::modelchecker::CheckResult > checkForResultAfterQuantitativeCheck(storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &checkTask, storm::OptimizationDirection const &player2Direction, std::pair< ValueType, ValueType > const &initialValueRange)
std::unique_ptr< storm::modelchecker::CheckResult > checkForResultAfterQualitativeCheck(storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &checkTask, storm::OptimizationDirection player2Direction, storm::dd::Bdd< Type > const &initialStates, storm::dd::Bdd< Type > const &prob0, storm::dd::Bdd< Type > const &prob1)
SymbolicQuantitativeGameResult< Type, ValueType > computeQuantitativeResult(Environment const &env, storm::OptimizationDirection player1Direction, storm::OptimizationDirection player2Direction, storm::gbar::abstraction::MenuGame< Type, ValueType > const &game, SymbolicQualitativeGameResultMinMax< Type > const &qualitativeResult, storm::dd::Add< Type, ValueType > const &initialStatesAdd, storm::dd::Bdd< Type > const &maybeStates, boost::optional< SymbolicQuantitativeGameResult< Type, ValueType > > const &startInfo=boost::none)
bool isLowerBound(ComparisonType t)
bool isStrict(ComparisonType t)
FragmentSpecification reachability()
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01(storm::models::sparse::DeterministicModel< T > const &model, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi i...
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01Max(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
ExplicitGameProb01Result performProb0(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< uint64_t > const &player1Groups, storm::storage::SparseMatrix< ValueType > const &player1BackwardTransitions, std::vector< uint64_t > const &player2BackwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, storm::OptimizationDirection const &player1Direction, storm::OptimizationDirection const &player2Direction, storm::storage::ExplicitGameStrategyPair *strategyPair)
Computes the set of states that have probability 0 given the strategies of the two players.
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under any pos...
storm::storage::BitVector performProb1A(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 1 of satisfying phi until psi under all possible re...
storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under at leas...
storm::storage::BitVector performProb0A(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
storm::storage::BitVector performProb1(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &, storm::storage::BitVector const &psiStates, storm::storage::BitVector const &statesWithProbabilityGreater0)
Computes the set of states of the given model for which all paths lead to the given set of target sta...
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 of satisfying phi until psi under at least one po...
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01Min(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
storm::storage::BitVector performProb1E(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability 1 of satisfying phi until psi under at least one po...
TargetType convertNumber(SourceType const &number)
solver::OptimizationDirection OptimizationDirection
Options that configure the game-based abstraction-refinement procedure.
ReuseMode reuseMode
The mode determining which results are reused.