Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SftToBddTransformator.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <vector>
5
12
13namespace storm::dft {
14namespace transformations {
15
19template<typename ValueType>
21 public:
22#ifdef STORM_HAVE_SYLVAN
23 using Bdd = sylvan::Bdd;
24#endif
25
26#ifdef STORM_HAVE_SYLVAN
27 SftToBddTransformator(std::shared_ptr<storm::dft::storage::DFT<ValueType>> dft, std::shared_ptr<storm::dft::storage::SylvanBddManager> sylvanBddManager,
28 storm::dft::utility::RelevantEvents relevantEvents = {})
29 : dft{std::move(dft)}, sylvanBddManager{std::move(sylvanBddManager)}, relevantEvents{relevantEvents} {
30 // create Variables for the BEs
31 for (auto const& i : this->dft->getBasicElements()) {
32 // Filter constantBeTrigger
33 if (i->name() != "constantBeTrigger") {
34 variables.push_back(this->sylvanBddManager->createVariable(i->name()));
35 }
36 }
37 }
38
48 Bdd const& transformTopLevel() {
49 auto const tlName{dft->getTopLevelElement()->name()};
50 if (relevantEventBdds.empty()) {
51 relevantEventBdds[tlName] = translate(dft->getTopLevelElement());
52 }
53 // else relevantEventBdds is not empty and we maintain the invariant
54 // that the toplevel event is in there
55 STORM_LOG_ASSERT(relevantEventBdds.count(tlName) == 1, "Not all relevantEvents where transformed into BDDs.");
56
57 return relevantEventBdds[tlName];
58 }
59
70 std::map<std::string, Bdd> const& transformRelevantEvents() {
71 if (relevantEventBdds.empty()) {
72 relevantEventBdds[dft->getTopLevelElement()->name()] = translate(dft->getTopLevelElement());
73 }
74
75 // we maintain the invariant that if relevantEventBdds is not empty
76 // then we have calculated all relevant bdds
77 STORM_LOG_ASSERT(relevantEventBdds.size() == relevantEvents.count(getDFT()), "Not all relevantEvents where transformed into BDDs.");
78
79 return relevantEventBdds;
80 }
81
85 std::vector<uint32_t> const& getDdVariables() const noexcept {
86 return variables;
87 }
88
92 std::shared_ptr<storm::dft::storage::DFT<ValueType>> getDFT() const noexcept {
93 return dft;
94 }
95
99 std::shared_ptr<storm::dft::storage::SylvanBddManager> getSylvanBddManager() const noexcept {
100 return sylvanBddManager;
101 }
102#else
103 SftToBddTransformator(std::shared_ptr<storm::dft::storage::DFT<ValueType>> dft, std::shared_ptr<storm::dft::storage::SylvanBddManager> sylvanBddManager,
104 storm::dft::utility::RelevantEvents relevantEvents = {}) {
105 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
106 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
107 "version of Storm with Sylvan support.");
108 }
109
110 std::vector<uint32_t> const& getDdVariables() const noexcept {
111 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
112 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
113 "version of Storm with Sylvan support.");
114 }
115
116 std::shared_ptr<storm::dft::storage::DFT<ValueType>> getDFT() const noexcept {
117 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
118 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
119 "version of Storm with Sylvan support.");
120 }
121
122 std::shared_ptr<storm::dft::storage::SylvanBddManager> getSylvanBddManager() const noexcept {
123 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
124 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
125 "version of Storm with Sylvan support.");
126 }
127#endif
128
129 private:
130#ifdef STORM_HAVE_SYLVAN
131 std::map<std::string, Bdd> relevantEventBdds{};
132 std::vector<uint32_t> variables{};
133 std::shared_ptr<storm::dft::storage::DFT<ValueType>> dft;
134 std::shared_ptr<storm::dft::storage::SylvanBddManager> sylvanBddManager;
136
143 Bdd translate(std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType> const> element) {
144 auto isRelevant{relevantEvents.isRelevant(element->name())};
145 if (isRelevant) {
146 auto const it{relevantEventBdds.find(element->name())};
147 if (it != relevantEventBdds.end()) {
148 return it->second;
149 }
150 }
151
152 Bdd rBdd;
153 if (element->isGate()) {
154 rBdd = translate(std::dynamic_pointer_cast<storm::dft::storage::elements::DFTGate<ValueType> const>(element));
155 } else if (element->isBasicElement()) {
156 rBdd = translate(std::dynamic_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType> const>(element));
157 } else {
158 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
159 "Element of type \"" << element->typestring() << "\" is not supported. Probably not a SFT.");
160 rBdd = sylvanBddManager->getZero();
161 }
162
163 if (isRelevant) {
164 // rBdd can't be in relevantEventBdds
165 // as we would've returned
166 // at the start of the function
167 relevantEventBdds[element->name()] = rBdd;
168 }
169
170 return rBdd;
171 }
172
179 Bdd translate(std::shared_ptr<storm::dft::storage::elements::DFTGate<ValueType> const> gate) {
181 // used only in conjunctions therefore neutral element -> 1
182 auto tmpBdd{sylvanBddManager->getOne()};
183 for (auto const& child : gate->children()) {
184 tmpBdd &= translate(child);
185 }
186 return tmpBdd;
187 } else if (gate->type() == storm::dft::storage::elements::DFTElementType::OR) {
188 // used only in disjunctions therefore neutral element -> 0
189 auto tmpBdd{sylvanBddManager->getZero()};
190 for (auto const& child : gate->children()) {
191 tmpBdd |= translate(child);
192 }
193 return tmpBdd;
194 } else if (gate->type() == storm::dft::storage::elements::DFTElementType::VOT) {
195 return translate(std::dynamic_pointer_cast<storm::dft::storage::elements::DFTVot<ValueType> const>(gate));
196 }
197 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate of type \"" << gate->typestring() << "\" is not supported. Probably not a SFT.");
198 return sylvanBddManager->getZero();
199 }
200
207 Bdd translate(std::shared_ptr<storm::dft::storage::elements::DFTVot<ValueType> const> vot) {
208 std::vector<Bdd> bdds;
209 bdds.reserve(vot->children().size());
210
211 for (auto const& child : vot->children()) {
212 bdds.push_back(translate(child));
213 }
214
215 auto const rval{translateVot(0, vot->threshold(), bdds)};
216 return rval;
217 }
218
233 Bdd translateVot(size_t const currentIndex, size_t const threshold, std::vector<Bdd> const& bdds) const {
234 if (threshold == 0) {
235 return sylvanBddManager->getOne();
236 } else if (currentIndex >= bdds.size()) {
237 return sylvanBddManager->getZero();
238 }
239
240 auto const notChosenBdd{translateVot(currentIndex + 1, threshold, bdds)};
241 auto const chosenBdd{translateVot(currentIndex + 1, threshold - 1, bdds)};
242
243 return bdds[currentIndex].Ite(chosenBdd, notChosenBdd);
244 }
245
252 Bdd translate(std::shared_ptr<storm::dft::storage::elements::DFTBE<ValueType> const> const basicElement) {
253 return sylvanBddManager->getPositiveLiteral(basicElement->name());
254 }
255#endif
256};
257
258} // namespace transformations
259} // namespace storm::dft
Represents a Dynamic Fault Tree.
Definition DFT.h:49
Abstract base class for DFT elements.
Definition DFTElement.h:38
std::shared_ptr< storm::dft::storage::SylvanBddManager > getSylvanBddManager() const noexcept
SftToBddTransformator(std::shared_ptr< storm::dft::storage::DFT< ValueType > > dft, std::shared_ptr< storm::dft::storage::SylvanBddManager > sylvanBddManager, storm::dft::utility::RelevantEvents relevantEvents={})
std::shared_ptr< storm::dft::storage::DFT< ValueType > > getDFT() const noexcept
std::vector< uint32_t > const & getDdVariables() const noexcept
bool isRelevant(std::string const &name) const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28