diff --git a/src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.cpp index 6578bd58c..2833a5142 100644 --- a/src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.cpp @@ -147,12 +147,16 @@ namespace storm { } STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException, "Can not apply parameter lifting on step bounded formula: The step bound has to be positive."); + //Every state is a maybeState + maybeStates = storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getColumnCount(), true); + resultsForNonMaybeStates = std::vector(this->parametricModel.getNumberOfStates()); + // Create the reward vector STORM_LOG_THROW((checkTask.isRewardModelSet() && this->parametricModel.hasRewardModel(checkTask.getRewardModel())) || (!checkTask.isRewardModelSet() && this->parametricModel.hasUniqueRewardModel()), storm::exceptions::InvalidPropertyException, "The reward model specified by the CheckTask is not available in the given model."); typename SparseModelType::RewardModelType const& rewardModel = checkTask.isRewardModelSet() ? this->parametricModel.getRewardModel(checkTask.getRewardModel()) : this->parametricModel.getUniqueRewardModel(); std::vector b = rewardModel.getTotalRewardVector(this->parametricModel.getTransitionMatrix()); - parameterLifter = std::make_unique>(this->parametricModel.getTransitionMatrix(), b, storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getRowCount(), true), storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getColumnCount(), true)); + parameterLifter = std::make_unique>(this->parametricModel.getTransitionMatrix(), b, maybeStates, maybeStates); // We only know a lower bound for the result @@ -175,6 +179,19 @@ namespace storm { if(upperResultBound) solver->setUpperBound(upperResultBound.get()); if(storm::solver::minimize(dirForParameters) && minSched && !stepBound) solver->setSchedulerHint(std::move(minSched.get())); if(storm::solver::maximize(dirForParameters) && maxSched && !stepBound) solver->setSchedulerHint(std::move(maxSched.get())); + if (this->currentCheckTask->isBoundSet() && solver->hasSchedulerHint()) { + // If we reach this point, we know that after applying the hint, the x-values can only become larger (if we maximize) or smaller (if we minimize). + std::unique_ptr> termCond; + storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel.getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); + if (storm::solver::minimize(dirForParameters)) { + // Terminate if the value for ALL relevant states is already below the threshold + termCond = std::make_unique> (relevantStatesInSubsystem, this->currentCheckTask->getBoundThreshold(), true, false); + } else { + // Terminate if the value for ALL relevant states is already above the threshold + termCond = std::make_unique> (relevantStatesInSubsystem, this->currentCheckTask->getBoundThreshold(), true, true); + } + solver->setTerminationCondition(std::move(termCond)); + } // Invoke the solver if(stepBound) { diff --git a/src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.cpp b/src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.cpp index e7060e42b..e2130cc2f 100644 --- a/src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.cpp +++ b/src/storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.cpp @@ -180,12 +180,16 @@ namespace storm { } STORM_LOG_THROW(*stepBound > 0, storm::exceptions::NotSupportedException, "Can not apply parameter lifting on step bounded formula: The step bound has to be positive."); + //Every state is a maybeState + maybeStates = storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getColumnCount(), true); + resultsForNonMaybeStates = std::vector(this->parametricModel.getNumberOfStates()); + // Create the reward vector STORM_LOG_THROW((checkTask.isRewardModelSet() && this->parametricModel.hasRewardModel(checkTask.getRewardModel())) || (!checkTask.isRewardModelSet() && this->parametricModel.hasUniqueRewardModel()), storm::exceptions::InvalidPropertyException, "The reward model specified by the CheckTask is not available in the given model."); typename SparseModelType::RewardModelType const& rewardModel = checkTask.isRewardModelSet() ? this->parametricModel.getRewardModel(checkTask.getRewardModel()) : this->parametricModel.getUniqueRewardModel(); std::vector b = rewardModel.getTotalRewardVector(this->parametricModel.getTransitionMatrix()); - parameterLifter = std::make_unique>(this->parametricModel.getTransitionMatrix(), b, storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getRowCount(), true), storm::storage::BitVector(this->parametricModel.getTransitionMatrix().getColumnCount(), true)); + parameterLifter = std::make_unique>(this->parametricModel.getTransitionMatrix(), b, maybeStates, maybeStates); applyPreviousResultAsHint = false; @@ -214,6 +218,19 @@ namespace storm { } else { x.assign(maybeStates.getNumberOfSetBits(), storm::utility::zero()); } + if (this->currentCheckTask->isBoundSet() && this->currentCheckTask->getOptimizationDirection() == dirForParameters && solver->hasSchedulerHints()) { + // If we reach this point, we know that after applying the hints, the x-values can only become larger (if we maximize) or smaller (if we minimize). + std::unique_ptr> termCond; + storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel.getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); + if (storm::solver::minimize(dirForParameters)) { + // Terminate if the value for ALL relevant states is already below the threshold + termCond = std::make_unique> (relevantStatesInSubsystem, this->currentCheckTask->getBoundThreshold(), true, false); + } else { + // Terminate if the value for ALL relevant states is already above the threshold + termCond = std::make_unique> (relevantStatesInSubsystem, this->currentCheckTask->getBoundThreshold(), true, true); + } + solver->setTerminationCondition(std::move(termCond)); + } // Invoke the solver if(stepBound) {