diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp index b298142286c9d6eccdaaae4c109f8305aac8e2e3..c079d65a95b789a84b9011c81a6925587e0064ab 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp @@ -16,45 +16,7 @@ automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& a return dispatch(automaton.getData()); } -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()); - - label::Label newInitialState = common::createUnique(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 = common::createUnique(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 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 e05ef2e1f639ebf04367a192e617352416c9663d..813ad6aadb3f0a1d2550e5e5da4ed7f5f2658831 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.h +++ b/alib2algo/src/automaton/transform/AutomatonIteration.h @@ -24,10 +24,51 @@ class AutomatonIteration : public std::SingleDispatch<AutomatonIteration, automa public: static automaton::Automaton iteration(const automaton::Automaton& automaton); - static automaton::NFA < > iteration(const automaton::DFA < > & automaton); - static automaton::NFA < > iteration(const automaton::NFA < > & automaton); + template < class SymbolType, class StateType > + static automaton::NFA < SymbolType, StateType > iteration(const automaton::DFA < SymbolType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::NFA < SymbolType, StateType > iteration(const automaton::NFA < SymbolType, StateType > & automaton); }; +template < class SymbolType, class StateType > +automaton::NFA < SymbolType, StateType > AutomatonIteration::iteration(const automaton::DFA < SymbolType, StateType > & automaton) { + automaton::NFA < SymbolType, StateType > 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()); + + StateType newInitialState = common::createUnique(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; +} + +template < class SymbolType, class StateType > +automaton::NFA < SymbolType, StateType > AutomatonIteration::iteration(const automaton::NFA < SymbolType, StateType > & automaton) { + automaton::NFA < SymbolType, StateType > 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()); + + StateType newInitialState = common::createUnique(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; +} + } /* namespace transform */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp index c0a49d1f1bdd4e06819fa010cf601ef8f22882c9..67d92430aec788a503b8a11116d334d2d1a5d26f 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp @@ -16,23 +16,7 @@ automaton::Automaton AutomatonIterationEpsilonTransition::iteration(const automa return dispatch(automaton.getData()); } -template<class T> -automaton::EpsilonNFA < > AutomatonIterationEpsilonTransition::iteration(const T& automaton) { - automaton::EpsilonNFA < > res(automaton); - - for(const auto&q : automaton.getFinalStates()) - res.addTransition(q, automaton.getInitialState()); - - label::Label newInitialState = common::createUnique(automaton.getInitialState(), automaton.getStates()); - res.addState(newInitialState); - res.setInitialState(newInitialState); - res.addFinalState(newInitialState); - - res.addTransition(newInitialState, automaton.getInitialState()); - return res; -} - -auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA<>>(AutomatonIterationEpsilonTransition::iteration); +auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::DFA < > >(AutomatonIterationEpsilonTransition::iteration); auto AutomatonIterationEpsilonTransitionNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::NFA < > >(AutomatonIterationEpsilonTransition::iteration); auto AutomatonIterationEpsilonTransitionEpsilonNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(AutomatonIterationEpsilonTransition::iteration); diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h index adfe609d41815c9ebfdee346f29e5fae9511467f..7615e25e1e23797041141c15f53ae94f37e7278c 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h @@ -24,10 +24,26 @@ class AutomatonIterationEpsilonTransition : public std::SingleDispatch<Automaton public: static automaton::Automaton iteration(const automaton::Automaton& automaton); - template<class T> - static automaton::EpsilonNFA < > iteration(const T& automaton); + template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class EpsilonType = DefaultEpsilonType, class StateType = typename automaton::StateTypeOfAutomaton < T > > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > iteration(const T& automaton); }; +template < class T, class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > AutomatonIterationEpsilonTransition::iteration(const T& automaton) { + automaton::EpsilonNFA < > res(automaton); + + for(const auto&q : automaton.getFinalStates()) + res.addTransition(q, automaton.getInitialState()); + + StateType newInitialState = common::createUnique(automaton.getInitialState(), automaton.getStates()); + res.addState(newInitialState); + res.setInitialState(newInitialState); + res.addFinalState(newInitialState); + + res.addTransition(newInitialState, automaton.getInitialState()); + return res; +} + } /* namespace transform */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/Compaction.cpp b/alib2algo/src/automaton/transform/Compaction.cpp index 43417fa743f07f396464360297a274c39cdb9a92..32e58355f55b98738395cc6569dcb63e5a1efb50 100644 --- a/alib2algo/src/automaton/transform/Compaction.cpp +++ b/alib2algo/src/automaton/transform/Compaction.cpp @@ -7,12 +7,6 @@ #include "Compaction.h" -#include <automaton/FSM/CompactNFA.h> -#include <automaton/FSM/DFA.h> - -#include <stack> -#include <tuple> - namespace automaton { namespace transform { @@ -21,66 +15,8 @@ automaton::Automaton Compaction::convert(const automaton::Automaton& automaton) return dispatch(automaton.getData()); } -automaton::CompactNFA < > Compaction::convert(const automaton::CompactNFA < > & automaton) { - return automaton; -} - auto CompactionCompactNFA = Compaction::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(Compaction::convert); - -automaton::CompactNFA < > Compaction::convert(const automaton::DFA<>& automaton) { - automaton::CompactNFA < > res(automaton.getInitialState()); - res.setInputAlphabet(automaton.getInputAlphabet()); - - std::set<label::Label> visited; - - std::stack<std::tuple<label::Label, label::Label, alphabet::Symbol>> stack; // state x lastFork x symbol we used to go to that state - for(const auto& transition: automaton.getTransitionsFromState(automaton.getInitialState())) - stack.push(std::make_tuple(transition.second, automaton.getInitialState(), transition.first.second)); - - if(automaton.getFinalStates().count(automaton.getInitialState()) > 0) - res.addFinalState(automaton.getInitialState()); - - while(!stack.empty()) { - label::Label q = std::move(std::get<0>(stack.top())); - label::Label lastFork = std::move(std::get<1>(stack.top())); - alphabet::Symbol symbol = std::move(std::get<2>(stack.top())); - stack.pop(); - - std::vector < alphabet::Symbol > path { symbol }; - - std::map<std::pair<label::Label, alphabet::Symbol>, label::Label> transitions; - // only 1 child and nonfinal - while((transitions = automaton.getTransitionsFromState(q)).size() == 1 && automaton.getFinalStates().count(q) == 0) { - const std::pair<std::pair<label::Label, alphabet::Symbol>, label::Label>& transition = * transitions.begin(); - path.push_back(transition.first.second); - q = transition.second; - } - - // fork or final state - res.addState(q); - - if(automaton.getFinalStates().count(q)) - res.addFinalState(q); - - res.addTransition(lastFork, path, q); - - for(const std::pair<const std::pair<label::Label, alphabet::Symbol>, label::Label>& transition : automaton.getTransitionsFromState(q)) - if(visited.insert(transition.second).second) - stack.push(std::make_tuple(transition.second, q, transition.first.second)); - - } - - return res; -} - -auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA < >, automaton::DFA<>>(Compaction::convert); - -automaton::CompactNFA < > Compaction::convert(const automaton::NFA < > & automaton) { - automaton::CompactNFA < > res(automaton.getInitialState()); - // TODO - return res; -} - +auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA < >, automaton::DFA < > >(Compaction::convert); auto CompactionNFA = Compaction::RegistratorWrapper<automaton::CompactNFA < >, automaton::NFA < > >(Compaction::convert); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h index 76a99b994a4e12e76b12457b43fcaf2ed4f7c148..b9543cc15418de3068ebfe62511c0a6da2bac154 100644 --- a/alib2algo/src/automaton/transform/Compaction.h +++ b/alib2algo/src/automaton/transform/Compaction.h @@ -8,9 +8,15 @@ #ifndef COMPACTION_H_ #define COMPACTION_H_ +#include <stack> +#include <tuple> + #include <core/multipleDispatch.hpp> + #include "automaton/Automaton.h" #include "automaton/AutomatonFeatures.h" +#include <automaton/FSM/CompactNFA.h> +#include <automaton/FSM/DFA.h> namespace automaton { @@ -21,9 +27,12 @@ namespace transform { */ class Compaction : public std::SingleDispatch<Compaction, automaton::Automaton, const automaton::AutomatonBase &> { public: - static automaton::CompactNFA < > convert( const automaton::DFA<>& automaton); - static automaton::CompactNFA < > convert( const automaton::NFA < > & automaton); - static automaton::CompactNFA < > convert( const automaton::CompactNFA < > & automaton); + template < class SymbolType, class StateType > + static automaton::CompactNFA < SymbolType, StateType > convert( const automaton::DFA < SymbolType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::CompactNFA < SymbolType, StateType > convert( const automaton::NFA < SymbolType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::CompactNFA < SymbolType, StateType > convert( const automaton::CompactNFA < SymbolType, StateType > & automaton); /** * Transforms @@ -33,6 +42,65 @@ public: static automaton::Automaton convert( const automaton::Automaton & automaton ); }; +template < class SymbolType, class StateType > +automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automaton::CompactNFA < SymbolType, StateType > & automaton) { + return automaton; +} + +template < class SymbolType, class StateType > +automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automaton::DFA < SymbolType, StateType > & automaton) { + automaton::CompactNFA < SymbolType, StateType > res(automaton.getInitialState()); + res.setInputAlphabet(automaton.getInputAlphabet()); + + std::set<label::Label> visited; + + std::stack<std::tuple<label::Label, label::Label, alphabet::Symbol>> stack; // state x lastFork x symbol we used to go to that state + for(const auto& transition: automaton.getTransitionsFromState(automaton.getInitialState())) + stack.push(std::make_tuple(transition.second, automaton.getInitialState(), transition.first.second)); + + if(automaton.getFinalStates().count(automaton.getInitialState()) > 0) + res.addFinalState(automaton.getInitialState()); + + while(!stack.empty()) { + label::Label q = std::move(std::get<0>(stack.top())); + label::Label lastFork = std::move(std::get<1>(stack.top())); + alphabet::Symbol symbol = std::move(std::get<2>(stack.top())); + stack.pop(); + + std::vector < alphabet::Symbol > path { symbol }; + + std::map<std::pair<label::Label, alphabet::Symbol>, label::Label> transitions; + // only 1 child and nonfinal + while((transitions = automaton.getTransitionsFromState(q)).size() == 1 && automaton.getFinalStates().count(q) == 0) { + const std::pair<std::pair<label::Label, alphabet::Symbol>, label::Label>& transition = * transitions.begin(); + path.push_back(transition.first.second); + q = transition.second; + } + + // fork or final state + res.addState(q); + + if(automaton.getFinalStates().count(q)) + res.addFinalState(q); + + res.addTransition(lastFork, path, q); + + for(const std::pair<const std::pair<label::Label, alphabet::Symbol>, label::Label>& transition : automaton.getTransitionsFromState(q)) + if(visited.insert(transition.second).second) + stack.push(std::make_tuple(transition.second, q, transition.first.second)); + + } + + return res; +} + +template < class SymbolType, class StateType > +automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automaton::NFA < SymbolType, StateType > & automaton) { + automaton::CompactNFA < SymbolType, StateType > res(automaton.getInitialState()); + // TODO + return res; +} + } /* namespace transform */ } /* namespace automaton */