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