diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5db1d4b20116bd3196797f9c544bd692109d833 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp @@ -0,0 +1,178 @@ +/* + * AutomataUnionCartesianProduct.cpp + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#include "AutomataUnionCartesianProduct.h" +#include <exception/AlibException.h> +#include "common/PairLabel.h" + +#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; +} + +automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& first, const automaton::DFA& second) +{ + automaton::State q0(pairLabel(first.getInitialState(), second.getInitialState())); + automaton::DFA res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getStates()) + res.addState(automaton::State(pairLabel(p, q))); + + for(const auto& p : first.getFinalStates()) + for(const auto& q : second.getStates()) + res.addFinalState(automaton::State(pairLabel(p, q))); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getFinalStates()) + res.addFinalState(automaton::State(pairLabel(p, q))); + + for(const auto& tp : first.getTransitions()) + for(const auto& tq : second.getTransitions()) + if(tp.first.second == tq.first.second) + res.addTransition(automaton::State(pairLabel(tp.first.first, tq.first.first)), tp.first.second, automaton::State(pairLabel(tp.second, tq.second))); + + return res; +} + +automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& first, const automaton::NFA& second) +{ + automaton::State q0(pairLabel(first.getInitialState(), second.getInitialState())); + automaton::NFA res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getStates()) + res.addState(automaton::State(pairLabel(p, q))); + + for(const auto& p : first.getFinalStates()) + for(const auto& q : second.getStates()) + res.addFinalState(automaton::State(pairLabel(p, q))); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getFinalStates()) + res.addFinalState(automaton::State(pairLabel(p, q))); + + for(const auto& tp : first.getTransitions()) + for(const auto& tq : second.getTransitions()) + if(tp.first.second == tq.first.second) + for(const auto& p : tp.second) + for(const auto& q : tq.second) + res.addTransition(automaton::State(pairLabel(tp.first.first, tq.first.first)), tp.first.second, automaton::State(pairLabel(p, q))); + + 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::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"); +} + +const AutomataUnionCartesianProduct AutomataUnionCartesianProduct::AUTOMATA_UNION_CARTESIAN_PRODUCT; + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h new file mode 100644 index 0000000000000000000000000000000000000000..305efabc5f7f082bcf9b98a4d322579f33181af3 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h @@ -0,0 +1,59 @@ +/* + * AutomataUnionCartesianProduct.h + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef AUTOMATA_UNION_CARTESIAN_H_ +#define AUTOMATA_UNION_CARTESIAN_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/EpsilonNFA.h> + +namespace automaton +{ + +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 +{ +public: + 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::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; + + static const AutomataUnionCartesianProduct AUTOMATA_UNION_CARTESIAN_PRODUCT; +}; + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* AUTOMATA_UNION_CARTESIAN_H_ */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..848135ec651125cbf79921a4f98ee7ef0069b726 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp @@ -0,0 +1,229 @@ +/* + * AutomataUnionEpsilonTransition.cpp + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#include "AutomataUnionEpsilonTransition.h" +#include <exception/AlibException.h> +#include "common/PairLabel.h" + +#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; +} + +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)); + for(const auto& q : second.getStates()) + states.insert(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); + automaton::EpsilonNFA res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_SECOND), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + return res; +} + +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)); + for(const auto& q : second.getStates()) + states.insert(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); + automaton::EpsilonNFA res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + for(const auto& t : first.getTransitions()) + for(const auto& q : t.second) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + + for(const auto& t : second.getTransitions()) + for(const auto& q : t.second) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_SECOND), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + return res; +} + +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)); + for(const auto& q : second.getStates()) + states.insert(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states); + automaton::EpsilonNFA res(q0); + + for(const auto& a : first.getInputAlphabet()) + res.addInputSymbol(a); + for(const auto& a : second.getInputAlphabet()) + res.addInputSymbol(a); + + for(const auto& q : states) + res.addState(q); + + for(const auto& q : first.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState())); + res.addTransition(q0, pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + for(const auto& t : first.getTransitions()) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_FIRST), t.second)); + + for(const auto& t : second.getTransitions()) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_SECOND), t.first.first), t.first.second, pairLabel(label::labelFrom(AUTOMATON_SECOND), t.second)); + + 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::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"); +} + +const AutomataUnionEpsilonTransition AutomataUnionEpsilonTransition::AUTOMATA_UNION_EPSILON_TRANSITION; + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h new file mode 100644 index 0000000000000000000000000000000000000000..855fc5b94d9b4ffa067785c0b14a1f87a9a5a2a7 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h @@ -0,0 +1,60 @@ +/* + * AutomataUnionEpsilonTransition.h + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef AUTOMATA_UNION_EPSILON_H_ +#define AUTOMATA_UNION_EPSILON_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/EpsilonNFA.h> + +namespace automaton +{ + +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 +{ +public: + static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second); + + static automaton::EpsilonNFA unification(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second); + static automaton::EpsilonNFA unification(const automaton::NFA& first, const automaton::NFA& second); + static automaton::EpsilonNFA unification(const automaton::DFA& first, const automaton::DFA& second); + +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::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; + + static const AutomataUnionEpsilonTransition AUTOMATA_UNION_EPSILON_TRANSITION; +}; + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* AUTOMATA_UNION_EPSILON_H_ */