sjunges
9 years ago
2 changed files with 183 additions and 8 deletions
@ -1,25 +1,201 @@ |
|||||
#pragma once |
#pragma once |
||||
|
|
||||
#include <vector> |
#include <vector> |
||||
|
#include <unordered_map> |
||||
|
#include "DFTElementType.h" |
||||
|
#include "DFTElements.h" |
||||
|
|
||||
namespace storm { |
namespace storm { |
||||
namespace storage { |
namespace storage { |
||||
|
|
||||
|
|
||||
|
struct GateGroupToHash { |
||||
|
static constexpr uint_fast64_t fivebitmask = (1 << 6) - 1; |
||||
|
static constexpr uint_fast64_t eightbitmaks = (1 << 8) - 1; |
||||
|
|
||||
|
/** |
||||
|
* Hash function, which ensures that the colours are sorted according to their rank. |
||||
|
*/ |
||||
|
uint_fast64_t operator()(DFTElementType type, size_t nrChildren, size_t nrParents, size_t nrPDEPs, size_t rank) const { |
||||
|
// Sets first bit to 1 |
||||
|
uint_fast64_t groupHash = static_cast<uint_fast64_t>(1) << 63; |
||||
|
//Assumes 5 bits for the rank, |
||||
|
groupHash |= (static_cast<uint_fast64_t>(rank) & fivebitmask) << (62 - 5); |
||||
|
// 8 bits for the nrChildren, |
||||
|
groupHash |= (static_cast<uint_fast64_t>(nrChildren) & eightbitmaks) << (62 - 5 - 8); |
||||
|
// 5 bits for nrParents, |
||||
|
groupHash |= (static_cast<uint_fast64_t>(nrParents) & fivebitmask) << (62 - 5 - 8 - 5); |
||||
|
// 5 bits for nrPDEPs, |
||||
|
groupHash |= (static_cast<uint_fast64_t>(nrPDEPs) & fivebitmask) << (62 - 5 - 8 - 5 - 5); |
||||
|
// 5 bits for the type |
||||
|
groupHash |= (static_cast<uint_fast64_t>(type) & fivebitmask) << (62 - 5 - 8 - 5 - 5 - 5); |
||||
|
return groupHash; |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
/** |
/** |
||||
* Saves isomorphism between subtrees |
|
||||
|
* |
||||
*/ |
*/ |
||||
class DFTIsomorphism { |
|
||||
std::vector<std::vector<size_t>> classes; |
|
||||
|
template<typename ValueType> |
||||
|
class BijectionCandidates { |
||||
|
std::unordered_map<size_t, std::vector<size_t>> groupCandidates; |
||||
|
std::unordered_map<std::pair<ValueType, ValueType>, std::vector<size_t>> beCandidates; |
||||
|
|
||||
}; |
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
/** |
||||
* Saves sets of isomorphic subtrees |
|
||||
|
* Saves isomorphism between subtrees |
||||
*/ |
*/ |
||||
class DFTIsomorphisms { |
|
||||
std::vector<DFTIsomorphism> isomorphisms; |
|
||||
|
template<typename ValueType> |
||||
|
class DFTIsomorphismCheck { |
||||
|
/// Coloured nodes as provided by the input: left hand side |
||||
|
BijectionCandidates<ValueType> const& bleft; |
||||
|
/// Coloured nodes as provided by the input: right hand side. |
||||
|
BijectionCandidates<ValueType> const& bright; |
||||
|
/// Whether the colourings are compatible |
||||
|
bool candidatesCompatible = true; |
||||
|
/// Current bijection |
||||
|
std::map<size_t, size_t> bijection; |
||||
|
/// Current permutations of right hand side groups which lead to the homomorphism. |
||||
|
/// Contains only colours with more than one member. |
||||
|
BijectionCandidates<ValueType> currentPermutations; |
||||
|
|
||||
|
public: |
||||
|
DFTIsomorphismCheck(BijectionCandidates<ValueType> const& left, BijectionCandidates<ValueType> const& right) : bleft(left), bright(right) |
||||
|
{ |
||||
|
checkCompatibility(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether the candidates are compatible, that is, checks the colours and the number of members for each colour. |
||||
|
* @return True iff compatible, ie if the preliminary check allows for a isomorphism. |
||||
|
*/ |
||||
|
bool compatible() { |
||||
|
return candidatesCompatible; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Returns the isomorphism |
||||
|
* Can only be called after the findIsomorphism procedure returned that an isomorphism has found. |
||||
|
* @see findIsomorphism |
||||
|
*/ |
||||
|
std::vector<std::pair<size_t, size_t>> getIsomorphism() const { |
||||
|
|
||||
|
} |
||||
|
|
||||
void addIsomorphismClass(DFTIsomorphism const &) { |
|
||||
|
/** |
||||
|
* Check whether an isomorphism exists. |
||||
|
* |
||||
|
* @return true iff an isomorphism exists. |
||||
|
*/ |
||||
|
bool findIsomorphism() { |
||||
|
if(!candidatesCompatible) return false; |
||||
|
constructInitialBijection(); |
||||
|
while(!check()) { |
||||
|
// continue our search |
||||
|
if(!findNextBijection()) { |
||||
|
// No further bijections to check, no is |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
protected: |
||||
|
|
||||
|
void constructInitialBijection() { |
||||
|
assert(candidatesCompatible); |
||||
|
// We first construct the currentPermutations, which helps to determine the current state of the check. |
||||
|
for(auto const& colour : bright.beCandidates) { |
||||
|
if(colour.second.size()>1) { |
||||
|
currentPermutations.beCandidates.insert(colour); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for(auto const& colour : bright.groupCandidates) { |
||||
|
if(colour.second.size()>1) { |
||||
|
currentPermutations.groupCandidates.insert(colour); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Constructing the initial homomorphism based on the right hand side instead of the current permutations allows us |
||||
|
// to treat trivial and non-trivial classes in one go. |
||||
|
for(auto const& colour : bleft.beCandidates) { |
||||
|
zipVectorsIntoMap(colour.second, bright.beCandidates.find(colour.first)->second, bijection); |
||||
|
} |
||||
|
|
||||
|
for(auto const& colour : bleft.groupCandidates) { |
||||
|
zipVectorsIntoMap(colour.second, bright.groupCandidates.find(colour.first)->second, bijection); |
||||
|
} |
||||
|
|
||||
} |
} |
||||
|
|
||||
|
bool findNextBijection() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
*/ |
||||
|
bool check() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
/** |
||||
|
* Returns true if the colours are compatible. |
||||
|
*/ |
||||
|
bool checkCompatibility() { |
||||
|
if(bleft.groupCandidates.size() != bright.groupCandidates.size()) { |
||||
|
candidatesCompatible = false; |
||||
|
} |
||||
|
else if(bleft.beCandidates.size() != bright.beCandidates.size()) { |
||||
|
candidatesCompatible = false; |
||||
|
} |
||||
|
else { |
||||
|
for (auto const &gc : bleft.groupCandidates) { |
||||
|
if (bright.groupCandidates.count(gc.first) == 0) { |
||||
|
candidatesCompatible = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if(candidatesCompatible) { |
||||
|
for(auto const& bc : bleft.groupCandidates) { |
||||
|
if(bright.beCandidates.count(bc.first) == 0) { |
||||
|
candidatesCompatible = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Local helper function for the creation of bijections, should be hidden from api. |
||||
|
*/ |
||||
|
void zipVectorsIntoMap(std::vector<size_t> const& a, std::vector<size_t> const& b, std::map<size_t, size_t>& map) const { |
||||
|
// Assert should pass due to compatibility check |
||||
|
assert(a.size() == b.size()); |
||||
|
auto it = b.cbegin(); |
||||
|
for(size_t lIndex : a) { |
||||
|
assert(map.count(lIndex) == 0); |
||||
|
map[lIndex] = *it; |
||||
|
++it; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//std::vector<std::pair<size_t, size_t>> computeNextCandidate(){ |
||||
|
|
||||
|
//} |
||||
}; |
}; |
||||
|
|
||||
|
|
||||
} // namespace storm::dft |
} // namespace storm::dft |
||||
} // namespace storm |
} // namespace storm |
Write
Preview
Loading…
Cancel
Save
Reference in new issue