diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp index 517384911eda043dbe762d8f2eaeaf11e9f3996c..14419a6a81342259edadb3eeb416d6ed2458b560 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp @@ -8,9 +8,6 @@ #include "AutomataConcatenation.h" #include <label/Label.h> -#define AUTOMATON_FIRST (label::Label(1)) -#define AUTOMATON_SECOND (label::Label(2)) - namespace automaton { namespace transform { @@ -19,94 +16,8 @@ automaton::Automaton AutomataConcatenation::concatenation(const automaton::Autom return dispatch(first.getData(), second.getData()); } -automaton::NFA < > AutomataConcatenation::concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second) { - label::Label q01q02(first.getInitialState(), second.getInitialState()); - automaton::NFA < > res(label::Label(AUTOMATON_FIRST, first.getInitialState())); - - for(const auto& q : first.getStates()) - res.addState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - res.addState(label::Label(AUTOMATON_SECOND, q)); - res.addState(q01q02); - - for(const auto& symbol : first.getInputAlphabet()) - res.addInputSymbol(symbol); - for(const auto& symbol : second.getInputAlphabet()) - res.addInputSymbol(symbol); - - if(first.getFinalStates().count(first.getInitialState()) > 0) - res.setInitialState(q01q02); - - for(const auto& t : first.getTransitions()) { - for(const auto& q : t.second) { - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, q)); - - if(first.getFinalStates().count(q) > 0) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, second.getInitialState())); - } - } - for(const auto& t : second.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, q)); - - for(const auto& t : first.getTransitionsFromState(first.getInitialState())) - for(const auto& q : t.second) - res.addTransition(q01q02, t.first.second, label::Label(AUTOMATON_FIRST, q)); - for(const auto& t : second.getTransitionsFromState(second.getInitialState())) - for(const auto& q : t.second) - res.addTransition(q01q02, t.first.second, label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - if(first.getFinalStates().count(first.getInitialState()) > 0) - res.addFinalState(q01q02); - - return res; -} - auto AutomataConcatenationNFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataConcatenation::concatenation); - -automaton::NFA < > AutomataConcatenation::concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second) { - label::Label q01q02(first.getInitialState(), second.getInitialState()); - automaton::NFA < > res(label::Label(AUTOMATON_FIRST, first.getInitialState())); - - for(const auto& q : first.getStates()) - res.addState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - res.addState(label::Label(AUTOMATON_SECOND, q)); - res.addState(q01q02); - - for(const auto& symbol : first.getInputAlphabet()) - res.addInputSymbol(symbol); - for(const auto& symbol : second.getInputAlphabet()) - res.addInputSymbol(symbol); - - if(first.getFinalStates().count(first.getInitialState()) > 0) - res.setInitialState(q01q02); - - for(const auto& t : first.getTransitions()) { - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, t.second)); - - if(first.getFinalStates().count(t.second) > 0) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, second.getInitialState())); - } - for(const auto& t : second.getTransitions()) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, t.second)); - - for(const auto& t : first.getTransitionsFromState(first.getInitialState())) - res.addTransition(q01q02, t.first.second, label::Label(AUTOMATON_FIRST, t.second)); - for(const auto& t : second.getTransitionsFromState(second.getInitialState())) - res.addTransition(q01q02, t.first.second, label::Label(AUTOMATON_SECOND, t.second)); - - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - if(first.getFinalStates().count(first.getInitialState()) > 0) - res.addFinalState(q01q02); - - return res; -} - -auto AutomataConcatenationDFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA < > , automaton::DFA<>>(AutomataConcatenation::concatenation); +auto AutomataConcatenationDFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA < > , automaton::DFA < > >(AutomataConcatenation::concatenation); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.h b/alib2algo/src/automaton/transform/AutomataConcatenation.h index 49640f6a6ef6f62a3ecbd7f98de7face3de8e5bc..faf1924ee0ef91a7e58081086f18dd672499c70e 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h @@ -24,10 +24,105 @@ class AutomataConcatenation : public std::PromotingDoubleDispatch<AutomataConcat public: static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second); - static automaton::NFA < > concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second); - static automaton::NFA < > concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second); + template < class SymbolType, class StateType > + static automaton::NFA < SymbolType, StateType > concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second); + template < class SymbolType, class StateType > + static automaton::NFA < SymbolType, StateType > concatenation(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second); }; +template < class SymbolType, class StateType > +automaton::NFA < SymbolType, StateType > AutomataConcatenation::concatenation(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + label::Label q01q02(first.getInitialState(), second.getInitialState()); + automaton::NFA < SymbolType, StateType > res(label::Label(firstDefault, first.getInitialState())); + + for(const auto& q : first.getStates()) + res.addState(label::Label(firstDefault, q)); + for(const auto& q : second.getStates()) + res.addState(label::Label(secondDefault, q)); + res.addState(q01q02); + + for(const auto& symbol : first.getInputAlphabet()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + if(first.getFinalStates().count(first.getInitialState()) > 0) + res.setInitialState(q01q02); + + for(const auto& t : first.getTransitions()) { + for(const auto& q : t.second) { + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(firstDefault, q)); + + if(first.getFinalStates().count(q) > 0) + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(secondDefault, second.getInitialState())); + } + } + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(label::Label(secondDefault, t.first.first), t.first.second, label::Label(secondDefault, q)); + + for(const auto& t : first.getTransitionsFromState(first.getInitialState())) + for(const auto& q : t.second) + res.addTransition(q01q02, t.first.second, label::Label(firstDefault, q)); + for(const auto& t : second.getTransitionsFromState(second.getInitialState())) + for(const auto& q : t.second) + res.addTransition(q01q02, t.first.second, label::Label(secondDefault, q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(label::Label(secondDefault, q)); + if(first.getFinalStates().count(first.getInitialState()) > 0) + res.addFinalState(q01q02); + + return res; +} + +template < class SymbolType, class StateType > +automaton::NFA < SymbolType, StateType > AutomataConcatenation::concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + label::Label q01q02(first.getInitialState(), second.getInitialState()); + automaton::NFA < SymbolType, StateType > res(label::Label(firstDefault, first.getInitialState())); + + for(const auto& q : first.getStates()) + res.addState(label::Label(firstDefault, q)); + for(const auto& q : second.getStates()) + res.addState(label::Label(secondDefault, q)); + res.addState(q01q02); + + for(const auto& symbol : first.getInputAlphabet()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + if(first.getFinalStates().count(first.getInitialState()) > 0) + res.setInitialState(q01q02); + + for(const auto& t : first.getTransitions()) { + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(firstDefault, t.second)); + + if(first.getFinalStates().count(t.second) > 0) + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(secondDefault, second.getInitialState())); + } + for(const auto& t : second.getTransitions()) + res.addTransition(label::Label(secondDefault, t.first.first), t.first.second, label::Label(secondDefault, t.second)); + + for(const auto& t : first.getTransitionsFromState(first.getInitialState())) + res.addTransition(q01q02, t.first.second, label::Label(firstDefault, t.second)); + for(const auto& t : second.getTransitionsFromState(second.getInitialState())) + res.addTransition(q01q02, t.first.second, label::Label(secondDefault, t.second)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(label::Label(secondDefault, q)); + if(first.getFinalStates().count(first.getInitialState()) > 0) + res.addFinalState(q01q02); + + return res; +} + } /* namespace transform */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp index 508b5b5f4177f163e274ced02773242a34fdf28a..6b1ea09622096cb24fa3d2d6bcfd5fcd2407c70c 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp @@ -8,9 +8,6 @@ #include "AutomataConcatenationEpsilonTransition.h" #include <label/Label.h> -#define AUTOMATON_FIRST (label::Label(1)) -#define AUTOMATON_SECOND (label::Label(2)) - namespace automaton { namespace transform { @@ -19,98 +16,8 @@ automaton::Automaton AutomataConcatenationEpsilonTransition::concatenation(const return dispatch(first.getData(), second.getData()); } -automaton::EpsilonNFA < > AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second) { - automaton::EpsilonNFA < > res(label::Label(AUTOMATON_FIRST, first.getInitialState())); - - for(const auto& symbol : first.getInputAlphabet()) - res.addInputSymbol(symbol); - for(const auto& symbol : second.getInputAlphabet()) - res.addInputSymbol(symbol); - - for(const auto& q : first.getStates()) - res.addState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - res.addState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& t : first.getTransitions()) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, t.second)); - - for(const auto& t : second.getTransitions()) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, t.second)); - - for(const auto& q : first.getFinalStates()) - res.addTransition(label::Label(AUTOMATON_FIRST, q), label::Label(AUTOMATON_SECOND, second.getInitialState())); - - return res; -} - -auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA<>>(AutomataConcatenationEpsilonTransition::concatenation); - -automaton::EpsilonNFA < > AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second) { - automaton::EpsilonNFA < > res(label::Label(AUTOMATON_FIRST, first.getInitialState())); - - for(const auto& symbol : first.getInputAlphabet()) - res.addInputSymbol(symbol); - for(const auto& symbol : second.getInputAlphabet()) - res.addInputSymbol(symbol); - - for(const auto& q : first.getStates()) - res.addState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - res.addState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& t : first.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, q)); - - for(const auto& t : second.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : first.getFinalStates()) - res.addTransition(label::Label(AUTOMATON_FIRST, q), label::Label(AUTOMATON_SECOND, second.getInitialState())); - - return res; -} - +auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA < > >(AutomataConcatenationEpsilonTransition::concatenation); auto AutomataConcatenationEpsilonTransitionNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::NFA < > >(AutomataConcatenationEpsilonTransition::concatenation); - -automaton::EpsilonNFA < > AutomataConcatenationEpsilonTransition::concatenation(const automaton::EpsilonNFA < > & first, const automaton::EpsilonNFA < > & second) { - automaton::EpsilonNFA < > res(label::Label(AUTOMATON_FIRST, first.getInitialState())); - - for(const auto& symbol : first.getInputAlphabet()) - res.addInputSymbol(symbol); - for(const auto& symbol : second.getInputAlphabet()) - res.addInputSymbol(symbol); - - for(const auto& q : first.getStates()) - res.addState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - res.addState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - for(const auto& t : first.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, q)); - - for(const auto& t : second.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, q)); - - for(const auto& q : first.getFinalStates()) - res.addTransition(label::Label(AUTOMATON_FIRST, q), label::Label(AUTOMATON_SECOND, second.getInitialState())); - - return res; -} - auto AutomataConcatenationEpsilonTransitionEpsilonNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < > , automaton::EpsilonNFA < > >(AutomataConcatenationEpsilonTransition::concatenation); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h index f7065803f0600b33c4af95219927d04fcd06901a..fb56b4a46bcedcce89ef3c4acfdc33151d9f2c21 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h @@ -24,11 +24,114 @@ class AutomataConcatenationEpsilonTransition : public std::PromotingDoubleDispat public: static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second); - static automaton::EpsilonNFA < > concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second); - static automaton::EpsilonNFA < > concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second); - static automaton::EpsilonNFA < > concatenation(const automaton::EpsilonNFA < > & first, const automaton::EpsilonNFA < > & second); + template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second); + template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > concatenation(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second); + template < class SymbolType, class EpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > concatenation(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & first, const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & second); }; +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(label::Label(firstDefault, first.getInitialState())); + + for(const auto& symbol : first.getInputAlphabet()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(label::Label(firstDefault, q)); + for(const auto& q : second.getStates()) + res.addState(label::Label(secondDefault, q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(label::Label(secondDefault, q)); + + for(const auto& t : first.getTransitions()) + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(firstDefault, t.second)); + + for(const auto& t : second.getTransitions()) + res.addTransition(label::Label(secondDefault, t.first.first), t.first.second, label::Label(secondDefault, t.second)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(label::Label(firstDefault, q), label::Label(secondDefault, second.getInitialState())); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(label::Label(firstDefault, first.getInitialState())); + + for(const auto& symbol : first.getInputAlphabet()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(label::Label(firstDefault, q)); + for(const auto& q : second.getStates()) + res.addState(label::Label(secondDefault, q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(label::Label(secondDefault, q)); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(firstDefault, q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(label::Label(secondDefault, t.first.first), t.first.second, label::Label(secondDefault, q)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(label::Label(firstDefault, q), label::Label(secondDefault, second.getInitialState())); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataConcatenationEpsilonTransition::concatenation(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & first, const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(label::Label(firstDefault, first.getInitialState())); + + for(const auto& symbol : first.getInputAlphabet()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(label::Label(firstDefault, q)); + for(const auto& q : second.getStates()) + res.addState(label::Label(secondDefault, q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(label::Label(secondDefault, q)); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(label::Label(firstDefault, t.first.first), t.first.second, label::Label(firstDefault, q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(label::Label(secondDefault, t.first.first), t.first.second, label::Label(secondDefault, q)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(label::Label(firstDefault, q), label::Label(secondDefault, second.getInitialState())); + + return res; +} + } /* namespace transform */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp index 6f886e6732187cb2400ef8dbba4cde4513b80ae2..bba6f9ceec573818a32858b3b347ecae3eb763b4 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp @@ -9,9 +9,6 @@ #include <label/InitialStateLabel.h> #include <common/createUnique.hpp> -#define AUTOMATON_FIRST (label::Label(1)) -#define AUTOMATON_SECOND (label::Label(2)) - namespace automaton { namespace transform { @@ -20,120 +17,9 @@ automaton::Automaton AutomataUnionEpsilonTransition::unification(const automaton return dispatch(first.getData(), second.getData()); } -automaton::EpsilonNFA < > AutomataUnionEpsilonTransition::unification(const automaton::EpsilonNFA < > & first, const automaton::EpsilonNFA < > & second) { - std::set<label::Label> states; - for(const auto& q : first.getStates()) - states.insert(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - states.insert(label::Label(AUTOMATON_SECOND, q)); - - label::Label q0 = common::createUnique(label::InitialStateLabel::instance < label::Label > ( ), states); - automaton::EpsilonNFA < > res(q0); - - for(const auto& a : first.getInputAlphabet()) - res.addInputSymbol(a); - for(const auto& a : second.getInputAlphabet()) - res.addInputSymbol(a); - - for(const auto& q : states) - res.addState(q); - - for(const auto& q : first.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - res.addTransition(q0, label::Label(AUTOMATON_FIRST, first.getInitialState())); - res.addTransition(q0, label::Label(AUTOMATON_SECOND, second.getInitialState())); - - for(const auto& t : first.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, q)); - - for(const auto& t : second.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, q)); - - return res; -} - auto AutomataUnionEpsilonTransitionEpsilonNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(AutomataUnionEpsilonTransition::unification); - -automaton::EpsilonNFA < > AutomataUnionEpsilonTransition::unification(const automaton::NFA < > & first, const automaton::NFA < > & second) { - std::set<label::Label> states; - for(const auto& q : first.getStates()) - states.insert(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - states.insert(label::Label(AUTOMATON_SECOND, q)); - - label::Label q0 = common::createUnique(label::InitialStateLabel::instance < label::Label > ( ), states); - automaton::EpsilonNFA < > res(q0); - - for(const auto& a : first.getInputAlphabet()) - res.addInputSymbol(a); - for(const auto& a : second.getInputAlphabet()) - res.addInputSymbol(a); - - for(const auto& q : states) - res.addState(q); - - for(const auto& q : first.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - res.addTransition(q0, label::Label(AUTOMATON_FIRST, first.getInitialState())); - res.addTransition(q0, label::Label(AUTOMATON_SECOND, second.getInitialState())); - - for(const auto& t : first.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, q)); - - for(const auto& t : second.getTransitions()) - for(const auto& q : t.second) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, q)); - - return res; -} - auto AutomataUnionEpsilonTransitionNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::NFA < > >(AutomataUnionEpsilonTransition::unification); - -automaton::EpsilonNFA < > AutomataUnionEpsilonTransition::unification(const automaton::DFA<>& first, const automaton::DFA<>& second) { - std::set<label::Label> states; - for(const auto& q : first.getStates()) - states.insert(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getStates()) - states.insert(label::Label(AUTOMATON_SECOND, q)); - - label::Label q0 = common::createUnique(label::InitialStateLabel::instance < label::Label > ( ), states); - automaton::EpsilonNFA < > res(q0); - - for(const auto& a : first.getInputAlphabet()) - res.addInputSymbol(a); - for(const auto& a : second.getInputAlphabet()) - res.addInputSymbol(a); - - for(const auto& q : states) - res.addState(q); - - for(const auto& q : first.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_FIRST, q)); - for(const auto& q : second.getFinalStates()) - res.addFinalState(label::Label(AUTOMATON_SECOND, q)); - - res.addTransition(q0, label::Label(AUTOMATON_FIRST, first.getInitialState())); - res.addTransition(q0, label::Label(AUTOMATON_SECOND, second.getInitialState())); - - for(const auto& t : first.getTransitions()) - res.addTransition(label::Label(AUTOMATON_FIRST, t.first.first), t.first.second, label::Label(AUTOMATON_FIRST, t.second)); - - for(const auto& t : second.getTransitions()) - res.addTransition(label::Label(AUTOMATON_SECOND, t.first.first), t.first.second, label::Label(AUTOMATON_SECOND, t.second)); - - return res; -} - -auto AutomataUnionEpsilonTransitionDFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA<>>(AutomataUnionEpsilonTransition::unification); +auto AutomataUnionEpsilonTransitionDFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA < > >(AutomataUnionEpsilonTransition::unification); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h index b70d21fe1d3b787f6b15e5e16ef43fdd8fb79df4..372eea4b9b96f947d19ebe9fe37b9fa16f6caf41 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h @@ -24,12 +24,136 @@ class AutomataUnionEpsilonTransition : public std::PromotingDoubleDispatch<Autom public: static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second); - static automaton::EpsilonNFA < > unification(const automaton::EpsilonNFA < > & first, const automaton::EpsilonNFA < > & second); - static automaton::EpsilonNFA < > unification(const automaton::NFA < > & first, const automaton::NFA < > & second); - static automaton::EpsilonNFA < > unification(const automaton::DFA<>& first, const automaton::DFA<>& second); + template < class SymbolType, class EpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > unification(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & first, const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & second); + template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > unification(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second); + template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > unification(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second); }; +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataUnionEpsilonTransition::unification(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & first, const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + std::set<StateType> states; + for(const auto& q : first.getStates()) + states.insert(StateType(firstDefault, q)); + for(const auto& q : second.getStates()) + states.insert(StateType(secondDefault, q)); + + StateType q0 = common::createUnique(label::InitialStateLabel::instance < StateType > ( ), states); + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(StateType(firstDefault, q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(StateType(secondDefault, q)); + + res.addTransition(q0, StateType(firstDefault, first.getInitialState())); + res.addTransition(q0, StateType(secondDefault, second.getInitialState())); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(StateType(firstDefault, t.first.first), t.first.second, StateType(firstDefault, q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(StateType(secondDefault, t.first.first), t.first.second, StateType(secondDefault, q)); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataUnionEpsilonTransition::unification(const automaton::NFA < SymbolType, StateType > & first, const automaton::NFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + std::set<StateType> states; + for(const auto& q : first.getStates()) + states.insert(StateType(firstDefault, q)); + for(const auto& q : second.getStates()) + states.insert(StateType(secondDefault, q)); + + StateType q0 = common::createUnique(label::InitialStateLabel::instance < StateType > ( ), states); + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(StateType(firstDefault, q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(StateType(secondDefault, q)); + + res.addTransition(q0, StateType(firstDefault, first.getInitialState())); + res.addTransition(q0, StateType(secondDefault, second.getInitialState())); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(StateType(firstDefault, t.first.first), t.first.second, StateType(firstDefault, q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(StateType(secondDefault, t.first.first), t.first.second, StateType(secondDefault, q)); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomataUnionEpsilonTransition::unification(const automaton::DFA< SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second) { + static StateType firstDefault ( 1 ); + static StateType secondDefault ( 2 ); + + std::set<StateType> states; + for(const auto& q : first.getStates()) + states.insert(StateType(firstDefault, q)); + for(const auto& q : second.getStates()) + states.insert(StateType(secondDefault, q)); + + StateType q0 = common::createUnique(label::InitialStateLabel::instance < StateType > ( ), states); + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(StateType(firstDefault, q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(StateType(secondDefault, q)); + + res.addTransition(q0, StateType(firstDefault, first.getInitialState())); + res.addTransition(q0, StateType(secondDefault, second.getInitialState())); + + for(const auto& t : first.getTransitions()) + res.addTransition(StateType(firstDefault, t.first.first), t.first.second, StateType(firstDefault, t.second)); + + for(const auto& t : second.getTransitions()) + res.addTransition(StateType(secondDefault, t.first.first), t.first.second, StateType(secondDefault, t.second)); + + return res; +} + } /* namespace transform */ } /* namespace automaton */