27namespace modelchecker {
29template<
typename SparseModelType,
typename ConstantType>
32 std::make_unique<
storm::solver::GeneralMinMaxLinearEquationSolverFactory<ConstantType>>()) {
36template<
typename SparseModelType,
typename ConstantType>
39 : solverFactory(
std::move(solverFactory)), solvingRequiresUpperRewardBounds(false), regionSplitEstimationsEnabled(false) {
43template<
typename SparseModelType,
typename ConstantType>
47 result &= parametricModel->isSparseModel();
48 result &= parametricModel->supportsParameters();
49 auto dtmc = parametricModel->template as<SparseModelType>();
50 result &=
static_cast<bool>(dtmc);
64template<
typename SparseModelType,
typename ConstantType>
66 std::shared_ptr<storm::models::ModelBase> parametricModel,
68 bool generateRegionSplitEstimates,
bool allowModelSimplification) {
69 auto dtmc = parametricModel->template as<SparseModelType>();
70 monotonicityChecker = std::make_unique<storm::analysis::MonotonicityChecker<ValueType>>(dtmc->getTransitionMatrix());
71 specify_internal(env, dtmc, checkTask, generateRegionSplitEstimates, !allowModelSimplification);
74template<
typename SparseModelType,
typename ConstantType>
76 std::shared_ptr<SparseModelType> parametricModel,
78 bool generateRegionSplitEstimates,
bool skipModelSimplification) {
79 STORM_LOG_ASSERT(this->canHandle(parametricModel, checkTask),
"specified model and formula can not be handled by this.");
83 regionSplitEstimationsEnabled = generateRegionSplitEstimates;
85 if (skipModelSimplification) {
86 this->parametricModel = parametricModel;
87 this->specifyFormula(env, checkTask);
90 if (!simplifier.simplify(checkTask.
getFormula())) {
91 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
93 this->parametricModel = simplifier.getSimplifiedModel();
94 this->specifyFormula(env, checkTask.
substituteFormula(*simplifier.getSimplifiedFormula()));
98template<
typename SparseModelType,
typename ConstantType>
102 STORM_LOG_THROW(!checkTask.
getFormula().hasLowerBound(), storm::exceptions::NotSupportedException,
"Lower step bounds are not supported.");
103 STORM_LOG_THROW(checkTask.
getFormula().hasUpperBound(), storm::exceptions::NotSupportedException,
"Expected a bounded until formula with an upper bound.");
105 "Expected a bounded until formula with step bounds.");
106 stepBound = checkTask.
getFormula().getUpperBound().evaluateAsInt();
107 STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException,
108 "Can not apply parameter lifting on step bounded formula: The step bound has to be positive.");
109 if (checkTask.
getFormula().isUpperBoundStrict()) {
110 STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException,
"Expected a strict upper step bound that is greater than zero.");
113 STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException,
114 "Can not apply parameter lifting on step bounded formula: The step bound has to be positive.");
120 storm::exceptions::NotSupportedException,
"Parameter lifting with non-propositional subformulas is not supported");
122 std::move(propositionalChecker.
check(checkTask.
getFormula().getLeftSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector());
124 std::move(propositionalChecker.
check(checkTask.
getFormula().getRightSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector());
128 maybeStates &= ~psiStates;
131 resultsForNonMaybeStates = std::vector<ConstantType>(this->parametricModel->getNumberOfStates(), storm::utility::zero<ConstantType>());
135 if (!maybeStates.empty()) {
137 std::vector<ValueType> b = this->parametricModel->getTransitionMatrix().getConstrainedRowSumVector(
139 parameterLifter = std::make_unique<storm::transformer::ParameterLifter<ValueType, ConstantType>>(
144 lowerResultBound = storm::utility::zero<ConstantType>();
145 upperResultBound = storm::utility::one<ConstantType>();
147 solverFactory->setRequirementsChecked(
true);
150 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
153 this->parametricModel->getTransitionMatrix());
156template<
typename SparseModelType,
typename ConstantType>
163 storm::exceptions::NotSupportedException,
"Parameter lifting with non-propositional subformulas is not supported");
165 std::move(propositionalChecker.
check(checkTask.
getFormula().getLeftSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector());
167 std::move(propositionalChecker.
check(checkTask.
getFormula().getRightSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector());
170 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
172 maybeStates = ~(statesWithProbability01.first | statesWithProbability01.second);
175 resultsForNonMaybeStates = std::vector<ConstantType>(this->parametricModel->getNumberOfStates(), storm::utility::zero<ConstantType>());
179 if (!maybeStates.empty()) {
181 std::vector<ValueType> b = this->parametricModel->getTransitionMatrix().getConstrainedRowSumVector(
182 storm::storage::BitVector(this->parametricModel->getTransitionMatrix().getRowCount(),
true), statesWithProbability01.second);
183 parameterLifter = std::make_unique<storm::transformer::ParameterLifter<ValueType, ConstantType>>(
184 this->parametricModel->getTransitionMatrix(), b, maybeStates, maybeStates, regionSplitEstimationsEnabled,
189 lowerResultBound = storm::utility::zero<ConstantType>();
190 upperResultBound = storm::utility::one<ConstantType>();
194 auto req = solverFactory->getRequirements(env,
true,
true, boost::none,
true);
196 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
197 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
198 solverFactory->setRequirementsChecked(
true);
201 this->parametricModel->getTransitionMatrix());
204template<
typename SparseModelType,
typename ConstantType>
210 "Parameter lifting with non-propositional subformulas is not supported");
212 std::move(propositionalChecker.
check(checkTask.
getFormula().getSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector());
215 this->parametricModel->getBackwardTransitions(),
storm::storage::BitVector(this->parametricModel->getNumberOfStates(),
true), targetStates);
217 maybeStates = ~(targetStates | infinityStates);
220 resultsForNonMaybeStates = std::vector<ConstantType>(this->parametricModel->getNumberOfStates(), storm::utility::zero<ConstantType>());
224 if (!maybeStates.empty()) {
227 (!checkTask.
isRewardModelSet() && this->parametricModel->hasUniqueRewardModel()),
228 storm::exceptions::InvalidPropertyException,
"The reward model specified by the CheckTask is not available in the given model.");
230 typename SparseModelType::RewardModelType
const& rewardModel =
233 std::vector<ValueType> b = rewardModel.getTotalRewardVector(this->parametricModel->getTransitionMatrix());
235 parameterLifter = std::make_unique<storm::transformer::ParameterLifter<ValueType, ConstantType>>(
236 this->parametricModel->getTransitionMatrix(), b, maybeStates, maybeStates, regionSplitEstimationsEnabled);
240 lowerResultBound = storm::utility::zero<ConstantType>();
244 auto req = solverFactory->getRequirements(env,
true,
true, boost::none,
true);
245 req.clearLowerBounds();
246 if (req.upperBounds()) {
247 solvingRequiresUpperRewardBounds =
true;
248 req.clearUpperBounds();
250 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
251 "Solver requirements " + req.getEnabledRequirementsAsString() +
" not checked.");
252 solverFactory->setRequirementsChecked(
true);
255template<
typename SparseModelType,
typename ConstantType>
259 stepBound = checkTask.
getFormula().getBound().evaluateAsInt();
261 STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException,
"Expected a strict upper step bound that is greater than zero.");
264 STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException,
265 "Can not apply parameter lifting on step bounded formula: The step bound has to be positive.");
269 resultsForNonMaybeStates = std::vector<ConstantType>(this->parametricModel->getNumberOfStates());
273 (!checkTask.
isRewardModelSet() && this->parametricModel->hasUniqueRewardModel()),
274 storm::exceptions::InvalidPropertyException,
"The reward model specified by the CheckTask is not available in the given model.");
275 typename SparseModelType::RewardModelType
const& rewardModel =
277 std::vector<ValueType> b = rewardModel.getTotalRewardVector(this->parametricModel->getTransitionMatrix());
279 parameterLifter = std::make_unique<storm::transformer::ParameterLifter<ValueType, ConstantType>>(this->parametricModel->getTransitionMatrix(), b,
280 maybeStates, maybeStates);
283 lowerResultBound = storm::utility::zero<ConstantType>();
286 solverFactory->setRequirementsChecked(
true);
289template<
typename SparseModelType,
typename ConstantType>
292 if (!instantiationCheckerSAT) {
293 instantiationCheckerSAT =
294 std::make_unique<storm::modelchecker::SparseDtmcInstantiationModelChecker<SparseModelType, ConstantType>>(*this->parametricModel);
295 instantiationCheckerSAT->
specifyFormula(this->currentCheckTask->template convertValueType<ValueType>());
296 instantiationCheckerSAT->setInstantiationsAreGraphPreserving(
true);
298 return *instantiationCheckerSAT;
301template<
typename SparseModelType,
typename ConstantType>
304 if (!instantiationCheckerVIO) {
305 instantiationCheckerVIO =
306 std::make_unique<storm::modelchecker::SparseDtmcInstantiationModelChecker<SparseModelType, ConstantType>>(*this->parametricModel);
307 instantiationCheckerVIO->
specifyFormula(this->currentCheckTask->template convertValueType<ValueType>());
308 instantiationCheckerVIO->setInstantiationsAreGraphPreserving(
true);
310 return *instantiationCheckerVIO;
313template<
typename SparseModelType,
typename ConstantType>
316 if (!instantiationChecker) {
317 instantiationChecker =
318 std::make_unique<storm::modelchecker::SparseDtmcInstantiationModelChecker<SparseModelType, ConstantType>>(*this->parametricModel);
319 instantiationChecker->
specifyFormula(this->currentCheckTask->template convertValueType<ValueType>());
320 instantiationChecker->setInstantiationsAreGraphPreserving(
true);
322 return *instantiationChecker;
325template<
typename SparseModelType,
typename ConstantType>
329 if (maybeStates.empty()) {
330 return std::make_unique<storm::modelchecker::ExplicitQuantitativeCheckResult<ConstantType>>(resultsForNonMaybeStates);
332 parameterLifter->specifyRegion(region, dirForParameters);
335 assert(*stepBound > 0);
336 x = std::vector<ConstantType>(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>());
338 multiplier->repeatedMultiplyAndReduce(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound);
340 auto solver = solverFactory->create(env, parameterLifter->getMatrix());
341 solver->setHasUniqueSolution();
342 solver->setHasNoEndComponents();
343 if (lowerResultBound)
344 solver->setLowerBound(lowerResultBound.get());
345 if (upperResultBound) {
346 solver->setUpperBound(upperResultBound.get());
347 }
else if (solvingRequiresUpperRewardBounds) {
349 std::vector<ConstantType> oneStepProbs;
350 oneStepProbs.reserve(parameterLifter->getMatrix().getRowCount());
351 for (uint64_t row = 0; row < parameterLifter->getMatrix().getRowCount(); ++row) {
352 oneStepProbs.push_back(storm::utility::one<ConstantType>() - parameterLifter->getMatrix().getRowSum(row));
354 if (dirForParameters == storm::OptimizationDirection::Minimize) {
364 solver->setTrackScheduler(
true);
366 if (localMonotonicityResult !=
nullptr && !this->isOnlyGlobalSet()) {
370 if (useMinimize && !minSchedChoices) {
371 minSchedChoices = std::vector<uint_fast64_t>(parameterLifter->getRowGroupCount(), 0);
373 if (!useMinimize && !maxSchedChoices) {
374 maxSchedChoices = std::vector<uint_fast64_t>(parameterLifter->getRowGroupCount(), 0);
377 auto const& occuringVariables = parameterLifter->getOccurringVariablesAtState();
378 for (uint_fast64_t state = 0; state < parameterLifter->getRowGroupCount(); ++state) {
379 auto oldStateNumber = parameterLifter->getOriginalStateNumber(state);
380 auto& variables = occuringVariables.at(oldStateNumber);
383 STORM_LOG_THROW(variables.size() <= 1, storm::exceptions::NotImplementedException,
384 "Using localMonRes not yet implemented for states with 2 or more variables, please run without --use-monotonicity");
386 bool allMonotone =
true;
387 for (
auto var : variables) {
388 auto monotonicity = localMonotonicityResult->getMonotonicity(oldStateNumber, var);
390 bool ignoreUpperBound = monotonicity == Monotonicity::Constant || (useMinimize && monotonicity == Monotonicity::Incr) ||
391 (!useMinimize && monotonicity == Monotonicity::Decr);
392 bool ignoreLowerBound =
393 !ignoreUpperBound && ((useMinimize && monotonicity == Monotonicity::Decr) || (!useMinimize && monotonicity == Monotonicity::Incr));
394 allMonotone &= (ignoreUpperBound || ignoreLowerBound);
395 if (ignoreLowerBound) {
397 minSchedChoices.get()[state] = 1;
399 maxSchedChoices.get()[state] = 1;
401 }
else if (ignoreUpperBound) {
403 minSchedChoices.get()[state] = 0;
405 maxSchedChoices.get()[state] = 0;
410 choiceFixedForStates.
set(state);
415 solver->setInitialScheduler(std::move(minSchedChoices.get()));
417 solver->setInitialScheduler(std::move(maxSchedChoices.get()));
418 solver->setSchedulerFixedForRowGroup(std::move(choiceFixedForStates));
421 solver->setInitialScheduler(std::move(minSchedChoices.get()));
423 solver->setInitialScheduler(std::move(maxSchedChoices.get()));
426 if (this->currentCheckTask->isBoundSet() && solver->hasInitialScheduler()) {
428 std::unique_ptr<storm::solver::TerminationCondition<ConstantType>> termCond;
430 ? this->parametricModel->getInitialStates() % maybeStates
434 termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumBelowThreshold<ConstantType>>(
435 relevantStatesInSubsystem,
true, this->currentCheckTask->getBoundThreshold(),
false);
438 termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumExceedsThreshold<ConstantType>>(
439 relevantStatesInSubsystem,
true, this->currentCheckTask->getBoundThreshold(),
true);
441 solver->setTerminationCondition(std::move(termCond));
445 x.resize(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>());
446 solver->solveEquations(env, dirForParameters, x, parameterLifter->getVector());
448 minSchedChoices = solver->getSchedulerChoices();
450 maxSchedChoices = solver->getSchedulerChoices();
452 if (isRegionSplitEstimateSupported()) {
453 computeRegionSplitEstimates(x, solver->getSchedulerChoices(), region, dirForParameters);
458 std::vector<ConstantType> result = resultsForNonMaybeStates;
459 auto maybeStateResIt = x.begin();
460 for (
auto const& maybeState : maybeStates) {
461 result[maybeState] = *maybeStateResIt;
464 return std::make_unique<storm::modelchecker::ExplicitQuantitativeCheckResult<ConstantType>>(std::move(result));
467template<
typename SparseModelType,
typename ConstantType>
469 std::vector<ConstantType>
const& quantitativeResult, std::vector<uint_fast64_t>
const& schedulerChoices,
471 std::map<VariableType, double> deltaLower, deltaUpper;
473 deltaLower.insert(std::make_pair(p, 0.0));
474 deltaUpper.insert(std::make_pair(p, 0.0));
476 auto const& choiceValuations = parameterLifter->getRowLabels();
477 auto const& matrix = parameterLifter->getMatrix();
478 auto const& vector = parameterLifter->getVector();
480 std::vector<ConstantType> stateResults;
481 for (uint64_t state = 0; state < schedulerChoices.size(); ++state) {
482 uint64_t rowOffset = matrix.getRowGroupIndices()[state];
483 uint64_t optimalChoice = schedulerChoices[state];
484 auto const& optimalChoiceVal = choiceValuations[rowOffset + optimalChoice];
485 assert(optimalChoiceVal.getUnspecifiedParameters().empty());
486 stateResults.clear();
487 for (uint64_t row = rowOffset; row < matrix.getRowGroupIndices()[state + 1]; ++row) {
488 stateResults.push_back(matrix.multiplyRowWithVector(row, quantitativeResult) + vector[row]);
491 bool checkUpperParameters =
false;
493 auto const& consideredParameters = checkUpperParameters ? optimalChoiceVal.getUpperParameters() : optimalChoiceVal.getLowerParameters();
494 for (
auto const& p : consideredParameters) {
496 ConstantType bestValue = 0;
497 bool foundBestValue =
false;
498 for (uint64_t choice = 0; choice < stateResults.size(); ++choice) {
499 if (choice != optimalChoice) {
500 auto const& otherBoundParsOfChoice = checkUpperParameters ? choiceValuations[rowOffset + choice].getLowerParameters()
501 : choiceValuations[rowOffset + choice].getUpperParameters();
502 if (otherBoundParsOfChoice.find(p) != otherBoundParsOfChoice.end()) {
503 ConstantType
const& choiceValue = stateResults[choice];
504 if (!foundBestValue || (
storm::solver::minimize(dirForParameters) ? choiceValue < bestValue : choiceValue > bestValue)) {
505 foundBestValue =
true;
506 bestValue = choiceValue;
511 auto optimal = storm::utility::convertNumber<double>(stateResults[optimalChoice]);
512 auto diff = optimal - storm::utility::convertNumber<double>(bestValue);
513 if (foundBestValue) {
514 if (checkUpperParameters) {
515 deltaLower[p] += std::abs(diff);
517 deltaUpper[p] += std::abs(diff);
521 checkUpperParameters = !checkUpperParameters;
522 }
while (checkUpperParameters);
525 regionSplitEstimates.clear();
526 useRegionSplitEstimates =
false;
528 if (this->possibleMonotoneParameters.find(p) != this->possibleMonotoneParameters.end()) {
529 if (deltaLower[p] > deltaUpper[p] && deltaUpper[p] >= 0.0001) {
530 regionSplitEstimates.insert(std::make_pair(p, deltaUpper[p]));
531 useRegionSplitEstimates =
true;
532 }
else if (deltaLower[p] <= deltaUpper[p] && deltaLower[p] >= 0.0001) {
534 regionSplitEstimates.insert(std::make_pair(p, deltaLower[p]));
535 useRegionSplitEstimates =
true;
543template<
typename SparseModelType,
typename ConstantType>
545 maybeStates.resize(0);
546 resultsForNonMaybeStates.clear();
547 stepBound = boost::none;
548 instantiationChecker =
nullptr;
549 parameterLifter =
nullptr;
550 minSchedChoices = boost::none;
551 maxSchedChoices = boost::none;
553 lowerResultBound = boost::none;
554 upperResultBound = boost::none;
555 regionSplitEstimationsEnabled =
false;
558template<
typename SparseModelType,
typename ConstantType>
560 if (!minSchedChoices) {
565 uint_fast64_t state = 0;
566 for (
auto const& schedulerChoice : minSchedChoices.get()) {
567 result.
setChoice(schedulerChoice, state);
574template<
typename SparseModelType,
typename ConstantType>
576 if (!maxSchedChoices) {
581 uint_fast64_t state = 0;
582 for (
auto const& schedulerChoice : maxSchedChoices.get()) {
583 result.
setChoice(schedulerChoice, state);
590template<
typename SparseModelType,
typename ConstantType>
592 return regionSplitEstimationsEnabled && !stepBound;
595template<
typename SparseModelType,
typename ConstantType>
596std::map<typename RegionModelChecker<typename SparseModelType::ValueType>::VariableType,
double>
598 STORM_LOG_THROW(isRegionSplitEstimateSupported(), storm::exceptions::InvalidOperationException,
599 "Region split estimation requested but are not enabled (or supported).");
600 return regionSplitEstimates;
603template<
typename SparseModelType,
typename ConstantType>
606 if (this->orderExtender) {
607 auto res = this->orderExtender->extendOrder(order, region);
608 order = std::get<0>(res);
609 if (std::get<1>(res) != order->getNumberOfStates()) {
610 this->orderExtender.get().setUnknownStates(order, std::get<1>(res), std::get<2>(res));
613 STORM_LOG_WARN(
"Extending order for RegionModelChecker not implemented");
618template<
typename SparseModelType,
typename ConstantType>
622 if (this->monotoneIncrParameters && !localMonotonicityResult->isFixedParametersSet()) {
623 for (
auto& var : this->monotoneIncrParameters.get()) {
624 localMonotonicityResult->setMonotoneIncreasing(var);
626 for (
auto& var : this->monotoneDecrParameters.get()) {
627 localMonotonicityResult->setMonotoneDecreasing(var);
630 auto state = order->getNextDoneState(-1);
631 auto const variablesAtState = parameterLifter->getOccurringVariablesAtState();
632 while (state != order->getNumberOfStates()) {
633 if (localMonotonicityResult->getMonotonicity(state) ==
nullptr) {
634 auto variables = variablesAtState[state];
635 if (variables.size() == 0 || order->isBottomState(state) || order->isTopState(state)) {
636 localMonotonicityResult->setConstant(state);
638 for (
auto const& var : variables) {
639 auto monotonicity = localMonotonicityResult->getMonotonicity(state, var);
640 if (monotonicity == Monotonicity::Unknown || monotonicity == Monotonicity::Not) {
641 monotonicity = monotonicityChecker->checkLocalMonotonicity(order, state, var, region);
642 if (monotonicity == Monotonicity::Unknown || monotonicity == Monotonicity::Not) {
645 localMonotonicityResult->setMonotonicity(state, var, monotonicity);
653 state = order->getNextDoneState(state);
655 auto const statesAtVariable = parameterLifter->getOccuringStatesAtVariable();
657 for (
auto const& entry : statesAtVariable) {
658 auto states = entry.second;
659 auto var = entry.first;
661 for (
auto const& state : states) {
662 done &= order->contains(state) && localMonotonicityResult->getMonotonicity(state, var) != Monotonicity::Unknown;
670 localMonotonicityResult->getGlobalMonotonicityResult()->setDoneForVar(var);
674 localMonotonicityResult->setDone();
675 while (order->existsNextState()) {
677 order->add(order->getNextStateNumber().second);
679 assert(order->getDoneBuilding());
683template<
typename SparseModelType,
typename ConstantType>
687 bool splitForExtremum)
const {
688 assert(regionVector.size() == 0);
690 std::multimap<double, VariableType> sortedOnValues;
691 std::set<VariableType> consideredVariables;
692 if (splitForExtremum) {
693 if (regionSplitEstimationsEnabled && useRegionSplitEstimates) {
695 for (
auto& entry : regionSplitEstimates) {
696 assert(!this->isUseMonotonicitySet() ||
697 (!monRes.
isMonotone(entry.first) && this->possibleMonotoneParameters.find(entry.first) != this->possibleMonotoneParameters.end()));
700 sortedOnValues.insert({-(entry.second), entry.first});
703 for (
auto itr = sortedOnValues.begin(); itr != sortedOnValues.end() && consideredVariables.size() < maxSplitDimensions; ++itr) {
704 consideredVariables.insert(itr->second);
706 assert(consideredVariables.size() > 0);
712 for (
auto itr = sortedOnDifference.begin(); itr != sortedOnDifference.end() && consideredVariables.size() < maxSplitDimensions; ++itr) {
713 if (!this->isUseMonotonicitySet() || !monRes.
isMonotone(itr->second)) {
714 consideredVariables.insert(itr->second);
722 if (regionSplitEstimationsEnabled && useRegionSplitEstimates) {
724 ConstantType diff = this->lastValue - (this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
725 for (
auto& entry : regionSplitEstimates) {
726 if ((!this->isUseMonotonicitySet() || !monRes.
isMonotone(entry.first)) && storm::utility::convertNumber<ConstantType>(entry.second) > diff) {
727 sortedOnValues.insert({-(entry.second * storm::utility::convertNumber<double>(region.
getDifference(entry.first)) *
728 storm::utility::convertNumber<double>(region.
getDifference(entry.first))),
733 for (
auto itr = sortedOnValues.begin(); itr != sortedOnValues.end() && consideredVariables.size() < maxSplitDimensions; ++itr) {
734 consideredVariables.insert(itr->second);
737 if (consideredVariables.size() == 0) {
739 for (
auto itr = sortedOnDifference.begin(); itr != sortedOnDifference.end() && consideredVariables.size() < maxSplitDimensions; ++itr) {
740 consideredVariables.insert(itr->second);
743 assert(consideredVariables.size() > 0);
748template<
typename SparseModelType,
typename ConstantType>
750 maxSplitDimensions = newValue;
753template<
typename SparseModelType,
typename ConstantType>
755 maxSplitDimensions = std::numeric_limits<uint64_t>::max();
bool isAllMonotonicity() const
Returns if all Variables are monotone.
bool isMonotone(VariableType var) const
bool isDone() const
Checks if the result is complete.
FragmentSpecification & setStepBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setTimeBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setCumulativeRewardFormulasAllowed(bool newValue)
FragmentSpecification & setReachabilityRewardFormulasAllowed(bool newValue)
FragmentSpecification & setRewardOperatorsAllowed(bool newValue)
FragmentSpecification & setBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setTimeBoundedCumulativeRewardFormulasAllowed(bool newValue)
FragmentSpecification & setStepBoundedCumulativeRewardFormulasAllowed(bool newValue)
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
CheckTask< NewFormulaType, ValueType > substituteFormula(NewFormulaType const &newFormula) const
Copies the check task from the source while replacing the formula with the new one.
bool isRewardModelSet() const
Retrieves whether a reward model was set.
std::string const & getRewardModel() const
Retrieves the reward model over which to perform the checking (if set).
FormulaType const & getFormula() const
Retrieves the formula from this task.
bool isUseMonotonicitySet() const
virtual void extendLocalMonotonicityResult(storm::storage::ParameterRegion< ValueType > const ®ion, std::shared_ptr< storm::analysis::Order > order, std::shared_ptr< storm::analysis::LocalMonotonicityResult< VariableType > > localMonotonicityResult) override
virtual std::shared_ptr< storm::analysis::Order > extendOrder(std::shared_ptr< storm::analysis::Order > order, storm::storage::ParameterRegion< ValueType > region) override
SparseDtmcParameterLiftingModelChecker()
virtual void specifyReachabilityRewardFormula(Environment const &env, CheckTask< storm::logic::EventuallyFormula, ConstantType > const &checkTask) override
virtual storm::modelchecker::SparseInstantiationModelChecker< SparseModelType, ConstantType > & getInstantiationCheckerVIO() override
virtual void specify(Environment const &env, std::shared_ptr< storm::models::ModelBase > parametricModel, CheckTask< storm::logic::Formula, ValueType > const &checkTask, bool generateRegionSplitEstimates=false, bool allowModelSimplification=true) override
virtual bool canHandle(std::shared_ptr< storm::models::ModelBase > parametricModel, CheckTask< storm::logic::Formula, ValueType > const &checkTask) const override
virtual void reset() override
virtual storm::modelchecker::SparseInstantiationModelChecker< SparseModelType, ConstantType > & getInstantiationChecker() override
virtual std::unique_ptr< CheckResult > computeQuantitativeValues(Environment const &env, storm::storage::ParameterRegion< ValueType > const ®ion, storm::solver::OptimizationDirection const &dirForParameters, std::shared_ptr< storm::analysis::LocalMonotonicityResult< VariableType > > localMonotonicityResult=nullptr) override
virtual void specifyBoundedUntilFormula(const CheckTask< storm::logic::BoundedUntilFormula, ConstantType > &checkTask) override
virtual void splitSmart(storm::storage::ParameterRegion< ValueType > ®ion, std::vector< storm::storage::ParameterRegion< ValueType > > ®ionVector, storm::analysis::MonotonicityResult< VariableType > &monRes, bool splitForExtremum) const override
boost::optional< storm::storage::Scheduler< ConstantType > > getCurrentMinScheduler()
boost::optional< storm::storage::Scheduler< ConstantType > > getCurrentMaxScheduler()
virtual void specifyCumulativeRewardFormula(const CheckTask< storm::logic::CumulativeRewardFormula, ConstantType > &checkTask) override
virtual storm::modelchecker::SparseInstantiationModelChecker< SparseModelType, ConstantType > & getInstantiationCheckerSAT() override
void resetMaxSplitDimensions() override
When splitting, split in every dimension.
void computeRegionSplitEstimates(std::vector< ConstantType > const &quantitativeResult, std::vector< uint_fast64_t > const &schedulerChoices, storm::storage::ParameterRegion< ValueType > const ®ion, storm::solver::OptimizationDirection const &dirForParameters)
void setMaxSplitDimensions(uint64_t) override
When splitting, split in at most this many dimensions.
virtual void specifyUntilFormula(Environment const &env, CheckTask< storm::logic::UntilFormula, ConstantType > const &checkTask) override
void specify_internal(Environment const &env, std::shared_ptr< SparseModelType > parametricModel, CheckTask< storm::logic::Formula, ValueType > const &checkTask, bool generateRegionSplitEstimates, bool skipModelSimplification)
virtual bool isRegionSplitEstimateSupported() const override
Returns true if region split estimation (a) was enabled when model and check task have been specified...
virtual std::map< VariableType, double > getRegionSplitEstimate() const override
Returns an estimate of the benefit of splitting the last checked region with respect to each paramete...
Class to efficiently check a formula on a parametric model with different parameter instantiations.
void specifyFormula(CheckTask< storm::logic::Formula, typename SparseModelType::ValueType > const &checkTask)
virtual bool canHandle(CheckTask< storm::logic::Formula, SolutionType > const &checkTask) const override
Determines whether the model checker can handle the given verification task.
ValueType computeUpperBound()
Computes an upper bound on the expected rewards.
std::vector< ValueType > computeUpperBounds()
Computes upper bounds on the expected rewards.
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
A bit vector that is internally represented as a vector of 64-bit values.
void complement()
Negates all bits in the bit vector.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
std::set< VariableType > const & getVariables() const
Valuation getCenterPoint() const
Returns the center point of this region.
CoefficientType getDifference(const std::string varName) const
void split(Valuation const &splittingPoint, std::vector< ParameterRegion< ParametricType > > ®ionVector) const
Splits the region at the given point and inserts the resulting subregions at the end of the given vec...
std::multimap< CoefficientType, VariableType > const & getVariablesSorted() const
This class defines which action is chosen in a particular state of a non-deterministic model.
void setChoice(SchedulerChoice< ValueType > const &choice, uint_fast64_t modelState, uint_fast64_t memoryState=0)
Sets the choice defined by the scheduler for the given state.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
FragmentSpecification reachability()
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)
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...
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
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...
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Sets the provided values at the provided positions in the given vector.