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