You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
6.2 KiB
155 lines
6.2 KiB
|
|
#ifndef DFTBUILDER_H
|
|
#define DFTBUILDER_H
|
|
|
|
#include "DFTElements.h"
|
|
#include <iostream>
|
|
#include <unordered_map>
|
|
#include <map>
|
|
#include "src/utility/macros.h"
|
|
|
|
namespace storm {
|
|
namespace storage {
|
|
template<typename ValueType>
|
|
class DFT;
|
|
|
|
template<typename ValueType>
|
|
class DFTBuilder {
|
|
|
|
using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>;
|
|
using DFTElementVector = std::vector<DFTElementPointer>;
|
|
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
|
|
using DFTGateVector = std::vector<DFTGatePointer>;
|
|
using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
|
|
|
|
private:
|
|
std::size_t mNextId = 0;
|
|
std::string topLevelIdentifier;
|
|
std::unordered_map<std::string, DFTElementPointer> mElements;
|
|
std::unordered_map<DFTElementPointer, std::vector<std::string>> mChildNames;
|
|
std::vector<DFTDependencyPointer> mDependencies;
|
|
|
|
public:
|
|
DFTBuilder() {
|
|
|
|
}
|
|
|
|
bool addAndElement(std::string const& name, std::vector<std::string> const& children) {
|
|
return addStandardGate(name, children, DFTElementType::AND);
|
|
}
|
|
|
|
bool addOrElement(std::string const& name, std::vector<std::string> const& children) {
|
|
return addStandardGate(name, children, DFTElementType::OR);
|
|
}
|
|
|
|
bool addPandElement(std::string const& name, std::vector<std::string> const& children) {
|
|
return addStandardGate(name, children, DFTElementType::PAND);
|
|
}
|
|
|
|
bool addPorElement(std::string const& name, std::vector<std::string> const& children) {
|
|
return addStandardGate(name, children, DFTElementType::POR);
|
|
}
|
|
|
|
bool addSpareElement(std::string const& name, std::vector<std::string> const& children) {
|
|
return addStandardGate(name, children, DFTElementType::SPARE);
|
|
}
|
|
|
|
bool addDepElement(std::string const& name, std::vector<std::string> const& children, ValueType probability) {
|
|
assert(children.size() > 1);
|
|
if(mElements.count(name) != 0) {
|
|
// Element with that name already exists.
|
|
return false;
|
|
}
|
|
|
|
if (storm::utility::isZero(probability)) {
|
|
// Element is superfluous
|
|
return true;
|
|
}
|
|
std::string trigger = children[0];
|
|
|
|
//TODO Matthias: collect constraints for SMT solving
|
|
//0 <= probability <= 1
|
|
if (!storm::utility::isOne(probability) && children.size() > 2) {
|
|
//TODO Matthias: introduce additional element for probability and then add pdeps with probability 1 to children
|
|
STORM_LOG_ERROR("Probability != 1 for more than one child currently not supported.");
|
|
return false;
|
|
}
|
|
|
|
for (size_t i = 1; i < children.size(); ++i) {
|
|
std::string nameDep = name + "_" + std::to_string(i);
|
|
if(mElements.count(nameDep) != 0) {
|
|
// Element with that name already exists.
|
|
STORM_LOG_ERROR("Element with name: " << nameDep << " already exists.");
|
|
return false;
|
|
}
|
|
assert(storm::utility::isOne(probability) || children.size() == 2);
|
|
DFTDependencyPointer element = std::make_shared<DFTDependency<ValueType>>(mNextId++, nameDep, trigger, children[i], probability);
|
|
mElements[element->name()] = element;
|
|
mDependencies.push_back(element);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool addVotElement(std::string const& name, unsigned threshold, std::vector<std::string> const& children) {
|
|
assert(children.size() > 0);
|
|
if(mElements.count(name) != 0) {
|
|
STORM_LOG_ERROR("Element with name: " << name << " already exists.");
|
|
return false;
|
|
}
|
|
// It is an and-gate
|
|
if(children.size() == threshold) {
|
|
return addAndElement(name, children);
|
|
}
|
|
// It is an or-gate
|
|
if(threshold == 1) {
|
|
return addOrElement(name, children);
|
|
}
|
|
|
|
if(threshold > children.size()) {
|
|
STORM_LOG_ERROR("Voting gates with threshold higher than the number of children is not supported.");
|
|
return false;
|
|
}
|
|
DFTElementPointer element = std::make_shared<DFTVot<ValueType>>(mNextId++, name, threshold);
|
|
|
|
mElements[name] = element;
|
|
mChildNames[element] = children;
|
|
return true;
|
|
}
|
|
|
|
bool addBasicElement(std::string const& name, ValueType failureRate, ValueType dormancyFactor) {
|
|
//TODO Matthias: collect constraints for SMT solving
|
|
//failureRate > 0
|
|
//0 <= dormancyFactor <= 1
|
|
|
|
mElements[name] = std::make_shared<DFTBE<ValueType>>(mNextId++, name, failureRate, dormancyFactor);
|
|
return true;
|
|
}
|
|
|
|
bool setTopLevel(std::string const& tle) {
|
|
topLevelIdentifier = tle;
|
|
return mElements.count(tle) > 0;
|
|
}
|
|
|
|
DFT<ValueType> build();
|
|
|
|
|
|
private:
|
|
|
|
unsigned computeRank(DFTElementPointer const& elem);
|
|
|
|
bool addStandardGate(std::string const& name, std::vector<std::string> const& children, DFTElementType tp);
|
|
|
|
enum class topoSortColour {WHITE, BLACK, GREY};
|
|
|
|
void topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>>& visited, DFTElementVector& L);
|
|
|
|
DFTElementVector topoSort();
|
|
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif /* DFTBUILDER_H */
|
|
|