From 994c874c8d37657a5a66a66e2ca6cc6d9d123b3f Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 3 Feb 2020 21:22:03 +0100
Subject: [PATCH] xmlapi Unordered NFTA

---
 .../src/automaton/xml/TA/UnorderedNFTA.cpp    |  20 +++
 .../src/automaton/xml/TA/UnorderedNFTA.h      | 152 ++++++++++++++++++
 .../xml/common/AutomatonFromXMLParser.h       |  15 ++
 .../xml/common/AutomatonToXMLComposer.h       |  12 ++
 examples2/automaton/UnorderedNFTA_fab_faa.xml |  95 +++++++++++
 5 files changed, 294 insertions(+)
 create mode 100644 alib2data/src/automaton/xml/TA/UnorderedNFTA.cpp
 create mode 100644 alib2data/src/automaton/xml/TA/UnorderedNFTA.h
 create mode 100644 examples2/automaton/UnorderedNFTA_fab_faa.xml

diff --git a/alib2data/src/automaton/xml/TA/UnorderedNFTA.cpp b/alib2data/src/automaton/xml/TA/UnorderedNFTA.cpp
new file mode 100644
index 0000000000..459f29a68d
--- /dev/null
+++ b/alib2data/src/automaton/xml/TA/UnorderedNFTA.cpp
@@ -0,0 +1,20 @@
+/*
+ * UnorderedNFTA.cpp
+ *
+ *  Created on: Mar 21, 2015
+ *      Author: Stepan Plachy
+ */
+
+#include "UnorderedNFTA.h"
+#include <object/Object.h>
+
+#include <registration/XmlRegistration.hpp>
+
+namespace {
+
+auto xmlWriteUnorderedNFTA = registration::XmlWriterRegister < automaton::UnorderedNFTA < > > ( );
+auto xmlReadUnorderedNFTA = registration::XmlReaderRegister < automaton::UnorderedNFTA < > > ( );
+
+auto xmlGroupUnorderedNFTA = registration::XmlRegisterTypeInGroup < object::Object, automaton::UnorderedNFTA < > > ( );
+
+} /* namespace */
diff --git a/alib2data/src/automaton/xml/TA/UnorderedNFTA.h b/alib2data/src/automaton/xml/TA/UnorderedNFTA.h
new file mode 100644
index 0000000000..086aa83dff
--- /dev/null
+++ b/alib2data/src/automaton/xml/TA/UnorderedNFTA.h
@@ -0,0 +1,152 @@
+/*
+ * UnorderedNFTA.h
+ *
+ * This file is part of Algorithms library toolkit.
+ * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
+
+ * Algorithms library toolkit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * Algorithms library toolkit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with Algorithms library toolkit.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Created on: Mar 21, 2015
+ *      Author: Stepan Plachy
+ */
+
+#ifndef _XML_UNORDERED_NFTA_H_
+#define _XML_UNORDERED_NFTA_H_
+
+#include <core/xmlApi.hpp>
+#include <automaton/TA/UnorderedNFTA.h>
+#include "../common/AutomatonFromXMLParser.h"
+#include "../common/AutomatonToXMLComposer.h"
+
+namespace core {
+
+template < class SymbolType, class StateType >
+struct xmlApi < automaton::UnorderedNFTA < SymbolType, StateType > > {
+	/**
+	 * \brief The XML tag name of class.
+	 *
+	 * \details Intentionaly a static member function to be safe in the initialisation before the main function starts.
+	 *
+	 * \returns string representing the XML tag name of the class
+	 */
+	static std::string xmlTagName() {
+		return "UnorderedNFTA";
+	}
+
+	/**
+	 * \brief Tests whether the token stream starts with this type
+	 *
+	 * \params input the iterator to sequence of xml tokens to test
+	 *
+	 * \returns true if the token stream iterator points to opening tag named with xml tag name of this type, false otherwise.
+	 */
+	static bool first ( const ext::deque < sax::Token >::const_iterator & input ) {
+		return sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );
+	}
+
+	/**
+	 * Parsing from a sequence of xml tokens helper.
+	 *
+	 * \params input the iterator to sequence of xml tokens to parse from
+	 *
+	 * \returns the new instance of the automaton
+	 */
+	static automaton::UnorderedNFTA < SymbolType, StateType > parse ( ext::deque < sax::Token >::iterator & input );
+
+	/**
+	 * Helper for parsing of individual transitions of the automaton from a sequence of xml tokens.
+	 *
+	 * \params input the iterator to sequence of xml tokens to parse from
+	 * \params automaton the automaton to add the rule to
+	 */
+	static void parseTransition ( ext::deque < sax::Token >::iterator & input, automaton::UnorderedNFTA < SymbolType, StateType > & automaton );
+
+	/**
+	 * Composing to a sequence of xml tokens helper.
+	 *
+	 * \param out the sink for new xml tokens representing the automaton
+	 * \param automaton the automaton to compose
+	 */
+	static void compose ( ext::deque < sax::Token > & out, const automaton::UnorderedNFTA < SymbolType, StateType > & automaton );
+
+	/**
+	 * Helper for composing transitions of the automaton to a sequence of xml tokens.
+	 *
+	 * \param out the sink for xml tokens representing the rules of the automaton
+	 * \param automaton the automaton to compose
+	 */
+	static void composeTransitions ( ext::deque < sax::Token > & out, const automaton::UnorderedNFTA < SymbolType, StateType > & automaton );
+};
+
+template < class SymbolType, class StateType >
+automaton::UnorderedNFTA < SymbolType, StateType > xmlApi < automaton::UnorderedNFTA < SymbolType, StateType > >::parse(ext::deque<sax::Token>::iterator& input) {
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );
+
+	ext::set<StateType> states = automaton::AutomatonFromXMLParser::parseStates<StateType>(input);
+	ext::set<common::ranked_symbol < SymbolType >> inputSymbols = automaton::AutomatonFromXMLParser::parseRankedInputAlphabet<common::ranked_symbol < SymbolType >>(input);
+	ext::set<StateType> finalStates = automaton::AutomatonFromXMLParser::parseFinalStates<StateType>(input);
+
+	automaton::UnorderedNFTA < SymbolType, StateType > automaton;
+	automaton.setStates(std::move(states));
+	automaton.setInputAlphabet(std::move(inputSymbols));
+	automaton.setFinalStates(std::move(finalStates));
+
+	automaton::AutomatonFromXMLParser::parseTransitions ( input, automaton );
+
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );
+	return automaton;
+}
+
+template < class SymbolType, class StateType >
+void xmlApi < automaton::UnorderedNFTA < SymbolType, StateType > >::parseTransition(ext::deque<sax::Token>::iterator& input, automaton::UnorderedNFTA < SymbolType, StateType > & automaton) {
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, "transition");
+	common::ranked_symbol < SymbolType > inputSymbol = automaton::AutomatonFromXMLParser::parseTransitionInputSymbol<common::ranked_symbol < SymbolType >>(input);
+	ext::multiset<StateType> from = automaton::AutomatonFromXMLParser::parseTransitionFromMultiset<StateType>(input);
+	StateType to = automaton::AutomatonFromXMLParser::parseTransitionTo<StateType>(input);
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transition");
+
+	automaton.addTransition(std::move(inputSymbol), std::move(from), std::move(to));
+}
+
+template < class SymbolType, class StateType >
+void xmlApi < automaton::UnorderedNFTA < SymbolType, StateType > >::compose(ext::deque<sax::Token>& out, const automaton::UnorderedNFTA < SymbolType, StateType > & automaton ) {
+	out.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT );
+
+	automaton::AutomatonToXMLComposer::composeStates(out, automaton.getStates());
+	automaton::AutomatonToXMLComposer::composeRankedInputAlphabet(out, automaton.getInputAlphabet());
+	automaton::AutomatonToXMLComposer::composeFinalStates(out, automaton.getFinalStates());
+	composeTransitions(out, automaton);
+
+	out.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
+}
+
+template < class SymbolType, class StateType >
+void xmlApi < automaton::UnorderedNFTA < SymbolType, StateType > >::composeTransitions(ext::deque<sax::Token>& out, const automaton::UnorderedNFTA < SymbolType, StateType > & automaton ) {
+	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
+	for(const auto& transition : automaton.getTransitions()) {
+		out.emplace_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT));
+
+		automaton::AutomatonToXMLComposer::composeTransitionInputSymbol(out, transition.first.first);
+		automaton::AutomatonToXMLComposer::composeTransitionFrom(out, transition.first.second);
+		automaton::AutomatonToXMLComposer::composeTransitionTo(out, transition.second);
+
+		out.emplace_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT));
+	}
+
+	out.emplace_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
+}
+
+} /* namespace core */
+
+#endif /* _XML_UNORDERED_NFTA_H_ */
diff --git a/alib2data/src/automaton/xml/common/AutomatonFromXMLParser.h b/alib2data/src/automaton/xml/common/AutomatonFromXMLParser.h
index 58f0b64a8f..399990fb0a 100644
--- a/alib2data/src/automaton/xml/common/AutomatonFromXMLParser.h
+++ b/alib2data/src/automaton/xml/common/AutomatonFromXMLParser.h
@@ -10,6 +10,7 @@
 
 #include <alib/deque>
 #include <alib/set>
