From 2b235b23141dd2e2bed55881d4b8f6f1fb843d29 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 12 Aug 2014 19:07:15 +0200
Subject: [PATCH] templated base class of automata

---
 alib2data/src/automaton/AutomatonBase.cpp     | 66 -------------------
 alib2data/src/automaton/AutomatonBase.h       | 38 +----------
 alib2data/src/automaton/FSM/CompactNFA.cpp    | 12 ++++
 alib2data/src/automaton/FSM/CompactNFA.h      |  7 ++
 alib2data/src/automaton/FSM/DFA.cpp           | 12 ++++
 alib2data/src/automaton/FSM/DFA.h             |  7 ++
 alib2data/src/automaton/FSM/EpsilonNFA.cpp    | 12 ++++
 alib2data/src/automaton/FSM/EpsilonNFA.h      |  7 ++
 alib2data/src/automaton/FSM/ExtendedNFA.cpp   | 12 ++++
 alib2data/src/automaton/FSM/ExtendedNFA.h     |  7 ++
 alib2data/src/automaton/FSM/NFA.cpp           | 12 ++++
 alib2data/src/automaton/FSM/NFA.h             |  7 ++
 alib2data/src/automaton/PDA/NPDA.cpp          | 12 ++++
 alib2data/src/automaton/PDA/NPDA.h            |  8 +++
 alib2data/src/automaton/PDA/SinglePopNPDA.cpp | 12 ++++
 alib2data/src/automaton/PDA/SinglePopNPDA.h   |  7 ++
 alib2data/src/automaton/TM/OneTapeDTM.cpp     | 12 ++++
 alib2data/src/automaton/TM/OneTapeDTM.h       |  8 +++
 alib2data/src/automaton/UnknownAutomaton.cpp  | 16 +++++
 alib2data/src/automaton/UnknownAutomaton.h    | 11 +++-
 20 files changed, 181 insertions(+), 104 deletions(-)
 delete mode 100644 alib2data/src/automaton/AutomatonBase.cpp

diff --git a/alib2data/src/automaton/AutomatonBase.cpp b/alib2data/src/automaton/AutomatonBase.cpp
deleted file mode 100644
index 5f0b45eb22..0000000000
--- a/alib2data/src/automaton/AutomatonBase.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * AutomatonBase.cpp
- *
- *  Created on: Apr 16, 2013
- *      Author: Jan Travnicek
- */
-
-#include "AutomatonBase.h"
-
-namespace automaton {
-
-AutomatonBase::~AutomatonBase() {
-
-}
-
-bool AutomatonBase::operator!=(const AutomatonBase& other) const {
-	return !(*this == other);
-}
-
-bool AutomatonBase::operator==(const UnknownAutomaton&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const DFA&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const NFA&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const EpsilonNFA&) const{
-	return false;
-}
-
-bool AutomatonBase::operator==(const CompactNFA&) const{
-	return false;
-}
-
-bool AutomatonBase::operator==(const ExtendedNFA&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const NPDA&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const SinglePopNPDA&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const OneTapeDTM&) const {
-	return false;
-}
-
-bool AutomatonBase::operator==(const AutomatonBase&) const {
-	return false;
-}
-
-std::ostream& operator<<(std::ostream& os, const AutomatonBase& automaton) {
-	automaton >> os;
-	return os;
-}
-
-} /* namespace automaton */
-
diff --git a/alib2data/src/automaton/AutomatonBase.h b/alib2data/src/automaton/AutomatonBase.h
index 48bb33c069..a0e1057d08 100644
--- a/alib2data/src/automaton/AutomatonBase.h
+++ b/alib2data/src/automaton/AutomatonBase.h
@@ -9,7 +9,7 @@
 #define AUTOMATON_BASE_H_
 
 #include "../std/visitor.hpp"
