18namespace modelchecker {
 
   19template<
typename ValueType>
 
   23template<
typename ValueType>
 
   29template<
typename ValueType>
 
   36template<
typename ValueType>
 
   38                                                                                             std::vector<ValueType>* actionBasedRewards) {
 
   39    std::vector<ValueType> choiceValues((pomdp.getNumberOfChoices()));
 
   40    pomdp.getTransitionMatrix().multiplyWithVector(stateValues, choiceValues, actionBasedRewards);
 
   44template<
typename ValueType>
 
   48    ValueType 
const& scoreThreshold, 
bool relativeScore) {
 
   52    auto choiceValues = getChoiceValues(stateValues, actionBasedRewards);
 
   53    auto const& choiceIndices = pomdp.getTransitionMatrix().getRowGroupIndices();
 
   54    std::vector<storm::storage::Distribution<ValueType, uint_fast64_t>> choiceDistributions(pomdp.getNrObservations());
 
   55    for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
 
   56        auto& choiceDistribution = choiceDistributions[pomdp.getObservation(state)];
 
   57        ValueType 
const& stateValue = stateValues[state];
 
   58        assert(stateValue >= storm::utility::zero<ValueType>());
 
   59        for (
auto choice = choiceIndices[state]; choice < choiceIndices[state + 1]; ++choice) {
 
   60            ValueType 
const& choiceValue = choiceValues[choice];
 
   61            assert(choiceValue >= storm::utility::zero<ValueType>());
 
   67                choiceDistribution.addProbability(choice - choiceIndices[state], scoreThreshold);
 
   69                ValueType choiceScore = info.
minimize() ? (choiceValue - stateValue) : (stateValue - choiceValue);
 
   71                    ValueType avg = (stateValue + choiceValue) / storm::utility::convertNumber<ValueType, uint64_t>(2);
 
   76                choiceScore = storm::utility::one<ValueType>() - choiceScore;
 
   77                if (choiceScore >= scoreThreshold) {
 
   78                    choiceDistribution.addProbability(choice - choiceIndices[state], choiceScore);
 
   83        if (choiceDistribution.size() == 0) {
 
   84            for (
auto choice = choiceIndices[state]; choice < choiceIndices[state + 1]; ++choice) {
 
   85                choiceDistribution.addProbability(choice - choiceIndices[state], scoreThreshold);
 
   88        STORM_LOG_ASSERT(choiceDistribution.size() > 0, 
"Empty choice distribution.");
 
   91    for (
auto& choiceDistribution : choiceDistributions) {
 
   92        choiceDistribution.normalize();
 
   95    for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
 
   96        pomdpScheduler.setChoice(choiceDistributions[pomdp.getObservation(state)], state);
 
   98    STORM_LOG_ASSERT(!pomdpScheduler.isPartialScheduler(), 
"Expected a fully defined scheduler.");
 
   99    auto scheduledModel = underlyingMdp->applyScheduler(pomdpScheduler, 
false);
 
  101    auto resultPtr = storm::api::verifyWithSparseEngine<ValueType>(env, scheduledModel, storm::api::createTask<ValueType>(formula.
asSharedPointer(), 
false));
 
  102    STORM_LOG_THROW(resultPtr, storm::exceptions::UnexpectedException, 
"No check result obtained.");
 
  103    STORM_LOG_THROW(resultPtr->isExplicitQuantitativeCheckResult(), storm::exceptions::UnexpectedException, 
"Unexpected Check result Type");
 
  104    std::vector<ValueType> pomdpSchedulerResult = std::move(resultPtr->template asExplicitQuantitativeCheckResult<ValueType>().getValueVector());
 
  105    return std::make_pair(pomdpSchedulerResult, pomdpScheduler);
 
  108template<
typename ValueType>
 
  114    STORM_LOG_DEBUG(
"Computing the unfolding for memory bound " << memoryBound);
 
  118    auto memPomdp = memoryUnfolder.transform(
false);
 
  121    std::vector<uint64_t> obsChoiceVector(memPomdp->getNrObservations());
 
  122    std::random_device rd;
 
  123    auto engine = std::mt19937(rd());
 
  124    for (uint64_t obs = 0; obs < memPomdp->getNrObservations(); ++obs) {
 
  125        uint64_t nrChoices = memPomdp->getNumberOfChoices(memPomdp->getStatesWithObservation(obs).front());
 
  126        std::uniform_int_distribution<uint64_t> uniform_dist(0, nrChoices - 1);
 
  127        obsChoiceVector[obs] = uniform_dist(engine);
 
  129    for (uint64_t state = 0; state < memPomdp->getNumberOfStates(); ++state) {
 
  130        pomdpScheduler.setChoice(obsChoiceVector[memPomdp->getObservation(state)], state);
 
  135        std::make_shared<storm::models::sparse::Mdp<ValueType>>(memPomdp->getTransitionMatrix(), memPomdp->getStateLabeling(), memPomdp->getRewardModels());
 
  136    auto scheduledModel = underlyingMdp->applyScheduler(pomdpScheduler, 
false);
 
  137    auto resultPtr = storm::api::verifyWithSparseEngine<ValueType>(env, scheduledModel, storm::api::createTask<ValueType>(formula.
asSharedPointer(), 
false));
 
  138    STORM_LOG_THROW(resultPtr, storm::exceptions::UnexpectedException, 
"No check result obtained.");
 
  139    STORM_LOG_THROW(resultPtr->isExplicitQuantitativeCheckResult(), storm::exceptions::UnexpectedException, 
"Unexpected Check result Type");
 
  140    std::vector<ValueType> pomdpSchedulerResult = std::move(resultPtr->template asExplicitQuantitativeCheckResult<ValueType>().getValueVector());
 
  143    std::vector<ValueType> res(pomdp.getNumberOfStates(), info.
minimize() ? storm::utility::infinity<ValueType>() : -
storm::utility::
infinity<
ValueType>());
 
  144    for (uint64_t memPomdpState = 0; memPomdpState < pomdpSchedulerResult.size(); ++memPomdpState) {
 
  145        uint64_t modelState = memPomdpState / memoryBound;
 
  146        if ((info.
minimize() && pomdpSchedulerResult[memPomdpState] < res[modelState]) ||
 
  147            (!info.
minimize() && pomdpSchedulerResult[memPomdpState] > res[modelState])) {
 
  148            res[modelState] = pomdpSchedulerResult[memPomdpState];
 
  151    return std::make_pair(res, pomdpScheduler);
 
  154template<
typename ValueType>
 
  156PreprocessingPomdpValueBoundsModelChecker<ValueType>::computeValuesForRandomMemorylessPolicy(
 
  160    std::vector<uint64_t> obsChoiceVector(pomdp.getNrObservations());
 
  162    std::random_device rd;
 
  163    auto engine = std::mt19937(rd());
 
  164    for (uint64_t obs = 0; obs < pomdp.getNrObservations(); ++obs) {
 
  165        uint64_t nrChoices = pomdp.getNumberOfChoices(pomdp.getStatesWithObservation(obs).front());
 
  166        std::uniform_int_distribution<uint64_t> uniform_dist(0, nrChoices - 1);
 
  167        obsChoiceVector[obs] = uniform_dist(engine);
 
  170    for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
 
  171        STORM_LOG_DEBUG(
"State " << state << 
" -- Random Choice " << obsChoiceVector[pomdp.getObservation(state)]);
 
  172        pomdpScheduler.setChoice(obsChoiceVector[pomdp.getObservation(state)], state);
 
  175    auto scheduledModel = underlyingMdp->applyScheduler(pomdpScheduler, 
false);
 
  177    auto resultPtr = storm::api::verifyWithSparseEngine<ValueType>(env, scheduledModel, storm::api::createTask<ValueType>(formula.
asSharedPointer(), 
false));
 
  178    STORM_LOG_THROW(resultPtr, storm::exceptions::UnexpectedException, 
"No check result obtained.");
 
  179    STORM_LOG_THROW(resultPtr->isExplicitQuantitativeCheckResult(), storm::exceptions::UnexpectedException, 
"Unexpected Check result Type");
 
  180    std::vector<ValueType> pomdpSchedulerResult = std::move(resultPtr->template asExplicitQuantitativeCheckResult<ValueType>().getValueVector());
 
  182    STORM_LOG_DEBUG(
"Initial Value for guessed Policy: " << pomdpSchedulerResult[pomdp.getInitialStates().getNextSetIndex(0)]);
 
  184    return std::make_pair(pomdpSchedulerResult, pomdpScheduler);
 
  187template<
typename ValueType>
 
  191                    "The property type is not supported for this analysis.");
 
  197        std::make_shared<storm::models::sparse::Mdp<ValueType>>(pomdp.getTransitionMatrix(), pomdp.getStateLabeling(), pomdp.getRewardModels());
 
  198    auto resultPtr = storm::api::verifyWithSparseEngine<ValueType>(env, underlyingMdp, storm::api::createTask<ValueType>(formula.
asSharedPointer(), 
false));
 
  199    STORM_LOG_THROW(resultPtr, storm::exceptions::UnexpectedException, 
"No check result obtained.");
 
  200    STORM_LOG_THROW(resultPtr->isExplicitQuantitativeCheckResult(), storm::exceptions::UnexpectedException, 
"Unexpected Check result Type");
 
  201    std::vector<ValueType> fullyObservableResult = std::move(resultPtr->template asExplicitQuantitativeCheckResult<ValueType>().getValueVector());
 
  203    std::vector<ValueType> actionBasedRewards;
 
  204    std::vector<ValueType>* actionBasedRewardsPtr = 
nullptr;
 
  206        actionBasedRewards = pomdp.getRewardModel(info.
getRewardModelName()).getTotalRewardVector(pomdp.getTransitionMatrix());
 
  207        actionBasedRewardsPtr = &actionBasedRewards;
 
  209    std::vector<std::vector<ValueType>> guessedSchedulerValues;
 
  210    std::vector<storm::storage::Scheduler<ValueType>> guessedSchedulers;
 
  212    std::vector<std::pair<double, bool>> guessParameters({{0.875, 
false}, {0.875, 
true}, {0.75, 
false}, {0.75, 
true}});
 
  213    for (
auto const& pars : guessParameters) {
 
  215            computeValuesForGuessedScheduler(env, fullyObservableResult, actionBasedRewardsPtr, formula, info, underlyingMdp,
 
  216                                             storm::utility::convertNumber<ValueType>(pars.first), pars.second));
 
  217        guessedSchedulerValues.push_back(guessedSchedulerPair->first);
 
  218        guessedSchedulers.push_back(guessedSchedulerPair->second);
 
  222    uint64_t bestGuess = 0;
 
  223    ValueType bestGuessSum = std::accumulate(guessedSchedulerValues.front().begin(), guessedSchedulerValues.front().end(), storm::utility::zero<ValueType>());
 
  224    for (uint64_t guess = 1; guess < guessedSchedulerValues.size(); ++guess) {
 
  225        ValueType guessSum = std::accumulate(guessedSchedulerValues[guess].begin(), guessedSchedulerValues[guess].end(), storm::utility::zero<ValueType>());
 
  226        if ((info.
minimize() && guessSum < bestGuessSum) || (info.
maximize() && guessSum > bestGuessSum)) {
 
  228            bestGuessSum = guessSum;
 
  232        computeValuesForGuessedScheduler(env, guessedSchedulerValues[bestGuess], actionBasedRewardsPtr, formula, info, underlyingMdp,
 
  233                                         storm::utility::convertNumber<ValueType>(guessParameters[bestGuess].first), guessParameters[bestGuess].second));
 
  234    guessedSchedulerValues.push_back(guessedSchedulerPair->first);
 
  235    guessedSchedulers.push_back(guessedSchedulerPair->second);
 
  237        computeValuesForGuessedScheduler(env, guessedSchedulerValues.back(), actionBasedRewardsPtr, formula, info, underlyingMdp,
 
  238                                         storm::utility::convertNumber<ValueType>(guessParameters[bestGuess].first), guessParameters[bestGuess].second));
 
  239    guessedSchedulerValues.push_back(guessedSchedulerPair->first);
 
  240    guessedSchedulers.push_back(guessedSchedulerPair->second);
 
  242        computeValuesForGuessedScheduler(env, guessedSchedulerValues.back(), actionBasedRewardsPtr, formula, info, underlyingMdp,
 
  243                                         storm::utility::convertNumber<ValueType>(guessParameters[bestGuess].first), guessParameters[bestGuess].second));
 
  244    guessedSchedulerValues.push_back(guessedSchedulerPair->first);
 
  245    guessedSchedulers.push_back(guessedSchedulerPair->second);
 
  250    for (uint64_t i = 0; i < guessedSchedulerValues.size() - 1; ++i) {
 
  251        if (!keptGuesses.
get(i)) {
 
  254        for (uint64_t j = i + 1; j < guessedSchedulerValues.size(); ++j) {
 
  255            if (!keptGuesses.
get(j)) {
 
  261                    keptGuesses.
set(j, 
false);
 
  264                    keptGuesses.
set(i, 
false);
 
  269                    keptGuesses.
set(i, 
false);
 
  272                    keptGuesses.
set(j, 
false);
 
  279    std::vector<storm::storage::Scheduler<ValueType>> filteredSchedulers;
 
  280    for (uint64_t i = 0; i < guessedSchedulers.size(); ++i) {
 
  281        if (keptGuesses[i]) {
 
  282            filteredSchedulers.push_back(guessedSchedulers[i]);
 
  289        result.
lower.push_back(std::move(fullyObservableResult));
 
  290        result.
upper = std::move(guessedSchedulerValues);
 
  293        result.
lower = std::move(guessedSchedulerValues);
 
  294        result.
upper.push_back(std::move(fullyObservableResult));
 
  298                              "Lower bound is larger than upper bound");
 
 
  302template<
typename ValueType>
 
  306    return getExtremeValueBound(env, formula);
 
 
  309template<
typename ValueType>
 
  315template<
typename ValueType>
 
  329    auto formulaPtr = std::make_shared<storm::logic::RewardOperatorFormula>(newFormula);
 
  331        std::make_shared<storm::models::sparse::Mdp<ValueType>>(pomdp.getTransitionMatrix(), pomdp.getStateLabeling(), pomdp.getRewardModels());
 
  332    auto resultPtr = storm::api::verifyWithSparseEngine<ValueType>(env, underlyingMdp, storm::api::createTask<ValueType>(formulaPtr, 
false));
 
  333    STORM_LOG_THROW(resultPtr, storm::exceptions::UnexpectedException, 
"No check result obtained.");
 
  334    STORM_LOG_THROW(resultPtr->isExplicitQuantitativeCheckResult(), storm::exceptions::UnexpectedException, 
"Unexpected Check result Type");
 
  335    std::vector<ValueType> resultVec = std::move(resultPtr->template asExplicitQuantitativeCheckResult<ValueType>().getValueVector());
 
  343    res.
values = std::move(resultVec);
 
 
This class represents a (discrete-time) Markov decision process.
 
This class represents a partially observable Markov decision process.
 
PreprocessingPomdpValueBoundsModelChecker(storm::models::sparse::Pomdp< ValueType > const &pomdp)
 
ExtremeValueBound getExtremeValueBound(storm::logic::Formula const &formula)
 
ValueBounds getValueBounds(storm::logic::Formula const &formula)
 
A bit vector that is internally represented as a vector of 64-bit values.
 
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
 
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
 
PomdpMemory build(PomdpMemoryPattern pattern, uint64_t numStates) const
 
This class defines which action is chosen in a particular state of a non-deterministic model.
 
#define STORM_LOG_INFO(message)
 
#define STORM_LOG_DEBUG(message)
 
#define STORM_LOG_ASSERT(cond, message)
 
#define STORM_LOG_THROW(cond, exception, message)
 
#define STORM_LOG_WARN_COND_DEBUG(cond, message)
 
SFTBDDChecker::ValueType ValueType
 
FormulaInformation getFormulaInformation(PomdpType const &pomdp, storm::logic::ProbabilityOperatorFormula const &formula)
 
bool compareElementWise(std::vector< T > const &left, std::vector< T > const &right, Comparator comp=std::less< T >())
 
storm::storage::BitVector filterInfinity(std::vector< T > const &values)
Retrieves a bit vector containing all the indices for which the value at this position is equal to on...
 
void filterVectorInPlace(std::vector< Type > &v, storm::storage::BitVector const &filter)
 
bool isZero(ValueType const &a)
 
bool isInfinity(ValueType const &a)
 
Struct to store the extreme bound values needed for the reward correction values when clipping is use...
 
std::vector< ValueType > values
 
storm::storage::BitVector isInfinite
 
Struct for storing precomputed values bounding the actual values on the POMDP.
 
std::vector< std::vector< ValueType > > upper
 
std::vector< std::vector< ValueType > > lower
 
std::vector< storm::storage::Scheduler< ValueType > > lowerSchedulers
 
std::vector< storm::storage::Scheduler< ValueType > > upperSchedulers