From cf31335555c67beb5e1a025c848fa68865dde2b9 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 3 Dec 2019 19:18:56 +0100
Subject: [PATCH] Unordered DFTA and Unordered pattern matching with FTA

---
 .../exact/ExactPatternMatchingAutomaton.cpp   |   4 +
 .../exact/ExactPatternMatchingAutomaton.h     |  58 ++
 .../exact/ExactSubtreeMatchingAutomaton.cpp   |   2 +
 .../exact/ExactSubtreeMatchingAutomaton.h     |  28 +
 .../src/automaton/determinize/Determinize.cpp |  14 +
 .../src/automaton/determinize/Determinize.h   |  32 +
 .../determinize/DeterminizeNFTAPart.hxx       |  70 ++
 alib2algo/src/automaton/run/Occurrences.cpp   |   7 +
 alib2algo/src/automaton/run/Occurrences.h     |  23 +
 alib2algo/src/automaton/run/Run.h             |  85 +++
 alib2data/src/automaton/TA/UnorderedDFTA.cpp  |  18 +
 alib2data/src/automaton/TA/UnorderedDFTA.h    | 633 +++++++++++++++++
 alib2data/src/automaton/TA/UnorderedNFTA.cpp  |  21 +
 alib2data/src/automaton/TA/UnorderedNFTA.h    | 661 ++++++++++++++++++
 .../src/automaton/common/AutomatonNormalize.h |  13 +
 .../test-src/tests/arbologyTest.cpp           |  35 +
 16 files changed, 1704 insertions(+)
 create mode 100644 alib2data/src/automaton/TA/UnorderedDFTA.cpp
 create mode 100644 alib2data/src/automaton/TA/UnorderedDFTA.h
 create mode 100644 alib2data/src/automaton/TA/UnorderedNFTA.cpp
 create mode 100644 alib2data/src/automaton/TA/UnorderedNFTA.h

diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
index f2bcff82e3..3161fe9514 100644
--- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp
@@ -22,4 +22,8 @@ auto ExactPatternMatchingAutomatonRankedTree = registration::AbstractRegister <
 
 auto ExactPatternMatchingAutomatonRankedPattern = registration::AbstractRegister < arbology::exact::ExactPatternMatchingAutomaton, automaton::NFTA < DefaultSymbolType, unsigned >, const tree::RankedPattern < > & > ( arbology::exact::ExactPatternMatchingAutomaton::construct );
 
+auto ExactPatternMatchingAutomatonUnorderedRankedTree = registration::AbstractRegister < arbology::exact::ExactPatternMatchingAutomaton, automaton::UnorderedNFTA < DefaultSymbolType, unsigned >, const tree::UnorderedRankedTree < > & > ( arbology::exact::ExactPatternMatchingAutomaton::construct );
+
+auto ExactPatternMatchingAutomatonUnorderedRankedPattern = registration::AbstractRegister < arbology::exact::ExactPatternMatchingAutomaton, automaton::UnorderedNFTA < DefaultSymbolType, unsigned >, const tree::UnorderedRankedPattern < > & > ( arbology::exact::ExactPatternMatchingAutomaton::construct );
+
 } /* namespace */
diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
index 6b098de11b..0da09b3e75 100644
--- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
+++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h
@@ -14,6 +14,8 @@
 
 #include <tree/ranked/RankedTree.h>
 #include <tree/ranked/RankedPattern.h>
+#include <tree/ranked/UnorderedRankedTree.h>
+#include <tree/ranked/UnorderedRankedPattern.h>
 #include <tree/ranked/PrefixRankedTree.h>
 #include <tree/ranked/PrefixRankedPattern.h>
 #include <tree/ranked/PrefixRankedBarTree.h>
@@ -23,6 +25,7 @@
 #include <automaton/PDA/VisiblyPushdownNPDA.h>
 #include <automaton/PDA/NPDA.h>
 #include <automaton/TA/NFTA.h>
+#include <automaton/TA/UnorderedNFTA.h>
 
 #include <common/ranked_symbol.hpp>
 #include <alphabet/BottomOfTheStackSymbol.h>
@@ -55,6 +58,12 @@ public:
 	template < class SymbolType >
 	static automaton::NFTA < SymbolType, unsigned > construct ( const tree::RankedPattern < SymbolType > & pattern );
 
+	template < class SymbolType >
+	static automaton::UnorderedNFTA < SymbolType, unsigned > construct ( const tree::UnorderedRankedTree < SymbolType > & pattern );
+
+	template < class SymbolType >
+	static automaton::UnorderedNFTA < SymbolType, unsigned > construct ( const tree::UnorderedRankedPattern < SymbolType > & pattern );
+
 };
 
 template < class SymbolType >
@@ -261,6 +270,55 @@ automaton::NFTA < SymbolType, unsigned > ExactPatternMatchingAutomaton::construc
 	return res;
 }
 
+template < class SymbolType >
+automaton::UnorderedNFTA < SymbolType, unsigned > ExactPatternMatchingAutomaton::construct ( const tree::UnorderedRankedTree < SymbolType > & pattern ) {
+	return ExactSubtreeMatchingAutomaton::construct ( pattern );
+}
+
+template < class SymbolType >
+unsigned constructRecursivePattern ( const ext::tree < common::ranked_symbol < SymbolType > > & node, automaton::UnorderedNFTA < SymbolType, unsigned > & res, const common::ranked_symbol < SymbolType > & subtreeWildcard, unsigned & nextState ) {
+	if ( node.getData ( ) == subtreeWildcard ) {
+		unsigned state = nextState++;
+		res.addState ( state );
+
+		for ( const common::ranked_symbol < SymbolType > & symbol : res.getInputAlphabet ( ) ) {
+			ext::multiset < unsigned > states;
+
+			for ( unsigned i = 0; i < ( unsigned ) symbol.getRank ( ); i++ )
+				states.insert ( state );
+
+			res.addTransition ( symbol, states, state );
+		}
+
+		return state;
+	} else {
+		ext::multiset < unsigned > states;
+
+		for ( const ext::tree < common::ranked_symbol < SymbolType > > & child : node.getChildren ( ) )
+			states.insert ( constructRecursivePattern ( child, res, subtreeWildcard,  nextState ) );
+
+		unsigned state = nextState++;
+		res.addState ( state );
+		res.addTransition ( node.getData ( ), states, state );
+		return state;
+	}
+}
+
+template < class SymbolType >
+automaton::UnorderedNFTA < SymbolType, unsigned > ExactPatternMatchingAutomaton::construct ( const tree::UnorderedRankedPattern < SymbolType > & pattern ) {
+	ext::set < common::ranked_symbol < SymbolType> > alphabet = pattern.getAlphabet ( );
+
+	alphabet.erase ( pattern.getSubtreeWildcard ( ) );
+
+	automaton::UnorderedNFTA < SymbolType, unsigned > res;
+	res.setInputAlphabet ( alphabet );
+
+	unsigned nextState = 0;
+
+	res.addFinalState ( constructRecursivePattern ( pattern.getContent ( ), res, pattern.getSubtreeWildcard ( ), nextState ) );
+	return res;
+}
+
 } /* namespace exact */
 
 } /* namespace arbology */
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
index 74ea0b8b00..c8327fefbe 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp
@@ -16,4 +16,6 @@ auto ExactSubtreeMatchingAutomatonPrefixRankedBarTree = registration::AbstractRe
 
 auto ExactSubtreeMatchingAutomatonRankedTree = registration::AbstractRegister < arbology::exact::ExactSubtreeMatchingAutomaton, automaton::NFTA < DefaultSymbolType, unsigned >, const tree::RankedTree < > & > ( arbology::exact::ExactSubtreeMatchingAutomaton::construct );
 
+auto ExactSubtreeMatchingAutomatonUnorderedRankedTree = registration::AbstractRegister < arbology::exact::ExactSubtreeMatchingAutomaton, automaton::UnorderedNFTA < DefaultSymbolType, unsigned >, const tree::UnorderedRankedTree < > & > ( arbology::exact::ExactSubtreeMatchingAutomaton::construct );
+
 } /* namespace */
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
index 5b6b53a225..0524631635 100644
--- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h
@@ -11,9 +11,11 @@
 #include <tree/ranked/PrefixRankedBarTree.h>
 #include <tree/ranked/PrefixRankedTree.h>
 #include <tree/ranked/RankedTree.h>
+#include <tree/ranked/UnorderedRankedTree.h>
 
 #include <automaton/PDA/InputDrivenNPDA.h>
 #include <automaton/TA/NFTA.h>
+#include <automaton/TA/UnorderedNFTA.h>
 
 #include <alphabet/BottomOfTheStackSymbol.h>
 
@@ -36,6 +38,9 @@ public:
 	template < class SymbolType >
 	static automaton::NFTA < SymbolType, unsigned > construct ( const tree::RankedTree < SymbolType > & pattern );
 
+	template < class SymbolType >
+	static automaton::UnorderedNFTA < SymbolType, unsigned > construct ( const tree::UnorderedRankedTree < SymbolType > & pattern );
+
 };
 
 template < class SymbolType >
@@ -119,6 +124,29 @@ automaton::NFTA < SymbolType, unsigned > ExactSubtreeMatchingAutomaton::construc
 	return res;
 }
 