-#include <iostream>
+#include "../common/base.hpp"
 
 namespace automaton {
 
@@ -26,41 +26,7 @@ class OneTapeDTM;
 /**
  * Abstract base class for all automata.
  */
-class AutomatonBase : public std::elementBase<UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, NPDA, SinglePopNPDA, OneTapeDTM> {
-public:
-	virtual AutomatonBase* clone() const = 0;
-
-	virtual AutomatonBase* plunder() && = 0;
-
-	virtual ~AutomatonBase() noexcept;
-
-	virtual bool operator!=(const AutomatonBase& other) const;
-
-	virtual bool operator==(const UnknownAutomaton& other) const;
-
-	virtual bool operator==(const DFA& other) const;
-
-	virtual bool operator==(const NFA& other) const;
-
-	virtual bool operator==(const EpsilonNFA& other) const;
-
-	virtual bool operator==(const CompactNFA& other) const;
-
-	virtual bool operator==(const ExtendedNFA& other) const;
-
-	virtual bool operator==(const NPDA& other) const;
-
-	virtual bool operator==(const SinglePopNPDA& other) const;
-
-	virtual bool operator==(const OneTapeDTM& other) const;
-
-	virtual bool operator==(const AutomatonBase& other) const = 0;
-
-	friend std::ostream& operator<<(std::ostream& os, const AutomatonBase& automaton);
-
-	virtual void operator>>(std::ostream&) const = 0;
-
-	virtual operator std::string () const = 0;
+class AutomatonBase : public alib::base<AutomatonBase, UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, NPDA, SinglePopNPDA, OneTapeDTM>, public std::elementBase<UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, NPDA, SinglePopNPDA, OneTapeDTM> {
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp
index 6671cf8e07..af6c0e970f 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2data/src/automaton/FSM/CompactNFA.cpp
@@ -113,10 +113,22 @@ bool CompactNFA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool CompactNFA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool CompactNFA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool CompactNFA::operator==(const CompactNFA& other) const {
 	return states == other.states && inputAlphabet == other.inputAlphabet && initialStates == other.initialStates && finalStates == other.finalStates && transitions == other.transitions;
 }
 
+bool CompactNFA::operator<(const CompactNFA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+}
+
 void CompactNFA::operator>>(std::ostream& out) const {
 	out << "(CompactNFA"
 		<< "states = " << states
diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h
index 17baf98b81..7b7dbb87e7 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.h
+++ b/alib2data/src/automaton/FSM/CompactNFA.h
@@ -70,13 +70,20 @@ public:
 	 */
 	std::map<std::pair<State, string::String>, std::set<State>> getTransitionsToState(const State& from) const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const CompactNFA& other) const;
+	virtual bool operator<(const CompactNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/FSM/DFA.cpp b/alib2data/src/automaton/FSM/DFA.cpp
index 6ff34348fb..dfa4247aa7 100644
--- a/alib2data/src/automaton/FSM/DFA.cpp
+++ b/alib2data/src/automaton/FSM/DFA.cpp
@@ -136,10 +136,22 @@ bool DFA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool DFA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool DFA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool DFA::operator==(const DFA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->transitions == other.transitions;
 }
 
+bool DFA::operator<(const DFA& other) const {
+	return std::tie(states, inputAlphabet, initialState, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+}
+
 void DFA::operator>>(std::ostream& out) const {
 	out << "(DFA"
 		<< " states = " << states
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index a87fd23d71..9813e3f949 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -80,13 +80,20 @@ public:
 	 */
 	bool isTotal() const;
 	
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const DFA& other) const;
+	virtual bool operator<(const DFA& other) const;
 	
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
index 2558499995..fc58c463da 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
@@ -236,10 +236,22 @@ bool EpsilonNFA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool EpsilonNFA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool EpsilonNFA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool EpsilonNFA::operator==(const EpsilonNFA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
 }
 
+bool EpsilonNFA::operator<(const EpsilonNFA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+}
+
 void EpsilonNFA::operator>>(std::ostream& out) const {
 	out << "(EpsilonNFA"
 		<< " states = " << states
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h
index d60f89c74c..2623f31db4 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.h
@@ -151,13 +151,20 @@ public:
 	 */
 	bool isTotal() const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const EpsilonNFA& other) const;
+	virtual bool operator<(const EpsilonNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
index e376438117..b15129083f 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
@@ -113,10 +113,22 @@ bool ExtendedNFA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool ExtendedNFA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool ExtendedNFA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool ExtendedNFA::operator==(const ExtendedNFA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
 }
 
+bool ExtendedNFA::operator<(const ExtendedNFA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+}
+
 void ExtendedNFA::operator>>(std::ostream& out) const {
 	out << "(ExtendedNFA"
 		<< " states = " << states
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index c95bb77aa3..493442e8f9 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -69,13 +69,20 @@ public:
 	 */
 	std::map<std::pair<State, regexp::RegExp>, std::set<State> > getTransitionsToState(const State& from) const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const ExtendedNFA& other) const;
+	virtual bool operator<(const ExtendedNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp
index ff79e0b4d8..24896aa6e2 100644
--- a/alib2data/src/automaton/FSM/NFA.cpp
+++ b/alib2data/src/automaton/FSM/NFA.cpp
@@ -125,10 +125,22 @@ bool NFA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool NFA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool NFA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool NFA::operator==(const NFA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
 }
 
+bool NFA::operator<(const NFA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+}
+
 void NFA::operator>>(std::ostream& out) const {
 	out << "(NFA"
 		<< " states = " << states
diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h
index 8bcfba5c5b..ff3a98ca17 100644
--- a/alib2data/src/automaton/FSM/NFA.h
+++ b/alib2data/src/automaton/FSM/NFA.h
@@ -89,13 +89,20 @@ public:
 	 */
 	bool isTotal() const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const NFA& other) const;
+	virtual bool operator<(const NFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/PDA/NPDA.cpp b/alib2data/src/automaton/PDA/NPDA.cpp
index 6a4809e22a..d321a1a398 100644
--- a/alib2data/src/automaton/PDA/NPDA.cpp
+++ b/alib2data/src/automaton/PDA/NPDA.cpp
@@ -137,10 +137,22 @@ bool NPDA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool NPDA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool NPDA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool NPDA::operator==(const NPDA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbols == other.initialSymbols && this->transitions == other.transitions;
 }
 
+bool NPDA::operator<(const NPDA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.transitions);
+}
+
 void NPDA::operator>>(std::ostream& out) const {
 	out << "(NPDA"
 		<< "states = " << states
diff --git a/alib2data/src/automaton/PDA/NPDA.h b/alib2data/src/automaton/PDA/NPDA.h
index dc4c65c5f1..8a816223d7 100644
--- a/alib2data/src/automaton/PDA/NPDA.h
+++ b/alib2data/src/automaton/PDA/NPDA.h
@@ -75,13 +75,21 @@ public:
 	 */
 	const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >& getTransitions() const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const NPDA& other) const;
 
+	virtual bool operator<(const NPDA& other) const;
+
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.cpp b/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
index cb7787a39a..8479e3d798 100644
--- a/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
+++ b/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
@@ -133,10 +133,22 @@ bool SinglePopNPDA::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool SinglePopNPDA::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool SinglePopNPDA::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool SinglePopNPDA::operator==(const SinglePopNPDA& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbols == other.initialSymbols && this->transitions == other.transitions;
 }
 
+bool SinglePopNPDA::operator<(const SinglePopNPDA& other) const {
+	return std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.transitions);
+}
+
 void SinglePopNPDA::operator>>(std::ostream& out) const {
 	out << "(SinglePopNPDA"
 		<< "states = " << states
diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.h b/alib2data/src/automaton/PDA/SinglePopNPDA.h
index 12767c98da..889259d248 100644
--- a/alib2data/src/automaton/PDA/SinglePopNPDA.h
+++ b/alib2data/src/automaton/PDA/SinglePopNPDA.h
@@ -75,13 +75,20 @@ public:
 	 */
 	const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<std::pair<State, std::vector<alphabet::Symbol> > > >& getTransitions() const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const SinglePopNPDA& other) const;
+	virtual bool operator<(const SinglePopNPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.cpp b/alib2data/src/automaton/TM/OneTapeDTM.cpp
index 27fb8467af..27f85323eb 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.cpp
+++ b/alib2data/src/automaton/TM/OneTapeDTM.cpp
@@ -115,10 +115,22 @@ bool OneTapeDTM::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool OneTapeDTM::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool OneTapeDTM::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool OneTapeDTM::operator==(const OneTapeDTM& other) const {
 	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->tapeAlphabet == other.tapeAlphabet && this->blankSymbol == other.blankSymbol && this->transitions == other.transitions;
 }
 
+bool OneTapeDTM::operator<(const OneTapeDTM& other) const {
+	return std::tie(states, inputAlphabet, initialState, finalStates, tapeAlphabet, blankSymbol, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.tapeAlphabet, other.blankSymbol, other.transitions);
+}
+
 void OneTapeDTM::operator>>(std::ostream& out) const {
 	out << "(OneTapeDTM"
 			<< "states = " << states
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h
index 0329719551..2a83fcc645 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.h
+++ b/alib2data/src/automaton/TM/OneTapeDTM.h
@@ -73,13 +73,21 @@ public:
 	 */
 	const std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> >& getTransitions() const;
 
+	virtual bool operator<(const AutomatonBase& other) const;
 	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator>(const AutomatonBase& other) const;
 
 	virtual bool operator==(const OneTapeDTM& other) const;
 
+	virtual bool operator<(const OneTapeDTM& other) const;
+
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2data/src/automaton/UnknownAutomaton.cpp b/alib2data/src/automaton/UnknownAutomaton.cpp
index 19eed66137..9c6ef85db7 100644
--- a/alib2data/src/automaton/UnknownAutomaton.cpp
+++ b/alib2data/src/automaton/UnknownAutomaton.cpp
@@ -8,6 +8,7 @@
 #include "UnknownAutomaton.h"
 #include "../std/set.hpp"
 #include <sstream>
+#include "../std/pointer.hpp"
 
 #include "AutomatonException.h"
 
@@ -184,6 +185,14 @@ bool UnknownAutomaton::operator==(const AutomatonBase& other) const {
 	return other == *this;
 }
 
+bool UnknownAutomaton::operator<(const AutomatonBase& other) const {
+	return other > *this;
+}
+
+bool UnknownAutomaton::operator>(const AutomatonBase& other) const {
+	return other < *this;
+}
+
 bool UnknownAutomaton::operator==(const UnknownAutomaton& other) const {
 	return states == other.states
 		&& inputAlphabet == other.inputAlphabet
@@ -196,6 +205,13 @@ bool UnknownAutomaton::operator==(const UnknownAutomaton& other) const {
 		&& transitions == other.transitions;
 }
 
+bool UnknownAutomaton::operator<(const UnknownAutomaton& other) const {
+	std::pointer<alphabet::Symbol> blankSymbolPointer(blankSymbol);
+	std::pointer<alphabet::Symbol> otherBlankSymbolPointer(other.blankSymbol);
+
+	return std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, tapeAlphabet, blankSymbolPointer, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.tapeAlphabet, otherBlankSymbolPointer, other.transitions);
+}
+
 void UnknownAutomaton::operator>>(std::ostream& out) const {
 	out << "(UnknownAutomaton"
 		<< " states = " << states
diff --git a/alib2data/src/automaton/UnknownAutomaton.h b/alib2data/src/automaton/UnknownAutomaton.h
index f8bd8f1375..986a52df24 100644
--- a/alib2data/src/automaton/UnknownAutomaton.h
+++ b/alib2data/src/automaton/UnknownAutomaton.h
@@ -271,17 +271,24 @@ public:
 	 */
 	const std::set<UnknownTransition>& getTransitions() const;
 	
+	virtual bool operator>(const AutomatonBase& other) const;
+	virtual bool operator==(const AutomatonBase& other) const;
+	virtual bool operator<(const AutomatonBase& other) const;
+
 	/**
 	 * Compares two instances of UnknownAutomata
 	 * @return true if this and other instance are same
 	 */
+	virtual bool operator<(const UnknownAutomaton& other) const;
 	virtual bool operator==(const UnknownAutomaton& other) const;
 
-	virtual bool operator==(const AutomatonBase& other) const;
-
 	virtual void operator>>(std::ostream& os) const;
 
 	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
 };
 
 } /* namespace automaton */
-- 
GitLab