Speed up mssc

This commit is contained in:
Robin Jadoul 2016-05-24 18:09:38 +02:00
parent 8ed2fd41e1
commit 8a59d19e5c
2 changed files with 23 additions and 8 deletions

View File

@ -34,6 +34,9 @@ namespace lxs {
struct ENFA : public NFA {
std::map<State, std::set<State> > epsilonTransitions;
virtual std::set<State> eClose(State) const;
private:
mutable std::map<State, std::set<State> > eCloseCache;
};
std::string toDot(const DFA& d);

View File

@ -98,6 +98,10 @@ namespace lxs {
}
std::set<State> ENFA::eClose(State s) const {
auto cachedIt = eCloseCache.find(s);
if (cachedIt != eCloseCache.end()) {
return cachedIt->second;
}
std::set<State> states;
std::queue<State> statequeue;
statequeue.push(s);
@ -114,7 +118,7 @@ namespace lxs {
}
}
}
return states;
return eCloseCache[s] = states;
}
std::set<State> NFA::eClose(State s) const {
@ -282,9 +286,9 @@ namespace lxs {
namespace { // Utility function for mssc
std::set<State> getNextState(std::set<State> oldstate, char symbol, const NFA& e) {
std::set<State> getNextState(const std::set<State>& oldstate, char symbol, const NFA& e) {
std::set<State> states;
for(auto &state: oldstate) {
for(const auto &state: oldstate) {
auto a = e.delta.find(state);
if(a != e.delta.end()) {
auto newStates = a->second.find(symbol);
@ -313,19 +317,27 @@ namespace lxs {
}
dfa[{}] = trans;
std::set<char> usedChars;
for (const auto& stateTrans : e.delta) {
for (const auto& tr : stateTrans.second) {
usedChars.insert(tr.first);
}
}
//Lazy evaluation, on a still implicit DFA
std::queue<std::set<State> > tocheck;
tocheck.push(e.eClose(e.starting));
while(!tocheck.empty()) {
auto state = tocheck.front();
auto state = std::move(tocheck.front());
tocheck.pop();
std::map<char, std::set<State> > trans;
for (int c = 0; c < 256; c++) {
for (char c : usedChars) {
auto nextstate = getNextState(state,c,e);
trans[c] = nextstate;
if(dfa.find(nextstate) == dfa.end()) {
dfa[nextstate] = {};
tocheck.push(nextstate);
}
trans[c] = std::move(nextstate);
}
dfa[state] = trans;
}