From 0f23254569da4f74fefbd2529c913d04f30239f7 Mon Sep 17 00:00:00 2001
From: Jan Vesely <janvesely@janvesely.net>
Date: Sat, 16 Nov 2013 12:14:57 +0100
Subject: [PATCH] move useful methods of fsm determinization into separate
 class

---
 adeterminize.fsm/src/FSMDeterminizer.cpp    | 89 ++++++---------------
 adeterminize.fsm/src/FSMDeterminizer.h      | 23 +-----
 alib/src/automaton/DeterminizationUtils.cpp | 57 +++++++++++++
 alib/src/automaton/DeterminizationUtils.h   | 40 +++++++++
 4 files changed, 123 insertions(+), 86 deletions(-)
 create mode 100644 alib/src/automaton/DeterminizationUtils.cpp
 create mode 100644 alib/src/automaton/DeterminizationUtils.h

diff --git a/adeterminize.fsm/src/FSMDeterminizer.cpp b/adeterminize.fsm/src/FSMDeterminizer.cpp
index 5c5007921a..454bacceec 100644
--- a/adeterminize.fsm/src/FSMDeterminizer.cpp
+++ b/adeterminize.fsm/src/FSMDeterminizer.cpp
@@ -2,66 +2,19 @@
 
 namespace automaton {
 
-string FSMDeterminizer::buildStateName(const set<State>& states) {
-    string name = "[";
-    for (set<State>::const_iterator state = states.begin(); state != states.end(); state++) {
-        if (state != states.begin()) {
-            name += ", ";
-        }
-        name += "'" + state->getName() + "'";
-    }
-    name += "]";
-    return name;
-}
-
-
-const State& FSMDeterminizer::getOrCreateState(const set<State>& states) {
-    string stateName = buildStateName(states);
-    
-    map<string, StateData>::iterator stateIter = this->states.find(stateName);
-    if (stateIter != this->states.end()) {
-        return stateIter->second.state;
-    }
-    
-    State state(stateName);
-    StateData stateData(state, states);
-    StateData& insertedData = this->states.insert(pair<string, StateData>(stateName, stateData)).first->second;
-    this->deterministicFSM->addState(state);
-    return insertedData.state;
-}
-
-
-void FSMDeterminizer::copyInputAlphabet() {
-    const set<Symbol>& inputAlphabet = this->nondeterministicFSM->getInputAlphabet();
-    for (set<Symbol>::iterator input = inputAlphabet.begin(); input != inputAlphabet.end(); input++) {
-        this->deterministicFSM->addInputSymbol(*input);
-    }
-}
-
-
-set<State> FSMDeterminizer::findTargetStatesInNfsm(const set<State>& nfsmStates, const Symbol& input) {
+set<State> FSMDeterminizer::findToStates(const set<State>& nfsmStates, const Symbol& input) {
     const set<TransitionFSM>& nfsmTransitions = this->nondeterministicFSM->getTransitions();
-    set<State> nextStates;
+    set<State> targetStates;
     for (set<State>::iterator state = nfsmStates.begin(); state != nfsmStates.end(); state++) {
         for (set<TransitionFSM>::iterator transition = nfsmTransitions.begin();
                 transition != nfsmTransitions.end();
                 transition++) {
             if (transition->getFrom() == *state && transition->getInput() == input) {
-                nextStates.insert(transition->getTo());
+                targetStates.insert(transition->getTo());
             }
         }
     }
-    return nextStates;
-}
-
-
-bool FSMDeterminizer::containSomeFinalStateOfNfsm(const set<State>& nfsmStates) {
-    const set<State>& nfsmFinalStates = this->nondeterministicFSM->getFinalStates();
-    set<State> intersection;
-    set_intersection(nfsmFinalStates.begin(), nfsmFinalStates.end(),
-                     nfsmStates.begin(), nfsmStates.end(),
-                     std::inserter(intersection, intersection.begin()));
-    return intersection.size() > 0;
+    return targetStates;
 }
 
 
@@ -72,24 +25,28 @@ FSMDeterminizer::FSMDeterminizer(FSM* automaton) {
 
 FSM* FSMDeterminizer::determinize() {
     this->deterministicFSM = new FSM();
-    this->states.clear();
-    this->copyInputAlphabet();
+    DeterminizationUtils::copyInputAlphabet(*this->nondeterministicFSM, *this->deterministicFSM);
+    map<string, DeterminizationUtils::StateData> states;
     
     const set<State>& nfsmInitialStates = this->nondeterministicFSM->getInitialStates();
-    const State& initialState = this->getOrCreateState(nfsmInitialStates);
+    const State& initialState = DeterminizationUtils::getOrCreateState(nfsmInitialStates, states, *this->deterministicFSM);
     
     while (true) {
         bool allStatesMarked = true;
-        for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
+        for (map<string, DeterminizationUtils::StateData>::iterator stateIter = states.begin();
+                stateIter != states.end();
+                stateIter++) {
             allStatesMarked &= stateIter->second.isMarked;
         }
         if (allStatesMarked) {
             break;
         }
         
-        StateData* unmarkedStateData;
-        for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
-            StateData& stateData = stateIter->second;
+        DeterminizationUtils::StateData* unmarkedStateData;
+        for (map<string, DeterminizationUtils::StateData>::iterator stateIter = states.begin();
+                stateIter != states.end();
+                stateIter++) {
+            DeterminizationUtils::StateData& stateData = stateIter->second;
             if (!stateData.isMarked) {
                 unmarkedStateData = &stateData;
                 break;
@@ -98,10 +55,10 @@ FSM* FSMDeterminizer::determinize() {
         
         const set<Symbol>& nfsmInputAlphabet = this->nondeterministicFSM->getInputAlphabet();
         for (set<Symbol>::iterator input = nfsmInputAlphabet.begin(); input != nfsmInputAlphabet.end(); input++) {
-            const set<State>& nfsmNextStates = this->findTargetStatesInNfsm(unmarkedStateData->nfsmStates, *input);
-            if (nfsmNextStates.size() > 0) {
-                const State& nextState = this->getOrCreateState(nfsmNextStates);
-                TransitionFSM transition(unmarkedStateData->state, *input, nextState);
+            const set<State>& nfsmToStates = this->findToStates(unmarkedStateData->originalStates, *input);
+            if (nfsmToStates.size() > 0) {
+                const State& targetState = DeterminizationUtils::getOrCreateState(nfsmToStates, states, *this->deterministicFSM);
+                TransitionFSM transition(unmarkedStateData->state, *input, targetState);
                 this->deterministicFSM->addTransition(transition);
             }
         }
@@ -111,9 +68,11 @@ FSM* FSMDeterminizer::determinize() {
     
     this->deterministicFSM->addInitialState(initialState);
     
-    for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
-        const StateData& stateData = stateIter->second;
-        if (this->containSomeFinalStateOfNfsm(stateData.nfsmStates)) {
+    for (map<string, DeterminizationUtils::StateData>::iterator stateIter = states.begin();
+            stateIter != states.end();
+            stateIter++) {
+        const DeterminizationUtils::StateData& stateData = stateIter->second;
+        if (DeterminizationUtils::containSomeFinalStateOfAutomaton(stateData.originalStates, *this->nondeterministicFSM)) {
             this->deterministicFSM->addFinalState(stateData.state);
         }
     }
diff --git a/adeterminize.fsm/src/FSMDeterminizer.h b/adeterminize.fsm/src/FSMDeterminizer.h
index 3990a57349..5b6b885e84 100644
--- a/adeterminize.fsm/src/FSMDeterminizer.h
+++ b/adeterminize.fsm/src/FSMDeterminizer.h
@@ -1,14 +1,12 @@
 #ifndef FSMDETERMINIZER_H_
 #define FSMDETERMINIZER_H_
 
-#include <iostream>
 #include <string>
 #include <set>
 #include <map>
-#include <algorithm>
 
 #include "automaton/State.h"
-#include "alphabet/Symbol.h"
+#include "automaton/DeterminizationUtils.h"
 #include "automaton/FSM/FSM.h"
 #include "automaton/FSM/TransitionFSM.h"
 
@@ -18,27 +16,10 @@ namespace automaton {
 
 class FSMDeterminizer {
 protected:
-    struct StateData {
-        const State state;
-        const set<State> nfsmStates;
-        bool isMarked;
-        
-        StateData(const State& state, const set<State>& nfsmStates)
-                : state(state),
-                  nfsmStates(nfsmStates) {
-            this->isMarked = false;
-        }
-    };
-    
     FSM* nondeterministicFSM;
     FSM* deterministicFSM;
-    map<string, StateData> states;
     
-    string buildStateName(const set<State>& states);
-    const State& getOrCreateState(const set<State>& states);
-    void copyInputAlphabet();
-    set<State> findTargetStatesInNfsm(const set<State>& nfsmStates, const Symbol& input);
-    bool containSomeFinalStateOfNfsm(const set<State>& nfsmStates);
+    set<State> findToStates(const set<State>& nfsmStates, const Symbol& input);
     
 public:
     FSMDeterminizer(FSM* automaton);
diff --git a/alib/src/automaton/DeterminizationUtils.cpp b/alib/src/automaton/DeterminizationUtils.cpp
new file mode 100644
index 0000000000..50dacc9620
--- /dev/null
+++ b/alib/src/automaton/DeterminizationUtils.cpp
@@ -0,0 +1,57 @@
+#include "DeterminizationUtils.h"
+
+namespace automaton {
+
+string DeterminizationUtils::buildStateName(const set<State>& states) {
+    string name = "[";
+    for (set<State>::const_iterator state = states.begin(); state != states.end(); state++) {
+        if (state != states.begin()) {
+            name += ", ";
+        }
+        name += "'" + state->getName() + "'";
+    }
+    name += "]";
+    return name;
+}
+
+const State& DeterminizationUtils::getOrCreateState(const set<State>& originalStates, map<string, StateData>& states, Automaton& automaton) {
+    string stateName = buildStateName(originalStates);
+    
+    map<string, StateData>::iterator stateIter = states.find(stateName);
+    if (stateIter != states.end()) {
+        return stateIter->second.state;
+    }
+    
+    State state(stateName);
+    StateData stateData(state, originalStates);
+    StateData& insertedData = states.insert(pair<string, StateData>(stateName, stateData)).first->second;
+    automaton.addState(state);
+    return insertedData.state;
+}
+
+
+void DeterminizationUtils::copyInputAlphabet(const Automaton& fromAutomaton, Automaton& toAutomaton) {
+    const set<Symbol>& alphabet = fromAutomaton.getInputAlphabet();
+    for (set<Symbol>::iterator input = alphabet.begin(); input != alphabet.end(); input++) {
+        toAutomaton.addInputSymbol(*input);
+    }
+}
+
+
+void DeterminizationUtils::copyStackAlphabet(const PDA& fromPDA, PDA& toPDA) {
+    const set<Symbol>& alphabet = fromPDA.getStackAlphabet();
+    for (set<Symbol>::iterator symbol = alphabet.begin(); symbol != alphabet.end(); symbol++) {
+        toPDA.addStackSymbol(*symbol);
+    }
+}
+
+
+bool DeterminizationUtils::containSomeFinalStateOfAutomaton(const set<State>& states, const Automaton& automaton) {
+    const set<State>& finalStates = automaton.getFinalStates();
+    set<State> intersection;
+    set_intersection(finalStates.begin(), finalStates.end(), states.begin(), states.end(),
+            std::inserter(intersection, intersection.begin()));
+    return intersection.size() > 0;
+}
+
+} /* namespace automaton */
diff --git a/alib/src/automaton/DeterminizationUtils.h b/alib/src/automaton/DeterminizationUtils.h
new file mode 100644
index 0000000000..87ee060714
--- /dev/null
+++ b/alib/src/automaton/DeterminizationUtils.h
@@ -0,0 +1,40 @@
+#ifndef DETERKMINIZATIONUTILS_H_
+#define DETERKMINIZATIONUTILS_H_
+
+#include <iostream>
+#include <string>
+#include <set>
+#include <map>
+#include <algorithm>
+
+#include "State.h"
+#include "Automaton.h"
+#include "PDA/PDA.h"
+
+using namespace std;
+
+namespace automaton {
+
+class DeterminizationUtils {
+public:
+    struct StateData {
+        const State state;
+        const set<State> originalStates;
+        bool isMarked;
+        
+        StateData(const State& state, const set<State>& originalStates)
+                : state(state),
+                  originalStates(originalStates) {
+            this->isMarked = false;
+        }
+    };
+    
+    static string buildStateName(const set<State>& states);
+    static const State& getOrCreateState(const set<State>& originalStates, map<string, StateData>& states, Automaton& automaton);
+    static void copyInputAlphabet(const Automaton& fromAutomaton, Automaton& toAutomaton);
+    static void copyStackAlphabet(const PDA& fromPDA, PDA& toPDA);
+    static bool containSomeFinalStateOfAutomaton(const set<State>& states, const Automaton& automaton);
+};
+
+} /* namespace automaton */
+#endif /* DETERKMINIZATIONUTILS_H_ */
\ No newline at end of file
-- 
GitLab