/* * File: SamplingModel.cpp * Author: tim * * Created on August 7, 2015, 9:31 AM */ #include "src/modelchecker/region/SamplingModel.h" #include "modelchecker/prctl/SparseDtmcPrctlModelChecker.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "exceptions/UnexpectedException.h" namespace storm { namespace modelchecker { template SparseDtmcRegionModelChecker::SamplingModel::SamplingModel(storm::models::sparse::Dtmc const& parametricModel) : mapping(), evaluationTable(){ // Run through the rows of the original model and obtain the set of distinct functions as well as a matrix with dummy entries std::set functionSet; storm::storage::SparseMatrixBuilder matrixBuilder(parametricModel.getNumberOfStates(), parametricModel.getNumberOfStates(), parametricModel.getTransitionMatrix().getEntryCount()); uint_fast64_t numOfNonConstEntries=0; for(typename storm::storage::SparseMatrix::index_type row=0; row < parametricModel.getTransitionMatrix().getRowCount(); ++row ){ ConstantType dummyEntry=storm::utility::one(); for(auto const& entry : parametricModel.getTransitionMatrix().getRow(row)){ if(!this->parametricTypeComparator.isConstant(entry.getValue())){ functionSet.insert(entry.getValue()); ++numOfNonConstEntries; } matrixBuilder.addNextValue(row,entry.getColumn(), dummyEntry); dummyEntry=storm::utility::zero(); } } //Obtain other model ingredients and the approximation model itself storm::models::sparse::StateLabeling labeling(parametricModel.getStateLabeling()); boost::optional> noStateRewards; boost::optional> noTransitionRewards; boost::optional>> noChoiceLabeling; this->model=std::make_shared>(matrixBuilder.build(), std::move(labeling), std::move(noStateRewards), std::move(noTransitionRewards), std::move(noChoiceLabeling)); //Get the evaluation table. Note that it remains sorted due to the fact that functionSet is sorted this->evaluationTable.reserve(functionSet.size()); for(auto const& func : functionSet){ this->evaluationTable.emplace_back(func, storm::utility::zero()); } //Fill in the entries for the mapping this->mapping.reserve(numOfNonConstEntries); auto samEntry = this->model->getTransitionMatrix().begin(); for(auto const& parEntry : parametricModel.getTransitionMatrix()){ if(this->parametricTypeComparator.isConstant(parEntry.getValue())){ samEntry->setValue(storm::utility::regions::convertNumber(storm::utility::regions::getConstantPart(parEntry.getValue()))); } else { std::pair searchedPair(parEntry.getValue(), storm::utility::zero()); auto const tableIt= std::lower_bound(evaluationTable.begin(), evaluationTable.end(), searchedPair); STORM_LOG_THROW((*tableIt==searchedPair), storm::exceptions::UnexpectedException, "Could not find the current pair in the evaluationTable. Either the table is missing that pair or it is not sorted properly"); mapping.emplace_back(std::make_pair(&(tableIt->second), samEntry)); } ++samEntry; } } template SparseDtmcRegionModelChecker::SamplingModel::~SamplingModel() { //Intentionally left empty } template std::shared_ptr> const& SparseDtmcRegionModelChecker::SamplingModel::getModel() const { return this->model; } template void SparseDtmcRegionModelChecker::SamplingModel::instantiate(std::mapconst& point) { //write entries into evaluation table for(auto& tableEntry : this->evaluationTable){ tableEntry.second=storm::utility::regions::convertNumber( storm::utility::regions::evaluateFunction(tableEntry.first, point)); } //write the instantiated values to the matrix according to the mapping for(auto& mappingPair : this->mapping){ mappingPair.second->setValue(*(mappingPair.first)); } } template std::vector const& SparseDtmcRegionModelChecker::SamplingModel::computeReachabilityProbabilities() { std::shared_ptr targetFormulaPtr(new storm::logic::AtomicLabelFormula("target")); storm::logic::EventuallyFormula eventuallyFormula(targetFormulaPtr); storm::modelchecker::SparseDtmcPrctlModelChecker modelChecker(*this->model); //perform model checking on the mdp std::unique_ptr resultPtr = modelChecker.computeEventuallyProbabilities(eventuallyFormula); return resultPtr->asExplicitQuantitativeCheckResult().getValueVector(); } #ifdef STORM_HAVE_CARL template class SparseDtmcRegionModelChecker::SamplingModel; #endif } }