From c42927eeddb2b3f04fa6e627fb499b4da2d47521 Mon Sep 17 00:00:00 2001 From: Tomas Pecka <peckato1@fit.cvut.cz> Date: Thu, 21 Mar 2019 09:36:37 +0100 Subject: [PATCH] Data: ExtendedNFTA --- alib2data/src/automaton/TA/ExtendedNFTA.cpp | 16 + alib2data/src/automaton/TA/ExtendedNFTA.h | 719 ++++++++++++++++++++ 2 files changed, 735 insertions(+) create mode 100644 alib2data/src/automaton/TA/ExtendedNFTA.cpp create mode 100644 alib2data/src/automaton/TA/ExtendedNFTA.h diff --git a/alib2data/src/automaton/TA/ExtendedNFTA.cpp b/alib2data/src/automaton/TA/ExtendedNFTA.cpp new file mode 100644 index 0000000000..0e5f3e8078 --- /dev/null +++ b/alib2data/src/automaton/TA/ExtendedNFTA.cpp @@ -0,0 +1,16 @@ +/* + * ExtendedNFTA.cpp + * + * Created on: Mar 13, 2019 + * Author: Tomas Pecka + */ + +#include "ExtendedNFTA.h" + +#include <registration/ValuePrinterRegistration.hpp> + +namespace { + +static auto valuePrinter = registration::ValuePrinterRegister < automaton::ExtendedNFTA < > > ( ); + +} /* namespace */ diff --git a/alib2data/src/automaton/TA/ExtendedNFTA.h b/alib2data/src/automaton/TA/ExtendedNFTA.h new file mode 100644 index 0000000000..ac14b6ec8e --- /dev/null +++ b/alib2data/src/automaton/TA/ExtendedNFTA.h @@ -0,0 +1,719 @@ +/* + * ExtendedNFTA.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 13, 2019 + * Author: Tomas Pecka + */ + +#ifndef EXTENDED_NFTA_H_ +#define EXTENDED_NFTA_H_ + +#include <ostream> +#include <sstream> + +#include <alib/map> +#include <alib/set> +#include <alib/vector> +#include <alib/compare> + +#include <core/components.hpp> + +#include <core/normalize.hpp> + +#include <common/DefaultStateType.h> +#include <common/DefaultSymbolType.h> +#include <common/DefaultRankType.h> + +#include <automaton/AutomatonException.h> + +#include <core/normalize.hpp> +#include <alphabet/common/SymbolNormalize.h> +#include <automaton/common/AutomatonNormalize.h> + +#include <rte/formal/FormalRTEElements.h> +#include <rte/formal/FormalRTEStructure.h> + +#include "DFTA.h" +#include "NFTA.h" + +namespace automaton { + +class InputAlphabet; +class States; +class FinalStates; + +/** + * \brief + * Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages. + + * \details + * Definition is classical definition of finite automata. + * A = (Q, T, \delta, F), + * Q (States) = nonempty finite set of states, + * T (TerminalAlphabet) = finite set of terminal ranked symbols - having this empty won't let automaton do much though, + * \delta = transition function of the form (A, B, C, ...) \times a -> P(Q), where A, B, C, ... \in Q, a \in T, and P(Q) is a powerset of states, + * F (FinalStates) = set of final states + * + * Elements of the \delta mapping must meet following criteria. The size of the state list must equal the rank of the ranked symbol. + * + * \tparam SymbolType used for the symbol part of the ranked symbol + * \tparam RankType used for the rank part of the ranked symbol + * \tparam StateType used to the states, and the initial state of the automaton. + */ +template < class SymbolType = DefaultSymbolType, class RankType = DefaultRankType, class StateType = DefaultStateType > +class ExtendedNFTA final : public ext::CompareOperators < ExtendedNFTA < SymbolType, RankType, StateType > >, public core::Components < ExtendedNFTA < SymbolType, RankType, StateType >, ext::set < common::ranked_symbol < SymbolType, RankType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > { + /** + * Transition function as mapping from a list of states times an input symbol on the left hand side to a set of states. + */ + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions; + +public: + /** + * \brief Creates a new instance of the automaton. + */ + explicit ExtendedNFTA ( ); + + /** + * \brief Creates a new instance of the automaton with a concrete set of states, input alphabet, and a set of final states. + * + * \param states the initial set of states of the automaton + * \param inputAlphabet the initial input alphabet + * \param finalStates the initial set of final states of the automaton + */ + explicit ExtendedNFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType, RankType > > inputAlphabet, ext::set < StateType > finalStates ); + + /* + * \brief Creates a new instance of the automaton based on the Deterministic finite tree automaton. + * + * \param other the Deterministic finite tree automaton + */ + explicit ExtendedNFTA ( const DFTA < SymbolType, RankType, StateType > & other ); + + /* + * \brief Creates a new instance of the automaton based on the Nondeterministic finite tree automaton. + * + * \param other the Deterministic finite tree automaton + */ + explicit ExtendedNFTA ( const NFTA < SymbolType, RankType, StateType > & other ); + + /** + * Getter of states. + * + * \returns the states of the automaton + */ + const ext::set < StateType > & getStates ( ) const & { + return this->template accessComponent < States > ( ).get ( ); + } + + /** + * Getter of states. + * + * \returns the states of the automaton + */ + ext::set < StateType > && getStates ( ) && { + return std::move ( this->template accessComponent < States > ( ).get ( ) ); + } + + /** + * Adder of a state. + * + * \param state the new state to be added to a set of states + * + * \returns true if the state was indeed added + */ + bool addState ( StateType state ) { + return this->template accessComponent < States > ( ).add ( std::move ( state ) ); + } + + /** + * Setter of states. + * + * \param states completely new set of states + */ + void setStates ( ext::set < StateType > states ) { + this->template accessComponent < States > ( ).set ( std::move ( states ) ); + } + + /** + * Remover of a state. + * + * \param state a state to be removed from a set of states + * + * \returns true if the state was indeed removed + */ + void removeState ( const StateType & state ) { + this->template accessComponent < States > ( ).remove ( state ); + } + + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ + const ext::set < StateType > & getFinalStates ( ) const & { + return this->template accessComponent < FinalStates > ( ).get ( ); + } + + /** + * Getter of final states. + * + * \returns the final states of the automaton + */ + ext::set < StateType > && getFinalStates ( ) && { + return std::move ( this->template accessComponent < FinalStates > ( ).get ( ) ); + } + + /** + * Adder of a final state. + * + * \param state the new state to be added to a set of final states + * + * \returns true if the state was indeed added + */ + bool addFinalState ( StateType state ) { + return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) ); + } + + /** + * Setter of final states. + * + * \param states completely new set of final states + */ + void setFinalStates ( ext::set < StateType > states ) { + this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) ); + } + + /** + * Remover of a final state. + * + * \param state a state to be removed from a set of final states + * + * \returns true if the state was indeed removed + */ + void removeFinalState ( const StateType & state ) { + this->template accessComponent < FinalStates > ( ).remove ( state ); + } + + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ + const ext::set < common::ranked_symbol < SymbolType, RankType > > & getInputAlphabet ( ) const & { + return this->template accessComponent < InputAlphabet > ( ).get ( ); + } + + /** + * Getter of the input alphabet. + * + * \returns the input alphabet of the automaton + */ + ext::set < common::ranked_symbol < SymbolType, RankType > > && getInputAlphabet ( ) && { + return std::move ( this->template accessComponent < InputAlphabet > ( ).get ( ) ); + } + + /** + * Adder of a input symbol. + * + * \param symbol the new symbol to be added to an input alphabet + * + * \returns true if the symbol was indeed added + */ + bool addInputSymbol ( common::ranked_symbol < SymbolType, RankType > symbol ) { + return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) ); + } + + /** + * Adder of input symbols. + * + * \param symbols new symbols to be added to an input alphabet + */ + void addInputSymbols ( ext::set < common::ranked_symbol < SymbolType, RankType > > symbols ) { + this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) ); + } + + /** + * Setter of input alphabet. + * + * \param symbols completely new input alphabet + */ + void setInputAlphabet ( ext::set < common::ranked_symbol < SymbolType, RankType > > symbols ) { + this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) ); + } + + /** + * Remover of an input symbol. + * + * \param symbol a symbol to be removed from an input alphabet + * + * \returns true if the symbol was indeed removed + */ + void removeInputSymbol ( const common::ranked_symbol < SymbolType, RankType > & symbol ) { + this->template accessComponent < InputAlphabet > ( ).remove ( symbol ); + } + + /** + * \brief Add a transition to the automaton. + * + * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T + * + * \param children the source states (A, B, C, ...) + * \param current the input symbol (a) + * \param next the target state (B) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added + */ + bool addTransition ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > current, ext::vector < StateType >, StateType next ); + + /** + * \brief Add a transition to the automaton. + * + * \details The transition is in a form ( A, B, C, ... ) \times a -> P(Q), where A, B, C, ... \in Q and a \in T, P(Q) is a powerset of states + * + * \param children the source states (A, B, C, ...) + * \param current the input symbol (a) + * \param next the target states (P(Q)) + * + * \throws AutomatonException when transition contains state or symbol not present in the automaton components + * + * \returns true if the transition was indeed added + */ + void addTransitions ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > current, ext::vector < StateType >, ext::set < StateType > next ); + + /** + * \brief Removes a transition from the automaton. + * + * \details The transition is in a form ( A, B, C, ... ) \times a -> X, where A, B, C, ..., X \in Q and a \in T + * + * \param children the source states (A, B, C, ...) + * \param current the input symbol (a) + * \param next the target state (B) + * + * \returns true if the transition was indeed removed + */ + bool removeTransition ( const rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, const ext::vector < StateType > & prevStates, const StateType& next ); + + /** + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton + */ + const ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > & getTransitions ( ) const & { + return transitions; + } + + /** + * Get the transition function of the automaton in its natural form. + * + * \returns transition function of the automaton + */ + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > && getTransitions ( ) && { + return std::move ( transitions ); + } + + /** + * \returns the subset of transitions where the state @p q is a target state + */ + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > getTransitionsToState ( const StateType & q ) const; + + /** + * \returns the subset of transitions where the state @p q is a source state + */ + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > getTransitionsFromState ( const StateType & q ) const; + + /** + * \brief Determines whether the automaton is deterministic. + * + * the automaton is deterministic if and only if: + * \li \c size of transition function \delta (from states, input symbol) \leq 1 + * + * \return true if the automaton is deterministic, false otherwise + */ + bool isDeterministic ( ) const; + + /** + * \brief Computes number of transitions in the automaton + * + * \return number of transitions in the automaton + */ + unsigned transitionsSize ( ) const; + + /** + * The actual compare method + * + * \param other the other instance + * + * \returns the actual relation between two by type same automata instances + */ + int compare ( const ExtendedNFTA & other ) const; + + /** + * Print this object as raw representation to ostream. + * + * \param out ostream where to print + * \param instance object to print + * + * \returns modified output stream + */ + friend std::ostream & operator << ( std::ostream & out, const ExtendedNFTA & instance ) { + return out << "(ExtendedNFTA " + << " states = " << instance.getStates ( ) + << " inputAlphabet = " << instance.getInputAlphabet ( ) + << " finalStates = " << instance.getFinalStates ( ) + << " transitions = " << instance.getTransitions ( ) + << ")"; + } + + /** + * Casts this instance to as compact as possible string representation. + * + * \returns string representation of the object + */ + operator std::string ( ) const; +}; + +template < class SymbolType, class RankType, class StateType > +ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA ( ext::set < StateType > states, ext::set < common::ranked_symbol < SymbolType, RankType > > inputAlphabet, ext::set < StateType > finalStates ) : core::Components < ExtendedNFTA, ext::set < common::ranked_symbol < SymbolType, RankType > >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ) ) { +} + +template < class SymbolType, class RankType, class StateType > +ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA() : ExtendedNFTA ( ext::set < StateType > { }, ext::set < common::ranked_symbol < SymbolType, RankType > > { }, ext::set < StateType > { } ) { +} + +template < class SymbolType, class RankType, class StateType > +ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA(const DFTA < SymbolType, RankType, StateType > & other) : ExtendedNFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) { + for ( const auto & transition : other.getTransitions ( ) ) { + // ( symbol, prevStates ) -> nextState + // ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions; + + ext::ptr_vector < rte::FormalRTEElement < ext::variant < SymbolType, StateType >, RankType > > children; + for ( const StateType & state : transition.first.second ) + children.push_back ( rte::FormalRTESymbolSubst < ext::variant < SymbolType, StateType >, RankType > ( common::ranked_symbol < ext::variant < SymbolType, StateType > > ( state, 0 ) ) ); + + common::ranked_symbol < ext::variant < SymbolType, StateType >, RankType > symbol ( transition.first.first.getSymbol ( ), transition.first.first.getRank ( ) ); + rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte ( rte::FormalRTESymbolAlphabet < ext::variant < SymbolType, StateType >, RankType > ( symbol, children ) ); + transitions [ ext::make_pair ( rte, transition.first.second ) ].insert ( transition.second ); + } +} + +template < class SymbolType, class RankType, class StateType > +ExtendedNFTA < SymbolType, RankType, StateType >::ExtendedNFTA(const NFTA < SymbolType, RankType, StateType > & other) : ExtendedNFTA ( other.getStates(), other.getInputAlphabet(), other.getFinalStates() ) { + for ( const auto & transition : other.getTransitions ( ) ) { + // ( symbol, prevStates ) -> nextState + // ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > transitions; + + ext::ptr_vector < rte::FormalRTEElement < ext::variant < SymbolType, StateType >, RankType > > children; + for ( const StateType & state : transition.first.second ) + children.push_back ( rte::FormalRTESymbolSubst < ext::variant < SymbolType, StateType >, RankType > ( common::ranked_symbol < ext::variant < SymbolType, StateType > > ( state, 0 ) ) ); + + common::ranked_symbol < ext::variant < SymbolType, StateType >, RankType > symbol ( transition.first.first.getSymbol ( ), transition.first.first.getRank ( ) ); + rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte ( rte::FormalRTESymbolAlphabet < ext::variant < SymbolType, StateType >, RankType > ( symbol, children ) ); + transitions [ ext::make_pair ( rte, transition.first.second ) ].insert ( transition.second ); + } +} + +template < class SymbolType, class RankType, class StateType > +bool ExtendedNFTA < SymbolType, RankType, StateType >::addTransition ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, ext::vector < StateType > prevStates, StateType next ) { + /* + if (prevStates.size() != ( size_t ) symbol.getRank() ) + throw AutomatonException("Number of states doesn't match rank of the symbol"); + + if (! getInputAlphabet().count(symbol)) + throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist."); + */ + + if (! getStates().count(next)) + throw AutomatonException("State \"" + ext::to_string ( next ) + "\" doesn't exist."); + + for (const StateType& it : prevStates) { + if (! getStates().count(it)) + throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist."); + } + + ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( std::move ( rte ), std::move ( prevStates ) ); + return transitions [ std::move ( key ) ].insert ( std::move ( next ) ).second; +} + +template < class SymbolType, class RankType, class StateType > +void ExtendedNFTA < SymbolType, RankType, StateType >::addTransitions ( rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, ext::vector < StateType > prevStates, ext::set < StateType > next ) { + /* + if (prevStates.size() != ( size_t ) symbol.getRank() ) + throw AutomatonException("Number of states doesn't match rank of the symbol"); + + if (! getInputAlphabet().count(symbol)) + throw AutomatonException("Input symbol \"" + ext::to_string ( symbol ) + "\" doesn't exist."); + */ + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), next.begin ( ), next.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + for (const StateType& it : prevStates) { + if (! getStates().count(it)) + throw AutomatonException("State \"" + ext::to_string ( it ) + "\" doesn't exist."); + } + + ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( std::move ( rte ), std::move ( prevStates ) ); + transitions [ std::move ( key ) ].insert ( ext::make_mover ( next ).begin ( ), ext::make_mover ( next ).end ( ) ); +} + +template < class SymbolType, class RankType, class StateType > +bool ExtendedNFTA < SymbolType, RankType, StateType >::removeTransition ( const rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte, const ext::vector < StateType > & prevStates, const StateType& next ) { + ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > > key = ext::make_pair ( rte, prevStates ); + return transitions [ key ].erase ( next ); +} + +template < class SymbolType, class RankType, class StateType > +bool ExtendedNFTA < SymbolType, RankType, StateType >::isDeterministic() const { + return false; +} + + +template < class SymbolType, class RankType, class StateType > +unsigned ExtendedNFTA < SymbolType, RankType, StateType >::transitionsSize() const { + int res = 0; + + for(const auto& transition : transitions ) + res += transition.second.size(); + + return res; +} + +template<class SymbolType, class RankType, class StateType > +ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > ExtendedNFTA < SymbolType, RankType, StateType >::getTransitionsToState ( const StateType & to ) const { + if ( !getStates ( ).count ( to ) ) + throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist" ); + + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, StateType > res; + + for ( const auto & transition : transitions ) + if ( transition.second.count ( to ) > 0 ) + res.insert ( ext::make_pair ( transition.first, to ) ); + + return res; +} + +template<class SymbolType, class RankType, class StateType > +ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > ExtendedNFTA < SymbolType, RankType, StateType >::getTransitionsFromState ( const StateType & from ) const { + if ( !getStates ( ).count ( from ) ) + throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" ); + + ext::map < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > res; + + for ( const auto & transition : transitions ) + if ( std::find ( transition.first.second.begin ( ), transition.first.second.end ( ), from ) != transition.first.second.end ( ) ) + res.insert ( transition ); + + return res; +} + + +template < class SymbolType, class RankType, class StateType > +int ExtendedNFTA < SymbolType, RankType, StateType >::compare(const ExtendedNFTA& other) const { + auto first = ext::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions); + auto second = ext::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions); + + static ext::compare<decltype(first)> comp; + return comp(first, second); +} + +template < class SymbolType, class RankType, class StateType > +ExtendedNFTA < SymbolType, RankType, StateType >::operator std::string ( ) const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ + +namespace core { + +/** + * Helper class specifying constraints for the automaton's internal input alphabet component. + * + * \tparam SymbolType used for the symbol part of the ranked symbol + * \tparam RankType used for the rank part of the ranked symbol + * \tparam StateType used for the terminal alphabet of the automaton. + */ +template < class SymbolType, class RankType, class StateType > +class SetConstraint< automaton::ExtendedNFTA < SymbolType, RankType, StateType >, common::ranked_symbol < SymbolType, RankType >, automaton::InputAlphabet > { +public: + /** + * Returns true if the symbol is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true if the symbol is used, false othervise + */ + static bool used ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > & automaton, const common::ranked_symbol < SymbolType, RankType > & symbol ) { + for ( const std::pair<const ext::pair<common::ranked_symbol < SymbolType, RankType >, ext::vector<StateType> >, ext::set<StateType>>& t : automaton.getTransitions()) + if (t.first.first == symbol) + return true; + + return false; + } + + /** + * Returns true as all symbols are possibly available to be elements of the input alphabet. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + * + * \returns true + */ + static bool available ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const common::ranked_symbol < SymbolType, RankType > & ) { + return true; + } + + /** + * All symbols are valid as input symbols. + * + * \param automaton the tested automaton + * \param symbol the tested symbol + */ + static void valid ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const common::ranked_symbol < SymbolType, RankType > & ) { + } +}; + +/** + * Helper class specifying constraints for the automaton's internal states component. + * + * \tparam SymbolType used for the symbol part of the ranked symbol + * \tparam RankType used for the rank part of the ranked symbol + * \tparam StateType used for the terminal alphabet of the automaton. + */ +template < class SymbolType, class RankType, class StateType > +class SetConstraint< automaton::ExtendedNFTA < SymbolType, RankType, StateType >, StateType, automaton::States > { +public: + /** + * Returns true if the state is still used in some transition of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is used, false othervise + */ + static bool used ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) { + if ( automaton.getFinalStates ( ).count ( state ) ) + return true; + + for ( const std::pair<const ext::pair<rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector<StateType> >, ext::set<StateType>>& t : automaton.getTransitions()) + if(ext::contains(t.first.second.begin(), t.first.second.end(), state ) || t . second.count ( state ) ) + return true; + + return false; + } + + /** + * Returns true as all states are possibly available to be elements of the states. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true + */ + static bool available ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const StateType & ) { + return true; + } + + /** + * All states are valid as a state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ + static void valid ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const StateType & ) { + } +}; + +/** + * Helper class specifying constraints for the automaton's internal final states component. + * + * \tparam SymbolType used for the symbol part of the ranked symbol + * \tparam RankType used for the rank part of the ranked symbol + * \tparam StateType used for the terminal alphabet of the automaton. + */ +template < class SymbolType, class RankType, class StateType > +class SetConstraint< automaton::ExtendedNFTA < SymbolType, RankType, StateType >, StateType, automaton::FinalStates > { +public: + /** + * Returns false. Final state is only a mark that the automaton itself does require further. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns false + */ + static bool used ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const StateType & ) { + return false; + } + + /** + * Determines whether the state is available in the automaton's states set. + * + * \param automaton the tested automaton + * \param state the tested state + * + * \returns true if the state is already in the set of states of the automaton + */ + static bool available ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > & automaton, const StateType & state ) { + return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state ); + } + + /** + * All states are valid as a final state of the automaton. + * + * \param automaton the tested automaton + * \param state the tested state + */ + static void valid ( const automaton::ExtendedNFTA < SymbolType, RankType, StateType > &, const StateType & ) { + } +}; + +/** + * Helper for normalisation of types specified by templates used as internal datatypes of symbols and states. + * + * \returns new instance of the automaton with default template parameters or unmodified instance if the template parameters were already the default ones + */ +template < class SymbolType, class RankType, class StateType > +struct normalize < automaton::ExtendedNFTA < SymbolType, RankType, StateType > > { + static automaton::ExtendedNFTA < > eval ( automaton::ExtendedNFTA < SymbolType, RankType, StateType > && value ) { + ext::set < common::ranked_symbol < > > alphabet = alphabet::SymbolNormalize::normalizeRankedAlphabet ( std::move ( value ).getInputAlphabet ( ) ); + ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) ); + ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) ); + + automaton::ExtendedNFTA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( finalStates ) ); + + for ( std::pair < ext::pair < rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType >, ext::vector < StateType > >, ext::set < StateType > > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) { + rte::FormalRTEStructure < ext::variant < SymbolType, StateType >, RankType > rte = transition.first.first; // TODO alphabet::SymbolNormalize::normalizeRankedSymbol ( std::move ( transition.first.first ) ); + ext::vector < DefaultStateType > from = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.first.second ) ); + ext::set < DefaultStateType > to = automaton::AutomatonNormalize::normalizeStates ( std::move ( transition.second ) ); + + res.addTransitions ( std::move ( rte ), std::move ( from ), std::move ( to ) ); + } + + return res; + } +}; + +} /* namespace core */ + +#endif /* EXTENDED_NFTA_H_ */ -- GitLab