#include "storm/modelchecker/rpatl/SparseSmgRpatlModelChecker.h" #include #include #include "storm/utility/macros.h" #include "storm/utility/FilteredRewardModel.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/modelchecker/helper/infinitehorizon/SparseNondeterministicGameInfiniteHorizonHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/logic/FragmentSpecification.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace modelchecker { template SparseSmgRpatlModelChecker::SparseSmgRpatlModelChecker(SparseSmgModelType const& model) : SparsePropositionalModelChecker(model) { // Intentionally left empty. } template bool SparseSmgRpatlModelChecker::canHandleStatic(CheckTask const& checkTask, bool* requiresSingleInitialState) { storm::logic::Formula const& formula = checkTask.getFormula(); if (formula.isInFragment(storm::logic::rpatl().setCoalitionOperatorsAllowed(true).setRewardOperatorsAllowed(true).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setLongRunAverageOperatorsAllowed(true))) { return true; } else { return false; } } template bool SparseSmgRpatlModelChecker::canHandle(CheckTask const& checkTask) const { bool requiresSingleInitialState = false; if (canHandleStatic(checkTask, &requiresSingleInitialState)) { return !requiresSingleInitialState || this->getModel().getInitialStates().getNumberOfSetBits() == 1; } else { return false; } } template std::unique_ptr SparseSmgRpatlModelChecker::checkGameFormula(Environment const& env, CheckTask const& checkTask) { STORM_LOG_DEBUG("checkGameFormula matrix: " << this->getModel().getTransitionMatrix().getDimensionsAsString()); STORM_LOG_DEBUG("checkGameFormula playerindices:"); STORM_LOG_DEBUG("checkGameFormula matrix: \n" << this->getModel().getTransitionMatrix()); // TODO set min max row groups w.r.t. coalition storm::logic::GameFormula const& gameFormula = checkTask.getFormula(); storm::logic::Formula const& subFormula = gameFormula.getSubformula(); STORM_LOG_DEBUG(gameFormula); if (subFormula.isRewardOperatorFormula()) { return this->checkRewardOperatorFormula(env, checkTask.substituteFormula(subFormula.asRewardOperatorFormula())); } else if (subFormula.isLongRunAverageOperatorFormula()) { return this->checkLongRunAverageOperatorFormula(env, checkTask.substituteFormula(subFormula.asLongRunAverageOperatorFormula())); } STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "checkGameFormula NYI"); } template std::unique_ptr SparseSmgRpatlModelChecker::checkRewardOperatorFormula(Environment const& env, CheckTask const& checkTask) { storm::logic::RewardOperatorFormula const& formula = checkTask.getFormula(); std::unique_ptr result = this->computeRewards(env, formula.getMeasureType(), checkTask.substituteFormula(formula.getSubformula())); return nullptr; } template std::unique_ptr AbstractModelChecker::computeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask const& checkTask) { storm::logic::Formula const& rewardFormula = checkTask.getFormula(); if (rewardFormula.isLongRunAverageRewardFormula()) { return this->computeLongRunAverageRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardFormula << "' is invalid."); } template std::unique_ptr AbstractModelChecker::checkLongRunAverageOperatorFormula(Environment const& env, CheckTask const& checkTask) { storm::logic::LongRunAverageOperatorFormula const& formula = checkTask.getFormula(); //STORM_LOG_THROW(formula.getSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); std::unique_ptr result = this->computeLongRunAverageProbabilities(env, checkTask.substituteFormula(formula.getSubformula().asStateFormula())); return result; //TODO check bounds. } template std::unique_ptr SparseSmgRpatlModelChecker::computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "NYI"); } template std::unique_ptr SparseSmgRpatlModelChecker::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); storm::modelchecker::helper::SparseNondeterministicGameInfiniteHorizonHelper helper(this->getModel().getTransitionMatrix(), this->getModel().getPlayerActionIndices()); storm::modelchecker::helper::setInformationFromCheckTaskNondeterministic(helper, checkTask, this->getModel()); auto values = helper.computeLongRunAverageRewards(env, rewardModel.get()); //std::unique_ptr result(new ExplicitQuantitativeCheckResult(std::move(values)); //return result; STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "NYI"); template void SparseSmgRpatlModelChecker::coalitionIndicator(Environment& env, CheckTask const& checkTask) { storm::storage::BitVector coalitionIndicators(this->getModel().getTransitionMatrix().getRowGroupCount()); std::vector> formulaPlayerIds = checkTask.getFormula().getCoalition().getPlayerIds(); std::vector playerIds; std::vector> playerActionIndices = this->getModel().getPlayerActionIndices(); for(auto const& player : formulaPlayerIds) { // If the player is given via the player name we have to look up its index if(player.type() == typeid(std::string)) { auto it = std::find_if(playerActionIndices.begin(), playerActionIndices.end(), [&player](const std::pair& element){ return element.first == boost::get(player); }); playerIds.push_back(it->second); // If the player is given by its index we have to shift it to match internal mappings } else if(player.type() == typeid(uint_fast64_t)) { playerIds.push_back(boost::get(player) - 1); } } for(uint i = 0; i < playerActionIndices.size(); i++) { if(std::find(playerIds.begin(), playerIds.end(), playerActionIndices.at(i).second) != playerIds.end()) { coalitionIndicators.set(i); } } coalitionIndicators.complement(); env.solver().multiplier().setOptimizationDirectionOverride(coalitionIndicators); } template class SparseSmgRpatlModelChecker>; #ifdef STORM_HAVE_CARL template class SparseSmgRpatlModelChecker>; //template class SparseSmgRpatlModelChecker>; TODO are we going to need this? #endif } }