tmp
This commit is contained in:
parent
1f1dc001a1
commit
41aa8daeb2
1 changed files with 45 additions and 50 deletions
|
|
@ -94,93 +94,87 @@ namespace tp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertices that are reachable from initial set with no input consumption (E-transitions)
|
typedef AvlTree<AvlNumericKey<State*>, bool> StatesSet;
|
||||||
// does not include initial set
|
|
||||||
void findClosureSet(const Buffer<State*>& from, Buffer<State*>& closureSet) const {
|
// Expands initial set with states that are reachable from initial set with no input consumption (E-transitions)
|
||||||
Map<alni, bool> lookup;
|
void expandSet(StatesSet& set) const {
|
||||||
List<State*> workingSet;
|
List<State*> workingSet;
|
||||||
|
|
||||||
for (auto item : from) {
|
set.forEach([&](AvlNumericKey<State*>& key, bool) { workingSet.pushBack(key.val); });
|
||||||
workingSet.pushBack(item.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
while (workingSet.length()) {
|
while (workingSet.length()) {
|
||||||
auto first = workingSet.first()->data;
|
auto first = workingSet.first()->data;
|
||||||
closureSet.append(first);
|
set.insert(first, {});
|
||||||
lookup.put((alni) first, {});
|
|
||||||
|
|
||||||
for (auto edge : first->mTransitions) {
|
for (auto transition : first->mTransitions) {
|
||||||
if (!edge.data().isEpsilon()) continue;
|
if (!transition->isEpsilon()) continue;
|
||||||
if (lookup.presents((alni) edge.data().mState)) continue;
|
if (set.find(transition->mState)) continue;
|
||||||
workingSet.pushBack(edge.data().mState);
|
workingSet.pushBack(transition->mState);
|
||||||
}
|
}
|
||||||
|
|
||||||
workingSet.popFront();
|
workingSet.popFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertices that are reachable from initial set with symbol transition
|
// States that are reachable from initial set with symbol transition
|
||||||
void findMoveSet(const Buffer<State*>& from, Buffer<State*>& moveSet, tAlphabetType symbol) const {
|
void findMoveSet(StatesSet& from, StatesSet& moveSet, tAlphabetType symbol) const {
|
||||||
Map<alni, bool> lookup;
|
from.forEach([&](AvlNumericKey<State*>& key, bool) {
|
||||||
|
for (auto transition : key.val->mTransitions) {
|
||||||
for (auto vertex : from) {
|
if (transition->isEpsilon()) continue;
|
||||||
for (auto edge : vertex->mTransitions) {
|
if (!transition->isTransition(symbol)) continue;
|
||||||
if (edge.data().isEpsilon()) continue;
|
if (moveSet.find(transition->mState)) continue;
|
||||||
if (!edge.data().isTransition(symbol)) continue;
|
moveSet.insert(transition->mState, {});
|
||||||
if (lookup.presents((alni) edge.data().mState)) continue;
|
|
||||||
moveSet.append(edge.data().mState);
|
|
||||||
lookup.put((alni) edge.data().mState, {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename tAlphabetIterator>
|
template <typename tAlphabetIterator>
|
||||||
bool makeDeterministic(const tAlphabetIterator& allSymbols) {
|
bool makeDeterministic(const tAlphabetIterator& allSymbols) {
|
||||||
if (!isValid()) return false;
|
if (!isValid()) return false;
|
||||||
|
|
||||||
typedef Buffer<State*> Group;
|
|
||||||
|
|
||||||
struct GroupKey {
|
struct GroupKey {
|
||||||
const Group* group;
|
const StatesSet* group;
|
||||||
static ualni hash(GroupKey key) { return 0; }
|
static ualni hash(GroupKey key) { return 0; }
|
||||||
bool operator==(const GroupKey& key) const { return false; }
|
bool operator==(const GroupKey& key) const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GroupInfo {
|
struct GroupInfo {
|
||||||
Group* group = nullptr;
|
StatesSet* group = nullptr;
|
||||||
AvlTree<AvlNumericKey<alni>, tAlphabetType> transitions;
|
AvlTree<AvlNumericKey<StatesSet*>, tAlphabetType> transitions;
|
||||||
State* newState = nullptr;
|
State* newState = nullptr;
|
||||||
bool accepting = false;
|
bool accepting = false;
|
||||||
tStateType stateVal = tStateType();
|
tStateType stateVal = tStateType();
|
||||||
};
|
};
|
||||||
|
|
||||||
Buffer<Group> groups = { {} };
|
Buffer<StatesSet> groups = { {} };
|
||||||
Map<GroupKey, GroupInfo, DefaultAllocator, GroupKey::hash> groupInfos;
|
Map<GroupKey, GroupInfo, DefaultAllocator, GroupKey::hash> groupInfos;
|
||||||
|
|
||||||
findClosureSet({ getStartState() }, groups.first());
|
groups.first().insert(getStartState(), false);
|
||||||
|
|
||||||
|
expandSet(groups.first());
|
||||||
|
|
||||||
groupInfos.put({ &groups.first() }, { &groups.first() });
|
groupInfos.put({ &groups.first() }, { &groups.first() });
|
||||||
|
|
||||||
// 1) find new states
|
// 1) find new states
|
||||||
List<Group*> workingSet;
|
List<StatesSet*> workingSet;
|
||||||
workingSet.pushBack(&groups.first());
|
workingSet.pushBack(&groups.first());
|
||||||
|
|
||||||
while (workingSet.length()) {
|
while (workingSet.length()) {
|
||||||
Group* group = workingSet.first()->data;
|
StatesSet* group = workingSet.first()->data;
|
||||||
GroupInfo* info = &groupInfos.get({ group });
|
GroupInfo* info = &groupInfos.get({ group });
|
||||||
|
|
||||||
for (auto symbol : allSymbols) {
|
for (auto symbol : allSymbols) {
|
||||||
|
|
||||||
// calculate new possible state
|
// calculate new possible state
|
||||||
Group potentialGroupTmp;
|
StatesSet potentialGroup;
|
||||||
Group potentialGroup;
|
|
||||||
|
|
||||||
findMoveSet(*group, potentialGroupTmp, symbol);
|
findMoveSet(*group, potentialGroup, symbol);
|
||||||
findClosureSet(potentialGroupTmp, potentialGroup);
|
expandSet(potentialGroup);
|
||||||
|
|
||||||
if (!potentialGroup.size()) continue;
|
if (!potentialGroup.size()) continue;
|
||||||
|
|
||||||
// find existing or create group
|
// find existing or create group
|
||||||
Group* targetGroup = nullptr;
|
StatesSet* targetGroup = nullptr;
|
||||||
auto iter = groupInfos.presents({ &potentialGroup });
|
auto iter = groupInfos.presents({ &potentialGroup });
|
||||||
if (iter) {
|
if (iter) {
|
||||||
targetGroup = groupInfos.getSlotVal(iter).group;
|
targetGroup = groupInfos.getSlotVal(iter).group;
|
||||||
|
|
@ -191,7 +185,7 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert transition is added
|
// assert transition is added
|
||||||
info->transitions.insert((alni) targetGroup, symbol);
|
info->transitions.insert(targetGroup, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
workingSet.popFront();
|
workingSet.popFront();
|
||||||
|
|
@ -200,18 +194,19 @@ namespace tp {
|
||||||
// 2) find new states termination values
|
// 2) find new states termination values
|
||||||
for (auto group : groupInfos) {
|
for (auto group : groupInfos) {
|
||||||
GroupInfo* info = &group->val;
|
GroupInfo* info = &group->val;
|
||||||
bool accepting = false;
|
ualni accepting = 0;
|
||||||
for (auto item : *info->group) {
|
|
||||||
if (item->mIsAccepting) {
|
info->group->forEach([&](AvlNumericKey<State*>& key, bool) {
|
||||||
if (accepting) return false;
|
if (key.val->mIsAccepting) {
|
||||||
accepting = true;
|
accepting++;
|
||||||
info->accepting = true;
|
info->accepting = true;
|
||||||
info->stateVal = item->mStateVal;
|
info->stateVal = key.val->mStateVal;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!accepting) {
|
if (!accepting) {
|
||||||
info->accepting = false;
|
info->accepting = false;
|
||||||
info->stateVal = info->group->first()->mStateVal;
|
info->stateVal = info->group->head()->key.val->mStateVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,8 +220,8 @@ namespace tp {
|
||||||
|
|
||||||
// create transitions
|
// create transitions
|
||||||
for (auto group : groupInfos) {
|
for (auto group : groupInfos) {
|
||||||
auto functor = [&](AvlNumericKey<alni> targetGroupKey, tAlphabetType symbol) {
|
auto functor = [&](AvlNumericKey<StatesSet*> targetGroupKey, tAlphabetType symbol) {
|
||||||
GroupInfo* targetGroup = &groupInfos.get({ (Group*) targetGroupKey.val });
|
GroupInfo* targetGroup = &groupInfos.get({ (StatesSet*) targetGroupKey.val });
|
||||||
addTransition(group->val.newState, targetGroup->newState, symbol);
|
addTransition(group->val.newState, targetGroup->newState, symbol);
|
||||||
};
|
};
|
||||||
group->val.transitions.forEach(functor);
|
group->val.transitions.forEach(functor);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue