From 4aa9a83cba3bbc3e66ec5b37283f9c0d94d7ec95 Mon Sep 17 00:00:00 2001
From: Jan Vesely <janvesely@janvesely.net>
Date: Wed, 6 Nov 2013 19:55:26 +0100
Subject: [PATCH] fix fsm determinization issues

---
 adeterminize/src/FSMDeterminizer.cpp | 51 ++++++++++++++--------------
 adeterminize/src/FSMDeterminizer.h   | 15 ++++----
 adeterminize/src/adeterminize.cpp    |  8 +++--
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/adeterminize/src/FSMDeterminizer.cpp b/adeterminize/src/FSMDeterminizer.cpp
index 1a9fa8daa6..ea8d98933f 100644
--- a/adeterminize/src/FSMDeterminizer.cpp
+++ b/adeterminize/src/FSMDeterminizer.cpp
@@ -18,16 +18,16 @@ string FSMDeterminizer::buildStateName(const set<State>& states) {
 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;
+    map<string, StateData>::iterator stateIter = this->states.find(stateName);
+    if (stateIter != this->states.end()) {
+        return stateIter->second.state;
     }
     
-    State* state = new State(stateName);
-    StateData stateData(*state, states);
-    this->states->insert(pair<string, StateData>(stateName, stateData));
-    this->deterministicFSM->addState(*state);
-    return *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;
 }
 
 
@@ -39,30 +39,29 @@ void FSMDeterminizer::copyInputAlphabet() {
 }
 
 
