diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp index 469aa9f185e2fd84d2e4ad4971f02471b3beb40f..1982aaa90de99cd6fb35a7a238d1070333259138 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp @@ -17,85 +17,8 @@ automaton::Automaton AutomataUnionCartesianProduct::unification(const automaton: return dispatch(first.getData(), second.getData()); } -automaton::DFA<> AutomataUnionCartesianProduct::unification(const automaton::DFA<>& first, const automaton::DFA<>& second) { - if(!first.isTotal() || !second.isTotal()) - throw exception::CommonException("Automata must be total to unify with cartesian product"); - - DefaultStateType q0(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(DefaultStateType(p, q)); - - for(const auto& p : first.getFinalStates()) - for(const auto& q : second.getStates()) - res.addFinalState(DefaultStateType(p, q)); - - for(const auto& p : first.getStates()) - for(const auto& q : second.getFinalStates()) - res.addFinalState(DefaultStateType(p, q)); - - for(const auto& state : res.getStates()) { - const DefaultStateType& label_p = static_cast<const DefaultStatesPairType&>(state.getData()).first; - const DefaultStateType& label_q = static_cast<const DefaultStatesPairType&>(state.getData()).second; - - for(const auto& tp : first.getTransitionsFromState(DefaultStateType(label_p))) - for(const auto& tq : second.getTransitionsFromState(DefaultStateType(label_q))) - if(tp.first.second == tq.first.second) - res.addTransition(state, tp.first.second, DefaultStateType(tp.second, tq.second)); - } - - return res; -} - -auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataUnionCartesianProduct::unification); - -automaton::NFA < > AutomataUnionCartesianProduct::unification(const automaton::NFA < > & first, const automaton::NFA < > & second) { - if(!first.isTotal() || !second.isTotal()) - throw exception::CommonException("Automata must be total to unify with cartesian product"); - - DefaultStateType q0(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(DefaultStateType(p, q)); - - for(const auto& p : first.getFinalStates()) - for(const auto& q : second.getStates()) - res.addFinalState(DefaultStateType(p, q)); - - for(const auto& p : first.getStates()) - for(const auto& q : second.getFinalStates()) - res.addFinalState(DefaultStateType(p, q)); - - for(const auto& state : res.getStates()) { - const DefaultStateType& label_p = static_cast<const DefaultStatesPairType&>(state.getData()).first; - const DefaultStateType& label_q = static_cast<const DefaultStatesPairType&>(state.getData()).second; - - for(const auto& tp : first.getTransitionsFromState(DefaultStateType(label_p))) - for(const auto& tq : second.getTransitionsFromState(DefaultStateType(label_q))) - if(tp.first.second == tq.first.second) - for(const auto& p : tp.second) - for(const auto& q : tq.second) - res.addTransition(state, tp.first.second, DefaultStateType(p, q)); - } - - return res; -} - -auto AutomataUnionCartesianProductNFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataUnionCartesianProduct::unification); +auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA < DefaultSymbolType, std::pair < DefaultStateType, DefaultStateType > >, automaton::DFA < > >(AutomataUnionCartesianProduct::unification); +auto AutomataUnionCartesianProductNFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::NFA < DefaultSymbolType, std::pair < DefaultStateType, DefaultStateType > >, automaton::NFA < > >(AutomataUnionCartesianProduct::unification); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h index feba05962f8bfb9ca68642c2fd14d74f47369d5d..71b72623c173aa895590d582229f4faa7ab100f9 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h @@ -24,10 +24,83 @@ class AutomataUnionCartesianProduct : public std::PromotingDoubleDispatch<Automa 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); + template < class SymbolType, class StateType1, class StateType2 > + static automaton::NFA < SymbolType, std::pair < StateType1, StateType2 > > unification(const automaton::NFA < SymbolType, StateType1 > & first, const automaton::NFA < SymbolType, StateType2 > & second); + template < class SymbolType, class StateType1, class StateType2 > + static automaton::DFA < SymbolType, std::pair < StateType1, StateType2 > > unification(const automaton::DFA < SymbolType, StateType1 > & first, const automaton::DFA < SymbolType, StateType2 > & second); }; +template < class SymbolType, class StateType1, class StateType2 > +automaton::DFA < SymbolType, std::pair < StateType1, StateType2 > > AutomataUnionCartesianProduct::unification(const automaton::DFA < SymbolType, StateType1 > & first, const automaton::DFA < SymbolType, StateType2 > & second) { + if(!first.isTotal() || !second.isTotal()) + throw exception::CommonException("Automata must be total to unify with cartesian product"); + + std::pair < StateType1, StateType2 > q0 ( first.getInitialState(), second.getInitialState() ); + automaton::DFA < SymbolType, std::pair < StateType1, StateType2 > > 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(std::make_pair(p, q)); + + for(const auto& p : first.getFinalStates()) + for(const auto& q : second.getStates()) + res.addFinalState(std::make_pair(p, q)); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getFinalStates()) + res.addFinalState(std::make_pair(p, q)); + + for(const auto& state : res.getStates()) + for(const auto& tp : first.getTransitionsFromState(state.first)) + for(const auto& tq : second.getTransitionsFromState(state.second)) + if(tp.first.second == tq.first.second) + res.addTransition(state, tp.first.second, std::make_pair(tp.second, tq.second)); + + + return res; +} + +template < class SymbolType, class StateType1, class StateType2 > +automaton::NFA < SymbolType, std::pair < StateType1, StateType2 > > AutomataUnionCartesianProduct::unification(const automaton::NFA < SymbolType, StateType1 > & first, const automaton::NFA < SymbolType, StateType2 > & second) { + if(!first.isTotal() || !second.isTotal()) + throw exception::CommonException("Automata must be total to unify with cartesian product"); + + std::pair < StateType1, StateType2 > q0 ( first.getInitialState(), second.getInitialState() ); + automaton::NFA < SymbolType, std::pair < StateType1, StateType2 > > 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(std::make_pair(p, q)); + + for(const auto& p : first.getFinalStates()) + for(const auto& q : second.getStates()) + res.addFinalState(std::make_pair(p, q)); + + for(const auto& p : first.getStates()) + for(const auto& q : second.getFinalStates()) + res.addFinalState(std::make_pair(p, q)); + + for(const auto& state : res.getStates()) + for(const auto& tp : first.getTransitionsFromState(state.first)) + for(const auto& tq : second.getTransitionsFromState(state.second)) + if(tp.first.second == tq.first.second) + for(const auto& p : tp.second) + for(const auto& q : tq.second) + res.addTransition(state, tp.first.second, std::make_pair(p, q)); + + return res; +} + } /* namespace transform */ } /* namespace automaton */