diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..199c99da24a805a2f5304213a0120ea5fc9d0086 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp @@ -0,0 +1,209 @@ +/* + * AutomataConcatenationEpsilonTransition.cpp + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#include "AutomataConcatenationEpsilonTransition.h" +#include <exception/AlibException.h> +#include <label/Label.h> +#include "common/PairLabel.h" + +#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; +} + +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()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + 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)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), q), pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + return res; +} + +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()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + 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)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), q), pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + return res; +} + +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()) + res.addInputSymbol(symbol); + for(const auto& symbol : second.getInputAlphabet()) + res.addInputSymbol(symbol); + + for(const auto& q : first.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_FIRST), q)); + for(const auto& q : second.getStates()) + res.addState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + for(const auto& q : second.getFinalStates()) + res.addFinalState(pairLabel(label::labelFrom(AUTOMATON_SECOND), q)); + + 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)); + + for(const auto& q : first.getFinalStates()) + res.addTransition(pairLabel(label::labelFrom(AUTOMATON_FIRST), q), pairLabel(label::labelFrom(AUTOMATON_SECOND), second.getInitialState())); + + 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::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"); +} + +const AutomataConcatenationEpsilonTransition AutomataConcatenationEpsilonTransition::AUTOMATA_CONCATENATION_EPSILON_TRANSITION; + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h new file mode 100644 index 0000000000000000000000000000000000000000..b1c5c547030ba09746df2c123448edf93f30ba82 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h @@ -0,0 +1,60 @@ +/* + * AutomataConcatenationEpsilonTransition.h + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_ +#define AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/EpsilonNFA.h> + +namespace automaton +{ + +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 +{ +public: + 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::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 AutomataConcatenationEpsilonTransition AUTOMATA_CONCATENATION_EPSILON_TRANSITION; +}; + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* AUTOMATA_CONCATENATION_EPSILON_H_ */ diff --git a/alib2algo/src/automaton/transform/common/PairLabel.cpp b/alib2algo/src/automaton/transform/common/PairLabel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76b42064854024030afd54da44d2e7ce6bbc3198 --- /dev/null +++ b/alib2algo/src/automaton/transform/common/PairLabel.cpp @@ -0,0 +1,26 @@ +/* + * PairLabel.cpp + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#include "PairLabel.h" + +namespace automaton { + +namespace transform { + +automaton::State pairLabel(const label::Label& first, const automaton::State& second) +{ + return automaton::State(label::Label(label::LabelPairLabel(std::make_pair(first, second.getName())))); +} + +automaton::State pairLabel(const automaton::State& first, const automaton::State& second) +{ + return automaton::State(label::Label(label::LabelPairLabel(std::make_pair(first.getName(), second.getName())))); +} + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/common/PairLabel.h b/alib2algo/src/automaton/transform/common/PairLabel.h new file mode 100644 index 0000000000000000000000000000000000000000..ed2e334d54d622d61d5fbf995e14bd5d82e5740a --- /dev/null +++ b/alib2algo/src/automaton/transform/common/PairLabel.h @@ -0,0 +1,25 @@ +/* + * PairLabel.h + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef PAIR_LABEL_H_ +#define PAIR_LABEL_H_ + +#include <automaton/common/State.h> +#include <label/LabelPairLabel.h> + +namespace automaton { + +namespace transform { + +automaton::State pairLabel(const label::Label& first, const automaton::State& second); +automaton::State pairLabel(const automaton::State& first, const automaton::State& second); + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* PAIR_LABEL_H_ */