Browse Source

Fixed problems with pdeps

Former-commit-id: c46c88b177
tempestpy_adaptions
Mavo 9 years ago
parent
commit
c78d9ff802
  1. 3
      benchmark_dft.py
  2. 5
      examples/dft/pdep3.dft
  3. 42
      src/builder/ExplicitDFTModelBuilder.cpp
  4. 12
      src/storage/dft/DFT.cpp
  5. 1
      src/storage/dft/DFTBuilder.cpp
  6. 48
      src/storage/dft/DFTElementState.h
  7. 2
      src/storage/dft/DFTElements.cpp
  8. 30
      src/storage/dft/DFTElements.h
  9. 42
      src/storage/dft/DFTState.cpp
  10. 23
      src/storage/dft/DFTState.h

3
benchmark_dft.py

@ -31,8 +31,9 @@ benchmarks = [
("or", False, [1, 1]), ("or", False, [1, 1]),
("pand", False, ["inf", 0.666667]), ("pand", False, ["inf", 0.666667]),
("pand_param", True, ["-1", "(x)/(y+x)"]), ("pand_param", True, ["-1", "(x)/(y+x)"]),
("pdep", False, [0, 1]), #Compute
("pdep", False, [2.66667, 1]),
("pdep2", False, [0, 1]), #Compute ("pdep2", False, [0, 1]), #Compute
("pdep3", False, [2.79167, 1]),
("spare", False, [3.53846, 1]), ("spare", False, [3.53846, 1]),
("spare2", False, [1.86957, 1]), ("spare2", False, [1.86957, 1]),
("spare3", False, [1.27273, 1]), ("spare3", False, [1.27273, 1]),

5
examples/dft/pdep3.dft

@ -0,0 +1,5 @@
toplevel "A";
"A" and "B" "C" "F";
"F" pdep=0.3 "B" "C";
"B" lambda=0.4 dorm=0;
"C" lambda=0.8 dorm=0;

42
src/builder/ExplicitDFTModelBuilder.cpp

@ -77,17 +77,20 @@ namespace storm {
// TODO Matthias: avoid transforming back and forth // TODO Matthias: avoid transforming back and forth
storm::storage::SparseMatrix<ValueType> rateMatrix(modelComponents.transitionMatrix); storm::storage::SparseMatrix<ValueType> rateMatrix(modelComponents.transitionMatrix);
for (uint_fast64_t row = 0; row < rateMatrix.getRowCount(); ++row) { for (uint_fast64_t row = 0; row < rateMatrix.getRowCount(); ++row) {
assert(row < modelComponents.markovianStates.size());
if (modelComponents.markovianStates.get(row)) { if (modelComponents.markovianStates.get(row)) {
for (auto& entry : rateMatrix.getRow(row)) { for (auto& entry : rateMatrix.getRow(row)) {
entry.setValue(entry.getValue() * modelComponents.exitRates[row]); entry.setValue(entry.getValue() * modelComponents.exitRates[row]);
} }
} }
} }
if (deterministic) { if (deterministic) {
model = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(std::move(rateMatrix), std::move(modelComponents.stateLabeling)); model = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(std::move(rateMatrix), std::move(modelComponents.stateLabeling));
} else { } else {
model = std::make_shared<storm::models::sparse::MarkovAutomaton<ValueType>>(std::move(rateMatrix), std::move(modelComponents.stateLabeling), std::move(modelComponents.markovianStates), std::move(modelComponents.exitRates)); model = std::make_shared<storm::models::sparse::MarkovAutomaton<ValueType>>(std::move(rateMatrix), std::move(modelComponents.stateLabeling), std::move(modelComponents.markovianStates), std::move(modelComponents.exitRates));
} }
model->printModelInformationToStream(std::cout); model->printModelInformationToStream(std::cout);
return model; return model;
} }
@ -143,9 +146,6 @@ namespace storm {
assert(nextBEPair.second == hasDependencies); assert(nextBEPair.second == hasDependencies);
STORM_LOG_TRACE("with the failure of: " << nextBE->name() << " [" << nextBE->id() << "]"); STORM_LOG_TRACE("with the failure of: " << nextBE->name() << " [" << nextBE->id() << "]");
// Update failable dependencies
newState->updateFailableDependencies(nextBE->id());
// Propagate failures // Propagate failures
storm::storage::DFTStateSpaceGenerationQueues<ValueType> queues; storm::storage::DFTStateSpaceGenerationQueues<ValueType> queues;
@ -170,6 +170,9 @@ namespace storm {
next->checkDontCareAnymore(*newState, queues); next->checkDontCareAnymore(*newState, queues);
} }
// Update failable dependencies
newState->updateFailableDependencies(nextBE->id());
if (mStates.contains(newState->status())) { if (mStates.contains(newState->status())) {
// State already exists // State already exists
newState = mStates.findOrAdd(newState->status(), newState); newState = mStates.findOrAdd(newState->status(), newState);
@ -180,7 +183,7 @@ namespace storm {
mStates.findOrAdd(newState->status(), newState); mStates.findOrAdd(newState->status(), newState);
STORM_LOG_TRACE("New state " << mDft.getStateString(newState)); STORM_LOG_TRACE("New state " << mDft.getStateString(newState));
// Add state to search
// Add state to search queue
stateQueue.push(newState); stateQueue.push(newState);
} }
@ -188,8 +191,37 @@ namespace storm {
if (hasDependencies) { if (hasDependencies) {
// Failure is due to dependency -> add non-deterministic choice // Failure is due to dependency -> add non-deterministic choice
std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dependency = mDft.getDependency(state->getDependencyId(smallest-1)); std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dependency = mDft.getDependency(state->getDependencyId(smallest-1));
transitionMatrixBuilder.addNextValue(state->getId() + rowOffset++, newState->getId(), dependency->probability());
transitionMatrixBuilder.addNextValue(state->getId() + rowOffset, newState->getId(), dependency->probability());
STORM_LOG_TRACE("Added transition from " << state->getId() << " to " << newState->getId() << " with probability " << dependency->probability()); STORM_LOG_TRACE("Added transition from " << state->getId() << " to " << newState->getId() << " with probability " << dependency->probability());
if (!storm::utility::isOne(dependency->probability())) {
// Add transition to state where dependency was unsuccessful
DFTStatePointer unsuccessfulState = std::make_shared<storm::storage::DFTState<ValueType>>(*state);
unsuccessfulState->letDependencyBeUnsuccessful(smallest-1);
if (mStates.contains(unsuccessfulState->status())) {
// Unsuccessful state already exists
unsuccessfulState = mStates.findOrAdd(unsuccessfulState->status(), unsuccessfulState);
STORM_LOG_TRACE("State " << mDft.getStateString(unsuccessfulState) << " already exists");
} else {
// New unsuccessful state
unsuccessfulState->setId(newIndex++);
mStates.findOrAdd(unsuccessfulState->status(), unsuccessfulState);
STORM_LOG_TRACE("New state " << mDft.getStateString(unsuccessfulState));
// Add unsuccessful state to search queue
stateQueue.push(unsuccessfulState);
}
ValueType remainingProbability = storm::utility::one<ValueType>() - dependency->probability();
transitionMatrixBuilder.addNextValue(state->getId() + rowOffset, unsuccessfulState->getId(), remainingProbability);
STORM_LOG_TRACE("Added transition from " << state->getId() << " to " << unsuccessfulState->getId() << " with probability " << remainingProbability);
} else {
// Self-loop with probability one cannot be eliminated later one.
assert(state->getId() != newState->getId());
}
++rowOffset;
} else { } else {
// Set failure rate according to usage // Set failure rate according to usage
bool isUsed = true; bool isUsed = true;

12
src/storage/dft/DFT.cpp

@ -118,13 +118,17 @@ namespace storm {
for (auto const& elem : mElements) { for (auto const& elem : mElements) {
stream << "[" << elem->id() << "]"; stream << "[" << elem->id() << "]";
stream << elem->toString(); stream << elem->toString();
stream << "\t** " << state->getElementState(elem->id());
if (elem->isDependency()) {
stream << "\t** " << storm::storage::toChar(state->getDependencyState(elem->id()));
} else {
stream << "\t** " << storm::storage::toChar(state->getElementState(elem->id()));
if(elem->isSpareGate()) { if(elem->isSpareGate()) {
if(state->isActiveSpare(elem->id())) { if(state->isActiveSpare(elem->id())) {
stream << " actively"; stream << " actively";
} }
stream << " using " << state->uses(elem->id()); stream << " using " << state->uses(elem->id());
} }
}
stream << std::endl; stream << std::endl;
} }
return stream.str(); return stream.str();
@ -135,7 +139,10 @@ namespace storm {
std::stringstream stream; std::stringstream stream;
stream << "(" << state->getId() << ") "; stream << "(" << state->getId() << ") ";
for (auto const& elem : mElements) { for (auto const& elem : mElements) {
stream << state->getElementStateInt(elem->id());
if (elem->isDependency()) {
stream << storm::storage::toChar(state->getDependencyState(elem->id())) << "[dep]";
} else {
stream << storm::storage::toChar(state->getElementState(elem->id()));
if(elem->isSpareGate()) { if(elem->isSpareGate()) {
stream << "["; stream << "[";
if(state->isActiveSpare(elem->id())) { if(state->isActiveSpare(elem->id())) {
@ -144,6 +151,7 @@ namespace storm {
stream << "using " << state->uses(elem->id()) << "]"; stream << "using " << state->uses(elem->id()) << "]";
} }
} }
}
return stream.str(); return stream.str();
} }

1
src/storage/dft/DFTBuilder.cpp

@ -40,6 +40,7 @@ namespace storm {
DFTGatePointer triggerEvent = std::static_pointer_cast<DFTGate<ValueType>>(mElements[dependency->nameTrigger()]); DFTGatePointer triggerEvent = std::static_pointer_cast<DFTGate<ValueType>>(mElements[dependency->nameTrigger()]);
std::shared_ptr<DFTBE<ValueType>> dependentEvent = std::static_pointer_cast<DFTBE<ValueType>>(mElements[dependency->nameDependent()]); std::shared_ptr<DFTBE<ValueType>> dependentEvent = std::static_pointer_cast<DFTBE<ValueType>>(mElements[dependency->nameDependent()]);
dependency->initialize(triggerEvent, dependentEvent); dependency->initialize(triggerEvent, dependentEvent);
triggerEvent->addDependency(dependency);
} }
// Sort elements topologically // Sort elements topologically

48
src/storage/dft/DFTElementState.h

@ -2,6 +2,8 @@
#ifndef DFTELEMENTSTATE_H #ifndef DFTELEMENTSTATE_H
#define DFTELEMENTSTATE_H #define DFTELEMENTSTATE_H
#include <cassert>
namespace storm { namespace storm {
namespace storage { namespace storage {
enum class DFTElementState {Operational = 0, Failed = 2, Failsafe = 1, DontCare = 3}; enum class DFTElementState {Operational = 0, Failed = 2, Failsafe = 1, DontCare = 3};
@ -17,7 +19,53 @@ namespace storm {
case DFTElementState::DontCare: case DFTElementState::DontCare:
return os << "Don't Care"; return os << "Don't Care";
} }
assert(false);
}
inline char toChar(DFTElementState st) {
switch(st) {
case DFTElementState::Operational:
return 'O';
case DFTElementState::Failed:
return 'F';
case DFTElementState::Failsafe:
return 'S';
case DFTElementState::DontCare:
return '-';
}
assert(false);
}
enum class DFTDependencyState {Passive = 0, Unsuccessful = 1, Successful = 2, DontCare = 3};
inline std::ostream& operator<<(std::ostream& os, DFTDependencyState st) {
switch(st) {
case DFTDependencyState::Passive:
return os << "Passive";
case DFTDependencyState::Successful:
return os << "Successful";
case DFTDependencyState::Unsuccessful:
return os << "Unsuccessful";
case DFTDependencyState::DontCare:
return os << "Don't Care";
}
assert(false);
} }
inline char toChar(DFTDependencyState st) {
switch(st) {
case DFTDependencyState::Passive:
return 'P';
case DFTDependencyState::Successful:
return 'S';
case DFTDependencyState::Unsuccessful:
return 'U';
case DFTDependencyState::DontCare:
return '-';
}
assert(false);
}
} }
} }

2
src/storage/dft/DFTElements.cpp

@ -7,7 +7,7 @@ namespace storm {
template<typename ValueType> template<typename ValueType>
bool DFTElement<ValueType>::checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const { bool DFTElement<ValueType>::checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
if(!state.dontCare(mId))
if(!state.dontCare(mId) && !hasDependencies())
{ {
for(DFTGatePointer const& parent : mParents) { for(DFTGatePointer const& parent : mParents) {
if(state.isOperational(parent->id())) { if(state.isOperational(parent->id())) {

30
src/storage/dft/DFTElements.h

@ -24,11 +24,16 @@ namespace storm {
template<typename ValueType> template<typename ValueType>
class DFTGate; class DFTGate;
template<typename ValueType>
class DFTDependency;
template<typename ValueType> template<typename ValueType>
class DFTElement { class DFTElement {
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>; using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
using DFTGateVector = std::vector<DFTGatePointer>; using DFTGateVector = std::vector<DFTGatePointer>;
using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
using DFTDependencyVector = std::vector<DFTDependencyPointer>;
protected: protected:
@ -36,6 +41,7 @@ namespace storm {
std::string mName; std::string mName;
size_t mRank = -1; size_t mRank = -1;
DFTGateVector mParents; DFTGateVector mParents;
DFTDependencyVector dependencies;
public: public:
DFTElement(size_t id, std::string const& name) : DFTElement(size_t id, std::string const& name) :
@ -133,6 +139,29 @@ namespace storm {
return res; return res;
} }
bool addDependency(DFTDependencyPointer const& e) {
if(std::find(dependencies.begin(), dependencies.end(), e) != dependencies.end()) {
return false;
}
else
{
dependencies.push_back(e);
return true;
}
}
bool hasDependencies() const {
return !dependencies.empty();
}
size_t nrDependencies() const {
return dependencies.size();
}
DFTDependencyVector const& getDependencies() const {
return dependencies;
}
virtual void extendSpareModule(std::set<size_t>& elementsInModule) const; virtual void extendSpareModule(std::set<size_t>& elementsInModule) const;
virtual size_t nrChildren() const = 0; virtual size_t nrChildren() const = 0;
@ -433,7 +462,6 @@ namespace storm {
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>; using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
using DFTBEPointer = std::shared_ptr<DFTBE<ValueType>>; using DFTBEPointer = std::shared_ptr<DFTBE<ValueType>>;
using DFTBEVector = std::vector<DFTBEPointer>;
protected: protected:
std::string mNameTrigger; std::string mNameTrigger;

42
src/storage/dft/DFTState.cpp

@ -20,6 +20,11 @@ namespace storm {
return static_cast<DFTElementState>(getElementStateInt(id)); return static_cast<DFTElementState>(getElementStateInt(id));
} }
template<typename ValueType>
DFTDependencyState DFTState<ValueType>::getDependencyState(size_t id) const {
return static_cast<DFTDependencyState>(getElementStateInt(id));
}
template<typename ValueType> template<typename ValueType>
int DFTState<ValueType>::getElementStateInt(size_t id) const { int DFTState<ValueType>::getElementStateInt(size_t id) const {
return mStatus.getAsInt(mDft.failureIndex(id), 2); return mStatus.getAsInt(mDft.failureIndex(id), 2);
@ -55,6 +60,20 @@ namespace storm {
return getElementState(id) == DFTElementState::DontCare; return getElementState(id) == DFTElementState::DontCare;
} }
template<typename ValueType>
bool DFTState<ValueType>::dependencyTriggered(size_t id) const {
return getElementStateInt(id) > 0;
}
template<typename ValueType>
bool DFTState<ValueType>::dependencySuccessful(size_t id) const {
return mStatus[mDft.failureIndex(id)];
}
template<typename ValueType>
bool DFTState<ValueType>::dependencyUnsuccessful(size_t id) const {
return mStatus[mDft.failureIndex(id)+1];
}
template<typename ValueType> template<typename ValueType>
void DFTState<ValueType>::setFailed(size_t id) { void DFTState<ValueType>::setFailed(size_t id) {
mStatus.set(mDft.failureIndex(id)); mStatus.set(mDft.failureIndex(id));
@ -70,6 +89,16 @@ namespace storm {
mStatus.setFromInt(mDft.failureIndex(id), 2, static_cast<uint_fast64_t>(DFTElementState::DontCare) ); mStatus.setFromInt(mDft.failureIndex(id), 2, static_cast<uint_fast64_t>(DFTElementState::DontCare) );
} }
template<typename ValueType>
void DFTState<ValueType>::setDependencySuccessful(size_t id) {
mStatus.set(mDft.failureIndex(id));
}
template<typename ValueType>
void DFTState<ValueType>::setDependencyUnsuccessful(size_t id) {
mStatus.set(mDft.failureIndex(id)+1);
}
template<typename ValueType> template<typename ValueType>
void DFTState<ValueType>::beNoLongerFailable(size_t id) { void DFTState<ValueType>::beNoLongerFailable(size_t id) {
auto it = std::find(mIsCurrentlyFailableBE.begin(), mIsCurrentlyFailableBE.end(), id); auto it = std::find(mIsCurrentlyFailableBE.begin(), mIsCurrentlyFailableBE.end(), id);
@ -84,7 +113,8 @@ namespace storm {
for (size_t i = 0; i < mDft.getDependencies().size(); ++i) { for (size_t i = 0; i < mDft.getDependencies().size(); ++i) {
std::shared_ptr<DFTDependency<ValueType> const> dependency = mDft.getDependency(mDft.getDependencies()[i]); std::shared_ptr<DFTDependency<ValueType> const> dependency = mDft.getDependency(mDft.getDependencies()[i]);
if (dependency->triggerEvent()->id() == id) { if (dependency->triggerEvent()->id() == id) {
if (!hasFailed(dependency->dependentEvent()->id())) {
if (getElementState(dependency->dependentEvent()->id()) == DFTElementState::Operational) {
assert(!isFailsafe(dependency->dependentEvent()->id()));
mFailableDependencies.push_back(dependency->id()); mFailableDependencies.push_back(dependency->id());
STORM_LOG_TRACE("New dependency failure: " << dependency->toString()); STORM_LOG_TRACE("New dependency failure: " << dependency->toString());
} }
@ -99,10 +129,12 @@ namespace storm {
STORM_LOG_TRACE("currently failable: " << getCurrentlyFailableString()); STORM_LOG_TRACE("currently failable: " << getCurrentlyFailableString());
if (nrFailableDependencies() > 0) { if (nrFailableDependencies() > 0) {
// Consider failure due to dependency // Consider failure due to dependency
assert(index < nrFailableDependencies());
std::shared_ptr<DFTDependency<ValueType> const> dependency = mDft.getDependency(getDependencyId(index)); std::shared_ptr<DFTDependency<ValueType> const> dependency = mDft.getDependency(getDependencyId(index));
std::pair<std::shared_ptr<DFTBE<ValueType> const>,bool> res(mDft.getBasicElement(dependency->dependentEvent()->id()), true); std::pair<std::shared_ptr<DFTBE<ValueType> const>,bool> res(mDft.getBasicElement(dependency->dependentEvent()->id()), true);
mFailableDependencies.erase(mFailableDependencies.begin() + index); mFailableDependencies.erase(mFailableDependencies.begin() + index);
setFailed(res.first->id()); setFailed(res.first->id());
setDependencySuccessful(dependency->id());
return res; return res;
} else { } else {
// Consider "normal" failure // Consider "normal" failure
@ -114,6 +146,14 @@ namespace storm {
} }
} }
template<typename ValueType>
void DFTState<ValueType>::letDependencyBeUnsuccessful(size_t index) {
assert(nrFailableDependencies() > 0 && index < nrFailableDependencies());
std::shared_ptr<DFTDependency<ValueType> const> dependency = mDft.getDependency(getDependencyId(index));
mFailableDependencies.erase(mFailableDependencies.begin() + index);
setDependencyUnsuccessful(dependency->id());
}
template<typename ValueType> template<typename ValueType>
void DFTState<ValueType>::activate(size_t repr) { void DFTState<ValueType>::activate(size_t repr) {
std::vector<size_t> const& module = mDft.module(repr); std::vector<size_t> const& module = mDft.module(repr);

23
src/storage/dft/DFTState.h

@ -22,6 +22,7 @@ namespace storm {
class DFTState { class DFTState {
friend struct std::hash<DFTState>; friend struct std::hash<DFTState>;
private: private:
// Status is bitvector where each element has two bits with the meaning according to DFTElementState
storm::storage::BitVector mStatus; storm::storage::BitVector mStatus;
size_t mId; size_t mId;
std::vector<size_t> mInactiveSpares; std::vector<size_t> mInactiveSpares;
@ -36,6 +37,8 @@ namespace storm {
DFTElementState getElementState(size_t id) const; DFTElementState getElementState(size_t id) const;
DFTDependencyState getDependencyState(size_t id) const;
int getElementStateInt(size_t id) const; int getElementStateInt(size_t id) const;
size_t getId() const; size_t getId() const;
@ -50,12 +53,22 @@ namespace storm {
bool dontCare(size_t id) const; bool dontCare(size_t id) const;
bool dependencyTriggered(size_t id) const;
bool dependencySuccessful(size_t id) const;
bool dependencyUnsuccessful(size_t id) const;
void setFailed(size_t id); void setFailed(size_t id);
void setFailsafe(size_t id); void setFailsafe(size_t id);
void setDontCare(size_t id); void setDontCare(size_t id);
void setDependencySuccessful(size_t id);
void setDependencyUnsuccessful(size_t id);
void beNoLongerFailable(size_t id); void beNoLongerFailable(size_t id);
void activate(size_t repr); void activate(size_t repr);
@ -135,10 +148,16 @@ namespace storm {
/** /**
* Sets the next BE as failed * Sets the next BE as failed
* @param smallestIndex Index in currentlyFailableBE of BE to fail
* @param index Index in currentlyFailableBE of BE to fail
* @return Pair of BE which fails and flag indicating if the failure was due to functional dependencies * @return Pair of BE which fails and flag indicating if the failure was due to functional dependencies
*/ */
std::pair<std::shared_ptr<DFTBE<ValueType> const>, bool> letNextBEFail(size_t smallestIndex = 0);
std::pair<std::shared_ptr<DFTBE<ValueType> const>, bool> letNextBEFail(size_t index = 0);
/**
* Sets the dependency as unsuccesful meaning no BE will fail.
* @param index Index of dependency to fail.
*/
void letDependencyBeUnsuccessful(size_t index = 0);
std::string getCurrentlyFailableString() const { std::string getCurrentlyFailableString() const {
std::stringstream stream; std::stringstream stream;

Loading…
Cancel
Save