-const set<State>& FSMDeterminizer::findNextStatesInNfsm(const set<State>& nfsmStates, const Symbol& input) {
+set<State> FSMDeterminizer::findTargetStatesInNfsm(const set<State>& nfsmStates, const Symbol& input) {
     const set<TransitionFSM>& nfsmTransitions = this->nondeterministicFSM->getTransitions();
-    set<State>* nextStates = new set<State>;
+    set<State> nextStates;
     for (set<State>::iterator state = nfsmStates.begin(); state != nfsmStates.end(); state++) {
         for (set<TransitionFSM>::iterator transition = nfsmTransitions.begin();
                 transition != nfsmTransitions.end();
                 transition++) {
             if (transition->getCurrent() == *state && transition->getInput() == input) {
-                nextStates->insert(transition->getNext());
+                nextStates.insert(transition->getNext());
             }
         }
     }
-    return *nextStates;
+    return nextStates;
 }
 
 
 bool FSMDeterminizer::containSomeFinalStateOfNfsm(const set<State>& nfsmStates) {
     const set<State>& nfsmFinalStates = this->nondeterministicFSM->getFinalStates();
-    for (set<State>::iterator finalState = nfsmFinalStates.begin(); finalState != nfsmFinalStates.end(); finalState++) {
-        if (nfsmStates.find(*finalState) != nfsmStates.end()) {
-            return true;
-        }
-    }
-    return false;
+    set<State> intersection;
+    set_intersection(nfsmFinalStates.begin(), nfsmFinalStates.end(),
+                     nfsmStates.begin(), nfsmStates.end(),
+                     std::inserter(intersection, intersection.begin()));
+    return intersection.size() > 0;
 }
 
 
@@ -73,7 +72,7 @@ FSMDeterminizer::FSMDeterminizer(FSM* automaton) {
 
 FSM* FSMDeterminizer::determinize() {
     this->deterministicFSM = new FSM();
-    this->states = new map<string, StateData>();
+    this->states.clear();
     this->copyInputAlphabet();
     
     const set<State>& nfsmInitialStates = this->nondeterministicFSM->getInitialStates();
@@ -81,7 +80,7 @@ FSM* FSMDeterminizer::determinize() {
     
     while (true) {
         bool allStatesMarked = true;
-        for (map<string, StateData>::iterator stateIter = this->states->begin(); stateIter != this->states->end(); stateIter++) {
+        for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
             allStatesMarked &= stateIter->second.isMarked;
         }
         if (allStatesMarked) {
@@ -89,7 +88,7 @@ FSM* FSMDeterminizer::determinize() {
         }
         
         StateData* unmarkedStateData;
-        for (map<string, StateData>::iterator stateIter = this->states->begin(); stateIter != this->states->end(); stateIter++) {
+        for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
             StateData& stateData = stateIter->second;
             if (!stateData.isMarked) {
                 unmarkedStateData = &stateData;
@@ -99,10 +98,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->findNextStatesInNfsm(*unmarkedStateData->nfsmStates, *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);
+                TransitionFSM transition(unmarkedStateData->state, *input, nextState);
                 this->deterministicFSM->addTransition(transition);
             }
         }
@@ -112,10 +111,10 @@ FSM* FSMDeterminizer::determinize() {
     
     this->deterministicFSM->addInitialState(initialState);
     
-    for (map<string, StateData>::iterator stateIter = this->states->begin(); stateIter != this->states->end(); stateIter++) {
+    for (map<string, StateData>::iterator stateIter = this->states.begin(); stateIter != this->states.end(); stateIter++) {
         const StateData& stateData = stateIter->second;
-        if (this->containSomeFinalStateOfNfsm(*stateData.nfsmStates)) {
-            this->deterministicFSM->addFinalState(*stateData.state);
+        if (this->containSomeFinalStateOfNfsm(stateData.nfsmStates)) {
+            this->deterministicFSM->addFinalState(stateData.state);
         }
     }
     
diff --git a/adeterminize/src/FSMDeterminizer.h b/adeterminize/src/FSMDeterminizer.h
index aea0ab4842..e51bef5c29 100644
--- a/adeterminize/src/FSMDeterminizer.h
+++ b/adeterminize/src/FSMDeterminizer.h
@@ -5,6 +5,7 @@
 #include <string>
 #include <set>
 #include <map>
+#include <algorithm>
 
 #include "automaton/State.h"
 #include "automaton/Symbol.h"
@@ -18,25 +19,25 @@ namespace automaton {
 class FSMDeterminizer {
 protected:
     struct StateData {
-        const State* state;
-        const set<State>* nfsmStates;
+        const State state;
+        const set<State> nfsmStates;
         bool isMarked;
         
-        StateData(const State& state, const set<State>& nfsmStates) {
-            this->state = &state;
-            this->nfsmStates = &nfsmStates;
+        StateData(const State& state, const set<State>& nfsmStates)
+                : state(state),
+                  nfsmStates(nfsmStates) {
             this->isMarked = false;
         }
     };
     
     FSM* nondeterministicFSM;
     FSM* deterministicFSM;
-    map<string, StateData>* states;
+    map<string, StateData> states;
     
     string buildStateName(const set<State>& states);
     const State& getOrCreateState(const set<State>& states);
     void copyInputAlphabet();
-    const set<State>& findNextStatesInNfsm(const set<State>& nfsmStates, const Symbol& input);
+    set<State> findTargetStatesInNfsm(const set<State>& nfsmStates, const Symbol& input);
     bool containSomeFinalStateOfNfsm(const set<State>& nfsmStates);
     
 public:
diff --git a/adeterminize/src/adeterminize.cpp b/adeterminize/src/adeterminize.cpp
index fcecc8d14d..05e308e0f8 100644
--- a/adeterminize/src/adeterminize.cpp
+++ b/adeterminize/src/adeterminize.cpp
@@ -20,10 +20,14 @@ int main(int argc, char** argv) {
         
         Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton);
         // TODO check that automaton is FSM
-        FSMDeterminizer* determinizer = new FSMDeterminizer((FSM*) knownAutomaton);
-        FSM* deterministicFSM = determinizer->determinize();
+        FSMDeterminizer determinizer((FSM*) knownAutomaton);
+        FSM* deterministicFSM = determinizer.determinize();
         deterministicFSM->toXML(cout);
         
+        delete automaton;
+        delete knownAutomaton;
+        delete deterministicFSM;
+        
     } catch (AlibException& e) {
         cout << e.toString() << endl;
         return 0;
-- 
GitLab