From f1f8b86ab1ac04adffb9a1a104f1826261e29cca Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 28 Oct 2016 19:35:57 +0200 Subject: [PATCH] template ExtendedNFA automaton --- acompare2/src/AutomatonCompare.cpp | 8 +- acompare2/src/AutomatonCompare.h | 6 +- aconvert2/src/DotConverter.cpp | 6 +- aconvert2/src/DotConverter.h | 4 +- aconvert2/src/GasTexConverter.cpp | 6 +- aconvert2/src/GasTexConverter.h | 4 +- aconvert2/src/TikZConverter.cpp | 6 +- aconvert2/src/TikZConverter.h | 4 +- alib2algo/src/automaton/convert/ToRegExp.cpp | 4 +- alib2algo/src/automaton/convert/ToRegExp.h | 2 +- .../convert/ToRegExpStateElimination.cpp | 12 +- .../convert/ToRegExpStateElimination.h | 6 +- .../properties/AllEpsilonClosure.cpp | 4 +- .../automaton/properties/AllEpsilonClosure.h | 2 +- .../automaton/properties/EpsilonClosure.cpp | 4 +- .../src/automaton/properties/EpsilonClosure.h | 2 +- .../automaton/properties/ReachableStates.cpp | 2 +- .../automaton/properties/UsefullStates.cpp | 2 +- .../automaton/simplify/SingleInitialState.cpp | 4 +- .../automaton/simplify/SingleInitialState.h | 2 +- alib2algo/src/automaton/simplify/Trim.cpp | 2 +- .../simplify/UnreachableStatesRemover.cpp | 2 +- .../simplify/UselessStatesRemover.cpp | 2 +- alib2data/src/automaton/AutomatonFeatures.h | 1 + alib2data/src/automaton/FSM/ExtendedNFA.cpp | 237 +---------- alib2data/src/automaton/FSM/ExtendedNFA.h | 381 ++++++++++++++---- .../test-src/automaton/AutomatonTest.cpp | 2 +- .../efficient/AllEpsilonClosure.cpp | 4 +- .../properties/efficient/AllEpsilonClosure.h | 2 +- .../properties/efficient/ReachableStates.cpp | 2 +- .../properties/efficient/UsefullStates.cpp | 2 +- .../src/automaton/simplify/efficient/Trim.cpp | 2 +- .../efficient/UnreachableStatesRemover.cpp | 2 +- .../efficient/UselessStatesRemover.cpp | 2 +- 34 files changed, 377 insertions(+), 356 deletions(-) diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp index 2b2316c638..90d2408299 100644 --- a/acompare2/src/AutomatonCompare.cpp +++ b/acompare2/src/AutomatonCompare.cpp @@ -70,7 +70,7 @@ bool AutomatonCompare::testCompare(const automaton::EpsilonNFA < > & a, const au a.getTransitions() == b.getTransitions() ; } -bool AutomatonCompare::testCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) { +bool AutomatonCompare::testCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) { return a.getFinalStates() == b.getFinalStates() && a.getInitialState() == b.getInitialState() && // a.getInputAlphabet() == b.getInputAlphabet() && @@ -414,7 +414,7 @@ void AutomatonCompare::printCompare(const automaton::EpsilonNFA < > & a, const a } } -void AutomatonCompare::printCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) { +void AutomatonCompare::printCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) { std::cout << "AutomatonCompareer" << std::endl; if(a.getFinalStates() != b.getFinalStates()){ @@ -1216,7 +1216,7 @@ int AutomatonCompare::compare(const automaton::EpsilonNFA < > & a, const automat auto AutomatonCompareEpsilonNFA = AutomatonCompare::RegistratorWrapper<int, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(AutomatonCompare::compare); -int AutomatonCompare::compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) { +int AutomatonCompare::compare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) { if(!AutomatonCompare::testCompare(a, b)) { AutomatonCompare::printCompare(a, b); return 1; @@ -1225,7 +1225,7 @@ int AutomatonCompare::compare(const automaton::ExtendedNFA& a, const automaton:: } } -auto AutomatonCompareExtendedNFA = AutomatonCompare::RegistratorWrapper<int, automaton::ExtendedNFA, automaton::ExtendedNFA>(AutomatonCompare::compare); +auto AutomatonCompareExtendedNFA = AutomatonCompare::RegistratorWrapper<int, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(AutomatonCompare::compare); int AutomatonCompare::compare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b) { if(!AutomatonCompare::testCompare(a, b)) { diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h index 10fdcc9afa..d1870b3a26 100644 --- a/acompare2/src/AutomatonCompare.h +++ b/acompare2/src/AutomatonCompare.h @@ -32,8 +32,8 @@ private: static bool testCompare(const automaton::EpsilonNFA < > & a, const automaton::EpsilonNFA < > & b); static void printCompare(const automaton::EpsilonNFA < > & a, const automaton::EpsilonNFA < > & b); - static bool testCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b); - static void printCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b); + static bool testCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b); + static void printCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b); static bool testCompare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b); static void printCompare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b); @@ -85,7 +85,7 @@ public: static int compare(const automaton::NFA < > & a, const automaton::NFA < > & b); static int compare(const automaton::MultiInitialStateNFA < >& a, const automaton::MultiInitialStateNFA < >& b); static int compare(const automaton::EpsilonNFA < > & a, const automaton::EpsilonNFA < > & b); - static int compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b); + static int compare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b); static int compare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b); static int compare(const automaton::DFTA < > & a, const automaton::DFTA < > & b); diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp index 88472d793f..88bcd01755 100644 --- a/aconvert2/src/DotConverter.cpp +++ b/aconvert2/src/DotConverter.cpp @@ -186,7 +186,7 @@ void DotConverter::convert(std::ostream& out, const automaton::DFA<>& a) { auto DotConverterDFA = DotConverter::RegistratorWrapper<void, automaton::DFA<>>(DotConverter::convert); -void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) { +void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA < > & a) { out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -217,7 +217,7 @@ void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) { out << "}"; } -auto DotConverterExtendedNFA = DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(DotConverter::convert); +auto DotConverterExtendedNFA = DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA < > >(DotConverter::convert); void DotConverter::convert(std::ostream& out, const automaton::CompactNFA < > & a) { out << "digraph automaton {\n"; @@ -816,7 +816,7 @@ void DotConverter::transitions(const automaton::DFA<>& fsm, const std::map<label } } -void DotConverter::transitions(const automaton::ExtendedNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out) { +void DotConverter::transitions(const automaton::ExtendedNFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out) { std::map<std::pair<int, int>, std::string> transitions; //put transitions from automaton to "transitions" diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h index 20d2ef38b1..feeef85866 100644 --- a/aconvert2/src/DotConverter.h +++ b/aconvert2/src/DotConverter.h @@ -24,7 +24,7 @@ class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, vo static void transitions(const automaton::MultiInitialStateNFA < >& fsm, const std::map<label::Label, int>& states, std::ostream& out); static void transitions(const automaton::NFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out); static void transitions(const automaton::DFA<>& fsm, const std::map<label::Label, int>& states, std::ostream& out); - static void transitions(const automaton::ExtendedNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out); + static void transitions(const automaton::ExtendedNFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out); static void transitions(const automaton::CompactNFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out); static void transitions(const automaton::NFTA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out); static void transitions(const automaton::DFTA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out); @@ -46,7 +46,7 @@ public: static void convert(std::ostream& out, const automaton::MultiInitialStateNFA < >& a); static void convert(std::ostream& out, const automaton::NFA < > & a); static void convert(std::ostream& out, const automaton::DFA<>& a); - static void convert(std::ostream& out, const automaton::ExtendedNFA& a); + static void convert(std::ostream& out, const automaton::ExtendedNFA < > & a); static void convert(std::ostream& out, const automaton::CompactNFA < > & a); static void convert(std::ostream& out, const automaton::NFTA < > & a); static void convert(std::ostream& out, const automaton::DFTA < > & a); diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp index 7cf18b57fe..b8bf6ef0e6 100644 --- a/aconvert2/src/GasTexConverter.cpp +++ b/aconvert2/src/GasTexConverter.cpp @@ -205,7 +205,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::DFA<>& a) { auto GasTexConverterDFA = GasTexConverter::RegistratorWrapper<void, automaton::DFA<>>(GasTexConverter::convert); -void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) { +void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA < > & a) { out << "\\begin{center}\n"; out << "\\begin{picture}(,)(,)\n"; @@ -244,7 +244,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a out << "\\end{picture}\n"; } -auto GasTexConverterExtendedNFA = GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(GasTexConverter::convert); +auto GasTexConverterExtendedNFA = GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA < > >(GasTexConverter::convert); void GasTexConverter::convert(std::ostream& out, const automaton::CompactNFA < > & a) { out << "\\begin{center}\n"; @@ -870,7 +870,7 @@ void GasTexConverter::transitions(const automaton::DFA<>& fsm, std::ostream& out printTransitionMap(transitionMap, out); } -void GasTexConverter::transitions(const automaton::ExtendedNFA& fsm, std::ostream& out) { +void GasTexConverter::transitions(const automaton::ExtendedNFA < > & fsm, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; for (const auto& transition : fsm.getTransitions()) { diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h index 41a455309d..baacda7c34 100644 --- a/aconvert2/src/GasTexConverter.h +++ b/aconvert2/src/GasTexConverter.h @@ -25,7 +25,7 @@ class GasTexConverter : public std::SingleDispatchFirstStaticParam<GasTexConvert static void transitions(const automaton::MultiInitialStateNFA < >& fsm, std::ostream& out); static void transitions(const automaton::NFA < > & fsm, std::ostream& out); static void transitions(const automaton::DFA<>& fsm, std::ostream& out); - static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out); + static void transitions(const automaton::ExtendedNFA < > & fsm, std::ostream& out); static void transitions(const automaton::CompactNFA < > & fsm, std::ostream& out); static void transitions(const automaton::NFTA < > & fsm, std::ostream& out); static void transitions(const automaton::DFTA < > & fsm, std::ostream& out); @@ -47,7 +47,7 @@ public: static void convert(std::ostream& out, const automaton::MultiInitialStateNFA < >& a); static void convert(std::ostream& out, const automaton::NFA < > & a); static void convert(std::ostream& out, const automaton::DFA<>& a); - static void convert(std::ostream& out, const automaton::ExtendedNFA& a); + static void convert(std::ostream& out, const automaton::ExtendedNFA < > & a); static void convert(std::ostream& out, const automaton::CompactNFA < > & a); static void convert(std::ostream& out, const automaton::NFTA < > & a); static void convert(std::ostream& out, const automaton::DFTA < > & a); diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp index 3f697750f6..1df53520ec 100644 --- a/aconvert2/src/TikZConverter.cpp +++ b/aconvert2/src/TikZConverter.cpp @@ -169,7 +169,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::DFA<> & a ) { auto TikZConverterDFA = TikZConverter::RegistratorWrapper < void, automaton::DFA<> > ( TikZConverter::convert ); -void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA & a ) { +void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA < > & a ) { out << "\\begin{tikzpicture}\n"; int cnt = 1; @@ -196,7 +196,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA & out << "\\end{tikzpicture}"; } -auto TikZConverterExtendedNFA = TikZConverter::RegistratorWrapper < void, automaton::ExtendedNFA > ( TikZConverter::convert ); +auto TikZConverterExtendedNFA = TikZConverter::RegistratorWrapper < void, automaton::ExtendedNFA < > > ( TikZConverter::convert ); void TikZConverter::convert ( std::ostream & out, const automaton::CompactNFA < > & a ) { out << "\\begin{tikzpicture}\n"; @@ -769,7 +769,7 @@ void TikZConverter::transitions ( const automaton::DFA<> & fsm, const std::map < } } -void TikZConverter::transitions ( const automaton::ExtendedNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ) { +void TikZConverter::transitions ( const automaton::ExtendedNFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ) { std::map < std::pair < int, int >, std::string > transitions; // put transitions from automaton to "transitions" diff --git a/aconvert2/src/TikZConverter.h b/aconvert2/src/TikZConverter.h index 6507240a06..f63decadb2 100644 --- a/aconvert2/src/TikZConverter.h +++ b/aconvert2/src/TikZConverter.h @@ -24,7 +24,7 @@ class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter static void transitions ( const automaton::MultiInitialStateNFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); static void transitions ( const automaton::NFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); static void transitions ( const automaton::DFA<> & fsm, const std::map < label::Label, int > & states, std::ostream & out ); - static void transitions ( const automaton::ExtendedNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ); + static void transitions ( const automaton::ExtendedNFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); static void transitions ( const automaton::CompactNFA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); static void transitions ( const automaton::NFTA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); static void transitions ( const automaton::DFTA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out ); @@ -47,7 +47,7 @@ public: static void convert ( std::ostream & out, const automaton::MultiInitialStateNFA < > & a ); static void convert ( std::ostream & out, const automaton::NFA < > & a ); static void convert ( std::ostream & out, const automaton::DFA<> & a ); - static void convert ( std::ostream & out, const automaton::ExtendedNFA & a ); + static void convert ( std::ostream & out, const automaton::ExtendedNFA < > & a ); static void convert ( std::ostream & out, const automaton::CompactNFA < > & a ); static void convert ( std::ostream & out, const automaton::NFTA < > & a ); static void convert ( std::ostream & out, const automaton::DFTA < > & a ); diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp index 549048bca0..81515b68fc 100644 --- a/alib2algo/src/automaton/convert/ToRegExp.cpp +++ b/alib2algo/src/automaton/convert/ToRegExp.cpp @@ -40,11 +40,11 @@ regexp::RegExp ToRegExp::convert(const automaton::DFA<>& automaton) { auto ToRegExpDFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::DFA<>>(ToRegExp::convert); -regexp::RegExp ToRegExp::convert(const automaton::ExtendedNFA& automaton) { +regexp::RegExp ToRegExp::convert(const automaton::ExtendedNFA < > & automaton) { return regexp::RegExp(ToRegExpStateElimination::convert(automaton)); } -auto ToRegExpExtendedNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::ExtendedNFA>(ToRegExp::convert); +auto ToRegExpExtendedNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::ExtendedNFA < > >(ToRegExp::convert); regexp::RegExp ToRegExp::convert(const automaton::CompactNFA < > & automaton) { return regexp::RegExp(ToRegExpStateElimination::convert(automaton)); diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h index bff129ed05..e433bc8029 100644 --- a/alib2algo/src/automaton/convert/ToRegExp.h +++ b/alib2algo/src/automaton/convert/ToRegExp.h @@ -35,7 +35,7 @@ public: static regexp::RegExp convert(const automaton::MultiInitialStateNFA < > & automaton); static regexp::RegExp convert(const automaton::NFA<>& automaton); static regexp::RegExp convert(const automaton::DFA<>& automaton); - static regexp::RegExp convert(const automaton::ExtendedNFA& automaton); + static regexp::RegExp convert(const automaton::ExtendedNFA < > & automaton); static regexp::RegExp convert(const automaton::CompactNFA < > & automaton); }; diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp index 46b0d7fe9c..17b6d64bf7 100644 --- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp +++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp @@ -26,7 +26,7 @@ regexp::UnboundedRegExp < > ToRegExpStateElimination::convert(const T& automaton return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < alphabet::Symbol > (regexp::UnboundedRegExpEmpty < alphabet::Symbol > ())); // steps 1 + 2 - automaton::ExtendedNFA extendedAutomaton(automaton); + automaton::ExtendedNFA < > extendedAutomaton(automaton); extendExtendedNFA(extendedAutomaton); // step 3 - Exterminate! @@ -48,11 +48,11 @@ auto ToRegExpStateEliminationEpsilonNFA = ToRegExpStateElimination::RegistratorW auto ToRegExpStateEliminationMultiInitialStateNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::MultiInitialStateNFA < > >(ToRegExpStateElimination::convert); auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::NFA < > >(ToRegExpStateElimination::convert); auto ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::DFA<>>(ToRegExpStateElimination::convert); -auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::ExtendedNFA>(ToRegExpStateElimination::convert); +auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::ExtendedNFA < > >(ToRegExpStateElimination::convert); auto ToRegExpStateEliminationCompactNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::CompactNFA < > >(ToRegExpStateElimination::convert); -automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& q) { - automaton::ExtendedNFA newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA) +automaton::ExtendedNFA < > ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA < > & extendedAutomaton, const label::Label& q) { + automaton::ExtendedNFA < > newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA) newAutomaton.setStates(extendedAutomaton.getStates()); newAutomaton.removeState(q); // preserve all states but q (the one to eliminate) newAutomaton.setInputAlphabet(extendedAutomaton.getInputAlphabet()); @@ -73,7 +73,7 @@ automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton: return newAutomaton; } -const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to) { +const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimination::transition(const automaton::ExtendedNFA < > & automaton, const label::Label& from, const label::Label& to) { regexp::UnboundedRegExpStructure < alphabet::Symbol > ret(regexp::UnboundedRegExpEmpty < alphabet::Symbol > { }); for(const auto& transition: automaton.getTransitionsFromState(from)) @@ -83,7 +83,7 @@ const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimina return regexp::simplify::RegExpOptimize::optimize(ret); } -void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) { +void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA < > & automaton) { const label::Label& initState = automaton.getInitialState(); if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 ) { label::Label q0 = label::createUniqueLabel(initState, automaton.getStates()); diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h index 070566a241..7febd74cdf 100644 --- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h +++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h @@ -41,11 +41,11 @@ public: static regexp::UnboundedRegExp < > convert(const T& automaton); private: - static void extendExtendedNFA(automaton::ExtendedNFA& automaton); + static void extendExtendedNFA(automaton::ExtendedNFA < > & automaton); - static const regexp::UnboundedRegExpStructure < alphabet::Symbol > transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to); + static const regexp::UnboundedRegExpStructure < alphabet::Symbol > transition(const automaton::ExtendedNFA < > & automaton, const label::Label& from, const label::Label& to); - static automaton::ExtendedNFA eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& state); + static automaton::ExtendedNFA < > eliminateState(const automaton::ExtendedNFA < > & extendedAutomaton, const label::Label& state); }; } /* namespace convert */ diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp index cff859cd7a..7d8a08f3d1 100644 --- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp @@ -81,7 +81,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA<>>(AllEpsilonClosure::allEpsilonClosure); -std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA & fsm) { +std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < > & fsm) { std::map<label::Label, std::set<label::Label>> res; std::map<label::Label, std::set<label::Label>> step; @@ -103,7 +103,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos return res; } -auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA>(AllEpsilonClosure::allEpsilonClosure); +auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA < > >(AllEpsilonClosure::allEpsilonClosure); std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < > & fsm) { std::map<label::Label, std::set<label::Label>> res; diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h index bc40ae920e..2e8194dcac 100644 --- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h +++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h @@ -31,7 +31,7 @@ public: static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::MultiInitialStateNFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::DFA < > & fsm); - static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA & fsm); + static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::CompactNFA < > & fsm); }; diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp index 6260c7e60d..aabf4c6dfe 100644 --- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp @@ -85,7 +85,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::DFA < > auto EpsilonClosureDFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(EpsilonClosure::epsilonClosure); -std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA & fsm, const label::Label & q ) { +std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA < > & fsm, const label::Label & q ) { if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton"); std::set<label::Label> closure; @@ -113,7 +113,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::Extended return closure; } -auto EpsilonClosureExtendedNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(EpsilonClosure::epsilonClosure); +auto EpsilonClosureExtendedNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(EpsilonClosure::epsilonClosure); std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::CompactNFA < > & fsm, const label::Label & q ) { if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton"); diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h index 56458df5cd..9b98436f99 100644 --- a/alib2algo/src/automaton/properties/EpsilonClosure.h +++ b/alib2algo/src/automaton/properties/EpsilonClosure.h @@ -32,7 +32,7 @@ public: static std::set<label::Label> epsilonClosure( const automaton::MultiInitialStateNFA < > & fsm, const label::Label & state ); static std::set<label::Label> epsilonClosure( const automaton::NFA < > & fsm, const label::Label & state ); static std::set<label::Label> epsilonClosure( const automaton::DFA < > & fsm, const label::Label & state ); - static std::set<label::Label> epsilonClosure( const automaton::ExtendedNFA & fsm, const label::Label & state ); + static std::set<label::Label> epsilonClosure( const automaton::ExtendedNFA < > & fsm, const label::Label & state ); static std::set<label::Label> epsilonClosure( const automaton::CompactNFA < > & fsm, const label::Label & state ); }; diff --git a/alib2algo/src/automaton/properties/ReachableStates.cpp b/alib2algo/src/automaton/properties/ReachableStates.cpp index 029f340865..ee19d16be9 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.cpp +++ b/alib2algo/src/automaton/properties/ReachableStates.cpp @@ -54,7 +54,7 @@ std::set<label::Label> ReachableStates::reachableStates( const T & fsm ) { auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(ReachableStates::reachableStates); auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(ReachableStates::reachableStates); auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(ReachableStates::reachableStates); -auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates); +auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates); template<> std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) { diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp index 1fd4061f41..539f0ec059 100644 --- a/alib2algo/src/automaton/properties/UsefullStates.cpp +++ b/alib2algo/src/automaton/properties/UsefullStates.cpp @@ -52,7 +52,7 @@ std::set<label::Label> UsefullStates::usefullStates( const T & fsm ) { auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(UsefullStates::usefullStates); auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(UsefullStates::usefullStates); auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(UsefullStates::usefullStates); -auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(UsefullStates::usefullStates); +auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(UsefullStates::usefullStates); auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA < > >(UsefullStates::usefullStates); template<> diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp index 7cdf8e9b1d..e3ff39b45b 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp +++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp @@ -89,11 +89,11 @@ automaton::CompactNFA < > SingleInitialState::convert(const automaton::CompactNF auto SingleInitialStateCompactNFA = SingleInitialState::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(SingleInitialState::convert); -automaton::ExtendedNFA SingleInitialState::convert(const automaton::ExtendedNFA& automaton) { +automaton::ExtendedNFA < > SingleInitialState::convert(const automaton::ExtendedNFA < > & automaton) { return automaton; } -auto SingleInitialStateExtendedNFA = SingleInitialState::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(SingleInitialState::convert); +auto SingleInitialStateExtendedNFA = SingleInitialState::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(SingleInitialState::convert); } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h index de59ea0e24..74941f6285 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -32,7 +32,7 @@ public: static automaton::DFA<> convert(const automaton::DFA<>& automaton); static automaton::NFA < > convert(const automaton::NFA < > & automaton); static automaton::EpsilonNFA < > convert(const automaton::EpsilonNFA < > & automaton); - static automaton::ExtendedNFA convert(const automaton::ExtendedNFA& automaton); + static automaton::ExtendedNFA < > convert(const automaton::ExtendedNFA < > & automaton); static automaton::CompactNFA < > convert(const automaton::CompactNFA < > & automaton); }; diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp index 615af0b54b..f159f5a202 100644 --- a/alib2algo/src/automaton/simplify/Trim.cpp +++ b/alib2algo/src/automaton/simplify/Trim.cpp @@ -29,7 +29,7 @@ auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > auto TrimMultiInitialStateNFA = Trim::RegistratorWrapper<automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > >(Trim::trim); auto TrimEpsilonNFA = Trim::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(Trim::trim); auto TrimCompactNFA = Trim::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(Trim::trim); -auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(Trim::trim); +auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(Trim::trim); automaton::Automaton Trim::trim(const automaton::Automaton& automaton) { return dispatch(automaton.getData()); diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp index 8e55235054..5b6e6b6e75 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp @@ -50,7 +50,7 @@ T UnreachableStatesRemover::remove( const T & fsm ) { auto UnreachableStatesRemoverEpsilonNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(UnreachableStatesRemover::remove); auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UnreachableStatesRemover::remove); auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UnreachableStatesRemover::remove); -auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove); +auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UnreachableStatesRemover::remove); template<> automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) { diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp index f3a42af5e2..871f6804aa 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp @@ -51,7 +51,7 @@ T UselessStatesRemover::remove( const T & fsm ) { auto UselessStatesRemoverEpsilonNFA = UselessStatesRemover::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(UselessStatesRemover::remove); auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UselessStatesRemover::remove); auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UselessStatesRemover::remove); -auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove); +auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UselessStatesRemover::remove); template<> automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) { diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h index a12f3729fd..dcde75948d 100644 --- a/alib2data/src/automaton/AutomatonFeatures.h +++ b/alib2data/src/automaton/AutomatonFeatures.h @@ -51,6 +51,7 @@ template<class SymbolType = typename alphabet::Symbol, class StateType = typenam class DFA; template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label > class CompactNFA; +template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label > class ExtendedNFA; template<class SymbolType = typename alphabet::Symbol, class EpsilonType = typename string::Epsilon < SymbolType >, class StateType = typename label::Label > class DPDA; diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp index 87242abcfe..6e777e0172 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp +++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp @@ -6,241 +6,22 @@ */ #include "ExtendedNFA.h" -#include "CompactNFA.h" -#include "EpsilonNFA.h" -#include "MultiInitialStateNFA.h" -#include "NFA.h" -#include "DFA.h" -#include "../../regexp/unbounded/UnboundedRegExpStructure.h" -#include "../../regexp/unbounded/UnboundedRegExpConcatenation.h" -#include "../../regexp/unbounded/UnboundedRegExpSymbol.h" -#include <ostream> -#include <algorithm> -#include <sstream> - -#include <sax/FromXMLParserHelper.h> -#include "../common/AutomatonFromXMLParser.h" -#include "../common/AutomatonToXMLComposer.h" #include "../Automaton.h" #include <object/Object.h> #include <core/xmlApi.hpp> -#include <core/castApi.hpp> -#include "../../label/InitialStateLabel.h" - -namespace automaton { - -ExtendedNFA::ExtendedNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ) : std::Components < ExtendedNFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) { -} - -ExtendedNFA::ExtendedNFA ( label::Label initialState ) : ExtendedNFA ( std::set < label::Label > { initialState }, std::set < alphabet::Symbol > { }, initialState, std::set < label::Label > { } ) { -} - -ExtendedNFA::ExtendedNFA ( const CompactNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { - for ( const auto & transition : other.getTransitions ( ) ) { - regexp::UnboundedRegExpConcatenation < alphabet::Symbol > con; - - for ( auto & symbol : transition.first.second ) - con.appendElement ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( symbol ) ); - - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( std::move ( con ) ) ); - transitions[key] = transition.second; - } -} - -ExtendedNFA::ExtendedNFA ( const EpsilonNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { - for ( const auto & transition : other.getTransitions ( ) ) { - if ( transition.first.second.is < string::Epsilon < > > ( ) ) { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( ) ); - transitions[key] = transition.second; - } else { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second.get < alphabet::Symbol > ( ) ) ) ); - transitions[key] = transition.second; - } - } -} - -ExtendedNFA::ExtendedNFA ( const MultiInitialStateNFA < > & other ) : ExtendedNFA ( other.getStates ( ) + std::set < label::Label > { label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ) }, other.getInputAlphabet ( ), label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ), other.getFinalStates ( ) ) { - for ( const auto & transition : other.getTransitions ( ) ) { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) ); - transitions[key] = transition.second; - } - - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( this->getInitialState ( ), regexp::UnboundedRegExpStructure < alphabet::Symbol > ( ) ); - transitions[key] = other.getInitialStates ( ); -} - -ExtendedNFA::ExtendedNFA ( const NFA <> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { - for ( const auto & transition : other.getTransitions ( ) ) { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) ); - transitions[key] = transition.second; - } -} - -ExtendedNFA::ExtendedNFA ( const DFA<> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { - for ( const auto & transition : other.getTransitions ( ) ) { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) ); - transitions[key].insert ( transition.second ); - } -} - -AutomatonBase * ExtendedNFA::clone ( ) const { - return new ExtendedNFA ( * this ); -} - -AutomatonBase * ExtendedNFA::plunder ( ) && { - return new ExtendedNFA ( std::move ( * this ) ); -} - -bool ExtendedNFA::addTransition ( label::Label from, regexp::UnboundedRegExpStructure < alphabet::Symbol > input, label::Label to ) { - if ( !getStates ( ).count ( from ) ) - throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." ); - - std::set < alphabet::Symbol > inputRegExpAlphabet = input.getStructure ( ).computeMinimalAlphabet ( ); - - // Transition regexp's alphabet must be subset of automaton's alphabet - if ( !std::includes ( getInputAlphabet ( ).begin ( ), getInputAlphabet ( ).end ( ), inputRegExpAlphabet.begin ( ), inputRegExpAlphabet.end ( ) ) ) - throw AutomatonException ( "Input string is over different alphabet than automaton" ); - - if ( !getStates ( ).count ( to ) ) - throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." ); - - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( std::move ( from ), std::move ( input ) ); - - return transitions[std::move ( key )].insert ( std::move ( to ) ).second; -} - -bool ExtendedNFA::removeTransition ( const label::Label & from, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & input, const label::Label & to ) { - std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( from, input ); - - return transitions[key].erase ( to ); -} - -const std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & ExtendedNFA::getTransitions ( ) const { - return transitions; -} - -std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > ExtendedNFA::getTransitionsFromState ( const label::Label & from ) const { - if ( !getStates ( ).count ( from ) ) - throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist" ); - - std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitionsFromState; - - for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : transitions ) - if ( transition.first.first == from ) - transitionsFromState.insert ( make_pair ( transition.first, transition.second ) ); - return transitionsFromState; -} - -std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > ExtendedNFA::getTransitionsToState ( const label::Label & to ) const { - if ( !getStates ( ).count ( to ) ) - throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist" ); - - std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitionsToState; - - for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : transitions ) - if ( transition.second.find ( to ) != transition.second.end ( ) ) - transitionsToState.insert ( make_pair ( transition.first, transition.second ) ); - - return transitionsToState; -} - -int ExtendedNFA::compare ( const ExtendedNFA & other ) const { - auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions ); - auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.getTransitions ( ) ); - - std::compare < decltype ( first ) > comp; - - return comp ( first, second ); -} - -void ExtendedNFA::operator >>( std::ostream & out ) const { - out << "(ExtendedNFA " - << "states = " << getStates ( ) - << "inputAlphabet = " << getInputAlphabet ( ) - << "initialState = " << getInitialState ( ) - << "finalStates = " << getFinalStates ( ) - << "transitions = " << transitions - << ")"; -} - -ExtendedNFA::operator std::string ( ) const { - std::stringstream ss; - ss << * this; - return ss.str ( ); -} - -ExtendedNFA ExtendedNFA::parse ( std::deque < sax::Token >::iterator & input ) { - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, ExtendedNFA::getXmlTagName() ); - - std::set < label::Label > states = AutomatonFromXMLParser::parseStates < label::Label > ( input ); - std::set < alphabet::Symbol > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet < alphabet::Symbol > ( input ); - label::Label initialState = AutomatonFromXMLParser::parseInitialState < label::Label > ( input ); - std::set < label::Label > finalStates = AutomatonFromXMLParser::parseFinalStates < label::Label > ( input ); - - ExtendedNFA automaton ( std::move ( initialState ) ); - - automaton.setStates ( std::move ( states ) ); - automaton.setInputAlphabet ( std::move ( inputSymbols ) ); - automaton.setFinalStates ( std::move ( finalStates ) ); - - AutomatonFromXMLParser::parseTransitions < ExtendedNFA > ( input, automaton ); - - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, ExtendedNFA::getXmlTagName() ); - return automaton; -} - -void ExtendedNFA::parseTransition ( std::deque < sax::Token >::iterator & input, ExtendedNFA & automaton ) { - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" ); - label::Label from = AutomatonFromXMLParser::parseTransitionFrom < label::Label > ( input ); - regexp::UnboundedRegExpStructure < alphabet::Symbol > inputRegexp = AutomatonFromXMLParser::parseTransitionInputRegexp < alphabet::Symbol > ( input ); - label::Label to = AutomatonFromXMLParser::parseTransitionTo < label::Label > ( input ); - sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "transition" ); - - automaton.addTransition ( std::move ( from ), std::move ( inputRegexp ), std::move ( to ) ); -} - -void ExtendedNFA::compose ( std::deque < sax::Token > & out ) const { - out.emplace_back ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::START_ELEMENT ); - - AutomatonToXMLComposer::composeStates ( out, this->getStates ( ) ); - AutomatonToXMLComposer::composeInputAlphabet ( out, this->getInputAlphabet ( ) ); - AutomatonToXMLComposer::composeInitialState ( out, this->getInitialState ( ) ); - AutomatonToXMLComposer::composeFinalStates ( out, this->getFinalStates ( ) ); - composeTransitions ( out ); - - out.emplace_back ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT ); -} - -void ExtendedNFA::composeTransitions ( std::deque < sax::Token > & out ) const { - out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT ); - - for ( const auto & transition : this->getTransitions ( ) ) - for ( const auto & targetState : transition.second ) { - out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT ); - - AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first ); - AutomatonToXMLComposer::composeTransitionInputRegexp ( out, transition.first.second ); - AutomatonToXMLComposer::composeTransitionTo ( out, targetState ); - - out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT ); - } - - out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT ); -} - -} /* namespace automaton */ +#include <core/castApi.hpp> namespace alib { -auto extendedNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::ExtendedNFA > ( ); -auto extendedNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::ExtendedNFA > ( ); +auto extendedNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::ExtendedNFA < > > ( ); +auto extendedNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::ExtendedNFA < > > ( ); -auto ExtendedNFAFromDFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::DFA < > > ( ); -auto ExtendedNFAFromNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::NFA < > > ( ); -auto ExtendedNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::MultiInitialStateNFA < > > ( ); -auto ExtendedNFAEpsilonNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::EpsilonNFA < > > ( ); -auto ExtendedNFACompactNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::CompactNFA < > > ( ); -auto ExtendedNFACastBinder = castApi::CastPoolStringBinder < automaton::ExtendedNFA > ( automaton::ExtendedNFA::getXmlTagName() ); +auto ExtendedNFAFromDFA = castApi::CastRegister < automaton::ExtendedNFA < >, automaton::DFA < > > ( ); +auto ExtendedNFAFromNFA = castApi::CastRegister < automaton::ExtendedNFA < >, automaton::NFA < > > ( ); +auto ExtendedNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::ExtendedNFA < >, automaton::MultiInitialStateNFA < > > ( ); +auto ExtendedNFAEpsilonNFA = castApi::CastRegister < automaton::ExtendedNFA < >, automaton::EpsilonNFA < > > ( ); +auto ExtendedNFACompactNFA = castApi::CastRegister < automaton::ExtendedNFA < >, automaton::CompactNFA < > > ( ); +auto ExtendedNFACastBinder = castApi::CastPoolStringBinder < automaton::ExtendedNFA < > > ( automaton::ExtendedNFA < >::getXmlTagName() ); } /* namespace alib */ diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h index dc3486f726..a99b3a9970 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.h +++ b/alib2data/src/automaton/FSM/ExtendedNFA.h @@ -8,17 +8,24 @@ #ifndef EXTENDED_NFA_H_ #define EXTENDED_NFA_H_ -#include "../AutomatonException.h" #include <map> +#include <ostream> +#include <algorithm> +#include <sstream> + +#include <sax/FromXMLParserHelper.h> #include <core/components.hpp> + +#include "../AutomatonException.h" #include "../AutomatonBase.h" -#include "../../regexp/RegExp.h" -#include "../../label/Label.h" -#include "CompactNFA.h" -#include "EpsilonNFA.h" -#include "MultiInitialStateNFA.h" -#include "NFA.h" -#include "DFA.h" +#include "../AutomatonFeatures.h" +#include "../common/AutomatonFromXMLParser.h" +#include "../common/AutomatonToXMLComposer.h" + +#include "../../label/InitialStateLabel.h" +#include "../../regexp/unbounded/UnboundedRegExpStructure.h" +#include "../../regexp/unbounded/UnboundedRegExpConcatenation.h" +#include "../../regexp/unbounded/UnboundedRegExpSymbol.h" namespace automaton { @@ -31,13 +38,14 @@ class States; class FinalStates; class InitialState; -class ExtendedNFA : public AutomatonBase, public std::Components < ExtendedNFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > { +template<class SymbolType, class StateType > +class ExtendedNFA : public AutomatonBase, public std::Components < ExtendedNFA < SymbolType, StateType >, SymbolType, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > { protected: - std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitions; + std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitions; public: - explicit ExtendedNFA ( label::Label initialState ); - explicit ExtendedNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ); + explicit ExtendedNFA ( StateType initialState ); + explicit ExtendedNFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ); explicit ExtendedNFA ( const CompactNFA < > & other ); explicit ExtendedNFA ( const EpsilonNFA < > & other ); explicit ExtendedNFA ( const MultiInitialStateNFA < > & other ); @@ -48,64 +56,64 @@ public: virtual AutomatonBase * plunder ( ) &&; - const label::Label & getInitialState ( ) const { - return accessElement < InitialState > ( ).get ( ); + const StateType & getInitialState ( ) const { + return this->template accessElement < InitialState > ( ).get ( ); } - bool setInitialState ( label::Label state ) { - return accessElement < InitialState > ( ).set ( std::move ( state ) ); + bool setInitialState ( StateType state ) { + return this->template accessElement < InitialState > ( ).set ( std::move ( state ) ); } - const std::set < label::Label > & getStates ( ) const { - return accessComponent < States > ( ).get ( ); + const std::set < StateType > & getStates ( ) const { + return this->template accessComponent < States > ( ).get ( ); } - bool addState ( label::Label state ) { - return accessComponent < States > ( ).add ( std::move ( state ) ); + bool addState ( StateType state ) { + return this->template accessComponent < States > ( ).add ( std::move ( state ) ); } - void setStates ( std::set < label::Label > states ) { - accessComponent < States > ( ).set ( std::move ( states ) ); + void setStates ( std::set < StateType > states ) { + this->template accessComponent < States > ( ).set ( std::move ( states ) ); } - void removeState ( const label::Label & state ) { - accessComponent < States > ( ).remove ( state ); + void removeState ( const StateType & state ) { + this->template accessComponent < States > ( ).remove ( state ); } - const std::set < label::Label > & getFinalStates ( ) const { - return accessComponent < FinalStates > ( ).get ( ); + const std::set < StateType > & getFinalStates ( ) const { + return this->template accessComponent < FinalStates > ( ).get ( ); } - bool addFinalState ( label::Label state ) { - return accessComponent < FinalStates > ( ).add ( std::move ( state ) ); + bool addFinalState ( StateType state ) { + return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); } - void setFinalStates ( std::set < label::Label > states ) { - accessComponent < FinalStates > ( ).set ( std::move ( states ) ); + void setFinalStates ( std::set < StateType > states ) { + this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); } - void removeFinalState ( const label::Label & state ) { - accessComponent < FinalStates > ( ).remove ( state ); + void removeFinalState ( const StateType & state ) { + this->template accessComponent < FinalStates > ( ).remove ( state ); } - const std::set < alphabet::Symbol > & getInputAlphabet ( ) const { - return accessComponent < InputAlphabet > ( ).get ( ); + const std::set < SymbolType > & getInputAlphabet ( ) const { + return this->template accessComponent < InputAlphabet > ( ).get ( ); } - bool addInputSymbol ( alphabet::Symbol symbol ) { - return accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); + bool addInputSymbol ( SymbolType symbol ) { + return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); } - void addInputSymbols ( std::set < alphabet::Symbol > symbols ) { - accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); + void addInputSymbols ( std::set < SymbolType > symbols ) { + this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); } - void setInputAlphabet ( std::set < alphabet::Symbol > symbols ) { - accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); + void setInputAlphabet ( std::set < SymbolType > symbols ) { + this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); } - void removeInputSymbol ( const alphabet::Symbol & symbol ) { - accessComponent < InputAlphabet > ( ).remove ( symbol ); + void removeInputSymbol ( const SymbolType & symbol ) { + this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); } /** @@ -115,29 +123,29 @@ public: * @param next next state * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton */ - bool addTransition ( label::Label current, regexp::UnboundedRegExpStructure < alphabet::Symbol > input, label::Label next ); + bool addTransition ( StateType current, regexp::UnboundedRegExpStructure < SymbolType > input, StateType next ); /** * Removes transition from the automaton. * @param transition transition to remove * @throws AutomatonException when transition doesn't exists. */ - bool removeTransition ( const label::Label & current, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & input, const label::Label & next ); + bool removeTransition ( const StateType & current, const regexp::UnboundedRegExpStructure < SymbolType > & input, const StateType & next ); /** * @return automaton transitions */ - const std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & getTransitions ( ) const; + const std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & getTransitions ( ) const; /** * @return automaton transitions from state */ - std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > getTransitionsFromState ( const label::Label & from ) const; + std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > getTransitionsFromState ( const StateType & from ) const; /** * @return automaton transitions to state */ - std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > getTransitionsToState ( const label::Label & from ) const; + std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > getTransitionsToState ( const StateType & from ) const; virtual int compare ( const ObjectBase & other ) const { if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other ); @@ -166,14 +174,245 @@ public: } /* namespace automaton */ +#include "DFA.h" +#include "NFA.h" +#include "CompactNFA.h" +#include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" + +namespace automaton { + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ) : std::Components < ExtendedNFA, SymbolType, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) { +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( StateType initialState ) : ExtendedNFA ( std::set < StateType > { initialState }, std::set < SymbolType > { }, initialState, std::set < StateType > { } ) { +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const CompactNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { + for ( const auto & transition : other.getTransitions ( ) ) { + regexp::UnboundedRegExpConcatenation < SymbolType > con; + + for ( auto & symbol : transition.first.second ) + con.appendElement ( regexp::UnboundedRegExpSymbol < SymbolType > ( symbol ) ); + + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( std::move ( con ) ) ); + transitions[key] = transition.second; + } +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const EpsilonNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { + for ( const auto & transition : other.getTransitions ( ) ) { + if ( transition.first.second.is < string::Epsilon < > > ( ) ) { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( ) ); + transitions[key] = transition.second; + } else { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second.get < SymbolType > ( ) ) ) ); + transitions[key] = transition.second; + } + } +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const MultiInitialStateNFA < > & other ) : ExtendedNFA ( other.getStates ( ) + std::set < StateType > { label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ) }, other.getInputAlphabet ( ), label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ), other.getFinalStates ( ) ) { + for ( const auto & transition : other.getTransitions ( ) ) { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) ); + transitions[key] = transition.second; + } + + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( this->getInitialState ( ), regexp::UnboundedRegExpStructure < SymbolType > ( ) ); + transitions[key] = other.getInitialStates ( ); +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const NFA <> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { + for ( const auto & transition : other.getTransitions ( ) ) { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) ); + transitions[key] = transition.second; + } +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const DFA<> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) { + for ( const auto & transition : other.getTransitions ( ) ) { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) ); + transitions[key].insert ( transition.second ); + } +} + +template<class SymbolType, class StateType > +AutomatonBase * ExtendedNFA < SymbolType, StateType >::clone ( ) const { + return new ExtendedNFA ( * this ); +} + +template<class SymbolType, class StateType > +AutomatonBase * ExtendedNFA < SymbolType, StateType >::plunder ( ) && { + return new ExtendedNFA ( std::move ( * this ) ); +} + +template<class SymbolType, class StateType > +bool ExtendedNFA < SymbolType, StateType >::addTransition ( StateType from, regexp::UnboundedRegExpStructure < SymbolType > input, StateType to ) { + if ( !getStates ( ).count ( from ) ) + throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." ); + + std::set < SymbolType > inputRegExpAlphabet = input.getStructure ( ).computeMinimalAlphabet ( ); + + // Transition regexp's alphabet must be subset of automaton's alphabet + if ( !std::includes ( getInputAlphabet ( ).begin ( ), getInputAlphabet ( ).end ( ), inputRegExpAlphabet.begin ( ), inputRegExpAlphabet.end ( ) ) ) + throw AutomatonException ( "Input string is over different alphabet than automaton" ); + + if ( !getStates ( ).count ( to ) ) + throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." ); + + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( std::move ( from ), std::move ( input ) ); + + return transitions[std::move ( key )].insert ( std::move ( to ) ).second; +} + +template<class SymbolType, class StateType > +bool ExtendedNFA < SymbolType, StateType >::removeTransition ( const StateType & from, const regexp::UnboundedRegExpStructure < SymbolType > & input, const StateType & to ) { + std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( from, input ); + + return transitions[key].erase ( to ); +} + +template<class SymbolType, class StateType > +const std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & ExtendedNFA < SymbolType, StateType >::getTransitions ( ) const { + return transitions; +} + +template<class SymbolType, class StateType > +std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > ExtendedNFA < SymbolType, StateType >::getTransitionsFromState ( const StateType & from ) const { + if ( !getStates ( ).count ( from ) ) + throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist" ); + + std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitionsFromState; + + for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : transitions ) + if ( transition.first.first == from ) + transitionsFromState.insert ( make_pair ( transition.first, transition.second ) ); + + return transitionsFromState; +} + +template<class SymbolType, class StateType > +std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > ExtendedNFA < SymbolType, StateType >::getTransitionsToState ( const StateType & to ) const { + if ( !getStates ( ).count ( to ) ) + throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist" ); + + std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitionsToState; + + for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : transitions ) + if ( transition.second.find ( to ) != transition.second.end ( ) ) + transitionsToState.insert ( make_pair ( transition.first, transition.second ) ); + + return transitionsToState; +} + +template<class SymbolType, class StateType > +int ExtendedNFA < SymbolType, StateType >::compare ( const ExtendedNFA & other ) const { + auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions ); + auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.getTransitions ( ) ); + + std::compare < decltype ( first ) > comp; + + return comp ( first, second ); +} + +template<class SymbolType, class StateType > +void ExtendedNFA < SymbolType, StateType >::operator >>( std::ostream & out ) const { + out << "(ExtendedNFA " + << "states = " << getStates ( ) + << "inputAlphabet = " << getInputAlphabet ( ) + << "initialState = " << getInitialState ( ) + << "finalStates = " << getFinalStates ( ) + << "transitions = " << transitions + << ")"; +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType >::operator std::string ( ) const { + std::stringstream ss; + ss << * this; + return ss.str ( ); +} + +template<class SymbolType, class StateType > +ExtendedNFA < SymbolType, StateType > ExtendedNFA < SymbolType, StateType >::parse ( std::deque < sax::Token >::iterator & input ) { + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, ExtendedNFA::getXmlTagName() ); + + std::set < StateType > states = AutomatonFromXMLParser::parseStates < StateType > ( input ); + std::set < SymbolType > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet < SymbolType > ( input ); + StateType initialState = AutomatonFromXMLParser::parseInitialState < StateType > ( input ); + std::set < StateType > finalStates = AutomatonFromXMLParser::parseFinalStates < StateType > ( input ); + + ExtendedNFA < SymbolType, StateType > automaton ( std::move ( initialState ) ); + + automaton.setStates ( std::move ( states ) ); + automaton.setInputAlphabet ( std::move ( inputSymbols ) ); + automaton.setFinalStates ( std::move ( finalStates ) ); + + AutomatonFromXMLParser::parseTransitions < ExtendedNFA > ( input, automaton ); + + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, ExtendedNFA::getXmlTagName() ); + return automaton; +} + +template<class SymbolType, class StateType > +void ExtendedNFA < SymbolType, StateType >::parseTransition ( std::deque < sax::Token >::iterator & input, ExtendedNFA & automaton ) { + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" ); + StateType from = AutomatonFromXMLParser::parseTransitionFrom < StateType > ( input ); + regexp::UnboundedRegExpStructure < SymbolType > inputRegexp = AutomatonFromXMLParser::parseTransitionInputRegexp < SymbolType > ( input ); + StateType to = AutomatonFromXMLParser::parseTransitionTo < StateType > ( input ); + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "transition" ); + + automaton.addTransition ( std::move ( from ), std::move ( inputRegexp ), std::move ( to ) ); +} + +template<class SymbolType, class StateType > +void ExtendedNFA < SymbolType, StateType >::compose ( std::deque < sax::Token > & out ) const { + out.emplace_back ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::START_ELEMENT ); + + AutomatonToXMLComposer::composeStates ( out, this->getStates ( ) ); + AutomatonToXMLComposer::composeInputAlphabet ( out, this->getInputAlphabet ( ) ); + AutomatonToXMLComposer::composeInitialState ( out, this->getInitialState ( ) ); + AutomatonToXMLComposer::composeFinalStates ( out, this->getFinalStates ( ) ); + composeTransitions ( out ); + + out.emplace_back ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT ); +} + +template<class SymbolType, class StateType > +void ExtendedNFA < SymbolType, StateType >::composeTransitions ( std::deque < sax::Token > & out ) const { + out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT ); + + for ( const auto & transition : this->getTransitions ( ) ) + for ( const auto & targetState : transition.second ) { + out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT ); + + AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first ); + AutomatonToXMLComposer::composeTransitionInputRegexp ( out, transition.first.second ); + AutomatonToXMLComposer::composeTransitionTo ( out, targetState ); + + out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT ); + } + + out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT ); +} + +} /* namespace automaton */ + namespace std { -template < > -class ComponentConstraint< automaton::ExtendedNFA, alphabet::Symbol, automaton::InputAlphabet > { +template<class SymbolType, class StateType > +class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > { public: - static bool used ( const automaton::ExtendedNFA & automaton, const alphabet::Symbol & symbol ) { - for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : automaton.getTransitions ( ) ) { - std::set < alphabet::Symbol > alphabet = transition.first.second.getStructure ( ).computeMinimalAlphabet ( ); + static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) { + for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : automaton.getTransitions ( ) ) { + std::set < SymbolType > alphabet = transition.first.second.getStructure ( ).computeMinimalAlphabet ( ); if ( alphabet.count ( symbol ) ) return true; } @@ -181,62 +420,62 @@ public: return false; } - static bool available ( const automaton::ExtendedNFA &, const alphabet::Symbol & ) { + static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) { return true; } - static void valid ( const automaton::ExtendedNFA &, const alphabet::Symbol & ) { + static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) { } }; -template < > -class ComponentConstraint< automaton::ExtendedNFA, label::Label, automaton::States > { +template<class SymbolType, class StateType > +class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::States > { public: - static bool used ( const automaton::ExtendedNFA & automaton, const label::Label & state ) { + static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { if ( automaton.getInitialState ( ) == state ) return true; if ( automaton.getFinalStates ( ).count ( state ) ) return true; - for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : automaton.getTransitions ( ) ) + for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : automaton.getTransitions ( ) ) if ( ( transition.first.first == state ) || ( transition.second.find ( state ) != transition.second.end ( ) ) ) return true; return false; } - static bool available ( const automaton::ExtendedNFA &, const label::Label & ) { + static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { return true; } - static void valid ( const automaton::ExtendedNFA &, const label::Label & ) { + static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; -template < > -class ComponentConstraint< automaton::ExtendedNFA, label::Label, automaton::FinalStates > { +template<class SymbolType, class StateType > +class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::FinalStates > { public: - static bool used ( const automaton::ExtendedNFA &, const label::Label & ) { + static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { return false; } - static bool available ( const automaton::ExtendedNFA & automaton, const label::Label & state ) { - return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state ); + static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { + return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } - static void valid ( const automaton::ExtendedNFA &, const label::Label & ) { + static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; -template < > -class ElementConstraint< automaton::ExtendedNFA, label::Label, automaton::InitialState > { +template<class SymbolType, class StateType > +class ElementConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::InitialState > { public: - static bool available ( const automaton::ExtendedNFA & automaton, const label::Label & state ) { - return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state ); + static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) { + return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); } - static void valid ( const automaton::ExtendedNFA &, const label::Label & ) { + static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) { } }; diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp index be37250b6b..837d74bd24 100644 --- a/alib2data/test-src/automaton/AutomatonTest.cpp +++ b/alib2data/test-src/automaton/AutomatonTest.cpp @@ -153,7 +153,7 @@ void AutomatonTest::DPDATransitions() { } void AutomatonTest::testExtendedNFAAlphabet() { - automaton::ExtendedNFA automaton (label::labelFrom(0)); + automaton::ExtendedNFA < > automaton (label::labelFrom(0)); label::Label s0 = label::labelFrom(0); label::Label s1 = label::labelFrom(1); automaton.addState(s0); diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp index 1f2b3181ba..ac6e066589 100644 --- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp +++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp @@ -94,7 +94,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA<>>(AllEpsilonClosure::allEpsilonClosure); -std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA & fsm) { +std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < > & fsm) { std::map<label::Label, std::set<label::Label>> res; for(const label::Label& state : fsm.getStates()) @@ -121,7 +121,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos return res; } -auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA>(AllEpsilonClosure::allEpsilonClosure); +auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA < > >(AllEpsilonClosure::allEpsilonClosure); std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < > & fsm) { std::map<label::Label, std::set<label::Label>> res; diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h index 4b5ecbf867..a0e51e4af1 100644 --- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h +++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h @@ -34,7 +34,7 @@ public: static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::MultiInitialStateNFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::DFA < > & fsm); - static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA & fsm); + static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA < > & fsm); static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::CompactNFA < > & fsm); }; diff --git a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp index 3356f62823..9fb30fc6b1 100644 --- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp +++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp @@ -52,7 +52,7 @@ std::set<label::Label> ReachableStates::reachableStates( const T & fsm ) { auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(ReachableStates::reachableStates); auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(ReachableStates::reachableStates); auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(ReachableStates::reachableStates); -auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates); +auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates); template<> std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) { diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp index d922e099ad..4804bd174c 100644 --- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp +++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp @@ -53,7 +53,7 @@ std::set<label::Label> UsefullStates::usefullStates( const T & fsm ) { auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(UsefullStates::usefullStates); auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(UsefullStates::usefullStates); auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(UsefullStates::usefullStates); -auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(UsefullStates::usefullStates); +auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(UsefullStates::usefullStates); auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA < >>(UsefullStates::usefullStates); template<> diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp index a638881a29..9ac969dbd7 100644 --- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp @@ -33,7 +33,7 @@ auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > auto TrimMultiInitialStateNFA = Trim::RegistratorWrapper<automaton::MultiInitialStateNFA < >, automaton::MultiInitialStateNFA < >>(Trim::trim); auto TrimEpsilonNFA = Trim::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(Trim::trim); auto TrimCompactNFA = Trim::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(Trim::trim); -auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(Trim::trim); +auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(Trim::trim); automaton::Automaton Trim::trim(const automaton::Automaton& automaton) { return dispatch(automaton.getData()); diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp index c7f6b19eb2..4ea8ef0b67 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp @@ -54,7 +54,7 @@ T UnreachableStatesRemover::remove( const T & fsm ) { auto UnreachableStatesRemoverEpsilonNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(UnreachableStatesRemover::remove); auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UnreachableStatesRemover::remove); auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UnreachableStatesRemover::remove); -auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove); +auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UnreachableStatesRemover::remove); template<> automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) { diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp index e87376c701..40dae88f1e 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp @@ -56,7 +56,7 @@ T UselessStatesRemover::remove( const T & fsm ) { auto UselessStatesRemoverEpsilonNFA = UselessStatesRemover::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(UselessStatesRemover::remove); auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UselessStatesRemover::remove); auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UselessStatesRemover::remove); -auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove); +auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UselessStatesRemover::remove); template<> automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) { -- GitLab