|
|
@ -2,6 +2,7 @@ |
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include "DFT.h"
|
|
|
|
#include "DFTBuilder.h"
|
|
|
|
#include "src/exceptions/NotSupportedException.h"
|
|
|
|
|
|
|
|
#include "DFTIsomorphism.h"
|
|
|
@ -229,6 +230,95 @@ namespace storm { |
|
|
|
return stateIndex; |
|
|
|
} |
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
|
DFT<ValueType> DFT<ValueType>::optimize() const { |
|
|
|
std::vector<size_t> modIdea = findModularisationRewrite(); |
|
|
|
std::cout << "Modularisation idea: " << std::endl; |
|
|
|
|
|
|
|
for( auto const& i : modIdea ) { |
|
|
|
std::cout << i << ", "; |
|
|
|
} |
|
|
|
|
|
|
|
if (modIdea.empty()) { |
|
|
|
// No rewrite needed
|
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::vector<size_t>> rewriteIds; |
|
|
|
rewriteIds.push_back(modIdea); |
|
|
|
|
|
|
|
DFTBuilder<ValueType> builder; |
|
|
|
|
|
|
|
// Accumulate elements which must be rewritten
|
|
|
|
std::set<size_t> rewriteSet; |
|
|
|
for (std::vector<size_t> rewrites : rewriteIds) { |
|
|
|
rewriteSet.insert(rewrites.front()); |
|
|
|
} |
|
|
|
// Copy all other elements which do not change
|
|
|
|
for (auto elem : mElements) { |
|
|
|
if (rewriteSet.count(elem->id()) == 0) { |
|
|
|
builder.copyElement(elem); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Add rewritten elements
|
|
|
|
for (std::vector<size_t> rewrites : rewriteIds) { |
|
|
|
assert(rewrites.size() > 1); |
|
|
|
assert(mElements[rewrites[1]]->hasParents()); |
|
|
|
assert(mElements[rewrites[1]]->parents().front()->isGate()); |
|
|
|
DFTGatePointer originalParent = std::static_pointer_cast<DFTGate<ValueType>>(mElements[rewrites[1]]->parents().front()); |
|
|
|
std::string newParentName = builder.getUniqueName(originalParent->name()); |
|
|
|
|
|
|
|
// Accumulate children names
|
|
|
|
std::vector<std::string> childrenNames; |
|
|
|
for (size_t i = 1; i < rewrites.size(); ++i) { |
|
|
|
assert(mElements[rewrites[i]]->parents().front()->id() == originalParent->id()); // Children have the same father
|
|
|
|
childrenNames.push_back(mElements[rewrites[i]]->name()); |
|
|
|
} |
|
|
|
|
|
|
|
// Add element inbetween parent and children
|
|
|
|
switch (originalParent->type()) { |
|
|
|
case DFTElementType::AND: |
|
|
|
builder.addAndElement(newParentName, childrenNames); |
|
|
|
break; |
|
|
|
case DFTElementType::OR: |
|
|
|
builder.addOrElement(newParentName, childrenNames); |
|
|
|
break; |
|
|
|
case DFTElementType::BE: |
|
|
|
case DFTElementType::CONSTF: |
|
|
|
case DFTElementType::CONSTS: |
|
|
|
case DFTElementType::VOT: |
|
|
|
case DFTElementType::PAND: |
|
|
|
case DFTElementType::SPARE: |
|
|
|
case DFTElementType::POR: |
|
|
|
case DFTElementType::PDEP: |
|
|
|
case DFTElementType::SEQ: |
|
|
|
case DFTElementType::MUTEX: |
|
|
|
// Other elements are not supported
|
|
|
|
assert(false); |
|
|
|
break; |
|
|
|
default: |
|
|
|
assert(false); |
|
|
|
} |
|
|
|
|
|
|
|
// Add parent with the new child newParent and all its remaining children
|
|
|
|
childrenNames.clear(); |
|
|
|
childrenNames.push_back(newParentName); |
|
|
|
for (auto const& child : originalParent->children()) { |
|
|
|
if (std::find(rewrites.begin()+1, rewrites.end(), child->id()) == rewrites.end()) { |
|
|
|
// Child was not rewritten and must be kept
|
|
|
|
childrenNames.push_back(child->name()); |
|
|
|
} |
|
|
|
} |
|
|
|
builder.copyGate(originalParent, childrenNames); |
|
|
|
} |
|
|
|
|
|
|
|
builder.setTopLevel(mElements[mTopLevelIndex]->name()); |
|
|
|
// TODO use reference?
|
|
|
|
DFT<ValueType> newDft = builder.build(); |
|
|
|
return newDft.optimize(); |
|
|
|
} |
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
|
std::string DFT<ValueType>::getElementsString() const { |
|
|
|
std::stringstream stream; |
|
|
@ -484,7 +574,6 @@ namespace storm { |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Explicitly instantiate the class.
|
|
|
|
template class DFT<double>; |
|
|
|
|
|
|
|