#include "DFTBuilder.h" #include "DFT.h" #include #include "OrderDFTElementsById.h" #include #include #include "../../exceptions/WrongFormatException.h" namespace storm { namespace storage { template DFT DFTBuilder::build() { for(auto& elem : mChildNames) { DFTGatePointer gate = std::static_pointer_cast>(elem.first); for(auto const& child : elem.second) { auto itFind = mElements.find(child); if (itFind != mElements.end()) { // Child found DFTElementPointer childElement = itFind->second; assert(!childElement->isDependency()); gate->pushBackChild(childElement); childElement->addParent(gate); } else { // Child not found -> find first dependent event to assure that child is dependency auto itFind = mElements.find(child + "_1"); assert(itFind != mElements.end()); assert(itFind->second->isDependency()); STORM_LOG_TRACE("Ignore functional dependency " << child << " in gate " << gate->name()); } } } // Initialize dependencies for (auto& dependency : mDependencies) { DFTGatePointer triggerEvent = std::static_pointer_cast>(mElements[dependency->nameTrigger()]); assert(mElements[dependency->nameDependent()]->isBasicElement()); std::shared_ptr> dependentEvent = std::static_pointer_cast>(mElements[dependency->nameDependent()]); dependency->initialize(triggerEvent, dependentEvent); triggerEvent->addDependency(dependency); } // Sort elements topologically // compute rank for (auto& elem : mElements) { computeRank(elem.second); } DFTElementVector elems = topoSort(); size_t id = 0; for(DFTElementPointer e : elems) { e->setId(id++); } return DFT(elems, mElements[topLevelIdentifier]); } template unsigned DFTBuilder::computeRank(DFTElementPointer const& elem) { if(elem->rank() == -1) { if(elem->nrChildren() == 0 || elem->isDependency()) { elem->setRank(0); } else { DFTGatePointer gate = std::static_pointer_cast>(elem); unsigned maxrnk = 0; unsigned newrnk = 0; for (DFTElementPointer const &child : gate->children()) { newrnk = computeRank(child); if (newrnk > maxrnk) { maxrnk = newrnk; } } elem->setRank(maxrnk + 1); } } return elem->rank(); } template bool DFTBuilder::addStandardGate(std::string const& name, std::vector const& children, DFTElementType tp) { assert(children.size() > 0); if(mElements.count(name) != 0) { // Element with that name already exists. return false; } DFTElementPointer element; switch(tp) { case DFTElementType::AND: element = std::make_shared>(mNextId++, name); break; case DFTElementType::OR: element = std::make_shared>(mNextId++, name); break; case DFTElementType::PAND: element = std::make_shared>(mNextId++, name); break; case DFTElementType::POR: element = std::make_shared>(mNextId++, name); break; case DFTElementType::SPARE: element = std::make_shared>(mNextId++, name); break; case DFTElementType::BE: case DFTElementType::VOT: // Handled separately STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type handled separately."); case DFTElementType::CONSTF: case DFTElementType::CONSTS: case DFTElementType::PDEP: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not supported."); default: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not known."); } mElements[name] = element; mChildNames[element] = children; return true; } template void DFTBuilder::topoVisit(DFTElementPointer const& n, std::map& visited, DFTElementVector& L) { if(visited[n] == topoSortColour::GREY) { throw storm::exceptions::WrongFormatException("DFT is cyclic"); } else if(visited[n] == topoSortColour::WHITE) { if(n->isGate()) { visited[n] = topoSortColour::GREY; for(DFTElementPointer const& c : std::static_pointer_cast>(n)->children()) { topoVisit(c, visited, L); } } visited[n] = topoSortColour::BLACK; L.push_back(n); } } // TODO Matthias: use typedefs template std::vector>> DFTBuilder::topoSort() { std::map visited; for(auto const& e : mElements) { visited.insert(std::make_pair(e.second, topoSortColour::WHITE)); } DFTElementVector L; for(auto const& e : visited) { topoVisit(e.first, visited, L); } //std::reverse(L.begin(), L.end()); return L; } // Explicitly instantiate the class. template class DFTBuilder; #ifdef STORM_HAVE_CARL template class DFTBuilder; #endif } }