From 9cd08197ed84ec72dacb528cad16e77170913410 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sat, 12 Oct 2019 20:52:35 +0200 Subject: [PATCH] construction algos for some AAG automata --- .../generate/NumberModuloAutomaton.cpp | 59 +++++++++++ .../generate/NumberModuloAutomaton.h | 52 ++++++++++ .../generate/NumberOfSymbolsAutomaton.cpp | 65 ++++++++++++ .../generate/NumberOfSymbolsAutomaton.h | 98 +++++++++++++++++++ 4 files changed, 274 insertions(+) create mode 100644 alib2algo/src/automaton/generate/NumberModuloAutomaton.cpp create mode 100644 alib2algo/src/automaton/generate/NumberModuloAutomaton.h create mode 100644 alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.cpp create mode 100644 alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.h diff --git a/alib2algo/src/automaton/generate/NumberModuloAutomaton.cpp b/alib2algo/src/automaton/generate/NumberModuloAutomaton.cpp new file mode 100644 index 0000000000..d909be6110 --- /dev/null +++ b/alib2algo/src/automaton/generate/NumberModuloAutomaton.cpp @@ -0,0 +1,59 @@ +/* + * NumberModuloAutomaton.cpp + * + * Created on: 9. 2. 2017 + * Author: Jan Travnicek + */ + +#include "NumberModuloAutomaton.h" +#include <exception/CommonException.h> +#include <registration/AlgoRegistration.hpp> + +namespace automaton::generate { + +automaton::DFA < std::string, unsigned > NumberModuloAutomaton::generate ( unsigned base, unsigned modulo, unsigned result_modulo ) { + if ( modulo == 0 ) + throw exception::CommonException ( "Modulo is zero." ); + + if ( base > 36 ) + throw exception::CommonException ( "Number base " + ext::to_string ( base ) + " not handled." ); + + if ( result_modulo >= modulo ) + throw exception::CommonException ( "Result modulo bigger than modulo limit." ); + + std::vector < std::string > base_map; + for ( unsigned i = 0; i < std::min ( 10u, base ); ++ i ) + base_map.push_back ( ext::to_string ( i ) ); + + for ( unsigned i = 10; i < base; ++ i ) + base_map.push_back ( std::string ( 'A' + i, 1 ) ); + + automaton::DFA < std::string, unsigned > res ( 0 ); + + for ( const std::string & input : base_map ) + res.addInputSymbol ( input ); + + for ( unsigned modulo_state = 0; modulo_state < modulo; ++ modulo_state ) + res.addState ( modulo_state ); + + for ( unsigned modulo_state = 0; modulo_state < modulo; ++ modulo_state ) + for ( unsigned input = 0; input < base; ++ input ) + res.addTransition ( modulo_state, base_map.at ( input ), ( modulo_state * base + input ) % modulo ); + + res.addFinalState ( result_modulo ); + + return res; +} + +} /* automaton::generate */ + +namespace { + +auto NumberModuloAutomatonDFA = registration::AbstractRegister < automaton::generate::NumberModuloAutomaton, automaton::DFA < std::string, unsigned >, unsigned, unsigned, unsigned > ( automaton::generate::NumberModuloAutomaton::generate, "base", "modulo", "result_modulo" ).setDocumentation ( +"Generates an automaton recognising numbers in given base that have modulo equal to a concrete value.\n\ +\n\ +@param base the base of read number\n\ +@param modulo the requested modulo\n\ +@param result_modulo the final modulo" ); + +} /* namespace */ diff --git a/alib2algo/src/automaton/generate/NumberModuloAutomaton.h b/alib2algo/src/automaton/generate/NumberModuloAutomaton.h new file mode 100644 index 0000000000..0bb8140208 --- /dev/null +++ b/alib2algo/src/automaton/generate/NumberModuloAutomaton.h @@ -0,0 +1,52 @@ +/* + * NumberModuloAutomaton.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: 9. 2. 2017 + * Author: Jan Travnicek + */ + +#ifndef NUMBER_MODULO_AUTOMATON_H_ +#define NUMBER_MODULO_AUTOMATON_H_ + +#include <automaton/FSM/DFA.h> + +namespace automaton { + +namespace generate { + +/** + * Algorithm to generate an automaton recognising numbers in given base that have modulo equal to a concrete value. + */ +class NumberModuloAutomaton { +public: + /** + * Generates an automaton recognising numbers in given base that have modulo equal to a concrete value. + * + * @param base the base of read number + * @param modulo the requested modulo + * @param result_modulo the final modulo + */ + static automaton::DFA < std::string, unsigned > generate ( unsigned base, unsigned modulo, unsigned result_modulo ); +}; + +} /* namespace generate */ + +} /* namespace automaton */ + +#endif /* NUMBER_MODULO_AUTOMATON_H_ */ diff --git a/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.cpp b/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.cpp new file mode 100644 index 0000000000..a2d28f0b54 --- /dev/null +++ b/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.cpp @@ -0,0 +1,65 @@ +/* + * NumberOfSymbolsAutomaton.cpp + * + * Created on: 27. 3. 2014 + * Author: Tomas Pecka + */ + +#include "NumberOfSymbolsAutomaton.h" +#include <registration/AlgoRegistration.hpp> + +#include <alib/deque> +#include <alib/algorithm> +#include <alib/random> + +namespace automaton::generate { + +automaton::NFA < std::string, unsigned > NumberOfSymbolsAutomaton::generateNFA ( size_t modulo, size_t alphabetSize, bool randomizedAlphabet, char symbol, size_t final_modulo ) { + if ( alphabetSize > 26 ) + throw exception::CommonException("Too big alphabet."); + + if ( alphabetSize < 1 ) + throw exception::CommonException("Too small alphabet."); + + if ( symbol < 'a' || symbol > 'z' ) + throw exception::CommonException("Invalid symbol " + ext::to_string ( symbol ) + "."); + + ext::deque < std::string > alphabet; + alphabet.push_back ( std::string ( 1, symbol ) ); + + for ( char i = 'a'; i <= 'z'; ++ i ) + if ( i != symbol ) + alphabet.push_back ( std::string ( 1, i ) ); + + if ( randomizedAlphabet ) + shuffle ( std::next ( alphabet.begin ( ) ), alphabet.end ( ), ext::random_devices::semirandom ); + + alphabet.resize ( alphabetSize ); + + return automaton::generate::NumberOfSymbolsAutomaton::generateNFA ( modulo, ext::set < std::string > ( alphabet.begin ( ), alphabet.end ( ) ), std::string ( 1, symbol ), final_modulo ); +} + +} /* namespace automaton::generate */ + +namespace { + +auto GenerateNFA1 = registration::AbstractRegister < automaton::generate::NumberOfSymbolsAutomaton, automaton::NFA < DefaultSymbolType, unsigned >, size_t, const ext::set < DefaultSymbolType > &, DefaultSymbolType, size_t > ( automaton::generate::NumberOfSymbolsAutomaton::generateNFA, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "modulo", "alphabet", "symbol", "final_modulo" ).setDocumentation ( +"Generates automaton accepting strings over alphabet where the number of symbol given by @p symbol is modulo @p modulo equal to @p final_modulo.\n\ +\n\ +@param modulo number of symbols to modulo by\n\ +@param alphabet Input alphabet of the automaton\n\ +@param symbol the counted symbol\n\ +@param final_modulo number of symbols to recognise mod modulo\n\ +@return random nondeterministic finite automaton" ); + +auto GenerateNFA2 = registration::AbstractRegister < automaton::generate::NumberOfSymbolsAutomaton, automaton::NFA < std::string, unsigned >, size_t, size_t, bool, char, size_t > ( automaton::generate::NumberOfSymbolsAutomaton::generateNFA, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "statesCount", "alphabetSize", "randomizedAlphabet", "symbol", "final_modulo" ).setDocumentation ( +"Generates automaton accepting strings over alphabet where the number of symbol given by @p symbol is modulo @p modulo equal to @p final_modulo.\n\ +\n\ +@param modulo number of symbols to modulo by\n\ +@param alphabetSize size of the alphabet (1-26)\n\ +@param randomizedAlphabet selects random symbols from a-z range if true\n\ +@param symbol the counted symbol\n\ +@param final_modulo number of symbols to recognise mod modulo\n\ +@return random nondeterministic finite automaton" ); + +} /* namespace */ diff --git a/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.h b/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.h new file mode 100644 index 0000000000..23c0c95f78 --- /dev/null +++ b/alib2algo/src/automaton/generate/NumberOfSymbolsAutomaton.h @@ -0,0 +1,98 @@ +/* + * NumberOfSymbolsAutomaton.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: 27. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef RANDOM_AUTOMATON_FACTORY_H_ +#define RANDOM_AUTOMATON_FACTORY_H_ + +#include <alib/set> +#include <alib/string> + +#include <exception/CommonException.h> + +#include <automaton/FSM/NFA.h> + +namespace automaton::generate { + +/** + * Algorithm NFA accepting strings with given number of symbols A modulo N. + */ +class NumberOfSymbolsAutomaton { +public: + /** + * Generates automaton accepting strings over alphabet where the number of symbol given by @p symbol is modulo @p modulo equal to @p final_modulo. + * @tparam SymbolType the type of terminal symbols of the random automaton + * + * @param modulo number of symbols to modulo by + * @param alphabet Input alphabet of the automaton + * @param symbol the counted symbol + * @param final_modulo number of symbols to recognise mod modulo + * + * @return nondeterministic finite automaton + */ + template < class SymbolType > + static automaton::NFA < SymbolType, unsigned > generateNFA ( size_t modulo, const ext::set < SymbolType > & alphabet, SymbolType symbol, size_t final_modulo ); + + /** + * \overload + * + * Generates automaton accepting strings over alphabet where the number of symbol given by @p symbol is modulo @p modulo equal to @p final_modulo. + * + * @param modulo number of symbols to modulo by + * @param alphabetSize size of the alphabet (1-26) + * @param randomizedAlphabet selects random symbols from a-z range if true + * @param symbol the counted symbol + * @param final_modulo number of symbols to recognise mod modulo + * + * @return nondeterministic finite automaton + */ + static automaton::NFA < std::string, unsigned > generateNFA ( size_t modulo, size_t alphabetSize, bool randomizedAlphabet, char symbol, size_t final_modulo ); +}; + +template < class SymbolType > +automaton::NFA < SymbolType, unsigned > NumberOfSymbolsAutomaton::generateNFA ( size_t modulo, const ext::set < SymbolType > & alphabet, SymbolType symbol, size_t final_modulo ) { + if ( ! alphabet.contains ( symbol ) ) + throw exception::CommonException ( "Symbol is not in the alphabet." ); + + automaton::NFA < SymbolType, unsigned > automaton ( 0 ); + + automaton.setInputAlphabet ( alphabet ); + + for ( size_t i = 1; i < modulo; ++ i ) + automaton.addState ( i ); + + for ( size_t i = 0; i < modulo; ++ i ) + automaton.addTransition ( i, symbol, ( i + 1 ) % modulo ); + + for ( size_t i = 0; i < modulo; ++ i ) + for ( const SymbolType & alphabet_symbol : alphabet ) + if ( alphabet_symbol != symbol ) + automaton.addTransition ( i, alphabet_symbol, i ); + + automaton.addFinalState ( final_modulo ); + + return automaton; +} + +} /* namespace automaton::generate */ + +#endif /* RANDOM_AUTOMATON_FACTORY_H_ */ -- GitLab