From 5536dd20d0c981b96fe62fe4133a68430847803e Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 25 Oct 2016 15:58:58 +0200 Subject: [PATCH] fix iteration of automata --- .../transform/AutomatonIteration.cpp | 36 ++++++++++++++++--- .../automaton/transform/AutomatonIteration.h | 4 +-- .../AutomatonIterationEpsilonTransition.cpp | 7 +++- .../transform/AutomatonIterationTest.cpp | 19 ++++++---- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp index 95bd5ee7bb..704657ba66 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 5ae24fb04d..e05ef2e1f6 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 d222a41262..d73327dcce 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 d059e5cfa0..20bfd484f2 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)); -- GitLab