16template<
typename ValueType>
26template<
typename ValueType>
28 STORM_LOG_THROW(!mTopLevelName.empty(), storm::exceptions::WrongFormatException,
"No top level element defined.");
31 for (
auto& gateChildrenPair : mChildNames) {
32 STORM_LOG_ASSERT(gateChildrenPair.first->isGate(),
"Element " << *gateChildrenPair.first <<
" with children is not a gate.");
33 DFTGatePointer gate = std::static_pointer_cast<storm::dft::storage::elements::DFTGate<ValueType>>(gateChildrenPair.first);
34 for (std::string
const& childName : gateChildrenPair.second) {
35 auto itFind = mElements.find(childName);
36 STORM_LOG_THROW(itFind != mElements.end(), storm::exceptions::WrongFormatException,
37 "Child '" << childName <<
"' for gate '" << gate->name() <<
"' not found.");
38 DFTElementPointer childElement = itFind->second;
39 if (childElement->isRestriction()) {
40 STORM_LOG_WARN(
"Restriction '" << childName <<
"' is ignored as input for gate '" << gate->name() <<
"', because restrictions have no output.");
41 }
else if (childElement->isDependency()) {
42 STORM_LOG_WARN(
"Dependency '" << childName <<
"' is ignored as input for gate '" << gate->name() <<
"', because dependencies have no output.");
44 gate->addChild(childElement);
45 childElement->addParent(gate);
51 for (
auto& restrictionChildrenPair : mRestrictionChildNames) {
52 DFTRestrictionPointer restriction = restrictionChildrenPair.first;
53 for (std::string
const& childName : restrictionChildrenPair.second) {
54 auto itFind = mElements.find(childName);
55 STORM_LOG_THROW(itFind != mElements.end(), storm::exceptions::WrongFormatException,
56 "Child '" << childName <<
"' for restriction '" << restriction->name() <<
"' not found.");
57 DFTElementPointer childElement = itFind->second;
58 STORM_LOG_THROW(childElement->isGate() || childElement->isBasicElement(), storm::exceptions::WrongFormatException,
59 "Child '" << childElement->name() <<
"' of restriction '" << restriction->name() <<
"' must be gate or BE.");
60 restriction->addChild(childElement);
61 childElement->addRestriction(restriction);
66 for (
auto& dependencyChildrenPair : mDependencyChildNames) {
67 DFTDependencyPointer dependency = dependencyChildrenPair.first;
68 bool triggerElement =
true;
69 for (std::string
const& childName : dependencyChildrenPair.second) {
70 auto itFind = mElements.find(childName);
71 STORM_LOG_THROW(itFind != mElements.end(), storm::exceptions::WrongFormatException,
72 "Child '" << childName <<
"' for dependency '" << dependency->name() <<
"' not found.");
73 DFTElementPointer childElement = itFind->second;
75 triggerElement =
false;
76 STORM_LOG_THROW(childElement->isGate() || childElement->isBasicElement(), storm::exceptions::WrongFormatException,
77 "Trigger element '" << childName <<
"' of dependency '" << dependency->name() <<
"' must be gate or BE.");
79 childElement->addOutgoingDependency(dependency);
81 STORM_LOG_THROW(childElement->isBasicElement(), storm::exceptions::WrongFormatException,
82 "Dependent element '" << childName <<
"' of dependency '" << dependency->name() <<
"' must be BE.");
83 DFTBEPointer dependentBE = std::static_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType>>(childElement);
84 dependency->addDependentEvent(dependentBE);
85 dependentBE->addIngoingDependency(dependency);
91 DFTElementVector elements = sortTopological();
94 for (DFTElementPointer e : elements) {
98 computeRank(mElements[mTopLevelName]);
99 for (
auto& elem : mElements) {
100 computeRank(elem.second);
107 for (
auto& elem : mElements) {
108 if (mLayoutInfo.count(elem.first) > 0) {
120template<
typename ValueType>
122 STORM_LOG_THROW(!nameInUse(element->name()), storm::exceptions::InvalidArgumentException,
"Element with name '" << element->name() <<
"' already exists.");
123 STORM_LOG_ASSERT(mNextId == mElements.size(),
"Current id " << mNextId <<
" and number of elements " << mElements.size() <<
" do not match.");
124 element->setId(mNextId++);
125 mElements[element->name()] = element;
128template<
typename ValueType>
133template<
typename ValueType>
136 if (storm::utility::isZero<ValueType>(probability)) {
137 addBasicElementConst(name,
false);
138 }
else if (storm::utility::isOne<ValueType>(probability)) {
139 addBasicElementConst(name,
true);
141 STORM_LOG_THROW(isValidProbability(probability), storm::exceptions::WrongFormatException,
142 "Failure probability " << probability <<
" of BE " << name <<
" is not within interval [0, 1].");
143 STORM_LOG_THROW(isValidProbability(dormancyFactor), storm::exceptions::WrongFormatException,
144 "Dormancy factor " << dormancyFactor <<
" of BE " << name <<
" is not within interval [0, 1].");
149template<
typename ValueType>
152 if (storm::utility::isZero<ValueType>(rate)) {
153 addBasicElementConst(name,
false);
155 STORM_LOG_THROW(this->comparator.isLess(storm::utility::zero<ValueType>(), rate), storm::exceptions::WrongFormatException,
156 "Failure rate " << rate <<
" of BE " << name <<
" must be positive.");
157 STORM_LOG_THROW(isValidProbability(dormancyFactor), storm::exceptions::WrongFormatException,
158 "Dormancy factor " << dormancyFactor <<
" of BE " << name <<
" is not within interval [0, 1].");
163template<
typename ValueType>
166 if (storm::utility::isZero<ValueType>(rate)) {
167 addBasicElementConst(name,
false);
168 }
else if (phases == 1) {
170 addBasicElementExponential(name, rate, dormancyFactor);
172 STORM_LOG_THROW(this->comparator.isLess(storm::utility::zero<ValueType>(), rate), storm::exceptions::WrongFormatException,
173 "Erlang distribution of BE " << name <<
" requires a positive rate.");
174 STORM_LOG_THROW(phases > 0, storm::exceptions::WrongFormatException,
"Erlang distribution of BE " << name <<
" requires a positive number of phases.");
175 STORM_LOG_THROW(isValidProbability(dormancyFactor), storm::exceptions::WrongFormatException,
176 "Dormancy factor " << dormancyFactor <<
" of BE " << name <<
" is not within interval [0, 1].");
181template<
typename ValueType>
183 STORM_LOG_THROW(this->comparator.isLess(storm::utility::zero<ValueType>(), rate), storm::exceptions::WrongFormatException,
184 "Weibull distribution of BE " << name <<
" requires a positive scale.");
185 STORM_LOG_THROW(this->comparator.isLess(storm::utility::zero<ValueType>(), shape), storm::exceptions::WrongFormatException,
186 "Weibull distribution of BE " << name <<
" requires a positive shape.");
189 if (storm::utility::isOne<ValueType>(shape)) {
191 addBasicElementExponential(name, storm::utility::one<ValueType>() / rate, storm::utility::one<ValueType>());
197template<
typename ValueType>
199 STORM_LOG_THROW(this->comparator.isLess(storm::utility::zero<ValueType>(), standardDeviation), storm::exceptions::WrongFormatException,
200 "Log-normal distribution of BE " << name <<
" requires a positive standard deviation.");
204template<
typename ValueType>
207 bool canFail =
false;
208 for (
auto const& sample : activeSamples) {
217 addBasicElementConst(name,
false);
223template<
typename ValueType>
225 STORM_LOG_THROW(children.size() > 0, storm::exceptions::WrongFormatException,
"No children given for gate " << gate <<
".");
226 mChildNames[gate] = children;
230template<
typename ValueType>
235template<
typename ValueType>
240template<
typename ValueType>
242 STORM_LOG_THROW(threshold <= children.size(), storm::exceptions::WrongFormatException,
243 "Voting gate " << name <<
" has threshold " << threshold <<
" higher than the number of children " << children.size() <<
".");
245 if (children.size() == threshold) {
246 addAndGate(name, children);
247 }
else if (threshold == 1) {
248 addOrGate(name, children);
254template<
typename ValueType>
259template<
typename ValueType>
264template<
typename ValueType>
269template<
typename ValueType>
271 STORM_LOG_THROW(children.size() > 1, storm::exceptions::WrongFormatException,
"Dependency " << dependency->name() <<
" requires at least two children.");
273 STORM_LOG_WARN(
"Dependency " << dependency->name() <<
" with probability 0 is superfluous and will not be added.");
275 STORM_LOG_THROW(isValidProbability(dependency->probability()), storm::exceptions::WrongFormatException,
276 "Probability " << dependency->probability() <<
" of PDEP " << *dependency <<
" is not within interval [0, 1].");
277 mDependencyChildNames[dependency] = children;
278 addElement(dependency);
282template<
typename ValueType>
287template<
typename ValueType>
289 STORM_LOG_THROW(children.size() > 1, storm::exceptions::WrongFormatException,
"Restriction " << restriction->name() <<
" requires at least two children.");
290 mRestrictionChildNames[restriction] = children;
291 addElement(restriction);
294template<
typename ValueType>
299template<
typename ValueType>
304template<
typename ValueType>
306 STORM_LOG_THROW(mTopLevelName.empty(), storm::exceptions::WrongFormatException,
"Top level element was already set");
307 STORM_LOG_THROW(nameInUse(tle), storm::exceptions::InvalidArgumentException,
"Element with name '" << tle <<
"' not known.");
311template<
typename ValueType>
313 STORM_LOG_THROW(nameInUse(name), storm::exceptions::InvalidArgumentException,
"Element with name '" << name <<
"' not found.");
317template<
typename ValueType>
319 switch (element->type()) {
321 addElement(element->clone());
331 auto elemWithChildren = std::static_pointer_cast<storm::dft::storage::elements::DFTChildren<ValueType>
const>(element);
332 std::vector<std::string> children{};
333 for (DFTElementPointer
const& elem : elemWithChildren->children()) {
334 children.push_back(elem->name());
336 cloneElementWithNewChildren(elemWithChildren, children);
340 auto dependency = std::static_pointer_cast<storm::dft::storage::elements::DFTDependency<ValueType>
const>(element);
341 std::vector<std::string> children = {dependency->triggerEvent()->name()};
342 for (
auto const& depEv : dependency->dependentEvents()) {
343 children.push_back(depEv->name());
349 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"DFT element type '" << element->type() <<
"' not known.");
354template<
typename ValueType>
356 switch (elemWithChildren->type()) {
370 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"DFT element type '" << elemWithChildren->type() <<
"' not known.");
375template<
typename ValueType>
378 DFTElementVector& visitedElements) {
379 STORM_LOG_THROW(visited[element] != topoSortColour::GREY, storm::exceptions::WrongFormatException,
"DFT is cyclic.");
380 if (visited[element] == topoSortColour::WHITE) {
382 visited[element] = topoSortColour::GREY;
384 if (element->isGate()) {
385 for (DFTElementPointer
const& child :
std::static_pointer_cast<
storm::dft::storage::elements::DFTGate<ValueType>>(element)->children()) {
387 topologicalVisit(child, visited, visitedElements);
391 else if (element->isRestriction()) {
392 for (DFTElementPointer
const& child :
std::static_pointer_cast<
storm::dft::storage::elements::DFTRestriction<ValueType>>(element)->children()) {
394 topologicalVisit(child, visited, visitedElements);
396 }
else if (element->isDependency()) {
397 for (DFTElementPointer
const& child :
398 std::static_pointer_cast<
storm::dft::storage::elements::DFTDependency<
ValueType>>(element)->dependentEvents()) {
400 topologicalVisit(child, visited, visitedElements);
406 STORM_LOG_ASSERT(element->isBasicElement(),
"Unknown element type " << element->type() <<
" for " << *element);
409 visited[element] = topoSortColour::BLACK;
411 visitedElements.push_back(element);
415template<
typename ValueType>
416bool DFTBuilder<ValueType>::nameInUse(std::string
const& name)
const {
417 return mElements.find(name) != mElements.end();
420template<
typename ValueType>
421bool DFTBuilder<ValueType>::isValidProbability(ValueType value)
const {
422 if (this->comparator.isZero(value) || this->comparator.isOne(value)) {
424 }
else if (!this->comparator.isConstant(value)) {
427 }
else if (this->comparator.isLess(storm::utility::zero<ValueType>(), value) && this->comparator.isLess(value, storm::utility::one<ValueType>())) {
433template<
typename ValueType>
434std::vector<std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType>>> DFTBuilder<ValueType>::sortTopological() {
436 std::map<DFTElementPointer, topoSortColour, storm::dft::storage::OrderElementsById<ValueType>> visited;
437 for (
auto const& e : mElements) {
438 visited.insert(std::make_pair(e.second, topoSortColour::WHITE));
441 DFTElementVector visitedElements;
443 topologicalVisit(mElements[mTopLevelName], visited, visitedElements);
444 for (
auto const& e : visited) {
446 topologicalVisit(e.first, visited, visitedElements);
448 return visitedElements;
451template<
typename ValueType>
452size_t DFTBuilder<ValueType>::computeRank(DFTElementPointer
const& elem) {
453 if (elem->rank() ==
static_cast<decltype(elem-
>rank())>(-1)) {
455 if (elem->isBasicElement() || elem->isDependency() || elem->isRestriction()) {
460 DFTGatePointer gate = std::static_pointer_cast<storm::dft::storage::elements::DFTGate<ValueType>>(elem);
462 for (DFTElementPointer
const& child : gate->children()) {
463 maxRank = std::max(maxRank, computeRank(child));
465 elem->setRank(maxRank + 1);
473template class DFTBuilder<double>;
474template class DFTBuilder<RationalFunction>;