From 0459d0beee2d1cfd624e4c1759e23758594d564e Mon Sep 17 00:00:00 2001 From: Jakub Doupal <doupajak@fit.cvut.cz> Date: Sat, 14 May 2016 19:18:54 +0200 Subject: [PATCH] Added run capabilities for NPDTA --- alib2algo/src/automaton/run/Accept.cpp | 9 ++ alib2algo/src/automaton/run/Accept.h | 1 + alib2algo/src/automaton/run/Run.cpp | 100 ++++++++++++++++++++++ alib2algo/src/automaton/run/Run.h | 1 + alib2algo/src/automaton/run/Translate.cpp | 41 +++++++++ alib2algo/src/automaton/run/Translate.h | 38 ++++++++ arun2/src/arun.cpp | 9 ++ 7 files changed, 199 insertions(+) create mode 100644 alib2algo/src/automaton/run/Translate.cpp create mode 100644 alib2algo/src/automaton/run/Translate.h diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp index 47089a7f5c..89ee3e4888 100644 --- a/alib2algo/src/automaton/run/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -15,8 +15,10 @@ #include <automaton/PDA/VisiblyPushdownDPDA.h> #include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> #include <automaton/PDA/DPDA.h> +#include <automaton/PDA/NPDTA.h> #include <deque> +#include <vector> #include <algorithm> namespace automaton { @@ -103,6 +105,13 @@ bool Accept::accept ( const automaton::DPDA & automaton, const string::LinearStr auto AcceptDPDALinearString = Accept::RegistratorWrapper < bool, automaton::DPDA, string::LinearString > ( Accept::accept ); +bool Accept::accept ( const automaton::NPDTA & automaton, const string::LinearString & string ) { + std::tuple < bool, std::set < automaton::State >, std::set < std::vector < alphabet::Symbol > > > res = Run::calculateStates ( automaton, string ); + return std::get<0>(res); +} + +auto AcceptNPDTALinearString = Accept::RegistratorWrapper < bool, automaton::NPDTA, string::LinearString > ( Accept::accept ); + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h index 4497396694..fa2d0fd08a 100644 --- a/alib2algo/src/automaton/run/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -36,6 +36,7 @@ public: static bool accept ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ); static bool accept ( const automaton::RealTimeHeightDeterministicDPDA & automaton, const string::LinearString & string ); static bool accept ( const automaton::DPDA & automaton, const string::LinearString & string ); + static bool accept ( const automaton::NPDTA & automaton, const string::LinearString & string ); }; diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp index 2e17ab5f8b..3580d1bc9f 100644 --- a/alib2algo/src/automaton/run/Run.cpp +++ b/alib2algo/src/automaton/run/Run.cpp @@ -14,9 +14,11 @@ #include <automaton/PDA/VisiblyPushdownDPDA.h> #include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> #include <automaton/PDA/DPDA.h> +#include <automaton/PDA/NPDTA.h> #include <global/GlobalData.h> #include <deque> +#include <algorithm> namespace automaton { @@ -468,6 +470,104 @@ std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol > // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +struct graphStructuredStack { + graphStructuredStack ( graphStructuredStack * parent, alphabet::Symbol data ) : parent(parent), data(data) {} + graphStructuredStack * parent; + alphabet::Symbol data; +}; + +std::tuple < bool, std::set < State >, std::set < std::vector < alphabet::Symbol > > > Run::calculateStates ( const automaton::NPDTA & automaton, const string::LinearString & string ) { + bool res = false; + unsigned i = 0; + std::set < unsigned > occurrences; + automaton::State state = automaton . getInitialState (); + std::vector<alphabet::Symbol>::const_iterator symbolIter = string . getContent () . begin (); + graphStructuredStack * stackNode = new graphStructuredStack ( NULL, (* symbolIter) ); + graphStructuredStack * outputNode = new graphStructuredStack ( NULL, (* symbolIter) ); + std::set < graphStructuredStack* > allNodes { stackNode, outputNode }; + + if ( automaton . getFinalStates () . count ( state ) ) { + occurrences . insert ( i ); + } + + std::deque < std::tuple < automaton::State, std::vector<alphabet::Symbol>::const_iterator, graphStructuredStack*, graphStructuredStack* > > bftQueue; + auto configuration = std::make_tuple ( state, symbolIter, stackNode, outputNode ); + bftQueue . push_back ( configuration ); + + std::set < std::vector < alphabet::Symbol > > allOutputs; + std::set < State > states; + + while ( ! bftQueue . empty () ) { + configuration = bftQueue . front (); bftQueue . pop_front (); + state = std::get<0>(configuration); + symbolIter = std::get<1>(configuration); + stackNode = std::get<2>(configuration); + outputNode = std::get<3>(configuration); + + if ( symbolIter == string . getContent () . end () ) { + states . insert ( state ); + if ( automaton . getFinalStates () . count ( state ) && stackNode -> parent == NULL ) { + res = true; + std::vector < alphabet::Symbol > output; + while ( outputNode->parent != NULL ) { + output . push_back ( outputNode->data ); + outputNode = outputNode -> parent; + } + std::reverse ( output.begin(), output.end() ); + allOutputs . insert ( output ); + } + continue; + } + + auto transitions = automaton . getTransitionsFromState ( state ); + for ( auto transition = transitions . begin (); transition != transitions . end (); transition ++ ) { + if ( std::get<1>(transition -> first) != (* symbolIter) && ! std::get<1>(transition -> first) . is<string::Epsilon>() ) { + continue; + } + auto pop = std::get<2>(transition -> first); + graphStructuredStack * stackNodeCopy = stackNode; + graphStructuredStack * outputNodeCopy = outputNode; + + unsigned j = 0; + for ( ; j < pop . size (); j ++ ) { + if ( stackNodeCopy->parent == NULL || stackNodeCopy->data != pop . at (j) ) { + break; + } + stackNodeCopy = stackNodeCopy -> parent; + } + if ( j == pop . size () ) { + for ( auto iter = (std::get<1>(transition -> second)).rbegin(); iter != (std::get<1>(transition -> second)).rend(); iter ++ ) { + stackNodeCopy = new graphStructuredStack ( stackNodeCopy, (* iter) ); + allNodes . insert ( stackNodeCopy ); + } + for ( auto iter = (std::get<2>(transition -> second)).begin(); iter != (std::get<2>(transition -> second)).end(); iter ++ ) { + outputNodeCopy = new graphStructuredStack ( outputNodeCopy, (* iter) ); + allNodes . insert ( outputNodeCopy ); + } + + if ( ! std::get<1>(transition -> first) . is<string::Epsilon>() ) { + configuration = std::make_tuple ( std::get<0>(transition -> second), symbolIter + 1, stackNodeCopy, outputNodeCopy ); + } + else { + configuration = std::make_tuple ( std::get<0>(transition -> second), symbolIter, stackNodeCopy, outputNodeCopy ); + } + bftQueue . push_back ( configuration ); + } + else { + states . insert ( state ); + } + } + } + + for ( auto iter = allNodes . begin (); iter != allNodes . end (); iter ++ ) { + delete (* iter); + } + + return std::make_tuple ( res, states, allOutputs ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h index 1f71d44ce8..477f486dbf 100644 --- a/alib2algo/src/automaton/run/Run.h +++ b/alib2algo/src/automaton/run/Run.h @@ -32,6 +32,7 @@ public: static std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ); static std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::RealTimeHeightDeterministicDPDA & automaton, const string::LinearString & string ); static std::tuple < bool, State, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::DPDA & automaton, const string::LinearString & string ); + static std::tuple < bool, std::set < State >, std::set < std::vector < alphabet::Symbol > > > calculateStates ( const automaton::NPDTA & automaton, const string::LinearString & string ); }; } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Translate.cpp b/alib2algo/src/automaton/run/Translate.cpp new file mode 100644 index 0000000000..4b430d1681 --- /dev/null +++ b/alib2algo/src/automaton/run/Translate.cpp @@ -0,0 +1,41 @@ +/* + * Translate.cpp + * + * Created on: 12. 5. 2016 + * Author: Jakub Doupal + */ + +#include "Translate.h" +#include "Run.h" +#include <automaton/PDA/NPDTA.h> + +#include <deque> +#include <set> + +namespace automaton { + +namespace run { + +std::set < string::LinearString > Translate::translate ( const automaton::Automaton & automaton, const alib::Object & object ) { + return dispatch ( automaton.getData ( ), object.getData ( ) ); +} + +std::set < string::LinearString > Translate::translate ( const automaton::Automaton & automaton, const string::LinearString & string ) { + return dispatch ( automaton.getData ( ), string ); +} + +std::set < string::LinearString > Translate::translate ( const automaton::NPDTA & automaton, const string::LinearString & string ) { + std::tuple < bool, std::set < automaton::State >, std::set < std::vector < alphabet::Symbol > > > res = Run::calculateStates ( automaton, string ); + std::set < string::LinearString > strings; + for ( auto iter = std::get<2>(res).begin(); iter != std::get<2>(res).end(); iter ++ ) { + string::LinearString str (* iter); + strings . insert ( str ); + } + return strings; +} + +auto TranslateNPDTALinearString = Translate::RegistratorWrapper < std::set < string::LinearString >, automaton::NPDTA, string::LinearString > ( Translate::translate ); + +} /* namespace run */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Translate.h b/alib2algo/src/automaton/run/Translate.h new file mode 100644 index 0000000000..2b52617679 --- /dev/null +++ b/alib2algo/src/automaton/run/Translate.h @@ -0,0 +1,38 @@ +/* + * Translate.h + * + * Created on: 12. 5. 2016 + * Author: Jakub Doupal + */ + +#ifndef _AUTOMATON_TRANSLATE_H__ +#define _AUTOMATON_TRANSLATE_H__ + +#include <core/multipleDispatch.hpp> +#include <automaton/Automaton.h> +#include <object/Object.h> +#include <string/LinearString.h> +#include <alphabet/Symbol.h> + +namespace automaton { + +namespace run { + +class Translate : public std::DoubleDispatch < Translate, std::set < string::LinearString >, automaton::AutomatonBase, alib::ObjectBase > { +public: + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static std::set < string::LinearString > translate ( const automaton::Automaton & automaton, const alib::Object & object ); + static std::set < string::LinearString > translate ( const automaton::Automaton & automaton, const string::LinearString & string ); + + static std::set < string::LinearString > translate ( const automaton::NPDTA & automaton, const string::LinearString & string ); + +}; + +} /* namespace run */ + +} /* namespace automaton */ + +#endif /* _AUTOMATON_TRANSLATE_H__ */ diff --git a/arun2/src/arun.cpp b/arun2/src/arun.cpp index 900f83169c..c871afe952 100644 --- a/arun2/src/arun.cpp +++ b/arun2/src/arun.cpp @@ -20,6 +20,7 @@ #include <automaton/Automaton.h> #include <automaton/run/Accept.h> #include <automaton/run/Result.h> +#include <automaton/run/Translate.h> #include <automaton/run/Occurrences.h> #include <container/ObjectsSet.h> @@ -36,6 +37,7 @@ int main(int argc, char* argv[]) { allowed.push_back("occurrences"); allowed.push_back("accept"); allowed.push_back("result"); + allowed.push_back("translate"); TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); TCLAP::ValueArg<std::string> type( "t", "type", "Run type", false, "accept", &allowedVals); @@ -89,6 +91,13 @@ int main(int argc, char* argv[]) { measurements::end(); measurements::start("Output write", measurements::Type::AUXILIARY); + alib::XmlDataFactory::toStdout( res ); + } else if( type.getValue() == "translate") { + std::set < string::LinearString > res = automaton::run::Translate::translate(automatonData, inputData); + + measurements::end(); + measurements::start("Output write", measurements::Type::AUXILIARY); + alib::XmlDataFactory::toStdout( res ); } else { throw exception::CommonException( "Invalid run type" ); -- GitLab