diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp index 95bd5ee7bba5504d0600afed47c04836fd3433c4..704657ba66f6abfa49e182605af15c4a41212be1 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp @@ -15,20 +15,46 @@ automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& a return dispatch(automaton.getData()); } -template<class T> -automaton::NFA < > AutomatonIteration::iteration(const T& automaton) { +automaton::NFA < > AutomatonIteration::iteration(const automaton::DFA < > & automaton) { automaton::NFA < > res(automaton); for(const auto& qf : res.getFinalStates()) for(const auto& t : res.getTransitionsToState(qf)) res.addTransition(t.first.first, t.first.second, res.getInitialState()); - res.addFinalState(automaton.getInitialState()); + label::Label newInitialState = label::createUniqueLabel(automaton.getInitialState(), automaton.getStates()); + res.addState(newInitialState); + res.setInitialState(newInitialState); + res.addFinalState(newInitialState); + + for(const auto& t : automaton.getTransitionsFromState(automaton.getInitialState())) + res.addTransition(newInitialState, t.first.second, t.second); + + return res; +} + +auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper < automaton::NFA < >, automaton::DFA < > > ( AutomatonIteration::iteration ); + +automaton::NFA < > AutomatonIteration::iteration(const automaton::NFA < > & automaton) { + automaton::NFA < > res(automaton); + + for(const auto& qf : res.getFinalStates()) + for(const auto& t : res.getTransitionsToState(qf)) + res.addTransition(t.first.first, t.first.second, res.getInitialState()); + + label::Label newInitialState = label::createUniqueLabel(automaton.getInitialState(), automaton.getStates()); + res.addState(newInitialState); + res.setInitialState(newInitialState); + res.addFinalState(newInitialState); + + for(const auto& t : automaton.getTransitionsFromState(automaton.getInitialState())) + for (const label::Label & toState : t.second ) + res.addTransition(newInitialState, t.first.second, toState); + return res; } -auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper<automaton::NFA < > , automaton::DFA<>>(AutomatonIteration::iteration); -auto AutomatonIterationNFA = AutomatonIteration::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomatonIteration::iteration); +auto AutomatonIterationNFA = AutomatonIteration::RegistratorWrapper < automaton::NFA < >, automaton::NFA < > > (AutomatonIteration::iteration); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h index 5ae24fb04dc9ce6b0949afce0d6d4b601d5ddc8d..e05ef2e1f639ebf04367a192e617352416c9663d 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.h +++ b/alib2algo/src/automaton/transform/AutomatonIteration.h @@ -24,8 +24,8 @@ class AutomatonIteration : public std::SingleDispatch<AutomatonIteration, automa public: static automaton::Automaton iteration(const automaton::Automaton& automaton); - template<class T> - static automaton::NFA < > iteration(const T& automaton); + static automaton::NFA < > iteration(const automaton::DFA < > & automaton); + static automaton::NFA < > iteration(const automaton::NFA < > & automaton); }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp index d222a412626bc462501a7d220ec14383bd07e8e5..d73327dcce1656dcef66ef8137805d2b3e6c4e87 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp @@ -22,7 +22,12 @@ automaton::EpsilonNFA < > AutomatonIterationEpsilonTransition::iteration(const T for(const auto&q : automaton.getFinalStates()) res.addTransition(q, automaton.getInitialState()); - res.addFinalState(automaton.getInitialState()); + label::Label newInitialState = label::createUniqueLabel(automaton.getInitialState(), automaton.getStates()); + res.addState(newInitialState); + res.setInitialState(newInitialState); + res.addFinalState(newInitialState); + + res.addTransition(newInitialState, automaton.getInitialState()); return res; } diff --git a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp index d059e5cfa020eaa509383d560777cf5fd7ff7d47..20bfd484f212a845616dc5d48a3b8f723cae38c5 100644 --- a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp +++ b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp @@ -25,27 +25,34 @@ void AutomatonIterationTest::tearDown() { void AutomatonIterationTest::testAutomatonIteration() { // Melichar 2.83 + label::Label q0 = label::labelFrom(0); label::Label q1 = label::labelFrom(1); label::Label q2 = label::labelFrom(2); label::Label q3 = label::labelFrom(3); - alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b')); + alphabet::Symbol a = alphabet::symbolFrom('a'); + alphabet::Symbol b = alphabet::symbolFrom('b'); - automaton::DFA<> m1(q1); + automaton::DFA < > m1(q1); m1.setStates({q1, q2, q3}); m1.addFinalState(q3); m1.setInputAlphabet({a, b}); m1.addTransition(q1, a, q2); m1.addTransition(q2, b, q2); m1.addTransition(q2, a, q3); + m1.addTransition(q3, a, q1); - automaton::NFA < > res(q1); - res.setStates({q1, q2, q3}); + automaton::EpsilonNFA < > res(q0); + res.setStates({q0, q1, q2, q3}); res.setInputAlphabet({a, b}); - res.setFinalStates({q1, q3}); + res.setFinalStates({q0, q3}); + res.addTransition(q1, a, q2); res.addTransition(q2, b, q2); res.addTransition(q2, a, q3); - res.addTransition(q2, a, q1); + res.addTransition(q3, a, q1); + + res.addTransition(q0, q1); + res.addTransition(q3, q1); automaton::Automaton i2 = automaton::transform::AutomatonIterationEpsilonTransition::iteration(automaton::Automaton(m1)); automaton::Automaton i1 = automaton::transform::AutomatonIteration::iteration(automaton::Automaton(m1));