diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp index fc3bbd95b4295cb138c0d297d7a827f29b73553d..24f13932efed09ca32a266f903fa27d057099808 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp @@ -13,23 +13,15 @@ #define AUTOMATON_FIRST (label::labelFrom(1)) #define AUTOMATON_SECOND (label::labelFrom(2)) -namespace automaton -{ - -namespace transform -{ - -automaton::Automaton AutomataConcatenation::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) -{ - AutomatonBase* out; - Accept((void*) &out, first.getData(), second.getData(), AutomataConcatenation::AUTOMATA_CONCATENATION); - automaton::Automaton res(*out); - delete out; - return res; +namespace automaton { + +namespace transform { + +automaton::Automaton AutomataConcatenation::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) { + return getInstance().dispatch(first.getData(), second.getData()); } -automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first, const automaton::NFA& second) -{ +automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first, const automaton::NFA& second) { automaton::State q01q02(pairLabel(first.getInitialState(), second.getInitialState())); automaton::NFA res(pairLabel(AUTOMATON_FIRST, first.getInitialState())); @@ -47,10 +39,8 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first, if(first.getFinalStates().count(first.getInitialState()) > 0) res.setInitialState(q01q02); - for(const auto& t : first.getTransitions()) - { - for(const auto& q : t.second) - { + for(const auto& t : first.getTransitions()) { + for(const auto& q : t.second) { res.addTransition(pairLabel(AUTOMATON_FIRST, t.first.first), t.first.second, pairLabel(AUTOMATON_FIRST, q)); if(first.getFinalStates().count(q) > 0) @@ -76,8 +66,9 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first, return res; } -automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA& first, const automaton::DFA& second) -{ +auto AutomataConcatenationNFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataConcatenation::getInstance(), AutomataConcatenation::concatenation); + +automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA& first, const automaton::DFA& second) { automaton::State q01q02(pairLabel(first.getInitialState(), second.getInitialState())); automaton::NFA res(pairLabel(AUTOMATON_FIRST, first.getInitialState())); @@ -95,8 +86,7 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA& first, if(first.getFinalStates().count(first.getInitialState()) > 0) res.setInitialState(q01q02); - for(const auto& t : first.getTransitions()) - { + for(const auto& t : first.getTransitions()) { res.addTransition(pairLabel(AUTOMATON_FIRST, t.first.first), t.first.second, pairLabel(AUTOMATON_FIRST, t.second)); if(first.getFinalStates().count(t.second) > 0) @@ -118,104 +108,7 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA& first, return res; } -void AutomataConcatenation::Visit(void*, const automaton::EpsilonNFA&, const automaton::EpsilonNFA&) const -{ - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::CompactNFA&, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomataConcatenation::Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataConcatenation::concatenation(first, second)).plunder(); -} - -void AutomataConcatenation::Visit(void*, const automaton::ExtendedNFA&, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::MultiInitialStateNFA&, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomataConcatenation::Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataConcatenation::concatenation(first, second)).plunder(); -} - -void AutomataConcatenation::Visit(void*, const automaton::DPDA&, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::NPDA&, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::InputDrivenDPDA&, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::InputDrivenNPDA&, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::SinglePopNPDA&, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::SinglePopDPDA&, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::VisiblyPushdownDPDA&, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::VisiblyPushdownNPDA&, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::OneTapeDTM&, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomataConcatenation::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomataConcatenation::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomataConcatenation AutomataConcatenation::AUTOMATA_CONCATENATION; +auto AutomataConcatenationDFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA, automaton::DFA>(AutomataConcatenation::getInstance(), AutomataConcatenation::concatenation); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.h b/alib2algo/src/automaton/transform/AutomataConcatenation.h index dc1dd54b3f2106e8d26637b5c88bb2b46e41a996..f57148bf81bd99248df0f1636524a18ec78af4b8 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h @@ -8,54 +8,29 @@ #ifndef AUTOMATA_CONCATENATION_H_ #define AUTOMATA_CONCATENATION_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Concatenates two automata. * - For finite automata A1, A2, we create automaton L accepting L(A1).L(A2) (Melichar, 2.78) */ -class AutomataConcatenation : public automaton::VisitableAutomatonBase::const_promoting_visitor_type -{ +class AutomataConcatenation : public std::PromotingDoubleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomataConcatenation() {} - 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); -private: - void Visit(void* data, const automaton::CompactNFA& first, const automaton::CompactNFA& second) const; - void Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const; - void Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const; - void Visit(void* data, const automaton::ExtendedNFA& first, const automaton::ExtendedNFA& second) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; - void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; - - void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; - void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; - void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; - void Visit(void* data, const automaton::InputDrivenDPDA& first, const automaton::InputDrivenDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& first, const automaton::RealTimeHeightDeterministicDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& first, const automaton::RealTimeHeightDeterministicNPDA& second) const; - void Visit(void* data, const automaton::SinglePopNPDA& first, const automaton::SinglePopNPDA& second) const; - void Visit(void* data, const automaton::SinglePopDPDA& first, const automaton::SinglePopDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& first, const automaton::VisiblyPushdownDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& first, const automaton::VisiblyPushdownNPDA& second) const; - - void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; - - void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; - void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; - - static const AutomataConcatenation AUTOMATA_CONCATENATION; + static AutomataConcatenation& getInstance() { + static AutomataConcatenation res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp index 2c41b90c9879d1f263bccd2867f673e967777e19..f555ad7cf1df50d3024746bbdcf7753417184580 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp @@ -13,23 +13,15 @@ #define AUTOMATON_FIRST 1 #define AUTOMATON_SECOND 2 -namespace automaton -{ - -namespace transform -{ - -automaton::Automaton AutomataConcatenationEpsilonTransition::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) -{ - AutomatonBase* out; - Accept((void*) &out, first.getData(), second.getData(), AutomataConcatenationEpsilonTransition::AUTOMATA_CONCATENATION_EPSILON_TRANSITION); - automaton::Automaton res(*out); - delete out; - return res; +namespace automaton { + +namespace transform { + +automaton::Automaton AutomataConcatenationEpsilonTransition::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) { + return getInstance().dispatch(first.getData(), second.getData()); } -automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA& first, const automaton::DFA& second) -{ +automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA& first, const automaton::DFA& second) { automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); for(const auto& symbol : first.getInputAlphabet()) @@ -57,8 +49,9 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons return res; } -automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA& first, const automaton::NFA& second) -{ +auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomataConcatenationEpsilonTransition::getInstance(), AutomataConcatenationEpsilonTransition::concatenation); + +automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA& first, const automaton::NFA& second) { automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); for(const auto& symbol : first.getInputAlphabet()) @@ -88,8 +81,9 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons return res; } -automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) -{ +auto AutomataConcatenationEpsilonTransitionNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomataConcatenationEpsilonTransition::getInstance(), AutomataConcatenationEpsilonTransition::concatenation); + +automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) { automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); for(const auto& symbol : first.getInputAlphabet()) @@ -119,105 +113,7 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons return res; } -void AutomataConcatenationEpsilonTransition::Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataConcatenationEpsilonTransition::concatenation(first, second)).plunder(); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::CompactNFA&, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataConcatenationEpsilonTransition::concatenation(first, second)).plunder(); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::ExtendedNFA&, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::MultiInitialStateNFA&, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataConcatenationEpsilonTransition::concatenation(first, second)).plunder(); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::DPDA&, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::NPDA&, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::InputDrivenDPDA&, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::InputDrivenNPDA&, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::SinglePopNPDA&, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::SinglePopDPDA&, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownDPDA&, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownNPDA&, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::OneTapeDTM&, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomataConcatenationEpsilonTransition AutomataConcatenationEpsilonTransition::AUTOMATA_CONCATENATION_EPSILON_TRANSITION; +auto AutomataConcatenationEpsilonTransitionEpsilonNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomataConcatenationEpsilonTransition::getInstance(), AutomataConcatenationEpsilonTransition::concatenation); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h index e8b27489db606020dd0a82e3881a3d0a89909063..b8e4ad8fae0fdb879c453daadd05e9877f21f56b 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h @@ -8,55 +8,30 @@ #ifndef AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_ #define AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Concatenates two automata. * - For finite automata A1, A2, we create automaton L accepting L(A1).L(A2) */ -class AutomataConcatenationEpsilonTransition : public automaton::VisitableAutomatonBase::const_promoting_visitor_type -{ +class AutomataConcatenationEpsilonTransition : public std::PromotingDoubleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomataConcatenationEpsilonTransition() {} - 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); -private: - void Visit(void* data, const automaton::CompactNFA& first, const automaton::CompactNFA& second) const; - void Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const; - void Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const; - void Visit(void* data, const automaton::ExtendedNFA& first, const automaton::ExtendedNFA& second) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; - void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; - - void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; - void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; - void Visit(void* data, const automaton::InputDrivenDPDA& first, const automaton::InputDrivenDPDA& second) const; - void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& first, const automaton::RealTimeHeightDeterministicDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& first, const automaton::RealTimeHeightDeterministicNPDA& second) const; - void Visit(void* data, const automaton::SinglePopNPDA& first, const automaton::SinglePopNPDA& second) const; - void Visit(void* data, const automaton::SinglePopDPDA& first, const automaton::SinglePopDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& first, const automaton::VisiblyPushdownDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& first, const automaton::VisiblyPushdownNPDA& second) const; - - void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; - - void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; - void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; - - static const AutomataConcatenationEpsilonTransition AUTOMATA_CONCATENATION_EPSILON_TRANSITION; + static AutomataConcatenationEpsilonTransition& getInstance() { + static AutomataConcatenationEpsilonTransition res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp index 187037c30e2ab79eb877e49faf1958b06af724fc..2356c905e741dfe15c72fc1841410ce3c1c48b88 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp @@ -12,23 +12,15 @@ #define AUTOMATON_FIRST 1 #define AUTOMATON_SECOND 2 -namespace automaton -{ - -namespace transform -{ - -automaton::Automaton AutomataIntersectionCartesianProduct::intersection(const automaton::Automaton& first, const automaton::Automaton& second) -{ - AutomatonBase* out; - Accept((void*) &out, first.getData(), second.getData(), AutomataIntersectionCartesianProduct::AUTOMATA_INTERSECTION_CARTESIAN_PRODUCT); - automaton::Automaton res(*out); - delete out; - return res; +namespace automaton { + +namespace transform { + +automaton::Automaton AutomataIntersectionCartesianProduct::intersection(const automaton::Automaton& first, const automaton::Automaton& second) { + return getInstance().dispatch(first.getData(), second.getData()); } -automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automaton::DFA& first, const automaton::DFA& second) -{ +automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automaton::DFA& first, const automaton::DFA& second) { automaton::State q0(pairLabel(first.getInitialState(), second.getInitialState())); automaton::DFA res(q0); @@ -45,8 +37,7 @@ automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automato for(const auto& q : second.getFinalStates()) res.addFinalState(automaton::State(pairLabel(p, q))); - for(const auto& state : res.getStates()) - { + for(const auto& state : res.getStates()) { const label::Label& label_p = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().first; const label::Label& label_q = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().second; @@ -59,8 +50,9 @@ automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automato return res; } -automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automaton::NFA& first, const automaton::NFA& second) -{ +auto AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA, automaton::DFA>(AutomataIntersectionCartesianProduct::getInstance(), AutomataIntersectionCartesianProduct::intersection); + +automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automaton::NFA& first, const automaton::NFA& second) { automaton::State q0(pairLabel(first.getInitialState(), second.getInitialState())); automaton::NFA res(q0); @@ -77,8 +69,7 @@ automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automato for(const auto& q : second.getFinalStates()) res.addFinalState(automaton::State(pairLabel(p, q))); - for(const auto& state : res.getStates()) - { + for(const auto& state : res.getStates()) { const label::Label& label_p = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().first; const label::Label& label_q = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().second; @@ -93,104 +84,7 @@ automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automato return res; } -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::EpsilonNFA&, const automaton::EpsilonNFA&) const -{ - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::CompactNFA&, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataIntersectionCartesianProduct::intersection(first, second)).plunder(); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::ExtendedNFA&, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::MultiInitialStateNFA&, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataIntersectionCartesianProduct::intersection(first, second)).plunder(); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::DPDA&, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::NPDA&, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::InputDrivenDPDA&, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::InputDrivenNPDA&, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::SinglePopNPDA&, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::SinglePopDPDA&, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::VisiblyPushdownDPDA&, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::VisiblyPushdownNPDA&, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::OneTapeDTM&, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomataIntersectionCartesianProduct AutomataIntersectionCartesianProduct::AUTOMATA_INTERSECTION_CARTESIAN_PRODUCT; +auto AutomataIntersectionCartesianProductNFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataIntersectionCartesianProduct::getInstance(), AutomataIntersectionCartesianProduct::intersection); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h index 5cba54c245c7974f97676078cb0059a4d7861dc2..824ce6f8651e855a24bab1fb32e841ed2ca2cdb8 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h @@ -8,54 +8,29 @@ #ifndef AUTOMATA_INTERSECTION_CARTESIAN_H_ #define AUTOMATA_INTERSECTION_CARTESIAN_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Intersection of two automata. * - For finite automata A1, A2, we create automaton L accepting L(A1) \cap L(A2) (Melichar, 2.75) */ -class AutomataIntersectionCartesianProduct : public automaton::VisitableAutomatonBase::const_promoting_visitor_type -{ +class AutomataIntersectionCartesianProduct : public std::PromotingDoubleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomataIntersectionCartesianProduct() {} - static automaton::Automaton intersection(const automaton::Automaton& first, const automaton::Automaton& second); static automaton::NFA intersection(const automaton::NFA& first, const automaton::NFA& second); static automaton::DFA intersection(const automaton::DFA& first, const automaton::DFA& second); -private: - void Visit(void* data, const automaton::CompactNFA& first, const automaton::CompactNFA& second) const; - void Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const; - void Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const; - void Visit(void* data, const automaton::ExtendedNFA& first, const automaton::ExtendedNFA& second) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; - void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; - - void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; - void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; - void Visit(void* data, const automaton::InputDrivenDPDA& first, const automaton::InputDrivenDPDA& second) const; - void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& first, const automaton::RealTimeHeightDeterministicDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& first, const automaton::RealTimeHeightDeterministicNPDA& second) const; - void Visit(void* data, const automaton::SinglePopNPDA& first, const automaton::SinglePopNPDA& second) const; - void Visit(void* data, const automaton::SinglePopDPDA& first, const automaton::SinglePopDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& first, const automaton::VisiblyPushdownDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& first, const automaton::VisiblyPushdownNPDA& second) const; - - void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; - - void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; - void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; - - static const AutomataIntersectionCartesianProduct AUTOMATA_INTERSECTION_CARTESIAN_PRODUCT; + static AutomataIntersectionCartesianProduct& getInstance() { + static AutomataIntersectionCartesianProduct res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp index 94ba56cbc059b638e36530e0c410d2a181ac1f9d..dd7f28889fc23a706fafb9ab6aede40d2e82a598 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp @@ -12,23 +12,15 @@ #define AUTOMATON_FIRST 1 #define AUTOMATON_SECOND 2 -namespace automaton -{ - -namespace transform -{ - -automaton::Automaton AutomataUnionCartesianProduct::unification(const automaton::Automaton& first, const automaton::Automaton& second) -{ - AutomatonBase* out; - Accept((void*) &out, first.getData(), second.getData(), AutomataUnionCartesianProduct::AUTOMATA_UNION_CARTESIAN_PRODUCT); - automaton::Automaton res(*out); - delete out; - return res; +namespace automaton { + +namespace transform { + +automaton::Automaton AutomataUnionCartesianProduct::unification(const automaton::Automaton& first, const automaton::Automaton& second) { + return getInstance().dispatch(first.getData(), second.getData()); } -automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& first, const automaton::DFA& second) -{ +automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& first, const automaton::DFA& second) { if(!first.isTotal() || !second.isTotal()) throw exception::AlibException("Automata must be total to unify with cartesian product"); @@ -52,8 +44,7 @@ automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& for(const auto& q : second.getFinalStates()) res.addFinalState(automaton::State(pairLabel(p, q))); - for(const auto& state : res.getStates()) - { + for(const auto& state : res.getStates()) { const label::Label& label_p = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().first; const label::Label& label_q = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().second; @@ -66,8 +57,9 @@ automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& return res; } -automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& first, const automaton::NFA& second) -{ +auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA, automaton::DFA>(AutomataUnionCartesianProduct::getInstance(), AutomataUnionCartesianProduct::unification); + +automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& first, const automaton::NFA& second) { if(!first.isTotal() || !second.isTotal()) throw exception::AlibException("Automata must be total to unify with cartesian product"); @@ -91,8 +83,7 @@ automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& for(const auto& q : second.getFinalStates()) res.addFinalState(automaton::State(pairLabel(p, q))); - for(const auto& state : res.getStates()) - { + for(const auto& state : res.getStates()) { const label::Label& label_p = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().first; const label::Label& label_q = static_cast<const label::LabelPairLabel&>(state.getName().getData()).getData().second; @@ -107,104 +98,7 @@ automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& return res; } -void AutomataUnionCartesianProduct::Visit(void*, const automaton::EpsilonNFA&, const automaton::EpsilonNFA&) const -{ - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::CompactNFA&, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomataUnionCartesianProduct::Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataUnionCartesianProduct::unification(first, second)).plunder(); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::ExtendedNFA&, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::MultiInitialStateNFA&, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomataUnionCartesianProduct::Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataUnionCartesianProduct::unification(first, second)).plunder(); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::DPDA&, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::NPDA&, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::InputDrivenDPDA&, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::InputDrivenNPDA&, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::SinglePopNPDA&, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::SinglePopDPDA&, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::VisiblyPushdownDPDA&, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::VisiblyPushdownNPDA&, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::OneTapeDTM&, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomataUnionCartesianProduct::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomataUnionCartesianProduct AutomataUnionCartesianProduct::AUTOMATA_UNION_CARTESIAN_PRODUCT; +auto AutomataUnionCartesianProductNFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataUnionCartesianProduct::getInstance(), AutomataUnionCartesianProduct::unification); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h index a06aed29c39046166d46ba32300bf4256b253e22..7ab7cc0baa03a05ec8f5f81e02c17975863db410 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h @@ -8,54 +8,29 @@ #ifndef AUTOMATA_UNION_CARTESIAN_H_ #define AUTOMATA_UNION_CARTESIAN_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Union two automata. * - For finite automata A1, A2, we create automaton L accepting L(A1) \cup L(A2) (Melichar, 2.71) */ -class AutomataUnionCartesianProduct : public automaton::VisitableAutomatonBase::const_promoting_visitor_type -{ +class AutomataUnionCartesianProduct : public std::PromotingDoubleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomataUnionCartesianProduct() {} - static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second); static automaton::NFA unification(const automaton::NFA& first, const automaton::NFA& second); static automaton::DFA unification(const automaton::DFA& first, const automaton::DFA& second); -private: - void Visit(void* data, const automaton::CompactNFA& first, const automaton::CompactNFA& second) const; - void Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const; - void Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const; - void Visit(void* data, const automaton::ExtendedNFA& first, const automaton::ExtendedNFA& second) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; - void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; - - void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; - void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; - void Visit(void* data, const automaton::InputDrivenDPDA& first, const automaton::InputDrivenDPDA& second) const; - void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& first, const automaton::RealTimeHeightDeterministicDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& first, const automaton::RealTimeHeightDeterministicNPDA& second) const; - void Visit(void* data, const automaton::SinglePopNPDA& first, const automaton::SinglePopNPDA& second) const; - void Visit(void* data, const automaton::SinglePopDPDA& first, const automaton::SinglePopDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& first, const automaton::VisiblyPushdownDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& first, const automaton::VisiblyPushdownNPDA& second) const; - - void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; - - void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; - void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; - - static const AutomataUnionCartesianProduct AUTOMATA_UNION_CARTESIAN_PRODUCT; + static AutomataUnionCartesianProduct& getInstance() { + static AutomataUnionCartesianProduct res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp index a5d303b7a7d0a097a53955f1e411b4b1ac1972e6..dd2df0369c29196f4b0275b4b1dbbeb8dded79dc 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp @@ -12,23 +12,15 @@ #define AUTOMATON_FIRST 1 #define AUTOMATON_SECOND 2 -namespace automaton -{ - -namespace transform -{ - -automaton::Automaton AutomataUnionEpsilonTransition::unification(const automaton::Automaton& first, const automaton::Automaton& second) -{ - AutomatonBase* out; - Accept((void*) &out, first.getData(), second.getData(), AutomataUnionEpsilonTransition::AUTOMATA_UNION_EPSILON_TRANSITION); - automaton::Automaton res(*out); - delete out; - return res; +namespace automaton { + +namespace transform { + +automaton::Automaton AutomataUnionEpsilonTransition::unification(const automaton::Automaton& first, const automaton::Automaton& second) { + return getInstance().dispatch(first.getData(), second.getData()); } -automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) -{ +automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) { std::set<automaton::State> states; for(const auto& q : first.getStates()) states.insert(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); @@ -65,8 +57,9 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato return res; } -automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::NFA& first, const automaton::NFA& second) -{ +auto AutomataUnionEpsilonTransitionEpsilonNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomataUnionEpsilonTransition::getInstance(), AutomataUnionEpsilonTransition::unification); + +automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::NFA& first, const automaton::NFA& second) { std::set<automaton::State> states; for(const auto& q : first.getStates()) states.insert(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); @@ -103,8 +96,9 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato return res; } -automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::DFA& first, const automaton::DFA& second) -{ +auto AutomataUnionEpsilonTransitionNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomataUnionEpsilonTransition::getInstance(), AutomataUnionEpsilonTransition::unification); + +automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::DFA& first, const automaton::DFA& second) { std::set<automaton::State> states; for(const auto& q : first.getStates()) states.insert(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); @@ -139,105 +133,7 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato return res; } -void AutomataUnionEpsilonTransition::Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataUnionEpsilonTransition::unification(first, second)).plunder(); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::CompactNFA&, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomataUnionEpsilonTransition::Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataUnionEpsilonTransition::unification(first, second)).plunder(); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::ExtendedNFA&, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::MultiInitialStateNFA&, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomataUnionEpsilonTransition::Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomataUnionEpsilonTransition::unification(first, second)).plunder(); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::DPDA&, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::NPDA&, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::InputDrivenDPDA&, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::InputDrivenNPDA&, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::SinglePopNPDA&, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::SinglePopDPDA&, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownDPDA&, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownNPDA&, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::OneTapeDTM&, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomataUnionEpsilonTransition::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomataUnionEpsilonTransition AutomataUnionEpsilonTransition::AUTOMATA_UNION_EPSILON_TRANSITION; +auto AutomataUnionEpsilonTransitionDFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomataUnionEpsilonTransition::getInstance(), AutomataUnionEpsilonTransition::unification); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h index c367d1d76a7607dc51992ba2fcc4e24839ceabd2..c893f45c3468533c6a0f327427e504e431f20c14 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h @@ -8,55 +8,30 @@ #ifndef AUTOMATA_UNION_EPSILON_H_ #define AUTOMATA_UNION_EPSILON_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Union two automata. * - For finite automata A1, A2, we create automaton L accepting L(A1) \cup L(A2) */ -class AutomataUnionEpsilonTransition : public automaton::VisitableAutomatonBase::const_promoting_visitor_type -{ +class AutomataUnionEpsilonTransition : public std::PromotingDoubleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomataUnionEpsilonTransition() {} - 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); -private: - void Visit(void* data, const automaton::CompactNFA& first, const automaton::CompactNFA& second) const; - void Visit(void* data, const automaton::DFA& first, const automaton::DFA& second) const; - void Visit(void* data, const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) const; - void Visit(void* data, const automaton::ExtendedNFA& first, const automaton::ExtendedNFA& second) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; - void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; - - void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; - void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; - void Visit(void* data, const automaton::InputDrivenDPDA& first, const automaton::InputDrivenDPDA& second) const; - void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& first, const automaton::RealTimeHeightDeterministicDPDA& second) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& first, const automaton::RealTimeHeightDeterministicNPDA& second) const; - void Visit(void* data, const automaton::SinglePopNPDA& first, const automaton::SinglePopNPDA& second) const; - void Visit(void* data, const automaton::SinglePopDPDA& first, const automaton::SinglePopDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& first, const automaton::VisiblyPushdownDPDA& second) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& first, const automaton::VisiblyPushdownNPDA& second) const; - - void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; - - void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; - void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; - - static const AutomataUnionEpsilonTransition AUTOMATA_UNION_EPSILON_TRANSITION; + static AutomataUnionEpsilonTransition& getInstance() { + static AutomataUnionEpsilonTransition res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp index c1dd029dde8c6b9c11c40a3c93f7c6cb697e0335..39af9570b50ca1579e22f7ec55c6b45e47b880c0 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp @@ -8,24 +8,16 @@ #include "AutomatonIteration.h" #include <exception/AlibException.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { -automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& automaton) -{ - AutomatonBase* out; - automaton.getData().Accept((void*) &out, AutomatonIteration::AUTOMATON_ITERATION); - automaton::Automaton res(*out); - delete out; - return res; +automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& automaton) { + return getInstance().dispatch(automaton.getData()); } template<class T> -automaton::NFA AutomatonIteration::iteration(const T& automaton) -{ +automaton::NFA AutomatonIteration::iteration(const T& automaton) { automaton::NFA res(automaton); for(const auto& qf : res.getFinalStates()) @@ -36,104 +28,8 @@ automaton::NFA AutomatonIteration::iteration(const T& automaton) return res; } -void AutomatonIteration::Visit(void*, const automaton::EpsilonNFA&) const -{ - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void AutomatonIteration::Visit(void*, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomatonIteration::Visit(void* data, const automaton::DFA& automaton) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomatonIteration::iteration(automaton)).plunder(); -} - -void AutomatonIteration::Visit(void*, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomatonIteration::Visit(void*, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomatonIteration::Visit(void* data, const automaton::NFA& automaton) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomatonIteration::iteration(automaton)).plunder(); -} - -void AutomatonIteration::Visit(void*, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomatonIteration::Visit(void*, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomatonIteration::Visit(void*, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomatonIteration::Visit(void*, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomatonIteration AutomatonIteration::AUTOMATON_ITERATION; +auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper<automaton::NFA, automaton::DFA>(AutomatonIteration::getInstance(), AutomatonIteration::iteration); +auto AutomatonIterationNFA = AutomatonIteration::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomatonIteration::getInstance(), AutomatonIteration::iteration); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h index fb7d2728e817282db4d4330aeb23622f952235e5..997aa375c58b37bec6b11a60840b4c4ac719bfdc 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.h +++ b/alib2algo/src/automaton/transform/AutomatonIteration.h @@ -8,54 +8,29 @@ #ifndef AUTOMATON_ITERATION_H_ #define AUTOMATON_ITERATION_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Iterates language given by automaton * - For finite automaton A1, we create automaton L accepting L(A1)* */ -class AutomatonIteration : public automaton::VisitableAutomatonBase::const_visitor_type -{ +class AutomatonIteration : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomatonIteration() {} - static automaton::Automaton iteration(const automaton::Automaton& automaton); template<class T> static automaton::NFA iteration(const T& automaton); -private: - void Visit(void* data, const automaton::CompactNFA& automaton) const; - void Visit(void* data, const automaton::DFA& automaton) const; - void Visit(void* data, const automaton::EpsilonNFA& automaton) const; - void Visit(void* data, const automaton::ExtendedNFA& automaton) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const; - void Visit(void* data, const automaton::NFA& automaton) const; - - void Visit(void* data, const automaton::DPDA& automaton) const; - void Visit(void* data, const automaton::NPDA& automaton) const; - void Visit(void* data, const automaton::InputDrivenDPDA& automaton) const; - void Visit(void* data, const automaton::InputDrivenNPDA& automaton) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const; - void Visit(void* data, const automaton::SinglePopNPDA& automaton) const; - void Visit(void* data, const automaton::SinglePopDPDA& automaton) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const; - - void Visit(void* data, const automaton::OneTapeDTM& automaton) const; - - void Visit(void* data, const automaton::DFTA& first) const; - void Visit(void* data, const automaton::NFTA& first) const; - - static const AutomatonIteration AUTOMATON_ITERATION; + static AutomatonIteration& getInstance() { + static AutomatonIteration res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp index 739a8f57275f28b50081fc6dd8b420ef0ce493e3..4f839d37528d6ac8d596302ac811d99c7c0d36b0 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp @@ -8,24 +8,16 @@ #include "AutomatonIterationEpsilonTransition.h" #include <exception/AlibException.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { -automaton::Automaton AutomatonIterationEpsilonTransition::iteration(const automaton::Automaton& automaton) -{ - AutomatonBase* out; - automaton.getData().Accept((void*) &out, AutomatonIterationEpsilonTransition::AUTOMATON_ITERATION_EPSILON_TRANSITION); - automaton::Automaton res(*out); - delete out; - return res; +automaton::Automaton AutomatonIterationEpsilonTransition::iteration(const automaton::Automaton& automaton) { + return getInstance().dispatch(automaton.getData()); } template<class T> -automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& automaton) -{ +automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& automaton) { automaton::EpsilonNFA res(automaton); for(const auto&q : automaton.getFinalStates()) @@ -35,105 +27,9 @@ automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& au return res; } -void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::EpsilonNFA& automaton) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::CompactNFA&) const -{ - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::DFA& automaton) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::NFA& automaton) const -{ - AutomatonBase* &ret = *(AutomatonBase**) data; - ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::DPDA&) const -{ - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::NPDA&) const -{ - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::InputDrivenDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::InputDrivenNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::SinglePopNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::SinglePopDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownDPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownNPDA&) const -{ - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::OneTapeDTM&) const -{ - throw exception::AlibException("Unsupported automaton type OneTapeDTM"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::DFTA&) const -{ - throw exception::AlibException("Unsupported automaton type DFTA"); -} - -void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::NFTA&) const -{ - throw exception::AlibException("Unsupported automaton type NFTA"); -} - -const AutomatonIterationEpsilonTransition AutomatonIterationEpsilonTransition::AUTOMATON_ITERATION_EPSILON_TRANSITION; +auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomatonIterationEpsilonTransition::getInstance(), AutomatonIterationEpsilonTransition::iteration); +auto AutomatonIterationEpsilonTransitionNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomatonIterationEpsilonTransition::getInstance(), AutomatonIterationEpsilonTransition::iteration); +auto AutomatonIterationEpsilonTransitionEpsilonNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomatonIterationEpsilonTransition::getInstance(), AutomatonIterationEpsilonTransition::iteration); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h index 307d6c55fec5f115acaedb1d6f9d4e152bdfe2d2..c9f7cb3365ede30a2c6924fc8619359c7dd31e1e 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h @@ -8,54 +8,29 @@ #ifndef AUTOMATON_ITERATION_EPSILON_TRANSITION_H_ #define AUTOMATON_ITERATION_EPSILON_TRANSITION_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/FSM/EpsilonNFA.h> -namespace automaton -{ +namespace automaton { -namespace transform -{ +namespace transform { /** * Iterates language given by automaton * - For finite automaton A1, we create automaton L accepting L(A1)* */ -class AutomatonIterationEpsilonTransition : public automaton::VisitableAutomatonBase::const_visitor_type -{ +class AutomatonIterationEpsilonTransition : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - AutomatonIterationEpsilonTransition() {} - static automaton::Automaton iteration(const automaton::Automaton& automaton); template<class T> static automaton::EpsilonNFA iteration(const T& automaton); -private: - void Visit(void* data, const automaton::CompactNFA& automaton) const; - void Visit(void* data, const automaton::DFA& automaton) const; - void Visit(void* data, const automaton::EpsilonNFA& automaton) const; - void Visit(void* data, const automaton::ExtendedNFA& automaton) const; - void Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const; - void Visit(void* data, const automaton::NFA& automaton) const; - - void Visit(void* data, const automaton::DPDA& automaton) const; - void Visit(void* data, const automaton::NPDA& automaton) const; - void Visit(void* data, const automaton::InputDrivenDPDA& automaton) const; - void Visit(void* data, const automaton::InputDrivenNPDA& automaton) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const; - void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const; - void Visit(void* data, const automaton::SinglePopNPDA& automaton) const; - void Visit(void* data, const automaton::SinglePopDPDA& automaton) const; - void Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const; - void Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const; - - void Visit(void* data, const automaton::OneTapeDTM& automaton) const; - - void Visit(void* data, const automaton::DFTA& first) const; - void Visit(void* data, const automaton::NFTA& first) const; - - static const AutomatonIterationEpsilonTransition AUTOMATON_ITERATION_EPSILON_TRANSITION; + static AutomatonIterationEpsilonTransition& getInstance() { + static AutomatonIterationEpsilonTransition res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/Compaction.cpp b/alib2algo/src/automaton/transform/Compaction.cpp index 1563cdefdd90c8703ab7a357b2940fa4979fdd3b..3e61aac160eca3f9d0ce34f0e9000d2e1043ec83 100644 --- a/alib2algo/src/automaton/transform/Compaction.cpp +++ b/alib2algo/src/automaton/transform/Compaction.cpp @@ -21,20 +21,16 @@ namespace automaton { namespace transform { automaton::Automaton Compaction::convert(const automaton::Automaton& automaton) { - automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, Compaction::COMPACTION); - automaton::Automaton res(std::move(*out)); - delete out; - return res; + return getInstance().dispatch(automaton.getData()); } -automaton::CompactNFA Compaction::convert(const automaton::CompactNFA& automaton) -{ +automaton::CompactNFA Compaction::convert(const automaton::CompactNFA& automaton) { return automaton; } -automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton) -{ +auto CompactionCompactNFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(Compaction::getInstance(), Compaction::convert); + +automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton) { automaton::CompactNFA res(automaton.getInitialState()); res.setInputAlphabet(automaton.getInputAlphabet()); @@ -80,47 +76,15 @@ automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton) return res; } -automaton::CompactNFA Compaction::convert(const automaton::NFA& automaton) -{ +auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::DFA>(Compaction::getInstance(), Compaction::convert); + +automaton::CompactNFA Compaction::convert(const automaton::NFA& automaton) { automaton::CompactNFA res(automaton.getInitialState()); // TODO return res; } -void Compaction::Visit(void* data, const CompactNFA& automaton) const -{ - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void Compaction::Visit(void* data, const DFA& automaton) const -{ - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void Compaction::Visit(void*, const EpsilonNFA&) const -{ - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void Compaction::Visit(void*, const ExtendedNFA&) const -{ - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void Compaction::Visit(void*, const MultiInitialStateNFA&) const -{ - throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); -} - -void Compaction::Visit(void* data, const NFA& automaton) const -{ - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -const Compaction Compaction::COMPACTION; +auto CompactionNFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::NFA>(Compaction::getInstance(), Compaction::convert); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h index e0da50de241a9bc60a33b67112a9e0b779552c99..1300602ef2e53480b950bb284a32181a8107a1e4 100644 --- a/alib2algo/src/automaton/transform/Compaction.h +++ b/alib2algo/src/automaton/transform/Compaction.h @@ -8,6 +8,7 @@ #ifndef COMPACTION_H_ #define COMPACTION_H_ +#include <common/multipleDispatch.hpp> #include "automaton/Automaton.h" namespace automaton { @@ -17,10 +18,8 @@ namespace transform { /** * Transforms FSM to CompactNFA */ -class Compaction : public automaton::VisitableConstFSMBase { +class Compaction : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - Compaction() {} - static automaton::CompactNFA convert( const automaton::DFA& automaton); static automaton::CompactNFA convert( const automaton::NFA& automaton); static automaton::CompactNFA convert( const automaton::CompactNFA& automaton); @@ -32,17 +31,10 @@ public: */ static automaton::Automaton convert( const automaton::Automaton & automaton ); -private: - using automaton::VisitableConstFSMBase::Visit; - - void Visit(void*, const CompactNFA& automaton) const; - void Visit(void*, const DFA& automaton) const; - void Visit(void*, const EpsilonNFA& automaton) const; - void Visit(void*, const ExtendedNFA& automaton) const; - void Visit(void*, const MultiInitialStateNFA& automaton) const; - void Visit(void*, const NFA& automaton) const; - - static const Compaction COMPACTION; + static Compaction& getInstance() { + static Compaction res; + return res; + } }; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/PDAToRHPDA.cpp b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp index 68c0d9efa40856c458438194617183a79b88ffce..a53cca884c23d5cb2576c203bfdac215a620e503 100644 --- a/alib2algo/src/automaton/transform/PDAToRHPDA.cpp +++ b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp @@ -25,10 +25,14 @@ automaton::RealTimeHeightDeterministicDPDA PDAToRHPDA::convert( const automaton: return pda; } +auto PDAToRHPDARealTimeHeightDeterministicDPDA = PDAToRHPDA::RegistratorWrapper<automaton::RealTimeHeightDeterministicDPDA, automaton::RealTimeHeightDeterministicDPDA>(PDAToRHPDA::getInstance(), PDAToRHPDA::convert); + automaton::RealTimeHeightDeterministicNPDA PDAToRHPDA::convert( const automaton::RealTimeHeightDeterministicNPDA & pda ) { return pda; } +auto PDAToRHPDARealTimeHeightDeterministicNPDA = PDAToRHPDA::RegistratorWrapper<automaton::RealTimeHeightDeterministicNPDA, automaton::RealTimeHeightDeterministicNPDA>(PDAToRHPDA::getInstance(), PDAToRHPDA::convert); + automaton::RealTimeHeightDeterministicDPDA PDAToRHPDA::convert( const automaton::DPDA & pda ) { automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), pda.getStates()); @@ -93,6 +97,8 @@ automaton::RealTimeHeightDeterministicDPDA PDAToRHPDA::convert( const automaton: return res; } +auto PDAToRHPDADPDA = PDAToRHPDA::RegistratorWrapper<automaton::RealTimeHeightDeterministicDPDA, automaton::DPDA>(PDAToRHPDA::getInstance(), PDAToRHPDA::convert); + automaton::RealTimeHeightDeterministicNPDA PDAToRHPDA::convert( const automaton::NPDA & pda ) { RealTimeHeightDeterministicNPDA res(alphabet::Symbol { alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK } ); @@ -159,59 +165,11 @@ automaton::RealTimeHeightDeterministicNPDA PDAToRHPDA::convert( const automaton: return res; } -automaton::Automaton PDAToRHPDA::convert(const Automaton& automaton) { - automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, PDAToRHPDA::PDA_TO_RHPDA); - automaton::Automaton res(std::move(*out)); - delete out; - return std::move(res); -} - -void PDAToRHPDA::Visit(void* data, const DPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void PDAToRHPDA::Visit(void*, const SinglePopDPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void PDAToRHPDA::Visit(void*, const InputDrivenDPDA&) const { - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} - -void PDAToRHPDA::Visit(void*, const InputDrivenNPDA&) const { - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} +auto PDAToRHPDANPDA = PDAToRHPDA::RegistratorWrapper<automaton::RealTimeHeightDeterministicNPDA, automaton::NPDA>(PDAToRHPDA::getInstance(), PDAToRHPDA::convert); -void PDAToRHPDA::Visit(void*, const VisiblyPushdownDPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void PDAToRHPDA::Visit(void*, const VisiblyPushdownNPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void PDAToRHPDA::Visit(void* data, const RealTimeHeightDeterministicDPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void PDAToRHPDA::Visit(void* data, const RealTimeHeightDeterministicNPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void PDAToRHPDA::Visit(void* data, const NPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void PDAToRHPDA::Visit(void*, const SinglePopNPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +automaton::Automaton PDAToRHPDA::convert(const Automaton& automaton) { + return getInstance().dispatch(automaton.getData()); } -const PDAToRHPDA PDAToRHPDA::PDA_TO_RHPDA; - } diff --git a/alib2algo/src/automaton/transform/PDAToRHPDA.h b/alib2algo/src/automaton/transform/PDAToRHPDA.h index 504043797daf98e566db46c2b6bde0b94ef5707b..6a6ff0c69527b40e5e919d0e10c12f0bd1467424 100644 --- a/alib2algo/src/automaton/transform/PDAToRHPDA.h +++ b/alib2algo/src/automaton/transform/PDAToRHPDA.h @@ -8,6 +8,7 @@ #ifndef PDA_TO_RHPDA_H_ #define PDA_TO_RHPDA_H_ +#include <common/multipleDispatch.hpp> #include <algorithm> #include <deque> #include <set> @@ -17,10 +18,8 @@ namespace automaton { -class PDAToRHPDA : public automaton::VisitableConstPDABase { +class PDAToRHPDA : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - PDAToRHPDA() {} - static automaton::RealTimeHeightDeterministicDPDA convert( const automaton::RealTimeHeightDeterministicDPDA & pda); static automaton::RealTimeHeightDeterministicDPDA convert( const automaton::DPDA & pda); static automaton::RealTimeHeightDeterministicNPDA convert( const automaton::RealTimeHeightDeterministicNPDA & pda); @@ -30,21 +29,11 @@ public: * Computes epsilon closure of a state in epsilon nonfree automaton */ static automaton::Automaton convert( const automaton::Automaton & automaton ); -private: - using automaton::VisitableConstPDABase::Visit; - - void Visit(void*, const DPDA& automaton) const; - void Visit(void*, const SinglePopDPDA& automaton) const; - void Visit(void*, const InputDrivenNPDA& automaton) const; - void Visit(void*, const InputDrivenDPDA& automaton) const; - void Visit(void*, const VisiblyPushdownDPDA& automaton) const; - void Visit(void*, const VisiblyPushdownNPDA& automaton) const; - void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; - void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; - void Visit(void*, const NPDA& automaton) const; - void Visit(void*, const SinglePopNPDA& automaton) const; - - static const PDAToRHPDA PDA_TO_RHPDA; + + static PDAToRHPDA& getInstance() { + static PDAToRHPDA res; + return res; + } }; } diff --git a/alib2algo/src/automaton/transform/RHPDAToPDA.cpp b/alib2algo/src/automaton/transform/RHPDAToPDA.cpp index 0e6e03742095131e208067d53c576e0b7b32deba..9789850625dc12412046a1d95d7df2b1da0195ba 100644 --- a/alib2algo/src/automaton/transform/RHPDAToPDA.cpp +++ b/alib2algo/src/automaton/transform/RHPDAToPDA.cpp @@ -128,6 +128,8 @@ automaton::DPDA RHPDAToPDA::convert( const automaton::RealTimeHeightDeterministi return res; } +auto RHPDAToPDARealTimeHeightDeterministicDPDA = RHPDAToPDA::RegistratorWrapper<automaton::DPDA, automaton::RealTimeHeightDeterministicDPDA>(RHPDAToPDA::getInstance(), RHPDAToPDA::convert); + //This may not work correctly -- generation of initial state and initial symbol automaton::NPDA RHPDAToPDA::convert( const automaton::RealTimeHeightDeterministicNPDA & pda ) { std::map<std::tuple<automaton::State, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::pair<automaton::State, std::vector<alphabet::Symbol>>>> readingTransitions; @@ -247,57 +249,11 @@ automaton::NPDA RHPDAToPDA::convert( const automaton::RealTimeHeightDeterministi return res; } -automaton::Automaton RHPDAToPDA::convert(const Automaton& automaton) { - automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, RHPDAToPDA::RHPDA_TO_PDA); - automaton::Automaton res(std::move(*out)); - delete out; - return std::move(res); -} - -void RHPDAToPDA::Visit(void*, const DPDA&) const { - throw exception::AlibException("Unsupported automaton type DPDA"); -} - -void RHPDAToPDA::Visit(void*, const SinglePopDPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); -} - -void RHPDAToPDA::Visit(void*, const InputDrivenDPDA&) const { - throw exception::AlibException("Unsupported automaton type InputDrivenDPDA"); -} +auto RHPDAToPDARealTimeHeightDeterministicNPDA = RHPDAToPDA::RegistratorWrapper<automaton::NPDA, automaton::RealTimeHeightDeterministicNPDA>(RHPDAToPDA::getInstance(), RHPDAToPDA::convert); -void RHPDAToPDA::Visit(void*, const InputDrivenNPDA&) const { - throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); -} - -void RHPDAToPDA::Visit(void*, const VisiblyPushdownDPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); -} - -void RHPDAToPDA::Visit(void*, const VisiblyPushdownNPDA&) const { - throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); -} - -void RHPDAToPDA::Visit(void* data, const RealTimeHeightDeterministicDPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void RHPDAToPDA::Visit(void* data, const RealTimeHeightDeterministicNPDA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void RHPDAToPDA::Visit(void*, const NPDA&) const { - throw exception::AlibException("Unsupported automaton type NPDA"); -} - -void RHPDAToPDA::Visit(void*, const SinglePopNPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +automaton::Automaton RHPDAToPDA::convert(const Automaton& automaton) { + return getInstance().dispatch(automaton.getData()); } -const RHPDAToPDA RHPDAToPDA::RHPDA_TO_PDA; - } diff --git a/alib2algo/src/automaton/transform/RHPDAToPDA.h b/alib2algo/src/automaton/transform/RHPDAToPDA.h index fe256487c7f6c94c17e5e61c22a381bdcecbcbe1..7763e7ca3cc1ca36e7dd3e5412eebc29328b66d4 100644 --- a/alib2algo/src/automaton/transform/RHPDAToPDA.h +++ b/alib2algo/src/automaton/transform/RHPDAToPDA.h @@ -8,6 +8,7 @@ #ifndef RHPDA_TO_PDA_H_ #define RHPDA_TO_PDA_H_ +#include <common/multipleDispatch.hpp> #include <algorithm> #include <deque> #include <set> @@ -17,10 +18,8 @@ namespace automaton { -class RHPDAToPDA : public VisitableConstPDABase { +class RHPDAToPDA : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - RHPDAToPDA() {} - static automaton::DPDA convert( const automaton::RealTimeHeightDeterministicDPDA & pda); static automaton::DPDA convert( const automaton::DPDA & pda); static automaton::NPDA convert( const automaton::RealTimeHeightDeterministicNPDA & pda); @@ -30,21 +29,11 @@ public: * Computes epsilon closure of a state in epsilon nonfree automaton */ static automaton::Automaton convert( const automaton::Automaton & automaton ); -private: - using automaton::VisitableConstPDABase::Visit; - - void Visit(void*, const DPDA& automaton) const; - void Visit(void*, const SinglePopDPDA& automaton) const; - void Visit(void*, const InputDrivenDPDA& automaton) const; - void Visit(void*, const InputDrivenNPDA& automaton) const; - void Visit(void*, const VisiblyPushdownDPDA& automaton) const; - void Visit(void*, const VisiblyPushdownNPDA& automaton) const; - void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; - void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; - void Visit(void*, const NPDA& automaton) const; - void Visit(void*, const SinglePopNPDA& automaton) const; - - static const RHPDAToPDA RHPDA_TO_PDA; + + static RHPDAToPDA& getInstance() { + static RHPDAToPDA res; + return res; + } }; } diff --git a/alib2algo/src/automaton/transform/Reverse.cpp b/alib2algo/src/automaton/transform/Reverse.cpp index 7afb8e28e1e25d28dd9ababd6fe6b337672bd3a6..f751f276015aa48fa1b4f9826e3d4dfad057c3ec 100644 --- a/alib2algo/src/automaton/transform/Reverse.cpp +++ b/alib2algo/src/automaton/transform/Reverse.cpp @@ -18,15 +18,10 @@ namespace automaton { namespace transform { automaton::Automaton Reverse::convert(const Automaton& automaton) { - automaton::Automaton* out = NULL; - automaton.getData().Accept((void*) &out, Reverse::REVERSE); - automaton::Automaton res(std::move(*out)); - delete out; - return std::move(res); + return getInstance().dispatch(automaton.getData()); } -automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA& automaton) -{ +automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA& automaton) { automaton::MultiInitialStateNFA res; res.setStates(automaton.getStates()); @@ -40,8 +35,9 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA& automaton return res; } -automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton) -{ +auto ReverseDFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::DFA>(Reverse::getInstance(), Reverse::convert); + +automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton) { automaton::MultiInitialStateNFA res; res.setStates(automaton.getStates()); @@ -56,8 +52,9 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton return res; } -automaton::MultiInitialStateNFA Reverse::convert(const automaton::MultiInitialStateNFA& automaton) -{ +auto ReverseNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::NFA>(Reverse::getInstance(), Reverse::convert); + +automaton::MultiInitialStateNFA Reverse::convert(const automaton::MultiInitialStateNFA& automaton) { automaton::MultiInitialStateNFA res; res.setStates(automaton.getStates()); @@ -72,34 +69,7 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::MultiInitialSt return res; } -void Reverse::Visit(void* data, const DFA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void Reverse::Visit(void* data, const NFA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void Reverse::Visit(void* data, const MultiInitialStateNFA& automaton) const { - automaton::Automaton*& out = *((automaton::Automaton**) data); - out = new automaton::Automaton(this->convert(automaton)); -} - -void Reverse::Visit(void*, const ExtendedNFA&) const { - throw exception::AlibException("Unsupported automaton type ExtendedNFA"); -} - -void Reverse::Visit(void*, const EpsilonNFA&) const { - throw exception::AlibException("Unsupported automaton type EpsilonNFA"); -} - -void Reverse::Visit(void*, const CompactNFA&) const { - throw exception::AlibException("Unsupported automaton type CompactNFA"); -} - -const Reverse Reverse::REVERSE; +auto ReverseMultiInitialStateNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(Reverse::getInstance(), Reverse::convert); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/Reverse.h b/alib2algo/src/automaton/transform/Reverse.h index de596f31a57f36796de46706a8c937e00e6532a5..337a7f647294dd82c9ed54b820bf31acf0cc5c9e 100644 --- a/alib2algo/src/automaton/transform/Reverse.h +++ b/alib2algo/src/automaton/transform/Reverse.h @@ -8,6 +8,7 @@ #ifndef REVERSE_H_ #define REVERSE_H_ +#include <common/multipleDispatch.hpp> #include <automaton/Automaton.h> #include <automaton/common/State.h> @@ -15,10 +16,8 @@ namespace automaton { namespace transform { -class Reverse : public automaton::VisitableConstFSMBase { +class Reverse : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> { public: - Reverse() {} - static automaton::MultiInitialStateNFA convert(const automaton::DFA& automaton); static automaton::MultiInitialStateNFA convert(const automaton::NFA& automaton); static automaton::MultiInitialStateNFA convert(const automaton::MultiInitialStateNFA& automaton); @@ -29,17 +28,11 @@ public: * @return Automaton reverse automaton */ static automaton::Automaton convert( const automaton::Automaton & automaton ); -private: - using automaton::VisitableConstFSMBase::Visit; - - void Visit(void*, const DFA& automaton) const; - void Visit(void*, const NFA& automaton) const; - void Visit(void*, const MultiInitialStateNFA& automaton) const; - void Visit(void*, const ExtendedNFA& automaton) const; - void Visit(void*, const EpsilonNFA& automaton) const; - void Visit(void*, const CompactNFA& automaton) const; - static const Reverse REVERSE; + static Reverse& getInstance() { + static Reverse res; + return res; + } }; } /* namespace transform */