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