Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DftModularizationChecker.cpp
Go to the documentation of this file.
2
3#include <sstream>
4
11
15
16namespace storm::dft {
17namespace modelchecker {
18
19template<typename ValueType>
21 : dft{dft}, modelchecker(true), sylvanBddManager{std::make_shared<storm::dft::storage::SylvanBddManager>()} {
22 // Initialize modules
24 auto topModule = modularizer.computeModules(*dft);
25 STORM_LOG_DEBUG("Modularization found the following modules:\n" << topModule.toString(*dft));
26
27 // Gather all dynamic modules
28 populateDynamicModules(topModule);
29}
30
31template<typename ValueType>
33 if (!module.isStatic()) {
34 // Found new dynamic module
35 dynamicModules.push_back(module);
36 } else if (!module.isFullyStatic()) {
37 // Module contains dynamic sub-modules -> recursively visit children
38 for (auto const& submodule : module.getSubModules()) {
39 populateDynamicModules(submodule);
40 }
41 }
42}
43
44template<typename ValueType>
45std::vector<ValueType> DftModularizationChecker<ValueType>::check(FormulaVector const& formulas, size_t chunksize) {
46 // Gather time points
48 std::set<ValueType> timepointSet;
49 for (auto const& formula : formulas) {
51 }
52 std::vector<ValueType> timepoints(timepointSet.begin(), timepointSet.end());
53
54 auto newDft = replaceDynamicModules(timepoints);
55
56 storm::dft::adapters::SFTBDDPropertyFormulaAdapter checker{newDft, formulas, {}, sylvanBddManager};
57 return checker.check(chunksize);
58}
59
60template<typename ValueType>
61std::vector<ValueType> DftModularizationChecker<ValueType>::getProbabilitiesAtTimepoints(std::vector<ValueType> const& timepoints, size_t chunksize) {
62 auto newDft = replaceDynamicModules(timepoints);
63 storm::dft::modelchecker::SFTBDDChecker checker{newDft, sylvanBddManager};
64 return checker.getProbabilitiesAtTimepoints(timepoints, chunksize);
65}
66
67template<typename ValueType>
68std::shared_ptr<storm::dft::storage::DFT<ValueType>> DftModularizationChecker<ValueType>::replaceDynamicModules(std::vector<ValueType> const& timepoints) {
69 // Map from module representatives to their sample points
70 std::map<size_t, std::map<ValueType, ValueType>> samplePoints;
71
72 // First analyse all dynamic modules
73 for (auto const& mod : dynamicModules) {
74 STORM_LOG_DEBUG("Analyse dynamic module " << mod.toString(*dft));
75 auto result = analyseDynamicModule(mod, timepoints);
76 // Remember probabilities for module
77 std::map<ValueType, ValueType> activeSamples{};
78 for (size_t i{0}; i < timepoints.size(); ++i) {
79 auto const probability{boost::get<ValueType>(result[i])};
80 auto const timebound{timepoints[i]};
81 activeSamples[timebound] = probability;
82 }
83 samplePoints.insert({mod.getRepresentative(), activeSamples});
84 }
85
86 // Gather all elements contained in dynamic modules
87 std::set<size_t> dynamicElements;
88 for (auto const& mod : dynamicModules) {
89 dynamicElements.merge(mod.getAllElements());
90 }
91
92 // Replace each dynamic module by a single BE which has samples corresponding to the previously computed analysis results
94 std::unordered_set<std::string> depInConflict;
95 for (auto const id : dft->getAllIds()) {
96 auto const element{dft->getElement(id)};
97 auto it = samplePoints.find(id);
98 if (it != samplePoints.end()) {
99 // Replace element by BE
100 builder.addBasicElementSamples(element->name(), it->second);
101 } else if (dynamicElements.find(id) == dynamicElements.end()) {
102 // Element is not part of a dynamic module -> keep
103 builder.cloneElement(element);
104 // Remember dependency conflict
105 if (element->isDependency() && dft->isDependencyInConflict(id)) {
106 depInConflict.insert(element->name());
107 }
108 }
109 }
110 builder.setTopLevel(dft->getTopLevelElement()->name());
111
112 auto newDft = std::make_shared<storm::dft::storage::DFT<ValueType>>(builder.build());
113 // Update dependency conflicts
114 for (size_t id : newDft->getDependencies()) {
115 // Set dependencies not in conflict
116 if (depInConflict.find(newDft->getElement(id)->name()) == depInConflict.end()) {
117 newDft->setDependencyNotInConflict(id);
118 }
119 }
120 STORM_LOG_DEBUG("Remaining static FT: " << newDft->getElementsString());
121 return newDft;
122}
123
124template<typename ValueType>
125typename storm::dft::modelchecker::DFTModelChecker<ValueType>::dft_results DftModularizationChecker<ValueType>::analyseDynamicModule(
126 storm::dft::storage::DftIndependentModule const& module, std::vector<ValueType> const& timepoints) {
127 STORM_LOG_ASSERT(!module.isStatic() && !module.isFullyStatic(), "Module should be dynamic.");
128 STORM_LOG_ASSERT(!dft->getElement(module.getRepresentative())->isBasicElement(), "Dynamic module should not be a single BE.");
129
130 auto subDft = module.getSubtree(*dft);
131
132 // Create properties
133 std::stringstream propertyStream{};
134 for (auto const timebound : timepoints) {
135 propertyStream << "Pmin=? [F<=" << timebound << "\"failed\"];";
136 }
137 auto const props{storm::api::extractFormulasFromProperties(storm::api::parseProperties(propertyStream.str()))};
138
139 return std::move(modelchecker.check(subDft, props, false, false, {}));
140}
141
142// Explicitly instantiate the class.
143template class DftModularizationChecker<double>;
144
145} // namespace modelchecker
146} // namespace storm::dft
static double getTimebound(FormulaCPointer const &formula)
std::vector< ValueType > check(size_t const chunksize=0)
Calculate the properties specified by the formulas.
static void checkForm(FormulaVector const &formulas)
Check if the formulas are of the form 'P=? [F op phi]' where op is in {<=, <, =} and phi is a state f...
void addBasicElementSamples(std::string const &name, std::map< ValueType, ValueType > const &activeSamples)
Create BE with distribution given by sample points and add it to DFT.
std::vector< boost::variant< ValueType, approximation_result > > dft_results
typename DFTModelChecker< ValueType >::property_vector FormulaVector
DftModularizationChecker(std::shared_ptr< storm::dft::storage::DFT< ValueType > > dft)
Initializes and computes all modules.
std::vector< ValueType > getProbabilitiesAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
Calculate the probability of failure for the given time points.
std::vector< ValueType > check(FormulaVector const &formulas, size_t chunksize=0)
Calculate the properties specified by the formulas.
Main class for the SFTBDDChecker.
std::vector< ValueType > getProbabilitiesAtTimepoints(std::vector< ValueType > const &timepoints, size_t const chunksize=0)
Represents a Dynamic Fault Tree.
Definition DFT.h:52
Represents an independent module/subtree.
Definition DftModule.h:66
bool isStatic() const
Returns whether the module contains only static elements (except in sub-modules).
Definition DftModule.h:85
bool isFullyStatic() const
Returns whether the module contains only static elements (also in sub-modules).
Definition DftModule.h:93
size_t getRepresentative() const
Get representative (top element of subtree).
Definition DftModule.h:31
Find modules (independent subtrees) in DFT.
storm::dft::storage::DftIndependentModule computeModules(storm::dft::storage::DFT< ValueType > const &dft)
Compute modules of DFT by applying the LTA/DR algorithm.
#define STORM_LOG_DEBUG(message)
Definition logging.h:23
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
IntegerType mod(IntegerType const &first, IntegerType const &second)
LabParser.cpp.
Definition cli.cpp:18