+template < class SymbolType >
+unsigned constructRecursive ( const ext::tree < common::ranked_symbol < SymbolType > > & node, automaton::UnorderedNFTA < SymbolType, unsigned > & res, unsigned & nextState ) {
+	ext::multiset < unsigned > states;
+
+	for ( const ext::tree < common::ranked_symbol < SymbolType > > & child : node.getChildren ( ) )
+		states.insert ( constructRecursive ( child, res, nextState ) );
+
+	unsigned state = nextState++;
+	res.addState ( state );
+	res.addTransition ( node.getData ( ), states, state );
+	return state;
+}
+
+template < class SymbolType >
+automaton::UnorderedNFTA < SymbolType, unsigned > ExactSubtreeMatchingAutomaton::construct ( const tree::UnorderedRankedTree < SymbolType > & pattern ) {
+	automaton::UnorderedNFTA < SymbolType, unsigned > res;
+
+	res.setInputAlphabet ( pattern.getAlphabet ( ) );
+	unsigned nextState = 0;
+	res.addFinalState ( constructRecursive ( pattern.getContent ( ), res, nextState ) );
+	return res;
+}
+
 } /* namespace exact */
 
 } /* namespace arbology */
diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
index b5b4185c61..6381a25f3f 100644
--- a/alib2algo/src/automaton/determinize/Determinize.cpp
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -16,6 +16,7 @@
 #include <automaton/PDA/VisiblyPushdownDPDA.h>
 #include <automaton/TM/OneTapeDTM.h>
 #include <automaton/TA/DFTA.h>
+#include <automaton/TA/UnorderedDFTA.h>
 #include <automaton/PDA/RealTimeHeightDeterministicNPDA.h>
 #include <registration/AlgoRegistration.hpp>
 
@@ -40,6 +41,19 @@ auto DeterminizeMultiInitialStateNFA = registration::AbstractRegister < automato
 @param nfa nondeterministic finite automaton with multiple initial states\n\
 @return deterministic finite automaton equivalent to @p nfa" );
 