+#include <alib/multiset>
 #include <alib/vector>
 #include <alib/map>
 
@@ -72,6 +73,8 @@ public:
 	template < class StateType >
 	static ext::vector<StateType> parseTransitionFromMultiple(ext::deque<sax::Token>::iterator& input);
 	template < class StateType >
+	static ext::multiset<StateType> parseTransitionFromMultiset(ext::deque<sax::Token>::iterator& input);
+	template < class StateType >
 	static StateType parseTransitionTo(ext::deque<sax::Token>::iterator& input);
 	template < class SymbolType >
 	static ext::vector<SymbolType> parseTransitionPop(ext::deque<sax::Token>::iterator& input);
@@ -358,6 +361,18 @@ ext::vector < StateType > AutomatonFromXMLParser::parseTransitionFromMultiple (
 	return states;
 }
 
+template < class StateType >
+ext::multiset < StateType > AutomatonFromXMLParser::parseTransitionFromMultiset ( ext::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "from" );
+	ext::multiset < StateType > states;
+
+	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
+		states.insert ( core::xmlApi < StateType >::parse ( input ) );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "from" );
+	return states;
+}
+
 template < class SymbolType >
 ext::vector < SymbolType > AutomatonFromXMLParser::parseTransitionPop ( ext::deque < sax::Token >::iterator & input ) {
 	ext::vector < SymbolType > pops;
diff --git a/alib2data/src/automaton/xml/common/AutomatonToXMLComposer.h b/alib2data/src/automaton/xml/common/AutomatonToXMLComposer.h
index 0db7cfee8e..fc562571fd 100644
--- a/alib2data/src/automaton/xml/common/AutomatonToXMLComposer.h
+++ b/alib2data/src/automaton/xml/common/AutomatonToXMLComposer.h
@@ -10,6 +10,7 @@
 
 #include <alib/deque>
 #include <alib/vector>
+#include <alib/multiset>
 #include <alib/set>
 #include <alib/map>
 
@@ -68,6 +69,8 @@ public:
 	static void composeTransitionFrom(ext::deque<sax::Token>&, const StateType& state);
 	template<class StateType>
 	static void composeTransitionFrom(ext::deque<sax::Token>&, const ext::vector<StateType> & states);
+	template<class StateType>
+	static void composeTransitionFrom(ext::deque<sax::Token>&, const ext::multiset<StateType> & states);
 	template<class SymbolType>
 	static void composeTransitionPop(ext::deque<sax::Token>&, const ext::vector<SymbolType>& symbols);
 	template<class SymbolType>
@@ -271,6 +274,15 @@ void AutomatonToXMLComposer::composeTransitionFrom(ext::deque<sax::Token>& out,
 	out.emplace_back("from", sax::Token::TokenType::END_ELEMENT);
 }
 
+template < class StateType >
+void AutomatonToXMLComposer::composeTransitionFrom(ext::deque<sax::Token>& out, const ext::multiset<StateType> & states) {
+	out.emplace_back("from", sax::Token::TokenType::START_ELEMENT);
+	for (const auto& state : states) {
+		core::xmlApi<StateType>::compose(out, state);
+	}
+	out.emplace_back("from", sax::Token::TokenType::END_ELEMENT);
+}
+
 template < class SymbolType >
 void AutomatonToXMLComposer::composeTransitionPop(ext::deque<sax::Token>& out, const ext::vector<SymbolType>& symbols) {
 	out.emplace_back("pop", sax::Token::TokenType::START_ELEMENT);
diff --git a/examples2/automaton/UnorderedNFTA_fab_faa.xml b/examples2/automaton/UnorderedNFTA_fab_faa.xml
new file mode 100644
index 0000000000..c29f958ae4
--- /dev/null
+++ b/examples2/automaton/UnorderedNFTA_fab_faa.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<UnorderedNFTA>
+	<states>
+		<String>1</String>
+		<String>2</String>
+		<String>3</String>
+		<String>4</String>
+		<String>5</String>
+		<String>6</String>
+	</states>
+	<rankedInputAlphabet>
+		<RankedSymbol>
+			<String>f</String>
+			<UnsignedLong>2</UnsignedLong>
+		</RankedSymbol>
+		<RankedSymbol>
+			<String>a</String>
+			<UnsignedLong>0</UnsignedLong>
+		</RankedSymbol>
+		<RankedSymbol>
+			<String>b</String>
+			<UnsignedLong>0</UnsignedLong>
+		</RankedSymbol>
+	</rankedInputAlphabet>
+	<finalStates>
+		<String>3</String>
+		<String>6</String>
+	</finalStates>
+	<transitions>
+		<transition>
+			<input>
+				<RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+			</from>
+			<to>
+				<String>1</String>
+			</to>
+		</transition>
+		<transition>
+			<input>
+				<RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+			</from>
+			<to>
+				<String>4</String>
+			</to>
+		</transition>
+		<transition>
+			<input>
+				<RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+			</from>
+			<to>
+				<String>5</String>
+			</to>
+		</transition>
+		<transition>
+			<input>
+				<RankedSymbol><String>b</String><UnsignedLong>0</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+			</from>
+			<to>
+				<String>2</String>
+			</to>
+		</transition>
+		<transition>
+			<input>
+				<RankedSymbol><String>f</String><UnsignedLong>2</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+				<String>1</String>
+				<String>2</String>
+			</from>
+			<to>
+				<String>3</String>
+			</to>
+		</transition>
+		<transition>
+			<input>
+				<RankedSymbol><String>f</String><UnsignedLong>2</UnsignedLong></RankedSymbol>
+			</input>
+			<from>
+				<String>4</String>
+				<String>5</String>
+			</from>
+			<to>
+				<String>6</String>
+			</to>
+		</transition>
+	</transitions>
+</UnorderedNFTA>
-- 
GitLab