8 changed files with 359 additions and 232 deletions
-
4resources/3rdparty/CMakeLists.txt
-
2src/CMakeLists.txt
-
41src/generator/DftNextStateGenerator.cpp
-
5src/generator/DftNextStateGenerator.h
-
201src/modelchecker/DFTAnalyser.h
-
214src/modelchecker/dft/DFTModelChecker.cpp
-
104src/modelchecker/dft/DFTModelChecker.h
-
20src/storm-dyftee.cpp
@ -1,201 +0,0 @@ |
|||||
#pragma once |
|
||||
|
|
||||
#include "src/logic/Formula.h" |
|
||||
#include "src/parser/DFTGalileoParser.h" |
|
||||
#include "src/builder/ExplicitDFTModelBuilder.h" |
|
||||
#include "src/builder/ExplicitDFTModelBuilderApprox.h" |
|
||||
#include "src/modelchecker/results/CheckResult.h" |
|
||||
#include "src/utility/storm.h" |
|
||||
#include "src/storage/dft/DFTIsomorphism.h" |
|
||||
#include "src/settings/modules/DFTSettings.h" |
|
||||
#include "src/utility/bitoperations.h" |
|
||||
|
|
||||
|
|
||||
#include <chrono> |
|
||||
|
|
||||
template<typename ValueType> |
|
||||
class DFTAnalyser { |
|
||||
|
|
||||
std::chrono::duration<double> buildingTime = std::chrono::duration<double>::zero(); |
|
||||
std::chrono::duration<double> explorationTime = std::chrono::duration<double>::zero(); |
|
||||
std::chrono::duration<double> bisimulationTime = std::chrono::duration<double>::zero(); |
|
||||
std::chrono::duration<double> modelCheckingTime = std::chrono::duration<double>::zero(); |
|
||||
std::chrono::duration<double> totalTime = std::chrono::duration<double>::zero(); |
|
||||
ValueType checkResult = storm::utility::zero<ValueType>(); |
|
||||
public: |
|
||||
void check(storm::storage::DFT<ValueType> const& origDft , std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true) { |
|
||||
|
|
||||
// Building DFT |
|
||||
std::chrono::high_resolution_clock::time_point totalStart = std::chrono::high_resolution_clock::now(); |
|
||||
|
|
||||
|
|
||||
// Optimizing DFT |
|
||||
storm::storage::DFT<ValueType> dft = origDft.optimize(); |
|
||||
checkResult = checkHelper(dft, formula, symred, allowModularisation, enableDC); |
|
||||
totalTime = std::chrono::high_resolution_clock::now() - totalStart; |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
ValueType checkHelper(storm::storage::DFT<ValueType> const& dft , std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true) { |
|
||||
STORM_LOG_TRACE("Check helper called"); |
|
||||
bool invResults = false; |
|
||||
std::vector<storm::storage::DFT<ValueType>> dfts = {dft}; |
|
||||
std::vector<ValueType> res; |
|
||||
size_t nrK = 0; // K out of M |
|
||||
size_t nrM = 0; // K out of M |
|
||||
|
|
||||
if(allowModularisation) { |
|
||||
if(dft.topLevelType() == storm::storage::DFTElementType::AND) { |
|
||||
STORM_LOG_TRACE("top modularisation called AND"); |
|
||||
dfts = dft.topModularisation(); |
|
||||
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
|
||||
nrK = dfts.size(); |
|
||||
nrM = dfts.size(); |
|
||||
} |
|
||||
if(dft.topLevelType() == storm::storage::DFTElementType::OR) { |
|
||||
STORM_LOG_TRACE("top modularisation called OR"); |
|
||||
dfts = dft.topModularisation(); |
|
||||
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
|
||||
nrK = 0; |
|
||||
nrM = dfts.size(); |
|
||||
invResults = true; |
|
||||
} |
|
||||
if(dft.topLevelType() == storm::storage::DFTElementType::VOT) { |
|
||||
STORM_LOG_TRACE("top modularisation called VOT"); |
|
||||
dfts = dft.topModularisation(); |
|
||||
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
|
||||
nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); |
|
||||
nrM = dfts.size(); |
|
||||
if(nrK <= nrM/2) { |
|
||||
nrK -= 1; |
|
||||
invResults = true; |
|
||||
} |
|
||||
} |
|
||||
if(dfts.size() > 1) { |
|
||||
STORM_LOG_TRACE("Recursive CHECK Call"); |
|
||||
for(auto const ft : dfts) { |
|
||||
res.push_back(checkHelper(ft, formula, symred, allowModularisation)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if(res.empty()) { |
|
||||
// Model based modularisation. |
|
||||
auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); |
|
||||
|
|
||||
|
|
||||
for (auto const& model : models) { |
|
||||
// Model checking |
|
||||
STORM_LOG_INFO("Model checking..."); |
|
||||
std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); |
|
||||
std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); |
|
||||
STORM_LOG_INFO("Model checking done."); |
|
||||
STORM_LOG_ASSERT(result, "Result does not exist."); |
|
||||
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); |
|
||||
modelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingStart; |
|
||||
res.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); |
|
||||
} |
|
||||
} |
|
||||
if(nrM <= 1) { |
|
||||
// No modularisation done. |
|
||||
STORM_LOG_ASSERT(res.size()==1, "Result size not 1."); |
|
||||
return res[0]; |
|
||||
} |
|
||||
|
|
||||
STORM_LOG_TRACE("Combining all results... K=" << nrK << "; M=" << nrM << "; invResults=" << (invResults?"On":"Off")); |
|
||||
ValueType result = storm::utility::zero<ValueType>(); |
|
||||
int limK = invResults ? -1 : nrM+1; |
|
||||
int chK = invResults ? -1 : 1; |
|
||||
for(int cK = nrK; cK != limK; cK += chK ) { |
|
||||
STORM_LOG_ASSERT(cK >= 0, "ck negative."); |
|
||||
size_t permutation = smallestIntWithNBitsSet(static_cast<size_t>(cK)); |
|
||||
do { |
|
||||
STORM_LOG_TRACE("Permutation="<<permutation); |
|
||||
ValueType permResult = storm::utility::one<ValueType>(); |
|
||||
for(size_t i = 0; i < res.size(); ++i) { |
|
||||
if(permutation & (1 << i)) { |
|
||||
permResult *= res[i]; |
|
||||
} else { |
|
||||
permResult *= storm::utility::one<ValueType>() - res[i]; |
|
||||
} |
|
||||
} |
|
||||
STORM_LOG_TRACE("Result for permutation:"<<permResult); |
|
||||
permutation = nextBitPermutation(permutation); |
|
||||
result += permResult; |
|
||||
} while(permutation < (1 << nrM) && permutation != 0); |
|
||||
} |
|
||||
if(invResults) { |
|
||||
return storm::utility::one<ValueType>() - result; |
|
||||
} |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC) { |
|
||||
std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> models; |
|
||||
for(auto& dft : dfts) { |
|
||||
std::chrono::high_resolution_clock::time_point buildingStart = std::chrono::high_resolution_clock::now(); |
|
||||
|
|
||||
std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry; |
|
||||
storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry); |
|
||||
if(symred) { |
|
||||
auto colouring = dft.colourDFT(); |
|
||||
symmetries = dft.findSymmetries(colouring); |
|
||||
STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); |
|
||||
STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); |
|
||||
} |
|
||||
std::chrono::high_resolution_clock::time_point buildingEnd = std::chrono::high_resolution_clock::now(); |
|
||||
buildingTime += buildingEnd - buildingStart; |
|
||||
|
|
||||
// Building Markov Automaton |
|
||||
STORM_LOG_INFO("Building Model..."); |
|
||||
std::shared_ptr<storm::models::sparse::Model<ValueType>> model; |
|
||||
// TODO Matthias: use only one builder if everything works again |
|
||||
if (storm::settings::getModule<storm::settings::modules::DFTSettings>().computeApproximation()) { |
|
||||
storm::builder::ExplicitDFTModelBuilderApprox<ValueType> builder(dft, symmetries, enableDC); |
|
||||
typename storm::builder::ExplicitDFTModelBuilderApprox<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula |
|
||||
model = builder.buildModel(labeloptions); |
|
||||
} else { |
|
||||
storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); |
|
||||
typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula |
|
||||
model = builder.buildModel(labeloptions); |
|
||||
} |
|
||||
//model->printModelInformationToStream(std::cout); |
|
||||
STORM_LOG_INFO("No. states (Explored): " << model->getNumberOfStates()); |
|
||||
STORM_LOG_INFO("No. transitions (Explored): " << model->getNumberOfTransitions()); |
|
||||
std::chrono::high_resolution_clock::time_point explorationEnd = std::chrono::high_resolution_clock::now(); |
|
||||
explorationTime += explorationEnd -buildingEnd; |
|
||||
|
|
||||
// Bisimulation |
|
||||
if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { |
|
||||
STORM_LOG_INFO("Bisimulation..."); |
|
||||
model = storm::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), {formula}, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); |
|
||||
//model->printModelInformationToStream(std::cout); |
|
||||
} |
|
||||
STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); |
|
||||
STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); |
|
||||
bisimulationTime += std::chrono::high_resolution_clock::now() - explorationEnd; |
|
||||
models.push_back(model); |
|
||||
} |
|
||||
return models; |
|
||||
} |
|
||||
|
|
||||
public: |
|
||||
void printTimings(std::ostream& os = std::cout) { |
|
||||
os << "Times:" << std::endl; |
|
||||
os << "Building:\t" << buildingTime.count() << std::endl; |
|
||||
os << "Exploration:\t" << explorationTime.count() << std::endl; |
|
||||
os << "Bisimulation:\t" << bisimulationTime.count() << std::endl; |
|
||||
os << "Modelchecking:\t" << modelCheckingTime.count() << std::endl; |
|
||||
os << "Total:\t\t" << totalTime.count() << std::endl; |
|
||||
} |
|
||||
|
|
||||
void printResult(std::ostream& os = std::cout) { |
|
||||
|
|
||||
os << "Result: ["; |
|
||||
os << checkResult << "]" << std::endl; |
|
||||
} |
|
||||
|
|
||||
}; |
|
@ -0,0 +1,214 @@ |
|||||
|
#include "src/modelchecker/dft/DFTModelChecker.h"
|
||||
|
|
||||
|
#include "src/builder/ExplicitDFTModelBuilder.h"
|
||||
|
#include "src/builder/ExplicitDFTModelBuilderApprox.h"
|
||||
|
#include "src/storage/dft/DFTIsomorphism.h"
|
||||
|
#include "src/settings/modules/DFTSettings.h"
|
||||
|
#include "src/utility/bitoperations.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace modelchecker { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
DFTModelChecker<ValueType>::DFTModelChecker() { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC) { |
||||
|
std::chrono::high_resolution_clock::time_point totalStart = std::chrono::high_resolution_clock::now(); |
||||
|
// Optimizing DFT
|
||||
|
storm::storage::DFT<ValueType> dft = origDft.optimize(); |
||||
|
checkResult = checkHelper(dft, formula, symred, allowModularisation, enableDC); |
||||
|
totalTime = std::chrono::high_resolution_clock::now() - totalStart; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
ValueType DFTModelChecker<ValueType>::checkHelper(storm::storage::DFT<ValueType> const& dft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC) { |
||||
|
STORM_LOG_TRACE("Check helper called"); |
||||
|
bool invResults = false; |
||||
|
std::vector<storm::storage::DFT<ValueType>> dfts = {dft}; |
||||
|
std::vector<ValueType> res; |
||||
|
size_t nrK = 0; // K out of M
|
||||
|
size_t nrM = 0; // K out of M
|
||||
|
|
||||
|
// Try modularisation
|
||||
|
if(allowModularisation) { |
||||
|
if(dft.topLevelType() == storm::storage::DFTElementType::AND) { |
||||
|
STORM_LOG_TRACE("top modularisation called AND"); |
||||
|
dfts = dft.topModularisation(); |
||||
|
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
||||
|
nrK = dfts.size(); |
||||
|
nrM = dfts.size(); |
||||
|
} |
||||
|
if(dft.topLevelType() == storm::storage::DFTElementType::OR) { |
||||
|
STORM_LOG_TRACE("top modularisation called OR"); |
||||
|
dfts = dft.topModularisation(); |
||||
|
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
||||
|
nrK = 0; |
||||
|
nrM = dfts.size(); |
||||
|
invResults = true; |
||||
|
} |
||||
|
if(dft.topLevelType() == storm::storage::DFTElementType::VOT) { |
||||
|
STORM_LOG_TRACE("top modularisation called VOT"); |
||||
|
dfts = dft.topModularisation(); |
||||
|
STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); |
||||
|
nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); |
||||
|
nrM = dfts.size(); |
||||
|
if(nrK <= nrM/2) { |
||||
|
nrK -= 1; |
||||
|
invResults = true; |
||||
|
} |
||||
|
} |
||||
|
if(dfts.size() > 1) { |
||||
|
STORM_LOG_TRACE("Recursive CHECK Call"); |
||||
|
for(auto const ft : dfts) { |
||||
|
res.push_back(checkHelper(ft, formula, symred, allowModularisation, enableDC)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if(res.empty()) { |
||||
|
// Model based modularisation.
|
||||
|
auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); |
||||
|
|
||||
|
for (auto const& model : models) { |
||||
|
// Model checking
|
||||
|
STORM_LOG_INFO("Model checking..."); |
||||
|
std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); |
||||
|
STORM_LOG_INFO("Model checking done."); |
||||
|
STORM_LOG_ASSERT(result, "Result does not exist."); |
||||
|
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); |
||||
|
modelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingStart; |
||||
|
res.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); |
||||
|
} |
||||
|
} |
||||
|
if(nrM <= 1) { |
||||
|
// No modularisation done.
|
||||
|
STORM_LOG_ASSERT(res.size()==1, "Result size not 1."); |
||||
|
return res[0]; |
||||
|
} |
||||
|
|
||||
|
STORM_LOG_TRACE("Combining all results... K=" << nrK << "; M=" << nrM << "; invResults=" << (invResults?"On":"Off")); |
||||
|
ValueType result = storm::utility::zero<ValueType>(); |
||||
|
int limK = invResults ? -1 : nrM+1; |
||||
|
int chK = invResults ? -1 : 1; |
||||
|
for(int cK = nrK; cK != limK; cK += chK ) { |
||||
|
STORM_LOG_ASSERT(cK >= 0, "ck negative."); |
||||
|
size_t permutation = smallestIntWithNBitsSet(static_cast<size_t>(cK)); |
||||
|
do { |
||||
|
STORM_LOG_TRACE("Permutation="<<permutation); |
||||
|
ValueType permResult = storm::utility::one<ValueType>(); |
||||
|
for(size_t i = 0; i < res.size(); ++i) { |
||||
|
if(permutation & (1 << i)) { |
||||
|
permResult *= res[i]; |
||||
|
} else { |
||||
|
permResult *= storm::utility::one<ValueType>() - res[i]; |
||||
|
} |
||||
|
} |
||||
|
STORM_LOG_TRACE("Result for permutation:"<<permResult); |
||||
|
permutation = nextBitPermutation(permutation); |
||||
|
result += permResult; |
||||
|
} while(permutation < (1 << nrM) && permutation != 0); |
||||
|
} |
||||
|
if(invResults) { |
||||
|
return storm::utility::one<ValueType>() - result; |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::vector<ValueType> DFTModelChecker<ValueType>::checkModel(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError) { |
||||
|
std::vector<ValueType> results; |
||||
|
|
||||
|
auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); |
||||
|
|
||||
|
for (auto const& model : models) { |
||||
|
// Model checking
|
||||
|
STORM_LOG_INFO("Model checking..."); |
||||
|
std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); |
||||
|
STORM_LOG_INFO("Model checking done."); |
||||
|
STORM_LOG_ASSERT(result, "Result does not exist."); |
||||
|
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); |
||||
|
modelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingStart; |
||||
|
results.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); |
||||
|
} |
||||
|
return results; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> DFTModelChecker<ValueType>::buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError) { |
||||
|
std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> models; |
||||
|
for(auto& dft : dfts) { |
||||
|
std::chrono::high_resolution_clock::time_point buildingStart = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry; |
||||
|
storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry); |
||||
|
if(symred) { |
||||
|
auto colouring = dft.colourDFT(); |
||||
|
symmetries = dft.findSymmetries(colouring); |
||||
|
STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); |
||||
|
STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); |
||||
|
} |
||||
|
std::chrono::high_resolution_clock::time_point buildingEnd = std::chrono::high_resolution_clock::now(); |
||||
|
buildingTime += buildingEnd - buildingStart; |
||||
|
|
||||
|
// Building Markov Automaton
|
||||
|
STORM_LOG_INFO("Building Model..."); |
||||
|
std::shared_ptr<storm::models::sparse::Model<ValueType>> model; |
||||
|
// TODO Matthias: use only one builder if everything works again
|
||||
|
if (storm::settings::getModule<storm::settings::modules::DFTSettings>().computeApproximation()) { |
||||
|
storm::builder::ExplicitDFTModelBuilderApprox<ValueType> builder(dft, symmetries, enableDC); |
||||
|
typename storm::builder::ExplicitDFTModelBuilderApprox<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula
|
||||
|
model = builder.buildModel(labeloptions); |
||||
|
} else { |
||||
|
storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); |
||||
|
typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula
|
||||
|
model = builder.buildModel(labeloptions); |
||||
|
} |
||||
|
//model->printModelInformationToStream(std::cout);
|
||||
|
STORM_LOG_INFO("No. states (Explored): " << model->getNumberOfStates()); |
||||
|
STORM_LOG_INFO("No. transitions (Explored): " << model->getNumberOfTransitions()); |
||||
|
std::chrono::high_resolution_clock::time_point explorationEnd = std::chrono::high_resolution_clock::now(); |
||||
|
explorationTime += explorationEnd -buildingEnd; |
||||
|
|
||||
|
// Bisimulation
|
||||
|
if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { |
||||
|
STORM_LOG_INFO("Bisimulation..."); |
||||
|
model = storm::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), {formula}, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); |
||||
|
//model->printModelInformationToStream(std::cout);
|
||||
|
} |
||||
|
STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); |
||||
|
STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); |
||||
|
bisimulationTime += std::chrono::high_resolution_clock::now() - explorationEnd; |
||||
|
models.push_back(model); |
||||
|
} |
||||
|
return models; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DFTModelChecker<ValueType>::printTimings(std::ostream& os) { |
||||
|
os << "Times:" << std::endl; |
||||
|
os << "Building:\t" << buildingTime.count() << std::endl; |
||||
|
os << "Exploration:\t" << explorationTime.count() << std::endl; |
||||
|
os << "Bisimulation:\t" << bisimulationTime.count() << std::endl; |
||||
|
os << "Modelchecking:\t" << modelCheckingTime.count() << std::endl; |
||||
|
os << "Total:\t\t" << totalTime.count() << std::endl; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void DFTModelChecker<ValueType>::printResult(std::ostream& os) { |
||||
|
os << "Result: ["; |
||||
|
os << checkResult << "]" << std::endl; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template class DFTModelChecker<double>; |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
template class DFTModelChecker<storm::RationalFunction>; |
||||
|
#endif
|
||||
|
} |
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
#ifndef STORM_MODELCHECKER_DFT_DFTMODELCHECKER_H_ |
||||
|
|
||||
|
#include "src/logic/Formula.h" |
||||
|
#include "src/modelchecker/results/CheckResult.h" |
||||
|
#include "src/storage/dft/DFT.h" |
||||
|
#include "src/utility/storm.h" |
||||
|
|
||||
|
#include <chrono> |
||||
|
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace modelchecker { |
||||
|
|
||||
|
/** |
||||
|
* Analyser for DFTs. |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
class DFTModelChecker { |
||||
|
|
||||
|
public: |
||||
|
|
||||
|
/** |
||||
|
* Constructor. |
||||
|
*/ |
||||
|
DFTModelChecker(); |
||||
|
|
||||
|
/** |
||||
|
* Main method for checking DFTs. |
||||
|
* |
||||
|
* @param origDft Original DFT |
||||
|
* @param formula Formula to check for |
||||
|
* @param symred Flag indicating if symmetry reduction should be used |
||||
|
* @param allowModularisation Flag indication if modularisation is allowed |
||||
|
* @param enableDC Flag indicating if dont care propagation should be used |
||||
|
*/ |
||||
|
void check(storm::storage::DFT<ValueType> const& origDft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true); |
||||
|
|
||||
|
/** |
||||
|
* Print timings of all operations to stream. |
||||
|
* |
||||
|
* @param os Output stream to write to. |
||||
|
*/ |
||||
|
void printTimings(std::ostream& os = std::cout); |
||||
|
|
||||
|
/** |
||||
|
* Print result to stream. |
||||
|
* |
||||
|
* @param os Output stream to write to. |
||||
|
*/ |
||||
|
void printResult(std::ostream& os = std::cout); |
||||
|
|
||||
|
private: |
||||
|
// Timing values |
||||
|
std::chrono::duration<double> buildingTime = std::chrono::duration<double>::zero(); |
||||
|
std::chrono::duration<double> explorationTime = std::chrono::duration<double>::zero(); |
||||
|
std::chrono::duration<double> bisimulationTime = std::chrono::duration<double>::zero(); |
||||
|
std::chrono::duration<double> modelCheckingTime = std::chrono::duration<double>::zero(); |
||||
|
std::chrono::duration<double> totalTime = std::chrono::duration<double>::zero(); |
||||
|
// Model checking result |
||||
|
ValueType checkResult = storm::utility::zero<ValueType>(); |
||||
|
|
||||
|
/** |
||||
|
* Internal helper for model checking a DFT. |
||||
|
* |
||||
|
* @param dft DFT |
||||
|
* @param formula Formula to check for |
||||
|
* @param symred Flag indicating if symmetry reduction should be used |
||||
|
* @param allowModularisation Flag indication if modularisation is allowed |
||||
|
* @param enableDC Flag indicating if dont care propagation should be used |
||||
|
* |
||||
|
* @return Model checking result |
||||
|
*/ |
||||
|
ValueType checkHelper(storm::storage::DFT<ValueType> const& dft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC); |
||||
|
|
||||
|
/** |
||||
|
* Check the Dfts via model checking. |
||||
|
* |
||||
|
* @param dfts Vector of Dfts |
||||
|
* @param formula Formula to check for |
||||
|
* @param symred Flag indicating if symmetry reduction should be used |
||||
|
* @param enableDC Flag indicating if dont care propagation should be used |
||||
|
* @param approximationError Error allowed for approximation. Value 0 indicates no approximation |
||||
|
* |
||||
|
* @return Vector of results for each model |
||||
|
*/ |
||||
|
std::vector<ValueType> checkModel(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError = 0.0); |
||||
|
|
||||
|
/** |
||||
|
* Build markov models from DFTs. |
||||
|
* |
||||
|
* @param dfts Vector of Dfts |
||||
|
* @param formula Formula to check for |
||||
|
* @param symred Flag indicating if symmetry reduction should be used |
||||
|
* @param enableDC Flag indicating if dont care propagation should be used |
||||
|
* @param approximationError Error allowed for approximation. Value 0 indicates no approximation |
||||
|
* |
||||
|
* @return Vector of markov models corresponding to DFTs. |
||||
|
*/ |
||||
|
std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError = 0.0); |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
#endif /* STORM_MODELCHECKER_DFT_DFTMODELCHECKER_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue