From ead8e4910c5e1ade2b25d5a599eabab921feeeb9 Mon Sep 17 00:00:00 2001
From: Jan Vesely <janvesely@janvesely.net>
Date: Sat, 16 Nov 2013 12:15:21 +0100
Subject: [PATCH] add idpda determinization

---
 adeterminize.idpda/src/IDPDADeterminizer.cpp  |  88 ++++++++++++
 adeterminize.idpda/src/IDPDADeterminizer.h    |  32 +++++
 adeterminize.idpda/src/adeterminize.idpda.cpp |  35 +++++
 examples/NIDPDA1.xml                          |  65 +++++++++
 examples/NIDPDA2.xml                          | 119 +++++++++++++++
 examples/NIDPDA3.xml                          |  89 ++++++++++++
 examples/NIDPDA4.xml                          | 135 ++++++++++++++++++
 7 files changed, 563 insertions(+)
 create mode 100644 adeterminize.idpda/src/IDPDADeterminizer.cpp
 create mode 100644 adeterminize.idpda/src/IDPDADeterminizer.h
 create mode 100644 adeterminize.idpda/src/adeterminize.idpda.cpp
 create mode 100644 examples/NIDPDA1.xml
 create mode 100644 examples/NIDPDA2.xml
 create mode 100644 examples/NIDPDA3.xml
 create mode 100644 examples/NIDPDA4.xml

