From ef3f93dc24cfe88e72a97f0de1214b83083e2761 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Tr=C3=A1vn=C3=AD=C4=8Dek?= <jan.travnicek@fit.cvut.cz>
Date: Tue, 14 Dec 2021 00:48:45 +0100
Subject: [PATCH] algo: simplify minimize by partitioning algo

---
 .../simplify/MinimizeByPartitioning.h         | 145 ++++--------------
 1 file changed, 34 insertions(+), 111 deletions(-)

diff --git a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h
index 0b2178b040..aa3d99a0e4 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 ( ) )
-- 
GitLab