+auto DeterminizeUnorderedDFTA = registration::AbstractRegister < automaton::determinize::Determinize, automaton::UnorderedDFTA < >, const automaton::UnorderedDFTA < > & > ( automaton::determinize::Determinize::determinize, "dfta" ).setDocumentation (
+"Determinization of deterministic finite tree automata.\n\
+Implemented as a no-op.\n\
+\n\
+@param dfta deterministic finite tree automaton\n\
+@return deterministic finite tree automaton equivalent to @p dfta" );
+
+auto DeterminizeUnorderedNFTA = registration::AbstractRegister < automaton::determinize::Determinize, automaton::UnorderedDFTA < DefaultSymbolType, ext::set < DefaultSymbolType > >, const automaton::UnorderedNFTA < > & > ( automaton::determinize::Determinize::determinize, "nfta" ).setDocumentation (
+"Implementation of subset determinization for nondeterministic finite tree automata.\n\
+\n\
+@param nfta nondeterministic finite tree automaton\n\
+@return deterministic finite tree automaton equivalent to @p nfta" );
+
 auto DeterminizeDFTA = registration::AbstractRegister < automaton::determinize::Determinize, automaton::DFTA < >, const automaton::DFTA < > & > ( automaton::determinize::Determinize::determinize, "dfta" ).setDocumentation (
 "Determinization of deterministic finite tree automata.\n\
 Implemented as a no-op.\n\
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index 6406acb071..b88e103672 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -37,6 +37,8 @@
 #include <automaton/FSM/MultiInitialStateNFA.h>
 #include <automaton/TA/NFTA.h>
 #include <automaton/TA/DFTA.h>
+#include <automaton/TA/UnorderedNFTA.h>
+#include <automaton/TA/UnorderedDFTA.h>
 
 #include <automaton/transform/PDAToRHPDA.h>
 #include <automaton/transform/RHPDAToPDA.h>
@@ -116,6 +118,31 @@ public:
 	template < class SymbolType, class StateType >
 	static automaton::DFTA < SymbolType, ext::set < StateType > > determinize ( const automaton::NFTA < SymbolType, StateType > & nfta );
 
+	/**
+	 * Determinization of deterministic finite tree automata.
+	 * Implemented as a no-op.
+	 *
+	 * @tparam SymbolType Type for the input symbols.
+	 * @tparam RankType Type for the rank (arity) in ranked alphabet.
+	 * @tparam StateType Type for the states.
+	 * @param dfta deterministic finite tree automaton
+	 * @return deterministic finite tree automaton equivalent to @p dfta
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::UnorderedDFTA < SymbolType, StateType > determinize ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton );
+
+	/**
+	 * Implementation of subset determinization for nondeterministic finite tree automata.
+	 *
+	 * @tparam SymbolType Type for the input symbols.
+	 * @tparam RankType Type for the rank (arity) in ranked alphabet.
+	 * @tparam StateType Type for the states.
+	 * @param nfta nondeterministic finite tree automaton
+	 * @return deterministic finite tree automaton equivalent to @p nfta
+	 */
+	template < class SymbolType, class StateType >
+	static automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > determinize ( const automaton::UnorderedNFTA < SymbolType, StateType > & nfta );
+
 	/**
 	 * Determinization of deterministic input-driven pushdown automata.
 	 * Implemented as a no-op.
@@ -252,6 +279,11 @@ automaton::DFTA < SymbolType, StateType > Determinize::determinize ( const autom
 	return automaton;
 }
 
+template < class SymbolType, class StateType >
+automaton::UnorderedDFTA < SymbolType, StateType > Determinize::determinize ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton ) {
+	return automaton;
+}
+
 template < class InputSymbolType, class PushdownSymbolType, class StateType >
 automaton::InputDrivenDPDA < InputSymbolType, PushdownSymbolType, StateType > Determinize::determinize ( const automaton::InputDrivenDPDA < InputSymbolType, PushdownSymbolType, StateType > & automaton ) {
 	return automaton;
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.hxx
index 5853e929d0..b75caaf06c 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.hxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.hxx
@@ -82,6 +82,76 @@ automaton::DFTA < SymbolType, ext::set < StateType > > Determinize::determinize
 	return res;
 }
 
+
+template < class SymbolType, class StateType >
+void constructTransitions ( const common::ranked_symbol < SymbolType > & symbol, typename ext::multiset < StateType >::const_iterator state, typename ext::multiset < StateType >::const_iterator end, const StateType & rhs, const ext::multimap < StateType, ext::set < StateType > > & nftaStateToDftaStates, ext::multiset < ext::set < StateType > > & transitionLHS, ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < ext::set < StateType > > >, ext::set < StateType > > & resultTransition ) {
+	if ( state == end ) {
+		resultTransition [ ext::make_pair ( symbol, transitionLHS ) ].insert ( rhs );
+	} else {
+		for ( const std::pair < const StateType, ext::set < StateType > > & dftaState : nftaStateToDftaStates.equal_range ( * state ) ) {
+			transitionLHS.insert ( dftaState.second );
+			constructTransitions ( symbol, std::next ( state ), end, rhs, nftaStateToDftaStates, transitionLHS, resultTransition );
+			transitionLHS.erase ( transitionLHS.find ( dftaState.second ) );
+		}
+	}
+}
+
+template < class SymbolType, class StateType >
+automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > Determinize::determinize ( const automaton::UnorderedNFTA < SymbolType, StateType > & nfta ) {
+	automaton::UnorderedDFTA < SymbolType, ext::set < StateType > > res;
+
+	res.setInputAlphabet ( nfta.getInputAlphabet ( ) );
+
+	ext::multimap < StateType, ext::set < StateType > > nftaStateToDftaStates; // each dfta state must be inserted only once to each nfta d-subset state
+
+	for ( const auto & symbol : nfta.getInputAlphabet ( ) ) {
+		if ( symbol.getRank ( ) != 0 )
+			continue;
+
+		ext::set < StateType > dftaState;
+		ext::multiset < StateType > source { };
+		for ( const auto & transition : nfta.getTransitions ( ).equal_range ( ext::tie ( symbol, source ) ) )
+			dftaState.insert ( transition.second );
+
+		for ( const auto & state : dftaState )
+			nftaStateToDftaStates.insert ( state, dftaState );
+
+		res.addState ( dftaState );
+
+		res.addTransition ( symbol, ext::multiset < ext::set < StateType > > { }, dftaState );
+	}
+
+	bool added = true;
+	while ( added ) {
+		added = false;
+
+		ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < ext::set < StateType > > >, ext::set < StateType > > transitions;
+
+		for ( const auto & transition : nfta.getTransitions ( ) ) {
+			ext::multiset < ext::set < StateType > > transitionLHS;
+			constructTransitions ( transition.first.first, transition.first.second.begin ( ), transition.first.second.end ( ), transition.second, nftaStateToDftaStates, transitionLHS, transitions );
+		}
+
+		for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < ext::set < StateType > > >, ext::set < StateType > > & transition : transitions ) {
+			if ( res.addState ( transition.second ) ) {
+				added = true;
+
+				for ( const auto & state : transition.second )
+					nftaStateToDftaStates.insert ( state, transition.second );
+			}
+			res.addTransition ( transition.first.first, transition.first.second, transition.second );
+		}
+
+	}
+
+	const ext::set < StateType > & finalLabels = nfta.getFinalStates();
+	for ( const ext::set < StateType > & dfaState : res.getStates ( ) )
+		if ( ! ext::excludes ( finalLabels.begin ( ), finalLabels.end ( ), dfaState.begin ( ), dfaState.end ( ) ) )
+			res.addFinalState ( dfaState );
+
+	return res;
+}
+
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp
index 3fe9695c9c..c6a15993e2 100644
--- a/alib2algo/src/automaton/run/Occurrences.cpp
+++ b/alib2algo/src/automaton/run/Occurrences.cpp
@@ -24,6 +24,13 @@ auto OccurrencesDFTARankedTree = registration::AbstractRegister < automaton::run
 @param string the input of the automaton\n\
 @return set of indexes to the string where the automaton passed a final state" );
 
+auto OccurrencesUnorderedDFTARankedTree = registration::AbstractRegister < automaton::run::Occurrences, ext::set < unsigned >, const automaton::UnorderedDFTA < > &, const tree::UnorderedRankedTree < > & > ( automaton::run::Occurrences::occurrences, "automaton", "tree" ).setDocumentation (
+"Automaton occurrences run implementation.\n\
+\n\
+@param automaton the runned automaton\n\
+@param string the input of the automaton\n\
+@return set of indexes to the string where the automaton passed a final state" );
+
 auto OccurrencesInputDrivenDPDALinearString = registration::AbstractRegister < automaton::run::Occurrences, ext::set < unsigned >, const automaton::InputDrivenDPDA < > &, const string::LinearString < > & > ( automaton::run::Occurrences::occurrences, "automaton", "string" ).setDocumentation (
 "Automaton occurrences run implementation.\n\
 \n\
diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h
index 166265c603..eda7144c6d 100644
--- a/alib2algo/src/automaton/run/Occurrences.h
+++ b/alib2algo/src/automaton/run/Occurrences.h
@@ -14,6 +14,7 @@
 #include "Run.h"
 #include <automaton/FSM/DFA.h>
 #include <automaton/TA/DFTA.h>
+#include <automaton/TA/UnorderedDFTA.h>
 #include <automaton/PDA/InputDrivenDPDA.h>
 #include <automaton/PDA/VisiblyPushdownDPDA.h>
 #include <automaton/PDA/RealTimeHeightDeterministicDPDA.h>
@@ -60,6 +61,21 @@ public:
 	template < class SymbolType, class StateType >
 	static ext::set < unsigned > occurrences ( const automaton::DFTA < SymbolType, StateType > & automaton, const tree::RankedTree < SymbolType > & tree );
 
+	/**
+	 * \override
+	 *
+	 * \tparam SymbolType type of symbols of tree nodes and terminal symbols of the runned automaton
+	 * \tparam RankType type of ranks of tree nodes and terminal symbols of the runned automaton
+	 * \tparam StateType type of states of the runned automaton
+	 *
+	 * \param automaton the runned automaton
+	 * \param string the input of the automaton
+	 *
+	 * \return set of indexes to the tree where the automaton passed a final state (as in the postorder traversal)
+	 */
+	template < class SymbolType, class StateType >
+	static ext::set < unsigned > occurrences ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const tree::UnorderedRankedTree < SymbolType > & tree );
+
 	/**
 	 * \override
 	 *
@@ -136,6 +152,13 @@ ext::set < unsigned > Occurrences::occurrences ( const automaton::DFTA < SymbolT
 	return std::get < 2 > ( res );
 }
 
+template < class SymbolType, class StateType >
+ext::set < unsigned > Occurrences::occurrences ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const tree::UnorderedRankedTree < SymbolType > & tree ) {
+	ext::tuple < bool, StateType, ext::set < unsigned > > res = Run::calculateState ( automaton, tree );
+
+	return std::get < 2 > ( res );
+}
+
 template < class InputSymbolType, class PushdownStoreSymbolType, class StateType >
 ext::set < unsigned > Occurrences::occurrences ( const automaton::InputDrivenDPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & automaton, const string::LinearString < InputSymbolType > & string ) {
 	ext::tuple < bool, StateType, ext::set < unsigned >, ext::deque < PushdownStoreSymbolType > > res = Run::calculateState ( automaton, string );
diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h
index 4c6a05225a..1c51792b96 100644
--- a/alib2algo/src/automaton/run/Run.h
+++ b/alib2algo/src/automaton/run/Run.h
@@ -10,12 +10,14 @@
 
 #include <string/LinearString.h>
 #include <tree/ranked/RankedTree.h>
+#include <tree/ranked/UnorderedRankedTree.h>
 
 #include <automaton/FSM/DFA.h>
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/EpsilonNFA.h>
 #include <automaton/TA/DFTA.h>
 #include <automaton/TA/NFTA.h>
+#include <automaton/TA/UnorderedDFTA.h>
 #include <automaton/PDA/InputDrivenDPDA.h>
 #include <automaton/PDA/VisiblyPushdownDPDA.h>
 #include <automaton/PDA/RealTimeHeightDeterministicDPDA.h>
@@ -59,6 +61,25 @@ class Run {
 	template < class SymbolType, class StateType >
 	static ext::pair < bool, StateType > calculateState ( const automaton::DFTA < SymbolType, StateType > & automaton, const ext::tree < common::ranked_symbol < SymbolType > > & node, ext::set < unsigned > & occ, unsigned & i );
 
+	/**
+	 * Recursive implementation of automaton run over a tree.
+	 *
+	 * \tparam SymbolType type of symbols of tree nodes and terminal symbols of the runned automaton
+	 * \tparam RankType type of ranks of tree nodes and terminal symbols of the runned automaton
+	 * \tparam StateType type of states of the runned automaton
+	 *
+	 * \param automaton the runned automaton
+	 * \param string the input of the automaton
+	 * \param occ the set of collected occurrences
+	 * \param i the index to the tree following the postorder traversal
+	 *
+	 * \return pair of
+	 *	true if the automaton does not fail to find transitions, false otherwise
+	 *	state where the computation ended
+	 */
+	template < class SymbolType, class StateType >
+	static ext::pair < bool, StateType > calculateState ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const ext::tree < common::ranked_symbol < SymbolType > > & node, ext::set < unsigned > & occ, unsigned & i );
+
 	/**
 	 * \override
 	 *
@@ -161,6 +182,24 @@ public:
 	template < class SymbolType, class StateType >
 	static ext::tuple < bool, StateType, ext::set < unsigned > > calculateState ( const automaton::DFTA < SymbolType, StateType > & automaton, const tree::RankedTree < SymbolType > & tree );
 
+	/**
+	 * \override
+	 *
+	 * \tparam SymbolType type of symbols of tree nodes and terminal symbols of the runned automaton
+	 * \tparam RankType type of ranks of tree nodes and terminal symbols of the runned automaton
+	 * \tparam StateType type of states of the runned automaton
+	 *
+	 * \param automaton the runned automaton
+	 * \param string the input of the automaton
+	 *
+	 * \return tuple of
+	 *	true if the automaton does not fail to find transitions, false otherwise
+	 *	state where the run stopped
+	 *	set of indexes to the tree where the automaton passed a final state (as in the postorder traversal)
+	 */
+	template < class SymbolType, class StateType >
+	static ext::tuple < bool, StateType, ext::set < unsigned > > calculateState ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const tree::UnorderedRankedTree < SymbolType > & tree );
+
 	/**
 	 * \override
 	 *
@@ -448,6 +487,52 @@ ext::tuple < bool, StateType, ext::set < unsigned > > Run::calculateState ( cons
 
 // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
+
+template < class SymbolType, class StateType >
+ext::pair < bool, StateType > Run::calculateState ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const ext::tree < common::ranked_symbol < SymbolType > > & node, ext::set < unsigned > & occ, unsigned & i ) {
+	ext::multiset < StateType > states;
+
+	unsigned tmp = i;
+	i++;
+
+	bool sign = true;
+
+	for ( const ext::tree < common::ranked_symbol < SymbolType > > & child : node.getChildren ( ) ) {
+		ext::pair < bool, StateType > res = calculateState ( automaton, child, occ, i );
+
+		if ( res.first == false )
+			sign = false;
+		else
+			states.insert ( res.second );
+	}
+
+	if ( !sign ) return ext::make_pair ( false, label::FailStateLabel::instance < StateType > ( ) );
+
+	const auto & it = automaton.getTransitions ( ).find ( ext::make_pair ( node.getData ( ), states ) );
+
+	if ( it == automaton.getTransitions ( ).end ( ) ) return ext::make_pair ( false, label::FailStateLabel::instance < StateType > ( ) );
+
+	StateType state = it->second;
+
+	if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( tmp );
+
+	if ( common::GlobalData::verbose )
+		common::Streams::log << state << std::endl;
+
+	return ext::make_pair ( true, state );
+}
+
+template < class SymbolType, class StateType >
+ext::tuple < bool, StateType, ext::set < unsigned > > Run::calculateState ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const tree::UnorderedRankedTree < SymbolType > & tree ) {
+	ext::set < unsigned > occ;
+	unsigned i = 0;
+	ext::pair < bool, StateType > res = calculateState ( automaton, tree.getContent ( ), occ, i );
+
+	return ext::make_tuple ( res.first, res.second, occ );
+}
+
+// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
 template < class SymbolType, class StateType >
 ext::pair < bool, ext::set < StateType > > Run::calculateStates ( const automaton::NFTA < SymbolType, StateType > & automaton, const ext::tree < common::ranked_symbol < SymbolType > > & node, ext::set < unsigned > & occ, unsigned & i ) {
 	ext::vector < ext::set < StateType > > resStates;
diff --git a/alib2data/src/automaton/TA/UnorderedDFTA.cpp b/alib2data/src/automaton/TA/UnorderedDFTA.cpp
new file mode 100644
index 0000000000..6c08bc4848
--- /dev/null
+++ b/alib2data/src/automaton/TA/UnorderedDFTA.cpp
@@ -0,0 +1,18 @@
+/*
+ * UnorderedDFTA.cpp
+ *
+ *  Created on: Apr 14, 2015
+ *      Author: Stepan Plachy
+ */
+
+#include "UnorderedDFTA.h"
+
+#include <registration/ValuePrinterRegistration.hpp>
+
+template class automaton::UnorderedDFTA < >;
+
+namespace {
+
+auto valuePrinter = registration::ValuePrinterRegister < automaton::UnorderedDFTA < > > ( );
+
+} /* namespace */
diff --git a/alib2data/src/automaton/TA/UnorderedDFTA.h b/alib2data/src/automaton/TA/UnorderedDFTA.h
new file mode 100644
index 0000000000..8f5c50c24e
--- /dev/null
+++ b/alib2data/src/automaton/TA/UnorderedDFTA.h
@@ -0,0 +1,633 @@
+/*
+ * UnorderedDFTA.h
+ *
+ * This file is part of Algorithms library toolkit.
+ * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
+
+ * Algorithms library toolkit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * Algorithms library toolkit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Created on: Apr 14, 2015
+ *      Author: Stepan Plachy
+ */
+
+#ifndef UNORDERED_DFTA_H_
+#define UNORDERED_DFTA_H_
+
+#include <ostream>
+#include <sstream>
+
+#include <alib/map>
+#include <alib/set>
+#include <alib/multiset>
+#include <alib/compare>
+
+#include <core/components.hpp>
+#include <common/ranked_symbol.hpp>
+
+#include <common/DefaultStateType.h>
+#include <common/DefaultSymbolType.h>
+
+#include <automaton/AutomatonException.h>
+
+#include <core/normalize.hpp>
+#include <alphabet/common/SymbolNormalize.h>
+#include <automaton/common/AutomatonNormalize.h>
+
+namespace automaton {
+
+class InputAlphabet;
+class States;
+class FinalStates;
+
+/**
+ * \brief
+ * Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages.
+
+ * \details
+ * Definition is classical definition of finite automata.
+ * A = (Q, T, \delta, F),
+ * Q (States) = nonempty finite set of states,
+ * T (TerminalAlphabet) = finite set of terminal ranked symbols - having this empty won't let automaton do much though,
+ * \delta = transition function of the form (A, B, C, ...) \times a -> X, where A, B, C, ..., X \in Q and a \in T,
+ * F (FinalStates) = set of final states
+ *
+ * Elements of the \delta mapping must meet following criteria. The size of the state list must equal the rank of the ranked symbol.
+ *
+ * Note that target state of a transition is required.
+ * This class is used to store minimal, total, ... variants of deterministic finite tree automata.
+ *
+ * Elements of the \delta mapping must meet following criteria. The size of the state list must equal the rank of the ranked symbol.
+ *
+ * \tparam SymbolTypeT used for the symbol part of the ranked symbol
+ * \tparam StateTypeT used to the states, and the initial state of the automaton.
+ */
+template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
+class UnorderedDFTA final : public ext::CompareOperators < UnorderedDFTA < SymbolTypeT, StateTypeT > >, public core::Components < UnorderedDFTA < SymbolTypeT, StateTypeT >, ext::set < common::ranked_symbol < SymbolTypeT > >, component::Set, InputAlphabet, ext::set < StateTypeT >, component::Set, std::tuple < States, FinalStates > > {
+public:
+	typedef SymbolTypeT SymbolType;
+	typedef StateTypeT StateType;
+
+private:
+	/**
+	 * Transition function as mapping from a list of states times an input symbol on the left hand side to a state.
+	 */
+	ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > transitions;
+
+public:
+	/**
+	 * \brief Creates a new instance of the automaton.
+	 */
+	explicit UnorderedDFTA ( );
+
+	/**
+	 * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, and  a set of final states.
+	 *
+	 * \param states the initial set of states of the automaton
+	 * \param inputAlphabet the initial input alphabet
+	 * \param finalStates the initial set of final states of the automaton
+	 */
+	explicit UnorderedDFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType > > inputAlphabet, ext::set < StateType > finalStates );
+
+	/**
+	 * Getter of states.
+	 *
+	 * \returns the states of the automaton
+	 */
+	const ext::set < StateType > & getStates ( ) const & {
+		return this->template accessComponent < States > ( ).get ( );
+	}
+
+	/**
+	 * Getter of states.
+	 *
+	 * \returns the states of the automaton
+	 */
+	ext::set < StateType > && getStates ( ) && {
+		return std::move ( this->template accessComponent < States > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a state.
+	 *
+	 * \param state the new state to be added to a set of states
+	 *
+	 * \returns true if the state was indeed added
+	 */
+	bool addState ( StateType state ) {
+		return this->template accessComponent < States > ( ).add ( std::move ( state ) );
+	}
+
+	/**
+	 * Setter of states.
+	 *
+	 * \param states completely new set of states
+	 */
+	void setStates ( ext::set < StateType > states ) {
+		this->template accessComponent < States > ( ).set ( std::move ( states ) );
+	}
+
+	/**
+	 * Remover of a state.
+	 *
+	 * \param state a state to be removed from a set of states
+	 *
+	 * \returns true if the state was indeed removed
+	 */
+	void removeState ( const StateType & state ) {
+		this->template accessComponent < States > ( ).remove ( state );
+	}
+
+	/**
+	 * Getter of final states.
+	 *
+	 * \returns the final states of the automaton
+	 */
+	const ext::set < StateType > & getFinalStates ( ) const & {
+		return this->template accessComponent < FinalStates > ( ).get ( );
+	}
+
+	/**
+	 * Getter of final states.
+	 *
+	 * \returns the final states of the automaton
+	 */
+	ext::set < StateType > && getFinalStates ( ) && {
+		return std::move ( this->template accessComponent < FinalStates > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a final state.
+	 *
+	 * \param state the new state to be added to a set of final states
+	 *
+	 * \returns true if the state was indeed added
+	 */
+	bool addFinalState ( StateType state ) {
+		return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
+	}
+
+	/**
+	 * Setter of final states.
+	 *
+	 * \param states completely new set of final states
+	 */
+	void setFinalStates ( ext::set < StateType > states ) {
+		this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
+	}
+
+	/**
+	 * Remover of a final state.
+	 *
+	 * \param state a state to be removed from a set of final states
+	 *
+	 * \returns true if the state was indeed removed
+	 */
+	void removeFinalState ( const StateType & state ) {
+		this->template accessComponent < FinalStates > ( ).remove ( state );
+	}
+
+	/**
+	 * Getter of the input alphabet.
+	 *
+	 * \returns the input alphabet of the automaton
+	 */
+	const ext::set < common::ranked_symbol < SymbolType > > & getInputAlphabet ( ) const & {
+		return this->template accessComponent < InputAlphabet > ( ).get ( );
+	}
+
+	/**
+	 * Getter of the input alphabet.
+	 *
+	 * \returns the input alphabet of the automaton
+	 */
+	ext::set < common::ranked_symbol < SymbolType > > && getInputAlphabet ( ) && {
+		return std::move ( this->template accessComponent < InputAlphabet > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a input symbol.
+	 *
+	 * \param symbol the new symbol to be added to an input alphabet
+	 *
+	 * \returns true if the symbol was indeed added
+	 */
+	bool addInputSymbol ( common::ranked_symbol < SymbolType > symbol ) {
+		return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
+	}
+
+	/**
+	 * Adder of input symbols.
+	 *
+	 * \param symbols new symbols to be added to an input alphabet
+	 */
+	void addInputSymbols ( ext::set < common::ranked_symbol < SymbolType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
+	}
+
+	/**
+	 * Setter of input alphabet.
+	 *
+	 * \param symbols completely new input alphabet
+	 */
+	void setInputAlphabet ( ext::set < common::ranked_symbol < SymbolType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
+	}
+
+	/**
+	 * Remover of an input symbol.
+	 *
+	 * \param symbol a symbol to be removed from an input alphabet
+	 *
+	 * \returns true if the symbol was indeed removed
+	 */
+	void removeInputSymbol ( const common::ranked_symbol < SymbolType > & symbol ) {
+		this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
+	}
+
+	/**
+	 * \brief Add a transition to the automaton.
+	 *
+	 * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T
+	 *
+	 * \param children the source states (A, B, C, ...)
+	 * \param current the input symbol (a)
+	 * \param next the target state (B)
+	 *
+	 * \throws AutomatonException when transition contains state or symbol not present in the automaton components
+	 *
+	 * \returns true if the transition was indeed added
+	 */
+	bool addTransition ( common::ranked_symbol < SymbolType > symbol, ext::multiset < StateType > prevStates, StateType next );
+
+	/**
+	 * \brief Removes a transition from the automaton.
+	 *
+	 * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T
+	 *
+	 * \param children the source states (A, B, C, ...)
+	 * \param current the input symbol (a)
+	 * \param next the target state (B)
+	 *
+	 * \returns true if the transition was indeed removed
+	 */
+	bool removeTransition ( const common::ranked_symbol < SymbolType > & symbol, const ext::multiset < StateType > & states, const StateType & next );
+
+	/**
+	 * Get the transition function of the automaton in its natural form.
+	 *
+	 * \returns transition function of the automaton
+	 */
+	const ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & getTransitions ( ) const & {
+		return transitions;
+	}
+
+	/**
+	 * Get the transition function of the automaton in its natural form.
+	 *
+	 * \returns transition function of the automaton
+	 */
+	ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > && getTransitions ( ) && {
+		return std::move ( transitions );
+	}
+
+	/**
+	 * \returns transitions to state @p q
+	 */
+	ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > getTransitionsToState ( const StateType & q ) const {
+		ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > res;
+
+		for ( const auto & transition : getTransitions ( ) ) {
+			if ( transition.second == q )
+				res.insert ( std::make_pair ( transition.first, q ) );
+		}
+
+		return res;
+	}
+
+	/**
+	 * \returns transitions from state @p q
+	 */
+	ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > getTransitionsFromState ( const StateType & q ) const {
+		ext::map < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > res;
+
+		for ( const auto & transition : getTransitions ( ) ) {
+			if ( std::find ( transition.first.second.begin ( ), transition.first.second.end ( ), q ) != transition.first.second.end ( ) )
+				res.insert ( transition );
+		}
+
+		return res;
+	}
+
+	/**
+	 * The actual compare method
+	 *
+	 * \param other the other instance
+	 *
+	 * \returns the actual relation between two by type same automata instances
+	 */
+	int compare ( const UnorderedDFTA & other ) const;
+
+	/**
+	 * Print this object as raw representation to ostream.
+	 *
+	 * \param out ostream where to print
+	 * \param instance object to print
+	 *
+	 * \returns modified output stream
+	 */
+	friend std::ostream & operator << ( std::ostream & out, const UnorderedDFTA & instance ) {
+		return out << "(UnorderedDFTA "
+			   << " states = " << instance.getStates ( )
+			   << " inputAlphabet = " << instance.getInputAlphabet ( )
+			   << " finalStates = " << instance.getFinalStates ( )
+			   << " transitions = " << instance.getTransitions ( )
+			   << ")";
+	}
+
+	/**
+	 * Casts this instance to as compact as possible string representation.
+	 *
+	 * \returns string representation of the object
+	 */
+	operator std::string ( ) const;
+};
+
+/**
+ * Trait to detect whether the type parameter T is or is not UnorderedDFTA. Derived from std::false_type.
+ *
+ * \tparam T the tested type parameter
+ */
+template < class T >
+class isUnorderedDFTA_impl : public std::false_type {};
+
+/**
+ * Trait to detect whether the type parameter T is or is not UnorderedDFTA. Derived from std::true_type.
+ *
+ * Specialisation for UnorderedDFTA.
+ *
+ * \tparam SymbolType used for the terminal alphabet of the automaton
+ * \tparam StateType used for the terminal alphabet of the automaton
+ */
+template < class SymbolType, class StateType >
+class isUnorderedDFTA_impl < UnorderedDFTA < SymbolType, StateType > > : public std::true_type {};
+
+/**
+ * Constexpr true if the type parameter T is UnorderedDFTA, false otherwise.
+ *
+ * \tparam T the tested type parameter
+ */
+template < class T >
+constexpr bool isUnorderedDFTA = isUnorderedDFTA_impl < T > { };
+
+template<class SymbolType, class StateType >
+UnorderedDFTA < SymbolType, StateType >::UnorderedDFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType > > inputAlphabet, ext::set < StateType > finalStates ) : core::Components < UnorderedDFTA, ext::set < common::ranked_symbol < SymbolType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ) ) {
+}
+
+template<class SymbolType, class StateType >
+UnorderedDFTA < SymbolType, StateType >::UnorderedDFTA() : UnorderedDFTA ( ext::set < StateType > { }, ext::set < common::ranked_symbol < SymbolType > > { }, ext::set < StateType > { } ) {
+}
+
+template<class SymbolType, class StateType >
+bool UnorderedDFTA < SymbolType, StateType >::addTransition ( common::ranked_symbol < SymbolType > symbol, ext::multiset<StateType> prevStates, StateType next) {
+	if ( prevStates.size() != ( size_t ) symbol.getRank() )
+		throw AutomatonException("Number of states doesn't match rank of the symbol");
+
+	if (! getInputAlphabet().count(symbol))
+		throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist.");
+
+	if (! getStates().count(next))
+		throw AutomatonException("State \"" + ext::to_string ( next ) + "\" doesn't exist.");
+
+	for ( const StateType & it : prevStates) {
+		if (! getStates().count(it))
+			throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist.");
+	}
+
+	ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> > key = ext::make_pair ( std::move ( symbol ), std::move ( prevStates ) );
+	if ( transitions.find ( key ) != transitions.end ( ) ) {
+		if ( transitions.find ( key )->second == next )
+			return false;
+		else
+			throw AutomatonException("Transition already exists");
+	}
+
+	transitions.insert ( std::move ( key ), std::move ( next ) );
+	return true;
+}
+
+template<class SymbolType, class StateType >
+bool UnorderedDFTA < SymbolType, StateType >::removeTransition(const common::ranked_symbol < SymbolType > & symbol, const ext::multiset<StateType> & states, const StateType & next) {
+	ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> > key = ext::make_pair(symbol, states);
+
+	if ( transitions.find ( key ) == transitions.end ( ) )
+		return false;
+
+	if ( transitions.find ( key )->second != next )
+		throw AutomatonException("Transition does not exist");
+
+	transitions.erase(key);
+	return true;
+}
+
+template<class SymbolType, class StateType >
+int UnorderedDFTA < SymbolType, StateType >::compare(const UnorderedDFTA& other) const {
+	auto first = ext::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions);
+	auto second = ext::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
+
+	static ext::compare<decltype(first)> comp;
+	return comp(first, second);
+}
+
+template<class SymbolType, class StateType >
+UnorderedDFTA < SymbolType, StateType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+} /* namespace automaton */
+
+namespace core {
+
+/**
+ * Helper class specifying constraints for the automaton's internal input alphabet component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template<class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedDFTA < SymbolType, StateType >, common::ranked_symbol < SymbolType >, automaton::InputAlphabet > {
+public:
+	/**
+	 * Returns true if the symbol is still used in some transition of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 *
+	 * \returns true if the symbol is used, false othervise
+	 */
+	static bool used ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const common::ranked_symbol < SymbolType > & symbol ) {
+		for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> >, StateType>& t : automaton.getTransitions())
+			if (t.first.first == symbol)
+				return true;
+
+		return false;
+	}
+
+	/**
+	 * Returns true as all symbols are possibly available to be elements of the input alphabet.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 *
+	 * \returns true
+	 */
+	static bool available ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const common::ranked_symbol < SymbolType > & ) {
+		return true;
+	}
+
+	/**
+	 * All symbols are valid as input symbols.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 */
+	static void valid ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const common::ranked_symbol < SymbolType > & ) {
+	}
+};
+
+/**
+ * Helper class specifying constraints for the automaton's internal states component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template<class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedDFTA < SymbolType, StateType >, StateType, automaton::States > {
+public:
+	/**
+	 * Returns true if the state is still used in some transition of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true if the state is used, false othervise
+	 */
+	static bool used ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const StateType & state ) {
+		if ( automaton.getFinalStates ( ).count ( state ) )
+			return true;
+
+		for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> >, StateType>& t : automaton.getTransitions())
+			if(ext::contains(t.first.second.begin(), t.first.second.end(), state ) || t.second == state)
+				return true;
+
+		return false;
+	}
+
+	/**
+	 * Returns true as all states are possibly available to be elements of the states.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true
+	 */
+	static bool available ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const StateType & ) {
+		return true;
+	}
+
+	/**
+	 * All states are valid as a state of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 */
+	static void valid ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const StateType & ) {
+	}
+};
+
+/**
+ * Helper class specifying constraints for the automaton's internal final states component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template<class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedDFTA < SymbolType, StateType >, StateType, automaton::FinalStates > {
+public:
+	/**
+	 * Returns false. Final state is only a mark that the automaton itself does require further.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns false
+	 */
+	static bool used ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const StateType & ) {
+		return false;
+	}
+
+	/**
+	 * Determines whether the state is available in the automaton's states set.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true if the state is already in the set of states of the automaton
+	 */
+	static bool available ( const automaton::UnorderedDFTA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
+	}
+
+	/**
+	 * All states are valid as a final state of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 */
+	static void valid ( const automaton::UnorderedDFTA < SymbolType, StateType > &, const StateType & ) {
+	}
+};
+
+/**
+ * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states.
+ *
+ * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones
+ */
+template < class SymbolType, class StateType >
+struct normalize < automaton::UnorderedDFTA < SymbolType, StateType > > {
+	static automaton::UnorderedDFTA < > eval ( automaton::UnorderedDFTA < SymbolType, StateType > && value ) {
+		ext::set < common::ranked_symbol < > > alphabet = alphabet::SymbolNormalize::normalizeRankedAlphabet ( std::move ( value ).getInputAlphabet ( ) );
+		ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
+		ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
+
+		automaton::UnorderedDFTA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( finalStates ) );
+
+		for ( std::pair < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
+			common::ranked_symbol < DefaultSymbolType > input = alphabet::SymbolNormalize::normalizeRankedSymbol ( std::move ( transition.first.first ) );
+			ext::multiset < DefaultStateType > from = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.first.second ) );
+			DefaultStateType to = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) );
+
+			res.addTransition ( std::move ( input ), std::move ( from ), std::move ( to ) );
+		}
+
+		return res;
+	}
+};
+
+} /* namespace core */
+
+extern template class automaton::UnorderedDFTA < >;
+
+#endif /* UNORDERED_DFTA_H_ */
diff --git a/alib2data/src/automaton/TA/UnorderedNFTA.cpp b/alib2data/src/automaton/TA/UnorderedNFTA.cpp
new file mode 100644
index 0000000000..89509ec514
--- /dev/null
+++ b/alib2data/src/automaton/TA/UnorderedNFTA.cpp
@@ -0,0 +1,21 @@
+/*
+ * UnorderedNFTA.cpp
+ *
+ *  Created on: Mar 21, 2015
+ *      Author: Stepan Plachy
+ */
+
+#include "UnorderedNFTA.h"
+
+#include <registration/ValuePrinterRegistration.hpp>
+#include <registration/CastRegistration.hpp>
+
+template class automaton::UnorderedNFTA < >;
+
+namespace {
+
+auto valuePrinter = registration::ValuePrinterRegister < automaton::UnorderedNFTA < > > ( );
+
+auto NFTAFromDFTA = registration::CastRegister < automaton::UnorderedNFTA < >, automaton::UnorderedDFTA < > > ( );
+
+} /* namespace */
diff --git a/alib2data/src/automaton/TA/UnorderedNFTA.h b/alib2data/src/automaton/TA/UnorderedNFTA.h
new file mode 100644
index 0000000000..374028acf6
--- /dev/null
+++ b/alib2data/src/automaton/TA/UnorderedNFTA.h
@@ -0,0 +1,661 @@
+/*
+ * UnorderedNFTA.h
+ *
+ * This file is part of Algorithms library toolkit.
+ * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
+
+ * Algorithms library toolkit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * Algorithms library toolkit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Created on: Mar 21, 2015
+ *      Author: Stepan Plachy
+ */
+
+#ifndef UNORDERED_NFTA_H_
+#define UNORDERED_NFTA_H_
+
+#include <ostream>
+#include <sstream>
+
+#include <alib/multimap>
+#include <alib/set>
+#include <alib/multiset>
+#include <alib/compare>
+
+#include <core/components.hpp>
+
+#include <core/normalize.hpp>
+
+#include <common/DefaultStateType.h>
+#include <common/DefaultSymbolType.h>
+
+#include <automaton/AutomatonException.h>
+
+#include <core/normalize.hpp>
+#include <alphabet/common/SymbolNormalize.h>
+#include <automaton/common/AutomatonNormalize.h>
+
+#include "UnorderedDFTA.h"
+
+namespace automaton {
+
+class InputAlphabet;
+class States;
+class FinalStates;
+
+/**
+ * \brief
+ * Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages.
+
+ * \details
+ * Definition is classical definition of finite automata.
+ * A = (Q, T, \delta, F),
+ * Q (States) = nonempty finite set of states,
+ * T (TerminalAlphabet) = finite set of terminal ranked symbols - having this empty won't let automaton do much though,
+ * \delta = transition function of the form (A, B, C, ...) \times a -> P(Q), where A, B, C, ... \in Q, a \in T, and P(Q) is a powerset of states,
+ * F (FinalStates) = set of final states
+ *
+ * Elements of the \delta multimapping must meet following criteria. The size of the state list must equal the rank of the ranked symbol.
+ *
+ * \tparam SymbolTypeT used for the symbol part of the ranked symbol
+ * \tparam StateTypeT used to the states, and the initial state of the automaton.
+ */
+template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
+class UnorderedNFTA final : public ext::CompareOperators < UnorderedNFTA < SymbolTypeT, StateTypeT > >, public core::Components < UnorderedNFTA < SymbolTypeT, StateTypeT >, ext::set < common::ranked_symbol < SymbolTypeT > >, component::Set, InputAlphabet, ext::set < StateTypeT >, component::Set, std::tuple < States, FinalStates > > {
+public:
+	typedef SymbolTypeT SymbolType;
+	typedef StateTypeT StateType;
+
+private:
+	/**
+	 * Transition function as multimapping from a list of states times an input symbol on the left hand side to a set of states.
+	 */
+	ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > transitions;
+
+public:
+	/**
+	 * \brief Creates a new instance of the automaton.
+	 */
+	explicit UnorderedNFTA ( );
+
+	/**
+	 * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, and  a set of final states.
+	 *
+	 * \param states the initial set of states of the automaton
+	 * \param inputAlphabet the initial input alphabet
+	 * \param finalStates the initial set of final states of the automaton
+	 */
+	explicit UnorderedNFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType > > inputAlphabet, ext::set < StateType > finalStates );
+
+	/*
+	 * \brief Creates a new instance of the automaton based on the Deterministic finite tree automaton.
+	 *
+	 * \param other the Deterministic finite tree automaton
+	 */
+	explicit UnorderedNFTA ( const UnorderedDFTA < SymbolType, StateType > & other );
+
+	/**
+	 * Getter of states.
+	 *
+	 * \returns the states of the automaton
+	 */
+	const ext::set < StateType > & getStates ( ) const & {
+		return this->template accessComponent < States > ( ).get ( );
+	}
+
+	/**
+	 * Getter of states.
+	 *
+	 * \returns the states of the automaton
+	 */
+	ext::set < StateType > && getStates ( ) && {
+		return std::move ( this->template accessComponent < States > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a state.
+	 *
+	 * \param state the new state to be added to a set of states
+	 *
+	 * \returns true if the state was indeed added
+	 */
+	bool addState ( StateType state ) {
+		return this->template accessComponent < States > ( ).add ( std::move ( state ) );
+	}
+
+	/**
+	 * Setter of states.
+	 *
+	 * \param states completely new set of states
+	 */
+	void setStates ( ext::set < StateType > states ) {
+		this->template accessComponent < States > ( ).set ( std::move ( states ) );
+	}
+
+	/**
+	 * Remover of a state.
+	 *
+	 * \param state a state to be removed from a set of states
+	 *
+	 * \returns true if the state was indeed removed
+	 */
+	void removeState ( const StateType & state ) {
+		this->template accessComponent < States > ( ).remove ( state );
+	}
+
+	/**
+	 * Getter of final states.
+	 *
+	 * \returns the final states of the automaton
+	 */
+	const ext::set < StateType > & getFinalStates ( ) const & {
+		return this->template accessComponent < FinalStates > ( ).get ( );
+	}
+
+	/**
+	 * Getter of final states.
+	 *
+	 * \returns the final states of the automaton
+	 */
+	ext::set < StateType > && getFinalStates ( ) && {
+		return std::move ( this->template accessComponent < FinalStates > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a final state.
+	 *
+	 * \param state the new state to be added to a set of final states
+	 *
+	 * \returns true if the state was indeed added
+	 */
+	bool addFinalState ( StateType state ) {
+		return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
+	}
+
+	/**
+	 * Setter of final states.
+	 *
+	 * \param states completely new set of final states
+	 */
+	void setFinalStates ( ext::set < StateType > states ) {
+		this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
+	}
+
+	/**
+	 * Remover of a final state.
+	 *
+	 * \param state a state to be removed from a set of final states
+	 *
+	 * \returns true if the state was indeed removed
+	 */
+	void removeFinalState ( const StateType & state ) {
+		this->template accessComponent < FinalStates > ( ).remove ( state );
+	}
+
+	/**
+	 * Getter of the input alphabet.
+	 *
+	 * \returns the input alphabet of the automaton
+	 */
+	const ext::set < common::ranked_symbol < SymbolType > > & getInputAlphabet ( ) const & {
+		return this->template accessComponent < InputAlphabet > ( ).get ( );
+	}
+
+	/**
+	 * Getter of the input alphabet.
+	 *
+	 * \returns the input alphabet of the automaton
+	 */
+	ext::set < common::ranked_symbol < SymbolType > > && getInputAlphabet ( ) && {
+		return std::move ( this->template accessComponent < InputAlphabet > ( ).get ( ) );
+	}
+
+	/**
+	 * Adder of a input symbol.
+	 *
+	 * \param symbol the new symbol to be added to an input alphabet
+	 *
+	 * \returns true if the symbol was indeed added
+	 */
+	bool addInputSymbol ( common::ranked_symbol < SymbolType > symbol ) {
+		return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
+	}
+
+	/**
+	 * Adder of input symbols.
+	 *
+	 * \param symbols new symbols to be added to an input alphabet
+	 */
+	void addInputSymbols ( ext::set < common::ranked_symbol < SymbolType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
+	}
+
+	/**
+	 * Setter of input alphabet.
+	 *
+	 * \param symbols completely new input alphabet
+	 */
+	void setInputAlphabet ( ext::set < common::ranked_symbol < SymbolType > > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
+	}
+
+	/**
+	 * Remover of an input symbol.
+	 *
+	 * \param symbol a symbol to be removed from an input alphabet
+	 *
+	 * \returns true if the symbol was indeed removed
+	 */
+	void removeInputSymbol ( const common::ranked_symbol < SymbolType > & symbol ) {
+		this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
+	}
+
+	/**
+	 * \brief Add a transition to the automaton.
+	 *
+	 * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T
+	 *
+	 * \param children the source states (A, B, C, ...)
+	 * \param current the input symbol (a)
+	 * \param next the target state (B)
+	 *
+	 * \throws AutomatonException when transition contains state or symbol not present in the automaton components
+	 *
+	 * \returns true if the transition was indeed added
+	 */
+	bool addTransition ( common::ranked_symbol < SymbolType > symbol, ext::multiset < StateType > prevStates, StateType next );
+
+	/**
+	 * \brief Removes a transition from the automaton.
+	 *
+	 * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T
+	 *
+	 * \param children the source states (A, B, C, ...)
+	 * \param current the input symbol (a)
+	 * \param next the target state (B)
+	 *
+	 * \returns true if the transition was indeed removed
+	 */
+	bool removeTransition ( const common::ranked_symbol < SymbolType > & symbol, const ext::multiset < StateType > & states, const StateType & next );
+
+	/**
+	 * Get the transition function of the automaton in its natural form.
+	 *
+	 * \returns transition function of the automaton
+	 */
+	const ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & getTransitions ( ) const & {
+		return transitions;
+	}
+
+	/**
+	 * Get the transition function of the automaton in its natural form.
+	 *
+	 * \returns transition function of the automaton
+	 */
+	ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > && getTransitions ( ) && {
+		return std::move ( transitions );
+	}
+
+	/**
+	 * \returns transitions to state @p q
+	 */
+	ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > getTransitionsToState ( const StateType & q ) const {
+		ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > res;
+
+		for ( const auto & transition : getTransitions ( ) )
+			if ( transition.second == q )
+				res.insert ( transition );
+
+		return res;
+	}
+
+	/**
+	 * \returns transitions from state @p q
+	 */
+	ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > getTransitionsFromState ( const StateType & q ) const {
+		ext::multimap < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > res;
+
+		for ( const auto & transition : getTransitions ( ) ) {
+			if ( std::find ( transition.first.second.begin ( ), transition.first.second.end ( ), q ) != transition.first.second.end ( ) )
+				res.insert ( transition );
+		}
+
+		return res;
+	}
+
+	/**
+	 * \brief Determines whether the automaton is deterministic.
+	 *
+	 * the automaton is deterministic if and only if:
+	 * \li \c size of transition function \delta (from states, input symbol) \leq 1
+	 *
+	 * \return true if the automaton is deterministic, false otherwise
+	 */
+	bool isDeterministic ( ) const;
+
+	/**
+	 * The actual compare method
+	 *
+	 * \param other the other instance
+	 *
+	 * \returns the actual relation between two by type same automata instances
+	 */
+	int compare ( const UnorderedNFTA & other ) const;
+
+	/**
+	 * Print this object as raw representation to ostream.
+	 *
+	 * \param out ostream where to print
+	 * \param instance object to print
+	 *
+	 * \returns modified output stream
+	 */
+	friend std::ostream & operator << ( std::ostream & out, const UnorderedNFTA & instance ) {
+		return out << "(UnorderedNFTA "
+			   << " states = " << instance.getStates ( )
+			   << " inputAlphabet = " << instance.getInputAlphabet ( )
+			   << " finalStates = " << instance.getFinalStates ( )
+			   << " transitions = " << instance.getTransitions ( )
+			   << ")";
+	}
+
+	/**
+	 * Casts this instance to as compact as possible string representation.
+	 *
+	 * \returns string representation of the object
+	 */
+	operator std::string ( ) const;
+};
+
+/**
+ * Trait to detect whether the type parameter T is or is not UnorderedNFTA. Derived from std::false_type.
+ *
+ * \tparam T the tested type parameter
+ */
+template < class T >
+class isUnorderedNFTA_impl : public std::false_type {};
+
+/**
+ * Trait to detect whether the type parameter T is or is not DFA. Derived from std::true_type.
+ *
+ * Specialisation for UnorderedNFTA.
+ *
+ * \tparam SymbolType used for the terminal alphabet of the automaton
+ * \tparam StateType used for the terminal alphabet of the automaton
+ */
+template < class SymbolType, class StateType >
+class isUnorderedNFTA_impl < UnorderedNFTA < SymbolType, StateType > > : public std::true_type {};
+
+/**
+ * Constexpr true if the type parameter T is UnorderedNFTA, false otherwise.
+ *
+ * \tparam T the tested type parameter
+ */
+template < class T >
+constexpr bool isUnorderedNFTA = isUnorderedNFTA_impl < T > { };
+
+template < class SymbolType, class StateType >
+UnorderedNFTA < SymbolType, StateType >::UnorderedNFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType > > inputAlphabet, ext::set < StateType > finalStates ) : core::Components < UnorderedNFTA, ext::set < common::ranked_symbol < SymbolType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ) ) {
+}
+
+template < class SymbolType, class StateType >
+UnorderedNFTA < SymbolType, StateType >::UnorderedNFTA() : UnorderedNFTA ( ext::set < StateType > { }, ext::set < common::ranked_symbol < SymbolType > > { }, ext::set < StateType > { } ) {
+}
+
+template < class SymbolType, class StateType >
+UnorderedNFTA < SymbolType, StateType >::UnorderedNFTA(const UnorderedDFTA < SymbolType, StateType > & other) : UnorderedNFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) {
+	transitions.insert ( other.getTransitions ( ).begin ( ), other.getTransitions ( ).end ( ) );
+}
+
+template < class SymbolType, class StateType >
+bool UnorderedNFTA < SymbolType, StateType >::addTransition ( common::ranked_symbol < SymbolType > symbol, ext::multiset<StateType> prevStates, StateType next) {
+	if (prevStates.size() != ( size_t ) symbol.getRank() )
+		throw AutomatonException("Number of states doesn't match rank of the symbol");
+
+	if (! getInputAlphabet().count(symbol))
+		throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist.");
+
+	if (! getStates().count(next))
+		throw AutomatonException("State \"" + ext::to_string ( next ) + "\" doesn't exist.");
+
+	for (const StateType& it : prevStates) {
+		if (! getStates().count(it))
+			throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist.");
+	}
+
+	auto upper_bound = transitions.upper_bound ( ext::tie ( symbol, prevStates ) );
+	auto lower_bound = transitions.lower_bound ( ext::tie ( symbol, prevStates ) );
+	auto iter = std::lower_bound ( lower_bound, upper_bound, next, [ ] ( const auto & transition, const auto & target ) { return transition.second < target; } );
+	if ( iter != upper_bound && next >= iter->second )
+		return false;
+
+	ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > > key = ext::make_pair ( std::move ( symbol ), std::move ( prevStates ) );
+	transitions.insert ( iter, std::make_pair ( std::move ( key ), std::move ( next ) ) );
+	return true;
+}
+
+template < class SymbolType, class StateType >
+bool UnorderedNFTA < SymbolType, StateType >::removeTransition(const common::ranked_symbol < SymbolType > & symbol, const ext::multiset<StateType> & states, const StateType & next) {
+	auto upper_bound = transitions.upper_bound ( ext::tie ( symbol, states ) );
+	auto lower_bound = transitions.lower_bound ( ext::tie ( symbol, states ) );
+	auto iter = std::find_if ( lower_bound, upper_bound, [ & ] ( const auto & transition ) { return transition.second == next; } );
+	if ( iter == upper_bound )
+		return false;
+
+	transitions.erase ( iter );
+	return true;
+}
+
+template < class SymbolType, class StateType >
+bool UnorderedNFTA < SymbolType, StateType >::isDeterministic() const {
+	if ( transitions.empty ( ) )
+		return true;
+
+	for ( auto iter = transitions.begin ( ); std::next ( iter ) != transitions.end ( ); ++ iter )
+		if ( iter->first == std::next ( iter )->first )
+			return false;
+
+	return true;
+}
+
+template < class SymbolType, class StateType >
+int UnorderedNFTA < SymbolType, StateType >::compare(const UnorderedNFTA& other) const {
+	auto first = ext::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions);
+	auto second = ext::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
+
+	static ext::compare<decltype(first)> comp;
+	return comp(first, second);
+}
+
+template < class SymbolType, class StateType >
+UnorderedNFTA < SymbolType, StateType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+} /* namespace automaton */
+
+namespace core {
+
+/**
+ * Helper class specifying constraints for the automaton's internal input alphabet component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedNFTA < SymbolType, StateType >, common::ranked_symbol < SymbolType >, automaton::InputAlphabet > {
+public:
+	/**
+	 * Returns true if the symbol is still used in some transition of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 *
+	 * \returns true if the symbol is used, false othervise
+	 */
+	static bool used ( const automaton::UnorderedNFTA < SymbolType, StateType > & automaton, const common::ranked_symbol < SymbolType > & symbol ) {
+		for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> >, StateType > & t : automaton.getTransitions())
+			if (t.first.first == symbol)
+				return true;
+
+		return false;
+	}
+
+	/**
+	 * Returns true as all symbols are possibly available to be elements of the input alphabet.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 *
+	 * \returns true
+	 */
+	static bool available ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const common::ranked_symbol < SymbolType > & ) {
+		return true;
+	}
+
+	/**
+	 * All symbols are valid as input symbols.
+	 *
+	 * \param automaton the tested automaton
+	 * \param symbol the tested symbol
+	 */
+	static void valid ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const common::ranked_symbol < SymbolType > & ) {
+	}
+};
+
+/**
+ * Helper class specifying constraints for the automaton's internal states component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedNFTA < SymbolType, StateType >, StateType, automaton::States > {
+public:
+	/**
+	 * Returns true if the state is still used in some transition of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true if the state is used, false othervise
+	 */
+	static bool used ( const automaton::UnorderedNFTA < SymbolType, StateType > & automaton, const StateType & state ) {
+		if ( automaton.getFinalStates ( ).count ( state ) )
+			return true;
+
+		for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType >, ext::multiset<StateType> >, StateType >& t : automaton.getTransitions())
+			if(ext::contains(t.first.second.begin(), t.first.second.end(), state ) || t . second == state )
+				return true;
+
+		return false;
+	}
+
+	/**
+	 * Returns true as all states are possibly available to be elements of the states.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true
+	 */
+	static bool available ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const StateType & ) {
+		return true;
+	}
+
+	/**
+	 * All states are valid as a state of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 */
+	static void valid ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const StateType & ) {
+	}
+};
+
+/**
+ * Helper class specifying constraints for the automaton's internal final states component.
+ *
+ * \tparam SymbolType used for the symbol part of the ranked symbol
+ * \tparam StateType used for the terminal alphabet of the automaton.
+ */
+template < class SymbolType, class StateType >
+class SetConstraint< automaton::UnorderedNFTA < SymbolType, StateType >, StateType, automaton::FinalStates > {
+public:
+	/**
+	 * Returns false. Final state is only a mark that the automaton itself does require further.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns false
+	 */
+	static bool used ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const StateType & ) {
+		return false;
+	}
+
+	/**
+	 * Determines whether the state is available in the automaton's states set.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 *
+	 * \returns true if the state is already in the set of states of the automaton
+	 */
+	static bool available ( const automaton::UnorderedNFTA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
+	}
+
+	/**
+	 * All states are valid as a final state of the automaton.
+	 *
+	 * \param automaton the tested automaton
+	 * \param state the tested state
+	 */
+	static void valid ( const automaton::UnorderedNFTA < SymbolType, StateType > &, const StateType & ) {
+	}
+};
+
+/**
+ * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states.
+ *
+ * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones
+ */
+template < class SymbolType, class StateType >
+struct normalize < automaton::UnorderedNFTA < SymbolType, StateType > > {
+	static automaton::UnorderedNFTA < > eval ( automaton::UnorderedNFTA < SymbolType, StateType > && value ) {
+		ext::set < common::ranked_symbol < > > alphabet = alphabet::SymbolNormalize::normalizeRankedAlphabet ( std::move ( value ).getInputAlphabet ( ) );
+		ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
+		ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
+
+		automaton::UnorderedNFTA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( finalStates ) );
+
+		for ( std::pair < ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
+			common::ranked_symbol < DefaultSymbolType > input = alphabet::SymbolNormalize::normalizeRankedSymbol ( std::move ( transition.first.first ) );
+			ext::multiset < DefaultStateType > from = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.first.second ) );
+			DefaultStateType to = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) );
+
+			res.addTransition ( std::move ( input ), std::move ( from ), std::move ( to ) );
+		}
+
+		return res;
+	}
+};
+
+} /* namespace core */
+
+extern template class automaton::UnorderedNFTA < >;
+
+#endif /* UNORDERED_NFTA_H_ */
diff --git a/alib2data/src/automaton/common/AutomatonNormalize.h b/alib2data/src/automaton/common/AutomatonNormalize.h
index dbb67ab12a..488b261146 100644
--- a/alib2data/src/automaton/common/AutomatonNormalize.h
+++ b/alib2data/src/automaton/common/AutomatonNormalize.h
@@ -11,6 +11,7 @@
 #include <alib/deque>
 #include <alib/vector>
 #include <alib/set>
