4 changed files with 218 additions and 63 deletions
-
158src/modelchecker/DFTAnalyser.h
-
40src/storage/dft/DFT.cpp
-
7src/storage/dft/DFT.h
-
76src/storm-dyftee.cpp
@ -0,0 +1,158 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "logic/Formula.h" |
||||
|
#include "parser/DFTGalileoParser.h" |
||||
|
#include "builder/ExplicitDFTModelBuilder.h" |
||||
|
#include "modelchecker/results/CheckResult.h" |
||||
|
#include "utility/storm.h" |
||||
|
#include "storage/dft/DFTIsomorphism.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> dft , std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true) { |
||||
|
|
||||
|
// Building DFT |
||||
|
std::chrono::high_resolution_clock::time_point totalStart = std::chrono::high_resolution_clock::now(); |
||||
|
|
||||
|
|
||||
|
// Optimizing DFT |
||||
|
dft = dft.optimize(); |
||||
|
std::vector<storm::storage::DFT<ValueType>> dfts; |
||||
|
checkResult = checkHelper(dft, formula, symred, allowModularisation); |
||||
|
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) { |
||||
|
std::cout << "check helper called" << std::endl; |
||||
|
bool invResults = false; |
||||
|
std::vector<storm::storage::DFT<ValueType>> dfts = {dft}; |
||||
|
std::vector<ValueType> res; |
||||
|
|
||||
|
if(allowModularisation) { |
||||
|
std::cout << dft.topLevelType() << std::endl; |
||||
|
if(dft.topLevelType() == storm::storage::DFTElementType::AND) { |
||||
|
std::cout << "top modularisation called AND" << std::endl; |
||||
|
dfts = dft.topModularisation(); |
||||
|
if(dfts.size() > 1) { |
||||
|
for(auto const ft : dfts) { |
||||
|
res.push_back(checkHelper(ft, formula, symred, allowModularisation)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if(dft.topLevelType() == storm::storage::DFTElementType::OR) { |
||||
|
std::cout << "top modularisation called OR" << std::endl; |
||||
|
dfts = dft.topModularisation(); |
||||
|
if(dfts.size() > 1) { |
||||
|
for(auto const ft : dfts) { |
||||
|
res.push_back(checkHelper(ft, formula, symred, allowModularisation)); |
||||
|
} |
||||
|
} |
||||
|
invResults = true; |
||||
|
} |
||||
|
} |
||||
|
if(res.empty()) { |
||||
|
// Model based modularisation. |
||||
|
auto const& models = buildMarkovModels(dfts, formula, symred); |
||||
|
|
||||
|
|
||||
|
for (auto const& model : models) { |
||||
|
// Model checking |
||||
|
std::cout << "Model checking..." << std::endl; |
||||
|
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)); |
||||
|
std::cout << "done." << std::endl; |
||||
|
assert(result); |
||||
|
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); |
||||
|
modelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingStart; |
||||
|
res.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ValueType result = storm::utility::one<ValueType>(); |
||||
|
for(auto const& r : res) { |
||||
|
if(invResults) { |
||||
|
result *= storm::utility::one<ValueType>() - r; |
||||
|
} else { |
||||
|
result *= r; |
||||
|
} |
||||
|
} |
||||
|
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) { |
||||
|
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); |
||||
|
std::cout << "Found " << symmetries.groups.size() << " symmetries." << std::endl; |
||||
|
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 |
||||
|
std::cout << "Building Model..." << std::endl; |
||||
|
storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries); |
||||
|
typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula |
||||
|
std::shared_ptr<storm::models::sparse::Model<ValueType>> model = builder.buildModel(labeloptions); |
||||
|
//model->printModelInformationToStream(std::cout); |
||||
|
std::cout << "No. states (Explored): " << model->getNumberOfStates() << std::endl; |
||||
|
std::cout << "No. transitions (Explored): " << model->getNumberOfTransitions() << std::endl; |
||||
|
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)) { |
||||
|
std::cout << "Bisimulation..." << std::endl; |
||||
|
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); |
||||
|
} |
||||
|
std::cout << "No. states (Bisimulation): " << model->getNumberOfStates() << std::endl; |
||||
|
std::cout << "No. transitions (Bisimulation): " << model->getNumberOfTransitions() << std::endl; |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue