diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp index 04e8ff6dbd3da113ef1cd23d7d563eacb6a266a2..fa4705494c0a9c1c1284a4003f4bad6a9d38c544 100644 --- a/aconvert2/src/DotConverter.cpp +++ b/aconvert2/src/DotConverter.cpp @@ -15,6 +15,8 @@ #include <automaton/FSM/CompactNFA.h> #include <automaton/PDA/NPDA.h> #include <automaton/PDA/SinglePopNPDA.h> +#include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/PDA/VisiblyPushdownNPDA.h> #include <automaton/PDA/DPDA.h> #include <automaton/PDA/SinglePopDPDA.h> #include <automaton/TM/OneTapeDTM.h> @@ -280,6 +282,76 @@ void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) out << "}"; } +void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& out) { + label::LabelToStringComposer composer; + + out << "digraph automaton {\n"; + out << "rankdir=LR;\n"; + int cnt = 1; + + //Map states to indices + std::map<automaton::State, int> states; + for (const automaton::State& state : a.getStates()) { + states.insert(std::make_pair(state, cnt++)); + } + + //Print final states + for (const automaton::State& state : a.getFinalStates()) { + out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + } + + //Print nonfinal states + for (const auto& state : states) { + if (!a.getFinalStates().count(state.first)) { + out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + } + } + + //Mark initial states + out << "node [shape = plaintext, label=\"start\"]; 0; \n"; + for (const automaton::State state : a.getInitialStates()) { + out << "0 -> " << states.find(state)->second << ";\n"; + } + + transitions(a, states, out); + out << "}"; +} + +void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out) { + label::LabelToStringComposer composer; + + out << "digraph automaton {\n"; + out << "rankdir=LR;\n"; + int cnt = 1; + + //Map states to indices + std::map<automaton::State, int> states; + for (const automaton::State& state : a.getStates()) { + states.insert(std::make_pair(state, cnt++)); + } + + //Print final states + for (const automaton::State& state : a.getFinalStates()) { + out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + } + + //Print nonfinal states + for (const auto& state : states) { + if (!a.getFinalStates().count(state.first)) { + out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + } + } + + //Mark initial states + out << "node [shape = plaintext, label=\"start\"]; 0; \n"; + for (const automaton::State state : a.getInitialStates()) { + out << "0 -> " << states.find(state)->second << ";\n"; + } + + transitions(a, states, out); + out << "}"; +} + void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) { label::LabelToStringComposer composer; @@ -630,6 +702,161 @@ void DotConverter::transitions(const automaton::SinglePopDPDA& pda, const std::m } } +void DotConverter::transitions(const automaton::InputDrivenNPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) { + std::map<std::pair<int, int>, std::string> transitions; + + const auto& symbolToPDSOperation = pda.getPushdownStoreOperations(); + for (const auto& transition : pda.getTransitions()) { + const auto& pop = symbolToPDSOperation.find(transition.first.second)->second.first; + const auto& push = symbolToPDSOperation.find(transition.first.second)->second.second; + + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + symbol = composer.compose(transition.first.second); + + symbol += " |"; + + //Pop part + if (pop.size() == 0) { + symbol += " ε"; + } else { + for (alphabet::Symbol symb : pop) { + alphabet::SymbolToStringComposer composer; + symbol += " " + composer.compose(symb); + } + + } + + symbol += " ->"; + + for(const auto& to : transition.second) { + //Push part + if (push.size() == 0) { + symbol += " ε"; + } else { + for (alphabet::Symbol symb : push) { + alphabet::SymbolToStringComposer composer; + symbol += " " + composer.compose(symb); + } + + } + + //Insert into map + std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); + std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); + + if (mapit == transitions.end()) { + transitions.insert(std::make_pair(key, symbol)); + } else { + mapit->second += ", " + symbol; + } + } + } + + //print the map + for (const std::pair<std::pair<int, int>, std::string> transition : transitions) { + out << transition.first.first << " -> " << transition.first.second; + out << "[label=\"" << transition.second << "\"]\n"; + } +} + +void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) { + std::map<std::pair<int, int>, std::string> transitions; + + for (const auto& transition : pda.getCallTransitions()) { + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + symbol = composer.compose(transition.first.second); + + symbol += " |"; + + //Pop part + symbol += " ε"; + symbol += " ->"; + + for(const auto& to : transition.second) { + alphabet::SymbolToStringComposer composer; + symbol += " " + composer.compose(to.second); + + //Insert into map + std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to.first)->second); + std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); + + if (mapit == transitions.end()) { + transitions.insert(std::make_pair(key, symbol)); + } else { + mapit->second += ", " + symbol; + } + } + } + + for (const auto& transition : pda.getReturnTransitions()) { + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + symbol = composer.compose(std::get<1>(transition.first)); + + symbol += " |"; + + //Pop part + symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " ->"; + + for(const auto& to : transition.second) { + symbol += " ε"; + + //Insert into map + std::pair<int, int> key(states.find(std::get<0>(transition.first))->second, states.find(to)->second); + std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); + + if (mapit == transitions.end()) { + transitions.insert(std::make_pair(key, symbol)); + } else { + mapit->second += ", " + symbol; + } + } + } + + for (const auto& transition : pda.getLocalTransitions()) { + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + symbol = composer.compose(transition.first.second); + + symbol += " |"; + + //Pop part + symbol += " ε"; + symbol += " ->"; + + for(const auto& to : transition.second) { + symbol += " ε"; + + //Insert into map + std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); + std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); + + if (mapit == transitions.end()) { + transitions.insert(std::make_pair(key, symbol)); + } else { + mapit->second += ", " + symbol; + } + } + } + + //print the map + for (const std::pair<std::pair<int, int>, std::string> transition : transitions) { + out << transition.first.first << " -> " << transition.first.second; + out << "[label=\"" << transition.second << "\"]\n"; + } +} + void DotConverter::transitions(const automaton::NPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) { std::map<std::pair<int, int>, std::string> transitions; @@ -822,6 +1049,14 @@ void DotConverter::Visit(void* data, const automaton::SinglePopDPDA& automaton) DotConverter::convert(automaton, *((std::ostream*) data)); } +void DotConverter::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const { + DotConverter::convert(automaton, *((std::ostream*) data)); +} + +void DotConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const { + DotConverter::convert(automaton, *((std::ostream*) data)); +} + void DotConverter::Visit(void* data, const automaton::NPDA& automaton) const { DotConverter::convert(automaton, *((std::ostream*) data)); } diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h index 8592b03f8c0c51f5d8d44847d48984c395506f1a..8f59741ec09164ed69f4ccb50cb0fa6ca72f34ce 100644 --- a/aconvert2/src/DotConverter.h +++ b/aconvert2/src/DotConverter.h @@ -24,6 +24,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; @@ -36,6 +38,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ static void transitions(const automaton::CompactNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::DPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::SinglePopDPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out); + static void transitions(const automaton::InputDrivenNPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out); + static void transitions(const automaton::VisiblyPushdownNPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::NPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::SinglePopNPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::OneTapeDTM& tm, const std::map<automaton::State, int>& states, std::ostream& out); @@ -52,6 +56,8 @@ public: static void convert(const automaton::CompactNFA& a, std::ostream& out); static void convert(const automaton::DPDA& a, std::ostream& out); static void convert(const automaton::SinglePopDPDA& a, std::ostream& out); + static void convert(const automaton::InputDrivenNPDA& a, std::ostream& out); + static void convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out); static void convert(const automaton::NPDA& a, std::ostream& out); static void convert(const automaton::SinglePopNPDA& a, std::ostream& out); static void convert(const automaton::OneTapeDTM& a, std::ostream& out); diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp index eb49c83135c14dad638912a72fea51121fbde333..fa023d640c6a827ca3eedb8b13a685fdd77ee50f 100644 --- a/aconvert2/src/GasTexConverter.cpp +++ b/aconvert2/src/GasTexConverter.cpp @@ -14,6 +14,8 @@ #include <automaton/FSM/CompactNFA.h> #include <automaton/PDA/DPDA.h> #include <automaton/PDA/SinglePopDPDA.h> +#include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/PDA/VisiblyPushdownNPDA.h> #include <automaton/PDA/NPDA.h> #include <automaton/PDA/SinglePopNPDA.h> #include <automaton/TM/OneTapeDTM.h> @@ -308,6 +310,84 @@ void GasTexConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& o out << "\\end{picture}\n"; } +void GasTexConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& out) { + out << "\\begin{center}\n"; + out << "\\begin{picture}(,)(,)\n"; + + for (auto& state : a.getStates()) { + bool initial = false; + bool final = false; + + if(a.getInitialStates().count(state)){ + initial = true; + } + if(a.getFinalStates().count(state)){ + final = true; + } + + if(initial || final) { + out << "\\node[Nmarks="; + if(initial){ + out << "i"; + } + if(final){ + out << "r"; + } + out<<"]("; + } else { + out <<"\\node("; + } + + out << state.getName(); + out << ")(,){"; + out << state.getName(); + out << "}\n"; + } + + transitions(a, out); + out << "\\end{center}\n"; + out << "\\end{picture}\n"; +} + +void GasTexConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out) { + out << "\\begin{center}\n"; + out << "\\begin{picture}(,)(,)\n"; + + for (auto& state : a.getStates()) { + bool initial = false; + bool final = false; + + if(a.getInitialStates().count(state)){ + initial = true; + } + if(a.getFinalStates().count(state)){ + final = true; + } + + if(initial || final) { + out << "\\node[Nmarks="; + if(initial){ + out << "i"; + } + if(final){ + out << "r"; + } + out<<"]("; + } else { + out <<"\\node("; + } + + out << state.getName(); + out << ")(,){"; + out << state.getName(); + out << "}\n"; + } + + transitions(a, out); + out << "\\end{center}\n"; + out << "\\end{picture}\n"; +} + void GasTexConverter::convert(const automaton::NPDA& a, std::ostream& out) { out << "\\begin{center}\n"; out << "\\begin{picture}(,)(,)\n"; @@ -630,6 +710,111 @@ void GasTexConverter::transitions(const automaton::SinglePopDPDA& pda, std::ostr printTransitionMap(transitionMap, out); } +void GasTexConverter::transitions(const automaton::InputDrivenNPDA& pda, std::ostream& out) { + std::map<std::pair<std::string, std::string>, std::string> transitionMap; + + alphabet::SymbolToStringComposer composer; + const auto& symbolToPDSOperation = pda.getPushdownStoreOperations(); + for (const auto& transition : pda.getTransitions()) { + const auto& pop = symbolToPDSOperation.find(std::get<1>(transition.first))->second.first; + const auto& push = symbolToPDSOperation.find(std::get<1>(transition.first))->second.second; + + for(const auto& to : transition.second) { + std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.getName()); + auto mapIterator = transitionMap.find(key); + + std::string symbol = composer.compose(transition.first.second); + + symbol += "|"; + + symbol += getStackSymbols(pop); + symbol += "\\rarrow"; + symbol += getStackSymbols(push); + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(std::make_pair(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + } + + printTransitionMap(transitionMap, out); +} + +void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std::ostream& out) { + std::map<std::pair<std::string, std::string>, std::string> transitionMap; + + alphabet::SymbolToStringComposer composer; + for (const auto& transition : pda.getCallTransitions()) { + for(const auto& to : transition.second) { + std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.first.getName()); + auto mapIterator = transitionMap.find(key); + + std::string symbol; + symbol = composer.compose(transition.first.second); + + symbol += "|"; + + symbol += "$\\varepsilon;$"; + symbol += "\\rarrow"; + symbol += composer.compose(to.second); + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(std::make_pair(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + } + + for (const auto& transition : pda.getReturnTransitions()) { + for(const auto& to : transition.second) { + std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) to.getName()); + auto mapIterator = transitionMap.find(key); + + std::string symbol; + symbol = composer.compose(std::get<1>(transition.first)); + + symbol += "|"; + + symbol += composer.compose(std::get<2>(transition.first)); + symbol += "\\rarrow"; + symbol += "$\\varepsilon;$"; + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(std::make_pair(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + } + + for (const auto& transition : pda.getLocalTransitions()) { + for(const auto& to : transition.second) { + std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.getName()); + auto mapIterator = transitionMap.find(key); + + std::string symbol; + symbol = composer.compose(transition.first.second); + + symbol += "|"; + + symbol += "$\\varepsilon;$"; + symbol += "\\rarrow"; + symbol += "$\\varepsilon;$"; + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(std::make_pair(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + } + + printTransitionMap(transitionMap, out); +} + void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; @@ -766,6 +951,14 @@ void GasTexConverter::Visit(void* data, const automaton::SinglePopDPDA& automato GasTexConverter::convert(automaton, *((std::ostream*) data)); } +void GasTexConverter::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const { + GasTexConverter::convert(automaton, *((std::ostream*) data)); +} + +void GasTexConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const { + GasTexConverter::convert(automaton, *((std::ostream*) data)); +} + void GasTexConverter::Visit(void* data, const automaton::NPDA& automaton) const { GasTexConverter::convert(automaton, *((std::ostream*) data)); } diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h index 84f821bc1eef21f2626755c9be5aaabd7ac95aa0..80072c67c1aea726374301e4339ef912395ea544 100644 --- a/aconvert2/src/GasTexConverter.h +++ b/aconvert2/src/GasTexConverter.h @@ -24,6 +24,8 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; @@ -39,6 +41,8 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ static void transitions(const automaton::CompactNFA& fsm, std::ostream& out); static void transitions(const automaton::DPDA& pda, std::ostream& out); static void transitions(const automaton::SinglePopDPDA& tm, std::ostream& out); + static void transitions(const automaton::InputDrivenNPDA& pda, std::ostream& out); + static void transitions(const automaton::VisiblyPushdownNPDA& tm, std::ostream& out); static void transitions(const automaton::NPDA& pda, std::ostream& out); static void transitions(const automaton::SinglePopNPDA& tm, std::ostream& out); static void transitions(const automaton::OneTapeDTM& tm, std::ostream& out); @@ -55,6 +59,8 @@ public: static void convert(const automaton::CompactNFA& a, std::ostream& out); static void convert(const automaton::DPDA& a, std::ostream& out); static void convert(const automaton::SinglePopDPDA& a, std::ostream& out); + static void convert(const automaton::InputDrivenNPDA& a, std::ostream& out); + static void convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out); static void convert(const automaton::NPDA& a, std::ostream& out); static void convert(const automaton::SinglePopNPDA& a, std::ostream& out); static void convert(const automaton::OneTapeDTM& a, std::ostream& out); diff --git a/aconvert2/src/aconvert.cpp b/aconvert2/src/aconvert.cpp index ed0e9473c98aedcb25e7874dc37af8eb639205ee..3fd16905ac17e3e89c9e7e723ea658da7ac91b23 100644 --- a/aconvert2/src/aconvert.cpp +++ b/aconvert2/src/aconvert.cpp @@ -6,6 +6,8 @@ #include "grammar/GrammarToStringComposer.h" #include "regexp/RegExpFromStringParser.h" #include "regexp/RegExpToStringComposer.h" +#include "string/StringFromStringParser.h" +#include "string/StringToStringComposer.h" #include <ctype.h> #include <stdio.h> @@ -28,6 +30,8 @@ #define GRAMMAR_TO_STRING 6 #define REG_EXP_FROM_STRING 7 #define REG_EXP_TO_STRING 8 +#define STRING_FROM_STRING 7 +#define STRING_TO_STRING 8 void printHelp() { std::cout << "Help" << std::endl; @@ -63,6 +67,16 @@ int regexpFromString(std::istream& in, std::ostream& out) { return 0; } +int stringFromString(std::istream& in, std::ostream& out) { + string::StringFromStringParser parser(in); + + string::String result = parser.parseValue(); + + alib::DataFactory::toStream(result, out); + + return 0; +} + int automatonToString(std::istream& in, std::ostream& out) { try { automaton::Automaton automaton = alib::DataFactory::fromStream<automaton::Automaton>(in); @@ -99,6 +113,18 @@ int regexpToString(std::istream& in, std::ostream& out) { return 0; } +int stringToString(std::istream& in, std::ostream& out) { + try { + string::String string = alib::DataFactory::fromStream<string::String>(in); + string::StringToStringComposer composer; + out << composer.compose(string); + } catch (exception::AlibException& e) { + std::cerr << e.getCause() << std::endl; + return 1; + } + return 0; +} + int automatonToDot(std::istream& in, std::ostream& out) { try { diff --git a/alib2algo/src/automaton/EpsilonClosure.cpp b/alib2algo/src/automaton/EpsilonClosure.cpp index 99f4577e545fa030dfe775f593ae3c8fe5ad5941..54ce6f1d52a876ef40d5468a93472c7a84e118c6 100644 --- a/alib2algo/src/automaton/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/EpsilonClosure.cpp @@ -164,6 +164,14 @@ void EpsilonClosure::Visit(void*, const SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void EpsilonClosure::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void EpsilonClosure::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + void EpsilonClosure::Visit(void*, const NPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } diff --git a/alib2algo/src/automaton/EpsilonClosure.h b/alib2algo/src/automaton/EpsilonClosure.h index 515c88f23de748391377187caf2e6b30f14edb7d..e6f026a7c79ebca86bfe93f62b5233bf277e4e5d 100644 --- a/alib2algo/src/automaton/EpsilonClosure.h +++ b/alib2algo/src/automaton/EpsilonClosure.h @@ -39,6 +39,8 @@ private: void Visit(void*, const CompactNFA& automaton) const; void Visit(void*, const DPDA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp index 741bddc720443f9eb98a523df1ef1653c74bd949..e8ab2ee41717a862589bad1cf92797f90c6f0f01 100644 --- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp +++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp @@ -102,6 +102,16 @@ void StateEliminationFormal::Visit(void*, const automaton::SinglePopDPDA&) const throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); } +void StateEliminationFormal::Visit(void*, const automaton::InputDrivenNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void StateEliminationFormal::Visit(void*, const automaton::VisiblyPushdownNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + void StateEliminationFormal::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h index 86fcb39b750f39a3d527bc2e2adaaf0d4acfbd55..76959dc25c59a8cde3ddb22dff3332ec6cf65f5b 100644 --- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h +++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h @@ -43,6 +43,8 @@ private: void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; diff --git a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp index 9ba6c2388f5cd93a67810c4c7edfda57af4d33e9..427544347b1ceff65b9f16ad8c6556bef974c494 100644 --- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp +++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp @@ -100,6 +100,16 @@ void StateEliminationUnbounded::Visit(void*, const automaton::SinglePopDPDA&) co throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); } +void StateEliminationUnbounded::Visit(void*, const automaton::InputDrivenNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void StateEliminationUnbounded::Visit(void*, const automaton::VisiblyPushdownNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + void StateEliminationUnbounded::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); diff --git a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h index 419e100b352293a630bd5972ef1167455535c5bd..70e114212dce8462bbad07e0b253e0744185548e 100644 --- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h +++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h @@ -43,6 +43,8 @@ private: void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp index da56c262a88154e533f833a112a9fc10869e9fe6..b42754ae072fe73f5bbc0e86bbeb30778acf838e 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp +++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp @@ -147,6 +147,14 @@ void FAtoLRGConverter::Visit(void*, const automaton::SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FAtoLRGConverter::Visit(void*, const automaton::InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FAtoLRGConverter::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + void FAtoLRGConverter::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h index e7558af5a7cdefe5838d1e8ed00107888872771f..53bf0f2e6cb16d660e0a675776c9ab3f82cdb917 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h +++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h @@ -34,10 +34,12 @@ private: void Visit(void*, const automaton::DFA& automaton) const; void Visit(void*, const automaton::ExtendedNFA& automaton) const; void Visit(void*, const automaton::CompactNFA& automaton) const; - void Visit(void*, const automaton::NPDA& automaton) const; - void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const automaton::NPDA& automaton) const; + void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; static const FAtoLRGConverter FA_TO_LRG_CONVERTER; diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp index e1fb2bd497c38eb0efb08bf0e2349f2b7ab15bc7..d9336f3f0ca2582a111da4f06c1dc62537b98c4d 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp +++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp @@ -141,6 +141,14 @@ void FAtoRRGConverter::Visit(void*, const automaton::SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FAtoRRGConverter::Visit(void*, const automaton::InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FAtoRRGConverter::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + void FAtoRRGConverter::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h index 97e8909d15d3b6f9806f79a99c4de62a78a8f95f..c3ee534601b66b6b21dd71f191212e667a5ba4ba 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h +++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h @@ -34,6 +34,8 @@ private: void Visit(void*, const automaton::DFA& automaton) const; void Visit(void*, const automaton::ExtendedNFA& automaton) const; void Visit(void*, const automaton::CompactNFA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp index 4b07bc9d1fb17c347c454e0ed2c4c36c95615aab..8c0e26689351b0d13faeb153f661844e1056942d 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp @@ -107,6 +107,14 @@ void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FSMEpsilonRemover::Visit(void*, const automaton::InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + +void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); +} + void FSMEpsilonRemover::Visit(void*, const automaton::NPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h index e31662e2dcfd71f6c59db6e44e3478b283726f5a..a456c085a3edc978ad152c9b4b5c1290117302b2 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h @@ -40,6 +40,8 @@ private: void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; diff --git a/alib2data/src/Api.cpp b/alib2data/src/Api.cpp index e5a60b8b3585d42b0f948473a108fa710360c386..c99ee8e0a60d081dce2e9e74d889ff3cdb8cdd57 100644 --- a/alib2data/src/Api.cpp +++ b/alib2data/src/Api.cpp @@ -176,6 +176,22 @@ std::list<sax::Token> api<automaton::SinglePopDPDA>::compose(const automaton::Si return ToXMLComposers::automatonComposer.compose(data); } +automaton::InputDrivenNPDA api<automaton::InputDrivenNPDA>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::automatonParser.parseInputDrivenNPDA(input); +} + +std::list<sax::Token> api<automaton::InputDrivenNPDA>::compose(const automaton::InputDrivenNPDA& data) { + return ToXMLComposers::automatonComposer.compose(data); +} + +automaton::VisiblyPushdownNPDA api<automaton::VisiblyPushdownNPDA>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::automatonParser.parseVisiblyPushdownNPDA(input); +} + +std::list<sax::Token> api<automaton::VisiblyPushdownNPDA>::compose(const automaton::VisiblyPushdownNPDA& data) { + return ToXMLComposers::automatonComposer.compose(data); +} + automaton::NPDA api<automaton::NPDA>::parse(std::list<sax::Token>& input) { return FromXMLParsers::automatonParser.parseNPDA(input); } @@ -484,6 +500,14 @@ void ToXMLComposers::Visit(void* data, const automaton::SinglePopDPDA& automaton *((std::list<sax::Token>*) data) = std::move(api<automaton::SinglePopDPDA>::compose(automaton)); } +void ToXMLComposers::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const { + *((std::list<sax::Token>*) data) = std::move(api<automaton::InputDrivenNPDA>::compose(automaton)); +} + +void ToXMLComposers::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const { + *((std::list<sax::Token>*) data) = std::move(api<automaton::VisiblyPushdownNPDA>::compose(automaton)); +} + void ToXMLComposers::Visit(void* data, const automaton::NPDA& automaton) const { *((std::list<sax::Token>*) data) = std::move(api<automaton::NPDA>::compose(automaton)); } diff --git a/alib2data/src/Api.hpp b/alib2data/src/Api.hpp index 675b892f73de43c530437e0bc61b040be0ed34a8..82a59480f339baa7ffbd387cfb90e54bbf1cfa76 100644 --- a/alib2data/src/Api.hpp +++ b/alib2data/src/Api.hpp @@ -148,6 +148,18 @@ struct api<automaton::SinglePopDPDA> { static std::list<sax::Token> compose(const automaton::SinglePopDPDA& data); }; +template<> +struct api<automaton::InputDrivenNPDA> { + static automaton::InputDrivenNPDA parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const automaton::InputDrivenNPDA& data); +}; + +template<> +struct api<automaton::VisiblyPushdownNPDA> { + static automaton::VisiblyPushdownNPDA parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const automaton::VisiblyPushdownNPDA& data); +}; + template<> struct api<automaton::NPDA> { static automaton::NPDA parse(std::list<sax::Token>& input); @@ -386,6 +398,8 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type { void Visit(void*, const automaton::CompactNFA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; + void Visit(void*, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const; void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; diff --git a/alib2data/src/automaton/AutomatonBase.h b/alib2data/src/automaton/AutomatonBase.h index 40e639a22c005fcca0c131ca5341a71691fd6aee..039c2011a405a7c29d6ca48deb27ae71aae45e80 100644 --- a/alib2data/src/automaton/AutomatonBase.h +++ b/alib2data/src/automaton/AutomatonBase.h @@ -14,7 +14,7 @@ namespace automaton { typedef std::acceptor_base< - automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM + automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM > VisitableAutomatonBase; /** diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h index 5677a8ba0a0ce1946188c0d3dc7b833e379e6d04..917593ddaedb3e2b5477004688a990b692c927cc 100644 --- a/alib2data/src/automaton/AutomatonFeatures.h +++ b/alib2data/src/automaton/AutomatonFeatures.h @@ -19,6 +19,8 @@ enum class FEATURES { EXTENDED_NFA, DPDA, SINGLE_POP_DPDA, + INPUT_DRIVEN_NPDA, + VISIBLY_PUSHDOWN_NPDA, NPDA, SINGLE_POP_NPDA, ONE_TAPE_DTM diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.cpp b/alib2data/src/automaton/AutomatonFromXMLParser.cpp index bda25b15d253723c3c0a7fda63e379bb4ac268e6..052eb7def6fd1e1b4cffe89a83ffaee99c160148 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.cpp +++ b/alib2data/src/automaton/AutomatonFromXMLParser.cpp @@ -18,7 +18,7 @@ namespace automaton { Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token> &input) const { - return parseAutomaton(input, std::set<FEATURES>({FEATURES::AUTOMATON, FEATURES::EPSILON_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::DPDA, FEATURES::SINGLE_POP_DPDA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM})); + return parseAutomaton(input, std::set<FEATURES>({FEATURES::AUTOMATON, FEATURES::EPSILON_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::DPDA, FEATURES::SINGLE_POP_DPDA, FEATURES::INPUT_DRIVEN_NPDA, FEATURES::VISIBLY_PUSHDOWN_NPDA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM})); } Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, const std::set<FEATURES>& features) const { @@ -46,6 +46,12 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, c } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA")) { if(!features.count(FEATURES::SINGLE_POP_DPDA)) throw exception::AlibException(); return Automaton(parseSinglePopDPDA(input)); + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "InputDrivenNPDA")) { + if(!features.count(FEATURES::INPUT_DRIVEN_NPDA)) throw exception::AlibException(); + return Automaton(parseNPDA(input)); + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "VisiblyPushdownNPDA")) { + if(!features.count(FEATURES::VISIBLY_PUSHDOWN_NPDA)) throw exception::AlibException(); + return Automaton(parseSinglePopNPDA(input)); } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA")) { if(!features.count(FEATURES::NPDA)) throw exception::AlibException(); return Automaton(parseNPDA(input)); @@ -67,6 +73,26 @@ bool AutomatonFromXMLParser::first(std::list<sax::Token>& input) const { } } +template<> +void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, VisiblyPushdownNPDA& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + parseTransition(input, automaton); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "transitions"); +} + +template<class T> +void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, T& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transition"); + parseTransition(input, automaton); + popToken(input, sax::Token::TokenType::END_ELEMENT, "transition"); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "transitions"); +} + UnknownAutomaton AutomatonFromXMLParser::parseUnknownAutomaton(std::list<sax::Token> &input) const { UnknownAutomaton automaton; @@ -245,6 +271,61 @@ SinglePopDPDA AutomatonFromXMLParser::parseSinglePopDPDA(std::list<sax::Token>& return automaton; } +InputDrivenNPDA AutomatonFromXMLParser::parseInputDrivenNPDA(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "InputDrivenNPDA"); + + std::set<State> states = parseStates(input); + std::set<alphabet::Symbol> inputSymbols = parseInputAlphabet(input); + std::set<alphabet::Symbol> stackSymbols = parseStackAlphabet(input); + std::set<State> initialStates = parseInitialStates(input); + alphabet::Symbol initialStackSymbol = parseInitialStackSymbol(input); + std::set<State> finalStates = parseFinalStates(input); + + InputDrivenNPDA automaton(initialStackSymbol); + automaton.setStates(states); + automaton.setInputSymbols(inputSymbols); + automaton.setStackSymbols(stackSymbols); + automaton.setInitialStates(initialStates); + automaton.setFinalStates(finalStates); + + parseInputToPushdownStoreOperation(input, automaton); + parseTransitions<InputDrivenNPDA>(input, automaton); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "InputDrivenNPDA"); + + return automaton; +} + +VisiblyPushdownNPDA AutomatonFromXMLParser::parseVisiblyPushdownNPDA(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "VisiblyPushdownNPDA"); + + std::set<State> states = parseStates(input); + std::set<alphabet::Symbol> callInputSymbols = parseCallInputAlphabet(input); + std::set<alphabet::Symbol> returnInputSymbols = parseReturnInputAlphabet(input); + std::set<alphabet::Symbol> localInputSymbols = parseLocalInputAlphabet(input); + std::set<alphabet::Symbol> stackSymbols = parseStackAlphabet(input); + std::set<State> initialStates = parseInitialStates(input); + alphabet::Symbol bottomOfTheStackSymbol = parseBottomOfTheStackSymbol(input); + std::set<State> finalStates = parseFinalStates(input); + + VisiblyPushdownNPDA automaton(bottomOfTheStackSymbol); + automaton.setStates(states); + automaton.setCallInputSymbols(callInputSymbols); + automaton.setReturnInputSymbols(callInputSymbols); + automaton.setLocalInputSymbols(callInputSymbols); + automaton.setReturnInputSymbols(returnInputSymbols); + automaton.setLocalInputSymbols(localInputSymbols); + automaton.setStackSymbols(stackSymbols); + automaton.setInitialStates(initialStates); + automaton.setFinalStates(finalStates); + + parseTransitions<VisiblyPushdownNPDA>(input, automaton); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "VisiblyPushdownNPDA"); + + return automaton; +} + NPDA AutomatonFromXMLParser::parseNPDA(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA"); @@ -328,6 +409,36 @@ std::set<State> AutomatonFromXMLParser::parseStates(std::list<sax::Token> &input return states; } +std::set<alphabet::Symbol> AutomatonFromXMLParser::parseCallInputAlphabet(std::list<sax::Token> &input) const { + std::set<alphabet::Symbol> inputSymbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "callInputAlphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + inputSymbols.insert(alib::api<alphabet::Symbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "callInputAlphabet"); + return inputSymbols; +} + +std::set<alphabet::Symbol> AutomatonFromXMLParser::parseReturnInputAlphabet(std::list<sax::Token> &input) const { + std::set<alphabet::Symbol> inputSymbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "returnInputAlphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + inputSymbols.insert(alib::api<alphabet::Symbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "returnInputAlphabet"); + return inputSymbols; +} + +std::set<alphabet::Symbol> AutomatonFromXMLParser::parseLocalInputAlphabet(std::list<sax::Token> &input) const { + std::set<alphabet::Symbol> inputSymbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "localInputAlphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + inputSymbols.insert(alib::api<alphabet::Symbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "localInputAlphabet"); + return inputSymbols; +} + std::set<alphabet::Symbol> AutomatonFromXMLParser::parseInputAlphabet(std::list<sax::Token> &input) const { std::set<alphabet::Symbol> inputSymbols; popToken(input, sax::Token::TokenType::START_ELEMENT, "inputAlphabet"); @@ -409,15 +520,28 @@ alphabet::Symbol AutomatonFromXMLParser::parseBlankSymbol(std::list<sax::Token>& return blank; } -template<class T> -void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, T& automaton) const { - popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions"); +alphabet::Symbol AutomatonFromXMLParser::parseBottomOfTheStackSymbol(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "bottomOfTheStackSymbol"); + alphabet::Symbol blank(alib::api<alphabet::Symbol>::parse(input)); + popToken(input, sax::Token::TokenType::END_ELEMENT, "bottomOfTheStackSymbol"); + return blank; +} + +void AutomatonFromXMLParser::parseInputToPushdownStoreOperation(std::list<sax::Token>& input, automaton::InputDrivenNPDA& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "inputToPushdownStoreOperations"); while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { - popToken(input, sax::Token::TokenType::START_ELEMENT, "transition"); - parseTransition(input, automaton); - popToken(input, sax::Token::TokenType::END_ELEMENT, "transition"); + popToken(input, sax::Token::TokenType::START_ELEMENT, "operation"); + + alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); + + std::vector<alphabet::Symbol> pop = parseTransitionPop(input); + std::vector<alphabet::Symbol> push = parseTransitionPush(input); + + automaton.setPushdownStoreOperation(inputSymbol, pop, push); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "operation"); } - popToken(input, sax::Token::TokenType::END_ELEMENT, "transitions"); + popToken(input, sax::Token::TokenType::END_ELEMENT, "inputToPushdownStoreOperations"); } void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, DFA& automaton) const { @@ -463,8 +587,8 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, Exten void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, DPDA& automaton) const { State from = parseTransitionFrom(input); std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); - State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> pop = parseTransitionPop(input); + State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> push = parseTransitionPush(input); automaton.addTransition(from, inputSymbol, pop, to, push); @@ -473,18 +597,56 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, DPDA& void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, SinglePopDPDA& automaton) const { State from = parseTransitionFrom(input); std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); - State to = parseTransitionFrom(input); alphabet::Symbol pop = parseTransitionSinglePop(input); + State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> push = parseTransitionPush(input); automaton.addTransition(from, inputSymbol, pop, to, push); } +void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, InputDrivenNPDA& automaton) const { + State from = parseTransitionFrom(input); + alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); + State to = parseTransitionTo(input); + + automaton.addTransition(from, inputSymbol, to); +} + +void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, VisiblyPushdownNPDA& automaton) const { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "callTransition")) { + popToken(input, sax::Token::TokenType::START_ELEMENT, "callTransition"); + State from = parseTransitionFrom(input); + alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); + State to = parseTransitionTo(input); + alphabet::Symbol push = parseTransitionSinglePush(input); + + automaton.addTransition(from, inputSymbol, to, push); + popToken(input, sax::Token::TokenType::END_ELEMENT, "callTransition"); + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "returnTransition")) { + popToken(input, sax::Token::TokenType::START_ELEMENT, "returnTransition"); + State from = parseTransitionFrom(input); + alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); + alphabet::Symbol pop = parseTransitionSinglePop(input); + State to = parseTransitionTo(input); + + automaton.addTransition(from, inputSymbol, pop, to); + popToken(input, sax::Token::TokenType::END_ELEMENT, "returnTransition"); + } else { + popToken(input, sax::Token::TokenType::START_ELEMENT, "localTransition"); + State from = parseTransitionFrom(input); + alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); + State to = parseTransitionTo(input); + + automaton.addTransition(from, inputSymbol, to); + popToken(input, sax::Token::TokenType::END_ELEMENT, "localTransition"); + } +} + void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, NPDA& automaton) const { State from = parseTransitionFrom(input); std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); - State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> pop = parseTransitionPop(input); + State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> push = parseTransitionPush(input); automaton.addTransition(from, inputSymbol, pop, to, push); @@ -493,8 +655,8 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, NPDA& void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, SinglePopNPDA& automaton) const { State from = parseTransitionFrom(input); std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); - State to = parseTransitionFrom(input); alphabet::Symbol pop = parseTransitionSinglePop(input); + State to = parseTransitionFrom(input); std::vector<alphabet::Symbol> push = parseTransitionPush(input); automaton.addTransition(from, inputSymbol, pop, to, push); @@ -596,6 +758,13 @@ std::vector<alphabet::Symbol> AutomatonFromXMLParser::parseTransitionPush(std::l return pushes; } +alphabet::Symbol AutomatonFromXMLParser::parseTransitionSinglePush(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "push"); + alphabet::Symbol push = alib::api<alphabet::Symbol>::parse(input); + popToken(input, sax::Token::TokenType::END_ELEMENT, "push"); + return push; +} + alphabet::Symbol AutomatonFromXMLParser::parseTransitionInputSymbol(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "input"); alphabet::Symbol result(alib::api<alphabet::Symbol>::parse(input)); diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.h b/alib2data/src/automaton/AutomatonFromXMLParser.h index 360a7315ae591dd707989898ebbffe5260ae734b..0aca28dbe1efb216b5941478d914005e5c12dcec 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.h +++ b/alib2data/src/automaton/AutomatonFromXMLParser.h @@ -19,6 +19,8 @@ #include "FSM/ExtendedNFA.h" #include "PDA/DPDA.h" #include "PDA/SinglePopDPDA.h" +#include "PDA/InputDrivenNPDA.h" +#include "PDA/VisiblyPushdownNPDA.h" #include "PDA/NPDA.h" #include "PDA/SinglePopNPDA.h" #include "TM/OneTapeDTM.h" @@ -43,6 +45,9 @@ namespace automaton { class AutomatonFromXMLParser : public sax::FromXMLParserHelper { std::set<State> parseStates(std::list<sax::Token> &input) const; std::set<alphabet::Symbol> parseInputAlphabet(std::list<sax::Token> &input) const; + std::set<alphabet::Symbol> parseCallInputAlphabet(std::list<sax::Token> &input) const; + std::set<alphabet::Symbol> parseReturnInputAlphabet(std::list<sax::Token> &input) const; + std::set<alphabet::Symbol> parseLocalInputAlphabet(std::list<sax::Token> &input) const; std::set<alphabet::Symbol> parseStackAlphabet(std::list<sax::Token> &input) const; std::set<alphabet::Symbol> parseInitialStackSymbols(std::list<sax::Token> &input) const; alphabet::Symbol parseInitialStackSymbol(std::list<sax::Token> &input) const; @@ -51,6 +56,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { std::set<State> parseInitialStates(std::list<sax::Token> &input) const; std::set<State> parseFinalStates(std::list<sax::Token> &input) const; alphabet::Symbol parseBlankSymbol(std::list<sax::Token> &input) const; + alphabet::Symbol parseBottomOfTheStackSymbol(std::list<sax::Token> &input) const; + void parseInputToPushdownStoreOperation(std::list<sax::Token>& input, automaton::InputDrivenNPDA& automaton) const; State parseTransitionFrom(std::list<sax::Token>& input) const; State parseTransitionTo(std::list<sax::Token>& input) const; @@ -58,6 +65,7 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { std::vector<alphabet::Symbol> parseTransitionPop(std::list<sax::Token>& input) const; alphabet::Symbol parseTransitionSinglePop(std::list<sax::Token>& input) const; std::vector<alphabet::Symbol> parseTransitionPush(std::list<sax::Token>& input) const; + alphabet::Symbol parseTransitionSinglePush(std::list<sax::Token>& input) const; template<class T> void parseTransitions(std::list<sax::Token> &input, T& automaton) const; @@ -69,6 +77,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { void parseTransition(std::list<sax::Token>& input, ExtendedNFA& automaton) const; void parseTransition(std::list<sax::Token>& input, DPDA& automaton) const; void parseTransition(std::list<sax::Token>& input, SinglePopDPDA& automaton) const; + void parseTransition(std::list<sax::Token>& input, InputDrivenNPDA& automaton) const; + void parseTransition(std::list<sax::Token>& input, VisiblyPushdownNPDA& automaton) const; void parseTransition(std::list<sax::Token>& input, NPDA& automaton) const; void parseTransition(std::list<sax::Token>& input, SinglePopNPDA& automaton) const; void parseTransition(std::list<sax::Token>& input, OneTapeDTM& automaton) const; @@ -97,6 +107,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { ExtendedNFA parseExtendedNFA(std::list<sax::Token>& input) const; DPDA parseDPDA(std::list<sax::Token>& input) const; SinglePopDPDA parseSinglePopDPDA(std::list<sax::Token>& input) const; + InputDrivenNPDA parseInputDrivenNPDA(std::list<sax::Token>& input) const; + VisiblyPushdownNPDA parseVisiblyPushdownNPDA(std::list<sax::Token>& input) const; NPDA parseNPDA(std::list<sax::Token>& input) const; SinglePopNPDA parseSinglePopNPDA(std::list<sax::Token>& input) const; OneTapeDTM parseOneTapeDTM(std::list<sax::Token>& input) const; diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.cpp b/alib2data/src/automaton/AutomatonToXMLComposer.cpp index 834d646130b24228e1a667457b17cdc2385d0a41..941eaf65486cd23a44f1fb7d90e13ece62644565 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.cpp +++ b/alib2data/src/automaton/AutomatonToXMLComposer.cpp @@ -28,6 +28,30 @@ void AutomatonToXMLComposer::composeInputAlphabet(std::list<sax::Token>& out, co out.push_back(sax::Token("inputAlphabet", sax::Token::TokenType::END_ELEMENT)); } +void AutomatonToXMLComposer::composeCallInputAlphabet(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& symbols) const { + out.push_back(sax::Token("callInputAlphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); + } + out.push_back(sax::Token("callInputAlphabet", sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::composeReturnInputAlphabet(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& symbols) const { + out.push_back(sax::Token("returnInputAlphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); + } + out.push_back(sax::Token("returnInputAlphabet", sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::composeLocalInputAlphabet(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& symbols) const { + out.push_back(sax::Token("localInputAlphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); + } + out.push_back(sax::Token("localInputAlphabet", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeInitialStates(std::list<sax::Token>& out, const std::set<State>& states) const { out.push_back(sax::Token("initialStates", sax::Token::TokenType::START_ELEMENT)); for (const auto& state : states) { @@ -86,6 +110,28 @@ void AutomatonToXMLComposer::composeBlankSymbol(std::list<sax::Token>& out, cons out.push_back(sax::Token("blankSymbol", sax::Token::TokenType::END_ELEMENT)); } +void AutomatonToXMLComposer::composeBottomOfTheStackSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol) const { + out.push_back(sax::Token("bottomOfTheStackSymbol", sax::Token::TokenType::START_ELEMENT)); + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); + out.push_back(sax::Token("bottomOfTheStackSymbol", sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::composeInputToPushdownStoreOperation(std::list<sax::Token>& out, const automaton::InputDrivenNPDA& automaton) const { + + out.push_back(sax::Token("inputToPushdownStoreOperation", sax::Token::TokenType::START_ELEMENT)); + for(const auto& pushdownStoreOperation : automaton.getPushdownStoreOperations()) { + out.push_back(sax::Token("operation", sax::Token::TokenType::START_ELEMENT)); + + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(pushdownStoreOperation.first)); + + composeTransitionPop(out, pushdownStoreOperation.second.first); + composeTransitionPush(out, pushdownStoreOperation.second.second); + + out.push_back(sax::Token("operation", sax::Token::TokenType::END_ELEMENT)); + } + out.push_back(sax::Token("inputToPushdownStoreOperation", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const UnknownAutomaton& automaton) const { out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); for (const auto& transition : automaton.getTransitions()) { @@ -236,6 +282,64 @@ void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, cons out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT)); } +void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const InputDrivenNPDA& automaton) const { + out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); + for(const auto& transition : automaton.getTransitions()) { + for(const auto& target: transition.second) { + out.push_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionFrom(out, transition.first.first); + composeTransitionInputSymbol(out, transition.first.second); + composeTransitionTo(out, target); + + out.push_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT)); + } + } + + out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const VisiblyPushdownNPDA& automaton) const { + out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); + for(const auto& transition : automaton.getCallTransitions()) { + for(const auto& target: transition.second) { + out.push_back(sax::Token("callTransition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionFrom(out, transition.first.first); + composeTransitionInputSymbol(out, transition.first.second); + composeTransitionTo(out, target.first); + composeTransitionSinglePush(out, target.second); + + out.push_back(sax::Token("calltransition", sax::Token::TokenType::END_ELEMENT)); + } + } + for(const auto& transition : automaton.getReturnTransitions()) { + for(const auto& target: transition.second) { + out.push_back(sax::Token("returnTransition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionFrom(out, std::get<0>(transition.first)); + composeTransitionInputSymbol(out, std::get<1>(transition.first)); + composeTransitionSinglePop(out, std::get<2>(transition.first)); + composeTransitionTo(out, target); + + out.push_back(sax::Token("returntransition", sax::Token::TokenType::END_ELEMENT)); + } + } + for(const auto& transition : automaton.getLocalTransitions()) { + for(const auto& target: transition.second) { + out.push_back(sax::Token("localTransition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionFrom(out, transition.first.first); + composeTransitionInputSymbol(out, transition.first.second); + composeTransitionTo(out, target); + + out.push_back(sax::Token("localtransition", sax::Token::TokenType::END_ELEMENT)); + } + } + + out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const NPDA& automaton) const { out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); for(const auto& transition : automaton.getTransitions()) { @@ -331,6 +435,12 @@ void AutomatonToXMLComposer::composeTransitionPush(std::list<sax::Token>& out, c out.push_back(sax::Token("push", sax::Token::TokenType::END_ELEMENT)); } +void AutomatonToXMLComposer::composeTransitionSinglePush(std::list<sax::Token>& out, const alphabet::Symbol& symbol) const { + out.push_back(sax::Token("push", sax::Token::TokenType::START_ELEMENT)); + out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); + out.push_back(sax::Token("push", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitionInputSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol) const { out.push_back(sax::Token("input", sax::Token::TokenType::START_ELEMENT)); out.splice(out.end(), alib::api<alphabet::Symbol>::compose(symbol)); @@ -526,6 +636,41 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const SinglePopDPDA& autom return out; } +std::list<sax::Token> AutomatonToXMLComposer::compose(const InputDrivenNPDA& automaton) const { + std::list<sax::Token> out; + out.push_back(sax::Token("InputDrivenNPDA", sax::Token::TokenType::START_ELEMENT)); + + composeStates(out, automaton.getStates()); + composeInputAlphabet(out, automaton.getInputAlphabet()); + composeStackAlphabet(out, automaton.getStackAlphabet()); + composeInitialStates(out, automaton.getInitialStates()); + composeFinalStates(out, automaton.getFinalStates()); + composeInitialStackSymbol(out, automaton.getInitialSymbol()); + composeInputToPushdownStoreOperation(out, automaton); + composeTransitions(out, automaton); + + out.push_back(sax::Token("InputDrivenNPDA", sax::Token::TokenType::END_ELEMENT)); + return out; +} + +std::list<sax::Token> AutomatonToXMLComposer::compose(const VisiblyPushdownNPDA& automaton) const { + std::list<sax::Token> out; + out.push_back(sax::Token("VisiblyPushdownNPDA", sax::Token::TokenType::START_ELEMENT)); + + composeStates(out, automaton.getStates()); + composeCallInputAlphabet(out, automaton.getCallInputAlphabet()); + composeReturnInputAlphabet(out, automaton.getReturnInputAlphabet()); + composeLocalInputAlphabet(out, automaton.getLocalInputAlphabet()); + composeStackAlphabet(out, automaton.getStackAlphabet()); + composeInitialStates(out, automaton.getInitialStates()); + composeFinalStates(out, automaton.getFinalStates()); + composeBottomOfTheStackSymbol(out, automaton.getBottomOfTheStackSymbol()); + composeTransitions(out, automaton); + + out.push_back(sax::Token("VisiblyPushdownNPDA", sax::Token::TokenType::END_ELEMENT)); + return out; +} + std::list<sax::Token> AutomatonToXMLComposer::compose(const NPDA& automaton) const { std::list<sax::Token> out; out.push_back(sax::Token("NPDA", sax::Token::TokenType::START_ELEMENT)); diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.h b/alib2data/src/automaton/AutomatonToXMLComposer.h index 50f3e1f8d49fd47833264a7477816a977e6b9bd6..2ee531b7074d614f0f3fb41596cea94c89520023 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.h +++ b/alib2data/src/automaton/AutomatonToXMLComposer.h @@ -17,6 +17,8 @@ #include "FSM/DFA.h" #include "FSM/CompactNFA.h" #include "FSM/ExtendedNFA.h" +#include "PDA/InputDrivenNPDA.h" +#include "PDA/VisiblyPushdownNPDA.h" #include "PDA/NPDA.h" #include "PDA/SinglePopNPDA.h" #include "TM/OneTapeDTM.h" @@ -37,6 +39,9 @@ namespace automaton { class AutomatonToXMLComposer { void composeStates(std::list<sax::Token>&, const std::set<State>& states) const; void composeInputAlphabet(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; + void composeCallInputAlphabet(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; + void composeReturnInputAlphabet(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; + void composeLocalInputAlphabet(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; void composeInitialStates(std::list<sax::Token>&, const std::set<State>& states) const; void composeInitialState(std::list<sax::Token>&, const State& state) const; void composeFinalStates(std::list<sax::Token>&, const std::set<State>& states) const; @@ -45,6 +50,8 @@ class AutomatonToXMLComposer { void composeInitialStackSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbols) const; void composeTapeAlphabet(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; void composeBlankSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; + void composeBottomOfTheStackSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; + void composeInputToPushdownStoreOperation(std::list<sax::Token>&, const automaton::InputDrivenNPDA& automaton) const; void composeTransitions(std::list<sax::Token>&, const UnknownAutomaton& automaton) const; void composeTransitions(std::list<sax::Token>&, const EpsilonNFA& automaton) const; @@ -54,6 +61,8 @@ class AutomatonToXMLComposer { void composeTransitions(std::list<sax::Token>&, const DFA& automaton) const; void composeTransitions(std::list<sax::Token>&, const DPDA& automaton) const; void composeTransitions(std::list<sax::Token>&, const SinglePopDPDA& automaton) const; + void composeTransitions(std::list<sax::Token>&, const InputDrivenNPDA& automaton) const; + void composeTransitions(std::list<sax::Token>&, const VisiblyPushdownNPDA& automaton) const; void composeTransitions(std::list<sax::Token>&, const NPDA& automaton) const; void composeTransitions(std::list<sax::Token>&, const SinglePopNPDA& automaton) const; void composeTransitions(std::list<sax::Token>&, const OneTapeDTM& automaton) const; @@ -64,6 +73,7 @@ class AutomatonToXMLComposer { void composeTransitionPop(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& symbols) const; void composeTransitionSinglePop(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionPush(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& symbols) const; + void composeTransitionSinglePush(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionInputSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionInputEpsilonSymbol(std::list<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&) const; void composeTransitionOutputSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol) const; @@ -88,6 +98,8 @@ class AutomatonToXMLComposer { std::list<sax::Token> compose(const CompactNFA& automaton) const; std::list<sax::Token> compose(const DPDA& automaton) const; std::list<sax::Token> compose(const SinglePopDPDA& automaton) const; + std::list<sax::Token> compose(const InputDrivenNPDA& automaton) const; + std::list<sax::Token> compose(const VisiblyPushdownNPDA& automaton) const; std::list<sax::Token> compose(const NPDA& automaton) const; std::list<sax::Token> compose(const SinglePopNPDA& automaton) const; std::list<sax::Token> compose(const OneTapeDTM& automaton) const; diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp index 69e337f6ed01b3faaa7d433e9247cd789e272e21..bc74ed86146b486a353f52f6f7e9bf4f7ed49ce2 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp @@ -194,6 +194,14 @@ void FiniteAutomatonToStringComposer::Visit(void*, const SinglePopDPDA&) const { throw exception::AlibException(); } +void FiniteAutomatonToStringComposer::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException(); +} + +void FiniteAutomatonToStringComposer::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException(); +} + void FiniteAutomatonToStringComposer::Visit(void*, const NPDA&) const { throw exception::AlibException(); } diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h index 3b6c906f845dadaa8dd33c1e8fa8fca616327868..cb61d3edeea73abe5d22e1dfa1bda66e10b2f1f7 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h @@ -16,10 +16,12 @@ class FiniteAutomatonToStringComposer : public VisitableAutomatonBase::const_vis void Visit(void*, const DFA& automaton) const; void Visit(void*, const ExtendedNFA& automaton) const; void Visit(void*, const CompactNFA& automaton) const; - void Visit(void*, const NPDA& automaton) const; - void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const DPDA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; void composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const; diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..573c4aab55d26d8da8162c7470d65a0bf2eb3c0d --- /dev/null +++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp @@ -0,0 +1,213 @@ +/* + * InputDrivenNPDA.cpp + * + * Created on: Mar 25, 2013 + * Author: Jan Travnicek + */ + +#include "InputDrivenNPDA.h" +#include "../AutomatonException.h" +#include <ostream> +#include <sstream> +#include <algorithm> + +namespace automaton { + +InputDrivenNPDA::InputDrivenNPDA(const alphabet::Symbol& initialPushdownSymbol) : SingleInitialSymbolPushdownStoreAlphabet(initialPushdownSymbol) { + +} + +AutomatonBase* InputDrivenNPDA::clone() const { + return new InputDrivenNPDA(*this); +} + +AutomatonBase* InputDrivenNPDA::plunder() && { + return new InputDrivenNPDA(std::move(*this)); +} + +bool InputDrivenNPDA::removeState(const State& state) { + if (initialStates.find(state) != initialStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state."); + } + + if (finalStates.find(state) != finalStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state."); + } + + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (t->first.first == state || t->second.find(state) != t->second.end()) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + } + + return states.erase(state); +} + +bool InputDrivenNPDA::removeInputSymbol(const alphabet::Symbol& symbol) { + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->first.second == symbol) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used."); + } + + return inputAlphabet.erase(symbol); +} + +bool InputDrivenNPDA::removeStackSymbol(const alphabet::Symbol& symbol) { + for (const auto& pushdownStoreOperation : inputSymbolToPushdownStoreOperation) { + if (std::find(pushdownStoreOperation.second.first.begin(), pushdownStoreOperation.second.first.end(), symbol) != pushdownStoreOperation.second.first.end()) + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition."); + if (std::find(pushdownStoreOperation.second.second.begin(), pushdownStoreOperation.second.second.end(), symbol) != pushdownStoreOperation.second.second.end()) + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition."); + } + + if(initialSymbol == symbol) { + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol."); + } + + return stackAlphabet.erase(symbol); +} + +bool InputDrivenNPDA::setPushdownStoreOperation(const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push) { + if (inputAlphabet.find(input) == inputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + } + + for(std::vector<alphabet::Symbol>::const_iterator popSymbol = pop.begin(); popSymbol != pop.end(); popSymbol++) { + if (stackAlphabet.find(*popSymbol) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + (std::string) *popSymbol + "\" doesn't exist."); + } + } + + for(std::vector<alphabet::Symbol>::const_iterator pushSymbol = push.begin(); pushSymbol != push.end(); pushSymbol++) { + if (stackAlphabet.find(*pushSymbol) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + (std::string) *pushSymbol + "\" doesn't exist."); + } + } + + return inputSymbolToPushdownStoreOperation.insert(std::make_pair(input, std::make_pair(pop, push))).second; +} + +bool InputDrivenNPDA::clearPushdownStoreOperation(const alphabet::Symbol& input) { + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->first.second == input) + throw AutomatonException("Input symbol \"" + (std::string) input + "\" is used."); + } + + return inputSymbolToPushdownStoreOperation.erase(input); +} + +const std::map<alphabet::Symbol, std::pair<std::vector<alphabet::Symbol>, std::vector<alphabet::Symbol>>>& InputDrivenNPDA::getPushdownStoreOperations() const { + return inputSymbolToPushdownStoreOperation; +} + +bool InputDrivenNPDA::addTransition(const State& from, const alphabet::Symbol& input, const State& to) { + if (states.find(from) == states.end()) + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); + + if (inputAlphabet.find(input) == inputAlphabet.end()) + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + + if (inputSymbolToPushdownStoreOperation.find(input) == inputSymbolToPushdownStoreOperation.end()) + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + + if (states.find(to) == states.end()) + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist."); + + std::pair<State, alphabet::Symbol> key = std::make_pair(from, input); + + return transitions[key].insert(to).second; +} + +bool InputDrivenNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const State& to) { + std::pair<State, alphabet::Symbol> key = std::make_pair(from, input); + + return transitions[key].erase(to); +} + +const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >& InputDrivenNPDA::getTransitions() const { + return transitions; +} + +std::map<std::pair<State, alphabet::Symbol>, std::set<State> > InputDrivenNPDA::getTransitionsFromState(const State& from) const { + if( states.find(from) == states.end()) + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist"); + + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitionsFromState; + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->first.first == from) { + transitionsFromState[transition->first].insert(transition->second.begin(), transition->second.end()); + } + } + + return transitionsFromState; +} + +std::map<std::pair<State, alphabet::Symbol>, std::set<State> > InputDrivenNPDA::getTransitionsToState(const State& to) const { + if( states.find(to) == states.end()) + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist"); + + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitionsToState; + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->second.find(to) != transition->second.end()) { + transitionsToState[transition->first].insert(transition->second.begin(), transition->second.end()); + } + } + + return transitionsToState; +} + +bool InputDrivenNPDA::isDeterministic() const { + if (initialStates.size() != 1) { + return false; + } + + for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end(); + transition++) { + if (transition->second.size() != 1 || transition->second.size() != 0) { + return false; + } + } + + return true; +} + +bool InputDrivenNPDA::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool InputDrivenNPDA::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool InputDrivenNPDA::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool InputDrivenNPDA::operator==(const InputDrivenNPDA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions; +} + +bool InputDrivenNPDA::operator<(const InputDrivenNPDA& other) const { + return std::tie(states, inputAlphabet, initialStates, finalStates, transitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions); +} + +void InputDrivenNPDA::operator>>(std::ostream& out) const { + out << "(InputDrivenNPDA" + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialStates = " << initialStates + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + +InputDrivenNPDA::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.h b/alib2data/src/automaton/PDA/InputDrivenNPDA.h new file mode 100644 index 0000000000000000000000000000000000000000..8474cca0b3b29adbe867244006b46f948f3be1b2 --- /dev/null +++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.h @@ -0,0 +1,109 @@ +/* + * INPUT_DRIVEN_NPDA.h + * + * Created on: Mar 25, 2013 + * Author: Jan Travnicek + */ + +#ifndef INPUT_DRIVEN_NPDA_H_ +#define INPUT_DRIVEN_NPDA_H_ + +#include <map> +#include "../../std/map.hpp" +#include "../AutomatonBase.h" +#include "../common/MultiInitialStates.h" +#include "../common/InputAlphabet.h" +#include "../common/SingleInitialSymbolPushdownStoreAlphabet.h" +#include "../../alphabet/Symbol.h" + +namespace automaton { + +/** + * Represents Finite Automaton. + * Can store nondeterministic finite automaton without epsilon transitions. + */ +class InputDrivenNPDA : public std::acceptor<InputDrivenNPDA, VisitableAutomatonBase, std::acceptor<InputDrivenNPDA, alib::VisitableObjectBase, AutomatonBase> >, public SingleInitialSymbolPushdownStoreAlphabet, public MultiInitialStates, public InputAlphabet { +protected: + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitions; + std::map<alphabet::Symbol, std::pair<std::vector<alphabet::Symbol>, std::vector<alphabet::Symbol>>> inputSymbolToPushdownStoreOperation; +public: + InputDrivenNPDA(const alphabet::Symbol& initialPushdownSymbol); + + virtual AutomatonBase* clone() const; + + virtual AutomatonBase* plunder() &&; + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual bool removeState(const State& state); + + /** + * @copydoc Automaton::removeInputSymbol(const Symbol&) + */ + virtual bool removeInputSymbol(const alphabet::Symbol& symbol); + + /* + * @copydoc Automaton::removeStackSymbol(const Symbol&) + */ + virtual bool removeStackSymbol(const alphabet::Symbol& symbol); + + bool setPushdownStoreOperation(const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push); + + bool clearPushdownStoreOperation(const alphabet::Symbol& input); + + const std::map<alphabet::Symbol, std::pair<std::vector<alphabet::Symbol>, std::vector<alphabet::Symbol>>>& getPushdownStoreOperations() const; + + /** + * Adds transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + bool addTransition(const State& current, const alphabet::Symbol& input, const State& next); + + /** + * Removes transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const State& current, const alphabet::Symbol& input, const State& next); + + /** + * @return automaton transitions + */ + const std::map<std::pair<State, alphabet::Symbol>, std::set<State> >& getTransitions() const; + + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > getTransitionsFromState(const State& from) const; + + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > getTransitionsToState(const State& to) const; + /** + * Determines whether InputDrivenNPDA is deterministic. + * FA is deterministic if and only if: + * \li \c contains only 1 initial state. + * \li \c is epsilon free. Trivial for this class + * \li \c size of transition function \delta (from state, input symbol) \leq 1 + * @return true when automaton is deterministic, false otherwise + */ + bool isDeterministic() const; + + virtual bool operator<(const alib::ObjectBase& other) const; + virtual bool operator==(const alib::ObjectBase& other) const; + virtual bool operator>(const alib::ObjectBase& other) const; + + virtual bool operator==(const InputDrivenNPDA& other) const; + virtual bool operator<(const InputDrivenNPDA& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace automaton */ + +#endif /* INPUT_DRIVEN_NPDA_H_ */ diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b70f68d506168987e53dd0e534cc99f8807c552f --- /dev/null +++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp @@ -0,0 +1,245 @@ +/* + * VisiblyPushdownNPDA.cpp + * + * Created on: Apr 10, 2013 + * Author: Martin Zak + */ + +#include "VisiblyPushdownNPDA.h" +#include "../../std/map.hpp" +#include "../AutomatonException.h" +#include <algorithm> +#include <sstream> + +namespace automaton { + +VisiblyPushdownNPDA::VisiblyPushdownNPDA(const alphabet::Symbol& bottomOfTheStackSymbol) : BottomOfTheStackSymbolPushdownStoreAlphabet(bottomOfTheStackSymbol) { + +} + +AutomatonBase* VisiblyPushdownNPDA::clone() const { + return new VisiblyPushdownNPDA(*this); +} + +AutomatonBase* VisiblyPushdownNPDA::plunder() && { + return new VisiblyPushdownNPDA(std::move(*this)); +} + +bool VisiblyPushdownNPDA::removeState(const State& state) { + if (initialStates.find(state) != initialStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state."); + } + + if (finalStates.find(state) != finalStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state."); + } + + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > >& callTransition : callTransitions) { + if (state == callTransition.first.first) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + for(const std::pair<State, alphabet::Symbol>& target : callTransition.second) { + if(target.first == state) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + } + } + + for (const std::pair<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> >& returnTransition : returnTransitions) { + if (state == std::get<0>(returnTransition.first)) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + for(const State& target : returnTransition.second) { + if(target == state) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + } + } + + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<State> >& localTransition : localTransitions) { + if (state == localTransition.first.first) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + for(const State& target : localTransition.second) { + if(target == state) + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition."); + } + } + + return states.erase(state); +} + +bool VisiblyPushdownNPDA::removeInputSymbol(const alphabet::Symbol& symbol) { + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > >& callTransition : callTransitions) { + if (symbol == callTransition.first.second) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> >& returnTransition : returnTransitions) { + if (symbol == std::get<1>(returnTransition.first)) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<State> >& localTransition : localTransitions) { + if (symbol == localTransition.first.second) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + return callInputAlphabet.erase(symbol) || returnInputAlphabet.erase(symbol) || localInputAlphabet.erase(symbol); +} + +bool VisiblyPushdownNPDA::removeStackSymbol(const alphabet::Symbol& symbol) { + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > >& callTransition : callTransitions) { + if (symbol == callTransition.first.second) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> >& returnTransition : returnTransitions) { + if (symbol == std::get<1>(returnTransition.first)) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::pair<State, alphabet::Symbol>, std::set<State> >& localTransition : localTransitions) { + if (symbol == localTransition.first.second) + throw AutomatonException("State \"" + (std::string) symbol + "\" is used in transition."); + } + + if(bottomOfTheStackSymbol == symbol) { + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol."); + } + + return stackAlphabet.erase(symbol); +} + +bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { + if (states.find(from) == states.end()) { + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); + } + + if (callInputAlphabet.find(input) == callInputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + } + + if (states.find(to) == states.end()) { + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist."); + } + + if (stackAlphabet.find(push) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + (std::string) push + "\" doesn't exist."); + } + + std::pair<State, alphabet::Symbol> key(from, input); + std::pair<automaton::State, alphabet::Symbol> value = std::make_pair(to, push); + + return callTransitions[key].insert(value).second; +} + +bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to) { + if (states.find(from) == states.end()) { + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); + } + + if (callInputAlphabet.find(input) == callInputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + } + + if (states.find(to) == states.end()) { + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist."); + } + + if (stackAlphabet.find(pop) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + (std::string) pop + "\" doesn't exist."); + } + + std::tuple<State, alphabet::Symbol, alphabet::Symbol> key(from, input, pop); + + return returnTransitions[key].insert(to).second; +} + +bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const State& to) { + if (states.find(from) == states.end()) { + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); + } + + if (callInputAlphabet.find(input) == callInputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist."); + } + + if (states.find(to) == states.end()) { + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist."); + } + + std::pair<State, alphabet::Symbol> key(from, input); + + return localTransitions[key].insert(to).second; +} + +bool VisiblyPushdownNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { + std::pair<State, alphabet::Symbol> key(from, input); + std::pair<automaton::State, alphabet::Symbol> value = std::make_pair(to, push); + + return callTransitions[key].erase(value); +} + +bool VisiblyPushdownNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to) { + std::tuple<State, alphabet::Symbol, alphabet::Symbol> key(from, input, pop); + + return returnTransitions[key].erase(to); +} + +bool VisiblyPushdownNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const State& to) { + std::pair<State, alphabet::Symbol> key(from, input); + + return localTransitions[key].erase(to); +} + +const std::map<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > > VisiblyPushdownNPDA::getCallTransitions() const { + return callTransitions; +} + +const std::map<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> > VisiblyPushdownNPDA::getReturnTransitions() const { + return returnTransitions; +} + +const std::map<std::pair<State, alphabet::Symbol>, std::set<State> > VisiblyPushdownNPDA::getLocalTransitions() const { + return localTransitions; +} + +bool VisiblyPushdownNPDA::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool VisiblyPushdownNPDA::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool VisiblyPushdownNPDA::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool VisiblyPushdownNPDA::operator==(const VisiblyPushdownNPDA& other) const { + return this->states == other.states && this->callInputAlphabet == other.callInputAlphabet && this->returnInputAlphabet == other.returnInputAlphabet && this->localInputAlphabet == other.localInputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->bottomOfTheStackSymbol == other.bottomOfTheStackSymbol && this->callTransitions == other.callTransitions && this->returnTransitions == other.returnTransitions && this->localTransitions == other.localTransitions; +} + +bool VisiblyPushdownNPDA::operator<(const VisiblyPushdownNPDA& other) const { + return std::tie(states, callInputAlphabet, returnInputAlphabet, localInputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.callInputAlphabet, other.returnInputAlphabet, other.localInputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions); +} + +void VisiblyPushdownNPDA::operator>>(std::ostream& out) const { + out << "(VisiblyPushdownNPDA" + << "states = " << states + << "callInputAlphabet = " << callInputAlphabet + << "returnInputAlphabet = " << returnInputAlphabet + << "localInputAlphabet = " << localInputAlphabet + << "initialStates = " << initialStates + << "finalStates = " << finalStates + << "stackAlphabet = " << stackAlphabet + << "bottomOfTheStackSymbol = " << bottomOfTheStackSymbol + << "callTransitions = " << callTransitions + << "returnTransitions = " << returnTransitions + << "localTransitions = " << localTransitions + << ")"; +} + +VisiblyPushdownNPDA::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h new file mode 100644 index 0000000000000000000000000000000000000000..e446916aafaf65999e2ef9f6a9862a5c85e84d50 --- /dev/null +++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h @@ -0,0 +1,125 @@ +/* + * VISIBLY_PUSHDOWN_NPDA.h + * + * Created on: Mar 25, 2013 + * Author: Jan Travnicek + */ + +#ifndef VISIBLY_PUSHDOWN_NPDA_H_ +#define VISIBLY_PUSHDOWN_NPDA_H_ + +#include <map> +#include <vector> +#include "../../std/map.hpp" +#include "../AutomatonBase.h" +#include "../common/MultiInitialStates.h" +#include "../common/CallReturnLocalInputAlphabet.h" +#include "../common/BottomOfTheStackSymbolPushdownStoreAlphabet.h" +#include "../../alphabet/Symbol.h" + +namespace automaton { + +/** + * Represents Finite Automaton. + * Can store nondeterministic finite automaton without epsilon transitions. + */ +class VisiblyPushdownNPDA : public std::acceptor<VisiblyPushdownNPDA, VisitableAutomatonBase, std::acceptor<VisiblyPushdownNPDA, alib::VisitableObjectBase, AutomatonBase> >, public BottomOfTheStackSymbolPushdownStoreAlphabet, public MultiInitialStates, public CallReturnLocalInputAlphabet { +protected: + std::map<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > > callTransitions; + std::map<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> > returnTransitions; + std::map<std::pair<State, alphabet::Symbol>, std::set<State> > localTransitions; +public: + VisiblyPushdownNPDA(const alphabet::Symbol& bottomOfTheStackSymbol); + + virtual AutomatonBase* clone() const; + + virtual AutomatonBase* plunder() &&; + + /** + * @copydoc Automaton::removeState(const State&) + */ + virtual bool removeState(const State& state); + + /** + * @copydoc Automaton::removeInputSymbol(const Symbol&) + */ + virtual bool removeInputSymbol(const alphabet::Symbol& symbol); + + /* + * @copydoc Automaton::removeStackSymbol(const Symbol&) + */ + virtual bool removeStackSymbol(const alphabet::Symbol& symbol); + + /** + * Adds call transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + bool addTransition(const State& current, const alphabet::Symbol& input, const State& next, const alphabet::Symbol& push); + + /** + * Adds return transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + bool addTransition(const State& current, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& next); + + /** + * Adds local transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + bool addTransition(const State& current, const alphabet::Symbol& input, const State& next); + + /** + * Removes call transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const State& current, const alphabet::Symbol& input, const State& next, const alphabet::Symbol& push); + + /** + * Removes return transition from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const State& current, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& next); + + /** + * Removes transition local from the automaton. + * @param transition transition to remove + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const State& current, const alphabet::Symbol& input, const State& next); + + const std::map<std::pair<State, alphabet::Symbol>, std::set<std::pair<State, alphabet::Symbol> > > getCallTransitions() const; + + const std::map<std::tuple<State, alphabet::Symbol, alphabet::Symbol>, std::set<State> > getReturnTransitions() const; + + const std::map<std::pair<State, alphabet::Symbol>, std::set<State> > getLocalTransitions() const; + + virtual bool operator<(const alib::ObjectBase& other) const; + virtual bool operator==(const alib::ObjectBase& other) const; + virtual bool operator>(const alib::ObjectBase& other) const; + + virtual bool operator==(const VisiblyPushdownNPDA& other) const; + virtual bool operator<(const VisiblyPushdownNPDA& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace automaton */ + +#endif /* VISIBLY_PUSHDOWN_NPDA_H_ */ diff --git a/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.cpp b/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..564e0e33f73795b37bfb3745d93325fd16aca967 --- /dev/null +++ b/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.cpp @@ -0,0 +1,30 @@ +/* + * BottomOfTheStackSymbolPushdownStoreAlphabet.cpp + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#include "BottomOfTheStackSymbolPushdownStoreAlphabet.h" +#include "../AutomatonException.h" +#include <algorithm> + +namespace automaton { + +BottomOfTheStackSymbolPushdownStoreAlphabet::BottomOfTheStackSymbolPushdownStoreAlphabet(const alphabet::Symbol& bottomOfTheStackSymbol) : bottomOfTheStackSymbol(bottomOfTheStackSymbol) { + addStackSymbol(bottomOfTheStackSymbol); +} + +void BottomOfTheStackSymbolPushdownStoreAlphabet::setBottomOfTheStackSymbol(const alphabet::Symbol& start) { + if (stackAlphabet.find(start) == stackAlphabet.end()) { + throw AutomatonException("Stack symbol \"" + (std::string) start + "\" doesn't exist."); + } + + bottomOfTheStackSymbol = start; +} + +const alphabet::Symbol& BottomOfTheStackSymbolPushdownStoreAlphabet::getBottomOfTheStackSymbol() const { + return bottomOfTheStackSymbol; +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.h b/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.h new file mode 100644 index 0000000000000000000000000000000000000000..e177cd142148d319eb4a205141c4be6dfc80091b --- /dev/null +++ b/alib2data/src/automaton/common/BottomOfTheStackSymbolPushdownStoreAlphabet.h @@ -0,0 +1,44 @@ +/* + * BottomOfTheStackSymbolPushdownStoreAlphabet.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef BOTTOM_OF_THE_STACK_SYMBOL_PUSHDOWN_STORE_ALPHABET_H_ +#define BOTTOM_OF_THE_STACK_SYMBOL_PUSHDOWN_STORE_ALPHABET_H_ + +#include <set> +#include "../../alphabet/Symbol.h" +#include "PushdownStoreAlphabet.h" + +namespace automaton { + +/** + * Push Down Automaton + */ +class BottomOfTheStackSymbolPushdownStoreAlphabet : public PushdownStoreAlphabet { +protected: + alphabet::Symbol bottomOfTheStackSymbol; +public: + BottomOfTheStackSymbolPushdownStoreAlphabet(const alphabet::Symbol& bottomOfTheStackSymbol); + + /** + * Set bottomOfTheStack symbol. BottomOfTheStack symbol is symbol that is pushed + * to the stack when BottomOfTheStackSymbolPushdownStoreAlphabet is created. + * @param start new bottomOfTheStack symbol + * @throws AutomatonException when symbol is not present in the stack alphabet + */ + void setBottomOfTheStackSymbol(const alphabet::Symbol& start); + + + /** + * @return list of start symbols + */ + const alphabet::Symbol& getBottomOfTheStackSymbol() const; + +}; + +} /* namespace automaton */ + +#endif /* BOTTOM_OF_THE_STACK_SYMBOL_PUSHDOWN_STORE_ALPHABET_H_ */ diff --git a/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.cpp b/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a031f3773ce6d8db5fc703db41c0b10ee7ba220 --- /dev/null +++ b/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.cpp @@ -0,0 +1,100 @@ +/* + * CallReturnLocalInputAlphabet.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "CallReturnLocalInputAlphabet.h" + +#include <algorithm> +#include "../AutomatonException.h" + +namespace automaton { + +const std::set<alphabet::Symbol>& CallReturnLocalInputAlphabet::getCallInputAlphabet() const { + return callInputAlphabet; +} + +bool CallReturnLocalInputAlphabet::addCallInputSymbol(const alphabet::Symbol& symbol) { + if(returnInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in return alphabet"); + if(localInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in local alphabet"); + return callInputAlphabet.insert(symbol).second; +} + +void CallReturnLocalInputAlphabet::setCallInputSymbols(const std::set<alphabet::Symbol>& newSymbols) { + std::set<alphabet::Symbol> removed; + std::set_difference(callInputAlphabet.begin(), callInputAlphabet.end(), newSymbols.begin(), newSymbols.end(), std::inserter(removed, removed.end())); + + std::set<alphabet::Symbol> added; + std::set_difference(newSymbols.begin(), newSymbols.end(), callInputAlphabet.begin(), callInputAlphabet.end(), std::inserter(added, added.end())); + + for(const alphabet::Symbol& removedSymbol : removed) { + removeInputSymbol(removedSymbol); + } + + for(const alphabet::Symbol& addedSymbol : added) { + addCallInputSymbol(addedSymbol); + } +} + +const std::set<alphabet::Symbol>& CallReturnLocalInputAlphabet::getReturnInputAlphabet() const { + return returnInputAlphabet; +} + +bool CallReturnLocalInputAlphabet::addReturnInputSymbol(const alphabet::Symbol& symbol) { + if(localInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in local alphabet"); + if(callInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in call alphabet"); + return returnInputAlphabet.insert(symbol).second; +} + +void CallReturnLocalInputAlphabet::setReturnInputSymbols(const std::set<alphabet::Symbol>& newSymbols) { + std::set<alphabet::Symbol> removed; + std::set_difference(returnInputAlphabet.begin(), returnInputAlphabet.end(), newSymbols.begin(), newSymbols.end(), std::inserter(removed, removed.end())); + + std::set<alphabet::Symbol> added; + std::set_difference(newSymbols.begin(), newSymbols.end(), returnInputAlphabet.begin(), returnInputAlphabet.end(), std::inserter(added, added.end())); + + for(const alphabet::Symbol& removedSymbol : removed) { + removeInputSymbol(removedSymbol); + } + + for(const alphabet::Symbol& addedSymbol : added) { + addReturnInputSymbol(addedSymbol); + } +} + +const std::set<alphabet::Symbol>& CallReturnLocalInputAlphabet::getLocalInputAlphabet() const { + return localInputAlphabet; +} + +bool CallReturnLocalInputAlphabet::addLocalInputSymbol(const alphabet::Symbol& symbol) { + if(callInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in call alphabet"); + if(returnInputAlphabet.count(symbol)) + throw exception::AlibException("Input symbol " + (std::string) symbol + " already in return alphabet"); + return localInputAlphabet.insert(symbol).second; +} + +void CallReturnLocalInputAlphabet::setLocalInputSymbols(const std::set<alphabet::Symbol>& newSymbols) { + std::set<alphabet::Symbol> removed; + std::set_difference(localInputAlphabet.begin(), localInputAlphabet.end(), newSymbols.begin(), newSymbols.end(), std::inserter(removed, removed.end())); + + std::set<alphabet::Symbol> added; + std::set_difference(newSymbols.begin(), newSymbols.end(), localInputAlphabet.begin(), localInputAlphabet.end(), std::inserter(added, added.end())); + + for(const alphabet::Symbol& removedSymbol : removed) { + removeInputSymbol(removedSymbol); + } + + for(const alphabet::Symbol& addedSymbol : added) { + addLocalInputSymbol(addedSymbol); + } +} + +} /* namespace automaton */ + diff --git a/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.h b/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.h new file mode 100644 index 0000000000000000000000000000000000000000..35c988b36d88f5eccd8ea16513fd4f7718578958 --- /dev/null +++ b/alib2data/src/automaton/common/CallReturnLocalInputAlphabet.h @@ -0,0 +1,96 @@ +/* + * CallReturnLocalInputAlphabet.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef CALL_RETURN_LOCAL_INPUT_ALPHABET_H_ +#define CALL_RETURN_LOCAL_INPUT_ALPHABET_H_ + +#include <set> +#include "../../alphabet/Symbol.h" + + +namespace automaton { + +/** + * Abstract base class for all automatons. Contains common elements of automatons. + */ +class CallReturnLocalInputAlphabet { +protected: + std::set<alphabet::Symbol> callInputAlphabet; + std::set<alphabet::Symbol> returnInputAlphabet; + std::set<alphabet::Symbol> localInputAlphabet; +public: + /** + * Adds input symbol to input alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol already exists + */ + bool addCallInputSymbol(const alphabet::Symbol& symbol); + + /** + * Sets input symbols of the automaton. + * @param symbols Symbols to set + * @throws AutomatonException when symbol already exists + */ + void setCallInputSymbols(const std::set<alphabet::Symbol>& symbols); + + /** + * Adds input symbol to input alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol already exists + */ + bool addReturnInputSymbol(const alphabet::Symbol& symbol); + + /** + * Sets input symbols of the automaton. + * @param symbols Symbols to set + * @throws AutomatonException when symbol already exists + */ + void setReturnInputSymbols(const std::set<alphabet::Symbol>& symbols); + + /** + * Adds input symbol to input alphabet. + * @param symbol Symbol to add + * @throws AutomatonException when symbol already exists + */ + bool addLocalInputSymbol(const alphabet::Symbol& symbol); + + /** + * Sets input symbols of the automaton. + * @param symbols Symbols to set + * @throws AutomatonException when symbol already exists + */ + void setLocalInputSymbols(const std::set<alphabet::Symbol>& symbols); + + /** + * Removes input symbol from the input alphabet. + * @param symbol Symbol to remove + * @throws AutomatonException when symbol is not present in input alphabet + * or when symbol is part of the transition + */ + virtual bool removeInputSymbol(const alphabet::Symbol& symbol) = 0; + + /** + * @return the input alphabet + */ + const std::set<alphabet::Symbol>& getCallInputAlphabet() const; + + /** + * @return the input alphabet + */ + const std::set<alphabet::Symbol>& getReturnInputAlphabet() const; + + /** + * @return the input alphabet + */ + const std::set<alphabet::Symbol>& getLocalInputAlphabet() const; + +}; + +} /* namespace automaton */ + +#endif /* CALL_RETURN_LOCAL_INPUT_ALPHABET_H_ */ + diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index cec271d494f2e7fcdf156133d91d5696366414c0..ceaf184d492374810931ea5efb237778096ab967 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -29,6 +29,8 @@ class DPDA; class SinglePopDPDA; class NPDA; class SinglePopNPDA; +class InputDrivenNPDA; +class VisiblyPushdownNPDA; class OneTapeDTM; } @@ -96,7 +98,7 @@ namespace alib { typedef std::acceptor_base< exception::AlibException, - automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM, + automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM, grammar::UnknownGrammar, grammar::LeftLG, grammar::LeftRG, grammar::RightLG, grammar::RightRG, grammar::LG, grammar::CFG, grammar::EpsilonFreeCFG, grammar::CNF, grammar::GNF, grammar::CSG, grammar::NonContractingGrammar, grammar::ContextPreservingUnrestrictedGrammar, grammar::UnrestrictedGrammar, label::StringLabel, label::IntegerLabel, label::CharacterLabel, label::LabelSetLabel, label::LabelPairLabel, regexp::UnboundedRegExp, regexp::FormalRegExp, @@ -109,7 +111,7 @@ class ObjectBase : public alib::base< ObjectBase, exception::AlibException, - automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM, + automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM, grammar::UnknownGrammar, grammar::LeftLG, grammar::LeftRG, grammar::RightLG, grammar::RightRG, grammar::LG, grammar::CFG, grammar::EpsilonFreeCFG, grammar::CNF, grammar::GNF, grammar::CSG, grammar::NonContractingGrammar, grammar::ContextPreservingUnrestrictedGrammar, grammar::UnrestrictedGrammar, label::StringLabel, label::IntegerLabel, label::CharacterLabel, label::LabelSetLabel, label::LabelPairLabel, regexp::UnboundedRegExp, regexp::FormalRegExp,