+#include <alib/multiset>
 #include <alib/map>
 
 #include <regexp/unbounded/UnboundedRegExpStructure.h>
@@ -27,6 +28,9 @@ namespace automaton {
  */
 class AutomatonNormalize {
 public:
+	template < class StateType >
+	static ext::multiset < DefaultStateType > normalizeStates ( ext::multiset < StateType > && states );
+
 	template < class StateType >
 	static ext::set < DefaultStateType > normalizeStates ( ext::set < StateType > && states );
 
@@ -44,6 +48,15 @@ public:
 
 };
 
+template < class StateType >
+ext::multiset < DefaultStateType > AutomatonNormalize::normalizeStates ( ext::multiset < StateType > && states ) {
+	ext::multiset < DefaultStateType > res;
+	for ( StateType && state : ext::make_mover ( states ) )
+		res.insert ( normalizeState ( std::move ( state ) ) );
+
+	return res;
+}
+
 template < class StateType >
 ext::set < DefaultStateType > AutomatonNormalize::normalizeStates ( ext::set < StateType > && states ) {
 	ext::set < DefaultStateType > res;
diff --git a/alib2integrationtest/test-src/tests/arbologyTest.cpp b/alib2integrationtest/test-src/tests/arbologyTest.cpp
index a87ce15945..43b200e68f 100644
--- a/alib2integrationtest/test-src/tests/arbologyTest.cpp
+++ b/alib2integrationtest/test-src/tests/arbologyTest.cpp
@@ -9,6 +9,8 @@ enum class EGenerateType {
 	SUBTREE,
 	NONLINEAR_PATTERN,
 	NONLINEAR_PATTERN_SINGLE_VAR,
+	UNORDERED_PATTERN,
+	UNORDERED_SUBTREE,
 
 	SUBJECT,
 };
@@ -25,6 +27,10 @@ std::ostream& operator << ( std::ostream& os, const EGenerateType& type ) {
 			return ( os << "NONLINEAR_PATTERN_SINGLE_VAR");
 		case EGenerateType::SUBJECT:
 			return ( os << "SUBJECT" );
+		case EGenerateType::UNORDERED_PATTERN:
+			return ( os << "UNORDERED_PATTERN" );
+		case EGenerateType::UNORDERED_SUBTREE:
+			return ( os << "UNORDERED_SUBTREE" );
 		default:
 			return ( os << "Unhandled EGenerateType" );
 	}
@@ -50,6 +56,10 @@ static std::string qGen ( const EGenerateType & type, int height, int nodes, int
 		oss << "tree::generate::RandomRankedNonlinearPatternFactory";
 	} else if ( type == EGenerateType::NONLINEAR_PATTERN_SINGLE_VAR ) {
 		oss << "tree::generate::RandomRankedNonlinearPatternFactory";
+	} else if ( type == EGenerateType::UNORDERED_PATTERN ) {
+		oss << "(UnorderedRankedPattern) tree::generate::RandomRankedPatternFactory";
+	} else if ( type == EGenerateType::UNORDERED_SUBTREE ) {
+		oss << "(UnorderedRankedTree) tree::generate::RandomRankedTreeFactory";
 	}
 
 	oss << " (int)" << height;
@@ -222,6 +232,31 @@ TEST_CASE ( "Arbology tests | pattern", "[integration]" ) {
 
 // --------------------------------------------------------------------------------------------------------------------
 
+TEST_CASE ( "Arbology tests | unordered pattern", "[integration]" ) {
+	auto definition = GENERATE ( as < std::tuple < std::string, std::string, size_t > > ( ),
+		std::make_tuple ( "Exact Pattern Matching Automaton (Pattern Tree)",
+				"automaton::run::Occurrences <(arbology::exact::ExactPatternMatchingAutomaton <(tree::GeneralAlphabet::add $pattern <(tree::GeneralAlphabet::get $subject)) | automaton::determinize::Determinize - ) $subject", 1000 ) );
+
+	auto exact = "arbology::exact::ExactPatternMatch $subject $pattern";
+	auto pattern = EGenerateType::UNORDERED_PATTERN;
+
+/*	SECTION ( "Test files" ) {
+		for ( const std::pair < std::string, std::string > files : pair_pattern_subject ( TestFiles::Get ( "/tree/aarbology.test[0-9]+.pattern.xml$" ), ".pattern.xml", ".subject.xml" ) ) {
+			CAPTURE ( std::get < 0 > ( definition ), std::get < 1 > ( definition ), files.first, files.second );
+			runTest ( exact, std::get < 1 > ( definition ), files.first, files.second );
+		}
+	}*/
+
+	SECTION ( "Random tests" ) {
+		for ( size_t i = 0; i < RANDOM_ITERATIONS; i++ ) {
+			CAPTURE ( std::get < 0 > ( definition ), std::get < 1 > ( definition ), pattern, std::get < 2 > ( definition ) );
+			runRandom ( exact, std::get < 1 > ( definition ), pattern, std::get < 2 > ( definition ) );
+		}
+	}
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
 TEST_CASE ( "Arbology tests | pattern ends ", "[integration]" ) {
 	auto definition = GENERATE ( as < std::tuple < std::string, std::string, size_t > > ( ),
 		std::make_tuple ( "Exact Pattern Matching Using Compressed Bit Vectors (PrefixRanked)",
-- 
GitLab