diff --git a/adeterminize.idpda/src/IDPDADeterminizer.cpp b/adeterminize.idpda/src/IDPDADeterminizer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..330642b31881dfd19b9a0f48a71fd8f3559d8c47 --- /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 0000000000000000000000000000000000000000..40e8b5da5f1d9eca5858d9f69e34fea7bc36a578 --- /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 0000000000000000000000000000000000000000..76c087f352da181145ff23d470c7dc15fcdcf5bc --- /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 0000000000000000000000000000000000000000..552053ef285405c445e05b9a2d49479928b8b18c --- /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 0000000000000000000000000000000000000000..1a0d4683f91b8a9836bc4630dd837ca72c2376dc --- /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 0000000000000000000000000000000000000000..0e90213ef6c97e8785d22530ab53741d4fb1c13a --- /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 0000000000000000000000000000000000000000..f6102b0dbcc63be53cf3f7070c4378166b75eb13 --- /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>