diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp index 35ebd2a4526b77d9da7efc704c1490e69ebaccb7..012ea0be36b88882921395d04670b6c5af300239 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp @@ -16,71 +16,8 @@ automaton::Automaton AutomataIntersectionCartesianProduct::intersection(const au return dispatch(first.getData(), second.getData()); } -automaton::DFA<> AutomataIntersectionCartesianProduct::intersection(const automaton::DFA<>& first, const automaton::DFA<>& second) { - 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.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 AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataIntersectionCartesianProduct::intersection); - -automaton::NFA < > AutomataIntersectionCartesianProduct::intersection(const automaton::NFA < > & first, const automaton::NFA < > & second) { - 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.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 AutomataIntersectionCartesianProductNFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataIntersectionCartesianProduct::intersection); +auto AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA < DefaultSymbolType, std::pair < DefaultStateType, DefaultStateType > >, automaton::DFA < > >(AutomataIntersectionCartesianProduct::intersection); +auto AutomataIntersectionCartesianProductNFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::NFA < DefaultSymbolType, std::pair < DefaultStateType, DefaultStateType > >, automaton::NFA < > >(AutomataIntersectionCartesianProduct::intersection); } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h index 7c07ff5d2162c3a21d0a8c1da362e202ec27f735..f9e48a5d42780bc157161b359288bb1724f0e301 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h @@ -24,10 +24,68 @@ class AutomataIntersectionCartesianProduct : public std::PromotingDoubleDispatch public: 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); + template < class SymbolType, class StateType1, class StateType2 > + static automaton::NFA < SymbolType, std::pair < StateType1, StateType2 > > intersection(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 > > intersection(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 > > AutomataIntersectionCartesianProduct::intersection(const automaton::DFA < SymbolType, StateType1 > & first, const automaton::DFA < SymbolType, StateType2 > & second) { + 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.getFinalStates()) + res.addFinalState ( std::make_pair ( p, q ) ); + + for(const std::pair < StateType1, StateType2 > & 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 > > AutomataIntersectionCartesianProduct::intersection(const automaton::NFA < SymbolType, StateType1 > & first, const automaton::NFA < SymbolType, StateType2 > & second) { + 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.getFinalStates()) + res.addFinalState ( std::make_pair ( p, q ) ); + + for(const std::pair < StateType1, StateType2 > & 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 */