Browse Source

Refactored and sorted bitvector

Former-commit-id: 28ca00af50
tempestpy_adaptions
Mavo 9 years ago
parent
commit
0d3687cf5e
  1. 43
      src/builder/ExplicitDFTModelBuilder.cpp
  2. 8
      src/builder/ExplicitDFTModelBuilder.h
  3. 100
      src/storage/dft/DFT.cpp
  4. 115
      src/storage/dft/DFT.h
  5. 23
      src/storage/dft/DFTElements.h
  6. 72
      src/storage/dft/DFTState.cpp
  7. 16
      src/storage/dft/DFTState.h

43
src/builder/ExplicitDFTModelBuilder.cpp

@ -13,11 +13,52 @@ namespace storm {
ExplicitDFTModelBuilder<ValueType>::ModelComponents::ModelComponents() : transitionMatrix(), stateLabeling(), markovianStates(), exitRates(), choiceLabeling() {
// Intentionally left empty.
}
template <typename ValueType>
ExplicitDFTModelBuilder<ValueType>::ExplicitDFTModelBuilder(storm::storage::DFT<ValueType> const& dft) : mDft(dft), mStates(((mDft.stateVectorSize() / 64) + 1) * 64, std::pow(2, mDft.nrBasicElements())) {
// stateSize is bound for size of bitvector
// 2^nrBE is upper bound for state space
// Find symmetries
// TODO activate
// Currently using hack to test
std::vector<std::vector<size_t>> symmetries;
std::vector<size_t> vecB;
std::vector<size_t> vecC;
std::vector<size_t> vecD;
if (false) {
for (size_t i = 0; i < mDft.nrElements(); ++i) {
std::string name = mDft.getElement(i)->name();
size_t id = mDft.getElement(i)->id();
if (boost::starts_with(name, "B")) {
vecB.push_back(id);
} else if (boost::starts_with(name, "C")) {
vecC.push_back(id);
} else if (boost::starts_with(name, "D")) {
vecD.push_back(id);
}
}
symmetries.push_back(vecB);
symmetries.push_back(vecC);
symmetries.push_back(vecD);
std::cout << "Found the following symmetries:" << std::endl;
for (auto const& symmetry : symmetries) {
for (auto const& elem : symmetry) {
std::cout << elem << " -> ";
}
std::cout << std::endl;
}
} else {
vecB.push_back(mDft.getTopLevelIndex());
}
mStateGenerationInfo = std::make_shared<storm::storage::DFTStateGenerationInfo>(mDft.buildStateGenerationInfo(vecB, symmetries));
}
template <typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> ExplicitDFTModelBuilder<ValueType>::buildModel() {
// Initialize
DFTStatePointer state = std::make_shared<storm::storage::DFTState<ValueType>>(mDft, newIndex++);
DFTStatePointer state = std::make_shared<storm::storage::DFTState<ValueType>>(mDft, *mStateGenerationInfo, newIndex++);
mStates.findOrAdd(state->status(), state);
std::queue<DFTStatePointer> stateQueue;

8
src/builder/ExplicitDFTModelBuilder.h

@ -44,15 +44,13 @@ namespace storm {
boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> choiceLabeling;
};
storm::storage::DFT<ValueType> const &mDft;
storm::storage::DFT<ValueType> const& mDft;
std::shared_ptr<storm::storage::DFTStateGenerationInfo> mStateGenerationInfo;
storm::storage::BitVectorHashMap<DFTStatePointer> mStates;
size_t newIndex = 0;
public:
ExplicitDFTModelBuilder(storm::storage::DFT<ValueType> const &dft) : mDft(dft), mStates(((mDft.stateVectorSize() / 64) + 1) * 64, std::pow(2, mDft.nrBasicElements())) {
// stateSize is bound for size of bitvector
// 2^nrBE is upper bound for state space
}
ExplicitDFTModelBuilder(storm::storage::DFT<ValueType> const& dft);
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildModel();

100
src/storage/dft/DFT.cpp

@ -10,15 +10,18 @@ namespace storm {
namespace storage {
template<typename ValueType>
DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mTopLevelIndex(tle->id()), mNrOfBEs(0), mNrOfSpares(0)
{
DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mNrOfBEs(0), mNrOfSpares(0), mTopLevelIndex(tle->id()) {
assert(elementIndicesCorrect());
mUsageInfoBits = storm::utility::math::uint64_log2(mElements.size()-1)+1;
size_t stateIndex = 0;
size_t stateVectorIndex = 0;
std::set<size_t> tmpRepresentatives;
size_t usageInfoBits = storm::utility::math::uint64_log2(mElements.size()-1)+1;
size_t nrRepresentatives = 0;
for (auto& elem : mElements) {
mIdToFailureIndex.push_back(stateIndex);
stateIndex += 2;
stateVectorIndex += 2;
if (isRepresentative(elem->id())) {
++nrRepresentatives;
}
if(elem->isBasicElement()) {
++mNrOfBEs;
}
@ -26,9 +29,7 @@ namespace storm {
++mNrOfSpares;
bool firstChild = true;
for(auto const& spareReprs : std::static_pointer_cast<DFTSpare<ValueType>>(elem)->children()) {
if(mActivationIndex.count(spareReprs->id()) == 0) {
mActivationIndex[spareReprs->id()] = stateIndex++;
}
tmpRepresentatives.insert(spareReprs->id());
std::set<size_t> module = {spareReprs->id()};
spareReprs->extendSpareModule(module);
std::vector<size_t> sparesAndBes;
@ -44,14 +45,13 @@ namespace storm {
mSpareModules.insert(std::make_pair(spareReprs->id(), sparesAndBes));
firstChild = false;
}
std::static_pointer_cast<DFTSpare<ValueType>>(elem)->setUseIndex(stateIndex);
mUsageIndex.insert(std::make_pair(elem->id(), stateIndex));
stateIndex += mUsageInfoBits;
stateVectorIndex += usageInfoBits;
} else if (elem->isDependency()) {
mDependencies.push_back(elem->id());
}
}
stateVectorIndex += tmpRepresentatives.size();
// For the top module, we assume, contrary to [Jun15], that we have all spare gates and basic elements which are not in another module.
std::set<size_t> topModuleSet;
@ -68,12 +68,84 @@ namespace storm {
}
}
mTopModule = std::vector<size_t>(topModuleSet.begin(), topModuleSet.end());
mStateVectorSize = stateIndex;
std::cout << tmpRepresentatives.size() << ", " << nrRepresentatives << std::endl;
std::cout << stateVectorIndex << ", " << (nrElements() * 2 + mNrOfSpares * usageInfoBits + tmpRepresentatives.size()) << std::endl;
assert(tmpRepresentatives.size() == nrRepresentatives);
assert(stateVectorIndex == nrElements() * 2 + mNrOfSpares * usageInfoBits + tmpRepresentatives.size());
mStateVectorSize = stateVectorIndex;
}
template<typename ValueType>
DFTStateGenerationInfo DFT<ValueType>::buildStateGenerationInfo(std::vector<size_t> const& subTreeRoots, std::vector<std::vector<size_t>> const& symmetries) const {
// Use symmetry
// Collect all elements in the first subtree
// TODO make recursive to use for nested subtrees
DFTStateGenerationInfo generationInfo(nrElements());
// Perform DFS and insert all elements of subtree sequentially
size_t stateIndex = 0;
std::queue<size_t> visitQueue;
std::set<size_t> visited;
visitQueue.push(subTreeRoots[0]);
bool consideredDependencies = false;
while (true) {
while (!visitQueue.empty()) {
size_t id = visitQueue.front();
visitQueue.pop();
if (visited.count(id) == 1) {
// Already visited
continue;
}
visited.insert(id);
DFTElementPointer element = mElements[id];
// Insert children
if (element->isGate()) {
for (auto const& child : std::static_pointer_cast<DFTGate<ValueType>>(element)->children()) {
visitQueue.push(child->id());
}
}
// Reserve bits for element
generationInfo.addStateIndex(id, stateIndex);
stateIndex += 2;
if (isRepresentative(id)) {
generationInfo.addSpareActivationIndex(id, stateIndex);
++stateIndex;
}
if (element->isSpareGate()) {
generationInfo.addSpareUsageIndex(id, stateIndex);
stateIndex += generationInfo.usageInfoBits();
}
}
if (consideredDependencies) {
break;
}
// Consider dependencies
for (size_t idDependency : getDependencies()) {
std::shared_ptr<DFTDependency<ValueType> const> dependency = getDependency(idDependency);
visitQueue.push(dependency->id());
visitQueue.push(dependency->triggerEvent()->id());
visitQueue.push(dependency->dependentEvent()->id());
}
consideredDependencies = true;
}
assert(stateIndex = mStateVectorSize);
STORM_LOG_TRACE(generationInfo);
return generationInfo;
}
template<typename ValueType>
std::string DFT<ValueType>::getElementsString() const {
std::stringstream stream;

115
src/storage/dft/DFT.h

@ -33,6 +33,69 @@ namespace storm {
// Forward declarations
template<typename T> class DFTColouring;
class DFTStateGenerationInfo {
private:
const size_t mUsageInfoBits;
std::map<size_t, size_t> mSpareUsageIndex; // id spare -> index first bit in state
std::map<size_t, size_t> mSpareActivationIndex; // id spare representative -> index in state
std::vector<size_t> mIdToStateIndex; // id -> index first bit in state
public:
DFTStateGenerationInfo(size_t nrElements) : mUsageInfoBits(storm::utility::math::uint64_log2(nrElements-1)+1), mIdToStateIndex(nrElements) {
}
size_t usageInfoBits() const {
return mUsageInfoBits;
}
void addStateIndex(size_t id, size_t index) {
assert(id < mIdToStateIndex.size());
mIdToStateIndex[id] = index;
}
void addSpareActivationIndex(size_t id, size_t index) {
mSpareActivationIndex[id] = index;
}
void addSpareUsageIndex(size_t id, size_t index) {
mSpareUsageIndex[id] = index;
}
size_t getStateIndex(size_t id) const {
assert(id < mIdToStateIndex.size());
return mIdToStateIndex[id];
}
size_t getSpareUsageIndex(size_t id) const {
assert(mSpareUsageIndex.count(id) > 0);
return mSpareUsageIndex.at(id);
}
size_t getSpareActivationIndex(size_t id) const {
assert(mSpareActivationIndex.count(id) > 0);
return mSpareActivationIndex.at(id);
}
friend std::ostream& operator<<(std::ostream& os, DFTStateGenerationInfo const& info) {
os << "Id to state index:" << std::endl;
for (size_t id = 0; id < info.mIdToStateIndex.size(); ++id) {
os << id << " -> " << info.getStateIndex(id) << std::endl;
}
os << "Spare usage index with usage InfoBits of size " << info.mUsageInfoBits << ":" << std::endl;
for (auto pair : info.mSpareUsageIndex) {
os << pair.first << " -> " << pair.second << std::endl;
}
os << "Spare activation index:" << std::endl;
for (auto pair : info.mSpareActivationIndex) {
os << pair.first << " -> " << pair.second << std::endl;
}
return os;
}
};
/**
* Represents a Dynamic Fault Tree
@ -52,18 +115,17 @@ namespace storm {
size_t mNrOfBEs;
size_t mNrOfSpares;
size_t mTopLevelIndex;
size_t mUsageInfoBits;
size_t mStateVectorSize;
std::map<size_t, size_t> mActivationIndex;
std::map<size_t, std::vector<size_t>> mSpareModules;
std::vector<size_t> mDependencies;
std::vector<size_t> mTopModule;
std::vector<size_t> mIdToFailureIndex;
std::map<size_t, size_t> mUsageIndex;
std::map<size_t, size_t> mRepresentants;
std::map<size_t, size_t> mRepresentants; // id element -> id representative
std::vector<std::vector<size_t>> mSymmetries;
public:
DFT(DFTElementVector const& elements, DFTElementPointer const& tle);
DFTStateGenerationInfo buildStateGenerationInfo(std::vector<size_t> const& subTreeRoots, std::vector<std::vector<size_t>> const& symmetries) const;
size_t stateVectorSize() const {
return mStateVectorSize;
@ -77,34 +139,8 @@ namespace storm {
return mNrOfBEs;
}
size_t usageInfoBits() const {
return mUsageInfoBits;
}
size_t usageIndex(size_t id) const {
assert(mUsageIndex.find(id) != mUsageIndex.end());
return mUsageIndex.find(id)->second;
}
size_t failureIndex(size_t id) const {
return mIdToFailureIndex[id];
}
void initializeUses(DFTState<ValueType>& state) const {
for(auto const& elem : mElements) {
if(elem->isSpareGate()) {
std::static_pointer_cast<DFTSpare<ValueType>>(elem)->initializeUses(state);
}
}
}
void initializeActivation(DFTState<ValueType>& state) const {
state.activate(mTopLevelIndex);
for(auto const& elem : mTopModule) {
if(mElements[elem]->isSpareGate()) {
propagateActivation(state, state.uses(elem));
}
}
size_t getTopLevelIndex() const {
return mTopLevelIndex;
}
std::vector<size_t> getSpareIndices() const {
@ -130,15 +166,6 @@ namespace storm {
return mDependencies;
}
void propagateActivation(DFTState<ValueType>& state, size_t representativeId) const {
state.activate(representativeId);
for(size_t id : module(representativeId)) {
if(mElements[id]->isSpareGate()) {
propagateActivation(state, state.uses(id));
}
}
}
std::vector<size_t> nonColdBEs() const {
std::vector<size_t> result;
for(DFTElementPointer elem : mElements) {
@ -170,10 +197,6 @@ namespace storm {
return getElement(index)->isDependency();
}
// std::shared_ptr<DFTGate<ValueType> const> getGate(size_t index) const {
// return
// }
std::shared_ptr<DFTBE<ValueType> const> getBasicElement(size_t index) const {
assert(isBasicElement(index));
return std::static_pointer_cast<DFTBE<ValueType> const>(mElements[index]);

23
src/storage/dft/DFTElements.h

@ -898,10 +898,6 @@ namespace storm {
template<typename ValueType>
class DFTSpare : public DFTGate<ValueType> {
private:
size_t mUseIndex;
size_t mActiveIndex;
public:
DFTSpare(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
DFTGate<ValueType>(id, name, children)
@ -919,24 +915,11 @@ namespace storm {
return true;
}
void setUseIndex(size_t useIndex) {
mUseIndex = useIndex;
}
void setActiveIndex(size_t activeIndex) {
mActiveIndex = activeIndex;
}
void initializeUses(storm::storage::DFTState<ValueType>& state) {
assert(this->mChildren.size() > 0);
state.setUsesAtPosition(mUseIndex, this->mChildren[0]->id());
}
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
if(state.isOperational(this->mId)) {
size_t uses = state.extractUses(mUseIndex);
size_t uses = state.uses(this->mId);
if(!state.isOperational(uses)) {
bool claimingSuccessful = state.claimNew(this->mId, mUseIndex, uses, this->mChildren);
bool claimingSuccessful = state.claimNew(this->mId, uses, this->mChildren);
if(!claimingSuccessful) {
this->fail(state, queues);
}
@ -946,7 +929,7 @@ namespace storm {
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
if(state.isOperational(this->mId)) {
if(state.isFailsafe(state.extractUses((mUseIndex)))) {
if(state.isFailsafe(state.uses(this->mId))) {
this->failsafe(state, queues);
this->childrenDontCare(state, queues);
}

72
src/storage/dft/DFTState.cpp

@ -6,10 +6,25 @@ namespace storm {
namespace storage {
template<typename ValueType>
DFTState<ValueType>::DFTState(DFT<ValueType> const& dft, size_t id) : mStatus(dft.stateVectorSize()), mId(id), mDft(dft) {
DFTState<ValueType>::DFTState(DFT<ValueType> const& dft, DFTStateGenerationInfo const& stateGenerationInfo, size_t id) : mStatus(dft.stateVectorSize()), mId(id), mDft(dft), mStateGenerationInfo(stateGenerationInfo) {
mInactiveSpares = dft.getSpareIndices();
dft.initializeUses(*this);
dft.initializeActivation(*this);
// Initialize uses
for(size_t id : mDft.getSpareIndices()) {
std::shared_ptr<DFTGate<ValueType> const> elem = mDft.getGate(id);
assert(elem->isSpareGate());
assert(elem->nrChildren() > 0);
this->setUses(id, elem->children()[0]->id());
}
// Initialize activation
this->activate(mDft.getTopLevelIndex());
for(auto const& id : mDft.module(mDft.getTopLevelIndex())) {
if(mDft.getElement(id)->isSpareGate()) {
propagateActivation(uses(id));
}
}
std::vector<size_t> alwaysActiveBEs = dft.nonColdBEs();
mIsCurrentlyFailableBE.insert(mIsCurrentlyFailableBE.end(), alwaysActiveBEs.begin(), alwaysActiveBEs.end());
}
@ -26,7 +41,7 @@ namespace storm {
template<typename ValueType>
int DFTState<ValueType>::getElementStateInt(size_t id) const {
return mStatus.getAsInt(mDft.failureIndex(id), 2);
return mStatus.getAsInt(mStateGenerationInfo.getStateIndex(id), 2);
}
template<typename ValueType>
@ -46,12 +61,12 @@ namespace storm {
template<typename ValueType>
bool DFTState<ValueType>::hasFailed(size_t id) const {
return mStatus[mDft.failureIndex(id)];
return mStatus[mStateGenerationInfo.getStateIndex(id)];
}
template<typename ValueType>
bool DFTState<ValueType>::isFailsafe(size_t id) const {
return mStatus[mDft.failureIndex(id)+1];
return mStatus[mStateGenerationInfo.getStateIndex(id)+1];
}
template<typename ValueType>
@ -66,38 +81,38 @@ namespace storm {
template<typename ValueType>
bool DFTState<ValueType>::dependencySuccessful(size_t id) const {
return mStatus[mDft.failureIndex(id)];
return mStatus[mStateGenerationInfo.getStateIndex(id)];
}
template<typename ValueType>
bool DFTState<ValueType>::dependencyUnsuccessful(size_t id) const {
return mStatus[mDft.failureIndex(id)+1];
return mStatus[mStateGenerationInfo.getStateIndex(id)+1];
}
template<typename ValueType>
void DFTState<ValueType>::setFailed(size_t id) {
mStatus.set(mDft.failureIndex(id));
mStatus.set(mStateGenerationInfo.getStateIndex(id));
}
template<typename ValueType>
void DFTState<ValueType>::setFailsafe(size_t id) {
mStatus.set(mDft.failureIndex(id)+1);
mStatus.set(mStateGenerationInfo.getStateIndex(id)+1);
}
template<typename ValueType>
void DFTState<ValueType>::setDontCare(size_t id) {
mStatus.setFromInt(mDft.failureIndex(id), 2, static_cast<uint_fast64_t>(DFTElementState::DontCare) );
mStatus.setFromInt(mStateGenerationInfo.getStateIndex(id), 2, static_cast<uint_fast64_t>(DFTElementState::DontCare) );
}
template<typename ValueType>
void DFTState<ValueType>::setDependencySuccessful(size_t id) {
// No distinction between successful dependency and no dependency at all
// -> we do not set bit
//mStatus.set(mDft.failureIndex(id));
// => we do not set bit
//mStatus.set(mStateGenerationInfo.mIdToStateIndex(id));
}
template<typename ValueType>
void DFTState<ValueType>::setDependencyUnsuccessful(size_t id) {
mStatus.set(mDft.failureIndex(id)+1);
mStatus.set(mStateGenerationInfo.getStateIndex(id)+1);
}
template<typename ValueType>
@ -157,8 +172,7 @@ namespace storm {
template<typename ValueType>
void DFTState<ValueType>::activate(size_t repr) {
std::vector<size_t> const& module = mDft.module(repr);
for(size_t elem : module) {
for(size_t elem : mDft.module(repr)) {
if(mDft.getElement(elem)->isColdBasicElement() && isOperational(elem)) {
mIsCurrentlyFailableBE.push_back(elem);
}
@ -174,16 +188,26 @@ namespace storm {
assert(mDft.getElement(id)->isSpareGate());
return (std::find(mInactiveSpares.begin(), mInactiveSpares.end(), id) == mInactiveSpares.end());
}
template<typename ValueType>
void DFTState<ValueType>::propagateActivation(size_t representativeId) {
activate(representativeId);
for(size_t id : mDft.module(representativeId)) {
if(mDft.getElement(id)->isSpareGate()) {
propagateActivation(uses(id));
}
}
}
template<typename ValueType>
uint_fast64_t DFTState<ValueType>::uses(size_t id) const {
return extractUses(mDft.usageIndex(id));
return extractUses(mStateGenerationInfo.getSpareUsageIndex(id));
}
template<typename ValueType>
uint_fast64_t DFTState<ValueType>::extractUses(size_t from) const {
assert(mDft.usageInfoBits() < 64);
return mStatus.getAsInt(from, mDft.usageInfoBits());
assert(mStateGenerationInfo.usageInfoBits() < 64);
return mStatus.getAsInt(from, mStateGenerationInfo.usageInfoBits());
}
template<typename ValueType>
@ -192,13 +216,13 @@ namespace storm {
}
template<typename ValueType>
void DFTState<ValueType>::setUsesAtPosition(size_t usageIndex, size_t child) {
mStatus.setFromInt(usageIndex, mDft.usageInfoBits(), child);
void DFTState<ValueType>::setUses(size_t spareId, size_t child) {
mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), child);
mUsedRepresentants.push_back(child);
}
template<typename ValueType>
bool DFTState<ValueType>::claimNew(size_t spareId, size_t usageIndex, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children) {
bool DFTState<ValueType>::claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children) {
auto it = children.begin();
while ((*it)->id() != currentlyUses) {
assert(it != children.end());
@ -208,9 +232,9 @@ namespace storm {
while(it != children.end()) {
size_t childId = (*it)->id();
if(!hasFailed(childId) && !isUsed(childId)) {
setUsesAtPosition(usageIndex, childId);
setUses(spareId, childId);
if(isActiveSpare(spareId)) {
mDft.propagateActivation(*this, childId);
propagateActivation(childId);
}
return true;
}

16
src/storage/dft/DFTState.h

@ -17,6 +17,7 @@ namespace storm {
class DFTBE;
template<typename ValueType>
class DFTElement;
class DFTStateGenerationInfo;
template<typename ValueType>
class DFTState {
@ -31,9 +32,10 @@ namespace storm {
std::vector<size_t> mUsedRepresentants;
bool mValid = true;
const DFT<ValueType>& mDft;
const DFTStateGenerationInfo& mStateGenerationInfo;
public:
DFTState(DFT<ValueType> const& dft, size_t id);
DFTState(DFT<ValueType> const& dft, DFTStateGenerationInfo const& stateGenerationInfo, size_t id);
DFTElementState getElementState(size_t id) const;
@ -75,6 +77,8 @@ namespace storm {
bool isActiveSpare(size_t id) const;
void propagateActivation(size_t representativeId);
void markAsInvalid() {
mValid = false;
}
@ -109,13 +113,13 @@ namespace storm {
bool isUsed(size_t child) const;
/**
* Sets to to the usageIndex which child is now used.
* @param usageIndex
* @param child
* Sets for the spare which child is now used.
* @param spareId Id of the spare
* @param child Id of the child which is now used
*/
void setUsesAtPosition(size_t usageIndex, size_t child);
void setUses(size_t spareId, size_t child);
bool claimNew(size_t spareId, size_t usageIndex, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children);
bool claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children);
bool hasOutgoingEdges() const {
return !mIsCurrentlyFailableBE.empty();

Loading…
Cancel
Save