1#include <gmm/gmm_std.h>
11namespace modelchecker {
35ValueType recursiveProbability(
Bdd const bdd, std::map<uint32_t, ValueType>
const &indexToProbability, std::map<uint64_t, ValueType> &bddToProbability) {
38 }
else if (bdd.isZero()) {
42 auto const it{bddToProbability.find(bdd.GetBDD())};
43 if (it != bddToProbability.end()) {
47 auto const currentVar{bdd.TopVar()};
48 auto const currentProbability{indexToProbability.at(currentVar)};
50 auto const thenProbability{recursiveProbability(bdd.Then(), indexToProbability, bddToProbability)};
51 auto const elseProbability{recursiveProbability(bdd.Else(), indexToProbability, bddToProbability)};
54 auto const probability{currentProbability * thenProbability + (1 - currentProbability) * elseProbability};
55 bddToProbability[bdd.GetBDD()] = probability;
83ValueType recursiveBirnbaumFactor(uint32_t
const variableIndex,
Bdd const bdd, std::map<uint32_t, ValueType>
const &indexToProbability,
84 std::map<uint64_t, ValueType> &bddToProbability, std::map<uint64_t, ValueType> &bddToBirnbaumFactor) {
85 if (bdd.isTerminal()) {
89 auto const it{bddToBirnbaumFactor.find(bdd.GetBDD())};
90 if (it != bddToBirnbaumFactor.end()) {
94 auto const currentVar{bdd.TopVar()};
95 auto const currentProbability{indexToProbability.at(currentVar)};
99 if (currentVar > variableIndex) {
101 }
else if (currentVar == variableIndex) {
102 auto const thenProbability{recursiveProbability(bdd.Then(), indexToProbability, bddToProbability)};
103 auto const elseProbability{recursiveProbability(bdd.Else(), indexToProbability, bddToProbability)};
104 birnbaumFactor = thenProbability - elseProbability;
105 }
else if (currentVar < variableIndex) {
106 auto const thenBirnbaumFactor{recursiveBirnbaumFactor(variableIndex, bdd.Then(), indexToProbability, bddToProbability, bddToBirnbaumFactor)};
107 auto const elseBirnbaumFactor{recursiveBirnbaumFactor(variableIndex, bdd.Else(), indexToProbability, bddToProbability, bddToBirnbaumFactor)};
109 birnbaumFactor = currentProbability * thenBirnbaumFactor + (1 - currentProbability) * elseBirnbaumFactor;
112 bddToBirnbaumFactor[bdd.GetBDD()] = birnbaumFactor;
113 return birnbaumFactor;
141Eigen::ArrayXd
const *recursiveProbabilities(
size_t const chunksize,
Bdd const bdd, std::map<uint32_t, Eigen::ArrayXd>
const &indexToProbabilities,
142 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToProbabilities) {
143 auto const bddId{bdd.GetBDD()};
144 auto const it{bddToProbabilities.find(bddId)};
145 if (it != bddToProbabilities.end() && it->second.first) {
146 return &it->second.second;
149 auto &bddToProbabilitiesElement{bddToProbabilities[bddId]};
151 bddToProbabilitiesElement.first =
true;
152 bddToProbabilitiesElement.second = Eigen::ArrayXd::Constant(chunksize, 1);
153 return &bddToProbabilitiesElement.second;
154 }
else if (bdd.isZero()) {
155 bddToProbabilitiesElement.first =
true;
156 bddToProbabilitiesElement.second = Eigen::ArrayXd::Constant(chunksize, 0);
157 return &bddToProbabilitiesElement.second;
160 auto const &thenProbabilities{*recursiveProbabilities(chunksize, bdd.Then(), indexToProbabilities, bddToProbabilities)};
161 auto const &elseProbabilities{*recursiveProbabilities(chunksize, bdd.Else(), indexToProbabilities, bddToProbabilities)};
163 auto const currentVar{bdd.TopVar()};
164 auto const ¤tProbabilities{indexToProbabilities.at(currentVar)};
167 bddToProbabilitiesElement.first =
true;
168 bddToProbabilitiesElement.second = currentProbabilities * thenProbabilities + (1 - currentProbabilities) * elseProbabilities;
169 return &bddToProbabilitiesElement.second;
199Eigen::ArrayXd
const *recursiveBirnbaumFactors(
size_t const chunksize, uint32_t
const variableIndex,
Bdd const bdd,
200 std::map<uint32_t, Eigen::ArrayXd>
const &indexToProbabilities,
201 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToProbabilities,
202 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToBirnbaumFactors) {
203 auto const bddId{bdd.GetBDD()};
204 auto const it{bddToBirnbaumFactors.find(bddId)};
205 if (it != bddToBirnbaumFactors.end() && it->second.first) {
206 return &it->second.second;
209 auto &bddToBirnbaumFactorsElement{bddToBirnbaumFactors[bddId]};
210 if (bdd.isTerminal() || bdd.TopVar() > variableIndex) {
212 bddToBirnbaumFactorsElement.second = Eigen::ArrayXd::Constant(chunksize, 0);
213 return &bddToBirnbaumFactorsElement.second;
216 auto const currentVar{bdd.TopVar()};
217 auto const ¤tProbabilities{indexToProbabilities.at(currentVar)};
219 if (currentVar == variableIndex) {
220 auto const &thenProbabilities{*recursiveProbabilities(chunksize, bdd.Then(), indexToProbabilities, bddToProbabilities)};
221 auto const &elseProbabilities{*recursiveProbabilities(chunksize, bdd.Else(), indexToProbabilities, bddToProbabilities)};
223 bddToBirnbaumFactorsElement.first =
true;
224 bddToBirnbaumFactorsElement.second = thenProbabilities - elseProbabilities;
225 return &bddToBirnbaumFactorsElement.second;
229 auto const &thenBirnbaumFactors{
230 *recursiveBirnbaumFactors(chunksize, variableIndex, bdd.Then(), indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
231 auto const &elseBirnbaumFactors{
232 *recursiveBirnbaumFactors(chunksize, variableIndex, bdd.Else(), indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
234 bddToBirnbaumFactorsElement.first =
true;
235 bddToBirnbaumFactorsElement.second = currentProbabilities * thenBirnbaumFactors + (1 - currentProbabilities) * elseBirnbaumFactors;
236 return &bddToBirnbaumFactorsElement.second;
241 : transformator{
std::make_shared<
storm::dft::transformations::SftToBddTransformator<
ValueType>>(dft, sylvanBddManager)} {}
245Bdd SFTBDDChecker::getTopLevelElementBdd() {
246 return transformator->transformTopLevel();
250 return transformator->getDFT();
253 return transformator->getSylvanBddManager();
257 return transformator;
263 std::vector<std::vector<std::string>> rval{};
264 rval.reserve(mcs.size());
265 while (!mcs.empty()) {
266 std::vector<std::string> tmp{};
267 tmp.reserve(mcs.back().size());
268 for (
auto const &be : mcs.back()) {
271 rval.push_back(std::move(tmp));
279 auto const bdd{getTopLevelElementBdd().Minsol()};
281 std::vector<std::vector<uint32_t>> mcs{};
282 std::vector<uint32_t> buffer{};
283 recursiveMCS(bdd, buffer, mcs);
288template<
typename FuncType>
289void SFTBDDChecker::chunkCalculationTemplate(std::vector<ValueType>
const &timepoints,
size_t chunksize, FuncType func)
const {
290 if (chunksize == 0) {
291 chunksize = timepoints.size();
295 auto const basicElements{
getDFT()->getBasicElements()};
296 std::map<uint32_t, Eigen::ArrayXd> indexToProbabilities{};
299 Eigen::ArrayXd timepointsArray{chunksize};
301 for (
size_t currentIndex{0}; currentIndex < timepoints.size(); currentIndex += chunksize) {
302 auto const sizeLeft{timepoints.size() - currentIndex};
303 if (sizeLeft < chunksize) {
304 chunksize = sizeLeft;
305 timepointsArray = Eigen::ArrayXd{chunksize};
309 for (
size_t i{currentIndex};
i < currentIndex + chunksize; ++
i) {
310 timepointsArray(i - currentIndex) = timepoints[
i];
314 for (
auto const &be : basicElements) {
319 auto const failureRate{std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>>(be)->activeFailureRate()};
323 indexToProbabilities[beIndex] = 1 - (-failureRate * timepointsArray).exp();
325 auto probabilities{timepointsArray};
326 for (
size_t i{0};
i < chunksize; ++
i) {
327 probabilities(i) = be->getUnreliability(timepointsArray(i));
329 indexToProbabilities[beIndex] = probabilities;
333 func(chunksize, timepointsArray, indexToProbabilities);
338 std::map<uint32_t, ValueType> indexToProbability{};
339 for (
auto const &be :
getDFT()->getBasicElements()) {
341 indexToProbability[currentIndex] = be->getUnreliability(timebound);
344 std::map<uint64_t, ValueType> bddToProbability{};
345 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
350 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
351 std::vector<ValueType> resultProbabilities{};
352 resultProbabilities.reserve(timepoints.size());
354 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
356 for (
auto &i : bddToProbabilities) {
357 i.second.first =
false;
362 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
365 for (
size_t i{0}; i < currentChunksize; ++i) {
366 resultProbabilities.push_back(probabilitiesArray(i));
370 return resultProbabilities;
373template<
typename FuncType>
374ValueType SFTBDDChecker::getImportanceMeasureAtTimebound(std::string
const &beName,
ValueType timebound, FuncType func) {
375 std::map<uint32_t, ValueType> indexToProbability{};
376 for (
auto const &be :
getDFT()->getBasicElements()) {
378 indexToProbability[currentIndex] = be->getUnreliability(timebound);
381 auto const bdd{getTopLevelElementBdd()};
383 std::map<uint64_t, ValueType> bddToProbability{};
384 std::map<uint64_t, ValueType> bddToBirnbaumFactor{};
385 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
386 auto const birnbaumFactor{recursiveBirnbaumFactor(index, bdd, indexToProbability, bddToProbability, bddToBirnbaumFactor)};
387 auto const &beProbability{indexToProbability[index]};
389 return func(beProbability, probability, birnbaumFactor);
392template<
typename FuncType>
393std::vector<ValueType> SFTBDDChecker::getAllImportanceMeasuresAtTimebound(
ValueType timebound, FuncType func) {
394 auto const bdd{getTopLevelElementBdd()};
396 std::vector<ValueType> resultVector{};
397 resultVector.reserve(
getDFT()->getBasicElements().size());
399 std::map<uint32_t, ValueType> indexToProbability{};
400 for (
auto const &be :
getDFT()->getBasicElements()) {
402 indexToProbability[currentIndex] = be->getUnreliability(timebound);
404 std::map<uint64_t, ValueType> bddToProbability{};
406 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
408 for (
auto const &be :
getDFT()->getBasicElements()) {
410 std::map<uint64_t, ValueType> bddToBirnbaumFactor{};
411 auto const birnbaumFactor{recursiveBirnbaumFactor(index, bdd, indexToProbability, bddToProbability, bddToBirnbaumFactor)};
412 auto const &beProbability{indexToProbability[index]};
413 resultVector.push_back(func(beProbability, probability, birnbaumFactor));
418template<
typename FuncType>
419std::vector<ValueType> SFTBDDChecker::getImportanceMeasuresAtTimepoints(std::string
const &beName, std::vector<ValueType>
const &timepoints,
size_t chunksize,
421 auto const bdd{getTopLevelElementBdd()};
422 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
423 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToBirnbaumFactors{};
424 std::vector<ValueType> resultVector{};
425 resultVector.reserve(timepoints.size());
427 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
429 for (
auto &i : bddToProbabilities) {
430 i.second.first =
false;
432 for (
auto &i : bddToBirnbaumFactors) {
433 i.second.first =
false;
438 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
439 auto const &birnbaumFactorsArray{
440 *recursiveBirnbaumFactors(currentChunksize, index, bdd, indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
442 auto const &beProbabilitiesArray{indexToProbabilities.at(index)};
443 auto const ImportanceMeasureArray{func(beProbabilitiesArray, probabilitiesArray, birnbaumFactorsArray)};
446 for (
size_t i{0};
i < currentChunksize; ++
i) {
447 resultVector.push_back(ImportanceMeasureArray(i));
454template<
typename FuncType>
455std::vector<std::vector<ValueType>> SFTBDDChecker::getAllImportanceMeasuresAtTimepoints(std::vector<ValueType>
const &timepoints,
size_t chunksize,
457 auto const bdd{getTopLevelElementBdd()};
458 auto const basicElements{
getDFT()->getBasicElements()};
460 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
461 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToBirnbaumFactors{};
462 std::vector<std::vector<ValueType>> resultVector{};
463 resultVector.resize(
getDFT()->getBasicElements().size());
464 for (
auto &i : resultVector) {
465 i.reserve(timepoints.size());
468 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
470 for (
auto &i : bddToProbabilities) {
471 i.second.first =
false;
474 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
476 for (
size_t basicElementIndex{0}; basicElementIndex < basicElements.size(); ++basicElementIndex) {
477 auto const &be{basicElements[basicElementIndex]};
479 for (
auto &i : bddToBirnbaumFactors) {
480 i.second.first =
false;
486 auto const &birnbaumFactorsArray{
487 *recursiveBirnbaumFactors(currentChunksize, index, bdd, indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
489 auto const &beProbabilitiesArray{indexToProbabilities.at(index)};
491 auto const ImportanceMeasureArray{func(beProbabilitiesArray, probabilitiesArray, birnbaumFactorsArray)};
494 for (
size_t i{0};
i < currentChunksize; ++
i) {
495 resultVector[basicElementIndex].push_back(ImportanceMeasureArray(i));
505struct BirnbaumFunctor {
507 constexpr auto operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
508 return birnbaumFactor;
514 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
515 return (beProbability / probability) * birnbaumFactor;
521 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
522 return beProbability + (beProbability * (1 - beProbability) * birnbaumFactor) / probability;
528 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
529 return 1 + ((1 - beProbability) * birnbaumFactor) / probability;
535 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
536 return probability / (probability - beProbability * birnbaumFactor);
543 return getImportanceMeasureAtTimebound(beName, timebound, BirnbaumFunctor{});
547 return getAllImportanceMeasuresAtTimebound(timebound, BirnbaumFunctor{});
551 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, BirnbaumFunctor{});
555 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, BirnbaumFunctor{});
559 return getImportanceMeasureAtTimebound(beName, timebound, CIFFunctor{});
563 return getAllImportanceMeasuresAtTimebound(timebound, CIFFunctor{});
567 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, CIFFunctor{});
571 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, CIFFunctor{});
575 return getImportanceMeasureAtTimebound(beName, timebound, DIFFunctor{});
579 return getAllImportanceMeasuresAtTimebound(timebound, DIFFunctor{});
583 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, DIFFunctor{});
587 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, DIFFunctor{});
591 return getImportanceMeasureAtTimebound(beName, timebound, RAWFunctor{});
595 return getAllImportanceMeasuresAtTimebound(timebound, RAWFunctor{});
599 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, RAWFunctor{});
603 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, RAWFunctor{});
607 return getImportanceMeasureAtTimebound(beName, timebound, RRWFunctor{});
611 return getAllImportanceMeasuresAtTimebound(timebound, RRWFunctor{});
615 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, RRWFunctor{});
619 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, RRWFunctor{});
622void SFTBDDChecker::recursiveMCS(
Bdd const bdd, std::vector<uint32_t> &buffer, std::vector<std::vector<uint32_t>> &minimalCutSets)
const {
624 minimalCutSets.push_back(buffer);
625 }
else if (!bdd.isZero()) {
626 auto const currentVar{bdd.TopVar()};
628 buffer.push_back(currentVar);
629 recursiveMCS(bdd.Then(), buffer, minimalCutSets);
632 recursiveMCS(bdd.Else(), buffer, minimalCutSets);
std::shared_ptr< storm::dft::storage::SylvanBddManager > getSylvanBddManager() const noexcept
std::vector< ValueType > getAllRRWsAtTimebound(ValueType timebound)
ValueType getRAWAtTimebound(std::string const &beName, ValueType timebound)
std::vector< std::vector< ValueType > > getAllRAWsAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
ValueType getCIFAtTimebound(std::string const &beName, ValueType timebound)
std::vector< std::vector< ValueType > > getAllBirnbaumFactorsAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
std::vector< ValueType > getAllDIFsAtTimebound(ValueType timebound)
std::vector< ValueType > getAllRAWsAtTimebound(ValueType timebound)
std::vector< ValueType > getRRWsAtTimepoints(std::string const &beName, std::vector< ValueType > const &timepoints, size_t chunksize=0)
SFTBDDChecker(std::shared_ptr< storm::dft::storage::DFT< ValueType > > dft, std::shared_ptr< storm::dft::storage::SylvanBddManager > sylvanBddManager=std::make_shared< storm::dft::storage::SylvanBddManager >())
std::shared_ptr< storm::dft::transformations::SftToBddTransformator< ValueType > > getTransformator() const noexcept
std::vector< std::vector< ValueType > > getAllDIFsAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
ValueType getRRWAtTimebound(std::string const &beName, ValueType timebound)
std::vector< std::vector< ValueType > > getAllRRWsAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
std::vector< ValueType > getAllBirnbaumFactorsAtTimebound(ValueType timebound)
std::vector< ValueType > getRAWsAtTimepoints(std::string const &beName, std::vector< ValueType > const &timepoints, size_t chunksize=0)
ValueType getBirnbaumFactorAtTimebound(std::string const &beName, ValueType timebound)
std::vector< ValueType > getProbabilitiesAtTimepoints(std::vector< ValueType > const &timepoints, size_t const chunksize=0)
std::shared_ptr< storm::dft::storage::DFT< ValueType > > getDFT() const noexcept
std::vector< std::vector< ValueType > > getAllCIFsAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
std::vector< ValueType > getBirnbaumFactorsAtTimepoints(std::string const &beName, std::vector< ValueType > const &timepoints, size_t chunksize=0)
std::vector< std::vector< uint32_t > > getMinimalCutSetsAsIndices()
std::vector< ValueType > getCIFsAtTimepoints(std::string const &beName, std::vector< ValueType > const &timepoints, size_t chunksize=0)
std::vector< std::vector< std::string > > getMinimalCutSets()
std::vector< ValueType > getAllCIFsAtTimebound(ValueType timebound)
ValueType getDIFAtTimebound(std::string const &beName, ValueType timebound)
std::vector< ValueType > getDIFsAtTimepoints(std::string const &beName, std::vector< ValueType > const &timepoints, size_t chunksize=0)
ValueType getProbabilityAtTimebound(ValueType timebound)
Represents a Dynamic Fault Tree.
SFTBDDChecker::ValueType ValueType