Speed up mssc
This commit is contained in:
parent
8ed2fd41e1
commit
8a59d19e5c
|
@ -34,6 +34,9 @@ namespace lxs {
|
||||||
struct ENFA : public NFA {
|
struct ENFA : public NFA {
|
||||||
std::map<State, std::set<State> > epsilonTransitions;
|
std::map<State, std::set<State> > epsilonTransitions;
|
||||||
virtual std::set<State> eClose(State) const;
|
virtual std::set<State> eClose(State) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::map<State, std::set<State> > eCloseCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string toDot(const DFA& d);
|
std::string toDot(const DFA& d);
|
||||||
|
|
|
@ -98,6 +98,10 @@ namespace lxs {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<State> ENFA::eClose(State s) const {
|
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::set<State> states;
|
||||||
std::queue<State> statequeue;
|
std::queue<State> statequeue;
|
||||||
statequeue.push(s);
|
statequeue.push(s);
|
||||||
|
@ -114,7 +118,7 @@ namespace lxs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return states;
|
return eCloseCache[s] = states;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<State> NFA::eClose(State s) const {
|
std::set<State> NFA::eClose(State s) const {
|
||||||
|
@ -282,9 +286,9 @@ namespace lxs {
|
||||||
|
|
||||||
namespace { // Utility function for mssc
|
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;
|
std::set<State> states;
|
||||||
for(auto &state: oldstate) {
|
for(const auto &state: oldstate) {
|
||||||
auto a = e.delta.find(state);
|
auto a = e.delta.find(state);
|
||||||
if(a != e.delta.end()) {
|
if(a != e.delta.end()) {
|
||||||
auto newStates = a->second.find(symbol);
|
auto newStates = a->second.find(symbol);
|
||||||
|
@ -306,26 +310,34 @@ namespace lxs {
|
||||||
|
|
||||||
DFA mssc(const NFA& e) {
|
DFA mssc(const NFA& e) {
|
||||||
//Temporary, improper dfa structure
|
//Temporary, improper dfa structure
|
||||||
std::map<std::set<State>,std::map<char,std::set<State> > > dfa;
|
std::map<std::set<State>, std::map<char,std::set<State> > > dfa;
|
||||||
std::map<char, std::set<State> > trans;
|
std::map<char, std::set<State> > trans;
|
||||||
for (int c = 0; c < 256; c++) {
|
for (int c = 0; c < 256; c++) {
|
||||||
trans[c] = {};
|
trans[c] = {};
|
||||||
}
|
}
|
||||||
dfa[{}] = trans;
|
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
|
//Lazy evaluation, on a still implicit DFA
|
||||||
std::queue<std::set<State> > tocheck;
|
std::queue<std::set<State> > tocheck;
|
||||||
tocheck.push(e.eClose(e.starting));
|
tocheck.push(e.eClose(e.starting));
|
||||||
while(!tocheck.empty()) {
|
while(!tocheck.empty()) {
|
||||||
auto state = tocheck.front();
|
auto state = std::move(tocheck.front());
|
||||||
tocheck.pop();
|
tocheck.pop();
|
||||||
std::map<char, std::set<State> > trans;
|
std::map<char, std::set<State> > trans;
|
||||||
for (int c = 0; c < 256; c++) {
|
for (char c : usedChars) {
|
||||||
auto nextstate = getNextState(state,c,e);
|
auto nextstate = getNextState(state,c,e);
|
||||||
trans[c] = nextstate;
|
|
||||||
if(dfa.find(nextstate) == dfa.end()) {
|
if(dfa.find(nextstate) == dfa.end()) {
|
||||||
|
dfa[nextstate] = {};
|
||||||
tocheck.push(nextstate);
|
tocheck.push(nextstate);
|
||||||
}
|
}
|
||||||
|
trans[c] = std::move(nextstate);
|
||||||
}
|
}
|
||||||
dfa[state] = trans;
|
dfa[state] = trans;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue