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