diff --git a/alib2data/src/alphabet/BarSymbol.cpp b/alib2data/src/alphabet/BarSymbol.cpp
index b357bd372f67efcfe2d6febd212ffa1c141eeae2..03aeee92a693614c3328ee33f2224d908c7ac309 100644
--- a/alib2data/src/alphabet/BarSymbol.cpp
+++ b/alib2data/src/alphabet/BarSymbol.cpp
@@ -21,24 +21,12 @@ SymbolBase* BarSymbol::plunder() && {
 	return new BarSymbol(std::move(*this));
 }
 
-bool BarSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int BarSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool BarSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool BarSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool BarSymbol::operator ==(const BarSymbol&) const {
-	return true;
-}
-
-bool BarSymbol::operator <(const BarSymbol&) const {
-	return false;
+int BarSymbol::compare(const BarSymbol&) const {
+	return 0;
 }
 
 void BarSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/BarSymbol.h b/alib2data/src/alphabet/BarSymbol.h
index 2932dd439e84ddd20494ab2b08ee567fd3d02f16..1368321a3c2eb3fd574c985c49e95cde113ae798 100644
--- a/alib2data/src/alphabet/BarSymbol.h
+++ b/alib2data/src/alphabet/BarSymbol.h
@@ -26,12 +26,8 @@ public:
 	virtual SymbolBase* clone() const;
 	virtual SymbolBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const BarSymbol& other) const;
