From aeb1d52de10d02d17736851353d67c4d46967897 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 13 Oct 2014 21:01:20 +0200 Subject: [PATCH] implementation of trivial conversions of FSMs --- .../fa2re/formal/StateEliminationFormal.cpp | 2 +- alib2data/src/automaton/FSM/CompactNFA.cpp | 52 +++++++++++++++ alib2data/src/automaton/FSM/CompactNFA.h | 4 ++ alib2data/src/automaton/FSM/EpsilonNFA.cpp | 37 +++++++++++ alib2data/src/automaton/FSM/EpsilonNFA.h | 3 + alib2data/src/automaton/FSM/ExtendedNFA.cpp | 64 +++++++++++++++++++ alib2data/src/automaton/FSM/ExtendedNFA.h | 5 ++ .../automaton/FSM/MultiInitialStateNFA.cpp | 26 ++++++++ .../src/automaton/FSM/MultiInitialStateNFA.h | 4 ++ alib2data/src/automaton/FSM/NFA.cpp | 10 +++ alib2data/src/automaton/FSM/NFA.h | 1 + alib2data/src/regexp/RegExp.cpp | 41 ++++++++++++ alib2data/src/regexp/RegExp.h | 11 ++++ alib2data/src/string/String.cpp | 23 +++++++ alib2data/src/string/String.h | 4 ++ 15 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 alib2data/src/regexp/RegExp.cpp create mode 100644 alib2data/src/string/String.cpp diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp index c872dd3bdf..ea5d6d9e74 100644 --- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp +++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp @@ -205,7 +205,7 @@ const regexp::FormalRegExpElement* StateEliminationFormal::transition(const auto return ret; } -//TODO prepsat jako konstruktory v alib2data +//TODO pouzit konstruktory v alib2data template<> automaton::ExtendedNFA StateEliminationFormal::constructExtendedNFA(const automaton::MultiInitialStateNFA& automaton) { diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp index 2a211f329c..14a1d3b804 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.cpp +++ b/alib2data/src/automaton/FSM/CompactNFA.cpp @@ -6,6 +6,11 @@ */ #include "CompactNFA.h" +#include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" +#include "../Automaton.h" #include "../../std/map.hpp" #include "../AutomatonException.h" #include "../../string/StringAlphabetGetter.h" @@ -19,6 +24,53 @@ CompactNFA::CompactNFA(const State& initialState) : SingleInitialState(initialSt } +CompactNFA::CompactNFA(const EpsilonNFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + if(transition.first.second.is<string::Epsilon>()) { + std::pair<State, string::LinearString> key = std::make_pair(transition.first.first, string::LinearString( std::vector<alphabet::Symbol> { } )); + transitions[key] = transition.second; + } else { + std::pair<State, string::LinearString> key = std::make_pair(transition.first.first, string::LinearString( std::vector<alphabet::Symbol> { transition.first.second.get<alphabet::Symbol>() } )); + transitions[key] = transition.second; + } + } +} + +CompactNFA::CompactNFA(const MultiInitialStateNFA& other) : SingleInitialState(automaton::createUniqueState(automaton::State("q0"), other.getStates())) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, string::LinearString> key = std::make_pair(transition.first.first, string::LinearString( std::vector<alphabet::Symbol> { transition.first.second} )); + transitions[key] = transition.second; + } + std::pair<State, string::LinearString> key = std::make_pair(this->getInitialState(), string::LinearString(std::vector<alphabet::Symbol> {})); + transitions[key] = other.getInitialStates(); +} + +CompactNFA::CompactNFA(const NFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, string::LinearString> key = std::make_pair(transition.first.first, string::LinearString( std::vector<alphabet::Symbol> { transition.first.second} )); + transitions[key] = transition.second; + } +} + +CompactNFA::CompactNFA(const DFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, string::LinearString> key = std::make_pair(transition.first.first, string::LinearString( std::vector<alphabet::Symbol> { transition.first.second} )); + transitions[key].insert(transition.second); + } +} + AutomatonBase* CompactNFA::clone() const { return new CompactNFA(*this); } diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h index 9a5cf0947c..97941daacb 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.h +++ b/alib2data/src/automaton/FSM/CompactNFA.h @@ -25,6 +25,10 @@ protected: std::map<std::pair<State, string::LinearString>, std::set<State> > transitions; public: explicit CompactNFA(const State& initialState); + explicit CompactNFA(const EpsilonNFA& other); + explicit CompactNFA(const MultiInitialStateNFA& other); + explicit CompactNFA(const NFA& other); + explicit CompactNFA(const DFA& other); virtual AutomatonBase* clone() const; diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp index c953b7a25f..1eb93f9649 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp +++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp @@ -6,8 +6,12 @@ */ #include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" #include "../../std/map.hpp" #include "../AutomatonException.h" +#include "../Automaton.h" #include <ostream> #include <sstream> @@ -17,6 +21,39 @@ EpsilonNFA::EpsilonNFA(const State& initialState) : SingleInitialState(initialSt } +EpsilonNFA::EpsilonNFA(const MultiInitialStateNFA& other) : SingleInitialState(automaton::createUniqueState(automaton::State("q0"), other.getStates())) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> > key = std::make_pair(transition.first.first, std::variant<string::Epsilon, alphabet::Symbol>(transition.first.second)); + transitions[key] = transition.second; + } + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> > key = std::make_pair(this->getInitialState(), std::variant<string::Epsilon, alphabet::Symbol>(string::Epsilon::EPSILON)); + transitions[key] = other.getInitialStates(); + +} + +EpsilonNFA::EpsilonNFA(const NFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> > key = std::make_pair(transition.first.first, std::variant<string::Epsilon, alphabet::Symbol>(transition.first.second)); + transitions[key] = transition.second; + } +} + +EpsilonNFA::EpsilonNFA(const DFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> > key = std::make_pair(transition.first.first, std::variant<string::Epsilon, alphabet::Symbol>(transition.first.second)); + transitions[key].insert(transition.second); + } +} + AutomatonBase* EpsilonNFA::clone() const { return new EpsilonNFA(*this); } diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h index 6e829caeee..ad4f323aa8 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.h +++ b/alib2data/src/automaton/FSM/EpsilonNFA.h @@ -27,6 +27,9 @@ protected: std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> >, std::set<State> > transitions; public: explicit EpsilonNFA(const State& initialState); + explicit EpsilonNFA(const MultiInitialStateNFA& other); + explicit EpsilonNFA(const NFA& other); + explicit EpsilonNFA(const DFA& other); virtual AutomatonBase* clone() const; diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp index 97b9a670c3..bbbc018197 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp +++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp @@ -6,8 +6,15 @@ */ #include "ExtendedNFA.h" +#include "CompactNFA.h" +#include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" #include "../../std/map.hpp" #include "../AutomatonException.h" +#include "../Automaton.h" +#include "../../regexp/RegExp.h" #include <ostream> #include <algorithm> #include "../../regexp/RegExpAlphabetGetter.h" @@ -19,6 +26,63 @@ ExtendedNFA::ExtendedNFA(const State& initialState) : SingleInitialState(initial } +ExtendedNFA::ExtendedNFA(const CompactNFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( transition.first.second ))); + transitions[key] = transition.second; + } +} + +ExtendedNFA::ExtendedNFA(const EpsilonNFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + if(transition.first.second.is<string::Epsilon>()) { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( string::LinearString( std::vector<alphabet::Symbol> { } ) ))); + transitions[key] = transition.second; + } else { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( transition.first.second.get<alphabet::Symbol>() ))); + transitions[key] = transition.second; + } + } +} + +ExtendedNFA::ExtendedNFA(const MultiInitialStateNFA& other) : SingleInitialState(automaton::createUniqueState(automaton::State("q0"), other.getStates())) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( transition.first.second ))); + transitions[key] = transition.second; + } + std::pair<State, regexp::RegExp> key = std::make_pair(this->getInitialState(), regexp::RegExp( regexp::regexpFrom ( string::LinearString(std::vector<alphabet::Symbol> {}) ))); + transitions[key] = other.getInitialStates(); +} + +ExtendedNFA::ExtendedNFA(const NFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( transition.first.second ))); + transitions[key] = transition.second; + } +} + +ExtendedNFA::ExtendedNFA(const DFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + std::pair<State, regexp::RegExp> key = std::make_pair(transition.first.first, regexp::RegExp( regexp::regexpFrom ( transition.first.second ))); + transitions[key].insert(transition.second); + } +} + AutomatonBase* ExtendedNFA::clone() const { return new ExtendedNFA(*this); } diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h index 0fdb6a5ceb..54db04aca6 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.h +++ b/alib2data/src/automaton/FSM/ExtendedNFA.h @@ -25,6 +25,11 @@ protected: std::map<std::pair<State, regexp::RegExp>, std::set<State> > transitions; public: explicit ExtendedNFA(const State& initialState); + explicit ExtendedNFA(const CompactNFA& other); + explicit ExtendedNFA(const EpsilonNFA& other); + explicit ExtendedNFA(const MultiInitialStateNFA& other); + explicit ExtendedNFA(const NFA& other); + explicit ExtendedNFA(const DFA& other); virtual AutomatonBase* clone() const; diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp index f134720688..40cf2cd0fa 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp @@ -6,12 +6,38 @@ */ #include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" #include "../AutomatonException.h" #include <ostream> #include <sstream> namespace automaton { +MultiInitialStateNFA::MultiInitialStateNFA() { + +} + +MultiInitialStateNFA::MultiInitialStateNFA(const DFA& other) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + initialStates = {other.getInitialState()}; + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + transitions[transition.first].insert(transition.second); + } +} + +MultiInitialStateNFA::MultiInitialStateNFA(const NFA& other) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + initialStates = {other.getInitialState()}; + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + transitions[transition.first] = transition.second; + } +} + AutomatonBase* MultiInitialStateNFA::clone() const { return new MultiInitialStateNFA(*this); } diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h index 691134e084..830f166f36 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h @@ -25,6 +25,10 @@ class MultiInitialStateNFA : public std::acceptor<MultiInitialStateNFA, Visitabl protected: std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitions; public: + explicit MultiInitialStateNFA(); + explicit MultiInitialStateNFA(const NFA& other); + explicit MultiInitialStateNFA(const DFA& other); + virtual AutomatonBase* clone() const; virtual AutomatonBase* plunder() &&; diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp index 97e68dfa94..f5ca944190 100644 --- a/alib2data/src/automaton/FSM/NFA.cpp +++ b/alib2data/src/automaton/FSM/NFA.cpp @@ -6,6 +6,7 @@ */ #include "NFA.h" +#include "DFA.h" #include "../AutomatonException.h" #include <ostream> #include <sstream> @@ -16,6 +17,15 @@ NFA::NFA(const State& initialState) : SingleInitialState(initialState) { } +NFA::NFA(const DFA& other) : SingleInitialState(other.getInitialState()) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + transitions[transition.first].insert(transition.second); + } +} + AutomatonBase* NFA::clone() const { return new NFA(*this); } diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h index 3dd0a87389..24af23d31d 100644 --- a/alib2data/src/automaton/FSM/NFA.h +++ b/alib2data/src/automaton/FSM/NFA.h @@ -26,6 +26,7 @@ protected: std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitions; public: explicit NFA(const State& initialState); + explicit NFA(const DFA& other); virtual AutomatonBase* clone() const; diff --git a/alib2data/src/regexp/RegExp.cpp b/alib2data/src/regexp/RegExp.cpp new file mode 100644 index 0000000000..fde75f2fa7 --- /dev/null +++ b/alib2data/src/regexp/RegExp.cpp @@ -0,0 +1,41 @@ +/* + * RegExp.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "RegExp.h" +#include "../alphabet/Symbol.h" +#include "unbounded/UnboundedRegExpSymbol.h" +#include "unbounded/UnboundedRegExpEmpty.h" +#include "unbounded/UnboundedRegExpConcatenation.h" + +namespace regexp { + +regexp::RegExp regexpFrom( const std::string& string ) { + regexp::UnboundedRegExpConcatenation con; + for(const auto& symbol : string) { + con.appendElement( regexp::UnboundedRegExpSymbol( alphabet::symbolFrom(symbol))); + } + return regexp::RegExp { regexp::UnboundedRegExp ( con ) }; +} + +regexp::RegExp regexpFrom( const string::LinearString& string ) { + regexp::UnboundedRegExpConcatenation con; + for(const auto& symbol : string.getContent()) { + con.appendElement( regexp::UnboundedRegExpSymbol(symbol)); + } + return regexp::RegExp { regexp::UnboundedRegExp ( con ) }; +} + +regexp::RegExp regexpFrom( const alphabet::Symbol& symbol ) { + return regexp::RegExp { regexp::UnboundedRegExp( regexp::UnboundedRegExpSymbol(symbol) ) }; +} + +regexp::RegExp regexpFrom( ) { + return regexp::RegExp { regexp::UnboundedRegExp( regexp::UnboundedRegExpEmpty { } ) }; +} + +} /* namespace regexp */ + diff --git a/alib2data/src/regexp/RegExp.h b/alib2data/src/regexp/RegExp.h index b42a3f670f..0446ca02ea 100644 --- a/alib2data/src/regexp/RegExp.h +++ b/alib2data/src/regexp/RegExp.h @@ -11,6 +11,9 @@ #include "../std/visitor.hpp" #include "../common/wrapper.hpp" #include "RegExpBase.h" +#include "../alphabet/Symbol.h" +#include "../string/LinearString.h" +#include <string> namespace regexp { @@ -19,6 +22,14 @@ namespace regexp { */ typedef alib::wrapper<RegExpBase> RegExp; +regexp::RegExp regexpFrom( const std::string& string ); + +regexp::RegExp regexpFrom( const string::LinearString& string ); + +regexp::RegExp regexpFrom( const alphabet::Symbol& symbol ); + +regexp::RegExp regexpFrom( ); + } /* namespace regexp */ #endif /* REG_EXP_H_ */ diff --git a/alib2data/src/string/String.cpp b/alib2data/src/string/String.cpp new file mode 100644 index 0000000000..8fc68125b5 --- /dev/null +++ b/alib2data/src/string/String.cpp @@ -0,0 +1,23 @@ +/* + * String.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "String.h" +#include "LinearString.h" +#include "../exception/AlibException.h" + +namespace string { + +string::String symbolFrom( const alphabet::Symbol& symbol ) { + return string::String { string::LinearString { std::vector<alphabet::Symbol> { symbol } } }; +} + +string::String symbolFrom( const std::string& string ) { + return string::String { string::LinearString { string } }; +} + +} /* namespace string */ + diff --git a/alib2data/src/string/String.h b/alib2data/src/string/String.h index 9da127df94..617cf4d04d 100644 --- a/alib2data/src/string/String.h +++ b/alib2data/src/string/String.h @@ -11,6 +11,7 @@ #include "../std/visitor.hpp" #include "../common/wrapper.hpp" #include "StringBase.h" +#include "../alphabet/Symbol.h" namespace string { @@ -19,6 +20,9 @@ namespace string { */ typedef alib::wrapper<StringBase> String; +string::String stringFrom(const alphabet::Symbol& symbol); +string::String stringFrom(const std::string& str); + } /* namespace string */ #endif /* STRING_H_ */ -- GitLab