diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp index ebd81291374a2acc7698dc7648facc14ca8d0f50..3a685478dbb5ab3cac243290a6914bc8817c7f38 100644 --- a/acompare2/src/AutomatonCompare.cpp +++ b/acompare2/src/AutomatonCompare.cpp @@ -25,6 +25,8 @@ #include "automaton/FSM/EpsilonNFA.h" #include "automaton/FSM/ExtendedNFA.h" #include "automaton/FSM/CompactNFA.h" +#include "automaton/TA/DFTA.h" +#include "automaton/TA/NFTA.h" #include "automaton/PDA/NPDA.h" #include "automaton/PDA/DPDA.h" #include "automaton/PDA/InputDrivenNPDA.h" @@ -87,6 +89,20 @@ bool AutomatonCompare::testCompare(const automaton::CompactNFA& a, const automat a.getTransitions() == b.getTransitions() ; } +bool AutomatonCompare::testCompare(const automaton::DFTA& a, const automaton::DFTA& b) { + return a.getFinalStates() == b.getFinalStates() && +// a.getInputAlphabet() == b.getInputAlphabet() && + a.getStates() == b.getStates() && + a.getTransitions() == b.getTransitions() ; +} + +bool AutomatonCompare::testCompare(const automaton::NFTA& a, const automaton::NFTA& b) { + return a.getFinalStates() == b.getFinalStates() && +// a.getInputAlphabet() == b.getInputAlphabet() && + a.getStates() == b.getStates() && + a.getTransitions() == b.getTransitions() ; +} + bool AutomatonCompare::testCompare(const automaton::DPDA& a, const automaton::DPDA& b) { return a.getFinalStates() == b.getFinalStates() && a.getInitialState() == b.getInitialState() && @@ -473,6 +489,62 @@ void AutomatonCompare::printCompare(const automaton::CompactNFA& a, const automa } } +void AutomatonCompare::printCompare(const automaton::DFTA& a, const automaton::DFTA& b) { + std::cout << "AutomatonCompareer" << std::endl; + + if(a.getFinalStates() != b.getFinalStates()){ + std::cout << "FinalStates" << std::endl; + + AutomatonCompare::setCompare(a.getFinalStates(), b.getFinalStates()); + } + + if(a.getInputAlphabet() != b.getInputAlphabet()) { + std::cout << "InputAlphabet" << std::endl; + + AutomatonCompare::setCompare(a.getInputAlphabet(), b.getInputAlphabet()); + } + + if(a.getStates() != b.getStates()) { + std::cout << "States" << std::endl; + + AutomatonCompare::setCompare(a.getStates(), b.getStates()); + } + + if(a.getTransitions() != b.getTransitions()) { + std::cout << "Transitions" << std::endl; + + AutomatonCompare::mapCompare(a.getTransitions(), b.getTransitions()); + } +} + +void AutomatonCompare::printCompare(const automaton::NFTA& a, const automaton::NFTA& b) { + std::cout << "AutomatonCompareer" << std::endl; + + if(a.getFinalStates() != b.getFinalStates()){ + std::cout << "FinalStates" << std::endl; + + AutomatonCompare::setCompare(a.getFinalStates(), b.getFinalStates()); + } + + if(a.getInputAlphabet() != b.getInputAlphabet()) { + std::cout << "InputAlphabet" << std::endl; + + AutomatonCompare::setCompare(a.getInputAlphabet(), b.getInputAlphabet()); + } + + if(a.getStates() != b.getStates()) { + std::cout << "States" << std::endl; + + AutomatonCompare::setCompare(a.getStates(), b.getStates()); + } + + if(a.getTransitions() != b.getTransitions()) { + std::cout << "Transitions" << std::endl; + + AutomatonCompare::mapCompare(a.getTransitions(), b.getTransitions()); + } +} + void AutomatonCompare::printCompare(const automaton::DPDA& a, const automaton::DPDA& b) { std::cout << "AutomatonCompareer" << std::endl; @@ -1157,6 +1229,24 @@ int AutomatonCompare::compare(const automaton::CompactNFA& a, const automaton::C } } +int AutomatonCompare::compare(const automaton::DFTA& a, const automaton::DFTA& b) { + if(!AutomatonCompare::testCompare(a, b)) { + AutomatonCompare::printCompare(a, b); + return 1; + } else { + return 0; + } +} + +int AutomatonCompare::compare(const automaton::NFTA& a, const automaton::NFTA& b) { + if(!AutomatonCompare::testCompare(a, b)) { + AutomatonCompare::printCompare(a, b); + return 1; + } else { + return 0; + } +} + int AutomatonCompare::compare(const automaton::DPDA& a, const automaton::DPDA& b) { if(!AutomatonCompare::testCompare(a, b)) { AutomatonCompare::printCompare(a, b); @@ -1286,6 +1376,14 @@ void AutomatonCompare::Visit(void* data, const automaton::NFA& first, const auto *((int*) data) = AutomatonCompare::compare(first, second); } +void AutomatonCompare::Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const { + *((int*) data) = AutomatonCompare::compare(first, second); +} + +void AutomatonCompare::Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const { + *((int*) data) = AutomatonCompare::compare(first, second); +} + void AutomatonCompare::Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const { *((int*) data) = AutomatonCompare::compare(first, second); } diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h index ac97ae0513b88ee3fb5f077764179dcd4531ea1c..58bcc32835947c71854ec8df6a9ada0ebdf02e2e 100644 --- a/acompare2/src/AutomatonCompare.h +++ b/acompare2/src/AutomatonCompare.h @@ -41,6 +41,12 @@ class AutomatonCompare : public automaton::VisitableAutomatonBase::const_same_vi static bool testCompare(const automaton::NPDA& a, const automaton::NPDA& b); static void printCompare(const automaton::NPDA& a, const automaton::NPDA& b); + static bool testCompare(const automaton::DFTA& a, const automaton::DFTA& b); + static void printCompare(const automaton::DFTA& a, const automaton::DFTA& b); + + static bool testCompare(const automaton::NFTA& a, const automaton::NFTA& b); + static void printCompare(const automaton::NFTA& a, const automaton::NFTA& b); + static bool testCompare(const automaton::InputDrivenDPDA& a, const automaton::InputDrivenDPDA& b); static void printCompare(const automaton::InputDrivenDPDA& a, const automaton::InputDrivenDPDA& b); @@ -79,6 +85,9 @@ public: void Visit(void* data, const automaton::MultiInitialStateNFA& first, const automaton::MultiInitialStateNFA& second) const; void Visit(void* data, const automaton::NFA& first, const automaton::NFA& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + void Visit(void* data, const automaton::DPDA& first, const automaton::DPDA& second) const; void Visit(void* data, const automaton::NPDA& first, const automaton::NPDA& second) const; void Visit(void* data, const automaton::InputDrivenNPDA& first, const automaton::InputDrivenNPDA& second) const; @@ -99,6 +108,9 @@ public: static int compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b); static int compare(const automaton::CompactNFA& a, const automaton::CompactNFA& b); + static int compare(const automaton::DFTA& a, const automaton::DFTA& b); + static int compare(const automaton::NFTA& a, const automaton::NFTA& b); + static int compare(const automaton::DPDA& a, const automaton::DPDA& b); static int compare(const automaton::NPDA& a, const automaton::NPDA& b); static int compare(const automaton::InputDrivenDPDA& a, const automaton::InputDrivenDPDA& b); diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp index 3801066f966d7a1f97e4cfb6b1528eaa7860e3f0..ece17ebb619b40cd596c66188f864984a955b4b1 100644 --- a/aconvert2/src/DotConverter.cpp +++ b/aconvert2/src/DotConverter.cpp @@ -238,6 +238,14 @@ void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) { out << "}"; } +void DotConverter::convert(const automaton::NFTA&, std::ostream&) { + //TODO +} + +void DotConverter::convert(const automaton::DFTA&, std::ostream&) { + //TODO +} + void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) { out << "digraph automaton {\n"; out << "rankdir=LR;\n"; @@ -790,6 +798,14 @@ void DotConverter::transitions(const automaton::CompactNFA& fsm, const std::map< } } +void DotConverter::transitions(const automaton::NFTA&, const std::map<automaton::State, int>&, std::ostream&) { + //TODO +} + +void DotConverter::transitions(const automaton::DFTA&, const std::map<automaton::State, int>&, std::ostream&) { + //TODO +} + void DotConverter::transitions(const automaton::DPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) { std::map<std::pair<int, int>, std::string> transitions; @@ -1758,3 +1774,11 @@ void DotConverter::Visit(void* data, const automaton::OneTapeDTM& automaton) con DotConverter::convert(automaton, *((std::ostream*) data)); } +void DotConverter::Visit(void* data, const automaton::NFTA& automaton) const { + DotConverter::convert(automaton, *((std::ostream*) data)); +} + +void DotConverter::Visit(void* data, const automaton::DFTA& automaton) const { + DotConverter::convert(automaton, *((std::ostream*) data)); +} + diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h index 5a9e26086da5e96ca5be50ad02b6f1d27d3a46ed..3e3d3c88e825a216da10a63f7b23dcdd89195648 100644 --- a/aconvert2/src/DotConverter.h +++ b/aconvert2/src/DotConverter.h @@ -33,6 +33,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; static void transitions(const automaton::EpsilonNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::MultiInitialStateNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); @@ -40,6 +42,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ static void transitions(const automaton::DFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::ExtendedNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); static void transitions(const automaton::CompactNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); + static void transitions(const automaton::NFTA& fsm, const std::map<automaton::State, int>& states, std::ostream& out); + static void transitions(const automaton::DFTA& 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::InputDrivenDPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out); @@ -62,6 +66,8 @@ public: static void convert(const automaton::DFA& a, std::ostream& out); static void convert(const automaton::ExtendedNFA& a, std::ostream& out); static void convert(const automaton::CompactNFA& a, std::ostream& out); + static void convert(const automaton::NFTA& a, std::ostream& out); + static void convert(const automaton::DFTA& 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::InputDrivenDPDA& a, std::ostream& out); diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp index d8635bcbe1700aa6559c76cbd97b4809fd82a6f2..f03a4a0a77e8f77df947bf0ca41c0ac5f559eac1 100644 --- a/aconvert2/src/GasTexConverter.cpp +++ b/aconvert2/src/GasTexConverter.cpp @@ -270,6 +270,14 @@ void GasTexConverter::convert(const automaton::CompactNFA& a, std::ostream& out) out << "\\end{picture}\n"; } +void GasTexConverter::convert(const automaton::NFTA&, std::ostream&) { + //TODO +} + +void GasTexConverter::convert(const automaton::DFTA&, std::ostream&) { + //TODO +} + void GasTexConverter::convert(const automaton::DPDA& a, std::ostream& out) { out << "\\begin{center}\n"; out << "\\begin{picture}(,)(,)\n"; @@ -859,6 +867,14 @@ void GasTexConverter::transitions(const automaton::CompactNFA& fsm, std::ostream printTransitionMap(transitionMap, out); } +void GasTexConverter::transitions(const automaton::NFTA&, std::ostream&) { + //TODO +} + +void GasTexConverter::transitions(const automaton::DFTA&, std::ostream&) { + //TODO +} + void GasTexConverter::transitions(const automaton::DPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; @@ -1443,3 +1459,11 @@ void GasTexConverter::Visit(void* data, const automaton::OneTapeDTM& automaton) GasTexConverter::convert(automaton, *((std::ostream*) data)); } +void GasTexConverter::Visit(void* data, const automaton::NFTA& automaton) const { + GasTexConverter::convert(automaton, *((std::ostream*) data)); +} + +void GasTexConverter::Visit(void* data, const automaton::DFTA& automaton) const { + GasTexConverter::convert(automaton, *((std::ostream*) data)); +} + diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h index 791b28ebf99b70f6c2fff8caff3ae93a6f854fe2..8b8a385d6292410284b6a95faf2fbca0ce387048 100644 --- a/aconvert2/src/GasTexConverter.h +++ b/aconvert2/src/GasTexConverter.h @@ -33,6 +33,8 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; static void printTransitionMap( const std::map<std::pair<std::string, std::string>, std::string> transitionMap, std::ostream& out); static std::string getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols); @@ -43,6 +45,8 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_ static void transitions(const automaton::DFA& fsm, std::ostream& out); static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out); static void transitions(const automaton::CompactNFA& fsm, std::ostream& out); + static void transitions(const automaton::NFTA& fsm, std::ostream& out); + static void transitions(const automaton::DFTA& 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::InputDrivenDPDA& pda, std::ostream& out); @@ -65,6 +69,8 @@ public: static void convert(const automaton::DFA& a, std::ostream& out); static void convert(const automaton::ExtendedNFA& a, std::ostream& out); static void convert(const automaton::CompactNFA& a, std::ostream& out); + static void convert(const automaton::NFTA& a, std::ostream& out); + static void convert(const automaton::DFTA& 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::InputDrivenDPDA& a, std::ostream& out); diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp index 9c1695445f2d4839a05610e2dca151d504d75b7a..21012d772479a8f332b693a3134c9300485d5add 100644 --- a/alib2algo/src/automaton/convert/ToGrammar.cpp +++ b/alib2algo/src/automaton/convert/ToGrammar.cpp @@ -91,6 +91,14 @@ void ToGrammar::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void ToGrammar::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void ToGrammar::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const ToGrammar ToGrammar::TO_GRAMMAR; } /* namespace convert */ diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h index 73e094c4e2b55fa11b73dc79318854d1b806ba9f..ecc050680c7fbf59fb3019915f3ed0ae3861cd68 100644 --- a/alib2algo/src/automaton/convert/ToGrammar.h +++ b/alib2algo/src/automaton/convert/ToGrammar.h @@ -45,6 +45,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const ToGrammar TO_GRAMMAR; }; diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp index f0609e19367f1be529625c51988be2cc2f622889..a2966075f08862da078a81dcb868b565e72254c4 100644 --- a/alib2algo/src/automaton/determinize/Determinize.cpp +++ b/alib2algo/src/automaton/determinize/Determinize.cpp @@ -106,6 +106,16 @@ void Determinize::Visit(void* data, const automaton::OneTapeDTM& automaton) cons out = new automaton::Automaton(automaton); } +void Determinize::Visit(void* data, const automaton::NFTA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->determinize(automaton)); +} + +void Determinize::Visit(void* data, const automaton::DFTA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(automaton); +} + const Determinize Determinize::DETERMINIZE; } /* namespace determinize */ @@ -116,4 +126,5 @@ const Determinize Determinize::DETERMINIZE; #include "DeterminizeIDPDAPart.cxx" #include "DeterminizeVPAPart.cxx" #include "DeterminizeRHDPDAPart.cxx" +#include "DeterminizeNFTAPart.cxx" diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h index 11f97515045b0b5d38509351b8cf807f621656d3..94f936c5f084021345dc073ca89e2ff8522c648c 100644 --- a/alib2algo/src/automaton/determinize/Determinize.h +++ b/alib2algo/src/automaton/determinize/Determinize.h @@ -19,6 +19,7 @@ #include <automaton/PDA/VisiblyPushdownDPDA.h> #include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> #include <automaton/TM/OneTapeDTM.h> +#include <automaton/TA/DFTA.h> #include <exception/AlibException.h> @@ -48,6 +49,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const Determinize DETERMINIZE; @@ -65,6 +68,7 @@ public: static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic); static automaton::InputDrivenDPDA determinize(const automaton::InputDrivenNPDA& nfa); static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic); + static automaton::DFTA determinize(const automaton::NFTA& nfta); }; } /* namespace determinize */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx new file mode 100644 index 0000000000000000000000000000000000000000..897f6057cf01c566536f65ad75ec56809a4dcf6b --- /dev/null +++ b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx @@ -0,0 +1,99 @@ +/* + * NFTADeterminizer.cpp + * + * Created on: 30. 3. 2015 + * Author: Stepan Plachy + */ + +#include "common/NFACommon.h" + +#include <automaton/TA/NFTA.h> +#include <deque> +#include <algorithm> + +namespace automaton { + +namespace determinize { + +std::set<State> getTransitionRightSide(const NFTA & nfta, const alphabet::RankedSymbol & symbol, const std::vector<State> & states) { + std::set<State> res; + for (const auto & transition : nfta.getTransitions()) { + if (transition.first.first != symbol) continue; + + int i = symbol.getRank().getData() - 1; + for (; i >= 0; i--) + if (!recreateNFAStates(states[i]).count(transition.first.second[i])) break; + + if (i == -1) res.insert(transition.second.begin(), transition.second.end()); + } + return res; +} + +DFTA Determinize::determinize(const NFTA & nfta) { + DFTA res; + res.setInputSymbols(nfta.getInputAlphabet()); + for (const auto & state : nfta.getStates()) res.addState(createDFAState({state})); + for (const auto & state : nfta.getFinalStates()) res.addFinalState(createDFAState({state})); + + std::deque<State> todo; + + //std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> > transitions; + for (const auto & transition : nfta.getTransitions()) { + State state = createDFAState(transition.second); + std::vector<State> states; + for (const auto & s : transition.first.second) states.push_back(createDFAState({s})); + if (transition.second.size() > 1 && res.addState(state)) todo.push_back(state); + res.addTransition(transition.first.first, states, state); + } + + while(!todo.empty()) { + State currentState = todo.front(); + todo.pop_front(); + std::set<State> nftaStates = recreateNFAStates(currentState); + + std::deque<std::pair<std::pair<alphabet::RankedSymbol, std::vector<State> >, State> > transitions; + std::deque<int> stops; + for (const auto & transition : res.getTransitions()) { + transitions.push_back(transition); + stops.push_back(0); + } + + while(!transitions.empty()) { + auto transition = transitions.front(); + int stop = stops.front(); + transitions.pop_front(); + stops.pop_front(); + const std::vector<State> & states = transition.first.second; + + for (int i = stop; i < (int) states.size(); i++) { + if (recreateNFAStates(states[i]).size() != 1) continue; + State nftaState = *recreateNFAStates(states[i]).begin(); + if (nftaStates.count(nftaState)) { + std::vector<State> newStates = states; + newStates[i] = currentState; + + std::set<State> newNextStates = getTransitionRightSide(nfta, transition.first.first, newStates); + if (!newNextStates.empty()) { + State newNextState = createDFAState(newNextStates); + if (res.addState(newNextState)) todo.push_back(newNextState); + if (res.addTransition(transition.first.first, newStates, newNextState) && i != (int) states.size()-1) { + transitions.push_back(std::make_pair(std::make_pair(transition.first.first, newStates), newNextState)); + stops.push_back(i + 1); + } + } + } + } + } + + for (const auto & state : nftaStates) { + if (nfta.getFinalStates().count(state)) {res.addFinalState(currentState); break;} + } + + } + + return res; +} + +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/common/NFACommon.cpp b/alib2algo/src/automaton/determinize/common/NFACommon.cpp index 16f996c94eee8d371edce31cc69d90aa45c1904c..52d945fdf2255a8378a2c93c140f0b2514782dbf 100644 --- a/alib2algo/src/automaton/determinize/common/NFACommon.cpp +++ b/alib2algo/src/automaton/determinize/common/NFACommon.cpp @@ -10,6 +10,7 @@ #include <deque> #include <algorithm> +#include <iostream> namespace automaton { @@ -24,8 +25,10 @@ automaton::State createDFAState(const std::set<automaton::State>& nfaStates) { } std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState) { +// std::cout << dfaState << std::endl; std::set<automaton::State> states; for (const auto& label : static_cast<const label::LabelSetLabel&>(dfaState.getName().getData()).getData()) { +// std::cout << label << std::endl; states.insert(automaton::State(label)); } return states; diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp index 1f3af73a94a0d5be9168ba57d29b0490a12cc630..c8f765befd125f059406dbb0c81bac9702903832 100644 --- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp @@ -154,6 +154,14 @@ void AllEpsilonClosure::Visit(void* data, const CompactNFA& automaton) const { out = std::move(this->allEpsilonClosure(automaton)); } +void AllEpsilonClosure::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AllEpsilonClosure::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void AllEpsilonClosure::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h index cdc4323f6b7cbff8b30ac10553399e475da0b120..c7fc6bfeed590b44aa0307418d9809ca26997d9d 100644 --- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h +++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h @@ -39,6 +39,8 @@ private: 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 NFTA& automaton) const; + void Visit(void*, const DFTA& automaton) const; void Visit(void*, const DPDA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; void Visit(void*, const InputDrivenDPDA& automaton) const; diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp index 56f3c292f75f1773a74d353f04ee0072d1581a7f..74d1d2df0f405b3fd57f65cc727e96bbfa9bd25b 100644 --- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp +++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp @@ -214,6 +214,14 @@ void EpsilonClosure::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void EpsilonClosure::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void EpsilonClosure::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const EpsilonClosure EpsilonClosure::EPSILON_CLOSURE; } /* namespace properties */ diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h index 2746d25f36dc160c130a1bdeb8d2dabdea0f1b6a..f2dd9f8ab967b0e6f11fdfeafc5745099f32e7b3 100644 --- a/alib2algo/src/automaton/properties/EpsilonClosure.h +++ b/alib2algo/src/automaton/properties/EpsilonClosure.h @@ -51,6 +51,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const EpsilonClosure EPSILON_CLOSURE; }; diff --git a/alib2algo/src/automaton/properties/ReachableStates.cpp b/alib2algo/src/automaton/properties/ReachableStates.cpp index 868d0b7a9ac1a3a9657d93f9a39b0de0a4783eac..b42f1bfc77e66e07205c0994d4dade589b0eec9d 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.cpp +++ b/alib2algo/src/automaton/properties/ReachableStates.cpp @@ -141,6 +141,14 @@ void ReachableStates::Visit(void* data, const CompactNFA& automaton) const { out = std::move(this->reachableStates(automaton)); } +void ReachableStates::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void ReachableStates::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void ReachableStates::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2algo/src/automaton/properties/ReachableStates.h b/alib2algo/src/automaton/properties/ReachableStates.h index a3f8559c25f8806dcfddbae73fed023fdaf85220..88ede0f89d0eb7c0e91aa813b572da989ca1a319 100644 --- a/alib2algo/src/automaton/properties/ReachableStates.h +++ b/alib2algo/src/automaton/properties/ReachableStates.h @@ -47,6 +47,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const ReachableStates REACHABLE_STATES; }; diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp index c62908e6c58f7683577298c822ab22cf76af160b..d02f690297172e90a1d699f0039e035d21c505af 100644 --- a/alib2algo/src/automaton/properties/UsefullStates.cpp +++ b/alib2algo/src/automaton/properties/UsefullStates.cpp @@ -156,6 +156,14 @@ void UsefullStates::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void UsefullStates::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UsefullStates::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const UsefullStates UsefullStates::USEFULL_STATES; } /* namespace properties */ diff --git a/alib2algo/src/automaton/properties/UsefullStates.h b/alib2algo/src/automaton/properties/UsefullStates.h index 5e8b745df27ce0d3361759381b213c36f08d7e47..3fa2b58735497d7ebd893cdb24439bd44f52e83e 100644 --- a/alib2algo/src/automaton/properties/UsefullStates.h +++ b/alib2algo/src/automaton/properties/UsefullStates.h @@ -47,6 +47,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const UsefullStates USEFULL_STATES; }; diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp index be35e5ae2dd0ebea3f98a29b83ab8541af9eb29e..36682d9f9f19d281cd8e5745f5cde25f86a2868d 100644 --- a/alib2algo/src/automaton/run/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -10,6 +10,8 @@ #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> #include <automaton/PDA/DPDA.h> +#include <automaton/TA/DFTA.h> +#include <automaton/TA/NFTA.h> #include <deque> @@ -17,8 +19,22 @@ namespace automaton { namespace run { +bool Accept::accept(const automaton::Automaton& automaton, const alib::Object& object) { + std::pair<const alib::Object*, bool> data(&object, false); + automaton.getData().Accept((void*) &data, Accept::ACCEPT); + return data.second; +} + bool Accept::accept(const automaton::Automaton& automaton, const string::LinearString& string) { - std::pair<const string::LinearString*, bool> data(&string, false); + alib::Object obj(string); + std::pair<const alib::Object*, bool> data(&obj, false); + automaton.getData().Accept((void*) &data, Accept::ACCEPT); + return data.second; +} + +bool Accept::accept(const automaton::Automaton& automaton, const tree::RankedTree& tree) { + alib::Object obj(tree); + std::pair<const alib::Object*, bool> data(&obj, false); automaton.getData().Accept((void*) &data, Accept::ACCEPT); return data.second; } @@ -34,6 +50,51 @@ bool Accept::accept(const automaton::DFA& automaton, const string::LinearString& return automaton.getFinalStates().count(state); } +State Accept::calculateState(const automaton::DFTA& automaton, const tree::RankedNode & node) { + std::vector<State> states; + states.reserve(node.getSymbol().getRank().getData()); + for (const auto & child : node.getChildren()) { + State state = calculateState(automaton, *child); + if (state == FAILSTATE) return FAILSTATE; + states.push_back(state); + } + const auto & it = automaton.getTransitions().find(std::make_pair(node.getSymbol(), states)); + if (it == automaton.getTransitions().end()) return FAILSTATE; + return it -> second; +} + +bool Accept::accept(const automaton::DFTA& automaton, const tree::RankedTree& tree) { + return automaton.getFinalStates().count(calculateState(automaton, tree.getRoot())); +} + +std::set<State> calculateStates(const automaton::NFTA& automaton, const tree::RankedNode & node) { + std::vector<std::set<State> > states; + states.reserve(node.getSymbol().getRank().getData()); + for (const auto & child : node.getChildren()) { + std::set<State> childStates = calculateStates(automaton, *child); + if (childStates.empty()) return childStates; + states.push_back(childStates); + } + + std::set<State> res; + for (const auto & transition : automaton.getTransitions()) { + if (transition.first.first != node.getSymbol()) continue; + int i = transition.first.first.getRank().getData() - 1; + for(; i >= 0 ; i--) + if (!states[i].count(transition.first.second[i])) break; + + if (i == -1) res.insert(transition.second.begin(), transition.second.end()); + } + return res; +} + +bool Accept::accept(const automaton::NFTA& automaton, const tree::RankedTree & tree) { + std::set<State> res = calculateStates(automaton, tree.getRoot()); + for (auto & state : res) + if (automaton.getFinalStates().count(state)) return true; + return false; +} + bool recursiveAccept(const automaton::NFA& automaton, const automaton::State& state, const string::LinearString& string) { if( string.getContent().empty( ) ) return automaton.getFinalStates().count( state ); @@ -101,13 +162,13 @@ void Accept::Visit(void*, const automaton::MultiInitialStateNFA& ) const { } void Accept::Visit(void* data, const automaton::NFA& automaton) const { - std::pair<const string::LinearString*, bool> & res = *((std::pair<const string::LinearString*, bool>*) data); - res.second = this->accept(automaton, *res.first); + std::pair<const alib::Object*, bool> & res = *((std::pair<const alib::Object*, bool>*) data); + res.second = this->accept(automaton, static_cast<const string::LinearString&>(res.first->getData())); } void Accept::Visit(void* data, const automaton::DFA& automaton) const { - std::pair<const string::LinearString*, bool> & res = *((std::pair<const string::LinearString*, bool>*) data); - res.second = this->accept(automaton, *res.first); + std::pair<const alib::Object*, bool> & res = *((std::pair<const alib::Object*, bool>*) data); + res.second = this->accept(automaton, static_cast<const string::LinearString&>(res.first->getData())); } void Accept::Visit(void*, const automaton::ExtendedNFA& ) const { @@ -119,8 +180,8 @@ void Accept::Visit(void*, const automaton::CompactNFA& ) const { } void Accept::Visit(void* data, const DPDA& automaton) const { - std::pair<const string::LinearString*, bool> & res = *((std::pair<const string::LinearString*, bool>*) data); - res.second = this->accept(automaton, *res.first); + std::pair<const alib::Object*, bool> & res = *((std::pair<const alib::Object*, bool>*) data); + res.second = this->accept(automaton, static_cast<const string::LinearString&>(res.first->getData())); } void Accept::Visit(void*, const SinglePopDPDA&) const { @@ -163,6 +224,16 @@ void Accept::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Accept::Visit(void* data, const automaton::DFTA& automaton) const { + std::pair<const alib::Object*, bool> & res = *((std::pair<const alib::Object*, bool>*) data); + res.second = this->accept(automaton, static_cast<const tree::RankedTree&>(res.first->getData())); +} + +void Accept::Visit(void* data, const NFTA& automaton) const { + std::pair<const alib::Object*, bool> & res = *((std::pair<const alib::Object*, bool>*) data); + res.second = this->accept(automaton, static_cast<const tree::RankedTree&>(res.first->getData())); +} + const Accept Accept::ACCEPT; } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h index e1cc13d7aca0af5e47c361e5c6420f76175bc9be..ed451178ce363eaddf8d5d975179f2e639eedbc0 100644 --- a/alib2algo/src/automaton/run/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -9,7 +9,9 @@ #define _AUTOMATON_ACCEPT_H__ #include <automaton/Automaton.h> +#include <object/Object.h> #include <string/LinearString.h> +#include <tree/RankedTree/RankedTree.h> namespace automaton { @@ -21,12 +23,18 @@ public: * Performs conversion. * @return left regular grammar equivalent to source automaton. */ + static bool accept(const automaton::Automaton& automaton, const alib::Object& object); static bool accept(const automaton::Automaton& automaton, const string::LinearString& string); + static bool accept(const automaton::Automaton& automaton, const tree::RankedTree& string); static bool accept(const automaton::DFA& automaton, const string::LinearString& string); static bool accept(const automaton::NFA& automaton, const string::LinearString& string); static bool accept(const automaton::DPDA& automaton, const string::LinearString& string); + static bool accept(const automaton::DFTA& automaton, const tree::RankedTree& tree); + static bool accept(const automaton::NFTA& automaton, const tree::RankedTree& tree); private: + static State calculateState(const automaton::DFTA& automaton, const tree::RankedNode & node); + void Visit(void*, const EpsilonNFA& automaton) const; void Visit(void*, const MultiInitialStateNFA& automaton) const; void Visit(void*, const NFA& automaton) const; @@ -44,6 +52,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const Accept ACCEPT; }; diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp index 6e92814c32346571efe6f3771fe43ef32089f983..a07b512feb40b3e08ffc979dc00774149c54e4a3 100644 --- a/alib2algo/src/automaton/run/Occurrences.cpp +++ b/alib2algo/src/automaton/run/Occurrences.cpp @@ -10,6 +10,7 @@ #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> #include <automaton/PDA/DPDA.h> +#include <automaton/TA/DFTA.h> #include <deque> @@ -17,8 +18,22 @@ namespace automaton { namespace run { +std::set<unsigned> Occurrences::occurrences(const automaton::Automaton& automaton, const alib::Object& object) { + std::pair<const alib::Object*, std::set<unsigned>> data(&object, {}); + automaton.getData().Accept((void*) &data, Occurrences::OCCURRENCES); + return data.second; +} + std::set<unsigned> Occurrences::occurrences(const automaton::Automaton& automaton, const string::LinearString& string) { - std::pair<const string::LinearString*, std::set<unsigned>> data(&string, {}); + alib::Object obj(string); + std::pair<const alib::Object*, std::set<unsigned>> data(&obj, {}); + automaton.getData().Accept((void*) &data, Occurrences::OCCURRENCES); + return data.second; +} + +std::set<unsigned> Occurrences::occurrences(const automaton::Automaton& automaton, const tree::RankedTree& tree) { + alib::Object obj(tree); + std::pair<const alib::Object*, std::set<unsigned>> data(&obj, {}); automaton.getData().Accept((void*) &data, Occurrences::OCCURRENCES); return data.second; } @@ -49,6 +64,32 @@ std::set<unsigned> Occurrences::occurrences(const automaton::DFA& automaton, con return occ; } +State Occurrences::occurences(const automaton::DFTA & automaton, const tree::RankedNode & node, std::set<unsigned> & occ, unsigned & i) { + std::vector<State> states; + unsigned tmp = i; + i++; + states.reserve(node.getSymbol().getRank().getData()); + bool fail = false; + for (const auto & child : node.getChildren()) { + State state = occurences(automaton, *child, occ, i); + if (state == FAILSTATE) fail = true; + else if (!fail) states.push_back(state); + } + if (fail) return FAILSTATE; + const auto & it = automaton.getTransitions().find(std::make_pair(node.getSymbol(), states)); + if (it == automaton.getTransitions().end()) return FAILSTATE; + State state = it -> second; + if (automaton.getFinalStates().count(state)) occ.insert(tmp); + return state; +} + +std::set<unsigned> Occurrences::occurrences(const automaton::DFTA& automaton, const tree::RankedTree & tree) { + std::set<unsigned> occ; + unsigned i = 0; + occurences(automaton, tree.getRoot(), occ, i); + return occ; +} + std::set<unsigned> Occurrences::occurrences(const automaton::DPDA& automaton, const string::LinearString& string) { automaton::State state = automaton.getInitialState(); std::deque<alphabet::Symbol> pushdownStore; @@ -111,8 +152,8 @@ void Occurrences::Visit(void*, const automaton::NFA& ) const { } void Occurrences::Visit(void* data, const automaton::DFA& automaton) const { - std::pair<const string::LinearString*, std::set<unsigned>> & res = *((std::pair<const string::LinearString*, std::set<unsigned>>*) data); - res.second = this->occurrences(automaton, *res.first); + std::pair<const alib::Object*, std::set<unsigned>> & res = *((std::pair<const alib::Object*, std::set<unsigned>>*) data); + res.second = this->occurrences(automaton, static_cast<const string::LinearString&>(res.first->getData())); } void Occurrences::Visit(void*, const automaton::ExtendedNFA& ) const { @@ -124,8 +165,8 @@ void Occurrences::Visit(void*, const automaton::CompactNFA& ) const { } void Occurrences::Visit(void* data, const DPDA& automaton) const { - std::pair<const string::LinearString*, std::set<unsigned>> & res = *((std::pair<const string::LinearString*, std::set<unsigned>>*) data); - res.second = this->occurrences(automaton, *res.first); + std::pair<const alib::Object*, std::set<unsigned>> & res = *((std::pair<const alib::Object*, std::set<unsigned>>*) data); + res.second = this->occurrences(automaton, static_cast<const string::LinearString&>(res.first->getData())); } void Occurrences::Visit(void*, const SinglePopDPDA&) const { @@ -168,6 +209,15 @@ void Occurrences::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Occurrences::Visit(void* data, const automaton::DFTA& automaton) const { + std::pair<const alib::Object*, std::set<unsigned>> & res = *((std::pair<const alib::Object*, std::set<unsigned>>*) data); + res.second = this->occurrences(automaton, static_cast<const tree::RankedTree&>(res.first->getData())); +} + +void Occurrences::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Occurrences Occurrences::OCCURRENCES; } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h index 7481e1033a4d0123a343a021cadcb4fbbc2d81de..dc15fb58485991fa00f81e2117c77ce6382e25ee 100644 --- a/alib2algo/src/automaton/run/Occurrences.h +++ b/alib2algo/src/automaton/run/Occurrences.h @@ -9,7 +9,9 @@ #define _AUTOMATON_OCCURRENCES_H__ #include <automaton/Automaton.h> +#include <object/Object.h> #include <string/LinearString.h> +#include <tree/RankedTree/RankedTree.h> namespace automaton { @@ -21,11 +23,16 @@ public: * Performs conversion. * @return left regular grammar equivalent to source automaton. */ + static std::set<unsigned> occurrences(const automaton::Automaton& automaton, const alib::Object& object); static std::set<unsigned> occurrences(const automaton::Automaton& automaton, const string::LinearString& string); + static std::set<unsigned> occurrences(const automaton::Automaton& automaton, const tree::RankedTree& string); static std::set<unsigned> occurrences(const automaton::DFA& automaton, const string::LinearString& string); static std::set<unsigned> occurrences(const automaton::DPDA& automaton, const string::LinearString& string); + static std::set<unsigned> occurrences(const automaton::DFTA& automaton, const tree::RankedTree & tree); private: + static State occurences(const automaton::DFTA & automaton, const tree::RankedNode & node, std::set<unsigned> & occ, unsigned & i); + void Visit(void*, const EpsilonNFA& automaton) const; void Visit(void*, const MultiInitialStateNFA& automaton) const; void Visit(void*, const NFA& automaton) const; @@ -43,6 +50,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const Occurrences OCCURRENCES; }; diff --git a/alib2algo/src/automaton/run/Result.cpp b/alib2algo/src/automaton/run/Result.cpp index 893125a1cca97f82034843fa145fe6ad85e0a37f..0194f931c5958dbf6b7548a4cc425ef053ad9b9c 100644 --- a/alib2algo/src/automaton/run/Result.cpp +++ b/alib2algo/src/automaton/run/Result.cpp @@ -9,6 +9,7 @@ #include <exception/AlibException.h> #include <automaton/FSM/DFA.h> #include <automaton/PDA/DPDA.h> +#include <automaton/TA/DFTA.h> #include <label/LabelSetLabel.h> #include <deque> @@ -17,8 +18,8 @@ namespace automaton { namespace run { -label::Label Result::result(const automaton::Automaton& automaton, const string::LinearString& string) { - std::pair<const string::LinearString*, label::Label*> data(&string, NULL); +label::Label Result::result(const automaton::Automaton& automaton, const alib::Object& object) { + std::pair<const alib::Object*, label::Label*> data(&object, NULL); automaton.getData().Accept((void*) &data, Result::RESULT); label::Label res = std::move(*data.second); delete data.second; @@ -74,6 +75,24 @@ label::Label Result::result(const automaton::DPDA& automaton, const string::Line } } +automaton::State Result::calculateState(const automaton::DFTA& automaton, const tree::RankedNode & node) { + std::vector<automaton::State> states; + states.reserve(node.getSymbol().getRank().getData()); + for (const auto & child : node.getChildren()) { + automaton::State state = calculateState(automaton, *child); + if (state == FAILSTATE) return FAILSTATE; + states.push_back(state); + } + const auto & it = automaton.getTransitions().find(std::make_pair(node.getSymbol(), states)); + if (it == automaton.getTransitions().end()) return FAILSTATE; + return it -> second; +} + +label::Label Result::result(const automaton::DFTA& automaton, const tree::RankedTree& tree) { + State state = calculateState(automaton, tree.getRoot()); + return state.getName(); +} + void Result::Visit(void*, const automaton::EpsilonNFA& ) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } @@ -87,8 +106,8 @@ void Result::Visit(void*, const automaton::NFA& ) const { } void Result::Visit(void* data, const automaton::DFA& automaton) const { - std::pair<const string::LinearString*, label::Label*> & res = *((std::pair<const string::LinearString*, label::Label*>*) data); - res.second = new label::Label(std::move(this->result(automaton, *res.first))); + std::pair<const alib::Object*, label::Label*> & res = *((std::pair<const alib::Object*, label::Label*>*) data); + res.second = new label::Label(std::move(this->result(automaton, static_cast<const string::LinearString&>(res.first->getData())))); } void Result::Visit(void*, const automaton::ExtendedNFA& ) const { @@ -100,8 +119,8 @@ void Result::Visit(void*, const automaton::CompactNFA& ) const { } void Result::Visit(void* data, const DPDA& automaton) const { - std::pair<const string::LinearString*, label::Label*> & res = *((std::pair<const string::LinearString*, label::Label*>*) data); - res.second = new label::Label(std::move(this->result(automaton, *res.first))); + std::pair<const alib::Object*, label::Label*> & res = *((std::pair<const alib::Object*, label::Label*>*) data); + res.second = new label::Label(std::move(this->result(automaton, static_cast<const string::LinearString&>(res.first->getData())))); } void Result::Visit(void*, const SinglePopDPDA&) const { @@ -144,6 +163,15 @@ void Result::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Result::Visit(void* data, const automaton::DFTA& automaton) const { + std::pair<const alib::Object*, label::Label*> & res = *((std::pair<const alib::Object*, label::Label*>*) data); + res.second = new label::Label(std::move(this->result(automaton, static_cast<const tree::RankedTree&>(res.first->getData())))); +} + +void Result::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Result Result::RESULT; } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Result.h b/alib2algo/src/automaton/run/Result.h index 15fd71dbb883074e041b9bab6da531585c4321f4..acdebc95b55c449b71ec25851149afb401cfa7ed 100644 --- a/alib2algo/src/automaton/run/Result.h +++ b/alib2algo/src/automaton/run/Result.h @@ -10,7 +10,9 @@ #include <automaton/Automaton.h> #include <string/LinearString.h> +#include <object/Object.h> #include <label/Label.h> +#include <tree/RankedTree/RankedTree.h> namespace automaton { @@ -22,12 +24,14 @@ public: * Performs conversion. * @return left regular grammar equivalent to source automaton. */ - static label::Label result(const automaton::Automaton& automaton, const string::LinearString& string); + static label::Label result(const automaton::Automaton& automaton, const alib::Object& object); static label::Label result(const automaton::DFA& automaton, const string::LinearString& string); - static label::Label result(const automaton::NFA& automaton, const string::LinearString& string); static label::Label result(const automaton::DPDA& automaton, const string::LinearString& string); + static label::Label result(const automaton::DFTA& automaton, const tree::RankedTree & tree); private: + static automaton::State calculateState(const automaton::DFTA& automaton, const tree::RankedNode & node); + void Visit(void*, const EpsilonNFA& automaton) const; void Visit(void*, const MultiInitialStateNFA& automaton) const; void Visit(void*, const NFA& automaton) const; @@ -45,6 +49,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const Result RESULT; }; diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp index cfdc6b57039742c47ab15dccb5e448762079849b..13c329b5cf7267acdde8f21748125655842244b7 100644 --- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp +++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp @@ -146,6 +146,14 @@ void EpsilonRemoverIncoming::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void EpsilonRemoverIncoming::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void EpsilonRemoverIncoming::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const EpsilonRemoverIncoming EpsilonRemoverIncoming::EPSILON_REMOVER_INCOMING; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h index 424a9e23bca9b3d9dc88bb72ce55b813f74b0fdb..8a79bb5d25ab83abcabb847f2aab047d39fb6aa8 100644 --- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h +++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h @@ -53,6 +53,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const EpsilonRemoverIncoming EPSILON_REMOVER_INCOMING; }; diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp index 966278070280652708469d0a7ba6de9bce5b3ce5..c4864600b21da29e1f1b69d8dc367b6233598774 100644 --- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp +++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp @@ -139,6 +139,14 @@ void EpsilonRemoverOutgoing::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void EpsilonRemoverOutgoing::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void EpsilonRemoverOutgoing::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const EpsilonRemoverOutgoing EpsilonRemoverOutgoing::EPSILON_REMOVER_OUTGOING; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h index 86f3201e500973adbc915b6652c7150a60a4595e..e76b99a711172295f2b4512593c6c821202df102 100644 --- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h +++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h @@ -53,6 +53,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const EpsilonRemoverOutgoing EPSILON_REMOVER_OUTGOING; }; diff --git a/alib2algo/src/automaton/simplify/Minimize.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp index 2bd6b930bc7ec8d378d94f968b9f88d59f903453..62e6bffa9ab5c77154cfa6909337a746b424250e 100644 --- a/alib2algo/src/automaton/simplify/Minimize.cpp +++ b/alib2algo/src/automaton/simplify/Minimize.cpp @@ -208,6 +208,14 @@ void Minimize::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Minimize::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void Minimize::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Minimize Minimize::MINIMIZE; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/Minimize.h b/alib2algo/src/automaton/simplify/Minimize.h index 00a68b654657583da3cb57c39b770da79c031cd5..d71753aa99a1d7c3896ee84e636b1444a3a24adc 100644 --- a/alib2algo/src/automaton/simplify/Minimize.h +++ b/alib2algo/src/automaton/simplify/Minimize.h @@ -42,6 +42,8 @@ protected: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const Minimize MINIMIZE; }; diff --git a/alib2algo/src/automaton/simplify/Normalize.cpp b/alib2algo/src/automaton/simplify/Normalize.cpp index 83edf5d8b303a5b5eba533f7aadb58f576811295..6dd62b0101444f4454eee51bc8b709497ee6b762 100644 --- a/alib2algo/src/automaton/simplify/Normalize.cpp +++ b/alib2algo/src/automaton/simplify/Normalize.cpp @@ -238,6 +238,14 @@ void Normalize::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Normalize::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void Normalize::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Normalize Normalize::NORMALIZE; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/Normalize.h b/alib2algo/src/automaton/simplify/Normalize.h index e6bad87ff6780479fc6a7f32a6955e177fce12ec..791ae5a70dcb913b5c1e38913f68746076ebda4e 100644 --- a/alib2algo/src/automaton/simplify/Normalize.h +++ b/alib2algo/src/automaton/simplify/Normalize.h @@ -45,6 +45,8 @@ protected: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const Normalize NORMALIZE; }; diff --git a/alib2algo/src/automaton/simplify/Rename.cpp b/alib2algo/src/automaton/simplify/Rename.cpp index c44b4ba020d4624ea3a26816575a8059a55b3ac9..30f84f8c40b95635c3d6c9c2eb0b961b8676bf7f 100644 --- a/alib2algo/src/automaton/simplify/Rename.cpp +++ b/alib2algo/src/automaton/simplify/Rename.cpp @@ -357,6 +357,14 @@ void Rename::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Rename::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void Rename::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Rename Rename::RENAME; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/Rename.h b/alib2algo/src/automaton/simplify/Rename.h index e3eb0281ec7099a766b41a0ae7898e88999cd93a..9312f94ed88010759c627c3e577867aaddbe496b 100644 --- a/alib2algo/src/automaton/simplify/Rename.h +++ b/alib2algo/src/automaton/simplify/Rename.h @@ -53,6 +53,8 @@ protected: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const Rename RENAME; }; diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp index 4712810c6e5360e8f4d6b9df79225abba601a0d5..d5abc7b46e3b938bd3232def8a5e55c0fc1ff377 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp +++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp @@ -166,6 +166,14 @@ void SingleInitialState::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void SingleInitialState::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void SingleInitialState::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const SingleInitialState SingleInitialState::SINGLE_INITIAL_STATE; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h index 65a0c20cfbb7825897610aed6512cf13ab6ff40f..881fe3526979ce7f2ac7b7a9e0540f7e92c13f30 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -52,6 +52,8 @@ private: void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; static const SingleInitialState SINGLE_INITIAL_STATE; }; diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp index a2cef7225aeecd92c85033f1a2954456804e39cc..16eba371dfc8ad255767e594958a6289e53b0085 100644 --- a/alib2algo/src/automaton/simplify/Trim.cpp +++ b/alib2algo/src/automaton/simplify/Trim.cpp @@ -117,6 +117,14 @@ void Trim::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void Trim::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void Trim::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const Trim Trim::TRIM; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/Trim.h b/alib2algo/src/automaton/simplify/Trim.h index 7b6ce047bdb337cc7f95291bc064ac14a281f365..2cb8fd2b5f787513f4316e51a525f35b195411e3 100644 --- a/alib2algo/src/automaton/simplify/Trim.h +++ b/alib2algo/src/automaton/simplify/Trim.h @@ -45,6 +45,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const Trim TRIM; }; diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp index b6a5312dd40f37ba3e50841bbdb2a6d86efc8c01..1e05460cc13e952e72f73a8cfebe6b06ee79396d 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp @@ -193,6 +193,14 @@ void UnreachableStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void UnreachableStatesRemover::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UnreachableStatesRemover::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const UnreachableStatesRemover UnreachableStatesRemover::UNREACHABLE_STATES_REMOVER; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h index 3f2d436d223a1a4f3f51923b5944e449aae1f17a..b584132ddac6947a1a59cf348df23a18310de6c3 100644 --- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h @@ -45,6 +45,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const UnreachableStatesRemover UNREACHABLE_STATES_REMOVER; }; diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp index 5b843eacdd4a203a4e7d9367278a2a189ef69322..b0881342918b6d72964a783f97383406abbcf5e8 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp @@ -202,6 +202,14 @@ void UselessStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void UselessStatesRemover::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UselessStatesRemover::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const UselessStatesRemover UselessStatesRemover::USELESS_STATES_REMOVER; } /* namespace simplify */ diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h index ba26622ab9b79603731120648ac3135a766f4142..38c86626323929881f93da667a1eccec50ad6bee 100644 --- a/alib2algo/src/automaton/simplify/UselessStatesRemover.h +++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h @@ -45,6 +45,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; static const UselessStatesRemover USELESS_STATES_REMOVER; }; diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp index b935f1892d0d71cd3b6068f809f32117287da257..fc3bbd95b4295cb138c0d297d7a827f29b73553d 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp @@ -205,6 +205,16 @@ void AutomataConcatenation::Visit(void*, const automaton::OneTapeDTM&, const aut throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataConcatenation::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataConcatenation::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataConcatenation AutomataConcatenation::AUTOMATA_CONCATENATION; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.h b/alib2algo/src/automaton/transform/AutomataConcatenation.h index 2cec016f668bc3754b8619223a976ef7e784054a..fb4cdda014b8f27890ba6e296c569e22997e8ca0 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenation.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h @@ -50,6 +50,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + static const AutomataConcatenation AUTOMATA_CONCATENATION; }; diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp index 8dc1219dad761aecc17a50e8432aced706e3cdbe..2c41b90c9879d1f263bccd2867f673e967777e19 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp @@ -207,6 +207,16 @@ void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::OneTa throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataConcatenationEpsilonTransition::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataConcatenationEpsilonTransition AutomataConcatenationEpsilonTransition::AUTOMATA_CONCATENATION_EPSILON_TRANSITION; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h index 29ea1403b3b9665a71125c257daa997862b46828..133b493f7a97ade53c498beb1efb217b31b96664 100644 --- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h @@ -51,6 +51,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + static const AutomataConcatenationEpsilonTransition AUTOMATA_CONCATENATION_EPSILON_TRANSITION; }; diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp index 2100360dc26b3294721a872c3840d33b45bdc91c..187037c30e2ab79eb877e49faf1958b06af724fc 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp @@ -180,6 +180,16 @@ void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::OneTape throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataIntersectionCartesianProduct::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataIntersectionCartesianProduct AutomataIntersectionCartesianProduct::AUTOMATA_INTERSECTION_CARTESIAN_PRODUCT; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h index 2878a772f1f006368b3eee78e8ed6a656765fab7..2369fda445bb5cbdf07f0be6790e02aebe5b03cf 100644 --- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h @@ -50,6 +50,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + static const AutomataIntersectionCartesianProduct AUTOMATA_INTERSECTION_CARTESIAN_PRODUCT; }; diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp index 380da7f87ac4a9142e035e5ec42bb6fb9e1cafbc..94ba56cbc059b638e36530e0c410d2a181ac1f9d 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp @@ -194,6 +194,16 @@ void AutomataUnionCartesianProduct::Visit(void*, const automaton::OneTapeDTM&, c throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataUnionCartesianProduct::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataUnionCartesianProduct::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataUnionCartesianProduct AutomataUnionCartesianProduct::AUTOMATA_UNION_CARTESIAN_PRODUCT; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h index 936de8af9f8357fb2ef3013e916de602cf668673..424f6f39d85c29b6994fd9e73146321b0db3ff1a 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h +++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h @@ -50,6 +50,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + static const AutomataUnionCartesianProduct AUTOMATA_UNION_CARTESIAN_PRODUCT; }; diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp index 27cef9981330dc1a74792a70c18abd2340429cc6..a5d303b7a7d0a097a53955f1e411b4b1ac1972e6 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp @@ -227,6 +227,16 @@ void AutomataUnionEpsilonTransition::Visit(void*, const automaton::OneTapeDTM&, throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataUnionEpsilonTransition::Visit(void*, const automaton::DFTA&, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataUnionEpsilonTransition::Visit(void*, const automaton::NFTA&, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataUnionEpsilonTransition AutomataUnionEpsilonTransition::AUTOMATA_UNION_EPSILON_TRANSITION; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h index 07a987af1488c0dde2da411a0bf4a3da37a16d66..7a79873aed1bf7987877b4fcc1f758ef4ab5e265 100644 --- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h @@ -51,6 +51,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& first, const automaton::OneTapeDTM& second) const; + void Visit(void* data, const automaton::DFTA& first, const automaton::DFTA& second) const; + void Visit(void* data, const automaton::NFTA& first, const automaton::NFTA& second) const; + static const AutomataUnionEpsilonTransition AUTOMATA_UNION_EPSILON_TRANSITION; }; diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp index e30f54c1ab04a41c412f914dd4aa583d957bd52d..c1dd029dde8c6b9c11c40a3c93f7c6cb697e0335 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp @@ -123,6 +123,16 @@ void AutomatonIteration::Visit(void*, const automaton::OneTapeDTM&) const throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomatonIteration::Visit(void*, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomatonIteration::Visit(void*, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomatonIteration AutomatonIteration::AUTOMATON_ITERATION; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h index 7df870107e786c76ab199d480e114e0f2d2d4980..1a7646abd8fdb1202a783b54f937f28b9bd6922b 100644 --- a/alib2algo/src/automaton/transform/AutomatonIteration.h +++ b/alib2algo/src/automaton/transform/AutomatonIteration.h @@ -50,6 +50,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& automaton) const; + void Visit(void* data, const automaton::DFTA& first) const; + void Visit(void* data, const automaton::NFTA& first) const; + static const AutomatonIteration AUTOMATON_ITERATION; }; diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp index 61eda50e793d9248c2cf1137088a0e4608f9b0db..739a8f57275f28b50081fc6dd8b420ef0ce493e3 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp @@ -123,6 +123,16 @@ void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::OneTapeD throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::DFTA&) const +{ + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::NFTA&) const +{ + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomatonIterationEpsilonTransition AutomatonIterationEpsilonTransition::AUTOMATON_ITERATION_EPSILON_TRANSITION; } /* namespace transform */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h index 2181c1d6f3ad907bf7aedffc5efd7b00ccbffd05..80cf82296d5f3c462c96f877fc88f34216e3c15b 100644 --- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h @@ -50,6 +50,9 @@ private: void Visit(void* data, const automaton::OneTapeDTM& automaton) const; + void Visit(void* data, const automaton::DFTA& first) const; + void Visit(void* data, const automaton::NFTA& first) const; + static const AutomatonIterationEpsilonTransition AUTOMATON_ITERATION_EPSILON_TRANSITION; }; diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ec371074f6980626359820d4a698cb383131cc5 --- /dev/null +++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp @@ -0,0 +1,238 @@ +/* + * RandomTreeFactory.cpp + * + * Created on: 18. 3. 2015 + * Author: Stepan Plachy + */ + +#include "RandomTreeFactory.h" + +#include <vector> +#include <map> +#include <set> +#include <algorithm> +#include <cstdlib> +#include <ctime> +#include <cmath> + +#include <iostream> + +namespace tree { + +namespace generate { + +int c = 0; + + +struct Node { + char symbol; + int depth; + Node * right; + Node * child = NULL; + int rank = 0; + + Node() : depth(0) {} + Node(Node * parent) : depth(parent -> depth + 1) { + if (parent -> child == NULL) { + parent -> child = this; + right = this; + } else { + right = parent -> child -> right; + parent -> child -> right = this; + } + parent -> rank++; + } + ~Node() { + if (child == NULL) return; + Node * ch = child; + do { + Node * tmp = ch -> right; + delete ch; + ch = tmp; + } while (ch != child); + } + + void rotateLeftBranch() { + if (child != NULL) child -> rotateLeftBranch(); + if (rank > 1) { + int angle = rand() % rank; + Node * newChild = child; + for (int i = 0; i < angle; i++) { + newChild = newChild -> right; + } + child = newChild; + } + } + + void generateUnrankedSymbols(const std::vector<char> & alphabet) { + symbol = alphabet[rand() % alphabet.size()]; + Node * nextChild = child; + for(int i = 0; i < rank; i++) { + nextChild -> generateUnrankedSymbols(alphabet); + nextChild = nextChild -> right; + } + } + + void generateRankedSymbols(const std::map<int, std::vector<char> > rankedAlphabet) { + const std::vector<char> & alphabet = rankedAlphabet.at(rank); + symbol = alphabet[rand() % alphabet.size()]; + Node * nextChild = child; + for(int i = 0; i < rank; i++) { + nextChild -> generateRankedSymbols(rankedAlphabet); + nextChild = nextChild -> right; + } + } + + void fillRanks(std::map<int, std::vector<char> > & rankedAlphabet) { + rankedAlphabet[rank]; + Node * nextChild = child; + for(int i = 0; i < rank; i++) { + nextChild -> fillRanks(rankedAlphabet); + nextChild = nextChild -> right; + } + } + + UnrankedNode * createUnrankedNode() { + std::list<UnrankedNode *> children; + Node * nextChild = child; + for(int i = 0; i < rank; i++) { + children.push_back(nextChild -> createUnrankedNode()); + nextChild = nextChild -> right; + } + return new UnrankedNode(alphabet::LabeledSymbol(symbol), children); + } + + RankedNode * createRankedNode() { + std::vector<RankedNode *> children; + Node * nextChild = child; + for(int i = 0; i < rank; i++) { + children.push_back(nextChild -> createRankedNode()); + nextChild = nextChild -> right; + } + return new RankedNode(alphabet::RankedSymbol(symbol, rank), children); + } + + void nicePrint(std::ostream & os = std::cout, const std::string & prefix = "", const bool last = true) const { + os << prefix; + + std::string nextPrefix(prefix); + if (last) { + os << "\\-"; + nextPrefix += " "; + } else { + os << "|-"; + nextPrefix += "| "; + } + os << symbol << " (" << rank << ")" << std::endl; + + Node * nextChild = child; + for (int i = 0; i < rank; i++) + { + //os << nextPrefix << "|" << std::endl; + nextChild -> nicePrint(os, nextPrefix, i == rank-1); + nextChild = nextChild -> right; + } + } +}; + +std::vector<char> generateUnrankedAlphabet(int maxAlphabetSize) { + std::vector<char> symbols (26); + for(int i = 0; i < 26; i++) symbols[i] = i + 'a'; + random_shuffle(symbols.begin(), symbols.end()); + return std::vector<char> (symbols.begin(), symbols.begin() + maxAlphabetSize); +} + +void generateRankedAlphabet(std::map<int, std::vector<char> > & rankedAlphabet, int maxAlphabetSize) { + int ranksCount = rankedAlphabet.size(); + std::vector<char> unrankedAlphabet = generateUnrankedAlphabet(maxAlphabetSize > ranksCount ? maxAlphabetSize : ranksCount); + + std::set<int> rankSeparators; + rankSeparators.insert(0); + rankSeparators.insert(unrankedAlphabet.size()); + while ((int)rankSeparators.size() != ranksCount + 1 /*&& rankSeparators.size() != maxRank + 2*/) rankSeparators.insert(rand() % unrankedAlphabet.size()); + + std::set<int>::iterator it = rankSeparators.begin(); + for (std::map<int, std::vector<char> >::iterator i = rankedAlphabet.begin(); i != rankedAlphabet.end(); ++i) { + std::set<int>::iterator prevIt = it++; + i -> second.insert(i -> second.begin(), unrankedAlphabet.begin() + *prevIt, unrankedAlphabet.begin() + *it); + } +} + +Node * generateTreeStructure(int depth, int nodesCount, int maxRank = INT_MAX) { + if(maxRank != INT_MAX && pow(maxRank, depth + 1) - 1 < nodesCount) throw exception::AlibException("number of nodes is too small"); + srand(time(NULL)); + std::vector<Node *> nodes (nodesCount); + + //generate path depth long + Node * root = nodes[0] = new Node(); + for (int i = 1; i <= depth; i++) nodes[i] = new Node(nodes[i-1]); + //move final leaf to end + nodes[nodesCount-1] = nodes[depth]; + + int availableNodesIndex = depth; + int finalNodesIndex = nodesCount - 2; + while(finalNodesIndex >= availableNodesIndex) { + int randomIndex = rand() % availableNodesIndex; + Node * parent = nodes[randomIndex]; + Node * node = new Node(parent); + + //put node to end if it reached depth limit + if (node -> depth < depth) { + nodes[availableNodesIndex] = node; + availableNodesIndex++; + } else { + nodes[finalNodesIndex] = node; + finalNodesIndex--; + } + + //put parent node to end if it reached rank limit + if (parent -> rank >= maxRank) { + nodes[randomIndex] = nodes[availableNodesIndex-1]; + nodes[finalNodesIndex] = parent; + availableNodesIndex--; + finalNodesIndex--; + } + } + + //move generated path to random branch + root -> rotateLeftBranch(); + + return root; +} + +UnrankedTree RandomTreeFactory::generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank) { + Node * root = generateTreeStructure(depth, nodesCount, maxRank); + std::vector<char> alphabet = generateUnrankedAlphabet(maxAlphabetSize); + root -> generateUnrankedSymbols(alphabet); + + std::set<alphabet::LabeledSymbol> treeAlphabet; + for (std::vector<char>::iterator it = alphabet.begin(); it != alphabet.end(); ++it) { + treeAlphabet.insert(alphabet::LabeledSymbol(*it)); + } + UnrankedTree tree (treeAlphabet, *std::move(root -> createUnrankedNode())); + delete root; + return tree; +} + +RankedTree RandomTreeFactory::generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank) { + Node * root = generateTreeStructure(depth, nodesCount, maxRank); + std::map<int, std::vector<char> > rankedAlphabet; + root -> fillRanks(rankedAlphabet); + generateRankedAlphabet(rankedAlphabet, maxAlphabetSize); + root -> generateRankedSymbols(rankedAlphabet); + + std::set<alphabet::RankedSymbol> treeRankedAlphabet; + for (std::map<int, std::vector<char> >::iterator it = rankedAlphabet.begin(); it != rankedAlphabet.end(); ++it) { + std::vector<char> & alphabet = it -> second; + for (std::vector<char>::iterator i = alphabet.begin(); i != alphabet.end(); ++i) { + treeRankedAlphabet.insert(alphabet::RankedSymbol(*i, it -> first)); + } + } + RankedTree tree (treeRankedAlphabet, std::move(*root -> createRankedNode())); + delete root; + return tree; +} + +} /* namespace generate */ + +} /* namespace automaton */ diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.h b/alib2algo/src/tree/generate/RandomTreeFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..89112bb39fa833639f5bdf078c2ee5ee3748ced3 --- /dev/null +++ b/alib2algo/src/tree/generate/RandomTreeFactory.h @@ -0,0 +1,37 @@ +/* + * RandomTreeFactory.h + * + * Created on: 18. 3. 2015 + * Author: Stepan Plachy + */ + +#ifndef RANDOM_TREE_FACTORY_H_ +#define RANDOM_TREE_FACTORY_H_ + +#include <deque> +#include <set> +#include <climits> + +#include <exception/AlibException.h> +#include <alphabet/RankedSymbol.h> +#include <alphabet/LabeledSymbol.h> +#include <tree/RankedTree/RankedTree.h> +#include <tree/UnrankedTree/UnrankedTree.h> + +namespace tree { + +namespace generate { + +class RandomTreeFactory { +public: + static tree::RankedTree generateRankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank = INT_MAX); + static tree::UnrankedTree generateUnrankedTree(int depth, int nodesCount, int maxAlphabetSize, int maxRank = INT_MAX); + +private: +}; + +} /* namespace generate */ + +} /* namespace tree */ + +#endif /* RANDOM_TREE_FACTORY_H_ */ diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp index 0dbc7162d7d42cfed436ce6e219d2686985a7571..500099a10cfc639a78adb7b69d0afd5dc1664fd8 100644 --- a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp +++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp @@ -2,6 +2,7 @@ #include "determinizeTest.h" #include <automaton/FSM/NFA.h> +#include <automaton/TA/NFTA.h> #include <automaton/PDA/InputDrivenNPDA.h> #include <automaton/PDA/VisiblyPushdownNPDA.h> #include <alphabet/BottomOfTheStackSymbol.h> @@ -104,3 +105,36 @@ void determinizeTest::testDeterminizeVPA() { automaton.addInitialState(automaton::State(0)); automaton.addFinalState(automaton::State(4)); } + +void determinizeTest::testDeterminizeNFTA() { + automaton::NFTA automaton; + + const alphabet::RankedSymbol a ('a', 2); + const alphabet::RankedSymbol b ('b', 1); + const alphabet::RankedSymbol c ('c', 0); + const std::set<alphabet::RankedSymbol> alphabet {a, b, c}; + automaton.setInputSymbols(alphabet); + + automaton.addState(automaton::State(1)); + automaton.addState(automaton::State(2)); + automaton.addState(automaton::State(3)); + + std::vector<automaton::State> a1States = {automaton::State(1), automaton::State(3)}; + automaton.addTransition(a, a1States, automaton::State(1)); + automaton.addTransition(a, a1States, automaton::State(3)); + std::vector<automaton::State> a2States = {automaton::State(3), automaton::State(3)}; + automaton.addTransition(a, a2States, automaton::State(2)); + std::vector<automaton::State> bStates = {automaton::State(2)}; + automaton.addTransition(b, bStates, automaton::State(1)); + std::vector<automaton::State> cStates; + automaton.addTransition(c, cStates, automaton::State(3)); + + automaton.addFinalState(automaton::State(3)); + + + automaton::DFTA determinized = automaton::determinize::Determinize::determinize(automaton); + + CPPUNIT_ASSERT(determinized.getStates().size() == 5); + CPPUNIT_ASSERT(determinized.getFinalStates().size() == 3); + CPPUNIT_ASSERT(determinized.getTransitions().size() == 15); +} diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.h b/alib2algo/test-src/automaton/determinize/determinizeTest.h index 1269f9ad95c40d94cadf1129ca8ab0b62d1de74e..8bb94b7742d68b247bf573a1d904b66cacb97f09 100644 --- a/alib2algo/test-src/automaton/determinize/determinizeTest.h +++ b/alib2algo/test-src/automaton/determinize/determinizeTest.h @@ -9,6 +9,7 @@ class determinizeTest : public CppUnit::TestFixture CPPUNIT_TEST( testDeterminizeNFA ); CPPUNIT_TEST( testDeterminizeIDPDA ); CPPUNIT_TEST( testDeterminizeVPA ); + CPPUNIT_TEST( testDeterminizeNFTA ); CPPUNIT_TEST_SUITE_END(); public: @@ -18,6 +19,7 @@ public: void testDeterminizeNFA(); void testDeterminizeIDPDA(); void testDeterminizeVPA(); + void testDeterminizeNFTA(); }; #endif // DETERMINIZE_TEST_H_ diff --git a/alib2data/src/XmlApi.cpp b/alib2data/src/XmlApi.cpp index 0cdd3c7054ec5fd02786276a6304ad246168826e..cb7bbd5f058a8054d886cf944a6f05a29976817e 100644 --- a/alib2data/src/XmlApi.cpp +++ b/alib2data/src/XmlApi.cpp @@ -20,6 +20,7 @@ const exception::ExceptionFromXMLParser FromXMLParsers::exceptionParser; const alib::ObjectFromXMLParser FromXMLParsers::objectParser; const container::ContainerFromXMLParser FromXMLParsers::containerParser; const primitive::PrimitiveFromXMLParser FromXMLParsers::primitiveParser; +const tree::TreeFromXMLParser FromXMLParsers::treeParser; const label::LabelToXMLComposer ToXMLComposers::labelComposer; const alphabet::SymbolToXMLComposer ToXMLComposers::symbolComposer; @@ -32,6 +33,7 @@ const alib::ObjectToXMLComposer ToXMLComposers::objectComposer; const exception::ExceptionToXMLComposer ToXMLComposers::exceptionComposer; const container::ContainerToXMLComposer ToXMLComposers::containerComposer; const primitive::PrimitiveToXMLComposer ToXMLComposers::primitiveComposer; +const tree::TreeToXMLComposer ToXMLComposers::treeComposer; const ToXMLComposers ToXMLComposers::toXMLComposers; @@ -59,6 +61,8 @@ const std::string Names::AUTOMATON_NFA = "NFA"; const std::string Names::AUTOMATON_DFA = "DFA"; const std::string Names::AUTOMATON_EXTENDED_NFA = "ExtendedNFA"; const std::string Names::AUTOMATON_COMPACT_NFA = "CompactNFA"; +const std::string Names::AUTOMATON_DFTA = "DFTA"; +const std::string Names::AUTOMATON_NFTA = "NFTA"; const std::string Names::AUTOMATON_DPDA = "DPDA"; const std::string Names::AUTOMATON_SINGLE_POP_DPDA = "SinglePopDPDA"; const std::string Names::AUTOMATON_INPUT_DRIVEN_DPDA = "InputDrivenDPDA"; @@ -102,6 +106,8 @@ const std::string Names::PRIMITIVE_INTEGER = "Integer"; const std::string Names::PRIMITIVE_CHARACTER = "Character"; const std::string Names::PRIMITIVE_UNSIGNED = "Unsigned"; const std::string Names::PRIMITIVE_BOOL = "Bool"; +const std::string Names::TREE_RANKED_TREE = "RankedTree"; +const std::string Names::TREE_UNRANKED_TREE = "UnrankedTree"; Void xmlApi<Void>::parse(std::deque<sax::Token>& input) { return FromXMLParsers::objectParser.parseVoid(input); @@ -572,6 +578,30 @@ void xmlApi<automaton::OneTapeDTM>::compose(std::deque<sax::Token>& output, cons ToXMLComposers::automatonComposer.compose(output, data); } +automaton::DFTA xmlApi<automaton::DFTA>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::automatonParser.parseDFTA(input); +} + +bool xmlApi<automaton::DFTA>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::AUTOMATON_DFTA); +} + +void xmlApi<automaton::DFTA>::compose(std::deque<sax::Token>& output, const automaton::DFTA& data) { + ToXMLComposers::automatonComposer.compose(output, data); +} + +automaton::NFTA xmlApi<automaton::NFTA>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::automatonParser.parseNFTA(input); +} + +bool xmlApi<automaton::NFTA>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::AUTOMATON_NFTA); +} + +void xmlApi<automaton::NFTA>::compose(std::deque<sax::Token>& output, const automaton::NFTA& data) { + ToXMLComposers::automatonComposer.compose(output, data); +} + automaton::State xmlApi<automaton::State>::parse(std::deque<sax::Token>& input) { return FromXMLParsers::automatonParser.parseState(input); } @@ -1094,6 +1124,42 @@ void xmlApi<bool>::compose(std::deque<sax::Token>& output, bool data) { ToXMLComposers::primitiveComposer.compose(output, data); } +tree::Tree xmlApi<tree::Tree>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.parseTree(input); +} + +bool xmlApi<tree::Tree>::first(const std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.first(input); +} + +void xmlApi<tree::Tree>::compose(std::deque<sax::Token>& output, const tree::Tree& data) { + ToXMLComposers::treeComposer.compose(output, data); +} + +tree::RankedTree xmlApi<tree::RankedTree>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.parseRankedTree(input); +} + +bool xmlApi<tree::RankedTree>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::TREE_RANKED_TREE); +} + +void xmlApi<tree::RankedTree>::compose(std::deque<sax::Token>& output, const tree::RankedTree& data) { + ToXMLComposers::treeComposer.compose(output, data); +} + +tree::UnrankedTree xmlApi<tree::UnrankedTree>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.parseUnrankedTree(input); +} + +bool xmlApi<tree::UnrankedTree>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::TREE_UNRANKED_TREE); +} + +void xmlApi<tree::UnrankedTree>::compose(std::deque<sax::Token>& output, const tree::UnrankedTree& data) { + ToXMLComposers::treeComposer.compose(output, data); +} + void ToXMLComposers::Visit(void* data, const Void& voidObject) const { xmlApi<Void>::compose(*((std::deque<sax::Token>*) data), voidObject); } @@ -1190,6 +1256,14 @@ void ToXMLComposers::Visit(void* data, const automaton::CompactNFA& automaton) c xmlApi<automaton::CompactNFA>::compose(*((std::deque<sax::Token>*) data), automaton); } +void ToXMLComposers::Visit(void* data, const automaton::DFTA& automaton) const { + xmlApi<automaton::DFTA>::compose(*((std::deque<sax::Token>*) data), automaton); +} + +void ToXMLComposers::Visit(void* data, const automaton::NFTA& automaton) const { + xmlApi<automaton::NFTA>::compose(*((std::deque<sax::Token>*) data), automaton); +} + void ToXMLComposers::Visit(void* data, const automaton::DPDA& automaton) const { xmlApi<automaton::DPDA>::compose(*((std::deque<sax::Token>*) data), automaton); } @@ -1358,4 +1432,12 @@ void ToXMLComposers::Visit(void* data, const primitive::Bool& primitive) const { xmlApi<primitive::Bool>::compose(*((std::deque<sax::Token>*) data), primitive); } +void ToXMLComposers::Visit(void* data, const tree::RankedTree& tree) const { + xmlApi<tree::RankedTree>::compose(*((std::deque<sax::Token>*) data), tree); +} + +void ToXMLComposers::Visit(void* data, const tree::UnrankedTree& tree) const { + xmlApi<tree::UnrankedTree>::compose(*((std::deque<sax::Token>*) data), tree); +} + } /* namespace alib */ diff --git a/alib2data/src/XmlApi.hpp b/alib2data/src/XmlApi.hpp index 7afbb7405606fad1e5a0f15beec7145469a491bc..cf32f8ff9ce2701a29ddd20652e5449a90a11585 100644 --- a/alib2data/src/XmlApi.hpp +++ b/alib2data/src/XmlApi.hpp @@ -18,6 +18,7 @@ #include "object/ObjectFromXMLParser.h" #include "exception/ExceptionFromXMLParser.h" #include "primitive/PrimitiveFromXMLParser.h" +#include "tree/TreeFromXMLParser.h" #include "label/LabelToXMLComposer.h" #include "alphabet/SymbolToXMLComposer.h" @@ -29,6 +30,7 @@ #include "object/ObjectToXMLComposer.h" #include "exception/ExceptionToXMLComposer.h" #include "primitive/PrimitiveToXMLComposer.h" +#include "tree/TreeToXMLComposer.h" #include "object/ObjectBase.h" @@ -60,6 +62,8 @@ public: const static std::string AUTOMATON_DFA; const static std::string AUTOMATON_EXTENDED_NFA; const static std::string AUTOMATON_COMPACT_NFA; + const static std::string AUTOMATON_DFTA; + const static std::string AUTOMATON_NFTA; const static std::string AUTOMATON_DPDA; const static std::string AUTOMATON_SINGLE_POP_DPDA; const static std::string AUTOMATON_INPUT_DRIVEN_DPDA; @@ -103,6 +107,8 @@ public: const static std::string PRIMITIVE_CHARACTER; const static std::string PRIMITIVE_UNSIGNED; const static std::string PRIMITIVE_BOOL; + const static std::string TREE_RANKED_TREE; + const static std::string TREE_UNRANKED_TREE; }; @@ -346,6 +352,20 @@ struct xmlApi<automaton::CompactNFA> { static void compose(std::deque<sax::Token>& output, const automaton::CompactNFA& data); }; +template<> +struct xmlApi<automaton::DFTA> { + static automaton::DFTA parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const automaton::DFTA& data); +}; + +template<> +struct xmlApi<automaton::NFTA> { + static automaton::NFTA parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const automaton::NFTA& data); +}; + template<> struct xmlApi<automaton::DPDA> { static automaton::DPDA parse(std::deque<sax::Token>& input); @@ -729,6 +749,27 @@ struct xmlApi<bool> { static void compose(std::deque<sax::Token>& output, bool data); }; +template<> +struct xmlApi<tree::Tree> { + static tree::Tree parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const tree::Tree& data); +}; + +template<> +struct xmlApi<tree::RankedTree> { + static tree::RankedTree parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const tree::RankedTree& data); +}; + +template<> +struct xmlApi<tree::UnrankedTree> { + static tree::UnrankedTree parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const tree::UnrankedTree& data); +}; + } /* namespace alib */ #include "container/ContainerFromXMLParser.hpp" @@ -761,6 +802,7 @@ public: static const ObjectFromXMLParser objectParser; static const container::ContainerFromXMLParser containerParser; static const primitive::PrimitiveFromXMLParser primitiveParser; + static const tree::TreeFromXMLParser treeParser; }; @@ -788,6 +830,8 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type { 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::DFTA& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; @@ -842,6 +886,9 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type { void Visit(void*, const primitive::Unsigned& primitive) const; void Visit(void*, const primitive::Bool& primitive) const; + void Visit(void*, const tree::RankedTree& tree) const; + void Visit(void*, const tree::UnrankedTree& tree) const; + public: static const label::LabelToXMLComposer labelComposer; static const alphabet::SymbolToXMLComposer symbolComposer; @@ -854,6 +901,7 @@ public: static const ObjectToXMLComposer objectComposer; static const container::ContainerToXMLComposer containerComposer; static const primitive::PrimitiveToXMLComposer primitiveComposer; + static const tree::TreeToXMLComposer treeComposer; static const ToXMLComposers toXMLComposers; }; diff --git a/alib2data/src/automaton/AutomatonBase.h b/alib2data/src/automaton/AutomatonBase.h index e98ef8e7cad1be867ffac516c970b713ed4d9bdc..0a36d3dcd3d2cbca3dbfe4f7b504125e61c19076 100644 --- a/alib2data/src/automaton/AutomatonBase.h +++ b/alib2data/src/automaton/AutomatonBase.h @@ -16,7 +16,7 @@ namespace automaton { class AutomatonBase; typedef std::acceptor_base<AutomatonBase, - automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM + automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DFTA, automaton::NFTA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM > VisitableAutomatonBase; /** @@ -34,6 +34,14 @@ public: class VisitableConstFSMBase : public VisitableAutomatonBase::const_visitor_type { + void Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); + } + + void Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); + } + void Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } @@ -81,6 +89,14 @@ class VisitableConstFSMBase : public VisitableAutomatonBase::const_visitor_type class VisitableConstPDABase : public VisitableAutomatonBase::const_visitor_type { + void Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); + } + + void Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); + } + void Visit(void*, const EpsilonNFA&) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } @@ -113,6 +129,10 @@ class VisitableConstPDABase : public VisitableAutomatonBase::const_visitor_type class VisitableConstNondeterministicAutomatonBase : public VisitableAutomatonBase::const_visitor_type { + void Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); + } + void Visit(void*, const DFA&) const { throw exception::AlibException("Unsupported automaton type DFA"); } @@ -144,6 +164,10 @@ class VisitableConstNondeterministicAutomatonBase : public VisitableAutomatonBas class VisitableConstDeterministicAutomatonBase : public VisitableAutomatonBase::const_visitor_type { + void Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); + } + void Visit(void*, const EpsilonNFA&) const { throw exception::AlibException("Unsupported automaton type EpsilonNFA"); } diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h index 9c9bbdd25dbba4f53d2caec450062f88c14a5ae1..c695337eae98efae92a39553023f799c042df075 100644 --- a/alib2data/src/automaton/AutomatonFeatures.h +++ b/alib2data/src/automaton/AutomatonFeatures.h @@ -27,7 +27,9 @@ enum class FEATURES { REAL_TIME_HEIGHT_DETERMINISTIC_NPDA, NPDA, SINGLE_POP_NPDA, - ONE_TAPE_DTM + ONE_TAPE_DTM, + DFTA, + NFTA }; } /* namespace automaton */ diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.cpp b/alib2data/src/automaton/AutomatonFromXMLParser.cpp index 893d816a4f0dbb8abb74f4ebec11cc866169a1ab..6112d695f1b1a8c1db0df91d4a05c236ac44ab8a 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.cpp +++ b/alib2data/src/automaton/AutomatonFromXMLParser.cpp @@ -16,7 +16,7 @@ namespace automaton { Automaton AutomatonFromXMLParser::parseAutomaton(std::deque<sax::Token> &input) const { - return parseAutomaton(input, std::set<FEATURES>({FEATURES::EPSILON_NFA, FEATURES::MULTI_INITIAL_STATE_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::DPDA, FEATURES::SINGLE_POP_DPDA, FEATURES::INPUT_DRIVEN_DPDA, FEATURES::INPUT_DRIVEN_NPDA, FEATURES::VISIBLY_PUSHDOWN_DPDA, FEATURES::VISIBLY_PUSHDOWN_NPDA, FEATURES::REAL_TIME_HEIGHT_DETERMINISTIC_DPDA, FEATURES::REAL_TIME_HEIGHT_DETERMINISTIC_NPDA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM})); + return parseAutomaton(input, std::set<FEATURES>({FEATURES::EPSILON_NFA, FEATURES::MULTI_INITIAL_STATE_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::DFTA, FEATURES::NFTA, FEATURES::DPDA, FEATURES::SINGLE_POP_DPDA, FEATURES::INPUT_DRIVEN_DPDA, FEATURES::INPUT_DRIVEN_NPDA, FEATURES::VISIBLY_PUSHDOWN_DPDA, FEATURES::VISIBLY_PUSHDOWN_NPDA, FEATURES::REAL_TIME_HEIGHT_DETERMINISTIC_DPDA, FEATURES::REAL_TIME_HEIGHT_DETERMINISTIC_NPDA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM})); } Automaton AutomatonFromXMLParser::parseAutomaton(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const { @@ -71,12 +71,18 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::deque<sax::Token>& input, } else if(alib::xmlApi<OneTapeDTM>::first(input)) { if(!features.count(FEATURES::ONE_TAPE_DTM)) throw exception::AlibException(); return Automaton(parseOneTapeDTM(input)); + } else if(alib::xmlApi<DFTA>::first(input)) { + if(!features.count(FEATURES::DFTA)) throw exception::AlibException(); + return Automaton(parseDFTA(input)); + } else if(alib::xmlApi<NFTA>::first(input)) { + if(!features.count(FEATURES::NFTA)) throw exception::AlibException(); + return Automaton(parseNFTA(input)); } else - throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA / CompactNFA / ExtendedNFA / DPDA / SinglePopDPDA / InputDrivenDPDA / InputDrivenNPDA / VisiblyPushdownDPDA / VisiblyPushdownNPDA / RealTimeHeightDeterministicDPDA / RealTimeHeightDeterministicNPDA / NPDA / SinglePopNPDA / OneTapeDTM", sax::Token::TokenType::START_ELEMENT), input.front()); + throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA / CompactNFA / ExtendedNFA / DFTA / NFTA / DPDA / SinglePopDPDA / InputDrivenDPDA / InputDrivenNPDA / VisiblyPushdownDPDA / VisiblyPushdownNPDA / RealTimeHeightDeterministicDPDA / RealTimeHeightDeterministicNPDA / NPDA / SinglePopNPDA / OneTapeDTM", sax::Token::TokenType::START_ELEMENT), input.front()); } bool AutomatonFromXMLParser::first(const std::deque<sax::Token>& input) const { - if(alib::xmlApi<EpsilonNFA>::first(input) || alib::xmlApi<NFA>::first(input) || alib::xmlApi<DFA>::first(input) || alib::xmlApi<CompactNFA>::first(input) || alib::xmlApi<ExtendedNFA>::first(input) || alib::xmlApi<DPDA>::first(input) || alib::xmlApi<SinglePopDPDA>::first(input) || alib::xmlApi<InputDrivenDPDA>::first(input) || alib::xmlApi<InputDrivenNPDA>::first(input) || alib::xmlApi<VisiblyPushdownDPDA>::first(input) || alib::xmlApi<VisiblyPushdownNPDA>::first(input) || alib::xmlApi<RealTimeHeightDeterministicDPDA>::first(input) || alib::xmlApi<RealTimeHeightDeterministicNPDA>::first(input) || alib::xmlApi<NPDA>::first(input) || alib::xmlApi<SinglePopNPDA>::first(input) || alib::xmlApi<OneTapeDTM>::first(input)) { + if(alib::xmlApi<EpsilonNFA>::first(input) || alib::xmlApi<NFA>::first(input) || alib::xmlApi<DFA>::first(input) || alib::xmlApi<CompactNFA>::first(input) || alib::xmlApi<ExtendedNFA>::first(input) || alib::xmlApi<DFTA>::first(input) || alib::xmlApi<NFTA>::first(input) || alib::xmlApi<DPDA>::first(input) || alib::xmlApi<SinglePopDPDA>::first(input) || alib::xmlApi<InputDrivenDPDA>::first(input) || alib::xmlApi<InputDrivenNPDA>::first(input) || alib::xmlApi<VisiblyPushdownDPDA>::first(input) || alib::xmlApi<VisiblyPushdownNPDA>::first(input) || alib::xmlApi<RealTimeHeightDeterministicDPDA>::first(input) || alib::xmlApi<RealTimeHeightDeterministicNPDA>::first(input) || alib::xmlApi<NPDA>::first(input) || alib::xmlApi<SinglePopNPDA>::first(input) || alib::xmlApi<OneTapeDTM>::first(input)) { return true; } else { return false; @@ -471,6 +477,42 @@ OneTapeDTM AutomatonFromXMLParser::parseOneTapeDTM(std::deque<sax::Token>& input return automaton; } +DFTA AutomatonFromXMLParser::parseDFTA(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::AUTOMATON_DFTA); + + std::set<State> states = parseStates(input); + std::set<alphabet::RankedSymbol> inputSymbols = parseRankedInputAlphabet(input); + std::set<State> finalStates = parseFinalStates(input); + + DFTA automaton; + automaton.setStates(states); + automaton.setInputSymbols(inputSymbols); + automaton.setFinalStates(finalStates); + + parseTransitions<DFTA>(input, automaton); + + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::AUTOMATON_DFTA); + return automaton; +} + +NFTA AutomatonFromXMLParser::parseNFTA(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::AUTOMATON_NFTA); + + std::set<State> states = parseStates(input); + std::set<alphabet::RankedSymbol> inputSymbols = parseRankedInputAlphabet(input); + std::set<State> finalStates = parseFinalStates(input); + + NFTA automaton; + automaton.setStates(states); + automaton.setInputSymbols(inputSymbols); + automaton.setFinalStates(finalStates); + + parseTransitions<NFTA>(input, automaton); + + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::AUTOMATON_NFTA); + return automaton; +} + std::set<State> AutomatonFromXMLParser::parseStates(std::deque<sax::Token> &input) const { std::set<State> states; popToken(input, sax::Token::TokenType::START_ELEMENT, "states"); @@ -525,6 +567,16 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseInputAlphabet(std::deque return inputSymbols; } +std::set<alphabet::RankedSymbol> AutomatonFromXMLParser::parseRankedInputAlphabet(std::deque<sax::Token> &input) const { + std::set<alphabet::RankedSymbol> inputSymbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "rankedInputAlphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + inputSymbols.insert(alib::xmlApi<alphabet::RankedSymbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "rankedInputAlphabet"); + return inputSymbols; +} + State AutomatonFromXMLParser::parseInitialState(std::deque<sax::Token> &input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "initialState"); State state(alib::xmlApi<label::Label>::parse(input)); @@ -897,6 +949,26 @@ void AutomatonFromXMLParser::parseTransition(std::deque<sax::Token>& input, OneT automaton.addTransition(std::move(from), std::move(inputSymbol), std::move(to), std::move(outputSymbol), shift); } +void AutomatonFromXMLParser::parseTransition(std::deque<sax::Token>& input, DFTA& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transition"); + alphabet::RankedSymbol inputSymbol = parseTransitionInputRankedSymbol(input); + std::vector<State> from = parseTransitionFromMultiple(input); + State to = parseTransitionTo(input); + popToken(input, sax::Token::TokenType::END_ELEMENT, "transition"); + + automaton.addTransition(inputSymbol, from, to); +} + +void AutomatonFromXMLParser::parseTransition(std::deque<sax::Token>& input, NFTA& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transition"); + alphabet::RankedSymbol inputSymbol = parseTransitionInputRankedSymbol(input); + std::vector<State> from = parseTransitionFromMultiple(input); + State to = parseTransitionTo(input); + popToken(input, sax::Token::TokenType::END_ELEMENT, "transition"); + + automaton.addTransition(inputSymbol, from, to); +} + State AutomatonFromXMLParser::parseTransitionTo(std::deque<sax::Token> &input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "to"); State state(alib::xmlApi<label::Label>::parse(input)); @@ -911,6 +983,16 @@ State AutomatonFromXMLParser::parseTransitionFrom(std::deque<sax::Token> &input) return state; } +std::vector<State> AutomatonFromXMLParser::parseTransitionFromMultiple(std::deque<sax::Token> &input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "from"); + std::vector<State> states; + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + states.push_back(State(alib::xmlApi<label::Label>::parse(input))); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "from"); + return states; +} + Shift AutomatonFromXMLParser::parseTransitionShift(std::deque<sax::Token>& input) const { Shift shift; @@ -971,6 +1053,13 @@ alphabet::Symbol AutomatonFromXMLParser::parseTransitionInputSymbol(std::deque<s return result; } +alphabet::RankedSymbol AutomatonFromXMLParser::parseTransitionInputRankedSymbol(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "input"); + alphabet::RankedSymbol result(alib::xmlApi<alphabet::RankedSymbol>::parse(input)); + popToken(input, sax::Token::TokenType::END_ELEMENT, "input"); + return result; +} + alphabet::Symbol AutomatonFromXMLParser::parseTransitionOutputSymbol(std::deque<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "output"); alphabet::Symbol result(alib::xmlApi<alphabet::Symbol>::parse(input)); diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.h b/alib2data/src/automaton/AutomatonFromXMLParser.h index 9e4a3eb64c2ce10e93b1c3894b6258f7b33dd461..21eb262110beb4156e7009768cb02dcb9b24fdbf 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.h +++ b/alib2data/src/automaton/AutomatonFromXMLParser.h @@ -28,8 +28,10 @@ #include "PDA/NPDA.h" #include "PDA/SinglePopNPDA.h" #include "TM/OneTapeDTM.h" +#include "TA/DFTA.h" +#include "TA/NFTA.h" -#include <list> +#include <deque> #include <set> #include <variant> #include "../sax/Token.h" @@ -44,7 +46,7 @@ struct xmlApi; namespace automaton { /** - * Parser used to get general FSM or EpsilonNFA, NFA, DFA from XML parsed into list of Tokens. + * Parser used to get general FSM or EpsilonNFA, NFA, DFA from XML parsed into deque of Tokens. */ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { std::set<State> parseStates(std::deque<sax::Token> &input) const; @@ -53,6 +55,7 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { std::set<alphabet::Symbol> parseCallInputAlphabet(std::deque<sax::Token> &input) const; std::set<alphabet::Symbol> parseReturnInputAlphabet(std::deque<sax::Token> &input) const; std::set<alphabet::Symbol> parseLocalInputAlphabet(std::deque<sax::Token> &input) const; + std::set<alphabet::RankedSymbol> parseRankedInputAlphabet(std::deque<sax::Token> &input) const; std::set<alphabet::Symbol> parseStackAlphabet(std::deque<sax::Token> &input) const; std::set<alphabet::Symbol> parseInitialStackSymbols(std::deque<sax::Token> &input) const; alphabet::Symbol parseInitialStackSymbol(std::deque<sax::Token> &input) const; @@ -66,6 +69,7 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { void parseInputToPushdownStoreOperation(std::deque<sax::Token>& input, automaton::InputDrivenNPDA& automaton) const; State parseTransitionFrom(std::deque<sax::Token>& input) const; + std::vector<State> parseTransitionFromMultiple(std::deque<sax::Token>& input) const; State parseTransitionTo(std::deque<sax::Token>& input) const; Shift parseTransitionShift(std::deque<sax::Token>& input) const; std::vector<alphabet::Symbol> parseTransitionPop(std::deque<sax::Token>& input) const; @@ -93,8 +97,11 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { void parseTransition(std::deque<sax::Token>& input, NPDA& automaton) const; void parseTransition(std::deque<sax::Token>& input, SinglePopNPDA& automaton) const; void parseTransition(std::deque<sax::Token>& input, OneTapeDTM& automaton) const; + void parseTransition(std::deque<sax::Token>& input, DFTA& automaton) const; + void parseTransition(std::deque<sax::Token>& input, NFTA& automaton) const; alphabet::Symbol parseTransitionInputSymbol(std::deque<sax::Token> &input) const; + alphabet::RankedSymbol parseTransitionInputRankedSymbol(std::deque<sax::Token> &input) const; std::variant<string::Epsilon, alphabet::Symbol> parseTransitionInputEpsilonSymbol(std::deque<sax::Token> &input) const; std::variant<string::Epsilon, alphabet::Symbol> parseTransitionInputBlankEpsilonSymbol(std::deque<sax::Token> &input) const; string::LinearString parseTransitionInputString(std::deque<sax::Token> &input) const; @@ -127,6 +134,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper { NPDA parseNPDA(std::deque<sax::Token>& input) const; SinglePopNPDA parseSinglePopNPDA(std::deque<sax::Token>& input) const; OneTapeDTM parseOneTapeDTM(std::deque<sax::Token>& input) const; + DFTA parseDFTA(std::deque<sax::Token>& input) const; + NFTA parseNFTA(std::deque<sax::Token>& input) const; template<typename T> friend class alib::xmlApi; public: diff --git a/alib2data/src/automaton/AutomatonToStringComposer.cpp b/alib2data/src/automaton/AutomatonToStringComposer.cpp index 8362e48db3ec214868f15293d46de2ef015f82c6..2023d4cd6e6cd41c7ef4fef397be8b907a07b634 100644 --- a/alib2data/src/automaton/AutomatonToStringComposer.cpp +++ b/alib2data/src/automaton/AutomatonToStringComposer.cpp @@ -261,4 +261,12 @@ void AutomatonToStringComposer::Visit(void*, const OneTapeDTM&) const { throw exception::AlibException(); } +void AutomatonToStringComposer::Visit(void*, const DFTA&) const { + throw exception::AlibException(); +} + +void AutomatonToStringComposer::Visit(void*, const NFTA&) const { + throw exception::AlibException(); +} + } /* namespace automaton */ diff --git a/alib2data/src/automaton/AutomatonToStringComposer.h b/alib2data/src/automaton/AutomatonToStringComposer.h index d0b324f8a03246d6b71e5092aaf84ca4ddc2e8ec..cadab745f0275e2fa5b1d8a365cc03972bd05fd0 100644 --- a/alib2data/src/automaton/AutomatonToStringComposer.h +++ b/alib2data/src/automaton/AutomatonToStringComposer.h @@ -35,6 +35,8 @@ class AutomatonToStringComposer : public VisitableAutomatonBase::const_visitor_t void Visit(void*, const NPDA& automaton) const; void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; + void Visit(void*, const DFTA& automaton) const; + void Visit(void*, const NFTA& automaton) const; void composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from) const; void composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) const; diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.cpp b/alib2data/src/automaton/AutomatonToXMLComposer.cpp index 737682c9d7930ac6a210793d39cb7e6fa01ba785..2030103543c1f452782e70167c49fa3116770ca6 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.cpp +++ b/alib2data/src/automaton/AutomatonToXMLComposer.cpp @@ -52,6 +52,14 @@ void AutomatonToXMLComposer::composeLocalInputAlphabet(std::deque<sax::Token>& o out.emplace_back("localInputAlphabet", sax::Token::TokenType::END_ELEMENT); } +void AutomatonToXMLComposer::composeRankedInputAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const { + out.emplace_back(sax::Token("rankedInputAlphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + alib::xmlApi<alphabet::RankedSymbol>::compose(out, symbol); + } + out.emplace_back(sax::Token("rankedInputAlphabet", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeInitialStates(std::deque<sax::Token>& out, const std::set<State>& states) const { out.emplace_back("initialStates", sax::Token::TokenType::START_ELEMENT); for (const auto& state : states) { @@ -515,6 +523,38 @@ void AutomatonToXMLComposer::composeTransitions(std::deque<sax::Token>& out, con out.emplace_back("transitions", sax::Token::TokenType::END_ELEMENT); } +void AutomatonToXMLComposer::composeTransitions(std::deque<sax::Token>& out, const DFTA& automaton) const { + out.emplace_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); + for(const auto& transition : automaton.getTransitions()) { + out.emplace_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionInputSymbol(out, transition.first.first); + composeTransitionFrom(out, transition.first.second); + composeTransitionTo(out, transition.second); + + out.emplace_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT)); + } + + out.emplace_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::composeTransitions(std::deque<sax::Token>& out, const NFTA& automaton) const { + out.emplace_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT)); + for(const auto& transition : automaton.getTransitions()) { + for(const auto& targetState: transition.second) { + out.emplace_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT)); + + composeTransitionInputSymbol(out, transition.first.first); + composeTransitionFrom(out, transition.first.second); + composeTransitionTo(out, targetState); + + out.emplace_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT)); + } + } + + out.emplace_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitionTo(std::deque<sax::Token>& out, const State& state) const { out.emplace_back("to", sax::Token::TokenType::START_ELEMENT); alib::xmlApi<label::Label>::compose(out, state.getName()); @@ -527,6 +567,14 @@ void AutomatonToXMLComposer::composeTransitionFrom(std::deque<sax::Token>& out, out.emplace_back("from", sax::Token::TokenType::END_ELEMENT); } +void AutomatonToXMLComposer::composeTransitionFrom(std::deque<sax::Token>& out, const std::vector<State> & states) const { + out.emplace_back(sax::Token("from", sax::Token::TokenType::START_ELEMENT)); + for (const auto& state : states) { + alib::xmlApi<label::Label>::compose(out, state.getName()); + } + out.emplace_back(sax::Token("from", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitionShift(std::deque<sax::Token>& out, const Shift shift) const { out.emplace_back("shift", sax::Token::TokenType::START_ELEMENT); out.emplace_back(SHIFT_NAMES [shift], sax::Token::TokenType::CHARACTER); @@ -567,6 +615,12 @@ void AutomatonToXMLComposer::composeTransitionInputSymbol(std::deque<sax::Token> out.emplace_back("input", sax::Token::TokenType::END_ELEMENT); } +void AutomatonToXMLComposer::composeTransitionInputSymbol(std::deque<sax::Token>& out, const alphabet::RankedSymbol& symbol) const { + out.emplace_back(sax::Token("input", sax::Token::TokenType::START_ELEMENT)); + alib::xmlApi<alphabet::RankedSymbol>::compose(out, symbol); + out.emplace_back(sax::Token("input", sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::composeTransitionOutputSymbol(std::deque<sax::Token>& out, const alphabet::Symbol& symbol) const { out.emplace_back("output", sax::Token::TokenType::START_ELEMENT); alib::xmlApi<alphabet::Symbol>::compose(out, symbol); @@ -847,6 +901,28 @@ void AutomatonToXMLComposer::compose(std::deque<sax::Token>& out, const OneTapeD out.emplace_back(alib::Names::AUTOMATON_ONE_TAPE_DTM, sax::Token::TokenType::END_ELEMENT); } +void AutomatonToXMLComposer::compose(std::deque<sax::Token>& out, const DFTA & automaton) const { + out.emplace_back(sax::Token(alib::Names::AUTOMATON_DFTA, sax::Token::TokenType::START_ELEMENT)); + + composeStates(out, automaton.getStates()); + composeRankedInputAlphabet(out, automaton.getInputAlphabet()); + composeFinalStates(out, automaton.getFinalStates()); + composeTransitions(out, automaton); + + out.emplace_back(sax::Token(alib::Names::AUTOMATON_DFTA, sax::Token::TokenType::END_ELEMENT)); +} + +void AutomatonToXMLComposer::compose(std::deque<sax::Token>& out, const NFTA & automaton) const { + out.emplace_back(sax::Token(alib::Names::AUTOMATON_NFTA, sax::Token::TokenType::START_ELEMENT)); + + composeStates(out, automaton.getStates()); + composeRankedInputAlphabet(out, automaton.getInputAlphabet()); + composeFinalStates(out, automaton.getFinalStates()); + composeTransitions(out, automaton); + + out.emplace_back(sax::Token(alib::Names::AUTOMATON_NFTA, sax::Token::TokenType::END_ELEMENT)); +} + void AutomatonToXMLComposer::compose(std::deque<sax::Token>& out, const State& state) const { alib::xmlApi<label::Label>::compose(out, state.getName()); } diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.h b/alib2data/src/automaton/AutomatonToXMLComposer.h index ab43de162ff544f1abd524a34c257c5354a73f60..03a15f46d27607a591f65731c9eddf214fa046f3 100644 --- a/alib2data/src/automaton/AutomatonToXMLComposer.h +++ b/alib2data/src/automaton/AutomatonToXMLComposer.h @@ -26,6 +26,7 @@ #include "PDA/NPDA.h" #include "PDA/SinglePopNPDA.h" #include "TM/OneTapeDTM.h" +#include "TA/NFTA.h" #include "../sax/Token.h" namespace alib { @@ -46,6 +47,7 @@ class AutomatonToXMLComposer { void composeCallInputAlphabet(std::deque<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; void composeReturnInputAlphabet(std::deque<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; void composeLocalInputAlphabet(std::deque<sax::Token>&, const std::set<alphabet::Symbol>& symbols) const; + void composeRankedInputAlphabet(std::deque<sax::Token>&, const std::set<alphabet::RankedSymbol>& symbols) const; void composeInitialStates(std::deque<sax::Token>&, const std::set<State>& states) const; void composeInitialState(std::deque<sax::Token>&, const State& state) const; void composeFinalStates(std::deque<sax::Token>&, const std::set<State>& states) const; @@ -75,15 +77,19 @@ class AutomatonToXMLComposer { void composeTransitions(std::deque<sax::Token>&, const NPDA& automaton) const; void composeTransitions(std::deque<sax::Token>&, const SinglePopNPDA& automaton) const; void composeTransitions(std::deque<sax::Token>&, const OneTapeDTM& automaton) const; + void composeTransitions(std::deque<sax::Token>&, const DFTA& automaton) const; + void composeTransitions(std::deque<sax::Token>&, const NFTA& automaton) const; void composeTransitionTo(std::deque<sax::Token>&, const State& state) const; void composeTransitionFrom(std::deque<sax::Token>&, const State& state) const; + void composeTransitionFrom(std::deque<sax::Token>&, const std::vector<State> & states) const; void composeTransitionShift(std::deque<sax::Token>&, const Shift shift) const; void composeTransitionPop(std::deque<sax::Token>&, const std::vector<alphabet::Symbol>& symbols) const; void composeTransitionSinglePop(std::deque<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionPush(std::deque<sax::Token>&, const std::vector<alphabet::Symbol>& symbols) const; void composeTransitionSinglePush(std::deque<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionInputSymbol(std::deque<sax::Token>&, const alphabet::Symbol& symbol) const; + void composeTransitionInputSymbol(std::deque<sax::Token>&, const alphabet::RankedSymbol& symbol) const; void composeTransitionInputEpsilonSymbol(std::deque<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&) const; void composeTransitionOutputSymbol(std::deque<sax::Token>&, const alphabet::Symbol& symbol) const; void composeTransitionOutputEpsilonSymbol(std::deque<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&) const; @@ -98,7 +104,7 @@ class AutomatonToXMLComposer { void compose(std::deque<sax::Token>& output, const AutomatonBase& automaton) const; void compose(std::deque<sax::Token>& output, const Automaton& automaton) const; - + void compose(std::deque<sax::Token>& output, const DFA& automaton) const; void compose(std::deque<sax::Token>& output, const NFA& automaton) const; void compose(std::deque<sax::Token>& output, const MultiInitialStateNFA& automaton) const; @@ -116,6 +122,8 @@ class AutomatonToXMLComposer { void compose(std::deque<sax::Token>& output, const NPDA& automaton) const; void compose(std::deque<sax::Token>& output, const SinglePopNPDA& automaton) const; void compose(std::deque<sax::Token>& output, const OneTapeDTM& automaton) const; + void compose(std::deque<sax::Token>& output, const DFTA& automaton) const; + void compose(std::deque<sax::Token>& output, const NFTA& automaton) const; void compose(std::deque<sax::Token>& output, const State& state) const; diff --git a/alib2data/src/automaton/TA/DFTA.cpp b/alib2data/src/automaton/TA/DFTA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12be0fa0e0e5ba5fdd7d57677f849480642135d0 --- /dev/null +++ b/alib2data/src/automaton/TA/DFTA.cpp @@ -0,0 +1,111 @@ +/* + * DFTA.cpp + * + * Created on: Apr 14, 2015 + * Author: Stepan Plachy + */ + +#include "DFTA.h" +#include "../AutomatonException.h" +#include <ostream> +#include <sstream> + +namespace automaton { + +DFTA::DFTA() { + +} + +AutomatonBase* DFTA::clone() const { + return new DFTA(*this); +} + +AutomatonBase* DFTA::plunder() && { + return new DFTA(std::move(*this)); +} + +bool DFTA::removeState(const State& state) { + if (finalStates.find(state) != finalStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state."); + } + + AutomatonException ex ("State \"" + (std::string) state.getName() + "\" is used in transition."); + for (std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, State>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + const std::vector<State> states = t -> first.second; + for (std::vector<State>::const_iterator it = states.begin(); it != states.end(); ++it) { + if (*it == state) throw ex; + } + if (t -> second == state) throw ex; + } + + return states.erase(state); +} + +bool DFTA::removeInputSymbol(const alphabet::RankedSymbol& symbol) { + for (std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, State>::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (t -> first.first == symbol) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used."); + } + + return inputAlphabet.erase(symbol); +} + +bool DFTA::addTransition(const alphabet::RankedSymbol & symbol, const std::vector<State> & prevStates, const State & next) { + + if ((int) prevStates.size() != symbol.getRank().getData()) + throw AutomatonException("Number of states doesn't match rank of the symbol"); + + if (inputAlphabet.find(symbol) == inputAlphabet.end()) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" doesn't exist."); + + if (states.find(next) == states.end()) + throw AutomatonException("State \"" + (std::string) next.getName() + "\" doesn't exist."); + + for (std::vector<State>::const_iterator it = prevStates.begin(); it != prevStates.end(); ++it) { + if (states.find(*it) == states.end()) + throw AutomatonException("State \"" + (std::string) it -> getName() + "\" doesn't exist."); + } + + std::pair<alphabet::RankedSymbol, std::vector<State> > key = std::make_pair(symbol, prevStates); + const auto & it = transitions.find(key); + if (it != transitions.end()) { + if (it -> second == next) return false; + else throw AutomatonException("Transition already exists"); + } + + transitions.insert(std::make_pair(key, next)); + return true; +} + +bool DFTA::removeTransition(const alphabet::RankedSymbol symbol, const std::vector<State> & states, const State & next) { + std::pair<alphabet::RankedSymbol, std::vector<State> > key = std::make_pair(symbol, states); + const auto & it = transitions.find(key); + if (it == transitions.end()) return false; + if (it -> second != next) throw AutomatonException("Transition does not exist"); + return transitions.erase(key); +} + +int DFTA::compare(const DFTA& other) const { + auto first = std::tie(states, inputAlphabet, finalStates, transitions); + auto second = std::tie(other.states, other.inputAlphabet, other.finalStates, other.transitions); + + std::compare<decltype(first)> comp; + return comp(first, second); +} + +void DFTA::operator>>(std::ostream& out) const { + out << "(DFTA " + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + +DFTA::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/TA/DFTA.h b/alib2data/src/automaton/TA/DFTA.h new file mode 100644 index 0000000000000000000000000000000000000000..aa1a656778ca7c465e66deb0e182bb352c04d52f --- /dev/null +++ b/alib2data/src/automaton/TA/DFTA.h @@ -0,0 +1,103 @@ +/* + * DFTA.h + * + * Created on: Apr 14, 2015 + * Author: Stepan Plachy + */ + +#ifndef DFTA_H_ +#define DFTA_H_ + +#include <map> +#include <vector> +#include "../AutomatonBase.h" +#include "../common/States.h" +//#include "../common/InputAlphabet.h" +#include "../../alphabet/RankedSymbol.h" + +namespace automaton { + +/** + * Represents Finite Tree Automaton. + * Can store nondeterministic finite automaton without epsilon transitions. + */ +class DFTA : public std::acceptor<DFTA, VisitableAutomatonBase, std::acceptor<DFTA, alib::VisitableObjectBase, AutomatonBase> >, public States { +protected: + std::set<alphabet::RankedSymbol> inputAlphabet; + std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, State > transitions; +public: + explicit DFTA(); + + 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::RankedSymbol& symbol); + + /** + * Adds transition defined by parameters to the automaton. + * @param current current symbol in node + * @param children states of children of current node + * @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 alphabet::RankedSymbol & current, const std::vector<State> & children, const State & next); + + /** + * Removes transition from the automaton. + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const alphabet::RankedSymbol symbol, const std::vector<State> & states, const State & next); + + /** + * @return automaton transitions + */ + const std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, State > & getTransitions() const {return transitions;} + + std::set<State> getTransitionRightSide(const alphabet::RankedSymbol symbol, const std::vector<State> & states); + + unsigned transitionsSize() const; + + const std::set<alphabet::RankedSymbol> & getInputAlphabet() const {return inputAlphabet;} + + void setInputSymbols(const std::set<alphabet::RankedSymbol> & symbols) {inputAlphabet = symbols;} + + void addInputSymbol(const alphabet::RankedSymbol & symbol) {inputAlphabet.insert(symbol);} + + virtual int compare(const ObjectBase& other) const { + return -other.compare(*this); + } + + virtual int compare(const DFTA& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId<DFTA>(); + } +}; + +} /* namespace automaton */ + +namespace std { + +template<> +struct compare<automaton::DFTA> { + int operator()(const automaton::DFTA& first, const automaton::DFTA& second) const { + return first.compare(second); + } +}; + +} /* namespace std */ + +#endif /* DFTA_H_ */ diff --git a/alib2data/src/automaton/TA/NFTA.cpp b/alib2data/src/automaton/TA/NFTA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb0919664ab9bcf851617ce0b3dcc125d363e28d --- /dev/null +++ b/alib2data/src/automaton/TA/NFTA.cpp @@ -0,0 +1,128 @@ +/* + * NFTA.cpp + * + * Created on: Mar 21, 2015 + * Author: Stepan Plachy + */ + +#include "NFTA.h" +#include "../AutomatonException.h" +#include <ostream> +#include <sstream> + +namespace automaton { + +NFTA::NFTA() { + +} + +NFTA::NFTA(const DFTA& other) { + inputAlphabet = other.getInputAlphabet(); + states = other.getStates(); + finalStates = other.getFinalStates(); + for(const auto& transition : other.getTransitions()) { + transitions[transition.first].insert(transition.second); + } +} + +AutomatonBase* NFTA::clone() const { + return new NFTA(*this); +} + +AutomatonBase* NFTA::plunder() && { + return new NFTA(std::move(*this)); +} + +bool NFTA::removeState(const State& state) { + if (finalStates.find(state) != finalStates.end()) { + throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state."); + } + + AutomatonException ex ("State \"" + (std::string) state.getName() + "\" is used in transition."); + for (std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> >::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + const std::vector<State> states = t -> first.second; + for (std::vector<State>::const_iterator it = states.begin(); it != states.end(); ++it) { + if (*it == state) throw ex; + } + if (t -> second.find(state) != t -> second.end()) throw ex; + } + + return states.erase(state); +} + +bool NFTA::removeInputSymbol(const alphabet::RankedSymbol& symbol) { + for (std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> >::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (t -> first.first == symbol) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used."); + } + + return inputAlphabet.erase(symbol); +} + +bool NFTA::addTransition(const alphabet::RankedSymbol & symbol, const std::vector<State> & prevStates, const State & next) { + + if ((int) prevStates.size() != symbol.getRank().getData()) + throw AutomatonException("Number of states doesn't match rank of the symbol"); + + if (inputAlphabet.find(symbol) == inputAlphabet.end()) + throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" doesn't exist."); + + if (states.find(next) == states.end()) + throw AutomatonException("State \"" + (std::string) next.getName() + "\" doesn't exist."); + + for (std::vector<State>::const_iterator it = prevStates.begin(); it != prevStates.end(); ++it) { + if (states.find(*it) == states.end()) + throw AutomatonException("State \"" + (std::string) it -> getName() + "\" doesn't exist."); + } + + std::pair<alphabet::RankedSymbol, std::vector<State> > key = std::make_pair(symbol, prevStates); + return transitions[key].insert(next).second; +} + +bool NFTA::removeTransition(const alphabet::RankedSymbol symbol, const std::vector<State> & states, const State & next) { + std::pair<alphabet::RankedSymbol, std::vector<State> > key = std::make_pair(symbol, states); + return transitions[key].erase(next); +} + +bool NFTA::isDeterministic() const { + for (std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> >::const_iterator t = transitions.begin(); t != transitions.end(); t++) { + if (t -> second.size() != 1 || t -> second.size() != 0) { + return false; + } + } + + return true; +} + +unsigned NFTA::transitionsSize() const { + int res = 0; + for(const auto& transition : transitions ){ + res += transition.second.size(); + } + return res; +} + +int NFTA::compare(const NFTA& other) const { + auto first = std::tie(states, inputAlphabet, finalStates, transitions); + auto second = std::tie(other.states, other.inputAlphabet, other.finalStates, other.transitions); + + std::compare<decltype(first)> comp; + return comp(first, second); +} + +void NFTA::operator>>(std::ostream& out) const { + out << "(NFTA " + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + +NFTA::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace automaton */ diff --git a/alib2data/src/automaton/TA/NFTA.h b/alib2data/src/automaton/TA/NFTA.h new file mode 100644 index 0000000000000000000000000000000000000000..95aa597b88018eb6cecd8b98bab0b0bde48c9e59 --- /dev/null +++ b/alib2data/src/automaton/TA/NFTA.h @@ -0,0 +1,115 @@ +/* + * NFTA.h + * + * Created on: Mar 21, 2015 + * Author: Stepan Plachy + */ + +#ifndef NFTA_H_ +#define NFTA_H_ + +#include <map> +#include <vector> +#include "../AutomatonBase.h" +#include "../common/States.h" +//#include "../common/InputAlphabet.h" +#include "../../alphabet/RankedSymbol.h" + +#include "DFTA.h" + +namespace automaton { + +/** + * Represents Finite Tree Automaton. + * Can store nondeterministic finite tree automaton without epsilon transitions. + */ +class NFTA : public std::acceptor<NFTA, VisitableAutomatonBase, std::acceptor<NFTA, alib::VisitableObjectBase, AutomatonBase> >, public States { +protected: + std::set<alphabet::RankedSymbol> inputAlphabet; + std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> > transitions; +public: + explicit NFTA(); + explicit NFTA(const DFTA& other); + + 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::RankedSymbol& symbol); + + /** + * Adds transition defined by parameters to the automaton. + * @param current current symbol in node + * @param children states of children of current node + * @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 alphabet::RankedSymbol & current, const std::vector<State> & children, const State & next); + + /** + * Removes transition from the automaton. + * @throws AutomatonException when transition doesn't exists. + */ + bool removeTransition(const alphabet::RankedSymbol symbol, const std::vector<State> & states, const State & next); + + /** + * @return automaton transitions + */ + const std::map<std::pair<alphabet::RankedSymbol, std::vector<State> >, std::set<State> > & getTransitions() const {return transitions;} + + std::set<State> getTransitionRightSide(const alphabet::RankedSymbol symbol, const std::vector<State> & states); + + /** + * Determines whether NFTA is deterministic. + * FA is deterministic if and only if: + * \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; + + unsigned transitionsSize() const; + + const std::set<alphabet::RankedSymbol> & getInputAlphabet() const {return inputAlphabet;} + + void setInputSymbols(const std::set<alphabet::RankedSymbol> & symbols) {inputAlphabet = symbols;} + + void addInputSymbol(const alphabet::RankedSymbol & symbol) {inputAlphabet.insert(symbol);} + + virtual int compare(const ObjectBase& other) const { + return -other.compare(*this); + } + + virtual int compare(const NFTA& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId<NFTA>(); + } +}; + +} /* namespace automaton */ + +namespace std { + +template<> +struct compare<automaton::NFTA> { + int operator()(const automaton::NFTA& first, const automaton::NFTA& second) const { + return first.compare(second); + } +}; + +} /* namespace std */ + +#endif /* NFTA_H_ */ diff --git a/alib2data/src/automaton/TA/TreeAutomaton.h b/alib2data/src/automaton/TA/TreeAutomaton.h deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/alib2data/src/automaton/common/State.h b/alib2data/src/automaton/common/State.h index 078060ce4aaf4645fdf711da644d527d46084f87..c772f68e0c055a868199fac0700a9d4551558e66 100644 --- a/alib2data/src/automaton/common/State.h +++ b/alib2data/src/automaton/common/State.h @@ -41,6 +41,8 @@ public: explicit operator std::string () const; }; +const State FAILSTATE = State("fail"); + } /* namespace automaton */ namespace std { diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index 42204a9f233f4e10d5af453b1c32b5ceebe7e080..f89976ee703c1a930edcecf860c03a24d8b6abc2 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -43,6 +43,8 @@ class InputDrivenNPDA; class VisiblyPushdownNPDA; class RealTimeHeightDeterministicNPDA; class OneTapeDTM; +class DFTA; +class NFTA; } @@ -133,6 +135,13 @@ class Bool; } +namespace tree { + +class RankedTree; +class UnrankedTree; + +} + namespace alib { class ObjectBase; @@ -140,7 +149,7 @@ class ObjectBase; typedef std::acceptor_base<ObjectBase, Void, exception::AlibException, - automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM, + automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DFTA, automaton::NFTA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM, 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, graph::DirectedGraph, graph::UndirectedGraph, label::PrimitiveLabel, label::HexavigesimalLabel, label::ObjectLabel, label::LabelSetLabel, label::LabelPairLabel, label::UniqueLabel, @@ -148,7 +157,8 @@ typedef std::acceptor_base<ObjectBase, string::Epsilon, string::LinearString, string::CyclicString, alphabet::EndSymbol, alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::RankedSymbol, alphabet::BarSymbol, alphabet::RankedBarSymbol, alphabet::SubtreeWildcardSymbol, alphabet::SymbolPairSymbol, alphabet::SymbolSetSymbol, alphabet::UniqueSymbol, alphabet::StartSymbol, container::ObjectsSet, container::ObjectsVector, container::ObjectsPair, container::ObjectsMap, - primitive::String, primitive::Integer, primitive::Character, primitive::Unsigned, primitive::Bool + primitive::String, primitive::Integer, primitive::Character, primitive::Unsigned, primitive::Bool, + tree::RankedTree, tree::UnrankedTree > VisitableObjectBase; class ObjectBase : @@ -156,7 +166,7 @@ class ObjectBase : ObjectBase, Void, exception::AlibException, - automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM, + automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DFTA, automaton::NFTA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenDPDA, automaton::VisiblyPushdownDPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::OneTapeDTM, 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, graph::DirectedGraph, graph::UndirectedGraph, label::PrimitiveLabel, label::HexavigesimalLabel, label::ObjectLabel, label::LabelSetLabel, label::LabelPairLabel, label::UniqueLabel, @@ -164,7 +174,8 @@ class ObjectBase : string::Epsilon, string::LinearString, string::CyclicString, alphabet::EndSymbol, alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::RankedSymbol, alphabet::BarSymbol, alphabet::RankedBarSymbol, alphabet::SubtreeWildcardSymbol, alphabet::SymbolPairSymbol, alphabet::SymbolSetSymbol, alphabet::UniqueSymbol, alphabet::StartSymbol, container::ObjectsSet, container::ObjectsVector, container::ObjectsPair, container::ObjectsMap, - primitive::String, primitive::Integer, primitive::Character, primitive::Unsigned, primitive::Bool + primitive::String, primitive::Integer, primitive::Character, primitive::Unsigned, primitive::Bool, + tree::RankedTree, tree::UnrankedTree >, public VisitableObjectBase { }; diff --git a/alib2data/src/object/ObjectFromXMLParser.cpp b/alib2data/src/object/ObjectFromXMLParser.cpp index e27b857f221684150bdcfece7285060e66f5941d..e397829b1672ecf4b5ac404a48d3c512a1d7cb58 100644 --- a/alib2data/src/object/ObjectFromXMLParser.cpp +++ b/alib2data/src/object/ObjectFromXMLParser.cpp @@ -51,6 +51,10 @@ Object ObjectFromXMLParser::parseObject(std::deque<sax::Token>& input) const { primitive::Primitive primitive = alib::xmlApi<primitive::Primitive>::parse(input); Object res(std::move(primitive.getData())); return res; + } else if(alib::FromXMLParsers::treeParser.first(input)) { + tree::Tree tree = alib::xmlApi<tree::Tree>::parse(input); + Object res(std::move(tree.getData())); + return res; } else if(alib::xmlApi<Void>::first(input)) { Object res(std::move(parseVoid(input))); return res; diff --git a/alib2data/src/tree/RankedTree/RankedNode.cpp b/alib2data/src/tree/RankedTree/RankedNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c68fe7dd7cdad415a0405bf33b52c8485e1604d3 --- /dev/null +++ b/alib2data/src/tree/RankedTree/RankedNode.cpp @@ -0,0 +1,193 @@ +/* + * RankedNode.cpp + * + * Created on: Nov 29, 2014 + * Author: Stepan Plachy + */ + +#include "RankedNode.h" +#include "../TreeException.h" +#include <iostream> +#include <set> + +namespace tree { + +RankedNode::RankedNode(const alphabet::RankedSymbol& symbol, const std::vector<RankedNode *> & children) : symbol(symbol), children(children) { + if((int) children.size() != symbol.getRank().getData()) throw TreeException("Number of children doesn't match the rank of the symbol"); + for (std::vector<RankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) { + (*it) -> parent = this; + } +} + +RankedNode::RankedNode(const RankedNode & other) : symbol(other.symbol.getLabel(), other.symbol.getRank()){ + children = std::vector<RankedNode *>(); + children.reserve(other.children.size()); + for (std::vector<RankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) { + RankedNode * child = (*it) -> clone(); + child -> parent = this; + children.push_back(child); + } +} + +RankedNode::RankedNode(RankedNode && other) : symbol(std::move(other.symbol.getLabel()), std::move(other.symbol.getRank())){ + children = std::vector<RankedNode *>(); + children.reserve(other.children.size()); + for (std::vector<RankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) { + RankedNode * child = std::move(**it).plunder(); + child -> parent = this; + children.push_back(child); + } +} + +RankedNode * RankedNode::clone() const { + return new RankedNode(*this); +} + +RankedNode * RankedNode::plunder() && { + return new RankedNode(std::move(*this)); +} + +RankedNode::~RankedNode() { + for (std::vector<RankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + { + delete *it; + } +} + +RankedNode & RankedNode::operator=(const RankedNode & other) { + if (this == &other) return *this; + *this = RankedNode(other); + return *this; +} + +RankedNode & RankedNode::operator=(RankedNode && other) { + std::swap(symbol, other.symbol); + std::swap(children, other.children); + for (std::vector<RankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + (*it) -> attachRankedTree(tree); + return *this; +} + +void RankedNode::setSymbol(alphabet::RankedSymbol & symbol) { + if (symbol.getRank().getData() != this -> symbol.getRank().getData()) throw TreeException("New ranked symbol has different rank"); + this -> symbol = symbol; + checkValidSymbol(); +} + +void RankedNode::attachRankedTree(RankedTree * tree) { + if (this -> tree == tree) return; + this -> tree = tree; + checkValidSymbol(); + for (std::vector<RankedNode *>::iterator i = children.begin(); i != children.end(); ++i) + { + (*i) -> attachRankedTree(tree); + } +} + +void RankedNode::checkValidSymbol() const { + if (tree == NULL) return; + const std::set<alphabet::RankedSymbol> & alphabet = tree -> getRankedAlphabet(); + if (alphabet.find(symbol) == alphabet.end()) throw TreeException("Ranked alphabet doesn't contain symbol in a node"); +} + +bool RankedNode::containsSymbol(const alphabet::RankedSymbol & symbol) const { + if(this -> symbol == symbol) return true; + for (std::vector<RankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) + { + if ((*it) -> containsSymbol(symbol)) return true; + } + return false; +} + +void RankedNode::changeChild(RankedNode * child, RankedNode * other) { + for (std::vector<RankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + { + if (*it == child) { + *it = other; + return; + } + } +} + +void RankedNode::switchSubtree(RankedNode * other) { + RankedNode * thisParent = parent; + RankedNode * otherParent = other -> parent; + if (thisParent != NULL) thisParent -> changeChild(this, other); + else if (tree != NULL) tree -> root = other; + if (otherParent != NULL) otherParent -> changeChild(other, this); + else if (other -> tree != NULL) other -> tree -> root = this; + parent = otherParent; + other -> parent = thisParent; + RankedTree * thisTree = tree; + RankedTree * otherTree = other -> tree; + attachRankedTree(otherTree); + other -> attachRankedTree(thisTree); +} + + +bool RankedNode::operator < (const RankedNode & other) const { + return compare(other) == -1; +} + +bool RankedNode::operator == (const RankedNode & other) const { + return compare(other) == 0; +} + +bool RankedNode::operator != (const RankedNode & other) const{ + return !(*this == other); +} + +int RankedNode::compare(const RankedNode & other) const { + if (symbol < other.symbol) return -1; + else if (symbol == other.symbol) { + std::vector<RankedNode *>::const_iterator i = children.begin(); + std::vector<RankedNode *>::const_iterator j = other.children.begin(); + while (i != this -> children.end() && j != other.children.end()) { + int result = (*i) -> compare(**j); + if (result != 0) return result; + ++i; + ++j; + } + if (i == children.end() && j == other.children.end()) return 0; + else if (j == other.children.end()) return 1; + else return -1; + } + else return 1; +} + +std::ostream& operator<<(std::ostream& out, const RankedNode& node) { + out << "(Ranked node " + << " symbol = " << node.symbol + << " children = {"; + for (std::vector<RankedNode *>::const_iterator it = node.children.begin(); it != node.children.end(); ++it) { + out << **it; + } + out << "})"; + return out; +} + +RankedNode::operator std::string () const { + return (std::string) symbol; +} + +void RankedNode::nicePrint(std::ostream & os, const std::string & prefix, const bool last) const { + os << prefix; + + std::string nextPrefix(prefix); + if (last) { + os << "\\-"; + nextPrefix += " "; + } else { + os << "|-"; + nextPrefix += "| "; + } + os << (std::string) symbol.getLabel() << "(" << symbol.getRank().getData() << ")" << std::endl; + + for (unsigned int i = 0; i < children.size(); i++) + { + os << nextPrefix << "|" << std::endl; + children[i] -> nicePrint(os, nextPrefix, i == children.size()-1); + } +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/RankedTree/RankedNode.h b/alib2data/src/tree/RankedTree/RankedNode.h new file mode 100644 index 0000000000000000000000000000000000000000..3b4c7c102e6e0e5f1e706922acd406999ce5b2e0 --- /dev/null +++ b/alib2data/src/tree/RankedTree/RankedNode.h @@ -0,0 +1,84 @@ +/* + * RankedNode.h + * + * Created on: Nov 29, 2014 + * Author: Stepan Plachy + */ + +#ifndef RANKED_NODE_H_ +#define RANKED_NODE_H_ + +#include <string> +#include <ostream> +#include <vector> + +#include "../../label/Label.h" +#include "../../alphabet/RankedSymbol.h" +#include "RankedTree.h" + +namespace tree { + + class RankedTree; + +/** + * Class representing node in a ranked tree. + */ +class RankedNode { +protected: + alphabet::RankedSymbol symbol; + RankedNode * parent = NULL; + std::vector<RankedNode *> children; + RankedTree * tree = NULL; + + void attachRankedTree(RankedTree *); + void changeChild(RankedNode * child, RankedNode * other); +public: + explicit RankedNode(const alphabet::RankedSymbol& symbol, const std::vector<RankedNode *> & children); + explicit RankedNode(const RankedNode &); + explicit RankedNode(RankedNode &&); + ~RankedNode(); + RankedNode & operator= (const RankedNode &); + RankedNode & operator= (RankedNode &&); + + RankedNode * clone() const; + RankedNode * plunder() &&; + + const alphabet::RankedSymbol& getSymbol() const {return symbol;} + void setSymbol(alphabet::RankedSymbol&); + RankedNode * getParent() const {return parent;} + const std::vector<const RankedNode *> & getChildren() const {return *reinterpret_cast<const std::vector<const RankedNode *> *>(&children);} + const std::vector<RankedNode *> & getChildren() {return children;} + RankedTree * getRankedTree() const {return tree;} + bool containsSymbol(const alphabet::RankedSymbol &) const; + void checkValidSymbol() const; + + void switchSubtree(RankedNode * other); + + bool operator < (const RankedNode& other) const; + bool operator == (const RankedNode& other) const; + bool operator != (const RankedNode& other) const; + int compare (const RankedNode& other) const; + + friend std::ostream& operator<<(std::ostream&, const RankedNode&); + + operator std::string () const; + + void nicePrint(std::ostream & = std::cout, const std::string & = "", const bool = true) const; + + friend class RankedTree; +}; + +} /* namespace tree */ + +namespace std { + +template<> +struct compare<tree::RankedNode> { + int operator()(const tree::RankedNode& first, const tree::RankedNode& second) const { + return first.compare(second); + } +}; + +} /* namespace std */ + +#endif /* RANKED_NODE_H_ */ diff --git a/alib2data/src/tree/RankedTree/RankedTree.cpp b/alib2data/src/tree/RankedTree/RankedTree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69a7e7ffe602b56723c0f0a00c0ed57dc38c9d8e --- /dev/null +++ b/alib2data/src/tree/RankedTree/RankedTree.cpp @@ -0,0 +1,106 @@ +/* + * RankedTree.cpp + * + * Created on: Nov 29, 2014 + * Author: Stepan Plachy + */ + +#include "RankedTree.h" +#include "../TreeException.h" +#include <ostream> +#include <sstream> + +namespace tree { + +RankedTree::RankedTree(const std::set<alphabet::RankedSymbol> & rankedAlphabet, const RankedNode & root) : rankedAlphabet(rankedAlphabet) { + this -> root = new RankedNode(root); + this -> root -> attachRankedTree(this); +} + +RankedTree::RankedTree(const std::set<alphabet::RankedSymbol> & rankedAlphabet, const RankedNode && root) : rankedAlphabet(rankedAlphabet) { + this -> root = new RankedNode(root); + if (this -> root -> tree != NULL) throw TreeException("Root is already in a tree"); + this -> root -> attachRankedTree(this); +} + +RankedTree::RankedTree(const RankedTree & other) { + rankedAlphabet = other.rankedAlphabet; + root = other.root -> clone(); + root -> attachRankedTree(this); +} + +RankedTree::RankedTree(RankedTree && other) { + rankedAlphabet = std::move(other.rankedAlphabet); + root = std::move(*other.root).plunder(); + root -> attachRankedTree(this); +} + +RankedTree::~RankedTree() { + delete root; +} + +TreeBase* RankedTree::clone() const { + return new RankedTree(*this); +} + +TreeBase* RankedTree::plunder() && { + return new RankedTree(std::move(*this)); +} + +void RankedTree::addRankedSymbol(alphabet::RankedSymbol & symbol) { + rankedAlphabet.insert(symbol); +} + +bool RankedTree::removeRankedSymbol(const alphabet::RankedSymbol& symbol) { + if (root -> containsSymbol(symbol)) throw TreeException("Symbol \"" + (std::string) symbol + "\" is used."); + return rankedAlphabet.erase(symbol); +} + +bool RankedTree::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool RankedTree::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool RankedTree::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool RankedTree::operator==(const RankedTree & other) const { + return this -> rankedAlphabet == other.rankedAlphabet && *(this -> root) == *(other.root); +} + +bool RankedTree::operator<(const RankedTree & other) const { + if (this -> rankedAlphabet < other.rankedAlphabet) return true; + else if (this -> rankedAlphabet == other.rankedAlphabet) return *(this -> root) < *(other.root); + else return false; +} + +void RankedTree::operator>>(std::ostream& out) const { + out << "(Ranked tree" + << " rankedAlphabet = " << rankedAlphabet + << " root = " << *root + << ")"; +} + +int RankedTree::compare(const RankedTree & other) const { + if (this -> rankedAlphabet == other.rankedAlphabet) { + return this -> root -> compare(*other.root); + } + else if (this -> rankedAlphabet < other.rankedAlphabet) return -1; + else return 1; +} + +void RankedTree::nicePrint(std::ostream & os) const { + root -> nicePrint(os); +} + +RankedTree::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/RankedTree/RankedTree.h b/alib2data/src/tree/RankedTree/RankedTree.h new file mode 100644 index 0000000000000000000000000000000000000000..14a93b5ff83aeb827aabf94b8cce5d1ae7187dff --- /dev/null +++ b/alib2data/src/tree/RankedTree/RankedTree.h @@ -0,0 +1,81 @@ +/* + * RankedTree.h + * + * Created on: Nov 29, 2014 + * Author: Stepan Plachy + */ + +#ifndef RANKEDTREE_H_ +#define RANKEDTREE_H_ + +#include <iostream> + +#include "../TreeBase.h" +#include "RankedNode.h" +#include "../../alphabet/RankedSymbol.h" +#include <set> + +namespace tree { + + class RankedNode; + +/** + * Represents Ranked Tree. + */ +class RankedTree : public std::acceptor<RankedTree, VisitableTreeBase, std::acceptor<RankedTree, alib::VisitableObjectBase, TreeBase> > { +protected: + std::set<alphabet::RankedSymbol> rankedAlphabet; + RankedNode * root; +public: + explicit RankedTree(const std::set<alphabet::RankedSymbol> & rankedAlphabet, const RankedNode & root); + explicit RankedTree(const std::set<alphabet::RankedSymbol> & rankedAlphabet, const RankedNode && root); + RankedTree(const RankedTree &); + explicit RankedTree(RankedTree &&); + + ~RankedTree(); + + virtual TreeBase* clone() const; + + virtual TreeBase* plunder() &&; + + /** + * @return tree root + */ + const RankedNode & getRoot() const {return *root;} + + RankedNode & getRoot() {return *root;} + + const std::set<alphabet::RankedSymbol> & getRankedAlphabet() const {return rankedAlphabet;} + + virtual void addRankedSymbol(alphabet::RankedSymbol & symbol); + virtual bool removeRankedSymbol(const alphabet::RankedSymbol & symbol); + + 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 RankedTree& other) const; + virtual bool operator<(const RankedTree& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual int compare(const ObjectBase& other) const { + return -other.compare(*this); + } + + virtual int compare(const RankedTree & other) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId<RankedTree>(); + } + + void nicePrint(std::ostream & os = std::cout) const; + + friend class RankedNode; +}; + +} /* namespace tree */ + +#endif /* RANKEDTREE_H_ */ diff --git a/alib2data/src/tree/Tree.cpp b/alib2data/src/tree/Tree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9eb3b4fbb035fc0361ffbff994c2bdc0dfe9d62f --- /dev/null +++ b/alib2data/src/tree/Tree.cpp @@ -0,0 +1,17 @@ +/* + * Tree.cpp + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#include "Tree.h" +//#include "../label/NextLabel.h" +//#include "../label/Label.h" +//#include <climits> +#include "TreeException.h" + +namespace tree { + +} /* namespace tree */ + diff --git a/alib2data/src/tree/Tree.h b/alib2data/src/tree/Tree.h new file mode 100644 index 0000000000000000000000000000000000000000..5a9b9981e51c76338994266c4820cc6adb493c7e --- /dev/null +++ b/alib2data/src/tree/Tree.h @@ -0,0 +1,24 @@ +/* + * Tree.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_H_ +#define TREE_H_ + +#include "TreeBase.h" +#include "../common/wrapper.hpp" + +namespace tree { + +/** + * Wrapper around tree. + */ +typedef alib::wrapper<TreeBase> Tree; + +} /* namespace tree */ + +#endif /* Tree_H_ */ + diff --git a/alib2data/src/tree/TreeBase.h b/alib2data/src/tree/TreeBase.h new file mode 100644 index 0000000000000000000000000000000000000000..8de49f03ae8d148dd4e26bb743efea40172e6808 --- /dev/null +++ b/alib2data/src/tree/TreeBase.h @@ -0,0 +1,39 @@ +/* + * TreeBase.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_BASE_H_ +#define TREE_BASE_H_ + +#include "../common/base.hpp" +#include "../object/ObjectBase.h" +#include "../exception/AlibException.h" + +namespace tree { + +class TreeBase; + +typedef std::acceptor_base<TreeBase, + tree::RankedTree, tree::UnrankedTree + > VisitableTreeBase; + +/** + * Abstract base class for all trees. + */ +class TreeBase : public alib::ObjectBase, public VisitableTreeBase { +public: + using VisitableTreeBase::Accept; + using alib::VisitableObjectBase::Accept; + + virtual TreeBase* clone() const = 0; + virtual TreeBase* plunder() && = 0; + +}; + +} /* namespace tree */ + +#endif /* TREE_BASE_H_ */ + diff --git a/alib2data/src/tree/TreeException.cpp b/alib2data/src/tree/TreeException.cpp new file mode 100644 index 0000000000000000000000000000000000000000..865b888792ebba0a60999e3a58fbccf6ebdba258 --- /dev/null +++ b/alib2data/src/tree/TreeException.cpp @@ -0,0 +1,23 @@ +/* + * TreeException.cpp + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#include "TreeException.h" + +namespace tree { + +TreeException::TreeException() { +} + +TreeException::TreeException(const std::string& cause) : + AlibException(cause) { +} + +TreeException::~TreeException() throw () { + +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/TreeException.h b/alib2data/src/tree/TreeException.h new file mode 100644 index 0000000000000000000000000000000000000000..1a30f23de7e2692b619d5384b99e1a76ca108599 --- /dev/null +++ b/alib2data/src/tree/TreeException.h @@ -0,0 +1,27 @@ +/* + * TreeException.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_EXCEPTION_H_ +#define TREE_EXCEPTION_H_ + +#include "../exception/AlibException.h" + +namespace tree { + +/** + * Exception thrown by an tree, tree parser or tree printer. + */ +class TreeException: public exception::AlibException { +public: + TreeException(); + explicit TreeException(const std::string& cause); + virtual ~TreeException() throw (); +}; + +} /* namespace tree */ + +#endif /* TREE_EXCEPTION_H_ */ diff --git a/alib2data/src/tree/TreeFeatures.h b/alib2data/src/tree/TreeFeatures.h new file mode 100644 index 0000000000000000000000000000000000000000..4947e68e077814eb4e9dac828dc1f762cd01ce9d --- /dev/null +++ b/alib2data/src/tree/TreeFeatures.h @@ -0,0 +1,19 @@ +/* + * TreeFeatures.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_FEATURES_H_ +#define TREE_FEATURES_H_ + +namespace tree { + +enum class FEATURES { + RANKED_TREE, UNRANKED_TREE +}; + +} /* namespace tree */ + +#endif /* TREE_FEATURES_H_ */ diff --git a/alib2data/src/tree/TreeFromXMLParser.cpp b/alib2data/src/tree/TreeFromXMLParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6127c058ff9de14e66dfde97ab3393f18069d4a6 --- /dev/null +++ b/alib2data/src/tree/TreeFromXMLParser.cpp @@ -0,0 +1,106 @@ +/* + * TreeFromXMLParser.cpp + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#include "TreeFromXMLParser.h" + +#include "../sax/ParserException.h" + +#include "../XmlApi.hpp" + +namespace tree { + + Tree TreeFromXMLParser::parseTree(std::deque<sax::Token> &input) const { + return parseTree(input, std::set<FEATURES>({FEATURES::RANKED_TREE, FEATURES::UNRANKED_TREE})); + } + + Tree TreeFromXMLParser::parseTree(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const { + if(alib::xmlApi<RankedTree>::first(input)) { + if(!features.count(FEATURES::RANKED_TREE)) throw exception::AlibException(); + return Tree(parseRankedTree(input)); + } else if(alib::xmlApi<UnrankedTree>::first(input)) { + if(!features.count(FEATURES::UNRANKED_TREE)) throw exception::AlibException(); + return Tree(parseUnrankedTree(input)); + } else + throw sax::ParserException(sax::Token("Tree / RankedTree / UnrankedTree", sax::Token::TokenType::START_ELEMENT), input.front()); + } + + RankedTree TreeFromXMLParser::parseRankedTree(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::TREE_RANKED_TREE); + + std::set<alphabet::RankedSymbol> rankedAlphabet = parseRankedAlphabet(input); + RankedNode * root = parseRankedNode(input); + RankedTree tree(rankedAlphabet, std::move(*root)); + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_RANKED_TREE); + return tree; + } + + UnrankedTree TreeFromXMLParser::parseUnrankedTree(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::TREE_UNRANKED_TREE); + + std::set<alphabet::LabeledSymbol> alphabet = parseAlphabet(input); + UnrankedNode * root = parseUnrankedNode(input); + UnrankedTree tree(alphabet, std::move(*root)); + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_UNRANKED_TREE); + return tree; + } + + std::set<alphabet::RankedSymbol> TreeFromXMLParser::parseRankedAlphabet(std::deque<sax::Token> &input) const { + std::set<alphabet::RankedSymbol> rankedSymbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "rankedAlphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + rankedSymbols.insert(alib::xmlApi<alphabet::RankedSymbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "rankedAlphabet"); + return rankedSymbols; + } + + std::set<alphabet::LabeledSymbol> TreeFromXMLParser::parseAlphabet(std::deque<sax::Token> &input) const { + std::set<alphabet::LabeledSymbol> symbols; + popToken(input, sax::Token::TokenType::START_ELEMENT, "alphabet"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + symbols.insert(alib::xmlApi<alphabet::LabeledSymbol>::parse(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "alphabet"); + return symbols; + } + + RankedNode * TreeFromXMLParser::parseRankedNode(std::deque<sax::Token> &input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "rankedNode"); + alphabet::RankedSymbol symbol = alib::xmlApi<alphabet::RankedSymbol>::parse(input); + int rank = symbol.getRank().getData(); + std::vector<RankedNode *> children; + children.reserve(rank); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + children.push_back(parseRankedNode(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "rankedNode"); + + return new RankedNode(symbol, children); + } + + UnrankedNode * TreeFromXMLParser::parseUnrankedNode(std::deque<sax::Token> &input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "unrankedNode"); + alphabet::LabeledSymbol symbol = alib::xmlApi<alphabet::LabeledSymbol>::parse(input); + std::list<UnrankedNode *> children; + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + children.push_back(parseUnrankedNode(input)); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "unrankedNode"); + + return new UnrankedNode(symbol, children); + } + + bool TreeFromXMLParser::first(const std::deque<sax::Token>& input) const { + if (alib::xmlApi<RankedTree>::first(input) || alib::xmlApi<UnrankedTree>::first(input)) { + return true; + } else { + return false; + } + } + +} /* namespace tree */ + diff --git a/alib2data/src/tree/TreeFromXMLParser.h b/alib2data/src/tree/TreeFromXMLParser.h new file mode 100644 index 0000000000000000000000000000000000000000..a2ace647cd16f36f644ed9a621e1a02d6da80fe3 --- /dev/null +++ b/alib2data/src/tree/TreeFromXMLParser.h @@ -0,0 +1,55 @@ +/* + * TreeFromXMLParser.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_FROM_XML_PARSER_H_ +#define TREE_FROM_XML_PARSER_H_ + +#include "../sax/FromXMLParserHelper.h" +#include "Tree.h" +#include "TreeFeatures.h" +#include "RankedTree/RankedTree.h" +#include "UnrankedTree/UnrankedTree.h" + +#include <deque> +#include <set> +#include <variant> +#include "../sax/Token.h" + +namespace alib { + +template<typename T> +struct xmlApi; + +} /* namespace alib */ + +namespace tree { + +/** + * Parser used to get tree from XML parsed into list of Tokens. + */ +class TreeFromXMLParser : public sax::FromXMLParserHelper { + + RankedNode * parseRankedNode(std::deque<sax::Token> &input) const; + UnrankedNode * parseUnrankedNode(std::deque<sax::Token> &input) const; + std::set<alphabet::RankedSymbol> parseRankedAlphabet(std::deque<sax::Token> &input) const; + std::set<alphabet::LabeledSymbol> parseAlphabet(std::deque<sax::Token> &input) const; + + Tree parseTree(std::deque<sax::Token>& input) const; + Tree parseTree(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const; + + RankedTree parseRankedTree(std::deque<sax::Token>& input) const; + UnrankedTree parseUnrankedTree(std::deque<sax::Token>& input) const; + + template<typename T> friend class alib::xmlApi; +public: + bool first(const std::deque<sax::Token>& input) const; +}; + +} /* namespace tree */ + +#endif /* TREE_FROM_XML_PARSER_H_ */ + diff --git a/alib2data/src/tree/TreeToXMLComposer.cpp b/alib2data/src/tree/TreeToXMLComposer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a33762e44314f99bb2e7bf9dccf3cb5f8b385e7 --- /dev/null +++ b/alib2data/src/tree/TreeToXMLComposer.cpp @@ -0,0 +1,77 @@ +/* + * TreeToXMLComposer.cpp + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#include "TreeToXMLComposer.h" + +#include "../XmlApi.hpp" + +namespace tree { + +void TreeToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const { + out.emplace_back(sax::Token("rankedAlphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + alib::xmlApi<alphabet::RankedSymbol>::compose(out, symbol); + } + out.emplace_back(sax::Token("rankedAlphabet", sax::Token::TokenType::END_ELEMENT)); +} + +void TreeToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::LabeledSymbol>& symbols) const { + out.emplace_back(sax::Token("alphabet", sax::Token::TokenType::START_ELEMENT)); + for (const auto& symbol : symbols) { + alib::xmlApi<alphabet::LabeledSymbol>::compose(out, symbol); + } + out.emplace_back(sax::Token("alphabet", sax::Token::TokenType::END_ELEMENT)); +} + +void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const TreeBase& tree) const { + tree.Accept((void*) &out, alib::ToXMLComposers::toXMLComposers); +} + +void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const Tree& tree) const { + tree.getData().Accept((void*) &out, alib::ToXMLComposers::toXMLComposers); +} + +void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const RankedTree& tree) const { + out.emplace_back(sax::Token(alib::Names::TREE_RANKED_TREE, sax::Token::TokenType::START_ELEMENT)); + + composeAlphabet(out, tree.getRankedAlphabet()); + composeNode(out, tree.getRoot()); + + out.emplace_back(sax::Token(alib::Names::TREE_RANKED_TREE, sax::Token::TokenType::END_ELEMENT)); +} + +void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const UnrankedTree& tree) const { + out.emplace_back(sax::Token(alib::Names::TREE_UNRANKED_TREE, sax::Token::TokenType::START_ELEMENT)); + + composeAlphabet(out, tree.getAlphabet()); + composeNode(out, tree.getRoot()); + + out.emplace_back(sax::Token(alib::Names::TREE_UNRANKED_TREE, sax::Token::TokenType::END_ELEMENT)); +} + +void TreeToXMLComposer::composeNode(std::deque<sax::Token>& out, const RankedNode& node) const { + out.emplace_back(sax::Token("rankedNode", sax::Token::TokenType::START_ELEMENT)); + alib::xmlApi<alphabet::RankedSymbol>::compose(out, node.getSymbol()); + for(const auto& child : node.getChildren()) { + composeNode(out, *child); + } + + out.emplace_back(sax::Token("rankedNode", sax::Token::TokenType::END_ELEMENT)); +} + +void TreeToXMLComposer::composeNode(std::deque<sax::Token>& out, const UnrankedNode& node) const { + out.emplace_back(sax::Token("unrankedNode", sax::Token::TokenType::START_ELEMENT)); + alib::xmlApi<alphabet::LabeledSymbol>::compose(out, node.getSymbol()); + for(const auto& child : node.getChildren()) { + composeNode(out, *child); + } + + out.emplace_back(sax::Token("unrankedNode", sax::Token::TokenType::END_ELEMENT)); +} + +} /* namespace automaton */ + diff --git a/alib2data/src/tree/TreeToXMLComposer.h b/alib2data/src/tree/TreeToXMLComposer.h new file mode 100644 index 0000000000000000000000000000000000000000..df71f10d5461c8917f46f71fa355e876300a3082 --- /dev/null +++ b/alib2data/src/tree/TreeToXMLComposer.h @@ -0,0 +1,59 @@ +/* + * TreeToXMLComposer.h + * + * Created on: Nov 16, 2014 + * Author: Stepan Plachy + */ + +#ifndef TREE_TO_XML_COMPOSER_H_ +#define TREE_TO_XML_COMPOSER_H_ + +#include <string> +#include <deque> +#include "Tree.h" +#include "RankedTree/RankedTree.h" +#include "UnrankedTree/UnrankedTree.h" +#include "../sax/Token.h" + +namespace alib { + +template<typename T> +struct xmlApi; + +} /* namespace alib */ + +namespace tree { + +/** + * This class contains methods to print XML representation of tree to the output stream. + */ +class TreeToXMLComposer { + + void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const; + + void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::LabeledSymbol>& symbols) const; + + /** + * Prints XML representation of Tree to the output stream. + * @param tree tree to print + * @return list of xml tokens representing the tree + */ + void compose(std::deque<sax::Token>& out, const TreeBase& tree) const; + + void compose(std::deque<sax::Token>& out, const Tree& tree) const; + + void compose(std::deque<sax::Token>& out, const RankedTree& tree) const; + + void compose(std::deque<sax::Token>& out, const UnrankedTree& tree) const; + + void composeNode(std::deque<sax::Token>& out, const RankedNode& node) const; + + void composeNode(std::deque<sax::Token>& out, const UnrankedNode& node) const; + + template<typename T> friend class alib::xmlApi; +}; + +} /* namespace tree */ + +#endif /* TREE_TO_XML_COMPOSER_H_ */ + diff --git a/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp b/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ac61818a7202e428a23361256486ef04cb3c5b8 --- /dev/null +++ b/alib2data/src/tree/UnrankedTree/UnrankedNode.cpp @@ -0,0 +1,215 @@ +/* + * UnrankedNode.cpp + * + * Created on: Mar 9, 2015 + * Author: Stepan Plachy + */ + +#include "UnrankedNode.h" +#include "../TreeException.h" +#include <iostream> +#include <set> + +namespace tree { + +UnrankedNode::UnrankedNode(const alphabet::LabeledSymbol& symbol, const std::list<UnrankedNode *> & children) : symbol(symbol), children(children) { + for (std::list<UnrankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) { + (*it) -> parent = this; + } +} + +UnrankedNode::UnrankedNode(const UnrankedNode & other) : symbol(other.symbol) { + children = std::list<UnrankedNode *>(); + for (std::list<UnrankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) { + UnrankedNode * child = (*it) -> clone(); + child -> parent = this; + children.push_back(child); + } +} + +UnrankedNode::UnrankedNode(UnrankedNode && other) : symbol(std::move(other.symbol)) { + children = std::list<UnrankedNode *>(); + for (std::list<UnrankedNode *>::const_iterator it = other.children.begin(); it != other.children.end(); ++it) { + UnrankedNode * child = std::move(**it).plunder(); + child -> parent = this; + children.push_back(child); + } +} + +UnrankedNode * UnrankedNode::clone() const { + return new UnrankedNode(*this); +} + +UnrankedNode * UnrankedNode::plunder() && { + return new UnrankedNode(std::move(*this)); +} + +UnrankedNode::~UnrankedNode() { + for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + { + delete *it; + } +} + +UnrankedNode & UnrankedNode::operator=(const UnrankedNode & other) { + if (this == &other) return *this; + *this = UnrankedNode(other); + return *this; +} + +UnrankedNode & UnrankedNode::operator=(UnrankedNode && other) { + std::swap(symbol, other.symbol); + std::swap(children, other.children); + for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + (*it) -> attachUnrankedTree(tree); + return *this; +} + +void UnrankedNode::setSymbol(alphabet::LabeledSymbol & symbol) { + this -> symbol = symbol; + checkValidSymbol(); +} + +void UnrankedNode::attachUnrankedTree(UnrankedTree * tree) { + if (this -> tree == tree) return; + this -> tree = tree; + checkValidSymbol(); + for (std::list<UnrankedNode *>::iterator i = children.begin(); i != children.end(); ++i) + { + (*i) -> attachUnrankedTree(tree); + } +} + +void UnrankedNode::checkValidSymbol() const { + if (tree == NULL) return; + const std::set<alphabet::LabeledSymbol> & alphabet = tree -> getAlphabet(); + if (alphabet.find(symbol) == alphabet.end()) throw TreeException("Alphabet doesn't contain symbol in a node"); +} + +bool UnrankedNode::containsSymbol(const alphabet::LabeledSymbol & symbol) const { + if(this -> symbol == symbol) return true; + for (std::list<UnrankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) + { + if ((*it) -> containsSymbol(symbol)) return true; + } + return false; +} + +UnrankedNode & UnrankedNode::extract() { + parent -> children.remove(this); + parent = NULL; + attachUnrankedTree(NULL); + return *this; +} + +void UnrankedNode::pushBackChild(UnrankedNode & child) { + child.attachUnrankedTree(tree); + children.push_back(&child); +} + +void UnrankedNode::insertSibling(UnrankedNode & sibling) { + parent -> insertChild(this, &sibling); +} + +void UnrankedNode::insertChild(UnrankedNode * position, UnrankedNode * child) { + for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + { + if (*it == position) { + children.insert(it, child); + return; + } + } +} + +void UnrankedNode::changeChild(UnrankedNode * child, UnrankedNode * other) { + for (std::list<UnrankedNode *>::iterator it = children.begin(); it != children.end(); ++it) + { + if (*it == child) { + *it = other; + return; + } + } +} + +void UnrankedNode::switchSubtree(UnrankedNode * other) { + UnrankedNode * thisParent = parent; + UnrankedNode * otherParent = other -> parent; + if (thisParent != NULL) thisParent -> changeChild(this, other); + else if (tree != NULL) tree -> root = other; + if (otherParent != NULL) otherParent -> changeChild(other, this); + else if (other -> tree != NULL) other -> tree -> root = this; + parent = otherParent; + other -> parent = thisParent; + UnrankedTree * thisTree = tree; + UnrankedTree * otherTree = other -> tree; + attachUnrankedTree(otherTree); + other -> attachUnrankedTree(thisTree); +} + +bool UnrankedNode::operator < (const UnrankedNode & other) const { + return compare(other) == -1; +} + +bool UnrankedNode::operator == (const UnrankedNode & other) const { + return compare(other) == 0; +} + +bool UnrankedNode::operator != (const UnrankedNode & other) const{ + return !(*this == other); +} + +int UnrankedNode::compare(const UnrankedNode & other) const { + if (symbol < other.symbol) return -1; + else if (symbol == other.symbol) { + std::list<UnrankedNode *>::const_iterator i = children.begin(); + std::list<UnrankedNode *>::const_iterator j = other.children.begin(); + while (i != this -> children.end() && j != other.children.end()) { + int result = (*i) -> compare(**j); + if (result != 0) return result; + ++i; + ++j; + } + if (i == children.end() && j == other.children.end()) return 0; + else if (j == other.children.end()) return 1; + else return -1; + } + else return 1; +} + +std::ostream& operator<<(std::ostream& out, const UnrankedNode& node) { + out << "(Unranked node " + << " symbol = " << node.symbol + << " children = {"; + for (std::list<UnrankedNode *>::const_iterator it = node.children.begin(); it != node.children.end(); ++it) { + out << **it; + } + out << "})"; + return out; +} + +UnrankedNode::operator std::string () const { + return (std::string) symbol; +} + +void UnrankedNode::nicePrint(std::ostream & os, const std::string & prefix, const bool last) const { + os << prefix; + + std::string nextPrefix(prefix); + if (last) { + os << "\\-"; + nextPrefix += " "; + } else { + os << "|-"; + nextPrefix += "| "; + } + os << (std::string) symbol.getLabel() << std::endl; + + for (std::list<UnrankedNode *>::const_iterator it = children.begin(); it != children.end(); ++it) + { + os << nextPrefix << "|" << std::endl; + (*it) -> nicePrint(os, nextPrefix, (*it) == children.back()); + } + +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/UnrankedTree/UnrankedNode.h b/alib2data/src/tree/UnrankedTree/UnrankedNode.h new file mode 100644 index 0000000000000000000000000000000000000000..e8f7951247ac3d59288cf81810dbb2baba681dcd --- /dev/null +++ b/alib2data/src/tree/UnrankedTree/UnrankedNode.h @@ -0,0 +1,78 @@ +/* + * UnrankedNode.h + * + * Created on: Mar 9, 2015 + * Author: Stepan Plachy + */ + +#ifndef UNRANKED_NODE_H_ +#define UNRANKED_NODE_H_ + +#include <string> +#include <iostream> +#include <list> + +#include "../../label/Label.h" +#include "../../alphabet/LabeledSymbol.h" +#include "UnrankedTree.h" + +namespace tree { + + class UnrankedTree; + +/** + * Class representing node in an unranked tree. + */ +class UnrankedNode { +private: + alphabet::LabeledSymbol symbol; + UnrankedNode * parent = NULL; + std::list<UnrankedNode *> children; + UnrankedTree * tree = NULL; + + void attachUnrankedTree(UnrankedTree *); + void changeChild(UnrankedNode * child, UnrankedNode * other); + void insertChild(UnrankedNode * position, UnrankedNode * child); +public: + explicit UnrankedNode(const alphabet::LabeledSymbol& symbol, const std::list<UnrankedNode *> & children); + explicit UnrankedNode(const UnrankedNode &); + explicit UnrankedNode(UnrankedNode &&); + ~UnrankedNode(); + UnrankedNode & operator= (const UnrankedNode &); + UnrankedNode & operator= (UnrankedNode &&); + + UnrankedNode * clone() const; + UnrankedNode * plunder() &&; + + + const alphabet::LabeledSymbol& getSymbol() const {return symbol;} + void setSymbol(alphabet::LabeledSymbol&); + UnrankedNode * getParent() const {return parent;} + const std::list<const UnrankedNode *> & getChildren() const {return *reinterpret_cast<const std::list<const UnrankedNode *> *>(&children);} + const std::list<UnrankedNode *> & getChildren() {return children;} + UnrankedTree * getUnrankedTree() const {return tree;} + bool containsSymbol(const alphabet::LabeledSymbol &) const; + void checkValidSymbol() const; + + UnrankedNode & extract(); + void pushBackChild(UnrankedNode &); + void insertSibling(UnrankedNode &); + void switchSubtree(UnrankedNode * other); + + bool operator < (const UnrankedNode& other) const; + bool operator == (const UnrankedNode& other) const; + bool operator != (const UnrankedNode& other) const; + int compare (const UnrankedNode& other) const; + + friend std::ostream& operator<<(std::ostream&, const UnrankedNode&); + + operator std::string () const; + + void nicePrint(std::ostream & = std::cout, const std::string & = "", const bool = true) const; + + friend class UnrankedTree; +}; + +} /* namespace tree */ + +#endif /* UNRANKED_NODE_H_ */ diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bb837b328ab53176991ab343d48097a25ac3610 --- /dev/null +++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.cpp @@ -0,0 +1,106 @@ +/* + * UnrankedTree.cpp + * + * Created on: Mar 9, 2015 + * Author: Stepan Plachy + */ + +#include "UnrankedTree.h" +#include "../TreeException.h" +#include <ostream> +#include <sstream> + +namespace tree { + +UnrankedTree::UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode & root) : alphabet(alphabet) { + this -> root = new UnrankedNode(root); + this -> root -> attachUnrankedTree(this); +} + +UnrankedTree::UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode && root) : alphabet(alphabet) { + this -> root = new UnrankedNode(root); + if (this -> root -> tree != NULL) throw TreeException("Root is already in a tree"); + this -> root -> attachUnrankedTree(this); +} + +UnrankedTree::UnrankedTree(const UnrankedTree & other) { + alphabet = other.alphabet; + root = other.root -> clone(); + root -> attachUnrankedTree(this); +} + +UnrankedTree::UnrankedTree(UnrankedTree && other) { + alphabet = std::move(other.alphabet); + root = std::move(*other.root).clone(); + root -> attachUnrankedTree(this); +} + +UnrankedTree::~UnrankedTree() { + delete root; +} + +TreeBase* UnrankedTree::clone() const { + return new UnrankedTree(*this); +} + +TreeBase* UnrankedTree::plunder() && { + return new UnrankedTree(std::move(*this)); +} + +void UnrankedTree::addSymbol(alphabet::LabeledSymbol & symbol) { + alphabet.insert(symbol); +} + +bool UnrankedTree::removeSymbol(const alphabet::LabeledSymbol& symbol) { + if (root -> containsSymbol(symbol)) throw TreeException("Symbol \"" + (std::string) symbol + "\" is used."); + return alphabet.erase(symbol); +} + +bool UnrankedTree::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool UnrankedTree::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool UnrankedTree::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool UnrankedTree::operator==(const UnrankedTree & other) const { + return this -> alphabet == other.alphabet && *(this -> root) == *(other.root); +} + +bool UnrankedTree::operator<(const UnrankedTree & other) const { + if (this -> alphabet < other.alphabet) return true; + else if (this -> alphabet == other.alphabet) return *(this -> root) < *(other.root); + else return false; +} + +void UnrankedTree::operator>>(std::ostream& out) const { + out << "(Unranked tree" + << " alphabet = " << alphabet + << " root = " << *root + << ")"; +} + +int UnrankedTree::compare(const UnrankedTree & other) const { + if (this -> alphabet == other.alphabet) { + return this -> root -> compare(*other.root); + } + else if (this -> alphabet < other.alphabet) return -1; + else return 1; +} + +void UnrankedTree::nicePrint(std::ostream & os) const { + root -> nicePrint(os); +} + +UnrankedTree::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/UnrankedTree/UnrankedTree.h b/alib2data/src/tree/UnrankedTree/UnrankedTree.h new file mode 100644 index 0000000000000000000000000000000000000000..c4e6392245fb44507160637477c4d594359cc4bf --- /dev/null +++ b/alib2data/src/tree/UnrankedTree/UnrankedTree.h @@ -0,0 +1,79 @@ +/* + * UnrankedTree.h + * + * Created on: Mar 9, 2015 + * Author: Stepan Plachy + */ + +#ifndef UNRANKEDTREE_H_ +#define UNRANKEDTREE_H_ + +#include "../TreeBase.h" +#include "UnrankedNode.h" +#include "../../alphabet/LabeledSymbol.h" +#include <set> + +#include <iostream> + +namespace tree { + + class UnrankedNode; + +/** + * Represents Unranked Tree. + */ +class UnrankedTree : public std::acceptor<UnrankedTree, VisitableTreeBase, std::acceptor<UnrankedTree, alib::VisitableObjectBase, TreeBase> > { +protected: + std::set<alphabet::LabeledSymbol> alphabet; + UnrankedNode * root; +public: + explicit UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode & root); + explicit UnrankedTree(const std::set<alphabet::LabeledSymbol> & alphabet, const UnrankedNode && root); + UnrankedTree(const UnrankedTree &); + explicit UnrankedTree(UnrankedTree &&); + + ~UnrankedTree(); + + virtual TreeBase* clone() const; + + virtual TreeBase* plunder() &&; + + /** + * @return tree root + */ + UnrankedNode & getRoot() const {return *root;} + + const std::set<alphabet::LabeledSymbol> & getAlphabet() const {return alphabet;} + + virtual void addSymbol(alphabet::LabeledSymbol & symbol); + virtual bool removeSymbol(const alphabet::LabeledSymbol & symbol); + + 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 UnrankedTree& other) const; + virtual bool operator<(const UnrankedTree& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual int compare(const ObjectBase& other) const { + return -other.compare(*this); + } + + virtual int compare(const UnrankedTree & other) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId<UnrankedTree>(); + } + + void nicePrint(std::ostream & os = std::cout) const; + + friend class UnrankedNode; +}; + +} /* namespace tree */ + +#endif /* RANKEDTREE_H_ */ diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp index 8b571818cfe0a00baf47069d06c8e4e65d8946cd..76733d8382e24198f443d3a13d33249e9f7fbc3f 100644 --- a/alib2data/test-src/automaton/AutomatonTest.cpp +++ b/alib2data/test-src/automaton/AutomatonTest.cpp @@ -1,4 +1,3 @@ -#include <list> #include "AutomatonTest.h" #include "sax/SaxParseInterface.h" @@ -8,6 +7,7 @@ #include "automaton/FSM/ExtendedNFA.h" #include "automaton/PDA/SinglePopDPDA.h" #include "automaton/PDA/DPDA.h" +#include "automaton/TA/NFTA.h" #include "automaton/AutomatonException.h" @@ -307,3 +307,85 @@ void AutomatonTest::testRHPDATransitions() { CPPUNIT_ASSERT(!(automaton < automaton)); CPPUNIT_ASSERT(automaton == automaton); } + +void AutomatonTest::testNFTAParser() { + alphabet::RankedSymbol a ('a', 2); + alphabet::RankedSymbol b ('b', 1); + alphabet::RankedSymbol c ('c', 0); + + automaton::State q2 ("q2"); + automaton::State q1 ("q1"); + automaton::State q0 ("q0"); + + automaton::NFTA automaton; + + automaton.addState(q2); + automaton.addState(q1); + automaton.addState(q0); + automaton.addInputSymbol(a); + automaton.addInputSymbol(b); + automaton.addInputSymbol(c); + + std::vector<automaton::State> states1 = {q1, q0}; + automaton.addTransition(a, states1, q2); + automaton.addTransition(a, states1, q1); + std::vector<automaton::State> states2 = {q0}; + automaton.addTransition(b, states2, q1); + automaton.addTransition(b, states2, q0); + std::vector<automaton::State> states3 = {}; + automaton.addTransition(c, states3, q0); + + automaton.addFinalState(q2); + + CPPUNIT_ASSERT( automaton == automaton ); + { + std::deque<sax::Token> tokens = alib::XmlDataFactory::toTokens(automaton); + std::string tmp; + sax::SaxComposeInterface::printMemory(tmp, tokens); + std::cout << tmp << std::endl; + + std::deque<sax::Token> tokens2; + sax::SaxParseInterface::parseMemory(tmp, tokens2); + automaton::NFTA automaton2 = alib::XmlDataFactory::fromTokens<automaton::NFTA>(tokens2); + + CPPUNIT_ASSERT( automaton == automaton2 ); + } +} + +void AutomatonTest::testNFTATransitions() { + alphabet::RankedSymbol a ('a', 2); + alphabet::RankedSymbol b ('b', 1); + alphabet::RankedSymbol c ('c', 0); + alphabet::RankedSymbol d ('d', 0); + + automaton::State q2 ("q2"); + automaton::State q1 ("q1"); + automaton::State q0 ("q0"); + + automaton::NFTA automaton; + + automaton.addState(q2); + automaton.addState(q1); + automaton.addState(q0); + automaton.addInputSymbol(a); + automaton.addInputSymbol(b); + automaton.addInputSymbol(c); + + std::vector<automaton::State> states1 = {q1, q0}; + automaton.addTransition(a, states1, q2); + automaton.addTransition(a, states1, q1); + std::vector<automaton::State> states2 = {q0}; + automaton.addTransition(b, states2, q1); + automaton.addTransition(b, states2, q0); + std::vector<automaton::State> states3 = {}; + automaton.addTransition(c, states3, q0); + + automaton.addFinalState(q2); + + CPPUNIT_ASSERT_THROW(automaton.removeInputSymbol(a), exception::AlibException); + CPPUNIT_ASSERT_NO_THROW(automaton.removeInputSymbol(d)); + CPPUNIT_ASSERT_NO_THROW(automaton.removeTransition(b, states1, q2)); + CPPUNIT_ASSERT_THROW(automaton.addTransition(b, states1, q1), exception::AlibException); + CPPUNIT_ASSERT_THROW(automaton.addTransition(a, states2, q1), exception::AlibException); + CPPUNIT_ASSERT_THROW(automaton.addTransition(d, states3, q0), exception::AlibException); +} diff --git a/alib2data/test-src/automaton/AutomatonTest.h b/alib2data/test-src/automaton/AutomatonTest.h index 5bdc5c7eca8a24395813fa89740e2e28e457f541..3330f48136bed7218591c515b42efda5c86366d0 100644 --- a/alib2data/test-src/automaton/AutomatonTest.h +++ b/alib2data/test-src/automaton/AutomatonTest.h @@ -13,6 +13,8 @@ class AutomatonTest : public CppUnit::TestFixture CPPUNIT_TEST( testExtendedNFAAlphabet ); CPPUNIT_TEST( testRHPDATransitions ); CPPUNIT_TEST( testNPDATransitions ); + CPPUNIT_TEST( testNFTAParser ); + CPPUNIT_TEST( testNFTATransitions ); CPPUNIT_TEST_SUITE_END(); public: @@ -26,6 +28,8 @@ public: void testExtendedNFAAlphabet(); void testRHPDATransitions(); void testNPDATransitions(); + void testNFTAParser(); + void testNFTATransitions(); }; #endif // AUTOMATON_TEST_H_ diff --git a/alib2data/test-src/tree/TreeTest.cpp b/alib2data/test-src/tree/TreeTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..48e86fd7c8b6b74ecb4c1c2735e5c1377d5de5ae --- /dev/null +++ b/alib2data/test-src/tree/TreeTest.cpp @@ -0,0 +1,430 @@ +#include "TreeTest.h" + +#include "sax/SaxParseInterface.h" +#include "sax/SaxComposeInterface.h" + +#include "tree/RankedTree/RankedTree.h" + +#include "tree/TreeException.h" + +#include "factory/XmlDataFactory.hpp" + +#include "alphabet/RankedSymbol.h" + + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( TreeTest ); + +void TreeTest::setUp() { +} + +void TreeTest::tearDown() { +} + +tree::RankedNode * prefixToNode(const std::string & s, int & pos) { + char c = s[pos]; + int r = s[pos+1] - '0'; + pos += 2; + std::vector<tree::RankedNode *> children (r); + for (int i = 0; i < r; i++) { + children[i] = prefixToNode(s, pos); + } + return new tree::RankedNode(alphabet::RankedSymbol(c, r), children); +} + +void TreeTest::testRankedTreeParser() { +/* + L=(a(2), b(1), c(0)) + + \-1.a(2) + | + |-2.b(1) + | | + | \-3.c(0) + | + \-4.c(0) +*/ + const alphabet::RankedSymbol a ('a', 2); + const alphabet::RankedSymbol b ('b', 1); + const alphabet::RankedSymbol c ('c', 0); + + const std::set<alphabet::RankedSymbol> alphabet {a, b, c}; + + std::vector<tree::RankedNode *> children3 (0); + tree::RankedNode * node3 = new tree::RankedNode(c, children3); + std::vector<tree::RankedNode *> children4 (0); + tree::RankedNode * node4 = new tree::RankedNode(c, children4); + std::vector<tree::RankedNode *> children2 {node3}; + tree::RankedNode * node2 = new tree::RankedNode(b, children2); + std::vector<tree::RankedNode *> children1 {node2, node4}; + tree::RankedNode * node1 = new tree::RankedNode(a, children1); + + tree::RankedTree tree(alphabet, std::move(*node1)); + + CPPUNIT_ASSERT( tree == tree ); + tree.getRoot().nicePrint(std::cout); + { + std::deque<sax::Token> tokens = alib::XmlDataFactory::toTokens(tree); + std::string tmp; + sax::SaxComposeInterface::printMemory(tmp, tokens); + + std::deque<sax::Token> tokens2; + sax::SaxParseInterface::parseMemory(tmp, tokens2); + tree::RankedTree tree2 = alib::XmlDataFactory::fromTokens<tree::RankedTree>(tokens2); + + CPPUNIT_ASSERT( tree == tree2 ); + std::cout << std::endl; + tree2.getRoot().nicePrint(std::cout); + } +/* + std::string s = "a2a2a2b1a2c0c0c0c0c0"; + int itmp = 0; + tree::RankedNode * node = prefixToNode(s, itmp); + std::set<alphabet::RankedSymbol> al; + for (unsigned i = 0; i < s.length(); i += 2) al.insert(alphabet::RankedSymbol(s[i], (int) (s[i+1] - '0'))); + tree::RankedTree t(al, std::move(*node)); + alib::XmlDataFactory::toStdout(t); +*/ +} + +void TreeTest::testRankedTreeCompare() { +/* + L=(a(2), b(1), c(0)) + + \-1.a(2) + | + |-2.b(1) + | | + | \-3.c(0) + | + \-4.c(0) + + \-5.a(2) + | + |-6.c(0) + | + \-7.b(1) + | + \-8.c(0) +*/ + const alphabet::RankedSymbol a ('a', 2); + const alphabet::RankedSymbol b ('b', 1); + const alphabet::RankedSymbol c ('c', 0); + + const std::set<alphabet::RankedSymbol> alphabet {a, b, c}; + + std::vector<tree::RankedNode *> children3 (0); + tree::RankedNode * node3 = new tree::RankedNode(c, children3); + std::vector<tree::RankedNode *> children4 (0); + tree::RankedNode * node4 = new tree::RankedNode(c, children4); + std::vector<tree::RankedNode *> children2 {node3}; + tree::RankedNode * node2 = new tree::RankedNode(b, children2); + std::vector<tree::RankedNode *> children1 {node2, node4}; + tree::RankedNode * node1 = new tree::RankedNode(a, children1); + + std::vector<tree::RankedNode *> children6 (0); + tree::RankedNode * node6 = new tree::RankedNode(c, children6); + std::vector<tree::RankedNode *> children8 (0); + tree::RankedNode * node8 = new tree::RankedNode(c, children8); + std::vector<tree::RankedNode *> children7 {node8}; + tree::RankedNode * node7 = new tree::RankedNode(b, children7); + std::vector<tree::RankedNode *> children5 {node6, node7}; + tree::RankedNode * node5 = new tree::RankedNode(a, children5); + + tree::RankedTree tree1(alphabet, std::move(*node1)); + tree::RankedTree tree2(alphabet, std::move(*node5)); + + CPPUNIT_ASSERT( tree1 != tree2 ); + CPPUNIT_ASSERT( tree1 < tree2 ); + CPPUNIT_ASSERT( tree2 > tree1 ); + CPPUNIT_ASSERT( !(tree1 > tree2) ); +} + +void TreeTest::testRankedTreeSymbolValidityCheck() { + alphabet::RankedSymbol a ('a', 2); + alphabet::RankedSymbol b ('b', 1); + alphabet::RankedSymbol c ('c', 0); + alphabet::RankedSymbol d ('d', 0); + alphabet::RankedSymbol e ('e', 0); + + const std::set<alphabet::RankedSymbol> alphabet {a, b, c, e}; + + std::vector<tree::RankedNode *> children3 (0); + tree::RankedNode * node3 = new tree::RankedNode(d, children3); + std::vector<tree::RankedNode *> children4 (0); + tree::RankedNode * node4 = new tree::RankedNode(c, children4); + std::vector<tree::RankedNode *> children2 {node3}; + tree::RankedNode * node2 = new tree::RankedNode(b, children2); + std::vector<tree::RankedNode *> children1 {node2, node4}; + tree::RankedNode * node1 = new tree::RankedNode(a, children1); + + CPPUNIT_ASSERT_THROW(tree::RankedTree tree1(alphabet, *node1), exception::AlibException); + + std::vector<tree::RankedNode *> children6 (0); + tree::RankedNode * node6 = new tree::RankedNode(e, children6); + std::vector<tree::RankedNode *> children8 (0); + tree::RankedNode * node8 = new tree::RankedNode(c, children8); + std::vector<tree::RankedNode *> children7 {node8}; + tree::RankedNode * node7 = new tree::RankedNode(b, children7); + std::vector<tree::RankedNode *> children5 {node6, node7}; + tree::RankedNode * node5 = new tree::RankedNode(a, children5); + + tree::RankedTree * tree = NULL; + CPPUNIT_ASSERT_NO_THROW(tree = new tree::RankedTree(alphabet, std::move(*node5))); + CPPUNIT_ASSERT_NO_THROW(tree -> getRoot().getChildren()[0] -> setSymbol(c)); + CPPUNIT_ASSERT_THROW(tree -> getRoot().getChildren()[1] -> setSymbol(d), exception::AlibException); + CPPUNIT_ASSERT_THROW(tree -> getRoot().getChildren()[0] -> setSymbol(a), exception::AlibException); + CPPUNIT_ASSERT_THROW(tree -> removeRankedSymbol(a), exception::AlibException); + CPPUNIT_ASSERT(tree -> removeRankedSymbol(e)); + delete tree; +} + +void TreeTest::testRankedTreeSubtreeSwitch() { + alphabet::RankedSymbol a ('a', 2); + alphabet::RankedSymbol b ('b', 1); + alphabet::RankedSymbol c ('c', 0); + alphabet::RankedSymbol d ('d', 0); + + const std::set<alphabet::RankedSymbol> alphabet1 {a, b, c}; + const std::set<alphabet::RankedSymbol> alphabet2 {a, b, c, d}; + + std::vector<tree::RankedNode *> children3 (0); + tree::RankedNode * node3 = new tree::RankedNode(c, children3); + std::vector<tree::RankedNode *> children4 (0); + tree::RankedNode * node4 = new tree::RankedNode(c, children4); + std::vector<tree::RankedNode *> children2 {node3}; + tree::RankedNode * node2 = new tree::RankedNode(b, children2); + std::vector<tree::RankedNode *> children1 {node2, node4}; + tree::RankedNode * node1 = new tree::RankedNode(a, children1); + + std::vector<tree::RankedNode *> children6 (0); + tree::RankedNode * node6 = new tree::RankedNode(d, children6); + std::vector<tree::RankedNode *> children8 (0); + tree::RankedNode * node8 = new tree::RankedNode(c, children8); + std::vector<tree::RankedNode *> children7 {node8}; + tree::RankedNode * node7 = new tree::RankedNode(b, children7); + std::vector<tree::RankedNode *> children5 {node6, node7}; + tree::RankedNode * node5 = new tree::RankedNode(a, children5); + + tree::RankedTree tree1(alphabet1, std::move(*node1)); + tree::RankedTree tree1Copy (tree1); + tree::RankedTree tree2(alphabet2, std::move(*node5)); + tree::RankedTree tree2Copy (tree2); + + tree1.getRoot().getChildren()[0] -> getChildren()[0] -> switchSubtree(tree2.getRoot().getChildren()[1]); + tree1.getRoot().getChildren()[0] -> getChildren()[0] -> switchSubtree(tree2.getRoot().getChildren()[1]); + + CPPUNIT_ASSERT(tree1 == tree1Copy); + CPPUNIT_ASSERT(tree2 == tree2Copy); + CPPUNIT_ASSERT_THROW(tree1.getRoot().getChildren()[1] -> switchSubtree(tree2.getRoot().getChildren()[0]), exception::AlibException); + + tree::RankedTree tree3(tree1Copy); + tree::RankedTree tree4(tree2Copy); + + tree4.getRoot().getChildren()[0] -> setSymbol(c); + + tree3.getRoot().nicePrint(); + std::cout << std::endl; + tree4.getRoot().nicePrint(); + + tree3.getRoot().switchSubtree(&tree4.getRoot()); + + CPPUNIT_ASSERT(tree3.getRoot() < tree2Copy.getRoot()); + CPPUNIT_ASSERT(tree4.getRoot() == tree1Copy.getRoot()); + +} + +void TreeTest::testUnrankedTreeParser() { +/* + L=(a, b, c) + + \-1.a + | + |-2.b + | | + | \-3.c + | + \-4.c +*/ + const alphabet::LabeledSymbol a ('a'); + const alphabet::LabeledSymbol b ('b'); + const alphabet::LabeledSymbol c ('c'); + + const std::set<alphabet::LabeledSymbol> alphabet {a, b, c}; + + std::list<tree::UnrankedNode *> children3; + tree::UnrankedNode * node3 = new tree::UnrankedNode(c, children3); + std::list<tree::UnrankedNode *> children4; + tree::UnrankedNode * node4 = new tree::UnrankedNode(c, children4); + std::list<tree::UnrankedNode *> children2 {node3}; + tree::UnrankedNode * node2 = new tree::UnrankedNode(b, children2); + std::list<tree::UnrankedNode *> children1 {node2, node4}; + tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1); + + tree::UnrankedTree tree(alphabet, std::move(*node1)); + + CPPUNIT_ASSERT( tree == tree ); + tree.getRoot().nicePrint(std::cout); + { + std::deque<sax::Token> tokens = alib::XmlDataFactory::toTokens(tree); + std::string tmp; + sax::SaxComposeInterface::printMemory(tmp, tokens); + std::cout << std::endl << tmp << std::endl << std::endl; + + std::deque<sax::Token> tokens2; + sax::SaxParseInterface::parseMemory(tmp, tokens2); + tree::UnrankedTree tree2 = alib::XmlDataFactory::fromTokens<tree::UnrankedTree>(tokens2); + + CPPUNIT_ASSERT( tree == tree2 ); + std::cout << std::endl; + tree2.getRoot().nicePrint(std::cout); + } +} + +void TreeTest::testUnrankedTreeCompare() { +/* + L=(a, b, c) + + \-1.a + | + |-2.b + | | + | \-3.c + | + \-4.c + + \-5.a + | + |-6.c + | + \-7.b + | + \-8.c +*/ + const alphabet::LabeledSymbol a ('a'); + const alphabet::LabeledSymbol b ('b'); + const alphabet::LabeledSymbol c ('c'); + + const std::set<alphabet::LabeledSymbol> alphabet {a, b, c}; + + std::list<tree::UnrankedNode *> children3; + tree::UnrankedNode * node3 = new tree::UnrankedNode(c, children3); + std::list<tree::UnrankedNode *> children4; + tree::UnrankedNode * node4 = new tree::UnrankedNode(c, children4); + std::list<tree::UnrankedNode *> children2 {node3}; + tree::UnrankedNode * node2 = new tree::UnrankedNode(b, children2); + std::list<tree::UnrankedNode *> children1 {node2, node4}; + tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1); + + std::list<tree::UnrankedNode *> children6; + tree::UnrankedNode * node6 = new tree::UnrankedNode(c, children6); + std::list<tree::UnrankedNode *> children8; + tree::UnrankedNode * node8 = new tree::UnrankedNode(c, children8); + std::list<tree::UnrankedNode *> children7 {node8}; + tree::UnrankedNode * node7 = new tree::UnrankedNode(b, children7); + std::list<tree::UnrankedNode *> children5 {node6, node7}; + tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5); + + tree::UnrankedTree tree1(alphabet, std::move(*node1)); + tree::UnrankedTree tree2(alphabet, std::move(*node5)); + + CPPUNIT_ASSERT( tree1 != tree2 ); + CPPUNIT_ASSERT( tree1 < tree2 ); + CPPUNIT_ASSERT( tree2 > tree1 ); + CPPUNIT_ASSERT( !(tree1 > tree2) ); +} + +void TreeTest::testUnrankedTreeSymbolValidityCheck() { + alphabet::LabeledSymbol a ('a'); + alphabet::LabeledSymbol b ('b'); + alphabet::LabeledSymbol c ('c'); + alphabet::LabeledSymbol d ('d'); + alphabet::LabeledSymbol e ('e'); + + const std::set<alphabet::LabeledSymbol> alphabet {a, b, c, e}; + + std::list<tree::UnrankedNode *> children3 (0); + tree::UnrankedNode * node3 = new tree::UnrankedNode(d, children3); + std::list<tree::UnrankedNode *> children4 (0); + tree::UnrankedNode * node4 = new tree::UnrankedNode(c, children4); + std::list<tree::UnrankedNode *> children2 {node3}; + tree::UnrankedNode * node2 = new tree::UnrankedNode(b, children2); + std::list<tree::UnrankedNode *> children1 {node2, node4}; + tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1); + + CPPUNIT_ASSERT_THROW(tree::UnrankedTree tree1(alphabet, *node1), exception::AlibException); + + std::list<tree::UnrankedNode *> children6 (0); + tree::UnrankedNode * node6 = new tree::UnrankedNode(e, children6); + std::list<tree::UnrankedNode *> children8 (0); + tree::UnrankedNode * node8 = new tree::UnrankedNode(c, children8); + std::list<tree::UnrankedNode *> children7 {node8}; + tree::UnrankedNode * node7 = new tree::UnrankedNode(b, children7); + std::list<tree::UnrankedNode *> children5 {node6, node7}; + tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5); + + tree::UnrankedTree * tree = NULL; + CPPUNIT_ASSERT_NO_THROW(tree = new tree::UnrankedTree(alphabet, std::move(*node5))); + CPPUNIT_ASSERT_NO_THROW((*tree -> getRoot().getChildren().begin()) -> setSymbol(c)); + CPPUNIT_ASSERT_THROW((*tree -> getRoot().getChildren().begin()) -> setSymbol(d), exception::AlibException); + CPPUNIT_ASSERT_NO_THROW((*(++tree -> getRoot().getChildren().begin())) -> setSymbol(a)); + CPPUNIT_ASSERT_THROW(tree -> removeSymbol(a), exception::AlibException); + CPPUNIT_ASSERT(tree -> removeSymbol(e)); + delete tree; +} + +void TreeTest::testUnrankedTreeSubtreeSwitch() { + alphabet::LabeledSymbol a ('a'); + alphabet::LabeledSymbol b ('b'); + alphabet::LabeledSymbol c ('c'); + alphabet::LabeledSymbol d ('d'); + + const std::set<alphabet::LabeledSymbol> alphabet1 {a, b, c}; + const std::set<alphabet::LabeledSymbol> alphabet2 {a, b, c, d}; + + std::list<tree::UnrankedNode *> children3; + tree::UnrankedNode * node3 = new tree::UnrankedNode(c, children3); + std::list<tree::UnrankedNode *> children4; + tree::UnrankedNode * node4 = new tree::UnrankedNode(c, children4); + std::list<tree::UnrankedNode *> children2 {node3}; + tree::UnrankedNode * node2 = new tree::UnrankedNode(b, children2); + std::list<tree::UnrankedNode *> children1 {node2, node4}; + tree::UnrankedNode * node1 = new tree::UnrankedNode(a, children1); + + std::list<tree::UnrankedNode *> children6; + tree::UnrankedNode * node6 = new tree::UnrankedNode(d, children6); + std::list<tree::UnrankedNode *> children8; + tree::UnrankedNode * node8 = new tree::UnrankedNode(c, children8); + std::list<tree::UnrankedNode *> children7 {node8}; + tree::UnrankedNode * node7 = new tree::UnrankedNode(b, children7); + std::list<tree::UnrankedNode *> children5 {node6, node7}; + tree::UnrankedNode * node5 = new tree::UnrankedNode(a, children5); + + tree::UnrankedTree tree1(alphabet1, std::move(*node1)); + tree::UnrankedTree tree1Copy (tree1); + tree::UnrankedTree tree2(alphabet2, std::move(*node5)); + tree::UnrankedTree tree2Copy (tree2); + + (*(*tree1.getRoot().getChildren().begin()) -> getChildren().begin()) -> switchSubtree(*(++tree2.getRoot().getChildren().begin())); + (*(*tree1.getRoot().getChildren().begin()) -> getChildren().begin()) -> switchSubtree(*(++tree2.getRoot().getChildren().begin())); + + CPPUNIT_ASSERT(tree1 == tree1Copy); + CPPUNIT_ASSERT(tree2 == tree2Copy); + CPPUNIT_ASSERT_THROW((*(++tree1.getRoot().getChildren().begin())) -> switchSubtree(*tree2.getRoot().getChildren().begin()), exception::AlibException); + + tree::UnrankedTree tree3(tree1Copy); + tree::UnrankedTree tree4(tree2Copy); + + (*tree4.getRoot().getChildren().begin()) -> setSymbol(c); + + tree3.getRoot().nicePrint(); + std::cout << std::endl; + tree4.getRoot().nicePrint(); + + tree3.getRoot().switchSubtree(&tree4.getRoot()); + + CPPUNIT_ASSERT(tree3.getRoot() < tree2Copy.getRoot()); + CPPUNIT_ASSERT(tree4.getRoot() == tree1Copy.getRoot()); +} + diff --git a/alib2data/test-src/tree/TreeTest.h b/alib2data/test-src/tree/TreeTest.h new file mode 100644 index 0000000000000000000000000000000000000000..842c4a60183fed811bedfceb67fd2be0fcc63f0e --- /dev/null +++ b/alib2data/test-src/tree/TreeTest.h @@ -0,0 +1,34 @@ +#ifndef TREE_TEST_H_ +#define TREE_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class TreeTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( TreeTest ); + CPPUNIT_TEST( testRankedTreeParser ); + CPPUNIT_TEST( testRankedTreeCompare ); + CPPUNIT_TEST( testRankedTreeSymbolValidityCheck ); + CPPUNIT_TEST( testRankedTreeSubtreeSwitch ); + CPPUNIT_TEST( testUnrankedTreeParser ); + CPPUNIT_TEST( testUnrankedTreeCompare ); + CPPUNIT_TEST( testUnrankedTreeSymbolValidityCheck ); + CPPUNIT_TEST( testUnrankedTreeSubtreeSwitch ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testRankedTreeParser(); + void testRankedTreeCompare(); + void testRankedTreeSymbolValidityCheck(); + void testRankedTreeSubtreeSwitch(); + + void testUnrankedTreeParser(); + void testUnrankedTreeCompare(); + void testUnrankedTreeSymbolValidityCheck(); + void testUnrankedTreeSubtreeSwitch(); +}; + +#endif // TREE_TEST_H_ diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp index 148ff0fcc9dc9a9eb933bd5d6c09467ff890e80f..6b6ac7f985bbf7c55067fd90d09c369021c4af2a 100644 --- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp +++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp @@ -178,6 +178,14 @@ void AllEpsilonClosure::Visit(void* data, const CompactNFA& automaton) const { out = std::move(this->allEpsilonClosure(automaton)); } +void AllEpsilonClosure::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AllEpsilonClosure::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void AllEpsilonClosure::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h index feea7164db559dc3e58e06c2bf0619ccf34d9d76..7b29e957aef8a45e2c6fc525dbb17cdfc0a3e3ce 100644 --- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h +++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h @@ -41,6 +41,8 @@ private: 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 NFTA& automaton) const; + void Visit(void*, const DFTA& automaton) const; void Visit(void*, const DPDA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; void Visit(void*, const InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp index 3070f632768a56bd3c95e4269604cbe6f6e69f6f..a4ccda4742fbc752bfe69d5fa6a37c771503964c 100644 --- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp +++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp @@ -131,6 +131,14 @@ void ReachableStates::Visit(void* data, const CompactNFA& automaton) const { out = std::move(this->reachableStates(automaton)); } +void ReachableStates::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void ReachableStates::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void ReachableStates::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/properties/efficient/ReachableStates.h b/alib2elgo/src/automaton/properties/efficient/ReachableStates.h index 6b52d3990d4d7056b8f27804de7f719cb6a25dc9..c58dbbd5246e920b69a71e8badc122c78ea60ce3 100644 --- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.h +++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.h @@ -38,6 +38,8 @@ private: 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 NFTA& automaton) const; + void Visit(void*, const DFTA& automaton) const; void Visit(void*, const DPDA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; void Visit(void*, const InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp index 446ee0da44f08473918b5fe14488edc2af447d34..e7e6684d28545c98d3d18d0e6b6bff5d96ce3635 100644 --- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp +++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp @@ -111,6 +111,14 @@ void UsefullStates::Visit(void* data, const CompactNFA& automaton) const { out = std::move(this->usefullStates(automaton)); } +void UsefullStates::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UsefullStates::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void UsefullStates::Visit(void*, const DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.h b/alib2elgo/src/automaton/properties/efficient/UsefullStates.h index 1a4117afcaeb63abbbd234485a06992a134ac824..46a1049392a14bdf2a74fe8b70800ba170e6d9f5 100644 --- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.h +++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.h @@ -39,6 +39,8 @@ private: void Visit(void*, const ExtendedNFA& automaton) const; void Visit(void*, const CompactNFA& automaton) const; void Visit(void*, const DPDA& automaton) const; + void Visit(void*, const NFTA& automaton) const; + void Visit(void*, const DFTA& automaton) const; void Visit(void*, const SinglePopDPDA& automaton) const; void Visit(void*, const InputDrivenDPDA& automaton) const; void Visit(void*, const InputDrivenNPDA& automaton) const; diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp index 9a57df5a5f9b691caf0f03cffa746b82757c4f5b..6ec1e00cd3efb8102e87f20964486d738ba31093 100644 --- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp @@ -98,6 +98,14 @@ void EpsilonRemoverIncoming::Visit(void* data, const automaton::DFA& automaton) out = new automaton::Automaton(this->remove(automaton)); } +void EpsilonRemoverIncoming::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void EpsilonRemoverIncoming::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void EpsilonRemoverIncoming::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h index 134c41bc91c1f05681ba9a03d36a510349b7d052..0165d210d1af42286ec8816e75673fcb68025e25 100644 --- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h +++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h @@ -44,6 +44,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::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp index d44d0af0d91e2ccbd08009545d1d26b1798509e0..871d1674e751faed45fe4c4e3c5d2f58db06a39c 100644 --- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp @@ -82,6 +82,14 @@ void EpsilonRemoverOutgoing::Visit(void* data, const automaton::DFA& automaton) out = new automaton::Automaton(this->remove(automaton)); } +void EpsilonRemoverOutgoing::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void EpsilonRemoverOutgoing::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void EpsilonRemoverOutgoing::Visit(void*, const automaton::ExtendedNFA& ) const { throw exception::AlibException("Unsupported automaton type ExtendedNFA"); } diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h index 17ec208f79bb8e15031514067170f9707baf3aaf..3ae5ea98172c6fa5dd399621627581f4ea50f064 100644 --- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h +++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h @@ -44,6 +44,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::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp index 627c532b2f93f285085a0369f1509e566a51739a..fd593234d290d1caaeef5729844b80486a8a5ab3 100644 --- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp @@ -75,6 +75,14 @@ void Trim::Visit(void* data, const automaton::CompactNFA& automaton) const { out = new automaton::Automaton(this->trim(automaton)); } +void Trim::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void Trim::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void Trim::Visit(void*, const automaton::DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.h b/alib2elgo/src/automaton/simplify/efficient/Trim.h index 8048d0cd9b6d94e2ad7e8d29db5c5f54a999430f..5a48ba8306a114aeb7827ac10d10a9428cf86fed 100644 --- a/alib2elgo/src/automaton/simplify/efficient/Trim.h +++ b/alib2elgo/src/automaton/simplify/efficient/Trim.h @@ -36,6 +36,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::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp index f0b7c582ea1f31690796251ee3cdd937eb831e1b..9271cd4c59674930fb6fa5bcd68fa32359ed59ad 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp @@ -151,6 +151,14 @@ void UnreachableStatesRemover::Visit(void* data, const automaton::CompactNFA& au out = new automaton::Automaton(this->remove(automaton)); } +void UnreachableStatesRemover::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UnreachableStatesRemover::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void UnreachableStatesRemover::Visit(void*, const automaton::DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h index 4fa148ed79672df6a2f38ef01ed4585adb2fe3db..4abec63a184f60735b707366a4c878be69f6297d 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h +++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h @@ -36,6 +36,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::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp index 536ed54becb0a4358eb5144e91beac3f96eb80cf..8299c4540a109aa8e38656288ae8c219bdfa6970 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp +++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp @@ -160,6 +160,14 @@ void UselessStatesRemover::Visit(void* data, const automaton::CompactNFA& automa out = new automaton::Automaton(this->remove(automaton)); } +void UselessStatesRemover::Visit(void*, const DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void UselessStatesRemover::Visit(void*, const NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + void UselessStatesRemover::Visit(void*, const automaton::DPDA&) const { throw exception::AlibException("Unsupported automaton type DPDA"); } diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h index df0b85d6f03bf7c13d33bffd630d1a8bc032b363..14877104fd8204bc78fbdf90355a3e6e38f7cf5b 100644 --- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h +++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h @@ -36,6 +36,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::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; void Visit(void*, const automaton::DPDA& automaton) const; void Visit(void*, const automaton::SinglePopDPDA& automaton) const; void Visit(void*, const automaton::InputDrivenDPDA& automaton) const; diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp index 925c1d65cc975c6d4b534cd9299d6256ba4e255a..761c2e61ed574831a5bd8a4c45af0b1731525918 100644 --- a/arand2/src/arand.cpp +++ b/arand2/src/arand.cpp @@ -10,10 +10,13 @@ #include <automaton/FSM/NFA.h> #include <regexp/unbounded/UnboundedRegExp.h> #include <factory/XmlDataFactory.hpp> +#include <tree/RankedTree/RankedTree.h> +#include <tree/UnrankedTree/UnrankedTree.h> #include "automaton/generate/RandomAutomatonFactory.h" #include "grammar/generate/RandomGrammarFactory.h" #include "regexp/generate/RandomRegExpFactory.h" #include "string/generate/RandomStringFactory.h" +#include "tree/generate/RandomTreeFactory.h" int main(int argc, char* argv[]) { try { @@ -24,6 +27,8 @@ int main(int argc, char* argv[]) { allowed.push_back("CFG"); allowed.push_back("RE"); allowed.push_back("ST"); + allowed.push_back("UT"); + allowed.push_back("RT"); TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); TCLAP::ValueArg<std::string> type( "t", "type", "Type of generated structure", true, "FSM", &allowedVals); @@ -38,6 +43,9 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg<int> nonterminals( "", "nonterminals", "Number of grammar's nononterminals", false, 5, "integer"); cmd.add( nonterminals ); + TCLAP::ValueArg<int> nodes( "", "nodes", "Number of automaton's or tree nodes", false, 5, "integer"); + cmd.add( nodes ); + TCLAP::ValueArg<int> states( "", "states", "Number of automaton's states", false, 5, "integer"); cmd.add( states ); @@ -50,6 +58,12 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg<int> length( "", "length", "Length of the string", false, 5, "integer"); cmd.add( length ); + TCLAP::ValueArg<int> depth( "", "depth", "Depth of the regexp or tree", false, 5, "integer"); + cmd.add( depth ); + + TCLAP::ValueArg<int> maxRank( "", "rank", "Maximal rank of tree nodes", false, 5, "integer"); + cmd.add( maxRank ); + cmd.parse(argc,argv); if(!type.isSet()) throw exception::AlibException("Type is not defined."); @@ -98,6 +112,12 @@ int main(int argc, char* argv[]) { string::LinearString res = string::generate::RandomStringFactory::generateLinearString(length.getValue(), alphabetSize.getValue() ); alib::XmlDataFactory::toStdout(res); + } else if( type.getValue() == "UT" ) { + tree::UnrankedTree res = tree::generate::RandomTreeFactory::generateUnrankedTree(depth.getValue(), nodes.getValue(), alphabetSize.getValue(), maxRank.getValue()); + alib::XmlDataFactory::toStdout(res); + } else if( type.getValue() == "RT" ) { + tree::RankedTree res = tree::generate::RandomTreeFactory::generateRankedTree(depth.getValue(), nodes.getValue(), alphabetSize.getValue(), maxRank.getValue()); + alib::XmlDataFactory::toStdout(res); } else { throw exception::AlibException("Invalid type."); } diff --git a/arun2/src/arun.cpp b/arun2/src/arun.cpp index 8b6c58ba593a3eff73d908e925e5af15c1af4c31..824ee5c9346d97ae2e5b1ccd822dedb46c512d14 100644 --- a/arun2/src/arun.cpp +++ b/arun2/src/arun.cpp @@ -11,11 +11,15 @@ #include <factory/XmlDataFactory.hpp> #include <exception/AlibException.h> #include <string/String.h> +#include <object/Object.h> +#include <tree/RankedTree/RankedTree.h> #include <automaton/Automaton.h> #include <automaton/run/Accept.h> #include <automaton/run/Result.h> #include <automaton/run/Occurrences.h> +#include <iostream> + int main(int argc, char* argv[]) { try { TCLAP::CmdLine cmd("Automaton run binary", ' ', "0.01"); @@ -60,18 +64,18 @@ int main(int argc, char* argv[]) { } if( type.getValue() == "occurrences") { - string::LinearString input = alib::XmlDataFactory::fromTokens<string::LinearString>(inputTokens); + alib::Object input = alib::XmlDataFactory::fromTokens<alib::Object>(inputTokens); automaton::Automaton automaton = alib::XmlDataFactory::fromTokens<automaton::Automaton>(automatonTokens); std::set<unsigned> res = automaton::run::Occurrences::occurrences(automaton, input); alib::XmlDataFactory::toStdout( res ); return 0; } else if( type.getValue() == "accept") { - string::LinearString input = alib::XmlDataFactory::fromTokens<string::LinearString>(inputTokens); + alib::Object input = alib::XmlDataFactory::fromTokens<alib::Object>(inputTokens); automaton::Automaton automaton = alib::XmlDataFactory::fromTokens<automaton::Automaton>(automatonTokens); bool res = automaton::run::Accept::accept(automaton, input); alib::XmlDataFactory::toStdout( res ); } else if( type.getValue() == "result") { - string::LinearString input = alib::XmlDataFactory::fromTokens<string::LinearString>(inputTokens); + alib::Object input = alib::XmlDataFactory::fromTokens<alib::Object>(inputTokens); automaton::Automaton automaton = alib::XmlDataFactory::fromTokens<automaton::Automaton>(automatonTokens); label::Label res = automaton::run::Result::result(automaton, input); alib::XmlDataFactory::toStdout( res ); diff --git a/astat2/src/AutomataStat.cpp b/astat2/src/AutomataStat.cpp index 01c0aafdc9268166185e28498b5d7193630963cd..e875d94608b040b5302b159fd2a722347c590a01 100644 --- a/astat2/src/AutomataStat.cpp +++ b/astat2/src/AutomataStat.cpp @@ -242,5 +242,13 @@ void AutomataStat::Visit(void*, const automaton::OneTapeDTM&) const { throw exception::AlibException("Unsupported automaton type OneTapeDTM"); } +void AutomataStat::Visit(void*, const automaton::DFTA&) const { + throw exception::AlibException("Unsupported automaton type DFTA"); +} + +void AutomataStat::Visit(void*, const automaton::NFTA&) const { + throw exception::AlibException("Unsupported automaton type NFTA"); +} + const AutomataStat AutomataStat::AUTOMATA_STAT; diff --git a/astat2/src/AutomataStat.h b/astat2/src/AutomataStat.h index cdcded194f47bd3091c82d3397560be704ddbda2..1f992e381fe6e6ec932977817ff1245ba25f78d2 100644 --- a/astat2/src/AutomataStat.h +++ b/astat2/src/AutomataStat.h @@ -42,6 +42,8 @@ private: void Visit(void*, const automaton::NPDA& automaton) const; void Visit(void*, const automaton::SinglePopNPDA& automaton) const; void Visit(void*, const automaton::OneTapeDTM& automaton) const; + void Visit(void*, const automaton::NFTA& automaton) const; + void Visit(void*, const automaton::DFTA& automaton) const; static const AutomataStat AUTOMATA_STAT; }; diff --git a/examples2/automaton/DFTA.xml b/examples2/automaton/DFTA.xml new file mode 100644 index 0000000000000000000000000000000000000000..4183107b6da64f28bc0a350d6a8a200647dab6fe --- /dev/null +++ b/examples2/automaton/DFTA.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<DFTA><states><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></states><rankedInputAlphabet><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedInputAlphabet><finalStates><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></finalStates><transitions><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol></input><from><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></from><to><LabelSetLabel><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></LabelSetLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></input><from/><to><LabelSetLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></LabelSetLabel></to></transition></transitions></DFTA> diff --git a/examples2/automaton/NFTA.xml b/examples2/automaton/NFTA.xml new file mode 100644 index 0000000000000000000000000000000000000000..3896e43e27766e049a5ff89d4c0101b013ad8732 --- /dev/null +++ b/examples2/automaton/NFTA.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<NFTA><states><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></states><rankedInputAlphabet><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedInputAlphabet><finalStates><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></finalStates><transitions><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></from><to><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></from><to><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol></input><from><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></from><to><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol></input><from><PrimitiveLabel><Integer>2</Integer></PrimitiveLabel></from><to><PrimitiveLabel><Integer>1</Integer></PrimitiveLabel></to></transition><transition><input><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></input><from/><to><PrimitiveLabel><Integer>3</Integer></PrimitiveLabel></to></transition></transitions></NFTA> diff --git a/examples2/tree/RankedTree.xml b/examples2/tree/RankedTree.xml new file mode 100644 index 0000000000000000000000000000000000000000..cfa71eadf93bbdfe514b1bbdc9dce5176bf4a946 --- /dev/null +++ b/examples2/tree/RankedTree.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<RankedTree><rankedAlphabet><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedAlphabet><rankedNode><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><rankedNode><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><rankedNode><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><rankedNode><RankedSymbol><PrimitiveLabel><Character>b</Character></PrimitiveLabel><Integer>1</Integer></RankedSymbol><rankedNode><RankedSymbol><PrimitiveLabel><Character>a</Character></PrimitiveLabel><Integer>2</Integer></RankedSymbol><rankedNode><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedNode><rankedNode><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedNode></rankedNode></rankedNode><rankedNode><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedNode></rankedNode><rankedNode><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedNode></rankedNode><rankedNode><RankedSymbol><PrimitiveLabel><Character>c</Character></PrimitiveLabel><Integer>0</Integer></RankedSymbol></rankedNode></rankedNode></RankedTree> diff --git a/makefile b/makefile index ceb618d20e7e22ba0f1a2533a61de56dd51d73e1..43a811f4dab8cf60555ee763c1bfe1ba787a132c 100644 --- a/makefile +++ b/makefile @@ -27,6 +27,7 @@ SUBDIRS_BINS = aecho2 \ astat2 \ astringology2 \ atrim2 \ + tniceprint \ ifneq (3.81, $(firstword $(sort $(MAKE_VERSION) 3.81))) @@ -42,6 +43,7 @@ CPPUNIT_EXISTS = $(shell g++ -c -o /dev/null -xc++ - <<< \\\#include\ \<cppunit/ ifneq (0, $(CPPUNIT_EXISTS)) $(error You need cppunit installed) endif + CPPUNIT_SO_TMP = $(shell ld --verbose | grep SEARCH | tr \ \\\n | sed s/SEARCH_DIR//g | sed s/\(\\\"//g | sed s/\\\"\)\\\;//g | sed s/^=//g | sort -u | sed \s/$$/\\/libcppunit.so/g\) CPPUNIT_SO_EXISTS = $(shell ls $(CPPUNIT_SO_TMP) 2>/dev/null | wc -l) ifeq (0, $(CPPUNIT_SO_EXISTS)) diff --git a/tests.examples.sh b/tests.examples.sh index c4eeed3693a38d028cf6f21ac7c1c8ef650cc1ca..597b76937ff3a1430ca6ae27e2ab30cc6c2c5c21 100755 --- a/tests.examples.sh +++ b/tests.examples.sh @@ -125,4 +125,5 @@ runTest "automaton" runTest "grammar" runTest "regexp" runTest "string" +runTest "tree" diff --git a/tniceprint/makefile b/tniceprint/makefile new file mode 100644 index 0000000000000000000000000000000000000000..d4d105b99aedc67657d4c7b39802510f9981aa65 --- /dev/null +++ b/tniceprint/makefile @@ -0,0 +1,128 @@ +SHELL:=/bin/bash +EXECUTABLE:=tniceprint + +define NEW_LINE + + +endef + +export NEW_LINE + +LDFLAGS_DEBUG:=-L../alib2std/lib-debug -L../alib2data/lib-debug -L../alib2algo/lib-debug -L../alib2elgo/lib-debug -rdynamic -lxml2 -lalib2std -lalib2data -lalib2algo -lalib2elgo -Wl,-rpath,. + +LDFLAGS_RELEASE:=-L../alib2std/lib-release -L../alib2data/lib-release -L../alib2algo/lib-release -L../alib2elgo/lib-release -rdynamic -lxml2 -lalib2std -lalib2data -lalib2algo -lalib2elgo -Wl,-rpath,. + +OBJECTS_DEBUG:=$(patsubst src/%.cpp, obj-debug/%.o, $(shell find src/ -name *cpp)) + +OBJECTS_RELEASE:=$(patsubst src/%.cpp, obj-release/%.o, $(shell find src/ -name *cpp)) + +.PHONY: all build-debug clean-debug doc + +all: + @echo "What to do master?" + +obj%/makefile: makefile + mkdir -p $(dir $@) + echo "\ + SHELL:=/bin/bash$${NEW_LINE}\ + SRCDIR:=$${NEW_LINE}\ + DEPTH:=$${NEW_LINE}\ + OBJECTS_BASE_DIR:=$${NEW_LINE}\ + $${NEW_LINE}\ + define NEW_LINE$${NEW_LINE}\ + $${NEW_LINE}\ + $${NEW_LINE}\ + endef$${NEW_LINE}\ + $${NEW_LINE}\ + export NEW_LINE$${NEW_LINE}\ + $${NEW_LINE}\ + CXXFLAGS:= -std=c++11 \$$(CXX_OTHER_FLAGS) -c -Wall -pedantic -Wextra -Werror -fPIC -I/usr/include/libxml2/ -I../../\$$(DEPTH)alib2std/src -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src/ -I../../\$$(DEPTH)alib2elgo/src/$${NEW_LINE}\ + $${NEW_LINE}\ + SOURCES:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")$${NEW_LINE}\ + DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d, \$$(SOURCES))$${NEW_LINE}\ + OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))$${NEW_LINE}\ + SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)$${NEW_LINE}\ + OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))$${NEW_LINE}\ + OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))$${NEW_LINE}\ + $${NEW_LINE}\ + .PHONY: all$${NEW_LINE}\ + .PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)$${NEW_LINE}\ + $${NEW_LINE}\ + all: \$$(OBJECTS_DIRS) \$$(OBJECTS)$${NEW_LINE}\ + $${NEW_LINE}\ + %.d: makefile$${NEW_LINE}\ + @echo \"\\$${NEW_LINE}\ + \$$(shell sha1sum <<< \"\$$@\" | sed \"s/ -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)\$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,../\$$(DEPTH)\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\$$\$${NEW_LINE}\\$${NEW_LINE}\ + \$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/ -//g\")) makefile\$$\$${NEW_LINE}\\$${NEW_LINE}\ + \\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\$$\$${NEW_LINE}\\$${NEW_LINE}\ + \" > \$$@$${NEW_LINE}\ + $${NEW_LINE}\ + %/makefile: makefile$${NEW_LINE}\ + mkdir -p \$$(dir \$$@)$${NEW_LINE}\ + cp makefile \$$@$${NEW_LINE}\ + $${NEW_LINE}\ + %/: FORCE | %/makefile$${NEW_LINE}\ + @accesstime=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\ + \$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ OBJECTS_BASE_DIR=\$$(OBJECTS_BASE_DIR) SOURCES_BASE_DIR=\$$(SOURCES_BASE_DIR) CXX_OTHER_FLAGS=\"\$$(CXX_OTHER_FLAGS)\" && \\$${NEW_LINE}\ + accesstime2=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\ + if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\$${NEW_LINE}\ + touch .; \\$${NEW_LINE}\ + fi$${NEW_LINE}\ + $${NEW_LINE}\ + FORCE:$${NEW_LINE}\ + $${NEW_LINE}\ + -include \$$(DEPENDENCIES)" > $@ + +debug: build-debug + +release: build-release + +clean: clean-debug clean-release + $(RM) -r doc + + + +bin-debug/$(EXECUTABLE): obj-debug/ $(OBJECTS_DEBUG) + mkdir -p $(dir $@) + $(CXX) $(OBJECTS_DEBUG) -o $@ $(LDFLAGS_DEBUG) + +bin-release/$(EXECUTABLE): obj-release/ $(OBJECTS_RELEASE) + mkdir -p $(dir $@) + $(CXX) $(OBJECTS_RELEASE) -o $@ $(LDFLAGS_RELEASE) + + + +obj-debug/: FORCE | obj-debug/makefile + $(MAKE) -C $@ OBJECTS_BASE_DIR=obj-debug SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-g -O0" + +obj-release/: FORCE | obj-release/makefile + $(MAKE) -C $@ OBJECTS_BASE_DIR=obj-release SOURCES_BASE_DIR=src CXX_OTHER_FLAGS="-O3" + + + +$(OBJECTS_DEBUG): obj-debug/ + +$(OBJECTS_RELEASE): obj-release/ + + +build-debug: bin-debug/$(EXECUTABLE) + +build-release: bin-release/$(EXECUTABLE) + + + +clean-debug: + $(RM) -r *.o *.d bin-debug obj-debug + +clean-release: + $(RM) -r *.o *.d bin-release obj-release + + + +FORCE: + + + +doc: + doxygen + diff --git a/tniceprint/src/tniceprint.cpp b/tniceprint/src/tniceprint.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec7abbd882a54a75faad9dcd0bd26b74d463ad56 --- /dev/null +++ b/tniceprint/src/tniceprint.cpp @@ -0,0 +1,58 @@ +/* + * acat.cpp + * + * Created on: 24. 2. 2014 + * Author: Martin Zak + */ + +#include <tclap/CmdLine.h> +#include <string> +#include <exception/AlibException.h> +#include <factory/XmlDataFactory.hpp> +#include <sax/SaxParseInterface.h> +#include <sax/ParserException.h> +#include <tree/Tree.h> + +int main(int argc, char** argv) { + try { + TCLAP::CmdLine cmd("Tree nice print binary", ' ', "0.01"); + + TCLAP::ValueArg<std::string> input( "i", "input", "Input to nice print", false, "-", "file"); + cmd.add( input ); + + cmd.parse(argc, argv); + + std::deque<sax::Token> tokens; + if(input.isSet()) { + if(input.getValue() == "-") { + sax::SaxParseInterface::parseStdin(tokens); + } else { + sax::SaxParseInterface::parseFile(input.getValue(), tokens); + } + } else { + sax::SaxParseInterface::parseStdin(tokens); + } + + if (alib::XmlDataFactory::first<tree::RankedTree>(tokens)) { + const tree::RankedTree & tree = alib::XmlDataFactory::fromTokens<tree::RankedTree>(tokens); + tree.nicePrint(); + } else if (alib::XmlDataFactory::first<tree::UnrankedTree>(tokens)) { + const tree::UnrankedTree & tree = alib::XmlDataFactory::fromTokens<tree::UnrankedTree>(tokens); + tree.nicePrint(); + } else throw exception::AlibException("no tree on input"); + + return 0; + } catch(const exception::AlibException& exception) { + alib::XmlDataFactory::toStdout(exception); + return 1; + } catch(const TCLAP::ArgException& exception) { + std::cerr << exception.error() << std::endl; + return 2; + } catch (const std::exception& exception) { + std::cerr << "Exception caught: " << exception.what() << std::endl; + return 3; + } catch(...) { + std::cerr << "Unknown exception caught." << std::endl; + return 127; + } +}