From 5a23a72c2209460b4b71f08c5a0adb8db4b41d36 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 3 Feb 2020 21:39:06 +0100
Subject: [PATCH] minimize by partitioning for unordered fta

---
 .../simplify/MinimizeByPartitioning.cpp       | 12 ++++
 .../simplify/MinimizeByPartitioning.h         | 70 +++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.cpp b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.cpp
index 82a2b39975..c0ec7eb170 100644
--- a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.cpp
+++ b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.cpp
@@ -34,4 +34,16 @@ auto MinimizeDistinguishableStatesNFTA = registration::AbstractRegister < automa
 @param dfta finite tree automaton to minimize.\n\
 @return Minimal deterministic finite tree automaton equivalent to @p dfta" );
 
+auto MinimizeDistinguishableStatesUnorderedDFTA = registration::AbstractRegister < automaton::simplify::MinimizeByPartitioning, automaton::UnorderedDFTA < DefaultSymbolType, ext::set < DefaultStateType > >, const automaton::UnorderedDFTA < > &, const ext::set < ext::set < DefaultStateType > > & > ( automaton::simplify::MinimizeByPartitioning::minimize, "dfta" ).setDocumentation (
+"Minimizes the given automaton using Distinguishable states method.\n\
+\n\
+@param dfta unordered finite tree automaton to minimize.\n\
+@return Minimal deterministic unordered finite tree automaton equivalent to @p dfta" );
+
+auto MinimizeDistinguishableStatesUnorderedNFTA = registration::AbstractRegister < automaton::simplify::MinimizeByPartitioning, automaton::UnorderedNFTA < DefaultSymbolType, ext::set < DefaultStateType > >, const automaton::UnorderedNFTA < > &, const ext::set < ext::set < DefaultStateType > > & > ( automaton::simplify::MinimizeByPartitioning::minimize, "dfta" ).setDocumentation (
+"Minimizes the given automaton using Distinguishable states method.\n\
+\n\
+@param dfta unordered finite tree automaton to minimize.\n\
+@return Minimal deterministic unordered finite tree automaton equivalent to @p dfta" );
+
 } /* namespace */
diff --git a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h
index 839e8f4626..b4bd8d261e 100644
--- a/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h
+++ b/alib2algo/src/automaton/simplify/MinimizeByPartitioning.h
@@ -31,6 +31,8 @@
 #include <automaton/FSM/NFA.h>
 #include <automaton/TA/DFTA.h>
 #include <automaton/TA/NFTA.h>
+#include <automaton/TA/UnorderedDFTA.h>
+#include <automaton/TA/UnorderedNFTA.h>
 
 namespace automaton {
 
@@ -100,6 +102,34 @@ public:
 	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 );
 
+	/**
+	 * Aggregates the given automaton with respect to a state partitioning.
+	 *
+	 * @tparam SymbolType Type for input symbols.
+	 * @tparam StateType Type for states.
+	 *
+	 * @param dfta deterministic unordered finite tree automaton to minimize.
+	 * @param partitions state partitioning
+	 *
+	 * @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 );
+
 private:
 	/**
 	 * Helper method to create mapping from state to the corresponding partition
@@ -199,6 +229,46 @@ 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 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;
+	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;
+}
+
 } /* namespace simplify */
 
 } /* namespace automaton */
-- 
GitLab