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