From 79428cd8a6cc25823653a58e9bd649d3767fe7d0 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 27 Oct 2014 08:01:34 +0100 Subject: [PATCH] implement occurrences finder --- aaccept2/src/aaccept.cpp | 4 +- .../src/automaton/{accept => run}/Accept.cpp | 6 +- .../src/automaton/{accept => run}/Accept.h | 4 +- alib2algo/src/automaton/run/Occurrences.cpp | 168 ++++++++++++++++++ alib2algo/src/automaton/run/Occurrences.h | 53 ++++++ 5 files changed, 228 insertions(+), 7 deletions(-) rename alib2algo/src/automaton/{accept => run}/Accept.cpp (98%) rename alib2algo/src/automaton/{accept => run}/Accept.h (97%) create mode 100644 alib2algo/src/automaton/run/Occurrences.cpp create mode 100644 alib2algo/src/automaton/run/Occurrences.h diff --git a/aaccept2/src/aaccept.cpp b/aaccept2/src/aaccept.cpp index e9aeaf73de..22d3a7e0d6 100644 --- a/aaccept2/src/aaccept.cpp +++ b/aaccept2/src/aaccept.cpp @@ -8,7 +8,7 @@ #include <exception/AlibException.h> #include <factory/DataFactory.hpp> -#include "automaton/accept/Accept.h" +#include "automaton/run/Accept.h" int main(int argc, char** argv) { @@ -19,7 +19,7 @@ int main(int argc, char** argv) { } else if (argc == 2) { automaton::Automaton automaton = alib::DataFactory::fromStdin<automaton::Automaton>(); string::LinearString string = alib::DataFactory::fromFile<string::LinearString>(argv[1]); - if(automaton::accept::Accept::accept(automaton, string)) { + if(automaton::run::Accept::accept(automaton, string)) { std::cout << "Accept" << std::endl; return 0; } else { diff --git a/alib2algo/src/automaton/accept/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp similarity index 98% rename from alib2algo/src/automaton/accept/Accept.cpp rename to alib2algo/src/automaton/run/Accept.cpp index 29b05fa60a..d810e76289 100644 --- a/alib2algo/src/automaton/accept/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -1,5 +1,5 @@ /* - * AcceptLeftRG.h + * Accept.cpp * * Created on: 9. 2. 2014 * Author: Jan Travnicek @@ -15,7 +15,7 @@ namespace automaton { -namespace accept { +namespace run { bool Accept::accept(const automaton::Automaton& automaton, const string::LinearString& string) { std::pair<const string::LinearString*, bool> data(&string, false); @@ -161,6 +161,6 @@ void Accept::Visit(void*, const OneTapeDTM&) const { const Accept Accept::ACCEPT; -} /* namespace accept */ +} /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/accept/Accept.h b/alib2algo/src/automaton/run/Accept.h similarity index 97% rename from alib2algo/src/automaton/accept/Accept.h rename to alib2algo/src/automaton/run/Accept.h index c10be122c3..e4ba6aba2c 100644 --- a/alib2algo/src/automaton/accept/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -13,7 +13,7 @@ namespace automaton { -namespace accept { +namespace run { class Accept : public automaton::VisitableAutomatonBase::const_visitor_type { public: @@ -47,7 +47,7 @@ private: static const Accept ACCEPT; }; -} /* namespace accept */ +} /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp new file mode 100644 index 0000000000..2b043b30e6 --- /dev/null +++ b/alib2algo/src/automaton/run/Occurrences.cpp @@ -0,0 +1,168 @@ +/* + * Occurrences.cpp + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#include "Occurrences.h" +#include <exception/AlibException.h> +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/PDA/DPDA.h> + +#include <deque> + +namespace automaton { + +namespace run { + +std::set<int> Occurrences::occurrences(const automaton::Automaton& automaton, const string::LinearString& string) { + std::pair<const string::LinearString*, std::set<int>> data(&string, {}); + automaton.getData().Accept((void*) &data, Occurrences::OCCURRENCES); + return data.second; +} + +std::set<int> Occurrences::occurrences(const automaton::DFA& automaton, const string::LinearString& string) { + automaton::State state = automaton.getInitialState(); + int i = 0; + std::set<int> occ; + + for(const alphabet::Symbol& symbol : string.getContent()) { + if(automaton.getFinalStates().count(state)) + occ.insert(i); + + auto transitions = automaton.getTransitionsFromState(state); + auto next = transitions.find(std::make_pair(state, symbol)); + if(next == transitions.end()) return {}; + state = next->second; + + i++; + } + + if(automaton.getFinalStates().count(state)) + occ.insert(i); + + return occ; +} + +std::set<int> Occurrences::occurrences(const automaton::DPDA& automaton, const string::LinearString& string) { + automaton::State state = automaton.getInitialState(); + std::deque<alphabet::Symbol> pushdownStore; + int i = 0; + std::set<int> occ; + + for(const alphabet::Symbol& symbol : string.getContent()) { + if(automaton.getFinalStates().count(state)) + occ.insert(i); + + auto transitions = automaton.getTransitionsFromState(state); + auto transition = transitions.begin(); + int pushdownStoreSize = pushdownStore.size(); + for(auto transition = transitions.begin(); transition != transitions.end(); transition++) { + if(std::get<1>(transition->first) != symbol) continue; + + const std::vector<alphabet::Symbol> & pop = std::get<2>(transition->first); + int popSize = pop.size(); + if(pushdownStoreSize < popSize) continue; + bool sign = true; + for(int i = 1; i <= popSize; i++) { + if(pop[popSize - i] != pushdownStore[pushdownStoreSize - i]) { + sign = false; + break; + } + } + if(!sign) continue; + + break; + } + if(transition == transitions.end()) return {}; + for(auto pop : std::get<2>(transition->first)) pushdownStore.pop_back(); + + state = transition->second.first; + for(const alphabet::Symbol& push : transition->second.second) pushdownStore.push_back(push); + + i++; + } + + if(automaton.getFinalStates().count(state)) + occ.insert(i); + + if(pushdownStore.empty()) { + return occ; + } else { + return {}; + } +} + +void Occurrences::Visit(void*, const automaton::EpsilonNFA& ) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void Occurrences::Visit(void*, const automaton::MultiInitialStateNFA& ) const { + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void Occurrences::Visit(void*, const automaton::NFA& ) const { + throw exception::AlibException("NFA"); +} + +void Occurrences::Visit(void* data, const automaton::DFA& automaton) const { + std::pair<const string::LinearString*, std::set<int>> & res = *((std::pair<const string::LinearString*, std::set<int>>*) data); + res.second = this->occurrences(automaton, *res.first); +} + +void Occurrences::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void Occurrences::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void Occurrences::Visit(void* data, const DPDA& automaton) const { + std::pair<const string::LinearString*, std::set<int>> & res = *((std::pair<const string::LinearString*, std::set<int>>*) data); + res.second = this->occurrences(automaton, *res.first); +} + +void Occurrences::Visit(void*, const SinglePopDPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void Occurrences::Visit(void*, const InputDrivenNPDA&) const { + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void Occurrences::Visit(void*, const VisiblyPushdownDPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void Occurrences::Visit(void*, const VisiblyPushdownNPDA&) const { + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void Occurrences::Visit(void*, const RealTimeHeightDeterministicDPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void Occurrences::Visit(void*, const RealTimeHeightDeterministicNPDA&) const { + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void Occurrences::Visit(void*, const NPDA&) const { + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void Occurrences::Visit(void*, const SinglePopNPDA&) const { + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void Occurrences::Visit(void*, const OneTapeDTM&) const { + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const Occurrences Occurrences::OCCURRENCES; + +} /* namespace run */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h new file mode 100644 index 0000000000..f15101fd50 --- /dev/null +++ b/alib2algo/src/automaton/run/Occurrences.h @@ -0,0 +1,53 @@ +/* + * Occurrences.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _AUTOMATON_OCCURRENCES_H__ +#define _AUTOMATON_OCCURRENCES_H__ + +#include <automaton/Automaton.h> +#include <string/LinearString.h> + +namespace automaton { + +namespace run { + +class Occurrences : public automaton::VisitableAutomatonBase::const_visitor_type { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static std::set<int> occurrences(const automaton::Automaton& automaton, const string::LinearString& string); + + static std::set<int> occurrences(const automaton::DFA& automaton, const string::LinearString& string); + static std::set<int> occurrences(const automaton::DPDA& automaton, const string::LinearString& string); +private: + void Visit(void*, const EpsilonNFA& automaton) const; + void Visit(void*, const MultiInitialStateNFA& automaton) const; + void Visit(void*, const NFA& automaton) const; + 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 DPDA& automaton) const; + void Visit(void*, const SinglePopDPDA& automaton) const; + void Visit(void*, const InputDrivenNPDA& automaton) const; + void Visit(void*, const VisiblyPushdownDPDA& automaton) const; + void Visit(void*, const VisiblyPushdownNPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void*, const NPDA& automaton) const; + void Visit(void*, const SinglePopNPDA& automaton) const; + void Visit(void*, const OneTapeDTM& automaton) const; + + static const Occurrences OCCURRENCES; +}; + +} /* namespace run */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_OCCURRENCES_H__ */ -- GitLab