#include "DftToGspnTransformator.h" #include "storm/exceptions/NotImplementedException.h" #include namespace storm { namespace transformations { namespace dft { // Prevent some magic constants static constexpr const uint64_t defaultPriority = 1; static constexpr const uint64_t defaultCapacity = 1; template DftToGspnTransformator::DftToGspnTransformator(storm::storage::DFT const& dft) : mDft(dft) { // Intentionally left empty. } template void DftToGspnTransformator::transform() { builder.setGspnName("DftToGspnTransformation"); // Loop through every DFT element and draw them as a GSPN. drawGSPNElements(); // Draw restrictions into the GSPN (i.e. SEQ or MUTEX). //drawGSPNRestrictions(); } template uint64_t DftToGspnTransformator::toplevelFailedPlaceId() { assert(failedNodes.size() > mDft.getTopLevelIndex()); return failedNodes[mDft.getTopLevelIndex()]; } template void DftToGspnTransformator::drawGSPNElements() { // Loop through every DFT element and draw them as a GSPN. for (std::size_t i = 0; i < mDft.nrElements(); i++) { auto dftElement = mDft.getElement(i); bool isRepresentative = mDft.isRepresentative(i); // Check which type the element is and call the corresponding drawing-function. switch (dftElement->type()) { case storm::storage::DFTElementType::AND: drawAND(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::OR: drawOR(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::VOT: drawVOT(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::PAND: drawPAND(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::SPARE: drawSPARE(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::POR: drawPOR(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::SEQ: drawSeq(std::static_pointer_cast const>(dftElement)); break; case storm::storage::DFTElementType::MUTEX: // No method call needed here. MUTEX only consists of restrictions, which are handled later. break; case storm::storage::DFTElementType::BE: drawBE(std::static_pointer_cast const>(dftElement), isRepresentative); break; case storm::storage::DFTElementType::CONSTF: drawCONSTF(dftElement, isRepresentative); break; case storm::storage::DFTElementType::CONSTS: drawCONSTS(dftElement, isRepresentative); break; case storm::storage::DFTElementType::PDEP: drawPDEP(std::static_pointer_cast const>(dftElement)); break; default: STORM_LOG_ASSERT(false, "DFT type unknown."); break; } } } template void DftToGspnTransformator::drawBE(std::shared_ptr const> dftBE, bool isRepresentative) { uint64_t beActive = builder.addPlace(defaultCapacity, isBEActive(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); activeNodes.emplace(dftBE->id(), beActive); uint64_t beFailed = builder.addPlace(defaultCapacity, 0, dftBE->name() + STR_FAILED); double xcenter = mDft.getElementLayoutInfo(dftBE->id()).x; double ycenter = mDft.getElementLayoutInfo(dftBE->id()).y; builder.setPlaceLayoutInfo(beActive, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); builder.setPlaceLayoutInfo(beFailed, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); uint64_t disabledNode = 0; if (!smart || dftBE->nrRestrictions() > 0) { disabledNode = addDisabledPlace(dftBE); } uint64_t unavailableNode = 0; if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftBE, storm::gspn::LayoutInfo(xcenter+9.0, ycenter)); } assert(failedNodes.size() == dftBE->id()); failedNodes.push_back(beFailed); uint64_t tActive = builder.addTimedTransition(defaultPriority, dftBE->activeFailureRate(), dftBE->name() + "_activeFailing"); builder.setTransitionLayoutInfo(tActive, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0)); builder.addInputArc(beActive, tActive); builder.addInhibitionArc(beFailed, tActive); builder.addOutputArc(tActive, beActive); builder.addOutputArc(tActive, beFailed); uint64_t tPassive = builder.addTimedTransition(defaultPriority, dftBE->passiveFailureRate(), dftBE->name() + "_passiveFailing"); builder.setTransitionLayoutInfo(tPassive, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0)); builder.addInhibitionArc(beActive, tPassive); builder.addInhibitionArc(beFailed, tPassive); builder.addOutputArc(tPassive, beFailed); if (!smart || dftBE->nrRestrictions() > 0) { builder.addInhibitionArc(disabledNode, tActive); builder.addInhibitionArc(disabledNode, tPassive); } if (!smart || isRepresentative) { builder.addOutputArc(tActive, unavailableNode); builder.addOutputArc(tPassive, unavailableNode); } } template void DftToGspnTransformator::drawAND(std::shared_ptr const> dftAnd, bool isRepresentative) { uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftAnd->name() + STR_FAILED); assert(failedNodes.size() == dftAnd->id()); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftAnd->id()).x; double ycenter = mDft.getElementLayoutInfo(dftAnd->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; if (isRepresentative) { unavailableNode = addUnavailableNode(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } uint64_t tAndFailed = builder.addImmediateTransition( getFailPriority(dftAnd) , 0.0, dftAnd->name() + STR_FAILING ); builder.setTransitionLayoutInfo(tAndFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tAndFailed); builder.addOutputArc(tAndFailed, nodeFailed); if (isRepresentative) { builder.addOutputArc(tAndFailed, unavailableNode); } for(auto const& child : dftAnd->children()) { assert(failedNodes.size() > child->id()); builder.addInputArc(failedNodes[child->id()], tAndFailed); builder.addOutputArc(tAndFailed, failedNodes[child->id()]); } } template void DftToGspnTransformator::drawOR(std::shared_ptr const> dftOr, bool isRepresentative) { uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftOr->name() + STR_FAILED); assert(failedNodes.size() == dftOr->id()); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftOr->id()).x; double ycenter = mDft.getElementLayoutInfo(dftOr->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; if (isRepresentative) { unavailableNode = addUnavailableNode(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } uint64_t i = 0; for (auto const& child : dftOr->children()) { uint64_t tNodeFailed = builder.addImmediateTransition( getFailPriority(dftOr), 0.0, dftOr->name() + STR_FAILING + std::to_string(i) ); builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addOutputArc(tNodeFailed, nodeFailed); if (isRepresentative) { builder.addOutputArc(tNodeFailed, unavailableNode); } assert(failedNodes.size() > child->id()); builder.addInputArc(failedNodes[child->id()], tNodeFailed); builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); ++i; } } template void DftToGspnTransformator::drawVOT(std::shared_ptr const> dftVot, bool isRepresentative) { // TODO: finish layouting uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftVot->name() + STR_FAILED); assert(failedNodes.size() == dftVot->id()); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftVot->id()).x; double ycenter = mDft.getElementLayoutInfo(dftVot->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); uint64_t unavailableNode = 0; if (isRepresentative) { unavailableNode = addUnavailableNode(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } uint64_t nodeCollector = builder.addPlace(dftVot->nrChildren(), 0, dftVot->name() + "_collector"); builder.setPlaceLayoutInfo(nodeCollector, storm::gspn::LayoutInfo(xcenter, ycenter)); uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); builder.addOutputArc(tNodeFailed, nodeFailed); if (isRepresentative) { builder.addOutputArc(tNodeFailed, unavailableNode); } builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addInputArc(nodeCollector, tNodeFailed, dftVot->threshold()); builder.addOutputArc(tNodeFailed, nodeCollector, dftVot->threshold()); uint64_t i = 0; for (auto const& child : dftVot->children()) { uint64_t childInhibPlace = builder.addPlace(1, 0, dftVot->name() + "_child_fail_inhib" + std::to_string(i)); uint64_t tCollect = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + "_child_collect" + std::to_string(i)); builder.addOutputArc(tCollect, nodeCollector); builder.addOutputArc(tCollect, childInhibPlace); builder.addInhibitionArc(childInhibPlace, tCollect); builder.addInputArc(failedNodes[child->id()], tCollect); builder.addOutputArc(tCollect, failedNodes[child->id()]); ++i; } } template void DftToGspnTransformator::drawPAND(std::shared_ptr const> dftPand, bool isRepresentative) { uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILED); assert(failedNodes.size() == dftPand->id()); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftPand->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPand->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); uint64_t unavailableNode = 0; if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftPand, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); } uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING); builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); builder.addInhibitionArc(nodeFailed, tNodeFailed); builder.addOutputArc(tNodeFailed, nodeFailed); if (!smart || isRepresentative) { builder.addOutputArc(tNodeFailed, nodeFailed); } if(dftPand->isInclusive()) { // Inclusive PAND uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILSAVE); builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); builder.addInhibitionArc(nodeFS, tNodeFailed); for(auto const& child : dftPand->children()) { builder.addInputArc(failedNodes[child->id()], tNodeFailed); builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); } for (uint64_t j = 1; j < dftPand->nrChildren(); ++j) { uint64_t tfs = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(j)); builder.setTransitionLayoutInfo(tfs, storm::gspn::LayoutInfo(xcenter-6.0+j*3.0, ycenter+3.0)); builder.addInputArc(failedNodes[dftPand->children().at(j)->id()], tfs); builder.addOutputArc(tfs, failedNodes[dftPand->children().at(j)->id()]); builder.addInhibitionArc(failedNodes[dftPand->children().at(j-1)->id()], tfs); builder.addOutputArc(tfs, nodeFS); builder.addInhibitionArc(nodeFS, tfs); } } else { // Exclusive PAND uint64_t fi = 0; uint64_t tn = 0; for(uint64_t j = 0; j < dftPand->nrChildren(); ++j) { auto const& child = dftPand->children()[j]; if (j > 0) { builder.addInhibitionArc(failedNodes.at(child->id()), tn); } if (j != dftPand->nrChildren() - 1) { tn = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(j)); builder.setTransitionLayoutInfo(tn, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); } else { tn = tNodeFailed; } builder.addInputArc(failedNodes.at(child->id()), tn); builder.addOutputArc(tn, failedNodes.at(child->id())); if (j > 0) { builder.addInputArc(fi, tn); } if (j != dftPand->nrChildren() - 1) { fi = builder.addPlace(defaultCapacity, 0, dftPand->name() + "_F_" + std::to_string(j)); builder.setPlaceLayoutInfo(fi, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter)); builder.addOutputArc(tn, fi); } } } } template void DftToGspnTransformator::drawPOR(std::shared_ptr const> dftPor, bool isRepresentative) { uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILED); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftPor->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPor->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); uint64_t unavailableNode = 0; if (!smart || isRepresentative) { unavailableNode = addUnavailableNode(dftPor, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); } uint64_t tfail = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILING); builder.setTransitionLayoutInfo(tfail, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); builder.addOutputArc(tfail, nodeFailed); builder.addInhibitionArc(nodeFailed, tfail); builder.addInputArc(failedNodes.at(dftPor->children().front()->id()), tfail); builder.addOutputArc(tfail, failedNodes.at(dftPor->children().front()->id())); if(!smart || isRepresentative) { builder.addOutputArc(tfail, unavailableNode); } if(dftPor->isInclusive()) { // Inclusive POR uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILSAVE); builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); builder.addInhibitionArc(nodeFS, tfail); uint64_t j = 0; for (auto const& child : dftPor->children()) { if(j > 0) { uint64_t tfailsf = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILSAVING + std::to_string(j)); builder.setTransitionLayoutInfo(tfailsf, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter+3.0)); builder.addInputArc(failedNodes.at(child->id()), tfailsf); builder.addOutputArc(tfailsf, failedNodes.at(child->id())); builder.addOutputArc(tfailsf, nodeFS); builder.addInhibitionArc(nodeFS, tfailsf); builder.addInhibitionArc(failedNodes.at(dftPor->children().front()->id()), tfailsf); } ++j; } } else { // Exclusive POR uint64_t j = 0; for (auto const& child : dftPor->children()) { if(j > 0) { builder.addInhibitionArc(failedNodes.at(child->id()), tfail); } ++j; } } } template void DftToGspnTransformator::drawSPARE(std::shared_ptr const> dftSpare, bool isRepresentative) { uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSpare->name() + STR_FAILED); failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftSpare->id()).x; double ycenter = mDft.getElementLayoutInfo(dftSpare->id()).y; builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); uint64_t unavailableNode = 0; if (isRepresentative) { unavailableNode = addUnavailableNode(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } uint64_t spareActive = builder.addPlace(defaultCapacity, isBEActive(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-8.0)); activeNodes.emplace(dftSpare->id(), spareActive); std::vector cucNodes; std::vector considerNodes; std::vector nextclTransitions; std::vector nextconsiderTransitions; uint64_t j = 0; for(auto const& child : dftSpare->children()) { if (j > 0) { size_t nodeConsider = builder.addPlace(defaultCapacity, 0, dftSpare->name()+ "_consider_" + child->name()); considerNodes.push_back(nodeConsider); builder.setPlaceLayoutInfo(nodeConsider, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter-8.0)); builder.addOutputArc(nextclTransitions.back(), considerNodes.back(), 1); if (j > 1) { builder.addOutputArc(nextconsiderTransitions.back(), considerNodes.back()); } uint64_t tnextconsider = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); builder.setTransitionLayoutInfo(tnextconsider, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter-8.0)); builder.addInputArc(considerNodes.back(), tnextconsider); builder.addInputArc(unavailableNodes.at(child->id()), tnextconsider); nextconsiderTransitions.push_back(tnextconsider); } size_t nodeCUC = builder.addPlace(defaultCapacity, j == 0 ? 1 : 0, dftSpare->name() + "_claimed_" + child->name()); cucNodes.push_back(nodeCUC); builder.setPlaceLayoutInfo(nodeCUC, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter+5.0)); if (j > 0) { uint64_t tclaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); builder.setTransitionLayoutInfo(tclaim, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter)); builder.addInhibitionArc(unavailableNodes.at(child->id()), tclaim); builder.addInputArc(considerNodes.back(), tclaim); builder.addOutputArc(tclaim, cucNodes.back()); } uint64_t tnextcl = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(j)); builder.setTransitionLayoutInfo(tnextcl, storm::gspn::LayoutInfo(xcenter-3.0+j*14.0, ycenter+5.0)); builder.addInputArc(cucNodes.back(), tnextcl); builder.addInputArc(failedNodes.at(child->id()), tnextcl); builder.addOutputArc(tnextcl, failedNodes.at(child->id())); nextclTransitions.push_back(tnextcl); ++j; for (uint64_t k : mDft.module(child->id())) { uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); builder.addInputArc(cucNodes.back(), tactive); builder.addOutputArc(tactive, cucNodes.back()); builder.addInputArc(spareActive, tactive); builder.addOutputArc(tactive, activeNodes.at(k)); builder.addInhibitionArc(activeNodes.at(k), tactive); } } builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); builder.addOutputArc(nextclTransitions.back(), nodeFailed); if (isRepresentative) { builder.addOutputArc(nextconsiderTransitions.back(), unavailableNode); builder.addOutputArc(nextclTransitions.back(), unavailableNode); } } template void DftToGspnTransformator::drawCONSTF(std::shared_ptr const> dftConstF, bool isRepresentative) { failedNodes.push_back(builder.addPlace(defaultCapacity, 1, dftConstF->name() + STR_FAILED)); uint64_t unavailableNode = 0; if (isRepresentative) { // TODO set position unavailableNode = addUnavailableNode(dftConstF, storm::gspn::LayoutInfo(0, 0), false); } } // template void DftToGspnTransformator::drawCONSTS(std::shared_ptr const> dftConstS, bool isRepresentative) { // storm::gspn::Place placeCONSTSFailed; // placeCONSTSFailed.setName(dftConstS->name() + STR_FAILED); // placeCONSTSFailed.setNumberOfInitialTokens(0); // placeCONSTSFailed.setCapacity(0); // It cannot contain a token, because it cannot fail. // mGspn.addPlace(placeCONSTSFailed); } // template void DftToGspnTransformator::drawPDEP(std::shared_ptr const> dftDependency) { double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x;; double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y;; uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); uint64_t t1 = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); builder.addInputArc(coinPlace, t1); builder.addInputArc(failedNodes.at(dftDependency->triggerEvent()->id()), t1); builder.addOutputArc(t1, failedNodes.at(dftDependency->triggerEvent()->id())); uint64_t forwardPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_forward"); builder.setPlaceLayoutInfo(forwardPlace, storm::gspn::LayoutInfo(xcenter+1.0, ycenter+2.0)); if (!smart || dftDependency->probability() < 1.0) { uint64_t flipPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_flip"); builder.addOutputArc(t1, flipPlace); builder.setPlaceLayoutInfo(flipPlace, storm::gspn::LayoutInfo(xcenter-2.0, ycenter+2.0)); uint64_t t2 = builder.addImmediateTransition(defaultPriority + 1, dftDependency->probability(), "_win_flip"); builder.addInputArc(flipPlace, t2); builder.addOutputArc(t2, forwardPlace); if (dftDependency->probability() < 1.0) { uint64_t t3 = builder.addImmediateTransition(defaultPriority + 1, 1 - dftDependency->probability(), "_loose_flip"); builder.addInputArc(flipPlace, t3); } } else { builder.addOutputArc(t1, forwardPlace); } for(auto const& depEv : dftDependency->dependentEvents()) { uint64_t tx = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_propagate_" + depEv->name()); builder.addInputArc(forwardPlace, tx); builder.addOutputArc(tx, forwardPlace); builder.addOutputArc(tx, failedNodes.at(depEv->id())); builder.addInhibitionArc(failedNodes.at(depEv->id()), tx); if (!smart || depEv->nrRestrictions() > 0) { builder.addInhibitionArc(disabledNodes.at(depEv->id()), tx); } if (!smart || mDft.isRepresentative(depEv->id())) { builder.addOutputArc(tx, unavailableNodes.at(depEv->id())); } } } template void DftToGspnTransformator::drawSeq(std::shared_ptr const> dftSeq) { STORM_LOG_THROW(dftSeq->allChildrenBEs(), storm::exceptions::NotImplementedException, "Sequence enforcers with gates as children are currently not supported"); uint64_t j = 0; uint64_t tEnable = 0; uint64_t nextPlace = 0; for(auto const& child : dftSeq->children()) { nextPlace = builder.addPlace(defaultCapacity, j==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); if (j>0) { builder.addOutputArc(tEnable, nextPlace); } tEnable = builder.addImmediateTransition(defaultPriority + 1, 0.0, dftSeq->name() + "_unblock_" +child->name() ); builder.addInputArc(nextPlace, tEnable); builder.addInputArc(disabledNodes.at(child->id()), tEnable); if (j>0) { builder.addInputArc(failedNodes.at(dftSeq->children().at(j-1)->id()), tEnable); } ++j; } } template uint64_t DftToGspnTransformator::addUnavailableNode(std::shared_ptr const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { uint64_t unavailableNode = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavailable"); assert(unavailableNode != 0); unavailableNodes.emplace(dftElement->id(), unavailableNode); builder.setPlaceLayoutInfo(unavailableNode, layoutInfo); return unavailableNode; } template uint64_t DftToGspnTransformator::addDisabledPlace(std::shared_ptr > dftBe) { uint64_t disabledNode = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); disabledNodes.emplace(dftBe->id(), disabledNode); return disabledNode; } // template bool DftToGspnTransformator::isBEActive(std::shared_ptr const> dftElement) { // If element is the top element, return true. if (dftElement->id() == mDft.getTopLevelIndex()) { return true; } else { // Else look at all parents. auto parents = dftElement->parents(); std::vector pathValidities; for (std::size_t i = 0; i < parents.size(); i++) { // Add all parents to the vector, except if the parent is a SPARE and the current element is an inactive child of the SPARE. if (parents[i]->type() == storm::storage::DFTElementType::SPARE) { auto children = std::static_pointer_cast const>(parents[i])->children(); if (children[0]->id() != dftElement->id()) { continue; } } pathValidities.push_back(isBEActive(parents[i])); } // Check all vector entries. If one is true, a "valid" path has been found. for (std::size_t i = 0; i < pathValidities.size(); i++) { if (pathValidities[i]) { return true; } } } // No "valid" path found. BE is inactive. return false; } template uint64_t DftToGspnTransformator::getFailPriority(std::shared_ptr const> dftElement) { return mDft.maxRank() - dftElement->rank() + 2; } template void DftToGspnTransformator::drawGSPNRestrictions() { } template gspn::GSPN* DftToGspnTransformator::obtainGSPN() { return builder.buildGspn(); } // Explicitly instantiate the class. template class DftToGspnTransformator; #ifdef STORM_HAVE_CARL // template class DftToGspnTransformator; #endif } // namespace dft } // namespace transformations } // namespace storm