diff --git a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h index 0b2178b0401d400c125f6a6806bd03d2217b8ab9..aa3d99a0e4759e010863c2f7b5adc8b51eca37e7 100644 --- a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h +++ b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h @@ -39,6 +39,15 @@ namespace simplify { * @sa automaton::simplify::MinimizeBrzozowski */ class MinimizeByPartitioning { + template < class T > + using FA = typename std::conditional < isDFA < T >, automaton::DFA < typename T::SymbolType, ext::set < typename T::StateType > >, automaton::NFA < typename T::SymbolType, ext::set < typename T::StateType > > >::type; + + template < class T > + using FTA = typename std::conditional < isDFTA < T >, automaton::DFTA < typename T::SymbolType, ext::set < typename T::StateType > >, automaton::NFTA < typename T::SymbolType, ext::set < typename T::StateType > > >::type; + + template < class T > + using UnorderedFTA = typename std::conditional < isUnorderedDFTA < T >, automaton::UnorderedDFTA < typename T::SymbolType, ext::set < typename T::StateType > >, automaton::UnorderedNFTA < typename T::SymbolType, ext::set < typename T::StateType > > >::type; + public: /** * Aggregates the given automaton with respect to a state partitioning. @@ -51,22 +60,9 @@ public: * * @return Minimal deterministic finite automaton equivalent to @p nfa */ - template < class SymbolType, class StateType > - static automaton::NFA < SymbolType, ext::set < StateType > > minimize ( const automaton::NFA < SymbolType, StateType > & nfa, const ext::set < ext::set < StateType > > & partitions ); - - /** - * Aggregates the given automaton with respect to a state partitioning. - * - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - * - * @param dfa deterministic finite automaton to minimize. - * @param partitions state partitioning - * - * @return Minimal deterministic finite automaton equivalent to @p dfa - */ - template < class SymbolType, class StateType > - static automaton::DFA < SymbolType, ext::set < StateType > > minimize ( const automaton::DFA < SymbolType, StateType > & dfa, const ext::set < ext::set < StateType > > & partitions ); + template < class T > + requires isDFA < T > || isNFA < T > + static FA < T > minimize ( const T & nfa, const ext::set < ext::set < typename T::StateType > > & partitions ); /** * Aggregates the given automaton with respect to a state partitioning. @@ -79,22 +75,9 @@ public: * * @return Minimal deterministic finite tree automaton equivalent to @p dfa */ - template < class SymbolType, class StateType > - static automaton::DFTA < SymbolType, ext::set < StateType > > minimize ( const automaton::DFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ); - - /** - * Aggregates the given automaton with respect to a state partitioning. - * - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - * - * @param fta nondeterministic finite tree automaton to aggregate. - * @param partitions state partitioning - * - * @return smaller nonderministic finite tree automaton equivalent to @p nfa - */ - template < class SymbolType, class StateType > - static automaton::NFTA < SymbolType, ext::set < StateType > > minimize ( const automaton::NFTA < SymbolType, StateType > & fta, const ext::set < ext::set < StateType > > & partitions ); + template < class T > + requires isDFTA < T > || isNFTA < T > + static FTA < T > minimize ( const T & dfta, const ext::set < ext::set < typename T::StateType > > & partitions ); /** * Aggregates the given automaton with respect to a state partitioning. @@ -107,22 +90,9 @@ public: * * @return Minimal deterministic unordered finite tree automaton equivalent to @p dfa */ - template < class SymbolType, class StateType > - static automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > minimize ( const automaton::UnorderedDFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ); - - /** - * Aggregates the given automaton with respect to a state partitioning. - * - * @tparam SymbolType Type for input symbols. - * @tparam StateType Type for states. - * - * @param fta nondeterministic unordered finite tree automaton to aggregate. - * @param partitions state partitioning - * - * @return smaller nonderministic unordered finite tree automaton equivalent to @p nfa - */ - template < class SymbolType, class StateType > - static automaton::UnorderedNFTA < SymbolType, ext::set < StateType > > minimize ( const automaton::UnorderedNFTA < SymbolType, StateType > & fta, const ext::set < ext::set < StateType > > & partitions ); + template < class T > + requires isUnorderedDFTA < T > || isUnorderedNFTA < T > + static UnorderedFTA < T > minimize ( const T & dfta, const ext::set < ext::set < typename T::StateType > > & partitions ); private: /** @@ -151,11 +121,14 @@ ext::map < StateType, ext::set < StateType > > MinimizeByPartitioning::partition return res; } -template < class SymbolType, class StateType > -automaton::NFA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::NFA < SymbolType, StateType > & nfa, const ext::set < ext::set < StateType > > & partitions ) { +template < class T > +requires isDFA < T > || isNFA < T > +MinimizeByPartitioning::FA < T > MinimizeByPartitioning::minimize ( const T & nfa, const ext::set < ext::set < typename T::StateType > > & partitions ) { + using StateType = typename T::StateType; + const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - automaton::NFA < SymbolType, ext::set < StateType > > res ( statePartitionMap.at ( nfa.getInitialState ( ) ) ); + MinimizeByPartitioning::FA < T > res ( statePartitionMap.at ( nfa.getInitialState ( ) ) ); res.setStates ( partitions ); res.addInputSymbols ( nfa.getInputAlphabet ( ) ); for ( const StateType & state : nfa.getFinalStates ( ) ) @@ -167,47 +140,14 @@ automaton::NFA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::mi return res; } -template < class SymbolType, class StateType > -automaton::DFA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::DFA < SymbolType, StateType > & dfa, const ext::set < ext::set < StateType > > & partitions ) { - const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - - automaton::DFA < SymbolType, ext::set < StateType > > res ( statePartitionMap.at ( dfa.getInitialState ( ) ) ); - res.setStates ( partitions ); - res.addInputSymbols ( dfa.getInputAlphabet ( ) ); - for ( const StateType & state : dfa.getFinalStates ( ) ) - res.addFinalState ( statePartitionMap.at ( state ) ); - - for ( const auto & transition : dfa.getTransitions ( ) ) - res.addTransition ( statePartitionMap.at ( transition.first.first ), transition.first.second, statePartitionMap.at ( transition.second ) ); - - return res; -} - -template < class SymbolType, class StateType > -automaton::DFTA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::DFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ) { - const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - - automaton::DFTA < SymbolType, ext::set < StateType > > res; - res.setStates ( partitions ); - res.addInputSymbols ( dfta.getInputAlphabet ( ) ); - for ( const StateType & state : dfta.getFinalStates ( ) ) - res.addFinalState ( statePartitionMap.at ( state ) ); - - for ( const auto & transition : dfta.getTransitions ( ) ) { - ext::vector < ext::set < StateType > > minimalFrom; - for ( const StateType & from : transition.first.second ) - minimalFrom.push_back ( statePartitionMap.at ( from ) ); - res.addTransition ( transition.first.first, minimalFrom, statePartitionMap.at ( transition.second ) ); - } - - return res; -} +template < class T > +requires isDFTA < T > || isNFTA < T > +MinimizeByPartitioning::FTA < T > MinimizeByPartitioning::minimize ( const T & dfta, const ext::set < ext::set < typename T::StateType > > & partitions ) { + using StateType = typename T::StateType; -template < class SymbolType, class StateType > -automaton::NFTA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::NFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ) { const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - automaton::NFTA < SymbolType, ext::set < StateType > > res; + MinimizeByPartitioning::FTA < T > res; res.setStates ( partitions ); res.addInputSymbols ( dfta.getInputAlphabet ( ) ); for ( const StateType & state : dfta.getFinalStates ( ) ) @@ -223,31 +163,14 @@ automaton::NFTA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::m return res; } -template < class SymbolType, class StateType > -automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::UnorderedDFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ) { - const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - - automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > res; - res.setStates ( partitions ); - res.addInputSymbols ( dfta.getInputAlphabet ( ) ); - for ( const StateType & state : dfta.getFinalStates ( ) ) - res.addFinalState ( statePartitionMap.at ( state ) ); - - for ( const auto & transition : dfta.getTransitions ( ) ) { - ext::multiset < ext::set < StateType > > minimalFrom; - for ( const StateType & from : transition.first.second ) - minimalFrom.insert ( statePartitionMap.at ( from ) ); - res.addTransition ( transition.first.first, minimalFrom, statePartitionMap.at ( transition.second ) ); - } - - return res; -} +template < class T > +requires isUnorderedDFTA < T > || isUnorderedNFTA < T > +MinimizeByPartitioning::UnorderedFTA < T > MinimizeByPartitioning::minimize ( const T & dfta, const ext::set < ext::set < typename T::StateType > > & partitions ) { + using StateType = typename T::StateType; -template < class SymbolType, class StateType > -automaton::UnorderedNFTA < SymbolType, ext::set < StateType > > MinimizeByPartitioning::minimize ( const automaton::UnorderedNFTA < SymbolType, StateType > & dfta, const ext::set < ext::set < StateType > > & partitions ) { const ext::map < StateType, ext::set < StateType > > statePartitionMap = partitionMap ( partitions ); - automaton::UnorderedNFTA < SymbolType, ext::set < StateType > > res; + MinimizeByPartitioning::UnorderedFTA < T > res; res.setStates ( partitions ); res.addInputSymbols ( dfta.getInputAlphabet ( ) ); for ( const StateType & state : dfta.getFinalStates ( ) )