diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp index 03a2bc1f2662fb793b64e439fc9698707431df0f..e0522d3ad818533cd90170e2a00f65121c780ce6 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp @@ -24,4 +24,11 @@ auto AutomataIntersectionCartesianProductDFA2 = registration::AbstractRegister < @param second Second automaton (A2)\n\ @return (non)deterministic FA representing the intersection of two automata" ); +auto AutomataIntersectionCartesianProductDFTA = registration::AbstractRegister < automaton::transform::AutomataIntersectionCartesianProduct, automaton::DFTA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFTA < > &, const automaton::DFTA < > & > ( automaton::transform::AutomataIntersectionCartesianProduct::intersection ).setDocumentation ( +"Intersects two finite automata.\n\ +\n\ +@param first First automaton (A1)\n\ +@param second Second automaton (A2)\n\ +@return (non)deterministic FA representing the intersection of two automata" ); + } /* namespace */ diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h index bca707e125d8f31dfde1950c36181a73c2beef8d..dca16548e1df3062c6dedb13fe6bb79f6fa0b3d8 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h @@ -24,7 +24,10 @@ #ifndef AUTOMATA_INTERSECTION_CARTESIAN_H_ #define AUTOMATA_INTERSECTION_CARTESIAN_H_ +#include <alib/foreach> + #include <automaton/FSM/EpsilonNFA.h> +#include <automaton/TA/NFTA.h> namespace automaton { @@ -54,6 +57,12 @@ public: */ template < class SymbolType, class StateType1, class StateType2 > static automaton::DFA < SymbolType, ext::pair < StateType1, StateType2 > > intersection(const automaton::DFA < SymbolType, StateType1 > & first, const automaton::DFA < SymbolType, StateType2 > & second); + + /** + * @overload + */ + template < class SymbolType, class StateType1, class StateType2 > + static automaton::DFTA < SymbolType, ext::pair < StateType1, StateType2 > > intersection(const automaton::DFTA < SymbolType, StateType1 > & first, const automaton::DFTA < SymbolType, StateType2 > & second); }; template < class SymbolType, class StateType1, class StateType2 > @@ -110,6 +119,36 @@ automaton::NFA < SymbolType, ext::pair < StateType1, StateType2 > > AutomataInte return res; } +template < class SymbolType, class StateType1, class StateType2 > +automaton::DFTA < SymbolType, ext::pair < StateType1, StateType2 > > AutomataIntersectionCartesianProduct::intersection(const automaton::DFTA < SymbolType, StateType1 > & first, const automaton::DFTA < SymbolType, StateType2 > & second) { + automaton::DFTA < SymbolType, ext::pair < StateType1, StateType2 > > res; + + 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 ( ext::make_pair ( p, q ) ); + + for(const auto& p : first.getFinalStates()) + for(const auto& q : second.getFinalStates()) + res.addFinalState ( ext::make_pair ( p, q ) ); + + for(const auto & tp : first.getTransitions ( ) ) + for(const auto & tq : second.getTransitions ( ) ) + if(tp.first.first == tq.first.first) { + ext::vector < ext::pair < StateType1, StateType2 > > source; + for ( ext::tuple < const StateType1 &, const StateType2 & > singleSourceState : ext::make_tuple_foreach ( tp.first.second, tq.first.second ) ) + source.push_back ( ext::make_pair ( std::get < 0 > ( singleSourceState ), std::get < 1 > ( singleSourceState ) ) ); + + res.addTransition ( tp.first.first, source, ext::make_pair ( tp.second, tq.second ) ); + } + + return res; +} + } /* namespace transform */ } /* namespace automaton */ diff --git a/examples2/aql/avy_tree_automata_assignment_solution.aql b/examples2/aql/avy_tree_automata_assignment_solution.aql new file mode 100644 index 0000000000000000000000000000000000000000..d852ab82cc49222d5363e81c649ba6bd64d9f456 --- /dev/null +++ b/examples2/aql/avy_tree_automata_assignment_solution.aql @@ -0,0 +1,13 @@ +execute string::Parse @Automaton "DFTA alter 2 concat 2 iter 1 a 0 b 0 c 0 eps 0 emp 0 +- - - [] - - - - al +- - - - [] [] [] [] as> +[al,al] [al,al] - - - - - - as +[as,as] [as,as] [as] - - - - - as +[al,as],[as,al] [al,as],[as,al] - - - - - - al" > $evenA +execute string::Parse @Automaton "DFTA alter 2 concat 2 iter 1 a 0 b 0 c 0 eps 0 emp 0 +- - - - [] - - - bl> +- - - [] - [] [] [] bs +[bl,bl] [bl,bl] - - - - - - bs +[bs,bs] [bs,bs] [bs] - - - - - bs +[bl,bs],[bs,bl] [bl,bs],[bs,bl] - - - - - - bl" > $oddB +print automaton::transform::AutomataIntersectionCartesianProduct $evenA $oddB | string::Compose -