-	virtual bool operator <(const BarSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const BarSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/BlankSymbol.cpp b/alib2data/src/alphabet/BlankSymbol.cpp
index ff267cb0c6d9f9354de3545f15d6fa68ceb4b282..6217ac0c8e6488eb2c98bea36e126c41e408c623 100644
--- a/alib2data/src/alphabet/BlankSymbol.cpp
+++ b/alib2data/src/alphabet/BlankSymbol.cpp
@@ -21,24 +21,12 @@ SymbolBase* BlankSymbol::plunder() && {
 	return new BlankSymbol(std::move(*this));
 }
 
-bool BlankSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int BlankSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool BlankSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool BlankSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool BlankSymbol::operator ==(const BlankSymbol&) const {
-	return true;
-}
-
-bool BlankSymbol::operator <(const BlankSymbol&) const {
-	return false;
+int BlankSymbol::compare(const BlankSymbol&) const {
+	return 0;
 }
 
 void BlankSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/BlankSymbol.h b/alib2data/src/alphabet/BlankSymbol.h
index 422432b38f1b491e4e07b1c5867aa0a575ff459a..962095050e8e1beda4869fc4ce7b2d97d8bd7833 100644
--- a/alib2data/src/alphabet/BlankSymbol.h
+++ b/alib2data/src/alphabet/BlankSymbol.h
@@ -26,12 +26,8 @@ public:
 	virtual SymbolBase* clone() const;
 	virtual SymbolBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const BlankSymbol& other) const;
-	virtual bool operator <(const BlankSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const BlankSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/BottomOfTheStackSymbol.cpp b/alib2data/src/alphabet/BottomOfTheStackSymbol.cpp
index e122375cc44b2a72536619fb7845beeb8d74afff..f20bbf187dfc51a960e0ee97af422620de9083aa 100644
--- a/alib2data/src/alphabet/BottomOfTheStackSymbol.cpp
+++ b/alib2data/src/alphabet/BottomOfTheStackSymbol.cpp
@@ -21,24 +21,12 @@ SymbolBase* BottomOfTheStackSymbol::plunder() && {
 	return new BottomOfTheStackSymbol(std::move(*this));
 }
 
-bool BottomOfTheStackSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int BottomOfTheStackSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool BottomOfTheStackSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool BottomOfTheStackSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool BottomOfTheStackSymbol::operator ==(const BottomOfTheStackSymbol&) const {
-	return true;
-}
-
-bool BottomOfTheStackSymbol::operator <(const BottomOfTheStackSymbol&) const {
-	return false;
+int BottomOfTheStackSymbol::compare(const BottomOfTheStackSymbol&) const {
+	return 0;
 }
 
 void BottomOfTheStackSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/BottomOfTheStackSymbol.h b/alib2data/src/alphabet/BottomOfTheStackSymbol.h
index 91c73bef286461d1ab4fff9cb4c02c08d166cb92..3494fcbf2799a5b65410b58ba40291d8da0586a1 100644
--- a/alib2data/src/alphabet/BottomOfTheStackSymbol.h
+++ b/alib2data/src/alphabet/BottomOfTheStackSymbol.h
@@ -26,12 +26,8 @@ public:
 	virtual SymbolBase* clone() const;
 	virtual SymbolBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const BottomOfTheStackSymbol& other) const;
-	virtual bool operator <(const BottomOfTheStackSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const BottomOfTheStackSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/EndSymbol.cpp b/alib2data/src/alphabet/EndSymbol.cpp
index 5ff720d88c8d1709d67211514d2607ac36dd5c64..958950ee5900838437c8ecd2f7998b55f17193db 100644
--- a/alib2data/src/alphabet/EndSymbol.cpp
+++ b/alib2data/src/alphabet/EndSymbol.cpp
@@ -21,24 +21,12 @@ SymbolBase* EndSymbol::plunder() && {
 	return new EndSymbol(std::move(*this));
 }
 
-bool EndSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int EndSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool EndSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool EndSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool EndSymbol::operator ==(const EndSymbol&) const {
-	return true;
-}
-
-bool EndSymbol::operator <(const EndSymbol&) const {
-	return false;
+int EndSymbol::compare(const EndSymbol&) const {
+	return 0;
 }
 
 void EndSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/EndSymbol.h b/alib2data/src/alphabet/EndSymbol.h
index dd1f88c29c1b1040479360a5582b8e9b708208af..49e07097a38b0fb0f83b7ea20dec418b2aaf1538 100644
--- a/alib2data/src/alphabet/EndSymbol.h
+++ b/alib2data/src/alphabet/EndSymbol.h
@@ -26,12 +26,8 @@ public:
 	virtual SymbolBase* clone() const;
 	virtual SymbolBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const EndSymbol& other) const;
-	virtual bool operator <(const EndSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const EndSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/LabeledSymbol.cpp b/alib2data/src/alphabet/LabeledSymbol.cpp
index 203cc91217bdc8db18af8385cd2e866adc24f517..8bb3cee5d055fee96f01cfd2336e21b1b46e135a 100644
--- a/alib2data/src/alphabet/LabeledSymbol.cpp
+++ b/alib2data/src/alphabet/LabeledSymbol.cpp
@@ -41,24 +41,12 @@ const label::Label& LabeledSymbol::getLabel() const {
 	return label;
 }
 
-bool LabeledSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int LabeledSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LabeledSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool LabeledSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool LabeledSymbol::operator ==(const LabeledSymbol& other) const {
-	return this->label == other.label;
-}
-
-bool LabeledSymbol::operator <(const LabeledSymbol& other) const {
-	return this->label < other.label;
+int LabeledSymbol::compare(const LabeledSymbol& other) const {
+	return this->label.getData().compare(other.label.getData());
 }
 
 void LabeledSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/LabeledSymbol.h b/alib2data/src/alphabet/LabeledSymbol.h
index 76a36e410d728945ebe87233aa2980fd05111b1f..e3ef61a405f16f9e7cf8c97f46b9d8e60e2a265d 100644
--- a/alib2data/src/alphabet/LabeledSymbol.h
+++ b/alib2data/src/alphabet/LabeledSymbol.h
@@ -41,12 +41,8 @@ public:
 	 */
 	const label::Label& getLabel() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const LabeledSymbol& other) const;
-	virtual bool operator <(const LabeledSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const LabeledSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/RankedBarSymbol.cpp b/alib2data/src/alphabet/RankedBarSymbol.cpp
index 577f390ac98db6e863ef59ca155009bea5e75045..9fbee197e023c1f59aaf7045acff464f2214a7c3 100644
--- a/alib2data/src/alphabet/RankedBarSymbol.cpp
+++ b/alib2data/src/alphabet/RankedBarSymbol.cpp
@@ -29,24 +29,12 @@ const primitive::Integer& RankedBarSymbol::getRank() const {
 	return rank;
 }
 
-bool RankedBarSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int RankedBarSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RankedBarSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool RankedBarSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool RankedBarSymbol::operator ==(const RankedBarSymbol&) const {
-	return true;
-}
-
-bool RankedBarSymbol::operator <(const RankedBarSymbol&) const {
-	return false;
+int RankedBarSymbol::compare(const RankedBarSymbol&) const {
+	return 0;
 }
 
 void RankedBarSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/RankedBarSymbol.h b/alib2data/src/alphabet/RankedBarSymbol.h
index ace0266530e011f4c361cfef96d83721b3d47c90..64e7e598adaf5770a5df484bb7b622e3a6d96a62 100644
--- a/alib2data/src/alphabet/RankedBarSymbol.h
+++ b/alib2data/src/alphabet/RankedBarSymbol.h
@@ -34,12 +34,8 @@ public:
 	 */
 	const primitive::Integer& getRank() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const RankedBarSymbol& other) const;
-	virtual bool operator <(const RankedBarSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RankedBarSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/RankedSymbol.cpp b/alib2data/src/alphabet/RankedSymbol.cpp
index eab63d315e797f1e65918a465426fe7825f52524..5b09ee5b641b8622214e08b3f268b50b814cdd2e 100644
--- a/alib2data/src/alphabet/RankedSymbol.cpp
+++ b/alib2data/src/alphabet/RankedSymbol.cpp
@@ -45,26 +45,14 @@ const primitive::Integer& RankedSymbol::getRank() const {
 	return rank;
 }
 
-bool RankedSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int RankedSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RankedSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool RankedSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool RankedSymbol::operator ==(const RankedSymbol& other) const {
-	return this->label == other.label && this -> rank == other.rank;
-}
-
-bool RankedSymbol::operator <(const RankedSymbol& other) const {
-	if (this->label < other.label) return true;
-	else if (this -> label == other.label) return this -> rank < other.rank;
-	else return false;
+int RankedSymbol::compare(const RankedSymbol& other) const {
+	int res = this->label.getData().compare(other.label.getData());
+	if(res == 0) res = this->rank.compare(other.rank);
+	return res;
 }
 
 void RankedSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/RankedSymbol.h b/alib2data/src/alphabet/RankedSymbol.h
index 4f2f2b43b62206867eab088717ae3c7585dd8d04..e759a42fc49537af39cf44b444436336deee827d 100644
--- a/alib2data/src/alphabet/RankedSymbol.h
+++ b/alib2data/src/alphabet/RankedSymbol.h
@@ -49,12 +49,8 @@ public:
 	 */
 	const primitive::Integer& getRank() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const RankedSymbol& other) const;
-	virtual bool operator <(const RankedSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RankedSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/alphabet/SubtreeWildcardSymbol.cpp b/alib2data/src/alphabet/SubtreeWildcardSymbol.cpp
index 52d0d87b00a868f7571164ceb4d16d67f0c583b9..908adc43c024588dd6a605550b0f93e1ca7979f1 100644
--- a/alib2data/src/alphabet/SubtreeWildcardSymbol.cpp
+++ b/alib2data/src/alphabet/SubtreeWildcardSymbol.cpp
@@ -21,24 +21,12 @@ SymbolBase* SubtreeWildcardSymbol::plunder() && {
 	return new SubtreeWildcardSymbol(std::move(*this));
 }
 
-bool SubtreeWildcardSymbol::operator <(const ObjectBase& other) const {
-	return other > *this;
+int SubtreeWildcardSymbol::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool SubtreeWildcardSymbol::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool SubtreeWildcardSymbol::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool SubtreeWildcardSymbol::operator ==(const SubtreeWildcardSymbol&) const {
-	return true;
-}
-
-bool SubtreeWildcardSymbol::operator <(const SubtreeWildcardSymbol&) const {
-	return false;
+int SubtreeWildcardSymbol::compare(const SubtreeWildcardSymbol&) const {
+	return 0;
 }
 
 void SubtreeWildcardSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/alphabet/SubtreeWildcardSymbol.h b/alib2data/src/alphabet/SubtreeWildcardSymbol.h
index 7237b9bc6157a354c7af8a17ee036b33894e609c..c9bcb75b2e70190839827e67ca32646d7b05754d 100644
--- a/alib2data/src/alphabet/SubtreeWildcardSymbol.h
+++ b/alib2data/src/alphabet/SubtreeWildcardSymbol.h
@@ -26,12 +26,8 @@ public:
 	virtual SymbolBase* clone() const;
 	virtual SymbolBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const SubtreeWildcardSymbol& other) const;
-	virtual bool operator <(const SubtreeWildcardSymbol& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const SubtreeWildcardSymbol& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp
index 14a1d3b804276a8195517e4936681075ce2c440e..e57181fdb3b78be73359d9877476a1e491f5390e 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2data/src/automaton/FSM/CompactNFA.cpp
@@ -164,24 +164,20 @@ std::map<std::pair<State, string::LinearString>, std::set<State>> CompactNFA::ge
 	return transitionsToState;
 }
 
-bool CompactNFA::operator==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool CompactNFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool CompactNFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool CompactNFA::operator==(const CompactNFA& other) const {
-	return states == other.states && inputAlphabet == other.inputAlphabet && initialState == other.initialState && finalStates == other.finalStates && transitions == other.transitions;
-}
-
-bool CompactNFA::operator<(const CompactNFA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+int CompactNFA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
+}
+
+int CompactNFA::compare(const CompactNFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void CompactNFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h
index 9993c60998e3d37adce31d452bad0ad83e7925d5..22f0ac7c09e421e25297505c5b2660272d4b7070 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.h
+++ b/alib2data/src/automaton/FSM/CompactNFA.h
@@ -79,12 +79,8 @@ public:
 	 */
 	std::map<std::pair<State, string::LinearString>, std::set<State>> getTransitionsToState(const State& from) const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const CompactNFA& other) const;
-	virtual bool operator<(const CompactNFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const CompactNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/FSM/DFA.cpp b/alib2data/src/automaton/FSM/DFA.cpp
index 5037f60424a77019b10fddc891111be355808c71..1c8c5e17066c94c1c818948668e0b03fc92614e9 100644
--- a/alib2data/src/automaton/FSM/DFA.cpp
+++ b/alib2data/src/automaton/FSM/DFA.cpp
@@ -132,24 +132,21 @@ bool DFA::isTotal() const {
 	return transitions.size() == inputAlphabet.size() * states.size();
 }
 
-bool DFA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int DFA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool DFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool DFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int DFA::compare(const DFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
 
-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);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void DFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index cd5344e6f35027535661c4acb6b036b6146ef4ae..3059c4d7755b7ed3609a613afd1bc5bac44949d7 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -80,12 +80,8 @@ public:
 	 */
 	bool isTotal() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const DFA& other) const;
-	virtual bool operator<(const DFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const DFA& other) const;
 	
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
index 1c47c21f6648bb2a8108927aaf34f6c2c32aa05c..99ebddec3225069aaa37495179dd9478e5fbef87 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
@@ -265,24 +265,21 @@ bool EpsilonNFA::isTotal() const {
 	return isDeterministic() && transitions.size() == inputAlphabet.size() * states.size();
 }
 
-bool EpsilonNFA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int EpsilonNFA::compare(const ObjectBase& other) const {
+	return other.compare(*this);
 }
 
-bool EpsilonNFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool EpsilonNFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int EpsilonNFA::compare(const EpsilonNFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
 
-bool EpsilonNFA::operator==(const EpsilonNFA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->transitions == other.transitions;
-}
-
-bool EpsilonNFA::operator<(const EpsilonNFA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void EpsilonNFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h
index 317e3cb8b40802f405b821934fb075fc898f2f78..22aabff97a90e99d4206cd410daa3af79f6513b6 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.h
@@ -158,12 +158,8 @@ public:
 	 */
 	bool isTotal() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const EpsilonNFA& other) const;
-	virtual bool operator<(const EpsilonNFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const EpsilonNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
index bbbc0181973bae23577cb8247a60b2c2b482b848..9e9a7a42017f9c237283b6af9397602a5a5132ec 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
@@ -176,24 +176,21 @@ std::map<std::pair<State, regexp::RegExp>, std::set<State> > ExtendedNFA::getTra
 	return transitionsToState;
 }
 
-bool ExtendedNFA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int ExtendedNFA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool ExtendedNFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ExtendedNFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int ExtendedNFA::compare(const ExtendedNFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
 
-bool ExtendedNFA::operator==(const ExtendedNFA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->transitions == other.transitions;
-}
-
-bool ExtendedNFA::operator<(const ExtendedNFA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void ExtendedNFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index d13f02c02fb6d43451d9b7ca2b6b6a8b38258ec5..375f682c4a0d97aedb600fc2c38a0d68901c751e 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -81,12 +81,8 @@ public:
 	 */
 	std::map<std::pair<State, regexp::RegExp>, std::set<State> > getTransitionsToState(const State& from) const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ExtendedNFA& other) const;
-	virtual bool operator<(const ExtendedNFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ExtendedNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
index 40cf2cd0fa71e99f78c7bb021ee40b6bb356e3e7..368272c2aca2b8be5f6883f3909ba63f4d1d581f 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
@@ -155,24 +155,21 @@ unsigned MultiInitialStateNFA::transitionsSize() const {
 	return res;
 }
 
-bool MultiInitialStateNFA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int MultiInitialStateNFA::compare(const ObjectBase& other) const {
+	return other.compare(*this);
 }
 
-bool MultiInitialStateNFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool MultiInitialStateNFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int MultiInitialStateNFA::compare(const MultiInitialStateNFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialStates, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
 
-bool MultiInitialStateNFA::operator==(const MultiInitialStateNFA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
-}
-
-bool MultiInitialStateNFA::operator<(const MultiInitialStateNFA& other) const {
-	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void MultiInitialStateNFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
index d026d17e22d1f06a3394438621ea5ad86abd9453..bef36397b1725896919c0754f226246822dff347 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
@@ -97,12 +97,8 @@ public:
 
 	unsigned transitionsSize() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const MultiInitialStateNFA& other) const;
-	virtual bool operator<(const MultiInitialStateNFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const MultiInitialStateNFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp
index f92be7d733b9e850a894a0091be3c0bd37164ba9..510bf9c92d8fee6462281cd255620634505787cf 100644
--- a/alib2data/src/automaton/FSM/NFA.cpp
+++ b/alib2data/src/automaton/FSM/NFA.cpp
@@ -138,24 +138,21 @@ unsigned NFA::transitionsSize() const {
 	return res;
 }
 
-bool NFA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int NFA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool NFA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool NFA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int NFA::compare(const NFA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
 
-bool NFA::operator==(const NFA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->transitions == other.transitions;
-}
-
-bool NFA::operator<(const NFA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void NFA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h
index 0221b9d36a931771108ae32dfd8d299ccffe1140..c998bad2e75742c90cd407edeb898a1b7e5b4db6 100644
--- a/alib2data/src/automaton/FSM/NFA.h
+++ b/alib2data/src/automaton/FSM/NFA.h
@@ -95,12 +95,8 @@ public:
 
 	unsigned transitionsSize() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const NFA& other) const;
-	virtual bool operator<(const NFA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const NFA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/DPDA.cpp b/alib2data/src/automaton/PDA/DPDA.cpp
index 08bf733a06bbaf279eedd5decc193561218ba4e0..9db8052048413675a2b2af8e18785844ad01f677 100644
--- a/alib2data/src/automaton/PDA/DPDA.cpp
+++ b/alib2data/src/automaton/PDA/DPDA.cpp
@@ -222,24 +222,21 @@ std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std:
 	return transitionsToState;
 }
 
-bool DPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int DPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool DPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool DPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int DPDA::compare(const DPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
 
-bool DPDA::operator==(const DPDA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbol == other.initialSymbol && this->transitions == other.transitions;
-}
-
-bool DPDA::operator<(const DPDA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void DPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/DPDA.h b/alib2data/src/automaton/PDA/DPDA.h
index 4cd0154110fcb9a25aafe2152e0a69c9c6e8b7ca..4a3b2cba81794753aa2a3e208178a37134aba924 100644
--- a/alib2data/src/automaton/PDA/DPDA.h
+++ b/alib2data/src/automaton/PDA/DPDA.h
@@ -91,13 +91,8 @@ public:
 	 */
 	std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > getTransitionsToState(const State& from) const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const DPDA& other) const;
-
-	virtual bool operator<(const DPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const DPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp
index 573c4aab55d26d8da8162c7470d65a0bf2eb3c0d..c91056b197fc61497c97fb665cc7c045f323c03a 100644
--- a/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp
+++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp
@@ -174,24 +174,21 @@ bool InputDrivenNPDA::isDeterministic() const {
 	return true;
 }
 
-bool InputDrivenNPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int InputDrivenNPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool InputDrivenNPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool InputDrivenNPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int InputDrivenNPDA::compare(const InputDrivenNPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialStates, finalStates, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
 
-bool InputDrivenNPDA::operator==(const InputDrivenNPDA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions;
-}
-
-bool InputDrivenNPDA::operator<(const InputDrivenNPDA& other) const {
-	return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void InputDrivenNPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.h b/alib2data/src/automaton/PDA/InputDrivenNPDA.h
index 40e4c13b1154df9ab99de8984cf14660d5071bfd..1054c421a418c5010c7c55f2d338f4df52864ba5 100644
--- a/alib2data/src/automaton/PDA/InputDrivenNPDA.h
+++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.h
@@ -88,12 +88,8 @@ public:
 	 */
 	bool isDeterministic() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const InputDrivenNPDA& other) const;
-	virtual bool operator<(const InputDrivenNPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const InputDrivenNPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/NPDA.cpp b/alib2data/src/automaton/PDA/NPDA.cpp
index 7d01b68d80382983ebddf978af427aaa0602d3ef..c546b60c815fd1237885a69a99e4736f85be9d87 100644
--- a/alib2data/src/automaton/PDA/NPDA.cpp
+++ b/alib2data/src/automaton/PDA/NPDA.cpp
@@ -133,24 +133,21 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>
 	return transitions;
 }
 
-bool NPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int NPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool NPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool NPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int NPDA::compare(const NPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.transitions);
 
-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);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void NPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/NPDA.h b/alib2data/src/automaton/PDA/NPDA.h
index cf066b4f4b5b579627c97553a18ac1aa074a60ce..dbaf1b76d14f286dcbd5cad1e60d7174ca4dff10 100644
--- a/alib2data/src/automaton/PDA/NPDA.h
+++ b/alib2data/src/automaton/PDA/NPDA.h
@@ -75,13 +75,8 @@ 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 alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const NPDA& other) const;
-
-	virtual bool operator<(const NPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const NPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp
index 054fa7492d854225860041d909f3b576ea3fb827..fe7b406fdc5d09485f39df185246dfd196c158c7 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp
@@ -366,24 +366,21 @@ const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>
 		return localTransitions;
 }
 
-bool RealTimeHeightDeterministicDPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int RealTimeHeightDeterministicDPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RealTimeHeightDeterministicDPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool RealTimeHeightDeterministicDPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int RealTimeHeightDeterministicDPDA::compare(const RealTimeHeightDeterministicDPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
 
-bool RealTimeHeightDeterministicDPDA::operator==(const RealTimeHeightDeterministicDPDA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->bottomOfTheStackSymbol == other.bottomOfTheStackSymbol && this->callTransitions == other.callTransitions && this->returnTransitions == other.returnTransitions && this->localTransitions == other.localTransitions;
-}
-
-bool RealTimeHeightDeterministicDPDA::operator<(const RealTimeHeightDeterministicDPDA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void RealTimeHeightDeterministicDPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
index 505fec37f09aa5dc12068b77147b48717f167682..772e86ac0228fb4833f2ad21a125441a7b3b337e 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.h
@@ -118,12 +118,8 @@ public:
 
 	const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, State>& getLocalTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const RealTimeHeightDeterministicDPDA& other) const;
-	virtual bool operator<(const RealTimeHeightDeterministicDPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RealTimeHeightDeterministicDPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp
index 2d2d84169e5a3001cb65a1ae88e74fe3beb1a145..4f1ee73d7c7108b7d5bd99679eae481d0680118a 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp
@@ -257,24 +257,21 @@ const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>
 		return localTransitions;
 }
 
-bool RealTimeHeightDeterministicNPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int RealTimeHeightDeterministicNPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RealTimeHeightDeterministicNPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool RealTimeHeightDeterministicNPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int RealTimeHeightDeterministicNPDA::compare(const RealTimeHeightDeterministicNPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
 
-bool RealTimeHeightDeterministicNPDA::operator==(const RealTimeHeightDeterministicNPDA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->bottomOfTheStackSymbol == other.bottomOfTheStackSymbol && this->callTransitions == other.callTransitions && this->returnTransitions == other.returnTransitions && this->localTransitions == other.localTransitions;
-}
-
-bool RealTimeHeightDeterministicNPDA::operator<(const RealTimeHeightDeterministicNPDA& other) const {
-	return std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void RealTimeHeightDeterministicNPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
index 335111cd88eaad95c583a01d15ddb58d90299f4a..bf74a0fb6f612d9ea5631b6137a3c752b995b465 100644
--- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
+++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h
@@ -118,12 +118,8 @@ public:
 
 	const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<State> >& getLocalTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const RealTimeHeightDeterministicNPDA& other) const;
-	virtual bool operator<(const RealTimeHeightDeterministicNPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RealTimeHeightDeterministicNPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/SinglePopDPDA.cpp b/alib2data/src/automaton/PDA/SinglePopDPDA.cpp
index 2b14eb9227dd2342fa1dbbd143d0e0c2eb52ac67..e46690da38904ba9a8991c9c98421338899f20f6 100644
--- a/alib2data/src/automaton/PDA/SinglePopDPDA.cpp
+++ b/alib2data/src/automaton/PDA/SinglePopDPDA.cpp
@@ -168,24 +168,21 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>
 	return transitions;
 }
 
-bool SinglePopDPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int SinglePopDPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool SinglePopDPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool SinglePopDPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int SinglePopDPDA::compare(const SinglePopDPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
 
-bool SinglePopDPDA::operator==(const SinglePopDPDA& other) const {
-	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbol == other.initialSymbol && this->transitions == other.transitions;
-}
-
-bool SinglePopDPDA::operator<(const SinglePopDPDA& other) const {
-	return std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
+	if(first == second) {
+		return 0;
+	} else if(first == second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void SinglePopDPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/SinglePopDPDA.h b/alib2data/src/automaton/PDA/SinglePopDPDA.h
index 7bb5678904eb7216b072e8ea13be2812ffc5d7ae..0601a411a4c11e954cdd2d07d1347001233071db 100644
--- a/alib2data/src/automaton/PDA/SinglePopDPDA.h
+++ b/alib2data/src/automaton/PDA/SinglePopDPDA.h
@@ -81,12 +81,8 @@ public:
 	 */
 	const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >& getTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const SinglePopDPDA& other) const;
-	virtual bool operator<(const SinglePopDPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const SinglePopDPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.cpp b/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
index 3c8ab22981e067ba561158934329dc93f3a3bd29..e8c41744c035b842515b1aed6d123396b963a0b4 100644
--- a/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
+++ b/alib2data/src/automaton/PDA/SinglePopNPDA.cpp
@@ -129,24 +129,21 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>
 	return transitions;
 }
 
-bool SinglePopNPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int SinglePopNPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool SinglePopNPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool SinglePopNPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int SinglePopNPDA::compare(const SinglePopNPDA& other) const {
+	auto first = std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.transitions);
 
-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);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void SinglePopNPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.h b/alib2data/src/automaton/PDA/SinglePopNPDA.h
index 158f829819fbe14934991e8e2fddae1a348f1ff9..cfb143ee806ba70861b1224002423878674721eb 100644
--- a/alib2data/src/automaton/PDA/SinglePopNPDA.h
+++ b/alib2data/src/automaton/PDA/SinglePopNPDA.h
@@ -75,12 +75,8 @@ 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 alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const SinglePopNPDA& other) const;
-	virtual bool operator<(const SinglePopNPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const SinglePopNPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.cpp b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.cpp
index 40fd7413375e259caa7476e2f5ec3b15d44e4c42..34228a06661a97406001c67053bb5b81c7ba5d9a 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.cpp
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.cpp
@@ -264,24 +264,21 @@ const std::map<std::pair<State, alphabet::Symbol>, State>& VisiblyPushdownDPDA::
 		return localTransitions;
 }
 
-bool VisiblyPushdownDPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int VisiblyPushdownDPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool VisiblyPushdownDPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool VisiblyPushdownDPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int VisiblyPushdownDPDA::compare(const VisiblyPushdownDPDA& other) const {
+	auto first = std::tie(states, callInputAlphabet, returnInputAlphabet, localInputAlphabet, initialState, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions);
+	auto second = std::tie(other.states, other.callInputAlphabet, other.returnInputAlphabet, other.localInputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
 
-bool VisiblyPushdownDPDA::operator==(const VisiblyPushdownDPDA& other) const {
-	return this->states == other.states && this->callInputAlphabet == other.callInputAlphabet && this->returnInputAlphabet == other.returnInputAlphabet && this->localInputAlphabet == other.localInputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->bottomOfTheStackSymbol == other.bottomOfTheStackSymbol && this->callTransitions == other.callTransitions && this->returnTransitions == other.returnTransitions && this->localTransitions == other.localTransitions;
-}
-
-bool VisiblyPushdownDPDA::operator<(const VisiblyPushdownDPDA& other) const {
-	return std::tie(states, callInputAlphabet, returnInputAlphabet, localInputAlphabet, initialState, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.callInputAlphabet, other.returnInputAlphabet, other.localInputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void VisiblyPushdownDPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
index a4560a4c6a8118eac212f1607f660f2fb490ce48..5337610be8a2c03992310bafbac576c38923e2c3 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownDPDA.h
@@ -104,12 +104,8 @@ public:
 
 	const std::map<std::pair<State, alphabet::Symbol>, State>& getLocalTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const VisiblyPushdownDPDA& other) const;
-	virtual bool operator<(const VisiblyPushdownDPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const VisiblyPushdownDPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp
index 1963146e55ca538d5686d1d8918f9bd31f7a4001..bb270a28e7bffc4b7d2cd83727fade384cdb1a07 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp
@@ -197,24 +197,21 @@ const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >& VisiblyPus
 		return localTransitions;
 }
 
-bool VisiblyPushdownNPDA::operator==(const ObjectBase& other) const {
-	return other == *this;
+int VisiblyPushdownNPDA::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool VisiblyPushdownNPDA::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool VisiblyPushdownNPDA::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int VisiblyPushdownNPDA::compare(const VisiblyPushdownNPDA& other) const {
+	auto first = std::tie(states, callInputAlphabet, returnInputAlphabet, localInputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions);
+	auto second = std::tie(other.states, other.callInputAlphabet, other.returnInputAlphabet, other.localInputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
 
-bool VisiblyPushdownNPDA::operator==(const VisiblyPushdownNPDA& other) const {
-	return this->states == other.states && this->callInputAlphabet == other.callInputAlphabet && this->returnInputAlphabet == other.returnInputAlphabet && this->localInputAlphabet == other.localInputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->bottomOfTheStackSymbol == other.bottomOfTheStackSymbol && this->callTransitions == other.callTransitions && this->returnTransitions == other.returnTransitions && this->localTransitions == other.localTransitions;
-}
-
-bool VisiblyPushdownNPDA::operator<(const VisiblyPushdownNPDA& other) const {
-	return std::tie(states, callInputAlphabet, returnInputAlphabet, localInputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.callInputAlphabet, other.returnInputAlphabet, other.localInputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void VisiblyPushdownNPDA::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
index cb4d663312216da4bbe703f1a20b2382e17662e7..90fcae5106d101e415e1e759f16b68d781e5f714 100644
--- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
+++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h
@@ -104,12 +104,8 @@ public:
 
 	const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >& getLocalTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const VisiblyPushdownNPDA& other) const;
-	virtual bool operator<(const VisiblyPushdownNPDA& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const VisiblyPushdownNPDA& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.cpp b/alib2data/src/automaton/TM/OneTapeDTM.cpp
index 77b7281862fe9753428908ce0441374dd98b9aed..9951f1f2c3a7e379be28ff24010783d7996cabc5 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.cpp
+++ b/alib2data/src/automaton/TM/OneTapeDTM.cpp
@@ -114,24 +114,21 @@ const std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::S
 	return transitions;
 }
 
-bool OneTapeDTM::operator==(const ObjectBase& other) const {
-	return other == *this;
+int OneTapeDTM::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool OneTapeDTM::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool OneTapeDTM::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int OneTapeDTM::compare(const OneTapeDTM& other) const {
+	auto first = std::tie(states, inputAlphabet, initialState, finalStates, tapeAlphabet, blankSymbol, transitions);
+	auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.tapeAlphabet, other.blankSymbol, other.transitions);
 
-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);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void OneTapeDTM::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h
index 40a366862ae32d1171c0422ca5f2e1636c594936..b8da5bdc4c6b025730d9388fd92353e1e956925c 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.h
+++ b/alib2data/src/automaton/TM/OneTapeDTM.h
@@ -73,13 +73,8 @@ public:
 	 */
 	const std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> >& getTransitions() const;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const OneTapeDTM& other) const;
-
-	virtual bool operator<(const OneTapeDTM& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const OneTapeDTM& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/common/base.hpp b/alib2data/src/common/base.hpp
index 54c1a5df1b821d91e99a61060383782e60dd79dd..4e13245d96d180d5972a8473a9832b9074916b0a 100644
--- a/alib2data/src/common/base.hpp
+++ b/alib2data/src/common/base.hpp
@@ -10,17 +10,13 @@
 
 #include <typeinfo>
 #include <ostream>
+#include <stdexcept>
 
 namespace alib {
 
 template<int ID>
 class base_base {
 public:
-/*	template<typename T>
-	static int typeId() {
-		return ID;
-	}*/
-
 	virtual int selfTypeId() const = 0;
 
 	virtual ~base_base() noexcept {
@@ -39,20 +35,20 @@ public:
 		return ID;
 	}
 
-	virtual bool operator==(const T &) const {
-		return false;
-	}
-
-	virtual bool operator<(const T &) const {
-		return this->selfTypeId() < typeId<T>();
+	virtual int compare(const T &) const {
+		if(this->selfTypeId() < typeId<T>())
+			return -1;
+		else if(this->selfTypeId() > typeId<T>())
+			return 1;
+		else
+			throw std::logic_error("Should not be reached");
 	}
 };
 
 template<int ID, typename T, typename... Types>
 class base_helper<ID, T, Types...> : public base_helper<ID + 1, Types...> {
 public:
-	using base_helper<ID + 1, Types...>::operator==;
-	using base_helper<ID + 1, Types...>::operator<;
+	using base_helper<ID + 1, Types...>::compare;
 	using base_helper<ID + 1, Types...>::typeId;
 
 	template<typename R, typename std::enable_if < std::is_same< R, T >::value >::type* = nullptr >
@@ -60,20 +56,20 @@ public:
 		return ID;
 	}
 
-	virtual bool operator==(const T &) const {
-		return false;
-	}
-
-	virtual bool operator<(const T &) const {
-		return this->selfTypeId() < typeId<T>();
+	virtual int compare(const T &) const {
+		if(this->selfTypeId() < typeId<T>())
+			return -1;
+		else if(this->selfTypeId() > typeId<T>())
+			return 1;
+		else
+			throw std::logic_error("Should not be reached");
 	}
 };
 
 template<typename T, typename... Types>
 class base : public base_helper<1, Types...> {
 public:
-	using base_helper<1, Types...>::operator==;
-	using base_helper<1, Types...>::operator<;
+	using base_helper<1, Types...>::compare;
 	using base_helper<1, Types...>::typeId;
 
 	virtual T* clone() const = 0;
@@ -84,10 +80,19 @@ public:
 		return !(*this == other);
 	}
 
-	virtual bool operator==(const T& other) const = 0;
+	bool operator==(const T& other) const {
+		return this->compare(other) == 0;
+	}
+
+	bool operator<(const T& other) const {
+		return this->compare(other) < 0;
+	}
+
+	bool operator>(const T& other) const {
+		return this->compare(other) > 0;
+	}
 
-	virtual bool operator<(const T& other) const = 0;
-	virtual bool operator>(const T& other) const = 0;
+	virtual int compare(const T& other) const = 0;
 
 	friend std::ostream& operator<<(std::ostream& os, const T& instance) {
 		instance >> os;
diff --git a/alib2data/src/container/ObjectsMap.cpp b/alib2data/src/container/ObjectsMap.cpp
index f8b07ca4bbd8a789dfe0a6c16317a20421794518..9dfc2156b5ac10225fd5af6c5269dda4f0f9d214 100644
--- a/alib2data/src/container/ObjectsMap.cpp
+++ b/alib2data/src/container/ObjectsMap.cpp
@@ -22,24 +22,19 @@ ContainerBase* ObjectsMap::plunder() && {
 	return new ObjectsMap(std::move(*this));
 }
 
-bool ObjectsMap::operator==(const ObjectBase& other) const {
-	return other == *this;
+int ObjectsMap::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool ObjectsMap::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ObjectsMap::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool ObjectsMap::operator==(const ObjectsMap& other) const {
-	return static_cast<const std::map<alib::Object, alib::Object>>(*this) == static_cast<const std::map<alib::Object, alib::Object>>(other);
-}
+int ObjectsMap::compare(const ObjectsMap& other) const {
+	if(static_cast<const std::map<alib::Object, alib::Object>>(*this) == static_cast<const std::map<alib::Object, alib::Object>>(other)) {
+		return 0;
+	} else if(static_cast<const std::map<alib::Object, alib::Object>>(*this) < static_cast<const std::map<alib::Object, alib::Object>>(other)) {
+		return -1;
+	} else {
+		return 1;
+	}
 
-bool ObjectsMap::operator<(const ObjectsMap& other) const {
-	return static_cast<const std::map<alib::Object, alib::Object>>(*this) < static_cast<const std::map<alib::Object, alib::Object>>(other);
 }
 
 void ObjectsMap::operator>>(std::ostream& os) const {
diff --git a/alib2data/src/container/ObjectsMap.h b/alib2data/src/container/ObjectsMap.h
index a2b989e8696ae340444932f94e22af8a6802f930..fbb2820190faa620f4ea8a0035a494fa2010e562 100644
--- a/alib2data/src/container/ObjectsMap.h
+++ b/alib2data/src/container/ObjectsMap.h
@@ -26,12 +26,8 @@ public:
 	
 	virtual ContainerBase* plunder() &&;
 
-	virtual bool operator>(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ObjectsMap& other) const;
-	virtual bool operator<(const ObjectsMap& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ObjectsMap& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/container/ObjectsPair.cpp b/alib2data/src/container/ObjectsPair.cpp
index 4517e6a0892433d535ae355b72a6f4398dae9dff..b44b02887eae6adcb16dff5ee2f6f5d41aee6575 100644
--- a/alib2data/src/container/ObjectsPair.cpp
+++ b/alib2data/src/container/ObjectsPair.cpp
@@ -26,24 +26,18 @@ ContainerBase* ObjectsPair::plunder() && {
 	return new ObjectsPair(std::move(*this));
 }
 
-bool ObjectsPair::operator==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool ObjectsPair::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ObjectsPair::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool ObjectsPair::operator==(const ObjectsPair& other) const {
-	return static_cast<const std::pair<alib::Object, alib::Object>>(*this) == static_cast<const std::pair<alib::Object, alib::Object>>(other);
-}
-
-bool ObjectsPair::operator<(const ObjectsPair& other) const {
-	return static_cast<const std::pair<alib::Object, alib::Object>>(*this) < static_cast<const std::pair<alib::Object, alib::Object>>(other);
+int ObjectsPair::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
+}
+
+int ObjectsPair::compare(const ObjectsPair& other) const {
+	if(static_cast<const std::pair<alib::Object, alib::Object>>(*this) == static_cast<const std::pair<alib::Object, alib::Object>>(other)) {
+		return 0;
+	} else if(static_cast<const std::pair<alib::Object, alib::Object>>(*this) < static_cast<const std::pair<alib::Object, alib::Object>>(other)) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void ObjectsPair::operator>>(std::ostream& os) const {
diff --git a/alib2data/src/container/ObjectsPair.h b/alib2data/src/container/ObjectsPair.h
index 270dcdea62eeaa09f08f220cc2ba87dd510e0cb9..484a637ec115cd9b5d965a04f2dc41c332631a31 100644
--- a/alib2data/src/container/ObjectsPair.h
+++ b/alib2data/src/container/ObjectsPair.h
@@ -28,12 +28,8 @@ public:
 	
 	virtual ContainerBase* plunder() &&;
 
-	virtual bool operator>(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ObjectsPair& other) const;
-	virtual bool operator<(const ObjectsPair& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ObjectsPair& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/container/ObjectsSet.cpp b/alib2data/src/container/ObjectsSet.cpp
index c127b8a5ad444d785472a02520338115fb4b877e..464e69e8623a105206815b66dc1cc061da003ebe 100644
--- a/alib2data/src/container/ObjectsSet.cpp
+++ b/alib2data/src/container/ObjectsSet.cpp
@@ -22,24 +22,18 @@ ContainerBase* ObjectsSet::plunder() && {
 	return new ObjectsSet(std::move(*this));
 }
 
-bool ObjectsSet::operator==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool ObjectsSet::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ObjectsSet::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool ObjectsSet::operator==(const ObjectsSet& other) const {
-	return static_cast<const std::set<alib::Object>>(*this) == static_cast<const std::set<alib::Object>>(other);
-}
-
-bool ObjectsSet::operator<(const ObjectsSet& other) const {
-	return static_cast<const std::set<alib::Object>>(*this) < static_cast<const std::set<alib::Object>>(other);
+int ObjectsSet::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
+}
+
+int ObjectsSet::compare(const ObjectsSet& other) const {
+	if(static_cast<const std::set<alib::Object>>(*this) == static_cast<const std::set<alib::Object>>(other)) {
+		return 0;
+	} else if(static_cast<const std::set<alib::Object>>(*this) < static_cast<const std::set<alib::Object>>(other)) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void ObjectsSet::operator>>(std::ostream& os) const {
diff --git a/alib2data/src/container/ObjectsSet.h b/alib2data/src/container/ObjectsSet.h
index 0a5fec7f9f28d1f70187cbd7b2b282b2d4ffbf17..35382caddf71b9aa1c12953d0f9d8e4ac5a6fad5 100644
--- a/alib2data/src/container/ObjectsSet.h
+++ b/alib2data/src/container/ObjectsSet.h
@@ -26,12 +26,8 @@ public:
 	
 	virtual ContainerBase* plunder() &&;
 
-	virtual bool operator>(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ObjectsSet& other) const;
-	virtual bool operator<(const ObjectsSet& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ObjectsSet& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/container/ObjectsVector.cpp b/alib2data/src/container/ObjectsVector.cpp
index d8105a41d2f1885184cf6388b93828972ccd27e0..9efb9292c990f9c7a8eef3ef89fc337c4bccd590 100644
--- a/alib2data/src/container/ObjectsVector.cpp
+++ b/alib2data/src/container/ObjectsVector.cpp
@@ -22,24 +22,18 @@ ContainerBase* ObjectsVector::plunder() && {
 	return new ObjectsVector(std::move(*this));
 }
 
-bool ObjectsVector::operator==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool ObjectsVector::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ObjectsVector::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool ObjectsVector::operator==(const ObjectsVector& other) const {
-	return static_cast<const std::vector<alib::Object>>(*this) == static_cast<const std::vector<alib::Object>>(other);
-}
-
-bool ObjectsVector::operator<(const ObjectsVector& other) const {
-	return static_cast<const std::vector<alib::Object>>(*this) < static_cast<const std::vector<alib::Object>>(other);
+int ObjectsVector::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
+}
+
+int ObjectsVector::compare(const ObjectsVector& other) const {
+	if(static_cast<const std::vector<alib::Object>>(*this) == static_cast<const std::vector<alib::Object>>(other)) {
+		return 0;
+	} else if(static_cast<const std::vector<alib::Object>>(*this) < static_cast<const std::vector<alib::Object>>(other)) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void ObjectsVector::operator>>(std::ostream& os) const {
diff --git a/alib2data/src/container/ObjectsVector.h b/alib2data/src/container/ObjectsVector.h
index 03e89ebad71a92b226d32a1212421195142da86c..da7c1373bb342bc2a6e681212f2f669e91a767aa 100644
--- a/alib2data/src/container/ObjectsVector.h
+++ b/alib2data/src/container/ObjectsVector.h
@@ -26,12 +26,8 @@ public:
 	
 	virtual ContainerBase* plunder() &&;
 
-	virtual bool operator>(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ObjectsVector& other) const;
-	virtual bool operator<(const ObjectsVector& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ObjectsVector& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/exception/AlibException.cpp b/alib2data/src/exception/AlibException.cpp
index 8571d7527d2749e35580d69f5272c6c0f7084bb9..5373bb86b99ff568c0be4e9a7a68abc362d08123 100644
--- a/alib2data/src/exception/AlibException.cpp
+++ b/alib2data/src/exception/AlibException.cpp
@@ -67,24 +67,12 @@ const std::string & AlibException::getBacktrace ( ) const {
 	return backtrace;
 }
 
-bool AlibException::operator==(const ObjectBase& other) const {
-	return other == *this;
+int AlibException::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool AlibException::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool AlibException::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool AlibException::operator==(const AlibException& other) const {
-	return this->whatMessage == other.whatMessage;
-}
-
-bool AlibException::operator<(const AlibException& other) const {
-	return this->whatMessage < other.whatMessage;
+int AlibException::compare(const AlibException& other) const {
+	return this->whatMessage.compare(other.whatMessage);
 }
 
 void AlibException::operator>>(std::ostream& os) const {
diff --git a/alib2data/src/exception/AlibException.h b/alib2data/src/exception/AlibException.h
index 09f53c66c1c6c84bd21a3a4b40f9865577649362..8cadc496a54d86f62997a9e1d4d7d3c547c8bda7 100644
--- a/alib2data/src/exception/AlibException.h
+++ b/alib2data/src/exception/AlibException.h
@@ -53,12 +53,8 @@ public:
 	 */
 	const std::string & getBacktrace ( ) const;
 
-	virtual bool operator>(const alib::ObjectBase& other) const;
-	virtual bool operator==(const alib::ObjectBase& other) const;
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const AlibException& other) const;
-	virtual bool operator<(const AlibException& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const AlibException& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextFree/CFG.cpp b/alib2data/src/grammar/ContextFree/CFG.cpp
index 6c2eca1b20e7f4b020d25950ea44dd5df32fbaf7..bab73c29f256eda3f838f68f15e1beb7779c5810 100644
--- a/alib2data/src/grammar/ContextFree/CFG.cpp
+++ b/alib2data/src/grammar/ContextFree/CFG.cpp
@@ -89,24 +89,21 @@ bool CFG::removeRule(const alphabet::Symbol& leftHandSide, const std::vector<alp
 	return rules[leftHandSide].erase(rightHandSide);
 }
 
-bool CFG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int CFG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool CFG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool CFG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int CFG::compare(const CFG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool CFG::operator==(const CFG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool CFG::operator<(const CFG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void CFG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextFree/CFG.h b/alib2data/src/grammar/ContextFree/CFG.h
index bb36acd0637c90100138d6f9f46f2faa893d8cec..afb714ca865cc61b2678a72bfd4ed1cdd401f969 100644
--- a/alib2data/src/grammar/ContextFree/CFG.h
+++ b/alib2data/src/grammar/ContextFree/CFG.h
@@ -47,13 +47,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const CFG& other) const;
-
-	virtual bool operator<(const CFG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const CFG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextFree/CNF.cpp b/alib2data/src/grammar/ContextFree/CNF.cpp
index 03da6a55750dd885bef1a539ad3894e66d6a1d60..449f53d362fe5af195be0212bc6f8d883f9287db 100644
--- a/alib2data/src/grammar/ContextFree/CNF.cpp
+++ b/alib2data/src/grammar/ContextFree/CNF.cpp
@@ -171,24 +171,21 @@ bool CNF::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool CNF::operator==(const ObjectBase& other) const {
-	return other == *this;
+int CNF::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool CNF::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool CNF::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int CNF::compare(const CNF& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool CNF::operator==(const CNF& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool CNF::operator<(const CNF& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void CNF::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h
index af5c56a4091951a9115e917fcdd2807ec1fb22c4..e972f0eda3163bf1faf20fd3a2c9f22ca54c60a8 100644
--- a/alib2data/src/grammar/ContextFree/CNF.h
+++ b/alib2data/src/grammar/ContextFree/CNF.h
@@ -56,13 +56,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const CNF& other) const;
-
-	virtual bool operator<(const CNF& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const CNF& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
index 081e3bddc4bd9721bdfbb6f080260fa388b69afa..9a9c80c5078ab88eec63e66337f63d051e2a3409 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.cpp
@@ -122,24 +122,21 @@ bool EpsilonFreeCFG::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool EpsilonFreeCFG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int EpsilonFreeCFG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool EpsilonFreeCFG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool EpsilonFreeCFG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int EpsilonFreeCFG::compare(const EpsilonFreeCFG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool EpsilonFreeCFG::operator==(const EpsilonFreeCFG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool EpsilonFreeCFG::operator<(const EpsilonFreeCFG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void EpsilonFreeCFG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
index 629b8cfaf38cfa6798c3d7718cb93f4fc0a271f1..17addf33f2114099c3134c67fdcbbd9ee7cb7151 100644
--- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
+++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h
@@ -51,13 +51,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const EpsilonFreeCFG& other) const;
-
-	virtual bool operator<(const EpsilonFreeCFG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const EpsilonFreeCFG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextFree/GNF.cpp b/alib2data/src/grammar/ContextFree/GNF.cpp
index 802169e44e4e24c15011649951a5e8295d844bb5..93f6b393db635057fff9f5edd0c68883492376fe 100644
--- a/alib2data/src/grammar/ContextFree/GNF.cpp
+++ b/alib2data/src/grammar/ContextFree/GNF.cpp
@@ -130,24 +130,21 @@ bool GNF::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool GNF::operator==(const ObjectBase& other) const {
-	return other == *this;
+int GNF::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool GNF::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool GNF::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int GNF::compare(const GNF& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool GNF::operator==(const GNF& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool GNF::operator<(const GNF& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void GNF::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextFree/GNF.h b/alib2data/src/grammar/ContextFree/GNF.h
index 2a9caa5336b4aaf5d48b240dea2dc195f1a376a7..6858955ce159443f95660a007fc753c082f4fe7a 100644
--- a/alib2data/src/grammar/ContextFree/GNF.h
+++ b/alib2data/src/grammar/ContextFree/GNF.h
@@ -50,13 +50,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const GNF& other) const;
-
-	virtual bool operator<(const GNF& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const GNF& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextFree/LG.cpp b/alib2data/src/grammar/ContextFree/LG.cpp
index 630de907b3a57b6bc0c1d3a95de24a4a583893d5..03a2b0336f3322761a069ce452c9e30262ebe927 100644
--- a/alib2data/src/grammar/ContextFree/LG.cpp
+++ b/alib2data/src/grammar/ContextFree/LG.cpp
@@ -180,24 +180,21 @@ bool LG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vector<a
 	}
 }
 
-bool LG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int LG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool LG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int LG::compare(const LG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool LG::operator==(const LG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool LG::operator<(const LG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void LG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h
index 7c56b5e9dc4d6e784f6b57a0a33cff5edd64f0a0..c531f4a59a2228125fd12744abd4f93f584b847c 100644
--- a/alib2data/src/grammar/ContextFree/LG.h
+++ b/alib2data/src/grammar/ContextFree/LG.h
@@ -52,13 +52,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const LG& other) const;
-
-	virtual bool operator<(const LG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const LG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.cpp b/alib2data/src/grammar/ContextSensitive/CSG.cpp
index 77e48595d34ec4a8085406ec46d31b81ba5141c6..6f580f2f01b62d618c58b1b4eb8856a6b6ed1aa6 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.cpp
+++ b/alib2data/src/grammar/ContextSensitive/CSG.cpp
@@ -119,24 +119,21 @@ bool CSG::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool CSG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int CSG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool CSG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool CSG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int CSG::compare(const CSG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool CSG::operator==(const CSG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool CSG::operator<(const CSG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void CSG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextSensitive/CSG.h b/alib2data/src/grammar/ContextSensitive/CSG.h
index f75ac10870b67e197728fad4fff21816ae59569c..0427a348b631984e236cbb1a582a2ac954cd03bd 100644
--- a/alib2data/src/grammar/ContextSensitive/CSG.h
+++ b/alib2data/src/grammar/ContextSensitive/CSG.h
@@ -44,13 +44,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const ObjectBase& other) const;
-	virtual bool operator ==(const ObjectBase& other) const;
-	virtual bool operator >(const ObjectBase& other) const;
-
-	virtual bool operator==(const CSG& other) const;
-
-	virtual bool operator<(const CSG& other) const;
+	virtual int compare(const ObjectBase& other) const;
+	virtual int compare(const CSG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
index 922140c3b97ea6f6a85b7c1bec4b1f877614e95f..44b8108f0cccbd366d843e2441951b9610032a50 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.cpp
@@ -100,24 +100,21 @@ bool NonContractingGrammar::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool NonContractingGrammar::operator==(const ObjectBase& other) const {
-	return other == *this;
+int NonContractingGrammar::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool NonContractingGrammar::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool NonContractingGrammar::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int NonContractingGrammar::compare(const NonContractingGrammar& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool NonContractingGrammar::operator==(const NonContractingGrammar& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool NonContractingGrammar::operator<(const NonContractingGrammar& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void NonContractingGrammar::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
index fc5cf10cd0b3fc3eefa31ef9f613987689965aed..fd20c2138138aa8cf1670d4d6f8014e81bd92da2 100644
--- a/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
+++ b/alib2data/src/grammar/ContextSensitive/NonContractingGrammar.h
@@ -44,13 +44,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const NonContractingGrammar& other) const;
-
-	virtual bool operator<(const NonContractingGrammar& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const NonContractingGrammar& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/Regular/LeftLG.cpp b/alib2data/src/grammar/Regular/LeftLG.cpp
index 1c66201141b9b6c1e613e5d39439c40fec7b1296..b379a7208ef098c54fca700ecf709639a6e146bf 100644
--- a/alib2data/src/grammar/Regular/LeftLG.cpp
+++ b/alib2data/src/grammar/Regular/LeftLG.cpp
@@ -165,24 +165,21 @@ bool LeftLG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vect
 	}
 }
 
-bool LeftLG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int LeftLG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LeftLG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool LeftLG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int LeftLG::compare(const LeftLG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool LeftLG::operator==(const LeftLG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool LeftLG::operator<(const LeftLG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void LeftLG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h
index 068b835035d62f8de988405ac66d6ecc1e64d551..95e46cb3559ffce26fbb8c8d20890d9ce2edf6db 100644
--- a/alib2data/src/grammar/Regular/LeftLG.h
+++ b/alib2data/src/grammar/Regular/LeftLG.h
@@ -51,13 +51,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const LeftLG& other) const;
-
-	virtual bool operator<(const LeftLG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const LeftLG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/Regular/LeftRG.cpp b/alib2data/src/grammar/Regular/LeftRG.cpp
index 3f789ea2cbbc8ee8ff7cd3b38a22518bfdcb13a3..1af289bbbbeaf4e5caaa0c1aa57beac3eda53423 100644
--- a/alib2data/src/grammar/Regular/LeftRG.cpp
+++ b/alib2data/src/grammar/Regular/LeftRG.cpp
@@ -169,24 +169,21 @@ bool LeftRG::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool LeftRG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int LeftRG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LeftRG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool LeftRG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int LeftRG::compare(const LeftRG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool LeftRG::operator==(const LeftRG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool LeftRG::operator<(const LeftRG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void LeftRG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h
index 680031560518dd4aaadd9ba610355b51cf940bbe..acfcd932bafc04deade7c65e27f8e90484c8ab62 100644
--- a/alib2data/src/grammar/Regular/LeftRG.h
+++ b/alib2data/src/grammar/Regular/LeftRG.h
@@ -124,29 +124,13 @@ public:
 	/**
 	 * double dispatch operator helper
 	 */
-	virtual bool operator <(const alib::ObjectBase& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
 
 	/**
-	 * double dispatch operator helper
-	 */
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-
-	/**
-	 * double dispatch operator helper
-	 */
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	/**
-	 * equals operator
-	 * @param other the other instance
-	 */
-	virtual bool operator==(const LeftRG& other) const;
-
-	/**
-	 * less operator
+	 * compare
 	 * @param other the other instance
 	 */
-	virtual bool operator<(const LeftRG& other) const;
+	virtual int compare(const LeftRG& other) const;
 
 	/**
 	 * print this instance as raw representation to ostream
diff --git a/alib2data/src/grammar/Regular/RightLG.cpp b/alib2data/src/grammar/Regular/RightLG.cpp
index 08faa71a17782e29615165b2a14aa037c29fa4a0..6585010a010105f3b4c62112eaf682eebff54ed6 100644
--- a/alib2data/src/grammar/Regular/RightLG.cpp
+++ b/alib2data/src/grammar/Regular/RightLG.cpp
@@ -165,24 +165,21 @@ bool RightLG::removeRawRule(const alphabet::Symbol& leftHandSide, const std::vec
 	}
 }
 
-bool RightLG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int RightLG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RightLG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool RightLG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int RightLG::compare(const RightLG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool RightLG::operator==(const RightLG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool RightLG::operator<(const RightLG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void RightLG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h
index fc0d2cf7d37190ee869e8c1160939d8cd1075d85..fd13d01a822a894daa3aa28509b9c7d527fb426f 100644
--- a/alib2data/src/grammar/Regular/RightLG.h
+++ b/alib2data/src/grammar/Regular/RightLG.h
@@ -51,13 +51,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const RightLG& other) const;
-
-	virtual bool operator<(const RightLG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RightLG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/Regular/RightRG.cpp b/alib2data/src/grammar/Regular/RightRG.cpp
index 07eb323a3908d02163c7e84a1ad647e5c3073a4a..e89179b96df53f4b088f6a3ab3c036685c56b571 100644
--- a/alib2data/src/grammar/Regular/RightRG.cpp
+++ b/alib2data/src/grammar/Regular/RightRG.cpp
@@ -169,24 +169,21 @@ bool RightRG::getGeneratesEpsilon() const {
 	return generatesEpsilon;
 }
 
-bool RightRG::operator==(const ObjectBase& other) const {
-	return other == *this;
+int RightRG::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool RightRG::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool RightRG::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int RightRG::compare(const RightRG& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool RightRG::operator==(const RightRG& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules && this->generatesEpsilon == other.generatesEpsilon;
-}
-
-bool RightRG::operator<(const RightRG& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void RightRG::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h
index b21e848b73a0a981da16dee7757e8b5fe56e5d5a..0580625a7f35016dfd37ec802f50bebc8b8d89f1 100644
--- a/alib2data/src/grammar/Regular/RightRG.h
+++ b/alib2data/src/grammar/Regular/RightRG.h
@@ -71,13 +71,8 @@ public:
 	void setGeneratesEpsilon(bool genEps);
 	bool getGeneratesEpsilon() const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const RightRG& other) const;
-
-	virtual bool operator<(const RightRG& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const RightRG& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
index f600000099fc42e9e1a038da0e5c9472ded5edc9..e10ea337dce77361b01c91420658a67abe35e43d 100644
--- a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
+++ b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.cpp
@@ -105,24 +105,21 @@ bool ContextPreservingUnrestrictedGrammar::removeRule(const std::vector<alphabet
 	return rules[make_tuple(lContext, leftHandSide, rContext)].erase(rightHandSide);
 }
 
-bool ContextPreservingUnrestrictedGrammar::operator==(const ObjectBase& other) const {
-	return other == *this;
+int ContextPreservingUnrestrictedGrammar::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool ContextPreservingUnrestrictedGrammar::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool ContextPreservingUnrestrictedGrammar::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int ContextPreservingUnrestrictedGrammar::compare(const ContextPreservingUnrestrictedGrammar& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool ContextPreservingUnrestrictedGrammar::operator==(const ContextPreservingUnrestrictedGrammar& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool ContextPreservingUnrestrictedGrammar::operator<(const ContextPreservingUnrestrictedGrammar& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void ContextPreservingUnrestrictedGrammar::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
index bb23181be01cfe7e749af6a824165b90c55bb90a..c781aded6616c59d5aac7510541fb34008eae00f 100644
--- a/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/ContextPreservingUnrestrictedGrammar.h
@@ -40,13 +40,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const ContextPreservingUnrestrictedGrammar& other) const;
-
-	virtual bool operator<(const ContextPreservingUnrestrictedGrammar& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const ContextPreservingUnrestrictedGrammar& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
index e5417bac4b0d20a7a2675d7daf821ea6b0f5c98f..4bce0a3fc3c61c13f527ed738c139f080fe85b36 100644
--- a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
+++ b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.cpp
@@ -86,24 +86,21 @@ bool UnrestrictedGrammar::removeRule(const std::vector<alphabet::Symbol>& leftHa
 	return rules[leftHandSide].erase(rightHandSide);
 }
 
-bool UnrestrictedGrammar::operator==(const ObjectBase& other) const {
-	return other == *this;
+int UnrestrictedGrammar::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool UnrestrictedGrammar::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool UnrestrictedGrammar::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
+int UnrestrictedGrammar::compare(const UnrestrictedGrammar& other) const {
+	auto first = std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules);
+	auto second = std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
 
-bool UnrestrictedGrammar::operator==(const UnrestrictedGrammar& other) const {
-	return this->nonterminalAlphabet == other.nonterminalAlphabet && this->terminalAlphabet == other.terminalAlphabet && this->initialSymbol == other.initialSymbol && this->rules == other.rules;
-}
-
-bool UnrestrictedGrammar::operator<(const UnrestrictedGrammar& other) const {
-	return std::tie(terminalAlphabet, nonterminalAlphabet, initialSymbol, rules) < std::tie(other.terminalAlphabet, other.nonterminalAlphabet, other.initialSymbol, other.rules);
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void UnrestrictedGrammar::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
index 46ec38d06f8856bf87c626573c0228d4fa2db2ba..d0b66dbe25a8bda8d581b360704b187f1f5f976e 100644
--- a/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
+++ b/alib2data/src/grammar/Unrestricted/UnrestrictedGrammar.h
@@ -40,13 +40,8 @@ public:
 
 	bool removeNonterminalSymbol(const alphabet::Symbol& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const UnrestrictedGrammar& other) const;
-
-	virtual bool operator<(const UnrestrictedGrammar& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const UnrestrictedGrammar& other) const;
 
 	virtual void operator>>(std::ostream& os) const;
 
diff --git a/alib2data/src/label/HexavigesimalLabel.cpp b/alib2data/src/label/HexavigesimalLabel.cpp
index 58c101f8af3dd7b6f24a724870ab8e43b24a50a5..1aa1a2e70360eeacd631ee62ad1db0b083b52769 100644
--- a/alib2data/src/label/HexavigesimalLabel.cpp
+++ b/alib2data/src/label/HexavigesimalLabel.cpp
@@ -26,25 +26,12 @@ int HexavigesimalLabel::getData() const {
 	return hexavigesimal;
 }
 
-bool HexavigesimalLabel::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int HexavigesimalLabel::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool HexavigesimalLabel::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool HexavigesimalLabel::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool HexavigesimalLabel::operator <(const HexavigesimalLabel& other) const {
-	return hexavigesimal < other.hexavigesimal;
-}
-
-bool HexavigesimalLabel::operator ==(const HexavigesimalLabel& other) const {
-	return hexavigesimal == other.hexavigesimal;
+int HexavigesimalLabel::compare(const HexavigesimalLabel& other) const {
+	return hexavigesimal - other.hexavigesimal;
 }
 
 void HexavigesimalLabel::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/label/HexavigesimalLabel.h b/alib2data/src/label/HexavigesimalLabel.h
index ce844d5ab898849536ccdf54384909a5664c960a..57494ab60c3c3c311d822f025c820f69f59db3a5 100644
--- a/alib2data/src/label/HexavigesimalLabel.h
+++ b/alib2data/src/label/HexavigesimalLabel.h
@@ -33,19 +33,13 @@ public:
 
 	virtual LabelBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	int getData() const;
 
-	virtual bool operator <(const HexavigesimalLabel& other) const;
-	virtual bool operator ==(const HexavigesimalLabel& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const HexavigesimalLabel& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/label/LabelPairLabel.cpp b/alib2data/src/label/LabelPairLabel.cpp
index 50dd7391a7cdc1b0afcf8be10a8596e2cdbbbedd..5b7c485203880e79332faaffa4a63a176d963290 100644
--- a/alib2data/src/label/LabelPairLabel.cpp
+++ b/alib2data/src/label/LabelPairLabel.cpp
@@ -31,25 +31,14 @@ const std::pair<Label, Label>& LabelPairLabel::getData() const {
 	return label;
 }
 
-bool LabelPairLabel::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int LabelPairLabel::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LabelPairLabel::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool LabelPairLabel::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool LabelPairLabel::operator <(const LabelPairLabel& other) const {
-	return label < other.label;
-}
-
-bool LabelPairLabel::operator ==(const LabelPairLabel& other) const {
-	return label == other.label;
+int LabelPairLabel::compare(const LabelPairLabel& other) const {
+	int res = label.first.getData().compare(other.label.first.getData());
+	if(res == 0) res = label.second.getData().compare(other.label.second.getData());
+	return res;
 }
 
 void LabelPairLabel::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/label/LabelPairLabel.h b/alib2data/src/label/LabelPairLabel.h
index 92414856909a79782a2a00e0180532498b1f886f..aeb32623e1b07ab50dad2b0223757c662f897533 100644
--- a/alib2data/src/label/LabelPairLabel.h
+++ b/alib2data/src/label/LabelPairLabel.h
@@ -37,19 +37,13 @@ public:
 
 	virtual LabelBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	const std::pair<Label, Label>& getData() const;
 
-	virtual bool operator <(const LabelPairLabel& other) const;
-	virtual bool operator ==(const LabelPairLabel& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const LabelPairLabel& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/label/LabelSetLabel.cpp b/alib2data/src/label/LabelSetLabel.cpp
index 45e00debe492680de95b89be5d215399121c799b..81c5225a29a50d2572c2097e3125bc8c9c0b7b87 100644
--- a/alib2data/src/label/LabelSetLabel.cpp
+++ b/alib2data/src/label/LabelSetLabel.cpp
@@ -31,25 +31,18 @@ const std::set<Label>& LabelSetLabel::getData() const {
 	return label;
 }
 
-bool LabelSetLabel::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int LabelSetLabel::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LabelSetLabel::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool LabelSetLabel::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool LabelSetLabel::operator <(const LabelSetLabel& other) const {
-	return label < other.label;
-}
-
-bool LabelSetLabel::operator ==(const LabelSetLabel& other) const {
-	return label == other.label;
+int LabelSetLabel::compare(const LabelSetLabel& other) const {
+	if(label == other.label) {
+		return 0;
+	} else if(label < other.label) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 void LabelSetLabel::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/label/LabelSetLabel.h b/alib2data/src/label/LabelSetLabel.h
index 9bdf8266c3ed7e3e957411706d1fa498f6898e0c..2bc5b77d608cf3a9ba22bb5d08c8f9cbf73a407a 100644
--- a/alib2data/src/label/LabelSetLabel.h
+++ b/alib2data/src/label/LabelSetLabel.h
@@ -37,19 +37,13 @@ public:
 
 	virtual LabelBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	const std::set<Label>& getData() const;
 
-	virtual bool operator <(const LabelSetLabel& other) const;
-	virtual bool operator ==(const LabelSetLabel& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const LabelSetLabel& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/label/ObjectLabel.cpp b/alib2data/src/label/ObjectLabel.cpp
index b235b61a25e99eedf08bf015b68f0f2839913b38..985115b3e7b135edfabf75929f9eb59efbcb784c 100644
--- a/alib2data/src/label/ObjectLabel.cpp
+++ b/alib2data/src/label/ObjectLabel.cpp
@@ -29,24 +29,12 @@ const alib::Object& ObjectLabel::getData() const {
 	return label;
 }
 
-bool ObjectLabel::operator <(const alib::ObjectBase& other) const {
-	return other > *this;
+int ObjectLabel::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool ObjectLabel::operator ==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool ObjectLabel::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-bool ObjectLabel::operator <(const ObjectLabel& other) const {
-	return label < other.label;
-}
-
-bool ObjectLabel::operator ==(const ObjectLabel& other) const {
-	return label == other.label;
+int ObjectLabel::compare(const ObjectLabel& other) const {
+	return label.getData().compare(other.label.getData());
 }
 
 void ObjectLabel::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/label/ObjectLabel.h b/alib2data/src/label/ObjectLabel.h
index a4bc6ff70fe448ccda0c4cf19ec60bf55f370d35..d5485d6c517ea4a4964cdd52326fdc5fb64a6c41 100644
--- a/alib2data/src/label/ObjectLabel.h
+++ b/alib2data/src/label/ObjectLabel.h
@@ -35,20 +35,14 @@ public:
 
 	virtual LabelBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	const alib::Object& getData() const;
 
-	virtual bool operator <(const ObjectLabel& other) const;
-	
-	virtual bool operator ==(const ObjectLabel& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+
+	virtual int compare(const ObjectLabel& other) const;
 	
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/label/PrimitiveLabel.cpp b/alib2data/src/label/PrimitiveLabel.cpp
index 7826e901ff0aa5a764f028253fb629df0986ba2d..35f63ae282c4bb7b6385478d60dc65446c088589 100644
--- a/alib2data/src/label/PrimitiveLabel.cpp
+++ b/alib2data/src/label/PrimitiveLabel.cpp
@@ -29,25 +29,12 @@ const primitive::Primitive& PrimitiveLabel::getData() const {
 	return primitive;
 }
 
-bool PrimitiveLabel::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int PrimitiveLabel::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool PrimitiveLabel::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool PrimitiveLabel::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool PrimitiveLabel::operator <(const PrimitiveLabel& other) const {
-	return primitive < other.primitive;
-}
-
-bool PrimitiveLabel::operator ==(const PrimitiveLabel& other) const {
-	return primitive == other.primitive;
+int PrimitiveLabel::compare(const PrimitiveLabel& other) const {
+	return primitive.getData().compare(other.primitive.getData());
 }
 
 void PrimitiveLabel::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/label/PrimitiveLabel.h b/alib2data/src/label/PrimitiveLabel.h
index 784f9fb44e33593dea00af7417dc4fd951e16dc4..6faa087a128f45e4de7edf0dcc6376f2124357b2 100644
--- a/alib2data/src/label/PrimitiveLabel.h
+++ b/alib2data/src/label/PrimitiveLabel.h
@@ -35,19 +35,13 @@ public:
 
 	virtual LabelBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	const primitive::Primitive& getData() const;
 
-	virtual bool operator <(const PrimitiveLabel& other) const;
-	virtual bool operator ==(const PrimitiveLabel& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const PrimitiveLabel& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/object/Void.cpp b/alib2data/src/object/Void.cpp
index 4c86fe19fa4cca855499e12aff08bb1db27f643f..4476934083d204f3a503a2d33ff975ed35a3a95e 100644
--- a/alib2data/src/object/Void.cpp
+++ b/alib2data/src/object/Void.cpp
@@ -21,24 +21,12 @@ ObjectBase* Void::plunder() && {
 	return new Void(std::move(*this));
 }
 
-bool Void::operator <(const ObjectBase& other) const {
-	return other > *this;
+int Void::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool Void::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool Void::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
-bool Void::operator ==(const Void&) const {
-	return true;
-}
-
-bool Void::operator <(const Void&) const {
-	return false;
+int Void::compare(const Void&) const {
+	return 0;
 }
 
 void Void::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/object/Void.h b/alib2data/src/object/Void.h
index fa35b2295d5a529055154770810434cef823134b..1218433d7d9d66d514db80450b081ab0a2360c4e 100644
--- a/alib2data/src/object/Void.h
+++ b/alib2data/src/object/Void.h
@@ -28,12 +28,8 @@ public:
 	virtual ObjectBase* clone() const;
 	virtual ObjectBase* plunder() &&;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator ==(const Void& other) const;
-	virtual bool operator <(const Void& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const Void& other) const;
 
 	virtual void operator>>(std::ostream& out) const;
 
diff --git a/alib2data/src/primitive/Character.cpp b/alib2data/src/primitive/Character.cpp
index b982d9791263c982c1a48dd048c4cae99da0e1d8..925d7da08b67c985bb85a36a8d124efa47c32aef 100644
--- a/alib2data/src/primitive/Character.cpp
+++ b/alib2data/src/primitive/Character.cpp
@@ -25,25 +25,12 @@ char Character::getData() const {
 	return data;
 }
 
-bool Character::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int Character::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool Character::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool Character::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool Character::operator <(const Character& other) const {
-	return data < other.data;
-}
-
-bool Character::operator ==(const Character& other) const {
-	return data == other.data;
+int Character::compare(const Character& other) const {
+	return data - other.data;
 }
 
 void Character::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/primitive/Character.h b/alib2data/src/primitive/Character.h
index ad358b7bba37e5ab17d4d002b8a109a596016d30..f36c11e0cc1716f044a82869596f06d02d0a67ab 100644
--- a/alib2data/src/primitive/Character.h
+++ b/alib2data/src/primitive/Character.h
@@ -33,20 +33,13 @@ public:
 
 	virtual PrimitiveBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	char getData() const;
 
-	virtual bool operator <(const Character& other) const;
-
-	virtual bool operator ==(const Character& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const Character& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/primitive/Integer.cpp b/alib2data/src/primitive/Integer.cpp
index 79eabd451d3aca3c91be0b5fd5b6bc44d5780b34..45635444cc97097ec91515aac764f35e90aa34eb 100644
--- a/alib2data/src/primitive/Integer.cpp
+++ b/alib2data/src/primitive/Integer.cpp
@@ -25,24 +25,12 @@ int Integer::getData() const {
 	return data;
 }
 
-bool Integer::operator <(const alib::ObjectBase& other) const {
-	return other > *this;
+int Integer::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool Integer::operator ==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool Integer::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-bool Integer::operator <(const Integer& other) const {
-	return data < other.data;
-}
-
-bool Integer::operator ==(const Integer& other) const {
-	return data == other.data;
+int Integer::compare(const Integer& other) const {
+	return data - other.data;
 }
 
 void Integer::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/primitive/Integer.h b/alib2data/src/primitive/Integer.h
index e70ca141c764e7aacfe1ce6a64332f12878c362f..6453e3905b9bd56f3db1a4b00fb4c1589579f27c 100644
--- a/alib2data/src/primitive/Integer.h
+++ b/alib2data/src/primitive/Integer.h
@@ -32,20 +32,14 @@ public:
 
 	virtual PrimitiveBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-	
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	int getData() const;
 
-	virtual bool operator <(const Integer& other) const;
-	
-	virtual bool operator ==(const Integer& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+
+	virtual int compare(const Integer& other) const;
 	
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/primitive/String.cpp b/alib2data/src/primitive/String.cpp
index af62a6e5498bbb75d83377f52301f1fb755c2b3c..659b0310456c595a896a4eb5bae3488ee2f5699e 100644
--- a/alib2data/src/primitive/String.cpp
+++ b/alib2data/src/primitive/String.cpp
@@ -29,25 +29,12 @@ const std::string& String::getData() const {
 	return data;
 }
 
-bool String::operator<(const alib::ObjectBase& other) const {
-	return other > *this;
+int String::compare(const alib::ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool String::operator==(const alib::ObjectBase& other) const {
-	return other == *this;
-}
-
-bool String::operator >(const alib::ObjectBase& other) const {
-	return other < *this;
-}
-
-
-bool String::operator <(const String& other) const {
-	return data < other.data;
-}
-
-bool String::operator ==(const String& other) const {
-	return data == other.data;
+int String::compare(const String& other) const {
+	return data.compare(other.data);
 }
 
 void String::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/primitive/String.h b/alib2data/src/primitive/String.h
index 5007dfd8fd2e0698f2bdbbd342dd98ac98da73e9..dd74681d1792ab544e3d4ad1272014c4d3d66bec 100644
--- a/alib2data/src/primitive/String.h
+++ b/alib2data/src/primitive/String.h
@@ -35,20 +35,14 @@ public:
 
 	virtual PrimitiveBase* plunder() &&;
 
-	virtual bool operator<(const alib::ObjectBase& other) const;
-
-	virtual bool operator>(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return name of the symbol
 	 */
 	const std::string& getData() const;
 
-	virtual bool operator <(const String& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
 
-	virtual bool operator ==(const String& other) const;
+	virtual int compare(const String& other) const;
 
 	virtual void operator>>(std::ostream&) const;
 
diff --git a/alib2data/src/regexp/formal/FormalRegExp.cpp b/alib2data/src/regexp/formal/FormalRegExp.cpp
index 62241b7b6b5cdfb9f8f2e2d001a5ce3c8c80005b..7e9df81cc2605b14b43eee67b878715ac76f7ed5 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExp.cpp
@@ -142,24 +142,21 @@ void FormalRegExp::operator >>(std::ostream& out) const {
 	out << "(FormalRegExp " << *(this->regExp) << ")";
 }
 
-bool FormalRegExp::operator<(const FormalRegExp& other) const {
-	return std::tie(*regExp, alphabet) < std::tie(*other.regExp, other.alphabet);
+int FormalRegExp::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExp::operator==(const FormalRegExp& other) const {
-	return *regExp == *other.regExp && this->alphabet == other.alphabet;
-}
-
-bool FormalRegExp::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
+int FormalRegExp::compare(const FormalRegExp& other) const {
+	auto first = std::tie(*regExp, alphabet);
+	auto second = std::tie(*other.regExp, other.alphabet);
 
-bool FormalRegExp::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool FormalRegExp::operator >(const ObjectBase& other) const {
-	return other < *this;
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 FormalRegExp::operator std::string () const {
diff --git a/alib2data/src/regexp/formal/FormalRegExp.h b/alib2data/src/regexp/formal/FormalRegExp.h
index 2322d436948f66c00e3f4b02d30479cce391ed67..705e59715f79f9f315c67d9db6ac34e8b994fbf4 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.h
+++ b/alib2data/src/regexp/formal/FormalRegExp.h
@@ -112,13 +112,8 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const FormalRegExp& other) const;
-
-	virtual bool operator<(const FormalRegExp& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const FormalRegExp& other) const;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
index d01a6a95083d90e667205e15a9423759078c50f7..d6cae69d65f764585f473e3a0036790b1e190908 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
@@ -128,26 +128,14 @@ UnboundedRegExpElement* FormalRegExpAlternation::cloneAsUnbounded() const {
 	return res;
 }
 
-bool FormalRegExpAlternation::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpAlternation::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpAlternation::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpAlternation::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool FormalRegExpAlternation::operator<(const FormalRegExpAlternation& other) const {
-	if(*left == *other.left) return *right < *other.right;
-	return *left < *other.left;
-}
-
-bool FormalRegExpAlternation::operator==(const FormalRegExpAlternation& other) const {
-	return *left == *other.left && *right == *other.right;
+int FormalRegExpAlternation::compare(const FormalRegExpAlternation& other) const {
+	int res = left->compare(*other.left);
+	if(res == 0) res = right->compare(*other.right);
+	return res;
 }
 
 void FormalRegExpAlternation::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index 0ff6327c5b07830da28a2b96e53d4eb5ee8f3bd7..5d4e51bdb12f327904a3d62a04873f0bf8398529 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -92,12 +92,8 @@ public:
 	void setRightElement(const FormalRegExpElement& element);
 	void setRightElement(FormalRegExpElement&& element);
 
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpAlternation&) const;
-	virtual bool operator==(const FormalRegExpAlternation&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpAlternation&) const;
 	
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
index 07c1b4327f237b5629f638640e1c73f03d029eb8..5eb76c295e1360983a10b91a121853e50edaa0ad 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
@@ -127,26 +127,14 @@ FormalRegExpElement* FormalRegExpConcatenation::plunder() && {
 	return new FormalRegExpConcatenation(std::move(*this));
 }
 
-bool FormalRegExpConcatenation::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpConcatenation::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpConcatenation::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpConcatenation::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool FormalRegExpConcatenation::operator<(const FormalRegExpConcatenation& other) const {
-	if(*left == *other.left) return *right < *other.right;
-	return *left < *other.left;
-}
-
-bool FormalRegExpConcatenation::operator==(const FormalRegExpConcatenation& other) const {
-	return *left == *other.left && *right == *other.right;
+int FormalRegExpConcatenation::compare(const FormalRegExpConcatenation& other) const {
+	int res = left->compare(*other.left);
+	if(res == 0) res = right->compare(*other.right);
+	return res;
 }
 
 void FormalRegExpConcatenation::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index b88af6b5898241739b62c8517685c9770fa80147..ca2463c3bc8b665d94631ab998c72cf675487871 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -90,12 +90,8 @@ public:
 	void setRightElement(const FormalRegExpElement& element);
 	void setRightElement(FormalRegExpElement&& element);
 
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpConcatenation&) const;
-	virtual bool operator==(const FormalRegExpConcatenation&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpConcatenation&) const;
 
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
index a55e9a92bd789f24ab28b301e24addef5cb37419..964ac14ea6c590cf38395626e7db871fa12d179d 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
@@ -44,25 +44,12 @@ UnboundedRegExpElement* FormalRegExpEmpty::cloneAsUnbounded() const {
 	return new UnboundedRegExpEmpty();
 }
 
-bool FormalRegExpEmpty::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpEmpty::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpEmpty::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpEmpty::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool FormalRegExpEmpty::operator<(const FormalRegExpEmpty&) const {
-	return false;
-}
-
-bool FormalRegExpEmpty::operator==(const FormalRegExpEmpty&) const {
-	return true;
+int FormalRegExpEmpty::compare(const FormalRegExpEmpty&) const {
+	return 0;
 }
 
 void FormalRegExpEmpty::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
index 300cd803fab8c95dd0e183497d3236f05c1dbab6..94fe4f51299a9de917ce4a687d6e8a7f79abec66 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
@@ -55,12 +55,8 @@ public:
 	 */
 	virtual FormalRegExpElement* plunder() &&;
 
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpEmpty&) const;
-	virtual bool operator==(const FormalRegExpEmpty&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpEmpty&) const;
 	
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
index 8d3d8563a23450d336dff6880af2e8020d31c815..ad3414027fd1ebfc825f69f2d65ffcf9f01380b7 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
@@ -45,25 +45,12 @@ UnboundedRegExpElement* FormalRegExpEpsilon::cloneAsUnbounded() const {
 	return new UnboundedRegExpEpsilon();
 }
 
-bool FormalRegExpEpsilon::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpEpsilon::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpEpsilon::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpEpsilon::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool FormalRegExpEpsilon::operator<(const FormalRegExpEpsilon&) const {
-	  return false;
-}
-
-bool FormalRegExpEpsilon::operator==(const FormalRegExpEpsilon&) const {
-	  return true;
+int FormalRegExpEpsilon::compare(const FormalRegExpEpsilon&) const {
+	  return 0;
 }
 
 void FormalRegExpEpsilon::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
index e146862bca84f63d9780ee32765eb513935aa3c8..6ab5146a9735aff1451f8f2602e4a39cc87ae395 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
@@ -56,12 +56,8 @@ public:
 	 */
 	virtual FormalRegExpElement* plunder() &&;
 	
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpEpsilon&) const;
-	virtual bool operator==(const FormalRegExpEpsilon&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpEpsilon&) const;
 	
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
index ea044dc85cb0e4005a38e32dbfc7ede38486e2c9..785f8543cab817b11e6c411490fad43943b91cc7 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
@@ -93,24 +93,12 @@ UnboundedRegExpElement* FormalRegExpIteration::cloneAsUnbounded() const {
 	return res;
 }
 
-bool FormalRegExpIteration::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpIteration::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpIteration::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpIteration::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-bool FormalRegExpIteration::operator<(const FormalRegExpIteration& other) const {
-	return *element < *other.element;
-}
-
-bool FormalRegExpIteration::operator==(const FormalRegExpIteration& other) const {
-	return *element == *other.element;
+int FormalRegExpIteration::compare(const FormalRegExpIteration& other) const {
+	return element->compare(*other.element);
 }
 
 void FormalRegExpIteration::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index 9d0629cd7679d693a3e3811dad0541705c8c4ac6..830d6e8562de3ea22c31d8e14da994f8a8571585 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -85,12 +85,8 @@ public:
 	
 	void setElement(FormalRegExpElement&& element);
 
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpIteration&) const;
-	virtual bool operator==(const FormalRegExpIteration&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpIteration&) const;
 
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
index 6849734da8f49191993a6b0d0dd4e31b252065b6..ef8ec7f7ee66c510b3d1ffa8978b7da8f720e10c 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
@@ -78,25 +78,12 @@ bool operator==(const alphabet::Symbol& first, const FormalRegExpSymbol& second)
 	return first == second.symbol;
 }
 
-bool FormalRegExpSymbol::operator<(const FormalRegExpElement& other) const {
-	return other > *this;
+int FormalRegExpSymbol::compare(const FormalRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool FormalRegExpSymbol::operator==(const FormalRegExpElement& other) const {
-	return other == *this;
-}
-
-bool FormalRegExpSymbol::operator>(const FormalRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool FormalRegExpSymbol::operator<(const FormalRegExpSymbol& other) const {
-	return symbol < other.symbol;
-}
-
-bool FormalRegExpSymbol::operator==(const FormalRegExpSymbol& other) const {
-	return symbol == other.symbol;
+int FormalRegExpSymbol::compare(const FormalRegExpSymbol& other) const {
+	return symbol.getData().compare(other.symbol.getData());
 }
 
 void FormalRegExpSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
index 05cbbb12198bb97b094a330e0d46c450230921fc..110adea9afee084f3824fd5db39f9e3ff4a63de8 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.h
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
@@ -67,12 +67,8 @@ public:
 	bool operator==(const alphabet::Symbol&) const;
 	friend bool operator==(const alphabet::Symbol&, const FormalRegExpSymbol&);
 
-	virtual bool operator<(const FormalRegExpElement&) const;
-	virtual bool operator==(const FormalRegExpElement&) const;
-	virtual bool operator>(const FormalRegExpElement&) const;
-
-	virtual bool operator<(const FormalRegExpSymbol&) const;
-	virtual bool operator==(const FormalRegExpSymbol&) const;
+	virtual int compare(const FormalRegExpElement&) const;
+	virtual int compare(const FormalRegExpSymbol&) const;
 	
 	/**
 	 * @copydoc FormalRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
index 237f6bb309367e601d050526f3d60aa1e1757d41..ec8e69e6cd94492c7cf3d778a152918fa78960b7 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
@@ -142,24 +142,21 @@ void UnboundedRegExp::operator >>(std::ostream& out) const {
 	out << "(UnboundedRegExp " << *(this->regExp) << ")";
 }
 
-bool UnboundedRegExp::operator<(const UnboundedRegExp& other) const {
-	return std::tie(*regExp, alphabet) < std::tie(*other.regExp, other.alphabet);
+int UnboundedRegExp::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExp::operator==(const UnboundedRegExp& other) const {
-	return *regExp == *other.regExp && this->alphabet == other.alphabet;
-}
-
-bool UnboundedRegExp::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
+int UnboundedRegExp::compare(const UnboundedRegExp& other) const {
+	auto first = std::tie(*regExp, alphabet);
+	auto second = std::tie(*other.regExp, other.alphabet);
 
-bool UnboundedRegExp::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExp::operator >(const ObjectBase& other) const {
-	return other < *this;
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
 UnboundedRegExp::operator std::string () const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.h b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
index 81a0f29af354085e69bfdb42ebf585d7fd0cda4c..934492fac8612c7cd54abba399f723e01aa74528 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
@@ -112,13 +112,8 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
-	virtual bool operator==(const UnboundedRegExp& other) const;
-
-	virtual bool operator<(const UnboundedRegExp& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
+	virtual int compare(const UnboundedRegExp& other) const;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
index 52f17c3fccefaeac1ec41bc03a4bc0a3c228a35d..b81cb5a0f656b54b8dd8c3be34dd562c9adaa1ee 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
@@ -108,45 +108,23 @@ FormalRegExpElement* UnboundedRegExpAlternation::cloneAsFormal() const {
 	return res;
 }
 
-bool UnboundedRegExpAlternation::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpAlternation::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpAlternation::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpAlternation::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool UnboundedRegExpAlternation::operator<(const UnboundedRegExpAlternation& other) const {
+int UnboundedRegExpAlternation::compare(const UnboundedRegExpAlternation& other) const {
 	int thisSize = this->elements.size();
 	int otherSize = other.elements.size();
-	if(thisSize < otherSize) return true;
-	if(thisSize > otherSize) return false;
+	if(thisSize < otherSize) return -1;
+	if(thisSize > otherSize) return 1;
 
 	auto thisIter = this->elements.begin();
 	auto otherIter = other.elements.begin();
 	for(; thisIter != this->elements.end(); thisIter++, otherIter++) {
-	  if(**thisIter != **otherIter) break;
+		int res = (*thisIter)->compare(**otherIter);
+		if(res != 0) return res;
 	}
-	if(thisIter == this->elements.end()) return false;
-
-	return **thisIter < **otherIter;
-}
-
-bool UnboundedRegExpAlternation::operator==(const UnboundedRegExpAlternation& other) const {
-	if(this->elements.size() != other.elements.size()) return false;
-
-	auto thisIter = this->elements.begin();
-	auto otherIter = other.elements.begin();
-	for(; thisIter != this->elements.end(); thisIter++, otherIter++) {
-	  if(**thisIter != **otherIter) return false;
-	}
-
-	return true;
+	return 0;
 }
 
 void UnboundedRegExpAlternation::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
index ab78cbfdac74d2f6e2a7b8b4b349a22337c05ea1..669d29d9136eadd478b3cfa8bf06713d7e95a1ae 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
@@ -86,12 +86,8 @@ public:
 	 */
 	void appendElement(UnboundedRegExpElement&& element);
 
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpAlternation&) const;
-	virtual bool operator==(const UnboundedRegExpAlternation&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpAlternation&) const;
 
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
index 96a9f65834c06035b05eb7ff25df5b4f4f76ab3d..a632d5bcaccd805492b8b333933a0cc8fd5e2564 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
@@ -107,45 +107,23 @@ FormalRegExpElement* UnboundedRegExpConcatenation::cloneAsFormal() const {
 	return res;
 }
 
-bool UnboundedRegExpConcatenation::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpConcatenation::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpConcatenation::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpConcatenation::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool UnboundedRegExpConcatenation::operator<(const UnboundedRegExpConcatenation& other) const {
+int UnboundedRegExpConcatenation::compare(const UnboundedRegExpConcatenation& other) const {
 	int thisSize = this->elements.size();
 	int otherSize = other.elements.size();
-	if(thisSize < otherSize) return true;
-	if(thisSize > otherSize) return false;
+	if(thisSize < otherSize) return -1;
+	if(thisSize > otherSize) return 1;
 
 	auto thisIter = this->elements.begin();
 	auto otherIter = other.elements.begin();
 	for(; thisIter != this->elements.end(); thisIter++, otherIter++) {
-		if(**thisIter != **otherIter) break;
+		int res = (*thisIter)->compare(**otherIter);
+		if(res != 0) return res;
 	}
-	if(thisIter == this->elements.end()) return false;
-
-	return **thisIter < **otherIter;
-}
-
-bool UnboundedRegExpConcatenation::operator==(const UnboundedRegExpConcatenation& other) const {
-	if(this->elements.size() != other.elements.size()) return false;
-
-	auto thisIter = this->elements.begin();
-	auto otherIter = other.elements.begin();
-	for(; thisIter != this->elements.end(); thisIter++, otherIter++) {
-		if(**thisIter != **otherIter) return false;
-	}
-
-	return true;
+	return 0;
 }
 
 void UnboundedRegExpConcatenation::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
index 04314dfad668306318fc7fbc8d5b2cc7452a1469..c69543fc03d5f810fc36e8b0eda552b9d1feb8a9 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
@@ -85,12 +85,8 @@ public:
 	
 	void appendElement(UnboundedRegExpElement&& element);
 
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpConcatenation&) const;
-	virtual bool operator==(const UnboundedRegExpConcatenation&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpConcatenation&) const;
 
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
index 06d15fa34e3eeb39c3e46cd519c09c057325f673..893ab6b978a3663914eb3fde6f074a0e71208e20 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
@@ -45,25 +45,12 @@ FormalRegExpElement* UnboundedRegExpEmpty::cloneAsFormal() const {
 	return new FormalRegExpEmpty();
 }
 
-bool UnboundedRegExpEmpty::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpEmpty::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpEmpty::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpEmpty::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool UnboundedRegExpEmpty::operator<(const UnboundedRegExpEmpty&) const {
-	return false;
-}
-
-bool UnboundedRegExpEmpty::operator==(const UnboundedRegExpEmpty&) const {
-	return true;
+int UnboundedRegExpEmpty::compare(const UnboundedRegExpEmpty&) const {
+	return 0;
 }
 
 void UnboundedRegExpEmpty::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
index 97fd1c08feb73ec7e2adcd4a6aee1b1eaa44f767..eff46b883215b2b13d6b3bea92262e9ca5ed9ba1 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
@@ -54,12 +54,8 @@ public:
 	 */
 	virtual UnboundedRegExpElement* plunder() &&;
 
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpEmpty&) const;
-	virtual bool operator==(const UnboundedRegExpEmpty&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpEmpty&) const;
 	
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
index f190a6055fd3219863810c7a9a643276fdb4c647..c1662b17e3fc0079d5cd493763df2cfdea35648b 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
@@ -45,25 +45,12 @@ FormalRegExpElement* UnboundedRegExpEpsilon::cloneAsFormal() const {
 	return new FormalRegExpEpsilon();
 }
 
-bool UnboundedRegExpEpsilon::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpEpsilon::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpEpsilon::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpEpsilon::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool UnboundedRegExpEpsilon::operator<(const UnboundedRegExpEpsilon&) const {
-	  return false;
-}
-
-bool UnboundedRegExpEpsilon::operator==(const UnboundedRegExpEpsilon&) const {
-	  return true;
+int UnboundedRegExpEpsilon::compare(const UnboundedRegExpEpsilon&) const {
+	  return 0;
 }
 
 void UnboundedRegExpEpsilon::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
index df1c9205c42cfb6a6d4c942c494c58d6e5cb5341..974a276582d40b95c61334788b698f3cb2abc718 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
@@ -56,12 +56,8 @@ public:
 	virtual UnboundedRegExpElement* plunder() &&;
 	
 	
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpEpsilon&) const;
-	virtual bool operator==(const UnboundedRegExpEpsilon&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpEpsilon&) const;
 	
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
index e2f9d5cf20b6aba2adf851ebe4de4432884f9874..2e597696382e66a5de77767448d1330f4482b692 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
@@ -93,24 +93,12 @@ FormalRegExpElement* UnboundedRegExpIteration::cloneAsFormal() const {
 	return res;
 }
 
-bool UnboundedRegExpIteration::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpIteration::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpIteration::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpIteration::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-bool UnboundedRegExpIteration::operator<(const UnboundedRegExpIteration& other) const {
-	return *(this->element) < *(other.element);
-}
-
-bool UnboundedRegExpIteration::operator==(const UnboundedRegExpIteration& other) const {
-	return *(this->element) == *(other.element);
+int UnboundedRegExpIteration::compare(const UnboundedRegExpIteration& other) const {
+	return element->compare(*other.element);
 }
 
 void UnboundedRegExpIteration::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index 26901d9629db18efcb720fa1a0a1f0c73886ddd5..30bf2f8fe36bb981e799c0d10887b6c9bb3469ad 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -84,12 +84,8 @@ public:
 	
 	void setElement(UnboundedRegExpElement&& element);
 
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpIteration&) const;
-	virtual bool operator==(const UnboundedRegExpIteration&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpIteration&) const;
 
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
index 77f399bead390fa8b8657a779f34611fc6be7f56..f06d1c16864c4fee47a135862d0c7398d9867e9c 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
@@ -78,25 +78,12 @@ bool operator==(const alphabet::Symbol& first, const UnboundedRegExpSymbol& seco
 	return first == second.symbol;
 }
 
-bool UnboundedRegExpSymbol::operator<(const UnboundedRegExpElement& other) const {
-	return other > *this;
+int UnboundedRegExpSymbol::compare(const UnboundedRegExpElement& other) const {
+	return -other.compare(*this);
 }
 
-bool UnboundedRegExpSymbol::operator==(const UnboundedRegExpElement& other) const {
-	return other == *this;
-}
-
-bool UnboundedRegExpSymbol::operator>(const UnboundedRegExpElement& other) const {
-	return other < *this;
-}
-
-
-bool UnboundedRegExpSymbol::operator<(const UnboundedRegExpSymbol& other) const {
-	return symbol < other.symbol;
-}
-
-bool UnboundedRegExpSymbol::operator==(const UnboundedRegExpSymbol& other) const {
-	return symbol == other.symbol;
+int UnboundedRegExpSymbol::compare(const UnboundedRegExpSymbol& other) const {
+	return symbol.getData().compare(other.symbol.getData());
 }
 
 void UnboundedRegExpSymbol::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
index d0c08c69e4a3945a98bc608f8f654a3cb39592d8..8491667ba36906d1ca5141aae99e42ede9b40e4e 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
@@ -66,12 +66,8 @@ public:
 	bool operator==(const alphabet::Symbol&) const;
 	friend bool operator==(const alphabet::Symbol&, const UnboundedRegExpSymbol&);
 
-	virtual bool operator<(const UnboundedRegExpElement&) const;
-	virtual bool operator==(const UnboundedRegExpElement&) const;
-	virtual bool operator>(const UnboundedRegExpElement&) const;
-
-	virtual bool operator<(const UnboundedRegExpSymbol&) const;
-	virtual bool operator==(const UnboundedRegExpSymbol&) const;
+	virtual int compare(const UnboundedRegExpElement&) const;
+	virtual int compare(const UnboundedRegExpSymbol&) const;
 	
 	/**
 	 * @copydoc UnboundedRegExpElement::operator>>() const
diff --git a/alib2data/src/std/tuple.hpp b/alib2data/src/std/tuple.hpp
index 76fe870ac5673b7063efce76695d942690acf506..93396f3188087e9196f02bbe6da33f2ea6f56ccc 100644
--- a/alib2data/src/std/tuple.hpp
+++ b/alib2data/src/std/tuple.hpp
@@ -37,15 +37,10 @@ struct operator_shift_left_impl<0, Tuple> {
 	}
 };
 
-template<class Tuple>
-void operator_shift_left(ostream& out, const Tuple& t) {
-	operator_shift_left_impl<tuple_size<Tuple>::value - 1, Tuple>::operator_shift_left(out, t);
-}
-
 template< class... Ts>
 std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...>& tuple) {
 	out << "(";
-	operator_shift_left(out, tuple);
+	operator_shift_left_impl<tuple_size<std::tuple<Ts...>>::value - 1, std::tuple<Ts...>>::operator_shift_left(out, tuple);
 	out << ")";
 	return out;
 }
diff --git a/alib2data/src/string/CyclicString.cpp b/alib2data/src/string/CyclicString.cpp
index fafb1457262c7b99c1bfaf182ab2af3f050ff1e7..0ccfdc33fe6fd3ee709454c740369ae96004ea6b 100644
--- a/alib2data/src/string/CyclicString.cpp
+++ b/alib2data/src/string/CyclicString.cpp
@@ -50,6 +50,10 @@ CyclicString::CyclicString(const std::string& str) {
 	alphabet = std::set<alphabet::Symbol>(m_Data.begin(), m_Data.end());
 }
 
+CyclicString::CyclicString(const Epsilon& epsilon) {
+	alphabet = epsilon.getAlphabet();
+}
+
 StringBase* CyclicString::clone() const {
 	return new CyclicString(*this);
 }
@@ -65,18 +69,6 @@ bool CyclicString::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	return alphabet.erase(symbol);
 }
 
-bool CyclicString::operator <(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool CyclicString::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool CyclicString::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
 const std::vector<alphabet::Symbol>& CyclicString::getContent() const {
 	return this->m_Data;
 }
@@ -97,32 +89,53 @@ bool CyclicString::isEmpty() const {
 	return this->m_Data.size() == 0;
 }
 
-bool CyclicString::operator<(const LinearString& other) const {
-	if(this->isEmpty() && other.isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
+int CyclicString::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool CyclicString::operator<(const CyclicString& other) const {
-	return std::tie(m_Data, alphabet) < std::tie(other.m_Data, other.alphabet);
+int CyclicString::compare(const LinearString& other) const {
+	if(this->isEmpty() && other.isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		else if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
+	
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
 }
 
-bool CyclicString::operator<(const Epsilon& other) const {
-	if(this->isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
-}
+int CyclicString::compare(const CyclicString& other) const {
+	auto first = std::tie(m_Data, alphabet);
+	auto second = std::tie(other.m_Data, other.alphabet);
 
-bool CyclicString::operator==(const LinearString& other) const {
-	if(this->isEmpty() && other.isEmpty()) return alphabet == other.getAlphabet();
-	return false;
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
-bool CyclicString::operator==(const CyclicString& other) const {
-	return m_Data == other.m_Data && alphabet == other.getAlphabet();
-}
+int CyclicString::compare(const Epsilon& other) const {
+	if(this->isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		else if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
 
-bool CyclicString::operator==(const Epsilon& other) const {
-	if(this->isEmpty()) return alphabet == other.getAlphabet();
-	return false;
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
 }
 
 void CyclicString::operator >>(std::ostream& out) const {
diff --git a/alib2data/src/string/CyclicString.h b/alib2data/src/string/CyclicString.h
index 61e5b8851bdc0c3f602d6e968a8bf0cab13e6b62..c85099f747439359c7c962bb415d19598d680398 100644
--- a/alib2data/src/string/CyclicString.h
+++ b/alib2data/src/string/CyclicString.h
@@ -16,6 +16,7 @@
 #include "../alphabet/Symbol.h"
 #include "StringBase.h"
 #include "common/StringAlphabet.h"
+#include "Epsilon.h"
 
 namespace string {
 
@@ -32,16 +33,13 @@ public:
 	explicit CyclicString(const std::vector<alphabet::Symbol>& data);
 	explicit CyclicString(std::vector<alphabet::Symbol>&& data);
 	explicit CyclicString(const std::string& str);
+	explicit CyclicString(const Epsilon& epsilon);
 
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
 
 	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return List of symbols forming string (const version).
 	 */
@@ -54,13 +52,11 @@ public:
 	 */
 	bool isEmpty() const;
 
-	virtual bool operator<(const LinearString& other) const;
-	virtual bool operator<(const CyclicString& other) const;
-	virtual bool operator<(const Epsilon& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
 
-	virtual bool operator==(const LinearString& other) const;
-	virtual bool operator==(const CyclicString& other) const;
-	virtual bool operator==(const Epsilon& other) const;
+	virtual int compare(const LinearString& other) const;
+	virtual int compare(const CyclicString& other) const;
+	virtual int compare(const Epsilon& other) const;
 
 	virtual void operator >>(std::ostream& out) const;
 
diff --git a/alib2data/src/string/Epsilon.cpp b/alib2data/src/string/Epsilon.cpp
index 7950335b849f37ec30d98fcef5996ca186d5101f..d7cb03b2b99fe4ea7ff62a477b683f5b0d551d2d 100644
--- a/alib2data/src/string/Epsilon.cpp
+++ b/alib2data/src/string/Epsilon.cpp
@@ -26,18 +26,6 @@ bool Epsilon::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	return alphabet.erase(symbol);
 }
 
-bool Epsilon::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool Epsilon::operator==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool Epsilon::operator>(const ObjectBase& other) const {
-	return other < *this;
-}
-
 std::vector<alphabet::Symbol> Epsilon::getContent() const {
 	return {};
 }
@@ -46,32 +34,49 @@ bool Epsilon::isEmpty() const {
 	return true;
 }
 
-bool Epsilon::operator<(const Epsilon& other) const {
-	return alphabet < other.alphabet;
-}
-
-bool Epsilon::operator<(const LinearString& other) const {
-	if(other.isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
-}
-
-bool Epsilon::operator<(const CyclicString& other) const {
-	if(other.isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
-}
-
-bool Epsilon::operator==(const Epsilon& other) const {
-	return alphabet == other.alphabet;
-}
-
-bool Epsilon::operator==(const LinearString& other) const {
-	if(other.isEmpty()) return alphabet == other.getAlphabet();
-	return false;
-}
-
-bool Epsilon::operator==(const CyclicString& other) const {
-	if(other.isEmpty()) return alphabet == other.getAlphabet();
-	return false;
+int Epsilon::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
+}
+
+int Epsilon::compare(const Epsilon& other) const {
+	if(alphabet == other.alphabet)
+		return 0;
+	else if(alphabet < other.alphabet)
+		return -1;
+	else
+		return 1;
+}
+
+int Epsilon::compare(const LinearString& other) const {
+	if(other.isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		else if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
+
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
+}
+
+int Epsilon::compare(const CyclicString& other) const {
+	if(other.isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		else if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
+
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
 }
 
 void Epsilon::operator>>(std::ostream& out) const {
diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h
index bf39c0cf98bb90c09f6ce85c464f5cff13683023..81ecbf3202dad0aa277d0ac61309fe1f2260531d 100644
--- a/alib2data/src/string/Epsilon.h
+++ b/alib2data/src/string/Epsilon.h
@@ -30,10 +30,6 @@ public:
 
 	virtual bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return List of symbols forming string (const version).
 	 */
@@ -44,13 +40,11 @@ public:
 	 */
 	bool isEmpty() const;
 
-	virtual bool operator<(const LinearString& other) const;
-	virtual bool operator<(const CyclicString& other) const;
-	virtual bool operator<(const Epsilon& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
 
-	virtual bool operator==(const LinearString& other) const;
-	virtual bool operator==(const CyclicString& other) const;
-	virtual bool operator==(const Epsilon& other) const;
+	virtual int compare(const LinearString& other) const;
+	virtual int compare(const CyclicString& other) const;
+	virtual int compare(const Epsilon& other) const;
 
 	virtual void operator >>(std::ostream& out) const;
 
diff --git a/alib2data/src/string/LinearString.cpp b/alib2data/src/string/LinearString.cpp
index d1e1626c0c262dd2a2dabd117e639ab0e4a2c1a5..840336ce9ab38cf3eee8316ad5013ddc448fd68c 100644
--- a/alib2data/src/string/LinearString.cpp
+++ b/alib2data/src/string/LinearString.cpp
@@ -50,6 +50,10 @@ LinearString::LinearString(const std::string& str) {
 	alphabet = std::set<alphabet::Symbol>(m_Data.begin(), m_Data.end());
 }
 
+LinearString::LinearString(const Epsilon& epsilon) {
+	alphabet = epsilon.getAlphabet();
+}
+
 StringBase* LinearString::clone() const {
 	return new LinearString(*this);
 }
@@ -77,18 +81,6 @@ void LinearString::appendSymbol(alphabet::Symbol&& symbol) {
 	m_Data.push_back(std::move(symbol));
 }
 
-bool LinearString::operator<(const ObjectBase& other) const {
-	return other > *this;
-}
-
-bool LinearString::operator ==(const ObjectBase& other) const {
-	return other == *this;
-}
-
-bool LinearString::operator >(const ObjectBase& other) const {
-	return other < *this;
-}
-
 const std::vector<alphabet::Symbol>& LinearString::getContent() const {
 	return this->m_Data;
 }
@@ -108,32 +100,53 @@ bool LinearString::isEmpty() const {
 	return this->m_Data.size() == 0;
 }
 
-bool LinearString::operator<(const LinearString& other) const {
-	return std::tie(m_Data, alphabet) < std::tie(other.m_Data, other.alphabet);
+int LinearString::compare(const ObjectBase& other) const {
+	return -other.compare(*this);
 }
 
-bool LinearString::operator<(const CyclicString& other) const {
-	if(this->isEmpty() && other.isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
-}
+int LinearString::compare(const LinearString& other) const {
+	auto first = std::tie(m_Data, alphabet);
+	auto second = std::tie(other.m_Data, other.alphabet);
 
-bool LinearString::operator<(const Epsilon& other) const {
-	if(this->isEmpty()) return alphabet < other.getAlphabet();
-	return typeid(*this).before(typeid(other));
-}
-
-bool LinearString::operator==(const LinearString& other) const {
-	return m_Data == other.m_Data && alphabet == other.getAlphabet();
-}
-
-bool LinearString::operator==(const CyclicString& other) const {
-	if(this->isEmpty() && other.isEmpty()) return alphabet == other.getAlphabet();
-	return false;
+	if(first == second) {
+		return 0;
+	} else if(first < second) {
+		return -1;
+	} else {
+		return 1;
+	}
 }
 
-bool LinearString::operator==(const Epsilon& other) const {
-	if(this->isEmpty()) return alphabet == other.getAlphabet();
-	return false;
+int LinearString::compare(const CyclicString& other) const {
+	if(this->isEmpty() && other.isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
+	
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
+}
+
+int LinearString::compare(const Epsilon& other) const {
+	if(this->isEmpty()) {
+		if(alphabet == other.getAlphabet())
+			return 0;
+		else if(alphabet < other.getAlphabet())
+			return -1;
+		else
+			return 1;
+	}
+	
+	if(typeid(*this).before(typeid(other)))
+		return -1;
+	else
+		return 1;
 }
 
 void LinearString::operator >>(std::ostream& out) const {
diff --git a/alib2data/src/string/LinearString.h b/alib2data/src/string/LinearString.h
index 914386b1e3231767843c743c738e663c8c3257f7..a74a468fb12640bc223bfcbedfcc9ff941623229 100644
--- a/alib2data/src/string/LinearString.h
+++ b/alib2data/src/string/LinearString.h
@@ -16,6 +16,7 @@
 #include "../alphabet/Symbol.h"
 #include "StringBase.h"
 #include "common/StringAlphabet.h"
+#include "Epsilon.h"
 
 namespace string {
 
@@ -33,6 +34,7 @@ public:
 	explicit LinearString(const std::vector<alphabet::Symbol>& data);
 	explicit LinearString(std::vector<alphabet::Symbol>&& data);
 	explicit LinearString(const std::string& str);
+	explicit LinearString(const Epsilon& epsilon);
 
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
@@ -46,10 +48,6 @@ public:
 	
 	void appendSymbol(alphabet::Symbol&& symbol);
 
-	virtual bool operator <(const alib::ObjectBase& other) const;
-	virtual bool operator ==(const alib::ObjectBase& other) const;
-	virtual bool operator >(const alib::ObjectBase& other) const;
-
 	/**
 	 * @return List of symbols forming string (const version).
 	 */
@@ -62,13 +60,11 @@ public:
 	 */
 	bool isEmpty() const;
 
-	virtual bool operator<(const LinearString& other) const;
-	virtual bool operator<(const CyclicString& other) const;
-	virtual bool operator<(const Epsilon& other) const;
+	virtual int compare(const alib::ObjectBase& other) const;
 
-	virtual bool operator==(const LinearString& other) const;
-	virtual bool operator==(const CyclicString& other) const;
-	virtual bool operator==(const Epsilon& other) const;
+	virtual int compare(const LinearString& other) const;
+	virtual int compare(const CyclicString& other) const;
+	virtual int compare(const Epsilon& other) const;
 
 	virtual void operator >>(std::ostream& out) const;
 
diff --git a/alib2data/test-src/std/StdVisitorTest.cpp b/alib2data/test-src/std/StdVisitorTest.cpp
index dbd7e2cedbb4c12f0a95586342f1a4298e458a16..2d275a47fbbca1278d61413e8093ee759aedec36 100644
--- a/alib2data/test-src/std/StdVisitorTest.cpp
+++ b/alib2data/test-src/std/StdVisitorTest.cpp
@@ -44,24 +44,12 @@ public:
 		return new Tmp1(*this);
 	}
 
-	virtual bool operator<(const TmpBase& other) const {
-		return other > *this;
+	virtual int compare(const TmpBase& other) const {
+		return -other.compare(*this);
 	}
 
-	virtual bool operator==(const TmpBase& other) const {
-		return other == *this;
-	}
-
-	virtual bool operator>(const TmpBase& other) const {
-		return other < *this;
-	}
-
-	virtual bool operator==(const Tmp1& other) const {
-		return this->data == other.data;
-	}
-
-	virtual bool operator<(const Tmp1& other) const {
-		return this->data < other.data;
+	virtual int compare(const Tmp1& other) const {
+		return this->data - other.data;
 	}
 
 	virtual void operator>>(std::ostream& os) const {
@@ -101,24 +89,12 @@ public:
 		return new Tmp2(*this);
 	}
 
-	virtual bool operator<(const TmpBase& other) const {
-		return other > *this;
-	}
-
-	virtual bool operator==(const TmpBase& other) const {
-		return other == *this;
-	}
-
-	virtual bool operator>(const TmpBase& other) const {
-		return other < *this;
-	}
-
-	virtual bool operator==(const Tmp2& other) const {
-		return this->data == other.data;
+	virtual int compare(const TmpBase& other) const {
+		return -other.compare(*this);
 	}
 
-	virtual bool operator<(const Tmp2& other) const {
-		return this->data < other.data;
+	virtual int compare(const Tmp2& other) const {
+		return this->data - other.data;
 	}
 
 	virtual void operator>>(std::ostream& os) const {
@@ -162,24 +138,12 @@ public:
 		return new Tmp3(*this);
 	}
 
-	virtual bool operator<(const TmpBase& other) const {
-		return other > *this;
-	}
-
-	virtual bool operator==(const TmpBase& other) const {
-		return other == *this;
-	}
-
-	virtual bool operator>(const TmpBase& other) const {
-		return other < *this;
-	}
-
-	virtual bool operator==(const Tmp3& other) const {
-		return this->data == other.data;
+	virtual int compare(const TmpBase& other) const {
+		return -other.compare(*this);
 	}
 
-	virtual bool operator<(const Tmp3& other) const {
-		return this->data < other.data;
+	virtual int compare(const Tmp3& other) const {
+		return this->data.compare(other.data);
 	}
 
 	virtual void operator>>(std::ostream& os) const {