diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp index 41c94810a2c52a0062bace2448ad2bff3f2f963e..0b0d3d5901b71d95de726d17c21022addc1dd874 100644 --- a/aconvert2/src/DotConverter.cpp +++ b/aconvert2/src/DotConverter.cpp @@ -17,6 +17,7 @@ #include <automaton/PDA/SinglePopNPDA.h> #include <automaton/PDA/InputDrivenNPDA.h> #include <automaton/PDA/VisiblyPushdownNPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> #include <automaton/PDA/DPDA.h> #include <automaton/PDA/SinglePopDPDA.h> #include <automaton/TM/OneTapeDTM.h> @@ -352,6 +353,41 @@ void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream out << "}"; } +void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& 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; @@ -865,6 +901,116 @@ void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const } } +void DotConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& 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; + if(transition.first.second.is<string::Epsilon>()) + symbol = "&epsilon"; + else + symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + + symbol += " |"; + + //Pop part + symbol += " ε"; + symbol += " ->"; + + std::string symbol2; + for(const auto& to : transition.second) { + symbol2 = symbol; + alphabet::SymbolToStringComposer composer; + symbol2 += " " + 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, symbol2)); + } else { + mapit->second += ", " + symbol2; + } + } + } + + for (const auto& transition : pda.getReturnTransitions()) { + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + if(std::get<1>(transition.first).is<string::Epsilon>()) + symbol = "ε"; + else + symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + + symbol += " |"; + + //Pop part + symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " ->"; + + std::string symbol2; + for(const auto& to : transition.second) { + symbol2 = symbol; + symbol2 += " ε"; + + //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, symbol2)); + } else { + mapit->second += ", " + symbol2; + } + } + } + + for (const auto& transition : pda.getLocalTransitions()) { + std::string symbol; + + //input symbol + alphabet::SymbolToStringComposer composer; + if(transition.first.second.is<string::Epsilon>()) + symbol = "ε"; + else + symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + + symbol += " |"; + + //Pop part + symbol += " ε"; + symbol += " ->"; + + std::string symbol2; + for(const auto& to : transition.second) { + symbol2 = symbol; + symbol2 += " ε"; + + //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, symbol2)); + } else { + mapit->second += ", " + symbol2; + } + } + } + + //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; @@ -1069,6 +1215,10 @@ void DotConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& autom DotConverter::convert(automaton, *((std::ostream*) data)); } +void DotConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& 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 8f59741ec09164ed69f4ccb50cb0fa6ca72f34ce..98bdf797c0b10c89c6a0bfe96d47c7686d9cfa5f 100644 --- a/aconvert2/src/DotConverter.h +++ b/aconvert2/src/DotConverter.h @@ -26,6 +26,7 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ 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::RealTimeHeightDeterministicNPDA& 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; @@ -40,6 +41,7 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ 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::RealTimeHeightDeterministicNPDA& 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); @@ -58,6 +60,7 @@ public: 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::RealTimeHeightDeterministicNPDA& 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 fa023d640c6a827ca3eedb8b13a685fdd77ee50f..bca98470c666a1e539134334955595374547ad71 100644 --- a/aconvert2/src/GasTexConverter.cpp +++ b/aconvert2/src/GasTexConverter.cpp @@ -16,6 +16,7 @@ #include <automaton/PDA/SinglePopDPDA.h> #include <automaton/PDA/InputDrivenNPDA.h> #include <automaton/PDA/VisiblyPushdownNPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> #include <automaton/PDA/NPDA.h> #include <automaton/PDA/SinglePopNPDA.h> #include <automaton/TM/OneTapeDTM.h> @@ -388,6 +389,45 @@ void GasTexConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostr out << "\\end{picture}\n"; } +void GasTexConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& 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"; @@ -815,6 +855,88 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std printTransitionMap(transitionMap, out); } +void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& 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; + if(transition.first.second.is<string::Epsilon>()) + symbol = "$\\varepsilon;$"; + else + symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + + 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; + if(std::get<1>(transition.first).is<string::Epsilon>()) + symbol = "$\\varepsilon;$"; + else + symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + + 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; + if(transition.first.second.is<string::Epsilon>()) + symbol = "$\\varepsilon;$"; + else + symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + + 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; @@ -959,6 +1081,10 @@ void GasTexConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& au GasTexConverter::convert(automaton, *((std::ostream*) data)); } +void GasTexConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& 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 80072c67c1aea726374301e4339ef912395ea544..31842aba6a9482da6d3468552f50e63cbe462891 100644 --- a/aconvert2/src/GasTexConverter.h +++ b/aconvert2/src/GasTexConverter.h @@ -26,6 +26,7 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ 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::RealTimeHeightDeterministicNPDA& 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; @@ -43,6 +44,7 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ 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::RealTimeHeightDeterministicNPDA& 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); @@ -61,6 +63,7 @@ public: 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::RealTimeHeightDeterministicNPDA& 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/alib2algo/src/automaton/EpsilonClosure.cpp b/alib2algo/src/automaton/EpsilonClosure.cpp index 54ce6f1d52a876ef40d5468a93472c7a84e118c6..e183968d4e92ebe8f5435371a7d816b5d6dae010 100644 --- a/alib2algo/src/automaton/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/EpsilonClosure.cpp @@ -172,6 +172,10 @@ void EpsilonClosure::Visit(void*, const VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void EpsilonClosure::Visit(void*, const RealTimeHeightDeterministicNPDA&) 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 e6f026a7c79ebca86bfe93f62b5233bf277e4e5d..bc4a867a2b9a9d6ab861eca1c5305cf36aa43560 100644 --- a/alib2algo/src/automaton/EpsilonClosure.h +++ b/alib2algo/src/automaton/EpsilonClosure.h @@ -41,6 +41,7 @@ private: 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 RealTimeHeightDeterministicNPDA& 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/automaton/FSMSingleInitialState.cpp b/alib2algo/src/automaton/FSMSingleInitialState.cpp index 9aa1d34b9a45cf178c11ef676748dcf4922dac69..286bd058364532f500944c65566e852985451cee 100644 --- a/alib2algo/src/automaton/FSMSingleInitialState.cpp +++ b/alib2algo/src/automaton/FSMSingleInitialState.cpp @@ -108,6 +108,10 @@ void FSMSingleInitialState::Visit(void*, const VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); } +void FSMSingleInitialState::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + void FSMSingleInitialState::Visit(void*, const NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); } diff --git a/alib2algo/src/automaton/FSMSingleInitialState.h b/alib2algo/src/automaton/FSMSingleInitialState.h index 09b67a5f84ac3b0db60f74c86b84510a65d31f64..a1cac7f05d6bf5d6259dd16843c8deab03b10140 100644 --- a/alib2algo/src/automaton/FSMSingleInitialState.h +++ b/alib2algo/src/automaton/FSMSingleInitialState.h @@ -43,6 +43,7 @@ private: 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 RealTimeHeightDeterministicNPDA& 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/automaton/FSMTotal.cpp b/alib2algo/src/automaton/FSMTotal.cpp index a0d8fb324745fa1eca035e2cae207f0f86f11949..6b0c83f1a633f1da31f4ab319820309701ee9c02 100644 --- a/alib2algo/src/automaton/FSMTotal.cpp +++ b/alib2algo/src/automaton/FSMTotal.cpp @@ -100,6 +100,10 @@ void FSMTotal::Visit(void*, const VisiblyPushdownNPDA&) const { throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); } +void FSMTotal::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + void FSMTotal::Visit(void*, const NPDA&) const { throw exception::AlibException("Unsupported automaton type NPDA"); } diff --git a/alib2algo/src/automaton/FSMTotal.h b/alib2algo/src/automaton/FSMTotal.h index 420abb04b34383bffd02c2b903c9249f9b9b9ca1..950ec9f659755bf004ac107e9318b29cb1a1c22e 100644 --- a/alib2algo/src/automaton/FSMTotal.h +++ b/alib2algo/src/automaton/FSMTotal.h @@ -42,6 +42,7 @@ private: 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 RealTimeHeightDeterministicNPDA& 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 6e8da9ec6b79d39cb1988043ddf5a8f2e38fa96e..12e09fae7de98de43b1a6db0ea9af252b2cb8480 100644 --- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp +++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp @@ -112,7 +112,12 @@ void StateEliminationFormal::Visit(void*, const automaton::InputDrivenNPDA&) con void StateEliminationFormal::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void StateEliminationFormal::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); } void StateEliminationFormal::Visit(void*, const automaton::NPDA&) const diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h index 7a1119185e93b88bbc8211f028fdacec7ab4b70c..d94d57d849658b452b691585402543842452e460 100644 --- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h +++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h @@ -48,6 +48,7 @@ private: 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::RealTimeHeightDeterministicNPDA& 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 c468c21e16c1ea2339a974e3a626806c6504f59b..dd4422ec1ec9934326fa87afdd5a11ac18ad65e1 100644 --- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp +++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp @@ -110,7 +110,12 @@ void StateEliminationUnbounded::Visit(void*, const automaton::InputDrivenNPDA&) void StateEliminationUnbounded::Visit(void*, const automaton::VisiblyPushdownNPDA&) const { - throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void StateEliminationUnbounded::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); } void StateEliminationUnbounded::Visit(void*, const automaton::NPDA&) const diff --git a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h index 337758bbeba5e8027b89a5ae0ef465dae6caf408..5cbd9c8840bd2a983d2bb74dba101ccbd09e7035 100644 --- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h +++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h @@ -48,6 +48,7 @@ private: 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::RealTimeHeightDeterministicNPDA& 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 46e952c7c913db075952241b1a39a6129e108c12..90bd5233c12d9e38aca47554e68d49b78c8b8ed3 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp +++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp @@ -158,6 +158,10 @@ void FAtoLRGConverter::Visit(void*, const automaton::VisiblyPushdownNPDA&) const throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FAtoLRGConverter::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) 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 72bad6fceb5a8e17daa275546973823d45250c19..0daa7a5e205546dc646b3f4e4dd8bd821bad6e61 100644 --- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h +++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h @@ -41,6 +41,7 @@ private: 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::RealTimeHeightDeterministicNPDA& 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/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp index 2ffe36d25dbce7ae816158099891a07138d87fb2..d841b06996428139da91ba772e6892735e68b133 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp +++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp @@ -152,6 +152,10 @@ void FAtoRRGConverter::Visit(void*, const automaton::VisiblyPushdownNPDA&) const throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FAtoRRGConverter::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) 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 830f442b087ba4f5641f68c9a79e245bb217d136..15c96024132f0f63f509224acca47439c72436d8 100644 --- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h +++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h @@ -39,6 +39,7 @@ private: 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::RealTimeHeightDeterministicNPDA& 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/determinize/vpa/VPADeterminizer.cpp b/alib2algo/src/determinize/vpa/VPADeterminizer.cpp index 56478c72e5764d11a33a9238ca2ef3d90c6e0bd5..4a2d1958761515651075bcebaddb3a0d101bd3b2 100644 --- a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp +++ b/alib2algo/src/determinize/vpa/VPADeterminizer.cpp @@ -48,7 +48,7 @@ void addRetTransition(const automaton::State& from, const alphabet::Symbol& inpu deterministic.addState(to); deterministic.addStackSymbol(dvpdaSymbol); - deterministic.addTransition(from, input, dvpdaSymbol, to); + deterministic.addReturnTransition(from, input, dvpdaSymbol, to); } void retInitial(const automaton::State& state, const alphabet::Symbol& pdaSymbol, const alphabet::Symbol& input, const automaton::VisiblyPushdownNPDA& nondeterministic, automaton::VisiblyPushdownNPDA& deterministic) { @@ -129,7 +129,7 @@ void addCallTransition(const automaton::State& from, const alphabet::Symbol& inp deterministic.addState(to); deterministic.addStackSymbol(dvpdaSymbol); - deterministic.addTransition(from, input, to, dvpdaSymbol); + deterministic.addCallTransition(from, input, to, dvpdaSymbol); } std::set<label::Label> retrieveDSubSet(const std::set<std::pair<label::Label, label::Label>>& localOperation) { @@ -176,7 +176,7 @@ void addLocalTransition(const automaton::State& from, const alphabet::Symbol& in deterministic.addState(from); deterministic.addState(to); - deterministic.addTransition(from, input, to); + deterministic.addLocalTransition(from, input, to); } void local(const automaton::State& state, const alphabet::Symbol& input, const automaton::VisiblyPushdownNPDA& nondeterministic, automaton::VisiblyPushdownNPDA& deterministic) { diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp index 8c0e26689351b0d13faeb153f661844e1056942d..0c60d41a0ad46854142932a05e9b8b30c119cf88 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp @@ -115,6 +115,10 @@ void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) cons throw exception::AlibException("Unsupported automaton type UnknownAutomaton"); } +void FSMEpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) 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 a456c085a3edc978ad152c9b4b5c1290117302b2..3aa68eaa7525e9632c5017f5cade8cb4b12f79be 100644 --- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h +++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h @@ -42,6 +42,7 @@ private: 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::RealTimeHeightDeterministicNPDA& 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/test-src/determinize/determinizeTest.cpp b/alib2algo/test-src/determinize/determinizeTest.cpp index e19b33138d46646285795f37cf1c905d7be10fee..760337638862368fdf5435af5bf62519b09c262c 100644 --- a/alib2algo/test-src/determinize/determinizeTest.cpp +++ b/alib2algo/test-src/determinize/determinizeTest.cpp @@ -61,8 +61,6 @@ void determinizeTest::testDeterminizeIDPDA() { automaton.addInitialState(automaton::State(1)); automaton.addFinalState(automaton::State(3)); - alib::DataFactory::toStdout(automaton); - automaton::DPDA determinized = determinize::IDPDADeterminizer::determinize(automaton); CPPUNIT_ASSERT(determinized.getStates().size() == 3); @@ -91,25 +89,23 @@ void determinizeTest::testDeterminizeVPA() { automaton.addState(automaton::State(6)); - automaton.addTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(0), alphabet::symbolFrom('A')); - automaton.addTransition(automaton::State(0), alphabet::symbolFrom('^'), alphabet::symbolFrom('A'), automaton::State(0)); + automaton.addCallTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(0), alphabet::symbolFrom('A')); + automaton.addReturnTransition(automaton::State(0), alphabet::symbolFrom('^'), alphabet::symbolFrom('A'), automaton::State(0)); - automaton.addTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(1), alphabet::symbolFrom('B')); + automaton.addCallTransition(automaton::State(0), alphabet::symbolFrom('a'), automaton::State(1), alphabet::symbolFrom('B')); - automaton.addTransition(automaton::State(1), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('C')); - automaton.addTransition(automaton::State(2), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('D')); - automaton.addTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('D'), automaton::State(2)); - automaton.addTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('C'), automaton::State(3)); + automaton.addCallTransition(automaton::State(1), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('C')); + automaton.addCallTransition(automaton::State(2), alphabet::symbolFrom('a'), automaton::State(2), alphabet::symbolFrom('D')); + automaton.addReturnTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('D'), automaton::State(2)); + automaton.addReturnTransition(automaton::State(2), alphabet::symbolFrom('^'), alphabet::symbolFrom('C'), automaton::State(3)); - automaton.addTransition(automaton::State(3), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('E')); - automaton.addTransition(automaton::State(4), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('F')); - automaton.addTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('F'), automaton::State(4)); - automaton.addTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('E'), automaton::State(5)); + automaton.addCallTransition(automaton::State(3), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('E')); + automaton.addCallTransition(automaton::State(4), alphabet::symbolFrom('a'), automaton::State(4), alphabet::symbolFrom('F')); + automaton.addReturnTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('F'), automaton::State(4)); + automaton.addReturnTransition(automaton::State(4), alphabet::symbolFrom('^'), alphabet::symbolFrom('E'), automaton::State(5)); - automaton.addTransition(automaton::State(5), alphabet::symbolFrom('^'), alphabet::symbolFrom('B'), automaton::State(6)); + automaton.addReturnTransition(automaton::State(5), alphabet::symbolFrom('^'), alphabet::symbolFrom('B'), automaton::State(6)); automaton.addInitialState(automaton::State(0)); automaton.addFinalState(automaton::State(4)); - - alib::DataFactory::toStdout(automaton); } diff --git a/alib2data/src/Api.cpp b/alib2data/src/Api.cpp index fa0ef6b0d86022a11dbb964fb0975313e34a294e..39901ba263cf9847d2965792aafe2496af18a2af 100644 --- a/alib2data/src/Api.cpp +++ b/alib2data/src/Api.cpp @@ -218,6 +218,14 @@ std::list<sax::Token> api<automaton::VisiblyPushdownNPDA>::compose(const automat return ToXMLComposers::automatonComposer.compose(data); } +automaton::RealTimeHeightDeterministicNPDA api<automaton::RealTimeHeightDeterministicNPDA>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::automatonParser.parseRealTimeHeightDeterministicNPDA(input); +} + +std::list<sax::Token> api<automaton::RealTimeHeightDeterministicNPDA>::compose(const automaton::RealTimeHeightDeterministicNPDA& data) { + return ToXMLComposers::automatonComposer.compose(data); +} + automaton::NPDA api<automaton::NPDA>::parse(std::list<sax::Token>& input) { return FromXMLParsers::automatonParser.parseNPDA(input); } @@ -580,6 +588,10 @@ void ToXMLComposers::Visit(void* data, const automaton::VisiblyPushdownNPDA& aut *((std::list<sax::Token>*) data) = std::move(api<automaton::VisiblyPushdownNPDA>::compose(automaton)); } +void ToXMLComposers::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const { + *((std::list<sax::Token>*) data) = std::move(api<automaton::RealTimeHeightDeterministicNPDA>::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 27fbbfb1967cd694efae5345220a6883a21a336a..fd58922caa2bf7cbfe42720b1f5ca0d9c9fa04d4 100644 --- a/alib2data/src/Api.hpp +++ b/alib2data/src/Api.hpp @@ -198,6 +198,12 @@ struct api<automaton::VisiblyPushdownNPDA> { static std::list<sax::Token> compose(const automaton::VisiblyPushdownNPDA& data); }; +template<> +struct api<automaton::RealTimeHeightDeterministicNPDA> { + static automaton::RealTimeHeightDeterministicNPDA parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const automaton::RealTimeHeightDeterministicNPDA& data); +}; + template<> struct api<automaton::NPDA> { static automaton::NPDA parse(std::list<sax::Token>& input); @@ -464,6 +470,7 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type { 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::RealTimeHeightDeterministicNPDA& 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 039c2011a405a7c29d6ca48deb27ae71aae45e80..ab8fa4f0d0c18066c25d76528302cedf6a980d22 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::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, 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::RealTimeHeightDeterministicNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM > VisitableAutomatonBase; /** diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h index 917593ddaedb3e2b5477004688a990b692c927cc..8ae376dfdaa84fa8457abf38c1075eedae8d0c86 100644 --- a/alib2data/src/automaton/AutomatonFeatures.h +++ b/alib2data/src/automaton/AutomatonFeatures.h @@ -21,6 +21,7 @@ enum class FEATURES { SINGLE_POP_DPDA, INPUT_DRIVEN_NPDA, VISIBLY_PUSHDOWN_NPDA, + REAL_TIME_HEIGHT_DETERMINISTIC_NPDA, NPDA, SINGLE_POP_NPDA, ONE_TAPE_DTM diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.cpp b/alib2data/src/automaton/AutomatonFromXMLParser.cpp index 16ed26b1cbbbcc46f5ecb217790288db4d859fed..59b733fef331c633e97faf8b7e503cc71e05b78e 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::INPUT_DRIVEN_NPDA, FEATURES::VISIBLY_PUSHDOWN_NPDA, 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::REAL_TIME_HEIGHT_DETERMINISTIC_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 { @@ -52,6 +52,9 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, c } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "VisiblyPushdownNPDA")) { if(!features.count(FEATURES::VISIBLY_PUSHDOWN_NPDA)) throw exception::AlibException(); return Automaton(parseVisiblyPushdownNPDA(input)); + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "RealTimeHeightDeterministicNPDA")) { + if(!features.count(FEATURES::REAL_TIME_HEIGHT_DETERMINISTIC_NPDA)) throw exception::AlibException(); + return Automaton(parseRealTimeHeightDeterministicNPDA(input)); } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA")) { if(!features.count(FEATURES::NPDA)) throw exception::AlibException(); return Automaton(parseNPDA(input)); @@ -313,8 +316,6 @@ VisiblyPushdownNPDA AutomatonFromXMLParser::parseVisiblyPushdownNPDA(std::list<s automaton.setCallInputSymbols(callInputSymbols); automaton.setReturnInputSymbols(returnInputSymbols); automaton.setLocalInputSymbols(localInputSymbols); - automaton.setReturnInputSymbols(returnInputSymbols); - automaton.setLocalInputSymbols(localInputSymbols); automaton.setStackSymbols(stackSymbols); automaton.setInitialStates(initialStates); automaton.setFinalStates(finalStates); @@ -326,6 +327,30 @@ VisiblyPushdownNPDA AutomatonFromXMLParser::parseVisiblyPushdownNPDA(std::list<s return automaton; } +RealTimeHeightDeterministicNPDA AutomatonFromXMLParser::parseRealTimeHeightDeterministicNPDA(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "RealTimeHeightDeterministicNPDA"); + + 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 bottomOfTheStackSymbol = parseBottomOfTheStackSymbol(input); + std::set<State> finalStates = parseFinalStates(input); + + RealTimeHeightDeterministicNPDA automaton(bottomOfTheStackSymbol); + automaton.setStates(states); + automaton.setInputSymbols(inputSymbols); + automaton.setStackSymbols(stackSymbols); + automaton.setInitialStates(initialStates); + automaton.setFinalStates(finalStates); + + parseTransitions<RealTimeHeightDeterministicNPDA>(input, automaton); + + popToken(input, sax::Token::TokenType::END_ELEMENT, "RealTimeHeightDeterministicNPDA"); + + return automaton; +} + NPDA AutomatonFromXMLParser::parseNPDA(std::list<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA"); @@ -620,7 +645,7 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, Visib State to = parseTransitionTo(input); alphabet::Symbol push = parseTransitionSinglePush(input); - automaton.addTransition(from, inputSymbol, to, push); + automaton.addCallTransition(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"); @@ -629,7 +654,7 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, Visib alphabet::Symbol pop = parseTransitionSinglePop(input); State to = parseTransitionTo(input); - automaton.addTransition(from, inputSymbol, pop, to); + automaton.addReturnTransition(from, inputSymbol, pop, to); popToken(input, sax::Token::TokenType::END_ELEMENT, "returnTransition"); } else { popToken(input, sax::Token::TokenType::START_ELEMENT, "localTransition"); @@ -637,7 +662,37 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, Visib alphabet::Symbol inputSymbol = parseTransitionInputSymbol(input); State to = parseTransitionTo(input); - automaton.addTransition(from, inputSymbol, to); + automaton.addLocalTransition(from, inputSymbol, to); + popToken(input, sax::Token::TokenType::END_ELEMENT, "localTransition"); + } +} + +void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, RealTimeHeightDeterministicNPDA& automaton) const { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "callTransition")) { + popToken(input, sax::Token::TokenType::START_ELEMENT, "callTransition"); + State from = parseTransitionFrom(input); + std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); + State to = parseTransitionTo(input); + alphabet::Symbol push = parseTransitionSinglePush(input); + + automaton.addCallTransition(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); + std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); + alphabet::Symbol pop = parseTransitionSinglePop(input); + State to = parseTransitionTo(input); + + automaton.addReturnTransition(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); + std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input); + State to = parseTransitionTo(input); + + automaton.addLocalTransition(from, inputSymbol, to); popToken(input, sax::Token::TokenType::END_ELEMENT, "localTransition"); } } diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.h b/alib2data/src/automaton/AutomatonFromXMLParser.h index 0aca28dbe1efb216b5941478d914005e5c12dcec..a1aa4e012b452ab07376ac4c09a1741d792c0b16 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.h +++ b/alib2data/src/automaton/AutomatonFromXMLParser.h @@ -21,6 +21,7 @@ #include "PDA/SinglePopDPDA.h" #include "PDA/InputDrivenNPDA.h" #include "PDA/VisiblyPushdownNPDA.h" +#include "PDA/RealTimeHeightDeterministicNPDA.h" #include "PDA/NPDA.h" #include "PDA/SinglePopNPDA.h" #include "TM/OneTapeDTM.h" @@ -79,6 +80,7 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { 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, RealTimeHeightDeterministicNPDA& 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; @@ -109,6 +111,7 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { SinglePopDPDA parseSinglePopDPDA(std::list<sax::Token>& input) const; InputDrivenNPDA parseInputDrivenNPDA(std::list<sax::Token>& input) const; VisiblyPushdownNPDA parseVisiblyPushdownNPDA(std::list<sax::Token>& input) const; + RealTimeHeightDeterministicNPDA parseRealTimeHeightDeterministicNPDA(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 b2ec69661159f5477d81b462978c976868779851..8b4fd75125e8964b0da024b24af472d52ecf6978 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.cpp +++ b/alib2data/src/automaton/AutomatonToXMLComposer.cpp @@ -340,6 +340,47 @@ 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 RealTimeHeightDeterministicNPDA& 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); + composeTransitionInputEpsilonSymbol(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)); + composeTransitionInputEpsilonSymbol(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); + composeTransitionInputEpsilonSymbol(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()) { @@ -671,6 +712,22 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const VisiblyPushdownNPDA& return out; } +std::list<sax::Token> AutomatonToXMLComposer::compose(const RealTimeHeightDeterministicNPDA& automaton) const { + std::list<sax::Token> out; + out.push_back(sax::Token("RealTimeHeightDeterministicNPDA", sax::Token::TokenType::START_ELEMENT)); + + composeStates(out, automaton.getStates()); + composeInputAlphabet(out, automaton.getInputAlphabet()); + composeStackAlphabet(out, automaton.getStackAlphabet()); + composeInitialStates(out, automaton.getInitialStates()); + composeBottomOfTheStackSymbol(out, automaton.getBottomOfTheStackSymbol()); + composeFinalStates(out, automaton.getFinalStates()); + composeTransitions(out, automaton); + + out.push_back(sax::Token("RealTimeHeightDeterministicNPDA", 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 2ee531b7074d614f0f3fb41596cea94c89520023..5b10c1eb081a9cd3e2259bc10180a4c0b464deb6 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.h +++ b/alib2data/src/automaton/AutomatonToXMLComposer.h @@ -63,6 +63,7 @@ class AutomatonToXMLComposer { 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 RealTimeHeightDeterministicNPDA& 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; @@ -100,6 +101,7 @@ class AutomatonToXMLComposer { 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 RealTimeHeightDeterministicNPDA& 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 bc74ed86146b486a353f52f6f7e9bf4f7ed49ce2..46c180a1332bdeaca8edd9397f978e95c2dd90e5 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp @@ -202,6 +202,10 @@ void FiniteAutomatonToStringComposer::Visit(void*, const VisiblyPushdownNPDA&) c throw exception::AlibException(); } +void FiniteAutomatonToStringComposer::Visit(void*, const RealTimeHeightDeterministicNPDA&) 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 cb61d3edeea73abe5d22e1dfa1bda66e10b2f1f7..74eac6ac19575af572573019db1bbf5060dedc74 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h @@ -20,6 +20,7 @@ class FiniteAutomatonToStringComposer : public VisitableAutomatonBase::const_vis 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 RealTimeHeightDeterministicNPDA& 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/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2d2d84169e5a3001cb65a1ae88e74fe3beb1a145 --- /dev/null +++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.cpp @@ -0,0 +1,300 @@ +/* + * RealTimeHeightDeterministicNPDA.cpp + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#include "RealTimeHeightDeterministicNPDA.h" +#include "../../std/map.hpp" +#include "../AutomatonException.h" +#include <algorithm> +#include <sstream> + +namespace automaton { + +RealTimeHeightDeterministicNPDA::RealTimeHeightDeterministicNPDA(const alphabet::Symbol& bottomOfTheStackSymbol) : BottomOfTheStackSymbolPushdownStoreAlphabet(bottomOfTheStackSymbol) { + +} + +AutomatonBase* RealTimeHeightDeterministicNPDA::clone() const { + return new RealTimeHeightDeterministicNPDA(*this); +} + +AutomatonBase* RealTimeHeightDeterministicNPDA::plunder() && { + return new RealTimeHeightDeterministicNPDA(std::move(*this)); +} + +bool RealTimeHeightDeterministicNPDA::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, std::variant<string::Epsilon, 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, std::variant<string::Epsilon, 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, std::variant<string::Epsilon, 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 RealTimeHeightDeterministicNPDA::removeInputSymbol(const alphabet::Symbol& symbol) { + for (const std::pair<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<std::pair<State, alphabet::Symbol> > >& callTransition : callTransitions) { + if (callTransition.first.second.is<alphabet::Symbol>() && symbol == callTransition.first.second.get<alphabet::Symbol>()) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<State> >& returnTransition : returnTransitions) { + if (std::get<1>(returnTransition.first).is<alphabet::Symbol>() && symbol == std::get<1>(returnTransition.first).get<alphabet::Symbol>()) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used in transition."); + } + + for (const std::pair<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<State> >& localTransition : localTransitions) { + if (localTransition.first.second.is<alphabet::Symbol>() && symbol == localTransition.first.second.get<alphabet::Symbol>()) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used in transition."); + } + + return inputAlphabet.erase(symbol); +} + +bool RealTimeHeightDeterministicNPDA::removeStackSymbol(const alphabet::Symbol& symbol) { + for (const std::pair<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<std::pair<State, alphabet::Symbol> > >& callTransition : callTransitions) { + for(const std::pair<State, alphabet::Symbol>& to : callTransition.second) { + if (symbol == to.second) + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition."); + } + } + + for (const std::pair<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<State> >& returnTransition : returnTransitions) { + if (symbol == std::get<2>(returnTransition.first)) + throw AutomatonException("Stack symbol \"" + (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 RealTimeHeightDeterministicNPDA::addCallTransition(const State& from, const std::variant<string::Epsilon, 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 (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" 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, std::variant<string::Epsilon, alphabet::Symbol>> key(from, input); + std::pair<automaton::State, alphabet::Symbol> value = std::make_pair(to, push); + + return callTransitions[key].insert(value).second; +} + +bool RealTimeHeightDeterministicNPDA::addCallTransition(const State& from, const State& to, const alphabet::Symbol& push) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return addCallTransition(from, inputVariant, to, push); +} + +bool RealTimeHeightDeterministicNPDA::addCallTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return addCallTransition(from, inputVariant, to, push); +} + +bool RealTimeHeightDeterministicNPDA::addReturnTransition(const State& from, const std::variant<string::Epsilon, 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 (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" 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, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop); + + return returnTransitions[key].insert(to).second; +} + +bool RealTimeHeightDeterministicNPDA::addReturnTransition(const State& from, const alphabet::Symbol& pop, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return addReturnTransition(from, inputVariant, pop, to); +} + +bool RealTimeHeightDeterministicNPDA::addReturnTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return addReturnTransition(from, inputVariant, pop, to); +} + +bool RealTimeHeightDeterministicNPDA::addLocalTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& to) { + if (states.find(from) == states.end()) { + throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist."); + } + + if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) { + throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist."); + } + + if (states.find(to) == states.end()) { + throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist."); + } + + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>> key(from, input); + + return localTransitions[key].insert(to).second; +} + +bool RealTimeHeightDeterministicNPDA::addLocalTransition(const State& from, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return addLocalTransition(from, inputVariant, to); +} + +bool RealTimeHeightDeterministicNPDA::addLocalTransition(const State& from, const alphabet::Symbol& input, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return addLocalTransition(from, inputVariant, to); +} + +bool RealTimeHeightDeterministicNPDA::removeCallTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& to, const alphabet::Symbol& push) { + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>> key(from, input); + std::pair<automaton::State, alphabet::Symbol> value = std::make_pair(to, push); + + return callTransitions[key].erase(value); +} + +bool RealTimeHeightDeterministicNPDA::removeCallTransition(const State& from, const State& to, const alphabet::Symbol& push) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return removeCallTransition(from, inputVariant, to, push); +} + +bool RealTimeHeightDeterministicNPDA::removeCallTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return removeCallTransition(from, inputVariant, to, push); +} + +bool RealTimeHeightDeterministicNPDA::removeReturnTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to) { + std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop); + + return returnTransitions[key].erase(to); +} + +bool RealTimeHeightDeterministicNPDA::removeReturnTransition(const State& from, const alphabet::Symbol& pop, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return removeReturnTransition(from, inputVariant, pop, to); +} + +bool RealTimeHeightDeterministicNPDA::removeReturnTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return removeReturnTransition(from, inputVariant, pop, to); +} + +bool RealTimeHeightDeterministicNPDA::removeLocalTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& to) { + std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>> key(from, input); + + return localTransitions[key].erase(to); +} + +bool RealTimeHeightDeterministicNPDA::removeLocalTransition(const State& from, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON); + return removeLocalTransition(from, inputVariant, to); +} + +bool RealTimeHeightDeterministicNPDA::removeLocalTransition(const State& from, const alphabet::Symbol& input, const State& to) { + std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input); + return removeLocalTransition(from, inputVariant, to); +} + +const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<std::pair<State, alphabet::Symbol> > >& RealTimeHeightDeterministicNPDA::getCallTransitions() const { + return callTransitions; +} + +const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<State> >& RealTimeHeightDeterministicNPDA::getReturnTransitions() const { + return returnTransitions; +} + +const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<State> >& RealTimeHeightDeterministicNPDA::getLocalTransitions() const { + return localTransitions; +} + +bool RealTimeHeightDeterministicNPDA::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool RealTimeHeightDeterministicNPDA::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool RealTimeHeightDeterministicNPDA::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool RealTimeHeightDeterministicNPDA::operator==(const RealTimeHeightDeterministicNPDA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && 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 RealTimeHeightDeterministicNPDA::operator<(const RealTimeHeightDeterministicNPDA& other) const { + return std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions) < std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions); +} + +void RealTimeHeightDeterministicNPDA::operator>>(std::ostream& out) const { + out << "(RealTimeHeightDeterministicNPDA" + << "states = " << states + << "inputAlphabet = " << inputAlphabet + << "initialStates = " << initialStates + << "finalStates = " << finalStates + << "stackAlphabet = " << stackAlphabet + << "bottomOfTheStackSymbol = " << bottomOfTheStackSymbol + << "callTransitions = " << callTransitions + << "returnTransitions = " << returnTransitions + << "localTransitions = " << localTransitions + << ")"; +} + +RealTimeHeightDeterministicNPDA::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h new file mode 100644 index 0000000000000000000000000000000000000000..d9ed4eeaa0b4241d08b3e230b0ebabf9c44fdc21 --- /dev/null +++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h @@ -0,0 +1,139 @@ +/* + * REAL_TIME_HEIGHT_DETERMINISTIC_NPDA.h + * + * Created on: Mar 25, 2013 + * Author: Jan Travnicek + */ + +#ifndef REAL_TIME_HEIGHT_DETERMINISTIC_NPDA_H_ +#define REAL_TIME_HEIGHT_DETERMINISTIC_NPDA_H_ + +#include <map> +#include <vector> +#include "../../std/map.hpp" +#include "../../std/variant.hpp" +#include "../AutomatonBase.h" +#include "../common/MultiInitialStates.h" +#include "../common/InputAlphabet.h" +#include "../common/BottomOfTheStackSymbolPushdownStoreAlphabet.h" +#include "../../alphabet/Symbol.h" +#include "../../string/Epsilon.h" + +namespace automaton { + +/** + * Represents Finite Automaton. + * Can store nondeterministic finite automaton without epsilon transitions. + */ +class RealTimeHeightDeterministicNPDA : public std::acceptor<RealTimeHeightDeterministicNPDA, VisitableAutomatonBase, std::acceptor<RealTimeHeightDeterministicNPDA, alib::VisitableObjectBase, AutomatonBase> >, public BottomOfTheStackSymbolPushdownStoreAlphabet, public MultiInitialStates, public InputAlphabet { +protected: + std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<std::pair<State, alphabet::Symbol> > > callTransitions; + std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<State> > returnTransitions; + std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<State> > localTransitions; +public: + RealTimeHeightDeterministicNPDA(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 addCallTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& next, const alphabet::Symbol& push); + bool addCallTransition(const State& current, const State& next, const alphabet::Symbol& push); + bool addCallTransition(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 addReturnTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& next); + bool addReturnTransition(const State& current, const alphabet::Symbol& pop, const State& next); + bool addReturnTransition(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 addLocalTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& next); + bool addLocalTransition(const State& current, const State& next); + bool addLocalTransition(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 removeCallTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& next, const alphabet::Symbol& push); + bool removeCallTransition(const State& current, const State& next, const alphabet::Symbol& push); + bool removeCallTransition(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 removeReturnTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& next); + bool removeReturnTransition(const State& current, const alphabet::Symbol& pop, const State& next); + bool removeReturnTransition(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 removeLocalTransition(const State& current, const std::variant<string::Epsilon, alphabet::Symbol>& input, const State& next); + bool removeLocalTransition(const State& current, const State& next); + bool removeLocalTransition(const State& current, const alphabet::Symbol& input, const State& next); + + const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>>, std::set<std::pair<State, alphabet::Symbol> > >& getCallTransitions() const; + + const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::set<State> >& getReturnTransitions() const; + + const std::map<std::pair<State, std::variant<string::Epsilon, 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 RealTimeHeightDeterministicNPDA& other) const; + virtual bool operator<(const RealTimeHeightDeterministicNPDA& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace automaton */ + +#endif /* REAL_TIME_HEIGHT_DETERMINISTIC_NPDA_H_ */ diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp index 57d1c97ceb5b416235c41d89d017154f817dda0d..1963146e55ca538d5686d1d8918f9bd31f7a4001 100644 --- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp +++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.cpp @@ -67,17 +67,17 @@ bool VisiblyPushdownNPDA::removeState(const State& 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."); + throw AutomatonException("Input symbol \"" + (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."); + throw AutomatonException("Input symbol \"" + (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."); + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used in transition."); } return callInputAlphabet.erase(symbol) || returnInputAlphabet.erase(symbol) || localInputAlphabet.erase(symbol); @@ -85,18 +85,15 @@ bool VisiblyPushdownNPDA::removeInputSymbol(const alphabet::Symbol& 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<State, alphabet::Symbol>& to : callTransition.second) { + if (symbol == to.second) + throw AutomatonException("Stack symbol \"" + (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 (symbol == std::get<2>(returnTransition.first)) + throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition."); } if(bottomOfTheStackSymbol == symbol) { @@ -106,7 +103,7 @@ bool VisiblyPushdownNPDA::removeStackSymbol(const alphabet::Symbol& symbol) { return stackAlphabet.erase(symbol); } -bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { +bool VisiblyPushdownNPDA::addCallTransition(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."); } @@ -129,7 +126,7 @@ bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbo return callTransitions[key].insert(value).second; } -bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to) { +bool VisiblyPushdownNPDA::addReturnTransition(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."); } @@ -151,7 +148,7 @@ bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbo return returnTransitions[key].insert(to).second; } -bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbol& input, const State& to) { +bool VisiblyPushdownNPDA::addLocalTransition(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."); } @@ -169,20 +166,20 @@ bool VisiblyPushdownNPDA::addTransition(const State& from, const alphabet::Symbo return localTransitions[key].insert(to).second; } -bool VisiblyPushdownNPDA::removeTransition(const State& from, const alphabet::Symbol& input, const State& to, const alphabet::Symbol& push) { +bool VisiblyPushdownNPDA::removeCallTransition(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) { +bool VisiblyPushdownNPDA::removeReturnTransition(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) { +bool VisiblyPushdownNPDA::removeLocalTransition(const State& from, const alphabet::Symbol& input, const State& to) { std::pair<State, alphabet::Symbol> key(from, input); return localTransitions[key].erase(to); diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h index 132293068f5daafd26116ddf81fba10c49a6c7e5..77926c24fbe90554c248d09ae3f2928c63adcd87 100644 --- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h +++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h @@ -57,7 +57,7 @@ public: * @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); + bool addCallTransition(const State& current, const alphabet::Symbol& input, const State& next, const alphabet::Symbol& push); /** * Adds return transition defined by parameters to the automaton. @@ -66,7 +66,7 @@ public: * @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); + bool addReturnTransition(const State& current, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& next); /** * Adds local transition defined by parameters to the automaton. @@ -75,28 +75,28 @@ public: * @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); + bool addLocalTransition(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); + bool removeCallTransition(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); + bool removeReturnTransition(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); + bool removeLocalTransition(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; diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index fccd24d1b18e9dae8e25c00d341445194ea87ad0..9116b8c38f6490e58f042c36b428be22a3ee5a61 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -31,6 +31,7 @@ class NPDA; class SinglePopNPDA; class InputDrivenNPDA; class VisiblyPushdownNPDA; +class RealTimeHeightDeterministicNPDA; class OneTapeDTM; } @@ -109,7 +110,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::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, 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::RealTimeHeightDeterministicNPDA, 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, @@ -123,7 +124,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::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, 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::RealTimeHeightDeterministicNPDA, 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,