10namespace modelchecker {
34ValueType recursiveProbability(
Bdd const bdd, std::map<uint32_t, ValueType>
const &indexToProbability, std::map<uint64_t, ValueType> &bddToProbability) {
37 }
else if (bdd.isZero()) {
41 auto const it{bddToProbability.find(bdd.GetBDD())};
42 if (it != bddToProbability.end()) {
46 auto const currentVar{bdd.TopVar()};
47 auto const currentProbability{indexToProbability.at(currentVar)};
49 auto const thenProbability{recursiveProbability(bdd.Then(), indexToProbability, bddToProbability)};
50 auto const elseProbability{recursiveProbability(bdd.Else(), indexToProbability, bddToProbability)};
53 auto const probability{currentProbability * thenProbability + (1 - currentProbability) * elseProbability};
54 bddToProbability[bdd.GetBDD()] = probability;
82ValueType recursiveBirnbaumFactor(uint32_t
const variableIndex,
Bdd const bdd, std::map<uint32_t, ValueType>
const &indexToProbability,
83 std::map<uint64_t, ValueType> &bddToProbability, std::map<uint64_t, ValueType> &bddToBirnbaumFactor) {
84 if (bdd.isTerminal()) {
88 auto const it{bddToBirnbaumFactor.find(bdd.GetBDD())};
89 if (it != bddToBirnbaumFactor.end()) {
93 auto const currentVar{bdd.TopVar()};
94 auto const currentProbability{indexToProbability.at(currentVar)};
98 if (currentVar > variableIndex) {
100 }
else if (currentVar == variableIndex) {
101 auto const thenProbability{recursiveProbability(bdd.Then(), indexToProbability, bddToProbability)};
102 auto const elseProbability{recursiveProbability(bdd.Else(), indexToProbability, bddToProbability)};
103 birnbaumFactor = thenProbability - elseProbability;
104 }
else if (currentVar < variableIndex) {
105 auto const thenBirnbaumFactor{recursiveBirnbaumFactor(variableIndex, bdd.Then(), indexToProbability, bddToProbability, bddToBirnbaumFactor)};
106 auto const elseBirnbaumFactor{recursiveBirnbaumFactor(variableIndex, bdd.Else(), indexToProbability, bddToProbability, bddToBirnbaumFactor)};
108 birnbaumFactor = currentProbability * thenBirnbaumFactor + (1 - currentProbability) * elseBirnbaumFactor;
111 bddToBirnbaumFactor[bdd.GetBDD()] = birnbaumFactor;
112 return birnbaumFactor;
140Eigen::ArrayXd
const *recursiveProbabilities(
size_t const chunksize,
Bdd const bdd, std::map<uint32_t, Eigen::ArrayXd>
const &indexToProbabilities,
141 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToProbabilities) {
142 auto const bddId{bdd.GetBDD()};
143 auto const it{bddToProbabilities.find(bddId)};
144 if (it != bddToProbabilities.end() && it->second.first) {
145 return &it->second.second;
148 auto &bddToProbabilitiesElement{bddToProbabilities[bddId]};
150 bddToProbabilitiesElement.first =
true;
151 bddToProbabilitiesElement.second = Eigen::ArrayXd::Constant(chunksize, 1);
152 return &bddToProbabilitiesElement.second;
153 }
else if (bdd.isZero()) {
154 bddToProbabilitiesElement.first =
true;
155 bddToProbabilitiesElement.second = Eigen::ArrayXd::Constant(chunksize, 0);
156 return &bddToProbabilitiesElement.second;
159 auto const &thenProbabilities{*recursiveProbabilities(chunksize, bdd.Then(), indexToProbabilities, bddToProbabilities)};
160 auto const &elseProbabilities{*recursiveProbabilities(chunksize, bdd.Else(), indexToProbabilities, bddToProbabilities)};
162 auto const currentVar{bdd.TopVar()};
163 auto const ¤tProbabilities{indexToProbabilities.at(currentVar)};
166 bddToProbabilitiesElement.first =
true;
167 bddToProbabilitiesElement.second = currentProbabilities * thenProbabilities + (1 - currentProbabilities) * elseProbabilities;
168 return &bddToProbabilitiesElement.second;
198Eigen::ArrayXd
const *recursiveBirnbaumFactors(
size_t const chunksize, uint32_t
const variableIndex,
Bdd const bdd,
199 std::map<uint32_t, Eigen::ArrayXd>
const &indexToProbabilities,
200 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToProbabilities,
201 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> &bddToBirnbaumFactors) {
202 auto const bddId{bdd.GetBDD()};
203 auto const it{bddToBirnbaumFactors.find(bddId)};
204 if (it != bddToBirnbaumFactors.end() && it->second.first) {
205 return &it->second.second;
208 auto &bddToBirnbaumFactorsElement{bddToBirnbaumFactors[bddId]};
209 if (bdd.isTerminal() || bdd.TopVar() > variableIndex) {
211 bddToBirnbaumFactorsElement.second = Eigen::ArrayXd::Constant(chunksize, 0);
212 return &bddToBirnbaumFactorsElement.second;
215 auto const currentVar{bdd.TopVar()};
216 auto const ¤tProbabilities{indexToProbabilities.at(currentVar)};
218 if (currentVar == variableIndex) {
219 auto const &thenProbabilities{*recursiveProbabilities(chunksize, bdd.Then(), indexToProbabilities, bddToProbabilities)};
220 auto const &elseProbabilities{*recursiveProbabilities(chunksize, bdd.Else(), indexToProbabilities, bddToProbabilities)};
222 bddToBirnbaumFactorsElement.first =
true;
223 bddToBirnbaumFactorsElement.second = thenProbabilities - elseProbabilities;
224 return &bddToBirnbaumFactorsElement.second;
228 auto const &thenBirnbaumFactors{
229 *recursiveBirnbaumFactors(chunksize, variableIndex, bdd.Then(), indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
230 auto const &elseBirnbaumFactors{
231 *recursiveBirnbaumFactors(chunksize, variableIndex, bdd.Else(), indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
233 bddToBirnbaumFactorsElement.first =
true;
234 bddToBirnbaumFactorsElement.second = currentProbabilities * thenBirnbaumFactors + (1 - currentProbabilities) * elseBirnbaumFactors;
235 return &bddToBirnbaumFactorsElement.second;
240 : transformator{
std::make_shared<
storm::dft::transformations::SftToBddTransformator<
ValueType>>(dft, sylvanBddManager)} {}
244Bdd SFTBDDChecker::getTopLevelElementBdd() {
245 return transformator->transformTopLevel();
249 return transformator->getDFT();
252 return transformator->getSylvanBddManager();
256 return transformator;
262 std::vector<std::vector<std::string>> rval{};
263 rval.reserve(mcs.size());
264 while (!mcs.empty()) {
265 std::vector<std::string> tmp{};
266 tmp.reserve(mcs.back().size());
267 for (
auto const &be : mcs.back()) {
270 rval.push_back(std::move(tmp));
278 auto const bdd{getTopLevelElementBdd().Minsol()};
280 std::vector<std::vector<uint32_t>> mcs{};
281 std::vector<uint32_t> buffer{};
282 recursiveMCS(bdd, buffer, mcs);
287template<
typename FuncType>
288void SFTBDDChecker::chunkCalculationTemplate(std::vector<ValueType>
const &timepoints,
size_t chunksize, FuncType func)
const {
289 if (chunksize == 0) {
290 chunksize = timepoints.size();
294 auto const basicElements{
getDFT()->getBasicElements()};
295 std::map<uint32_t, Eigen::ArrayXd> indexToProbabilities{};
298 Eigen::ArrayXd timepointsArray{chunksize};
300 for (
size_t currentIndex{0}; currentIndex < timepoints.size(); currentIndex += chunksize) {
301 auto const sizeLeft{timepoints.size() - currentIndex};
302 if (sizeLeft < chunksize) {
303 chunksize = sizeLeft;
304 timepointsArray = Eigen::ArrayXd{chunksize};
308 for (
size_t i{currentIndex};
i < currentIndex + chunksize; ++
i) {
309 timepointsArray(i - currentIndex) = timepoints[
i];
313 for (
auto const &be : basicElements) {
318 auto const failureRate{std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(be)->activeFailureRate()};
322 indexToProbabilities[beIndex] = 1 - (-failureRate * timepointsArray).exp();
324 auto probabilities{timepointsArray};
325 for (
size_t i{0};
i < chunksize; ++
i) {
326 probabilities(i) = be->getUnreliability(timepointsArray(i));
328 indexToProbabilities[beIndex] = probabilities;
332 func(chunksize, timepointsArray, indexToProbabilities);
337 std::map<uint32_t, ValueType> indexToProbability{};
338 for (
auto const &be :
getDFT()->getBasicElements()) {
340 indexToProbability[currentIndex] = be->getUnreliability(timebound);
343 std::map<uint64_t, ValueType> bddToProbability{};
344 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
349 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
350 std::vector<ValueType> resultProbabilities{};
351 resultProbabilities.reserve(timepoints.size());
353 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
355 for (
auto &i : bddToProbabilities) {
356 i.second.first =
false;
361 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
364 for (
size_t i{0}; i < currentChunksize; ++i) {
365 resultProbabilities.push_back(probabilitiesArray(i));
369 return resultProbabilities;
372template<
typename FuncType>
373ValueType SFTBDDChecker::getImportanceMeasureAtTimebound(std::string
const &beName,
ValueType timebound, FuncType func) {
374 std::map<uint32_t, ValueType> indexToProbability{};
375 for (
auto const &be :
getDFT()->getBasicElements()) {
377 indexToProbability[currentIndex] = be->getUnreliability(timebound);
380 auto const bdd{getTopLevelElementBdd()};
382 std::map<uint64_t, ValueType> bddToProbability{};
383 std::map<uint64_t, ValueType> bddToBirnbaumFactor{};
384 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
385 auto const birnbaumFactor{recursiveBirnbaumFactor(index, bdd, indexToProbability, bddToProbability, bddToBirnbaumFactor)};
386 auto const &beProbability{indexToProbability[index]};
388 return func(beProbability, probability, birnbaumFactor);
391template<
typename FuncType>
392std::vector<ValueType> SFTBDDChecker::getAllImportanceMeasuresAtTimebound(
ValueType timebound, FuncType func) {
393 auto const bdd{getTopLevelElementBdd()};
395 std::vector<ValueType> resultVector{};
396 resultVector.reserve(
getDFT()->getBasicElements().size());
398 std::map<uint32_t, ValueType> indexToProbability{};
399 for (
auto const &be :
getDFT()->getBasicElements()) {
401 indexToProbability[currentIndex] = be->getUnreliability(timebound);
403 std::map<uint64_t, ValueType> bddToProbability{};
405 auto const probability{recursiveProbability(bdd, indexToProbability, bddToProbability)};
407 for (
auto const &be :
getDFT()->getBasicElements()) {
409 std::map<uint64_t, ValueType> bddToBirnbaumFactor{};
410 auto const birnbaumFactor{recursiveBirnbaumFactor(index, bdd, indexToProbability, bddToProbability, bddToBirnbaumFactor)};
411 auto const &beProbability{indexToProbability[index]};
412 resultVector.push_back(func(beProbability, probability, birnbaumFactor));
417template<
typename FuncType>
418std::vector<ValueType> SFTBDDChecker::getImportanceMeasuresAtTimepoints(std::string
const &beName, std::vector<ValueType>
const &timepoints,
size_t chunksize,
420 auto const bdd{getTopLevelElementBdd()};
421 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
422 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToBirnbaumFactors{};
423 std::vector<ValueType> resultVector{};
424 resultVector.reserve(timepoints.size());
426 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
428 for (
auto &i : bddToProbabilities) {
429 i.second.first =
false;
431 for (
auto &i : bddToBirnbaumFactors) {
432 i.second.first =
false;
437 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
438 auto const &birnbaumFactorsArray{
439 *recursiveBirnbaumFactors(currentChunksize, index, bdd, indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
441 auto const &beProbabilitiesArray{indexToProbabilities.at(index)};
442 auto const ImportanceMeasureArray{func(beProbabilitiesArray, probabilitiesArray, birnbaumFactorsArray)};
445 for (
size_t i{0};
i < currentChunksize; ++
i) {
446 resultVector.push_back(ImportanceMeasureArray(i));
453template<
typename FuncType>
454std::vector<std::vector<ValueType>> SFTBDDChecker::getAllImportanceMeasuresAtTimepoints(std::vector<ValueType>
const &timepoints,
size_t chunksize,
456 auto const bdd{getTopLevelElementBdd()};
457 auto const basicElements{
getDFT()->getBasicElements()};
459 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToProbabilities{};
460 std::unordered_map<uint64_t, std::pair<bool, Eigen::ArrayXd>> bddToBirnbaumFactors{};
461 std::vector<std::vector<ValueType>> resultVector{};
462 resultVector.resize(
getDFT()->getBasicElements().size());
463 for (
auto &i : resultVector) {
464 i.reserve(timepoints.size());
467 chunkCalculationTemplate(timepoints, chunksize, [&](
auto const currentChunksize,
auto const &timepointsArray,
auto const &indexToProbabilities) {
469 for (
auto &i : bddToProbabilities) {
470 i.second.first =
false;
473 auto const &probabilitiesArray{*recursiveProbabilities(currentChunksize, bdd, indexToProbabilities, bddToProbabilities)};
475 for (
size_t basicElementIndex{0}; basicElementIndex < basicElements.size(); ++basicElementIndex) {
476 auto const &be{basicElements[basicElementIndex]};
478 for (
auto &i : bddToBirnbaumFactors) {
479 i.second.first =
false;
485 auto const &birnbaumFactorsArray{
486 *recursiveBirnbaumFactors(currentChunksize, index, bdd, indexToProbabilities, bddToProbabilities, bddToBirnbaumFactors)};
488 auto const &beProbabilitiesArray{indexToProbabilities.at(index)};
490 auto const ImportanceMeasureArray{func(beProbabilitiesArray, probabilitiesArray, birnbaumFactorsArray)};
493 for (
size_t i{0};
i < currentChunksize; ++
i) {
494 resultVector[basicElementIndex].push_back(ImportanceMeasureArray(i));
504struct BirnbaumFunctor {
506 constexpr auto operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
507 return birnbaumFactor;
513 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
514 return (beProbability / probability) * birnbaumFactor;
520 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
521 return beProbability + (beProbability * (1 - beProbability) * birnbaumFactor) / probability;
527 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
528 return 1 + ((1 - beProbability) * birnbaumFactor) / probability;
534 constexpr T operator()(T
const &beProbability, T
const &probability, T
const &birnbaumFactor)
const {
535 return probability / (probability - beProbability * birnbaumFactor);
542 return getImportanceMeasureAtTimebound(beName, timebound, BirnbaumFunctor{});
546 return getAllImportanceMeasuresAtTimebound(timebound, BirnbaumFunctor{});
550 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, BirnbaumFunctor{});
554 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, BirnbaumFunctor{});
558 return getImportanceMeasureAtTimebound(beName, timebound, CIFFunctor{});
562 return getAllImportanceMeasuresAtTimebound(timebound, CIFFunctor{});
566 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, CIFFunctor{});
570 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, CIFFunctor{});
574 return getImportanceMeasureAtTimebound(beName, timebound, DIFFunctor{});
578 return getAllImportanceMeasuresAtTimebound(timebound, DIFFunctor{});
582 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, DIFFunctor{});
586 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, DIFFunctor{});
590 return getImportanceMeasureAtTimebound(beName, timebound, RAWFunctor{});
594 return getAllImportanceMeasuresAtTimebound(timebound, RAWFunctor{});
598 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, RAWFunctor{});
602 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, RAWFunctor{});
606 return getImportanceMeasureAtTimebound(beName, timebound, RRWFunctor{});
610 return getAllImportanceMeasuresAtTimebound(timebound, RRWFunctor{});
614 return getImportanceMeasuresAtTimepoints(beName, timepoints, chunksize, RRWFunctor{});
618 return getAllImportanceMeasuresAtTimepoints(timepoints, chunksize, RRWFunctor{});
621void SFTBDDChecker::recursiveMCS(
Bdd const bdd, std::vector<uint32_t> &buffer, std::vector<std::vector<uint32_t>> &minimalCutSets)
const {
623 minimalCutSets.push_back(buffer);
624 }
else if (!bdd.isZero()) {
625 auto const currentVar{bdd.TopVar()};
627 buffer.push_back(currentVar);
628 recursiveMCS(bdd.Then(), buffer, minimalCutSets);
631 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