diff --git a/adeterminize.idpda/src/IDPDADeterminizer.cpp b/adeterminize.idpda/src/IDPDADeterminizer.cpp
new file mode 100644
index 0000000000..330642b318
--- /dev/null
+++ b/adeterminize.idpda/src/IDPDADeterminizer.cpp
@@ -0,0 +1,88 @@
+#include "IDPDADeterminizer.h"
+
+namespace automaton {
+
+set<State> IDPDADeterminizer::findToStates(const set<State>& nidpdaStates, const Symbol& input, list<Symbol>* stackPop, list<Symbol>* stackPush) {
+    const set<TransitionPDA>& nidpdaTransitions = this->nondeterministicIDPDA->getTransitions();
+    set<State> targetStates;
+    for (set<State>::iterator state = nidpdaStates.begin(); state != nidpdaStates.end(); state++) {
+        for (set<TransitionPDA>::iterator transition = nidpdaTransitions.begin();
+                transition != nidpdaTransitions.end();
+                transition++) {
+            if (transition->getFrom() == *state && transition->getInput() == input) {
+                *stackPop = transition->getPop();
+                *stackPush = transition->getPush();
+                targetStates.insert(transition->getTo());
+            }
+        }
+    }
+    return targetStates;
+}
+
+
+IDPDADeterminizer::IDPDADeterminizer(PDA* automaton) {
+    this->nondeterministicIDPDA = automaton;
+}
+
+
+PDA* IDPDADeterminizer::determinize() {
+    this->deterministicIDPDA = new PDA();
+    DeterminizationUtils::copyInputAlphabet(*this->nondeterministicIDPDA, *this->deterministicIDPDA);
+    DeterminizationUtils::copyStackAlphabet(*this->nondeterministicIDPDA, *this->deterministicIDPDA);
+    map<string, DeterminizationUtils::StateData> states;
+    
+    const set<State>& nidpdaInitialStates = this->nondeterministicIDPDA->getInitialStates();
+    const State& initialState = DeterminizationUtils::getOrCreateState(nidpdaInitialStates, states, *this->deterministicIDPDA);
+    
+    while (true) {
+        bool allStatesMarked = true;
+        for (map<string, DeterminizationUtils::StateData>::iterator stateIter = states.begin();
+                stateIter != states.end();
+                stateIter++) {
+            allStatesMarked &= stateIter->second.isMarked;
+        }
+        if (allStatesMarked) {
+            break;
+        }
+        
+        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;
+            }
+        }
+        
+        const set<Symbol>& nidpdaInputAlphabet = this->nondeterministicIDPDA->getInputAlphabet();
+        for (set<Symbol>::iterator input = nidpdaInputAlphabet.begin(); input != nidpdaInputAlphabet.end(); input++) {
+            list<Symbol> stackPop;
+            list<Symbol> stackPush;
+            const set<State>& nidpdaToStates = this->findToStates(unmarkedStateData->originalStates, *input, &stackPop, &stackPush);
+            if (nidpdaToStates.size() > 0) {
+                const State& targetState = DeterminizationUtils::getOrCreateState(nidpdaToStates, states, *this->deterministicIDPDA);
+                TransitionPDA transition(unmarkedStateData->state, *input, targetState, stackPop, stackPush);
+                this->deterministicIDPDA->addTransition(transition);
+            }
+        }
+        
+        unmarkedStateData->isMarked = true;
+    }
+    
+    this->deterministicIDPDA->addInitialState(initialState);
+    
+    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->nondeterministicIDPDA)) {
+            this->deterministicIDPDA->addFinalState(stateData.state);
+        }
+    }
+    
+    return this->deterministicIDPDA;
+}
+
+} /* namespace automaton */
diff --git a/adeterminize.idpda/src/IDPDADeterminizer.h b/adeterminize.idpda/src/IDPDADeterminizer.h
new file mode 100644
index 0000000000..40e8b5da5f
--- /dev/null
+++ b/adeterminize.idpda/src/IDPDADeterminizer.h
@@ -0,0 +1,32 @@
+#ifndef IDPDADETERMINIZER_H_
+#define IDPDADETERMINIZER_H_
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+
+#include "automaton/State.h"
+#include "automaton/DeterminizationUtils.h"
+#include "automaton/PDA/PDA.h"
+#include "automaton/PDA/TransitionPDA.h"
+
+using namespace std;
+
+namespace automaton {
+
+class IDPDADeterminizer {
+protected:
+    PDA* nondeterministicIDPDA;
+    PDA* deterministicIDPDA;
+    
+    set<State> findToStates(const set<State>& nidpdaStates, const Symbol& input, list<Symbol>* stackPop, list<Symbol>* stackPush);
+    
+public:
+    IDPDADeterminizer(PDA* automaton);
+    PDA* determinize();
+    
+};
+
+} /* namespace automaton */
+#endif /* IDPDADETERMINIZER_H_ */
\ No newline at end of file
diff --git a/adeterminize.idpda/src/adeterminize.idpda.cpp b/adeterminize.idpda/src/adeterminize.idpda.cpp
new file mode 100644
index 0000000000..76c087f352
--- /dev/null
+++ b/adeterminize.idpda/src/adeterminize.idpda.cpp
@@ -0,0 +1,35 @@
+#include <iostream>
+#include <set>
+
+#include "automaton/UnknownAutomaton.h"
+#include "AutomatonFactory.h"
+#include "AlibException.h"
+#include "IDPDADeterminizer.h"
+
+
+using namespace std;
+using namespace automaton;
+using namespace alib;
+
+
+int main(int argc, char** argv) {
+    UnknownAutomaton automaton;
+    
+    try {
+        string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>()));
+        automaton = AutomatonFactory::fromString(input);
+        
+        Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(&automaton);
+        // TODO check that automaton is FSM
+        IDPDADeterminizer determinizer((PDA*) knownAutomaton);
+        PDA* deterministicIDPDA = determinizer.determinize();
+        deterministicIDPDA->toXML(cout);
+        
+        delete knownAutomaton;
+        delete deterministicIDPDA;
+        
+    } catch (AlibException& e) {
+        cout << e.what() << endl;
+        return 0;
+    }
+}
\ No newline at end of file
diff --git a/examples/NIDPDA1.xml b/examples/NIDPDA1.xml
new file mode 100644
index 0000000000..552053ef28
--- /dev/null
+++ b/examples/NIDPDA1.xml
@@ -0,0 +1,65 @@
+<automaton>
+  <states>
+    <state>S</state>
+    <state>A</state>
+    <state>B</state>
+    <state>C</state>
+  </states>
+  <inputAlphabet>
+    <symbol>0</symbol>
+    <symbol>1</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>a</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>S</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>1</input>
+      <to>S</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>1</input>
+      <to>B</to>
+      <pop></pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>0</input>
+      <to>C</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>S</state>
+  </initialStates>
+  <startSymbols></startSymbols>
+  <finalStates>
+    <state>C</state>
+  </finalStates>
+</automaton>
diff --git a/examples/NIDPDA2.xml b/examples/NIDPDA2.xml
new file mode 100644
index 0000000000..1a0d4683f9
--- /dev/null
+++ b/examples/NIDPDA2.xml
@@ -0,0 +1,119 @@
+<automaton>
+  <states>
+    <state>S</state>
+    <state>A</state>
+    <state>B</state>
+    <state>C</state>
+  </states>
+  <inputAlphabet>
+    <symbol>0</symbol>
+    <symbol>1</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>a</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>B</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>1</input>
+      <to>C</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>0</input>
+      <to>C</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>1</input>
+      <to>A</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>0</input>
+      <to>C</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>1</input>
+      <to>B</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>1</input>
+      <to>A</to>
+      <pop>
+        <symbol>a</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>C</from>
+      <input>0</input>
+      <to>S</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>C</from>
+      <input>0</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>S</state>
+  </initialStates>
+  <startSymbols>
+    <symbol>a</symbol>
+    <symbol>a</symbol>
+    <symbol>a</symbol>
+  </startSymbols>
+  <finalStates>
+    <state>B</state>
+    <state>C</state>
+  </finalStates>
+</automaton>
diff --git a/examples/NIDPDA3.xml b/examples/NIDPDA3.xml
new file mode 100644
index 0000000000..0e90213ef6
--- /dev/null
+++ b/examples/NIDPDA3.xml
@@ -0,0 +1,89 @@
+<automaton>
+  <states>
+    <state>S</state>
+    <state>A</state>
+    <state>B</state>
+    <state>C</state>
+  </states>
+  <inputAlphabet>
+    <symbol>0</symbol>
+    <symbol>1</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>a</symbol>
+    <symbol>b</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>S</to>
+      <pop></pop>
+      <push>
+        <symbol>b</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>0</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>b</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>S</from>
+      <input>1</input>
+      <to>B</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>1</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>1</input>
+      <to>C</to>
+      <pop></pop>
+      <push>
+        <symbol>a</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>1</input>
+      <to>S</to>
+    </transition>
+    <transition>
+      <from>C</from>
+      <input>0</input>
+      <to>B</to>
+      <pop></pop>
+      <push>
+        <symbol>b</symbol>
+      </push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>S</state>
+  </initialStates>
+  <startSymbols>
+    <symbol>a</symbol>
+    <symbol>b</symbol>
+    <symbol>a</symbol>
+  </startSymbols>
+  <finalStates>
+    <state>B</state>
+    <state>C</state>
+  </finalStates>
+</automaton>
diff --git a/examples/NIDPDA4.xml b/examples/NIDPDA4.xml
new file mode 100644
index 0000000000..f6102b0dbc
--- /dev/null
+++ b/examples/NIDPDA4.xml
@@ -0,0 +1,135 @@
+<automaton>
+  <states>
+    <state>A</state>
+    <state>B</state>
+    <state>C</state>
+    <state>D</state>
+    <state>E</state>
+    <state>F</state>
+  </states>
+  <inputAlphabet>
+    <symbol>a</symbol>
+    <symbol>b</symbol>
+  </inputAlphabet>
+  <stackAlphabet>
+    <symbol>1</symbol>
+  </stackAlphabet>
+  <transitions>
+    <transition>
+      <from>A</from>
+      <input>a</input>
+      <to>A</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>a</input>
+      <to>B</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>b</input>
+      <to>A</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>A</from>
+      <input>b</input>
+      <to>E</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>B</from>
+      <input>a</input>
+      <to>C</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>C</from>
+      <input>a</input>
+      <to>D</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>C</from>
+      <input>b</input>
+      <to>D</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>D</from>
+      <input>a</input>
+      <to>D</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>D</from>
+      <input>b</input>
+      <to>D</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>E</from>
+      <input>a</input>
+      <to>F</to>
+      <pop></pop>
+      <push>
+        <symbol>1</symbol>
+      </push>
+    </transition>
+    <transition>
+      <from>E</from>
+      <input>b</input>
+      <to>D</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+    <transition>
+      <from>F</from>
+      <input>b</input>
+      <to>D</to>
+      <pop>
+        <symbol>1</symbol>
+      </pop>
+      <push></push>
+    </transition>
+  </transitions>
+  <initialStates>
+    <state>A</state>
+  </initialStates>
+  <startSymbols></startSymbols>
+  <finalStates>
+    <state>D</state>
+    <state>E</state>
+  </finalStates>
+</automaton>
-- 
GitLab