Skip to content
Snippets Groups Projects
Commit 41905b1a authored by Jan Vesely's avatar Jan Vesely
Browse files

add fsm determinization

parent 42d8edb9
No related branches found
No related tags found
No related merge requests found
#include "FSMDeterminizer.h"
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 = new State(stateName);
StateData stateData(*state, states);
this->states->insert(pair<string, StateData>(stateName, stateData));
this->deterministicFSM->addState(*state);
return *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);
}
}
const set<State>& FSMDeterminizer::findNextStatesInNfsm(const set<State>& nfsmStates, const Symbol& input) {
const set<TransitionFSM>& nfsmTransitions = this->nondeterministicFSM->getTransitions();
set<State>* nextStates = new set<State>;
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());
}
}
}
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;
}
FSMDeterminizer::FSMDeterminizer(FSM* automaton) {
this->nondeterministicFSM = automaton;
}
FSM* FSMDeterminizer::determinize() {
this->deterministicFSM = new FSM();
this->states = new map<string, StateData>();
this->copyInputAlphabet();
const set<State>& nfsmInitialStates = this->nondeterministicFSM->getInitialStates();
const State& initialState = this->getOrCreateState(nfsmInitialStates);
while (true) {
bool allStatesMarked = true;
for (map<string, StateData>::iterator stateIter = this->states->begin(); stateIter != this->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;
if (!stateData.isMarked) {
unmarkedStateData = &stateData;
break;
}
}
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);
if (nfsmNextStates.size() > 0) {
const State& nextState = this->getOrCreateState(nfsmNextStates);
TransitionFSM transition(*unmarkedStateData->state, *input, nextState);
this->deterministicFSM->addTransition(transition);
}
}
unmarkedStateData->isMarked = true;
}
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)) {
this->deterministicFSM->addFinalState(*stateData.state);
}
}
return this->deterministicFSM;
}
} /* namespace automaton */
#ifndef FSMDETERMINIZER_H_
#define FSMDETERMINIZER_H_
#include <iostream>
#include <string>
#include <set>
#include <map>
#include "automaton/State.h"
#include "automaton/Symbol.h"
#include "automaton/FSM/FSM.h"
#include "automaton/FSM/TransitionFSM.h"
using namespace std;
namespace automaton {
class FSMDeterminizer {
protected:
struct StateData {
const State* state;
const set<State>* nfsmStates;
bool isMarked;
StateData(const State& state, const set<State>& nfsmStates) {
this->state = &state;
this->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();
const set<State>& findNextStatesInNfsm(const set<State>& nfsmStates, const Symbol& input);
bool containSomeFinalStateOfNfsm(const set<State>& nfsmStates);
public:
FSMDeterminizer(FSM* automaton);
FSM* determinize();
};
} /* namespace automaton */
#endif /* FSMDETERMINIZER_H_ */
\ No newline at end of file
#include <iostream>
#include <set>
#include "automaton/UnknownAutomaton.h"
#include "AutomatonFactory.h"
#include "AlibException.h"
#include "FSMDeterminizer.h"
using namespace std;
using namespace automaton;
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
FSMDeterminizer* determinizer = new FSMDeterminizer((FSM*) knownAutomaton);
FSM* deterministicFSM = determinizer->determinize();
deterministicFSM->toXML(cout);
} catch (AlibException& e) {
cout << e.toString() << endl;
return 0;
}
}
\ No newline at end of file
<automaton>
<states>
<state>S</state>
<state>A</state>
<state>B</state>
<state>C</state>
</states>
<inputAlphabet>
<symbol>0</symbol>
<symbol>1</symbol>
</inputAlphabet>
<transitions>
<transition>
<current>S</current>
<input>0</input>
<next>S</next>
</transition>
<transition>
<current>S</current>
<input>0</input>
<next>A</next>
</transition>
<transition>
<current>S</current>
<input>1</input>
<next>S</next>
</transition>
<transition>
<current>A</current>
<input>1</input>
<next>B</next>
</transition>
<transition>
<current>B</current>
<input>0</input>
<next>C</next>
</transition>
</transitions>
<initialStates>
<state>S</state>
</initialStates>
<finalStates>
<state>C</state>
</finalStates>
</automaton>
<automaton>
<states>
<state>S</state>
<state>A</state>
<state>B</state>
<state>C</state>
</states>
<inputAlphabet>
<symbol>0</symbol>
<symbol>1</symbol>
</inputAlphabet>
<transitions>
<transition>
<current>S</current>
<input>0</input>
<next>A</next>
</transition>
<transition>
<current>S</current>
<input>0</input>
<next>B</next>
</transition>
<transition>
<current>S</current>
<input>1</input>
<next>C</next>
</transition>
<transition>
<current>A</current>
<input>0</input>
<next>C</next>
</transition>
<transition>
<current>A</current>
<input>1</input>
<next>A</next>
</transition>
<transition>
<current>B</current>
<input>0</input>
<next>C</next>
</transition>
<transition>
<current>B</current>
<input>1</input>
<next>B</next>
</transition>
<transition>
<current>B</current>
<input>1</input>
<next>A</next>
</transition>
<transition>
<current>C</current>
<input>0</input>
<next>S</next>
</transition>
<transition>
<current>C</current>
<input>0</input>
<next>A</next>
</transition>
</transitions>
<initialStates>
<state>S</state>
</initialStates>
<finalStates>
<state>B</state>
<state>C</state>
</finalStates>
</automaton>
<automaton>
<states>
<state>S</state>
<state>A</state>
<state>B</state>
<state>C</state>
</states>
<inputAlphabet>
<symbol>0</symbol>
<symbol>1</symbol>
</inputAlphabet>
<transitions>
<transition>
<current>S</current>
<input>0</input>
<next>S</next>
</transition>
<transition>
<current>S</current>
<input>0</input>
<next>A</next>
</transition>
<transition>
<current>S</current>
<input>1</input>
<next>B</next>
</transition>
<transition>
<current>A</current>
<input>1</input>
<next>A</next>
</transition>
<transition>
<current>A</current>
<input>1</input>
<next>C</next>
</transition>
<transition>
<current>B</current>
<input>1</input>
<next>S</next>
</transition>
<transition>
<current>C</current>
<input>0</input>
<next>B</next>
</transition>
</transitions>
<initialStates>
<state>S</state>
</initialStates>
<finalStates>
<state>B</state>
<state>C</state>
</finalStates>
</automaton>
<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>
<transitions>
<transition>
<current>A</current>
<input>a</input>
<next>A</next>
</transition>
<transition>
<current>A</current>
<input>a</input>
<next>B</next>
</transition>
<transition>
<current>A</current>
<input>b</input>
<next>A</next>
</transition>
<transition>
<current>A</current>
<input>b</input>
<next>E</next>
</transition>
<transition>
<current>B</current>
<input>a</input>
<next>C</next>
</transition>
<transition>
<current>C</current>
<input>a</input>
<next>D</next>
</transition>
<transition>
<current>C</current>
<input>b</input>
<next>D</next>
</transition>
<transition>
<current>D</current>
<input>a</input>
<next>D</next>
</transition>
<transition>
<current>D</current>
<input>b</input>
<next>D</next>
</transition>
<transition>
<current>E</current>
<input>a</input>
<next>F</next>
</transition>
<transition>
<current>E</current>
<input>b</input>
<next>D</next>
</transition>
<transition>
<current>F</current>
<input>b</input>
<next>D</next>
</transition>
</transitions>
<initialStates>
<state>A</state>
</initialStates>
<finalStates>
<state>D</state>
<state>E</state>
</finalStates>
</automaton>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment